Layers are components that get added to the MapBean in a hierarchical stacking order. The map is drawn by painting the graphics of each layer starting with the bottommost one and proceeding up the hierarchy. Successive layers render their graphics on top of the graphics of lower ones.
PlugIns are components that are used by the PlugInLayer to fetch data and prepare graphics for the map.
Layers and PlugIns are responsible for aquiring, constructing, and rendering their own graphical data. The OMGraphics package provides a simple way to construct vector and raster graphics out of geo-spatial and XY data.
They can also be interactive, by registering for mouse events and constructing their very own GUI widget controls.
When a layer is added to the MapBean, it automatically becomes a ProjectionListener of the MapBean. This means that the layer receives notification when the Projection (or view) of the map changes.
To reiterate, the standard capabilities of a Layer are:
This is a generic layer for displaying data in ESRI shapefile format. See the ShapeLayer class.
A different component for handling Shape data is in the esri plugin package.
This is a generic layer for displaying NIMA VPF data. See the VPFLayer class.
The EarthquakeLayer displays data of recent earthquake activity. It gets its data by querying live data feeds at the USGS.
To write your own layer, you need to extend the
Layer class. The minimum
requirement is that you override the projectionChanged()
and
paint()
methods. This former method is invoked when your layer
is part of the MapBean and the view changes (e.g., when someone
recenters the map). It is up to you to fetch and prepare your
graphics (or maybe do something else), and then repaint()
yourself. The easiest way to write your own layer is to derive it
from another one already cooked up. For some simple examples see the
GraticuleLayer and
TestLayer
classes.
Many layers get their data from the local disk or cdrom of the machine that they run on, but there are others that query remote sites on the Internet. The Earthquake Layer is a good example of live layer.
To write your own PlugIn, you can extend the
AbstractPlugIn class, which implements the
PlugIn interface. You only have to implement the
getRectangle()
method, which returns an
OMGraphicList to the PlugInLayer. PlugIns can also receive
MouseEvents and create a GUI palette, just like layers. The advantage
to creating a PlugIn is that you don't have to deal with the
Swing Worker which should be used by
layers to kick off another thread to do their work, in order not to
slow the application down. The PlugInLayer does this for the PlugIn.
OMGraphics help you to turn your vector or raster data into interactive graphics that can be rendered on the map canvas. Each OMGraphic provides a simple interface to manage projecting, rendering, and gesturing.
In general, there are three steps needed to get your data to appear on
the screen. The OMGraphic needs to be created. Then call
generate()
on the OMGraphic with the current
Projection to prepare for rendering.
Then call render()
on the OMGraphic with the java.awt.Graphics
context. This final step is usually performed when the paint()
method is invoked on your layer. To trigger the AWT painting, call
repaint()
, instead of paint()
directly. Note that even if
the graphic is already in XY, it still needs to be `generated' before
it is `rendered', or it will not show up on the map.
The OMGraphicList is a unique OMGraphic: it can be used to manage a vector of OMGraphics. It can also contain other OMGraphicLists, so you can create nested groupings of graphics.
And of course you can extend any of the OMGraphic classes to create your own specific graphic or extended functionality.
Palettes are layer-specific GUI components that provide another means
to configure and interact with the layer. The Layer interface
provides a getGUI()
method which can be used by the layer to
return its GUI. The OpenMap Viewer application presents a layer's
palette in an InternalFrame. This is accessible from the
LayersPanel component.
When developing your own layer you should be aware of how it could
potentially affect the overall performance of OpenMap. Specifically,
a layer should not block too long on paint()
,
projectionChanged()
, or other interface methods. If, for
instance, your layer needs to do a lot of computation each time
projectionChanged()
is invoked, then you should consider spawning
a thread to do the work. This way you won't block the propagation of
projectionChanged()
to other layers and components. Since all
layers are Swing components, they can call repaint()
anytime when
they've got something new to show. So once your thread finishes doing
work, and you've got new data, you can initiate a repaint()
.
The SwingWorker is a class which supports spawning and managing worker threads; Sun has a tutorial on the SwingWorker. Several of our main Layers use this service, including the ShapeLayer.