Recently,
I've been working for gvSIG
CE project,
thanks to the folks of geomati.co
(I'm part
of the team
now!). I
was solving some GDAL related open cases (this,
this
and this).
the aim is to get a functional and stable gvSIG CE 1.0 version.
There are still a couple of cases to solve (this
and this),
but I think we're pretty close. I'd
like to explain what I did to solve these cases.
Make
gvSIG CE work with GDAL 1.9.x
This
bug was hard to find but easy to fix. First, a 1-minute
introduction to GDAL use in gvSIG CE. gvSIG
CE uses a JNI wrapper (based on GDAL 1.7.x GDAL packed JNI wrapper)
to make C++ native calls to GDAL library. There are 2
important GDAL JNI wrapper classes involved in most GDAL
operations:
Gdal.java
(it interacts with native C++ GDALDataset class)
GdalRasterBand,java
(it interacts with native C++ GDALRasterBand class)
Both
classes inherit from the same base class: JNIBase. This class defines
a function named baseSimpleFunctions that
calls one of several native C functions, depending on an input
parameter. But some of these native C functions
are GDALDataset-based, and other are GDALRasterBand-based. I
mean, the pointer passed to them doesn't hold the same C structure
(wrapping C++ object) in all cases.
And
here was the thing. To actually read the raster data, the Java
function GdalRasterBand::readRaster
is called. This function checks the position and size of the region
being accessed, comparing it with the raster dimensions. To check
this, the C functions getRasterXSize
and getRasterYSize
are
called. These functions expect a pointer to a GDALDataset C
object, but the GdalRasterBand
Java class provides a pointer to a GDALRasterBand C object. I had to
replace those Dataset-based calls to RasterBand based calls, to match
the underlying C structure.
Replace
ECW and MrSID driver with GDAL
First,
a few comments on these formats. ECW
stands for enhanced
compression wavelet.
This propietary format is
a high-performance image-compression format designed specifically for
geospatial imagery. It's
patented and owned by Intergraph. More
information here.
Intergraph
provides a license needed SDK for encoding data and a free SDK for
reading. Since version 4.1, this free SDK is only available for
Desktop development on Windows systems. There are promises
to include Linux support since 5.0 version, but gvSIG CE doesn't plan
to support ECW and other proprietary formats. So, I worked with the
last known version working on Linux systems too. This is 3.3.
About
MrSID, it stands for multiresolution
seamless image database.
It's a proprietary format too, owned by LizardTech.
As happens with ECW, there's a free SDK to read MrSID files. It can
be downloaded from here
(MrSID SDK, under Tools
& Utilities.
Free register required). And as happens with ECW too, gvSIG CE won't
directly support this format. So, it delegates in GDAL.
In
both cases, we'll need to compile GDAL with the proper support. So, I
had to download and compile MrSID and ECW libraries and build GDAL
using --with-ecw and --with-mrsid options.
As
there is a JNI wrapper for GDAL, there are JNI wrappers for ECW and
MrSID. The goal was: get rid of them, and give GDAL credentials to
handle these formats. Four steps involved here:
- Compile
GDAL with ECW and MrSID support, as said
- Tell GDAL
to take care of those formats for reading (class GdalDriver)
- Unregister
ECW and MrSID drivers from gvSIG CE raster library (libRaster)
- Delete ECW
and MrSID wrappers and native code.
Once
done, you have gvSIG CE using GDAL 1.9.2 to read raster data,
including ECW, JP2, MrSID and Lidar files (previously managed by ECW
and MrSID drivers).
Thanks for your great work Jorge! We now have amazingly good GDAL drivers support in gvSIG CE. The issue with the latest ECW SDK on Linux just confirms a basic truth: proprietary, closed-source code will _always_ cause trouble in open source projects and must be removed eventually. Neither ECW nor MrSID can do anything that you couldn't do with GeoTIFF...
ReplyDelete