mapnik / mapnik-support

Use the issues queue here to ask questions and offer help on using Mapnik (maybe if this works well we can retire the mailing list at http://mapnik.org/contact/?)
6 stars 6 forks source link

Transparent images - how to? #64

Open OnkelTem opened 8 years ago

OnkelTem commented 8 years ago

I need to place a transparent raster image on the map. The image source is in PNG format with transparency and without geospacial information, so my first step was to create GeoTiff from it using gdal_translate:

gdal_translate -a_srs +init=epsg:3857 -of GTiff -co INTERLEAVE=PIXEL -a_ullr $xmin $ymax $xmax $ymin in.png out.tif

The resulting out.tif image when viewed in an imageview has no transparency, but when I add it as a raster layer in QGis it gains transparency.

Now when I add it to my map using this XML:

<Style name="raster" filter-mode="first">
  <Rule>
    <RasterSymbolizer/>
  </Rule>
</Style>
<Layer name="GDAL Layer from TIFF file"
  srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
  <StyleName>raster</StyleName>
  <Datasource>
      <Parameter name="type">gdal</Parameter>
      <Parameter name="file">/home/osm/styles/openstreetmap-carto/layers/out.tif</Parameter>
  </Datasource>
</Layer>

it has not any transparency. So how to make it transparent?

OnkelTem commented 8 years ago

The problem is partially solved now, but at GDAL side.

First I had to upgrade GDAL from 1.x version (which is default on Ubuntu 14.04 ) to 2.0.2. (There were no prebuilt versions for trusty, so I've build it myself. ) Then I rewrote the command adding -expand rgba option:

gdal_translate -a_srs +init=epsg:3857 -of GTiff -co INTERLEAVE=PIXEL -expand rgba -a_ullr $xmin $ymax $xmax $ymin in.png out.tif

which made resulting TIFFs transparent.

You can see an example of the source image (PNG with transparency) here

And this is a part of the final result:

talaj commented 8 years ago

The TIFF format does not support the alpha component in the color table, see. So you have these options:

Unfortunately, the last option is not currently working in Mapnik. You can see here, that values are not confronted with no-data value. It can be fixed by this quick & dirty modification:

diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp              
index 968fc6d..fc8088a 100644                                                                             
--- a/plugins/input/gdal/gdal_featureset.cpp                                                              
+++ b/plugins/input/gdal/gdal_featureset.cpp                                                              
@@ -518,6 +518,8 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)                      

                     if (color_table)                                                                     
                     {                                                                                    
+                        double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;            
+                        unsigned nodata_value = static_cast<unsigned>(apply_nodata);                     
                         MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Loading color table...";             
                         for (unsigned y = 0; y < image.height(); ++y)                                    
                         {                                                                                
@@ -525,6 +527,11 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)                     
                             for (unsigned x = 0; x < image.width(); ++x)                                 
                             {                                                                            
                                 unsigned value = row[x] & 0xff;                                          
+                                if (value == nodata_value)                                               
+                                {                                                                        
+                                    row[x] = 0;                                                          
+                                    continue;                                                            
+                                }                                                                        
                                 const GDALColorEntry *ce = color_table->GetColorEntry(value);            
                                 if (ce)                                                                  
                                 {                                                                        

Your tiff has NoData Value=0 and after applying the above patch the output is as expected:

<Map background-color="steelblue">                                 
  <Parameters>                                                     
    <Parameter name="sizes">1000,1000</Parameter>                  
  </Parameters>                                                    
<Style name="s">                                                
  <Rule>                                                           
      <RasterSymbolizer />                                         
  </Rule>                                                          
</Style>                                                           
<Layer>                                                            
    <StyleName>s</StyleName>                                    
    <Datasource>                                                   
       <Parameter name="file">../../data/out.tif</Parameter>       
       <Parameter name="type">gdal</Parameter>                     
    </Datasource>                                                  
  </Layer>                                                         
</Map>                                                       

tiff-nodata-edge-rgba-1000-1000-1 0-agg-reference

kennykb commented 6 years ago

Any chance this patch will ever get applied? I have several raster layers that have NODATA values, and no easy way to render them. (Fortunately, on most of the maps that I produce, the NODATA regions are outside the area of interest, but I actually do some weird hacks in places to cover up the NODATA with other things.)

Any way that I can help move things forward?