Commit 5afd8f90 authored by Eric Duminil's avatar Eric Duminil
Browse files

Save OSM files in cache

parent 2c31e4f1
......@@ -2,17 +2,16 @@ 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.ArrayList;
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;
......@@ -26,7 +25,6 @@ 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;
......@@ -35,25 +33,29 @@ import de.hft.stuttgart.citygml.green.osm.RoadArea;
import de.hft.stuttgart.citygml.green.osm.TreeUtils;
import jakarta.xml.bind.JAXBException;
public class AlkisGreenEnricher {
public class AlkisGreenEnricher
{
private static Set<String> greenAreaTypes = new HashSet<>();
private static Set<String> 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, CityGMLContextException, CityGMLReadException, JAXBException, CityGMLWriteException {
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]);
CityModel cityModel = GreenEnricher.readCityGml(inFile);
......@@ -62,33 +64,37 @@ public class AlkisGreenEnricher {
OsmData osmData = new OsmData();
String boundingBoxString = GreenEnricher.extractAndConvertBoundingBox(cityModel, osmData);
// HttpResponse<String> response = getOsmData(boundingBoxString);
// Files.write(Path.of("osm_response.xml"), response.body().getBytes(StandardCharsets.UTF_8));
// String osmResponse = response.body();
String osmResponse = Files.readString(Paths.get("data", "osm_response.xml"));
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<String> 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);
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);
GreenEnricher.clampToGround(cityModel);
String inputString = inFile.getFileName().toString();
String inputPathWithoutFileEnding = inputString.substring(0, inputString.lastIndexOf('.'));
Path outputPath = Paths.get("data", inputPathWithoutFileEnding + "_with_alkis_greens_realistic.gml");
......@@ -101,7 +107,7 @@ public class AlkisGreenEnricher {
private static void parseAlkisData(OsmData osmData) throws MalformedURLException, IOException {
Path alkisDataPath = Paths.get("data", "tn_09663", "Nutzung.shp");
Map<String, Object> readParameters = new HashMap<>();
readParameters.put("url", alkisDataPath.toUri().toURL());
readParameters.put("charset", StandardCharsets.UTF_8);
......@@ -111,15 +117,15 @@ public class AlkisGreenEnricher {
FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures();
List<GreenArea> greenAreas = osmData.getGreenAreas();
List<RoadArea> roadAreas = osmData.getRoadAreas();
List<LandUseArea> landUseAreas = osmData.getLandUseAreas();
try (FeatureIterator<SimpleFeature> 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) {
......
......@@ -18,9 +18,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.ParserConfigurationException;
import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.building.Building;
import org.citygml4j.core.model.core.AbstractCityObject;
......@@ -62,7 +60,6 @@ import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty;
import org.xmlobjects.gml.model.geometry.primitives.LinearRing;
import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
import de.hft.stuttgart.citygml.green.osm.jaxb.OSM;
import de.hft.stuttgart.citygml.green.osm.jaxb.OsmMember;
import de.hft.stuttgart.citygml.green.osm.jaxb.OsmNode;
......@@ -73,7 +70,9 @@ import de.hft.stuttgart.citygml.green.osm.jaxb.WayNode;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
public class GreenEnricher {
public class GreenEnricher
{
private static final int BOUNDING_BOX_INCREASE_IN_M = 100;
......@@ -123,9 +122,9 @@ public class GreenEnricher {
OsmData osmData = new OsmData();
String boundingBoxString = extractAndConvertBoundingBox(cityModel, osmData);
// HttpResponse<String> response = getOsmData(boundingBoxString);
// Files.write(Path.of("osm_response.xml"), response.body().getBytes(StandardCharsets.UTF_8));
// String osmResponse = response.body();
// HttpResponse<String> response = getOsmData(boundingBoxString);
// Files.write(Path.of("osm_response.xml"), response.body().getBytes(StandardCharsets.UTF_8));
// String osmResponse = response.body();
String osmResponse = Files.readString(Paths.get("data", "osm_response.xml"));
System.out.println("Parsing OSM response");
......@@ -143,7 +142,7 @@ public class GreenEnricher {
// trees
TreeUtils.insertTrees(cityModel, osmData);
clampToGround(cityModel);
String inputString = inFile.getFileName().toString();
......@@ -229,7 +228,7 @@ public class GreenEnricher {
landUseArea.setArea((Polygon) intersection);
}
}
landUseAreas.addAll(newLandUseAreas);
landUseAreas.addAll(newLandUseAreas);
}
......@@ -318,6 +317,7 @@ public class GreenEnricher {
}
}
}
public static void clampToGround(CityModel cityModel) {
for (AbstractCityObjectProperty afp : cityModel.getCityObjectMembers()) {
AbstractCityObject af = afp.getObject();
......@@ -376,7 +376,7 @@ public class GreenEnricher {
return result;
}
private static HttpResponse<String> getOsmData(String boundingBoxString) throws IOException, InterruptedException {
public static HttpResponse<String> getOsmData(String boundingBoxString) throws IOException, InterruptedException {
String data = OSM_STRING.replace("{{bbox}}", boundingBoxString);
String body = URLEncoder.encode("data", StandardCharsets.UTF_8) + "="
+ URLEncoder.encode(data, StandardCharsets.UTF_8);
......@@ -436,7 +436,7 @@ public class GreenEnricher {
}
}
}
if (!coordinates.isEmpty() && coordinates.get(0).equals2D(coordinates.get(coordinates.size() - 1))) {
// one huge polygon apparently
Polygon polygon = GEOM_FACTORY.createPolygon(coordinates.toArray(new Coordinate[coordinates.size()]));
......@@ -445,13 +445,13 @@ public class GreenEnricher {
} else {
// line
}
for (OsmTag tag : rel.getTags()) {
if ("water".equals(tag.getValue()) || "waterway".equals(tag.getKey())) {
isWater = true;
}
}
if (isWater) {
for (Polygon p : polygons) {
data.getWaterAreas().add(new WaterArea(p));
......@@ -587,28 +587,28 @@ public class GreenEnricher {
data.getWaterAreas().add(new WaterArea(polygon));
}
// validateRing(outerRing);
// validateRing(outerRing);
// create the outer ring
// org.locationtech.jts.geom.LinearRing outerLinearRing = geomFactory
// .createLinearRing(outerRing.toArray(new Coordinate[outerRing.size()]));
//
// // create the inner rings
// List<org.locationtech.jts.geom.LinearRing> innerLinearRings = new ArrayList<>();
// for (List<Coordinate> innerRing : innerRings) {
// org.locationtech.jts.geom.LinearRing innerLinearRing = geomFactory
// .createLinearRing(innerRing.toArray(new Coordinate[innerRing.size()]));
// innerLinearRings.add(innerLinearRing);
// }
//
// if (outerRing.isEmpty()) {
// return false;
// }
//
// // create the polygon
// Polygon polygon = geomFactory.createPolygon(outerLinearRing,
// innerLinearRings.toArray(new org.locationtech.jts.geom.LinearRing[innerLinearRings.size()]));
//
// data.getGreenAreas().add(new GreenArea(polygon));
// org.locationtech.jts.geom.LinearRing outerLinearRing = geomFactory
// .createLinearRing(outerRing.toArray(new Coordinate[outerRing.size()]));
//
// // create the inner rings
// List<org.locationtech.jts.geom.LinearRing> innerLinearRings = new ArrayList<>();
// for (List<Coordinate> innerRing : innerRings) {
// org.locationtech.jts.geom.LinearRing innerLinearRing = geomFactory
// .createLinearRing(innerRing.toArray(new Coordinate[innerRing.size()]));
// innerLinearRings.add(innerLinearRing);
// }
//
// if (outerRing.isEmpty()) {
// return false;
// }
//
// // create the polygon
// Polygon polygon = geomFactory.createPolygon(outerLinearRing,
// innerLinearRings.toArray(new org.locationtech.jts.geom.LinearRing[innerLinearRings.size()]));
//
// data.getGreenAreas().add(new GreenArea(polygon));
return true;
}
......@@ -637,9 +637,9 @@ public class GreenEnricher {
ProjCoordinate converted = convertCoordinatesFrom84(lon, lat);
coordinates.add(new Coordinate(converted.x, converted.y));
} else if ("tag".equals(child.getNodeName())) {
// if (existTagWithValue(child, "k", "natural") && existTagWithValue(child, "v", "tree_row")) {
// line = true;
// }
// if (existTagWithValue(child, "k", "natural") && existTagWithValue(child, "v", "tree_row")) {
// line = true;
// }
if ((existTagWithValue(child, "k", "natural") && existTagWithValue(child, "v", "water"))
|| existTagWithValue(child, "k", "waterway")) {
water = true;
......
......@@ -4,7 +4,6 @@ import java.io.IOException;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.UUID;
import org.citygml4j.core.model.core.AbstractCityObjectProperty;
import org.citygml4j.core.model.core.CityModel;
import org.citygml4j.core.model.vegetation.SolitaryVegetationObject;
......@@ -13,23 +12,26 @@ import org.xmlobjects.gml.model.basictypes.Code;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
public class TreeUtils {
public class TreeUtils
{
public static void insertTrees(CityModel cityModel, OsmData osmData) throws IOException {
TreeKatasterData katasterData = TreeKatasterData.parseTreeKatasterData(Paths.get("data", "Trees_realisticScenario_20240201.shp"));
TreeKatasterData katasterData = TreeKatasterData
.parseTreeKatasterData(Paths.get("data", "Trees", "Trees_realisticScenario_20240201.shp"));
generateTreesFromKataster(cityModel, katasterData);
// TreeKatasterData katasterData2 = TreeKatasterData.parseTreeKatasterData(Paths.get("data", "Trees_realistic_20240201.shp"));
// generateTreesFromKataster(cityModel, katasterData2);
// TreeKatasterData katasterData2 = TreeKatasterData.parseTreeKatasterData(Paths.get("data", "Trees_realistic_20240201.shp"));
// generateTreesFromKataster(cityModel, katasterData2);
// All kataster trees are taken, osm trees are removed
filterDuplicateTreesFromOSM(osmData, katasterData);
// filterDuplicateTreesFromOSM(osmData, katasterData2);
// filterDuplicateTreesFromOSM(osmData, katasterData2);
generateTreesFromOSM(cityModel, osmData);
}
private static void filterDuplicateTreesFromOSM(OsmData osmData, TreeKatasterData katasterData) {
for (Iterator<TreePoint> iterator = osmData.getTreePoints().iterator(); iterator.hasNext();) {
TreePoint tp = iterator.next();
......@@ -41,7 +43,7 @@ public class TreeUtils {
}
}
}
private static void generateTreesFromOSM(CityModel cityModel, OsmData osmData) {
for (TreePoint tp : osmData.getTreePoints()) {
// standard tree
......
package de.hft.stuttgart.citygml.green.alkis;
import java.io.IOException;
import org.citygml4j.xml.CityGMLContextException;
import org.citygml4j.xml.reader.CityGMLReadException;
import org.citygml4j.xml.writer.CityGMLWriteException;
import org.junit.jupiter.api.Test;
import jakarta.xml.bind.JAXBException;
class AlkisGreenEnricherTest {
class AlkisGreenEnricherTest
{
@Test
void testAlkisGreen() throws IOException, CityGMLContextException, CityGMLReadException, JAXBException, CityGMLWriteException {
String[] args = new String[] {"data/Grombühl_v4_case_study.gml"};
void testAlkisGreen() throws Exception {
String[] args = new String[] { "data/Grombühl_v4_case_study.gml" };
AlkisGreenEnricher.main(args);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment