Commit 690d78b9 authored by Matthias Betz's avatar Matthias Betz
Browse files

initial commit for osm data enricher

parent fb3bf74b
# Created by https://www.gitignore.io/api/java,maven,macos,linux,eclipse,windows,netbeans,intellij
# Edit at https://www.gitignore.io/?templates=java,maven,macos,linux,eclipse,windows,netbeans,intellij
# User specific
.sonarlint/
Servers/
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
### Eclipse Patch ###
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Annotation Processing
.apt_generated
.sts4-cache/
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/sonarlint
### Java ###
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
### NetBeans ###
**/nbproject/private/
**/nbproject/Makefile-*.mk
**/nbproject/Package-*.bash
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
### Windows ###
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.gitignore.io/api/java,maven,macos,linux,eclipse,windows,netbeans,intellij
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.hft.stuttgart</groupId>
<artifactId>enrich-citygml-with-osm</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.citygml4j/citygml4j-core -->
<dependency>
<groupId>org.citygml4j</groupId>
<artifactId>citygml4j-core</artifactId>
<version>3.0.0-rc.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.locationtech.proj4j/proj4j -->
<dependency>
<groupId>org.locationtech.proj4j</groupId>
<artifactId>proj4j</artifactId>
<version>1.1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.locationtech.jts/jts-core -->
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.19.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.citygml4j/citygml4j-xml -->
<dependency>
<groupId>org.citygml4j</groupId>
<artifactId>citygml4j-xml</artifactId>
<version>3.0.0-rc.5</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package de.hft.stuttgart.citygml.green.osm;
import org.locationtech.jts.geom.Polygon;
public class GreenArea {
private Polygon area;
public GreenArea() {
}
public GreenArea(Polygon area) {
this.area = area;
}
public void setArea(Polygon area) {
this.area = area;
}
public Polygon getArea() {
return area;
}
@Override
public String toString() {
return "GreenArea [area=" + area + "]";
}
}
package de.hft.stuttgart.citygml.green.osm;
import java.util.ArrayList;
import java.util.List;
import org.locationtech.jts.geom.Polygon;
public class OsmData {
private Polygon boundingBox;
private List<TreePoint> treePoints = new ArrayList<>();
private List<GreenArea> greenAreas = new ArrayList<>();
private List<TreeRow> treeRows = new ArrayList<>();
private List<Waterway> waterways = new ArrayList<>();
private List<WaterArea> waterAreas = new ArrayList<>();
public void setBoundingBox(Polygon boundingBox) {
this.boundingBox = boundingBox;
}
public List<WaterArea> getWaterAreas() {
return waterAreas;
}
public List<Waterway> getWaterways() {
return waterways;
}
public Polygon getBoundingBox() {
return boundingBox;
}
public List<GreenArea> getGreenAreas() {
return greenAreas;
}
public List<TreePoint> getTreePoints() {
return treePoints;
}
public List<TreeRow> getTreeRows() {
return treeRows;
}
}
package de.hft.stuttgart.citygml.green.osm;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Polygon;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
public class TreeGenerator {
private static final double TRUNK_INCREASE_FACTOR = 1.2;
public static MultiSurface generateTree(Coordinate point, double trunkRadius, double trunkHeight,
double crownXRadius, double crownYRadius, double crownHeight) {
List<Coordinate> trunkWestCoordinateList = new ArrayList<>();
trunkWestCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y - trunkRadius, 0));
double drawTrunkHeight = trunkHeight * TRUNK_INCREASE_FACTOR;
trunkWestCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y - trunkRadius, drawTrunkHeight));
trunkWestCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y + trunkRadius, drawTrunkHeight));
trunkWestCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y + trunkRadius, 0));
trunkWestCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y - trunkRadius, 0));
Polygon trunkWestPolygon = convertPolygon(trunkWestCoordinateList);
var trunkWestConvertedPolygon = GreenEnricher.convertToCityGmlPoly(trunkWestPolygon);
MultiSurface ms = new MultiSurface();
ms.getSurfaceMember().add(new SurfaceProperty(trunkWestConvertedPolygon));
List<Coordinate> trunkEastCoordinateList = new ArrayList<>();
trunkEastCoordinateList.add(new Coordinate(point.x + trunkRadius, point.y - trunkRadius, 0));
trunkEastCoordinateList.add(new Coordinate(point.x + trunkRadius, point.y + trunkRadius, 0));
trunkEastCoordinateList.add(new Coordinate(point.x + trunkRadius, point.y + trunkRadius, drawTrunkHeight));
trunkEastCoordinateList.add(new Coordinate(point.x + trunkRadius, point.y - trunkRadius, drawTrunkHeight));
trunkEastCoordinateList.add(new Coordinate(point.x + trunkRadius, point.y - trunkRadius, 0));
Polygon trunkEastPolygon = convertPolygon(trunkEastCoordinateList);
var trunkEastConvertedPolygon = GreenEnricher.convertToCityGmlPoly(trunkEastPolygon);
ms.getSurfaceMember().add(new SurfaceProperty(trunkEastConvertedPolygon));
List<Coordinate> trunkSouthCoordinateList = new ArrayList<>();
trunkSouthCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y - trunkRadius, 0));
trunkSouthCoordinateList.add(new Coordinate(point.x + trunkRadius, point.y - trunkRadius, 0));
trunkSouthCoordinateList.add(new Coordinate(point.x + trunkRadius, point.y - trunkRadius, drawTrunkHeight));
trunkSouthCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y - trunkRadius, drawTrunkHeight));
trunkSouthCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y - trunkRadius, 0));
Polygon trunkSouthPolygon = convertPolygon(trunkSouthCoordinateList);
var trunkSouthConvertedPolygon = GreenEnricher.convertToCityGmlPoly(trunkSouthPolygon);
ms.getSurfaceMember().add(new SurfaceProperty(trunkSouthConvertedPolygon));
List<Coordinate> trunkNorthCoordinateList = new ArrayList<>();
trunkNorthCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y + trunkRadius, 0));
trunkNorthCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y + trunkRadius, drawTrunkHeight));
trunkNorthCoordinateList.add(new Coordinate(point.x + trunkRadius, point.y + trunkRadius, drawTrunkHeight));
trunkNorthCoordinateList.add(new Coordinate(point.x + trunkRadius, point.y + trunkRadius, 0));
trunkNorthCoordinateList.add(new Coordinate(point.x - trunkRadius, point.y + trunkRadius, 0));
Polygon trunkNorthPolygon = convertPolygon(trunkNorthCoordinateList);
var trunkNorthConvertedPolygon = GreenEnricher.convertToCityGmlPoly(trunkNorthPolygon);
ms.getSurfaceMember().add(new SurfaceProperty(trunkNorthConvertedPolygon));
/*-
* Spheroid formula:
* x = a * sin(thetha) * cos(phi)
* y = b * sin(thetha) * sin(phi)
* z = c * cos(thetha)
*
* 0 <= theta <= pi
* 0 <= phi < 2 pi
*/
// create crown
// divide by 2 to get radius, height is diameter
double c = crownHeight / 2D;
double a = crownXRadius;
double b = crownYRadius;
int numberOfThetaRings = 5;
int numberOfPhiRings = 10;
double thetaDelta = Math.PI / (numberOfThetaRings - 1);
double phiDelta = Math.PI * 2 / numberOfPhiRings;
List<List<Coordinate>> ringCoordinates = new ArrayList<>();
// top point triangles
Coordinate topPoint = new Coordinate(point.x, point.y, point.z + c + trunkHeight + c);
ringCoordinates.add(Collections.singletonList(topPoint));
for (int i = 1; i < numberOfThetaRings - 1; i++) {
double theta = i * thetaDelta;
List<Coordinate> coords = new ArrayList<>();
ringCoordinates.add(coords);
for (int j = 0; j < numberOfPhiRings; j++) {
double phi = j * phiDelta;
double x = a * Math.sin(theta) * Math.cos(phi) + point.x;
double y = b * Math.sin(theta) * Math.sin(phi) + point.y;
double z = c * Math.cos(theta) + point.z + trunkHeight + c;
Coordinate p1 = new Coordinate(x, y, z);
coords.add(p1);
}
}
Coordinate bottomPoint = new Coordinate(point.x, point.y, point.z + trunkHeight);
ringCoordinates.add(Collections.singletonList(bottomPoint));
List<Coordinate> secondRing = ringCoordinates.get(1);
for (int i = 0; i < secondRing.size(); i++) {
Coordinate[] coordArray = new Coordinate[] { topPoint, secondRing.get(i), secondRing.get((i + 1) % secondRing.size()), topPoint };
Polygon polygon = GreenEnricher.geomFactory.createPolygon(coordArray);
var convertedPoly = GreenEnricher.convertToCityGmlPoly(polygon);
ms.getSurfaceMember().add(new SurfaceProperty(convertedPoly));
}
for (int i = 1; i < ringCoordinates.size() - 2; i++) {
List<Coordinate> topRing = ringCoordinates.get(i);
List<Coordinate> bottomRing = ringCoordinates.get(i + 1);
for (int j = 0; j < topRing.size(); j++) {
int nextRingIndex = (j + 1) % topRing.size();
Coordinate p1 = topRing.get(j);
Coordinate p2 = topRing.get(nextRingIndex);
Coordinate p3 = bottomRing.get(j);
Coordinate p4 = bottomRing.get(nextRingIndex);
Coordinate[] coordArray = new Coordinate[] { p1, p3, p4, p2, p1 };
Polygon polygon = GreenEnricher.geomFactory.createPolygon(coordArray);
var convertedPoly = GreenEnricher.convertToCityGmlPoly(polygon);
ms.getSurfaceMember().add(new SurfaceProperty(convertedPoly));
}
}
// bottom point triangles
List<Coordinate> bottomRing = ringCoordinates.get(ringCoordinates.size() - 2);
for (int i = 0; i < bottomRing.size(); i++) {
int nextRingIndex = (i + 1) % bottomRing.size();
Coordinate p1 = bottomRing.get(i);
Coordinate p2 = bottomRing.get(nextRingIndex);
Coordinate[] coordArray = new Coordinate[] { p2, p1, bottomPoint, p2 };
Polygon polygon = GreenEnricher.geomFactory.createPolygon(coordArray);
var convertedPoly = GreenEnricher.convertToCityGmlPoly(polygon);
ms.getSurfaceMember().add(new SurfaceProperty(convertedPoly));
}
return ms;
}
private static Polygon convertPolygon(List<Coordinate> trunkWestCoordinateList) {
return GreenEnricher.geomFactory
.createPolygon(trunkWestCoordinateList.toArray(new Coordinate[trunkWestCoordinateList.size()]));
}
}
package de.hft.stuttgart.citygml.green.osm;
import org.locationtech.jts.geom.Point;
public class TreePoint {
private Point point;
public TreePoint() {
}
public TreePoint(Point point) {
this.point = point;
}
public void setPoint(Point point) {
this.point = point;
}
public Point getPoint() {
return point;
}
@Override
public String toString() {
return "TreePoint [point=" + point + "]";
}
}
package de.hft.stuttgart.citygml.green.osm;
import org.locationtech.jts.geom.LineString;
public class TreeRow {
private LineString line;
public TreeRow() {
}