view src/java/de/intevation/mxd/writer/MapScriptWriter.java @ 146:e4a8c39985d7

* mxd/Styles/label/*: Added two examples to show basic labeling within an MXD. More will not be supported though.
author Stephan Holl <stephan.holl@intevation.de>
date Wed, 29 Jun 2011 17:36:44 +0200
parents b2c5a66022f1
children 2bf35f0babd0
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 edu.umn.gis.mapscript.MS_CONNECTION_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;
    private String MS_BINDIR = "c:/ms_6.1-dev/bin";
    private String prefix = "";

    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.
            String lname = layerElement.getAttribute("name");
            lname = lname.replaceAll(" ", "");
            layer.setName(lname);
            layer.setMetaData("wms_title", 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 = 0;
            double minScale = 0;
            try {
                maxScale =
                    Double.parseDouble(layerElement.getAttribute("max_scale"));
                minScale =
                    Double.parseDouble(layerElement.getAttribute("min_scale"));
            }
            catch(NumberFormatException nfe) {
                logger.warn("Error setting scale.");
                maxScale = 0;
                minScale = 0;
            }
            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 con_type = layerElement.getAttribute("connection_type");
            if(con_type.equals("local")) {
                String datasource = "";
                if(layerElement.hasAttribute("workspace")) {
                    datasource = layerElement.getAttribute("workspace");
                    datasource += File.separator;
                }
                datasource += layerElement.getAttribute("data_source");
                layer.setData(datasource);
            }
            else if(con_type.equals("SDE")) {
                logger.info(
                    "SDE datasource found." +
                    " Please edit password in mapfile.");
                layer.setConnectionType(
                MS_CONNECTION_TYPE.MS_PLUGIN.swigValue(),
                MS_BINDIR + "/ms/plugins/msplugin_sde_93.dll");
                layer.setConnection(
                layerElement.getAttribute("server") + "," +
                    "port:" + layerElement.getAttribute("instance") + "," +
                layerElement.getAttribute("database") + "," +
                layerElement.getAttribute("user") + ",<PASSWORD>");
                layer.setData(
                    layerElement.getAttribute("data_source") +
                    ",SHAPE," +
                    layerElement.getAttribute("version"));
                layer.setProcessing("CLOSE_CONNECTION=defer");
                layer.setProcessing("ATTRIBUTE_QUALIFIED=TRUE");
                if(layerElement.hasAttribute("join_table")) {
                    layer.setProcessing(
                        "JOINTABLE=" +
                    layerElement.getAttribute("join_table"));
                    layer.setFilter(
                        "where " + 
                        layerElement.getAttribute("definition_query") +
                        " AND " +
                        layerElement.getAttribute("join_table_target") + "." +
                        layerElement.getAttribute("join_field_target") + "=" +
                        layerElement.getAttribute("join_table") + "." +
                        layerElement.getAttribute("join_field"));
                }
                else {
                    prefix = layerElement.getAttribute("data_source");
                }
            }
            layer.setTemplate("PleaseInsertAValidTemplateForGFI");
            //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")) {
                co.setExpression(createExpression(classElement));
            }
            //Write symbols and styles.
            NodeList l = classElement.getChildNodes();
            for (int j = l.getLength() - 1; j >= 0; 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 createExpression(Element ce) {
        String expression = "(";
        int count = 0;
        try {
            count = Integer.parseInt(ce.getAttribute("field_count"));
        }
        catch(NumberFormatException nfe) {
            return "";
        }
        if(count == 1) {
            try {
                Double.parseDouble(ce.getAttribute("value"));
                String exp = ce.getAttribute("expression_field_0");
                String pre = "";
                if (!prefix.equals("") && !exp.startsWith(prefix)) {
                    pre = prefix + ".";
                }
                expression += "[" + pre;
                expression += ce.getAttribute("expression_field_0") + "]";
                if(ce.hasAttribute("min_value")) {
                    expression += " > " + ce.getAttribute("min_value");
                    expression += " AND [";
                    expression += ce.getAttribute("expression_field_0")+ "]";
                }
                expression += " " + ce.getAttribute("expression_operator");
                expression += " " + ce.getAttribute("value") + ")";
            }
            catch(NumberFormatException nfe) {
                String exp = ce.getAttribute("expression_field_0");
                String pre = "";
                if (!prefix.equals("") && !exp.startsWith(prefix)) {
                    pre = prefix + ".";
                }
                expression += "\"[" + pre;
                expression += ce.getAttribute("expression_field_0") + "]\"";
                expression += " " + ce.getAttribute("expression_operator");
                expression += " \"" + ce.getAttribute("value") + "\")";	
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
        else {
            for (int i = 0; i < count; i++) {
                try {
                    Double.parseDouble(ce.getAttribute("value_" + i));
                    String exp = ce.getAttribute("expression_field_" + i);
                    String pre = "";
                    if (!prefix.equals("") && !exp.startsWith(prefix)) {
                       pre = prefix + ".";
                    }
                    expression += "[" + pre;
                    expression += ce.getAttribute("expression_field_" + i) + "]";
                    expression += " " + ce.getAttribute("expression_operator");
                    expression += " " + ce.getAttribute("value_" + i);
                    if (i < count - 1) {
                        expression += " AND ";
                    }
                    else {
                        expression += ")";
                    }
                }
                catch (NumberFormatException nfe) {
                    String exp = ce.getAttribute("expression_field_" + i);
                    String pre = "";
                    if (!prefix.equals("") && !exp.startsWith(prefix)) {
                       pre = prefix + ".";
                    }
                    expression += "\"[" + pre;
                    expression += ce.getAttribute("expression_field_" + i) + "]\"";
                    expression += " " + ce.getAttribute("expression_operator");
                    expression += " " + ce.getAttribute("value_" + i);
                    if (i < count - 1) {
                        expression += " AND ";
                    }
                    else {
                        expression += ")";
                    }
                }
            }
        }
        return expression;
    }
}
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)