package eu.simstadt.nf; import java.io.StringWriter; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.geotools.geometry.GeneralDirectPosition; import org.geotools.referencing.CRS; import org.opengis.geometry.DirectPosition; import org.opengis.geometry.MismatchedDimensionException; import org.opengis.referencing.FactoryException; import org.opengis.referencing.NoSuchAuthorityCodeException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Builds nF import and export jobs using nF's XML job format. * * @author Marcel Bruse */ public class NFJobBuilder { /** * This is an intermediate prototype. * * @param regionPolygon A polygon of geo coordinates which encloses the buildings to be downloaded. * @return Returns a string representation of the nF export job. */ public static String buildExportJob(List regionPolygon) { String result = null; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.newDocument(); Element root = doc.createElement("EXPORT_JOB"); root.setAttribute("version", "1.0.0"); doc.appendChild(root); Element job = doc.createElement("job"); root.appendChild(job); Element initiator = doc.createElement("initiator"); initiator.appendChild(doc.createTextNode("2758")); job.appendChild(initiator); Element jobnumber = doc.createElement("jobnumber"); jobnumber.appendChild(doc.createTextNode("GR_EXPORT_CITYGML_LOD1")); job.appendChild(jobnumber); Element account = doc.createElement("account"); account.appendChild(doc.createTextNode("Habib")); job.appendChild(account); Element product = doc.createElement("product"); product.appendChild(doc.createTextNode("LBTEST")); root.appendChild(product); Element layers = doc.createElement("layers"); layers.setAttribute("color", "0"); layers.setAttribute("mono", "0"); layers.setAttribute("plotLabelSrs", "-1"); layers.setAttribute("plotframe", "0"); layers.setAttribute("single", "1"); root.appendChild(layers); Element layer = doc.createElement("layer"); layer.setAttribute("name", "GML"); layer.setAttribute("product", "LBTEST"); layer.setAttribute("style", "#000000"); layers.appendChild(layer); Element srs = doc.createElement("srs"); srs.appendChild(doc.createTextNode("31467")); root.appendChild(srs); Element extent = doc.createElement("extent"); extent.setAttribute("merge_mapsheets", "off"); extent.setAttribute("tile1asgn", "false"); root.appendChild(extent); Element polygon = appendRegionPolygon(doc, regionPolygon); extent.appendChild(polygon); Element resolution = doc.createElement("resolution"); resolution.appendChild(doc.createTextNode("100.0")); root.appendChild(resolution); Element scale = doc.createElement("scale"); scale.appendChild(doc.createTextNode("10000.0")); root.appendChild(scale); Element format = doc.createElement("format"); format.setAttribute("alphalinscale", "0.0"); format.setAttribute("alphascale", "1.0"); format.setAttribute("citygml_actfunc", "tolod1"); format.setAttribute("citygml_apptheme", ""); format.setAttribute("citygml_elemclasses", "true"); format.setAttribute("citygml_lodmode", "all"); format.setAttribute("citygml_lods", "1"); format.setAttribute("citygml_metadata", "true"); format.setAttribute("citygml_outmode", "normal"); format.setAttribute("dtm", "false"); format.setAttribute("foredit", "false"); format.setAttribute("materialcopymode", "none"); format.setAttribute("polyopts_reverse", "false"); format.setAttribute("relcoords", "false"); format.setAttribute("rooftxr", "false"); format.setAttribute("roundcoords", "3"); format.setAttribute("schemetxr", "false"); format.setAttribute("solar", "false"); format.setAttribute("solargeoplex", "false"); format.setAttribute("tex", "false"); format.setAttribute("tolod1", "true"); format.setAttribute("tolod1_add", "false"); format.setAttribute("tolod1_delrest", "false"); format.setAttribute("tolod1_dstattrabsgrnd", ""); format.setAttribute("tolod1_dstattrabsheight", ""); format.setAttribute("tolod1_dstattrrelheight", ""); format.setAttribute("tolod1_dstattrzmode", ""); format.setAttribute("tolod1_geommode", "lod1solid"); format.setAttribute("tolod1_lodsrcmode", "all"); format.setAttribute("tolod1_triangulate", "false"); format.setAttribute("tolod1_zroofmode", "mid"); format.setAttribute("tolod1_zusegenattrs", ""); format.setAttribute("tolod1_zusemeasuredheight", "false"); format.setAttribute("xyz", "false"); format.appendChild(doc.createTextNode("CityGML")); root.appendChild(format); Element exportmetadata = doc.createElement("exportmetadata"); exportmetadata.setAttribute("calibration", "0"); exportmetadata.setAttribute("xmetadata", "0"); exportmetadata.appendChild(doc.createTextNode("1")); root.appendChild(exportmetadata); Element addfile = doc.createElement("addfile"); addfile.setAttribute("col", "0"); addfile.setAttribute("eck", ""); root.appendChild(addfile); Element usenodatamask = doc.createElement("usenodatamask"); usenodatamask.appendChild(doc.createTextNode("0")); root.appendChild(usenodatamask); Element usepdctborderpoly = doc.createElement("usepdctborderpoly"); usepdctborderpoly.appendChild(doc.createTextNode("0")); root.appendChild(usepdctborderpoly); Element dhkresolvereferences = doc.createElement("dhkresolvereferences"); dhkresolvereferences.appendChild(doc.createTextNode("1")); root.appendChild(dhkresolvereferences); Element zipresult = doc.createElement("zipresult"); zipresult.appendChild(doc.createTextNode("0")); root.appendChild(zipresult); Element userdescription = doc.createElement("userdescription"); root.appendChild(userdescription); Element namingpattern = doc.createElement("namingpattern"); root.appendChild(namingpattern); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); StringWriter writer = new StringWriter(); StreamResult streamResult = new StreamResult(writer); transformer.transform(new DOMSource(doc), streamResult); result = writer.toString(); } catch (ParserConfigurationException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } catch (TransformerConfigurationException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } catch (TransformerException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } return result; } /** * Transforms a global WGS 84 position into a coordinate of the given target SRS. * * @param wgs84Position The WGS 84 position to be transformed to a position within the target SRS. * @param targetCRS The target SRS for the transformation. * @return The transformed target position within the target SRS. */ public static DirectPosition transformCoordinate(DirectPosition wgs84Position, CoordinateReferenceSystem targetCRS) { DirectPosition result = null; try { CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326"); // WGS 84 (used by Google Maps) MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true); result = transform.transform(wgs84Position, null); } catch (NoSuchAuthorityCodeException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } catch (FactoryException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } catch (MismatchedDimensionException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } catch (TransformException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } return result; } /** * Appends the region polygon to the XML export job document. In order to do this, the given WGS 84 region * polygon will be transformed into a DHDN Gauss-Kruger zone 3 polygon. * * @param doc The XML export job document. * @param regionPolygon The polygon of the region which has been selected to be exported. * @return The w3c.dom.Element of the XML export job which describes the region polygon. */ private static Element appendRegionPolygon(Document doc, List regionPolygon) { Element polygon = doc.createElement("polygon"); polygon.setAttribute("srs", "31467"); try { CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:31467"); // DHDN Gauss-Kruger zone 3 for (Coord coord : regionPolygon) { DirectPosition sourcePosition = new GeneralDirectPosition(coord.latitude, coord.longitude); DirectPosition targetPosition = transformCoordinate(sourcePosition, targetCRS); Element vertex = doc.createElement("vertex"); vertex.setAttribute("x", String.valueOf(targetPosition.getCoordinate()[1])); vertex.setAttribute("y", String.valueOf(targetPosition.getCoordinate()[0])); polygon.appendChild(vertex); } } catch (FactoryException ex) { // TODO Auto-generated catch block ex.printStackTrace(); } return polygon; } }