Dashboard > Hacking > Home > MrSID and GDAL
MrSID and GDAL Log In | Sign Up   View a printable version of the current page.

Added by Administrator , last edited by Jody Garnett on Mar 11, 2008  (view change)
Labels: 
(None)

MrSID is a nifty raster library suffering from the unfortunate constraint of being a C library. Since uDig is supposed to be the best thing around for integration work we will use MrSID as an example of how to get the job done.

MRSID

Check the License

The MrSID license is pretty sweet; it lets you both develop with the library (on a reasonable number of machines) and redistribute the result:

You will need to keep this license file for later; we will be including it in our "MrSID" plugin.

Download the Binaries

Head on over to LizardTech (sign up as needed) and grab a download:
http://www.lizardtech.com/developer/members/downloads.php

The binaries are available for a range of platforms; my impression is we make a single:

  • com.lizardtech.dsdk plugin

With the binaries held as a platform specific fragments:

  • com.lizardtech.dsdk-win32 fragment

Create JNDI Wrappers

This is the annoying part; MrSID like many C++/C libraries has not supplied java bindings. Searching around on the web there are a couple half hearted attempts mostly concerning unsupported SWIG based bindings of GDAL.

One solutions would be to generate the bindings by hand (fun fun), or we can start to look at tools. Since we have had recent plesent experience with JOGL we may as well check out the tool they use to produce OpenGL bindings:

So far this is looking pretty good on the tech side; and horrible on the documentation side.

After a battle with the above tool it appears that it would take at least a week to get it to spit out decent bindings.

GDAL

Another C project that wraps up MrSID (and ECWSDK) is the GDAL project. Searching around the web I can find a couple of examples of GDAL bindings being available:

gvSIG

The gvSIG project has some GDAL bindings (only evidence is a GeoServer discussion on the topic). Since the project is GPL I am going to give this one a miss - we can reach a larger audience by staying with LGPL.

imageio-ext

The ImageIO project has some GDAL goodness as a result of a Google Summer of Code project.

While you can use ImageIO stuff directly, it is usually used in collaboration with JAI. The benef of using JAI is a declarative style of image processing similar to SQL. You define a chain of operations and "pull" data through from disk. Because it is declarative (you only say what you want) the ImageIO library can do tricks and optimizations for you - such as working with a tile cache.

To use ImageIO to work with rasters it is way more fun to go through the GeoTools project. It serves up a nice GridCoverage abstraction that slots into the existing SLD based rendering. The consulting company GeoSolutions and the easy thing to do is to hire them.

While we wait for that to happen let's grab the GDAL bindings they made and try them out:

To build this thing you need to have JAVA_HOME set and then:

mvn install -Ddeploylibs=true -Pfullkakadu -Dmaven.test.skip=true

This will deploy some DLL files into your JRE and build as much stuff as possible.

DLL HELL

Their are various ways to try to get the java Jars and their native DLL files working together. In the normal course of things the JAR needs to be on the classpath and the DLL needs to be on the library path.

And then we started using OSGi and classloaders.

  • Root of the Plugin? Not really.
    While the jar will be able to find these DLLs, this only works for one level. We can find the GDAL DLL, but the gdal plugins (ie other DLL files) will not be found by GDAL.
  • Root of a fragment? No
    We are supposed to contribute platform specific stuff using fragments. This did not work at all.
  • Root of a fragment with jars in the fragments as well? Maybe
    This is untested; but since it is the way SWT operates it may actually work out...
  • JRE/ext/i386? No
    This should of worked .. but did not
  • JRE/bin? YES

JRE Extensions

So at the end of the day do the following:

-Dosgi.parentClassloader=ext

If you do not do this your applications will start up just using the java "boot classpath", and none of the JRE extensions will be picked up.

UDIG Integration

The first task is to simply list these resources in the uDig catalog; to accomplish that we need to implement a couple of extension points provided by the uDig "GIS Platform".

To try this stuff out:

cd community
svn co http://svn.geotools.org/udig/community/daniele/ daniele

You can then import these plugins into your workspace:

  • net.refractions.udig.catalog.imageio - the actual plugin
  • net.refractions.udig.catalog.imageio.win32.x86 - fragment used to experiment with DLL hell

net.refractions.udig.catalog.ui.fileFormat

The File Open Dialog needs to know what kind of files the application supports; it does so by processing this fileFormat extension point.

plugin.xml
<extension
         point="net.refractions.udig.catalog.ui.fileFormat">
      <fileService
            fileExtension="*.ecw"
            name="%ECW"/>
      <fileService
            fileExtension="*.jp2"
            name="%JP2"/>
   </extension>

The above example adds the ECW and JP2 files to the list.

The strange "%" syntax means the value name is translatable. We need to supply the (possibly locale specific) name in a plugin.properties file:

plugin.xml
ECW=Enhanced Compressed Wavelet
JP2=JPEG 2000
MRSID=Multi Resolution Seamless Image Database

net.refractions.udig.catalog.ServiceExtention

Next up we need to teach the uDig catalog (ie the catalogue data structure) about our new format type.

plugin=xml
<extension point="net.refractions.udig.catalog.ServiceExtension">
  <service
    class="net.refractions.udig.catalog.imageio.internal.ImageServiceExtension"
     id="imageio"
     name="%ImageIO"/>
</extension>
plugin.properties
ImageIO=Image IO Extensions

This extension point points out a class, ie ImageServiceExtention, which will act as a factory. This class is an implementation of ServiceExtention2 and will be used to answer a few questions about our new format(s):

  • createParams(url): create "sensible" connection parameters given only a URL
  • createService( id, params ): create a IService (representing the file in the catalog)
  • reasonForFailure( params): human readable description of why we could not connect
  • reasonForFailure( url ): ditto

Implementing IService

IService is covered in a bit more detail in the GIS Platform documentation, but if you wander into uDig you may find the code full of all sorts of interesting hacks (nested classes to save a few pointers and so on).

Here is a picture:

And you can check out the code here:

We started this code by copying an example (WorldImageService), and broke it down into a few files for readability.

IService has the job of representing the file on disk, and reporting back connection information (such as the file not being readable, or the file being missing).

IServiceInfo is a description of the file. This information may come from the operating system, or from the file header as needed.

Implementing IGeoResource

IGeoResource represents the actual contents of the file. If the file has more than one kind of content (it does happen!) then there will be a GeoResource for each kind of content.

The workflow for IGeoResource is to resolve to any API you can image. In this case we are interested in turning ourselves into a GridCoverageReader. We could also resolve directly to the GDAL Dataset API as well.

The final part of the puzzle is IGeoResourceInfo which is the all important description of the content. Particular important is the projection and bounds of the content. This information pretty much always has to come from the file header (or metadata).

GridCoverage source = (GridCoverage) resource.findResource();
org.opengis.geometry.Envelope ptBounds = source
		.getEnvelope();
env = new Envelope(ptBounds.getMinimum(0), ptBounds
		.getMaximum(0), ptBounds.getMinimum(1), ptBounds
		.getMaximum(1));

CoordinateReferenceSystem geomcrs = source
		.getCoordinateReferenceSystem();

If you are ever stuck looking at all the data and calculating the bounds yourself be sure to cache the answer ... and ask yourself if you really are working with a good spatial format?

GeoTools Integration (Optional)

The GeoTools project is responsible for the GridCoverage and GridReader ideas provided above. This work seems to be happening in a private svn ... a few questions later and it is commited as an unsupported modules on both 2.4.x and trunk.

Powered by a free Atlassian Confluence Open Source Project License granted to uDig. Evaluate Confluence today.
Powered by Atlassian Confluence 2.7.1, the Enterprise Wiki. Bug/feature request - Atlassian news - Contact administrators
User-friendly Desktop Internet GIS