GeoTools : MapLayerArchitecture - 2_PriorArt

Created by Matthias Basler, last modified by Adrian Custer on Jul 12, 2006

Prior art - An evaluation of what exists in GeoTools, GeoAPI and Udig

GeoTools

Maps and map layers

GeoTools map interfaces and implementations reside in org.geotools.map. There are two interfaces, MapContext and MapLayer. The default implementations are DefaultMapContext and DefaultMapLayer. Both interfaces are intuitive to me for the very most part. They contain mainly the methods, functions and listener plugs that one would expect for describing a geographical map and its layers.

Basically the map interfaces manages layers, allows to set the area of interest (plus its CRS), has a zoom/pan function(?) and has following metadata attached: Abstract, ContactInformation, Keywords and Title.
Listener plugs exist for MapLayerListListener, MapBoundsListener and PropertyChangeListener

The map layer interfaces manages FeatureSource, Style and an optional Query.
It has only the title as metadata and a visibility flag.
Listener plugs exist for MapLayerListener, which listens for visibility and title.

Data access

GeoTools has direct data access: The layer directly contains the FeatureSource, which gives direct access to the FeatureCollection and the FeatureStore.

Rendering

There is one renderer for the whole map (LiteRenderer preferred as of August 2005) which is provided with the MapContext, a Graphics2D graphics context, a transform and a rectangle that determines the area to render.
As said, this renderer renders the whole map.

uDig

The uDig project brings its own interfaces for maps and map layers, obviously since within uDig the project the GeoTools interfaces were not considered adequate. (Why not. What were the main reasons to come up with own interfaces?) It should be noted that the corresponding interfaces, IMap and ILayer, do not extend the GeoTools interfaces either.
Jesse wrote:

The starting place for the udig map model is the OGC context document and was, during design, a superset of the WMS context document.

IMap currently has external dependencies on

org. eclipse.core.runtime.IProgressMonitor and

import org.geotools.geometry.JTS (the ReferencedEnvelope class)

Beside the expected list of ILayer the IMap class contains references to the IViewportModel, IEditManager, IRenderManager, a IBlackboard
Furthermore its bounds and aspect ratio can be queried.
It contains following metadata: abstract.
Last but not least it contains methods for executing MapCommands

That is an awful lot of objects, whose purpose requires some explainations:

IViewportModel - it describes the object (some sort of map pane). It contains the CRS used for map display, the size of the display, the "worldToScreenTransform" (which covers zooming and such) and some related functions.

IEditManager - It returns the layer and feature currently being edited (if any) and the currently selected layer. IEditManagerListener can be registered.

IRenderManager - It manages the rendering process, e.g. initiates rerendering of changes occur. It has a reference to the IMapDisplay (the UI object, such as a map pane) and contains a list of IRenderers. Furthermore some methods to initiate and stop rendering exist.
All of the above objects contain a reference back to the map. I guess this means, that there is a 1:1 relationship, i.e. one viewport model, edit manager and render manager are tied to one map.The backbord, last but not least, is "used by various plugins in order to store data and collaborate."

This was the IMap only. Now let's have a look at the ILayer. It has external dependencies on (GeoTools and GeoAPI not considered):

com.vividsolutions.jts.geom.Envelope;

org.eclipse.core.runtime.IProgressMonitor;

org.eclipse.jface.resource.ImageDescriptor;
The layer, as expected, points to the geodata proxy, a IGeoResource, plus there is a method (getResource(...)) for direct access to this geodata.Note: It is not clear to me whether a layer implementation should/can/cannot have more than one IGeoResource. Is one of them the "default" one?
Beside this, the layer can return its FeatureType, its query, its bounds, its Z-Order, the filter used to filter out features and its rendering status (such as UNAVAILABLE, WORKING or DONE). The latter can also be set. As with the GeoTools layer interface there is a visibility flag. It contains functions to check, which (editing) tools can be used on a layer. There is a again a IBlackboard, for the styles in this case, and an inofficial one ("get Properties") for other things. One function requests a filter for all objects within a given rectangle (bounds).
When it comes to referencing, each layer has its CRS attached, plus the MathTransforms needed to go from the layer CRS to the map's CRS and vice versa.
It is clear, that the ILayer contains a reference back to its map.
Also it contains following metadata: name, ID (an URL) and a glyph (small icon for the legend).
There are plugs for {{ILayerListener}}s.

Wow, that was heavy for a newby like me. So, lets sort out some points of discussion:

