Wednesday, October 13, 2010

Selection of audio file with component identification

In the current version of mGIS interface, which audio file is to play for a layer of components, is defined inside the program. After the last discussion with our Geography partners, seems like all of the students should have an identical view of a single map data. So individualization of mGIS interface may not be an issue. But if we want the educators able to select audio files for different layers, we should provide some facilities for doing this.

Using style sheet may be an option. I can think of it as a table lookup process. Here I am describing how we can incorporate style sheet:

We already have mouse motion event listener registered with the map components. Whenever the mouse pointer points a pixel, this listener triggers the event and calls the event performed method.

eventPerformed(mouseMotion event){

String layerName = identifyMapLayer(event.getX, event.getY);
String audioFileName = style.Layer(layerName);


}

Here the identifyMapLayer returns the layer name and the style sheet then look up the audio file name for the corresponding layer. We know how to define the identifyMapLayer method. Now we need to find out a way to define a style sheet.

In this way the style sheet will have no dependency on arcGIS components and events. If we think about this from the modular point of view, this style sheet can be built independently without having much integration cost. I hope the educators of mGIS interface will be able to select or change the audio files for different layers.

Sunday, October 10, 2010

Style sheet API thoughts

    I'm looking through Keith Albin's style sheet project (part of his B.S. thesis project) and starting to think about how to turn it into a useful library for the current project and future projects.

    In the version Keith wrote, the interface to a soundscape map is through the map data structure.  That structure, called a "geoshape", was conceptually similar to a shapes in an ArcGIS shapefile  (because ultimately that's where the data came from, though it went through a couple of transformations on its way into the program), but it was a new Java data structure.  The style sheet processor worked as follows:
  •  Parse the style sheet(s).  There could be more than one because it provided "cascading" like CSS, but  somewhat more powerful (e.g., it provided variables with some simple string manipulation, to make style sheets much more compact and modular).
  •  For each geoshape
  •             look up the attributes for the geoshape by class and identifier
  •             attach attributes to the geoshape data structure

   I'm pretty sure that's not the interface we want, because we don't want the GIS software to have to put all the map data into a custom data structure.  I think it will be pretty straightforward to instead allow the GIS software to look up attributes of a shape as needed.   So now I'm thinking about what that API should be.  I'd like to keep it as independent of the particular GIS data structures as possible, but still convenient to use.

   My initial thought is that it might work something like this:
  • Instantiate a style sheet object, giving it a name or search path for a style sheet specification file.  (I.e., the constructor  of a style sheet object will require information on where to find a style sheet).
  •  Further interactions will take place from within event listeners, or code called by event listeners.  If we were drawing the map ourselves, they might also take place from methods that paint the map on the screen.  A typical call might be  something like


  AttributeDescriptor  styles.getAttribute ( 

            eventKind,   // Should this be a string?
            shapeLayerName, // Ditto ... string?  Probably fast enough
            shapeID // String?
                                              );


     The eventKind parameter might be redundant if the AttributeDescriptor is itself a table for looking up particular  attributes, e.g., a simple string -> string table like this.

{ (color: #44c819), (on-entry-sound:  mp3#carsCrashing.mp3),
  (on-exit-sound: midi(some-textual-rep-of-midi-spec)) }


My current thinking, though, is that there isn't much advantage in retrieving all the attributes for a particular object, and then picking out the particular attributes of interest.  It seems that in almost all cases (except for painting the  map on the screen) we need only one attribute from an object, such as "what sound do I play when the cursor  enters the object called 'Yellowstone Lake' in the 'Bodies of Water' layer?"

So what is the type of the thing returned by the style sheet object in answer to that question?  Consider that some types    make sense (e.g., mp3 file and midi spec might make sense for a sound) and others don't (hexadecimal codes for  colors don't make sense for a sound).  A simple answer would be to always return a string, and let the mGIS software be responsible for making sense of the string.  However, besides making the mGIS software a bit more complex, I think there might be some performance issues with that.  For example, if the mGIS software doesn't learn the name of an   mp3 file to play until the cursor reaches an object requiring that sound clip, it cannot preload the mp3 for immediate playback.  This makes me think that there should probably be a somewhat more complex instantiation of the  style-sheet object with some "hooks" to allow much more specific attribute objects to be returned when needed.

Although I haven't thought it through completely, I'm thinking of something like a framework, where the stylesheet software (or a layer just above the core stylesheet software) allows plugging in objects with custom methods for different kinds of interaction.  Think of them as being like listeners --- the mGIS software would provide a set of listener objects when instantiating the style sheet package, and the style sheet package would invoke those listeners when the mGIS software reported an event on a particular object.   So instead of styles.getAttribute above, it might be something like

styles.reactToEvent( eventKind, shapeLayerName, shapeID )

which would find the correct listener in the style sheet internal structure and call it.

Does this make sense? Thoughts on how to make it better or easier to use?