view src/java/de/intevation/mxd/writer/MapScriptWriter.java @ 327:35bf59a760ad

Tagged as release 'release-1.1'
author Andre Heinecke <aheinecke@intevation.de>
date Mon, 15 Oct 2012 12:22:02 +0200
parents 5e7e6d99f997
children da60e3ac2b5d
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 org.apache.log4j.Logger;

import java.awt.Color;

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.labelObj;
import edu.umn.gis.mapscript.colorObj;
import edu.umn.gis.mapscript.fontSetObj;
import edu.umn.gis.mapscript.hashTableObj;
import edu.umn.gis.mapscript.shapeObj;
import edu.umn.gis.mapscript.pointObj;
import edu.umn.gis.mapscript.lineObj;

import edu.umn.gis.mapscript.MS_UNITS;
import edu.umn.gis.mapscript.MS_LAYER_TYPE;
import edu.umn.gis.mapscript.MS_CONNECTION_TYPE;
import edu.umn.gis.mapscript.MS_SHAPE_TYPE;
import edu.umn.gis.mapscript.MS_FONT_TYPE;
import edu.umn.gis.mapscript.MS_POSITIONS_ENUM;

import de.intevation.mxd.utils.XMLUtils;
import de.intevation.mxd.utils.MapScriptUtils;

/**
 * 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 MapScriptUtils msutils;
    private String mapFilename;
    private String MS_BINDIR = "c:/mapserver/bin";
    private String prefix = "";
    private MS_UNITS units = MS_UNITS.MS_METERS;

    /**
     * Default constructor.
     * Creates a mapscript writer object with an empty map.
     */
    public MapScriptWriter() {
        map = new mapObj("");
        msutils = new MapScriptUtils();
        mapFilename = "";
    }

    /**
     * Contructor with template and output filename.
     * Creates a mapscript writer object with the given template that saves the
     * map to the filename.
     *
     * @param templ    Mapfile template.
     * @param filename Output file name.
     */
    public MapScriptWriter(String templ, String filename) {
        String path = System.getProperty("user.dir");
        map = new mapObj(templ);
        msutils = new MapScriptUtils();
        File f = new File(filename);
        mapFilename = filename;
        if(f.isAbsolute()) {
            map.setMappath(mapFilename);
        }
        else {
            map.setMappath(
                System.getProperty("user.dir") +
                File.separator +
                mapFilename);
            mapFilename = System.getProperty("user.dir") +
                File.separator +
                mapFilename;
        }
        String fontSetPath = map.getFontset().getFilename();
        File fonts = new File(fontSetPath);
        String fontSet = fonts.getAbsolutePath();
        fontSet = fontSet.replaceAll("\\\\", "/");
        map.setFontSet(fontSet);
    }

    /**
     * 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.
        boolean ret = writeLayer();
        //Save the map.
        if (ret) {
            mapObj cloneMap = map.cloneMap();
            cloneMap.save(mapFilename);
            logger.info("Mapfile created: " + mapFilename);
            return true;
        }
        return false;
    }

    /**
     * Create the map object and set the attributes.
     */
    private void writeMap()
        throws UnknownError
    {
        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")));

        map.setMetaData(
            "ows_extent",
            mapNode.getAttribute("extent_min_x") + ", " +
            mapNode.getAttribute("extent_min_y") + ", " +
            mapNode.getAttribute("extent_max_x") + ", " +
            mapNode.getAttribute("extent_max_y"));

        map.setSize(800, 600);

        //Set the units and projection.
        int proj = Integer.parseInt(mapNode.getAttribute("projection"));
        if(proj != 0) {
            try {
                map.setProjection("epsg:" + mapNode.getAttribute("projection"));
            }
            catch(UnknownError e) {
                logger.error( "Could not set projection: " + mapNode.getAttribute("projection") +
                        ". Please ensure that it is described in your espg file.");
                throw e;
            }
        }
        String u = mapNode.getAttribute("units");
        if(u.equals("feet")) {
            units = MS_UNITS.MS_FEET;
        }
        else if(u.equals("inches")) {
            units = MS_UNITS.MS_INCHES;
        }
        else if(u.equals("kilometers")) {
            units = MS_UNITS.MS_KILOMETERS;
        }
        else if(u.equals("meters")) {
            units = MS_UNITS.MS_METERS;
        }
        else if(u.equals("miles")) {
            units = MS_UNITS.MS_MILES;
        }
        else if(u.equals("nauticalmiles")) {
            units = MS_UNITS.MS_NAUTICALMILES;
        }
        else if(u.equals("points")) {
            units = MS_UNITS.MS_PIXELS;
        }
        else if(u.equals("degree")) {
            units = MS_UNITS.MS_DD;
        }
        else {
            units = MS_UNITS.MS_METERS;
        }
        map.setUnits(units);

        String mproj = mapNode.getAttribute("projection");
        if(mproj != null && !mproj.equals("") && ! mproj.equals("0")) {
            MapScriptUtils msu = new MapScriptUtils();
            String wmssrs = msu.getMetaData(map, "wms_srs");
            String owssrs = msu.getMetaData(map, "ows_srs");
            if(wmssrs.indexOf(mproj) < 0) {
                if(wmssrs.equals("")) {
                    wmssrs = "EPSG:";
                }
                else {
                    wmssrs += " EPSG:";
                }
                wmssrs += mproj;
            }
            if(owssrs.indexOf(mproj) < 0) {
                if(owssrs.equals("")) {
                    owssrs = "EPSG:";
                }
                else {
                    owssrs += " EPSG:";
                }
                owssrs += mproj;
            }
            map.setMetaData("ows_srs", owssrs);
            map.setMetaData("wms_srs", wmssrs);
        }
    }

    /**
     * Create layer objects and set the attributes.
     */
    private boolean 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);
            NodeList renderer = layerElement.getElementsByTagName("renderer");

            //The layer name.
            String group = "";
            if(layerElement.hasAttribute("group")) {
                group = layerElement.getAttribute("group");
                String[] splitted = group.split("/");
                String cleangroup = "";
                for(int j = 0; j < splitted.length; j++) {
                    if(!splitted[j].equals("")) {
                        splitted[j] = msutils.replaceUmlauts(splitted[j]);
                        cleangroup += "/" + 
                                      msutils.removeSpecialChars(splitted[j]);
                    }
                }
                group = cleangroup;
            }
            String lname = layerElement.getAttribute("name");
            lname = msutils.removeSpecialChars(lname);
            lname = msutils.replaceUmlauts(lname);
            String ulgroup = group.replaceAll("/", ".");
            String ulname = ulgroup + "." + lname;
            if(ulname.startsWith(".")) {
                ulname = ulname.substring(1);
            }
            if(ulgroup.startsWith(".")) {
                ulgroup = ulgroup.substring(1);
            }
            layer.setName(ulname);
            layer.setUnits(units.swigValue());
            if(!group.equals("")) {
                layer.setGroup(ulgroup);
                layer.setMetaData("wms_layer_group", group);
            }
            layer.setMetaData("wms_title", ulname);

            //Set the projection for the Layers
            if (layerElement.hasAttribute("projection")) {
                int proj = Integer.parseInt(layerElement.getAttribute("projection"));
                if(proj != 0) {
                    try {
                        layer.setProjection("epsg:" + layerElement.getAttribute("projection"));
                    }
                    catch(UnknownError e) {
                        logger.error( "Could not set projection in layer: " + layerElement.getAttribute("projection") +
                                ". Please ensure that it is described in your espg file.");
                        throw e;
                    }
                }
            }
            // Projection metadata.
            String mproj = mapNode.getAttribute("projection");
            if (layerElement.hasAttribute("projection")) {
                // Overwrite the Map Projection in the layer
                mproj = layerElement.getAttribute("projection");
            }
            if(mproj != null && !mproj.equals("") && !mproj.equals("0")) {
                String wmssrs = layer.getMetaData("wms_srs");
                String owssrs = layer.getMetaData("ows_srs");
                if(wmssrs == null) {
                    wmssrs = "EPSG:";
                }
                else {
                    wmssrs += " EPSG:";
                }
                if(owssrs == null) {
                    owssrs = "EPSG:";
                }
                else {
                    owssrs += " EPSG:";
                }
                wmssrs += mproj;
                owssrs += mproj;
                layer.setMetaData("wms_srs", wmssrs);
                layer.setMetaData("ows_srs", owssrs);
            }

            // WMS Version
            if (layerElement.hasAttribute("wms_server_version")) {
                layer.setMetaData("wms_server_version",
                    layerElement.getAttribute("wms_server_version"));
            }

            // WMS Version
            if (layerElement.hasAttribute("imageType")) {
                layer.setMetaData("wms_format",
                    layerElement.getAttribute("imageType"));
            }

            // The layer extent metadata.
            if(layerElement.hasAttribute("extent_min_x") &&
               layerElement.hasAttribute("extent_max_x") &&
               layerElement.hasAttribute("extent_min_y") &&
               layerElement.hasAttribute("extent_max_y")) {
                layer.setMetaData(
                    "ows_extent",
                    layerElement.getAttribute("extent_min_x") + ", " +
                    layerElement.getAttribute("extent_min_y") + ", " +
                    layerElement.getAttribute("extent_max_x") + ", " +
                    layerElement.getAttribute("extent_max_y"));
            }
            //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("min_scale"));
                minScale =
                    Double.parseDouble(layerElement.getAttribute("max_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);
                layer.setTileitem("");
            }
            else if (type.equals("line")) {
                layer.setType(MS_LAYER_TYPE.MS_LAYER_LINE);
                layer.setTileitem("");
            }
            else if (type.equals("polygon")) {
                layer.setType(MS_LAYER_TYPE.MS_LAYER_POLYGON);
                layer.setTileitem("");
            }
            else if (type.equals("raster")) {
                layer.setType(MS_LAYER_TYPE.MS_LAYER_RASTER);
            }
            else if (type == "annotation") {
                layer.setType(MS_LAYER_TYPE.MS_LAYER_ANNOTATION);
            }

            //The layer datasource.
            String con_type = layerElement.getAttribute("connection_type");
            if(con_type.equals("local")) {
                // The data source is a local file. (.shp or Image)
                String datasource = "";
                if(layerElement.hasAttribute("workspace")) {
                    datasource = layerElement.getAttribute("workspace");
                    datasource += File.separator;
                }
                datasource += layerElement.getAttribute("data_source");
                datasource = datasource.replaceAll("\\\\", "/");
                layer.setData(datasource);
            }
            else if(con_type.equals("SDE") && !type.equals("raster")) {
                // The data source is a sde database.
                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");
                String database_auth = layerElement.getAttribute("database");
                if (database_auth.equals("") || database_auth == null) {
                    logger.warn("Could not set the database connection user." +
                                " Setting to \"sde\" as default.");
                    database_auth = "sde";
                }

                String port = layerElement.getAttribute("instance");
                StringBuffer strBuff = new StringBuffer();
                char c;

                for (int j = 0; j < port.length() ; j++) {
                    c = port.charAt(j);

                    if(Character.isDigit(c)) {
                        strBuff.append(c);
                    }
                }

                layer.setConnection(
                layerElement.getAttribute("server") + "," +
                    "port:" + strBuff.toString() + "," +
                database_auth + "," +
                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")) {
                    logger.info(
                        "The layer " +
                        layer.getName() +
                        " contains a jointable attribute." +
                        " Please verify the attribute parameters.");
                    String join = layerElement.getAttribute("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");
                    if (!prefix.isEmpty()) {
                        prefix += ".";
                    }
                    if(layerElement.hasAttribute("definition_query") &&
                       !layerElement.getAttribute("definition_query")
                                     .equals("")) {
                        layer.setFilter("where " +
                        layerElement.getAttribute("definition_query"));
                    }
                }
            }
            else if(con_type.equals("SDE") && type.equals("raster")) {
                // The data source is a sde database.
                logger.info(
                    "SDE datasource found." +
                    " Please edit password in mapfile.");
                String database_auth = layerElement.getAttribute("database");
                if (database_auth.equals("") || database_auth == null) {
                    logger.warn("Could not set the database connection user." +
                                " Setting to \"sde\" as default.");
                    database_auth = "sde";
                }

                String port = layerElement.getAttribute("instance");
                StringBuffer strBuff = new StringBuffer();
                char c;

                for (int j = 0; j < port.length() ; j++) {
                    c = port.charAt(j);
                    if(Character.isDigit(c)) {
                        strBuff.append(c);
                    }
                }

                layer.setData(
                    "SDE:" + layerElement.getAttribute("server") +
                    "," + strBuff +
                    "," + layerElement.getAttribute("database") +
                    "," + layerElement.getAttribute("user") +
                    ",<PASSWORD>," + layerElement.getAttribute("dataset"));
                layer.setType(MS_LAYER_TYPE.MS_LAYER_RASTER);
                if(layerElement.hasAttribute("definition_query") &&
                   !layerElement.getAttribute("definition_query").equals("")) {
                        layer.setFilter("where " +
                        layerElement.getAttribute("definition_query"));
                }
            } else if(con_type.equals("WMS")) {
                layer.setType(MS_LAYER_TYPE.MS_LAYER_RASTER);
                layer.setConnection(layerElement.getAttribute("connection"));
                layer.setConnectionType(MS_CONNECTION_TYPE.MS_WMS.swigValue(), "");
                layer.setMetaData("wms_name",
                    layerElement.getAttribute("wms_name"));
            } else if(con_type.equals("ogr")) {
                layer.setConnectionType(MS_CONNECTION_TYPE.MS_OGR.swigValue(), "");
                layer.setConnection(layerElement.getAttribute("connection"));
                layer.setData(layerElement.getAttribute("data_source"));
            }
            if(!type.equals("raster")) {
                layer.setTemplate("PleaseInsertAValidTemplateForGFI");
            }

            // Set Offsite value for raster layer
            if(type == "raster") {
                layer.setOffsite(new colorObj(255,255,255,-4));
            }

            // Set scaling properties for layer and add Processing
            if(type == "annotation") {
                if (mapNode.hasAttribute("referencescale")) {
                    layer.setSymbolscaledenom(Double.parseDouble(
                            mapNode.getAttribute("referencescale")));
                }
                layer.addProcessing("ITEMS=classId");
                layer.setClassitem("classId");
            }

            // Create labelitem
            NodeList labels = layerElement.getElementsByTagName("label");
            if(labels.getLength() > 0) {
                Element label = (Element)labels.item(0);
                String expr = label.getAttribute("expression");
                expr = expr.replaceAll("\\[", "");
                expr = expr.replaceAll("\\]", "");
                if (con_type == "ogr") {
                    // ogr expression fields come prefixed from arcgis
                    // the prefix has to be removed in order to work with
                    // mapserver
                    String unwantedPrefix = layerElement.getAttribute("data") + ".";
                    logger.debug("Removing expression Prefix: " + unwantedPrefix);
                    boolean isShapeFile = false;
                    if (layerElement.getAttribute("connection_type") == "local") {
                        isShapeFile = true;
                    }
                    expr = sanitizeAttribute(expr,
                                      unwantedPrefix, prefix, isShapeFile);
                }
                if(!prefix.equals("")) {
                    expr = prefix + "." + expr;
                }
                layer.setLabelitem(expr.trim());
            }

            //Write elements.
            writeFeatures(layer, layerElement);

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

    /**
     * Adds the elements (Features) to the layer.
     * @param layer        Mapscript layer object.
     * @param layerElement Dom element containing the feature attributes.
     */
    private void writeFeatures(layerObj layer, Element layerElement) {
        NodeList list = layerElement.getElementsByTagName("feature");
        for(int i = 0; i < list.getLength(); i++) {
            logger.debug("Writing an element");
            Element feature = (Element)list.item(i);
            pointObj poi = new pointObj(
                      Double.parseDouble(feature.getAttribute("X")),
                      Double.parseDouble(feature.getAttribute("Y")),
                      0.0, -2e38);
            lineObj line = new lineObj();
            line.add(poi);
            logger.debug("Set the line");

            shapeObj shape = new shapeObj(MS_SHAPE_TYPE.MS_SHAPE_POINT.swigValue());
            shape.add(line);
            shape.setText(feature.getAttribute("text"));

            shape.initValues(1);
            shape.setValue(0, feature.getAttribute("classId"));

            // Write the Style / Symbol for each element as a single class
            // TODO build a hash of the style/symbol and check if classes can be
            // grouped

            classObj co = new classObj(layer);
            writeLabel(co, feature, layerElement.getAttribute("type"));
            co.setExpression("\"" + feature.getAttribute("classId") + "\"");
            LabelStyleWriter swriter = new LabelStyleWriter (this.map, co);
            swriter.write((Element)feature.getFirstChild());
            layer.addFeature(shape);
        }
    }

    /**
     * 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");
            name = msutils.replaceUmlauts(name);
            if (name.equals("")) {
                name = layerElement.getAttribute("name");
                name = msutils.replaceUmlauts(name);
                if (list.getLength() > 1) {
                    name += "-" + i;
                }
            }
            co.setName (name);

            //Create label object.
            NodeList labels = layerElement.getElementsByTagName("label");
            if(labels.getLength() > 0) {
                Element labelElement = (Element)labels.item(0);
                String  layerType = layerElement.getAttribute("type");
                writeLabel(co, labelElement, layerType);
            }

            //Create definition expression.
            if(classElement.hasAttribute("field_count")) {
                String unwantedPrefix = layerElement.getAttribute("data") + ".";
                boolean isShapeFile = false;
                if (layerElement.getAttribute("connection_type") == "local") {
                    isShapeFile = true;
                }
                co.setExpression(createExpression(classElement, i, unwantedPrefix, isShapeFile));
            }

            //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);
                }
            }
        }
    }

    /**
     * Create a label object in a class object.
     *
     * @param co Class object.
     * @param labelElement DOM element containing label attributes.
     * @param layertype The layer type. Used to define the label position.
     */
    private void writeLabel(
        classObj co,
        Element labelElement,
        String layerType) {

        //Get the label object. Each class has a predefined labelobject.
        labelObj label = co.getLabel();

        //Get the label text symbol attributes from DOM.
        Element symbol = (Element)labelElement.getFirstChild();
        if(symbol != null && symbol.getTagName().equals("symbol")) {
            String type = symbol.getAttribute("type");
            if(type.equals("text")) {
                label.setType(MS_FONT_TYPE.MS_TRUETYPE);
            }
            label.setSize(Double.parseDouble(symbol.getAttribute("size")));

            if(symbol.hasAttribute("color")) {
                String c = symbol.getAttribute("color");
                Color col = Color.decode(c);
                colorObj color = new colorObj(
                    col.getRed(),
                    col.getGreen(),
                    col.getBlue(),
                    -4);
                label.setColor(color);
            }
            if(symbol.hasAttribute("font")) {
                String font = symbol.getAttribute("font");
                fontSetObj fso = this.map.getFontset();
                hashTableObj fonts = fso.getFonts();
                String mapFont = fonts.get(font,"");
                if(mapFont != null && !mapFont.equals("")) {
                    label.setFont(font);
                }
                else {
                    logger.info(
                        "Could not find font " + font + " in font set. " +
                        "Using FreeSans for labels.");
                        label.setFont("FreeSans");
                }
            }

            if(labelElement.hasAttribute("max_scale")) {
                double min =
                    Double.parseDouble(labelElement.getAttribute("max_scale"));
                if(min > 0) {
                    label.setMinscaledenom(min);
                }
            }
            if(labelElement.hasAttribute("min_scale")) {
                double max =
                    Double.parseDouble(labelElement.getAttribute("min_scale"));
                if(max > 0) {
                    label.setMaxscaledenom(max);
                }
            }

            //Set the label position.
            if(layerType.equals("point")) {
                label.setPosition(MS_POSITIONS_ENUM.MS_UC.swigValue());
            }

            //Set annotation specific values
            if (layerType == "annotation") {
                label.setPosition(MS_POSITIONS_ENUM.MS_CC.swigValue());
                label.setOffsetx(2);
                label.setOffsety(-2);
            }

        }
    }

    /** Sanitze an attribute
     *
     * Fixes invalid Field names and/or adds and removes a prefix
     *
     * @param attribute The Attribute to sanitize
     * @param prefixToRemove A Prefix that should be removed (empty otherwise)
     * @param prefixToAdd A Prefix that should be added (empty otherwise)
     * @param enforceShpLimit True if the attribute should follow shapefile
     * format restrictions.
     */
    private String sanitizeAttribute(String attribute, String prefixToRemove,
                                     String prefixToAdd, boolean enforceShpLimit) {
        if (enforceShpLimit) {
            /* Workaround for non standard conform shapefile implementations
             * like the one used by ArcGis that appends the field type after the
             * eleventh character. Although the standard actually defines 10
             * as the maximum length of Field Names GDAL handles the case where
             * the terminating 0 is actually a Character allowing for Field
             * names of up to 11 characters.
             */
            if (attribute.length() > 10) {
                // Just remove the Type Delimiter
                if (attribute.endsWith("C") ||
                    attribute.endsWith("D") ||
                    attribute.endsWith("N") ||
                    attribute.endsWith("L") ||
                    attribute.endsWith("M")) {
                        attribute = attribute.substring(0, attribute.length() - 1);
                    }
            }
        }
        if (!prefixToRemove.isEmpty() && attribute.startsWith(prefixToRemove)) {
            attribute = attribute.replace(prefixToRemove, "");
        }
        if (!prefixToAdd.isEmpty() && !attribute.startsWith(prefixToAdd)) {
            attribute = prefixToAdd + attribute;
        }
        return attribute;
    }

    /**
     * Create definition expression.
     *
     * @param ce DOM elementcontaining the class expression information.
     * @param index Index to determine the correct expression operator.
     * @param prefixToRemove A string that will be removed from the start of
     * expression fields.
     * @param isShapeFile true if shapefile attribute limits should be enforced
     */
    private String createExpression(Element ce, int index, String prefixToRemove,
            boolean isShapeFile) {
        String expression = "(";
        int count = 0;
        try {
            count = Integer.parseInt(ce.getAttribute("field_count"));
        }
        catch(NumberFormatException nfe) {
            return "";
        }

        if(count == 1) {
           //Create single field expression.
           try {
                //If no exception is thrown, the expression value is a number.
                Double.parseDouble(ce.getAttribute("value"));
                expression += "[" + 
                    sanitizeAttribute(ce.getAttribute("expression_field_0"),
                                      prefixToRemove, prefix, isShapeFile) + "]";
                if(ce.hasAttribute("min_value")) {
                    if(index == 0) {
                        expression += " >= " + ce.getAttribute("min_value");
                    }
                    else {
                        expression += " > " + ce.getAttribute("min_value");
                    }
                    expression += " AND [" + 
                    sanitizeAttribute(ce.getAttribute("expression_field_0"),
                                      prefixToRemove, prefix, isShapeFile) + "]";
                    expression += "]";
                }
                expression += " " + ce.getAttribute("expression_operator");
                expression += " " + ce.getAttribute("value") + ")";
            }
            catch(NumberFormatException nfe) {
                //The expression value is a strings.
                expression += "\"[";
                expression += sanitizeAttribute(ce.getAttribute("expression_field_0"),
                                      prefixToRemove, prefix, isShapeFile) + "]\"";
                expression += " " + ce.getAttribute("expression_operator");
                expression += " \"" + ce.getAttribute("value") + "\")";
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
        else {
            //Create a multi field expression.
            for (int i = 0; i < count; i++) {
                try {
                    //If no exception is thrown, the expression values are
                    //numbers.
                    Double.parseDouble(ce.getAttribute("value_" + i));
                    expression += "[";
                    expression += sanitizeAttribute(ce.getAttribute("expression_field_" + i),
                                      prefixToRemove, prefix, isShapeFile);
                    expression += "]";
                    expression += " " + ce.getAttribute("expression_operator");
                    expression += " " + ce.getAttribute("value_" + i);
                    if (i < count - 1) {
                        expression += " AND ";
                    }
                    else {
                        expression += ")";
                    }
                }
                catch (NumberFormatException nfe) {
                    //The expression values are strings.
                    expression += "\"[";
                    expression += sanitizeAttribute(ce.getAttribute("expression_field_" + i),
                                      prefixToRemove, prefix, isShapeFile);
                    expression += "]\"";
                    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)