Here are some notes as I hack in ImageMoasic support.
Related
Lack of Documentation
The first thing that becomes clear is that these developers want you to read the source code (rather than the wiki). Indeed the only way to figure out what is needed is to try and run those command line tools.
Fair enough - use the source luke.
Design Approach
For MRSID we went ahead and created a new IService and IGeoResource (because MRSID was a new kind of file format). This time ImageMoasic is is captured as a shapefile (a format we already support) that acts as an index for a set of rasters – so we are going to use IResolveAdapterFactory in order to teach our existing shapefile how to resolve to a GridCoverage.
The other way we could do this would be to write a custom renderer that recognizes the shapefile schmea as one that represents a ImageMoasic and takes appropriate action. This approach would only help with rendering so we did not go that way.
Classpath HELL
Adding net.refractions.udig.catalog.shp as an OPTIONAL dependency to the net.refractions.udig.imageio plugin. While adding this code to net.refractions.udig.catalog.rasterings is a good long term solution; my goal is a moasic of MRSID files today.
So we are going to get stuck on the great divide between GeoTools using FactorySPI and uDIG using OSGi. Explicitly: gt2-imagemoasic-2.5-SNAPSHOT.jar expects to be able to find gt2-mrsid-2.5-SNAPSHOT.jar on the classpath so it can check manifest folders. This works if everyone is in the same place (like net.refractions.udig.libs), but fails every other way we try (including buddy class loaders that is the way we are supposed to do it).
So here is the game plan:
- add gt2-imagemoasic-2.5-SNAPSHOT.jar to our imageio plugin
- add gt2-imagemoasic-2.5-SNAPSHOT.jar to our rasterings plugin
We will write two adapaters; both will report back canAdapat true when presented with imagemoasic shapefile; but when push comes to shove only one of them will succeed. ie When we try to adapat we will read the file and have a look at the directory contents and return null if the moasic is not intended for us.
The good way to do this is to make an extention point for raster stuff; and then use the GeoTools FactoryIterator hooks to teach geotools how to navigate our eclipse RCP environment. Since this is untested and unknown I am not risking it right now.
Use of ResolveAdaptorFactory
Search For Examples
Looking at the existing examples of ResolveAdaptorFactory were frankly terrifying hacks. The good examples were all done for our commercial undertakings apparently.

We need to check that we canAdapt:
public boolean canAdapt(IResolve resolve, Class<? extends Object> adapter) {
if (adapter.isAssignableFrom(ImageMosaicReader.class)) {
ShpGeoResourceImpl resource = (ShpGeoResourceImpl) resolve;
ShpServiceImpl service = resource.service();
File file = service.toFile();
if( file != null ){
return format.accepts( file );
}
}
return false;
}
And then actually do the work:
AbstractGridCoverage2DReader toGridCoverage2DReader( ShpGeoResourceImpl shapefile, IProgressMonitor monitor ) throws IOException {
ShpServiceImpl service = shapefile.service();
File file = service.toFile();
if( format.accepts( file )){
return new ImageMosaicReader( file, null );
}
return null; }
Update plugin.xml
The resolvers extention point is pretty easy; the target class is resolveableType (ie ShapefileGeoResource) and we only have a single resolve adaptee (ie GridCoverage).
<extension
id="net.refractions.udig.catalog.imageio.resolvers"
name="ImageIO Resolvers"
point="net.refractions.udig.catalog.resolvers">
<factory
class="net.refractions.udig.catalog.imaio.internal.ShapefileImageMoasicAdaptorFactory"
resolveableType="org.geotools.catalog.shapefile.ShapefileGeoResource">
<resolve
type="org.opengis.coverage.grid.GridCoverage"></resolve>
</factory>
</extension>
If anyone can think of a way to tighten up the above names I am open to suggestions.