Next Previous Contents

5. Layers and PlugIns

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:

5.1 ShapeLayer

This is a generic layer for displaying data in ESRI shapefile format. See the ShapeLayer class.

5.2 ShapePlugIn

A different component for handling Shape data is in the esri plugin package.

5.3 VPFLayer

This is a generic layer for displaying NIMA VPF data. See the VPFLayer class.

5.4 EarthquakeLayer

The EarthquakeLayer displays data of recent earthquake activity. It gets its data by querying live data feeds at the USGS.

5.5 Raster Layers

5.6 Writing your own Layer or PlugIn

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

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.

Layer GUI Palettes

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.

Multi-threading and the SwingWorker

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.


Next Previous Contents