view src/java/de/intevation/mxd/writer/FillStyleWriter.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 2cb2f26d0d54
line wrap: on
line source
/*
 * 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.writer;

import java.io.IOException;
import java.awt.Color;
import org.apache.log4j.Logger;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import edu.umn.gis.mapscript.mapObj;
import edu.umn.gis.mapscript.layerObj;
import edu.umn.gis.mapscript.classObj;
import edu.umn.gis.mapscript.styleObj;
import edu.umn.gis.mapscript.colorObj;
import edu.umn.gis.mapscript.symbolObj;
import edu.umn.gis.mapscript.symbolSetObj;
import edu.umn.gis.mapscript.lineObj;
import edu.umn.gis.mapscript.pointObj;


/**
 * The interface to the mapfile writer.
 *
 * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
 */
public class FillStyleWriter {

    /**
     * The Logger.
     */
    private static final Logger logger =
        Logger.getLogger(FillStyleWriter.class);

    /**
     * Private member.
     */
    private mapObj map;
    private classObj cl;
    private styleObj style;
    private colorObj fill;

    /**
     * Constructor with map object and class object.
     *
     * @param map The map object.
     * @param cl  The class object containing the style.
     */
    public FillStyleWriter (mapObj map, classObj cl) {
        logger.debug("contructor(mapObj, classObj)");
        this.map = map;
        this.cl = cl;
        this.style = new styleObj(cl);
    }

    /**
     * Write the content.
     *
     * @param symbolElement DOM element containing style attributes.
     */
    public boolean write(Element symbolElement) {
        logger.debug("write(Element)");
        symbolSetObj symbolSet = map.getSymbolset();

        if(symbolElement.hasChildNodes()) {
            NodeList symbols = symbolElement.getChildNodes();
            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"))) &&
                   type.equals("line")) {
                    if(symbolElement.hasAttribute("color")) {
                        Color oCol = Color.decode(
                        symbolElement.getAttribute("color"));
                        fill = new colorObj(
                            oCol.getRed(),
                            oCol.getGreen(),
                            oCol.getBlue(),
                            -4);
                    }
                    writeOutline(nextSym);
                    if (symbols.getLength() == 1) {
                        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") &&
                   !symbolElement.hasAttribute("hatch") ||
                   (i == 1 && type.equals("marker"))) {
                    double gap = 0;
                    if(symbolElement.hasAttribute("xseparation")) {
                        try {
                            gap = Double.parseDouble(
                                symbolElement.getAttribute("xseparation"));
                        }
                        catch(NumberFormatException nfe) {
                            gap = 0;
                        }
                    }
                    writeMarker(nextSym, gap);
                }
                else if (nextSym.getTagName().equals("symbol") &&
                         symbolElement.hasAttribute("hatch")) {
                    if(i == 0) {
                        writeOutline(nextSym);
                    }
                    else {
                        if(symbolElement.hasAttribute("angle")) {
                            nextSym.setAttribute(
                                "angle",
                                symbolElement.getAttribute("angle"));
                        }
                        if(symbolElement.hasAttribute("separation")) {
                            nextSym.setAttribute(
                                "size",
                                symbolElement.getAttribute("separation"));
                        }
                        writeMarker(nextSym, -1);
                    }
                }
                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 {
            writeSimple(symbolElement);
            if(symbolElement.hasAttribute("outline_color")) {
                Color oCol = Color.decode(
                    symbolElement.getAttribute("outline_color"));
                colorObj outlineColor = new colorObj(
                    oCol.getRed(),
                    oCol.getGreen(),
                    oCol.getBlue(),
                    -4);
                style.setOutlinecolor(outlineColor);
                try {
                    style.setOutlinewidth(Double.parseDouble(
                        symbolElement.getAttribute("outline_size")));
                }
                catch(NumberFormatException nfe) {
                    logger.warn("Error setting outline width.");
                    style.setOutlinewidth(0.0);
                }
            }
            try {
                SymbolWriter sw = new SymbolWriter(this.map, this.cl);
                sw.saveSymbolSet(symbolSet);
            }
            catch(Exception e) {
                logger.warn("Could not save symbol set.");
            }
        }
        return true;
    }

    /**
     * Write the outline for a polygon.
     *
     * @param symbolElement Dom element containing the symbol attributes.
     */
    private void writeOutline(Element symbolElement) {
        logger.debug("writeOutline()");
        //write transparent outline
        colorObj color = new colorObj(-1, -1, -1, -4);
        double w = 0;
        double transp = -1;
        if(symbolElement.hasAttribute("width")) {
            try {
                w = Double.parseDouble(symbolElement.getAttribute("width"));
                if(symbolElement.hasAttribute("transparency")) {
                    transp = Double.parseDouble(
                        symbolElement.getAttribute("transparency"));
                }
                else {
                    transp = -1;
                }
            }
            catch(NumberFormatException nfe) {
                logger.warn("Error setting outline width or transparency.");
                w = 0;
                transp = -1;
            }
        }

        Color oCol = Color.decode(
            symbolElement.getAttribute("color"));

        styleObj outline = new styleObj (cl);
        if (w < 1.0) {
            symbolElement.setAttribute("width", "1");
        }
        colorObj outlinecolor = new colorObj(
            oCol.getRed(),
            oCol.getGreen(),
            oCol.getBlue(),
            -4);
        outline.setOutlinecolor(outlinecolor);
        if(transp >= 0) {
            int opacity = (int)((1 - (transp/255)) * 100);
            outline.setOpacity(opacity); 
        }
        try {
            outline.setOutlinewidth(Double.parseDouble(
                symbolElement.getAttribute("width")));
        }
        catch(NumberFormatException nfe) {
            logger.warn("Error setting outline width.");
            outline.setOutlinewidth(0.0);
        }
        if(symbolElement.hasAttribute("linestyle")) {
            //Write predefined dashed or dotted lines.
            String ls = symbolElement.getAttribute("linestyle");
            double[] vals;
            if(ls.equals("dash")) {
                outline.setPatternlength(2);
                vals = new double[] {4.0, 4.0, 0, 0, 0, 0, 0, 0, 0, 0};
                outline.setPattern(vals);
            }
            else if(ls.equals("dot")) {
                outline.setPatternlength(2);
                vals = new double[] {1.0, 3.0, 0, 0, 0, 0, 0, 0, 0, 0};
                outline.setPattern(vals);
            }
            else if(ls.equals("dashdot")) {
                outline.setPatternlength(4);
                vals = new double[] {4.0, 3.0, 1.0, 3.0, 0, 0, 0, 0, 0, 0, 0};
                outline.setPattern(vals);
            }
            else if (ls.equals("dashdotdot")) {
                outline.setPatternlength(6);
                vals = new double[] {5.0, 3.0, 1.0, 3.0, 1.0, 4.0, 0, 0, 0, 0};
                outline.setPattern(vals);
            }
        }
        else if(symbolElement.hasAttribute("pattern_count")) {
            //Write dashed or dotted lines defined with a template.
            int count = 0;
            try {
                count = Integer.parseInt(
                            symbolElement.getAttribute("pattern_count"));
                double[] vals = new double[10];
                double move = 0.0;
                int pos = 0;
                for(int i = 0; i < count; i++) {
                    double mark =
                        Double.parseDouble(symbolElement.getAttribute("mark_" + i));
                    double gap =
                        Double.parseDouble(symbolElement.getAttribute("gap_" + i));
                    if(i == 0 && mark == 0.0) {
                        move = gap;
                    }
                    else if(i == count - 1 && move > 0.0) {
                       vals[pos++] = mark;
                       vals[pos++] = gap + move;
                    }
                    else {
                        vals[pos++] = mark;
                        vals[pos++] = gap;
                    }
                }
                if(move > 0.0) {
                    outline.setPatternlength((count*2) -2);
                }
                else {
                    outline.setPatternlength(count*2);
                }
                outline.setPattern(vals);

            }
            catch(NumberFormatException nfe) {
                logger.warn("Could not write PATTERN.");
            }
        }
    }

    /**
     * Write marker attributes and a symbol for the polygon fill.
     *
     * @param symbolElement DOM element containingg the symbol attributes.
     * @param gap           The initial gap at the begining of a line.
     */
    private void writeMarker(Element symbolElement, double gap) {
        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(
                   Double.parseDouble(symbolElement.getAttribute("angle")));
            }
            catch(NumberFormatException nfe) {
                logger.warn("Error setting angle.");
                style.setAngle(0.0);
            }
        }
        if(symbolElement.hasAttribute("color")) {
            String c = symbolElement.getAttribute("color");
            Color col = Color.decode(c);
            colorObj color = new colorObj(
                col.getRed(),
                col.getGreen(),
                col.getBlue(),
                -4);
            style.setColor(color);
        }
        if (symbolElement.hasAttribute ("size")) {
            double size = 1;
            try {
                size = Double.parseDouble(symbolElement.getAttribute("size"));
            }
            catch(NumberFormatException nfe) {
                size = 1.0;
            }
            style.setSize(size);
            //In arcgis the separation goes from center to center, so the gap is
            //the separation - size
            if (gap > 0) {
                style.setGap(gap - size);
            }
        }
        if(symbolElement.hasAttribute("width")) {
            double width = 1;
            try {
                width = Double.parseDouble(symbolElement.getAttribute("width"));
            }
            catch(NumberFormatException nfe) {
                width = 1.0;
            }
            style.setWidth(width);
        }
        if(symbolElement.hasAttribute("outline_color")) {
            Color oCol = Color.decode(
                symbolElement.getAttribute("outline_color"));
            colorObj outlineColor = new colorObj(
                oCol.getRed(),
                oCol.getGreen(),
                oCol.getBlue(),
                -4);
            style.setOutlinecolor(outlineColor);
            try {
                style.setOutlinewidth(Double.parseDouble(
                    symbolElement.getAttribute("outline_size")));
            }
            catch(NumberFormatException nfe) {
                logger.warn("Error setting angle.");
                style.setOutlinewidth(0.0);
            }
        }
        if(type.equals("marker")) {
            style.setSymbolByName(map, name);
            SymbolWriter sw = new SymbolWriter(this.map, this.cl);
            sw.write(symbolElement);
        }
        else if(type.equals("line")) {
            style.setSymbolByName(map, "hatch");
            SymbolWriter sw = new SymbolWriter(this.map, this.cl);
            symbolElement.setAttribute("name", "hatch");
            sw.write(symbolElement);
            if(symbolElement.hasAttribute("linestyle")) {
                String ls = symbolElement.getAttribute("linestyle");
                double[] vals;
                if(ls.equals("dash")) {
                    style.setPatternlength(2);
                    vals = new double[] {4.0, 4.0, 0, 0, 0, 0, 0, 0, 0, 0};
                    style.setPattern(vals);
                }
                else if(ls.equals("dot")) {
                    style.setPatternlength(2);
                    vals = new double[] {1.0, 3.0, 0, 0, 0, 0, 0, 0, 0, 0};
                    style.setPattern(vals);
                }
                else if(ls.equals("dashdot")) {
                    style.setPatternlength(4);
                    vals = new double[] {4.0, 3.0, 1.0, 3.0, 0, 0, 0, 0, 0, 0, 0};
                    style.setPattern(vals);
                }
                else if (ls.equals("dashdotdot")) {
                    style.setPatternlength(6);
                    vals = new double[] {5.0, 3.0, 1.0, 3.0, 1.0, 4.0, 0, 0, 0, 0};
                    style.setPattern(vals);
                }
            }
        }
        if(stype.equals("picture")) {
            style.setSymbolByName(map, name);
        }
    }

    /**
     * Write simple fill attributes.
     *
     * @param symbolElement DOM element containing the symbol attributes.
     */
    private void writeSimple(Element symbolElement) {
        logger.debug("writeSimple(Element)");
        if(symbolElement.hasAttribute("transparency")) {
            double value = 0;
            try {
                value = Double.parseDouble(
                    symbolElement.getAttribute("transparency"));
            }
            catch(NumberFormatException nfe) {
                value = 0;
            }
            int opacity = (int)(1 - (value/255)) * 100;
            style.setOpacity(opacity);
        }
        if(symbolElement.hasAttribute("color")) {
            String c = symbolElement.getAttribute("color");
            Color col = Color.decode(c);
            colorObj color = new colorObj(
                col.getRed(),
                col.getGreen(),
                col.getBlue(),
                -4);
            style.setColor(color);
        }
    }
}
// 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)