Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Mayer
CircularGreenSimCity
Commits
f0f212e1
Commit
f0f212e1
authored
Apr 30, 2024
by
Matthias Betz
Browse files
add wkt polygon fitting
parent
fe063002
Changes
4
Hide whitespace changes
Inline
Side-by-side
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/alkis/AlkisGreenEnricher.java
View file @
f0f212e1
...
@@ -12,6 +12,7 @@ import java.util.HashSet;
...
@@ -12,6 +12,7 @@ import java.util.HashSet;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.Set
;
import
org.citygml4j.core.model.core.CityModel
;
import
org.citygml4j.core.model.core.CityModel
;
import
org.citygml4j.xml.CityGMLContextException
;
import
org.citygml4j.xml.CityGMLContextException
;
import
org.citygml4j.xml.reader.CityGMLReadException
;
import
org.citygml4j.xml.reader.CityGMLReadException
;
...
@@ -21,10 +22,19 @@ import org.geotools.data.DataStoreFinder;
...
@@ -21,10 +22,19 @@ import org.geotools.data.DataStoreFinder;
import
org.geotools.data.FeatureSource
;
import
org.geotools.data.FeatureSource
;
import
org.geotools.feature.FeatureCollection
;
import
org.geotools.feature.FeatureCollection
;
import
org.geotools.feature.FeatureIterator
;
import
org.geotools.feature.FeatureIterator
;
import
org.locationtech.jts.geom.CoordinateFilter
;
import
org.locationtech.jts.geom.Geometry
;
import
org.locationtech.jts.geom.MultiPolygon
;
import
org.locationtech.jts.geom.MultiPolygon
;
import
org.locationtech.jts.geom.Polygon
;
import
org.locationtech.jts.geom.Polygon
;
import
org.locationtech.jts.io.ParseException
;
import
org.locationtech.jts.io.WKTReader
;
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.SimpleFeature
;
import
org.opengis.feature.simple.SimpleFeatureType
;
import
org.opengis.feature.simple.SimpleFeatureType
;
import
de.hft.stuttgart.citygml.green.osm.GreenArea
;
import
de.hft.stuttgart.citygml.green.osm.GreenArea
;
import
de.hft.stuttgart.citygml.green.osm.GreenEnricher
;
import
de.hft.stuttgart.citygml.green.osm.GreenEnricher
;
import
de.hft.stuttgart.citygml.green.osm.LandUseArea
;
import
de.hft.stuttgart.citygml.green.osm.LandUseArea
;
...
@@ -36,6 +46,12 @@ import jakarta.xml.bind.JAXBException;
...
@@ -36,6 +46,12 @@ import jakarta.xml.bind.JAXBException;
public
class
AlkisGreenEnricher
public
class
AlkisGreenEnricher
{
{
private
static
final
CRSFactory
CRS_FACTORY
=
new
CRSFactory
();
private
static
final
String
WGS_84
=
"EPSG:4326"
;
private
static
final
CoordinateReferenceSystem
wgs84
=
CRS_FACTORY
.
createFromName
(
WGS_84
);
private
static
final
CoordinateReferenceSystem
targetCrs
=
CRS_FACTORY
.
createFromName
(
"EPSG:25832"
);
private
static
final
BasicCoordinateTransform
bct
=
new
BasicCoordinateTransform
(
wgs84
,
targetCrs
);
private
static
Set
<
String
>
greenAreaTypes
=
new
HashSet
<>();
private
static
Set
<
String
>
greenAreaTypes
=
new
HashSet
<>();
private
static
Set
<
String
>
roadAreaTypes
=
new
HashSet
<>();
private
static
Set
<
String
>
roadAreaTypes
=
new
HashSet
<>();
...
@@ -55,45 +71,69 @@ public class AlkisGreenEnricher
...
@@ -55,45 +71,69 @@ public class AlkisGreenEnricher
public
static
void
main
(
String
[]
args
)
public
static
void
main
(
String
[]
args
)
throws
IOException
,
InterruptedException
,
CityGMLContextException
,
CityGMLReadException
,
JAXBException
,
throws
IOException
,
InterruptedException
,
CityGMLContextException
,
CityGMLReadException
,
JAXBException
,
CityGMLWriteException
{
CityGMLWriteException
,
ParseException
{
System
.
out
.
println
(
"Reading CityGML file"
);
System
.
out
.
println
(
"Reading CityGML file"
);
Path
inFile
=
Paths
.
get
(
args
[
0
]);
Path
inFile
=
Paths
.
get
(
args
[
0
]);
Path
alkisDataPath
=
Paths
.
get
(
args
[
1
]);
// shp, shx and dbf should be present.
Path
alkisDataPath
=
Paths
.
get
(
args
[
1
]);
// shp, shx and dbf should be present.
Path
baumKatasterPath
=
Paths
.
get
(
args
[
2
]);
Path
baumKatasterPath
=
Paths
.
get
(
args
[
2
]);
String
outputSuffix
=
args
[
3
];
String
outputSuffix
=
args
[
3
];
Polygon
wktPolygon
=
null
;
if
(
args
.
length
==
5
)
{
WKTReader
wktReader
=
new
WKTReader
();
Geometry
wktGeometry
=
wktReader
.
read
(
args
[
4
]);
if
(!(
wktGeometry
instanceof
Polygon
))
{
throw
new
IllegalArgumentException
(
"WKT is not a polygon"
);
}
wktPolygon
=
(
Polygon
)
wktGeometry
;
wktPolygon
.
apply
((
CoordinateFilter
)
c
->
{
ProjCoordinate
p1
=
new
ProjCoordinate
();
p1
.
x
=
c
.
x
;
p1
.
y
=
c
.
y
;
ProjCoordinate
p2
=
new
ProjCoordinate
();
bct
.
transform
(
p1
,
p2
);
c
.
x
=
p2
.
x
;
c
.
y
=
p2
.
y
;
});
wktPolygon
.
geometryChanged
();
}
CityModel
cityModel
=
GreenEnricher
.
readCityGml
(
inFile
);
CityModel
cityModel
=
GreenEnricher
.
readCityGml
(
inFile
);
GreenEnricher
.
createTransformers
(
cityModel
);
GreenEnricher
.
createTransformers
(
cityModel
);
OsmData
osmData
=
new
OsmData
();
OsmData
osmData
=
new
OsmData
();
String
boundingBoxString
=
GreenEnricher
.
extractAndConvertBoundingBox
(
cityModel
,
osmData
);
//
String boundingBoxString = GreenEnricher.extractAndConvertBoundingBox(cityModel, osmData);
String
boundingBoxBasename
=
boundingBoxString
.
replace
(
","
,
"__"
).
replace
(
'.'
,
'_'
);
//
String boundingBoxBasename = boundingBoxString.replace(",", "__").replace('.', '_');
Path
osmCache
=
Paths
.
get
(
"data"
,
"cache"
,
"osm_response_"
+
boundingBoxBasename
+
".xml"
);
//
Path osmCache = Paths.get("data", "cache", "osm_response_" + boundingBoxBasename + ".xml");
if
(!
Files
.
exists
(
osmCache
))
{
//
if (!Files.exists(osmCache)) {
System
.
out
.
println
(
"Downloading OSM data for "
+
boundingBoxString
);
//
System.out.println("Downloading OSM data for " + boundingBoxString);
HttpResponse
<
String
>
response
=
GreenEnricher
.
getOsmData
(
boundingBoxString
);
//
HttpResponse<String> response = GreenEnricher.getOsmData(boundingBoxString);
Files
.
write
(
osmCache
,
response
.
body
().
getBytes
(
StandardCharsets
.
UTF_8
));
//
Files.write(osmCache, response.body().getBytes(StandardCharsets.UTF_8));
}
//
}
String
osmResponse
=
Files
.
readString
(
osmCache
);
//
String osmResponse = Files.readString(osmCache);
System
.
out
.
println
(
"Parsing OSM response"
);
//
System.out.println("Parsing OSM response");
GreenEnricher
.
parseOsmResponse
(
osmResponse
,
osmData
);
//
GreenEnricher.parseOsmResponse(osmResponse, osmData);
// ignore green areas from osm
// ignore green areas from osm
osmData
.
getGreenAreas
().
clear
();
//
osmData.getGreenAreas().clear();
parseAlkisData
(
osmData
,
alkisDataPath
);
parseAlkisData
(
osmData
,
alkisDataPath
);
System
.
out
.
println
(
"Fit data in bounding box"
);
System
.
out
.
println
(
"Fit data in bounding box"
);
GreenEnricher
.
fitToBoundingBox
(
osmData
);
if
(
wktPolygon
!=
null
)
{
GreenEnricher
.
fitToPolygon
(
osmData
,
wktPolygon
);
}
else
{
GreenEnricher
.
fitToBoundingBox
(
osmData
);
}
GreenEnricher
.
convertGreenAreasToCityGML
(
cityModel
,
osmData
.
getGreenAreas
());
GreenEnricher
.
convertGreenAreasToCityGML
(
cityModel
,
osmData
.
getGreenAreas
());
GreenEnricher
.
convertWaterAreasToCityGML
(
cityModel
,
osmData
);
GreenEnricher
.
convertWaterAreasToCityGML
(
cityModel
,
osmData
);
GreenEnricher
.
convertRoadAreasToCityGML
(
cityModel
,
osmData
);
GreenEnricher
.
convertRoadAreasToCityGML
(
cityModel
,
osmData
);
GreenEnricher
.
converLandUseAreasToCityGML
(
cityModel
,
osmData
);
GreenEnricher
.
conver
t
LandUseAreasToCityGML
(
cityModel
,
osmData
);
TreeUtils
.
insertTrees
(
cityModel
,
osmData
,
baumKatasterPath
);
TreeUtils
.
insertTrees
(
cityModel
,
osmData
,
baumKatasterPath
,
wktPolygon
);
GreenEnricher
.
clampToGround
(
cityModel
);
GreenEnricher
.
clampToGround
(
cityModel
);
...
...
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/GreenEnricher.java
View file @
f0f212e1
...
@@ -18,7 +18,7 @@ import java.util.Set;
...
@@ -18,7 +18,7 @@ import java.util.Set;
import
java.util.UUID
;
import
java.util.UUID
;
import
java.util.regex.Matcher
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
java.util.regex.Pattern
;
import
javax.xml.parsers.ParserConfigurationException
;
import
org.citygml4j.core.model.CityGMLVersion
;
import
org.citygml4j.core.model.CityGMLVersion
;
import
org.citygml4j.core.model.building.Building
;
import
org.citygml4j.core.model.building.Building
;
import
org.citygml4j.core.model.core.AbstractCityObject
;
import
org.citygml4j.core.model.core.AbstractCityObject
;
...
@@ -40,12 +40,15 @@ import org.citygml4j.xml.writer.CityGMLOutputFactory;
...
@@ -40,12 +40,15 @@ import org.citygml4j.xml.writer.CityGMLOutputFactory;
import
org.citygml4j.xml.writer.CityGMLWriteException
;
import
org.citygml4j.xml.writer.CityGMLWriteException
;
import
org.citygml4j.xml.writer.CityGMLWriter
;
import
org.citygml4j.xml.writer.CityGMLWriter
;
import
org.locationtech.jts.geom.Coordinate
;
import
org.locationtech.jts.geom.Coordinate
;
import
org.locationtech.jts.geom.CoordinateFilter
;
import
org.locationtech.jts.geom.Geometry
;
import
org.locationtech.jts.geom.Geometry
;
import
org.locationtech.jts.geom.GeometryFactory
;
import
org.locationtech.jts.geom.GeometryFactory
;
import
org.locationtech.jts.geom.LineString
;
import
org.locationtech.jts.geom.LineString
;
import
org.locationtech.jts.geom.MultiPolygon
;
import
org.locationtech.jts.geom.MultiPolygon
;
import
org.locationtech.jts.geom.Point
;
import
org.locationtech.jts.geom.Point
;
import
org.locationtech.jts.geom.Polygon
;
import
org.locationtech.jts.geom.Polygon
;
import
org.locationtech.jts.io.ParseException
;
import
org.locationtech.jts.io.WKTReader
;
import
org.locationtech.proj4j.BasicCoordinateTransform
;
import
org.locationtech.proj4j.BasicCoordinateTransform
;
import
org.locationtech.proj4j.CRSFactory
;
import
org.locationtech.proj4j.CRSFactory
;
import
org.locationtech.proj4j.CoordinateReferenceSystem
;
import
org.locationtech.proj4j.CoordinateReferenceSystem
;
...
@@ -60,6 +63,7 @@ import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
...
@@ -60,6 +63,7 @@ import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import
org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.LinearRing
;
import
org.xmlobjects.gml.model.geometry.primitives.LinearRing
;
import
org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty
;
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.OSM
;
import
de.hft.stuttgart.citygml.green.osm.jaxb.OsmMember
;
import
de.hft.stuttgart.citygml.green.osm.jaxb.OsmMember
;
import
de.hft.stuttgart.citygml.green.osm.jaxb.OsmNode
;
import
de.hft.stuttgart.citygml.green.osm.jaxb.OsmNode
;
...
@@ -73,7 +77,6 @@ import jakarta.xml.bind.JAXBException;
...
@@ -73,7 +77,6 @@ import jakarta.xml.bind.JAXBException;
public
class
GreenEnricher
public
class
GreenEnricher
{
{
private
static
final
int
BOUNDING_BOX_INCREASE_IN_M
=
100
;
private
static
final
int
BOUNDING_BOX_INCREASE_IN_M
=
100
;
// in degrees
// in degrees
...
@@ -107,17 +110,38 @@ public class GreenEnricher
...
@@ -107,17 +110,38 @@ public class GreenEnricher
private
static
final
URI
OVERPASS_API_URI
=
URI
.
create
(
"http://www.overpass-api.de/api/interpreter"
);
private
static
final
URI
OVERPASS_API_URI
=
URI
.
create
(
"http://www.overpass-api.de/api/interpreter"
);
private
static
final
CRSFactory
CRS_FACTORY
=
new
CRSFactory
();
private
static
final
CRSFactory
CRS_FACTORY
=
new
CRSFactory
();
private
static
CoordinateReferenceSystem
sourceCRS
;
private
static
CoordinateReferenceSystem
sourceCRS
;
private
static
CoordinateReferenceSystem
targetCRS
=
CRS_FACTORY
.
createFromName
(
"EPSG:4326"
);
private
static
CoordinateReferenceSystem
wgs84
=
CRS_FACTORY
.
createFromName
(
"EPSG:4326"
);
private
static
BasicCoordinateTransform
transform
;
private
static
BasicCoordinateTransform
transform
;
private
static
BasicCoordinateTransform
backTransform
;
private
static
BasicCoordinateTransform
backTransform
;
public
static
final
GeometryFactory
GEOM_FACTORY
=
new
GeometryFactory
();
public
static
final
GeometryFactory
GEOM_FACTORY
=
new
GeometryFactory
();
public
static
void
main
(
String
[]
args
)
throws
IOException
,
CityGMLContextException
,
CityGMLReadException
,
public
static
void
main
(
String
[]
args
)
throws
IOException
,
CityGMLContextException
,
CityGMLReadException
,
InterruptedException
,
ParserConfigurationException
,
CityGMLWriteException
,
JAXBException
{
InterruptedException
,
CityGMLWriteException
,
JAXBException
,
ParseException
{
System
.
out
.
println
(
"Reading CityGML file"
);
System
.
out
.
println
(
"Reading CityGML file"
);
Path
inFile
=
Paths
.
get
(
args
[
0
]);
Path
inFile
=
Paths
.
get
(
args
[
0
]);
Path
baumKatasterPath
=
Paths
.
get
(
args
[
1
]);
Path
baumKatasterPath
=
Paths
.
get
(
args
[
1
]);
String
outputSuffix
=
args
[
2
];
String
outputSuffix
=
args
[
2
];
Polygon
wktPolygon
=
null
;
if
(
args
.
length
==
4
)
{
WKTReader
wktReader
=
new
WKTReader
();
Geometry
wktGeometry
=
wktReader
.
read
(
args
[
3
]);
if
(!(
wktGeometry
instanceof
Polygon
))
{
throw
new
IllegalArgumentException
(
"WKT is not a polygon"
);
}
wktPolygon
=
(
Polygon
)
wktGeometry
;
CoordinateReferenceSystem
utm32
=
CRS_FACTORY
.
createFromName
(
"EPSG:25832"
);
BasicCoordinateTransform
bct
=
new
BasicCoordinateTransform
(
wgs84
,
utm32
);
wktPolygon
.
apply
((
CoordinateFilter
)
c
->
{
ProjCoordinate
p1
=
new
ProjCoordinate
();
p1
.
x
=
c
.
x
;
p1
.
y
=
c
.
y
;
ProjCoordinate
p2
=
new
ProjCoordinate
();
bct
.
transform
(
p1
,
p2
);
c
.
x
=
p2
.
x
;
c
.
y
=
p2
.
y
;
});
wktPolygon
.
geometryChanged
();
}
CityModel
cityModel
=
readCityGml
(
inFile
);
CityModel
cityModel
=
readCityGml
(
inFile
);
createTransformers
(
cityModel
);
createTransformers
(
cityModel
);
...
@@ -137,7 +161,11 @@ public class GreenEnricher
...
@@ -137,7 +161,11 @@ public class GreenEnricher
parseOsmResponse
(
osmResponse
,
osmData
);
parseOsmResponse
(
osmResponse
,
osmData
);
System
.
out
.
println
(
"Fit data in bounding box"
);
System
.
out
.
println
(
"Fit data in bounding box"
);
fitToBoundingBox
(
osmData
);
if
(
wktPolygon
!=
null
)
{
fitToPolygon
(
osmData
,
wktPolygon
);
}
else
{
fitToBoundingBox
(
osmData
);
}
System
.
out
.
println
(
"Filter intersecting areas"
);
System
.
out
.
println
(
"Filter intersecting areas"
);
List
<
GreenArea
>
greenAreas
=
osmData
.
getGreenAreas
();
List
<
GreenArea
>
greenAreas
=
osmData
.
getGreenAreas
();
...
@@ -147,7 +175,7 @@ public class GreenEnricher
...
@@ -147,7 +175,7 @@ public class GreenEnricher
convertWaterAreasToCityGML
(
cityModel
,
osmData
);
convertWaterAreasToCityGML
(
cityModel
,
osmData
);
// trees
// trees
TreeUtils
.
insertTrees
(
cityModel
,
osmData
,
baumKatasterPath
);
TreeUtils
.
insertTrees
(
cityModel
,
osmData
,
baumKatasterPath
,
wktPolygon
);
clampToGround
(
cityModel
);
clampToGround
(
cityModel
);
...
@@ -161,11 +189,27 @@ public class GreenEnricher
...
@@ -161,11 +189,27 @@ public class GreenEnricher
}
}
public
static
void
fitToPolygon
(
OsmData
osmData
,
Polygon
wktPolygon
)
{
fitGreenAreasToBounds
(
wktPolygon
,
osmData
.
getGreenAreas
());
fitRoadAreasToBounds
(
wktPolygon
,
osmData
.
getRoadAreas
());
fitLandUseAreasToBounds
(
wktPolygon
,
osmData
.
getLandUseAreas
());
fitWaterAreasToBounds
(
wktPolygon
,
osmData
.
getWaterAreas
());
for
(
Iterator
<
TreePoint
>
iterator
=
osmData
.
getTreePoints
().
iterator
();
iterator
.
hasNext
();)
{
TreePoint
tp
=
iterator
.
next
();
if
(!
osmData
.
getBoundingBox
().
contains
(
tp
.
getPoint
()))
{
iterator
.
remove
();
}
}
}
public
static
void
createTransformers
(
CityModel
cityModel
)
{
public
static
void
createTransformers
(
CityModel
cityModel
)
{
String
epsgCode
=
extractEpsgCode
(
cityModel
);
String
epsgCode
=
extractEpsgCode
(
cityModel
);
sourceCRS
=
CRS_FACTORY
.
createFromName
(
epsgCode
);
sourceCRS
=
CRS_FACTORY
.
createFromName
(
epsgCode
);
transform
=
new
BasicCoordinateTransform
(
sourceCRS
,
targetCRS
);
transform
=
new
BasicCoordinateTransform
(
sourceCRS
,
wgs84
);
backTransform
=
new
BasicCoordinateTransform
(
targetCRS
,
sourceCRS
);
backTransform
=
new
BasicCoordinateTransform
(
wgs84
,
sourceCRS
);
}
}
...
@@ -202,11 +246,10 @@ public class GreenEnricher
...
@@ -202,11 +246,10 @@ public class GreenEnricher
}
}
public
static
void
fitToBoundingBox
(
OsmData
osmData
)
{
public
static
void
fitToBoundingBox
(
OsmData
osmData
)
{
fitGreenAreas
(
osmData
,
osmData
.
getGreenAreas
());
fitGreenAreasToBounds
(
osmData
.
getBoundingBox
(),
osmData
.
getGreenAreas
());
fitRoadAreas
(
osmData
,
osmData
.
getRoadAreas
());
fitRoadAreasToBounds
(
osmData
.
getBoundingBox
(),
osmData
.
getRoadAreas
());
fitLandUseAreas
(
osmData
,
osmData
.
getLandUseAreas
());
fitLandUseAreasToBounds
(
osmData
.
getBoundingBox
(),
osmData
.
getLandUseAreas
());
fitWaterAreasToBounds
(
osmData
.
getBoundingBox
(),
osmData
.
getWaterAreas
());
clipWaterAreasToBoundingBox
(
osmData
);
for
(
Iterator
<
TreePoint
>
iterator
=
osmData
.
getTreePoints
().
iterator
();
iterator
.
hasNext
();)
{
for
(
Iterator
<
TreePoint
>
iterator
=
osmData
.
getTreePoints
().
iterator
();
iterator
.
hasNext
();)
{
TreePoint
tp
=
iterator
.
next
();
TreePoint
tp
=
iterator
.
next
();
...
@@ -217,11 +260,11 @@ public class GreenEnricher
...
@@ -217,11 +260,11 @@ public class GreenEnricher
}
}
private
static
void
fitLandUseAreas
(
OsmData
osmData
,
List
<
LandUseArea
>
landUseAreas
)
{
private
static
void
fitLandUseAreas
ToBounds
(
Geometry
bounds
,
List
<
LandUseArea
>
landUseAreas
)
{
List
<
LandUseArea
>
newLandUseAreas
=
new
ArrayList
<>();
List
<
LandUseArea
>
newLandUseAreas
=
new
ArrayList
<>();
for
(
LandUseArea
landUseArea
:
landUseAreas
)
{
for
(
LandUseArea
landUseArea
:
landUseAreas
)
{
Polygon
area
=
landUseArea
.
getArea
();
Polygon
area
=
landUseArea
.
getArea
();
Geometry
intersection
=
area
.
intersection
(
osmData
.
getBoundingBox
()
);
Geometry
intersection
=
area
.
intersection
(
bounds
);
if
(
intersection
instanceof
MultiPolygon
multi
)
{
if
(
intersection
instanceof
MultiPolygon
multi
)
{
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
landUseArea
.
setArea
(
poly1
);
landUseArea
.
setArea
(
poly1
);
...
@@ -238,11 +281,11 @@ public class GreenEnricher
...
@@ -238,11 +281,11 @@ public class GreenEnricher
}
}
private
static
void
fitRoadAreas
(
OsmData
osmData
,
List
<
RoadArea
>
roadAreas
)
{
private
static
void
fitRoadAreas
ToBounds
(
Geometry
bounds
,
List
<
RoadArea
>
roadAreas
)
{
List
<
RoadArea
>
newRoadAreas
=
new
ArrayList
<>();
List
<
RoadArea
>
newRoadAreas
=
new
ArrayList
<>();
for
(
RoadArea
roadArea
:
roadAreas
)
{
for
(
RoadArea
roadArea
:
roadAreas
)
{
Polygon
area
=
roadArea
.
getArea
();
Polygon
area
=
roadArea
.
getArea
();
Geometry
intersection
=
area
.
intersection
(
osmData
.
getBoundingBox
()
);
Geometry
intersection
=
area
.
intersection
(
bounds
);
if
(
intersection
instanceof
MultiPolygon
multi
)
{
if
(
intersection
instanceof
MultiPolygon
multi
)
{
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
roadArea
.
setArea
(
poly1
);
roadArea
.
setArea
(
poly1
);
...
@@ -259,11 +302,11 @@ public class GreenEnricher
...
@@ -259,11 +302,11 @@ public class GreenEnricher
}
}
private
static
void
fitGreenAreas
(
OsmData
osmData
,
List
<
GreenArea
>
greenAreas
)
{
private
static
void
fitGreenAreas
ToBounds
(
Geometry
bounds
,
List
<
GreenArea
>
greenAreas
)
{
List
<
GreenArea
>
newGreenAreas
=
new
ArrayList
<>();
List
<
GreenArea
>
newGreenAreas
=
new
ArrayList
<>();
for
(
GreenArea
greenArea
:
greenAreas
)
{
for
(
GreenArea
greenArea
:
greenAreas
)
{
Polygon
area
=
greenArea
.
getArea
();
Polygon
area
=
greenArea
.
getArea
();
Geometry
intersection
=
area
.
intersection
(
osmData
.
getBoundingBox
()
);
Geometry
intersection
=
area
.
intersection
(
bounds
);
if
(
intersection
instanceof
MultiPolygon
multi
)
{
if
(
intersection
instanceof
MultiPolygon
multi
)
{
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
greenArea
.
setArea
(
poly1
);
greenArea
.
setArea
(
poly1
);
...
@@ -279,11 +322,11 @@ public class GreenEnricher
...
@@ -279,11 +322,11 @@ public class GreenEnricher
greenAreas
.
addAll
(
newGreenAreas
);
greenAreas
.
addAll
(
newGreenAreas
);
}
}
private
static
void
clip
WaterAreasToBound
ingBox
(
OsmData
osmData
)
{
private
static
void
fit
WaterAreasToBound
s
(
Geometry
bounds
,
List
<
WaterArea
>
waterAreas
)
{
List
<
WaterArea
>
newWaterAreas
=
new
ArrayList
<>();
List
<
WaterArea
>
newWaterAreas
=
new
ArrayList
<>();
for
(
WaterArea
waterArea
:
osmData
.
getW
aterAreas
()
)
{
for
(
WaterArea
waterArea
:
w
aterAreas
)
{
Polygon
area
=
waterArea
.
getArea
();
Polygon
area
=
waterArea
.
getArea
();
Geometry
intersection
=
area
.
intersection
(
osmData
.
getBoundingBox
()
);
Geometry
intersection
=
area
.
intersection
(
bounds
);
if
(
intersection
instanceof
MultiPolygon
multi
)
{
if
(
intersection
instanceof
MultiPolygon
multi
)
{
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
waterArea
.
setArea
(
poly1
);
waterArea
.
setArea
(
poly1
);
...
@@ -296,6 +339,7 @@ public class GreenEnricher
...
@@ -296,6 +339,7 @@ public class GreenEnricher
waterArea
.
setArea
((
Polygon
)
intersection
);
waterArea
.
setArea
((
Polygon
)
intersection
);
}
}
}
}
waterAreas
.
addAll
(
newWaterAreas
);
}
}
private
static
void
removeDuplicateAreas
(
List
<
GreenArea
>
greenAreas
)
{
private
static
void
removeDuplicateAreas
(
List
<
GreenArea
>
greenAreas
)
{
...
@@ -808,7 +852,7 @@ public class GreenEnricher
...
@@ -808,7 +852,7 @@ public class GreenEnricher
}
}
public
static
void
converLandUseAreasToCityGML
(
CityModel
cityModel
,
OsmData
osmData
)
{
public
static
void
conver
t
LandUseAreasToCityGML
(
CityModel
cityModel
,
OsmData
osmData
)
{
for
(
LandUseArea
landUseArea
:
osmData
.
getLandUseAreas
())
{
for
(
LandUseArea
landUseArea
:
osmData
.
getLandUseAreas
())
{
LandUse
landUse
=
new
LandUse
();
LandUse
landUse
=
new
LandUse
();
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
poly
=
convertToCityGmlPoly
(
landUseArea
.
getArea
());
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
poly
=
convertToCityGmlPoly
(
landUseArea
.
getArea
());
...
...
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/TreeUtils.java
View file @
f0f212e1
...
@@ -8,26 +8,31 @@ import org.citygml4j.core.model.core.AbstractCityObjectProperty;
...
@@ -8,26 +8,31 @@ import org.citygml4j.core.model.core.AbstractCityObjectProperty;
import
org.citygml4j.core.model.core.CityModel
;
import
org.citygml4j.core.model.core.CityModel
;
import
org.citygml4j.core.model.vegetation.SolitaryVegetationObject
;
import
org.citygml4j.core.model.vegetation.SolitaryVegetationObject
;
import
org.locationtech.jts.geom.Coordinate
;
import
org.locationtech.jts.geom.Coordinate
;
import
org.locationtech.jts.geom.GeometryFactory
;
import
org.locationtech.jts.geom.Polygon
;
import
org.xmlobjects.gml.model.basictypes.Code
;
import
org.xmlobjects.gml.model.basictypes.Code
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty
;
public
class
TreeUtils
{
public
class
TreeUtils
private
static
final
GeometryFactory
FACTORY
=
new
GeometryFactory
();
{
public
static
void
insertTrees
(
CityModel
cityModel
,
OsmData
osmData
,
Path
baumKatasterPath
)
throws
IOException
{
public
static
void
insertTrees
(
CityModel
cityModel
,
OsmData
osmData
,
Path
baumKatasterPath
,
Polygon
wktPolygon
)
throws
IOException
{
TreeKatasterData
katasterData
=
TreeKatasterData
.
parseTreeKatasterData
(
baumKatasterPath
);
TreeKatasterData
katasterData
=
TreeKatasterData
.
parseTreeKatasterData
(
baumKatasterPath
);
generateTreesFromKataster
(
cityModel
,
katasterData
);
generateTreesFromKataster
(
cityModel
,
katasterData
,
osmData
,
wktPolygon
);
// TreeKatasterData katasterData2 = TreeKatasterData.parseTreeKatasterData(Paths.get("data", "Trees_realistic_20240201.shp"));
// TreeKatasterData katasterData2 =
// generateTreesFromKataster(cityModel, katasterData2);
// TreeKatasterData.parseTreeKatasterData(Paths.get("data",
// "Trees_realistic_20240201.shp"));
// generateTreesFromKataster(cityModel, katasterData2);
// All kataster trees are taken, osm trees are removed
// All kataster trees are taken, osm trees are removed
filterDuplicateTreesFromOSM
(
osmData
,
katasterData
);
//
filterDuplicateTreesFromOSM(osmData, katasterData);
//
filterDuplicateTreesFromOSM(osmData, katasterData2);
//
filterDuplicateTreesFromOSM(osmData, katasterData2);
generateTreesFromOSM
(
cityModel
,
osmData
);
//
generateTreesFromOSM(cityModel, osmData
, wktPolygon
);
}
}
...
@@ -43,14 +48,19 @@ public class TreeUtils
...
@@ -43,14 +48,19 @@ public class TreeUtils
}
}
}
}
private
static
void
generateTreesFromOSM
(
CityModel
cityModel
,
OsmData
osmData
)
{
private
static
void
generateTreesFromOSM
(
CityModel
cityModel
,
OsmData
osmData
,
Polygon
wktPolygon
)
{
for
(
TreePoint
tp
:
osmData
.
getTreePoints
())
{
for
(
TreePoint
tp
:
osmData
.
getTreePoints
())
{
Coordinate
coordinate
=
tp
.
getPoint
().
getCoordinate
();
if
((
wktPolygon
!=
null
&&
!
wktPolygon
.
contains
(
FACTORY
.
createPoint
(
coordinate
)))
||
!
osmData
.
getBoundingBox
().
contains
(
FACTORY
.
createPoint
(
coordinate
)))
{
// ignore trees outside bounds
continue
;
}
// standard tree
// standard tree
double
trunkRadius
=
0.89
/
(
2
*
Math
.
PI
);
double
trunkRadius
=
0.89
/
(
2
*
Math
.
PI
);
double
trunkHeight
=
TreeKatasterData
.
TRUNK_PERCENTAGE
*
11.46
;
double
trunkHeight
=
TreeKatasterData
.
TRUNK_PERCENTAGE
*
11.46
;
double
crownHeight
=
TreeKatasterData
.
CROWN_PERCENTAGE
*
11.46
;
double
crownHeight
=
TreeKatasterData
.
CROWN_PERCENTAGE
*
11.46
;
double
crownRadius
=
8
/
2
d
;
double
crownRadius
=
8
/
2
d
;
Coordinate
coordinate
=
tp
.
getPoint
().
getCoordinate
();
if
(
Double
.
isNaN
(
coordinate
.
z
))
{
if
(
Double
.
isNaN
(
coordinate
.
z
))
{
coordinate
.
z
=
0
;
coordinate
.
z
=
0
;
}
}
...
@@ -64,14 +74,21 @@ public class TreeUtils
...
@@ -64,14 +74,21 @@ public class TreeUtils
}
}
}
}
private
static
void
generateTreesFromKataster
(
CityModel
cityModel
,
TreeKatasterData
katasterData
)
{
private
static
void
generateTreesFromKataster
(
CityModel
cityModel
,
TreeKatasterData
katasterData
,
OsmData
osmData
,
Polygon
wktPolygon
)
{
for
(
Tree
tree
:
katasterData
.
getTrees
())
{
for
(
Tree
tree
:
katasterData
.
getTrees
())
{
// check if tree is in area
Coordinate
coordinate
=
tree
.
getPoint
().
getCoordinate
();
if
((
wktPolygon
!=
null
&&
!
wktPolygon
.
contains
(
FACTORY
.
createPoint
(
coordinate
)))
||
!
osmData
.
getBoundingBox
().
contains
(
FACTORY
.
createPoint
(
coordinate
)))
{
continue
;
}
double
trunkRadius
=
tree
.
getTrunkRadius
();
double
trunkRadius
=
tree
.
getTrunkRadius
();
double
trunkHeight
=
tree
.
getTrunkHeight
();
double
trunkHeight
=
tree
.
getTrunkHeight
();
double
crownHeight
=
tree
.
getCrownHeight
();
double
crownHeight
=
tree
.
getCrownHeight
();
double
crownRadius
=
tree
.
getCrownRadius
();
double
crownRadius
=
tree
.
getCrownRadius
();
Coordinate
coordinate
=
tree
.
getPoint
().
getCoordinate
();
if
(
Double
.
isNaN
(
coordinate
.
z
))
{
if
(
Double
.
isNaN
(
coordinate
.
z
))
{
coordinate
.
z
=
0
;
coordinate
.
z
=
0
;
}
}
...
...
enrich-citygml-with-greenarea/src/test/java/de/hft/stuttgart/citygml/green/alkis/AlkisGreenEnricherTest.java
View file @
f0f212e1
...
@@ -21,7 +21,8 @@ class AlkisGreenEnricherTest
...
@@ -21,7 +21,8 @@ class AlkisGreenEnricherTest
"data/tn_09663/Nutzung.shp"
,
// ALKIS Data
"data/tn_09663/Nutzung.shp"
,
// ALKIS Data
//NOTE: From https://transfer.hft-stuttgart.de/gitlab/circulargreensimcity/circulargreensimcity/-/issues/26#note_6544
//NOTE: From https://transfer.hft-stuttgart.de/gitlab/circulargreensimcity/circulargreensimcity/-/issues/26#note_6544
"data/Trees/Trees_realisticScenario_20240201.shp"
,
// Added trees, in Baumkatasterformat,
"data/Trees/Trees_realisticScenario_20240201.shp"
,
// Added trees, in Baumkatasterformat,
"alkis_test"
// Output GML suffix
"alkis_test"
,
// Output GML suffix
"POLYGON((9.946874 49.803172, 9.949785 49.803205, 9.952122 49.803312, 9.953435 49.803089, 9.956488 49.803150, 9.955465 49.802374, 9.953216 49.800916, 9.952371 49.800676, 9.951810 49.800509, 9.949172 49.800829, 9.946792 49.800796, 9.946874 49.803172))"
};
};
AlkisGreenEnricher
.
main
(
args
);
AlkisGreenEnricher
.
main
(
args
);
assertTrue
(
Files
.
exists
(
outputGML
));
assertTrue
(
Files
.
exists
(
outputGML
));
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment