Commit eacaa411 authored by Matthias Betz's avatar Matthias Betz
Browse files

Handle trees from kataster

parent ccd43258
......@@ -2,6 +2,7 @@ package de.hft.stuttgart.citygml.green.osm;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
......@@ -12,11 +13,14 @@ 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.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
......@@ -30,7 +34,10 @@ import org.citygml4j.core.model.building.Building;
import org.citygml4j.core.model.core.AbstractCityObject;
import org.citygml4j.core.model.core.AbstractCityObjectProperty;
import org.citygml4j.core.model.core.AbstractFeature;
import org.citygml4j.core.model.core.AbstractGenericAttribute;
import org.citygml4j.core.model.core.AbstractGenericAttributeProperty;
import org.citygml4j.core.model.core.CityModel;
import org.citygml4j.core.model.generics.StringAttribute;
import org.citygml4j.core.model.vegetation.PlantCover;
import org.citygml4j.core.model.vegetation.SolitaryVegetationObject;
import org.citygml4j.core.model.waterbody.WaterBody;
......@@ -44,6 +51,11 @@ import org.citygml4j.xml.reader.CityGMLReader;
import org.citygml4j.xml.writer.CityGMLOutputFactory;
import org.citygml4j.xml.writer.CityGMLWriteException;
import org.citygml4j.xml.writer.CityGMLWriter;
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.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
......@@ -55,6 +67,8 @@ import org.locationtech.proj4j.BasicCoordinateTransform;
import org.locationtech.proj4j.CRSFactory;
import org.locationtech.proj4j.CoordinateReferenceSystem;
import org.locationtech.proj4j.ProjCoordinate;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
......@@ -69,6 +83,9 @@ import org.xmlobjects.gml.model.geometry.primitives.LinearRing;
import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
public class GreenEnricher {
private static final double TRUNK_PERCENTAGE = 0.2;
private static final double CROWN_PERCENTAGE = 1 - TRUNK_PERCENTAGE;
private static final int BOUNDING_BOX_INCREASE_IN_M = 100;
......@@ -145,20 +162,65 @@ public class GreenEnricher {
for (Waterway waterWay : osmData.getWaterways()) {
}
// trees
TreeKatasterData katasterData = parseTreeKatasterData(Paths.get("data", "Baum.shp"));
for (Iterator<TreePoint> 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();
}
}
}
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();
StringAttribute typeAttribute = new StringAttribute("type", tree.getType());
AbstractGenericAttributeProperty attributeProp = new AbstractGenericAttributeProperty(typeAttribute);
cover.getGenericAttributes().add(attributeProp);
cover.setId(UUID.randomUUID().toString());
cover.setLod2MultiSurface(new MultiSurfaceProperty(generatedTree));
cityModel.getCityObjectMembers().add(new AbstractCityObjectProperty(cover));
}
for (TreePoint tp : osmData.getTreePoints()) {
double trunkRadius = 0.2;
double trunkHeight = 3;
// standard tree
double trunkRadius = 0.89 / (2 * Math.PI);
double trunkHeight = TRUNK_PERCENTAGE * 11.46;
double crownHeight = 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, 3, 3, 10);
MultiSurface generatedTree = TreeGenerator.generateTree(coordinate, trunkRadius, trunkHeight, crownRadius, crownRadius, crownHeight);
SolitaryVegetationObject cover = new SolitaryVegetationObject();
StringAttribute typeAttribute = new StringAttribute("type", "Acer campestre");
AbstractGenericAttributeProperty attributeProp = new AbstractGenericAttributeProperty(typeAttribute);
cover.getGenericAttributes().add(attributeProp);
cover.setId(UUID.randomUUID().toString());
cover.setLod2MultiSurface(new MultiSurfaceProperty(generatedTree));
cityModel.getCityObjectMembers().add(new AbstractCityObjectProperty(cover));
}
//
// for (TreeRow tr : osmData.getTreeRows()) {
// System.out.println(tr);
......@@ -175,6 +237,56 @@ public class GreenEnricher {
}
private static TreeKatasterData parseTreeKatasterData(Path path) throws IOException {
TreeKatasterData result = new TreeKatasterData();
Map<String, Object> readParameters = new HashMap<>();
readParameters.put("url", path.toUri().toURL());
readParameters.put("charset", StandardCharsets.UTF_8);
DataStore dataStore = DataStoreFinder.getDataStore(readParameters);
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> source =
dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures();
try (FeatureIterator<SimpleFeature> features = collection.features()) {
while (features.hasNext()) {
SimpleFeature feature = features.next();
Tree tree = new Tree();
Point p = (Point) feature.getAttribute("the_geom");
tree.setPoint(p);
String type = feature.getAttribute("Bezeichnun").toString();
tree.setType(type);
Object treeHeightObject = feature.getAttribute("Baumhöhe");
if (treeHeightObject == null) {
continue;
}
int treeHeight = Integer.parseInt(treeHeightObject.toString());
double crownHeight = CROWN_PERCENTAGE * treeHeight;
double trunkHeight = TRUNK_PERCENTAGE * treeHeight;
tree.setCrownHeight(crownHeight);
tree.setTrunkHeight(trunkHeight);
Object crownWidth = feature.getAttribute("Kronenbrei");
if (crownWidth == null) {
continue;
}
tree.setCrownRadius(Float.parseFloat(crownWidth.toString()) / 2);
Object trunkCirc = feature.getAttribute("Stammumfan");
if (trunkCirc == null) {
continue;
}
tree.setTrunkRadius(Integer.parseInt(trunkCirc.toString()) / (2 * Math.PI) / 100);
result.getTrees().add(tree);
}
}
return result;
}
private static void convertWaterAreasToCityGML(CityModel cityModel, OsmData osmData) {
for (WaterArea waterArea : osmData.getWaterAreas()) {
WaterBody wb = new WaterBody();
......
package de.hft.stuttgart.citygml.green.osm;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Point;
public class Tree {
private Coordinate point;
private String type;
private Point point;
private double trunkHeight;
private double trunkRadius;
private double crownRadius;
private double crownHeight;
public Coordinate getPoint() {
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
public Point getPoint() {
return point;
}
public void setPoint(Coordinate point) {
public void setPoint(Point point) {
this.point = point;
}
......
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