From e5ba2757944ecc84f1ba62c5a852b4caebde058d Mon Sep 17 00:00:00 2001 From: kunitoki Date: Mon, 5 Dec 2011 11:10:13 +0100 Subject: [PATCH] - initial implementation of the geotiff output by using libgeotiff, not complete (issue #967) --- include/mapnik/tiff_io.hpp | 86 +++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/include/mapnik/tiff_io.hpp b/include/mapnik/tiff_io.hpp index a63d88925..52616f36b 100644 --- a/include/mapnik/tiff_io.hpp +++ b/include/mapnik/tiff_io.hpp @@ -29,7 +29,16 @@ extern "C" { -#include +#ifdef HAVE_GEOTIFF + #include + #include + #define RealTIFFOpen XTIFFClientOpen + #define RealTIFFClose XTIFFClose +#else + #include + #define RealTIFFOpen TIFFClientOpen + #define RealTIFFClose TIFFClose +#endif } namespace mapnik { @@ -103,16 +112,20 @@ void save_as_tiff(T1 & file, T2 const& image) const int height = image.height(); const int scanline_size = sizeof(unsigned char) * width * 3; - TIFF* output = TIFFClientOpen("mapnik_tiff_stream", - "w", - (thandle_t)&file, - tiff_dummy_read_proc, - tiff_write_proc, - tiff_seek_proc, - tiff_close_proc, - tiff_size_proc, - tiff_dummy_map_proc, - tiff_dummy_unmap_proc); + TIFF* output = RealTIFFOpen("mapnik_tiff_stream", + "w", + (thandle_t)&file, + tiff_dummy_read_proc, + tiff_write_proc, + tiff_seek_proc, + tiff_close_proc, + tiff_size_proc, + tiff_dummy_map_proc, + tiff_dummy_unmap_proc); + if (! output) + { + // throw ? + } TIFFSetField(output, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(output, TIFFTAG_IMAGELENGTH, height); @@ -123,6 +136,44 @@ void save_as_tiff(T1 & file, T2 const& image) TIFFSetField(output, TIFFTAG_SAMPLESPERPIXEL, 3); TIFFSetField(output, TIFFTAG_ROWSPERSTRIP, 1); + // TODO - handle palette images + // std::vector const& palette + /* + unsigned short r[256], g[256], b[256]; + for (int i = 0; i < (1 << 24); ++i) + { + r[i] = (unsigned short)palette[i * 3 + 0] << 8; + g[i] = (unsigned short)palette[i * 3 + 1] << 8; + b[i] = (unsigned short)palette[i * 3 + 2] << 8; + } + TIFFSetField(output, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE); + TIFFSetField(output, TIFFTAG_COLORMAP, r, g, b); + */ + +#ifdef HAVE_GEOTIFF + GTIF* geotiff = GTIFNew(output); + if (! geotiff) + { + // throw ? + } + + GTIFKeySet(geotiff, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic); + GTIFKeySet(geotiff, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsPoint); + GTIFKeySet(geotiff, GeographicTypeGeoKey, TYPE_SHORT, 1, 4326); // parameter needed ! + GTIFKeySet(geotiff, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, Angular_Degree); + GTIFKeySet(geotiff, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, Linear_Meter); + + double lowerLeftLon = 130.0f; // parameter needed ! + double upperRightLat = 32.0; // parameter needed ! + double tiepoints[] = { 0.0, 0.0, 0.0, lowerLeftLon, upperRightLat, 0.0 }; + TIFFSetField(output, TIFFTAG_GEOTIEPOINTS, sizeof(tiepoints)/sizeof(double), tiepoints); + + double pixelScaleX = 0.0001; // parameter needed ! + double pixelScaleY = 0.0001; // parameter needed ! + double pixscale[] = { pixelScaleX, pixelScaleY, 0.0 }; + TIFFSetField(output, TIFFTAG_GEOPIXELSCALE, sizeof(pixscale)/sizeof(double), pixscale); +#endif + int next_scanline = 0; unsigned char* row = reinterpret_cast(::operator new(scanline_size)); @@ -132,15 +183,15 @@ void save_as_tiff(T1 & file, T2 const& image) for (int i = 0, index = 0; i < width; ++i) { - #ifdef MAPNIK_BIG_ENDIAN +#ifdef MAPNIK_BIG_ENDIAN row[index++] = (imageRow[i] >> 24) & 0xff; row[index++] = (imageRow[i] >> 16) & 0xff; row[index++] = (imageRow[i] >> 8) & 0xff; - #else +#else row[index++] = (imageRow[i]) & 0xff; row[index++] = (imageRow[i] >> 8) & 0xff; row[index++] = (imageRow[i] >> 16) & 0xff; - #endif +#endif } TIFFWriteScanline(output, row, next_scanline, 0); @@ -149,7 +200,12 @@ void save_as_tiff(T1 & file, T2 const& image) ::operator delete(row); - TIFFClose(output); +#ifdef HAVE_GEOTIFF + GTIFWriteKeys(geotiff); + GTIFFree(geotiff); +#endif + + RealTIFFClose(output); } }