Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CityDoctor
CityDoctor2
Commits
3f3c1884
Commit
3f3c1884
authored
Jun 24, 2022
by
Matthias Betz
Browse files
change to citygml4j 3.0.0 rc4
change to quality ade 0.1.4
parent
92f3e523
Pipeline
#6596
failed with stage
in 17 seconds
Changes
106
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Opening.java
View file @
3f3c1884
...
...
@@ -18,10 +18,11 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
org.citygml4j.factory.GMLGeometryFactory
;
import
org.citygml4j.model.citygml.core.AbstractCityObject
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSurface
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSurfaceProperty
;
import
org.citygml4j.core.model.construction.AbstractFillingSurface
;
import
org.citygml4j.core.model.core.AbstractCityObject
;
import
org.citygml4j.core.util.geometry.GeometryFactory
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
...
...
@@ -45,21 +46,22 @@ public class Opening extends CityObject {
private
OpeningType
type
;
private
SurfaceFeatureType
featureType
;
private
Abstract
CityObject
ao
;
private
Abstract
FillingSurface
ao
;
private
Opening
(
OpeningType
type
)
{
this
.
type
=
type
;
}
public
Opening
(
OpeningType
type
,
SurfaceFeatureType
featureType
,
BoundarySurface
partOf
,
AbstractCityObject
ao
)
{
public
Opening
(
OpeningType
type
,
SurfaceFeatureType
featureType
,
BoundarySurface
partOf
,
AbstractFillingSurface
ao
)
{
this
.
featureType
=
featureType
;
this
.
partOf
=
partOf
;
this
.
type
=
type
;
this
.
ao
=
ao
;
}
public
void
reCreateGeometries
(
GML
GeometryFactory
factory
,
ParserConfiguration
config
)
{
if
(
!
ao
.
isS
etId
())
{
public
void
reCreateGeometries
(
GeometryFactory
factory
,
ParserConfiguration
config
)
{
if
(
ao
.
g
etId
()
!=
null
)
{
ao
.
setId
(
getGmlId
().
getGmlString
());
}
for
(
Geometry
geom
:
getGeometries
())
{
...
...
@@ -67,55 +69,33 @@ public class Opening extends CityObject {
MultiSurface
ms
=
CityGmlUtils
.
createMultiSurface
(
geom
,
factory
,
config
);
setGeometryAccordingToLod
(
geom
.
getLod
(),
new
MultiSurfaceProperty
(
ms
));
}
else
{
throw
new
IllegalStateException
(
"
BoundarySurface
s can only have MultiSurface geometries"
);
throw
new
IllegalStateException
(
"
Opening
s can only have MultiSurface geometries"
);
}
}
}
private
void
setGeometryAccordingToLod
(
Lod
lod
,
MultiSurfaceProperty
ms
)
{
switch
(
lod
)
{
case
LOD0:
ao
.
setLod0MultiSurface
(
ms
);
break
;
case
LOD1:
ao
.
setLod1MultiSurface
(
ms
);
break
;
case
LOD2:
ao
.
setLod2MultiSurface
(
ms
);
break
;
case
LOD3:
setLod3M
s
(
ms
);
ao
.
setLod3M
ultiSurface
(
ms
);
break
;
case
LOD4:
setLod4Ms
(
ms
);
ao
.
getDeprecatedProperties
().
setLod4MultiSurface
(
ms
);
break
;
default
:
throw
new
IllegalStateException
(
"Cannot add geometry to opening because lod is not allowed: "
+
lod
);
}
}
private
void
setLod3Ms
(
MultiSurfaceProperty
ms
)
{
switch
(
featureType
)
{
case
BRIDGE:
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractOpening
bridgeAo
=
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractOpening
)
ao
;
bridgeAo
.
setLod3MultiSurface
(
ms
);
break
;
case
BUILDING:
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractOpening
buildAo
=
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractOpening
)
ao
;
buildAo
.
setLod3MultiSurface
(
ms
);
break
;
case
TUNNEL:
org
.
citygml4j
.
model
.
citygml
.
tunnel
.
AbstractOpening
tunAo
=
(
org
.
citygml4j
.
model
.
citygml
.
tunnel
.
AbstractOpening
)
ao
;
tunAo
.
setLod3MultiSurface
(
ms
);
}
}
private
void
setLod4Ms
(
MultiSurfaceProperty
ms
)
{
switch
(
featureType
)
{
case
BRIDGE:
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractOpening
bridgeAo
=
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractOpening
)
ao
;
bridgeAo
.
setLod4MultiSurface
(
ms
);
break
;
case
BUILDING:
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractOpening
buildAo
=
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractOpening
)
ao
;
buildAo
.
setLod4MultiSurface
(
ms
);
break
;
case
TUNNEL:
org
.
citygml4j
.
model
.
citygml
.
tunnel
.
AbstractOpening
tunAo
=
(
org
.
citygml4j
.
model
.
citygml
.
tunnel
.
AbstractOpening
)
ao
;
tunAo
.
setLod4MultiSurface
(
ms
);
}
}
public
SurfaceFeatureType
getSurfaceFeatureType
()
{
return
featureType
;
...
...
@@ -147,22 +127,11 @@ public class Opening extends CityObject {
}
public
void
unsetGmlGeometries
()
{
switch
(
featureType
)
{
case
BRIDGE:
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractOpening
bridgeAo
=
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractOpening
)
ao
;
bridgeAo
.
unsetLod3MultiSurface
();
bridgeAo
.
unsetLod4MultiSurface
();
break
;
case
BUILDING:
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractOpening
buildAo
=
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractOpening
)
ao
;
buildAo
.
unsetLod3MultiSurface
();
buildAo
.
unsetLod4MultiSurface
();
break
;
case
TUNNEL:
org
.
citygml4j
.
model
.
citygml
.
tunnel
.
AbstractOpening
tunAo
=
(
org
.
citygml4j
.
model
.
citygml
.
tunnel
.
AbstractOpening
)
ao
;
tunAo
.
unsetLod3MultiSurface
();
tunAo
.
unsetLod4MultiSurface
();
}
ao
.
setLod0MultiSurface
(
null
);
ao
.
setLod1MultiSurface
(
null
);
ao
.
setLod2MultiSurface
(
null
);
ao
.
setLod3MultiSurface
(
null
);
ao
.
getDeprecatedProperties
().
setLod4MultiSurface
(
null
);
}
@Override
...
...
@@ -188,13 +157,13 @@ public class Opening extends CityObject {
public
Copyable
createCopyInstance
()
{
return
new
Opening
(
type
);
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
super
.
collectInstances
(
handler
);
handler
.
addInstance
(
partOf
);
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
super
.
fillValues
(
original
,
handler
);
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Polygon.java
View file @
3f3c1884
...
...
@@ -77,5 +77,7 @@ public abstract class Polygon extends GmlElement {
abstract
void
anonymize
();
public
abstract
ConcretePolygon
getOriginal
();
public
abstract
void
remove
();
}
\ No newline at end of file
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationObject.java
View file @
3f3c1884
...
...
@@ -21,14 +21,14 @@ package de.hft.stuttgart.citydoctor2.datastructure;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.citygml4j.
factory.GMLGeometryFactory
;
import
org.citygml4j.
model.citygm
l.core.Abstract
CityObject
;
import
org.citygml4j.
model.citygm
l.transportation.AbstractTransportation
Object
;
import
org.citygml4j.
model.citygm
l.transportation.AuxiliaryTrafficArea
;
import
org.citygml4j.
model.citygm
l.transportation.TrafficArea
;
import
org.citygml4j.
model.citygml.transportation.TransportationComplex
;
import
org.
city
gml
4j
.model.
gml.
geometry.aggregates.MultiSurface
;
import
org.
city
gml
4j
.model.
gml.
geometry.aggregates.MultiSurfaceProperty
;
import
org.citygml4j.
core.model.core.AbstractCityObject
;
import
org.citygml4j.
core.mode
l.core.Abstract
Space
;
import
org.citygml4j.
core.mode
l.transportation.AbstractTransportation
Space
;
import
org.citygml4j.
core.mode
l.transportation.AuxiliaryTrafficArea
;
import
org.citygml4j.
core.mode
l.transportation.TrafficArea
;
import
org.citygml4j.
core.util.geometry.GeometryFactory
;
import
org.
xmlobjects.
gml.model.geometry.aggregates.MultiSurface
;
import
org.
xmlobjects.
gml.model.geometry.aggregates.MultiSurfaceProperty
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
...
...
@@ -49,10 +49,10 @@ public class TransportationObject extends CityObject {
private
static
final
long
serialVersionUID
=
-
2698907271726700390L
;
public
enum
TransportationType
{
ROAD
,
TRACK
,
RAILWAY
,
TRAFFIC_AREA
,
AUXILLIARY_TRAFFIC_AREA
,
TRANSPORTATION_COMPLEX
,
SQUARE
ROAD
,
TRACK
,
RAILWAY
,
TRAFFIC_AREA
,
AUXILLIARY_TRAFFIC_AREA
,
TRANSPORTATION_COMPLEX
,
SQUARE
,
AUXILLIARY_TRAFFIC_SPACE
,
TRAFFIC_SPACE
}
private
Abstract
Transportation
Object
ato
;
private
Abstract
City
Object
ato
;
private
List
<
TransportationObject
>
composesOf
=
new
ArrayList
<>(
1
);
private
TransportationType
type
;
...
...
@@ -66,17 +66,13 @@ public class TransportationObject extends CityObject {
}
@Override
public
void
reCreateGeometries
(
GML
GeometryFactory
factory
,
ParserConfiguration
config
)
{
public
void
reCreateGeometries
(
GeometryFactory
factory
,
ParserConfiguration
config
)
{
for
(
Geometry
geom
:
getGeometries
())
{
if
(
geom
.
getType
()
==
GeometryType
.
MULTI_SURFACE
)
{
MultiSurface
ms
=
CityGmlUtils
.
createMultiSurface
(
geom
,
factory
,
config
);
switch
(
type
)
{
case
ROAD:
case
TRACK:
case
RAILWAY:
case
SQUARE:
case
TRANSPORTATION_COMPLEX:
TransportationComplex
tc
=
(
TransportationComplex
)
ato
;
case
ROAD
,
TRACK
,
RAILWAY
,
SQUARE
,
TRANSPORTATION_COMPLEX:
AbstractTransportationSpace
tc
=
(
AbstractTransportationSpace
)
ato
;
setMultiSurfaceAccordingToLod
(
tc
,
ms
,
geom
.
getLod
());
break
;
case
TRAFFIC_AREA:
...
...
@@ -87,6 +83,10 @@ public class TransportationObject extends CityObject {
AuxiliaryTrafficArea
ata
=
(
AuxiliaryTrafficArea
)
ato
;
setMultiSurfaceAccordingToLod
(
ata
,
ms
,
geom
.
getLod
());
break
;
case
AUXILLIARY_TRAFFIC_SPACE
,
TRAFFIC_SPACE:
AbstractSpace
ats
=
(
AbstractSpace
)
ato
;
setMultiSurfaceAccordingToLod
(
ats
,
ms
,
geom
.
getLod
());
break
;
}
}
else
{
throw
new
IllegalStateException
(
"Geometry in TransportationObject cannot be of type "
+
geom
.
getType
()
...
...
@@ -98,10 +98,26 @@ public class TransportationObject extends CityObject {
}
}
private
void
setMultiSurfaceAccordingToLod
(
TransportationComplex
tc
,
MultiSurface
ms
,
Lod
lod
)
{
private
void
setMultiSurfaceAccordingToLod
(
AbstractSpace
ats
,
MultiSurface
ms
,
Lod
lod
)
{
switch
(
lod
)
{
case
LOD0:
ats
.
setLod0MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD2:
ats
.
setLod2MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD3:
ats
.
setLod3MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
default
:
throw
new
IllegalStateException
(
"cannot set geometry with LOD for AuxiliaryTrafficSpace: "
+
lod
);
}
}
private
void
setMultiSurfaceAccordingToLod
(
AbstractTransportationSpace
tc
,
MultiSurface
ms
,
Lod
lod
)
{
switch
(
lod
)
{
case
LOD1:
tc
.
setLod1MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
tc
.
getDeprecatedProperties
().
setLod1MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD2:
tc
.
setLod2MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
...
...
@@ -110,7 +126,7 @@ public class TransportationObject extends CityObject {
tc
.
setLod3MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD4:
tc
.
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
tc
.
getDeprecatedProperties
().
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
default
:
throw
new
IllegalStateException
(
"cannot set geometry with LOD for TransportationComplex: "
+
lod
);
...
...
@@ -119,6 +135,12 @@ public class TransportationObject extends CityObject {
private
void
setMultiSurfaceAccordingToLod
(
AuxiliaryTrafficArea
ata
,
MultiSurface
ms
,
Lod
lod
)
{
switch
(
lod
)
{
case
LOD0:
ata
.
setLod0MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD1:
ata
.
setLod1MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD2:
ata
.
setLod2MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
...
...
@@ -126,7 +148,7 @@ public class TransportationObject extends CityObject {
ata
.
setLod3MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD4:
ata
.
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
ata
.
getDeprecatedProperties
().
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
default
:
throw
new
IllegalStateException
(
"cannot set geometry with LOD for AuxiliaryTrafficArea: "
+
lod
);
...
...
@@ -142,7 +164,7 @@ public class TransportationObject extends CityObject {
ta
.
setLod3MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD4:
ta
.
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
ta
.
getDeprecatedProperties
().
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
default
:
throw
new
IllegalStateException
(
"cannot set geometry with LOD for TrafficArea: "
+
lod
);
...
...
@@ -217,28 +239,36 @@ public class TransportationObject extends CityObject {
case
RAILWAY:
case
SQUARE:
case
TRANSPORTATION_COMPLEX:
Transportation
Complex
tc
=
(
Transportation
Complex
)
ato
;
tc
.
un
setLod1MultiSurface
();
tc
.
un
setLod2MultiSurface
();
tc
.
un
setLod3MultiSurface
();
tc
.
un
setLod4MultiSurface
();
Abstract
Transportation
Space
tc
=
(
Abstract
Transportation
Space
)
ato
;
tc
.
getDeprecatedProperties
().
setLod1MultiSurface
(
null
);
tc
.
setLod2MultiSurface
(
null
);
tc
.
setLod3MultiSurface
(
null
);
tc
.
getDeprecatedProperties
().
setLod4MultiSurface
(
null
);
break
;
case
TRAFFIC_AREA:
TrafficArea
ta
=
(
TrafficArea
)
ato
;
ta
.
un
setLod2MultiSurface
();
ta
.
un
setLod3MultiSurface
();
ta
.
un
setLod4MultiSurface
();
ta
.
setLod2MultiSurface
(
null
);
ta
.
setLod3MultiSurface
(
null
);
ta
.
getDeprecatedProperties
().
setLod4MultiSurface
(
null
);
break
;
case
AUXILLIARY_TRAFFIC_AREA:
AuxiliaryTrafficArea
ata
=
(
AuxiliaryTrafficArea
)
ato
;
ata
.
unsetLod2MultiSurface
();
ata
.
unsetLod3MultiSurface
();
ata
.
unsetLod4MultiSurface
();
ata
.
setLod0MultiSurface
(
null
);
ata
.
setLod1MultiSurface
(
null
);
ata
.
setLod2MultiSurface
(
null
);
ata
.
setLod3MultiSurface
(
null
);
ata
.
getDeprecatedProperties
().
setLod4MultiSurface
(
null
);
break
;
case
AUXILLIARY_TRAFFIC_SPACE
,
TRAFFIC_SPACE:
AbstractSpace
ats
=
(
AbstractSpace
)
ato
;
ats
.
setLod0MultiSurface
(
null
);
ats
.
setLod2MultiSurface
(
null
);
ats
.
setLod3MultiSurface
(
null
);
break
;
}
}
public
void
setGmlObject
(
Abstract
Transportation
Object
tc
)
{
public
void
setGmlObject
(
Abstract
City
Object
tc
)
{
ato
=
tc
;
}
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Vegetation.java
View file @
3f3c1884
...
...
@@ -18,22 +18,23 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
org.citygml4j.factory.GMLGeometryFactory
;
import
org.citygml4j.model.citygml.core.AbstractCityObject
;
import
org.citygml4j.model.citygml.vegetation.AbstractVegetationObject
;
import
org.citygml4j.model.citygml.vegetation.PlantCover
;
import
org.citygml4j.model.citygml.vegetation.SolitaryVegetationObject
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSolid
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSolidProperty
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSurface
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSurfaceProperty
;
import
org.citygml4j.model.gml.geometry.primitives.Solid
;
import
org.citygml4j.model.gml.geometry.primitives.SolidProperty
;
import
java.util.Collections
;
import
org.citygml4j.core.model.core.AbstractCityObject
;
import
org.citygml4j.core.model.vegetation.AbstractVegetationObject
;
import
org.citygml4j.core.model.vegetation.PlantCover
;
import
org.citygml4j.core.model.vegetation.SolitaryVegetationObject
;
import
org.citygml4j.core.util.geometry.GeometryFactory
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSolid
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSolidProperty
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.Solid
;
import
org.xmlobjects.gml.model.geometry.primitives.SolidProperty
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
de.hft.stuttgart.citydoctor2.utils.CityGmlUtils
;
import
de.hft.stuttgart.citydoctor2.utils.CopyHandler
;
import
de.hft.stuttgart.citydoctor2.utils.Copyable
;
/**
...
...
@@ -63,7 +64,7 @@ public class Vegetation extends CityObject {
}
@Override
public
void
reCreateGeometries
(
GML
GeometryFactory
factory
,
ParserConfiguration
config
)
{
public
void
reCreateGeometries
(
GeometryFactory
factory
,
ParserConfiguration
config
)
{
for
(
Geometry
geom
:
getGeometries
())
{
if
(
geom
.
getType
()
==
GeometryType
.
MULTI_SURFACE
)
{
MultiSurface
ms
=
CityGmlUtils
.
createMultiSurface
(
geom
,
factory
,
config
);
...
...
@@ -90,16 +91,16 @@ public class Vegetation extends CityObject {
private
void
setSolidAccordingToLod
(
PlantCover
pc
,
Solid
solid
,
Lod
lod
)
{
switch
(
lod
)
{
case
LOD1:
pc
.
setLod1MultiSolid
(
new
MultiSolidProperty
(
new
MultiSolid
(
solid
)));
pc
.
getDeprecatedProperties
().
setLod1MultiSolid
(
new
MultiSolidProperty
(
new
MultiSolid
(
Collections
.
singletonList
(
new
SolidProperty
(
solid
))
)));
break
;
case
LOD2:
pc
.
setLod2MultiSolid
(
new
MultiSolidProperty
(
new
MultiSolid
(
solid
)));
pc
.
getDeprecatedProperties
().
setLod2MultiSolid
(
new
MultiSolidProperty
(
new
MultiSolid
(
Collections
.
singletonList
(
new
SolidProperty
(
solid
))
)));
break
;
case
LOD3:
pc
.
setLod3MultiSolid
(
new
MultiSolidProperty
(
new
MultiSolid
(
solid
)));
pc
.
getDeprecatedProperties
().
setLod3MultiSolid
(
new
MultiSolidProperty
(
new
MultiSolid
(
Collections
.
singletonList
(
new
SolidProperty
(
solid
))
)));
break
;
case
LOD4:
pc
.
setLod4MultiSolid
(
new
MultiSolidProperty
(
new
MultiSolid
(
solid
)));
pc
.
getDeprecatedProperties
().
setLod4MultiSolid
(
new
MultiSolidProperty
(
new
MultiSolid
(
Collections
.
singletonList
(
new
SolidProperty
(
solid
))
)));
break
;
default
:
throw
new
IllegalStateException
(
"Cannot set Solid with lod to PlantCover:"
+
lod
);
...
...
@@ -109,16 +110,16 @@ public class Vegetation extends CityObject {
private
void
setSolidAccordingToLod
(
SolitaryVegetationObject
svo
,
Solid
solid
,
Lod
lod
)
{
switch
(
lod
)
{
case
LOD1:
svo
.
setLod1Geometry
(
new
SolidProperty
(
solid
));
svo
.
getDeprecatedProperties
().
setLod1Geometry
(
new
SolidProperty
(
solid
));
break
;
case
LOD2:
svo
.
setLod2Geometry
(
new
SolidProperty
(
solid
));
svo
.
getDeprecatedProperties
().
setLod2Geometry
(
new
SolidProperty
(
solid
));
break
;
case
LOD3:
svo
.
setLod3Geometry
(
new
SolidProperty
(
solid
));
svo
.
getDeprecatedProperties
().
setLod3Geometry
(
new
SolidProperty
(
solid
));
break
;
case
LOD4:
svo
.
setLod4Geometry
(
new
SolidProperty
(
solid
));
svo
.
getDeprecatedProperties
().
setLod4Geometry
(
new
SolidProperty
(
solid
));
break
;
default
:
throw
new
IllegalStateException
(
"Cannot set Solid with lod to SolitaryVegetationObject:"
+
lod
);
...
...
@@ -128,7 +129,7 @@ public class Vegetation extends CityObject {
private
void
setMultiSurfaceAccordingToLod
(
PlantCover
pc
,
MultiSurface
ms
,
Lod
lod
)
{
switch
(
lod
)
{
case
LOD1:
pc
.
setLod1MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
pc
.
getDeprecatedProperties
().
setLod1MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD2:
pc
.
setLod2MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
...
...
@@ -137,7 +138,7 @@ public class Vegetation extends CityObject {
pc
.
setLod3MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD4:
pc
.
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
pc
.
getDeprecatedProperties
().
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
default
:
throw
new
IllegalStateException
(
"Cannot set MultiSurface with lod to PlantCover:"
+
lod
);
...
...
@@ -148,16 +149,16 @@ public class Vegetation extends CityObject {
private
void
setMultiSurfaceAccordingToLod
(
SolitaryVegetationObject
svo
,
MultiSurface
ms
,
Lod
lod
)
{
switch
(
lod
)
{
case
LOD1:
svo
.
setLod1Geometry
(
new
MultiSurfaceProperty
(
ms
));
svo
.
getDeprecatedProperties
().
setLod1Geometry
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD2:
svo
.
setLod2Geometry
(
new
MultiSurfaceProperty
(
ms
));
svo
.
getDeprecatedProperties
().
setLod2Geometry
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD3:
svo
.
setLod3Geometry
(
new
MultiSurfaceProperty
(
ms
));
svo
.
getDeprecatedProperties
().
setLod3Geometry
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD4:
svo
.
setLod4Geometry
(
new
MultiSurfaceProperty
(
ms
));
svo
.
getDeprecatedProperties
().
setLod4Geometry
(
new
MultiSurfaceProperty
(
ms
));
break
;
default
:
throw
new
IllegalStateException
(
"Cannot set MultiSurface with lod to SolitaryVegetationObject:"
+
lod
);
...
...
@@ -181,16 +182,16 @@ public class Vegetation extends CityObject {
public
void
unsetGmlGeometries
()
{
if
(
type
==
VegetationType
.
SOLITARY_VEGETATION_OBJECT
)
{
SolitaryVegetationObject
svo
=
(
SolitaryVegetationObject
)
citygmlVegetation
;
svo
.
un
setLod1Geometry
();
svo
.
un
setLod2Geometry
();
svo
.
un
setLod3Geometry
();
svo
.
un
setLod4Geometry
();
svo
.
getDeprecatedProperties
().
setLod1Geometry
(
null
);
svo
.
getDeprecatedProperties
().
setLod2Geometry
(
null
);
svo
.
getDeprecatedProperties
().
setLod3Geometry
(
null
);
svo
.
getDeprecatedProperties
().
setLod4Geometry
(
null
);
}
else
{
PlantCover
pc
=
(
PlantCover
)
citygmlVegetation
;
pc
.
un
setLod1MultiSurface
();
pc
.
un
setLod2MultiSurface
();
pc
.
un
setLod3MultiSurface
();
pc
.
un
setLod4MultiSurface
();
pc
.
getDeprecatedProperties
().
setLod1MultiSurface
(
null
);
pc
.
setLod2MultiSurface
(
null
);
pc
.
setLod3MultiSurface
(
null
);
pc
.
getDeprecatedProperties
().
setLod4MultiSurface
(
null
);
}
}
...
...
@@ -211,11 +212,4 @@ public class Vegetation extends CityObject {
public
Copyable
createCopyInstance
()
{
return
new
Vegetation
(
type
);
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
super
.
fillValues
(
original
,
handler
);
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/WaterObject.java
View file @
3f3c1884
...
...
@@ -18,11 +18,14 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
org.citygml4j.factory.GMLGeometryFactory
;
import
org.citygml4j.model.citygml.core.AbstractCityObject
;
import
org.citygml4j.model.citygml.waterbody.WaterBody
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSurface
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSurfaceProperty
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.citygml4j.core.model.core.AbstractCityObject
;
import
org.citygml4j.core.model.waterbody.WaterBody
;
import
org.citygml4j.core.util.geometry.GeometryFactory
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
...
...
@@ -41,16 +44,17 @@ public class WaterObject extends CityObject {
private
static
final
long
serialVersionUID
=
-
3821060595086337424L
;
private
WaterBody
gmlWater
;
private
List
<
BoundarySurface
>
boundarySurfaceList
=
new
ArrayList
<>();
@Override
public
void
reCreateGeometries
(
GML
GeometryFactory
factory
,
ParserConfiguration
config
)
{
public
void
reCreateGeometries
(
GeometryFactory
factory
,
ParserConfiguration
config
)
{
for
(
Geometry
geom
:
getGeometries
())
{
if
(
geom
.
getType
()
==
GeometryType
.
MULTI_SURFACE
)
{
MultiSurface
ms
=
CityGmlUtils
.
createMultiSurface
(
geom
,
factory
,
config
);
if
(
geom
.
getLod
()
==
Lod
.
LOD0
)
{
gmlWater
.
setLod0MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
}
else
if
(
geom
.
getLod
()
==
Lod
.
LOD1
)
{
gmlWater
.
setLod1MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
gmlWater
.
getDeprecatedProperties
().
setLod1MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
}
else
{
throw
new
IllegalStateException
(
"Cannot add MultiSurface geometry with lod to WaterBody:"
+
geom
.
getLod
());
...
...
@@ -60,6 +64,20 @@ public class WaterObject extends CityObject {
}
}
}
/**
* Getter for all boundary surfaces contained in this building.
*
* @return the boundary surfaces
*/
public
List
<
BoundarySurface
>
getBoundarySurfaces
()
{
return
boundarySurfaceList
;
}
public
void
addBoundarySurface
(
BoundarySurface
bs
)
{
boundarySurfaceList
.
add
(
bs
);
bs
.
setParent
(
this
);
}
@Override
public
FeatureType
getFeatureType
()
{
...
...
@@ -81,12 +99,8 @@ public class WaterObject extends CityObject {
@Override
public
void
unsetGmlGeometries
()
{
gmlWater
.
unsetLod0MultiSurface
();
gmlWater
.
unsetLod1MultiSurface
();
gmlWater
.
unsetLod1Solid
();
gmlWater
.
unsetLod2Solid
();
gmlWater
.
unsetLod3Solid
();
gmlWater
.
unsetLod4Solid
();
gmlWater
.
setLod0MultiSurface
(
null
);
gmlWater
.
getDeprecatedProperties
().
setLod1MultiSurface
(
null
);
}
public
void
setGmlObject
(
WaterBody
waterBody
)
{
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/exceptions/CityDoctorWriteException.java
0 → 100644
View file @
3f3c1884
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.exceptions
;
public
class
CityDoctorWriteException
extends
Exception
{
private
static
final
long
serialVersionUID
=
2902212162405599516L
;
public
CityDoctorWriteException
()
{
super
();
}
public
CityDoctorWriteException
(
String
message
,
Throwable
cause
,
boolean
enableSuppression
,
boolean
writableStackTrace
)
{
super
(
message
,
cause
,
enableSuppression
,
writableStackTrace
);
}
public
CityDoctorWriteException
(
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
}
public
CityDoctorWriteException
(
String
message
)
{
super
(
message
);
}
public
CityDoctorWriteException
(
Throwable
cause
)
{
super
(
cause
);
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/FeatureMapper.java
deleted
100644 → 0
View file @
92f3e523
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.mapper
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.citygml4j.model.citygml.bridge.AbstractBridge
;
import
org.citygml4j.model.citygml.bridge.Bridge
;
import
org.citygml4j.model.citygml.bridge.BridgePart
;
import
org.citygml4j.model.citygml.building.BuildingInstallationProperty
;
import
org.citygml4j.model.citygml.building.BuildingPartProperty
;
import
org.citygml4j.model.citygml.building.OpeningProperty
;
import
org.citygml4j.model.citygml.core.CityModel
;
import
org.citygml4j.model.citygml.landuse.LandUse
;
import
org.citygml4j.model.citygml.transportation.AuxiliaryTrafficArea
;
import
org.citygml4j.model.citygml.transportation.AuxiliaryTrafficAreaProperty
;
import
org.citygml4j.model.citygml.transportation.Railway
;
import
org.citygml4j.model.citygml.transportation.Road
;
import
org.citygml4j.model.citygml.transportation.Square
;
import
org.citygml4j.model.citygml.transportation.Track
;
import
org.citygml4j.model.citygml.transportation.TrafficArea
;
import
org.citygml4j.model.citygml.transportation.TrafficAreaProperty
;
import
org.citygml4j.model.citygml.transportation.TransportationComplex
;
import
org.citygml4j.model.citygml.vegetation.PlantCover
;
import
org.citygml4j.model.citygml.vegetation.SolitaryVegetationObject
;
import
org.citygml4j.model.citygml.waterbody.WaterBody
;
import
org.citygml4j.model.gml.geometry.AbstractGeometry
;
import
org.citygml4j.model.gml.geometry.GeometryProperty
;
import
org.citygml4j.model.gml.geometry.complexes.CompositeSurface
;
import
org.citygml4j.model.gml.geometry.primitives.AbstractSolid
;
import
org.citygml4j.util.walker.FeatureWalker
;
import
de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType
;
import
de.hft.stuttgart.citydoctor2.datastructure.BridgeObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.BridgeObject.BridgeType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.BuildingInstallation
;
import
de.hft.stuttgart.citydoctor2.datastructure.BuildingPart
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.GmlId
;
import
de.hft.stuttgart.citydoctor2.datastructure.LandObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinkedPolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.datastructure.Opening
;
import
de.hft.stuttgart.citydoctor2.datastructure.OpeningType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.SurfaceFeatureType
;
import
de.hft.stuttgart.citydoctor2.datastructure.TransportationObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.TransportationObject.TransportationType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vegetation
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vegetation.VegetationType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
import
de.hft.stuttgart.citydoctor2.datastructure.WaterObject
;
import
de.hft.stuttgart.citydoctor2.math.graph.KDTree
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
de.hft.stuttgart.citydoctor2.utils.Localization
;
import
de.hft.stuttgart.citydoctor2.utils.Pair
;
/**
* This walker maps all cityGML4j features to the respective CityDoctor data
* structure.
*
* @author Matthias Betz
*
*/
public
class
FeatureMapper
extends
FeatureWalker
{
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
FeatureMapper
.
class
);
private
CityDoctorModel
model
;
private
ParserConfiguration
config
;
private
double
neighborDistance
;
public
FeatureMapper
(
ParserConfiguration
config
,
File
file
)
{
this
.
config
=
config
;
neighborDistance
=
1.8d
/
Math
.
pow
(
10
,
config
.
getNumberOfRoundingPlaces
());
model
=
new
CityDoctorModel
(
config
,
file
);
}
@Override
public
void
visit
(
WaterBody
waterBody
)
{
WaterObject
wo
=
new
WaterObject
();
model
.
addWater
(
wo
);
wo
.
setGmlObject
(
waterBody
);
if
(
waterBody
.
isSetId
())
{
wo
.
setGmlId
(
new
GmlId
(
waterBody
.
getId
()));
}
mapWaterBodyGeometries
(
waterBody
,
wo
);
}
private
void
mapWaterBodyGeometries
(
WaterBody
waterBody
,
WaterObject
wo
)
{
Map
<
String
,
ConcretePolygon
>
polygons
=
new
HashMap
<>();
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
=
new
ArrayList
<>();
GeometryMapper
.
mapLod0MultiSurface
(
waterBody
.
getLod0MultiSurface
(),
wo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
waterBody
.
unsetLod0MultiSurface
();
GeometryMapper
.
mapLod1MultiSurface
(
waterBody
.
getLod1MultiSurface
(),
wo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
waterBody
.
unsetLod1MultiSurface
();
GeometryMapper
.
mapLod1Solid
(
waterBody
.
getLod1Solid
(),
wo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
waterBody
.
unsetLod1Solid
();
GeometryMapper
.
mapLod2Solid
(
waterBody
.
getLod2Solid
(),
wo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
waterBody
.
unsetLod2Solid
();
GeometryMapper
.
mapLod3Solid
(
waterBody
.
getLod3Solid
(),
wo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
waterBody
.
unsetLod3Solid
();
GeometryMapper
.
mapLod4Solid
(
waterBody
.
getLod4Solid
(),
wo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
waterBody
.
unsetLod4Solid
();
createLinkedPolygons
(
polygons
,
linkedPolygons
);
updateEdgesAndVertices
(
wo
);
}
private
void
createLinkedPolygons
(
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
)
{
for
(
Pair
<
String
,
Geometry
>
link
:
linkedPolygons
)
{
ConcretePolygon
concPoly
=
polygons
.
get
(
link
.
getValue0
());
if
(
concPoly
==
null
)
{
if
(
logger
.
isWarnEnabled
())
{
logger
.
warn
(
Localization
.
getText
(
"FeatureMapper.polygonUnreferenced"
),
link
.
getValue0
());
}
continue
;
}
Geometry
geom
=
link
.
getValue1
();
LinkedPolygon
lPoly
=
new
LinkedPolygon
(
concPoly
,
geom
);
if
(
geom
.
getParent
()
instanceof
BoundarySurface
)
{
BoundarySurface
bs
=
(
BoundarySurface
)
geom
.
getParent
();
lPoly
.
setPartOfSurface
(
bs
);
if
(
bs
.
getParent
()
instanceof
BuildingInstallation
)
{
lPoly
.
setPartOfInstallation
((
BuildingInstallation
)
bs
.
getParent
());
}
}
geom
.
addPolygon
(
lPoly
);
}
}
private
void
updateEdgesAndVertices
(
CityObject
co
)
{
// searching for neighboring vertices, replacing them with one single vertex to
// avoid later problems with edges and manifold problems
for
(
Geometry
geom
:
co
.
getGeometries
())
{
KDTree
tree
=
new
KDTree
();
for
(
Polygon
poly
:
geom
.
getPolygons
())
{
LinearRing
lr
=
poly
.
getExteriorRing
();
updateRing
(
tree
,
lr
);
for
(
LinearRing
innerRing
:
poly
.
getInnerRings
())
{
updateRing
(
tree
,
innerRing
);
}
}
if
(!
config
.
useLowMemoryConsumption
())
{
// no low memory consumption mode meaning create all meta information in geometry
geom
.
updateEdgesAndVertices
();
}
}
}
private
void
updateRing
(
KDTree
tree
,
LinearRing
lr
)
{
for
(
int
i
=
0
;
i
<
lr
.
getVertices
().
size
();
i
++)
{
Vertex
v
=
lr
.
getVertices
().
get
(
i
);
List
<
Vertex
>
nodesInRange
=
tree
.
getNodesInRange
(
v
,
neighborDistance
);
if
(
nodesInRange
.
isEmpty
())
{
tree
.
add
(
v
);
}
else
{
// replace other vertex with any neighboring one
Vertex
original
=
nodesInRange
.
get
(
0
);
lr
.
setVertex
(
i
,
original
);
}
}
}
@Override
public
void
visit
(
PlantCover
plantCover
)
{
Vegetation
veg
=
new
Vegetation
(
VegetationType
.
PLANT_COVER
);
model
.
addVegetation
(
veg
);
mapPlantCover
(
plantCover
,
veg
);
}
private
void
mapPlantCover
(
PlantCover
plantCover
,
Vegetation
veg
)
{
veg
.
setGmlObject
(
plantCover
);
if
(
plantCover
.
isSetId
())
{
veg
.
setGmlId
(
new
GmlId
(
plantCover
.
getId
()));
}
mapPlantCoverGeometries
(
plantCover
,
veg
);
}
private
void
mapPlantCoverGeometries
(
PlantCover
plantCover
,
Vegetation
veg
)
{
Map
<
String
,
ConcretePolygon
>
polygons
=
new
HashMap
<>();
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
=
new
ArrayList
<>();
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
GeometryMapper
.
mapLod1MultiSurface
(
plantCover
.
getLod1MultiSurface
(),
veg
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
plantCover
.
unsetLod1MultiSurface
();
GeometryMapper
.
mapLod2MultiSurface
(
plantCover
.
getLod2MultiSurface
(),
veg
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
plantCover
.
unsetLod2MultiSurface
();
GeometryMapper
.
mapLod3MultiSurface
(
plantCover
.
getLod3MultiSurface
(),
veg
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
plantCover
.
unsetLod3MultiSurface
();
GeometryMapper
.
mapLod4MultiSurface
(
plantCover
.
getLod4MultiSurface
(),
veg
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
plantCover
.
unsetLod4MultiSurface
();
createLinkedPolygons
(
polygons
,
linkedPolygons
);
updateEdgesAndVertices
(
veg
);
}
@Override
public
void
visit
(
SolitaryVegetationObject
solitaryVegetationObject
)
{
Vegetation
veg
=
new
Vegetation
(
VegetationType
.
SOLITARY_VEGETATION_OBJECT
);
model
.
addVegetation
(
veg
);
mapSolitaryVegObject
(
solitaryVegetationObject
,
veg
);
}
private
void
mapSolitaryVegObject
(
SolitaryVegetationObject
svo
,
Vegetation
veg
)
{
veg
.
setGmlObject
(
svo
);
if
(
svo
.
isSetId
())
{
veg
.
setGmlId
(
new
GmlId
(
svo
.
getId
()));
}
mapSolitaryVegGeometries
(
svo
,
veg
);
}
private
void
mapSolitaryVegGeometries
(
SolitaryVegetationObject
svo
,
Vegetation
veg
)
{
Map
<
String
,
ConcretePolygon
>
polygons
=
new
HashMap
<>();
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
=
new
ArrayList
<>();
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
GeometryMapper
.
mapLod1Geometry
(
svo
.
getLod1Geometry
(),
veg
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
svo
.
unsetLod1Geometry
();
GeometryMapper
.
mapLod2Geometry
(
svo
.
getLod2Geometry
(),
veg
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
svo
.
unsetLod2Geometry
();
GeometryMapper
.
mapLod3Geometry
(
svo
.
getLod3Geometry
(),
veg
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
svo
.
unsetLod3Geometry
();
GeometryMapper
.
mapLod4Geometry
(
svo
.
getLod4Geometry
(),
veg
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
svo
.
unsetLod4Geometry
();
createLinkedPolygons
(
polygons
,
linkedPolygons
);
updateEdgesAndVertices
(
veg
);
}
@Override
public
void
visit
(
LandUse
landUse
)
{
LandObject
lo
=
new
LandObject
(
landUse
);
model
.
addLand
(
lo
);
mapLandUse
(
landUse
,
lo
);
}
private
void
mapLandUse
(
LandUse
landUse
,
LandObject
lo
)
{
lo
.
setGmlObject
(
landUse
);
if
(
landUse
.
isSetId
())
{
lo
.
setGmlId
(
new
GmlId
(
landUse
.
getId
()));
}
mapLandUseGeometries
(
landUse
,
lo
);
}
private
void
mapLandUseGeometries
(
LandUse
landUse
,
LandObject
lo
)
{
Map
<
String
,
ConcretePolygon
>
polygons
=
new
HashMap
<>();
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
=
new
ArrayList
<>();
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
GeometryMapper
.
mapLod0MultiSurface
(
landUse
.
getLod0MultiSurface
(),
lo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
landUse
.
unsetLod0MultiSurface
();
GeometryMapper
.
mapLod1MultiSurface
(
landUse
.
getLod1MultiSurface
(),
lo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
landUse
.
unsetLod1MultiSurface
();
GeometryMapper
.
mapLod2MultiSurface
(
landUse
.
getLod2MultiSurface
(),
lo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
landUse
.
unsetLod2MultiSurface
();
GeometryMapper
.
mapLod3MultiSurface
(
landUse
.
getLod3MultiSurface
(),
lo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
landUse
.
unsetLod3MultiSurface
();
GeometryMapper
.
mapLod4MultiSurface
(
landUse
.
getLod4MultiSurface
(),
lo
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
landUse
.
unsetLod4MultiSurface
();
createLinkedPolygons
(
polygons
,
linkedPolygons
);
updateEdgesAndVertices
(
lo
);
}
@Override
public
void
visit
(
Road
road
)
{
TransportationObject
trans
=
new
TransportationObject
(
TransportationType
.
ROAD
);
mapTransportationComplex
(
road
,
trans
);
}
@Override
public
void
visit
(
Railway
railway
)
{
TransportationObject
trans
=
new
TransportationObject
(
TransportationType
.
RAILWAY
);
mapTransportationComplex
(
railway
,
trans
);
}
@Override
public
void
visit
(
Square
square
)
{
TransportationObject
trans
=
new
TransportationObject
(
TransportationType
.
SQUARE
);
mapTransportationComplex
(
square
,
trans
);
}
@Override
public
void
visit
(
Track
track
)
{
TransportationObject
trans
=
new
TransportationObject
(
TransportationType
.
TRACK
);
mapTransportationComplex
(
track
,
trans
);
}
@Override
public
void
visit
(
AuxiliaryTrafficArea
auxiliaryTrafficArea
)
{
TransportationObject
trans
=
new
TransportationObject
(
TransportationType
.
AUXILLIARY_TRAFFIC_AREA
);
mapAuxTrafficArea
(
auxiliaryTrafficArea
,
trans
);
}
@Override
public
void
visit
(
TransportationComplex
tc
)
{
TransportationObject
trans
=
new
TransportationObject
(
TransportationType
.
TRANSPORTATION_COMPLEX
);
model
.
addTransportation
(
trans
);
mapTransportationComplex
(
tc
,
trans
);
if
(
tc
.
isSetAuxiliaryTrafficArea
())
{
for
(
AuxiliaryTrafficAreaProperty
atap
:
tc
.
getAuxiliaryTrafficArea
())
{
if
(
atap
.
isSetAuxiliaryTrafficArea
())
{
TransportationObject
subTrans
=
new
TransportationObject
(
TransportationType
.
AUXILLIARY_TRAFFIC_AREA
);
trans
.
addChild
(
subTrans
);
mapAuxTrafficArea
(
atap
.
getAuxiliaryTrafficArea
(),
subTrans
);
}
}
}
if
(
tc
.
isSetTrafficArea
())
{
for
(
TrafficAreaProperty
tap
:
tc
.
getTrafficArea
())
{
if
(
tap
.
isSetTrafficArea
())
{
TransportationObject
subTrans
=
new
TransportationObject
(
TransportationType
.
TRAFFIC_AREA
);
trans
.
addChild
(
subTrans
);
mapTrafficArea
(
tap
.
getTrafficArea
(),
subTrans
);
}
}
}
}
@Override
public
void
visit
(
TrafficArea
trafficArea
)
{
TransportationObject
trans
=
new
TransportationObject
(
TransportationType
.
TRAFFIC_AREA
);
model
.
addTransportation
(
trans
);
mapTrafficArea
(
trafficArea
,
trans
);
}
private
void
mapTrafficArea
(
TrafficArea
ta
,
TransportationObject
to
)
{
to
.
setGmlObject
(
ta
);
if
(
ta
.
isSetId
())
{
to
.
setGmlId
(
new
GmlId
(
ta
.
getId
()));
}
mapTrafficAreaGeometries
(
ta
,
to
);
}
private
void
mapTrafficAreaGeometries
(
TrafficArea
ta
,
TransportationObject
to
)
{
Map
<
String
,
ConcretePolygon
>
polygons
=
new
HashMap
<>();
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
=
new
ArrayList
<>();
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
GeometryMapper
.
mapLod2MultiSurface
(
ta
.
getLod2MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ta
.
unsetLod2MultiSurface
();
GeometryMapper
.
mapLod3MultiSurface
(
ta
.
getLod3MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ta
.
unsetLod3MultiSurface
();
GeometryMapper
.
mapLod4MultiSurface
(
ta
.
getLod4MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ta
.
unsetLod4MultiSurface
();
createLinkedPolygons
(
polygons
,
linkedPolygons
);
updateEdgesAndVertices
(
to
);
}
private
void
mapAuxTrafficArea
(
AuxiliaryTrafficArea
ata
,
TransportationObject
to
)
{
to
.
setGmlObject
(
ata
);
if
(
ata
.
isSetId
())
{
to
.
setGmlId
(
new
GmlId
(
ata
.
getId
()));
}
mapAuxTrafficAreaGeometries
(
ata
,
to
);
}
private
void
mapAuxTrafficAreaGeometries
(
AuxiliaryTrafficArea
ata
,
TransportationObject
to
)
{
Map
<
String
,
ConcretePolygon
>
polygons
=
new
HashMap
<>();
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
=
new
ArrayList
<>();
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
GeometryMapper
.
mapLod2MultiSurface
(
ata
.
getLod2MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ata
.
unsetLod2MultiSurface
();
GeometryMapper
.
mapLod3MultiSurface
(
ata
.
getLod3MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ata
.
unsetLod3MultiSurface
();
GeometryMapper
.
mapLod4MultiSurface
(
ata
.
getLod4MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ata
.
unsetLod4MultiSurface
();
createLinkedPolygons
(
polygons
,
linkedPolygons
);
updateEdgesAndVertices
(
to
);
}
private
void
mapTransportationComplex
(
TransportationComplex
tc
,
TransportationObject
to
)
{
model
.
addTransportation
(
to
);
to
.
setGmlObject
(
tc
);
if
(
tc
.
isSetId
())
{
to
.
setGmlId
(
new
GmlId
(
tc
.
getId
()));
}
mapTransportationComplexGeometries
(
tc
,
to
);
}
private
void
mapTransportationComplexGeometries
(
TransportationComplex
tc
,
TransportationObject
to
)
{
Map
<
String
,
ConcretePolygon
>
polygons
=
new
HashMap
<>();
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
=
new
ArrayList
<>();
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
GeometryMapper
.
mapLod1MultiSurface
(
tc
.
getLod1MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
tc
.
unsetLod1MultiSurface
();
GeometryMapper
.
mapLod2MultiSurface
(
tc
.
getLod2MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
tc
.
unsetLod2MultiSurface
();
GeometryMapper
.
mapLod3MultiSurface
(
tc
.
getLod3MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
tc
.
unsetLod3MultiSurface
();
GeometryMapper
.
mapLod4MultiSurface
(
tc
.
getLod4MultiSurface
(),
to
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
tc
.
unsetLod4MultiSurface
();
createLinkedPolygons
(
polygons
,
linkedPolygons
);
updateEdgesAndVertices
(
to
);
}
@Override
public
void
visit
(
org
.
citygml4j
.
model
.
citygml
.
building
.
Building
building
)
{
Building
coBuilding
=
new
Building
();
model
.
addBuilding
(
coBuilding
);
mapAbstractBuilding
(
building
,
coBuilding
);
if
(
building
.
isSetConsistsOfBuildingPart
())
{
for
(
BuildingPartProperty
bpp
:
building
.
getConsistsOfBuildingPart
())
{
if
(
bpp
.
isSetBuildingPart
())
{
BuildingPart
coBuildingPart
=
new
BuildingPart
(
coBuilding
);
mapAbstractBuilding
(
bpp
.
getBuildingPart
(),
coBuildingPart
);
}
}
}
}
private
void
mapAbstractBuilding
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractBuilding
ab
,
AbstractBuilding
coBuilding
)
{
coBuilding
.
setGmlObject
(
ab
);
if
(
ab
.
isSetId
())
{
coBuilding
.
setGmlId
(
new
GmlId
(
ab
.
getId
()));
}
Map
<
String
,
ConcretePolygon
>
polygons
=
new
HashMap
<>();
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
=
new
ArrayList
<>();
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
mapBuildingMultiSurfaceGeometries
(
ab
,
coBuilding
,
polygons
,
linkedPolygons
,
vertexMap
);
mapBuildingSolidGeometries
(
ab
,
coBuilding
,
polygons
,
linkedPolygons
,
vertexMap
);
// handle boundary surfaces
if
(
ab
.
isSetBoundedBySurface
())
{
for
(
org
.
citygml4j
.
model
.
citygml
.
building
.
BoundarySurfaceProperty
bsp
:
ab
.
getBoundedBySurface
())
{
mapBuildingSurface
(
bsp
,
coBuilding
,
polygons
,
linkedPolygons
,
vertexMap
);
}
}
// handle outer building installations
if
(
ab
.
isSetOuterBuildingInstallation
())
{
for
(
BuildingInstallationProperty
bip
:
ab
.
getOuterBuildingInstallation
())
{
mapBuildingInstallation
(
bip
,
coBuilding
,
polygons
,
linkedPolygons
,
vertexMap
);
}
}
createLinkedPolygons
(
polygons
,
linkedPolygons
);
updateEdgesAndVertices
(
coBuilding
);
}
private
void
mapBuildingInstallation
(
BuildingInstallationProperty
bip
,
AbstractBuilding
coBuilding
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(!
bip
.
isSetBuildingInstallation
())
{
return
;
}
BuildingInstallation
coBi
=
new
BuildingInstallation
();
coBuilding
.
addBuildingInstallation
(
coBi
);
org
.
citygml4j
.
model
.
citygml
.
building
.
BuildingInstallation
gmlBi
=
bip
.
getBuildingInstallation
();
coBi
.
setGmlObject
(
gmlBi
);
if
(
gmlBi
.
isSetLod2Geometry
())
{
GeometryProperty
<?
extends
AbstractGeometry
>
abstractGeometry
=
gmlBi
.
getLod2Geometry
();
GeometryType
type
=
extractGeometryType
(
abstractGeometry
);
Geometry
geom
=
new
Geometry
(
type
,
Lod
.
LOD2
);
GeometryMapper
mapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
GeometryMapper
.
mapBuildingInstallationIntoGeometry
(
abstractGeometry
,
mapper
,
coBi
);
coBi
.
addGeometry
(
geom
);
gmlBi
.
unsetLod2Geometry
();
}
if
(
gmlBi
.
isSetLod3Geometry
())
{
GeometryProperty
<?
extends
AbstractGeometry
>
abstractGeometry
=
gmlBi
.
getLod3Geometry
();
GeometryType
type
=
extractGeometryType
(
abstractGeometry
);
Geometry
geom
=
new
Geometry
(
type
,
Lod
.
LOD3
);
GeometryMapper
mapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
GeometryMapper
.
mapBuildingInstallationIntoGeometry
(
abstractGeometry
,
mapper
,
coBi
);
coBi
.
addGeometry
(
geom
);
gmlBi
.
unsetLod3Geometry
();
}
if
(
gmlBi
.
isSetLod4Geometry
())
{
GeometryProperty
<?
extends
AbstractGeometry
>
abstractGeometry
=
gmlBi
.
getLod4Geometry
();
GeometryType
type
=
extractGeometryType
(
abstractGeometry
);
Geometry
geom
=
new
Geometry
(
type
,
Lod
.
LOD4
);
GeometryMapper
mapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
GeometryMapper
.
mapBuildingInstallationIntoGeometry
(
abstractGeometry
,
mapper
,
coBi
);
coBi
.
addGeometry
(
geom
);
gmlBi
.
unsetLod4Geometry
();
}
// handle boundary surfaces
if
(
gmlBi
.
isSetBoundedBySurface
())
{
for
(
org
.
citygml4j
.
model
.
citygml
.
building
.
BoundarySurfaceProperty
bsp
:
gmlBi
.
getBoundedBySurface
())
{
mapBuildingInstallationSurface
(
bsp
,
coBi
,
polygons
,
linkedPolygons
,
vertexMap
);
}
}
updateEdgesAndVertices
(
coBi
);
}
private
GeometryType
extractGeometryType
(
GeometryProperty
<?
extends
AbstractGeometry
>
agp
)
{
AbstractGeometry
abstractGeometry
=
agp
.
getObject
();
if
(
abstractGeometry
instanceof
CompositeSurface
)
{
return
GeometryType
.
COMPOSITE_SURFACE
;
}
else
if
(
abstractGeometry
instanceof
AbstractSolid
)
{
return
GeometryType
.
SOLID
;
}
return
GeometryType
.
MULTI_SURFACE
;
}
private
void
mapBuildingSolidGeometries
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractBuilding
ab
,
AbstractBuilding
coBuilding
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
GeometryMapper
.
mapLod1Solid
(
ab
.
getLod1Solid
(),
coBuilding
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ab
.
unsetLod1Solid
();
GeometryMapper
.
mapLod2Solid
(
ab
.
getLod2Solid
(),
coBuilding
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ab
.
unsetLod2Solid
();
GeometryMapper
.
mapLod3Solid
(
ab
.
getLod3Solid
(),
coBuilding
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ab
.
unsetLod3Solid
();
GeometryMapper
.
mapLod4Solid
(
ab
.
getLod4Solid
(),
coBuilding
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ab
.
unsetLod4Solid
();
}
private
void
mapBuildingMultiSurfaceGeometries
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractBuilding
ab
,
AbstractBuilding
coBuilding
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
GeometryMapper
.
mapLod1MultiSurface
(
ab
.
getLod1MultiSurface
(),
coBuilding
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ab
.
unsetLod1MultiSurface
();
GeometryMapper
.
mapLod2MultiSurface
(
ab
.
getLod2MultiSurface
(),
coBuilding
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ab
.
unsetLod2MultiSurface
();
GeometryMapper
.
mapLod3MultiSurface
(
ab
.
getLod3MultiSurface
(),
coBuilding
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ab
.
unsetLod3MultiSurface
();
GeometryMapper
.
mapLod4MultiSurface
(
ab
.
getLod4MultiSurface
(),
coBuilding
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ab
.
unsetLod4MultiSurface
();
}
private
void
mapBuildingSurface
(
org
.
citygml4j
.
model
.
citygml
.
building
.
BoundarySurfaceProperty
bsp
,
AbstractBuilding
coBuilding
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(!
bsp
.
isSetBoundarySurface
())
{
return
;
}
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractBoundarySurface
abs
=
bsp
.
getBoundarySurface
();
BoundarySurfaceType
surfaceType
=
mapSurfaceType
(
abs
);
BoundarySurface
bs
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
surfaceType
,
abs
);
if
(
abs
.
isSetId
())
{
bs
.
setGmlId
(
new
GmlId
(
abs
.
getId
()));
}
coBuilding
.
addBoundarySurface
(
bs
);
createBoundarySurfaceGeometries
(
abs
,
bs
,
null
,
polygons
,
linkedPolygons
,
vertexMap
);
mapBuildingOpenings
(
abs
.
getOpening
(),
bs
,
polygons
,
linkedPolygons
,
vertexMap
);
updateEdgesAndVertices
(
bs
);
}
private
void
mapBuildingOpenings
(
List
<
OpeningProperty
>
openings
,
BoundarySurface
bs
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
openings
==
null
||
openings
.
isEmpty
())
{
return
;
}
for
(
org
.
citygml4j
.
model
.
citygml
.
building
.
OpeningProperty
op
:
openings
)
{
if
(!
op
.
isSetOpening
())
{
continue
;
}
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractOpening
ap
=
op
.
getOpening
();
OpeningType
type
=
mapOpeningType
(
ap
);
Opening
opening
=
new
Opening
(
type
,
SurfaceFeatureType
.
BUILDING
,
bs
,
ap
);
bs
.
addOpening
(
opening
);
createOpeningGeometries
(
ap
,
opening
,
polygons
,
linkedPolygons
,
vertexMap
);
updateEdgesAndVertices
(
opening
);
}
}
private
void
createOpeningGeometries
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractOpening
ap
,
Opening
opening
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
ap
.
isSetLod3MultiSurface
())
{
GeometryMapper
.
mapLod3MultiSurface
(
ap
.
getLod3MultiSurface
(),
opening
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ap
.
unsetLod3MultiSurface
();
}
if
(
ap
.
isSetLod4MultiSurface
())
{
GeometryMapper
.
mapLod4MultiSurface
(
ap
.
getLod3MultiSurface
(),
opening
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ap
.
unsetLod4MultiSurface
();
}
}
private
OpeningType
mapOpeningType
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractOpening
ap
)
{
if
(
ap
instanceof
org
.
citygml4j
.
model
.
citygml
.
building
.
Door
)
{
return
OpeningType
.
DOOR
;
}
if
(
ap
instanceof
org
.
citygml4j
.
model
.
citygml
.
building
.
Window
)
{
return
OpeningType
.
WINDOW
;
}
return
OpeningType
.
UNKNOWN
;
}
private
void
mapBuildingInstallationSurface
(
org
.
citygml4j
.
model
.
citygml
.
building
.
BoundarySurfaceProperty
bsp
,
BuildingInstallation
coBi
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(!
bsp
.
isSetBoundarySurface
())
{
return
;
}
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractBoundarySurface
abs
=
bsp
.
getBoundarySurface
();
BoundarySurfaceType
surfaceType
=
mapSurfaceType
(
abs
);
BoundarySurface
bs
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
surfaceType
,
abs
);
if
(
abs
.
isSetId
())
{
bs
.
setGmlId
(
new
GmlId
(
abs
.
getId
()));
}
coBi
.
addBoundarySurface
(
bs
);
createBoundarySurfaceGeometries
(
abs
,
bs
,
coBi
,
polygons
,
linkedPolygons
,
vertexMap
);
mapBuildingOpenings
(
abs
.
getOpening
(),
bs
,
polygons
,
linkedPolygons
,
vertexMap
);
updateEdgesAndVertices
(
bs
);
}
private
void
createBoundarySurfaceGeometries
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractBoundarySurface
abs
,
BoundarySurface
bs
,
BuildingInstallation
coBi
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
abs
.
isSetLod2MultiSurface
())
{
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD2
);
GeometryMapper
mapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
GeometryMapper
.
mapBoundarySurfaceIntoGeometry
(
abs
.
getLod2MultiSurface
(),
mapper
,
bs
,
coBi
);
bs
.
addGeometry
(
geom
);
abs
.
unsetLod2MultiSurface
();
}
if
(
abs
.
isSetLod3MultiSurface
())
{
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD3
);
GeometryMapper
mapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
GeometryMapper
.
mapBoundarySurfaceIntoGeometry
(
abs
.
getLod3MultiSurface
(),
mapper
,
bs
,
coBi
);
bs
.
addGeometry
(
geom
);
abs
.
unsetLod3MultiSurface
();
}
if
(
abs
.
isSetLod4MultiSurface
())
{
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD4
);
GeometryMapper
mapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
GeometryMapper
.
mapBoundarySurfaceIntoGeometry
(
abs
.
getLod4MultiSurface
(),
mapper
,
bs
,
coBi
);
bs
.
addGeometry
(
geom
);
abs
.
unsetLod4MultiSurface
();
}
}
private
void
createBoundarySurfaceGeometries
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractBoundarySurface
abs
,
BoundarySurface
bs
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
abs
.
isSetLod2MultiSurface
())
{
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD2
);
GeometryMapper
mapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
GeometryMapper
.
mapBoundarySurfaceIntoGeometry
(
abs
.
getLod2MultiSurface
(),
mapper
,
bs
,
null
);
bs
.
addGeometry
(
geom
);
abs
.
unsetLod2MultiSurface
();
}
if
(
abs
.
isSetLod3MultiSurface
())
{
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD3
);
GeometryMapper
mapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
GeometryMapper
.
mapBoundarySurfaceIntoGeometry
(
abs
.
getLod3MultiSurface
(),
mapper
,
bs
,
null
);
bs
.
addGeometry
(
geom
);
abs
.
unsetLod3MultiSurface
();
}
if
(
abs
.
isSetLod4MultiSurface
())
{
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD4
);
GeometryMapper
mapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
GeometryMapper
.
mapBoundarySurfaceIntoGeometry
(
abs
.
getLod4MultiSurface
(),
mapper
,
bs
,
null
);
bs
.
addGeometry
(
geom
);
abs
.
unsetLod4MultiSurface
();
}
}
private
BoundarySurfaceType
mapSurfaceType
(
org
.
citygml4j
.
model
.
citygml
.
building
.
AbstractBoundarySurface
abs
)
{
switch
(
abs
.
getCityGMLClass
())
{
case
BUILDING_WALL_SURFACE:
return
BoundarySurfaceType
.
WALL
;
case
BUILDING_ROOF_SURFACE:
return
BoundarySurfaceType
.
ROOF
;
case
BUILDING_GROUND_SURFACE:
return
BoundarySurfaceType
.
GROUND
;
case
BUILDING_CLOSURE_SURFACE:
return
BoundarySurfaceType
.
CLOSURE
;
case
BUILDING_FLOOR_SURFACE:
return
BoundarySurfaceType
.
OUTER_FLOOR
;
case
OUTER_BUILDING_FLOOR_SURFACE:
return
BoundarySurfaceType
.
OUTER_FLOOR
;
case
BUILDING_CEILING_SURFACE:
return
BoundarySurfaceType
.
OUTER_CEILING
;
case
OUTER_BUILDING_CEILING_SURFACE:
return
BoundarySurfaceType
.
OUTER_CEILING
;
default
:
return
BoundarySurfaceType
.
UNDEFINED
;
}
}
@Override
public
void
visit
(
Bridge
bridge
)
{
BridgeObject
coBridge
=
new
BridgeObject
(
BridgeType
.
BRIDGE
,
bridge
);
mapBridge
(
bridge
,
coBridge
);
}
@Override
public
void
visit
(
BridgePart
bridgePart
)
{
BridgeObject
coBridge
=
new
BridgeObject
(
BridgeType
.
BRIDGE_PART
,
bridgePart
);
mapBridge
(
bridgePart
,
coBridge
);
}
private
void
mapBridge
(
AbstractBridge
aBridge
,
BridgeObject
coBridge
)
{
model
.
addBridge
(
coBridge
);
coBridge
.
setGmlObject
(
aBridge
);
if
(
aBridge
.
isSetId
())
{
coBridge
.
setGmlId
(
new
GmlId
(
aBridge
.
getId
()));
}
Map
<
String
,
ConcretePolygon
>
polygons
=
new
HashMap
<>();
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
=
new
ArrayList
<>();
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
// map geometries
mapBridgeMultiSurfaceGeometries
(
aBridge
,
coBridge
,
polygons
,
linkedPolygons
,
vertexMap
);
mapBridgeSolidGeometries
(
aBridge
,
coBridge
,
polygons
,
linkedPolygons
,
vertexMap
);
// handle boundary surfaces
if
(
aBridge
.
isSetBoundedBySurface
())
{
for
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
BoundarySurfaceProperty
bsp
:
aBridge
.
getBoundedBySurface
())
{
mapBridgeSurface
(
bsp
,
coBridge
,
polygons
,
linkedPolygons
,
vertexMap
);
}
}
createLinkedPolygons
(
polygons
,
linkedPolygons
);
updateEdgesAndVertices
(
coBridge
);
}
private
void
mapBridgeMultiSurfaceGeometries
(
AbstractBridge
aBridge
,
BridgeObject
coBridge
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
GeometryMapper
.
mapLod1MultiSurface
(
aBridge
.
getLod1MultiSurface
(),
coBridge
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
aBridge
.
unsetLod1MultiSurface
();
GeometryMapper
.
mapLod2MultiSurface
(
aBridge
.
getLod2MultiSurface
(),
coBridge
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
aBridge
.
unsetLod2MultiSurface
();
GeometryMapper
.
mapLod3MultiSurface
(
aBridge
.
getLod3MultiSurface
(),
coBridge
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
aBridge
.
unsetLod3MultiSurface
();
GeometryMapper
.
mapLod4MultiSurface
(
aBridge
.
getLod4MultiSurface
(),
coBridge
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
aBridge
.
unsetLod4MultiSurface
();
}
private
void
mapBridgeSolidGeometries
(
AbstractBridge
aBridge
,
BridgeObject
coBridge
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
GeometryMapper
.
mapLod1Solid
(
aBridge
.
getLod1Solid
(),
coBridge
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
aBridge
.
unsetLod1Solid
();
GeometryMapper
.
mapLod2Solid
(
aBridge
.
getLod2Solid
(),
coBridge
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
aBridge
.
unsetLod2Solid
();
GeometryMapper
.
mapLod3Solid
(
aBridge
.
getLod3Solid
(),
coBridge
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
aBridge
.
unsetLod3Solid
();
GeometryMapper
.
mapLod4Solid
(
aBridge
.
getLod4Solid
(),
coBridge
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
aBridge
.
unsetLod4Solid
();
}
private
void
mapBridgeSurface
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
BoundarySurfaceProperty
bsp
,
BridgeObject
coBridge
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(!
bsp
.
isSetBoundarySurface
())
{
return
;
}
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractBoundarySurface
abs
=
bsp
.
getBoundarySurface
();
BoundarySurfaceType
surfaceType
=
mapSurfaceType
(
abs
);
BoundarySurface
bs
=
new
BoundarySurface
(
SurfaceFeatureType
.
BRIDGE
,
surfaceType
,
abs
);
bs
.
setGmlObject
(
abs
);
coBridge
.
addBoundarySurface
(
bs
);
mapBridgeOpenings
(
abs
.
getOpening
(),
bs
,
polygons
,
linkedPolygons
,
vertexMap
);
createBoundarySurfaceGeometries
(
abs
,
bs
,
polygons
,
linkedPolygons
,
vertexMap
);
updateEdgesAndVertices
(
bs
);
}
private
void
mapBridgeOpenings
(
List
<
org
.
citygml4j
.
model
.
citygml
.
bridge
.
OpeningProperty
>
openings
,
BoundarySurface
bs
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
openings
==
null
||
openings
.
isEmpty
())
{
return
;
}
for
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
OpeningProperty
op
:
openings
)
{
if
(!
op
.
isSetOpening
())
{
continue
;
}
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractOpening
ap
=
op
.
getOpening
();
OpeningType
type
=
mapOpeningType
(
ap
);
Opening
opening
=
new
Opening
(
type
,
SurfaceFeatureType
.
BRIDGE
,
bs
,
ap
);
bs
.
addOpening
(
opening
);
createOpeningGeometries
(
ap
,
opening
,
polygons
,
linkedPolygons
,
vertexMap
);
updateEdgesAndVertices
(
opening
);
}
}
private
void
createOpeningGeometries
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractOpening
ap
,
Opening
opening
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
ap
.
isSetLod3MultiSurface
())
{
GeometryMapper
.
mapLod3MultiSurface
(
ap
.
getLod3MultiSurface
(),
opening
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ap
.
unsetLod3MultiSurface
();
}
if
(
ap
.
isSetLod4MultiSurface
())
{
GeometryMapper
.
mapLod4MultiSurface
(
ap
.
getLod3MultiSurface
(),
opening
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
ap
.
unsetLod4MultiSurface
();
}
}
private
OpeningType
mapOpeningType
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractOpening
ap
)
{
if
(
ap
instanceof
org
.
citygml4j
.
model
.
citygml
.
bridge
.
Door
)
{
return
OpeningType
.
DOOR
;
}
if
(
ap
instanceof
org
.
citygml4j
.
model
.
citygml
.
bridge
.
Window
)
{
return
OpeningType
.
WINDOW
;
}
return
OpeningType
.
UNKNOWN
;
}
private
BoundarySurfaceType
mapSurfaceType
(
org
.
citygml4j
.
model
.
citygml
.
bridge
.
AbstractBoundarySurface
abs
)
{
switch
(
abs
.
getCityGMLClass
())
{
case
BRIDGE_CEILING_SURFACE:
return
BoundarySurfaceType
.
CEILING
;
case
BRIDGE_CLOSURE_SURFACE:
return
BoundarySurfaceType
.
CLOSURE
;
case
BRIDGE_FLOOR_SURFACE:
return
BoundarySurfaceType
.
FLOOR
;
case
BRIDGE_GROUND_SURFACE:
return
BoundarySurfaceType
.
GROUND
;
case
BRIDGE_ROOF_SURFACE:
return
BoundarySurfaceType
.
ROOF
;
case
BRIDGE_WALL_SURFACE:
return
BoundarySurfaceType
.
WALL
;
case
INTERIOR_BRIDGE_WALL_SURFACE:
return
BoundarySurfaceType
.
INTERIOR_WALL
;
case
OUTER_BRIDGE_CEILING_SURFACE:
return
BoundarySurfaceType
.
OUTER_CEILING
;
case
OUTER_BUILDING_FLOOR_SURFACE:
return
BoundarySurfaceType
.
OUTER_FLOOR
;
default
:
return
BoundarySurfaceType
.
UNDEFINED
;
}
}
public
CityDoctorModel
getModel
()
{
return
model
;
}
public
void
setCityModel
(
CityModel
cModel
)
{
model
.
setCityModel
(
cModel
);
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/GeometryMapper.java
deleted
100644 → 0
View file @
92f3e523
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.mapper
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.util.List
;
import
java.util.Map
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.citygml4j.model.gml.geometry.AbstractGeometry
;
import
org.citygml4j.model.gml.geometry.GeometryProperty
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSurface
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSurfaceProperty
;
import
org.citygml4j.model.gml.geometry.complexes.CompositeSurface
;
import
org.citygml4j.model.gml.geometry.primitives.AbstractRing
;
import
org.citygml4j.model.gml.geometry.primitives.AbstractRingProperty
;
import
org.citygml4j.model.gml.geometry.primitives.Coord
;
import
org.citygml4j.model.gml.geometry.primitives.DirectPosition
;
import
org.citygml4j.model.gml.geometry.primitives.DirectPositionList
;
import
org.citygml4j.model.gml.geometry.primitives.PosOrPointPropertyOrPointRep
;
import
org.citygml4j.model.gml.geometry.primitives.SolidProperty
;
import
org.citygml4j.model.gml.geometry.primitives.SurfaceProperty
;
import
org.citygml4j.util.walker.GeometryWalker
;
import
org.locationtech.proj4j.BasicCoordinateTransform
;
import
org.locationtech.proj4j.ProjCoordinate
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface
;
import
de.hft.stuttgart.citydoctor2.datastructure.BuildingInstallation
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.GmlId
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
de.hft.stuttgart.citydoctor2.utils.Localization
;
import
de.hft.stuttgart.citydoctor2.utils.Pair
;
/**
*
* @author Matthias Betz
*
*/
public
class
GeometryMapper
extends
GeometryWalker
{
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
GeometryMapper
.
class
);
private
Geometry
geom
;
private
ParserConfiguration
config
;
private
Map
<
Vertex
,
Vertex
>
vertexMap
;
private
Map
<
String
,
ConcretePolygon
>
polygons
;
private
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
;
private
LinearRing
currentRing
;
private
BoundarySurface
bs
;
private
BuildingInstallation
bi
;
private
ProjCoordinate
p1
=
new
ProjCoordinate
();
private
ProjCoordinate
p2
=
new
ProjCoordinate
();
public
GeometryMapper
(
Geometry
geom
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertices
)
{
this
.
geom
=
geom
;
this
.
config
=
config
;
vertexMap
=
vertices
;
this
.
polygons
=
polygons
;
this
.
linkedPolygons
=
linkedPolygons
;
}
public
void
setBoundarySurface
(
BoundarySurface
bs
)
{
this
.
bs
=
bs
;
}
public
void
setBuildingInstallation
(
BuildingInstallation
bi
)
{
this
.
bi
=
bi
;
}
@Override
public
void
visit
(
MultiSurface
multiSurface
)
{
super
.
visit
(
multiSurface
);
for
(
SurfaceProperty
sp
:
multiSurface
.
getSurfaceMember
())
{
if
(
sp
.
isSetHref
())
{
String
linkedPoly
=
sp
.
getHref
();
if
(
linkedPoly
.
charAt
(
0
)
==
'#'
)
{
linkedPoly
=
linkedPoly
.
substring
(
1
);
}
linkedPolygons
.
add
(
new
Pair
<>(
linkedPoly
,
geom
));
}
}
}
@Override
public
void
visit
(
CompositeSurface
compositeSurface
)
{
super
.
visit
(
compositeSurface
);
for
(
SurfaceProperty
sp
:
compositeSurface
.
getSurfaceMember
())
{
if
(
sp
.
isSetHref
())
{
String
linkedPoly
=
sp
.
getHref
();
if
(
linkedPoly
.
charAt
(
0
)
==
'#'
)
{
linkedPoly
=
linkedPoly
.
substring
(
1
);
}
linkedPolygons
.
add
(
new
Pair
<>(
linkedPoly
,
geom
));
}
}
}
@Override
public
void
visit
(
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
Polygon
gmlPoly
)
{
if
(!
gmlPoly
.
isSetExterior
())
{
if
(
logger
.
isWarnEnabled
())
{
logger
.
warn
(
Localization
.
getText
(
"GeometryMapper.emptyPolygon"
));
}
return
;
}
ConcretePolygon
cdPoly
=
new
ConcretePolygon
();
addPolygonToAvailablePolygons
(
gmlPoly
,
cdPoly
);
geom
.
addPolygon
(
cdPoly
);
if
(
bs
!=
null
)
{
// polygon is part of a boundary surface
cdPoly
.
setPartOfSurface
(
bs
);
if
(
bi
!=
null
)
{
// polygon is part of a boundary surface in a building installation
cdPoly
.
setPartOfInstallation
(
bi
);
}
}
else
{
if
(
bi
!=
null
)
{
// polygon is only part of a building installation
cdPoly
.
setPartOfInstallation
(
bi
);
}
}
// parse rings
LinearRing
extRing
=
new
LinearRing
(
LinearRingType
.
EXTERIOR
);
cdPoly
.
setExteriorRing
(
extRing
);
mapRing
(
gmlPoly
.
getExterior
(),
extRing
);
if
(
gmlPoly
.
isSetInterior
())
{
for
(
AbstractRingProperty
arp
:
gmlPoly
.
getInterior
())
{
if
(
arp
.
isSetRing
())
{
LinearRing
innerRing
=
new
LinearRing
(
LinearRingType
.
INTERIOR
);
cdPoly
.
addInteriorRing
(
innerRing
);
mapRing
(
arp
,
innerRing
);
}
}
}
}
private
void
addPolygonToAvailablePolygons
(
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
Polygon
gmlPoly
,
ConcretePolygon
cdPoly
)
{
if
(
gmlPoly
.
isSetId
())
{
cdPoly
.
setGmlId
(
new
GmlId
(
gmlPoly
.
getId
()));
if
(
polygons
.
put
(
gmlPoly
.
getId
(),
cdPoly
)
!=
null
)
{
logger
.
warn
(
"Found already existing polygon ID {}, duplicate IDs are not valid"
,
gmlPoly
.
getId
());
}
}
}
private
void
mapRing
(
AbstractRingProperty
gmlRing
,
LinearRing
cdRing
)
{
AbstractRing
ringGeometry
=
gmlRing
.
getRing
();
if
(
ringGeometry
.
isSetId
())
{
cdRing
.
setGmlId
(
new
GmlId
(
ringGeometry
.
getId
()));
}
currentRing
=
cdRing
;
// jump to LinearRing or Ring visit
ringGeometry
.
accept
(
this
);
}
@Override
public
void
visit
(
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
LinearRing
linearRing
)
{
if
(
linearRing
.
isSetCoord
())
{
List
<
Coord
>
coords
=
linearRing
.
getCoord
();
for
(
Coord
coord
:
coords
)
{
createVertex
(
coord
.
getX
(),
coord
.
getY
(),
coord
.
getZ
());
}
}
if
(
linearRing
.
isSetPosList
())
{
parsePosList
(
linearRing
);
}
if
(
linearRing
.
isSetPosOrPointPropertyOrPointRep
())
{
parsePoints
(
linearRing
);
}
}
private
void
parsePoints
(
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
LinearRing
linearRing
)
{
List
<
PosOrPointPropertyOrPointRep
>
points
=
linearRing
.
getPosOrPointPropertyOrPointRep
();
for
(
PosOrPointPropertyOrPointRep
point
:
points
)
{
if
(!
point
.
isSetPos
())
{
throw
new
UnsupportedOperationException
(
"Cannot parse points for: "
+
linearRing
.
getId
());
}
DirectPosition
pos
=
point
.
getPos
();
List
<
Double
>
coords
=
pos
.
getValue
();
int
dimension
=
getDimension
(
linearRing
,
pos
,
coords
);
switch
(
dimension
)
{
case
1
:
createVertex
(
coords
.
get
(
0
),
0
,
0
);
break
;
case
2
:
createVertex
(
coords
.
get
(
0
),
coords
.
get
(
1
),
0
);
break
;
case
3
:
createVertex
(
coords
.
get
(
0
),
coords
.
get
(
1
),
coords
.
get
(
2
));
break
;
default
:
throw
new
UnsupportedOperationException
(
"Cannot parse Coordinates with dimension:"
+
dimension
);
}
}
}
private
void
parsePosList
(
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
LinearRing
linearRing
)
{
DirectPositionList
directPosList
=
linearRing
.
getPosList
();
if
(
directPosList
.
isSetValue
())
{
List
<
Double
>
coords
=
directPosList
.
getValue
();
int
dimension
=
getDimension
(
linearRing
,
directPosList
,
coords
);
switch
(
dimension
)
{
case
1
:
for
(
int
i
=
0
;
i
<
coords
.
size
();
i
++)
{
createVertex
(
coords
.
get
(
i
),
0
,
0
);
}
break
;
case
2
:
for
(
int
i
=
0
;
i
<
coords
.
size
();
i
=
i
+
2
)
{
createVertex
(
coords
.
get
(
i
+
0
),
coords
.
get
(
i
+
1
),
0
);
}
break
;
case
3
:
for
(
int
i
=
0
;
i
<
coords
.
size
();
i
=
i
+
3
)
{
createVertex
(
coords
.
get
(
i
+
0
),
coords
.
get
(
i
+
1
),
coords
.
get
(
i
+
2
));
}
break
;
default
:
throw
new
UnsupportedOperationException
(
"Cannot parse Coordinates with dimension:"
+
dimension
);
}
}
}
private
int
getDimension
(
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
LinearRing
linearRing
,
DirectPosition
pos
,
List
<
Double
>
coords
)
{
int
dimension
=
3
;
if
(
pos
.
isSetSrsDimension
())
{
dimension
=
pos
.
getSrsDimension
();
}
if
(
coords
.
size
()
%
dimension
!=
0
)
{
throw
new
IllegalStateException
(
"Number of coordinates do not match dimension: "
+
dimension
+
", ring: "
+
linearRing
.
getId
()
+
", polygon: "
+
currentRing
.
getParent
().
getGmlId
().
getGmlString
());
}
return
dimension
;
}
private
int
getDimension
(
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
LinearRing
linearRing
,
DirectPositionList
directPosList
,
List
<
Double
>
coords
)
{
int
dimension
=
3
;
if
(
directPosList
.
isSetSrsDimension
())
{
dimension
=
directPosList
.
getSrsDimension
();
}
if
(
coords
.
size
()
%
dimension
!=
0
)
{
throw
new
IllegalStateException
(
"Number of coordinates do not match dimension: "
+
dimension
+
", ring: "
+
linearRing
.
getId
()
+
", polygon: "
+
currentRing
.
getParent
().
getGmlId
().
getGmlString
());
}
return
dimension
;
}
private
void
createVertex
(
double
x
,
double
y
,
double
z
)
{
// transform into utm, if available
BasicCoordinateTransform
trans
=
config
.
getTargetTransform
();
if
(
trans
!=
null
)
{
p1
.
setValue
(
x
,
y
);
trans
.
transform
(
p1
,
p2
);
x
=
p2
.
x
;
y
=
p2
.
y
;
z
=
z
/
config
.
getFromMetres
();
}
x
=
round
(
x
,
config
.
getNumberOfRoundingPlaces
());
y
=
round
(
y
,
config
.
getNumberOfRoundingPlaces
());
z
=
round
(
z
,
config
.
getNumberOfRoundingPlaces
());
Vertex
v
=
new
Vertex
(
x
,
y
,
z
);
Vertex
duplicate
=
vertexMap
.
get
(
v
);
if
(
duplicate
==
null
)
{
vertexMap
.
put
(
v
,
v
);
}
else
{
v
=
duplicate
;
}
currentRing
.
addVertex
(
v
);
}
private
double
round
(
double
value
,
int
places
)
{
if
(
places
<
0
)
{
throw
new
IllegalArgumentException
();
}
BigDecimal
bd
=
BigDecimal
.
valueOf
(
value
);
bd
=
bd
.
setScale
(
places
,
RoundingMode
.
HALF_UP
);
return
bd
.
doubleValue
();
}
private
static
GeometryMapper
parseGeometry
(
AbstractGeometry
gmlG
,
Geometry
geom
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
gmlG
.
isSetId
())
{
geom
.
setGmlId
(
new
GmlId
(
gmlG
.
getId
()));
}
co
.
addGeometry
(
geom
);
GeometryMapper
geomMapper
=
new
GeometryMapper
(
geom
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
gmlG
.
accept
(
geomMapper
);
return
geomMapper
;
}
private
static
void
parseIntoGeometry
(
AbstractGeometry
geometry
,
GeometryMapper
geomMapper
,
BoundarySurface
bs
,
BuildingInstallation
coBi
)
{
geomMapper
.
setBoundarySurface
(
bs
);
geomMapper
.
setBuildingInstallation
(
coBi
);
geometry
.
accept
(
geomMapper
);
}
public
static
void
mapLod0MultiSurface
(
MultiSurfaceProperty
lod0ms
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod0ms
==
null
||
!
lod0ms
.
isSetMultiSurface
())
{
return
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD0
);
parseGeometry
(
lod0ms
.
getMultiSurface
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
GeometryMapper
mapLod1MultiSurface
(
MultiSurfaceProperty
lod1ms
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod1ms
==
null
||
!
lod1ms
.
isSetMultiSurface
())
{
return
null
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD1
);
return
parseGeometry
(
lod1ms
.
getMultiSurface
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
GeometryMapper
mapLod2MultiSurface
(
MultiSurfaceProperty
lod2MultiSurface
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod2MultiSurface
==
null
||
!
lod2MultiSurface
.
isSetMultiSurface
())
{
return
null
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD2
);
return
parseGeometry
(
lod2MultiSurface
.
getMultiSurface
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
GeometryMapper
mapLod3MultiSurface
(
MultiSurfaceProperty
lod3MultiSurface
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod3MultiSurface
==
null
||
!
lod3MultiSurface
.
isSetMultiSurface
())
{
return
null
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD3
);
return
parseGeometry
(
lod3MultiSurface
.
getMultiSurface
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
GeometryMapper
mapLod4MultiSurface
(
MultiSurfaceProperty
lod4MultiSurface
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod4MultiSurface
==
null
||
!
lod4MultiSurface
.
isSetMultiSurface
())
{
return
null
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD4
);
return
parseGeometry
(
lod4MultiSurface
.
getMultiSurface
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
GeometryMapper
mapLod1Solid
(
SolidProperty
lod1Solid
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod1Solid
==
null
||
!
lod1Solid
.
isSetSolid
())
{
return
null
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
SOLID
,
Lod
.
LOD1
);
return
parseGeometry
(
lod1Solid
.
getSolid
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
GeometryMapper
mapLod2Solid
(
SolidProperty
lod2Solid
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod2Solid
==
null
||
!
lod2Solid
.
isSetSolid
())
{
return
null
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
SOLID
,
Lod
.
LOD2
);
return
parseGeometry
(
lod2Solid
.
getSolid
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
GeometryMapper
mapLod3Solid
(
SolidProperty
lod3Solid
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod3Solid
==
null
||
!
lod3Solid
.
isSetSolid
())
{
return
null
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
SOLID
,
Lod
.
LOD3
);
return
parseGeometry
(
lod3Solid
.
getSolid
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
GeometryMapper
mapLod4Solid
(
SolidProperty
lod4Solid
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod4Solid
==
null
||
!
lod4Solid
.
isSetSolid
())
{
return
null
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
SOLID
,
Lod
.
LOD4
);
return
parseGeometry
(
lod4Solid
.
getSolid
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
void
mapLod1Geometry
(
GeometryProperty
<?
extends
AbstractGeometry
>
lod1Geometry
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod1Geometry
==
null
||
!
lod1Geometry
.
isSetGeometry
())
{
return
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD1
);
parseGeometry
(
lod1Geometry
.
getGeometry
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
void
mapLod2Geometry
(
GeometryProperty
<?
extends
AbstractGeometry
>
lod2Geometry
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod2Geometry
==
null
||
!
lod2Geometry
.
isSetGeometry
())
{
return
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD2
);
parseGeometry
(
lod2Geometry
.
getGeometry
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
void
mapLod3Geometry
(
GeometryProperty
<?
extends
AbstractGeometry
>
lod3Geometry
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod3Geometry
==
null
||
!
lod3Geometry
.
isSetGeometry
())
{
return
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD3
);
parseGeometry
(
lod3Geometry
.
getGeometry
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
void
mapLod4Geometry
(
GeometryProperty
<?
extends
AbstractGeometry
>
lod4Geometry
,
CityObject
co
,
ParserConfiguration
config
,
Map
<
String
,
ConcretePolygon
>
polygons
,
List
<
Pair
<
String
,
Geometry
>>
linkedPolygons
,
Map
<
Vertex
,
Vertex
>
vertexMap
)
{
if
(
lod4Geometry
==
null
||
!
lod4Geometry
.
isSetGeometry
())
{
return
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
Lod
.
LOD4
);
parseGeometry
(
lod4Geometry
.
getGeometry
(),
geom
,
co
,
config
,
polygons
,
linkedPolygons
,
vertexMap
);
}
public
static
void
mapBoundarySurfaceIntoGeometry
(
MultiSurfaceProperty
msp
,
GeometryMapper
geom
,
BoundarySurface
bs
,
BuildingInstallation
coBi
)
{
if
(
msp
==
null
||
!
msp
.
isSetGeometry
())
{
return
;
}
parseIntoGeometry
(
msp
.
getGeometry
(),
geom
,
bs
,
coBi
);
}
public
static
void
mapBuildingInstallationIntoGeometry
(
GeometryProperty
<?
extends
AbstractGeometry
>
gp
,
GeometryMapper
geom
,
BuildingInstallation
coBi
)
{
if
(
gp
==
null
||
!
gp
.
isSetGeometry
())
{
return
;
}
parseIntoGeometry
(
gp
.
getGeometry
(),
geom
,
null
,
coBi
);
}
public
Geometry
getGeometry
()
{
return
geom
;
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java
0 → 100644
View file @
3f3c1884
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.mapper.citygml3
;
import
java.nio.file.Path
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.citygml4j.core.model.CityGMLVersion
;
import
org.citygml4j.core.model.bridge.AbstractBridge
;
import
org.citygml4j.core.model.bridge.Bridge
;
import
org.citygml4j.core.model.bridge.BridgePart
;
import
org.citygml4j.core.model.bridge.BridgePartProperty
;
import
org.citygml4j.core.model.building.BuildingInstallationProperty
;
import
org.citygml4j.core.model.building.BuildingPartProperty
;
import
org.citygml4j.core.model.construction.AbstractConstruction
;
import
org.citygml4j.core.model.core.AbstractCityObject
;
import
org.citygml4j.core.model.core.AbstractFeatureWithLifespan
;
import
org.citygml4j.core.model.core.AbstractOccupiedSpace
;
import
org.citygml4j.core.model.core.AbstractPhysicalSpace
;
import
org.citygml4j.core.model.core.AbstractSpace
;
import
org.citygml4j.core.model.core.AbstractSpaceBoundary
;
import
org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty
;
import
org.citygml4j.core.model.core.AbstractThematicSurface
;
import
org.citygml4j.core.model.core.AbstractUnoccupiedSpace
;
import
org.citygml4j.core.model.core.CityModel
;
import
org.citygml4j.core.model.deprecated.transportation.TransportationComplex
;
import
org.citygml4j.core.model.landuse.LandUse
;
import
org.citygml4j.core.model.transportation.AbstractTransportationSpace
;
import
org.citygml4j.core.model.transportation.AuxiliaryTrafficArea
;
import
org.citygml4j.core.model.transportation.AuxiliaryTrafficSpace
;
import
org.citygml4j.core.model.transportation.AuxiliaryTrafficSpaceProperty
;
import
org.citygml4j.core.model.transportation.Railway
;
import
org.citygml4j.core.model.transportation.Road
;
import
org.citygml4j.core.model.transportation.Square
;
import
org.citygml4j.core.model.transportation.Track
;
import
org.citygml4j.core.model.transportation.TrafficArea
;
import
org.citygml4j.core.model.transportation.TrafficSpace
;
import
org.citygml4j.core.model.transportation.TrafficSpaceProperty
;
import
org.citygml4j.core.model.vegetation.AbstractVegetationObject
;
import
org.citygml4j.core.model.vegetation.PlantCover
;
import
org.citygml4j.core.model.waterbody.WaterBody
;
import
org.citygml4j.core.visitor.ObjectWalker
;
import
org.xmlobjects.gml.model.base.AbstractGML
;
import
org.xmlobjects.gml.model.feature.AbstractFeature
;
import
org.xmlobjects.gml.model.geometry.AbstractGeometry
;
import
org.xmlobjects.gml.model.geometry.GeometryProperty
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.AbstractSolid
;
import
org.xmlobjects.gml.model.geometry.primitives.AbstractSurface
;
import
org.xmlobjects.gml.model.geometry.primitives.Shell
;
import
org.xmlobjects.gml.model.geometry.primitives.ShellProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.Solid
;
import
org.xmlobjects.gml.model.geometry.primitives.SolidProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty
;
import
de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface
;
import
de.hft.stuttgart.citydoctor2.datastructure.BridgeObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.BridgeObject.BridgeType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.BuildingInstallation
;
import
de.hft.stuttgart.citydoctor2.datastructure.BuildingPart
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.GmlElement
;
import
de.hft.stuttgart.citydoctor2.datastructure.GmlId
;
import
de.hft.stuttgart.citydoctor2.datastructure.LandObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinkedPolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.TransportationObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.TransportationObject.TransportationType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vegetation
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vegetation.VegetationType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
import
de.hft.stuttgart.citydoctor2.datastructure.WaterObject
;
import
de.hft.stuttgart.citydoctor2.math.graph.KDTree
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
de.hft.stuttgart.citydoctor2.utils.Localization
;
public
class
Citygml3FeatureMapper
extends
ObjectWalker
{
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
Citygml3FeatureMapper
.
class
);
private
CityDoctorModel
model
;
private
Map
<
String
,
ConcretePolygon
>
polygonMap
=
new
HashMap
<>();
private
List
<
ResolvableReference
>
references
=
new
ArrayList
<>();
private
Map
<
Vertex
,
Vertex
>
vertexMap
=
new
HashMap
<>();
private
ParserConfiguration
config
;
private
double
neighborDistance
;
public
Citygml3FeatureMapper
(
ParserConfiguration
config
,
Path
path
)
{
this
.
config
=
config
;
model
=
new
CityDoctorModel
(
config
,
path
.
toFile
());
neighborDistance
=
1.8d
/
Math
.
pow
(
10
,
config
.
getNumberOfRoundingPlaces
());
}
@Override
public
void
visit
(
AbstractSpace
space
)
{
// if we are here, an AbstractSpace thing was read that is not handled in the
// other methods
}
@Override
public
void
visit
(
org
.
citygml4j
.
core
.
model
.
building
.
Building
gmlBuilding
)
{
Building
cdBuilding
=
new
Building
();
readAbstractBuilding
(
gmlBuilding
,
cdBuilding
);
for
(
BuildingPartProperty
bpProp
:
gmlBuilding
.
getBuildingParts
())
{
if
(!
bpProp
.
isSetObject
())
{
continue
;
}
BuildingPart
part
=
new
BuildingPart
(
cdBuilding
);
readAbstractBuilding
(
bpProp
.
getObject
(),
part
);
cdBuilding
.
addBuildingPart
(
part
);
}
model
.
addBuilding
(
cdBuilding
);
}
@Override
public
void
visit
(
WaterBody
waterBody
)
{
WaterObject
wo
=
new
WaterObject
();
wo
.
setGmlObject
(
waterBody
);
mapAbstractOccupiedSpace
(
waterBody
,
wo
);
parseAndAddMultiSurface
(
waterBody
.
getDeprecatedProperties
().
getLod1MultiSurface
(),
Lod
.
LOD1
,
wo
);
parseAndAddSolid
(
waterBody
.
getDeprecatedProperties
().
getLod4Solid
(),
Lod
.
LOD4
,
wo
);
SurfaceMapper
surfaceMapper
=
new
SurfaceMapper
(
polygonMap
,
references
,
vertexMap
,
config
);
for
(
AbstractSpaceBoundaryProperty
surfaceProp
:
waterBody
.
getBoundaries
())
{
if
(!
surfaceProp
.
isSetObject
())
{
continue
;
}
AbstractSpaceBoundary
surface
=
surfaceProp
.
getObject
();
surface
.
accept
(
surfaceMapper
);
}
for
(
BoundarySurface
bs
:
surfaceMapper
.
getSurfaces
())
{
wo
.
addBoundarySurface
(
bs
);
}
resolveAndClearReferences
();
wo
.
unsetGmlGeometries
();
updateEdgesAndVertices
(
wo
);
for
(
BoundarySurface
bs
:
surfaceMapper
.
getSurfaces
())
{
updateEdgesAndVertices
(
bs
);
}
model
.
addWater
(
wo
);
}
@Override
public
void
visit
(
LandUse
landUse
)
{
LandObject
lo
=
new
LandObject
(
landUse
);
mapAbstractThematicSurface
(
landUse
,
lo
);
finishCityObjectConstruction
(
lo
);
model
.
addLand
(
lo
);
}
@Override
public
void
visit
(
PlantCover
plantCover
)
{
Vegetation
veg
=
new
Vegetation
(
VegetationType
.
PLANT_COVER
);
veg
.
setGmlObject
(
plantCover
);
mapAbstractVegetationObject
(
plantCover
,
veg
);
parseAndAddMultiSurface
(
plantCover
.
getDeprecatedProperties
().
getLod1MultiSurface
(),
Lod
.
LOD1
,
veg
);
parseAndAddMultiSurface
(
plantCover
.
getDeprecatedProperties
().
getLod4MultiSurface
(),
Lod
.
LOD4
,
veg
);
finishCityObjectConstruction
(
veg
);
model
.
addVegetation
(
veg
);
}
private
void
mapAbstractVegetationObject
(
AbstractVegetationObject
avo
,
Vegetation
veg
)
{
mapAbstractOccupiedSpace
(
avo
,
veg
);
}
private
void
mapAbstractOccupiedSpace
(
AbstractOccupiedSpace
aos
,
CityObject
co
)
{
mapAbstractPhysicalSpace
(
aos
,
co
);
}
private
void
mapAbstractPhysicalSpace
(
AbstractPhysicalSpace
aps
,
CityObject
co
)
{
mapAbstractSpace
(
aps
,
co
);
}
private
void
mapAbstractSpace
(
AbstractSpace
as
,
CityObject
co
)
{
mapAbstractFeature
(
as
,
co
);
parseAndAddMultiSurface
(
as
.
getLod0MultiSurface
(),
Lod
.
LOD0
,
co
);
parseAndAddMultiSurface
(
as
.
getLod2MultiSurface
(),
Lod
.
LOD2
,
co
);
parseAndAddMultiSurface
(
as
.
getLod3MultiSurface
(),
Lod
.
LOD3
,
co
);
parseAndAddSolid
(
as
.
getLod1Solid
(),
Lod
.
LOD1
,
co
);
parseAndAddSolid
(
as
.
getLod2Solid
(),
Lod
.
LOD2
,
co
);
parseAndAddSolid
(
as
.
getLod3Solid
(),
Lod
.
LOD3
,
co
);
}
@Override
public
void
visit
(
Bridge
bridge
)
{
BridgeObject
bo
=
new
BridgeObject
(
BridgeType
.
BRIDGE
,
bridge
);
for
(
BridgePartProperty
bPartProperty
:
bridge
.
getBridgeParts
())
{
if
(!
bPartProperty
.
isSetObject
())
{
continue
;
}
BridgePart
gmlBridgePart
=
bPartProperty
.
getObject
();
BridgeObject
bPart
=
new
BridgeObject
(
BridgeType
.
BRIDGE_PART
,
gmlBridgePart
);
mapAbstractBridge
(
gmlBridgePart
,
bPart
);
bo
.
addBridgePart
(
bPart
);
}
mapAbstractBridge
(
bridge
,
bo
);
resolveAndClearReferences
();
updateEdgesAndVertices
(
bo
);
for
(
BridgeObject
part
:
bo
.
getParts
())
{
updateEdgesAndVertices
(
part
);
}
model
.
addBridge
(
bo
);
}
private
void
mapAbstractBridge
(
AbstractBridge
ab
,
BridgeObject
bo
)
{
mapAbstractConstruction
(
ab
,
bo
);
bo
.
unsetGmlGeometries
();
}
private
void
mapAbstractConstruction
(
AbstractConstruction
ac
,
BridgeObject
bo
)
{
mapAbstractOccupiedSpace
(
ac
,
bo
);
}
@Override
public
void
visit
(
AuxiliaryTrafficArea
ata
)
{
TransportationObject
to
=
new
TransportationObject
(
TransportationType
.
AUXILLIARY_TRAFFIC_AREA
);
mapAbstractThematicSurface
(
ata
,
to
);
finishTransportationMapping
(
to
);
}
@Override
public
void
visit
(
TrafficArea
ta
)
{
TransportationObject
to
=
new
TransportationObject
(
TransportationType
.
TRAFFIC_AREA
);
mapAbstractThematicSurface
(
ta
,
to
);
finishTransportationMapping
(
to
);
}
@Override
public
void
visit
(
Road
road
)
{
TransportationObject
to
=
new
TransportationObject
(
TransportationType
.
ROAD
);
mapAbstractTransportationSpace
(
road
,
to
);
finishTransportationMapping
(
to
);
}
private
void
mapAbstractThematicSurface
(
AbstractThematicSurface
ats
,
CityObject
co
)
{
mapAbstractSpaceBoundary
(
ats
,
co
);
parseAndAddMultiSurface
(
ats
.
getLod0MultiSurface
(),
Lod
.
LOD0
,
co
);
parseAndAddMultiSurface
(
ats
.
getLod1MultiSurface
(),
Lod
.
LOD1
,
co
);
parseAndAddMultiSurface
(
ats
.
getLod2MultiSurface
(),
Lod
.
LOD2
,
co
);
parseAndAddMultiSurface
(
ats
.
getLod3MultiSurface
(),
Lod
.
LOD3
,
co
);
parseAndAddMultiSurface
(
ats
.
getDeprecatedProperties
().
getLod4MultiSurface
(),
Lod
.
LOD4
,
co
);
}
private
void
mapAbstractSpaceBoundary
(
AbstractSpaceBoundary
asb
,
CityObject
co
)
{
mapAbstractCityObject
(
asb
,
co
);
}
private
void
mapAbstractCityObject
(
AbstractCityObject
aco
,
CityObject
to
)
{
mapAbstractFeatureWithLifespan
(
aco
,
to
);
}
private
void
mapAbstractFeatureWithLifespan
(
AbstractFeatureWithLifespan
afwl
,
CityObject
to
)
{
mapAbstractFeature
(
afwl
,
to
);
}
private
void
mapAbstractFeature
(
AbstractFeature
af
,
CityObject
to
)
{
mapAbstractGML
(
af
,
to
);
}
private
void
mapAbstractGML
(
AbstractGML
ag
,
CityObject
to
)
{
parseId
(
ag
,
to
);
}
@Override
public
void
visit
(
Railway
railway
)
{
TransportationObject
to
=
new
TransportationObject
(
TransportationType
.
RAILWAY
);
mapAbstractTransportationSpace
(
railway
,
to
);
finishTransportationMapping
(
to
);
}
@Override
public
void
visit
(
Square
square
)
{
TransportationObject
to
=
new
TransportationObject
(
TransportationType
.
SQUARE
);
mapAbstractTransportationSpace
(
square
,
to
);
finishTransportationMapping
(
to
);
}
@Override
public
void
visit
(
Track
track
)
{
TransportationObject
to
=
new
TransportationObject
(
TransportationType
.
TRACK
);
mapAbstractTransportationSpace
(
track
,
to
);
finishTransportationMapping
(
to
);
}
@Override
public
void
visit
(
TransportationComplex
transportationComplex
)
{
TransportationObject
to
=
new
TransportationObject
(
TransportationType
.
TRANSPORTATION_COMPLEX
);
mapAbstractTransportationSpace
(
transportationComplex
,
to
);
finishTransportationMapping
(
to
);
}
private
void
finishTransportationMapping
(
TransportationObject
to
)
{
finishCityObjectConstruction
(
to
);
model
.
addTransportation
(
to
);
}
private
void
finishCityObjectConstruction
(
CityObject
co
)
{
co
.
unsetGmlGeometries
();
resolveAndClearReferences
();
updateEdgesAndVertices
(
co
);
}
private
void
mapAbstractTransportationSpace
(
AbstractTransportationSpace
ats
,
TransportationObject
to
)
{
to
.
setGmlObject
(
ats
);
parseAbstractTransportationSpaceGeometries
(
ats
,
to
);
for
(
TrafficSpaceProperty
tsp
:
ats
.
getTrafficSpaces
())
{
if
(
tsp
.
isSetObject
())
{
TransportationObject
trafficSpace
=
new
TransportationObject
(
TransportationType
.
TRAFFIC_SPACE
);
mapTrafficSpace
(
tsp
.
getObject
(),
trafficSpace
);
finishTransportationMapping
(
trafficSpace
);
to
.
getChildren
().
add
(
trafficSpace
);
}
}
for
(
AuxiliaryTrafficSpaceProperty
auxTrafficProp
:
ats
.
getAuxiliaryTrafficSpaces
())
{
if
(
auxTrafficProp
.
isSetObject
())
{
TransportationObject
trafficSpace
=
parseAuxiliaryTrafficSpace
(
auxTrafficProp
.
getObject
());
finishTransportationMapping
(
trafficSpace
);
to
.
addChild
(
trafficSpace
);
}
}
}
private
void
mapTrafficSpace
(
TrafficSpace
ts
,
TransportationObject
to
)
{
mapAbstractUnoccupiedSpace
(
ts
,
to
);
}
private
void
mapAbstractUnoccupiedSpace
(
AbstractUnoccupiedSpace
aus
,
TransportationObject
to
)
{
mapAbstractPhysicalSpace
(
aus
,
to
);
}
private
TransportationObject
parseAuxiliaryTrafficSpace
(
AuxiliaryTrafficSpace
ats
)
{
TransportationObject
to
=
new
TransportationObject
(
TransportationType
.
AUXILLIARY_TRAFFIC_SPACE
);
parseAbstractSpaceGeometries
(
ats
,
to
);
finishCityObjectConstruction
(
to
);
return
to
;
}
private
void
parseAbstractTransportationSpaceGeometries
(
AbstractTransportationSpace
space
,
CityObject
co
)
{
parseAndAddMultiSurface
(
space
.
getDeprecatedProperties
().
getLod1MultiSurface
(),
Lod
.
LOD1
,
co
);
parseAndAddMultiSurface
(
space
.
getDeprecatedProperties
().
getLod4MultiSurface
(),
Lod
.
LOD4
,
co
);
}
private
void
parseAbstractSpaceGeometries
(
AbstractSpace
as
,
CityObject
co
)
{
parseAndAddMultiSurface
(
as
.
getLod0MultiSurface
(),
Lod
.
LOD0
,
co
);
parseAndAddMultiSurface
(
as
.
getLod2MultiSurface
(),
Lod
.
LOD2
,
co
);
parseAndAddMultiSurface
(
as
.
getLod3MultiSurface
(),
Lod
.
LOD3
,
co
);
parseAndAddSolid
(
as
.
getLod1Solid
(),
Lod
.
LOD1
,
co
);
parseAndAddSolid
(
as
.
getLod2Solid
(),
Lod
.
LOD2
,
co
);
parseAndAddSolid
(
as
.
getLod3Solid
(),
Lod
.
LOD3
,
co
);
}
private
void
parseAndAddMultiSurface
(
MultiSurfaceProperty
msp
,
Lod
lod
,
CityObject
co
)
{
if
(
msp
==
null
||
msp
.
getObject
()
==
null
)
{
return
;
}
Geometry
geom
=
parseMultiSurface
(
msp
.
getObject
(),
lod
);
co
.
addGeometry
(
geom
);
}
private
void
parseAndAddSolid
(
SolidProperty
sp
,
Lod
lod
,
CityObject
co
)
{
if
(
sp
==
null
||
sp
.
getObject
()
==
null
)
{
return
;
}
Geometry
geom
=
parseSolid
(
sp
.
getObject
(),
lod
);
if
(
geom
!=
null
)
{
co
.
addGeometry
(
geom
);
}
}
private
void
resolveAndClearReferences
()
{
for
(
ResolvableReference
ref
:
references
)
{
String
href
=
ref
.
href
();
if
(
href
.
startsWith
(
"#"
))
{
href
=
href
.
substring
(
1
);
}
Geometry
geom
=
ref
.
geometry
();
ConcretePolygon
concPoly
=
polygonMap
.
get
(
href
);
if
(
concPoly
==
null
)
{
if
(
logger
.
isWarnEnabled
())
{
logger
.
warn
(
Localization
.
getText
(
"FeatureMapper.polygonUnreferenced"
),
href
);
}
continue
;
}
LinkedPolygon
lPoly
=
new
LinkedPolygon
(
concPoly
,
geom
);
if
(
geom
.
getParent
()
instanceof
BoundarySurface
bs
)
{
lPoly
.
setPartOfSurface
(
bs
);
if
(
bs
.
getParent
()
instanceof
BuildingInstallation
bi
)
{
lPoly
.
setPartOfInstallation
(
bi
);
}
}
geom
.
addPolygon
(
lPoly
);
}
// clear storage for polygons and vertices
// probably faster than .clear() ?
references
=
new
ArrayList
<>();
vertexMap
=
new
HashMap
<>();
polygonMap
=
new
HashMap
<>();
}
private
void
readAbstractBuilding
(
org
.
citygml4j
.
core
.
model
.
building
.
AbstractBuilding
gmlAb
,
AbstractBuilding
cdBuilding
)
{
mapAbstractOccupiedSpace
(
gmlAb
,
cdBuilding
);
cdBuilding
.
setGmlObject
(
gmlAb
);
// parse deprecated geometries
parseAndAddMultiSurface
(
gmlAb
.
getDeprecatedProperties
().
getLod1MultiSurface
(),
Lod
.
LOD1
,
cdBuilding
);
parseAndAddMultiSurface
(
gmlAb
.
getDeprecatedProperties
().
getLod4MultiSurface
(),
Lod
.
LOD4
,
cdBuilding
);
parseAndAddSolid
(
gmlAb
.
getDeprecatedProperties
().
getLod4Solid
(),
Lod
.
LOD4
,
cdBuilding
);
for
(
BuildingInstallationProperty
biProp
:
gmlAb
.
getBuildingInstallations
())
{
var
gmlBi
=
biProp
.
getObject
();
if
(
gmlBi
==
null
)
{
// ignore empty properties
continue
;
}
BuildingInstallation
bi
=
mapBuildingInstallation
(
gmlBi
);
cdBuilding
.
addBuildingInstallation
(
bi
);
}
SurfaceMapper
surfaceMapper
=
new
SurfaceMapper
(
polygonMap
,
references
,
vertexMap
,
config
);
for
(
AbstractSpaceBoundaryProperty
surfaceProp
:
gmlAb
.
getBoundaries
())
{
if
(!
surfaceProp
.
isSetObject
())
{
continue
;
}
AbstractSpaceBoundary
surface
=
surfaceProp
.
getObject
();
surface
.
accept
(
surfaceMapper
);
}
for
(
BoundarySurface
bs
:
surfaceMapper
.
getSurfaces
())
{
cdBuilding
.
addBoundarySurface
(
bs
);
for
(
Geometry
geom
:
bs
.
getGeometries
())
{
for
(
Polygon
p
:
geom
.
getPolygons
())
{
p
.
setPartOfSurface
(
bs
);
}
}
}
cdBuilding
.
unsetGmlGeometries
();
resolveAndClearReferences
();
updateEdgesAndVertices
(
cdBuilding
);
for
(
BoundarySurface
bs
:
surfaceMapper
.
getSurfaces
())
{
updateEdgesAndVertices
(
bs
);
}
for
(
BuildingInstallation
bi
:
cdBuilding
.
getBuildingInstallations
())
{
updateEdgesAndVertices
(
bi
);
for
(
BoundarySurface
bs
:
bi
.
getBoundarySurfaces
())
{
updateEdgesAndVertices
(
bs
);
}
}
}
public
static
void
parseId
(
AbstractGML
gml
,
GmlElement
gmlElement
)
{
String
id
=
gml
.
getId
();
if
(
id
!=
null
)
{
gmlElement
.
setGmlId
(
new
GmlId
(
id
));
}
}
private
BuildingInstallation
mapBuildingInstallation
(
org
.
citygml4j
.
core
.
model
.
building
.
BuildingInstallation
gmlBi
)
{
BuildingInstallation
bi
=
new
BuildingInstallation
();
bi
.
setGmlObject
(
gmlBi
);
mapAbstractOccupiedSpace
(
gmlBi
,
bi
);
GeometryProperty
<?>
lod2Prop
=
gmlBi
.
getDeprecatedProperties
().
getLod2Geometry
();
parseAndAddAbstractGeometry
(
lod2Prop
,
Lod
.
LOD2
,
bi
);
GeometryProperty
<?>
lod3Prop
=
gmlBi
.
getDeprecatedProperties
().
getLod3Geometry
();
parseAndAddAbstractGeometry
(
lod3Prop
,
Lod
.
LOD3
,
bi
);
GeometryProperty
<?>
lod4Prop
=
gmlBi
.
getDeprecatedProperties
().
getLod4Geometry
();
parseAndAddAbstractGeometry
(
lod4Prop
,
Lod
.
LOD4
,
bi
);
bi
.
unsetGmlGeometries
();
SurfaceMapper
surfaceMapper
=
new
SurfaceMapper
(
polygonMap
,
references
,
vertexMap
,
config
);
for
(
AbstractSpaceBoundaryProperty
surfaceProp
:
gmlBi
.
getBoundaries
())
{
if
(!
surfaceProp
.
isSetObject
())
{
continue
;
}
AbstractSpaceBoundary
surface
=
surfaceProp
.
getObject
();
surface
.
accept
(
surfaceMapper
);
}
for
(
BoundarySurface
bs
:
surfaceMapper
.
getSurfaces
())
{
bi
.
addBoundarySurface
(
bs
);
for
(
Geometry
geom
:
bs
.
getGeometries
())
{
for
(
Polygon
p
:
geom
.
getPolygons
())
{
p
.
setPartOfSurface
(
bs
);
p
.
setPartOfInstallation
(
bi
);
}
}
}
for
(
Geometry
geom
:
bi
.
getGeometries
())
{
for
(
Polygon
p
:
geom
.
getPolygons
())
{
p
.
setPartOfInstallation
(
bi
);
}
}
return
bi
;
}
private
void
parseAndAddAbstractGeometry
(
GeometryProperty
<?>
geomProp
,
Lod
lod
,
CityObject
co
)
{
if
(
geomProp
==
null
||
geomProp
.
getObject
()
==
null
)
{
return
;
}
AbstractGeometry
abstractGeometry
=
geomProp
.
getObject
();
if
(
abstractGeometry
instanceof
MultiSurface
ms
)
{
Geometry
geom
=
parseMultiSurface
(
ms
,
lod
);
co
.
addGeometry
(
geom
);
}
else
if
(
abstractGeometry
instanceof
Solid
solid
)
{
Geometry
geom
=
parseSolid
(
solid
,
lod
);
if
(
geom
!=
null
)
{
co
.
addGeometry
(
geom
);
}
}
else
{
logger
.
warn
(
"Cannot handle geometry type {}, ignoring"
,
abstractGeometry
.
getClass
().
getSimpleName
());
}
}
private
Geometry
parseSolid
(
AbstractSolid
abstractSolid
,
Lod
lod
)
{
if
(
abstractSolid
instanceof
Solid
s
)
{
return
handleSolidGeometry
(
s
,
lod
);
}
else
{
logger
.
warn
(
"Cannot handle solid class {}, can only process pure solids"
,
abstractSolid
.
getClass
().
getSimpleName
());
return
null
;
}
}
private
Geometry
handleSolidGeometry
(
Solid
solid
,
Lod
lod
)
{
ShellProperty
exteriorProperty
=
solid
.
getExterior
();
if
(
exteriorProperty
==
null
||
exteriorProperty
.
getObject
()
==
null
)
{
logger
.
warn
(
"Found solid {} without exterior hull, ignoring"
,
solid
.
getId
());
return
null
;
}
Geometry
geom
=
new
Geometry
(
GeometryType
.
SOLID
,
lod
);
Shell
exterior
=
solid
.
getExterior
().
getObject
();
Citygml3GeometryMapper
geometryMapper
=
new
Citygml3GeometryMapper
(
config
,
vertexMap
);
readSurfaceMember
(
geom
,
geometryMapper
,
exterior
.
getSurfaceMembers
());
return
geom
;
}
private
Geometry
parseMultiSurface
(
MultiSurface
ms
,
Lod
lod
)
{
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
lod
);
Citygml3GeometryMapper
geometryMapper
=
new
Citygml3GeometryMapper
(
config
,
vertexMap
);
readSurfaceMember
(
geom
,
geometryMapper
,
ms
.
getSurfaceMember
());
return
geom
;
}
private
void
readSurfaceMember
(
Geometry
geom
,
Citygml3GeometryMapper
geometryMapper
,
List
<
SurfaceProperty
>
surfaceMember
)
{
for
(
SurfaceProperty
prop
:
surfaceMember
)
{
if
(
prop
.
getHref
()
!=
null
)
{
references
.
add
(
new
ResolvableReference
(
prop
.
getHref
(),
geom
));
continue
;
}
if
(
prop
.
getObject
()
!=
null
)
{
AbstractSurface
as
=
prop
.
getObject
();
as
.
accept
(
geometryMapper
);
}
}
List
<
ConcretePolygon
>
polygons
=
geometryMapper
.
getPolygons
();
for
(
ConcretePolygon
concretePoly
:
polygons
)
{
geom
.
addPolygon
(
concretePoly
);
if
(
concretePoly
.
hasExistingGmlId
())
{
polygonMap
.
put
(
concretePoly
.
getGmlId
().
getGmlString
(),
concretePoly
);
}
}
}
private
void
updateEdgesAndVertices
(
CityObject
co
)
{
// searching for neighboring vertices, replacing them with one single vertex to
// avoid later problems with edges and manifold problems
for
(
Geometry
geom
:
co
.
getGeometries
())
{
KDTree
tree
=
new
KDTree
();
for
(
Polygon
poly
:
geom
.
getPolygons
())
{
LinearRing
lr
=
poly
.
getExteriorRing
();
updateRing
(
tree
,
lr
);
for
(
LinearRing
innerRing
:
poly
.
getInnerRings
())
{
updateRing
(
tree
,
innerRing
);
}
}
if
(!
config
.
useLowMemoryConsumption
())
{
// no low memory consumption mode meaning create all meta information in
// geometry
geom
.
updateEdgesAndVertices
();
}
}
}
private
void
updateRing
(
KDTree
tree
,
LinearRing
lr
)
{
for
(
int
i
=
0
;
i
<
lr
.
getVertices
().
size
();
i
++)
{
Vertex
v
=
lr
.
getVertices
().
get
(
i
);
List
<
Vertex
>
nodesInRange
=
tree
.
getNodesInRange
(
v
,
neighborDistance
);
if
(
nodesInRange
.
isEmpty
())
{
tree
.
add
(
v
);
}
else
{
// replace other vertex with any neighboring one
Vertex
original
=
nodesInRange
.
get
(
0
);
lr
.
setVertex
(
i
,
original
);
}
}
}
public
void
setCityModel
(
CityModel
cModel
)
{
model
.
setCityModel
(
cModel
);
}
public
CityDoctorModel
getModel
()
{
return
model
;
}
public
void
setCityGMLVersion
(
CityGMLVersion
cityGMLVersion
)
{
model
.
setParsedCityGMLVersion
(
cityGMLVersion
);
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3GeometryMapper.java
0 → 100644
View file @
3f3c1884
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.mapper.citygml3
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.locationtech.proj4j.BasicCoordinateTransform
;
import
org.locationtech.proj4j.ProjCoordinate
;
import
org.xmlobjects.gml.model.geometry.primitives.AbstractRing
;
import
org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.Polygon
;
import
org.xmlobjects.gml.model.geometry.primitives.Ring
;
import
org.xmlobjects.gml.visitor.GeometryWalker
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.GmlId
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
de.hft.stuttgart.citydoctor2.utils.Localization
;
public
class
Citygml3GeometryMapper
extends
GeometryWalker
{
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
Citygml3GeometryMapper
.
class
);
private
List
<
ConcretePolygon
>
polygons
=
new
ArrayList
<>();
private
LinearRing
currentRing
=
null
;
private
ParserConfiguration
config
;
private
ProjCoordinate
p1
=
new
ProjCoordinate
();
private
ProjCoordinate
p2
=
new
ProjCoordinate
();
private
Map
<
Vertex
,
Vertex
>
vertexMap
;
public
Citygml3GeometryMapper
(
ParserConfiguration
config
,
Map
<
Vertex
,
Vertex
>
vertices
)
{
this
.
config
=
config
;
this
.
vertexMap
=
vertices
;
}
@Override
public
void
visit
(
Polygon
polygon
)
{
parsePolygon
(
polygon
.
getId
(),
polygon
.
getExterior
(),
polygon
.
getInterior
());
if
(
polygon
.
getExterior
()
==
null
)
{
System
.
out
.
println
(
"No exterior: "
+
polygon
.
getId
());
}
}
private
void
parsePolygon
(
String
id
,
AbstractRingProperty
exterior
,
List
<
AbstractRingProperty
>
interior
)
{
if
(
exterior
==
null
||
exterior
.
getObject
()
==
null
)
{
if
(
logger
.
isWarnEnabled
())
{
logger
.
warn
(
Localization
.
getText
(
"GeometryMapper.emptyPolygon"
));
}
return
;
}
ConcretePolygon
cdPoly
=
new
ConcretePolygon
();
polygons
.
add
(
cdPoly
);
if
(
id
!=
null
)
{
cdPoly
.
setGmlId
(
new
GmlId
(
id
));
}
currentRing
=
new
LinearRing
(
LinearRingType
.
EXTERIOR
);
exterior
.
getObject
().
accept
(
this
);
cdPoly
.
setExteriorRing
(
currentRing
);
for
(
AbstractRingProperty
interiorGmlRing
:
interior
)
{
AbstractRing
gmlRing
=
interiorGmlRing
.
getObject
();
if
(
gmlRing
==
null
)
{
continue
;
}
currentRing
=
new
LinearRing
(
LinearRingType
.
INTERIOR
);
gmlRing
.
accept
(
this
);
cdPoly
.
addInteriorRing
(
currentRing
);
}
}
@Override
public
void
visit
(
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
LinearRing
gmlRing
)
{
if
(
gmlRing
.
getSrsDimension
()
!=
null
&&
gmlRing
.
getSrsDimension
()
!=
3
)
{
logger
.
warn
(
"Cannot handle geometry with srsDimension not 3"
);
return
;
}
if
(
gmlRing
.
getId
()
!=
null
)
{
currentRing
.
setGmlId
(
new
GmlId
(
gmlRing
.
getId
()));
}
List
<
Double
>
coordinates
=
gmlRing
.
toCoordinateList3D
();
handleCoordinateList
(
coordinates
);
}
@Override
public
void
visit
(
Ring
ring
)
{
if
(
ring
.
getSrsDimension
()
!=
null
&&
ring
.
getSrsDimension
()
!=
3
)
{
logger
.
warn
(
"Cannot handle geometry with srsDimension not 3"
);
return
;
}
if
(
ring
.
getId
()
!=
null
)
{
currentRing
.
setGmlId
(
new
GmlId
(
ring
.
getId
()));
}
List
<
Double
>
coordinates
=
ring
.
toCoordinateList3D
();
handleCoordinateList
(
coordinates
);
}
private
void
handleCoordinateList
(
List
<
Double
>
coordinates
)
{
if
(
coordinates
.
size
()
%
3
!=
0
)
{
String
id
;
if
(
currentRing
.
hasExistingGmlId
())
{
id
=
currentRing
.
getGmlId
().
getGmlString
();
}
else
{
id
=
""
;
}
logger
.
warn
(
"The number of coordinates for linear ring {} do not result in fully 3D points"
,
id
);
}
for
(
int
i
=
0
;
i
<
coordinates
.
size
();
i
=
i
+
3
)
{
double
x
=
coordinates
.
get
(
i
+
0
);
double
y
=
coordinates
.
get
(
i
+
1
);
double
z
=
coordinates
.
get
(
i
+
2
);
createVertex
(
x
,
y
,
z
);
}
}
private
void
createVertex
(
double
x
,
double
y
,
double
z
)
{
// transform into utm, if available
BasicCoordinateTransform
trans
=
config
.
getTargetTransform
();
if
(
trans
!=
null
)
{
p1
.
setValue
(
x
,
y
);
trans
.
transform
(
p1
,
p2
);
x
=
p2
.
x
;
y
=
p2
.
y
;
z
=
z
/
config
.
getFromMetres
();
}
x
=
round
(
x
,
config
.
getNumberOfRoundingPlaces
());
y
=
round
(
y
,
config
.
getNumberOfRoundingPlaces
());
z
=
round
(
z
,
config
.
getNumberOfRoundingPlaces
());
Vertex
v
=
new
Vertex
(
x
,
y
,
z
);
Vertex
duplicate
=
vertexMap
.
get
(
v
);
if
(
duplicate
==
null
)
{
vertexMap
.
put
(
v
,
v
);
}
else
{
v
=
duplicate
;
}
currentRing
.
addVertex
(
v
);
}
private
double
round
(
double
value
,
int
places
)
{
if
(
places
<
0
)
{
throw
new
IllegalArgumentException
();
}
BigDecimal
bd
=
BigDecimal
.
valueOf
(
value
);
bd
=
bd
.
setScale
(
places
,
RoundingMode
.
HALF_UP
);
return
bd
.
doubleValue
();
}
public
List
<
ConcretePolygon
>
getPolygons
()
{
return
polygons
;
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/GMLValidationHandler.java
0 → 100644
View file @
3f3c1884
/*-
* Copyright 2022 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.mapper.citygml3
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.xml.sax.ErrorHandler
;
import
org.xml.sax.SAXParseException
;
public
class
GMLValidationHandler
implements
ErrorHandler
{
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
GMLValidationHandler
.
class
);
private
List
<
String
>
messages
=
new
ArrayList
<>();
@Override
public
void
error
(
SAXParseException
exception
)
{
String
message
=
"["
+
exception
.
getLineNumber
()
+
", "
+
exception
.
getColumnNumber
()
+
"] "
+
exception
.
getMessage
();
logger
.
error
(
message
);
messages
.
add
(
message
);
}
@Override
public
void
warning
(
SAXParseException
exception
)
{
String
message
=
"["
+
exception
.
getLineNumber
()
+
", "
+
exception
.
getColumnNumber
()
+
"] "
+
exception
.
getMessage
();
logger
.
warn
(
message
);
messages
.
add
(
message
);
}
@Override
public
void
fatalError
(
SAXParseException
exception
)
{
String
message
=
"["
+
exception
.
getLineNumber
()
+
", "
+
exception
.
getColumnNumber
()
+
"] "
+
exception
.
getMessage
();
logger
.
fatal
(
message
);
messages
.
add
(
message
);
}
public
List
<
String
>
getMessages
()
{
return
messages
;
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/ResolvableReference.java
0 → 100644
View file @
3f3c1884
/*-
* Copyright 2022 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.mapper.citygml3
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
public
record
ResolvableReference
(
String
href
,
Geometry
geometry
)
{
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/SurfaceMapper.java
0 → 100644
View file @
3f3c1884
/*-
* Copyright 2022 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.mapper.citygml3
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
org.citygml4j.core.model.construction.AbstractConstructionSurface
;
import
org.citygml4j.core.model.construction.AbstractFillingSurface
;
import
org.citygml4j.core.model.construction.AbstractFillingSurfaceProperty
;
import
org.citygml4j.core.model.construction.CeilingSurface
;
import
org.citygml4j.core.model.construction.DoorSurface
;
import
org.citygml4j.core.model.construction.FloorSurface
;
import
org.citygml4j.core.model.construction.GroundSurface
;
import
org.citygml4j.core.model.construction.InteriorWallSurface
;
import
org.citygml4j.core.model.construction.OuterCeilingSurface
;
import
org.citygml4j.core.model.construction.OuterFloorSurface
;
import
org.citygml4j.core.model.construction.RoofSurface
;
import
org.citygml4j.core.model.construction.WallSurface
;
import
org.citygml4j.core.model.construction.WindowSurface
;
import
org.citygml4j.core.model.core.AbstractThematicSurface
;
import
org.citygml4j.core.model.core.ClosureSurface
;
import
org.citygml4j.core.visitor.ObjectWalker
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.AbstractSurface
;
import
org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.datastructure.Opening
;
import
de.hft.stuttgart.citydoctor2.datastructure.OpeningType
;
import
de.hft.stuttgart.citydoctor2.datastructure.SurfaceFeatureType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
public
class
SurfaceMapper
extends
ObjectWalker
{
private
List
<
BoundarySurface
>
surfaces
=
new
ArrayList
<>();
private
Map
<
String
,
ConcretePolygon
>
polygonMap
;
private
List
<
ResolvableReference
>
references
;
private
Map
<
Vertex
,
Vertex
>
vertexMap
;
private
ParserConfiguration
config
;
public
SurfaceMapper
(
Map
<
String
,
ConcretePolygon
>
polygonMap
,
List
<
ResolvableReference
>
references
,
Map
<
Vertex
,
Vertex
>
vertexMap
,
ParserConfiguration
config
)
{
this
.
polygonMap
=
polygonMap
;
this
.
references
=
references
;
this
.
vertexMap
=
vertexMap
;
this
.
config
=
config
;
}
@Override
public
void
visit
(
WallSurface
wallSurface
)
{
BoundarySurface
surface
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
BoundarySurfaceType
.
WALL
,
wallSurface
);
handleConstructionSurface
(
wallSurface
,
surface
);
surfaces
.
add
(
surface
);
}
private
void
handleConstructionSurface
(
AbstractConstructionSurface
gmlSurface
,
BoundarySurface
cdSurface
)
{
for
(
AbstractFillingSurfaceProperty
fillingProp
:
gmlSurface
.
getFillingSurfaces
())
{
if
(
fillingProp
.
isSetObject
())
{
readAbstractFillingSurface
(
fillingProp
.
getObject
(),
cdSurface
);
}
}
handleThematicSurface
(
gmlSurface
,
cdSurface
);
cdSurface
.
unsetGmlGeometries
();
}
private
void
readAbstractFillingSurface
(
AbstractFillingSurface
afs
,
BoundarySurface
cdSurface
)
{
Opening
o
;
if
(
afs
instanceof
DoorSurface
ds
)
{
o
=
new
Opening
(
OpeningType
.
DOOR
,
SurfaceFeatureType
.
BUILDING
,
cdSurface
,
ds
);
}
else
if
(
afs
instanceof
WindowSurface
ws
){
o
=
new
Opening
(
OpeningType
.
WINDOW
,
SurfaceFeatureType
.
BUILDING
,
cdSurface
,
ws
);
}
else
{
o
=
new
Opening
(
OpeningType
.
UNKNOWN
,
SurfaceFeatureType
.
BUILDING
,
cdSurface
,
afs
);
}
cdSurface
.
addOpening
(
o
);
parseAndAddMultiSurface
(
afs
.
getLod0MultiSurface
(),
Lod
.
LOD0
,
o
);
parseAndAddMultiSurface
(
afs
.
getLod1MultiSurface
(),
Lod
.
LOD1
,
o
);
parseAndAddMultiSurface
(
afs
.
getLod2MultiSurface
(),
Lod
.
LOD2
,
o
);
parseAndAddMultiSurface
(
afs
.
getLod3MultiSurface
(),
Lod
.
LOD3
,
o
);
parseAndAddMultiSurface
(
afs
.
getDeprecatedProperties
().
getLod4MultiSurface
(),
Lod
.
LOD4
,
o
);
o
.
unsetGmlGeometries
();
}
private
void
handleThematicSurface
(
AbstractThematicSurface
gmlSurface
,
CityObject
cdSurface
)
{
Citygml3FeatureMapper
.
parseId
(
gmlSurface
,
cdSurface
);
parseAndAddMultiSurface
(
gmlSurface
.
getLod0MultiSurface
(),
Lod
.
LOD0
,
cdSurface
);
parseAndAddMultiSurface
(
gmlSurface
.
getLod1MultiSurface
(),
Lod
.
LOD1
,
cdSurface
);
parseAndAddMultiSurface
(
gmlSurface
.
getLod2MultiSurface
(),
Lod
.
LOD2
,
cdSurface
);
parseAndAddMultiSurface
(
gmlSurface
.
getLod3MultiSurface
(),
Lod
.
LOD3
,
cdSurface
);
parseAndAddMultiSurface
(
gmlSurface
.
getDeprecatedProperties
().
getLod4MultiSurface
(),
Lod
.
LOD4
,
cdSurface
);
}
private
void
parseAndAddMultiSurface
(
MultiSurfaceProperty
msp
,
Lod
lod
,
CityObject
cdSurface
)
{
if
(
msp
==
null
||
msp
.
getObject
()
==
null
)
{
return
;
}
Geometry
geom
=
parseMultiSurface
(
msp
.
getObject
(),
lod
);
cdSurface
.
addGeometry
(
geom
);
}
private
Geometry
parseMultiSurface
(
MultiSurface
ms
,
Lod
lod
)
{
Geometry
geom
=
new
Geometry
(
GeometryType
.
MULTI_SURFACE
,
lod
);
Citygml3GeometryMapper
geometryMapper
=
new
Citygml3GeometryMapper
(
config
,
vertexMap
);
readSurfaceMember
(
geom
,
geometryMapper
,
ms
.
getSurfaceMember
());
return
geom
;
}
private
void
readSurfaceMember
(
Geometry
geom
,
Citygml3GeometryMapper
geometryMapper
,
List
<
SurfaceProperty
>
surfaceMember
)
{
for
(
SurfaceProperty
prop
:
surfaceMember
)
{
if
(
prop
.
getHref
()
!=
null
)
{
references
.
add
(
new
ResolvableReference
(
prop
.
getHref
(),
geom
));
continue
;
}
if
(
prop
.
getObject
()
!=
null
)
{
AbstractSurface
as
=
prop
.
getObject
();
as
.
accept
(
geometryMapper
);
}
}
List
<
ConcretePolygon
>
polygons
=
geometryMapper
.
getPolygons
();
for
(
ConcretePolygon
concretePoly
:
polygons
)
{
geom
.
addPolygon
(
concretePoly
);
if
(
concretePoly
.
hasExistingGmlId
())
{
polygonMap
.
put
(
concretePoly
.
getGmlId
().
getGmlString
(),
concretePoly
);
}
}
}
@Override
public
void
visit
(
FloorSurface
floorSurface
)
{
BoundarySurface
surface
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
BoundarySurfaceType
.
FLOOR
,
floorSurface
);
handleConstructionSurface
(
floorSurface
,
surface
);
surfaces
.
add
(
surface
);
}
@Override
public
void
visit
(
CeilingSurface
ceilingSurface
)
{
BoundarySurface
surface
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
BoundarySurfaceType
.
CEILING
,
ceilingSurface
);
handleConstructionSurface
(
ceilingSurface
,
surface
);
surfaces
.
add
(
surface
);
}
@Override
public
void
visit
(
GroundSurface
groundSurface
)
{
BoundarySurface
surface
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
BoundarySurfaceType
.
GROUND
,
groundSurface
);
handleConstructionSurface
(
groundSurface
,
surface
);
surfaces
.
add
(
surface
);
}
@Override
public
void
visit
(
InteriorWallSurface
interiorWallSurface
)
{
BoundarySurface
surface
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
BoundarySurfaceType
.
INTERIOR_WALL
,
interiorWallSurface
);
handleConstructionSurface
(
interiorWallSurface
,
surface
);
surfaces
.
add
(
surface
);
}
@Override
public
void
visit
(
OuterCeilingSurface
outerCeilingSurface
)
{
BoundarySurface
surface
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
BoundarySurfaceType
.
OUTER_CEILING
,
outerCeilingSurface
);
handleConstructionSurface
(
outerCeilingSurface
,
surface
);
surfaces
.
add
(
surface
);
}
@Override
public
void
visit
(
OuterFloorSurface
outerFloorSurface
)
{
BoundarySurface
surface
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
BoundarySurfaceType
.
OUTER_FLOOR
,
outerFloorSurface
);
handleConstructionSurface
(
outerFloorSurface
,
surface
);
surfaces
.
add
(
surface
);
}
@Override
public
void
visit
(
RoofSurface
roofSurface
)
{
BoundarySurface
surface
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
BoundarySurfaceType
.
ROOF
,
roofSurface
);
handleConstructionSurface
(
roofSurface
,
surface
);
surfaces
.
add
(
surface
);
}
@Override
public
void
visit
(
ClosureSurface
closureSurface
)
{
BoundarySurface
surface
=
new
BoundarySurface
(
SurfaceFeatureType
.
BUILDING
,
BoundarySurfaceType
.
CLOSURE
,
closureSurface
);
handleThematicSurface
(
closureSurface
,
surface
);
surfaces
.
add
(
surface
);
}
public
List
<
BoundarySurface
>
getSurfaces
()
{
return
surfaces
;
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlConsumer.java
View file @
3f3c1884
...
...
@@ -18,7 +18,7 @@
*/
package
de.hft.stuttgart.citydoctor2.parser
;
import
org.citygml4j.
model.citygm
l.core.CityModel
;
import
org.citygml4j.
core.mode
l.core.CityModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
View file @
3f3c1884
/*-
* Copyright 202
0
Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
* Copyright 202
2
Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
...
...
@@ -23,72 +23,68 @@ import java.io.File;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.UncheckedIOException
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.util.ArrayList
;
import
java.util.Enumeration
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.ServiceLoader
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipFile
;
import
javax.xml.XMLConstants
;
import
javax.xml.bind.ValidationEventHandler
;
import
javax.xml.namespace.QName
;
import
javax.xml.parsers.ParserConfigurationException
;
import
javax.xml.parsers.SAXParser
;
import
javax.xml.parsers.SAXParserFactory
;
import
javax.xml.transform.Source
;
import
javax.xml.transform.stream.StreamSource
;
import
javax.xml.validation.Schema
;
import
javax.xml.validation.SchemaFactory
;
import
javax.xml.validation.Validator
;
import
org.apache.logging.log4j.Level
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.citygml4j.CityGMLContext
;
import
org.citygml4j.builder.jaxb.CityGMLBuilder
;
import
org.citygml4j.builder.jaxb.CityGMLBuilderException
;
import
org.citygml4j.model.citygml.CityGML
;
import
org.citygml4j.model.citygml.ade.ADEComponent
;
import
org.citygml4j.model.citygml.ade.ADEException
;
import
org.citygml4j.model.citygml.ade.binding.ADEContext
;
import
org.citygml4j.model.citygml.ade.generic.ADEGenericElement
;
import
org.citygml4j.model.citygml.bridge.Bridge
;
import
org.citygml4j.model.citygml.core.AbstractCityObject
;
import
org.citygml4j.model.citygml.core.CityModel
;
import
org.citygml4j.model.citygml.core.CityObjectMember
;
import
org.citygml4j.model.citygml.landuse.LandUse
;
import
org.citygml4j.model.citygml.transportation.AbstractTransportationObject
;
import
org.citygml4j.model.citygml.vegetation.AbstractVegetationObject
;
import
org.citygml4j.model.citygml.waterbody.WaterBody
;
import
org.citygml4j.model.gml.feature.AbstractFeature
;
import
org.citygml4j.model.module.citygml.CityGMLVersion
;
import
org.citygml4j.xml.io.CityGMLInputFactory
;
import
org.citygml4j.xml.io.CityGMLOutputFactory
;
import
org.citygml4j.xml.io.reader.CityGMLReadException
;
import
org.citygml4j.xml.io.reader.CityGMLReader
;
import
org.citygml4j.xml.io.reader.FeatureReadMode
;
import
org.citygml4j.xml.io.reader.ParentInfo
;
import
org.citygml4j.xml.io.writer.CityGMLWriteException
;
import
org.citygml4j.xml.io.writer.CityModelInfo
;
import
org.citygml4j.xml.io.writer.CityModelWriter
;
import
org.citygml4j.core.ade.ADEException
;
import
org.citygml4j.core.ade.ADERegistry
;
import
org.citygml4j.core.model.ade.ADEProperty
;
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.CityModel
;
import
org.citygml4j.core.util.CityGMLConstants
;
import
org.citygml4j.xml.CityGMLContext
;
import
org.citygml4j.xml.CityGMLContextException
;
import
org.citygml4j.xml.module.citygml.CityGMLModule
;
import
org.citygml4j.xml.module.citygml.CityGMLModules
;
import
org.citygml4j.xml.reader.ChunkOptions
;
import
org.citygml4j.xml.reader.CityGMLInputFactory
;
import
org.citygml4j.xml.reader.CityGMLReadException
;
import
org.citygml4j.xml.reader.CityGMLReader
;
import
org.citygml4j.xml.reader.FeatureInfo
;
import
org.citygml4j.xml.schema.CityGMLSchemaHandler
;
import
org.citygml4j.xml.writer.CityGMLChunkWriter
;
import
org.citygml4j.xml.writer.CityGMLOutputFactory
;
import
org.citygml4j.xml.writer.CityGMLWriteException
;
import
org.locationtech.proj4j.BasicCoordinateTransform
;
import
org.locationtech.proj4j.CRSFactory
;
import
org.locationtech.proj4j.CoordinateReferenceSystem
;
import
org.locationtech.proj4j.ProjCoordinate
;
import
org.locationtech.proj4j.proj.Projection
;
import
org.locationtech.proj4j.units.Units
;
import
org.w3c.dom.DOMException
;
import
org.xml.sax.InputSource
;
import
org.xml.sax.SAXException
;
import
org.xml.sax.SAXNotRecognizedException
;
import
org.xml.sax.SAXNotSupportedException
;
import
org.xml
.sax.SAXParse
Exception
;
import
org.xml
objects.schema.SchemaHandler
Exception
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.mapper.FeatureMapper
;
import
de.hft.stuttgart.citydoctor2.mapper.citygml3.Citygml3FeatureMapper
;
import
de.hft.stuttgart.citydoctor2.mapper.citygml3.GMLValidationHandler
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
import
de.hft.stuttgart.citydoctor2.utils.Localization
;
import
de.hft.stuttgart.quality.QualityADEContext
;
import
de.hft.stuttgart.quality.QualityADEModule
;
/**
...
...
@@ -99,6 +95,8 @@ import de.hft.stuttgart.quality.QualityADEModule;
*/
public
class
CityGmlParser
{
private
static
final
String
CITY_OBJECT_MEMBER
=
"cityObjectMember"
;
private
static
final
String
WGS_84
=
"EPSG:4326"
;
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
CityGmlParser
.
class
);
...
...
@@ -119,6 +117,9 @@ public class CityGmlParser {
private
static
final
SAXParserFactory
FACTORY
;
private
static
CityGMLContext
context
;
private
static
List
<
QName
>
chunkProperties
=
new
ArrayList
<>();
static
{
FACTORY
=
SAXParserFactory
.
newInstance
();
try
{
...
...
@@ -126,10 +127,31 @@ public class CityGmlParser {
}
catch
(
SAXNotRecognizedException
|
SAXNotSupportedException
|
ParserConfigurationException
e
)
{
logger
.
catching
(
e
);
}
chunkProperties
.
add
(
new
QName
(
CityGMLConstants
.
CITYGML_1_0_CORE_NAMESPACE
,
CITY_OBJECT_MEMBER
));
chunkProperties
.
add
(
new
QName
(
CityGMLConstants
.
CITYGML_2_0_CORE_NAMESPACE
,
CITY_OBJECT_MEMBER
));
chunkProperties
.
add
(
new
QName
(
CityGMLConstants
.
CITYGML_3_0_CORE_NAMESPACE
,
CITY_OBJECT_MEMBER
));
}
private
CityGmlParser
()
{
// only static access
}
public
static
synchronized
CityGMLContext
getContext
()
{
if
(
context
==
null
)
{
try
{
context
=
CityGMLContext
.
newInstance
(
CityGmlParser
.
class
.
getClassLoader
());
// also setup ades
ADERegistry
adeRegistry
=
ADERegistry
.
getInstance
();
adeRegistry
.
loadADE
(
new
QualityADEContext
());
}
catch
(
CityGMLContextException
e
)
{
logger
.
fatal
(
"Unable to create citygml4j context"
,
e
);
throw
new
IllegalStateException
(
"Unable to create citygml4j context"
);
}
catch
(
ADEException
e
)
{
logger
.
fatal
(
"Unable to add ADE plugins to citygml4j"
,
e
);
throw
new
IllegalStateException
(
"Unable to add ADE plugins to citygml4j"
);
}
}
return
context
;
}
public
static
CityDoctorModel
parseCityGmlFile
(
String
file
,
ParserConfiguration
config
)
...
...
@@ -143,329 +165,99 @@ public class CityGmlParser {
}
public
static
CityDoctorModel
parseCityGmlFile
(
String
filePath
,
ParserConfiguration
config
,
ProgressListener
l
,
ValidationEventHandler
handler
)
throws
CityGmlParseException
,
InvalidGmlFileException
{
File
file
=
new
File
(
filePath
);
GMLValidationHandler
handler
)
throws
CityGmlParseException
,
InvalidGmlFileException
{
CityGMLContext
context
=
getContext
();
Path
file
=
Paths
.
get
(
filePath
);
if
(
config
.
getValidate
())
{
List
<
String
>
messages
=
validateFile
(
context
,
handler
,
file
);
if
(!
messages
.
isEmpty
())
{
throw
new
InvalidGmlFileException
(
"Invalid GML File. First error: \n"
+
messages
.
get
(
0
));
}
}
try
{
parseEpsgCodeFromFile
(
file
,
config
);
CityGMLBuilder
builder
=
setupCityGmlBuilder
();
CityGMLInputFactory
inputFactory
=
setupGmlReader
(
builder
,
config
);
if
(
handler
!=
null
)
{
inputFactory
.
setValidationEventHandler
(
handler
);
}
// try with resources for automatic closing
try
(
ObservedInputStream
ois
=
new
ObservedInputStream
(
file
))
{
CityGMLInputFactory
in
=
context
.
createCityGMLInputFactory
()
.
withChunking
(
ChunkOptions
.
chunkByProperties
(
chunkProperties
).
skipCityModel
(
false
));
try
(
ObservedInputStream
ois
=
new
ObservedInputStream
(
file
.
toFile
()))
{
if
(
l
!=
null
)
{
ois
.
addListener
(
l:
:
updateProgress
);
}
return
readAndKeepFeatures
(
config
,
file
,
inputFactory
,
ois
);
}
}
catch
(
CityGMLReadException
e
)
{
if
(
e
.
getCause
()
instanceof
SAXParseException
)
{
throw
new
InvalidGmlFileException
(
Localization
.
getText
(
"CityGmlParser.notValidGmlFile"
)
+
e
.
getCause
().
getMessage
(),
e
);
}
throw
new
CityGmlParseException
(
e
);
}
catch
(
IOException
|
CityGMLBuilderException
|
ParserConfigurationException
|
SAXException
|
ADEException
e
)
{
throw
new
CityGmlParseException
(
e
);
}
catch
(
DOMException
e
)
{
// the citygml4j split per feature tries to insert an element
// this sometimes fails because of namespace mismatch
// fallback solution is to parse the whole file at once
// problems with memory consumption may arise
try
{
if
(
logger
.
isWarnEnabled
())
{
logger
.
warn
(
Localization
.
getText
(
"CityGmlParser.chunkReadFailed"
),
e
);
}
return
parseCityGmlFileComplete
(
file
,
config
,
l
);
}
catch
(
CityGMLBuilderException
|
CityGMLReadException
|
IOException
e1
)
{
throw
new
CityGmlParseException
(
e1
);
}
}
}
private
static
CityDoctorModel
readAndKeepFeatures
(
ParserConfiguration
config
,
File
file
,
CityGMLInputFactory
inputFactory
,
ObservedInputStream
ois
)
throws
CityGMLReadException
{
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
file
.
getAbsolutePath
(),
ois
))
{
FeatureMapper
mapper
=
new
FeatureMapper
(
config
,
file
);
// model is read in chunked mode
// object members are replaced by href in model
// need to remove the refs and re-add unparsed objects
List
<
AbstractCityObject
>
acos
=
new
ArrayList
<>();
List
<
ADEGenericElement
>
genericElements
=
new
ArrayList
<>();
while
(
reader
.
hasNext
())
{
CityGML
chunk
=
reader
.
nextFeature
();
if
(
chunk
instanceof
AbstractCityObject
aco
)
{
aco
.
accept
(
mapper
);
acos
.
add
(
aco
);
}
else
if
(
chunk
instanceof
CityModel
cModel
)
{
((
CityModel
)
chunk
).
unsetCityObjectMember
();
// re-add all objects
for
(
AbstractCityObject
aco
:
acos
)
{
cModel
.
addCityObjectMember
(
new
CityObjectMember
(
aco
));
}
// remove those that should have been parsed
unsetParsedCityObjectMembers
(
cModel
);
for
(
ADEGenericElement
ele
:
genericElements
)
{
cModel
.
addGenericADEElement
(
ele
);
}
mapper
.
setCityModel
(
cModel
);
}
else
if
(
chunk
instanceof
ADEGenericElement
ge
)
{
genericElements
.
add
(
ge
);
}
}
if
(
logger
.
isInfoEnabled
())
{
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.parsedObjects"
),
mapper
.
getModel
().
getNumberOfFeatures
());
}
return
mapper
.
getModel
();
}
}
private
static
CityDoctorModel
parseCityGmlFileComplete
(
File
file
,
ParserConfiguration
config
,
ProgressListener
l
)
throws
CityGMLBuilderException
,
IOException
,
CityGMLReadException
,
CityGmlParseException
{
CityGMLContext
context
=
CityGMLContext
.
getInstance
();
CityGMLBuilder
builder
=
context
.
createCityGMLBuilder
();
CityGMLInputFactory
inputFactory
=
builder
.
createCityGMLInputFactory
();
inputFactory
.
setProperty
(
CityGMLInputFactory
.
FAIL_ON_MISSING_ADE_SCHEMA
,
false
);
inputFactory
.
setProperty
(
CityGMLInputFactory
.
USE_VALIDATION
,
config
.
getValidate
());
try
(
ObservedInputStream
ois
=
new
ObservedInputStream
(
file
))
{
if
(
l
!=
null
)
{
ois
.
addListener
(
l:
:
updateProgress
);
}
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
file
.
getAbsolutePath
(),
ois
))
{
FeatureMapper
mapper
=
new
FeatureMapper
(
config
,
file
);
CityGML
chunk
=
reader
.
nextFeature
();
if
(!(
chunk
instanceof
CityModel
))
{
throw
new
CityGmlParseException
(
"Did not read CityModel as first element of gml file."
);
}
CityModel
model
=
(
CityModel
)
chunk
;
mapper
.
setCityModel
(
model
);
if
(
model
.
isSetCityObjectMember
())
{
for
(
CityObjectMember
com
:
model
.
getCityObjectMember
())
{
if
(
com
.
isSetCityObject
())
{
com
.
getCityObject
().
accept
(
mapper
);
}
}
}
model
.
unsetCityObjectMember
();
return
mapper
.
getModel
();
}
}
}
private
static
CityGMLInputFactory
setupGmlReader
(
CityGMLBuilder
builder
,
ParserConfiguration
config
)
throws
CityGMLBuilderException
{
CityGMLInputFactory
inputFactory
=
builder
.
createCityGMLInputFactory
();
inputFactory
.
setProperty
(
CityGMLInputFactory
.
FEATURE_READ_MODE
,
FeatureReadMode
.
SPLIT_PER_FEATURE
);
if
(
config
!=
null
)
{
inputFactory
.
setProperty
(
CityGMLInputFactory
.
USE_VALIDATION
,
config
.
getValidate
());
}
inputFactory
.
setProperty
(
CityGMLInputFactory
.
FAIL_ON_MISSING_ADE_SCHEMA
,
false
);
inputFactory
.
setProperty
(
CityGMLInputFactory
.
EXCLUDE_FROM_SPLITTING
,
new
QName
[]
{
new
QName
(
"WallSurface"
),
new
QName
(
"RoofSurface"
),
new
QName
(
"GroundSurface"
),
new
QName
(
"CeilingSurface"
),
new
QName
(
"ClosureSurface"
),
new
QName
(
"FloorSurface"
),
new
QName
(
"InteriorWallSurface"
),
new
QName
(
"OuterCeilingSurface"
),
new
QName
(
"OuterFloorSurface"
),
new
QName
(
"BuildingInstallation"
),
new
QName
(
"BuildingPart"
),
new
QName
(
"Door"
),
new
QName
(
"Window"
)
});
return
inputFactory
;
}
private
static
CityGMLBuilder
setupCityGmlBuilder
()
throws
ADEException
,
CityGMLBuilderException
{
CityGMLContext
context
=
CityGMLContext
.
getInstance
();
// setup energy ade stuff, so the parser doesn't crash on encountering this
if
(!
context
.
hasADEContexts
())
{
for
(
ADEContext
adeContext
:
ServiceLoader
.
load
(
ADEContext
.
class
))
{
context
.
registerADEContext
(
adeContext
);
return
readAndKeepFeatures
(
config
,
file
,
in
,
ois
);
}
}
catch
(
CityGMLReadException
|
IOException
e
)
{
throw
new
CityGmlParseException
(
"Failed to read CityGML file"
,
e
);
}
return
context
.
createCityGMLBuilder
(
CityGmlParser
.
class
.
getClassLoader
());
}
public
static
void
streamCityGml
(
String
file
,
ParserConfiguration
config
,
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGmlParseException
{
File
f
=
new
File
(
file
);
Path
f
=
Paths
.
get
(
file
);
streamCityGml
(
f
,
config
,
null
,
cityObjectConsumer
,
outputFile
);
}
public
static
void
streamCityGml
(
File
file
,
ParserConfiguration
config
,
ProgressListener
l
,
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGmlParseException
{
try
{
if
(
getExtension
(
file
.
getName
()).
equals
(
"zip"
))
{
streamZipFile
(
file
,
config
);
}
parseEpsgCodeFromFile
(
file
,
config
);
CityGMLBuilder
builder
=
setupCityGmlBuilder
();
startReadingCityGml
(
file
,
config
,
l
,
cityObjectConsumer
,
builder
,
outputFile
);
}
catch
(
CityGMLBuilderException
|
IOException
|
ParserConfigurationException
|
SAXException
|
ADEException
e
)
{
throw
new
CityGmlParseException
(
e
);
}
}
private
static
void
startReadingCityGml
(
File
file
,
ParserConfiguration
config
,
ProgressListener
l
,
CityGmlConsumer
cityObjectConsumer
,
CityGMLBuilder
builder
,
String
outputFile
)
throws
CityGMLBuilderException
{
try
(
ObservedInputStream
ois
=
new
ObservedInputStream
(
file
))
{
if
(
l
!=
null
)
{
ois
.
addListener
(
l:
:
updateProgress
);
}
readAndDiscardFeatures
(
file
,
config
,
builder
,
ois
,
cityObjectConsumer
,
outputFile
);
}
catch
(
IOException
e
)
{
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorReadingGmlFile"
),
e
.
getMessage
());
logger
.
catching
(
Level
.
ERROR
,
e
);
}
}
private
static
void
streamZipFile
(
File
file
,
ParserConfiguration
config
)
throws
CityGmlParseException
{
try
(
ZipFile
zip
=
new
ZipFile
(
file
))
{
Enumeration
<?
extends
ZipEntry
>
entries
=
zip
.
entries
();
while
(
entries
.
hasMoreElements
())
{
ZipEntry
ze
=
entries
.
nextElement
();
BufferedInputStream
bis
=
new
BufferedInputStream
(
zip
.
getInputStream
(
ze
));
parseEpsgCodeFromStream
(
bis
,
config
);
}
}
catch
(
IOException
e
)
{
throw
new
UncheckedIOException
(
e
);
}
catch
(
ParserConfigurationException
|
SAXException
e
)
{
throw
new
CityGmlParseException
(
e
);
}
}
private
static
String
getExtension
(
String
fileName
)
{
char
ch
;
int
len
;
if
(
fileName
==
null
||
(
len
=
fileName
.
length
())
==
0
||
(
ch
=
fileName
.
charAt
(
len
-
1
))
==
'/'
||
ch
==
'\\'
||
ch
==
'.'
)
{
return
""
;
}
int
dotInd
=
fileName
.
lastIndexOf
(
'.'
);
int
sepInd
=
Math
.
max
(
fileName
.
lastIndexOf
(
'/'
),
fileName
.
lastIndexOf
(
'\\'
));
if
(
dotInd
<=
sepInd
)
return
""
;
else
return
fileName
.
substring
(
dotInd
+
1
).
toLowerCase
();
}
public
static
void
streamCityGml
(
File
file
,
ParserConfiguration
parserConfig
,
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGmlParseException
{
streamCityGml
(
file
,
parserConfig
,
null
,
cityObjectConsumer
,
outputFile
);
streamCityGml
(
file
.
toPath
()
,
parserConfig
,
null
,
cityObjectConsumer
,
outputFile
);
}
/**
* The srsName (The name by which this reference system is identified) inside
* the CityGML file can have multiple formats. This method tries to parse the
* string and detect the corresponding reference system. If it is found, it
* returns a proj4j.CoordinateReferenceSystem. It throws an
* IllegalArgumentException otherwise.
*
* This method should be able to parse any EPSG id : e.g. "EPSG:1234". German
* Citygmls might also have "DE_DHDN_3GK3" or "ETRS89_UTM32" as srsName, so
* those are also included. It isn't guaranteed that those formats are correctly
* parsed, though.
*
* The EPSG ids and parameters are defined in resources ('nad/epsg') inside
* proj4j-0.1.0.jar. Some EPSG ids are missing though, e.g. 7415
*
* @param srsName
* @return CoordinateReferenceSystem
*/
private
static
CoordinateReferenceSystem
crsFromSrsName
(
String
srsName
)
{
srsName
=
srsName
.
trim
();
Matcher
mEPSG
=
P_EPSG
.
matcher
(
srsName
);
if
(
mEPSG
.
find
())
{
if
(
"EPSG:4979"
.
contentEquals
(
srsName
))
{
srsName
=
"EPSG:4236"
;
}
else
if
(
"EPSG:7415"
.
contentEquals
(
srsName
))
{
return
CRS_FACTORY
.
createFromParameters
(
"EPSG:7415"
,
"+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +towgs84=565.417,50.3319,465.552,-0.398957,0.343988,-1.8774,4.0725 +units=m +no_defs"
);
}
return
CRS_FACTORY
.
createFromName
(
srsName
);
}
Matcher
mOGC
=
P_OGC
.
matcher
(
srsName
);
if
(
mOGC
.
find
())
{
return
CRS_FACTORY
.
createFromName
(
"EPSG:"
+
mOGC
.
group
(
1
));
}
Matcher
mOGC2
=
P_OGC2
.
matcher
(
srsName
);
if
(
mOGC2
.
find
())
{
return
CRS_FACTORY
.
createFromName
(
"EPSG:"
+
mOGC2
.
group
(
1
));
}
Matcher
mURN
=
P_URN
.
matcher
(
srsName
);
// NOTE: Could use a HashMap if the switch/case becomes too long.
if
(
mURN
.
find
())
{
switch
(
mURN
.
group
(
1
))
{
case
"DE_DHDN_3GK2"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:31466"
);
case
"DE_DHDN_3GK3"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:31467"
);
case
"DE_DHDN_3GK4"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:31468"
);
case
"DE_DHDN_3GK5"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:31469"
);
case
"ETRS89_UTM32"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:25832"
);
default
:
return
null
;
}
}
if
(
srsName
.
equals
(
"http://www.opengis.net/def/crs/EPSG/0/6697"
))
{
return
CRS_FACTORY
.
createFromParameters
(
"EPSG:6697"
,
"+proj=longlat +ellps=GRS80 +no_defs +axis=neu"
);
}
return
null
;
public
static
void
streamCityGml
(
Path
file
,
ParserConfiguration
config
,
ProgressListener
l
,
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGmlParseException
{
parseEpsgCodeFromFile
(
file
,
config
);
startReadingCityGml
(
file
,
config
,
l
,
cityObjectConsumer
,
outputFile
);
}
public
static
CityModel
parseOnlyCityModel
(
File
inputFile
)
throws
CityGmlParseException
{
try
{
CityGML
Builder
setupCityGmlBuilder
=
setupCityGmlBuilder
()
;
CityGMLInputFactory
inputFactory
=
setupGmlReader
(
setupCityGmlBuilder
,
null
);
CityGML
InputFactory
inputFactory
=
context
.
createCityGMLInputFactory
()
.
withChunking
(
ChunkOptions
.
chunkByProperties
(
chunkProperties
).
skipCityModel
(
false
)
);
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
inputFile
))
{
while
(
reader
.
hasNext
())
{
CityGML
chunk
=
reader
.
next
Feature
();
AbstractFeature
chunk
=
reader
.
next
();
if
(
chunk
instanceof
CityModel
cModel
)
{
unsetParsed
CityObjectMembers
(
cMode
l
);
cModel
.
set
CityObjectMembers
(
nul
l
);
return
cModel
;
}
}
}
}
catch
(
CityGML
BuilderException
|
CityGMLReadException
|
ADE
Exception
e
)
{
}
catch
(
CityGML
Read
Exception
e
)
{
throw
new
CityGmlParseException
(
e
);
}
throw
new
CityGmlParseException
(
"Did not find any CityModel in CityGML file"
);
}
private
static
void
unsetParsedCityObjectMembers
(
CityModel
cModel
)
{
Iterator
<
CityObjectMember
>
iterator
=
cModel
.
getCityObjectMember
().
iterator
();
while
(
iterator
.
hasNext
())
{
CityObjectMember
m
=
iterator
.
next
();
AbstractCityObject
aco
=
m
.
getCityObject
();
if
(
aco
instanceof
Bridge
||
aco
instanceof
org
.
citygml4j
.
model
.
citygml
.
building
.
Building
||
aco
instanceof
AbstractTransportationObject
||
aco
instanceof
AbstractVegetationObject
||
aco
instanceof
WaterBody
||
aco
instanceof
LandUse
)
{
iterator
.
remove
();
private
static
void
startReadingCityGml
(
Path
file
,
ParserConfiguration
config
,
ProgressListener
l
,
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
{
try
(
ObservedInputStream
ois
=
new
ObservedInputStream
(
file
.
toFile
()))
{
if
(
l
!=
null
)
{
ois
.
addListener
(
l:
:
updateProgress
);
}
readAndDiscardFeatures
(
file
,
config
,
ois
,
cityObjectConsumer
,
outputFile
);
}
catch
(
IOException
|
CityGMLReadException
e
)
{
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorReadingGmlFile"
),
e
.
getMessage
());
logger
.
catching
(
Level
.
ERROR
,
e
);
}
}
private
static
void
readAndDiscardFeatures
(
File
file
,
ParserConfiguration
config
,
CityGMLBuilder
builder
,
ObservedInputStream
ois
,
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGMLBuilderException
{
CityGMLInputFactory
inputFactory
=
setupGmlReader
(
builder
,
config
);
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
file
.
getAbsolutePath
(),
ois
);
CityModelWriter
writer
=
createCityModelWriter
(
builder
,
outputFile
))
{
FeatureMapper
mapper
=
new
FeatureMapper
(
config
,
file
);
private
static
void
readAndDiscardFeatures
(
Path
file
,
ParserConfiguration
config
,
ObservedInputStream
ois
,
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGMLReadException
{
getContext
();
CityGMLInputFactory
inputFactory
=
context
.
createCityGMLInputFactory
()
.
withChunking
(
ChunkOptions
.
chunkByProperties
(
chunkProperties
).
skipCityModel
(
false
));
CityGMLChunkWriter
writer
=
null
;
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
ois
))
{
Citygml3FeatureMapper
mapper
=
new
Citygml3FeatureMapper
(
config
,
file
);
CityDoctorModel
model
=
mapper
.
getModel
();
boolean
isInitialized
=
false
;
CityModelInfo
cityModelInfo
=
null
;
while
(
reader
.
hasNext
())
{
CityGML
chunk
=
reader
.
nextFeature
();
if
(!
isInitialized
&&
writer
!=
null
)
{
ParentInfo
parentInfo
=
reader
.
getParentInfo
();
cityModelInfo
=
new
CityModelInfo
(
parentInfo
);
writer
.
setCityModelInfo
(
cityModelInfo
);
writer
.
writeStartDocument
();
AbstractFeature
chunk
=
reader
.
next
();
if
(
writer
==
null
)
{
writer
=
createCityModelWriter
(
outputFile
,
reader
);
}
if
(!
isInitialized
&&
writer
!=
null
&&
reader
.
getParentInfo
()
!=
null
&&
reader
.
getParentInfo
().
getTypeName
().
getLocalPart
().
equals
(
"CityModel"
))
{
FeatureInfo
parentInfo
=
reader
.
getParentInfo
();
writer
.
withCityModelInfo
(
parentInfo
);
isInitialized
=
true
;
}
if
(
chunk
instanceof
AbstractCityObject
ag
)
{
...
...
@@ -473,14 +265,13 @@ public class CityGmlParser {
drainCityModel
(
model
,
cityObjectConsumer
);
writeAbstractCityObject
(
writer
,
ag
);
}
else
if
(
chunk
instanceof
CityModel
cModel
)
{
cModel
.
un
setCityObjectMember
(
);
cModel
.
setCityObjectMember
s
(
null
);
mapper
.
setCityModel
(
cModel
);
cityObjectConsumer
.
accept
(
cModel
);
writeCityModel
(
writer
,
cityModelInfo
,
cModel
);
}
else
if
(
chunk
instanceof
AbstractFeature
af
&&
writer
!=
null
)
{
writer
.
write
Feature
Member
(
af
);
writeCityModel
(
writer
,
cModel
);
}
else
if
(
writer
!=
null
)
{
writer
.
writeMember
(
chunk
);
}
}
// end of stream
logger
.
debug
(
"End of gml file stream"
);
...
...
@@ -488,49 +279,99 @@ public class CityGmlParser {
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorReadingGmlFile"
),
e
.
getMessage
(),
e
);
}
catch
(
CityGMLWriteException
e
)
{
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorWritingGmlFile"
),
e
.
getMessage
(),
e
);
}
finally
{
if
(
writer
!=
null
)
{
try
{
writer
.
close
();
}
catch
(
CityGMLWriteException
e
)
{
// ignore
}
}
}
}
private
static
void
writeAbstractCityObject
(
CityModelWriter
writer
,
AbstractCityObject
ag
)
throws
CityGMLWriteException
{
private
static
void
writeCityModel
(
CityGMLChunkWriter
writer
,
CityModel
cModel
)
{
if
(
writer
!=
null
)
{
writer
.
writeFeatureMember
(
ag
);
for
(
ADEProperty
genEle
:
cModel
.
getADEProperties
())
{
writer
.
getCityModelInfo
().
addADEProperty
(
genEle
);
}
}
}
private
static
void
write
CityModel
(
CityModelWriter
writer
,
CityModelInfo
cityModelInfo
,
CityModel
cModel
)
private
static
void
write
AbstractCityObject
(
CityGMLChunkWriter
writer
,
AbstractCityObject
ag
)
throws
CityGMLWriteException
{
if
(
writer
!=
null
)
{
for
(
ADEGenericElement
genEle
:
cModel
.
getGenericADEElement
())
{
cityModelInfo
.
addGenericADEElement
(
genEle
);
}
for
(
ADEComponent
adeComp
:
cModel
.
getGenericApplicationPropertyOfCityModel
())
{
cityModelInfo
.
addGenericApplicationPropertyOfCityModel
(
adeComp
);
}
writer
.
writeEndDocument
();
writer
.
writeMember
(
ag
);
}
}
private
static
City
Model
Writer
createCityModelWriter
(
CityGMLBuilder
builder
,
String
outputFile
)
private
static
City
GMLChunk
Writer
createCityModelWriter
(
String
outputFile
,
CityGMLReader
reader
)
throws
CityGMLWriteException
{
if
(
outputFile
==
null
)
{
return
null
;
}
CityGMLOutputFactory
factory
=
builder
.
createCityGMLOutputFactory
();
CityModelWriter
writer
=
factory
.
createCityModelWriter
(
new
File
(
outputFile
),
"UTF-8"
);
writer
.
setPrefix
(
"qual"
,
QualityADEModule
.
NAMESPACE_URI
);
writer
.
setSchemaLocation
(
QualityADEModule
.
NAMESPACE_URI
,
QualityADEModule
.
NAMESPACE_URI
+
"/qualityAde.xsd"
);
writer
.
setIndentString
(
" "
);
writer
.
setPrefixes
(
CityGMLVersion
.
DEFAULT
);
writer
.
setSchemaLocations
(
CityGMLVersion
.
DEFAULT
);
CityGMLContext
gmlContext
=
CityGmlParser
.
getContext
();
CityGMLModule
module
=
CityGMLModules
.
getCityGMLModule
(
reader
.
getName
().
getNamespaceURI
());
CityGMLOutputFactory
factory
=
gmlContext
.
createCityGMLOutputFactory
(
module
.
getCityGMLVersion
());
CityGMLChunkWriter
writer
=
factory
.
createCityGMLChunkWriter
(
new
File
(
outputFile
),
StandardCharsets
.
UTF_8
.
name
());
writer
.
withPrefix
(
"qual"
,
QualityADEModule
.
NAMESPACE_URI
);
writer
.
withSchemaLocation
(
QualityADEModule
.
NAMESPACE_URI
,
QualityADEModule
.
NAMESPACE_URI
+
"/qualityAde.xsd"
);
writer
.
withIndent
(
" "
);
writer
.
withDefaultPrefixes
();
writer
.
withDefaultSchemaLocations
();
return
writer
;
}
private
static
void
parseEpsgCodeFromFile
(
File
file
,
ParserConfiguration
config
)
throws
IOException
,
ParserConfigurationException
,
SAXException
{
try
(
BufferedInputStream
bis
=
new
BufferedInputStream
(
new
FileInputStream
(
file
)))
{
private
static
CityDoctorModel
readAndKeepFeatures
(
ParserConfiguration
config
,
Path
file
,
CityGMLInputFactory
inputFactory
,
ObservedInputStream
ois
)
throws
CityGMLReadException
{
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
ois
))
{
Citygml3FeatureMapper
mapper
=
new
Citygml3FeatureMapper
(
config
,
file
);
// model is read in chunked mode
// object members are replaced by href in model
// need to remove the refs and re-add unparsed objects
List
<
AbstractCityObject
>
acos
=
new
ArrayList
<>();
while
(
reader
.
hasNext
())
{
AbstractFeature
chunk
=
reader
.
next
();
if
(
chunk
instanceof
CityModel
cModel
)
{
cModel
.
setCityObjectMembers
(
null
);
mapper
.
setCityModel
(
cModel
);
CityGMLModule
module
=
CityGMLModules
.
getCityGMLModule
(
reader
.
getName
().
getNamespaceURI
());
mapper
.
setCityGMLVersion
(
module
.
getCityGMLVersion
());
}
else
if
(
chunk
instanceof
AbstractCityObject
aco
)
{
acos
.
add
(
aco
);
aco
.
accept
(
mapper
);
}
}
if
(
mapper
.
getModel
().
getCityModel
()
==
null
)
{
// file does not contain a city model?
// create it for now
mapper
.
setCityModel
(
new
CityModel
());
}
CityModel
cModel
=
mapper
.
getModel
().
getCityModel
();
// remove those that should have been parsed
List
<
AbstractCityObject
>
parsedCityObjects
=
mapper
.
getModel
().
createFeatureStream
()
.
map
(
CityObject:
:
getGmlObject
).
toList
();
acos
.
removeAll
(
parsedCityObjects
);
// re-add all not parsed objects
for
(
AbstractCityObject
aco
:
acos
)
{
cModel
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
aco
));
}
if
(
logger
.
isInfoEnabled
())
{
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.parsedObjects"
),
mapper
.
getModel
().
getNumberOfFeatures
());
}
return
mapper
.
getModel
();
}
}
private
static
void
parseEpsgCodeFromFile
(
Path
file
,
ParserConfiguration
config
)
throws
CityGmlParseException
{
try
(
BufferedInputStream
bis
=
new
BufferedInputStream
(
new
FileInputStream
(
file
.
toFile
())))
{
parseEpsgCodeFromStream
(
bis
,
config
);
}
catch
(
ParserConfigurationException
|
SAXException
|
IOException
e
)
{
throw
new
CityGmlParseException
(
"Failed to read CityGML file"
,
e
);
}
}
...
...
@@ -615,6 +456,89 @@ public class CityGmlParser {
}
}
/**
* The srsName (The name by which this reference system is identified) inside
* the CityGML file can have multiple formats. This method tries to parse the
* string and detect the corresponding reference system. If it is found, it
* returns a proj4j.CoordinateReferenceSystem. It throws an
* IllegalArgumentException otherwise.
*
* This method should be able to parse any EPSG id : e.g. "EPSG:1234". German
* Citygmls might also have "DE_DHDN_3GK3" or "ETRS89_UTM32" as srsName, so
* those are also included. It isn't guaranteed that those formats are correctly
* parsed, though.
*
* The EPSG ids and parameters are defined in resources ('nad/epsg') inside
* proj4j-0.1.0.jar. Some EPSG ids are missing though, e.g. 7415
*
* @param srsName
* @return CoordinateReferenceSystem
*/
private
static
CoordinateReferenceSystem
crsFromSrsName
(
String
srsName
)
{
srsName
=
srsName
.
trim
();
Matcher
mEPSG
=
P_EPSG
.
matcher
(
srsName
);
if
(
mEPSG
.
find
())
{
if
(
"EPSG:4979"
.
contentEquals
(
srsName
))
{
srsName
=
"EPSG:4236"
;
}
else
if
(
"EPSG:7415"
.
contentEquals
(
srsName
))
{
return
CRS_FACTORY
.
createFromParameters
(
"EPSG:7415"
,
"+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +towgs84=565.417,50.3319,465.552,-0.398957,0.343988,-1.8774,4.0725 +units=m +no_defs"
);
}
return
CRS_FACTORY
.
createFromName
(
srsName
);
}
Matcher
mOGC
=
P_OGC
.
matcher
(
srsName
);
if
(
mOGC
.
find
())
{
return
CRS_FACTORY
.
createFromName
(
"EPSG:"
+
mOGC
.
group
(
1
));
}
Matcher
mOGC2
=
P_OGC2
.
matcher
(
srsName
);
if
(
mOGC2
.
find
())
{
return
CRS_FACTORY
.
createFromName
(
"EPSG:"
+
mOGC2
.
group
(
1
));
}
Matcher
mURN
=
P_URN
.
matcher
(
srsName
);
// NOTE: Could use a HashMap if the switch/case becomes too long.
if
(
mURN
.
find
())
{
switch
(
mURN
.
group
(
1
))
{
case
"DE_DHDN_3GK2"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:31466"
);
case
"DE_DHDN_3GK3"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:31467"
);
case
"DE_DHDN_3GK4"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:31468"
);
case
"DE_DHDN_3GK5"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:31469"
);
case
"ETRS89_UTM32"
:
return
CRS_FACTORY
.
createFromName
(
"EPSG:25832"
);
default
:
return
null
;
}
}
if
(
srsName
.
equals
(
"http://www.opengis.net/def/crs/EPSG/0/6697"
))
{
return
CRS_FACTORY
.
createFromParameters
(
"EPSG:6697"
,
"+proj=longlat +ellps=GRS80 +no_defs +axis=neu"
);
}
return
null
;
}
private
static
List
<
String
>
validateFile
(
CityGMLContext
context
,
GMLValidationHandler
handler
,
Path
file
)
throws
CityGmlParseException
{
if
(
handler
==
null
)
{
handler
=
new
GMLValidationHandler
();
}
try
{
CityGMLSchemaHandler
schemaHandler
=
context
.
getDefaultSchemaHandler
();
Source
[]
schemas
=
schemaHandler
.
getSchemas
();
SchemaFactory
schemaFactory
=
SchemaFactory
.
newInstance
(
XMLConstants
.
W3C_XML_SCHEMA_NS_URI
);
schemaFactory
.
setFeature
(
"http://apache.org/xml/features/disallow-doctype-decl"
,
true
);
Schema
schema
=
schemaFactory
.
newSchema
(
schemas
);
Validator
validator
=
schema
.
newValidator
();
validator
.
setErrorHandler
(
handler
);
validator
.
validate
(
new
StreamSource
(
file
.
toFile
()));
return
handler
.
getMessages
();
}
catch
(
SchemaHandlerException
|
SAXException
|
IOException
e
)
{
throw
new
CityGmlParseException
(
"Failed to validate CityGML file"
,
e
);
}
}
private
static
void
drainCityModel
(
CityDoctorModel
model
,
CityGmlConsumer
cityObjectConsumer
)
{
drainCityObjectList
(
model
.
getBuildings
(),
cityObjectConsumer
);
drainCityObjectList
(
model
.
getBridges
(),
cityObjectConsumer
);
...
...
@@ -630,4 +554,5 @@ public class CityGmlParser {
}
objects
.
clear
();
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/CityGmlUtils.java
View file @
3f3c1884
...
...
@@ -21,17 +21,16 @@ package de.hft.stuttgart.citydoctor2.utils;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.citygml4j.factory.DimensionMismatchException
;
import
org.citygml4j.factory.GMLGeometryFactory
;
import
org.citygml4j.model.gml.geometry.aggregates.MultiSurface
;
import
org.citygml4j.model.gml.geometry.complexes.CompositeSurface
;
import
org.citygml4j.model.gml.geometry.primitives.AbstractSurface
;
import
org.citygml4j.model.gml.geometry.primitives.Exterior
;
import
org.citygml4j.model.gml.geometry.primitives.Interior
;
import
org.citygml4j.model.gml.geometry.primitives.Solid
;
import
org.citygml4j.model.gml.geometry.primitives.SurfaceProperty
;
import
org.citygml4j.core.util.geometry.GeometryFactory
;
import
org.locationtech.proj4j.BasicCoordinateTransform
;
import
org.locationtech.proj4j.ProjCoordinate
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.complexes.CompositeSurface
;
import
org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.Shell
;
import
org.xmlobjects.gml.model.geometry.primitives.ShellProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.Solid
;
import
org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
...
...
@@ -52,33 +51,28 @@ public final class CityGmlUtils {
// util class
}
public
static
org
.
city
gml
4j
.
model
.
gml
.
geometry
.
primitives
.
Polygon
createGmlPolygon
(
GML
GeometryFactory
factory
,
public
static
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
createGmlPolygon
(
GeometryFactory
factory
,
Polygon
cdPoly
,
ParserConfiguration
config
)
{
if
(
cdPoly
.
getExteriorRing
()
==
null
)
{
return
null
;
}
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
Polygon
gmlPoly
=
new
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
Polygon
();
try
{
// exterior ring
LinearRing
extLr
=
cdPoly
.
getExteriorRing
();
org
.
citygml4j
.
model
.
gml
.
geometry
.
primitives
.
LinearRing
gmlLr
=
createGmlRing
(
factory
,
config
,
extLr
);
gmlPoly
.
setExterior
(
new
Exterior
(
gmlLr
));
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
gmlPoly
=
new
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
();
// exterior ring
LinearRing
extLr
=
cdPoly
.
getExteriorRing
();
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
LinearRing
gmlLr
=
createGmlRing
(
factory
,
config
,
extLr
);
gmlPoly
.
setExterior
(
new
AbstractRingProperty
(
gmlLr
));
// interior rings
for
(
LinearRing
lr
:
cdPoly
.
getInnerRings
())
{
gmlLr
=
createGmlRing
(
factory
,
config
,
lr
);
gmlPoly
.
addInterior
(
new
Interior
(
gmlLr
));
}
gmlPoly
.
setId
(
cdPoly
.
getGmlId
().
getGmlString
());
return
gmlPoly
;
}
catch
(
DimensionMismatchException
e
)
{
// cannot happen as every vertex has 3 coordinates
return
null
;
// interior rings
for
(
LinearRing
lr
:
cdPoly
.
getInnerRings
())
{
gmlLr
=
createGmlRing
(
factory
,
config
,
lr
);
gmlPoly
.
getInterior
().
add
(
new
AbstractRingProperty
(
gmlLr
));
}
gmlPoly
.
setId
(
cdPoly
.
getGmlId
().
getGmlString
());
return
gmlPoly
;
}
private
static
org
.
city
gml
4j
.
model
.
gml
.
geometry
.
primitives
.
LinearRing
createGmlRing
(
GML
GeometryFactory
factory
,
ParserConfiguration
config
,
LinearRing
lr
)
throws
DimensionMismatchException
{
private
static
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
LinearRing
createGmlRing
(
GeometryFactory
factory
,
ParserConfiguration
config
,
LinearRing
lr
)
{
ProjCoordinate
p1
=
new
ProjCoordinate
();
ProjCoordinate
p2
=
new
ProjCoordinate
();
List
<
Double
>
ringValues
=
new
ArrayList
<>();
...
...
@@ -99,20 +93,21 @@ public final class CityGmlUtils {
ringValues
.
add
(
y
);
ringValues
.
add
(
z
);
}
org
.
city
gml
4j
.
model
.
gml
.
geometry
.
primitives
.
LinearRing
gmlLr
=
factory
.
createLinearRing
(
ringValues
,
3
);
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
LinearRing
gmlLr
=
factory
.
createLinearRing
(
ringValues
,
3
);
gmlLr
.
setId
(
lr
.
getGmlId
().
getGmlString
());
return
gmlLr
;
}
public
static
Solid
createSolid
(
Geometry
geom
,
GML
GeometryFactory
factory
,
ParserConfiguration
config
)
{
public
static
Solid
createSolid
(
Geometry
geom
,
GeometryFactory
factory
,
ParserConfiguration
config
)
{
if
(
geom
.
getType
()
!=
GeometryType
.
SOLID
)
{
throw
new
IllegalArgumentException
(
"Only solids are allowed"
);
}
List
<
SurfaceProperty
>
surfaceMember
=
new
ArrayList
<>();
CompositeSurface
comp
=
new
CompositeSurface
();
List
<
SurfaceProperty
>
surfaceMember
=
comp
.
getSurfaceMembers
();
for
(
Polygon
cdPoly
:
geom
.
getPolygons
())
{
if
(!
cdPoly
.
isLink
())
{
org
.
city
gml
4j
.
model
.
gml
.
geometry
.
primitives
.
Polygon
gmlPoly
=
createGmlPolygon
(
factory
,
cdPoly
,
config
);
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
gmlPoly
=
createGmlPolygon
(
factory
,
cdPoly
,
config
);
if
(
gmlPoly
!=
null
)
{
surfaceMember
.
add
(
new
SurfaceProperty
(
gmlPoly
));
}
...
...
@@ -125,32 +120,29 @@ public final class CityGmlUtils {
if
(
surfaceMember
.
isEmpty
())
{
return
null
;
}
CompositeSurface
comp
=
new
CompositeSurface
();
comp
.
setSurfaceMember
(
surfaceMember
);
Solid
solid
=
new
Solid
();
solid
.
setExterior
(
new
SurfaceProperty
(
comp
));
Shell
shell
=
new
Shell
(
surfaceMember
);
solid
.
setExterior
(
new
ShellProperty
(
shell
));
solid
.
setId
(
geom
.
getGmlId
().
getGmlString
());
return
solid
;
}
public
static
MultiSurface
createMultiSurface
(
Geometry
geom
,
GML
GeometryFactory
factory
,
public
static
MultiSurface
createMultiSurface
(
Geometry
geom
,
GeometryFactory
factory
,
ParserConfiguration
config
)
{
if
(
geom
.
getType
()
!=
GeometryType
.
MULTI_SURFACE
)
{
throw
new
IllegalArgumentException
(
"This can only handle MultiSurfaces"
);
}
List
<
AbstractSurface
>
surfaces
=
new
ArrayList
<>();
List
<
SurfaceProperty
>
surfaces
=
new
ArrayList
<>();
for
(
Polygon
cdPoly
:
geom
.
getPolygons
())
{
if
(!
cdPoly
.
isLink
())
{
// is not part of a boundary surface
org
.
city
gml
4j
.
model
.
gml
.
geometry
.
primitives
.
Polygon
gmlPoly
=
createGmlPolygon
(
factory
,
cdPoly
,
config
);
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
gmlPoly
=
createGmlPolygon
(
factory
,
cdPoly
,
config
);
if
(
gmlPoly
!=
null
)
{
surfaces
.
add
(
gmlPoly
);
surfaces
.
add
(
new
SurfaceProperty
(
gmlPoly
)
)
;
}
}
else
{
// add reference to polygon
CompositeSurface
cs
=
new
CompositeSurface
();
cs
.
addSurfaceMember
(
new
SurfaceProperty
(
"#"
+
cdPoly
.
getGmlId
().
getGmlString
()));
surfaces
.
add
(
cs
);
surfaces
.
add
(
new
SurfaceProperty
(
"#"
+
cdPoly
.
getGmlId
().
getGmlString
()));
}
}
if
(
surfaces
.
isEmpty
())
{
...
...
@@ -161,13 +153,13 @@ public final class CityGmlUtils {
return
ms
;
}
public
static
MultiSurface
createMultiSurface
(
List
<
Polygon
>
polygons
,
GML
GeometryFactory
factory
,
public
static
MultiSurface
createMultiSurface
(
List
<
Polygon
>
polygons
,
GeometryFactory
factory
,
ParserConfiguration
config
)
{
List
<
AbstractSurface
>
surfaces
=
new
ArrayList
<>();
List
<
SurfaceProperty
>
surfaces
=
new
ArrayList
<>();
for
(
Polygon
cdPoly
:
polygons
)
{
org
.
city
gml
4j
.
model
.
gml
.
geometry
.
primitives
.
Polygon
gmlPoly
=
createGmlPolygon
(
factory
,
cdPoly
,
config
);
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
gmlPoly
=
createGmlPolygon
(
factory
,
cdPoly
,
config
);
if
(
gmlPoly
!=
null
)
{
surfaces
.
add
(
gmlPoly
);
surfaces
.
add
(
new
SurfaceProperty
(
gmlPoly
)
)
;
}
}
if
(
surfaces
.
isEmpty
())
{
...
...
@@ -176,13 +168,13 @@ public final class CityGmlUtils {
return
new
MultiSurface
(
surfaces
);
}
public
static
CompositeSurface
createCompositeSurface
(
Geometry
geom
,
GML
GeometryFactory
factory
,
public
static
CompositeSurface
createCompositeSurface
(
Geometry
geom
,
GeometryFactory
factory
,
ParserConfiguration
config
)
{
List
<
AbstractSurface
>
surfaces
=
new
ArrayList
<>();
List
<
SurfaceProperty
>
surfaces
=
new
ArrayList
<>();
for
(
Polygon
cdPoly
:
geom
.
getPolygons
())
{
org
.
city
gml
4j
.
model
.
gml
.
geometry
.
primitives
.
Polygon
gmlPoly
=
createGmlPolygon
(
factory
,
cdPoly
,
config
);
org
.
xmlobjects
.
gml
.
model
.
geometry
.
primitives
.
Polygon
gmlPoly
=
createGmlPolygon
(
factory
,
cdPoly
,
config
);
if
(
gmlPoly
!=
null
)
{
surfaces
.
add
(
gmlPoly
);
surfaces
.
add
(
new
SurfaceProperty
(
gmlPoly
)
)
;
}
}
if
(
surfaces
.
isEmpty
())
{
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/QualityADEUtils.java
View file @
3f3c1884
...
...
@@ -23,19 +23,20 @@ import java.util.HashSet;
import
java.util.List
;
import
java.util.Set
;
import
org.citygml4j.model.citygml.ade.ADEComponent
;
import
org.citygml4j.model.citygml.core.CityModel
;
import
org.citygml4j.model.gml.geometry.primitives.DirectPosition
;
import
org.xmlobjects.gml.model.base.Reference
;
import
org.xmlobjects.gml.model.geometry.DirectPosition
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
import
de.hft.stuttgart.citydoctor2.check.ErrorId
;
import
de.hft.stuttgart.citydoctor2.check.
error.UnknownCheckErr
or
;
import
de.hft.stuttgart.citydoctor2.check.
QualityAdeErrorVisit
or
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
import
de.hft.stuttgart.quality.model.Edge
;
import
de.hft.stuttgart.quality.model.Validation
;
import
de.hft.stuttgart.quality.model.ValidationResult
;
import
de.hft.stuttgart.quality.model.jaxb.ResultType
;
import
de.hft.stuttgart.quality.model.enums.ResultType
;
import
de.hft.stuttgart.quality.model.properties.ValidationResultProperty
;
import
de.hft.stuttgart.quality.model.types.CityObjectProperties
;
import
de.hft.stuttgart.quality.model.types.Edge
;
import
de.hft.stuttgart.quality.model.types.Validation
;
import
de.hft.stuttgart.quality.model.types.ValidationResult
;
public
class
QualityADEUtils
{
...
...
@@ -59,97 +60,76 @@ public class QualityADEUtils {
return
result
;
}
public
static
void
writeQualityAde
(
CityObject
co
)
{
public
static
void
writeQualityAde
(
CityObject
co
,
Validation
val
)
{
ValidationResult
res
=
new
ValidationResult
();
res
.
setValidationPlanID
(
new
Reference
(
val
));
if
(
co
.
isValidated
())
{
List
<
CheckError
>
errors
=
new
ArrayList
<>();
co
.
collectContainedErrors
(
errors
);
if
(
errors
.
isEmpty
())
{
res
.
setResult
(
ResultType
.
OK
);
res
.
setResult
Type
(
ResultType
.
OK
);
}
else
{
res
.
setResult
(
ResultType
.
ERROR
);
res
.
setResult
Type
(
ResultType
.
ERROR
);
Set
<
CheckError
>
errorSet
=
new
HashSet
<>(
errors
);
for
(
CheckError
e
:
errorSet
)
{
if
(
e
instanceof
UnknownCheckError
)
{
// an error happened while checking
// set to not checked
res
.
setResult
(
ResultType
.
NOT_CHECKED
);
}
else
{
e
.
convertToQualityAdeDatastructure
().
ifPresent
(
res
.
getErrors
()::
add
);
}
QualityAdeErrorVisitor
visitor
=
new
QualityAdeErrorVisitor
(
res
);
e
.
accept
(
visitor
);
}
}
}
else
{
res
.
setResult
(
ResultType
.
NOT_CHECKED
);
res
.
setResult
Type
(
ResultType
.
NOT_CHECKED
);
}
co
.
getGmlObject
().
addGenericApplicationPropertyOfCityObject
(
res
);
CityObjectProperties
property
=
new
CityObjectProperties
();
property
.
setValidationResult
(
new
ValidationResultProperty
(
res
));
co
.
getGmlObject
().
addADEProperty
(
property
);
}
public
static
void
removeValidationResult
(
CityObject
co
)
{
for
(
ADEComponent
comp
:
co
.
getGmlObject
().
getGenericApplicationPropertyOfCityObject
())
{
if
(
comp
instanceof
ValidationResult
)
{
co
.
getGmlObject
().
getGenericApplicationPropertyOfCityObject
().
remove
(
comp
);
return
;
}
}
}
public
static
void
removeValidation
(
CityModel
cm
)
{
for
(
ADEComponent
comp
:
cm
.
getGenericApplicationPropertyOfCityModel
())
{
if
(
comp
instanceof
Validation
)
{
cm
.
getGenericApplicationPropertyOfCityModel
().
remove
(
comp
);
return
;
}
}
}
public
static
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
mapErrorIdToAdeId
(
ErrorId
key
)
{
public
static
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
mapErrorIdToAdeId
(
ErrorId
key
)
{
switch
(
key
.
getIdString
())
{
case
"GE_R_NOT_CLOSED"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_R_NOT_CLOSED
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_R_NOT_CLOSED
;
case
"GE_R_TOO_FEW_POINTS"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_R_TOO_FEW_POINTS
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_R_TOO_FEW_POINTS
;
case
"GE_R_CONSECUTIVE_POINTS_SAME"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_R_CONSECUTIVE_POINTS_SAME
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_R_CONSECUTIVE_POINTS_SAME
;
case
"GE_R_SELF_INTERSECTION"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_R_SELF_INTERSECTION
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_R_SELF_INTERSECTION
;
case
"GE_P_NON_PLANAR_POLYGON_NORMALS_DEVIATION"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_P_NON_PLANAR_POLYGON_NORMALS_DEVIATION
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_P_NON_PLANAR_POLYGON_NORMALS_DEVIATION
;
case
"GE_P_NON_PLANAR_POLYGON_DISTANCE_PLANE"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_P_NON_PLANAR_POLYGON_DISTANCE_PLANE
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_P_NON_PLANAR_POLYGON_DISTANCE_PLANE
;
case
"GE_P_INTERIOR_DISCONNECTED"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_P_INTERIOR_DISCONNECTED
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_P_INTERIOR_DISCONNECTED
;
case
"GE_P_INTERSECTING_RINGS"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_P_INTERSECTING_RINGS
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_P_INTERSECTING_RINGS
;
case
"GE_P_HOLE_OUTSIDE"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_P_HOLE_OUTSIDE
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_P_HOLE_OUTSIDE
;
case
"GE_P_ORIENTATION_RINGS_SAME"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_P_ORIENTATION_RINGS_SAME
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_P_ORIENTATION_RINGS_SAME
;
case
"GE_P_INNER_RINGS_NESTED"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_P_INNER_RINGS_NESTED
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_P_INNER_RINGS_NESTED
;
case
"GE_S_TOO_FEW_POLYGONS"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_S_TOO_FEW_POLYGONS
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_S_TOO_FEW_POLYGONS
;
case
"GE_S_NOT_CLOSED"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_S_NOT_CLOSED
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_S_NOT_CLOSED
;
case
"GE_S_NON_MANIFOLD_EDGE"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_S_NON_MANIFOLD_EDGE
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_S_NON_MANIFOLD_EDGE
;
case
"GE_S_POLYGON_WRONG_ORIENTATION"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_S_POLYGON_WRONG_ORIENTATION
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_S_POLYGON_WRONG_ORIENTATION
;
case
"GE_S_ALL_POLYGONS_WRONG_ORIENTATION"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_S_ALL_POLYGONS_WRONG_ORIENTATION
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_S_ALL_POLYGONS_WRONG_ORIENTATION
;
case
"GE_S_NON_MANIFOLD_VERTEX"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_S_NON_MANIFOLD_VERTEX
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_S_NON_MANIFOLD_VERTEX
;
case
"GE_S_SELF_INTERSECTION"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_S_SELF_INTERSECTION
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_S_SELF_INTERSECTION
;
case
"GE_S_MULTIPLE_CONNECTED_COMPONENTS"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
GE_S_MULTIPLE_CONNECTED_COMPONENTS
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
GE_S_MULTIPLE_CONNECTED_COMPONENTS
;
case
"SE_ATTRIBUTE_WRONG_VALUE"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
SE_ATTRIBUTE_WRONG_VALUE
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
SE_ATTRIBUTE_WRONG_VALUE
;
case
"SE_ATTRIBUTE_MISSING"
:
return
de
.
hft
.
stuttgart
.
quality
.
model
.
jaxb
.
ErrorId
.
SE_ATTRIBUTE_MISSING
;
return
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
.
SE_ATTRIBUTE_MISSING
;
default
:
return
null
;
// throw new IllegalStateException("Cannot map " + key + " to ADE Error Id");
}
}
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/writer/CityGMLWriterUtils.java
0 → 100644
View file @
3f3c1884
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.writer
;
import
java.io.File
;
import
java.time.ZonedDateTime
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.Set
;
import
java.util.UUID
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
org.citygml4j.core.model.CityGMLVersion
;
import
org.citygml4j.core.model.core.AbstractCityObjectProperty
;
import
org.citygml4j.core.model.core.AbstractFeatureProperty
;
import
org.citygml4j.core.model.core.CityModel
;
import
org.citygml4j.core.util.geometry.GeometryFactory
;
import
org.citygml4j.xml.CityGMLContext
;
import
org.citygml4j.xml.writer.CityGMLOutputFactory
;
import
org.citygml4j.xml.writer.CityGMLWriteException
;
import
org.citygml4j.xml.writer.CityGMLWriter
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
import
de.hft.stuttgart.citydoctor2.check.ErrorId
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParser
;
import
de.hft.stuttgart.citydoctor2.utils.Localization
;
import
de.hft.stuttgart.citydoctor2.utils.QualityADEUtils
;
import
de.hft.stuttgart.quality.QualityADEModule
;
import
de.hft.stuttgart.quality.model.properties.ErrorProperty
;
import
de.hft.stuttgart.quality.model.properties.FeatureStatisticsProperty
;
import
de.hft.stuttgart.quality.model.properties.StatisticsProperty
;
import
de.hft.stuttgart.quality.model.properties.ValidationPlanProperty
;
import
de.hft.stuttgart.quality.model.types.FeatureStatistics
;
import
de.hft.stuttgart.quality.model.types.Statistics
;
import
de.hft.stuttgart.quality.model.types.Validation
;
public
class
CityGMLWriterUtils
{
public
static
void
writeCityModel
(
String
file
,
CityDoctorModel
model
)
throws
CityDoctorWriteException
{
CityGMLContext
gmlContext
=
CityGmlParser
.
getContext
();
CityModel
cModel
=
model
.
getCityModel
();
CityGMLOutputFactory
factory
=
gmlContext
.
createCityGMLOutputFactory
(
CityGMLVersion
.
v2_0
);
try
(
CityGMLWriter
writer
=
factory
.
createCityGMLWriter
(
new
File
(
file
)))
{
writer
.
withIndent
(
" "
);
writer
.
withDefaultPrefixes
();
writer
.
withDefaultSchemaLocations
();
Validation
val
=
null
;
if
(
model
.
isValidated
())
{
writer
.
withPrefix
(
"qual"
,
QualityADEModule
.
NAMESPACE_URI
);
writer
.
withSchemaLocation
(
QualityADEModule
.
NAMESPACE_URI
,
QualityADEModule
.
NAMESPACE_URI
+
"/qualityAde.xsd"
);
// create new quality ade validation datastructures
val
=
createValidation
(
model
);
// add to city model
cModel
.
getFeatureMembers
().
add
(
new
AbstractFeatureProperty
(
val
));
}
GeometryFactory
gmlFactory
=
GeometryFactory
.
newInstance
();
storeCityObjects
(
model
.
getBuildings
(),
gmlFactory
,
model
,
cModel
,
val
);
storeCityObjects
(
model
.
getVegetation
(),
gmlFactory
,
model
,
cModel
,
val
);
storeCityObjects
(
model
.
getBridges
(),
gmlFactory
,
model
,
cModel
,
val
);
storeCityObjects
(
model
.
getLand
(),
gmlFactory
,
model
,
cModel
,
val
);
storeCityObjects
(
model
.
getTransportation
(),
gmlFactory
,
model
,
cModel
,
val
);
storeCityObjects
(
model
.
getWater
(),
gmlFactory
,
model
,
cModel
,
val
);
writer
.
write
(
cModel
);
}
catch
(
CityGMLWriteException
e
)
{
throw
new
CityDoctorWriteException
(
e
);
}
}
private
static
Validation
createValidation
(
CityDoctorModel
model
)
{
Validation
val
=
new
Validation
();
val
.
setId
(
"CD"
+
UUID
.
randomUUID
().
toString
());
val
.
setValidationDate
(
ZonedDateTime
.
now
());
val
.
setValidationSoftware
(
"CityDoctor "
+
Localization
.
getText
(
Localization
.
VERSION
));
Statistics
statistics
=
new
Statistics
();
Set
<
CheckError
>
errors
=
model
.
collectErrors
();
Map
<
ErrorId
,
AtomicInteger
>
errorCount
=
new
HashMap
<>();
for
(
CheckError
e
:
errors
)
{
errorCount
.
compute
(
e
.
getErrorId
(),
(
k
,
v
)
->
{
if
(
v
==
null
)
{
return
new
AtomicInteger
(
1
);
}
v
.
incrementAndGet
();
return
v
;
});
}
for
(
Entry
<
ErrorId
,
AtomicInteger
>
e
:
errorCount
.
entrySet
())
{
de
.
hft
.
stuttgart
.
quality
.
model
.
types
.
Error
stats
=
new
de
.
hft
.
stuttgart
.
quality
.
model
.
types
.
Error
();
stats
.
setOccurrences
(
e
.
getValue
().
get
());
de
.
hft
.
stuttgart
.
quality
.
model
.
enums
.
ErrorId
adeId
=
QualityADEUtils
.
mapErrorIdToAdeId
(
e
.
getKey
());
if
(
adeId
==
null
)
{
// error that is not part of the ade standard
continue
;
}
stats
.
setName
(
adeId
);
statistics
.
getErrors
().
add
(
new
ErrorProperty
(
stats
));
}
statistics
.
setNumErrorBuildings
(
new
FeatureStatisticsProperty
(
countValidatedCityObjects
(
model
.
getBuildings
())));
statistics
.
setNumErrorBridgeObjects
(
new
FeatureStatisticsProperty
(
countValidatedCityObjects
(
model
.
getBridges
())));
statistics
.
setNumErrorLandObjects
(
new
FeatureStatisticsProperty
(
countValidatedCityObjects
(
model
.
getLand
())));
statistics
.
setNumErrorTransportation
(
new
FeatureStatisticsProperty
(
countValidatedCityObjects
(
model
.
getTransportation
())));
statistics
.
setNumErrorVegetation
(
new
FeatureStatisticsProperty
(
countValidatedCityObjects
(
model
.
getVegetation
())));
statistics
.
setNumErrorWaterObjects
(
new
FeatureStatisticsProperty
(
countValidatedCityObjects
(
model
.
getWater
())));
val
.
setStatistics
(
new
StatisticsProperty
(
statistics
));
val
.
setValidationPlan
(
new
ValidationPlanProperty
(
model
.
getValidationPlan
()));
return
val
;
}
private
static
FeatureStatistics
countValidatedCityObjects
(
List
<?
extends
CityObject
>
cos
)
{
int
numChecked
=
0
;
int
numError
=
0
;
for
(
CityObject
co
:
cos
)
{
if
(
co
.
isValidated
())
{
numChecked
++;
if
(
co
.
containsAnyError
())
{
numError
++;
}
}
}
return
new
FeatureStatistics
(
numChecked
,
numError
);
}
private
static
void
storeCityObjects
(
List
<?
extends
CityObject
>
cos
,
GeometryFactory
gmlFactory
,
CityDoctorModel
model
,
CityModel
cModel
,
Validation
val
)
{
for
(
CityObject
co
:
cos
)
{
if
(
model
.
isValidated
()
&&
val
!=
null
)
{
QualityADEUtils
.
writeQualityAde
(
co
,
val
);
}
co
.
reCreateGeometries
(
gmlFactory
,
model
.
getParserConfig
());
cModel
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
co
.
getGmlObject
()));
}
}
}
CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization_de.properties
View file @
3f3c1884
...
...
@@ -97,7 +97,7 @@ WriteReportDialog.xAxisLabel=Fehler
WriteReportDialog.yAxisLabel
=
Anzahl
Unit.Radian
=
Radiant
Unit.Degree
=
Grad
FeatureMapper.polygonUnreferenced
=
Polygon {} ist referenziert wurde aber nicht
in
gefunden
FeatureMapper.polygonUnreferenced
=
Polygon {} ist referenziert wurde aber nicht gefunden
GeometryMapper.emptyPolygon
=
Polygon ohne externen Ring gefunden, ignoriere
CityGmlParser.parsedObjects
=
Modell mit {} Objekten gelesen
CityGmlParser.chunkReadFailed
=
Konnte Datei nicht in St
\u
00fccken lesen, versuche komplett zu lesen
...
...
CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/check/error/AllPolygonsWrongOrientationErrorTest.java
View file @
3f3c1884
...
...
@@ -19,19 +19,21 @@
package
de.hft.stuttgart.citydoctor2.check.error
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.util.
Optional
;
import
java.util.
List
;
import
org.junit.Test
;
import
de.hft.stuttgart.citydoctor2.check.QualityAdeErrorVisitor
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.GmlId
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.quality.model.AllPolygonsWrongOrientation
;
import
de.hft.stuttgart.quality.model.ValidationError
;
import
de.hft.stuttgart.quality.model.properties.AbstractErrorProperty
;
import
de.hft.stuttgart.quality.model.types.AbstractError
;
import
de.hft.stuttgart.quality.model.types.AllPolygonsOrientedWrongError
;
import
de.hft.stuttgart.quality.model.types.ValidationResult
;
public
class
AllPolygonsWrongOrientationErrorTest
{
...
...
@@ -41,14 +43,19 @@ public class AllPolygonsWrongOrientationErrorTest {
GmlId
gmlId
=
new
GmlId
(
"testId"
);
geom
.
setGmlId
(
gmlId
);
AllPolygonsWrongOrientationError
err
=
new
AllPolygonsWrongOrientationError
(
geom
);
Optional
<
ValidationError
>
ade
=
err
.
convertToQualityAdeDatastructure
();
assertNotNull
(
ade
);
assertTrue
(
ade
.
isPresent
());
ValidationError
validationError
=
ade
.
get
();
assertTrue
(
validationError
instanceof
AllPolygonsWrongOrientation
);
AllPolygonsWrongOrientation
adeErr
=
(
AllPolygonsWrongOrientation
)
validationError
;
ValidationResult
result
=
new
ValidationResult
();
QualityAdeErrorVisitor
visitor
=
new
QualityAdeErrorVisitor
(
result
);
err
.
accept
(
visitor
);
List
<
AbstractErrorProperty
>
errors
=
result
.
getErrors
();
assertEquals
(
1
,
errors
.
size
());
AbstractError
validationError
=
errors
.
get
(
0
).
getObject
();
assertTrue
(
validationError
instanceof
AllPolygonsOrientedWrongError
);
AllPolygonsOrientedWrongError
adeErr
=
(
AllPolygonsOrientedWrongError
)
validationError
;
String
geometryId
=
adeErr
.
getGeometryId
();
assertEquals
(
gmlId
.
getGmlString
(),
geometryId
);
}
}
Prev
1
2
3
4
5
6
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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