rrenkert@41: package de.intevation.mxd.writer;
rrenkert@41:
rrenkert@41: import org.apache.log4j.Logger;
rrenkert@41:
rrenkert@41: import org.w3c.dom.Document;
rrenkert@41: import org.w3c.dom.Element;
rrenkert@41: import org.w3c.dom.NodeList;
rrenkert@42:
rrenkert@98: import java.io.File;
rrenkert@98:
rrenkert@41: import javax.xml.xpath.XPathConstants;
rrenkert@41:
rrenkert@41: import edu.umn.gis.mapscript.mapObj;
rrenkert@41: import edu.umn.gis.mapscript.layerObj;
rrenkert@42: import edu.umn.gis.mapscript.classObj;
rrenkert@42:
rrenkert@41: import edu.umn.gis.mapscript.MS_UNITS;
rrenkert@42: import edu.umn.gis.mapscript.MS_LAYER_TYPE;
vc11884admin@130: import edu.umn.gis.mapscript.MS_CONNECTION_TYPE;
rrenkert@41:
rrenkert@41: import de.intevation.mxd.utils.XMLUtils;
rrenkert@41:
rrenkert@41: /**
rrenkert@43: * The Mapfile Writer.
rrenkert@43: * This Writer uses the MapScript Java API to create Mapfiles from a DOM.
rrenkert@41: *
rrenkert@41: * @author Raimund Renkert
rrenkert@41: */
rrenkert@41: public class MapScriptWriter
rrenkert@41: implements IWriter
rrenkert@41: {
rrenkert@43: /**
rrenkert@43: * The Logger.
rrenkert@43: */
rrenkert@43: private static final Logger logger = Logger.getLogger(MapScriptWriter.class);
rrenkert@43:
rrenkert@43: /**
rrenkert@43: * Private member.
rrenkert@43: */
rrenkert@41: private Document root;
rrenkert@41: private mapObj map;
rrenkert@55: private String mapFilename;
vc11884admin@130: private String MS_BINDIR = "c:/ms_6.1-dev/bin";
rrenkert@41:
rrenkert@41: public MapScriptWriter() {
rrenkert@55: map = new mapObj("");
rrenkert@55: mapFilename = "";
rrenkert@41: }
rrenkert@41:
rrenkert@55: public MapScriptWriter(String templ, String filename) {
rrenkert@55: map = new mapObj(templ);
rrenkert@55: mapFilename = filename;
rrenkert@41: }
rrenkert@41:
rrenkert@43: /**
rrenkert@43: * Write the mapfile.
rrenkert@43: * @param doc The root document containin the map attributes.
rrenkert@43: *
rrenkert@43: * @return Currently always true.
rrenkert@43: */
rrenkert@120: public boolean write(Document doc) {
rrenkert@41: logger.debug("write()");
rrenkert@41: this.root = doc;
rrenkert@41:
rrenkert@41: //Get the filename.
rrenkert@41: Element fileNode = (Element)XMLUtils.xpath(
rrenkert@41: root,
rrenkert@41: "/mxd/file",
rrenkert@41: XPathConstants.NODE);
rrenkert@41: //Write the map attributes.
rrenkert@41: writeMap();
rrenkert@42: //Write the layers.
rrenkert@42: writeLayer();
rrenkert@41: //Save the map.
rrenkert@42: mapObj cloneMap = map.cloneMap();
rrenkert@55: cloneMap.save(mapFilename);
rrenkert@120: logger.info("Mapfile successfully created.");
rrenkert@41: return true;
rrenkert@41: }
rrenkert@41:
rrenkert@43: /**
rrenkert@43: * Create the map object and set the attributes.
rrenkert@43: */
rrenkert@41: private void writeMap() {
rrenkert@41: logger.debug("writeMap()");
rrenkert@41: //Get the map.
rrenkert@41: Element mapNode = (Element)XMLUtils.xpath(
rrenkert@41: root,
rrenkert@41: "/mxd/map",
rrenkert@41: XPathConstants.NODE);
rrenkert@41:
rrenkert@41: //Set the name.
rrenkert@41: map.setName(mapNode.getAttribute("name"));
rrenkert@42: map.setMetaData("wms_title", mapNode.getAttribute("name"));
rrenkert@41: //Set the extent.
rrenkert@41: map.setExtent(
rrenkert@41: Double.parseDouble(mapNode.getAttribute("extent_min_x")),
rrenkert@41: Double.parseDouble(mapNode.getAttribute("extent_min_y")),
rrenkert@41: Double.parseDouble(mapNode.getAttribute("extent_max_x")),
rrenkert@41: Double.parseDouble(mapNode.getAttribute("extent_max_y")));
rrenkert@41:
rrenkert@41: //Set the units.
rrenkert@41: String units = mapNode.getAttribute("units");
rrenkert@41: MS_UNITS msu;
rrenkert@41: if(units.equals("feet")) {
rrenkert@41: msu = MS_UNITS.MS_FEET;
rrenkert@41: }
rrenkert@41: else if(units.equals("inches")) {
rrenkert@41: msu = MS_UNITS.MS_INCHES;
rrenkert@41: }
rrenkert@41: else if(units.equals("kilometers")) {
rrenkert@41: msu = MS_UNITS.MS_KILOMETERS;
rrenkert@41: }
rrenkert@41: else if(units.equals("meters")) {
rrenkert@41: msu = MS_UNITS.MS_METERS;
rrenkert@41: }
rrenkert@41: else if(units.equals("miles")) {
rrenkert@41: msu = MS_UNITS.MS_MILES;
rrenkert@41: }
rrenkert@41: else if(units.equals("nauticalmiles")) {
rrenkert@41: msu = MS_UNITS.MS_NAUTICALMILES;
rrenkert@41: }
rrenkert@41: else if(units.equals("points")) {
rrenkert@41: msu = MS_UNITS.MS_PIXELS;
rrenkert@41: }
rrenkert@41: else {
rrenkert@57: msu = MS_UNITS.MS_METERS;
rrenkert@41: }
rrenkert@41: map.setUnits(msu);
rrenkert@41:
rrenkert@41: //TODO: Find out whats the correct scale value.
rrenkert@41: //map.setScaledenom(Double.parseDouble(mapNode.getAttribute("scale")));
rrenkert@41: }
rrenkert@41:
rrenkert@43: /**
rrenkert@43: * Create layer objects and set the attributes.
rrenkert@43: */
rrenkert@120: private void writeLayer() {
rrenkert@42: logger.debug("writeLayer()");
rrenkert@42: Element mapNode = (Element)XMLUtils.xpath(
rrenkert@42: root,
rrenkert@42: "/mxd/map",
rrenkert@42: XPathConstants.NODE);
rrenkert@42: NodeList list = mapNode.getElementsByTagName("layer");
rrenkert@42: for(int i = 0; i < list.getLength(); i++) {
rrenkert@42: Element layerElement = (Element)list.item(i);
rrenkert@42: layerObj layer = new layerObj(map);
rrenkert@42:
rrenkert@42: //The layer name.
vc11884admin@132: String lname = layerElement.getAttribute("name");
vc11884admin@132: lname = lname.replaceAll(" ", "");
vc11884admin@132: layer.setName(lname);
rrenkert@128: layer.setMetaData("wms_title", layerElement.getAttribute("name"));
rrenkert@42:
rrenkert@42: //The layer status.
rrenkert@42: String stat = layerElement.getAttribute("status");
rrenkert@42: if (stat.equals("on")) {
rrenkert@42: layer.setStatus(1);
rrenkert@42: }
rrenkert@42: else {
rrenkert@42: layer.setStatus(0);
rrenkert@42: }
rrenkert@42:
rrenkert@42: //The scale.
rrenkert@42: double maxScale =
rrenkert@42: Double.parseDouble(layerElement.getAttribute("max_scale"));
rrenkert@42: double minScale =
rrenkert@42: Double.parseDouble(layerElement.getAttribute("min_scale"));
rrenkert@42: layer.setMaxscaledenom(maxScale);
rrenkert@42: layer.setMinscaledenom(minScale);
rrenkert@42:
rrenkert@42: //The layer type.
rrenkert@42: String type = layerElement.getAttribute("type");
rrenkert@42: if(type.equals("point")) {
rrenkert@42: layer.setType(MS_LAYER_TYPE.MS_LAYER_POINT);
rrenkert@42: }
rrenkert@62: else if (type.equals("line")) {
rrenkert@62: layer.setType(MS_LAYER_TYPE.MS_LAYER_LINE);
rrenkert@62: }
rrenkert@97: else if (type.equals("polygon")) {
rrenkert@97: layer.setType(MS_LAYER_TYPE.MS_LAYER_POLYGON);
rrenkert@97: }
rrenkert@102: layer.setTileitem("");
rrenkert@42:
rrenkert@42: //The layer datasource.
vc11884admin@130: String con_type = layerElement.getAttribute("connection_type");
vc11884admin@130: if(con_type.equals("local")) {
vc11884admin@130: String datasource = "";
vc11884admin@130: if(layerElement.hasAttribute("workspace")) {
vc11884admin@130: datasource = layerElement.getAttribute("workspace");
vc11884admin@130: datasource += File.separator;
vc11884admin@130: }
vc11884admin@130: datasource += layerElement.getAttribute("data_source");
vc11884admin@130: layer.setData(datasource);
vc11884admin@130: }
vc11884admin@130: else if(con_type.equals("SDE")) {
vc11884admin@130: logger.info(
vc11884admin@130: "SDE datasource found." +
vc11884admin@130: " Please edit password in mapfile.");
vc11884admin@130: layer.setConnectionType(
vc11884admin@130: MS_CONNECTION_TYPE.MS_PLUGIN.swigValue(),
vc11884admin@130: MS_BINDIR + "/ms/plugins/msplugin_sde_93.dll");
vc11884admin@130: layer.setConnection(
vc11884admin@130: layerElement.getAttribute("server") + "," +
vc11884admin@130: "port:" + layerElement.getAttribute("instance") + "," +
vc11884admin@130: layerElement.getAttribute("database") + "," +
vc11884admin@130: layerElement.getAttribute("user") + ",");
vc11884admin@130: layer.setData(
vc11884admin@130: layerElement.getAttribute("data_source") +
vc11884admin@130: ",SHAPE," +
vc11884admin@130: layerElement.getAttribute("version"));
vc11884admin@130: layer.setProcessing("CLOSE_CONNECTION=defer");
vc11884admin@130: layer.setProcessing("ATTRIBUTE_QUALIFIED=TRUE");
vc11884admin@130: layer.setProcessing(
vc11884admin@130: "JOINTABLE=" +
vc11884admin@130: layerElement.getAttribute("join_table"));
vc11884admin@130: layer.setFilter(
vc11884admin@130: "where " +
vc11884admin@130: layerElement.getAttribute("definition_query") +
vc11884admin@130: " AND " +
vc11884admin@130: layerElement.getAttribute("join_table_target") + "." +
vc11884admin@130: layerElement.getAttribute("join_field_target") + "=" +
vc11884admin@130: layerElement.getAttribute("join_table") + "." +
vc11884admin@130: layerElement.getAttribute("join_field"));
rrenkert@42:
vc11884admin@130: }
rrenkert@129: layer.setTemplate("PleaseInsertAValidTemplateForGFI");
rrenkert@42: //Write classes.
rrenkert@42: writeClass(layer, layerElement);
rrenkert@42: }
rrenkert@41:
rrenkert@41: }
rrenkert@41:
rrenkert@42: /**
rrenkert@42: * Adds the classes to the layer.
rrenkert@42: * @param layer Mapscript layer object.
rrenkert@42: * @param layerElement Dom element containing the class attributes.
rrenkert@42: */
rrenkert@120: private void writeClass(layerObj layer, Element layerElement) {
rrenkert@87: logger.debug("writeClass(layerObj, Element)");
rrenkert@42: //Get all renderer elements (renderer in arcgis equals class in the
rrenkert@42: //mapfile.)
rrenkert@42: NodeList list = layerElement.getElementsByTagName("renderer");
rrenkert@41:
rrenkert@42: //Create all found class objects and write the symbols and styles for
rrenkert@42: //each class.
rrenkert@42: for(int i = 0; i < list.getLength(); i++) {
rrenkert@42: Element classElement = (Element)list.item(i);
rrenkert@42: classObj co = new classObj(layer);
rrenkert@124: String name = classElement.getAttribute("label");
rrenkert@99: if (name.equals("")) {
rrenkert@99: name = layerElement.getAttribute("name");
rrenkert@99: if (list.getLength() > 1) {
rrenkert@99: name += "-" + i;
rrenkert@99: }
rrenkert@99: }
rrenkert@99: co.setName (name);
rrenkert@44: if(classElement.hasAttribute("field_count")) {
rrenkert@44: int count =
rrenkert@44: Integer.parseInt(classElement.getAttribute("field_count"));
rrenkert@126: int type = 0;
rrenkert@126: try {
rrenkert@126: Double.parseDouble(classElement.getAttribute("value"));
rrenkert@126: type = 1;
rrenkert@44: }
rrenkert@126: catch(Exception e) {
rrenkert@126: type = 2;
rrenkert@126: }
rrenkert@126: if (type == 1) {
rrenkert@126: co.setExpression(createDoubleExpression(classElement, count));
rrenkert@126: }
rrenkert@127: else if (type == 2) {
rrenkert@127: co.setExpression(createStringExpression(classElement, count));
rrenkert@127: }
rrenkert@127:
rrenkert@44: }
rrenkert@42: //Write symbols and styles.
rrenkert@97: NodeList l = classElement.getChildNodes();
rrenkert@97: for (int j = 0; j < l.getLength(); j++) {
rrenkert@97: Element elem = (Element)l.item(j);
rrenkert@97:
rrenkert@97: String type = layerElement.getAttribute("type");
rrenkert@97: if(type.equals("point") && elem.getTagName().equals("symbol")) {
rrenkert@87: MarkerStyleWriter swriter = new MarkerStyleWriter (this.map, co);
rrenkert@97: swriter.write (elem);
rrenkert@87: }
rrenkert@97: else if(type.equals("line") && elem.getTagName().equals("symbol")) {
rrenkert@95: LineStyleWriter swriter = new LineStyleWriter (this.map, co);
rrenkert@97: swriter.write (elem);
rrenkert@97: }
rrenkert@97: else if(type.equals("polygon") && elem.getTagName().equals("symbol")) {
rrenkert@97: FillStyleWriter swriter = new FillStyleWriter (this.map, co);
rrenkert@97: swriter.write (elem);
rrenkert@87: }
rrenkert@87: }
rrenkert@42: }
rrenkert@41: }
rrenkert@126:
rrenkert@126: private String createDoubleExpression (Element classElement, int count) {
rrenkert@126: String exp = "";
rrenkert@126: String op = classElement.getAttribute("expression_operator");
rrenkert@126: String op1 = "";
rrenkert@126: String op2 = "";
rrenkert@126: if (op.equals("<=")) {
rrenkert@126: op1 = ">=";
rrenkert@126: op2 = op;
rrenkert@126: for(int j = 0; j < count; j++) {
rrenkert@126: if (classElement.getAttribute("min_value").equals(
rrenkert@126: classElement.getAttribute("value"))) {
rrenkert@126: exp = "([" +
rrenkert@126: classElement.getAttribute(
rrenkert@126: "expression_field_" + j) +
rrenkert@126: "] == " +
rrenkert@126: classElement.getAttribute("value") +
rrenkert@126: ")";
rrenkert@126: }
rrenkert@126: else {
rrenkert@126: exp = "([";
rrenkert@126: exp += classElement.getAttribute(
rrenkert@126: "expression_field_" + j);
rrenkert@126: exp += "] " + op1;
rrenkert@126: exp += " " + classElement.getAttribute("min_value");
rrenkert@126: exp += " AND [" + classElement.getAttribute(
rrenkert@126: "expression_field_" + j);
rrenkert@126: exp += "] " + op2 + " ";
rrenkert@126: exp += classElement.getAttribute("value");
rrenkert@126: exp += ")";
rrenkert@126: }
rrenkert@126: }
rrenkert@126: }
rrenkert@127: else if (op.equals("=")) {
rrenkert@126: op1 = op;
rrenkert@126: for(int j = 0; j < count; j++) {
rrenkert@126: exp = "([" +
rrenkert@126: classElement.getAttribute("expression_field_" + j) +
rrenkert@126: "] == " +
rrenkert@126: classElement.getAttribute("value") + ")";
rrenkert@126: }
rrenkert@126: }
rrenkert@126: return exp;
rrenkert@126: }
rrenkert@127:
rrenkert@127: private String createStringExpression (Element classElement, int count) {
rrenkert@127: String exp = "";
rrenkert@127: String op = classElement.getAttribute("expression_operator");
rrenkert@127: if (op.equals("=")) {
rrenkert@127: for(int j = 0; j < count; j++) {
rrenkert@127: exp = "(\"[";
rrenkert@127: exp += classElement.getAttribute(
rrenkert@127: "expression_field_" + j);
rrenkert@127: exp += "]\" " + op;
rrenkert@127: exp += " \"" + classElement.getAttribute("value");
rrenkert@127: exp += "\")";
rrenkert@127: }
rrenkert@127: }
rrenkert@127: return exp;
rrenkert@127: }
rrenkert@41: }
rrenkert@41: