changeset 251:6b80e46b8f38

Added picture symbol support to the converter.
author raimund renkert <raimund.renkert@intevation.de>
date Fri, 12 Aug 2011 16:08:57 +0200
parents d10fd4de02aa
children eae3fe89e669
files ChangeLog build.xml src/java/de/intevation/mxd/reader/FillSymbolReader.java src/java/de/intevation/mxd/reader/PictureFillSymbolReader.java src/java/de/intevation/mxd/reader/PictureLineSymbolReader.java src/java/de/intevation/mxd/reader/PictureMarkerSymbolReader.java src/java/de/intevation/mxd/writer/FillStyleWriter.java src/java/de/intevation/mxd/writer/LineStyleWriter.java src/java/de/intevation/mxd/writer/MarkerStyleWriter.java src/java/de/intevation/mxd/writer/SymbolWriter.java
diffstat 10 files changed, 482 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Aug 12 09:15:34 2011 +0200
+++ b/ChangeLog	Fri Aug 12 16:08:57 2011 +0200
@@ -1,3 +1,26 @@
+2011-08-12  Raimund Renkert  <raimund.renkert@intevation.de>
+
+	* build.xml: Added Apache commons-codec library for base64 encoding.
+
+	* src\java\de\intevation\mxd\reader\FillSymbolReader.java:
+	  Added PictureFillSymbolReader to the available symbol readers.
+
+	* src\java\de\intevation\mxd\reader\PictureLineSymbolReader.java,
+	  src\java\de\intevation\mxd\reader\PictureMarkerSymbolReader.java:
+	  Completed the functionality to be able to read images.
+
+	* src\java\de\intevation\mxd\writer\FillStyleWriter.java
+	  src\java\de\intevation\mxd\writer\LineStyleWriter.java
+	  src\java\de\intevation\mxd\writer\MarkerStyleWriter.java:
+	  Added "picture" (in MapServer PIXMAP) to the writeable symbols.
+
+	* src\java\de\intevation\mxd\writer\SymbolWriter.java:
+	  Create the images used for map symbols and create the corresponding
+	  symbols in the symbol set.
+
+	* src\java\de\intevation\mxd\reader\PictureFillSymbolReader.java
+	  New. Reads images and symbol attributes for layers of type polygon.
+
 2011-08-10  Raimund Renkert  <raimund.renkert@intevation.de>
 
 	* src/java/de/intevation/mxd/writer/MapScriptWriter.java:
--- a/build.xml	Fri Aug 12 09:15:34 2011 +0200
+++ b/build.xml	Fri Aug 12 16:08:57 2011 +0200
@@ -64,7 +64,7 @@
     <jar jarfile="${dist.dir}/mxd2map-${hash}.jar" compress="true" basedir="${class.dir}">
       <manifest>
         <attribute name="Main-Class" value="de.intevation.mxd.Converter"/>
-	<attribute name="Class-Path" value="lib/log4j-1.2.16.jar lib/mapscript.jar lib/arcobjects.jar lib/jargs.jar"/>
+	<attribute name="Class-Path" value="lib/log4j-1.2.16.jar lib/mapscript.jar lib/arcobjects.jar lib/jargs.jar lib/commons-codec-1.5.jar"/>
       </manifest>
     </jar>
   </target>
@@ -74,7 +74,7 @@
     <jar jarfile="${dist.dir}/mxd2map.jar" compress="true" basedir="${class.dir}">
       <manifest>
         <attribute name="Main-Class" value="de.intevation.mxd.Converter"/>
-	<attribute name="Class-Path" value="lib/log4j-1.2.16.jar lib/mapscript.jar lib/jargs.jar"/>
+	<attribute name="Class-Path" value="lib/log4j-1.2.16.jar lib/mapscript.jar lib/jargs.jar lib/commons-codec-1.5.jar"/>
       </manifest>
     </jar>
   </target>
--- a/src/java/de/intevation/mxd/reader/FillSymbolReader.java	Fri Aug 12 09:15:34 2011 +0200
+++ b/src/java/de/intevation/mxd/reader/FillSymbolReader.java	Fri Aug 12 16:08:57 2011 +0200
@@ -31,6 +31,7 @@
 import com.esri.arcgis.display.SimpleFillSymbol;
 import com.esri.arcgis.display.MarkerFillSymbol;
 import com.esri.arcgis.display.LineFillSymbol;
+import com.esri.arcgis.display.PictureFillSymbol;
 
 /**
  * Wrapper for fill symbol reader.
@@ -107,6 +108,9 @@
                 else if(symbol instanceof LineFillSymbol) {
                     sreader = new LineFillSymbolReader(symbol);
                 }
+                else if(symbol instanceof PictureFillSymbol) {
+                    sreader = new PictureFillSymbolReader(symbol);
+                }
                 else {
                     logger.debug("The reader for type " +
                                  symbol.getClass().toString() +
@@ -135,6 +139,9 @@
                 else if(fillSymbol instanceof LineFillSymbol) {
                     sreader = new LineFillSymbolReader(fillSymbol);
                 }
+                else if(fillSymbol instanceof PictureFillSymbol) {
+                    sreader = new PictureFillSymbolReader(fillSymbol);
+                }
                 else {
                     logger.debug("The reader for type " +
                                  fillSymbol.getClass().toString() +
@@ -189,7 +196,8 @@
         if(sym instanceof SimpleFillSymbol ||
            sym instanceof MarkerFillSymbol ||
            sym instanceof MultiLayerFillSymbol ||
-           sym instanceof LineFillSymbol) {
+           sym instanceof LineFillSymbol ||
+           sym instanceof PictureFillSymbol) {
             return true;
         }
         else {
@@ -206,7 +214,8 @@
         if(sym instanceof SimpleFillSymbol ||
            sym instanceof MarkerFillSymbol ||
            sym instanceof MultiLayerFillSymbol ||
-           sym instanceof LineFillSymbol) {
+           sym instanceof LineFillSymbol ||
+           sym instanceof PictureFillSymbol) {
             return true;
         }
         else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java/de/intevation/mxd/reader/PictureFillSymbolReader.java	Fri Aug 12 16:08:57 2011 +0200
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2011 by Intevation GmbH, Germany <info@intevation.de>
+ *
+ * This file is part of MXD2map.
+ *
+ * This program is free software under the LGPL (>=v2.1)
+ * Read the file LICENCE.txt coming with the software for details
+ * or visit http://www.gnu.org/licenses/ if it does not exist.
+ *
+ * MXD2map has been developed on behalf of the
+ * Bundesamt fuer Seeschifffahrt und Hydrographie (BSH) in Hamburg
+ * by Intevation GmbH.
+ *
+ * Authors:
+ * Raimund Renkert <raimund.renkert@intevation.de>
+ * Bjoern Schilberg <bjoern.schilberg@intevation.de>
+ * Stephan Holl <stephan.holl@intevation.de>
+ */
+
+package de.intevation.mxd.reader;
+
+import java.awt.Color;
+import java.awt.Image;
+
+import org.apache.log4j.Logger;
+
+import com.esri.arcgis.display.ISymbol;
+import com.esri.arcgis.display.ILineSymbol;
+import com.esri.arcgis.display.IFillSymbol;
+import com.esri.arcgis.display.PictureFillSymbol;
+import com.esri.arcgis.support.ms.stdole.Picture;
+import com.esri.arcgis.display.IRgbColor;
+import com.esri.arcgis.display.RgbColor;
+
+import org.w3c.dom.Element;
+import java.io.IOException;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import javax.imageio.ImageIO;
+import java.io.ByteArrayOutputStream;
+
+import org.apache.commons.codec.binary.Base64;
+/**
+ * Reads picture fill symbol information.
+ *
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class PictureFillSymbolReader
+extends AbstractSymbolReader {
+
+    /**
+     * The logger.
+     */
+    private static final Logger logger =
+        Logger.getLogger(PictureFillSymbolReader.class);
+
+    /**
+     * Private member.
+     */
+    private PictureFillSymbol symbol;
+
+    public PictureFillSymbolReader(ISymbol symbol)
+    throws Exception {
+        logger.debug("contructor()");
+        if(symbol instanceof PictureFillSymbol) {
+            this.symbol = (PictureFillSymbol)symbol;
+        }
+        else {
+            throw new Exception("Not a PictureFillSymbol!");
+        }
+    }
+
+    public PictureFillSymbolReader(IFillSymbol symbol)
+    throws Exception {
+        logger.debug("contructor()");
+        if(symbol instanceof PictureFillSymbol) {
+            this.symbol = (PictureFillSymbol)symbol;
+        }
+        else {
+            throw new Exception("Not a PictureFillSymbol!");
+        }
+    }
+
+    /**
+     * Reads the symbol attributes.
+     *
+     * @return The XML node.
+     */
+    public Element read() {
+        logger.debug("read()");
+        Element symbolElement = util.addSymbol(parent);
+
+        try {
+            symbolElement.setAttribute("name", symbol.getNameString());
+        }
+        catch(IOException ioe) {
+            logger.warn("Could not read name. Setting name to \"default\"");
+            symbolElement.setAttribute("name", "default");
+        }
+
+        try {
+            symbolElement.setAttribute(
+                "x_scale",
+                String.valueOf(symbol.getXScale()));
+        }
+        catch(IOException ioe) {
+            logger.warn("Could not read x-scale.");
+        }
+
+        try {
+            symbolElement.setAttribute(
+                "y_scale",
+                String.valueOf(symbol.getYScale()));
+        }
+        catch(IOException ioe) {
+            logger.warn("Could not read y-scale.");
+        }
+
+        try {
+            symbolElement.setAttribute(
+                "xseparation",
+                String.valueOf(symbol.getXSeparation()));
+        }
+        catch(IOException ioe) {
+            logger.warn("Could not read x-separation.");
+        }
+
+        try {
+            symbolElement.setAttribute(
+                "yseparation",
+                String.valueOf(symbol.getYSeparation()));
+        }
+        catch(IOException ioe) {
+            logger.warn(
+                "Could not read y-separation.");
+        }
+
+	try {
+            ILineSymbol ls = symbol.getOutline();
+            LineSymbolReader lsr = new LineSymbolReader();
+            if(lsr.canRead(ls)) {
+                lsr.setSymbol(ls);
+                lsr.setUtil(util);
+                lsr.setParent(symbolElement);
+                lsr.read();
+            }
+            else {
+                logger.debug("The type of " + ls.getClass().toString() +
+                             " is not implemented!");
+            }
+        }
+        catch(Exception e) {
+            logger.warn("Could not read outline.");
+        }
+
+        //Read the picture and convert to base64.
+        try {
+            Picture p = symbol.getPicture();
+            Image i = p.toImage();
+            if(i instanceof BufferedImage) {
+                BufferedImage bi = (BufferedImage)i;
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                //Get byte array from image.
+                ImageIO.write(bi, "BMP", baos);
+                Base64 encoder = new Base64();
+                //encode in a base64 string
+                String pict = encoder.encodeBase64String(baos.toByteArray());
+                symbolElement.setAttribute("picture", pict);
+
+                //Get transparent color.
+                RgbColor c = new RgbColor();
+                c.setRGB(symbol.getBitmapTransparencyColor().getRGB());
+                Color transp = new Color (
+                        c.getRed(),
+                        c.getGreen(),
+                        c.getBlue());
+                symbolElement.setAttribute(
+                    "transparent_color",
+                    String.valueOf(transp.getRGB()));
+            }
+            else {
+                logger.warn("Could not read image symbol.");
+                return null;
+            }
+        }
+        catch(IOException ioe) {
+            logger.warn("Could not read picture.");
+        }
+        symbolElement.setAttribute("type", "fill");
+        symbolElement.setAttribute("style", "picture");
+
+        return symbolElement;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/src/java/de/intevation/mxd/reader/PictureLineSymbolReader.java	Fri Aug 12 09:15:34 2011 +0200
+++ b/src/java/de/intevation/mxd/reader/PictureLineSymbolReader.java	Fri Aug 12 16:08:57 2011 +0200
@@ -33,7 +33,12 @@
 
 import org.w3c.dom.Element;
 import java.io.IOException;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import javax.imageio.ImageIO;
+import java.io.ByteArrayOutputStream;
 
+import org.apache.commons.codec.binary.Base64;
 /**
  * Reads picture line symbol information.
  *
@@ -95,29 +100,6 @@
         }
 
         try {
-            if(symbol.getColor() instanceof IRgbColor) {
-                IRgbColor color = (IRgbColor)symbol.getColor();
-                Color c = new Color (
-                    color.getRed(),
-                    color.getGreen(),
-                    color.getBlue());
-                symbolElement.setAttribute("color", String.valueOf(c.getRGB()));
-            }
-            else {
-                RgbColor col = new RgbColor();
-                col.setRGB(symbol.getColor().getRGB());
-                Color c = new Color (
-                    col.getRed(),
-                    col.getGreen(),
-                    col.getBlue());
-                symbolElement.setAttribute("color", String.valueOf(c.getRGB()));
-            }
-        }
-        catch(IOException ioe) {
-            logger.warn("Could not read color.");
-        }
-
-        try {
             symbolElement.setAttribute(
                 "offset",
                 String.valueOf(symbol.getOffset()));
@@ -152,7 +134,40 @@
         catch(IOException ioe) {
             logger.warn("Could not read width.");
         }
+        
+        //Read the picture and convert to base64.
+        try {
+            Picture p = symbol.getPicture();
+            Image i = p.toImage();
+            if(i instanceof BufferedImage) {
+                BufferedImage bi = (BufferedImage)i;
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                //Get byte array from image.
+                ImageIO.write(bi, "BMP", baos);
+                Base64 encoder = new Base64();
+                //encode in a base64 string
+                String pict = encoder.encodeBase64String(baos.toByteArray());
+                symbolElement.setAttribute("picture", pict);
 
+                //Get transparent color.
+                RgbColor c = new RgbColor();
+                c.setRGB(symbol.getBitmapTransparencyColor().getRGB());
+                Color transp = new Color (
+                        c.getRed(),
+                        c.getGreen(),
+                        c.getBlue());
+                symbolElement.setAttribute(
+                    "transparent_color",
+                    String.valueOf(transp.getRGB()));
+            }
+            else {
+                logger.warn("Could not read image symbol.");
+                return null;
+            }
+        }
+        catch(IOException ioe) {
+            logger.warn("Could not read picture.");
+        }
         symbolElement.setAttribute("type", "line");
         symbolElement.setAttribute("style", "picture");
 
--- a/src/java/de/intevation/mxd/reader/PictureMarkerSymbolReader.java	Fri Aug 12 09:15:34 2011 +0200
+++ b/src/java/de/intevation/mxd/reader/PictureMarkerSymbolReader.java	Fri Aug 12 16:08:57 2011 +0200
@@ -25,9 +25,19 @@
 import com.esri.arcgis.display.IMarkerSymbol;
 import com.esri.arcgis.display.PictureMarkerSymbol;
 import com.esri.arcgis.carto.PictureElement;
+import com.esri.arcgis.support.ms.stdole.Picture;
+import com.esri.arcgis.display.RgbColor;
 
 import org.w3c.dom.Element;
 import java.io.IOException;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import javax.imageio.ImageIO;
+import java.io.ByteArrayOutputStream;
+import java.awt.Color;
+
+import org.apache.commons.codec.binary.Base64;
 
 /**
  * Reads picture marker symbol information.
@@ -128,9 +138,35 @@
             symbolElement.setAttribute("name", "default");
         }
 
+        //Read the picture and convert to base64.
         try {
-            PictureElement pElem = new PictureElement();
-            pElem.importPicture(symbol.getPicture());
+            Picture p = symbol.getPicture();
+            Image i = p.toImage();
+            if(i instanceof BufferedImage) {
+                BufferedImage bi = (BufferedImage)i;
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                //Get byte array from image.
+                ImageIO.write(bi, "BMP", baos);
+                Base64 encoder = new Base64();
+                //encode in a base64 string
+                String pict = encoder.encodeBase64String(baos.toByteArray());
+                symbolElement.setAttribute("picture", pict);
+
+                //Get transparent color.
+                RgbColor c = new RgbColor();
+                c.setRGB(symbol.getBitmapTransparencyColor().getRGB());
+                Color transp = new Color (
+                        c.getRed(),
+                        c.getGreen(),
+                        c.getBlue());
+                symbolElement.setAttribute(
+                    "transparent_color",
+                    String.valueOf(transp.getRGB()));
+            }
+            else {
+                logger.warn("Could not read image symbol.");
+                return null;
+            }
         }
         catch(IOException ioe) {
             logger.warn("Could not read picture.");
--- a/src/java/de/intevation/mxd/writer/FillStyleWriter.java	Fri Aug 12 09:15:34 2011 +0200
+++ b/src/java/de/intevation/mxd/writer/FillStyleWriter.java	Fri Aug 12 16:08:57 2011 +0200
@@ -77,7 +77,7 @@
      * @param symbolElement DOM element containing style attributes.
      */
     public boolean write(Element symbolElement) {
-        logger.debug("write()Element");
+        logger.debug("write(Element)");
         symbolSetObj symbolSet = map.getSymbolset();
 
         if(symbolElement.hasChildNodes()) {
@@ -85,7 +85,6 @@
             for (int i = 0; i < symbols.getLength(); i++) {
                 Element nextSym = (Element)symbols.item(i);
                 String type = nextSym.getAttribute("type");
-
                 if(((symbols.getLength() > 1 && i == 0) ||
                     (symbols.getLength() == 1 &&
                      !symbolElement.hasAttribute("hatch"))) &&
@@ -101,14 +100,41 @@
                     }
                     writeOutline(nextSym);
                     if (symbols.getLength() == 1) {
-                        writeSimple(symbolElement);
-                    }
-                    try {
-                        SymbolWriter sw = new SymbolWriter(this.map, this.cl);
-                        sw.saveSymbolSet(symbolSet);
-                    }
-                    catch(Exception e) {
-                        logger.warn("Could not save symbol set.");
+                        String stype = symbolElement.getAttribute("style");
+                        if(stype.equals("picture")) {
+                            double gap = 0;
+                            if(symbolElement.hasAttribute("xseparation")) {
+                                try {
+                                    gap = Double.parseDouble(
+                                        symbolElement.getAttribute("xseparation"));
+                                }
+                                catch(NumberFormatException nfe) {
+                                    gap = 0;
+                                }
+                            }
+                            
+                            try {
+                                SymbolWriter sw =
+                                    new SymbolWriter(this.map, this.cl);
+                                sw.write(symbolElement);
+                                sw.saveSymbolSet(symbolSet);
+                            }
+                            catch(Exception e) {
+                                logger.warn("Could not save symbol set.");
+                            }
+                            writeMarker(symbolElement, gap);
+                        }
+                        else {
+                            writeSimple(symbolElement);
+                             try {
+                                 SymbolWriter sw =
+                                     new SymbolWriter(this.map, this.cl);
+                                 sw.saveSymbolSet(symbolSet);
+                             }
+                             catch(Exception e) {
+                                 logger.warn("Could not save symbol set.");
+                             }
+                        }
                     }
                 }
                 else if(nextSym.getTagName().equals("symbol") &&
@@ -148,7 +174,8 @@
                 else {
                     writeSimple(symbolElement);
                     try {
-                        SymbolWriter sw = new SymbolWriter(this.map, this.cl);
+                        SymbolWriter sw =
+                            new SymbolWriter(this.map, this.cl);
                         sw.saveSymbolSet(symbolSet);
                     }
                     catch(Exception e) {
@@ -318,6 +345,7 @@
         logger.debug("writeMarker()");
         String name = symbolElement.getAttribute("name");
         String type = symbolElement.getAttribute("type");
+        String stype = symbolElement.getAttribute("style");
         if (symbolElement.hasAttribute("angle")) {
             try {
                style.setAngle(
@@ -416,6 +444,9 @@
                 }
             }
         }
+        if(stype.equals("picture")) {
+            style.setSymbolByName(map, name);
+        }
     }
 
     /**
--- a/src/java/de/intevation/mxd/writer/LineStyleWriter.java	Fri Aug 12 09:15:34 2011 +0200
+++ b/src/java/de/intevation/mxd/writer/LineStyleWriter.java	Fri Aug 12 16:08:57 2011 +0200
@@ -225,6 +225,12 @@
         else {
             try {
                 SymbolWriter sw = new SymbolWriter (this.map, this.cl);
+                if(symbolElement.getAttribute("style").equals("picture")){
+                    sw.write(symbolElement);
+                    style.setSymbolByName(
+                        map,
+                        symbolElement.getAttribute("name"));
+                }
                 sw.saveSymbolSet (symbolSet);
             }
             catch (Exception e) {
--- a/src/java/de/intevation/mxd/writer/MarkerStyleWriter.java	Fri Aug 12 09:15:34 2011 +0200
+++ b/src/java/de/intevation/mxd/writer/MarkerStyleWriter.java	Fri Aug 12 16:08:57 2011 +0200
@@ -148,7 +148,8 @@
         String symType = symbolElement.getAttribute("style");
         if(symType.equals("point") ||
            symType.equals("arrow") ||
-           symType.equals("char")) {
+           symType.equals("char") ||
+           symType.equals("picture")) {
            SymbolWriter sw = new SymbolWriter(this.map, this.cl);
            sw.write(symbolElement);
         }
--- a/src/java/de/intevation/mxd/writer/SymbolWriter.java	Fri Aug 12 09:15:34 2011 +0200
+++ b/src/java/de/intevation/mxd/writer/SymbolWriter.java	Fri Aug 12 16:08:57 2011 +0200
@@ -35,6 +35,20 @@
 import edu.umn.gis.mapscript.MS_SYMBOL_TYPE;
 
 import java.io.File;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import java.awt.image.FilteredImageSource; 
+import java.awt.image.ImageFilter; 
+import java.awt.image.ImageProducer; 
+import java.awt.image.RGBImageFilter; 
+import java.awt.Toolkit;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import javax.imageio.ImageIO;
+import java.io.ByteArrayInputStream;
+
+import org.apache.commons.codec.binary.Base64;
 
 /**
  * The interface to the mapfile writer.
@@ -75,17 +89,22 @@
         logger.debug("write(Element)");
         symbolSetObj symbolSet = map.getSymbolset();
 
-        String name = symbolElement.getAttribute("name");
-        symbolObj sym = symbolSet.getSymbolByName(name);
         String symType = symbolElement.getAttribute("style");
         String type = symbolElement.getAttribute("type");
         if(symType.equals("point")) {
+            String name = symbolElement.getAttribute("name");
+            symbolObj sym = symbolSet.getSymbolByName(name);
             writeSimple(sym);
         }
         else if (symType.equals("arrow")) {
+            String name = symbolElement.getAttribute("name");
+            symbolObj sym = symbolSet.getSymbolByName(name);
             writeArrow(sym, symbolElement);
         }
         else if (symType.equals("char")) {
+            String name = symbolElement.getAttribute("name");
+            symbolObj sym = symbolSet.getSymbolByName(name);
+
             int exists = symbolExists(symbolElement);
             if(exists == -1) {
                 String old = symbolElement.getAttribute("name");
@@ -100,9 +119,32 @@
                     symbolSet.getSymbol(exists).getName());
             }
         }
-        else if (type.equals("line")) {
+        else if (type.equals("line") && !symType.equals("picture")) {
+            String name = symbolElement.getAttribute("name");
+            symbolObj sym = symbolSet.getSymbolByName(name);
             writeHatch(sym);
         }
+        else if(symType.equals("picture")) {
+            // Create the path to the picture.
+            int exists = symbolExists(symbolElement);
+            String n = symbolElement.getAttribute("name");
+            symbolElement.setAttribute(
+                "name",
+                n + symbolSet.getNumsymbols() + 1);
+            String path = this.map.getMappath();
+            if (path.endsWith(".map")) {
+                path = path.substring(0, path.lastIndexOf(File.separator) + 1);
+                path += symbolElement.getAttribute("name") + ".png";
+            }
+            else {
+                path += symbolElement.getAttribute("name") + ".png";
+            }
+            // Create a new symbol using the path as symbol name.
+            // This is a workarround to set the IMAGE attribute to the path
+            // since this attribute is immutable via mapscript.
+            symbolObj sym = symbolSet.getSymbolByName(path);
+            writePicture(sym, symbolElement, path);
+        }
         else {
             return false;
         }
@@ -193,7 +235,53 @@
         symbol.setCharacter("&#" + symbolElement.getAttribute("char") + ";");
     }
 
+
     /**
+     * Create the image and a pixmap symbol.
+     *
+     * @param sym The symbol object.
+     * @param symElem The DOM element containing symbol informations.
+     */
+    private void writePicture(symbolObj sym, Element symElem, String path) {
+        logger.info("writePicture(symbolObj, Element)");
+        try {
+            // Create the image as png.
+            if(symElem.hasAttribute("picture")) {
+                Base64 decoder = new Base64();
+                // Decode the base64 string.
+                byte[] ba = decoder.decode(symElem.getAttribute("picture"));
+                ByteArrayInputStream ins = new ByteArrayInputStream(ba);
+                // Create temporary image from byte array.
+                BufferedImage bi = ImageIO.read(ins);
+                Color c = Color.decode(
+                    symElem.getAttribute("transparent_color"));
+                // Make a color transparent.
+                Image im = colorToTransparent(bi, c);
+
+                // Save image as png.
+                BufferedImage dest = new BufferedImage(
+                    bi.getWidth(),
+                    bi.getHeight(),
+                    BufferedImage.TYPE_INT_ARGB); 
+                Graphics2D g2 = dest.createGraphics(); 
+                g2.drawImage(im, 0, 0, null); 
+                g2.dispose(); 
+                File f = new File(path);
+                ImageIO.write(dest, "PNG", f);
+            }
+            // Set symbol attributes.
+            // Overwrite the symbol name conating the path to the image
+            // with the real name. This is part of the workarround(line 137).
+            sym.setName(symElem.getAttribute("name"));
+            sym.setType(MS_SYMBOL_TYPE.MS_SYMBOL_PIXMAP.swigValue());
+        }
+        catch(Exception e) {
+            logger.warn("Could not save image for pixmap symbol.");
+        }
+    }
+
+
+     /**
      * Create a hatch symbol for polygon fill.
      *
      * @param symbol The symbol object.
@@ -212,7 +300,8 @@
         if (type.equals("point") ||
             type.equals("arrow") ||
             type.equals("char") ||
-            type.equals("line")) {
+            type.equals("line") ||
+            type.equals("picture")) {
             return true;
         }
         else {
@@ -284,8 +373,40 @@
                     etype.equals("hatch")) {
                 return i;
             }
+            else if(stype == MS_SYMBOL_TYPE.MS_SYMBOL_PIXMAP.swigValue() &&
+                    etype.equals("picture")) {
+                return i;        
+            }
         }
         return -1;
     }
+
+
+    /**
+     * Transform a color to transparency.
+     *
+     * @param bi The image.
+     * @param col the color.
+     *
+     * @return The image with transparent color.
+     */
+    private Image colorToTransparent(BufferedImage bi, Color col) {
+        final int markerRGB = col.getRGB() | 0xFF000000;
+        ImageFilter filter = new RGBImageFilter() {
+            public final int filterRGB(int x, int y, int rgb) {
+                if ((rgb | 0xFF000000) == markerRGB) {
+                    // Mark the alpha bits as zero - transparent
+                    return 0x00FFFFFF & rgb;
+                }
+                else {
+                    // nothing to do
+                    return rgb;
+                }
+            }
+        };
+        ImageProducer ip = new FilteredImageSource(bi.getSource(), filter);
+        return Toolkit.getDefaultToolkit().createImage(ip);
+    }
+    
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)