IProgressMonitor. Since it would introduce a dependency on Eclipse, I'd not like to have it in any API that lives in GeoTools. Not that I dislike Eclipse! I just would like to keep the API clean from to specific dependencies.
There exists an interface "ProgressListener" in GeoTools which might be a good choice. All that would be needed for uDig is an adapter class to IProgressMonitor. Would this be possible?
-> Interface in GeoTools, Eclipse adapter class into GeoWidgets?

JTS.ReferencedEnvelope as the second external import. JTS is included in GeoTools, so that's OK to use.
Currently the JTS:Envelope class is widely used, such as in the GeoTools:MapLayer class. Martin told me, that on the long run the GeoAPI:Envelope interface should be used. Jesse finds this interface "unwieldly". Hmm.

The ImageDesriptor. This will (hopefully ) be discussed in a "How to cope with AWT vs. SWT" section later.

Unlike in GeoTools every object knows its co-objects. You can query a map for its viewport model and the viewport model for its map. Same for map and map layers and so on. Obviously this makes it easy to query any other object, if one of the group of objects is known. As said, this implies a 1:1 relationship - does this make sense always? Also it requires that these links are kept synchronous. Alternative concepts should be evaluated. When there will be some objects living in GeoTools and some in GeoWidgets or uDig, such bidirectional references might not always be possible. Sometimes they will probably not be desired as well. (See my notes about data interfaces, which should not know anything about the context they are used in.)

Blackboards. They make sense in application specific interfaces, but I'd like to keep them out of data interfaces. Applications can add them on top of the basic interfaces whenever they need them.

What I like is that the interfaces show clearly that each layer may have a CRS different from the map CRS and that the layers might need to get transformed.

GeoAPI

There is only a Layer interfaces in GeoAPI. This is based on the WMS specification 19128. It is the "basic unit of geographic information that may be requested as a map from a server." and "may be added to FeatureCanvas or Canvas".

The GeoAPI Layer can hold a list of child Layers. This allows to use this very same interface to represent a group of layers (or even a map?)

It returns a collection of bounding boxes (Envelope), a list of Style a list of rendered graphics and a set of CRS. Each bounding box must have a different CRS. A geographic bounding box can also be returned.
Layers may have fixed height or width or might only able to render the area within their bounding boxes. They can be opaqe (paint over all layers below). There is a getCascaded counter (see Javadoc for more details). Furthermore a flag isQueryable "indicates whether the GetFeatureInfo operation is supported on this Layer."
Metadata stored are abstract, attribution, authority URLs, feature list URLs, identifiers, keywords, name and title. A minimum and maximum map scale at which to render the map can also get defined.

I'm not familar with this interface, so I will carefully judge about it:

There is lots of metadata stored. I wonder if it wouldn't be a good idea to put them into a separate class - there might be the need to add some more means of description.

I like the idea of telling the renderer that a layer should(?) not be drawn outside a range of map scales. Also the isOpaque flag might make sense, given a rendering logic that uses it.

What I don't understand yet is the hierarchical concept of child Layers within a Layer. Is this a means of grouping multiple layers with one data set to "map-like" objects?

OGC specification 05-005 "Web map contect documents 1.1.0"

The above GeoAPI layer class is based on the Open Geospatial Consortium's Web map contect documents 1.1.0 specification. So it might me helpful to take a look at the actual document here to understand the interface and how it was designed.

The "Web map context" describes, on the first glimpse, exactly what this map framework is about: A map layer, a map (or "Map Context") and even a map collection (called "Context Collection"). However the specification is really tailored to Web maps, i.e. map layers that offer images from WMS servers. As such several attributes are included that do not make much sense outside this scope, such as "Format list" (which lists available image formats as MIME types) and several specific metadata URLs.
A remark at the beginning of the document states this clearly: "... organisations whishing to extend the ViewContext to include non-WMS services should create a new schema that is consistent with this specification ...".

There's one more point that I consider important. The "Web map contect document" describes an XML schema, not a Java interface! The GeoAPI Layer class has, imho, made the mistake to copy the schema to directly to Java classes and attributes. This results in an interface, that closely mirrors the specification, but seems to be too specific to be used in what I imagine for a generic and general map framework (sorry, Jesse Crossley).

Other projects

I have no insight what exists in this field beside GeoTools/GeoAPI and uDig. If someone knows other Java projects of this kind that have a map/maplayer architecture, please add the project and its status and concepts of their map/layer/rendering API here.

Ideas gotten from existing GIS apps

Some applications allow to group layers within a map. (This is the same concept as "code folding"): One can make a whole bunch of layers visible or invisible with one click - both in the legend widget and on the map. I consider this useful for maps with many layers.