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@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@87: public boolean write(Document doc) rrenkert@87: throws Exception { 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@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@87: private void writeLayer() rrenkert@87: throws Exception { 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@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@42: rrenkert@42: //The layer datasource. rrenkert@42: layer.setData(layerElement.getAttribute("data_source")); rrenkert@42: 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@87: private void writeClass(layerObj layer, Element layerElement) rrenkert@87: throws Exception { 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@42: co.setName(classElement.getAttribute("name")); rrenkert@44: if(classElement.hasAttribute("field_count")) { rrenkert@44: int count = rrenkert@44: Integer.parseInt(classElement.getAttribute("field_count")); rrenkert@44: String exp = ""; rrenkert@44: for(int j = 0; j < count; j++) { rrenkert@44: //TODO Find a way to create Expressions. rrenkert@44: exp = "([" + classElement.getAttribute("expression_field_" + j); rrenkert@46: exp += "] " + classElement.getAttribute("expression_operator"); rrenkert@46: exp += " " + classElement.getAttribute("value") + ")"; rrenkert@44: } rrenkert@44: co.setExpression(exp); rrenkert@44: } rrenkert@42: //Write symbols and styles. rrenkert@87: NodeList slist = classElement.getElementsByTagName("symbol"); rrenkert@87: String type = layerElement.getAttribute("type"); rrenkert@87: if(type.equals("point")) { rrenkert@87: for(int j = 0; j < slist.getLength(); j++){ rrenkert@87: Element symbolElement = (Element) slist.item(j); rrenkert@87: MarkerStyleWriter swriter = new MarkerStyleWriter (this.map, co); rrenkert@87: swriter.write (symbolElement); rrenkert@87: } rrenkert@87: } rrenkert@87: else if(type.equals("line")) { rrenkert@87: for(int j = 0; j < slist.getLength(); j++){ rrenkert@87: Element symbolElement = (Element) slist.item(j); rrenkert@95: LineStyleWriter swriter = new LineStyleWriter (this.map, co); rrenkert@95: swriter.write (symbolElement); rrenkert@87: } rrenkert@87: } rrenkert@42: } rrenkert@41: } rrenkert@41: } rrenkert@41: