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"; vc11884admin@134: private String prefix = ""; vc11884admin@170: private MS_UNITS units = MS_UNITS.MS_METERS; 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) { raimund@174: String path = System.getProperty("user.dir"); rrenkert@55: map = new mapObj(templ); raimund@174: File f = new File(filename); raimund@174: mapFilename = filename; raimund@174: if(f.isAbsolute()) { raimund@174: map.setMappath(mapFilename); raimund@174: } raimund@174: else { raimund@174: map.setMappath( raimund@174: System.getProperty("user.dir") + raimund@174: File.separator + raimund@174: mapFilename); raimund@174: mapFilename = System.getProperty("user.dir") + raimund@174: File.separator + raimund@174: mapFilename; raimund@175: } raimund@175: String fontSetPath = map.getFontset().getFilename(); raimund@175: File fonts = new File(fontSetPath); raimund@175: String fontSet = fonts.getAbsolutePath(); raimund@175: fontSet = fontSet.replaceAll("\\\\", "/"); raimund@175: map.setFontSet(fontSet); 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(); raimund@174: raimund@174: cloneMap.save(mapFilename); raimund@174: logger.info("Mapfile created: " + mapFilename); 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: vc11884admin@172: //Set the units and projection. vc11884admin@172: int proj = Integer.parseInt(mapNode.getAttribute("projection")); vc11884admin@172: if(proj != 0) { vc11884admin@172: map.setProjection("epsg:" + mapNode.getAttribute("projection")); vc11884admin@172: } vc11884admin@170: String u = mapNode.getAttribute("units"); vc11884admin@170: if(u.equals("feet")) { vc11884admin@170: units = MS_UNITS.MS_FEET; rrenkert@41: } vc11884admin@170: else if(u.equals("inches")) { vc11884admin@170: units = MS_UNITS.MS_INCHES; rrenkert@41: } vc11884admin@170: else if(u.equals("kilometers")) { vc11884admin@170: units = MS_UNITS.MS_KILOMETERS; rrenkert@41: } vc11884admin@170: else if(u.equals("meters")) { vc11884admin@170: units = MS_UNITS.MS_METERS; rrenkert@41: } vc11884admin@170: else if(u.equals("miles")) { vc11884admin@170: units = MS_UNITS.MS_MILES; vc11884admin@170: } vc11884admin@170: else if(u.equals("nauticalmiles")) { vc11884admin@170: units = MS_UNITS.MS_NAUTICALMILES; vc11884admin@170: } vc11884admin@170: else if(u.equals("points")) { vc11884admin@170: units = MS_UNITS.MS_PIXELS; vc11884admin@170: } vc11884admin@170: else if(u.equals("degree")) { vc11884admin@170: units = MS_UNITS.MS_DD; vc11884admin@170: } rrenkert@41: else { vc11884admin@170: units = MS_UNITS.MS_METERS; rrenkert@41: } vc11884admin@170: map.setUnits(units); 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. rrenkert@137: String lname = layerElement.getAttribute("name"); rrenkert@137: lname = lname.replaceAll(" ", ""); vc11884admin@132: layer.setName(lname); vc11884admin@170: layer.setUnits(units.swigValue()); rrenkert@128: layer.setMetaData("wms_title", layerElement.getAttribute("name")); vc11884admin@148: if(layerElement.hasAttribute("group")) { vc11884admin@148: layer.setGroup(layerElement.getAttribute("group")); vc11884admin@148: } 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@145: double maxScale = 0; rrenkert@145: double minScale = 0; rrenkert@145: try { rrenkert@145: maxScale = vc11884admin@153: Double.parseDouble(layerElement.getAttribute("min_scale")); vc11884admin@153: minScale = rrenkert@145: Double.parseDouble(layerElement.getAttribute("max_scale")); rrenkert@145: } rrenkert@145: catch(NumberFormatException nfe) { rrenkert@145: logger.warn("Error setting scale."); rrenkert@145: maxScale = 0; rrenkert@145: minScale = 0; rrenkert@145: } 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. rrenkert@137: String con_type = layerElement.getAttribute("connection_type"); vc11884admin@134: 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"); raimund@175: datasource = datasource.replaceAll("\\\\", "/"); vc11884admin@130: layer.setData(datasource); rrenkert@137: } rrenkert@137: else if(con_type.equals("SDE")) { rrenkert@137: logger.info( rrenkert@137: "SDE datasource found." + rrenkert@137: " Please edit password in mapfile."); rrenkert@137: layer.setConnectionType( rrenkert@137: MS_CONNECTION_TYPE.MS_PLUGIN.swigValue(), rrenkert@137: MS_BINDIR + "/ms/plugins/msplugin_sde_93.dll"); vc11884admin@130: layer.setConnection( rrenkert@137: layerElement.getAttribute("server") + "," + rrenkert@137: "port:" + layerElement.getAttribute("instance") + "," + rrenkert@137: layerElement.getAttribute("database") + "," + rrenkert@137: layerElement.getAttribute("user") + ","); rrenkert@137: layer.setData( rrenkert@137: layerElement.getAttribute("data_source") + rrenkert@137: ",SHAPE," + rrenkert@137: layerElement.getAttribute("version")); rrenkert@137: layer.setProcessing("CLOSE_CONNECTION=defer"); vc11884admin@134: layer.setProcessing("ATTRIBUTE_QUALIFIED=TRUE"); rrenkert@137: if(layerElement.hasAttribute("join_table")) { vc11884admin@134: layer.setProcessing( rrenkert@137: "JOINTABLE=" + rrenkert@137: layerElement.getAttribute("join_table")); vc11884admin@134: layer.setFilter( vc11884admin@134: "where " + vc11884admin@134: layerElement.getAttribute("definition_query") + vc11884admin@134: " AND " + vc11884admin@134: layerElement.getAttribute("join_table_target") + "." + vc11884admin@134: layerElement.getAttribute("join_field_target") + "=" + vc11884admin@134: layerElement.getAttribute("join_table") + "." + vc11884admin@134: layerElement.getAttribute("join_field")); rrenkert@137: } rrenkert@137: else { rrenkert@137: prefix = layerElement.getAttribute("data_source"); vc11884admin@169: if(layerElement.hasAttribute("definition_query") && vc11884admin@169: !layerElement.getAttribute("definition_query").equals("")) { vc11884admin@169: layer.setFilter("where " + vc11884admin@169: layerElement.getAttribute("definition_query")); vc11884admin@169: } rrenkert@137: } vc11884admin@169: rrenkert@137: } 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")) { vc11884admin@152: co.setExpression(createExpression(classElement, i)); rrenkert@44: } rrenkert@42: //Write symbols and styles. rrenkert@97: NodeList l = classElement.getChildNodes(); vc11884admin@141: for (int j = l.getLength() - 1; j >= 0; 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: vc11884admin@134: vc11884admin@152: private String createExpression(Element ce, int index) { rrenkert@137: String expression = "("; rrenkert@137: int count = 0; rrenkert@137: try { rrenkert@137: count = Integer.parseInt(ce.getAttribute("field_count")); rrenkert@137: } rrenkert@137: catch(NumberFormatException nfe) { rrenkert@137: return ""; rrenkert@137: } rrenkert@137: if(count == 1) { vc11884admin@134: try { vc11884admin@134: Double.parseDouble(ce.getAttribute("value")); rrenkert@137: String exp = ce.getAttribute("expression_field_0"); rrenkert@137: String pre = ""; rrenkert@137: if (!prefix.equals("") && !exp.startsWith(prefix)) { vc11884admin@134: pre = prefix + "."; rrenkert@137: } rrenkert@137: expression += "[" + pre; rrenkert@137: expression += ce.getAttribute("expression_field_0") + "]"; rrenkert@137: if(ce.hasAttribute("min_value")) { vc11884admin@152: if(index == 0) { vc11884admin@152: expression += " >= " + ce.getAttribute("min_value"); vc11884admin@152: } vc11884admin@152: else { vc11884admin@152: expression += " > " + ce.getAttribute("min_value"); vc11884admin@152: } vc11884admin@169: expression += " AND [" + pre; rrenkert@137: expression += ce.getAttribute("expression_field_0")+ "]"; rrenkert@137: } rrenkert@137: expression += " " + ce.getAttribute("expression_operator"); rrenkert@137: expression += " " + ce.getAttribute("value") + ")"; rrenkert@137: } rrenkert@137: catch(NumberFormatException nfe) { rrenkert@137: String exp = ce.getAttribute("expression_field_0"); rrenkert@137: String pre = ""; rrenkert@137: if (!prefix.equals("") && !exp.startsWith(prefix)) { vc11884admin@134: pre = prefix + "."; rrenkert@137: } rrenkert@137: expression += "\"[" + pre; rrenkert@137: expression += ce.getAttribute("expression_field_0") + "]\""; rrenkert@137: expression += " " + ce.getAttribute("expression_operator"); rrenkert@137: expression += " \"" + ce.getAttribute("value") + "\")"; rrenkert@137: } rrenkert@137: catch(Exception e) { rrenkert@137: e.printStackTrace(); rrenkert@137: } rrenkert@137: } rrenkert@137: else { vc11884admin@134: for (int i = 0; i < count; i++) { vc11884admin@134: try { vc11884admin@134: Double.parseDouble(ce.getAttribute("value_" + i)); vc11884admin@134: String exp = ce.getAttribute("expression_field_" + i); vc11884admin@134: String pre = ""; vc11884admin@134: if (!prefix.equals("") && !exp.startsWith(prefix)) { vc11884admin@134: pre = prefix + "."; vc11884admin@134: } vc11884admin@134: expression += "[" + pre; vc11884admin@134: expression += ce.getAttribute("expression_field_" + i) + "]"; vc11884admin@134: expression += " " + ce.getAttribute("expression_operator"); vc11884admin@134: expression += " " + ce.getAttribute("value_" + i); rrenkert@137: if (i < count - 1) { rrenkert@137: expression += " AND "; rrenkert@137: } rrenkert@137: else { rrenkert@137: expression += ")"; rrenkert@137: } rrenkert@137: } rrenkert@137: catch (NumberFormatException nfe) { rrenkert@137: String exp = ce.getAttribute("expression_field_" + i); vc11884admin@134: String pre = ""; vc11884admin@134: if (!prefix.equals("") && !exp.startsWith(prefix)) { vc11884admin@134: pre = prefix + "."; vc11884admin@134: } vc11884admin@134: expression += "\"[" + pre; vc11884admin@134: expression += ce.getAttribute("expression_field_" + i) + "]\""; vc11884admin@134: expression += " " + ce.getAttribute("expression_operator"); vc11884admin@134: expression += " " + ce.getAttribute("value_" + i); rrenkert@137: if (i < count - 1) { rrenkert@137: expression += " AND "; rrenkert@137: } rrenkert@137: else { rrenkert@137: expression += ")"; rrenkert@137: } rrenkert@126: } rrenkert@126: } rrenkert@126: } rrenkert@137: return expression; rrenkert@127: } rrenkert@41: } rrenkert@41: