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
1fc540d9
Commit
1fc540d9
authored
Nov 28, 2025
by
Matthias Betz
Browse files
fix solid self intersection false positives
parent
ad52781c
Pipeline
#12155
passed with stage
in 1 minute and 58 seconds
Changes
15
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/SchematronError.java
View file @
1fc540d9
...
@@ -59,6 +59,7 @@ public class SchematronError implements CheckError {
...
@@ -59,6 +59,7 @@ public class SchematronError implements CheckError {
@Override
@Override
public
void
report
(
ErrorReport
report
)
{
public
void
report
(
ErrorReport
report
)
{
report
.
add
(
"errorId"
,
errorId
);
report
.
add
(
"errorId"
,
errorId
);
report
.
add
(
"message"
,
nameOfAttribute
);
}
}
@Override
@Override
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObject.java
View file @
1fc540d9
...
@@ -61,15 +61,11 @@ public class BridgeObject extends CityObject {
...
@@ -61,15 +61,11 @@ public class BridgeObject extends CityObject {
private
BridgeObject
parent
;
private
BridgeObject
parent
;
public
BridgeObject
(
AbstractBridge
ab
)
{
public
BridgeObject
(
AbstractBridge
ab
)
{
this
.
ab
=
ab
;
this
(
BridgeType
.
BRIDGE
,
ab
,
null
);
this
.
type
=
BridgeType
.
BRIDGE
;
this
.
parent
=
null
;
}
}
public
BridgeObject
(
AbstractBridge
ab
,
BridgeObject
parent
)
{
public
BridgeObject
(
AbstractBridge
ab
,
BridgeObject
parent
)
{
this
.
ab
=
ab
;
this
(
BridgeType
.
BRIDGE_PART
,
ab
,
parent
);
this
.
type
=
BridgeType
.
BRIDGE_PART
;
this
.
parent
=
parent
;
}
}
private
BridgeObject
(
BridgeType
type
,
AbstractBridge
ab
,
BridgeObject
parent
)
{
private
BridgeObject
(
BridgeType
type
,
AbstractBridge
ab
,
BridgeObject
parent
)
{
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingConstructiveElement.java
View file @
1fc540d9
package
de.hft.stuttgart.citydoctor2.datastructure
;
package
de.hft.stuttgart.citydoctor2.datastructure
;
import
de.hft.stuttgart.citydoctor2.check.CheckableVisitor
;
import
java.io.Serial
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
java.util.ArrayList
;
import
de.hft.stuttgart.citydoctor2.utils.CityGmlUtils
;
import
java.util.List
;
import
javafx.scene.paint.Color
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.apache.logging.log4j.Logger
;
import
org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty
;
import
org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty
;
import
org.citygml4j.core.model.deprecated.bridge.DeprecatedPropertiesOfBridgeConstructiveElement
;
import
org.citygml4j.core.util.geometry.GeometryFactory
;
import
org.citygml4j.core.util.geometry.GeometryFactory
;
import
org.xmlobjects.gml.model.geometry.GeometryProperty
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurface
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty
;
import
org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty
;
import
org.xmlobjects.gml.model.geometry.complexes.CompositeSurface
;
import
org.xmlobjects.gml.model.geometry.primitives.Solid
;
import
org.xmlobjects.gml.model.geometry.primitives.Solid
;
import
org.xmlobjects.gml.model.geometry.primitives.SolidProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.SolidProperty
;
import
org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty
;
import
java.io.Serial
;
import
de.hft.stuttgart.citydoctor2.check.CheckableVisitor
;
import
java.util.ArrayList
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.utils.CityGmlUtils
;
import
javafx.scene.paint.Color
;
public
class
BuildingConstructiveElement
extends
CityObject
{
public
class
BuildingConstructiveElement
extends
CityObject
{
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Opening.java
View file @
1fc540d9
...
@@ -48,10 +48,6 @@ public class Opening extends CityObject {
...
@@ -48,10 +48,6 @@ public class Opening extends CityObject {
private
AbstractFillingSurface
ao
;
private
AbstractFillingSurface
ao
;
private
Opening
(
OpeningType
type
)
{
this
.
type
=
type
;
}
public
Opening
(
OpeningType
type
,
SurfaceFeatureType
featureType
,
BoundarySurface
partOf
,
public
Opening
(
OpeningType
type
,
SurfaceFeatureType
featureType
,
BoundarySurface
partOf
,
AbstractFillingSurface
ao
)
{
AbstractFillingSurface
ao
)
{
this
.
featureType
=
featureType
;
this
.
featureType
=
featureType
;
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TunnelPart.java
View file @
1fc540d9
...
@@ -9,6 +9,8 @@ public class TunnelPart extends AbstractTunnel {
...
@@ -9,6 +9,8 @@ public class TunnelPart extends AbstractTunnel {
private
Tunnel
parent
;
private
Tunnel
parent
;
private
TunnelPart
()
{
}
public
TunnelPart
(
Tunnel
parent
)
{
public
TunnelPart
(
Tunnel
parent
)
{
this
.
parent
=
parent
;
this
.
parent
=
parent
;
...
@@ -34,6 +36,4 @@ public class TunnelPart extends AbstractTunnel {
...
@@ -34,6 +36,4 @@ public class TunnelPart extends AbstractTunnel {
return
"TunnelPart [id="
+
getGmlId
()
+
"]"
;
return
"TunnelPart [id="
+
getGmlId
()
+
"]"
;
}
}
private
TunnelPart
()
{
}
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Triangle3d.java
View file @
1fc540d9
...
@@ -87,8 +87,13 @@ public class Triangle3d implements Serializable {
...
@@ -87,8 +87,13 @@ public class Triangle3d implements Serializable {
Vector3d
n2
=
v1
.
cross
(
v2
);
Vector3d
n2
=
v1
.
cross
(
v2
);
return
new
Plane
(
n2
,
p1
);
return
new
Plane
(
n2
,
p1
);
}
}
public
boolean
doesIntersect
(
Triangle3d
other
)
{
public
boolean
doesIntersect
(
Triangle3d
other
)
{
return
doesIntersect
(
other
,
EPSILON
);
}
public
boolean
doesIntersect
(
Triangle3d
other
,
double
epsilon
)
{
// plane of other triangle
// plane of other triangle
Plane
planeT2
=
other
.
getPlane
();
Plane
planeT2
=
other
.
getPlane
();
// check if all points are on one side of the plane
// check if all points are on one side of the plane
...
@@ -96,13 +101,13 @@ public class Triangle3d implements Serializable {
...
@@ -96,13 +101,13 @@ public class Triangle3d implements Serializable {
double
distanceP2T2
=
planeT2
.
getSignedDistance
(
p2
);
double
distanceP2T2
=
planeT2
.
getSignedDistance
(
p2
);
double
distanceP3T2
=
planeT2
.
getSignedDistance
(
p3
);
double
distanceP3T2
=
planeT2
.
getSignedDistance
(
p3
);
if
(
Math
.
abs
(
distanceP1T2
)
<
EPSILON
)
{
if
(
Math
.
abs
(
distanceP1T2
)
<
epsilon
)
{
distanceP1T2
=
0.0
;
distanceP1T2
=
0.0
;
}
}
if
(
Math
.
abs
(
distanceP2T2
)
<
EPSILON
)
{
if
(
Math
.
abs
(
distanceP2T2
)
<
epsilon
)
{
distanceP2T2
=
0.0
;
distanceP2T2
=
0.0
;
}
}
if
(
Math
.
abs
(
distanceP3T2
)
<
EPSILON
)
{
if
(
Math
.
abs
(
distanceP3T2
)
<
epsilon
)
{
distanceP3T2
=
0.0
;
distanceP3T2
=
0.0
;
}
}
...
@@ -123,13 +128,13 @@ public class Triangle3d implements Serializable {
...
@@ -123,13 +128,13 @@ public class Triangle3d implements Serializable {
double
distanceP2T1
=
planeT1
.
getSignedDistance
(
other
.
getP2
());
double
distanceP2T1
=
planeT1
.
getSignedDistance
(
other
.
getP2
());
double
distanceP3T1
=
planeT1
.
getSignedDistance
(
other
.
getP3
());
double
distanceP3T1
=
planeT1
.
getSignedDistance
(
other
.
getP3
());
if
(
Math
.
abs
(
distanceP1T1
)
<
EPSILON
)
{
if
(
Math
.
abs
(
distanceP1T1
)
<
epsilon
)
{
distanceP1T1
=
0.0
;
distanceP1T1
=
0.0
;
}
}
if
(
Math
.
abs
(
distanceP2T1
)
<
EPSILON
)
{
if
(
Math
.
abs
(
distanceP2T1
)
<
epsilon
)
{
distanceP2T1
=
0.0
;
distanceP2T1
=
0.0
;
}
}
if
(
Math
.
abs
(
distanceP3T1
)
<
EPSILON
)
{
if
(
Math
.
abs
(
distanceP3T1
)
<
epsilon
)
{
distanceP3T1
=
0.0
;
distanceP3T1
=
0.0
;
}
}
...
@@ -139,11 +144,15 @@ public class Triangle3d implements Serializable {
...
@@ -139,11 +144,15 @@ public class Triangle3d implements Serializable {
return
false
;
return
false
;
}
}
return
checkTriangleLineIntersection
(
other
,
p1
,
p2
)
||
checkTriangleLineIntersection
(
other
,
p1
,
p3
)
boolean
intersects
=
checkTriangleLineIntersection
(
other
,
p1
,
p2
)
||
checkTriangleLineIntersection
(
other
,
p1
,
p3
)
||
checkTriangleLineIntersection
(
other
,
p2
,
p3
)
||
checkTriangleLineIntersection
(
other
,
p2
,
p3
)
||
checkTriangleLineIntersection
(
this
,
other
.
p1
,
other
.
p2
)
||
checkTriangleLineIntersection
(
this
,
other
.
p1
,
other
.
p2
)
||
checkTriangleLineIntersection
(
this
,
other
.
p1
,
other
.
p3
)
||
checkTriangleLineIntersection
(
this
,
other
.
p1
,
other
.
p3
)
||
checkTriangleLineIntersection
(
this
,
other
.
p2
,
other
.
p3
);
||
checkTriangleLineIntersection
(
this
,
other
.
p2
,
other
.
p3
);
if
(
intersects
)
{
System
.
out
.
println
();
}
return
intersects
;
}
}
private
boolean
checkTriangleLineIntersection
(
Triangle3d
other
,
Vector3d
a
,
Vector3d
b
)
{
private
boolean
checkTriangleLineIntersection
(
Triangle3d
other
,
Vector3d
a
,
Vector3d
b
)
{
...
@@ -171,7 +180,11 @@ public class Triangle3d implements Serializable {
...
@@ -171,7 +180,11 @@ public class Triangle3d implements Serializable {
private
boolean
doesIntersectCoplanarTriangle
(
Triangle3d
other
)
{
private
boolean
doesIntersectCoplanarTriangle
(
Triangle3d
other
)
{
Triangle2d
t1
=
projectTo2d
();
Triangle2d
t1
=
projectTo2d
();
Triangle2d
t2
=
other
.
projectTo2d
();
Triangle2d
t2
=
other
.
projectTo2d
();
return
t1
.
intersects
(
t2
);
boolean
intersects
=
t1
.
intersects
(
t2
);
if
(
intersects
)
{
System
.
out
.
println
();
}
return
intersects
;
}
}
public
Triangle2d
projectTo2d
()
{
public
Triangle2d
projectTo2d
()
{
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/tesselation/EarcutTesselator.java
View file @
1fc540d9
...
@@ -49,6 +49,15 @@ public class EarcutTesselator {
...
@@ -49,6 +49,15 @@ public class EarcutTesselator {
start
=
addRingToArray
(
innerRing
,
vertices
,
start
,
axis
);
start
=
addRingToArray
(
innerRing
,
vertices
,
start
,
axis
);
}
}
// center vertices?
// double[] projectedCenter = new double[2];
// Geometry geometry = p.getParent();
// Vector3d center = geometry.getCenter();
// axis.writeCoordinatesOfVectorInArray(center, projectedCenter, 0);
// for (int i = 0; i < vertices.length; i++) {
// vertices[i] = vertices[i] - projectedCenter[i % 2];
// }
// triangulation
// triangulation
List
<
Integer
>
indices
=
Earcut
.
earcut
(
vertices
,
holeStart
,
2
);
List
<
Integer
>
indices
=
Earcut
.
earcut
(
vertices
,
holeStart
,
2
);
List
<
Triangle3d
>
triangles
=
new
ArrayList
<>();
List
<
Triangle3d
>
triangles
=
new
ArrayList
<>();
...
@@ -56,14 +65,15 @@ public class EarcutTesselator {
...
@@ -56,14 +65,15 @@ public class EarcutTesselator {
throw
new
IllegalStateException
();
throw
new
IllegalStateException
();
}
}
for
(
int
i
=
0
;
i
<
indices
.
size
();
i
=
i
+
3
)
{
for
(
int
i
=
0
;
i
<
indices
.
size
();
i
=
i
+
3
)
{
Triangle3d
t
=
new
Triangle3d
(
vertexObjects
.
get
(
indices
.
get
(
i
+
0
)),
Vertex
v1
=
vertexObjects
.
get
(
indices
.
get
(
i
+
0
));
vertexObjects
.
get
(
indices
.
get
(
i
+
1
)),
Vertex
v2
=
vertexObjects
.
get
(
indices
.
get
(
i
+
1
));
vertexObjects
.
get
(
indices
.
get
(
i
+
2
)));
Vertex
v3
=
vertexObjects
.
get
(
indices
.
get
(
i
+
2
));
Triangle3d
t
=
new
Triangle3d
(
v1
,
v2
,
v3
);
triangles
.
add
(
t
);
triangles
.
add
(
t
);
}
}
return
new
TesselatedPolygon
(
triangles
,
p
);
return
new
TesselatedPolygon
(
triangles
,
p
);
}
}
private
static
void
addVerticesToList
(
LinearRing
ring
,
List
<
Vertex
>
vertexObjects
)
{
private
static
void
addVerticesToList
(
LinearRing
ring
,
List
<
Vertex
>
vertexObjects
)
{
List
<
Vertex
>
vertices
=
ring
.
getVertices
();
List
<
Vertex
>
vertices
=
ring
.
getVertices
();
for
(
int
i
=
0
;
i
<
vertices
.
size
()
-
1
;
i
++)
{
for
(
int
i
=
0
;
i
<
vertices
.
size
()
-
1
;
i
++)
{
...
...
CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
View file @
1fc540d9
...
@@ -203,26 +203,60 @@ public class Checker {
...
@@ -203,26 +203,60 @@ public class Checker {
}
}
private
void
handleSchematronResults
(
SvrlContentHandler
handler
)
{
private
void
handleSchematronResults
(
SvrlContentHandler
handler
)
{
model
.
addGlobalErrors
(
handler
.
getGeneralErrors
());
handleSchematronErrorsGlobal
(
handler
.
getGeneralErrors
());
Map
<
String
,
CityObject
>
featureMap
=
new
HashMap
<>();
Map
<
String
,
CityObject
>
featureMap
=
new
HashMap
<>();
model
.
createFeatureStream
().
forEach
(
f
->
featureMap
.
put
(
f
.
getGmlId
().
getGmlString
(),
f
));
boolean
onlySchematron
=
execLayers
.
isEmpty
();
if
(
onlySchematron
)
{
CheckableUtilsVisitor
visitor
=
new
CheckableUtilsVisitor
()
{
@Override
public
void
check
(
Checkable
checkable
)
{
checkable
.
setValidated
(
true
);
}
};
model
.
createFeatureStream
().
forEach
(
f
->
{
featureMap
.
put
(
f
.
getGmlId
().
getGmlString
(),
f
);
f
.
accept
(
visitor
);
});
}
else
{
model
.
createFeatureStream
().
forEach
(
f
->
featureMap
.
put
(
f
.
getGmlId
().
getGmlString
(),
f
));
}
handler
.
getFeatureErrors
().
forEach
((
k
,
v
)
->
{
handler
.
getFeatureErrors
().
forEach
((
k
,
v
)
->
{
if
(
k
.
trim
().
isEmpty
())
{
if
(
k
.
trim
().
isEmpty
())
{
// missing gml id, ignore?
handleSchematronErrorsGlobal
(
v
);
return
;
return
;
}
}
CityObject
co
=
featureMap
.
get
(
k
);
CityObject
co
=
featureMap
.
get
(
k
);
if
(
co
==
null
)
{
if
(
co
==
null
)
{
// gml id reported by schematron was not found, add to general errors
// gml id reported by schematron was not found, add to general errors
for
(
SchematronError
se
:
v
)
{
handleSchematronErrorsGlobal
(
v
);
model
.
addGlobalError
(
se
);
}
// for (SchematronError se : v) {
// model.addGlobalError(se);
// }
}
else
{
}
else
{
handleSchematronErrorsForCityObject
(
v
,
co
);
handleSchematronErrorsForCityObject
(
v
,
co
);
co
.
setValidated
(
true
);
}
}
});
});
}
}
private
void
handleSchematronErrorsGlobal
(
List
<
SchematronError
>
v
)
{
for
(
SchematronError
se
:
v
)
{
// CheckError err;
// if (AttributeMissingError.ID.getIdString().equals(se.getErrorIdString())) {
// err = new AttributeMissingError(null, se.getChildId(), se.getNameOfAttribute());
// } else if (AttributeValueWrongError.ID.getIdString().equals(se.getErrorIdString())) {
// err = new AttributeValueWrongError(null, se.getChildId(), se.getNameOfAttribute());
// } else if (AttributeInvalidError.ID.getIdString().equals(se.getErrorIdString())) {
// err = new AttributeInvalidError(null, se.getChildId(), se.getNameOfAttribute());
// } else {
// throw new IllegalStateException(
// "Unknown error ID was given in schematron file: " + se.getErrorIdString());
// }
model
.
addGlobalError
(
se
);
}
}
public
static
void
handleSchematronErrorsForCityObject
(
List
<
SchematronError
>
v
,
CityObject
co
)
{
public
static
void
handleSchematronErrorsForCityObject
(
List
<
SchematronError
>
v
,
CityObject
co
)
{
int
count
=
0
;
int
count
=
0
;
for
(
SchematronError
se
:
v
)
{
for
(
SchematronError
se
:
v
)
{
...
@@ -435,7 +469,6 @@ public class Checker {
...
@@ -435,7 +469,6 @@ public class Checker {
}
}
}
}
@SuppressWarnings
(
"resource"
)
public
static
SvrlContentHandler
executeSchematronValidationIfAvailable
(
ValidationConfiguration
config
,
public
static
SvrlContentHandler
executeSchematronValidationIfAvailable
(
ValidationConfiguration
config
,
InputStream
in
)
{
InputStream
in
)
{
if
(
config
.
getSchematronFilePath
()
!=
null
&&
!
config
.
getSchematronFilePath
().
isEmpty
())
{
if
(
config
.
getSchematronFilePath
()
!=
null
&&
!
config
.
getSchematronFilePath
().
isEmpty
())
{
...
...
CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/SvrlContentHandler.java
View file @
1fc540d9
...
@@ -106,7 +106,7 @@ public class SvrlContentHandler implements ContentHandler {
...
@@ -106,7 +106,7 @@ public class SvrlContentHandler implements ContentHandler {
throw
new
IllegalStateException
(
throw
new
IllegalStateException
(
"Schematron File is not formed according to specification for CityDoctor."
);
"Schematron File is not formed according to specification for CityDoctor."
);
}
}
String
gmlId
=
split
[
0
];
String
gmlId
=
split
[
0
]
.
strip
()
;
String
childId
=
split
[
1
];
String
childId
=
split
[
1
];
String
errorId
=
split
[
2
];
String
errorId
=
split
[
2
];
String
nameOfAttribute
=
split
[
3
];
String
nameOfAttribute
=
split
[
3
];
...
...
CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PlanarCheck.java
View file @
1fc540d9
...
@@ -57,10 +57,12 @@ import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon;
...
@@ -57,10 +57,12 @@ import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon;
*/
*/
public
class
PlanarCheck
extends
Check
{
public
class
PlanarCheck
extends
Check
{
private
static
final
String
DISTANCE
=
"distance"
;
public
static
final
String
ANGLE
=
"angle"
;
private
static
final
String
DISTANCE_TOLERANCE
=
"distanceTolerance"
;
public
static
final
String
DISTANCE
=
"distance"
;
public
static
final
String
BOTH
=
"both"
;
public
static
final
String
DISTANCE_TOLERANCE
=
"distanceTolerance"
;
private
static
final
String
ANGLE_TOLERANCE
=
"angleTolerance"
;
private
static
final
String
ANGLE_TOLERANCE
=
"angleTolerance"
;
p
rivate
static
final
String
TYPE
=
"type"
;
p
ublic
static
final
String
TYPE
=
"type"
;
private
static
final
List
<
CheckId
>
dependencies
;
private
static
final
List
<
CheckId
>
dependencies
;
...
@@ -97,7 +99,7 @@ public class PlanarCheck extends Check {
...
@@ -97,7 +99,7 @@ public class PlanarCheck extends Check {
public
void
check
(
Polygon
p
)
{
public
void
check
(
Polygon
p
)
{
if
(
DISTANCE
.
equals
(
planarCheckType
))
{
if
(
DISTANCE
.
equals
(
planarCheckType
))
{
planarDistance
(
p
);
planarDistance
(
p
);
}
else
if
(
"angle"
.
equals
(
planarCheckType
))
{
}
else
if
(
ANGLE
.
equals
(
planarCheckType
))
{
planarNormalDeviation
(
p
);
planarNormalDeviation
(
p
);
}
else
if
(
"both"
.
equals
(
planarCheckType
))
{
}
else
if
(
"both"
.
equals
(
planarCheckType
))
{
planarDistance
(
p
);
planarDistance
(
p
);
...
...
CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheck.java
View file @
1fc540d9
...
@@ -21,13 +21,13 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
...
@@ -21,13 +21,13 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.Set
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
import
de.hft.stuttgart.citydoctor2.check.CheckId
;
import
de.hft.stuttgart.citydoctor2.check.CheckId
;
import
de.hft.stuttgart.citydoctor2.check.CheckResult
;
import
de.hft.stuttgart.citydoctor2.check.CheckResult
;
import
de.hft.stuttgart.citydoctor2.check.GeometrySelfIntersection
;
import
de.hft.stuttgart.citydoctor2.check.Requirement
;
import
de.hft.stuttgart.citydoctor2.check.Requirement
;
import
de.hft.stuttgart.citydoctor2.check.RequirementType
;
import
de.hft.stuttgart.citydoctor2.check.RequirementType
;
import
de.hft.stuttgart.citydoctor2.check.ResultStatus
;
import
de.hft.stuttgart.citydoctor2.check.ResultStatus
;
...
@@ -36,6 +36,7 @@ import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils;
...
@@ -36,6 +36,7 @@ import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils;
import
de.hft.stuttgart.citydoctor2.checks.util.SelfIntersectionUtil
;
import
de.hft.stuttgart.citydoctor2.checks.util.SelfIntersectionUtil
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
de.hft.stuttgart.citydoctor2.utils.PolygonIntersection
;
import
de.hft.stuttgart.citydoctor2.utils.PolygonIntersection
;
/**
/**
...
@@ -47,7 +48,9 @@ import de.hft.stuttgart.citydoctor2.utils.PolygonIntersection;
...
@@ -47,7 +48,9 @@ import de.hft.stuttgart.citydoctor2.utils.PolygonIntersection;
public
class
SolidSelfIntCheck
extends
Check
{
public
class
SolidSelfIntCheck
extends
Check
{
private
static
final
List
<
CheckId
>
dependencies
;
private
static
final
List
<
CheckId
>
dependencies
;
private
double
delta
=
0.01
;
static
{
static
{
ArrayList
<
CheckId
>
deps
=
new
ArrayList
<>();
ArrayList
<
CheckId
>
deps
=
new
ArrayList
<>();
dependencies
=
Collections
.
unmodifiableList
(
deps
);
dependencies
=
Collections
.
unmodifiableList
(
deps
);
...
@@ -68,6 +71,13 @@ public class SolidSelfIntCheck extends Check {
...
@@ -68,6 +71,13 @@ public class SolidSelfIntCheck extends Check {
deps
.
add
(
CheckId
.
C_GE_S_NON_MANIFOLD_VERTEX
);
deps
.
add
(
CheckId
.
C_GE_S_NON_MANIFOLD_VERTEX
);
deps
.
add
(
CheckId
.
C_GE_S_POLYGON_WRONG_ORIENTATION
);
deps
.
add
(
CheckId
.
C_GE_S_POLYGON_WRONG_ORIENTATION
);
}
}
@Override
public
void
init
(
Map
<
String
,
String
>
parameters
,
ParserConfiguration
config
)
{
if
(
parameters
.
containsKey
(
PlanarCheck
.
DISTANCE_TOLERANCE
))
{
delta
=
Double
.
parseDouble
(
parameters
.
get
(
PlanarCheck
.
DISTANCE_TOLERANCE
));
}
}
@Override
@Override
public
void
check
(
Geometry
g
)
{
public
void
check
(
Geometry
g
)
{
...
@@ -75,7 +85,7 @@ public class SolidSelfIntCheck extends Check {
...
@@ -75,7 +85,7 @@ public class SolidSelfIntCheck extends Check {
return
;
return
;
}
}
CheckResult
cr
;
CheckResult
cr
;
List
<
PolygonIntersection
>
intersections
=
SelfIntersectionUtil
.
calculateSolidSelfIntersection
(
g
);
List
<
PolygonIntersection
>
intersections
=
SelfIntersectionUtil
.
calculateSolidSelfIntersection
(
g
,
delta
);
if
(
intersections
.
isEmpty
())
{
if
(
intersections
.
isEmpty
())
{
cr
=
new
CheckResult
(
this
,
ResultStatus
.
OK
,
null
);
cr
=
new
CheckResult
(
this
,
ResultStatus
.
OK
,
null
);
}
else
{
}
else
{
...
@@ -85,18 +95,6 @@ public class SolidSelfIntCheck extends Check {
...
@@ -85,18 +95,6 @@ public class SolidSelfIntCheck extends Check {
g
.
addCheckResult
(
cr
);
g
.
addCheckResult
(
cr
);
}
}
@SuppressWarnings
(
"unused"
)
private
CheckResult
oldIntersectionAlgorithm
(
Geometry
g
)
{
CheckResult
cr
;
GeometrySelfIntersection
intersect
=
SelfIntersectionUtil
.
doesSolidSelfIntersect
(
g
);
if
(
intersect
!=
null
)
{
cr
=
new
CheckResult
(
this
,
ResultStatus
.
ERROR
,
null
);
}
else
{
cr
=
new
CheckResult
(
this
,
ResultStatus
.
OK
,
null
);
}
return
cr
;
}
@Override
@Override
public
List
<
CheckId
>
getDependencies
()
{
public
List
<
CheckId
>
getDependencies
()
{
return
dependencies
;
return
dependencies
;
...
...
CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/util/SelfIntersectionUtil.java
View file @
1fc540d9
...
@@ -21,6 +21,7 @@ package de.hft.stuttgart.citydoctor2.checks.util;
...
@@ -21,6 +21,7 @@ package de.hft.stuttgart.citydoctor2.checks.util;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.IdentityHashMap
;
import
java.util.IdentityHashMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -39,6 +40,8 @@ import org.locationtech.jts.geom.impl.CoordinateArraySequence;
...
@@ -39,6 +40,8 @@ import org.locationtech.jts.geom.impl.CoordinateArraySequence;
import
org.locationtech.jts.operation.overlay.OverlayOp
;
import
org.locationtech.jts.operation.overlay.OverlayOp
;
import
org.locationtech.jts.operation.overlay.snap.SnapIfNeededOverlayOp
;
import
org.locationtech.jts.operation.overlay.snap.SnapIfNeededOverlayOp
;
import
Jama.EigenvalueDecomposition
;
import
Jama.Matrix
;
import
de.hft.stuttgart.citydoctor2.check.GeometrySelfIntersection
;
import
de.hft.stuttgart.citydoctor2.check.GeometrySelfIntersection
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
...
@@ -50,8 +53,10 @@ import de.hft.stuttgart.citydoctor2.edge.EdgePolygon;
...
@@ -50,8 +53,10 @@ import de.hft.stuttgart.citydoctor2.edge.EdgePolygon;
import
de.hft.stuttgart.citydoctor2.edge.IntersectPlanarPolygons
;
import
de.hft.stuttgart.citydoctor2.edge.IntersectPlanarPolygons
;
import
de.hft.stuttgart.citydoctor2.edge.MeshSurface
;
import
de.hft.stuttgart.citydoctor2.edge.MeshSurface
;
import
de.hft.stuttgart.citydoctor2.edge.PolygonPolygonIntersection
;
import
de.hft.stuttgart.citydoctor2.edge.PolygonPolygonIntersection
;
import
de.hft.stuttgart.citydoctor2.math.CovarianceMatrix
;
import
de.hft.stuttgart.citydoctor2.math.MovedPolygon
;
import
de.hft.stuttgart.citydoctor2.math.MovedPolygon
;
import
de.hft.stuttgart.citydoctor2.math.MovedRing
;
import
de.hft.stuttgart.citydoctor2.math.MovedRing
;
import
de.hft.stuttgart.citydoctor2.math.OrthogonalRegressionPlane
;
import
de.hft.stuttgart.citydoctor2.math.Plane
;
import
de.hft.stuttgart.citydoctor2.math.Plane
;
import
de.hft.stuttgart.citydoctor2.math.PlaneSegmentIntersection
;
import
de.hft.stuttgart.citydoctor2.math.PlaneSegmentIntersection
;
import
de.hft.stuttgart.citydoctor2.math.PlaneSegmentIntersection.Type
;
import
de.hft.stuttgart.citydoctor2.math.PlaneSegmentIntersection.Type
;
...
@@ -83,18 +88,37 @@ public class SelfIntersectionUtil {
...
@@ -83,18 +88,37 @@ public class SelfIntersectionUtil {
private
SelfIntersectionUtil
()
{
private
SelfIntersectionUtil
()
{
}
}
public
static
List
<
PolygonIntersection
>
calculateSolidSelfIntersection
(
Geometry
g
)
{
public
static
List
<
PolygonIntersection
>
calculateSolidSelfIntersection
(
Geometry
g
,
double
delta
)
{
List
<
TesselatedPolygon
>
tesselatedPolygons
=
new
ArrayList
<>();
List
<
TesselatedPolygon
>
tesselatedPolygons
=
new
ArrayList
<>();
for
(
Polygon
p
:
g
.
getPolygons
())
{
for
(
Polygon
p
:
g
.
getPolygons
())
{
tesselatedPolygons
.
add
(
EarcutTesselator
.
tesselatePolygon
(
p
));
TesselatedPolygon
tessPolygon
=
EarcutTesselator
.
tesselatePolygon
(
p
);
for
(
Iterator
<
Triangle3d
>
iterator
=
tessPolygon
.
getTriangles
().
iterator
();
iterator
.
hasNext
();)
{
Triangle3d
t
=
iterator
.
next
();
List
<
Vector3d
>
vertices
=
new
ArrayList
<>(
3
);
vertices
.
add
(
t
.
getP1
());
vertices
.
add
(
t
.
getP2
());
vertices
.
add
(
t
.
getP3
());
Vector3d
centroid
=
CovarianceMatrix
.
getCentroid
(
vertices
);
EigenvalueDecomposition
ed
=
OrthogonalRegressionPlane
.
decompose
(
vertices
,
centroid
);
Matrix
eigenValues
=
ed
.
getD
();
double
[]
eigenValuesArray
=
new
double
[
3
];
eigenValuesArray
[
0
]
=
eigenValues
.
get
(
0
,
0
);
eigenValuesArray
[
1
]
=
eigenValues
.
get
(
1
,
1
);
eigenValuesArray
[
2
]
=
eigenValues
.
get
(
2
,
2
);
if
(
eigenValuesArray
[
1
]
<
delta
)
{
iterator
.
remove
();
}
}
tesselatedPolygons
.
add
(
tessPolygon
);
}
}
List
<
PolygonIntersection
>
intersections
=
new
ArrayList
<>();
List
<
PolygonIntersection
>
intersections
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
tesselatedPolygons
.
size
()
-
1
;
i
++)
{
for
(
int
i
=
0
;
i
<
tesselatedPolygons
.
size
()
-
1
;
i
++)
{
TesselatedPolygon
p1
=
tesselatedPolygons
.
get
(
i
);
TesselatedPolygon
p1
=
tesselatedPolygons
.
get
(
i
);
for
(
int
j
=
i
+
1
;
j
<
tesselatedPolygons
.
size
();
j
++)
{
for
(
int
j
=
i
+
1
;
j
<
tesselatedPolygons
.
size
();
j
++)
{
TesselatedPolygon
p2
=
tesselatedPolygons
.
get
(
j
);
TesselatedPolygon
p2
=
tesselatedPolygons
.
get
(
j
);
GeometrySelfIntersection
intersection
=
doPolygonsIntersect
(
p1
,
p2
);
GeometrySelfIntersection
intersection
=
doPolygonsIntersect
(
p1
,
p2
,
delta
);
if
(
intersection
!=
null
)
{
if
(
intersection
!=
null
)
{
intersections
.
add
(
PolygonIntersection
.
triangles
(
intersection
.
t1
(),
intersection
.
t2
()));
intersections
.
add
(
PolygonIntersection
.
triangles
(
intersection
.
t1
(),
intersection
.
t2
()));
}
}
...
@@ -103,8 +127,8 @@ public class SelfIntersectionUtil {
...
@@ -103,8 +127,8 @@ public class SelfIntersectionUtil {
return
intersections
;
return
intersections
;
}
}
public
static
GeometrySelfIntersection
doesSolidSelfIntersect
(
Geometry
g
)
{
public
static
GeometrySelfIntersection
doesSolidSelfIntersect
(
Geometry
g
,
double
epsilon
)
{
return
selfIntersectionJava
(
g
);
return
selfIntersectionJava
(
g
,
epsilon
);
}
}
public
static
List
<
PolygonIntersection
>
doesSolidSelfIntersect2
(
Geometry
g
)
{
public
static
List
<
PolygonIntersection
>
doesSolidSelfIntersect2
(
Geometry
g
)
{
...
@@ -404,7 +428,7 @@ public class SelfIntersectionUtil {
...
@@ -404,7 +428,7 @@ public class SelfIntersectionUtil {
return
sign
!=
0
;
return
sign
!=
0
;
}
}
private
static
GeometrySelfIntersection
selfIntersectionJava
(
Geometry
g
)
{
private
static
GeometrySelfIntersection
selfIntersectionJava
(
Geometry
g
,
double
epsilon
)
{
List
<
TesselatedPolygon
>
tessPolys
=
new
ArrayList
<>();
List
<
TesselatedPolygon
>
tessPolys
=
new
ArrayList
<>();
for
(
Polygon
p
:
g
.
getPolygons
())
{
for
(
Polygon
p
:
g
.
getPolygons
())
{
tessPolys
.
add
(
JoglTesselator
.
tesselatePolygon
(
p
));
tessPolys
.
add
(
JoglTesselator
.
tesselatePolygon
(
p
));
...
@@ -413,7 +437,7 @@ public class SelfIntersectionUtil {
...
@@ -413,7 +437,7 @@ public class SelfIntersectionUtil {
TesselatedPolygon
p1
=
tessPolys
.
get
(
i
);
TesselatedPolygon
p1
=
tessPolys
.
get
(
i
);
for
(
int
j
=
i
+
1
;
j
<
tessPolys
.
size
();
j
++)
{
for
(
int
j
=
i
+
1
;
j
<
tessPolys
.
size
();
j
++)
{
TesselatedPolygon
p2
=
tessPolys
.
get
(
j
);
TesselatedPolygon
p2
=
tessPolys
.
get
(
j
);
GeometrySelfIntersection
intersection
=
doPolygonsIntersect
(
p1
,
p2
);
GeometrySelfIntersection
intersection
=
doPolygonsIntersect
(
p1
,
p2
,
epsilon
);
if
(
intersection
!=
null
)
{
if
(
intersection
!=
null
)
{
return
intersection
;
return
intersection
;
}
}
...
@@ -422,12 +446,12 @@ public class SelfIntersectionUtil {
...
@@ -422,12 +446,12 @@ public class SelfIntersectionUtil {
return
null
;
return
null
;
}
}
private
static
GeometrySelfIntersection
doPolygonsIntersect
(
TesselatedPolygon
p1
,
TesselatedPolygon
p2
)
{
private
static
GeometrySelfIntersection
doPolygonsIntersect
(
TesselatedPolygon
p1
,
TesselatedPolygon
p2
,
double
epsilon
)
{
for
(
int
p1Index
=
0
;
p1Index
<
p1
.
getTriangles
().
size
();
p1Index
++)
{
for
(
int
p1Index
=
0
;
p1Index
<
p1
.
getTriangles
().
size
();
p1Index
++)
{
for
(
int
p2Index
=
0
;
p2Index
<
p2
.
getTriangles
().
size
();
p2Index
++)
{
for
(
int
p2Index
=
0
;
p2Index
<
p2
.
getTriangles
().
size
();
p2Index
++)
{
Triangle3d
t1
=
p1
.
getTriangles
().
get
(
p1Index
);
Triangle3d
t1
=
p1
.
getTriangles
().
get
(
p1Index
);
Triangle3d
t2
=
p2
.
getTriangles
().
get
(
p2Index
);
Triangle3d
t2
=
p2
.
getTriangles
().
get
(
p2Index
);
if
(
t1
.
doesIntersect
(
t2
))
{
if
(
t1
.
doesIntersect
(
t2
,
epsilon
))
{
logger
.
trace
(
"{} intersects {}"
,
t1
,
t2
);
logger
.
trace
(
"{} intersects {}"
,
t1
,
t2
);
logger
.
trace
(
"GML-ID: {} intersects {}"
,
t1
.
getPartOf
().
getOriginal
().
getGmlId
(),
logger
.
trace
(
"GML-ID: {} intersects {}"
,
t1
.
getPartOf
().
getOriginal
().
getGmlId
(),
t2
.
getPartOf
().
getOriginal
().
getGmlId
());
t2
.
getPartOf
().
getOriginal
().
getGmlId
());
...
...
CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheckTest.java
View file @
1fc540d9
...
@@ -25,14 +25,18 @@ import static org.junit.Assert.assertNotNull;
...
@@ -25,14 +25,18 @@ import static org.junit.Assert.assertNotNull;
import
org.junit.Assert
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
org.junit.Test
;
import
de.hft.stuttgart.citydoctor2.check.CheckId
;
import
de.hft.stuttgart.citydoctor2.check.CheckResult
;
import
de.hft.stuttgart.citydoctor2.check.CheckResult
;
import
de.hft.stuttgart.citydoctor2.check.Checker
;
import
de.hft.stuttgart.citydoctor2.check.Checker
;
import
de.hft.stuttgart.citydoctor2.check.ResultStatus
;
import
de.hft.stuttgart.citydoctor2.check.ResultStatus
;
import
de.hft.stuttgart.citydoctor2.check.ValidationConfiguration
;
import
de.hft.stuttgart.citydoctor2.check.ValidationConfiguration
;
import
de.hft.stuttgart.citydoctor2.check.error.NonPlanarPolygonDistancePlaneError
;
import
de.hft.stuttgart.citydoctor2.checks.util.GeometryTestUtils
;
import
de.hft.stuttgart.citydoctor2.checks.util.GeometryTestUtils
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParseException
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParseException
;
...
@@ -45,6 +49,22 @@ import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
...
@@ -45,6 +49,22 @@ import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
*
*
*/
*/
public
class
SolidSelfIntCheckTest
{
public
class
SolidSelfIntCheckTest
{
@Test
public
void
testDependencyChecking
()
{
Geometry
geom
=
new
Geometry
(
GeometryType
.
SOLID
,
Lod
.
LOD2
,
Orientation
.
OUTWARD
);
ConcretePolygon
p
=
new
ConcretePolygon
();
geom
.
addPolygon
(
p
);
NonPlanarPolygonDistancePlaneError
err
=
new
NonPlanarPolygonDistancePlaneError
(
p
,
2
,
null
,
null
);
CheckResult
cr
=
new
CheckResult
(
CheckId
.
C_GE_P_NON_PLANAR
,
ResultStatus
.
ERROR
,
err
);
p
.
addCheckResult
(
cr
);
SolidSelfIntCheck
selfIntCheck
=
new
SolidSelfIntCheck
();
boolean
canExecute
=
selfIntCheck
.
canExecute
(
geom
);
assertFalse
(
canExecute
);
}
@Test
@Test
public
void
testGoodGeometry
()
{
public
void
testGoodGeometry
()
{
...
...
CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PlanarTest.java
View file @
1fc540d9
...
@@ -31,6 +31,7 @@ import de.hft.stuttgart.citydoctor2.check.CheckResult;
...
@@ -31,6 +31,7 @@ import de.hft.stuttgart.citydoctor2.check.CheckResult;
import
de.hft.stuttgart.citydoctor2.check.Checker
;
import
de.hft.stuttgart.citydoctor2.check.Checker
;
import
de.hft.stuttgart.citydoctor2.check.ErrorId
;
import
de.hft.stuttgart.citydoctor2.check.ErrorId
;
import
de.hft.stuttgart.citydoctor2.check.ResultStatus
;
import
de.hft.stuttgart.citydoctor2.check.ResultStatus
;
import
de.hft.stuttgart.citydoctor2.checks.geometry.PlanarCheck
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParseException
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParseException
;
...
@@ -142,7 +143,7 @@ public class PlanarTest {
...
@@ -142,7 +143,7 @@ public class PlanarTest {
public
void
testPlanarPolygon6
()
throws
CityGmlParseException
,
IOException
,
InvalidGmlFileException
{
public
void
testPlanarPolygon6
()
throws
CityGmlParseException
,
IOException
,
InvalidGmlFileException
{
Map
<
String
,
Map
<
String
,
String
>>
paramMap
=
new
HashMap
<>();
Map
<
String
,
Map
<
String
,
String
>>
paramMap
=
new
HashMap
<>();
Map
<
String
,
String
>
parameter
=
new
HashMap
<>();
Map
<
String
,
String
>
parameter
=
new
HashMap
<>();
parameter
.
put
(
"type"
,
"both"
);
parameter
.
put
(
PlanarCheck
.
TYPE
,
PlanarCheck
.
BOTH
);
parameter
.
put
(
"distanceTolerance"
,
"0.5"
);
parameter
.
put
(
"distanceTolerance"
,
"0.5"
);
paramMap
.
put
(
RequirementId
.
R_GE_P_NON_PLANAR
.
toString
(),
parameter
);
paramMap
.
put
(
RequirementId
.
R_GE_P_NON_PLANAR
.
toString
(),
parameter
);
CityDoctorModel
c
=
TestUtil
.
loadAndCheckCityModel
(
"src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0002-T0002.gml"
,
paramMap
);
CityDoctorModel
c
=
TestUtil
.
loadAndCheckCityModel
(
"src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0002-T0002.gml"
,
paramMap
);
...
...
CityDoctorParent/Extensions/CityDoctorHealerGUI/src/main/java/de/hft/stuttgart/citydoctor2/healer/gui/HealerController.java
View file @
1fc540d9
...
@@ -538,60 +538,45 @@ public class HealerController {
...
@@ -538,60 +538,45 @@ public class HealerController {
}
}
public
void
injectSolid
(
boolean
useBs
,
boolean
useBi
,
boolean
useLod2
,
boolean
useLod3
,
boolean
useLod4
)
{
public
void
injectSolid
(
boolean
useBs
,
boolean
useBi
,
boolean
useLod2
,
boolean
useLod3
,
boolean
useLod4
)
{
if
(
model
==
null
||
currentFeature
==
null
)
{
// if (model == null || currentFeature == null) {
return
;
// return;
}
// }
CityObject
oldFeature
=
currentFeature
;
currentFeature
.
prepareForChecking
();
for
(
Building
b
:
model
.
getBuildings
())
{
if
(
currentFeature
instanceof
BoundarySurface
)
{
// collect polygons
BoundarySurface
surface
=
(
BoundarySurface
)
currentFeature
;
Map
<
Lod
,
List
<
Polygon
>>
availablePolygons
=
new
EnumMap
<>(
Lod
.
class
);
currentFeature
=
surface
.
getParent
();
Map
<
Lod
,
Set
<
Polygon
>>
existingPolygons
=
new
EnumMap
<>(
Lod
.
class
);
}
collectPolygons
(
useBs
,
useBi
,
availablePolygons
,
existingPolygons
,
b
);
if
(!(
currentFeature
instanceof
Building
))
{
if
(
useLod2
)
{
return
;
insertSolidGeometry
(
availablePolygons
,
b
,
existingPolygons
,
Lod
.
LOD2
);
}
}
// collect polygons
if
(
useLod3
)
{
Map
<
Lod
,
List
<
Polygon
>>
availablePolygons
=
new
EnumMap
<>(
Lod
.
class
);
insertSolidGeometry
(
availablePolygons
,
b
,
existingPolygons
,
Lod
.
LOD3
);
Map
<
Lod
,
Set
<
Polygon
>>
existingPolygons
=
new
EnumMap
<>(
Lod
.
class
);
}
Building
b
=
(
Building
)
currentFeature
;
if
(
useLod4
)
{
collectPolygons
(
useBs
,
useBi
,
availablePolygons
,
existingPolygons
,
b
);
insertSolidGeometry
(
availablePolygons
,
b
,
existingPolygons
,
Lod
.
LOD4
);
if
(
useLod2
)
{
}
insertSolidGeometry
(
availablePolygons
,
b
,
existingPolygons
,
Lod
.
LOD2
);
for
(
BuildingPart
part
:
b
.
getBuildingParts
())
{
}
// collect polygons
if
(
useLod3
)
{
availablePolygons
=
new
EnumMap
<>(
Lod
.
class
);
insertSolidGeometry
(
availablePolygons
,
b
,
existingPolygons
,
Lod
.
LOD3
);
existingPolygons
=
new
EnumMap
<>(
Lod
.
class
);
}
collectPolygons
(
useBs
,
useBi
,
availablePolygons
,
existingPolygons
,
part
);
if
(
useLod4
)
{
if
(
useLod2
)
{
insertSolidGeometry
(
availablePolygons
,
b
,
existingPolygons
,
Lod
.
LOD4
);
insertSolidGeometry
(
availablePolygons
,
part
,
existingPolygons
,
Lod
.
LOD2
);
}
if
(
useLod3
)
{
insertSolidGeometry
(
availablePolygons
,
part
,
existingPolygons
,
Lod
.
LOD3
);
}
if
(
useLod4
)
{
insertSolidGeometry
(
availablePolygons
,
part
,
existingPolygons
,
Lod
.
LOD4
);
}
}
}
}
nextFeature
=
null
;
nextGeometry
=
null
;
Lod
lod
=
currentGeometry
.
getLod
();
GeometryType
type
=
GeometryType
.
SOLID
;
currentGeometry
=
Objects
.
requireNonNull
(
currentFeature
.
getGeometry
(
type
,
lod
));
checker
.
executeChecksForCheckable
(
currentFeature
);
healerView
.
getNextErrorList
().
getItems
().
clear
();
healerView
.
getNextMeshGroup
().
getChildren
().
clear
();
updateCurrentErrors
();
currentTriangulatedGeometry
=
TriangulatedGeometry
.
of
(
currentGeometry
);
currentErrorVisitor
.
setGeometry
(
currentTriangulatedGeometry
);
currentTriangulatedGeometry
.
setCullFace
(
culling
);
currentTriangulatedGeometry
.
setDrawMode
(
drawMode
);
healerView
.
zoomOutForBoundingBox
(
currentGeometry
.
calculateBoundingBox
());
healerView
.
getCurrentMeshGroup
().
getChildren
().
clear
();
healerView
.
getCurrentMeshGroup
().
getChildren
().
addAll
(
currentTriangulatedGeometry
.
getMeshes
());
healerView
.
getNextStepBtn
().
setDisable
(
false
);
healerView
.
getHealCompleteBtn
().
setDisable
(
false
);
healerView
.
getAcceptBtn
().
setDisable
(
true
);
healerView
.
getCancelBtn
().
setDisable
(
true
);
healerView
.
getSolidInjectorBtn
().
setDisable
(
true
);
currentFeature
=
oldFeature
;
}
}
private
void
collectPolygons
(
boolean
useBs
,
boolean
useBi
,
Map
<
Lod
,
List
<
Polygon
>>
availablePolygons
,
private
void
collectPolygons
(
boolean
useBs
,
boolean
useBi
,
Map
<
Lod
,
List
<
Polygon
>>
availablePolygons
,
Map
<
Lod
,
Set
<
Polygon
>>
existingPolygons
,
Building
b
)
{
Map
<
Lod
,
Set
<
Polygon
>>
existingPolygons
,
Abstract
Building
b
)
{
if
(
useBs
)
{
if
(
useBs
)
{
collectPolygons
(
availablePolygons
,
b
.
getBoundarySurfaces
());
collectPolygons
(
availablePolygons
,
b
.
getBoundarySurfaces
());
}
}
...
@@ -604,13 +589,13 @@ public class HealerController {
...
@@ -604,13 +589,13 @@ public class HealerController {
collectPolygons
(
availablePolygons
,
bi
.
getBoundarySurfaces
());
collectPolygons
(
availablePolygons
,
bi
.
getBoundarySurfaces
());
}
}
}
}
for
(
Geometry
geom
:
b
.
getGeometries
())
{
//
for (Geometry geom : b.getGeometries()) {
Set
<
Polygon
>
polygons
=
existingPolygons
.
computeIfAbsent
(
geom
.
getLod
(),
l
->
new
HashSet
<>());
//
Set<Polygon> polygons = existingPolygons.computeIfAbsent(geom.getLod(), l -> new HashSet<>());
polygons
.
addAll
(
geom
.
getPolygons
());
//
polygons.addAll(geom.getPolygons());
}
//
}
}
}
private
void
insertSolidGeometry
(
Map
<
Lod
,
List
<
Polygon
>>
availablePolygons
,
Building
b
,
private
void
insertSolidGeometry
(
Map
<
Lod
,
List
<
Polygon
>>
availablePolygons
,
Abstract
Building
b
,
Map
<
Lod
,
Set
<
Polygon
>>
existingPolygons
,
Lod
lod
)
{
Map
<
Lod
,
Set
<
Polygon
>>
existingPolygons
,
Lod
lod
)
{
List
<
Polygon
>
newPolygons
=
availablePolygons
.
get
(
lod
);
List
<
Polygon
>
newPolygons
=
availablePolygons
.
get
(
lod
);
if
(
newPolygons
!=
null
)
{
if
(
newPolygons
!=
null
)
{
...
...
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