package de.hft.stuttgart.citygml.green.alkis; import java.io.IOException; import java.net.MalformedURLException; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.citygml4j.core.model.core.CityModel; import org.citygml4j.xml.CityGMLContextException; import org.citygml4j.xml.reader.CityGMLReadException; import org.citygml4j.xml.writer.CityGMLWriteException; import org.geotools.data.DataStore; import org.geotools.data.DataStoreFinder; import org.geotools.data.FeatureSource; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.locationtech.jts.geom.MultiPolygon; import org.locationtech.jts.geom.Polygon; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import de.hft.stuttgart.citygml.green.osm.GreenArea; import de.hft.stuttgart.citygml.green.osm.GreenEnricher; import de.hft.stuttgart.citygml.green.osm.LandUseArea; import de.hft.stuttgart.citygml.green.osm.OsmData; import de.hft.stuttgart.citygml.green.osm.RoadArea; import de.hft.stuttgart.citygml.green.osm.TreeUtils; import jakarta.xml.bind.JAXBException; public class AlkisGreenEnricher { private static Set greenAreaTypes = new HashSet<>(); private static Set roadAreaTypes = new HashSet<>(); static { greenAreaTypes.add("Wald"); greenAreaTypes.add("Landwirtschaft"); greenAreaTypes.add("Friedhof"); greenAreaTypes.add("Gehölz"); greenAreaTypes.add("Sport-, Freizeit- und Erholungsfläche"); roadAreaTypes.add("Weg"); roadAreaTypes.add("Straßenverkehr"); roadAreaTypes.add("Bahnverkehr"); } public static void main(String[] args) throws IOException, InterruptedException, CityGMLContextException, CityGMLReadException, JAXBException, CityGMLWriteException { System.out.println("Reading CityGML file"); Path inFile = Paths.get(args[0]); Path alkisDataPath = Paths.get(args[1]); // shp, shx and dbf should be present. Path baumKatasterPath = Paths.get(args[2]); String outputSuffix = args[3]; CityModel cityModel = GreenEnricher.readCityGml(inFile); GreenEnricher.createTransformers(cityModel); OsmData osmData = new OsmData(); String boundingBoxString = GreenEnricher.extractAndConvertBoundingBox(cityModel, osmData); String boundingBoxBasename = boundingBoxString.replace(",", "__").replace('.', '_'); Path osmCache = Paths.get("data", "cache", "osm_response_" + boundingBoxBasename + ".xml"); if (!Files.exists(osmCache)) { System.out.println("Downloading OSM data for " + boundingBoxString); HttpResponse response = GreenEnricher.getOsmData(boundingBoxString); Files.write(osmCache, response.body().getBytes(StandardCharsets.UTF_8)); } String osmResponse = Files.readString(osmCache); System.out.println("Parsing OSM response"); GreenEnricher.parseOsmResponse(osmResponse, osmData); // ignore green areas from osm osmData.getGreenAreas().clear(); parseAlkisData(osmData, alkisDataPath); System.out.println("Fit data in bounding box"); GreenEnricher.fitToBoundingBox(osmData); GreenEnricher.convertGreenAreasToCityGML(cityModel, osmData.getGreenAreas()); GreenEnricher.convertWaterAreasToCityGML(cityModel, osmData); GreenEnricher.convertRoadAreasToCityGML(cityModel, osmData); GreenEnricher.converLandUseAreasToCityGML(cityModel, osmData); TreeUtils.insertTrees(cityModel, osmData, baumKatasterPath); GreenEnricher.clampToGround(cityModel); String inputString = inFile.getFileName().toString(); String inputPathWithoutFileEnding = inputString.substring(0, inputString.lastIndexOf('.')); Path outputPath = Paths.get("data", inputPathWithoutFileEnding + "_" + outputSuffix + ".gml"); System.out.println("Writing output file."); GreenEnricher.writeCityGML(cityModel, outputPath); System.out.println("Done"); } private static void parseAlkisData(OsmData osmData, Path alkisDataPath) throws MalformedURLException, IOException { Map readParameters = new HashMap<>(); readParameters.put("url", alkisDataPath.toUri().toURL()); readParameters.put("charset", StandardCharsets.UTF_8); DataStore dataStore = DataStoreFinder.getDataStore(readParameters); String typeName = dataStore.getTypeNames()[0]; FeatureSource source = dataStore.getFeatureSource(typeName); FeatureCollection collection = source.getFeatures(); List greenAreas = osmData.getGreenAreas(); List roadAreas = osmData.getRoadAreas(); List landUseAreas = osmData.getLandUseAreas(); try (FeatureIterator features = collection.features()) { while (features.hasNext()) { SimpleFeature feature = features.next(); MultiPolygon geometry = (MultiPolygon) feature.getAttribute("the_geom"); String nutzart = feature.getAttribute("nutzart").toString(); if (geometry.getNumGeometries() > 1) { throw new IllegalStateException(); } if (greenAreaTypes.contains(nutzart)) { greenAreas.add(new GreenArea((Polygon) geometry.getGeometryN(0))); } else if (roadAreaTypes.contains(nutzart)) { roadAreas.add(new RoadArea((Polygon) geometry.getGeometryN(0))); } else { landUseAreas.add(new LandUseArea((Polygon) geometry.getGeometryN(0))); } } } } }