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
3e042784
Commit
3e042784
authored
Mar 31, 2023
by
Matthias Betz
Browse files
add alkis land use parsing
parent
eacaa411
Changes
19
Show whitespace changes
Inline
Side-by-side
enrich-citygml-with-greenarea/pom.xml
View file @
3e042784
...
...
@@ -25,6 +25,19 @@
</repositories>
<dependencies>
<!-- https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api -->
<dependency>
<groupId>
jakarta.xml.bind
</groupId>
<artifactId>
jakarta.xml.bind-api
</artifactId>
<version>
4.0.0
</version>
</dependency>
<dependency>
<groupId>
com.sun.xml.bind
</groupId>
<artifactId>
jaxb-impl
</artifactId>
<version>
4.0.0
</version>
<scope>
runtime
</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.geotools/gt-shapefile -->
<dependency>
<groupId>
org.geotools
</groupId>
...
...
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/alkis/AlkisGreenEnricher.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.alkis
;
import
java.io.IOException
;
import
java.net.MalformedURLException
;
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
;
import
org.citygml4j.xml.writer.CityGMLWriteException
;
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.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
;
import
de.hft.stuttgart.citygml.green.osm.OsmData
;
import
de.hft.stuttgart.citygml.green.osm.RoadArea
;
import
de.hft.stuttgart.citygml.green.osm.TreeUtils
;
import
jakarta.xml.bind.JAXBException
;
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
{
System
.
out
.
println
(
"Reading CityGML file"
);
Path
inFile
=
Paths
.
get
(
args
[
0
]);
CityModel
cityModel
=
GreenEnricher
.
readCityGml
(
inFile
);
GreenEnricher
.
createTransformers
(
cityModel
);
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"
));
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.gml"
);
System
.
out
.
println
(
"Writing output file."
);
GreenEnricher
.
writeCityGML
(
cityModel
,
outputPath
);
System
.
out
.
println
(
"Done"
);
}
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
);
DataStore
dataStore
=
DataStoreFinder
.
getDataStore
(
readParameters
);
String
typeName
=
dataStore
.
getTypeNames
()[
0
];
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
)
{
throw
new
IllegalStateException
();
}
if
(
greenAreaTypes
.
contains
(
nutzart
))
{
greenAreas
.
add
(
new
GreenArea
((
Polygon
)
geometry
.
getGeometryN
(
0
)));
}
else
if
(
roadAreaTypes
.
contains
(
nutzart
))
{
roadAreas
.
add
(
new
RoadArea
((
Polygon
)
geometry
.
getGeometryN
(
0
)));
}
else
{
landUseAreas
.
add
(
new
LandUseArea
((
Polygon
)
geometry
.
getGeometryN
(
0
)));
}
}
}
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/GreenEnricher.java
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm
;
import
java.io.ByteArrayInputStream
;
import
java.io.IOException
;
import
java.
net.MalformedURLException
;
import
java.
io.StringReader
;
import
java.net.URI
;
import
java.net.URLEncoder
;
import
java.net.http.HttpClient
;
...
...
@@ -13,20 +12,13 @@ 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
;
import
javax.xml.XMLConstants
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
javax.xml.parsers.ParserConfigurationException
;
import
org.citygml4j.core.model.CityGMLVersion
;
...
...
@@ -34,12 +26,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.landuse.LandUse
;
import
org.citygml4j.core.model.transportation.Road
;
import
org.citygml4j.core.model.vegetation.PlantCover
;
import
org.citygml4j.core.model.vegetation.SolitaryVegetationObject
;
import
org.citygml4j.core.model.waterbody.WaterBody
;
import
org.citygml4j.core.visitor.ObjectWalker
;
import
org.citygml4j.xml.CityGMLContext
;
...
...
@@ -51,11 +41,6 @@ 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
;
...
...
@@ -67,12 +52,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
;
import
org.xml.sax.SAXException
;
import
org.xmlobjects.gml.model.geometry.DirectPosition
;
import
org.xmlobjects.gml.model.geometry.DirectPositionList
;
import
org.xmlobjects.gml.model.geometry.Envelope
;
...
...
@@ -82,10 +63,17 @@ import org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty;
import
org.xmlobjects.gml.model.geometry.primitives.LinearRing
;
import
org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty
;
public
class
GreenEnricher
{
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
;
import
de.hft.stuttgart.citygml.green.osm.jaxb.OsmRelation
;
import
de.hft.stuttgart.citygml.green.osm.jaxb.OsmTag
;
import
de.hft.stuttgart.citygml.green.osm.jaxb.OsmWay
;
import
de.hft.stuttgart.citygml.green.osm.jaxb.WayNode
;
import
jakarta.xml.bind.JAXBContext
;
import
jakarta.xml.bind.JAXBException
;
private
static
final
double
TRUNK_PERCENTAGE
=
0.2
;
private
static
final
double
CROWN_PERCENTAGE
=
1
-
TRUNK_PERCENTAGE
;
public
class
GreenEnricher
{
private
static
final
int
BOUNDING_BOX_INCREASE_IN_M
=
100
;
...
...
@@ -113,6 +101,7 @@ public class GreenEnricher {
nwr["
type
"="
waterway
"];
nwr["
waterway
"="
stream
"];
nwr["
water
"="
pond
"];
nwr["
landuse
"="
vineyard
"];
);
out geom;"""
;
...
...
@@ -122,23 +111,18 @@ public class GreenEnricher {
private
static
CoordinateReferenceSystem
targetCRS
=
CRS_FACTORY
.
createFromName
(
"EPSG:4326"
);
private
static
BasicCoordinateTransform
transform
;
private
static
BasicCoordinateTransform
backTransform
;
public
static
GeometryFactory
geomFactory
=
new
GeometryFactory
();
public
static
final
GeometryFactory
GEOM_FACTORY
=
new
GeometryFactory
();
public
static
void
main
(
String
[]
args
)
throws
IOException
,
CityGMLContextException
,
CityGMLReadException
,
InterruptedException
,
ParserConfigurationException
,
SAXException
,
CityGMLWrite
Exception
{
InterruptedException
,
ParserConfigurationException
,
CityGMLWriteException
,
JAXB
Exception
{
System
.
out
.
println
(
"Reading CityGML file"
);
Path
inFile
=
Paths
.
get
(
args
[
0
]);
CityModel
cityModel
=
readCityGml
(
inFile
);
String
epsgCode
=
extractEpsgCode
(
cityModel
);
sourceCRS
=
CRS_FACTORY
.
createFromName
(
epsgCode
);
transform
=
new
BasicCoordinateTransform
(
sourceCRS
,
targetCRS
);
backTransform
=
new
BasicCoordinateTransform
(
targetCRS
,
sourceCRS
);
createTransformers
(
cityModel
);
OsmData
osmData
=
new
OsmData
();
String
boundingBoxString
=
extractAndConvertBoundingBox
(
cityModel
,
epsgCode
,
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();
...
...
@@ -146,9 +130,6 @@ public class GreenEnricher {
System
.
out
.
println
(
"Parsing OSM response"
);
parseOsmResponse
(
osmResponse
,
osmData
);
createBoundingBox
(
cityModel
,
osmData
);
// List<GreenArea> newGreenAreas = new ArrayList<>();
System
.
out
.
println
(
"Fit data in bounding box"
);
fitToBoundingBox
(
osmData
);
...
...
@@ -160,134 +141,30 @@ public class GreenEnricher {
convertGreenAreasToCityGML
(
cityModel
,
greenAreas
);
convertWaterAreasToCityGML
(
cityModel
,
osmData
);
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
())
{
// standard tree
double
trunkRadius
=
0.89
/
(
2
*
Math
.
PI
);
double
trunkHeight
=
TRUNK_PERCENTAGE
*
11.46
;
double
crownHeight
=
CROWN_PERCENTAGE
*
11.46
;
double
crownRadius
=
8
/
2
d
;
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
();
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);
// }
TreeUtils
.
insertTrees
(
cityModel
,
osmData
);
clampToGround
(
cityModel
);
String
inputString
=
inFile
.
getFileName
().
toString
();
String
inputPathWithoutFileEnding
=
inputString
.
substring
(
0
,
inputString
.
lastIndexOf
(
'.'
));
Path
outputPath
=
Paths
.
get
(
"data"
,
inputPathWithoutFileEnding
+
"_with_greens.gml"
);
Path
outputPath
=
Paths
.
get
(
"data"
,
inputPathWithoutFileEnding
+
"_with_
osm_
greens.gml"
);
System
.
out
.
println
(
"Writing output file."
);
writeCityGML
(
cityModel
,
outputPath
);
System
.
out
.
println
(
"Done"
);
}
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
;
public
static
void
createTransformers
(
CityModel
cityModel
)
{
String
epsgCode
=
extractEpsgCode
(
cityModel
);
sourceCRS
=
CRS_FACTORY
.
createFromName
(
epsgCode
);
transform
=
new
BasicCoordinateTransform
(
sourceCRS
,
targetCRS
);
backTransform
=
new
BasicCoordinateTransform
(
targetCRS
,
sourceCRS
);
}
tree
.
setTrunkRadius
(
Integer
.
parseInt
(
trunkCirc
.
toString
())
/
(
2
*
Math
.
PI
)
/
100
);
result
.
getTrees
().
add
(
tree
);
}
}
return
result
;
}
p
rivate
static
void
convertWaterAreasToCityGML
(
CityModel
cityModel
,
OsmData
osmData
)
{
p
ublic
static
void
convertWaterAreasToCityGML
(
CityModel
cityModel
,
OsmData
osmData
)
{
for
(
WaterArea
waterArea
:
osmData
.
getWaterAreas
())
{
WaterBody
wb
=
new
WaterBody
();
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
poly
=
convertToCityGmlPoly
(
waterArea
.
getArea
());
...
...
@@ -303,7 +180,7 @@ public class GreenEnricher {
}
}
p
rivate
static
void
convertGreenAreasToCityGML
(
CityModel
cityModel
,
List
<
GreenArea
>
greenAreas
)
{
p
ublic
static
void
convertGreenAreasToCityGML
(
CityModel
cityModel
,
List
<
GreenArea
>
greenAreas
)
{
for
(
GreenArea
ga
:
greenAreas
)
{
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
poly
=
convertToCityGmlPoly
(
ga
.
getArea
());
if
(
poly
==
null
)
{
...
...
@@ -319,8 +196,65 @@ public class GreenEnricher {
}
}
private
static
void
fitToBoundingBox
(
OsmData
osmData
)
{
List
<
GreenArea
>
greenAreas
=
osmData
.
getGreenAreas
();
public
static
void
fitToBoundingBox
(
OsmData
osmData
)
{
fitGreenAreas
(
osmData
,
osmData
.
getGreenAreas
());
fitRoadAreas
(
osmData
,
osmData
.
getRoadAreas
());
fitLandUseAreas
(
osmData
,
osmData
.
getLandUseAreas
());
clipWaterAreasToBoundingBox
(
osmData
);
for
(
Iterator
<
TreePoint
>
iterator
=
osmData
.
getTreePoints
().
iterator
();
iterator
.
hasNext
();)
{
TreePoint
tp
=
iterator
.
next
();
if
(!
osmData
.
getBoundingBox
().
contains
(
tp
.
getPoint
()))
{
iterator
.
remove
();
}
}
}
private
static
void
fitLandUseAreas
(
OsmData
osmData
,
List
<
LandUseArea
>
landUseAreas
)
{
List
<
LandUseArea
>
newLandUseAreas
=
new
ArrayList
<>();
for
(
LandUseArea
landUseArea
:
landUseAreas
)
{
Polygon
area
=
landUseArea
.
getArea
();
Geometry
intersection
=
area
.
intersection
(
osmData
.
getBoundingBox
());
if
(
intersection
instanceof
MultiPolygon
multi
)
{
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
landUseArea
.
setArea
(
poly1
);
for
(
int
k
=
1
;
k
<
multi
.
getNumGeometries
();
k
++)
{
LandUseArea
newLandUseArea
=
new
LandUseArea
();
newLandUseArea
.
setArea
((
Polygon
)
multi
.
getGeometryN
(
k
));
newLandUseAreas
.
add
(
newLandUseArea
);
}
}
else
{
landUseArea
.
setArea
((
Polygon
)
intersection
);
}
}
landUseAreas
.
addAll
(
newLandUseAreas
);
}
private
static
void
fitRoadAreas
(
OsmData
osmData
,
List
<
RoadArea
>
roadAreas
)
{
List
<
RoadArea
>
newRoadAreas
=
new
ArrayList
<>();
for
(
RoadArea
roadArea
:
roadAreas
)
{
Polygon
area
=
roadArea
.
getArea
();
Geometry
intersection
=
area
.
intersection
(
osmData
.
getBoundingBox
());
if
(
intersection
instanceof
MultiPolygon
multi
)
{
Polygon
poly1
=
(
Polygon
)
multi
.
getGeometryN
(
0
);
roadArea
.
setArea
(
poly1
);
for
(
int
k
=
1
;
k
<
multi
.
getNumGeometries
();
k
++)
{
RoadArea
newRoadArea
=
new
RoadArea
();
newRoadArea
.
setArea
((
Polygon
)
multi
.
getGeometryN
(
k
));
newRoadAreas
.
add
(
newRoadArea
);
}
}
else
{
roadArea
.
setArea
((
Polygon
)
intersection
);
}
}
roadAreas
.
addAll
(
newRoadAreas
);
}
private
static
void
fitGreenAreas
(
OsmData
osmData
,
List
<
GreenArea
>
greenAreas
)
{
List
<
GreenArea
>
newGreenAreas
=
new
ArrayList
<>();
for
(
GreenArea
greenArea
:
greenAreas
)
{
Polygon
area
=
greenArea
.
getArea
();
...
...
@@ -338,16 +272,6 @@ public class GreenEnricher {
}
}
greenAreas
.
addAll
(
newGreenAreas
);
clipWaterAreasToBoundingBox
(
osmData
);
for
(
Iterator
<
TreePoint
>
iterator
=
osmData
.
getTreePoints
().
iterator
();
iterator
.
hasNext
();)
{
TreePoint
tp
=
iterator
.
next
();
if
(!
osmData
.
getBoundingBox
().
contains
(
tp
.
getPoint
()))
{
iterator
.
remove
();
}
}
}
private
static
void
clipWaterAreasToBoundingBox
(
OsmData
osmData
)
{
...
...
@@ -394,25 +318,7 @@ public class GreenEnricher {
}
}
}
private
static
void
createBoundingBox
(
CityModel
cityModel
,
OsmData
osmData
)
{
// TODO Auto-generated method stub
}
// private static MultiSurface generateTree(Point p) {
// double radiusTrunk = 0.2;
//
// MultiSurface result = new MultiSurface();
//
// // trunk
// Coordinate center = p.getCoordinate();
// List<Coordinate> coords = new ArrayList<>();
// coords.add(new Coordinate(center.x, center.y + radiusTrunk));
// coords.add(new Coordinate(center.x + radiusTrunk / 2, center.y + Math.cos(0.5) * radiusTrunk));
// }
private
static
void
clampToGround
(
CityModel
cityModel
)
{
public
static
void
clampToGround
(
CityModel
cityModel
)
{
for
(
AbstractCityObjectProperty
afp
:
cityModel
.
getCityObjectMembers
())
{
AbstractCityObject
af
=
afp
.
getObject
();
if
(
af
instanceof
Building
b
)
{
...
...
@@ -487,7 +393,7 @@ public class GreenEnricher {
return
response
;
}
p
rivate
static
void
writeCityGML
(
CityModel
cityModel
,
Path
outputPath
)
p
ublic
static
void
writeCityGML
(
CityModel
cityModel
,
Path
outputPath
)
throws
CityGMLWriteException
,
CityGMLContextException
{
CityGMLContext
context
=
CityGMLContext
.
newInstance
();
CityGMLVersion
version
=
CityGMLVersion
.
v2_0
;
...
...
@@ -499,28 +405,110 @@ public class GreenEnricher {
}
}
private
static
OsmData
parseOsmResponse
(
String
osmResponse
,
OsmData
osmData
)
throws
ParserConfigurationException
,
SAXException
,
IOException
{
Document
document
=
createDomFromOsmResponse
(
osmResponse
);
public
static
void
parseOsmResponse
(
String
osmResponse
,
OsmData
osmData
)
throws
JAXBException
{
JAXBContext
context
=
JAXBContext
.
newInstance
(
OSM
.
class
);
OSM
osm
=
(
OSM
)
context
.
createUnmarshaller
().
unmarshal
(
new
StringReader
(
osmResponse
));
parseTrees
(
osmData
.
getTreePoints
(),
osm
.
getNodes
());
parseWays
(
osmData
,
osm
);
parseRelations
(
osmData
,
osm
);
}
// root element
Node
osmItem
=
document
.
getChildNodes
().
item
(
0
);
NodeList
childNodes
=
osmItem
.
getChildNodes
()
;
private
static
void
parseRelations
(
OsmData
data
,
OSM
osm
)
{
for
(
OsmRelation
rel
:
osm
.
getRelations
())
{
boolean
isWater
=
false
;
Set
<
String
>
usedIds
=
new
HashSet
<>();
List
<
Polygon
>
polygons
=
new
ArrayList
<>();
List
<
Coordinate
>
coordinates
=
new
ArrayList
<>();
for
(
OsmMember
member
:
rel
.
getMembers
())
{
for
(
WayNode
nd
:
member
.
getNodes
())
{
ProjCoordinate
converted
=
convertCoordinatesFrom84
(
nd
.
getLon
(),
nd
.
getLat
());
coordinates
.
add
(
new
Coordinate
(
converted
.
x
,
converted
.
y
));
}
for
(
int
i
=
0
;
i
<
childNodes
.
getLength
();
i
++)
{
Node
node
=
childNodes
.
item
(
i
);
if
(
parseTreeIfPossible
(
osmData
.
getTreePoints
(),
node
,
usedIds
))
{
continue
;
if
(
member
.
getRole
().
isBlank
())
{
// assume outer ring
// check if this ring is closed
if
(
coordinates
.
get
(
0
).
equals2D
(
coordinates
.
get
(
coordinates
.
size
()
-
1
)))
{
// ring is closed, create a polygon out of it
Polygon
polygon
=
GEOM_FACTORY
.
createPolygon
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
coordinates
.
clear
();
polygons
.
add
(
polygon
);
}
if
(
parseGreenAreasIfPossible
(
osmData
,
node
,
usedIds
))
{
continue
;
}
parseGreenRelationsIfPossible
(
osmData
,
node
,
usedIds
);
}
return
osmData
;
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
()]));
coordinates
.
clear
();
polygons
.
add
(
polygon
);
}
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
));
}
}
else
{
for
(
Polygon
p
:
polygons
)
{
data
.
getGreenAreas
().
add
(
new
GreenArea
(
p
));
}
}
}
}
private
static
void
parseWays
(
OsmData
data
,
OSM
osm
)
{
for
(
OsmWay
way
:
osm
.
getWays
())
{
boolean
water
=
false
;
// search if it is water of green stuff
for
(
OsmTag
tag
:
way
.
getTags
())
{
if
(
"water"
.
equals
(
tag
.
getValue
())
||
"waterway"
.
equals
(
tag
.
getKey
()))
{
water
=
true
;
}
}
List
<
Coordinate
>
coordinates
=
new
ArrayList
<>();
for
(
WayNode
nd
:
way
.
getNodes
())
{
ProjCoordinate
converted
=
convertCoordinatesFrom84
(
nd
.
getLon
(),
nd
.
getLat
());
coordinates
.
add
(
new
Coordinate
(
converted
.
x
,
converted
.
y
));
}
boolean
isLine
=
false
;
if
(!
coordinates
.
get
(
0
).
equals
(
coordinates
.
get
(
coordinates
.
size
()
-
1
)))
{
// assume line if start and end coordinate do not match?
isLine
=
true
;
}
if
(
water
)
{
if
(
isLine
)
{
LineString
lineString
=
GEOM_FACTORY
.
createLineString
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
data
.
getWaterways
().
add
(
new
Waterway
(
lineString
));
}
else
{
Polygon
polygon
=
GEOM_FACTORY
.
createPolygon
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
data
.
getWaterAreas
().
add
(
new
WaterArea
(
polygon
));
}
}
else
{
if
(
isLine
)
{
LineString
lineString
=
GEOM_FACTORY
.
createLineString
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
data
.
getTreeRows
().
add
(
new
TreeRow
(
lineString
));
}
else
{
Polygon
polygon
=
GEOM_FACTORY
.
createPolygon
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
data
.
getGreenAreas
().
add
(
new
GreenArea
(
polygon
));
}
}
}
}
private
static
boolean
parseGreenRelationsIfPossible
(
OsmData
data
,
Node
node
,
Set
<
String
>
usedIds
)
{
...
...
@@ -583,17 +571,17 @@ public class GreenEnricher {
}
if
(
water
)
{
org
.
locationtech
.
jts
.
geom
.
LinearRing
outerLinearRing
=
geomFactory
org
.
locationtech
.
jts
.
geom
.
LinearRing
outerLinearRing
=
GEOM_FACTORY
.
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
org
.
locationtech
.
jts
.
geom
.
LinearRing
innerLinearRing
=
GEOM_FACTORY
.
createLinearRing
(
innerRing
.
toArray
(
new
Coordinate
[
innerRing
.
size
()]));
innerLinearRings
.
add
(
innerLinearRing
);
}
Polygon
polygon
=
geomFactory
.
createPolygon
(
outerLinearRing
,
Polygon
polygon
=
GEOM_FACTORY
.
createPolygon
(
outerLinearRing
,
innerLinearRings
.
toArray
(
new
org
.
locationtech
.
jts
.
geom
.
LinearRing
[
innerLinearRings
.
size
()]));
data
.
getWaterAreas
().
add
(
new
WaterArea
(
polygon
));
...
...
@@ -625,16 +613,6 @@ public class GreenEnricher {
}
private
static
void
validateRing
(
List
<
Coordinate
>
outerRing
)
{
if
(
outerRing
.
isEmpty
())
{
return
;
}
if
(!
outerRing
.
get
(
0
).
equals
(
outerRing
.
get
(
outerRing
.
size
()
-
1
)))
{
// close ring
outerRing
.
add
(
outerRing
.
get
(
0
));
}
}
private
static
boolean
parseGreenAreasIfPossible
(
OsmData
data
,
Node
node
,
Set
<
String
>
usedIds
)
{
if
(!
"way"
.
equals
(
node
.
getNodeName
()))
{
return
false
;
...
...
@@ -676,20 +654,20 @@ public class GreenEnricher {
if
(
water
)
{
if
(
line
)
{
LineString
lineString
=
geomFactory
LineString
lineString
=
GEOM_FACTORY
.
createLineString
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
data
.
getWaterways
().
add
(
new
Waterway
(
lineString
));
}
else
{
Polygon
polygon
=
geomFactory
.
createPolygon
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
Polygon
polygon
=
GEOM_FACTORY
.
createPolygon
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
data
.
getWaterAreas
().
add
(
new
WaterArea
(
polygon
));
}
}
else
{
if
(
line
)
{
LineString
lineString
=
geomFactory
LineString
lineString
=
GEOM_FACTORY
.
createLineString
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
data
.
getTreeRows
().
add
(
new
TreeRow
(
lineString
));
}
else
{
Polygon
polygon
=
geomFactory
.
createPolygon
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
Polygon
polygon
=
GEOM_FACTORY
.
createPolygon
(
coordinates
.
toArray
(
new
Coordinate
[
coordinates
.
size
()]));
data
.
getGreenAreas
().
add
(
new
GreenArea
(
polygon
));
}
}
...
...
@@ -709,41 +687,15 @@ public class GreenEnricher {
return
namedItem
.
getNodeValue
();
}
private
static
boolean
parseTreeIfPossible
(
List
<
TreePoint
>
treePoints
,
Node
node
,
Set
<
String
>
usedIds
)
{
if
(!
"node"
.
equals
(
node
.
getNodeName
()))
{
return
false
;
}
String
id
=
node
.
getAttributes
().
getNamedItem
(
"id"
).
getNodeValue
();
if
(
usedIds
.
contains
(
id
))
{
System
.
out
.
println
(
"Already used node id "
+
id
);
return
true
;
}
usedIds
.
add
(
id
);
double
lat
=
Double
.
parseDouble
(
node
.
getAttributes
().
getNamedItem
(
"lat"
).
getNodeValue
());
double
lon
=
Double
.
parseDouble
(
node
.
getAttributes
().
getNamedItem
(
"lon"
).
getNodeValue
());
ProjCoordinate
converted
=
convertCoordinatesFrom84
(
lon
,
lat
);
Point
point
=
geomFactory
.
createPoint
(
new
Coordinate
(
converted
.
x
,
converted
.
y
));
private
static
void
parseTrees
(
List
<
TreePoint
>
treePoints
,
List
<
OsmNode
>
nodes
)
{
for
(
OsmNode
node
:
nodes
)
{
ProjCoordinate
converted
=
convertCoordinatesFrom84
(
node
.
getLon
(),
node
.
getLat
());
Point
point
=
GEOM_FACTORY
.
createPoint
(
new
Coordinate
(
converted
.
x
,
converted
.
y
));
treePoints
.
add
(
new
TreePoint
(
point
));
return
true
;
}
private
static
Document
createDomFromOsmResponse
(
String
body
)
throws
ParserConfigurationException
,
SAXException
,
IOException
{
DocumentBuilderFactory
factory
=
DocumentBuilderFactory
.
newInstance
();
// to be compliant, completely disable DOCTYPE declaration:
factory
.
setFeature
(
"http://apache.org/xml/features/disallow-doctype-decl"
,
true
);
// or completely disable external entities declarations:
factory
.
setFeature
(
"http://xml.org/sax/features/external-general-entities"
,
false
);
factory
.
setFeature
(
"http://xml.org/sax/features/external-parameter-entities"
,
false
);
// or prohibit the use of all protocols by external entities:
factory
.
setAttribute
(
XMLConstants
.
ACCESS_EXTERNAL_DTD
,
""
);
factory
.
setAttribute
(
XMLConstants
.
ACCESS_EXTERNAL_SCHEMA
,
""
);
DocumentBuilder
builder
=
factory
.
newDocumentBuilder
();
ByteArrayInputStream
input
=
new
ByteArrayInputStream
(
body
.
getBytes
(
StandardCharsets
.
UTF_8
));
return
builder
.
parse
(
input
);
}
p
rivate
static
CityModel
readCityGml
(
Path
inFile
)
throws
CityGMLContextException
,
CityGMLReadException
{
p
ublic
static
CityModel
readCityGml
(
Path
inFile
)
throws
CityGMLContextException
,
CityGMLReadException
{
CityGMLContext
context
=
CityGMLContext
.
newInstance
();
CityGMLInputFactory
in
=
context
.
createCityGMLInputFactory
();
try
(
CityGMLReader
reader
=
in
.
createCityGMLReader
(
inFile
))
{
...
...
@@ -774,7 +726,7 @@ public class GreenEnricher {
return
srsName
;
}
p
rivate
static
String
extractAndConvertBoundingBox
(
CityModel
cityModel
,
String
epsgCode
,
OsmData
osmData
)
{
p
ublic
static
String
extractAndConvertBoundingBox
(
CityModel
cityModel
,
OsmData
osmData
)
{
Envelope
calculatedEnvelope
=
cityModel
.
computeEnvelope
();
DirectPosition
lowerCorner
=
calculatedEnvelope
.
getLowerCorner
();
...
...
@@ -805,7 +757,7 @@ public class GreenEnricher {
bboxCoordinates
.
add
(
new
Coordinate
(
lowerCorner
.
getValue
().
get
(
0
)
-
BOUNDING_BOX_INCREASE_IN_M
,
lowerCorner
.
getValue
().
get
(
1
)
-
BOUNDING_BOX_INCREASE_IN_M
));
Polygon
poly
=
geomFactory
.
createPolygon
(
bboxCoordinates
.
toArray
(
new
Coordinate
[
bboxCoordinates
.
size
()]));
Polygon
poly
=
GEOM_FACTORY
.
createPolygon
(
bboxCoordinates
.
toArray
(
new
Coordinate
[
bboxCoordinates
.
size
()]));
osmData
.
setBoundingBox
(
poly
);
return
lowerCornerProjected
.
y
+
","
+
lowerCornerProjected
.
x
+
","
+
upperCornerProjected
.
y
+
","
...
...
@@ -832,4 +784,38 @@ public class GreenEnricher {
return
result
;
}
public
static
void
convertRoadAreasToCityGML
(
CityModel
cityModel
,
OsmData
osmData
)
{
for
(
RoadArea
roadArea
:
osmData
.
getRoadAreas
())
{
Road
road
=
new
Road
();
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
poly
=
convertToCityGmlPoly
(
roadArea
.
getArea
());
if
(
poly
==
null
)
{
System
.
out
.
println
(
"Skipping RoadArea: "
+
roadArea
.
getArea
());
continue
;
}
MultiSurface
ms
=
new
MultiSurface
();
road
.
setId
(
UUID
.
randomUUID
().
toString
());
ms
.
getSurfaceMember
().
add
(
new
SurfaceProperty
(
poly
));
road
.
setLod0MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
cityModel
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
road
));
}
}
public
static
void
converLandUseAreasToCityGML
(
CityModel
cityModel
,
OsmData
osmData
)
{
for
(
LandUseArea
landUseArea
:
osmData
.
getLandUseAreas
())
{
LandUse
landUse
=
new
LandUse
();
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
poly
=
convertToCityGmlPoly
(
landUseArea
.
getArea
());
if
(
poly
==
null
)
{
System
.
out
.
println
(
"Skipping RoadArea: "
+
landUseArea
.
getArea
());
continue
;
}
MultiSurface
ms
=
new
MultiSurface
();
landUse
.
setId
(
UUID
.
randomUUID
().
toString
());
ms
.
getSurfaceMember
().
add
(
new
SurfaceProperty
(
poly
));
landUse
.
setLod0MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
cityModel
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
landUse
));
}
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/LandUseArea.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm
;
import
org.locationtech.jts.geom.Polygon
;
public
class
LandUseArea
{
private
Polygon
area
;
public
LandUseArea
()
{
}
public
LandUseArea
(
Polygon
area
)
{
this
.
area
=
area
;
}
public
void
setArea
(
Polygon
area
)
{
this
.
area
=
area
;
}
public
Polygon
getArea
()
{
return
area
;
}
@Override
public
String
toString
()
{
return
"LandUseArea [area="
+
area
+
"]"
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/OsmData.java
View file @
3e042784
...
...
@@ -14,6 +14,8 @@ public class OsmData {
private
List
<
TreeRow
>
treeRows
=
new
ArrayList
<>();
private
List
<
Waterway
>
waterways
=
new
ArrayList
<>();
private
List
<
WaterArea
>
waterAreas
=
new
ArrayList
<>();
private
List
<
RoadArea
>
roadAreas
=
new
ArrayList
<>();
private
List
<
LandUseArea
>
landUseAreas
=
new
ArrayList
<>();
public
void
setBoundingBox
(
Polygon
boundingBox
)
{
this
.
boundingBox
=
boundingBox
;
...
...
@@ -43,4 +45,12 @@ public class OsmData {
return
treeRows
;
}
public
List
<
RoadArea
>
getRoadAreas
()
{
return
roadAreas
;
}
public
List
<
LandUseArea
>
getLandUseAreas
()
{
return
landUseAreas
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/RoadArea.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm
;
import
org.locationtech.jts.geom.Polygon
;
public
class
RoadArea
{
private
Polygon
area
;
public
RoadArea
()
{
}
public
RoadArea
(
Polygon
area
)
{
this
.
area
=
area
;
}
public
void
setArea
(
Polygon
area
)
{
this
.
area
=
area
;
}
public
Polygon
getArea
()
{
return
area
;
}
@Override
public
String
toString
()
{
return
"RoadArea [area="
+
area
+
"]"
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/TreeGenerator.java
View file @
3e042784
...
...
@@ -104,7 +104,7 @@ public class TreeGenerator {
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
);
Polygon
polygon
=
GreenEnricher
.
GEOM_FACTORY
.
createPolygon
(
coordArray
);
var
convertedPoly
=
GreenEnricher
.
convertToCityGmlPoly
(
polygon
);
ms
.
getSurfaceMember
().
add
(
new
SurfaceProperty
(
convertedPoly
));
}
...
...
@@ -118,7 +118,7 @@ public class TreeGenerator {
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
);
Polygon
polygon
=
GreenEnricher
.
GEOM_FACTORY
.
createPolygon
(
coordArray
);
var
convertedPoly
=
GreenEnricher
.
convertToCityGmlPoly
(
polygon
);
ms
.
getSurfaceMember
().
add
(
new
SurfaceProperty
(
convertedPoly
));
}
...
...
@@ -131,7 +131,7 @@ public class TreeGenerator {
Coordinate
p1
=
bottomRing
.
get
(
i
);
Coordinate
p2
=
bottomRing
.
get
(
nextRingIndex
);
Coordinate
[]
coordArray
=
new
Coordinate
[]
{
p2
,
p1
,
bottomPoint
,
p2
};
Polygon
polygon
=
GreenEnricher
.
geomFactory
.
createPolygon
(
coordArray
);
Polygon
polygon
=
GreenEnricher
.
GEOM_FACTORY
.
createPolygon
(
coordArray
);
var
convertedPoly
=
GreenEnricher
.
convertToCityGmlPoly
(
polygon
);
ms
.
getSurfaceMember
().
add
(
new
SurfaceProperty
(
convertedPoly
));
}
...
...
@@ -140,7 +140,7 @@ public class TreeGenerator {
}
private
static
Polygon
convertPolygon
(
List
<
Coordinate
>
trunkWestCoordinateList
)
{
return
GreenEnricher
.
geomFactory
return
GreenEnricher
.
GEOM_FACTORY
.
createPolygon
(
trunkWestCoordinateList
.
toArray
(
new
Coordinate
[
trunkWestCoordinateList
.
size
()]));
}
...
...
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/TreeKatasterData.java
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm
;
import
java.io.IOException
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Path
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
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.Point
;
import
org.opengis.feature.simple.SimpleFeature
;
import
org.opengis.feature.simple.SimpleFeatureType
;
public
class
TreeKatasterData
{
public
static
final
double
TRUNK_PERCENTAGE
=
0.2
;
public
static
final
double
CROWN_PERCENTAGE
=
1
-
TRUNK_PERCENTAGE
;
private
List
<
Tree
>
trees
;
public
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
;
}
public
List
<
Tree
>
getTrees
()
{
if
(
trees
==
null
)
{
trees
=
new
ArrayList
<>();
...
...
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/TreeUtils.java
0 → 100644
View file @
3e042784
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"
,
"Baum.shp"
));
generateTreesFromKataster
(
cityModel
,
katasterData
);
// All kataster trees are taken, osm trees are removed
filterDuplicateTreesFromOSM
(
osmData
,
katasterData
);
generateTreesFromOSM
(
cityModel
,
osmData
);
}
private
static
void
filterDuplicateTreesFromOSM
(
OsmData
osmData
,
TreeKatasterData
katasterData
)
{
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
();
}
}
}
}
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
/
2
d
;
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 campestre"
));
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
));
}
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/jaxb/Bounds.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm.jaxb
;
import
jakarta.xml.bind.annotation.XmlAttribute
;
public
class
Bounds
{
@XmlAttribute
(
name
=
"minlat"
)
private
double
minLat
;
@XmlAttribute
(
name
=
"minlon"
)
private
double
minLon
;
@XmlAttribute
(
name
=
"maxlat"
)
private
double
maxLat
;
@XmlAttribute
(
name
=
"maxlon"
)
private
double
maxLon
;
public
double
getMaxLat
()
{
return
maxLat
;
}
public
double
getMaxLon
()
{
return
maxLon
;
}
public
double
getMinLat
()
{
return
minLat
;
}
public
double
getMinLon
()
{
return
minLon
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/jaxb/Meta.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm.jaxb
;
import
jakarta.xml.bind.annotation.XmlAttribute
;
public
class
Meta
{
@XmlAttribute
(
name
=
"osm_base"
)
private
String
osmBase
;
public
String
getOsmBase
()
{
return
osmBase
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/jaxb/OSM.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm.jaxb
;
import
java.util.ArrayList
;
import
java.util.List
;
import
jakarta.xml.bind.annotation.XmlAttribute
;
import
jakarta.xml.bind.annotation.XmlElement
;
import
jakarta.xml.bind.annotation.XmlElements
;
import
jakarta.xml.bind.annotation.XmlRootElement
;
@XmlRootElement
(
name
=
"osm"
)
public
class
OSM
{
@XmlAttribute
private
String
version
;
@XmlAttribute
private
String
generator
;
@XmlElement
private
String
note
;
@XmlElement
private
Meta
meta
;
@XmlElement
private
Bounds
bounds
;
@XmlElements
(
value
=
{
@XmlElement
(
name
=
"node"
,
type
=
OsmNode
.
class
)
})
private
List
<
OsmNode
>
nodes
;
@XmlElements
(
value
=
{
@XmlElement
(
name
=
"way"
,
type
=
OsmWay
.
class
)
})
private
List
<
OsmWay
>
ways
;
@XmlElements
(
value
=
{
@XmlElement
(
name
=
"relation"
,
type
=
OsmRelation
.
class
)
})
private
List
<
OsmRelation
>
relations
;
public
List
<
OsmRelation
>
getRelations
()
{
if
(
relations
==
null
)
{
relations
=
new
ArrayList
<>();
}
return
relations
;
}
public
List
<
OsmWay
>
getWays
()
{
if
(
ways
==
null
)
{
ways
=
new
ArrayList
<>();
}
return
ways
;
}
public
List
<
OsmNode
>
getNodes
()
{
if
(
nodes
==
null
)
{
nodes
=
new
ArrayList
<>();
}
return
nodes
;
}
public
Bounds
getBounds
()
{
return
bounds
;
}
public
String
getVersion
()
{
return
version
;
}
public
String
getGenerator
()
{
return
generator
;
}
public
String
getNote
()
{
return
note
;
}
public
Meta
getMeta
()
{
return
meta
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/jaxb/OsmMember.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm.jaxb
;
import
java.util.ArrayList
;
import
java.util.List
;
import
jakarta.xml.bind.annotation.XmlAttribute
;
import
jakarta.xml.bind.annotation.XmlElement
;
import
jakarta.xml.bind.annotation.XmlElements
;
public
class
OsmMember
{
@XmlAttribute
private
String
type
;
@XmlAttribute
private
String
ref
;
@XmlAttribute
private
String
role
;
@XmlElements
(
value
=
{
@XmlElement
(
name
=
"nd"
,
type
=
WayNode
.
class
)
})
private
List
<
WayNode
>
nodes
;
public
List
<
WayNode
>
getNodes
()
{
if
(
nodes
==
null
)
{
nodes
=
new
ArrayList
<>();
}
return
nodes
;
}
public
String
getRef
()
{
return
ref
;
}
public
String
getRole
()
{
return
role
;
}
public
String
getType
()
{
return
type
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/jaxb/OsmNode.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm.jaxb
;
import
java.util.ArrayList
;
import
java.util.List
;
import
jakarta.xml.bind.annotation.XmlAttribute
;
import
jakarta.xml.bind.annotation.XmlElement
;
import
jakarta.xml.bind.annotation.XmlElements
;
public
class
OsmNode
{
@XmlAttribute
private
String
id
;
@XmlAttribute
private
double
lat
;
@XmlAttribute
private
double
lon
;
@XmlElements
(
value
=
{
@XmlElement
(
name
=
"tag"
,
type
=
OsmTag
.
class
)
})
private
List
<
OsmTag
>
tags
;
public
String
getId
()
{
return
id
;
}
public
double
getLat
()
{
return
lat
;
}
public
double
getLon
()
{
return
lon
;
}
public
List
<
OsmTag
>
getTags
()
{
if
(
tags
==
null
)
{
tags
=
new
ArrayList
<>();
}
return
tags
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/jaxb/OsmRelation.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm.jaxb
;
import
java.util.ArrayList
;
import
java.util.List
;
import
jakarta.xml.bind.annotation.XmlAttribute
;
import
jakarta.xml.bind.annotation.XmlElement
;
import
jakarta.xml.bind.annotation.XmlElements
;
public
class
OsmRelation
{
@XmlAttribute
private
String
id
;
@XmlElement
private
Bounds
bounds
;
@XmlElements
(
value
=
{
@XmlElement
(
name
=
"member"
,
type
=
OsmMember
.
class
)
})
private
List
<
OsmMember
>
members
;
@XmlElements
(
value
=
{
@XmlElement
(
name
=
"tag"
,
type
=
OsmTag
.
class
)
})
private
List
<
OsmTag
>
tags
;
public
List
<
OsmTag
>
getTags
()
{
if
(
tags
==
null
)
{
tags
=
new
ArrayList
<>();
}
return
tags
;
}
public
List
<
OsmMember
>
getMembers
()
{
if
(
members
==
null
)
{
members
=
new
ArrayList
<>();
}
return
members
;
}
public
Bounds
getBounds
()
{
return
bounds
;
}
public
String
getId
()
{
return
id
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/jaxb/OsmTag.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm.jaxb
;
import
jakarta.xml.bind.annotation.XmlAttribute
;
public
class
OsmTag
{
@XmlAttribute
(
name
=
"k"
)
private
String
key
;
@XmlAttribute
(
name
=
"v"
)
private
String
value
;
public
String
getKey
()
{
return
key
;
}
public
String
getValue
()
{
return
value
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/jaxb/OsmWay.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm.jaxb
;
import
java.util.ArrayList
;
import
java.util.List
;
import
jakarta.xml.bind.annotation.XmlAttribute
;
import
jakarta.xml.bind.annotation.XmlElement
;
import
jakarta.xml.bind.annotation.XmlElements
;
public
class
OsmWay
{
@XmlAttribute
private
String
id
;
@XmlElement
private
Bounds
bounds
;
@XmlElements
(
value
=
{
@XmlElement
(
name
=
"nd"
,
type
=
WayNode
.
class
)
})
private
List
<
WayNode
>
nodes
;
@XmlElements
(
value
=
{
@XmlElement
(
name
=
"tag"
,
type
=
OsmTag
.
class
)
})
private
List
<
OsmTag
>
tags
;
public
List
<
OsmTag
>
getTags
()
{
if
(
tags
==
null
)
{
tags
=
new
ArrayList
<>();
}
return
tags
;
}
public
String
getId
()
{
return
id
;
}
public
Bounds
getBounds
()
{
return
bounds
;
}
public
List
<
WayNode
>
getNodes
()
{
if
(
nodes
==
null
)
{
nodes
=
new
ArrayList
<>();
}
return
nodes
;
}
}
enrich-citygml-with-greenarea/src/main/java/de/hft/stuttgart/citygml/green/osm/jaxb/WayNode.java
0 → 100644
View file @
3e042784
package
de.hft.stuttgart.citygml.green.osm.jaxb
;
import
jakarta.xml.bind.annotation.XmlAttribute
;
public
class
WayNode
{
@XmlAttribute
private
String
ref
;
@XmlAttribute
private
double
lat
;
@XmlAttribute
private
double
lon
;
public
double
getLat
()
{
return
lat
;
}
public
double
getLon
()
{
return
lon
;
}
public
String
getRef
()
{
return
ref
;
}
}
enrich-citygml-with-greenarea/src/test/java/de/hft/stuttgart/citygml/green/alkis/AlkisGreenEnricherTest.java
0 → 100644
View file @
3e042784
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
{
@Test
void
testAlkisGreen
()
throws
IOException
,
CityGMLContextException
,
CityGMLReadException
,
JAXBException
,
CityGMLWriteException
{
String
[]
args
=
new
String
[]
{
"data/Grombühl_v3.gml"
};
AlkisGreenEnricher
.
main
(
args
);
}
}
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