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; 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; 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. rrenkert@42: layer.setName(layerElement.getAttribute("name")); 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. rrenkert@98: String datasource = ""; rrenkert@98: if(layerElement.hasAttribute("workspace")) { rrenkert@98: datasource = layerElement.getAttribute("workspace"); rrenkert@98: datasource += File.separator; rrenkert@98: } rrenkert@98: datasource += layerElement.getAttribute("data_source"); rrenkert@98: layer.setData(datasource); rrenkert@42: 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: