diff src/java/de/intevation/mxd/writer/SymbolWriter.java @ 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 df4e0946ef02
children 8e5d67c45b64
line wrap: on
line diff
--- 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)