Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CityDoctor
CityDoctor2
Commits
02de0a22
Commit
02de0a22
authored
Oct 30, 2024
by
Riegel
Browse files
Reformat code
parent
ad3589e8
Pipeline
#10297
passed with stage
in 1 minute and 5 seconds
Changes
61
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CompositePolygon.java
View file @
02de0a22
...
...
@@ -11,12 +11,18 @@ import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import
de.hft.stuttgart.citydoctor2.utils.Copyable
;
import
java.io.Serial
;
import
java.util.*
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
/**
* Dataholding class for parsing and resolving of CompositeSurfaces.
* Pseudo-abstract polygon class for parsing and resolving of CompositeSurfaces and references to them.
* <p>CompositePolygons have no exterior or interior LinearRings themselves and need to be filtered out from
* the polygons of a CityObject geometry before further processing steps.
*
* @author Riegel
*/
public
final
class
CompositePolygon
extends
ConcretePolygon
{
public
final
class
CompositePolygon
extends
ConcretePolygon
{
@Serial
private
static
final
long
serialVersionUID
=
-
1867197873443341287L
;
...
...
@@ -32,7 +38,8 @@ public final class CompositePolygon extends ConcretePolygon{
}
@Override
public
void
accept
(
Check
c
){}
public
void
accept
(
Check
c
)
{
}
@Override
public
Class
<?
extends
Checkable
>
getCheckClass
()
{
...
...
@@ -40,24 +47,25 @@ public final class CompositePolygon extends ConcretePolygon{
}
@Override
public
boolean
containsAnyError
(){
public
boolean
containsAnyError
()
{
return
false
;
}
@Override
public
void
collectContainedErrors
(
List
<
CheckError
>
errors
)
{}
public
void
collectContainedErrors
(
List
<
CheckError
>
errors
)
{
}
@Override
public
void
clearAllContainedCheckResults
()
{
}
public
void
addCompositeMember
(
ConcretePolygon
p
){
public
void
addCompositeMember
(
ConcretePolygon
p
)
{
compositeMembers
.
add
(
p
);
p
.
setPartOfComposite
(
this
);
}
public
List
<
ConcretePolygon
>
getCompositeMembers
(){
public
List
<
ConcretePolygon
>
getCompositeMembers
()
{
return
compositeMembers
;
}
...
...
@@ -67,7 +75,6 @@ public final class CompositePolygon extends ConcretePolygon{
}
@Override
public
Vector3d
calculateNormal
()
{
return
compositeMembers
.
get
(
0
).
calculateNormal
();
...
...
@@ -76,7 +83,7 @@ public final class CompositePolygon extends ConcretePolygon{
@Override
public
TesselatedPolygon
tesselate
()
{
List
<
Triangle3d
>
tessPolys
=
new
ArrayList
<>();
return
new
TesselatedPolygon
(
tessPolys
,
this
);
return
new
TesselatedPolygon
(
tessPolys
,
this
);
}
@Override
...
...
@@ -190,7 +197,6 @@ public final class CompositePolygon extends ConcretePolygon{
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ConcretePolygon.java
View file @
02de0a22
...
...
@@ -53,9 +53,7 @@ public class ConcretePolygon extends Polygon {
private
Geometry
parent
;
private
LinkedPolygon
linkedFromPolygon
;
public
ConcretePolygon
()
{
// TODO Auto-generated constructor stub
}
public
ConcretePolygon
()
{}
/*
* (non-Javadoc)
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Edge.java
View file @
02de0a22
/*-
* 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
...
...
@@ -18,202 +18,201 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
de.hft.stuttgart.citydoctor2.utils.CopyHandler
;
import
de.hft.stuttgart.citydoctor2.utils.Copyable
;
import
java.io.Serial
;
import
java.io.Serializable
;
import
java.util.ArrayList
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.utils.CopyHandler
;
import
de.hft.stuttgart.citydoctor2.utils.Copyable
;
/**
* Representing an edge between two consecutive points of a linear ring
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
class
Edge
implements
Serializable
,
Copyable
{
@Serial
private
static
final
long
serialVersionUID
=
-
504694863498128296L
;
private
final
List
<
Polygon
>
adjacentPolygons
=
new
ArrayList
<>(
2
);
private
final
List
<
LinearRing
>
adjacentRings
=
new
ArrayList
<>(
2
);
private
Vertex
from
;
private
Vertex
to
;
// start with 1 for a new edge
private
int
numberOfHalfEdges
=
1
;
private
int
numberOfOppositeHalfEdges
;
public
Edge
(
Vertex
from
,
Vertex
to
)
{
this
.
from
=
from
;
this
.
to
=
to
;
}
private
Edge
()
{
}
public
Vertex
getFrom
()
{
return
from
;
}
public
Vertex
getTo
()
{
return
to
;
}
public
void
addHalfEdge
(
Vertex
v0
,
Vertex
v1
)
{
if
(
v0
==
null
||
v1
==
null
)
{
return
;
}
if
(
isPointOfEdge
(
v0
,
from
)
&&
isPointOfEdge
(
v1
,
to
))
{
numberOfHalfEdges
++;
return
;
}
if
(
isPointOfEdge
(
v1
,
from
)
&&
isPointOfEdge
(
v0
,
to
))
{
numberOfOppositeHalfEdges
++;
return
;
}
throw
new
IllegalStateException
(
"The given vertices do not form this edge\n v0="
+
v0
+
", v1="
+
v1
+
", edge"
+
this
);
}
private
boolean
isPointOfEdge
(
Vertex
v0
,
Vertex
edgePoint
)
{
@Serial
private
static
final
long
serialVersionUID
=
-
504694863498128296L
;
private
final
List
<
Polygon
>
adjacentPolygons
=
new
ArrayList
<>(
2
);
private
final
List
<
LinearRing
>
adjacentRings
=
new
ArrayList
<>(
2
);
private
Vertex
from
;
private
Vertex
to
;
// start with 1 for a new edge
private
int
numberOfHalfEdges
=
1
;
private
int
numberOfOppositeHalfEdges
;
public
Edge
(
Vertex
from
,
Vertex
to
)
{
this
.
from
=
from
;
this
.
to
=
to
;
}
private
Edge
()
{
}
public
Vertex
getFrom
()
{
return
from
;
}
public
Vertex
getTo
()
{
return
to
;
}
public
void
addHalfEdge
(
Vertex
v0
,
Vertex
v1
)
{
if
(
v0
==
null
||
v1
==
null
)
{
return
;
}
if
(
isPointOfEdge
(
v0
,
from
)
&&
isPointOfEdge
(
v1
,
to
))
{
numberOfHalfEdges
++;
return
;
}
if
(
isPointOfEdge
(
v1
,
from
)
&&
isPointOfEdge
(
v0
,
to
))
{
numberOfOppositeHalfEdges
++;
return
;
}
throw
new
IllegalStateException
(
"The given vertices do not form this edge\n v0="
+
v0
+
", v1="
+
v1
+
", edge"
+
this
);
}
private
boolean
isPointOfEdge
(
Vertex
v0
,
Vertex
edgePoint
)
{
return
v0
.
equals
(
edgePoint
);
}
public
boolean
formedByIgnoreDirection
(
Vertex
v1
,
Vertex
v2
)
{
return
(
v1
==
from
&&
v2
==
to
)
||
(
v1
==
to
&&
v2
==
from
);
}
public
boolean
equalsIgnoreDirection
(
Edge
other
)
{
return
(
other
.
from
.
equals
(
from
)
&&
other
.
to
.
equals
(
to
))
||
(
other
.
from
.
equals
(
to
)
&&
other
.
to
.
equals
(
from
));
}
public
int
getNumberOfHalfEdges
()
{
return
numberOfHalfEdges
;
}
public
int
getNumberOppositeHalfEdges
()
{
return
numberOfOppositeHalfEdges
;
}
public
int
getNumberOfAllHalfEdges
()
{
return
numberOfHalfEdges
+
numberOfOppositeHalfEdges
;
}
public
List
<
Polygon
>
getAdjacentPolygons
()
{
return
adjacentPolygons
;
}
public
List
<
LinearRing
>
getAdjacentRings
()
{
return
adjacentRings
;
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
((
from
==
null
)
?
0
:
from
.
hashCode
());
result
=
prime
*
result
+
((
to
==
null
)
?
0
:
to
.
hashCode
());
return
result
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
Edge
other
=
(
Edge
)
obj
;
if
(
from
==
null
)
{
if
(
other
.
from
!=
null
)
{
return
false
;
}
}
else
if
(!
from
.
equals
(
other
.
from
))
{
return
false
;
}
if
(
to
==
null
)
{
public
boolean
formedByIgnoreDirection
(
Vertex
v1
,
Vertex
v2
)
{
return
(
v1
==
from
&&
v2
==
to
)
||
(
v1
==
to
&&
v2
==
from
);
}
public
boolean
equalsIgnoreDirection
(
Edge
other
)
{
return
(
other
.
from
.
equals
(
from
)
&&
other
.
to
.
equals
(
to
))
||
(
other
.
from
.
equals
(
to
)
&&
other
.
to
.
equals
(
from
));
}
public
int
getNumberOfHalfEdges
()
{
return
numberOfHalfEdges
;
}
public
int
getNumberOppositeHalfEdges
()
{
return
numberOfOppositeHalfEdges
;
}
public
int
getNumberOfAllHalfEdges
()
{
return
numberOfHalfEdges
+
numberOfOppositeHalfEdges
;
}
public
List
<
Polygon
>
getAdjacentPolygons
()
{
return
adjacentPolygons
;
}
public
List
<
LinearRing
>
getAdjacentRings
()
{
return
adjacentRings
;
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
((
from
==
null
)
?
0
:
from
.
hashCode
());
result
=
prime
*
result
+
((
to
==
null
)
?
0
:
to
.
hashCode
());
return
result
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
Edge
other
=
(
Edge
)
obj
;
if
(
from
==
null
)
{
if
(
other
.
from
!=
null
)
{
return
false
;
}
}
else
if
(!
from
.
equals
(
other
.
from
))
{
return
false
;
}
if
(
to
==
null
)
{
return
other
.
to
==
null
;
}
else
return
to
.
equals
(
other
.
to
);
}
public
void
addAdjacentPolygon
(
Polygon
p
)
{
adjacentPolygons
.
add
(
p
);
}
public
void
addAdjacentRing
(
LinearRing
lr
)
{
adjacentRings
.
add
(
lr
);
}
@Override
public
String
toString
()
{
return
"Edge [from="
+
from
+
", to="
+
to
+
"]"
;
}
public
boolean
contains
(
Vertex
v
)
{
return
v
==
from
||
v
==
to
;
}
public
Vertex
getConnectionPoint
(
Edge
e
)
{
if
(
from
==
e
.
getTo
()
||
from
==
e
.
getFrom
())
{
return
from
;
}
if
(
to
==
e
.
getTo
()
||
to
==
e
.
getFrom
())
{
return
to
;
}
return
null
;
}
/**
* finds the point on the other end of the edge if the given vertex is one of
* the end points.
*
* @param c the given vertex
* @return the opposite vertex or null if the given vertex is not an end point.
*/
public
Vertex
getOppositeVertex
(
Vertex
c
)
{
if
(
c
==
from
)
{
return
to
;
}
if
(
c
==
to
)
{
return
from
;
}
return
null
;
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
handler
.
addInstance
(
from
);
handler
.
addInstance
(
to
);
handler
.
addInstance
(
adjacentPolygons
);
handler
.
addInstance
(
adjacentRings
);
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
Edge
();
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
Edge
originalEdge
=
(
Edge
)
original
;
from
=
handler
.
getCopyInstance
(
originalEdge
.
from
);
to
=
handler
.
getCopyInstance
(
originalEdge
.
to
);
numberOfHalfEdges
=
originalEdge
.
numberOfHalfEdges
;
numberOfOppositeHalfEdges
=
originalEdge
.
numberOfOppositeHalfEdges
;
for
(
Polygon
originalPoly
:
originalEdge
.
adjacentPolygons
)
{
adjacentPolygons
.
add
(
handler
.
getCopyInstance
(
originalPoly
));
}
for
(
LinearRing
originalRing
:
originalEdge
.
adjacentRings
)
{
adjacentRings
.
add
(
handler
.
getCopyInstance
(
originalRing
));
}
}
}
else
return
to
.
equals
(
other
.
to
);
}
public
void
addAdjacentPolygon
(
Polygon
p
)
{
adjacentPolygons
.
add
(
p
);
}
public
void
addAdjacentRing
(
LinearRing
lr
)
{
adjacentRings
.
add
(
lr
);
}
@Override
public
String
toString
()
{
return
"Edge [from="
+
from
+
", to="
+
to
+
"]"
;
}
public
boolean
contains
(
Vertex
v
)
{
return
v
==
from
||
v
==
to
;
}
public
Vertex
getConnectionPoint
(
Edge
e
)
{
if
(
from
==
e
.
getTo
()
||
from
==
e
.
getFrom
())
{
return
from
;
}
if
(
to
==
e
.
getTo
()
||
to
==
e
.
getFrom
())
{
return
to
;
}
return
null
;
}
/**
* finds the point on the other end of the edge if the given vertex is one of
* the end points.
*
* @param c the given vertex
* @return the opposite vertex or null if the given vertex is not an end point.
*/
public
Vertex
getOppositeVertex
(
Vertex
c
)
{
if
(
c
==
from
)
{
return
to
;
}
if
(
c
==
to
)
{
return
from
;
}
return
null
;
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
handler
.
addInstance
(
from
);
handler
.
addInstance
(
to
);
handler
.
addInstance
(
adjacentPolygons
);
handler
.
addInstance
(
adjacentRings
);
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
Edge
();
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
Edge
originalEdge
=
(
Edge
)
original
;
from
=
handler
.
getCopyInstance
(
originalEdge
.
from
);
to
=
handler
.
getCopyInstance
(
originalEdge
.
to
);
numberOfHalfEdges
=
originalEdge
.
numberOfHalfEdges
;
numberOfOppositeHalfEdges
=
originalEdge
.
numberOfOppositeHalfEdges
;
for
(
Polygon
originalPoly
:
originalEdge
.
adjacentPolygons
)
{
adjacentPolygons
.
add
(
handler
.
getCopyInstance
(
originalPoly
));
}
for
(
LinearRing
originalRing
:
originalEdge
.
adjacentRings
)
{
adjacentRings
.
add
(
handler
.
getCopyInstance
(
originalRing
));
}
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/FeatureType.java
View file @
02de0a22
/*-
* 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
...
...
@@ -20,13 +20,12 @@ package de.hft.stuttgart.citydoctor2.datastructure;
/**
* Possible feature types in CityGML
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
enum
FeatureType
{
BUILDING
,
TRANSPORTATION
,
VEGETATION
,
BRIDGE
,
LAND
,
WATER
,
BOUNDARY_SURFACE
,
INSTALLATION
,
OPENING
,
BUILDING_PART
,
BUILDING_SUBDIVISION
,
BRIDGE_CONSTRUCTION_ELEMENT
,
BRIDGE_INSTALLATION
,
ROOM
,
FURNITURE
,
CITY_FURNITURE
,
GENERIC_CITY_OBJECT
,
TUNNEL
,
TUNNEL_PART
BUILDING
,
TRANSPORTATION
,
VEGETATION
,
BRIDGE
,
LAND
,
WATER
,
BOUNDARY_SURFACE
,
INSTALLATION
,
OPENING
,
BUILDING_PART
,
BUILDING_SUBDIVISION
,
BRIDGE_CONSTRUCTION_ELEMENT
,
BRIDGE_INSTALLATION
,
ROOM
,
FURNITURE
,
CITY_FURNITURE
,
GENERIC_CITY_OBJECT
,
TUNNEL
,
TUNNEL_PART
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericCityObject.java
View file @
02de0a22
...
...
@@ -24,7 +24,7 @@ import java.util.List;
/**
*
*/
public
class
GenericCityObject
extends
CityObject
{
public
class
GenericCityObject
extends
CityObject
{
@Serial
private
static
final
long
serialVersionUID
=
5886527664552294353L
;
...
...
@@ -49,7 +49,7 @@ public class GenericCityObject extends CityObject{
@Override
public
void
reCreateGeometries
(
GeometryFactory
factory
,
ParserConfiguration
config
)
{
for
(
Geometry
geom
:
getGeometries
())
{
if
(
geom
instanceof
ImplicitGeometryHolder
){
if
(
geom
instanceof
ImplicitGeometryHolder
)
{
continue
;
}
if
(
geom
.
getType
()
==
GeometryType
.
MULTI_SURFACE
)
{
...
...
@@ -213,7 +213,7 @@ public class GenericCityObject extends CityObject{
}
}
public
void
setGmlObject
(
org
.
citygml4j
.
core
.
model
.
generics
.
GenericOccupiedSpace
gos
){
public
void
setGmlObject
(
org
.
citygml4j
.
core
.
model
.
generics
.
GenericOccupiedSpace
gos
)
{
this
.
cgmlGos
=
gos
;
}
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Geometry.java
View file @
02de0a22
/*-
* 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
...
...
@@ -18,16 +18,6 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
java.io.Serial
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.Random
;
import
java.util.Set
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
import
de.hft.stuttgart.citydoctor2.check.CheckId
;
...
...
@@ -39,420 +29,423 @@ import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import
de.hft.stuttgart.citydoctor2.utils.Copyable
;
import
de.hft.stuttgart.citydoctor2.utils.SerializablePair
;
import
java.io.Serial
;
import
java.util.*
;
import
java.util.Map.Entry
;
/**
* Representation of a geometry containing the polygons and edges
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
class
Geometry
extends
GmlElement
{
private
static
final
String
FAILED_REMOVING_POLYGON
=
"Removing polygon %s but polygon is not in geometry"
;
@Serial
private
static
final
long
serialVersionUID
=
2539031030917731575L
;
private
static
final
Random
r
=
new
Random
();
private
GeometryType
type
;
private
final
Lod
lod
;
private
CityObject
parent
;
private
final
List
<
Polygon
>
polygons
=
new
ArrayList
<>(
2
);
private
List
<
Edge
>
edges
;
private
Map
<
SerializablePair
<
Vertex
,
Vertex
>,
Edge
>
edgeMap
;
private
List
<
Vertex
>
vertices
;
public
Geometry
(
GeometryType
type
,
Lod
lod
)
{
this
.
lod
=
lod
;
this
.
type
=
type
;
}
void
setParent
(
CityObject
parent
)
{
this
.
parent
=
parent
;
}
public
CityObject
getParent
()
{
return
parent
;
}
public
void
setType
(
GeometryType
type
)
{
this
.
type
=
type
;
}
public
GeometryType
getType
()
{
return
type
;
}
public
Lod
getLod
()
{
return
lod
;
}
public
List
<
Polygon
>
getPolygons
()
{
return
polygons
;
}
public
void
addPolygon
(
Polygon
cdPoly
)
{
polygons
.
add
(
cdPoly
);
cdPoly
.
setParent
(
this
);
// set part of boundary surface or building installation or both
if
(
parent
instanceof
BoundarySurface
bs
)
{
cdPoly
.
setPartOfSurface
(
bs
);
if
(
bs
.
getParent
()
instanceof
Installation
bi
)
{
cdPoly
.
setPartOfInstallation
(
bi
);
}
}
else
if
(
parent
instanceof
Installation
bi
)
{
cdPoly
.
setPartOfInstallation
(
bi
);
}
}
public
void
updateEdges
()
{
edges
=
new
ArrayList
<>();
edgeMap
=
new
HashMap
<>();
Map
<
Edge
,
Edge
>
duplicacyMap
=
new
HashMap
<>();
for
(
Polygon
p
:
polygons
)
{
LinearRing
extRing
=
p
.
getExteriorRing
();
createEdgesFromRing
(
duplicacyMap
,
p
,
extRing
);
for
(
LinearRing
inner
:
p
.
getInnerRings
())
{
createEdgesFromRing
(
duplicacyMap
,
p
,
inner
);
}
}
}
void
anonymize
()
{
setGmlId
(
GmlId
.
generateId
());
for
(
Polygon
p
:
polygons
)
{
p
.
anonymize
();
}
double
minX
=
Double
.
MAX_VALUE
;
double
minY
=
Double
.
MAX_VALUE
;
double
minZ
=
Double
.
MAX_VALUE
;
for
(
Vertex
v
:
vertices
)
{
if
(
v
.
getX
()
<
minX
)
{
minX
=
v
.
getX
();
}
if
(
v
.
getY
()
<
minY
)
{
minY
=
v
.
getY
();
}
if
(
v
.
getZ
()
<
minZ
)
{
minZ
=
v
.
getZ
();
}
}
double
varX
=
r
.
nextDouble
()
*
10
;
double
varY
=
r
.
nextDouble
()
*
10
;
double
varZ
=
r
.
nextDouble
()
*
10
;
for
(
Vertex
v
:
vertices
)
{
v
.
setX
(
v
.
getX
()
-
minX
+
varX
);
v
.
setY
(
v
.
getY
()
-
minY
+
varY
);
v
.
setZ
(
v
.
getZ
()
-
minZ
+
varZ
);
}
}
private
void
createEdgesFromRing
(
Map
<
Edge
,
Edge
>
duplicacyMap
,
Polygon
p
,
LinearRing
ring
)
{
if
(
ring
==
null
)
{
return
;
}
// only go to size -1 as ring should be closed
for
(
int
i
=
0
;
i
<
ring
.
getVertices
().
size
()
-
1
;
i
++)
{
Vertex
v0
=
ring
.
getVertices
().
get
(
i
);
Vertex
v1
=
ring
.
getVertices
().
get
(
i
+
1
);
Edge
tempEdge
=
new
Edge
(
v0
,
v1
);
Edge
e
=
duplicacyMap
.
get
(
tempEdge
);
if
(
e
==
null
)
{
// no duplicate found, enter edges
Edge
oppositeEdge
=
new
Edge
(
v1
,
v0
);
duplicacyMap
.
put
(
tempEdge
,
tempEdge
);
duplicacyMap
.
put
(
oppositeEdge
,
tempEdge
);
e
=
tempEdge
;
edges
.
add
(
e
);
edgeMap
.
put
(
new
SerializablePair
<>(
v0
,
v1
),
e
);
edgeMap
.
put
(
new
SerializablePair
<>(
v1
,
v0
),
e
);
}
else
{
e
.
addHalfEdge
(
v0
,
v1
);
}
e
.
addAdjacentPolygon
(
p
);
e
.
addAdjacentRing
(
ring
);
}
}
public
Vector3d
getCenter
()
{
return
calculateBoundingBox
().
getCenter
();
}
/**
* This will calculate two points where every other point in the geometry is
* between those two. If the geometry does not contain points or is null, an
* empty array is returned. This is considered an axis aligned bounding box.
* Only the exterior rings of the polygons is used as inner rings should be
* within the exterior or they are faulty.
*
* @return an array of two points. The first contains the lowest coordinates,
*
the second contains the highest coordinates
*/
public
BoundingBox
calculateBoundingBox
()
{
return
BoundingBoxCalculator
.
calculateBoundingBox
(
polygons
);
}
public
double
calculateVolume
()
{
double
sum
=
0
;
Vector3d
center
=
calculateBoundingBox
().
getCenter
();
for
(
Polygon
p
:
polygons
)
{
TesselatedPolygon
tesselatedPolygon
=
p
.
tesselate
();
for
(
Triangle3d
t
:
tesselatedPolygon
.
getTriangles
())
{
Vector3d
p1
=
t
.
getP1
().
minus
(
center
);
Vector3d
p2
=
t
.
getP2
().
minus
(
center
);
Vector3d
p3
=
t
.
getP3
().
minus
(
center
);
sum
+=
det
(
p1
.
getCoordinates
(),
p2
.
getCoordinates
(),
p3
.
getCoordinates
());
}
}
return
sum
/
6
d
;
}
private
double
det
(
double
[]
a
,
double
[]
b
,
double
[]
c
)
{
return
-
c
[
0
]
*
b
[
1
]
*
a
[
2
]
+
b
[
0
]
*
c
[
1
]
*
a
[
2
]
+
c
[
0
]
*
a
[
1
]
*
b
[
2
]
-
a
[
0
]
*
c
[
1
]
*
b
[
2
]
-
b
[
0
]
*
a
[
1
]
*
c
[
2
]
+
a
[
0
]
*
b
[
1
]
*
c
[
2
];
}
@Override
public
boolean
containsError
(
CheckId
checkIdentifier
)
{
boolean
hasError
=
super
.
containsError
(
checkIdentifier
);
if
(
hasError
)
{
return
true
;
}
for
(
Polygon
p
:
polygons
)
{
if
(
p
.
containsError
(
checkIdentifier
))
{
return
true
;
}
}
return
false
;
}
@Override
public
void
clearAllContainedCheckResults
()
{
super
.
clearCheckResults
();
for
(
Polygon
p
:
polygons
)
{
p
.
clearAllContainedCheckResults
();
}
}
@Override
public
void
collectContainedErrors
(
List
<
CheckError
>
errors
)
{
super
.
collectContainedErrors
(
errors
);
for
(
Polygon
p
:
polygons
)
{
p
.
collectContainedErrors
(
errors
);
}
}
@Override
public
boolean
containsAnyError
()
{
boolean
hasError
=
super
.
containsAnyError
();
if
(
hasError
)
{
return
true
;
}
for
(
Polygon
p
:
polygons
)
{
if
(
p
.
containsAnyError
())
{
return
true
;
}
}
return
false
;
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
for
(
Polygon
p
:
polygons
)
{
p
.
accept
(
c
);
}
}
@Override
public
String
toString
()
{
return
"Geometry [type="
+
type
+
", lod="
+
lod
+
", id="
+
getGmlId
()
+
"]"
;
}
public
List
<
Vertex
>
getVertices
()
{
return
vertices
;
}
public
List
<
Edge
>
getEdges
()
{
return
edges
;
}
public
List
<
Edge
>
getEdgesAdjacentTo
(
Vertex
v
)
{
List
<
Edge
>
adjacentEdges
=
new
ArrayList
<>();
for
(
Edge
e
:
edges
)
{
if
(
e
.
getFrom
()
==
v
||
e
.
getTo
()
==
v
)
{
adjacentEdges
.
add
(
e
);
}
}
return
adjacentEdges
;
}
public
Edge
getEdge
(
Vertex
v1
,
Vertex
v2
)
{
return
edgeMap
.
get
(
new
SerializablePair
<>(
v1
,
v2
));
}
public
void
updateEdgesAndVertices
()
{
updateVertices
();
updateEdges
();
}
public
void
updateVertices
()
{
Set
<
Vertex
>
vertexSet
=
new
HashSet
<>();
for
(
Polygon
p
:
getPolygons
())
{
updateRing
(
vertexSet
,
p
.
getExteriorRing
());
for
(
LinearRing
inner
:
p
.
getInnerRings
())
{
updateRing
(
vertexSet
,
inner
);
}
}
vertices
=
new
ArrayList
<>(
vertexSet
);
}
private
void
updateRing
(
Set
<
Vertex
>
vertexSet
,
LinearRing
ring
)
{
if
(
ring
==
null
)
{
return
;
}
for
(
Vertex
v
:
ring
.
getVertices
())
{
if
(
vertexSet
.
add
(
v
))
{
// new vertex, clear adjacent rings in case new rings have been added
v
.
clearAdjacentRings
(
this
);
}
// add ring to adjacent rings of vertex
v
.
addAdjacentRing
(
ring
,
this
);
}
}
void
removePolygon
(
Polygon
p
)
{
p
.
removeRings
();
if
(!
polygons
.
remove
(
p
))
{
throw
new
IllegalStateException
(
String
.
format
(
FAILED_REMOVING_POLYGON
,
p
));
}
if
(
p
.
isLink
())
{
Polygon
original
=
p
.
getOriginal
();
if
(!
original
.
getParent
().
polygons
.
remove
(
original
))
{
throw
new
IllegalStateException
(
String
.
format
(
FAILED_REMOVING_POLYGON
,
p
));
}
}
else
if
(
p
.
isLinkedTo
())
{
Polygon
link
=
p
.
getLinkedFromPolygon
();
if
(!
link
.
getParent
().
polygons
.
remove
(
link
))
{
throw
new
IllegalStateException
(
String
.
format
(
FAILED_REMOVING_POLYGON
,
p
));
}
}
}
public
void
replacePolygon
(
Polygon
p
,
ConcretePolygon
...
polygons
)
{
removePolygon
(
p
);
if
(
p
.
isLink
())
{
Geometry
geom2
=
p
.
getOriginal
().
getParent
();
for
(
ConcretePolygon
newPoly
:
polygons
)
{
geom2
.
addPolygon
(
newPoly
);
addPolygon
(
new
LinkedPolygon
(
newPoly
,
this
));
}
}
else
if
(
p
.
isLinkedTo
())
{
Geometry
geom2
=
p
.
getLinkedFromPolygon
().
getParent
();
for
(
ConcretePolygon
newPoly
:
polygons
)
{
addPolygon
(
newPoly
);
geom2
.
addPolygon
(
new
LinkedPolygon
(
newPoly
,
geom2
));
}
}
else
{
for
(
Polygon
newPoly
:
polygons
)
{
addPolygon
(
newPoly
);
}
}
}
public
List
<
Edge
>
getEdgesAdjacentTo
(
Polygon
p
)
{
List
<
Edge
>
list
=
new
ArrayList
<>();
for
(
Edge
e
:
edges
)
{
if
(
e
.
getAdjacentPolygons
().
contains
(
p
))
{
list
.
add
(
e
);
}
}
return
list
;
}
public
boolean
containsPolygon
(
Polygon
other
)
{
for
(
Polygon
p
:
polygons
)
{
if
(
p
.
getGmlId
().
equals
(
other
.
getGmlId
()))
{
return
true
;
}
}
return
false
;
}
@Override
public
void
prepareForChecking
()
{
updateEdgesAndVertices
();
}
@Override
public
void
clearMetaInformation
()
{
if
(
vertices
!=
null
)
{
for
(
Vertex
v
:
vertices
)
{
v
.
clearAdjacentRings
();
}
vertices
=
null
;
}
edges
=
null
;
edgeMap
=
null
;
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
handler
.
addInstance
(
parent
);
handler
.
addInstance
(
polygons
);
handler
.
addInstance
(
edges
);
handler
.
addInstance
(
vertices
);
if
(
edgeMap
!=
null
)
{
for
(
Entry
<
SerializablePair
<
Vertex
,
Vertex
>,
Edge
>
e
:
edgeMap
.
entrySet
())
{
handler
.
addInstance
(
e
.
getKey
().
getValue0
());
handler
.
addInstance
(
e
.
getKey
().
getValue1
());
handler
.
addInstance
(
e
.
getValue
());
}
}
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
Geometry
(
type
,
lod
);
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
super
.
fillValues
(
original
,
handler
);
Geometry
originalGeometry
=
(
Geometry
)
original
;
for
(
Polygon
originalPoly
:
originalGeometry
.
polygons
)
{
polygons
.
add
(
handler
.
getCopyInstance
(
originalPoly
));
}
if
(
originalGeometry
.
edges
!=
null
)
{
edges
=
new
ArrayList
<>(
originalGeometry
.
edges
.
size
());
for
(
Edge
originalEdge
:
originalGeometry
.
edges
)
{
edges
.
add
(
handler
.
getCopyInstance
(
originalEdge
));
}
}
if
(
originalGeometry
.
edgeMap
!=
null
)
{
edgeMap
=
new
HashMap
<>(
originalGeometry
.
edgeMap
.
size
());
for
(
Entry
<
SerializablePair
<
Vertex
,
Vertex
>,
Edge
>
originalEntry
:
originalGeometry
.
edgeMap
.
entrySet
())
{
Vertex
copyV0
=
handler
.
getCopyInstance
(
originalEntry
.
getKey
().
getValue0
());
Vertex
copyV1
=
handler
.
getCopyInstance
(
originalEntry
.
getKey
().
getValue1
());
SerializablePair
<
Vertex
,
Vertex
>
pair
=
new
SerializablePair
<>(
copyV0
,
copyV1
);
Edge
copyEdge
=
handler
.
getCopyInstance
(
originalEntry
.
getValue
());
edgeMap
.
put
(
pair
,
copyEdge
);
}
}
if
(
originalGeometry
.
vertices
!=
null
)
{
vertices
=
new
ArrayList
<>(
originalGeometry
.
vertices
.
size
());
for
(
Vertex
originalVertex
:
originalGeometry
.
vertices
)
{
vertices
.
add
(
handler
.
getCopyInstance
(
originalVertex
));
}
}
parent
=
handler
.
getCopyInstance
(
originalGeometry
.
parent
);
}
private
static
final
String
FAILED_REMOVING_POLYGON
=
"Removing polygon %s but polygon is not in geometry"
;
@Serial
private
static
final
long
serialVersionUID
=
2539031030917731575L
;
private
static
final
Random
r
=
new
Random
();
private
GeometryType
type
;
private
final
Lod
lod
;
private
CityObject
parent
;
private
final
List
<
Polygon
>
polygons
=
new
ArrayList
<>(
2
);
private
List
<
Edge
>
edges
;
private
Map
<
SerializablePair
<
Vertex
,
Vertex
>,
Edge
>
edgeMap
;
private
List
<
Vertex
>
vertices
;
public
Geometry
(
GeometryType
type
,
Lod
lod
)
{
this
.
lod
=
lod
;
this
.
type
=
type
;
}
void
setParent
(
CityObject
parent
)
{
this
.
parent
=
parent
;
}
public
CityObject
getParent
()
{
return
parent
;
}
public
void
setType
(
GeometryType
type
)
{
this
.
type
=
type
;
}
public
GeometryType
getType
()
{
return
type
;
}
public
Lod
getLod
()
{
return
lod
;
}
public
List
<
Polygon
>
getPolygons
()
{
return
polygons
;
}
public
void
addPolygon
(
Polygon
cdPoly
)
{
polygons
.
add
(
cdPoly
);
cdPoly
.
setParent
(
this
);
// set part of boundary surface or building installation or both
if
(
parent
instanceof
BoundarySurface
bs
)
{
cdPoly
.
setPartOfSurface
(
bs
);
if
(
bs
.
getParent
()
instanceof
Installation
bi
)
{
cdPoly
.
setPartOfInstallation
(
bi
);
}
}
else
if
(
parent
instanceof
Installation
bi
)
{
cdPoly
.
setPartOfInstallation
(
bi
);
}
}
public
void
updateEdges
()
{
edges
=
new
ArrayList
<>();
edgeMap
=
new
HashMap
<>();
Map
<
Edge
,
Edge
>
duplicacyMap
=
new
HashMap
<>();
for
(
Polygon
p
:
polygons
)
{
LinearRing
extRing
=
p
.
getExteriorRing
();
createEdgesFromRing
(
duplicacyMap
,
p
,
extRing
);
for
(
LinearRing
inner
:
p
.
getInnerRings
())
{
createEdgesFromRing
(
duplicacyMap
,
p
,
inner
);
}
}
}
void
anonymize
()
{
setGmlId
(
GmlId
.
generateId
());
for
(
Polygon
p
:
polygons
)
{
p
.
anonymize
();
}
double
minX
=
Double
.
MAX_VALUE
;
double
minY
=
Double
.
MAX_VALUE
;
double
minZ
=
Double
.
MAX_VALUE
;
for
(
Vertex
v
:
vertices
)
{
if
(
v
.
getX
()
<
minX
)
{
minX
=
v
.
getX
();
}
if
(
v
.
getY
()
<
minY
)
{
minY
=
v
.
getY
();
}
if
(
v
.
getZ
()
<
minZ
)
{
minZ
=
v
.
getZ
();
}
}
double
varX
=
r
.
nextDouble
()
*
10
;
double
varY
=
r
.
nextDouble
()
*
10
;
double
varZ
=
r
.
nextDouble
()
*
10
;
for
(
Vertex
v
:
vertices
)
{
v
.
setX
(
v
.
getX
()
-
minX
+
varX
);
v
.
setY
(
v
.
getY
()
-
minY
+
varY
);
v
.
setZ
(
v
.
getZ
()
-
minZ
+
varZ
);
}
}
private
void
createEdgesFromRing
(
Map
<
Edge
,
Edge
>
duplicacyMap
,
Polygon
p
,
LinearRing
ring
)
{
if
(
ring
==
null
)
{
return
;
}
// only go to size -1 as ring should be closed
for
(
int
i
=
0
;
i
<
ring
.
getVertices
().
size
()
-
1
;
i
++)
{
Vertex
v0
=
ring
.
getVertices
().
get
(
i
);
Vertex
v1
=
ring
.
getVertices
().
get
(
i
+
1
);
Edge
tempEdge
=
new
Edge
(
v0
,
v1
);
Edge
e
=
duplicacyMap
.
get
(
tempEdge
);
if
(
e
==
null
)
{
// no duplicate found, enter edges
Edge
oppositeEdge
=
new
Edge
(
v1
,
v0
);
duplicacyMap
.
put
(
tempEdge
,
tempEdge
);
duplicacyMap
.
put
(
oppositeEdge
,
tempEdge
);
e
=
tempEdge
;
edges
.
add
(
e
);
edgeMap
.
put
(
new
SerializablePair
<>(
v0
,
v1
),
e
);
edgeMap
.
put
(
new
SerializablePair
<>(
v1
,
v0
),
e
);
}
else
{
e
.
addHalfEdge
(
v0
,
v1
);
}
e
.
addAdjacentPolygon
(
p
);
e
.
addAdjacentRing
(
ring
);
}
}
public
Vector3d
getCenter
()
{
return
calculateBoundingBox
().
getCenter
();
}
/**
* This will calculate two points where every other point in the geometry is
* between those two. If the geometry does not contain points or is null, an
* empty array is returned. This is considered an axis aligned bounding box.
* Only the exterior rings of the polygons is used as inner rings should be
* within the exterior or they are faulty.
*
* @return an array of two points. The first contains the lowest coordinates,
*
the second contains the highest coordinates
*/
public
BoundingBox
calculateBoundingBox
()
{
return
BoundingBoxCalculator
.
calculateBoundingBox
(
polygons
);
}
public
double
calculateVolume
()
{
double
sum
=
0
;
Vector3d
center
=
calculateBoundingBox
().
getCenter
();
for
(
Polygon
p
:
polygons
)
{
TesselatedPolygon
tesselatedPolygon
=
p
.
tesselate
();
for
(
Triangle3d
t
:
tesselatedPolygon
.
getTriangles
())
{
Vector3d
p1
=
t
.
getP1
().
minus
(
center
);
Vector3d
p2
=
t
.
getP2
().
minus
(
center
);
Vector3d
p3
=
t
.
getP3
().
minus
(
center
);
sum
+=
det
(
p1
.
getCoordinates
(),
p2
.
getCoordinates
(),
p3
.
getCoordinates
());
}
}
return
sum
/
6
d
;
}
private
double
det
(
double
[]
a
,
double
[]
b
,
double
[]
c
)
{
return
-
c
[
0
]
*
b
[
1
]
*
a
[
2
]
+
b
[
0
]
*
c
[
1
]
*
a
[
2
]
+
c
[
0
]
*
a
[
1
]
*
b
[
2
]
-
a
[
0
]
*
c
[
1
]
*
b
[
2
]
-
b
[
0
]
*
a
[
1
]
*
c
[
2
]
+
a
[
0
]
*
b
[
1
]
*
c
[
2
];
}
@Override
public
boolean
containsError
(
CheckId
checkIdentifier
)
{
boolean
hasError
=
super
.
containsError
(
checkIdentifier
);
if
(
hasError
)
{
return
true
;
}
for
(
Polygon
p
:
polygons
)
{
if
(
p
.
containsError
(
checkIdentifier
))
{
return
true
;
}
}
return
false
;
}
@Override
public
void
clearAllContainedCheckResults
()
{
super
.
clearCheckResults
();
for
(
Polygon
p
:
polygons
)
{
p
.
clearAllContainedCheckResults
();
}
}
@Override
public
void
collectContainedErrors
(
List
<
CheckError
>
errors
)
{
super
.
collectContainedErrors
(
errors
);
for
(
Polygon
p
:
polygons
)
{
p
.
collectContainedErrors
(
errors
);
}
}
@Override
public
boolean
containsAnyError
()
{
boolean
hasError
=
super
.
containsAnyError
();
if
(
hasError
)
{
return
true
;
}
for
(
Polygon
p
:
polygons
)
{
if
(
p
.
containsAnyError
())
{
return
true
;
}
}
return
false
;
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
for
(
Polygon
p
:
polygons
)
{
p
.
accept
(
c
);
}
}
@Override
public
String
toString
()
{
return
"Geometry [type="
+
type
+
", lod="
+
lod
+
", id="
+
getGmlId
()
+
"]"
;
}
public
List
<
Vertex
>
getVertices
()
{
return
vertices
;
}
public
List
<
Edge
>
getEdges
()
{
return
edges
;
}
public
List
<
Edge
>
getEdgesAdjacentTo
(
Vertex
v
)
{
List
<
Edge
>
adjacentEdges
=
new
ArrayList
<>();
for
(
Edge
e
:
edges
)
{
if
(
e
.
getFrom
()
==
v
||
e
.
getTo
()
==
v
)
{
adjacentEdges
.
add
(
e
);
}
}
return
adjacentEdges
;
}
public
Edge
getEdge
(
Vertex
v1
,
Vertex
v2
)
{
return
edgeMap
.
get
(
new
SerializablePair
<>(
v1
,
v2
));
}
public
void
updateEdgesAndVertices
()
{
updateVertices
();
updateEdges
();
}
public
void
updateVertices
()
{
Set
<
Vertex
>
vertexSet
=
new
HashSet
<>();
for
(
Polygon
p
:
getPolygons
())
{
updateRing
(
vertexSet
,
p
.
getExteriorRing
());
for
(
LinearRing
inner
:
p
.
getInnerRings
())
{
updateRing
(
vertexSet
,
inner
);
}
}
vertices
=
new
ArrayList
<>(
vertexSet
);
}
private
void
updateRing
(
Set
<
Vertex
>
vertexSet
,
LinearRing
ring
)
{
if
(
ring
==
null
)
{
return
;
}
for
(
Vertex
v
:
ring
.
getVertices
())
{
if
(
vertexSet
.
add
(
v
))
{
// new vertex, clear adjacent rings in case new rings have been added
v
.
clearAdjacentRings
(
this
);
}
// add ring to adjacent rings of vertex
v
.
addAdjacentRing
(
ring
,
this
);
}
}
void
removePolygon
(
Polygon
p
)
{
p
.
removeRings
();
if
(!
polygons
.
remove
(
p
))
{
throw
new
IllegalStateException
(
String
.
format
(
FAILED_REMOVING_POLYGON
,
p
));
}
if
(
p
.
isLink
())
{
Polygon
original
=
p
.
getOriginal
();
if
(!
original
.
getParent
().
polygons
.
remove
(
original
))
{
throw
new
IllegalStateException
(
String
.
format
(
FAILED_REMOVING_POLYGON
,
p
));
}
}
else
if
(
p
.
isLinkedTo
())
{
Polygon
link
=
p
.
getLinkedFromPolygon
();
if
(!
link
.
getParent
().
polygons
.
remove
(
link
))
{
throw
new
IllegalStateException
(
String
.
format
(
FAILED_REMOVING_POLYGON
,
p
));
}
}
}
public
void
replacePolygon
(
Polygon
p
,
ConcretePolygon
...
polygons
)
{
removePolygon
(
p
);
if
(
p
.
isLink
())
{
Geometry
geom2
=
p
.
getOriginal
().
getParent
();
for
(
ConcretePolygon
newPoly
:
polygons
)
{
geom2
.
addPolygon
(
newPoly
);
addPolygon
(
new
LinkedPolygon
(
newPoly
,
this
));
}
}
else
if
(
p
.
isLinkedTo
())
{
Geometry
geom2
=
p
.
getLinkedFromPolygon
().
getParent
();
for
(
ConcretePolygon
newPoly
:
polygons
)
{
addPolygon
(
newPoly
);
geom2
.
addPolygon
(
new
LinkedPolygon
(
newPoly
,
geom2
));
}
}
else
{
for
(
Polygon
newPoly
:
polygons
)
{
addPolygon
(
newPoly
);
}
}
}
public
List
<
Edge
>
getEdgesAdjacentTo
(
Polygon
p
)
{
List
<
Edge
>
list
=
new
ArrayList
<>();
for
(
Edge
e
:
edges
)
{
if
(
e
.
getAdjacentPolygons
().
contains
(
p
))
{
list
.
add
(
e
);
}
}
return
list
;
}
public
boolean
containsPolygon
(
Polygon
other
)
{
for
(
Polygon
p
:
polygons
)
{
if
(
p
.
getGmlId
().
equals
(
other
.
getGmlId
()))
{
return
true
;
}
}
return
false
;
}
@Override
public
void
prepareForChecking
()
{
updateEdgesAndVertices
();
}
@Override
public
void
clearMetaInformation
()
{
if
(
vertices
!=
null
)
{
for
(
Vertex
v
:
vertices
)
{
v
.
clearAdjacentRings
();
}
vertices
=
null
;
}
edges
=
null
;
edgeMap
=
null
;
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
handler
.
addInstance
(
parent
);
handler
.
addInstance
(
polygons
);
handler
.
addInstance
(
edges
);
handler
.
addInstance
(
vertices
);
if
(
edgeMap
!=
null
)
{
for
(
Entry
<
SerializablePair
<
Vertex
,
Vertex
>,
Edge
>
e
:
edgeMap
.
entrySet
())
{
handler
.
addInstance
(
e
.
getKey
().
getValue0
());
handler
.
addInstance
(
e
.
getKey
().
getValue1
());
handler
.
addInstance
(
e
.
getValue
());
}
}
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
Geometry
(
type
,
lod
);
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
super
.
fillValues
(
original
,
handler
);
Geometry
originalGeometry
=
(
Geometry
)
original
;
for
(
Polygon
originalPoly
:
originalGeometry
.
polygons
)
{
polygons
.
add
(
handler
.
getCopyInstance
(
originalPoly
));
}
if
(
originalGeometry
.
edges
!=
null
)
{
edges
=
new
ArrayList
<>(
originalGeometry
.
edges
.
size
());
for
(
Edge
originalEdge
:
originalGeometry
.
edges
)
{
edges
.
add
(
handler
.
getCopyInstance
(
originalEdge
));
}
}
if
(
originalGeometry
.
edgeMap
!=
null
)
{
edgeMap
=
new
HashMap
<>(
originalGeometry
.
edgeMap
.
size
());
for
(
Entry
<
SerializablePair
<
Vertex
,
Vertex
>,
Edge
>
originalEntry
:
originalGeometry
.
edgeMap
.
entrySet
())
{
Vertex
copyV0
=
handler
.
getCopyInstance
(
originalEntry
.
getKey
().
getValue0
());
Vertex
copyV1
=
handler
.
getCopyInstance
(
originalEntry
.
getKey
().
getValue1
());
SerializablePair
<
Vertex
,
Vertex
>
pair
=
new
SerializablePair
<>(
copyV0
,
copyV1
);
Edge
copyEdge
=
handler
.
getCopyInstance
(
originalEntry
.
getValue
());
edgeMap
.
put
(
pair
,
copyEdge
);
}
}
if
(
originalGeometry
.
vertices
!=
null
)
{
vertices
=
new
ArrayList
<>(
originalGeometry
.
vertices
.
size
());
for
(
Vertex
originalVertex
:
originalGeometry
.
vertices
)
{
vertices
.
add
(
handler
.
getCopyInstance
(
originalVertex
));
}
}
parent
=
handler
.
getCopyInstance
(
originalGeometry
.
parent
);
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GeometryType.java
View file @
02de0a22
/*-
* 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
...
...
@@ -20,12 +20,11 @@ package de.hft.stuttgart.citydoctor2.datastructure;
/**
* Available geometry types
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
enum
GeometryType
{
MULTI_SURFACE
,
SOLID
,
COMPOSITE_SURFACE
MULTI_SURFACE
,
SOLID
,
COMPOSITE_SURFACE
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GmlElement.java
View file @
02de0a22
/*-
* 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
...
...
@@ -26,38 +26,37 @@ import java.io.Serial;
/**
* A general GML element that has a gml id
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
abstract
class
GmlElement
extends
Checkable
implements
Copyable
{
@Serial
private
static
final
long
serialVersionUID
=
-
3242505393303017359L
;
private
GmlId
gmlId
;
public
void
setGmlId
(
GmlId
id
)
{
gmlId
=
id
;
}
@Override
public
GmlId
getGmlId
()
{
if
(
gmlId
==
null
)
{
gmlId
=
GmlId
.
generateId
();
}
return
gmlId
;
}
public
boolean
hasExistingGmlId
()
{
return
gmlId
!=
null
&&
!
gmlId
.
isGenerated
();
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
GmlElement
originalElement
=
(
GmlElement
)
original
;
// generate gml id before copying
gmlId
=
originalElement
.
getGmlId
();
}
@Serial
private
static
final
long
serialVersionUID
=
-
3242505393303017359L
;
private
GmlId
gmlId
;
public
void
setGmlId
(
GmlId
id
)
{
gmlId
=
id
;
}
@Override
public
GmlId
getGmlId
()
{
if
(
gmlId
==
null
)
{
gmlId
=
GmlId
.
generateId
();
}
return
gmlId
;
}
public
boolean
hasExistingGmlId
()
{
return
gmlId
!=
null
&&
!
gmlId
.
isGenerated
();
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
GmlElement
originalElement
=
(
GmlElement
)
original
;
// generate gml id before copying
gmlId
=
originalElement
.
getGmlId
();
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GmlId.java
View file @
02de0a22
/*-
* 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
...
...
@@ -25,83 +25,82 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* Represents a GML id. Additionally contains information whether this id was
* generated by city doctor
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
class
GmlId
implements
Serializable
{
@Serial
private
static
final
long
serialVersionUID
=
4273817255150972966L
;
@Serial
private
static
final
long
serialVersionUID
=
4273817255150972966L
;
/* prefixes for generation */
private
static
final
String
GENERAL_GEN
=
"CityDoctor_%d_%d"
;
private
static
final
AtomicInteger
ID_COUNTER
=
new
AtomicInteger
();
/* prefixes for generation */
private
static
final
String
GENERAL_GEN
=
"CityDoctor_%d_%d"
;
private
static
final
AtomicInteger
ID_COUNTER
=
new
AtomicInteger
();
private
final
String
gmlString
;
private
final
boolean
generated
;
private
final
String
gmlString
;
private
final
boolean
generated
;
public
GmlId
(
String
gmlId
)
{
this
(
gmlId
,
false
);
}
public
GmlId
(
String
gmlId
)
{
this
(
gmlId
,
false
);
}
private
GmlId
(
String
gmlId
,
boolean
generated
)
{
if
(
gmlId
==
null
||
gmlId
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"GmlId may not be null or empty. If no GmlId is given generate one"
);
}
this
.
gmlString
=
gmlId
;
this
.
generated
=
generated
;
}
private
GmlId
(
String
gmlId
,
boolean
generated
)
{
if
(
gmlId
==
null
||
gmlId
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"GmlId may not be null or empty. If no GmlId is given generate one"
);
}
this
.
gmlString
=
gmlId
;
this
.
generated
=
generated
;
}
@Override
public
String
toString
()
{
return
gmlString
;
}
@Override
public
String
toString
()
{
return
gmlString
;
}
public
String
getGmlString
()
{
return
gmlString
;
}
public
String
getGmlString
()
{
return
gmlString
;
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
(
generated
?
1231
:
1237
);
result
=
prime
*
result
+
((
gmlString
==
null
)
?
0
:
gmlString
.
hashCode
());
return
result
;
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
(
generated
?
1231
:
1237
);
result
=
prime
*
result
+
((
gmlString
==
null
)
?
0
:
gmlString
.
hashCode
());
return
result
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
GmlId
other
=
(
GmlId
)
obj
;
if
(
generated
!=
other
.
generated
)
{
return
false
;
}
if
(
gmlString
==
null
)
{
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
GmlId
other
=
(
GmlId
)
obj
;
if
(
generated
!=
other
.
generated
)
{
return
false
;
}
if
(
gmlString
==
null
)
{
return
other
.
gmlString
==
null
;
}
else
return
gmlString
.
equals
(
other
.
gmlString
);
}
else
return
gmlString
.
equals
(
other
.
gmlString
);
}
/**
* Determines if the GML-ID was generated by CityDoctor or not.
*
* @return True if it was generated, otherwise false.
*/
public
boolean
isGenerated
()
{
return
generated
;
}
/**
* Determines if the GML-ID was generated by CityDoctor or not.
*
* @return True if it was generated, otherwise false.
*/
public
boolean
isGenerated
()
{
return
generated
;
}
public
static
GmlId
generateId
()
{
return
new
GmlId
(
String
.
format
(
GENERAL_GEN
,
System
.
currentTimeMillis
(),
ID_COUNTER
.
getAndIncrement
()),
true
);
}
public
static
GmlId
generateId
()
{
return
new
GmlId
(
String
.
format
(
GENERAL_GEN
,
System
.
currentTimeMillis
(),
ID_COUNTER
.
getAndIncrement
()),
true
);
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ImplicitGeometryHolder.java
View file @
02de0a22
...
...
@@ -2,7 +2,6 @@ package de.hft.stuttgart.citydoctor2.datastructure;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.math.TransformationMatrix
;
import
de.hft.stuttgart.citydoctor2.utils.CopyHandler
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.citygml4j.core.model.core.ImplicitGeometry
;
...
...
@@ -10,9 +9,11 @@ import org.citygml4j.core.model.core.ImplicitGeometry;
import
java.io.Serial
;
/**
* Datastructure for representation of implicit geometries
* Datastructure for representation and resolving of implicit geometries
*
* @author Riegel
*/
public
class
ImplicitGeometryHolder
extends
Geometry
{
public
class
ImplicitGeometryHolder
extends
Geometry
{
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
LibraryObject
.
class
);
@Serial
...
...
@@ -34,7 +35,7 @@ public class ImplicitGeometryHolder extends Geometry{
}
public
ImplicitGeometryHolder
(
ImplicitGeometry
cgmlImplicitGeometry
,
RelativeGeometry
relativeGeometry
)
{
super
(
relativeGeometry
.
getType
(),
relativeGeometry
.
getLod
());
super
(
relativeGeometry
.
getType
(),
relativeGeometry
.
getLod
());
this
.
libObject
=
null
;
this
.
relativeGeom
=
relativeGeometry
;
this
.
cgmlImplicitGeometry
=
cgmlImplicitGeometry
;
...
...
@@ -59,15 +60,15 @@ public class ImplicitGeometryHolder extends Geometry{
* Applies the transformation matrix of the implicit geometry to a copy of the reference geometry and copies the resulting
* transformed geometry into this object.
*/
private
void
applyTransformation
(){
private
void
applyTransformation
()
{
TransformationMatrix
transformMatrix
=
new
TransformationMatrix
(
cgmlImplicitGeometry
);
Geometry
refGeo
=
null
;
if
(
libObject
==
null
){
if
(
libObject
==
null
)
{
refGeo
=
relativeGeom
;
}
else
if
(
relativeGeom
==
null
){
}
else
if
(
relativeGeom
==
null
)
{
refGeo
=
libObject
;
}
if
(
refGeo
==
null
){
if
(
refGeo
==
null
)
{
throw
new
NullPointerException
(
"Geometry reference object of ImplicitGeometryHolder is null!"
);
}
Geometry
transformedGeom
=
transformMatrix
.
transformGeometry
(
refGeo
);
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Installation.java
View file @
02de0a22
/*-
* 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
...
...
@@ -18,10 +18,13 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
java.io.Serial
;
import
java.util.ArrayList
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
import
de.hft.stuttgart.citydoctor2.check.CheckId
;
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
;
import
org.citygml4j.core.model.bridge.BridgeInstallation
;
import
org.citygml4j.core.model.construction.AbstractInstallation
;
import
org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty
;
...
...
@@ -32,252 +35,248 @@ import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import
org.xmlobjects.gml.model.geometry.complexes.CompositeSurface
;
import
org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
import
de.hft.stuttgart.citydoctor2.check.CheckId
;
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
;
import
java.io.Serial
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
Installation
extends
CityObject
{
@Serial
private
static
final
long
serialVersionUID
=
1576237433322680191L
;
private
List
<
BoundarySurface
>
boundarySurfaces
=
new
ArrayList
<>(
4
);
private
AbstractInstallation
gmlBi
;
private
CityObject
parent
;
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
(
ms
!=
null
)
{
setGeometryAccordingToLod
(
geom
.
getLod
(),
new
MultiSurfaceProperty
(
ms
));
}
}
else
if
(
geom
.
getType
()
==
GeometryType
.
COMPOSITE_SURFACE
)
{
CompositeSurface
cs
=
CityGmlUtils
.
createCompositeSurface
(
geom
,
factory
,
config
);
if
(
cs
!=
null
)
{
setGeometryAccordingToLod
(
geom
.
getLod
(),
new
SurfaceProperty
(
cs
));
}
}
else
{
throw
new
IllegalStateException
(
"BuildingInstallation not have Solid geometries"
);
}
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
reCreateGeometries
(
factory
,
config
);
}
}
private
void
setGeometryAccordingToLod
(
Lod
lod
,
GeometryProperty
<?>
ms
)
{
if
(
gmlBi
instanceof
org
.
citygml4j
.
core
.
model
.
building
.
BuildingInstallation
localBi
)
{
addGeometryToBuildingInstallation
(
lod
,
ms
,
localBi
);
}
else
if
(
gmlBi
instanceof
BridgeInstallation
localBi
)
{
addGeometryToBridgeInstallation
(
lod
,
ms
,
localBi
);
}
}
private
void
addGeometryToBuildingInstallation
(
Lod
lod
,
GeometryProperty
<?>
ms
,
org
.
citygml4j
.
core
.
model
.
building
.
BuildingInstallation
localBi
)
{
switch
(
lod
)
{
case
LOD2:
localBi
.
getDeprecatedProperties
().
setLod2Geometry
(
ms
);
break
;
case
LOD3:
localBi
.
getDeprecatedProperties
().
setLod3Geometry
(
ms
);
break
;
case
LOD4:
localBi
.
getDeprecatedProperties
().
setLod4Geometry
(
ms
);
break
;
default
:
throw
new
IllegalStateException
(
"Found geometry with LOD other than LOD2,"
+
" LOD3, LOD4, which is illegal for BuildingInstallations: "
+
lod
);
}
}
private
void
addGeometryToBridgeInstallation
(
Lod
lod
,
GeometryProperty
<?>
ms
,
BridgeInstallation
localBi
)
{
switch
(
lod
)
{
case
LOD2:
localBi
.
getDeprecatedProperties
().
setLod2Geometry
(
ms
);
break
;
case
LOD3:
localBi
.
getDeprecatedProperties
().
setLod3Geometry
(
ms
);
break
;
case
LOD4:
localBi
.
getDeprecatedProperties
().
setLod4Geometry
(
ms
);
break
;
default
:
throw
new
IllegalStateException
(
"Found geometry with LOD other than LOD2,"
+
" LOD3, LOD4, which is illegal for BuildingInstallations: "
+
lod
);
}
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
accept
(
c
);
}
}
@Override
public
void
clearAllContainedCheckResults
()
{
super
.
clearAllContainedCheckResults
();
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
clearAllContainedCheckResults
();
}
}
@Override
public
void
collectContainedErrors
(
List
<
CheckError
>
errors
)
{
super
.
collectContainedErrors
(
errors
);
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
collectContainedErrors
(
errors
);
}
}
@Override
public
boolean
containsAnyError
()
{
boolean
hasError
=
super
.
containsAnyError
();
if
(
hasError
)
{
return
true
;
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
if
(
bs
.
containsAnyError
())
{
return
true
;
}
}
return
false
;
}
@Override
public
boolean
containsError
(
CheckId
checkIdentifier
)
{
boolean
hasError
=
super
.
containsError
(
checkIdentifier
);
if
(
hasError
)
{
return
true
;
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
if
(
bs
.
containsError
(
checkIdentifier
))
{
return
true
;
}
}
return
false
;
}
public
void
setParent
(
CityObject
parent
)
{
this
.
parent
=
parent
;
}
public
CityObject
getParent
()
{
return
parent
;
}
public
void
addBoundarySurface
(
BoundarySurface
bs
)
{
boundarySurfaces
.
add
(
bs
);
bs
.
setParent
(
this
);
}
public
void
unsetGmlGeometries
()
{
if
(
gmlBi
instanceof
org
.
citygml4j
.
core
.
model
.
building
.
BuildingInstallation
localBi
)
{
localBi
.
getDeprecatedProperties
().
setLod2Geometry
(
null
);
localBi
.
getDeprecatedProperties
().
setLod3Geometry
(
null
);
localBi
.
getDeprecatedProperties
().
setLod4Geometry
(
null
);
}
else
if
(
gmlBi
instanceof
BridgeInstallation
localBi
)
{
removeGeometriesFromBridgeInstallation
(
localBi
);
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
unsetGmlGeometries
();
}
}
private
void
removeGeometriesFromBridgeInstallation
(
BridgeInstallation
localBi
)
{
localBi
.
getDeprecatedProperties
().
setLod2Geometry
(
null
);
localBi
.
getDeprecatedProperties
().
setLod3Geometry
(
null
);
localBi
.
getDeprecatedProperties
().
setLod4Geometry
(
null
);
}
public
void
setGmlObject
(
AbstractInstallation
gmlBi
)
{
this
.
gmlBi
=
gmlBi
;
}
@Override
public
String
toString
()
{
return
"BuildingInstallation [id="
+
getGmlId
()
+
"]"
;
}
void
anonymize
()
{
setGmlId
(
GmlId
.
generateId
());
gmlBi
=
new
org
.
citygml4j
.
core
.
model
.
building
.
BuildingInstallation
();
gmlBi
.
setId
(
getGmlId
().
getGmlString
());
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
anonymize
();
gmlBi
.
getBoundaries
().
add
(
new
AbstractSpaceBoundaryProperty
(
bs
.
getGmlObject
()));
}
}
@Override
public
AbstractInstallation
getGmlObject
()
{
return
gmlBi
;
}
@Override
public
FeatureType
getFeatureType
()
{
return
FeatureType
.
INSTALLATION
;
}
public
List
<
BoundarySurface
>
getBoundarySurfaces
()
{
if
(
boundarySurfaces
==
null
)
{
boundarySurfaces
=
new
ArrayList
<>(
4
);
}
return
boundarySurfaces
;
}
@Override
public
void
clearMetaInformation
()
{
super
.
clearMetaInformation
();
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
clearMetaInformation
();
}
}
@Override
public
void
prepareForChecking
()
{
super
.
prepareForChecking
();
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
prepareForChecking
();
}
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
super
.
fillValues
(
original
,
handler
);
Installation
originalBi
=
(
Installation
)
original
;
for
(
BoundarySurface
originalBs
:
originalBi
.
boundarySurfaces
)
{
boundarySurfaces
.
add
(
handler
.
getCopyInstance
(
originalBs
));
}
gmlBi
=
originalBi
.
gmlBi
;
parent
=
handler
.
getCopyInstance
(
parent
);
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
super
.
collectInstances
(
handler
);
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
handler
.
addInstance
(
bs
);
}
handler
.
addInstance
(
parent
);
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
Installation
();
}
@Serial
private
static
final
long
serialVersionUID
=
1576237433322680191L
;
private
List
<
BoundarySurface
>
boundarySurfaces
=
new
ArrayList
<>(
4
);
private
AbstractInstallation
gmlBi
;
private
CityObject
parent
;
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
(
ms
!=
null
)
{
setGeometryAccordingToLod
(
geom
.
getLod
(),
new
MultiSurfaceProperty
(
ms
));
}
}
else
if
(
geom
.
getType
()
==
GeometryType
.
COMPOSITE_SURFACE
)
{
CompositeSurface
cs
=
CityGmlUtils
.
createCompositeSurface
(
geom
,
factory
,
config
);
if
(
cs
!=
null
)
{
setGeometryAccordingToLod
(
geom
.
getLod
(),
new
SurfaceProperty
(
cs
));
}
}
else
{
throw
new
IllegalStateException
(
"BuildingInstallation not have Solid geometries"
);
}
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
reCreateGeometries
(
factory
,
config
);
}
}
private
void
setGeometryAccordingToLod
(
Lod
lod
,
GeometryProperty
<?>
ms
)
{
if
(
gmlBi
instanceof
org
.
citygml4j
.
core
.
model
.
building
.
BuildingInstallation
localBi
)
{
addGeometryToBuildingInstallation
(
lod
,
ms
,
localBi
);
}
else
if
(
gmlBi
instanceof
BridgeInstallation
localBi
)
{
addGeometryToBridgeInstallation
(
lod
,
ms
,
localBi
);
}
}
private
void
addGeometryToBuildingInstallation
(
Lod
lod
,
GeometryProperty
<?>
ms
,
org
.
citygml4j
.
core
.
model
.
building
.
BuildingInstallation
localBi
)
{
switch
(
lod
)
{
case
LOD2:
localBi
.
getDeprecatedProperties
().
setLod2Geometry
(
ms
);
break
;
case
LOD3:
localBi
.
getDeprecatedProperties
().
setLod3Geometry
(
ms
);
break
;
case
LOD4:
localBi
.
getDeprecatedProperties
().
setLod4Geometry
(
ms
);
break
;
default
:
throw
new
IllegalStateException
(
"Found geometry with LOD other than LOD2,"
+
" LOD3, LOD4, which is illegal for BuildingInstallations: "
+
lod
);
}
}
private
void
addGeometryToBridgeInstallation
(
Lod
lod
,
GeometryProperty
<?>
ms
,
BridgeInstallation
localBi
)
{
switch
(
lod
)
{
case
LOD2:
localBi
.
getDeprecatedProperties
().
setLod2Geometry
(
ms
);
break
;
case
LOD3:
localBi
.
getDeprecatedProperties
().
setLod3Geometry
(
ms
);
break
;
case
LOD4:
localBi
.
getDeprecatedProperties
().
setLod4Geometry
(
ms
);
break
;
default
:
throw
new
IllegalStateException
(
"Found geometry with LOD other than LOD2,"
+
" LOD3, LOD4, which is illegal for BuildingInstallations: "
+
lod
);
}
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
accept
(
c
);
}
}
@Override
public
void
clearAllContainedCheckResults
()
{
super
.
clearAllContainedCheckResults
();
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
clearAllContainedCheckResults
();
}
}
@Override
public
void
collectContainedErrors
(
List
<
CheckError
>
errors
)
{
super
.
collectContainedErrors
(
errors
);
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
collectContainedErrors
(
errors
);
}
}
@Override
public
boolean
containsAnyError
()
{
boolean
hasError
=
super
.
containsAnyError
();
if
(
hasError
)
{
return
true
;
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
if
(
bs
.
containsAnyError
())
{
return
true
;
}
}
return
false
;
}
@Override
public
boolean
containsError
(
CheckId
checkIdentifier
)
{
boolean
hasError
=
super
.
containsError
(
checkIdentifier
);
if
(
hasError
)
{
return
true
;
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
if
(
bs
.
containsError
(
checkIdentifier
))
{
return
true
;
}
}
return
false
;
}
public
void
setParent
(
CityObject
parent
)
{
this
.
parent
=
parent
;
}
public
CityObject
getParent
()
{
return
parent
;
}
public
void
addBoundarySurface
(
BoundarySurface
bs
)
{
boundarySurfaces
.
add
(
bs
);
bs
.
setParent
(
this
);
}
public
void
unsetGmlGeometries
()
{
if
(
gmlBi
instanceof
org
.
citygml4j
.
core
.
model
.
building
.
BuildingInstallation
localBi
)
{
localBi
.
getDeprecatedProperties
().
setLod2Geometry
(
null
);
localBi
.
getDeprecatedProperties
().
setLod3Geometry
(
null
);
localBi
.
getDeprecatedProperties
().
setLod4Geometry
(
null
);
}
else
if
(
gmlBi
instanceof
BridgeInstallation
localBi
)
{
removeGeometriesFromBridgeInstallation
(
localBi
);
}
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
unsetGmlGeometries
();
}
}
private
void
removeGeometriesFromBridgeInstallation
(
BridgeInstallation
localBi
)
{
localBi
.
getDeprecatedProperties
().
setLod2Geometry
(
null
);
localBi
.
getDeprecatedProperties
().
setLod3Geometry
(
null
);
localBi
.
getDeprecatedProperties
().
setLod4Geometry
(
null
);
}
public
void
setGmlObject
(
AbstractInstallation
gmlBi
)
{
this
.
gmlBi
=
gmlBi
;
}
@Override
public
String
toString
()
{
return
"BuildingInstallation [id="
+
getGmlId
()
+
"]"
;
}
void
anonymize
()
{
setGmlId
(
GmlId
.
generateId
());
gmlBi
=
new
org
.
citygml4j
.
core
.
model
.
building
.
BuildingInstallation
();
gmlBi
.
setId
(
getGmlId
().
getGmlString
());
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
anonymize
();
gmlBi
.
getBoundaries
().
add
(
new
AbstractSpaceBoundaryProperty
(
bs
.
getGmlObject
()));
}
}
@Override
public
AbstractInstallation
getGmlObject
()
{
return
gmlBi
;
}
@Override
public
FeatureType
getFeatureType
()
{
return
FeatureType
.
INSTALLATION
;
}
public
List
<
BoundarySurface
>
getBoundarySurfaces
()
{
if
(
boundarySurfaces
==
null
)
{
boundarySurfaces
=
new
ArrayList
<>(
4
);
}
return
boundarySurfaces
;
}
@Override
public
void
clearMetaInformation
()
{
super
.
clearMetaInformation
();
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
clearMetaInformation
();
}
}
@Override
public
void
prepareForChecking
()
{
super
.
prepareForChecking
();
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
bs
.
prepareForChecking
();
}
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
super
.
fillValues
(
original
,
handler
);
Installation
originalBi
=
(
Installation
)
original
;
for
(
BoundarySurface
originalBs
:
originalBi
.
boundarySurfaces
)
{
boundarySurfaces
.
add
(
handler
.
getCopyInstance
(
originalBs
));
}
gmlBi
=
originalBi
.
gmlBi
;
parent
=
handler
.
getCopyInstance
(
parent
);
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
super
.
collectInstances
(
handler
);
for
(
BoundarySurface
bs
:
boundarySurfaces
)
{
handler
.
addInstance
(
bs
);
}
handler
.
addInstance
(
parent
);
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
Installation
();
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LandObject.java
View file @
02de0a22
/*-
* 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
...
...
@@ -18,107 +18,105 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
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.Copyable
;
import
org.citygml4j.core.model.core.AbstractCityObject
;
import
org.citygml4j.core.model.landuse.LandUse
;
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
;
import
de.hft.stuttgart.citydoctor2.utils.CityGmlUtils
;
import
de.hft.stuttgart.citydoctor2.utils.Copyable
;
import
java.io.Serial
;
/**
* Represents a land use CityGML object.
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
class
LandObject
extends
CityObject
{
@Serial
private
static
final
long
serialVersionUID
=
1887455662411087326L
;
private
LandUse
lu
;
public
LandObject
(
LandUse
lu
)
{
this
.
lu
=
lu
;
}
@Override
public
void
reCreateGeometries
(
GeometryFactory
factory
,
ParserConfiguration
config
)
{
for
(
Geometry
geom
:
getGeometries
())
{
if
(
geom
.
getType
()
==
GeometryType
.
MULTI_SURFACE
)
{
MultiSurface
ms
=
CityGmlUtils
.
createMultiSurface
(
geom
,
factory
,
config
);
setMultiSurfaceAccordingToLod
(
geom
,
ms
);
}
else
{
throw
new
IllegalStateException
(
"Landuse cannot have solids: "
+
geom
);
}
}
}
@Override
public
FeatureType
getFeatureType
()
{
return
FeatureType
.
LAND
;
}
private
void
setMultiSurfaceAccordingToLod
(
Geometry
geom
,
MultiSurface
ms
)
{
switch
(
geom
.
getLod
())
{
case
LOD0:
lu
.
setLod0MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD1:
lu
.
setLod1MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD2:
lu
.
setLod2MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD3:
lu
.
setLod3MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD4:
lu
.
getDeprecatedProperties
().
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
}
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
}
@Override
public
AbstractCityObject
getGmlObject
()
{
return
lu
;
}
@Override
public
void
unsetGmlGeometries
()
{
lu
.
setLod0MultiSurface
(
null
);
lu
.
setLod1MultiSurface
(
null
);
lu
.
setLod2MultiSurface
(
null
);
lu
.
setLod3MultiSurface
(
null
);
lu
.
getDeprecatedProperties
().
setLod4MultiSurface
(
null
);
}
public
void
setGmlObject
(
LandUse
landUse
)
{
lu
=
landUse
;
}
@Override
public
String
toString
()
{
return
"LandObject [id="
+
getGmlId
()
+
"]"
;
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
LandObject
(
lu
);
}
@Serial
private
static
final
long
serialVersionUID
=
1887455662411087326L
;
private
LandUse
lu
;
public
LandObject
(
LandUse
lu
)
{
this
.
lu
=
lu
;
}
@Override
public
void
reCreateGeometries
(
GeometryFactory
factory
,
ParserConfiguration
config
)
{
for
(
Geometry
geom
:
getGeometries
())
{
if
(
geom
.
getType
()
==
GeometryType
.
MULTI_SURFACE
)
{
MultiSurface
ms
=
CityGmlUtils
.
createMultiSurface
(
geom
,
factory
,
config
);
setMultiSurfaceAccordingToLod
(
geom
,
ms
);
}
else
{
throw
new
IllegalStateException
(
"Landuse cannot have solids: "
+
geom
);
}
}
}
@Override
public
FeatureType
getFeatureType
()
{
return
FeatureType
.
LAND
;
}
private
void
setMultiSurfaceAccordingToLod
(
Geometry
geom
,
MultiSurface
ms
)
{
switch
(
geom
.
getLod
())
{
case
LOD0:
lu
.
setLod0MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD1:
lu
.
setLod1MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD2:
lu
.
setLod2MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD3:
lu
.
setLod3MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
case
LOD4:
lu
.
getDeprecatedProperties
().
setLod4MultiSurface
(
new
MultiSurfaceProperty
(
ms
));
break
;
}
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
}
@Override
public
AbstractCityObject
getGmlObject
()
{
return
lu
;
}
@Override
public
void
unsetGmlGeometries
()
{
lu
.
setLod0MultiSurface
(
null
);
lu
.
setLod1MultiSurface
(
null
);
lu
.
setLod2MultiSurface
(
null
);
lu
.
setLod3MultiSurface
(
null
);
lu
.
getDeprecatedProperties
().
setLod4MultiSurface
(
null
);
}
public
void
setGmlObject
(
LandUse
landUse
)
{
lu
=
landUse
;
}
@Override
public
String
toString
()
{
return
"LandObject [id="
+
getGmlId
()
+
"]"
;
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
LandObject
(
lu
);
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LibraryObject.java
View file @
02de0a22
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.mapper.citygml3.Citygml3FeatureMapper
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParseException
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParser
;
import
de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
de.hft.stuttgart.citydoctor2.utils.CopyHandler
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
...
...
@@ -14,17 +11,20 @@ import java.io.Serial;
import
java.nio.file.Path
;
import
java.util.HashMap
;
import
java.util.List
;
/**
* Reference object for handling of implicit geometries with a library object contained in an external file
*
* @author Riegel
*/
public
class
LibraryObject
extends
Geometry
{
public
class
LibraryObject
extends
Geometry
{
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
LibraryObject
.
class
);
@Serial
private
static
final
long
serialVersionUID
=
-
50293435187454911L
;
private
final
String
filepath
;
private
final
ParserConfiguration
config
;
private
static
HashMap
<
String
,
LibraryObject
>
libraryObjects
=
new
HashMap
<>();
private
static
HashMap
<
String
,
LibraryObject
>
libraryObjects
=
new
HashMap
<>();
public
static
LibraryObject
of
(
Path
path
,
ParserConfiguration
config
)
{
if
(
libraryObjects
.
containsKey
(
path
.
toString
()))
{
...
...
@@ -34,7 +34,7 @@ public class LibraryObject extends Geometry{
if
(
protoGeom
==
null
)
{
return
null
;
}
LibraryObject
libOb
=
new
LibraryObject
(
protoGeom
.
getType
(),
protoGeom
.
getLod
(),
path
,
config
);
LibraryObject
libOb
=
new
LibraryObject
(
protoGeom
.
getType
(),
protoGeom
.
getLod
(),
path
,
config
);
protoGeom
.
getPolygons
().
forEach
(
libOb:
:
addPolygon
);
libOb
.
updateEdgesAndVertices
();
libraryObjects
.
put
(
path
.
toString
(),
libOb
);
...
...
@@ -42,7 +42,7 @@ public class LibraryObject extends Geometry{
}
private
LibraryObject
(
GeometryType
type
,
Lod
lod
,
Path
path
,
ParserConfiguration
config
)
{
super
(
type
,
lod
);
super
(
type
,
lod
);
this
.
filepath
=
path
.
toString
();
this
.
config
=
config
;
}
...
...
@@ -50,28 +50,28 @@ public class LibraryObject extends Geometry{
private
static
Geometry
parseFile
(
Path
path
,
ParserConfiguration
config
)
{
Geometry
geo
=
null
;
if
(
path
.
toFile
().
exists
()){
if
(
path
.
toFile
().
exists
())
{
try
{
CityGmlParser
.
gagLogger
(
true
);
CityDoctorModel
model
=
CityGmlParser
.
parseCityGmlFile
(
path
.
toString
(),
config
);
List
<
CityObject
>
objects
=
model
.
createFeatureStream
().
toList
();
if
(
objects
.
isEmpty
()){
if
(
objects
.
isEmpty
())
{
throw
new
InvalidGmlFileException
(
"Referenced library-object's gml file does not contain a CityGML object!"
);
}
else
if
(
objects
.
size
()
>
1
){
}
else
if
(
objects
.
size
()
>
1
)
{
throw
new
InvalidGmlFileException
(
"Referenced library-object's gml file contains more than one CityGML object!"
);
}
geo
=
objects
.
get
(
0
).
getHighestLodGeometry
();
}
catch
(
CityGmlParseException
e
){
}
catch
(
CityGmlParseException
e
)
{
logger
.
error
(
String
.
format
(
"Encountered an error while parsing library object %s"
,
path
));
logger
.
error
(
e
.
getStackTrace
());
}
catch
(
InvalidGmlFileException
e
){
}
catch
(
InvalidGmlFileException
e
)
{
logger
.
error
(
e
.
getStackTrace
());
}
finally
{
// Failsafe to remove gag should parsing fail
CityGmlParser
.
gagLogger
(
false
);
}
}
else
{
}
else
{
logger
.
error
(
String
.
format
(
"Implicit geometry references non-existing library object file %s."
,
path
));
}
return
geo
;
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinearRing.java
View file @
02de0a22
/*-
* 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
...
...
@@ -18,337 +18,332 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
java.io.Serial
;
import
java.util.ArrayList
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.math.ProjectionAxis
;
import
de.hft.stuttgart.citydoctor2.math.Ring2d
;
import
de.hft.stuttgart.citydoctor2.math.UnitVector3d
;
import
de.hft.stuttgart.citydoctor2.math.Vector2d
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
import
de.hft.stuttgart.citydoctor2.math.*
;
import
de.hft.stuttgart.citydoctor2.utils.CopyHandler
;
import
de.hft.stuttgart.citydoctor2.utils.Copyable
;
import
java.io.Serial
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* Represents a linear ring used in polygons. The ring contains the vertices.
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
class
LinearRing
extends
GmlElement
{
@Serial
private
static
final
long
serialVersionUID
=
-
2488180830514940722L
;
private
LinearRingType
type
;
private
Polygon
parent
;
private
final
List
<
Vertex
>
vertices
=
new
ArrayList
<>();
public
enum
LinearRingType
{
EXTERIOR
,
INTERIOR
}
public
LinearRing
(
LinearRingType
type
)
{
this
.
type
=
type
;
}
/**
* Checks whether a point is inside this ring. A point on the edge does count as
* inside.
*
* @param v the point.
* @return true if the point is inside or on an edge, false if it is outside.
*/
public
boolean
isPointInside
(
Vector3d
v
)
{
// project to 2d ring
ProjectionAxis
axis
=
ProjectionAxis
.
of
(
this
);
Vector2d
point
=
axis
.
project
(
v
);
Ring2d
ring
=
Ring2d
.
of
(
this
,
axis
);
int
t
=
-
1
;
for
(
int
i
=
0
;
i
<
ring
.
getVertices
().
size
()
-
1
;
i
++)
{
t
=
t
*
crossProdTest
(
point
,
ring
.
getVertices
().
get
(
i
),
ring
.
getVertices
().
get
(
i
+
1
));
if
(
t
==
0
)
{
return
true
;
}
}
return
t
>=
0
;
}
private
int
crossProdTest
(
Vector2d
a
,
Vector2d
b
,
Vector2d
c
)
{
if
(
a
.
getY
()
==
b
.
getY
()
&&
a
.
getY
()
==
c
.
getY
())
{
if
((
b
.
getX
()
<=
a
.
getX
()
&&
a
.
getX
()
<=
c
.
getX
())
||
(
c
.
getX
()
<=
a
.
getX
()
&&
a
.
getX
()
<=
b
.
getX
()))
{
return
0
;
}
else
{
return
1
;
}
}
if
(
a
.
getY
()
==
b
.
getY
()
&&
a
.
getX
()
==
b
.
getX
())
{
return
0
;
}
if
(
b
.
getY
()
>
c
.
getY
())
{
Vector2d
temp
=
b
;
b
=
c
;
c
=
temp
;
}
if
(
a
.
getY
()
<=
b
.
getY
()
||
a
.
getY
()
>
c
.
getY
())
{
return
1
;
}
return
calculateDelta
(
a
,
b
,
c
);
}
private
int
calculateDelta
(
Vector2d
a
,
Vector2d
b
,
Vector2d
c
)
{
double
delta
=
(
b
.
getX
()
-
a
.
getX
())
*
(
c
.
getY
()
-
a
.
getY
())
-
(
b
.
getY
()
-
a
.
getY
())
*
(
c
.
getX
()
-
a
.
getX
());
if
(
delta
>
0
)
{
return
-
1
;
}
else
if
(
delta
<
0
)
{
return
1
;
}
else
{
return
0
;
}
}
/**
* Calculates the normal vector of the ring. Method by Newell. If the Newell
* method would return a (0, 0, 0) vector a cross product is formed from the
* first 3 vertices. If there are no 3 vertices available (1, 0, 0) is returned.
*
* @return the normal as a normalized vector
*/
public
UnitVector3d
calculateNormalNormalized
()
{
return
calculateNormal
().
normalize
();
}
/**
* Calculates the normal vector of the ring. Method by Newell. If the Newell
* method would return a (0, 0, 0) vector a cross product is formed from the
* first 3 vertices. If there are no 3 vertices available (1, 0, 0) is returned.
*
* @return the normal vector
*/
public
Vector3d
calculateNormal
()
{
double
[]
coords
=
new
double
[
3
];
for
(
int
i
=
0
;
i
<
vertices
.
size
()
-
1
;
i
++)
{
Vertex
current
=
vertices
.
get
(
i
);
Vertex
next
=
vertices
.
get
(
i
+
1
);
coords
[
0
]
+=
(
current
.
getZ
()
+
next
.
getZ
())
*
(
current
.
getY
()
-
next
.
getY
());
coords
[
1
]
+=
(
current
.
getX
()
+
next
.
getX
())
*
(
current
.
getZ
()
-
next
.
getZ
());
coords
[
2
]
+=
(
current
.
getY
()
+
next
.
getY
())
*
(
current
.
getX
()
-
next
.
getX
());
}
if
(
coords
[
0
]
==
0
&&
coords
[
1
]
==
0
&&
coords
[
2
]
==
0
)
{
// no valid normal vector found
if
(
vertices
.
size
()
<
3
)
{
// no three points, return x-axis
return
UnitVector3d
.
X_AXIS
;
}
Vertex
v1
=
vertices
.
get
(
0
);
Vertex
v2
=
vertices
.
get
(
1
);
Vertex
v3
=
vertices
.
get
(
2
);
return
calculateNormalWithCross
(
v1
,
v2
,
v3
);
}
return
new
Vector3d
(
coords
);
}
public
double
getArea
()
{
int
n
=
vertices
.
size
();
if
(
n
<
3
)
return
0.0
;
// a degenerated polygon
// prepare an vertex array with n+2 vertices:
// V[0] ... V[n-1] - the n different vertices
// V[n]=V[0]
// V[n+1]=V[1]
Vertex
[]
vertexArray
=
new
Vertex
[
n
+
2
];
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
vertexArray
[
i
]
=
vertices
.
get
(
i
);
}
vertexArray
[
n
]
=
vertices
.
get
(
0
);
vertexArray
[
n
+
1
]
=
vertices
.
get
(
1
);
double
area
=
0
;
// make sure the normal has been calculated
Vector3d
normal
=
calculateNormal
();
// select largest abs coordinate to ignore for projection
double
ax
=
Math
.
abs
(
normal
.
getX
());
// abs x-coord
double
ay
=
Math
.
abs
(
normal
.
getY
());
// abs y-coord
double
az
=
Math
.
abs
(
normal
.
getZ
());
// abs z-coord
// coord to ignore: 1=x, 2=y, 3=z
int
coord
=
3
;
// ignore z-coord
if
(
ax
>
ay
)
{
if
(
ax
>
az
)
{
coord
=
1
;
// ignore x-coord
}
}
else
if
(
ay
>
az
)
{
coord
=
2
;
// ignore y-coord
}
// compute area of the 2D projection
for
(
int
i
=
1
,
j
=
2
,
k
=
0
;
i
<=
vertexArray
.
length
-
2
;
i
++,
j
++,
k
++)
{
switch
(
coord
)
{
case
1
:
area
+=
(
vertexArray
[
i
].
getY
()
*
(
vertexArray
[
j
].
getZ
()
-
vertexArray
[
k
].
getZ
()));
break
;
case
2
:
area
+=
(
vertexArray
[
i
].
getX
()
*
(
vertexArray
[
j
].
getZ
()
-
vertexArray
[
k
].
getZ
()));
break
;
case
3
:
area
+=
(
vertexArray
[
i
].
getX
()
*
(
vertexArray
[
j
].
getY
()
-
vertexArray
[
k
].
getY
()));
break
;
default
:
throw
new
IllegalStateException
();
}
}
// scale to get area before projection
double
an
=
Math
.
sqrt
(
ax
*
ax
+
ay
*
ay
+
az
*
az
);
// length of normal vector
switch
(
coord
)
{
case
1
:
area
*=
(
an
/
(
2
*
ax
));
break
;
case
2
:
area
*=
(
an
/
(
2
*
ay
));
break
;
case
3
:
area
*=
(
an
/
(
2
*
az
));
break
;
default
:
throw
new
IllegalStateException
();
}
return
Math
.
abs
(
area
);
}
private
UnitVector3d
calculateNormalWithCross
(
Vertex
v1
,
Vertex
v2
,
Vertex
v3
)
{
Vector3d
dir1
=
v2
.
minus
(
v1
);
Vector3d
dir2
=
v3
.
minus
(
v1
);
Vector3d
cross
=
dir1
.
cross
(
dir2
);
return
cross
.
normalize
();
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
}
@Override
public
void
clearAllContainedCheckResults
()
{
super
.
clearCheckResults
();
}
public
void
setParent
(
Polygon
polygon
)
{
parent
=
polygon
;
}
public
Polygon
getParent
()
{
return
parent
;
}
public
LinearRingType
getType
()
{
return
type
;
}
public
List
<
Vertex
>
getVertices
()
{
return
vertices
;
}
public
void
addVertex
(
Vertex
v
)
{
vertices
.
add
(
v
);
if
(
parent
==
null
)
{
return
;
}
if
(
parent
.
isLinkedTo
())
{
v
.
addAdjacentRing
(
this
,
parent
.
getLinkedFromPolygon
().
getParent
());
}
v
.
addAdjacentRing
(
this
,
parent
.
getParent
());
}
public
void
addVertex
(
int
i
,
Vertex
v
)
{
vertices
.
add
(
i
,
v
);
if
(
parent
.
isLinkedTo
())
{
v
.
addAdjacentRing
(
this
,
parent
.
getLinkedFromPolygon
().
getParent
());
}
v
.
addAdjacentRing
(
this
,
parent
.
getParent
());
}
public
void
setVertex
(
int
i
,
Vertex
v
)
{
vertices
.
set
(
i
,
v
);
if
(
parent
.
isLinkedTo
())
{
v
.
addAdjacentRing
(
this
,
parent
.
getLinkedFromPolygon
().
getParent
());
}
v
.
addAdjacentRing
(
this
,
parent
.
getParent
());
}
@Override
public
String
toString
()
{
return
"LinearRing [type="
+
type
+
", gmlId="
+
getGmlId
()
+
"]"
;
}
void
anonymize
()
{
setGmlId
(
GmlId
.
generateId
());
}
public
boolean
isRingConnectedViaPoint
(
LinearRing
other
)
{
for
(
Vertex
v
:
vertices
)
{
if
(
other
.
getVertices
().
contains
(
v
))
{
return
true
;
}
}
return
false
;
}
public
boolean
hasPointAsCorner
(
Vertex
v
)
{
return
vertices
.
contains
(
v
);
}
public
void
setType
(
LinearRingType
type
)
{
this
.
type
=
type
;
}
public
void
addAllVertices
(
List
<
Vertex
>
extRing
)
{
vertices
.
addAll
(
extRing
);
}
@Override
public
void
prepareForChecking
()
{
parent
.
getParent
().
prepareForChecking
();
}
@Override
public
void
clearMetaInformation
()
{
parent
.
getParent
().
clearMetaInformation
();
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
super
.
fillValues
(
original
,
handler
);
LinearRing
originalRing
=
(
LinearRing
)
original
;
type
=
originalRing
.
type
;
parent
=
handler
.
getCopyInstance
(
originalRing
.
parent
);
for
(
Vertex
v
:
originalRing
.
vertices
)
{
vertices
.
add
(
handler
.
getCopyInstance
(
v
));
}
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
for
(
Vertex
v
:
vertices
)
{
handler
.
addInstance
(
v
);
}
handler
.
addInstance
(
parent
);
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
LinearRing
(
type
);
}
@Serial
private
static
final
long
serialVersionUID
=
-
2488180830514940722L
;
private
LinearRingType
type
;
private
Polygon
parent
;
private
final
List
<
Vertex
>
vertices
=
new
ArrayList
<>();
public
enum
LinearRingType
{
EXTERIOR
,
INTERIOR
}
public
LinearRing
(
LinearRingType
type
)
{
this
.
type
=
type
;
}
/**
* Checks whether a point is inside this ring. A point on the edge does count as
* inside.
*
* @param v the point.
* @return true if the point is inside or on an edge, false if it is outside.
*/
public
boolean
isPointInside
(
Vector3d
v
)
{
// project to 2d ring
ProjectionAxis
axis
=
ProjectionAxis
.
of
(
this
);
Vector2d
point
=
axis
.
project
(
v
);
Ring2d
ring
=
Ring2d
.
of
(
this
,
axis
);
int
t
=
-
1
;
for
(
int
i
=
0
;
i
<
ring
.
getVertices
().
size
()
-
1
;
i
++)
{
t
=
t
*
crossProdTest
(
point
,
ring
.
getVertices
().
get
(
i
),
ring
.
getVertices
().
get
(
i
+
1
));
if
(
t
==
0
)
{
return
true
;
}
}
return
t
>=
0
;
}
private
int
crossProdTest
(
Vector2d
a
,
Vector2d
b
,
Vector2d
c
)
{
if
(
a
.
getY
()
==
b
.
getY
()
&&
a
.
getY
()
==
c
.
getY
())
{
if
((
b
.
getX
()
<=
a
.
getX
()
&&
a
.
getX
()
<=
c
.
getX
())
||
(
c
.
getX
()
<=
a
.
getX
()
&&
a
.
getX
()
<=
b
.
getX
()))
{
return
0
;
}
else
{
return
1
;
}
}
if
(
a
.
getY
()
==
b
.
getY
()
&&
a
.
getX
()
==
b
.
getX
())
{
return
0
;
}
if
(
b
.
getY
()
>
c
.
getY
())
{
Vector2d
temp
=
b
;
b
=
c
;
c
=
temp
;
}
if
(
a
.
getY
()
<=
b
.
getY
()
||
a
.
getY
()
>
c
.
getY
())
{
return
1
;
}
return
calculateDelta
(
a
,
b
,
c
);
}
private
int
calculateDelta
(
Vector2d
a
,
Vector2d
b
,
Vector2d
c
)
{
double
delta
=
(
b
.
getX
()
-
a
.
getX
())
*
(
c
.
getY
()
-
a
.
getY
())
-
(
b
.
getY
()
-
a
.
getY
())
*
(
c
.
getX
()
-
a
.
getX
());
if
(
delta
>
0
)
{
return
-
1
;
}
else
if
(
delta
<
0
)
{
return
1
;
}
else
{
return
0
;
}
}
/**
* Calculates the normal vector of the ring. Method by Newell. If the Newell
* method would return a (0, 0, 0) vector a cross product is formed from the
* first 3 vertices. If there are no 3 vertices available (1, 0, 0) is returned.
*
* @return the normal as a normalized vector
*/
public
UnitVector3d
calculateNormalNormalized
()
{
return
calculateNormal
().
normalize
();
}
/**
* Calculates the normal vector of the ring. Method by Newell. If the Newell
* method would return a (0, 0, 0) vector a cross product is formed from the
* first 3 vertices. If there are no 3 vertices available (1, 0, 0) is returned.
*
* @return the normal vector
*/
public
Vector3d
calculateNormal
()
{
double
[]
coords
=
new
double
[
3
];
for
(
int
i
=
0
;
i
<
vertices
.
size
()
-
1
;
i
++)
{
Vertex
current
=
vertices
.
get
(
i
);
Vertex
next
=
vertices
.
get
(
i
+
1
);
coords
[
0
]
+=
(
current
.
getZ
()
+
next
.
getZ
())
*
(
current
.
getY
()
-
next
.
getY
());
coords
[
1
]
+=
(
current
.
getX
()
+
next
.
getX
())
*
(
current
.
getZ
()
-
next
.
getZ
());
coords
[
2
]
+=
(
current
.
getY
()
+
next
.
getY
())
*
(
current
.
getX
()
-
next
.
getX
());
}
if
(
coords
[
0
]
==
0
&&
coords
[
1
]
==
0
&&
coords
[
2
]
==
0
)
{
// no valid normal vector found
if
(
vertices
.
size
()
<
3
)
{
// no three points, return x-axis
return
UnitVector3d
.
X_AXIS
;
}
Vertex
v1
=
vertices
.
get
(
0
);
Vertex
v2
=
vertices
.
get
(
1
);
Vertex
v3
=
vertices
.
get
(
2
);
return
calculateNormalWithCross
(
v1
,
v2
,
v3
);
}
return
new
Vector3d
(
coords
);
}
public
double
getArea
()
{
int
n
=
vertices
.
size
();
if
(
n
<
3
)
return
0.0
;
// a degenerated polygon
// prepare an vertex array with n+2 vertices:
// V[0] ... V[n-1] - the n different vertices
// V[n]=V[0]
// V[n+1]=V[1]
Vertex
[]
vertexArray
=
new
Vertex
[
n
+
2
];
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
vertexArray
[
i
]
=
vertices
.
get
(
i
);
}
vertexArray
[
n
]
=
vertices
.
get
(
0
);
vertexArray
[
n
+
1
]
=
vertices
.
get
(
1
);
double
area
=
0
;
// make sure the normal has been calculated
Vector3d
normal
=
calculateNormal
();
// select largest abs coordinate to ignore for projection
double
ax
=
Math
.
abs
(
normal
.
getX
());
// abs x-coord
double
ay
=
Math
.
abs
(
normal
.
getY
());
// abs y-coord
double
az
=
Math
.
abs
(
normal
.
getZ
());
// abs z-coord
// coord to ignore: 1=x, 2=y, 3=z
int
coord
=
3
;
// ignore z-coord
if
(
ax
>
ay
)
{
if
(
ax
>
az
)
{
coord
=
1
;
// ignore x-coord
}
}
else
if
(
ay
>
az
)
{
coord
=
2
;
// ignore y-coord
}
// compute area of the 2D projection
for
(
int
i
=
1
,
j
=
2
,
k
=
0
;
i
<=
vertexArray
.
length
-
2
;
i
++,
j
++,
k
++)
{
switch
(
coord
)
{
case
1
:
area
+=
(
vertexArray
[
i
].
getY
()
*
(
vertexArray
[
j
].
getZ
()
-
vertexArray
[
k
].
getZ
()));
break
;
case
2
:
area
+=
(
vertexArray
[
i
].
getX
()
*
(
vertexArray
[
j
].
getZ
()
-
vertexArray
[
k
].
getZ
()));
break
;
case
3
:
area
+=
(
vertexArray
[
i
].
getX
()
*
(
vertexArray
[
j
].
getY
()
-
vertexArray
[
k
].
getY
()));
break
;
default
:
throw
new
IllegalStateException
();
}
}
// scale to get area before projection
double
an
=
Math
.
sqrt
(
ax
*
ax
+
ay
*
ay
+
az
*
az
);
// length of normal vector
switch
(
coord
)
{
case
1
:
area
*=
(
an
/
(
2
*
ax
));
break
;
case
2
:
area
*=
(
an
/
(
2
*
ay
));
break
;
case
3
:
area
*=
(
an
/
(
2
*
az
));
break
;
default
:
throw
new
IllegalStateException
();
}
return
Math
.
abs
(
area
);
}
private
UnitVector3d
calculateNormalWithCross
(
Vertex
v1
,
Vertex
v2
,
Vertex
v3
)
{
Vector3d
dir1
=
v2
.
minus
(
v1
);
Vector3d
dir2
=
v3
.
minus
(
v1
);
Vector3d
cross
=
dir1
.
cross
(
dir2
);
return
cross
.
normalize
();
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
}
@Override
public
void
clearAllContainedCheckResults
()
{
super
.
clearCheckResults
();
}
public
void
setParent
(
Polygon
polygon
)
{
parent
=
polygon
;
}
public
Polygon
getParent
()
{
return
parent
;
}
public
LinearRingType
getType
()
{
return
type
;
}
public
List
<
Vertex
>
getVertices
()
{
return
vertices
;
}
public
void
addVertex
(
Vertex
v
)
{
vertices
.
add
(
v
);
if
(
parent
==
null
)
{
return
;
}
if
(
parent
.
isLinkedTo
())
{
v
.
addAdjacentRing
(
this
,
parent
.
getLinkedFromPolygon
().
getParent
());
}
v
.
addAdjacentRing
(
this
,
parent
.
getParent
());
}
public
void
addVertex
(
int
i
,
Vertex
v
)
{
vertices
.
add
(
i
,
v
);
if
(
parent
.
isLinkedTo
())
{
v
.
addAdjacentRing
(
this
,
parent
.
getLinkedFromPolygon
().
getParent
());
}
v
.
addAdjacentRing
(
this
,
parent
.
getParent
());
}
public
void
setVertex
(
int
i
,
Vertex
v
)
{
vertices
.
set
(
i
,
v
);
if
(
parent
.
isLinkedTo
())
{
v
.
addAdjacentRing
(
this
,
parent
.
getLinkedFromPolygon
().
getParent
());
}
v
.
addAdjacentRing
(
this
,
parent
.
getParent
());
}
@Override
public
String
toString
()
{
return
"LinearRing [type="
+
type
+
", gmlId="
+
getGmlId
()
+
"]"
;
}
void
anonymize
()
{
setGmlId
(
GmlId
.
generateId
());
}
public
boolean
isRingConnectedViaPoint
(
LinearRing
other
)
{
for
(
Vertex
v
:
vertices
)
{
if
(
other
.
getVertices
().
contains
(
v
))
{
return
true
;
}
}
return
false
;
}
public
boolean
hasPointAsCorner
(
Vertex
v
)
{
return
vertices
.
contains
(
v
);
}
public
void
setType
(
LinearRingType
type
)
{
this
.
type
=
type
;
}
public
void
addAllVertices
(
List
<
Vertex
>
extRing
)
{
vertices
.
addAll
(
extRing
);
}
@Override
public
void
prepareForChecking
()
{
parent
.
getParent
().
prepareForChecking
();
}
@Override
public
void
clearMetaInformation
()
{
parent
.
getParent
().
clearMetaInformation
();
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
super
.
fillValues
(
original
,
handler
);
LinearRing
originalRing
=
(
LinearRing
)
original
;
type
=
originalRing
.
type
;
parent
=
handler
.
getCopyInstance
(
originalRing
.
parent
);
for
(
Vertex
v
:
originalRing
.
vertices
)
{
vertices
.
add
(
handler
.
getCopyInstance
(
v
));
}
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
for
(
Vertex
v
:
vertices
)
{
handler
.
addInstance
(
v
);
}
handler
.
addInstance
(
parent
);
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
LinearRing
(
type
);
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinkedPolygon.java
View file @
02de0a22
/*-
* 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
...
...
@@ -18,10 +18,6 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
java.io.Serial
;
import
java.util.List
;
import
java.util.Map
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
import
de.hft.stuttgart.citydoctor2.check.CheckId
;
...
...
@@ -31,275 +27,277 @@ import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon;
import
de.hft.stuttgart.citydoctor2.utils.CopyHandler
;
import
de.hft.stuttgart.citydoctor2.utils.Copyable
;
import
java.io.Serial
;
import
java.util.List
;
import
java.util.Map
;
/**
* A polygon that does not contain the geometry but is only a link to an actual
* polygon. Created when href in CityGML are used.
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
class
LinkedPolygon
extends
Polygon
{
@Serial
private
static
final
long
serialVersionUID
=
-
4897578390280277931L
;
private
Geometry
parent
;
private
ConcretePolygon
poly
;
private
LinkedPolygon
()
{
}
/**
*
* @param poly polygon this is linked to
* @param parent the parent of the linked polygon
*/
public
LinkedPolygon
(
ConcretePolygon
poly
,
Geometry
parent
)
{
this
.
parent
=
parent
;
this
.
poly
=
poly
;
poly
.
setLinkedTo
(
this
);
for
(
Vertex
v
:
poly
.
getExteriorRing
().
getVertices
())
{
v
.
addAdjacentRing
(
poly
.
getExteriorRing
(),
parent
);
}
for
(
LinearRing
lr
:
poly
.
getInnerRings
())
{
for
(
Vertex
v
:
lr
.
getVertices
())
{
v
.
addAdjacentRing
(
lr
,
parent
);
}
}
}
@Override
public
CheckResult
getCheckResult
(
Check
c
)
{
return
poly
.
getCheckResult
(
c
);
}
@Override
public
Map
<
CheckId
,
CheckResult
>
getAllCheckResults
()
{
return
poly
.
getAllCheckResults
();
}
@Override
public
boolean
hasAnyError
()
{
return
poly
.
hasAnyError
();
}
@Override
public
boolean
hasDependencyNotMetError
(
CheckId
id
)
{
return
poly
.
hasDependencyNotMetError
(
id
);
}
@Override
public
CheckResult
getCheckResult
(
CheckId
id
)
{
return
poly
.
getCheckResult
(
id
);
}
@Override
public
boolean
hasCheckResults
()
{
return
poly
.
hasCheckResults
();
}
@Override
public
void
setGmlId
(
GmlId
id
)
{
poly
.
setGmlId
(
id
);
}
@Override
public
GmlId
getGmlId
()
{
return
poly
.
getGmlId
();
}
@Override
public
void
accept
(
Check
c
)
{
// linked polygons are not checked
setValidated
(
true
);
}
@Override
public
void
addCheckResult
(
CheckResult
cr
)
{
poly
.
addCheckResult
(
cr
);
}
@Override
public
void
collectContainedErrors
(
List
<
CheckError
>
errors
)
{
poly
.
collectContainedErrors
(
errors
);
}
@Override
public
boolean
containsAnyError
()
{
return
poly
.
containsAnyError
();
}
@Override
public
boolean
containsError
(
CheckId
checkIdentifier
)
{
return
poly
.
containsError
(
checkIdentifier
);
}
@Override
public
void
clearCheckResults
()
{
poly
.
clearCheckResults
();
}
@Override
public
Vector3d
calculateNormalNormalized
()
{
return
poly
.
calculateNormalNormalized
();
}
@Override
public
Vector3d
calculateNormal
()
{
return
poly
.
calculateNormal
();
}
@Override
public
TesselatedPolygon
tesselate
()
{
return
poly
.
tesselate
();
}
@Override
public
LinearRing
getExteriorRing
()
{
return
poly
.
getExteriorRing
();
}
@Override
public
List
<
LinearRing
>
getInnerRings
()
{
return
poly
.
getInnerRings
();
}
@Override
public
boolean
isPointInsideExteriorRing
(
Vector3d
v
)
{
return
poly
.
isPointInsideExteriorRing
(
v
);
}
@Override
public
Geometry
getParent
()
{
return
parent
;
}
@Override
public
void
setParent
(
Geometry
geometry
)
{
this
.
parent
=
geometry
;
}
@Override
public
void
setExteriorRing
(
LinearRing
extRing
)
{
poly
.
setExteriorRing
(
extRing
);
}
@Override
public
boolean
isPolygonConnectedViaPoint
(
Polygon
other
)
{
return
poly
.
isPolygonConnectedViaPoint
(
other
);
}
@Override
public
String
toString
()
{
return
"LinkedPolygon ["
+
poly
.
getGmlId
()
+
"]"
;
}
@Override
public
void
addInteriorRing
(
LinearRing
inter
)
{
poly
.
addInteriorRing
(
inter
);
}
@Override
public
BoundarySurface
getPartOfSurface
()
{
return
poly
.
getPartOfSurface
();
}
@Override
public
void
setPartOfSurface
(
BoundarySurface
bs
)
{
poly
.
setPartOfSurface
(
bs
);
}
@Override
public
void
removeInnerRing
(
LinearRing
ring
)
{
poly
.
removeInnerRing
(
ring
);
}
@Override
public
void
setPartOfInstallation
(
Installation
bi
)
{
poly
.
setPartOfInstallation
(
bi
);
}
@Override
public
Installation
getPartOfInstallation
()
{
return
poly
.
getPartOfInstallation
();
}
@Override
public
boolean
hasPointAsCorner
(
Vertex
v
)
{
return
poly
.
hasPointAsCorner
(
v
);
}
@Override
public
void
removeRings
()
{
poly
.
removeRings
();
}
@Override
public
boolean
isLink
()
{
return
true
;
}
@Override
public
LinkedPolygon
getLinkedFromPolygon
()
{
return
this
;
}
@Override
void
anonymize
()
{
poly
.
anonymize
();
}
@Override
public
void
clearAllContainedCheckResults
()
{
poly
.
clearAllContainedCheckResults
();
}
@Override
public
ConcretePolygon
getOriginal
()
{
return
poly
;
}
@Override
public
void
prepareForChecking
()
{
poly
.
prepareForChecking
();
}
@Override
public
void
clearMetaInformation
()
{
poly
.
clearMetaInformation
();
}
@Override
public
boolean
isLinkedTo
()
{
return
false
;
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
handler
.
addInstance
(
parent
);
handler
.
addInstance
(
poly
);
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
LinkedPolygon
();
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
LinkedPolygon
linkedOriginal
=
(
LinkedPolygon
)
original
;
parent
=
handler
.
getCopyInstance
(
linkedOriginal
.
parent
);
poly
=
handler
.
getCopyInstance
(
linkedOriginal
.
poly
);
}
@Override
public
void
remove
()
{
poly
.
remove
();
}
@Override
public
double
getArea
()
{
return
poly
.
getArea
();
}
@Serial
private
static
final
long
serialVersionUID
=
-
4897578390280277931L
;
private
Geometry
parent
;
private
ConcretePolygon
poly
;
private
LinkedPolygon
()
{
}
/**
* @param poly polygon this is linked to
* @param parent the parent of the linked polygon
*/
public
LinkedPolygon
(
ConcretePolygon
poly
,
Geometry
parent
)
{
this
.
parent
=
parent
;
this
.
poly
=
poly
;
poly
.
setLinkedTo
(
this
);
for
(
Vertex
v
:
poly
.
getExteriorRing
().
getVertices
())
{
v
.
addAdjacentRing
(
poly
.
getExteriorRing
(),
parent
);
}
for
(
LinearRing
lr
:
poly
.
getInnerRings
())
{
for
(
Vertex
v
:
lr
.
getVertices
())
{
v
.
addAdjacentRing
(
lr
,
parent
);
}
}
}
@Override
public
CheckResult
getCheckResult
(
Check
c
)
{
return
poly
.
getCheckResult
(
c
);
}
@Override
public
Map
<
CheckId
,
CheckResult
>
getAllCheckResults
()
{
return
poly
.
getAllCheckResults
();
}
@Override
public
boolean
hasAnyError
()
{
return
poly
.
hasAnyError
();
}
@Override
public
boolean
hasDependencyNotMetError
(
CheckId
id
)
{
return
poly
.
hasDependencyNotMetError
(
id
);
}
@Override
public
CheckResult
getCheckResult
(
CheckId
id
)
{
return
poly
.
getCheckResult
(
id
);
}
@Override
public
boolean
hasCheckResults
()
{
return
poly
.
hasCheckResults
();
}
@Override
public
void
setGmlId
(
GmlId
id
)
{
poly
.
setGmlId
(
id
);
}
@Override
public
GmlId
getGmlId
()
{
return
poly
.
getGmlId
();
}
@Override
public
void
accept
(
Check
c
)
{
// linked polygons are not checked
setValidated
(
true
);
}
@Override
public
void
addCheckResult
(
CheckResult
cr
)
{
poly
.
addCheckResult
(
cr
);
}
@Override
public
void
collectContainedErrors
(
List
<
CheckError
>
errors
)
{
poly
.
collectContainedErrors
(
errors
);
}
@Override
public
boolean
containsAnyError
()
{
return
poly
.
containsAnyError
();
}
@Override
public
boolean
containsError
(
CheckId
checkIdentifier
)
{
return
poly
.
containsError
(
checkIdentifier
);
}
@Override
public
void
clearCheckResults
()
{
poly
.
clearCheckResults
();
}
@Override
public
Vector3d
calculateNormalNormalized
()
{
return
poly
.
calculateNormalNormalized
();
}
@Override
public
Vector3d
calculateNormal
()
{
return
poly
.
calculateNormal
();
}
@Override
public
TesselatedPolygon
tesselate
()
{
return
poly
.
tesselate
();
}
@Override
public
LinearRing
getExteriorRing
()
{
return
poly
.
getExteriorRing
();
}
@Override
public
List
<
LinearRing
>
getInnerRings
()
{
return
poly
.
getInnerRings
();
}
@Override
public
boolean
isPointInsideExteriorRing
(
Vector3d
v
)
{
return
poly
.
isPointInsideExteriorRing
(
v
);
}
@Override
public
Geometry
getParent
()
{
return
parent
;
}
@Override
public
void
setParent
(
Geometry
geometry
)
{
this
.
parent
=
geometry
;
}
@Override
public
void
setExteriorRing
(
LinearRing
extRing
)
{
poly
.
setExteriorRing
(
extRing
);
}
@Override
public
boolean
isPolygonConnectedViaPoint
(
Polygon
other
)
{
return
poly
.
isPolygonConnectedViaPoint
(
other
);
}
@Override
public
String
toString
()
{
return
"LinkedPolygon ["
+
poly
.
getGmlId
()
+
"]"
;
}
@Override
public
void
addInteriorRing
(
LinearRing
inter
)
{
poly
.
addInteriorRing
(
inter
);
}
@Override
public
BoundarySurface
getPartOfSurface
()
{
return
poly
.
getPartOfSurface
();
}
@Override
public
void
setPartOfSurface
(
BoundarySurface
bs
)
{
poly
.
setPartOfSurface
(
bs
);
}
@Override
public
void
removeInnerRing
(
LinearRing
ring
)
{
poly
.
removeInnerRing
(
ring
);
}
@Override
public
void
setPartOfInstallation
(
Installation
bi
)
{
poly
.
setPartOfInstallation
(
bi
);
}
@Override
public
Installation
getPartOfInstallation
()
{
return
poly
.
getPartOfInstallation
();
}
@Override
public
boolean
hasPointAsCorner
(
Vertex
v
)
{
return
poly
.
hasPointAsCorner
(
v
);
}
@Override
public
void
removeRings
()
{
poly
.
removeRings
();
}
@Override
public
boolean
isLink
()
{
return
true
;
}
@Override
public
LinkedPolygon
getLinkedFromPolygon
()
{
return
this
;
}
@Override
void
anonymize
()
{
poly
.
anonymize
();
}
@Override
public
void
clearAllContainedCheckResults
()
{
poly
.
clearAllContainedCheckResults
();
}
@Override
public
ConcretePolygon
getOriginal
()
{
return
poly
;
}
@Override
public
void
prepareForChecking
()
{
poly
.
prepareForChecking
();
}
@Override
public
void
clearMetaInformation
()
{
poly
.
clearMetaInformation
();
}
@Override
public
boolean
isLinkedTo
()
{
return
false
;
}
@Override
public
void
collectInstances
(
CopyHandler
handler
)
{
handler
.
addInstance
(
parent
);
handler
.
addInstance
(
poly
);
}
@Override
public
Copyable
createCopyInstance
()
{
return
new
LinkedPolygon
();
}
@Override
public
void
fillValues
(
Copyable
original
,
CopyHandler
handler
)
{
LinkedPolygon
linkedOriginal
=
(
LinkedPolygon
)
original
;
parent
=
handler
.
getCopyInstance
(
linkedOriginal
.
parent
);
poly
=
handler
.
getCopyInstance
(
linkedOriginal
.
poly
);
}
@Override
public
void
remove
()
{
poly
.
remove
();
}
@Override
public
double
getArea
()
{
return
poly
.
getArea
();
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Lod.java
View file @
02de0a22
/*-
* 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
...
...
@@ -20,24 +20,23 @@ package de.hft.stuttgart.citydoctor2.datastructure;
/**
* The different LODs available in CityGML
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
enum
Lod
{
LOD0
(
0
),
LOD1
(
1
),
LOD2
(
2
),
LOD3
(
3
),
LOD4
(
4
);
LOD0
(
0
),
LOD1
(
1
),
LOD2
(
2
),
LOD3
(
3
),
LOD4
(
4
);
private
final
int
rank
;
private
final
int
rank
;
private
Lod
(
int
rank
)
{
this
.
rank
=
rank
;
}
private
Lod
(
int
rank
)
{
this
.
rank
=
rank
;
}
public
boolean
isHigher
(
Lod
other
)
{
if
(
other
==
null
)
{
return
true
;
}
return
rank
>
other
.
rank
;
}
public
boolean
isHigher
(
Lod
other
)
{
if
(
other
==
null
)
{
return
true
;
}
return
rank
>
other
.
rank
;
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Opening.java
View file @
02de0a22
/*-
* 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
...
...
@@ -18,17 +18,16 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
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
;
import
de.hft.stuttgart.citydoctor2.utils.CityGmlUtils
;
import
de.hft.stuttgart.citydoctor2.utils.CopyHandler
;
import
de.hft.stuttgart.citydoctor2.utils.Copyable
;
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
java.io.Serial
;
...
...
@@ -36,145 +35,144 @@ import java.io.Serial;
* Represents an Opening suchs a window or Door in a surface of a feature.
* Contains a reference to the boundary surface where this opening is embedded
* in.
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
class
Opening
extends
CityObject
{
@Serial
private
static
final
long
serialVersionUID
=
6409303152284607944L
;
private
BoundarySurface
partOf
;
private
OpeningType
type
;
private
SurfaceFeatureType
featureType
;
private
AbstractFillingSurface
ao
;
private
Opening
(
OpeningType
type
)
{
this
.
type
=
type
;
}
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
(
GeometryFactory
factory
,
ParserConfiguration
config
)
{
if
(
ao
.
getId
()
!=
null
)
{
ao
.
setId
(
getGmlId
().
getGmlString
());
}
for
(
Geometry
geom
:
getGeometries
())
{
if
(
geom
.
getType
()
==
GeometryType
.
MULTI_SURFACE
)
{
MultiSurface
ms
=
CityGmlUtils
.
createMultiSurface
(
geom
,
factory
,
config
);
setGeometryAccordingToLod
(
geom
.
getLod
(),
new
MultiSurfaceProperty
(
ms
));
}
else
{
throw
new
IllegalStateException
(
"Openings 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:
ao
.
setLod3MultiSurface
(
ms
);
break
;
case
LOD4:
ao
.
getDeprecatedProperties
().
setLod4MultiSurface
(
ms
);
break
;
default
:
throw
new
IllegalStateException
(
"Cannot add geometry to opening because lod is not allowed: "
+
lod
);
}
}
public
SurfaceFeatureType
getSurfaceFeatureType
()
{
return
featureType
;
}
public
BoundarySurface
getPartOf
()
{
return
partOf
;
}
public
void
setType
(
OpeningType
type
)
{
this
.
type
=
type
;
}
public
OpeningType
getType
()
{
return
type
;
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
}
@Override
public
void
clearAllContainedCheckResults
()
{
super
.
clearCheckResults
();
}
public
void
unsetGmlGeometries
()
{
ao
.
setLod0MultiSurface
(
null
);
ao
.
setLod1MultiSurface
(
null
);
ao
.
setLod2MultiSurface
(
null
);
ao
.
setLod3MultiSurface
(
null
);
ao
.
getDeprecatedProperties
().
setLod4MultiSurface
(
null
);
}
@Override
public
String
toString
()
{
return
"Opening [type="
+
type
+
", id="
+
getGmlId
()
+
"]"
;
}
public
void
setPartOfSurface
(
BoundarySurface
boundarySurface
)
{
partOf
=
boundarySurface
;
}
@Override
public
AbstractCityObject
getGmlObject
()
{
return
ao
;
}
@Override
public
FeatureType
getFeatureType
()
{
return
FeatureType
.
OPENING
;
}
@Override
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
);
Opening
originalOpening
=
(
Opening
)
original
;
partOf
=
handler
.
getCopyInstance
(
originalOpening
.
partOf
);
type
=
originalOpening
.
type
;
featureType
=
originalOpening
.
featureType
;
ao
=
originalOpening
.
ao
;
}
@Serial
private
static
final
long
serialVersionUID
=
6409303152284607944L
;
private
BoundarySurface
partOf
;
private
OpeningType
type
;
private
SurfaceFeatureType
featureType
;
private
AbstractFillingSurface
ao
;
private
Opening
(
OpeningType
type
)
{
this
.
type
=
type
;
}
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
(
GeometryFactory
factory
,
ParserConfiguration
config
)
{
if
(
ao
.
getId
()
!=
null
)
{
ao
.
setId
(
getGmlId
().
getGmlString
());
}
for
(
Geometry
geom
:
getGeometries
())
{
if
(
geom
.
getType
()
==
GeometryType
.
MULTI_SURFACE
)
{
MultiSurface
ms
=
CityGmlUtils
.
createMultiSurface
(
geom
,
factory
,
config
);
setGeometryAccordingToLod
(
geom
.
getLod
(),
new
MultiSurfaceProperty
(
ms
));
}
else
{
throw
new
IllegalStateException
(
"Openings 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:
ao
.
setLod3MultiSurface
(
ms
);
break
;
case
LOD4:
ao
.
getDeprecatedProperties
().
setLod4MultiSurface
(
ms
);
break
;
default
:
throw
new
IllegalStateException
(
"Cannot add geometry to opening because lod is not allowed: "
+
lod
);
}
}
public
SurfaceFeatureType
getSurfaceFeatureType
()
{
return
featureType
;
}
public
BoundarySurface
getPartOf
()
{
return
partOf
;
}
public
void
setType
(
OpeningType
type
)
{
this
.
type
=
type
;
}
public
OpeningType
getType
()
{
return
type
;
}
@Override
public
void
accept
(
Check
c
)
{
super
.
accept
(
c
);
if
(
c
.
canExecute
(
this
))
{
c
.
check
(
this
);
}
}
@Override
public
void
clearAllContainedCheckResults
()
{
super
.
clearCheckResults
();
}
public
void
unsetGmlGeometries
()
{
ao
.
setLod0MultiSurface
(
null
);
ao
.
setLod1MultiSurface
(
null
);
ao
.
setLod2MultiSurface
(
null
);
ao
.
setLod3MultiSurface
(
null
);
ao
.
getDeprecatedProperties
().
setLod4MultiSurface
(
null
);
}
@Override
public
String
toString
()
{
return
"Opening [type="
+
type
+
", id="
+
getGmlId
()
+
"]"
;
}
public
void
setPartOfSurface
(
BoundarySurface
boundarySurface
)
{
partOf
=
boundarySurface
;
}
@Override
public
AbstractCityObject
getGmlObject
()
{
return
ao
;
}
@Override
public
FeatureType
getFeatureType
()
{
return
FeatureType
.
OPENING
;
}
@Override
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
);
Opening
originalOpening
=
(
Opening
)
original
;
partOf
=
handler
.
getCopyInstance
(
originalOpening
.
partOf
);
type
=
originalOpening
.
type
;
featureType
=
originalOpening
.
featureType
;
ao
=
originalOpening
.
ao
;
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/OpeningType.java
View file @
02de0a22
/*-
* 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
...
...
@@ -20,12 +20,11 @@ package de.hft.stuttgart.citydoctor2.datastructure;
/**
* The available opening types in CityGML
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
enum
OpeningType
{
DOOR
,
WINDOW
,
UNKNOWN
DOOR
,
WINDOW
,
UNKNOWN
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Polygon.java
View file @
02de0a22
/*-
* 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
...
...
@@ -18,70 +18,70 @@
*/
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
java.io.Serial
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
import
de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon
;
import
java.io.Serial
;
import
java.util.List
;
/**
* Interface for concrete and linked polygons.
*
* @author Matthias Betz
*
* @author Matthias Betz
*/
public
abstract
class
Polygon
extends
GmlElement
{
@Serial
private
static
final
long
serialVersionUID
=
-
613942946364706513L
;
@Serial
private
static
final
long
serialVersionUID
=
-
613942946364706513L
;
public
abstract
Vector3d
calculateNormalNormalized
();
public
abstract
Vector3d
calculateNormal
();
public
abstract
TesselatedPolygon
tesselate
();
public
abstract
Vector3d
calculateNormalNormalized
();
public
abstract
Vector3d
calculateNormal
();
public
abstract
LinearRing
getExteriorRing
();
public
abstract
TesselatedPolygon
tesselate
();
public
abstract
List
<
LinearRing
>
getInnerRings
();
public
abstract
LinearRing
get
ExteriorRing
();
public
abstract
boolean
isPointInside
ExteriorRing
(
Vector3d
v
);
public
abstract
List
<
LinearRing
>
getInnerRings
();
public
abstract
Geometry
getParent
();
public
abstract
boolean
isPointInsideExteriorRing
(
Vector3d
v
);
public
abstract
void
setParent
(
Geometry
geometry
);
public
abstract
Geometry
getParent
(
);
public
abstract
void
setExteriorRing
(
LinearRing
extRing
);
public
abstract
void
setParent
(
Geometry
geometry
);
public
abstract
boolean
isPolygonConnectedViaPoint
(
Polygon
other
);
public
abstract
void
setEx
teriorRing
(
LinearRing
extRing
);
public
abstract
void
addIn
teriorRing
(
LinearRing
inter
);
public
abstract
boolean
isPolygonConnectedViaPoint
(
Polygon
other
);
public
abstract
BoundarySurface
getPartOfSurface
(
);
public
abstract
void
addInteriorRing
(
LinearRing
inter
);
public
abstract
void
setPartOfSurface
(
BoundarySurface
bs
);
public
abstract
BoundarySurface
getPartOfSurface
(
);
public
abstract
void
removeInnerRing
(
LinearRing
ring
);
public
abstract
void
setPartOf
Surface
(
BoundarySurface
b
s
);
public
abstract
void
setPartOf
Installation
(
Installation
b
i
);
public
abstract
void
removeInnerRing
(
LinearRing
ring
);
public
abstract
Installation
getPartOfInstallation
(
);
public
abstract
void
setPartOfInstallation
(
Installation
bi
);
public
abstract
boolean
hasPointAsCorner
(
Vertex
v
);
public
abstract
Installation
getPartOfInstallation
();
public
abstract
void
removeRings
();
public
abstract
boolean
hasPointAsCorner
(
Vertex
v
);
public
abstract
boolean
isLinkedTo
(
);
public
abstract
void
removeRings
();
public
abstract
boolean
isLink
();
public
abstract
boolean
isLinkedTo
();
public
abstract
LinkedPolygon
getLinkedFromPolygon
();
public
abstract
boolean
isLink
();
abstract
void
anonymize
();
public
abstract
Linked
Polygon
get
LinkedFromPolygon
();
public
abstract
Concrete
Polygon
get
Original
();
abstract
void
anonymiz
e
();
public
abstract
void
remov
e
();
public
abstract
ConcretePolygon
getOriginal
();
public
abstract
void
remove
();
public
abstract
double
getArea
();
public
abstract
double
getArea
();
}
\ No newline at end of file
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/RelativeGeometry.java
View file @
02de0a22
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
de.hft.stuttgart.citydoctor2.utils.CopyHandler
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
...
...
@@ -10,6 +9,8 @@ import java.util.HashMap;
/**
* Reference object for handling of implicit geometries with a relative geometry
*
* @author Riegel
*/
public
class
RelativeGeometry
extends
Geometry
{
...
...
@@ -17,16 +18,16 @@ public class RelativeGeometry extends Geometry {
@Serial
private
static
final
long
serialVersionUID
=
-
686112245455298977L
;
private
static
HashMap
<
Geometry
,
RelativeGeometry
>
relativeGeometries
=
new
HashMap
<>();
private
static
HashMap
<
Geometry
,
RelativeGeometry
>
relativeGeometries
=
new
HashMap
<>();
public
static
RelativeGeometry
of
(
Geometry
geom
){
if
(
relativeGeometries
.
containsKey
(
geom
)){
public
static
RelativeGeometry
of
(
Geometry
geom
)
{
if
(
relativeGeometries
.
containsKey
(
geom
))
{
return
relativeGeometries
.
get
(
geom
);
}
RelativeGeometry
relGeo
=
new
RelativeGeometry
(
geom
.
getType
(),
geom
.
getLod
());
RelativeGeometry
relGeo
=
new
RelativeGeometry
(
geom
.
getType
(),
geom
.
getLod
());
geom
.
getPolygons
().
forEach
(
relGeo:
:
addPolygon
);
relGeo
.
updateEdgesAndVertices
();
relativeGeometries
.
put
(
geom
,
relGeo
);
relativeGeometries
.
put
(
geom
,
relGeo
);
return
relGeo
;
}
...
...
Prev
1
2
3
4
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment