Mercurial > mxd2map
view src/java/de/intevation/mxd/writer/MapScriptWriter.java @ 62:e468cf8701ea
Prepared the converter to handle and write line symbols.
author | Raimund Renkert <rrenkert@intevation.de> |
---|---|
date | Tue, 24 May 2011 14:16:25 +0200 |
parents | ef1ee8e752b2 |
children | 7d4cf2db43f1 |
line wrap: on
line source
package de.intevation.mxd.writer; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import javax.xml.xpath.XPathConstants; import java.awt.Color; import edu.umn.gis.mapscript.mapObj; import edu.umn.gis.mapscript.layerObj; import edu.umn.gis.mapscript.classObj; import edu.umn.gis.mapscript.styleObj; import edu.umn.gis.mapscript.colorObj; import edu.umn.gis.mapscript.symbolObj; import edu.umn.gis.mapscript.symbolSetObj; import edu.umn.gis.mapscript.lineObj; import edu.umn.gis.mapscript.pointObj; import edu.umn.gis.mapscript.MS_UNITS; import edu.umn.gis.mapscript.MS_LAYER_TYPE; import edu.umn.gis.mapscript.MS_SYMBOL_TYPE; import de.intevation.mxd.utils.XMLUtils; /** * The Mapfile Writer. * This Writer uses the MapScript Java API to create Mapfiles from a DOM. * * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a> */ public class MapScriptWriter implements IWriter { /** * The Logger. */ private static final Logger logger = Logger.getLogger(MapScriptWriter.class); /** * Private member. */ private Document root; private mapObj map; private String mapFilename; public MapScriptWriter() { map = new mapObj(""); mapFilename = ""; } public MapScriptWriter(String templ, String filename) { map = new mapObj(templ); mapFilename = filename; } /** * Write the mapfile. * @param doc The root document containin the map attributes. * * @return Currently always true. */ public boolean write(Document doc) { logger.debug("write()"); this.root = doc; //Get the filename. Element fileNode = (Element)XMLUtils.xpath( root, "/mxd/file", XPathConstants.NODE); //Write the map attributes. writeMap(); //Write the layers. writeLayer(); //Save the map. mapObj cloneMap = map.cloneMap(); cloneMap.save(mapFilename); return true; } /** * Create the map object and set the attributes. */ private void writeMap() { logger.debug("writeMap()"); //Get the map. Element mapNode = (Element)XMLUtils.xpath( root, "/mxd/map", XPathConstants.NODE); //Set the name. map.setName(mapNode.getAttribute("name")); map.setMetaData("wms_title", mapNode.getAttribute("name")); //Set the extent. map.setExtent( Double.parseDouble(mapNode.getAttribute("extent_min_x")), Double.parseDouble(mapNode.getAttribute("extent_min_y")), Double.parseDouble(mapNode.getAttribute("extent_max_x")), Double.parseDouble(mapNode.getAttribute("extent_max_y"))); //Set the units. String units = mapNode.getAttribute("units"); MS_UNITS msu; if(units.equals("feet")) { msu = MS_UNITS.MS_FEET; } else if(units.equals("inches")) { msu = MS_UNITS.MS_INCHES; } else if(units.equals("kilometers")) { msu = MS_UNITS.MS_KILOMETERS; } else if(units.equals("meters")) { msu = MS_UNITS.MS_METERS; } else if(units.equals("miles")) { msu = MS_UNITS.MS_MILES; } else if(units.equals("nauticalmiles")) { msu = MS_UNITS.MS_NAUTICALMILES; } else if(units.equals("points")) { msu = MS_UNITS.MS_PIXELS; } else { msu = MS_UNITS.MS_METERS; } map.setUnits(msu); //TODO: Find out whats the correct scale value. //map.setScaledenom(Double.parseDouble(mapNode.getAttribute("scale"))); } /** * Create layer objects and set the attributes. */ private void writeLayer() { logger.debug("writeLayer()"); Element mapNode = (Element)XMLUtils.xpath( root, "/mxd/map", XPathConstants.NODE); NodeList list = mapNode.getElementsByTagName("layer"); for(int i = 0; i < list.getLength(); i++) { Element layerElement = (Element)list.item(i); layerObj layer = new layerObj(map); //The layer name. layer.setName(layerElement.getAttribute("name")); //The layer status. String stat = layerElement.getAttribute("status"); if (stat.equals("on")) { layer.setStatus(1); } else { layer.setStatus(0); } //The scale. double maxScale = Double.parseDouble(layerElement.getAttribute("max_scale")); double minScale = Double.parseDouble(layerElement.getAttribute("min_scale")); layer.setMaxscaledenom(maxScale); layer.setMinscaledenom(minScale); //The layer type. String type = layerElement.getAttribute("type"); if(type.equals("point")) { layer.setType(MS_LAYER_TYPE.MS_LAYER_POINT); } else if (type.equals("line")) { layer.setType(MS_LAYER_TYPE.MS_LAYER_LINE); } //The layer datasource. layer.setData(layerElement.getAttribute("data_source")); //Write classes. writeClass(layer, layerElement); } } /** * Adds the classes to the layer. * @param layer Mapscript layer object. * @param layerElement Dom element containing the class attributes. */ private void writeClass(layerObj layer, Element layerElement) { //Get all renderer elements (renderer in arcgis equals class in the //mapfile.) NodeList list = layerElement.getElementsByTagName("renderer"); //Create all found class objects and write the symbols and styles for //each class. for(int i = 0; i < list.getLength(); i++) { Element classElement = (Element)list.item(i); classObj co = new classObj(layer); co.setName(classElement.getAttribute("name")); if(classElement.hasAttribute("field_count")) { int count = Integer.parseInt(classElement.getAttribute("field_count")); String exp = ""; for(int j = 0; j < count; j++) { //TODO Find a way to create Expressions. exp = "([" + classElement.getAttribute("expression_field_" + j); exp += "] " + classElement.getAttribute("expression_operator"); exp += " " + classElement.getAttribute("value") + ")"; } co.setExpression(exp); } //Write symbols and styles. writeSymbol(co, classElement); } } /** * Adds the symbols and styles to the mapfile. * @param co Mapscript class object. * @param classElement Dom element containing the style and symbol * attributes. */ private void writeSymbol(classObj co, Element classElement) { //Get all symbol elements from dom. NodeList list = classElement.getElementsByTagName("symbol"); //Get the symbol set from the map object. symbolSetObj symbolSet = map.getSymbolset(); for(int i = 0; i < list.getLength(); i++){ Element symbolElement = (Element) list.item(i); styleObj style = new styleObj(co); if (symbolElement.hasAttribute("angle")) { style.setAngle( Double.parseDouble(symbolElement.getAttribute("angle"))); } if(symbolElement.hasAttribute("color")) { String c = symbolElement.getAttribute("color"); Color col = Color.decode(c); colorObj color = new colorObj( col.getRed(), col.getGreen(), col.getBlue(), -4); style.setColor(color); } if (symbolElement.hasAttribute ("size")) { style.setSize(Double.parseDouble( symbolElement.getAttribute("size"))); } if(symbolElement.hasAttribute("outline_color")) { Color oCol = Color.decode( symbolElement.getAttribute("outline_color")); colorObj outlineColor = new colorObj( oCol.getRed(), oCol.getGreen(), oCol.getBlue(), -4); style.setOutlinecolor(outlineColor); style.setOutlinewidth(Double.parseDouble( symbolElement.getAttribute("outline_size"))); } //Section for line symbols //Setting the width if(symbolElement.hasAttribute("width")) { style.setWidth((int)Double.parseDouble( symbolElement.getAttribute("width"))); } String name = symbolElement.getAttribute("name"); style.setSymbolByName(map, name); symbolObj sym = symbolSet.getSymbolByName(name); //The following lines are for dashed and/or dotted lines. //These lines throw an "incorrect array size" error. //TODO Find out how to set the pattern correctly. // style.setPatternlength(2); // double[] vals = new double[] {1.0, 2.0, 3.0}; // vals[0] = 1.0; // vals[1] = 2.0; // vals[2] = 3.0; // vals[3] = 4.0; // style.setPattern(vals); String symType = symbolElement.getAttribute("style"); if(symType.equals("point")) { writePointSymbol(sym, symbolElement); } else if (symType.equals("arrow")) { writeArrowSymbol(sym, symbolElement); } else if (symType.equals("char")) { writeCharSymbol(sym, symbolElement); } else if(symType.equals("line")) { writeSimpleLineSymbol(sym, symbolElement); } } saveSymbolSet(symbolSet); } /** * Write point symbols to the map. * @param symbol The symbol object. * @param symbolElement The DOM object containing the attributes. */ private void writePointSymbol(symbolObj symbol, Element symbolElement) { lineObj points = new lineObj(); points.add(new pointObj(1,1,0)); symbol.setType(MS_SYMBOL_TYPE.MS_SYMBOL_ELLIPSE.swigValue()); symbol.setPoints(points); symbol.setFilled(1); } /** * Write arrow symbol to the map. * @param symbol The symbol object. * @param symbolElement The DOM object containig the attributes. */ private void writeArrowSymbol(symbolObj symbol, Element symbolElement) { double len = Double.parseDouble(symbolElement.getAttribute("length")); double width = Double.parseDouble(symbolElement.getAttribute("width")); double ratio = len/width; lineObj points = new lineObj(); points.add(new pointObj(0, 0, 0)); points.add(new pointObj((1*ratio), 0.5, 0)); points.add(new pointObj(0, 1, 0)); points.add(new pointObj(0, 0, 0)); symbol.setType(MS_SYMBOL_TYPE.MS_SYMBOL_VECTOR.swigValue()); symbol.setPoints(points); symbol.setFilled(1); } /** * Write font symbols to the map. * @param symbol The symbol object. * @param symbolElement The DOM object containing the attributes. */ private void writeCharSymbol(symbolObj symbol, Element symbolElement) { //TODO Write the symbol correctly. See Issue 3885 on trac.osgeo.org symbol.setFont(symbolElement.getAttribute("font")); symbol.setType(MS_SYMBOL_TYPE.MS_SYMBOL_TRUETYPE.swigValue()); symbol.setAntialias(1); symbol.setCharacter("#&" + symbolElement.getAttribute("char") + ";"); } private void writeSimpleLineSymbol( symbolObj symbol, Element symbolElement) { logger.debug("writeSimpleLineSymbol()"); symbol.setType(MS_SYMBOL_TYPE.MS_SYMBOL_SIMPLE.swigValue()); String ls = symbolElement.getAttribute("linestyle"); if(ls.equals("solid")) { symbol.setFilled(1); } } /** * Save the symbol set. * @param symbols The symbol set. */ private void saveSymbolSet(symbolSetObj symbols) { Element fileNode = (Element)XMLUtils.xpath( root, "/mxd/file", XPathConstants.NODE); String path = ""; if(mapFilename.contains("/")) { path = mapFilename.substring(0, mapFilename.lastIndexOf("/")); } else if(mapFilename.contains("\\")) { path = mapFilename.substring(0, mapFilename.lastIndexOf("\\")); } symbols.save(path + "/symbols.sym"); } }