view src/java/de/intevation/mxd/writer/MapScriptWriter.java @ 127:5ba8bf865dc7

Write expressions for string values to the mapfile.
author Raimund Renkert <rrenkert@intevation.de>
date Mon, 20 Jun 2011 11:35:40 +0200
parents ff0354265a7d
children 1616622a8c8d
line wrap: on
line source
package de.intevation.mxd.writer;

import org.apache.log4j.Logger;

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

import java.io.File;

import javax.xml.xpath.XPathConstants;

import edu.umn.gis.mapscript.mapObj;
import edu.umn.gis.mapscript.layerObj;
import edu.umn.gis.mapscript.classObj;

import edu.umn.gis.mapscript.MS_UNITS;
import edu.umn.gis.mapscript.MS_LAYER_TYPE;

import de.intevation.mxd.utils.XMLUtils;

/**
 * The Mapfile Writer.
 * This Writer uses the MapScript Java API to create Mapfiles from a DOM.
 *
 * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
 */
public class MapScriptWriter
implements IWriter
{
    /**
     * The Logger.
     */
    private static final Logger logger = Logger.getLogger(MapScriptWriter.class);

    /**
     * Private member.
     */
    private Document root;
    private mapObj map;
    private String mapFilename;

    public MapScriptWriter() {
        map = new mapObj("");
        mapFilename = "";
    }

    public MapScriptWriter(String templ, String filename) {
        map = new mapObj(templ);
        mapFilename = filename;
    }

    /**
     * Write the mapfile.
     * @param doc The root document containin the map attributes.
     *
     * @return Currently always true.
     */
    public boolean write(Document doc) {
        logger.debug("write()");
        this.root = doc;

        //Get the filename.
        Element fileNode = (Element)XMLUtils.xpath(
            root,
            "/mxd/file",
            XPathConstants.NODE);
        //Write the map attributes.
        writeMap();
        //Write the layers.
        writeLayer();
        //Save the map.
        mapObj cloneMap = map.cloneMap();
        cloneMap.save(mapFilename);
        logger.info("Mapfile successfully created.");
        return true;
    }

    /**
     * Create the map object and set the attributes.
     */
    private void writeMap() {
        logger.debug("writeMap()");
        //Get the map.
        Element mapNode = (Element)XMLUtils.xpath(
            root,
            "/mxd/map",
            XPathConstants.NODE);

        //Set the name.
        map.setName(mapNode.getAttribute("name"));
        map.setMetaData("wms_title", mapNode.getAttribute("name"));
        //Set the extent.
        map.setExtent(
            Double.parseDouble(mapNode.getAttribute("extent_min_x")),
            Double.parseDouble(mapNode.getAttribute("extent_min_y")),
            Double.parseDouble(mapNode.getAttribute("extent_max_x")),
            Double.parseDouble(mapNode.getAttribute("extent_max_y")));

        //Set the units.
        String units = mapNode.getAttribute("units");
        MS_UNITS msu;
        if(units.equals("feet")) {
            msu = MS_UNITS.MS_FEET;
        }
        else if(units.equals("inches")) {
            msu = MS_UNITS.MS_INCHES;
        }
        else if(units.equals("kilometers")) {
            msu = MS_UNITS.MS_KILOMETERS;
        }
        else if(units.equals("meters")) {
            msu = MS_UNITS.MS_METERS;
        }
        else if(units.equals("miles")) {
            msu = MS_UNITS.MS_MILES;
        }
        else if(units.equals("nauticalmiles")) {
            msu = MS_UNITS.MS_NAUTICALMILES;
        }
        else if(units.equals("points")) {
            msu = MS_UNITS.MS_PIXELS;
        }
        else {
            msu = MS_UNITS.MS_METERS;
        }
        map.setUnits(msu);

        //TODO: Find out whats the correct scale value.
        //map.setScaledenom(Double.parseDouble(mapNode.getAttribute("scale")));
    }

    /**
     * Create layer objects and set the attributes.
     */
    private void writeLayer() {
        logger.debug("writeLayer()");
        Element mapNode = (Element)XMLUtils.xpath(
            root,
            "/mxd/map",
            XPathConstants.NODE);
        NodeList list = mapNode.getElementsByTagName("layer");
        for(int i = 0; i < list.getLength(); i++) {
            Element layerElement = (Element)list.item(i);
            layerObj layer = new layerObj(map);

            //The layer name.
            layer.setName(layerElement.getAttribute("name"));

            //The layer status.
            String stat = layerElement.getAttribute("status");
            if (stat.equals("on")) {
                layer.setStatus(1);
            }
            else {
                layer.setStatus(0);
            }

            //The scale.
            double maxScale =
                Double.parseDouble(layerElement.getAttribute("max_scale"));
            double minScale =
                Double.parseDouble(layerElement.getAttribute("min_scale"));
            layer.setMaxscaledenom(maxScale);
            layer.setMinscaledenom(minScale);

            //The layer type.
            String type = layerElement.getAttribute("type");
            if(type.equals("point")) {
                layer.setType(MS_LAYER_TYPE.MS_LAYER_POINT);
            }
            else if (type.equals("line")) {
                layer.setType(MS_LAYER_TYPE.MS_LAYER_LINE);
            }
            else if (type.equals("polygon")) {
                layer.setType(MS_LAYER_TYPE.MS_LAYER_POLYGON);
            }
            layer.setTileitem("");

            //The layer datasource.
            String datasource = "";
            if(layerElement.hasAttribute("workspace")) {
                datasource = layerElement.getAttribute("workspace");
                datasource += File.separator;
            }
            datasource += layerElement.getAttribute("data_source");
            layer.setData(datasource);

            //Write classes.
            writeClass(layer, layerElement);
        }

    }

    /**
     * Adds the classes to the layer.
     * @param layer        Mapscript layer object.
     * @param layerElement Dom element containing the class attributes.
     */
    private void writeClass(layerObj layer, Element layerElement) {
        logger.debug("writeClass(layerObj, Element)");
        //Get all renderer elements (renderer in arcgis equals class in the
        //mapfile.)
        NodeList list = layerElement.getElementsByTagName("renderer");

        //Create all found class objects and write the symbols and styles for
        //each class.
        for(int i = 0; i < list.getLength(); i++) {
            Element classElement = (Element)list.item(i);
            classObj co = new classObj(layer);
            String name = classElement.getAttribute("label");
            if (name.equals("")) {
                name = layerElement.getAttribute("name");
                if (list.getLength() > 1) {
                    name += "-" + i;
                }
            }
            co.setName (name);
            if(classElement.hasAttribute("field_count")) {
                int count =
                    Integer.parseInt(classElement.getAttribute("field_count"));
                int type = 0;
                try {
                    Double.parseDouble(classElement.getAttribute("value"));
                    type = 1;
                }
                catch(Exception e) {
                    type = 2;
                }
                if (type == 1) {
                    co.setExpression(createDoubleExpression(classElement, count));
                }
                else if (type == 2) {
                    co.setExpression(createStringExpression(classElement, count));
                }

            }
            //Write symbols and styles.
            NodeList l = classElement.getChildNodes();
            for (int j = 0; j < l.getLength(); j++) {
                Element elem = (Element)l.item(j);

                String type = layerElement.getAttribute("type");
                if(type.equals("point") && elem.getTagName().equals("symbol")) {
                    MarkerStyleWriter swriter = new MarkerStyleWriter (this.map, co);
                    swriter.write (elem);
                }
                else if(type.equals("line") && elem.getTagName().equals("symbol")) {
                    LineStyleWriter swriter = new LineStyleWriter (this.map, co);
                    swriter.write (elem);
                }
                else if(type.equals("polygon") && elem.getTagName().equals("symbol")) {
                    FillStyleWriter swriter = new FillStyleWriter (this.map, co);
                    swriter.write (elem);
                }
            }
        }
    }

    private String createDoubleExpression (Element classElement, int count) {
        String exp = "";
        String op = classElement.getAttribute("expression_operator");
        String op1 = "";
        String op2 = "";
        if (op.equals("<=")) {
            op1 = ">=";
            op2 = op;
            for(int j = 0; j < count; j++) {
                if (classElement.getAttribute("min_value").equals(
                    classElement.getAttribute("value"))) {
                    exp = "([" +
                          classElement.getAttribute(
                              "expression_field_" + j) +
                          "] == " +
                          classElement.getAttribute("value") +
                          ")";
                }
                else {
                    exp = "([";
                    exp += classElement.getAttribute(
                                "expression_field_" + j);
                    exp += "] " + op1;
                    exp += " " + classElement.getAttribute("min_value");
                    exp += " AND [" + classElement.getAttribute(
                            "expression_field_" + j);
                    exp += "] " + op2 + " ";
                    exp += classElement.getAttribute("value");
                    exp += ")";
                }
            }
        }
        else if (op.equals("=")) {
            op1 = op;
            for(int j = 0; j < count; j++) {
               exp = "([" +
                     classElement.getAttribute("expression_field_" + j) +
                     "] == " +
                     classElement.getAttribute("value") + ")";
            }
        }
        return exp;
    }

    private String createStringExpression (Element classElement, int count) {
        String exp = "";
        String op = classElement.getAttribute("expression_operator");
        if (op.equals("=")) {
            for(int j = 0; j < count; j++) {
                exp = "(\"[";
                exp += classElement.getAttribute(
                            "expression_field_" + j);
                exp += "]\" " + op;
                exp += " \"" + classElement.getAttribute("value");
                exp += "\")";
            }
        }
        return exp;
    }
}
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)