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@42: import java.awt.Color; 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: import edu.umn.gis.mapscript.styleObj; rrenkert@42: import edu.umn.gis.mapscript.colorObj; rrenkert@42: import edu.umn.gis.mapscript.symbolObj; rrenkert@42: import edu.umn.gis.mapscript.symbolSetObj; rrenkert@42: import edu.umn.gis.mapscript.lineObj; rrenkert@42: import edu.umn.gis.mapscript.pointObj; rrenkert@42: rrenkert@41: import edu.umn.gis.mapscript.MS_UNITS; rrenkert@42: import edu.umn.gis.mapscript.MS_LAYER_TYPE; rrenkert@42: import edu.umn.gis.mapscript.MS_SYMBOL_TYPE; rrenkert@41: rrenkert@41: import de.intevation.mxd.utils.XMLUtils; rrenkert@41: rrenkert@41: /** rrenkert@41: * The MXD file reader. rrenkert@41: * rrenkert@41: * @author Raimund Renkert rrenkert@41: */ rrenkert@41: public class MapScriptWriter rrenkert@41: implements IWriter rrenkert@41: { rrenkert@41: private Document root; rrenkert@41: private mapObj map; rrenkert@41: rrenkert@41: private static final Logger logger = Logger.getLogger(MapScriptWriter.class); rrenkert@41: rrenkert@41: public MapScriptWriter() { rrenkert@41: map = new mapObj(""); rrenkert@41: } rrenkert@41: rrenkert@41: public MapScriptWriter(String path) { rrenkert@41: map = new mapObj(path); rrenkert@41: } rrenkert@41: rrenkert@41: 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: String filename = fileNode.getAttribute("name"); rrenkert@41: if(filename.endsWith(".mxd")) { rrenkert@41: filename = filename.replace(".mxd", ".map"); rrenkert@41: } 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@42: cloneMap.save(filename); rrenkert@41: return true; rrenkert@41: } rrenkert@41: 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@42: //TODO Get the following values from a template. rrenkert@42: map.setShapepath("/home/intevation/mxd-testbed/testdata-frida"); rrenkert@42: map.setHeight(700); rrenkert@42: map.setWidth(800); rrenkert@42: map.setProjection("EPSG:4326"); rrenkert@42: 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@41: msu = MS_UNITS.MS_DD; 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@41: 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@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@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@42: private void writeClass(layerObj layer, Element layerElement) { 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@42: //Write symbols and styles. rrenkert@42: writeSymbol(co, classElement); rrenkert@42: } rrenkert@41: } rrenkert@41: rrenkert@42: /** rrenkert@42: * Adds teh symbols and styles to the mapfile. rrenkert@42: * @param co Mapscript class object. rrenkert@42: * @param classElement Dom element containing the style and symbol rrenkert@42: * attributes. rrenkert@42: */ rrenkert@42: private void writeSymbol(classObj co, Element classElement) { rrenkert@42: //Get all symbol elements from dom. rrenkert@42: NodeList list = classElement.getElementsByTagName("symbol"); rrenkert@41: rrenkert@42: //Get the symbol set from the map object. rrenkert@42: symbolSetObj symbolSet = map.getSymbolset(); rrenkert@42: rrenkert@42: // rrenkert@42: for(int i = 0; i < list.getLength(); i++){ rrenkert@42: Element symbolElement = (Element) list.item(i); rrenkert@42: styleObj style = new styleObj(co); rrenkert@42: style.setAngle( rrenkert@42: Double.parseDouble(symbolElement.getAttribute("angle"))); rrenkert@42: String c = symbolElement.getAttribute("color"); rrenkert@42: Color col = Color.decode(c); rrenkert@42: colorObj color = new colorObj( rrenkert@42: col.getRed(), rrenkert@42: col.getGreen(), rrenkert@42: col.getBlue(), rrenkert@42: -4); rrenkert@42: style.setColor(color); rrenkert@42: style.setSize(Double.parseDouble(symbolElement.getAttribute("size"))); rrenkert@42: Color oCol = Color.decode( rrenkert@42: symbolElement.getAttribute("outline_color")); rrenkert@42: colorObj outlineColor = new colorObj( rrenkert@42: oCol.getRed(), rrenkert@42: oCol.getGreen(), rrenkert@42: oCol.getBlue(), rrenkert@42: -4); rrenkert@42: style.setOutlinecolor(outlineColor); rrenkert@42: style.setOutlinewidth( rrenkert@42: Double.parseDouble(symbolElement.getAttribute("outline_size"))); rrenkert@42: style.setSymbolByName(map, symbolElement.getAttribute("name")); rrenkert@42: rrenkert@42: symbolObj sym = symbolSet.getSymbolByName(symbolElement.getAttribute("name")); rrenkert@42: String symType = symbolElement.getAttribute("style"); rrenkert@42: if(symType.equals("point")) { rrenkert@42: lineObj points = new lineObj(); rrenkert@42: points.add(new pointObj(1,1,0)); rrenkert@42: sym.setType(MS_SYMBOL_TYPE.MS_SYMBOL_ELLIPSE.swigValue()); rrenkert@42: sym.setPoints(points); rrenkert@42: sym.setFilled(1); rrenkert@42: } rrenkert@42: } rrenkert@42: saveSymbolSet(symbolSet); rrenkert@41: } rrenkert@41: rrenkert@42: /** rrenkert@42: * Save the symbol set. rrenkert@42: * @param rrenkert@42: */ rrenkert@42: private void saveSymbolSet(symbolSetObj symbols) { rrenkert@42: Element fileNode = (Element)XMLUtils.xpath( rrenkert@42: root, rrenkert@42: "/mxd/file", rrenkert@42: XPathConstants.NODE); rrenkert@42: String filename = fileNode.getAttribute("name"); rrenkert@42: String path = ""; rrenkert@42: if(filename.contains("/")) { rrenkert@42: path = filename.substring(0, filename.lastIndexOf("/")); rrenkert@42: } rrenkert@42: else if(filename.contains("\\")) { rrenkert@42: path = filename.substring(0, filename.lastIndexOf("\\")); rrenkert@42: } rrenkert@42: symbols.save(path + "/symbols.sym"); rrenkert@42: } rrenkert@41: } rrenkert@41: