package de.hft.stuttgart.citygml.green.osm; 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; import org.locationtech.jts.geom.Coordinate; 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 static void insertTrees(CityModel cityModel, OsmData osmData) throws IOException { TreeKatasterData katasterData = TreeKatasterData.parseTreeKatasterData(Paths.get("data", "Trees_realisticScenario_20240201.shp")); generateTreesFromKataster(cityModel, katasterData); // 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); generateTreesFromOSM(cityModel, osmData); } private static void filterDuplicateTreesFromOSM(OsmData osmData, TreeKatasterData katasterData) { for (Iterator iterator = osmData.getTreePoints().iterator(); iterator.hasNext();) { TreePoint tp = iterator.next(); // if another tree from kataster is within 3m ignore it for (Tree tree : katasterData.getTrees()) { if (tp.getPoint().distance(tree.getPoint()) < 3) { iterator.remove(); } } } } private static void generateTreesFromOSM(CityModel cityModel, OsmData osmData) { for (TreePoint tp : osmData.getTreePoints()) { // standard tree double trunkRadius = 0.89 / (2 * Math.PI); double trunkHeight = TreeKatasterData.TRUNK_PERCENTAGE * 11.46; double crownHeight = TreeKatasterData.CROWN_PERCENTAGE * 11.46; double crownRadius = 8 / 2d; Coordinate coordinate = tp.getPoint().getCoordinate(); if (Double.isNaN(coordinate.z)) { coordinate.z = 0; } MultiSurface generatedTree = TreeGenerator.generateTree(coordinate, trunkRadius, trunkHeight, crownRadius, crownRadius, crownHeight); SolitaryVegetationObject cover = new SolitaryVegetationObject(); cover.setSpecies(new Code("Acer platanoides")); cover.setId(UUID.randomUUID().toString()); cover.setLod2MultiSurface(new MultiSurfaceProperty(generatedTree)); cityModel.getCityObjectMembers().add(new AbstractCityObjectProperty(cover)); } } private static void generateTreesFromKataster(CityModel cityModel, TreeKatasterData katasterData) { for (Tree tree : katasterData.getTrees()) { double trunkRadius = tree.getTrunkRadius(); double trunkHeight = tree.getTrunkHeight(); double crownHeight = tree.getCrownHeight(); double crownRadius = tree.getCrownRadius(); Coordinate coordinate = tree.getPoint().getCoordinate(); if (Double.isNaN(coordinate.z)) { coordinate.z = 0; } MultiSurface generatedTree = TreeGenerator.generateTree(coordinate, trunkRadius, trunkHeight, crownRadius, crownRadius, crownHeight); SolitaryVegetationObject cover = new SolitaryVegetationObject(); cover.setSpecies(new Code(tree.getType())); cover.setId(UUID.randomUUID().toString()); cover.setLod2MultiSurface(new MultiSurfaceProperty(generatedTree)); cityModel.getCityObjectMembers().add(new AbstractCityObjectProperty(cover)); } } }