Developing a new data source

Understanding the data source backup paradigm

The base class IlvMapDataSource includes a fallback mechanism to allow map reprojection and export even when associated source data (file, network path, database connection...) is not available at the time the map needs to be manipulated. For that mechanism to operate, a subclass of IlvMapDataSource must override the method isSourceDataAvailable and perform appropriate checks on related data availability.
If this method returns false , the IlvMapDataSource tries to perform operations on the map (change of coordinate system, export) from the current map objects instead of reading them from the original source data. Note that this may lead to loss of precision or even data as this is the expected behavior when chaining-up several non-invertible projections.
Another way to force the use of a backup data source is by setting a flag using the method setForceUsingBackupDataSource. This will result in much faster operations (such as reprojection) as the source data is not read back from its original format. However, as mentioned above, this leads to potential precision or data loss.
Should you need to access these backup data sources of a given data source directly, you can do so by calling getBackupDataSources. It returns an array of data sources of the class IlvGraphicLayerDataSource .
The source code for the Map Builder demonstration, which contains all of the code described in this section, can be found at <installdir> /jviews-maps810/samples/mapbuilder/index.html.

Renderer management

Unless you need specific rendering, you should use the base IlvMapDataSource class renderer management, which either finds the renderer associated with the IlvMapReusableFeatureIterator or creates a new IlvDefaultFeatureRenderer.

Layer management

By default, the base IlvMapDataSource class layer manager creates a map layer when needed, and connects it to the manager (by creating an IlvManagerLayer).
Usually, the only layer management method you have to rewrite is the initInsertionLayer method, when you need to create a tiled layer instead of a standard IlvManagerLayer:
protected void initInsertionLayer(IlvMapLayer layer) {
    layer.insert(new IlvTiledLayer(new IlvRect(), null, 
IlvTileController.FREE));
}
If you want your data source to manage more than a single map layer you may have to write more complex layer management code, or create a subclass of the IlvHierarchicalDataSource.

Data tiling

It you have a data format or readers that support tiles, you may have to create the tiles and tile loaders in a specific start method. Here is an example used in the shapefile data source:
public void start() throws Exception
{
// construct a tiled shape tile loader
  IlvShapeFileTileLoader tileLoader = new IlvShapeFileTileLoader(shp, dbf,shx, 
idx);
  tileLoader.setCoordinateSystem(getCoordinateSystem());
tileLoader.setFeatureRenderer(getFeatureRenderer());
// create a threaded tile loader to load the shape data on a background thread.
  IlvTiledLayer tiledLayer = (IlvTiledLayer)getInsertionLayer().
     getManagerLayer();
  IlvThreadedTileLoader threadedLoader = new IlvThreadedTileLoader(tileLoader,
     true);
tiledLayer.setTileLoader(threadedLoader);
...
// for each tile known by the tile loader
  for (int i = ...) {
    for (int j = ...) {
      // Compute projected tile bounds, ie the bounds of the tile in the manager 
coordinates
      IlvRect r = IlvMapUtil.computeTransformedBounds(...);
      Point2D.Double ul = new Point2D.Double(r.getX(), r.getY());
      Point2D.Double lr = new Point2D.Double(r.getX() + r.getWidth(), r.getY() 
+ r.getHeight());
tiledLayer.getTileController().addTile(new IlvMapFreeTile(ul, lr,
   tiledLayer.getTileController(), i, j));
    }
  }
}

Feature management

The IlvMapReusableFeatureIterator is a subinterface of IlvMapFeatureIterator. It adds to the base interface the capability to restart the iteration more than once. This is necessary when, for example, projection parameters have changed and the data source needs to render all the graphic objects again. This is also used for load-on-demand or save/reload mechanisms.
You can transform a feature iterator (such as for readers written for a previous version of JViews Maps) into a reusable feature iterator by using the IlvMapDelegateFeatureIterator abstract class. For example, the code below uses the feature iterator returned by an IlvMapLoader:
String fileName="some file name";
public IlvMapReusableFeatureIterator getFeatureIterator() {
   return new IlvMapDelegateFeatureIterator() {
      public void restart() {
         IlvMapLoader loader = new IlvMapLoader(null);
            try {
               setDelegate(loader.makeFeatureIterator(fileName));
            } catch (IOException e) {
               e.printStackTrace();
            }
        }
    };
}