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
97a65114
Commit
97a65114
authored
Sep 10, 2024
by
Riegel
Browse files
Merge branch 'dev' into 'master'
Version 3.15.0 See merge request
!8
parents
99c8f6a8
5950ea5f
Pipeline
#10106
passed with stage
in 3 minutes and 15 seconds
Changes
589
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/RandomHeuristic.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.check.HealingMethod
;
import
de.hft.stuttgart.citydoctor2.healer.HealingMethodPrototype
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
public
class
RandomHeuristic
implements
Heuristic
<
HealingPlan
>
{
private
List
<
HealingMethodPrototype
>
availableHealingMethods
;
public
RandomHeuristic
(
List
<
HealingMethodPrototype
>
availableHealingMethods
)
{
this
.
availableHealingMethods
=
availableHealingMethods
;
}
@Override
public
HealingPlan
generate
()
{
List
<
HealingMethod
>
methods
=
new
ArrayList
<>();
for
(
HealingMethodPrototype
proto
:
availableHealingMethods
)
{
methods
.
add
(
proto
.
createMethod
());
}
Collections
.
shuffle
(
methods
);
HealingPlan
plan
=
new
HealingPlan
();
plan
.
getHealingMethods
().
addAll
(
methods
);
System
.
out
.
println
(
"Generated: "
+
plan
);
return
plan
;
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/RandomSwitchMutation.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
java.util.List
;
import
java.util.Random
;
import
de.hft.stuttgart.citydoctor2.check.HealingMethod
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
public
class
RandomSwitchMutation
implements
Mutation
<
HealingPlan
>
{
private
Random
r
=
new
Random
();
@Override
public
HealingPlan
mutate
(
HealingPlan
individual
)
{
double
percentage
=
r
.
nextDouble
();
if
(
percentage
>
0.7
)
{
// mutate 30% of the time
List
<
HealingMethod
>
healingMethods
=
individual
.
getHealingMethods
();
int
index
=
r
.
nextInt
(
healingMethods
.
size
()
-
1
);
HealingMethod
temp
=
healingMethods
.
get
(
index
+
1
);
healingMethods
.
set
(
index
+
1
,
healingMethods
.
get
(
index
));
healingMethods
.
set
(
index
,
temp
);
}
return
individual
;
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/gui/GeneticsGUI.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.healer.genetic.gui
;
import
java.io.IOException
;
import
java.io.UncheckedIOException
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.Set
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.check.CheckId
;
import
de.hft.stuttgart.citydoctor2.check.Checker
;
import
de.hft.stuttgart.citydoctor2.check.Requirement
;
import
de.hft.stuttgart.citydoctor2.check.RequirementType
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundingBox
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GmlId
;
import
de.hft.stuttgart.citydoctor2.gui.MainWindow
;
import
de.hft.stuttgart.citydoctor2.gui.TriangulatedGeometry
;
import
de.hft.stuttgart.citydoctor2.gui.View
;
import
de.hft.stuttgart.citydoctor2.gui.ViewRegistration
;
import
de.hft.stuttgart.citydoctor2.healer.HealingMethods
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.GeneticAlgorithm
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.NoMutation
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.OrderCrossover
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.RandomHeuristic
;
import
de.hft.stuttgart.citydoctor2.healer.gui.HealerGUI
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
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.Copy
;
import
javafx.beans.property.DoubleProperty
;
import
javafx.beans.property.SimpleDoubleProperty
;
import
javafx.fxml.FXML
;
import
javafx.fxml.FXMLLoader
;
import
javafx.scene.AmbientLight
;
import
javafx.scene.Group
;
import
javafx.scene.Node
;
import
javafx.scene.Parent
;
import
javafx.scene.PerspectiveCamera
;
import
javafx.scene.SceneAntialiasing
;
import
javafx.scene.SnapshotParameters
;
import
javafx.scene.SubScene
;
import
javafx.scene.control.Button
;
import
javafx.scene.image.Image
;
import
javafx.scene.input.MouseButton
;
import
javafx.scene.layout.HBox
;
import
javafx.scene.layout.Pane
;
import
javafx.scene.paint.Color
;
import
javafx.scene.shape.CullFace
;
import
javafx.scene.shape.DrawMode
;
import
javafx.scene.transform.Rotate
;
public
class
GeneticsGUI
extends
View
{
private
static
final
double
CAMERA_INITIAL_X_ANGLE
=
20.0
;
private
static
final
double
CAMERA_INITIAL_Y_ANGLE
=
120.0
;
private
Parent
pane
;
private
Image
image
;
private
DoubleProperty
translateZ
;
private
DoubleProperty
cameraXRot
;
private
DoubleProperty
cameraYRot
;
private
boolean
enableGuiControls
=
true
;
private
Group
currentWorld
;
private
Group
nextWorld
;
private
Group
currentMeshGroup
;
private
Group
nextMeshGroup
;
@FXML
private
Pane
view1
;
@FXML
private
Pane
view2
;
@FXML
private
Button
test
;
private
Geometry
currentGeometry
;
private
CityObject
currentFeature
;
private
Checker
currentChecker
;
private
TriangulatedGeometry
currentTriangulatedGeometry
;
private
TriangulatedGeometry
nextTriangulatedGeometry
;
private
Geometry
nextGeometry
;
private
double
dragX
;
private
double
dragY
;
public
GeneticsGUI
()
{
image
=
new
Image
(
getClass
().
getResourceAsStream
(
"genetic.png"
));
}
public
void
initialize
()
{
view2
.
prefWidthProperty
().
bind
(
view1
.
widthProperty
());
view2
.
prefHeightProperty
().
bind
(
view1
.
heightProperty
());
translateZ
=
new
SimpleDoubleProperty
(
0
);
cameraXRot
=
new
SimpleDoubleProperty
(
CAMERA_INITIAL_X_ANGLE
);
cameraYRot
=
new
SimpleDoubleProperty
(
CAMERA_INITIAL_Y_ANGLE
);
test
.
setOnAction
(
ae
->
{
test
.
setDisable
(
true
);
enableGuiControls
=
false
;
GmlId
gmlId
=
currentGeometry
.
getGmlId
();
OrderCrossover
cross
=
new
OrderCrossover
();
NoMutation
mutation
=
new
NoMutation
();
RandomHeuristic
heuristic
=
new
RandomHeuristic
(
HealingMethods
.
getAvailableHealingMethods
());
VisualFitness
fitness
=
new
VisualFitness
(
this
,
currentGeometry
,
currentChecker
);
GeneticAlgorithm
<
HealingPlan
>
ga
=
GeneticAlgorithm
.
of
(
cross
,
mutation
,
heuristic
,
fitness
);
ga
.
run
();
CityObject
nextFeature
=
Copy
.
copy
(
currentFeature
);
nextGeometry
=
findNextGeometry
(
gmlId
,
nextFeature
);
System
.
out
.
println
(
gmlId
);
System
.
out
.
println
(
nextGeometry
);
System
.
out
.
println
(
nextFeature
.
getGeometries
().
get
(
0
));
showCurrentGeometry
();
showNextGeometry
();
test
.
setDisable
(
false
);
enableGuiControls
=
true
;
});
buildCurrent3dView
();
buildNext3dView
();
}
private
Geometry
findNextGeometry
(
GmlId
gmlId
,
CityObject
nextFeature
)
{
Geometry
[]
foundGeom
=
new
Geometry
[
1
];
Check
geomFinder
=
new
Check
()
{
@Override
public
void
check
(
Geometry
geom
)
{
if
(
geom
.
getGmlId
().
equals
(
gmlId
))
{
foundGeom
[
0
]
=
geom
;
}
}
@Override
public
RequirementType
getType
()
{
return
null
;
}
@Override
public
Check
createNewInstance
()
{
return
null
;
}
@Override
public
CheckId
getCheckId
()
{
return
null
;
}
@Override
public
Set
<
Requirement
>
appliesToRequirements
()
{
return
null
;
}
};
nextFeature
.
accept
(
geomFinder
);
return
foundGeom
[
0
];
}
private
void
showCurrentGeometry
()
{
currentTriangulatedGeometry
=
TriangulatedGeometry
.
of
(
currentGeometry
);
currentTriangulatedGeometry
.
setCullFace
(
CullFace
.
BACK
);
currentTriangulatedGeometry
.
setDrawMode
(
DrawMode
.
FILL
);
zoomOutForBoundingBox
(
currentGeometry
.
calculateBoundingBox
());
getCurrentMeshGroup
().
getChildren
().
clear
();
getCurrentMeshGroup
().
getChildren
().
addAll
(
currentTriangulatedGeometry
.
getMeshes
());
}
private
void
showNextGeometry
()
{
nextTriangulatedGeometry
=
TriangulatedGeometry
.
of
(
nextGeometry
);
nextTriangulatedGeometry
.
setCullFace
(
CullFace
.
BACK
);
nextTriangulatedGeometry
.
setDrawMode
(
DrawMode
.
FILL
);
zoomOutForBoundingBox
(
nextGeometry
.
calculateBoundingBox
());
getNextMeshGroup
().
getChildren
().
clear
();
getNextMeshGroup
().
getChildren
().
addAll
(
nextTriangulatedGeometry
.
getMeshes
());
}
private
Group
getNextMeshGroup
()
{
return
nextMeshGroup
;
}
private
List
<
Image
>
makeScreenshots
(
int
xRotSteps
,
int
yRotSteps
)
{
List
<
Image
>
images
=
new
ArrayList
<>();
SnapshotParameters
params
=
new
SnapshotParameters
();
for
(
int
j
=
0
;
j
<
xRotSteps
;
j
++)
{
cameraXRot
.
set
(
j
*
(
180
d
/
xRotSteps
));
for
(
int
i
=
0
;
i
<
yRotSteps
;
i
++)
{
cameraYRot
.
set
(
i
*
(
360
d
/
yRotSteps
));
Image
screen
=
view1
.
snapshot
(
params
,
null
);
images
.
add
(
screen
);
}
}
cameraXRot
.
set
(
0
);
cameraYRot
.
set
(
0
);
return
images
;
}
private
void
buildCurrent3dView
()
{
Group
currentRoot
=
new
Group
();
SubScene
currentScene
=
new
SubScene
(
currentRoot
,
500
,
300
,
true
,
SceneAntialiasing
.
BALANCED
);
currentScene
.
heightProperty
().
bind
(
view1
.
heightProperty
());
currentScene
.
widthProperty
().
bind
(
view1
.
widthProperty
());
currentScene
.
setFill
(
Color
.
AZURE
);
view1
.
getChildren
().
add
(
currentScene
);
currentWorld
=
new
Group
();
currentRoot
.
getChildren
().
add
(
currentWorld
);
currentMeshGroup
=
new
Group
();
currentWorld
.
getChildren
().
add
(
currentMeshGroup
);
AmbientLight
al
=
new
AmbientLight
(
Color
.
WHITE
);
currentRoot
.
getChildren
().
add
(
al
);
PerspectiveCamera
currentCamera
=
new
PerspectiveCamera
(
true
);
currentCamera
.
setNearClip
(
0.1
);
currentCamera
.
setFarClip
(
10000
d
);
currentCamera
.
translateZProperty
().
bind
(
translateZ
);
Rotate
cameraZRotation
=
new
Rotate
();
Rotate
cameraXRotation
=
new
Rotate
();
cameraXRotation
.
setAxis
(
Rotate
.
X_AXIS
);
cameraZRotation
.
setAxis
(
Rotate
.
Z_AXIS
);
cameraZRotation
.
angleProperty
().
bind
(
cameraXRot
);
cameraXRotation
.
angleProperty
().
bind
(
cameraYRot
);
currentWorld
.
getTransforms
().
add
(
cameraXRotation
);
currentWorld
.
getTransforms
().
add
(
cameraZRotation
);
currentRoot
.
getChildren
().
add
(
currentCamera
);
currentScene
.
setCamera
(
currentCamera
);
setupMeshViewControls
(
view1
);
}
private
void
setupMeshViewControls
(
Pane
canvas
)
{
canvas
.
setOnMousePressed
(
me
->
{
if
(
enableGuiControls
&&
me
.
getButton
()
==
MouseButton
.
PRIMARY
)
{
dragX
=
me
.
getScreenX
();
dragY
=
me
.
getScreenY
();
}
});
canvas
.
setOnScroll
(
se
->
translateZ
.
set
(
translateZ
.
get
()
+
se
.
getDeltaY
()
/
10
d
));
canvas
.
setOnMouseDragged
(
me
->
{
if
(
enableGuiControls
&&
me
.
getButton
()
==
MouseButton
.
PRIMARY
)
{
double
deltaX
=
me
.
getScreenX
()
-
dragX
;
double
deltaY
=
me
.
getScreenY
()
-
dragY
;
dragX
=
me
.
getScreenX
();
dragY
=
me
.
getScreenY
();
cameraXRot
.
set
(
cameraXRot
.
get
()
+
((
deltaX
/
3
d
)
%
360
));
cameraYRot
.
set
(
cameraYRot
.
get
()
+
((
deltaY
/
3
d
)
%
360
));
}
});
}
private
void
buildNext3dView
()
{
Group
nextRoot
=
new
Group
();
SubScene
nextScene
=
new
SubScene
(
nextRoot
,
500
,
300
,
true
,
SceneAntialiasing
.
BALANCED
);
nextScene
.
heightProperty
().
bind
(
view2
.
heightProperty
());
nextScene
.
widthProperty
().
bind
(
view2
.
widthProperty
());
nextScene
.
setFill
(
Color
.
AZURE
);
view2
.
getChildren
().
add
(
nextScene
);
nextWorld
=
new
Group
();
nextRoot
.
getChildren
().
add
(
nextWorld
);
nextMeshGroup
=
new
Group
();
nextWorld
.
getChildren
().
add
(
nextMeshGroup
);
AmbientLight
al
=
new
AmbientLight
(
Color
.
WHITE
);
nextRoot
.
getChildren
().
add
(
al
);
PerspectiveCamera
nextCamera
=
new
PerspectiveCamera
(
true
);
nextCamera
.
setNearClip
(
0.1
);
nextCamera
.
setFarClip
(
10000
d
);
nextCamera
.
translateZProperty
().
bind
(
translateZ
);
Rotate
cameraZRotation
=
new
Rotate
();
Rotate
cameraXRotation
=
new
Rotate
();
cameraXRotation
.
setAxis
(
Rotate
.
X_AXIS
);
cameraZRotation
.
setAxis
(
Rotate
.
Z_AXIS
);
cameraZRotation
.
angleProperty
().
bind
(
cameraXRot
);
cameraXRotation
.
angleProperty
().
bind
(
cameraYRot
);
nextWorld
.
getTransforms
().
add
(
cameraXRotation
);
nextWorld
.
getTransforms
().
add
(
cameraZRotation
);
nextRoot
.
getChildren
().
add
(
nextCamera
);
nextScene
.
setCamera
(
nextCamera
);
}
@Override
public
Optional
<
HBox
>
getToolbar
()
{
return
Optional
.
empty
();
}
@Override
public
Node
getMainScreen
()
{
return
pane
;
}
@Override
public
Image
getViewLogo
()
{
return
image
;
}
@Override
public
void
initializeView
(
MainWindow
mainWindow
)
{
FXMLLoader
loader
=
new
FXMLLoader
(
getClass
().
getResource
(
"geneticGUI.fxml"
));
loader
.
setController
(
this
);
try
{
pane
=
loader
.
load
();
}
catch
(
IOException
e
)
{
throw
new
UncheckedIOException
(
e
);
}
try
{
setupViews
();
}
catch
(
CityGmlParseException
|
InvalidGmlFileException
e
)
{
e
.
printStackTrace
();
}
}
private
void
setupViews
()
throws
CityGmlParseException
,
InvalidGmlFileException
{
ParserConfiguration
parserConfig
=
new
ParserConfiguration
(
8
,
false
);
// CityDoctorModel model1 = CityGmlParser.parseCityGmlFile("src/test/resources/SimpleSolid_SrefBS.gml",
// parserConfig);
CityDoctorModel
model1
=
CityGmlParser
.
parseCityGmlFile
(
"src/test/resources/TestBuilding3.gml"
,
parserConfig
);
currentChecker
=
new
Checker
(
model1
);
currentChecker
.
runChecks
();
Building
building
=
model1
.
getBuildings
().
get
(
0
);
currentGeometry
=
building
.
getGeometries
().
get
(
0
);
currentFeature
=
building
;
showCurrentGeometry
();
}
public
void
zoomOutForBoundingBox
(
BoundingBox
b
)
{
double
cameraDistance
=
2.0d
;
Vector3d
objectSizes
=
b
.
getDiagonal
();
double
objectSize
=
max
(
objectSizes
.
getX
(),
objectSizes
.
getY
(),
objectSizes
.
getZ
());
double
cameraView
=
2.0d
*
Math
.
tan
(
0.5d
*
Math
.
toRadians
(
30
));
// Visible height 1 meter in front
double
distance
=
cameraDistance
*
objectSize
/
cameraView
;
// Combined wanted distance from the object
distance
+=
0.5d
*
objectSize
;
// Estimated offset from the center to the outside of the object
translateZ
.
set
(-
distance
);
}
private
double
max
(
double
a
,
double
b
,
double
c
)
{
double
temp
=
Math
.
max
(
a
,
b
);
return
Math
.
max
(
temp
,
c
);
}
public
Group
getCurrentMeshGroup
()
{
return
currentMeshGroup
;
}
@Override
public
void
onHide
()
{
// TODO Auto-generated method stub
}
@Override
public
void
onShow
(
CityDoctorModel
model
,
Checker
checker
)
{
// TODO Auto-generated method stub
}
public
static
void
main
(
String
[]
args
)
{
ViewRegistration
.
registerView
(
new
GeneticsGUI
());
HealerGUI
.
main
(
args
);
}
public
List
<
Image
>
createScreenshots
(
Geometry
geom
,
double
zoomLevel
,
int
xRotSteps
,
int
yRotSteps
)
{
currentGeometry
=
geom
;
currentTriangulatedGeometry
=
TriangulatedGeometry
.
of
(
currentGeometry
);
currentTriangulatedGeometry
.
setCullFace
(
CullFace
.
BACK
);
currentTriangulatedGeometry
.
setDrawMode
(
DrawMode
.
FILL
);
setZoomLevel
(
zoomLevel
);
getCurrentMeshGroup
().
getChildren
().
clear
();
getCurrentMeshGroup
().
getChildren
().
addAll
(
currentTriangulatedGeometry
.
getMeshes
());
return
makeScreenshots
(
xRotSteps
,
yRotSteps
);
}
private
void
setZoomLevel
(
double
zoomLevel
)
{
translateZ
.
set
(
zoomLevel
);
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/gui/ImageComparison.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.healer.genetic.gui
;
import
java.util.Objects
;
import
javafx.scene.image.Image
;
import
javafx.scene.image.PixelReader
;
import
javafx.scene.paint.Color
;
public
class
ImageComparison
{
private
ImageComparison
()
{
// only static access
}
public
static
double
compare
(
Image
image1
,
Image
image2
)
{
assertPredefinitions
(
image1
,
image2
);
PixelReader
pr1
=
image1
.
getPixelReader
();
Objects
.
requireNonNull
(
pr1
);
PixelReader
pr2
=
image2
.
getPixelReader
();
Objects
.
requireNonNull
(
pr2
);
double
pictureDif
=
0
;
for
(
int
i
=
0
;
i
<
image1
.
getWidth
();
i
++)
{
for
(
int
j
=
0
;
j
<
image2
.
getHeight
();
j
++)
{
double
pixelComp
=
1.0
;
Color
c1
=
pr1
.
getColor
(
i
,
j
);
Color
c2
=
pr2
.
getColor
(
i
,
j
);
double
redDif
=
Math
.
abs
(
c1
.
getRed
()
-
c2
.
getRed
());
double
blueDif
=
Math
.
abs
(
c1
.
getBlue
()
-
c2
.
getBlue
());
double
greenDif
=
Math
.
abs
(
c1
.
getGreen
()
-
c2
.
getGreen
());
if
(
redDif
>
0.05
)
{
pixelComp
-=
1
/
3
d
;
}
if
(
blueDif
>
0.05
)
{
pixelComp
-=
1
/
3
d
;
}
if
(
greenDif
>
0.05
)
{
pixelComp
-=
1
/
3
d
;
}
pictureDif
+=
pixelComp
;
}
}
double
dimension
=
image1
.
getWidth
()
*
image1
.
getHeight
();
pictureDif
=
Math
.
max
(
0
,
dimension
-
50
*
(
dimension
-
pictureDif
));
return
pictureDif
/
dimension
;
}
private
static
void
assertPredefinitions
(
Image
image1
,
Image
image2
)
{
if
(
image1
.
getProgress
()
!=
1.0
||
image2
.
getProgress
()
!=
1.0
)
{
throw
new
IllegalArgumentException
(
"Pictures are not fully loaded"
);
}
if
(
image1
.
getWidth
()
!=
image2
.
getWidth
()
||
image1
.
getHeight
()
!=
image2
.
getHeight
())
{
throw
new
IllegalArgumentException
(
"Pictures have to be the same size"
);
}
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/gui/VisualFitness.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.healer.genetic.gui
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.check.Checker
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundingBox
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.healer.Healer
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.FitnessEvaluation
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
import
de.hft.stuttgart.citydoctor2.utils.Copy
;
import
javafx.scene.image.Image
;
public
class
VisualFitness
implements
FitnessEvaluation
<
HealingPlan
>
{
private
int
xRotSteps
=
6
;
private
int
yRotSteps
=
12
;
private
GeneticsGUI
gui
;
private
Geometry
geom
;
private
List
<
Image
>
originalImages
;
private
Checker
c
;
private
double
distance
;
public
VisualFitness
(
GeneticsGUI
gui
,
Geometry
geom
,
Checker
c
)
{
this
.
gui
=
gui
;
this
.
geom
=
geom
;
this
.
c
=
c
;
BoundingBox
b
=
geom
.
calculateBoundingBox
();
double
cameraDistance
=
2.0d
;
Vector3d
objectSizes
=
b
.
getDiagonal
();
double
objectSize
=
max
(
objectSizes
.
getX
(),
objectSizes
.
getY
(),
objectSizes
.
getZ
());
double
cameraView
=
2.0d
*
Math
.
tan
(
0.5d
*
Math
.
toRadians
(
30
));
// Visible height 1 meter in front
distance
=
cameraDistance
*
objectSize
/
cameraView
;
distance
+=
0.5d
*
objectSize
;
// Estimated offset from the center to the outside of the object
distance
=
-
distance
;
originalImages
=
gui
.
createScreenshots
(
geom
,
distance
,
xRotSteps
,
yRotSteps
);
}
private
double
max
(
double
a
,
double
b
,
double
c
)
{
double
temp
=
Math
.
max
(
a
,
b
);
return
Math
.
max
(
temp
,
c
);
}
@Override
public
double
evaluate
(
HealingPlan
plan
)
{
Healer
healer
=
new
Healer
(
c
,
plan
);
Geometry
copy
=
Copy
.
copy
(
geom
);
healer
.
heal
(
copy
,
copy
.
getParent
());
if
(
copy
.
containsAnyError
())
{
System
.
out
.
println
(
plan
);
System
.
out
.
println
(
"Fitness: 0"
);
return
0
;
}
List
<
Image
>
compareImages
=
gui
.
createScreenshots
(
copy
,
distance
,
xRotSteps
,
yRotSteps
);
if
(
originalImages
.
size
()
!=
compareImages
.
size
())
{
throw
new
IllegalStateException
(
"Number of images differs"
);
}
double
value
=
0
;
for
(
int
i
=
0
;
i
<
originalImages
.
size
();
i
++)
{
Image
orig
=
originalImages
.
get
(
i
);
Image
compare
=
compareImages
.
get
(
i
);
value
+=
ImageComparison
.
compare
(
orig
,
compare
);
}
double
fitness
=
value
/
(
xRotSteps
*
yRotSteps
);
System
.
out
.
println
(
"Fitness: "
+
fitness
);
return
fitness
;
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/main/resources/de/hft/stuttgart/citydoctor2/healer/genetic/gui/genetic.png
0 → 100644
View file @
97a65114
1.13 KB
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/main/resources/de/hft/stuttgart/citydoctor2/healer/genetic/gui/geneticGUI.fxml
0 → 100644
View file @
97a65114
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<VBox
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
minHeight=
"-Infinity"
minWidth=
"-Infinity"
xmlns=
"http://javafx.com/javafx/8.0.221"
xmlns:fx=
"http://javafx.com/fxml/1"
>
<children>
<SplitPane
dividerPositions=
"0.7"
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
orientation=
"VERTICAL"
VBox.vgrow=
"ALWAYS"
>
<items>
<HBox
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
>
<children>
<Pane
fx:id=
"view1"
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
HBox.hgrow=
"ALWAYS"
/>
<Pane
fx:id=
"view2"
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
HBox.hgrow=
"ALWAYS"
/>
</children>
</HBox>
<HBox>
<children>
<Button
fx:id=
"test"
mnemonicParsing=
"false"
text=
"Button"
/>
</children>
</HBox>
</items>
</SplitPane>
</children>
</VBox>
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/test/java/de/hft/stuttgart/citydoctor2/healer/genetic/GeneticAlgorithmTest.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
static
org
.
junit
.
Assert
.*;
import
org.junit.Test
;
import
de.hft.stuttgart.citydoctor2.healer.HealingMethods
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
public
class
GeneticAlgorithmTest
{
@Test
public
void
test
()
{
Crossover
<
HealingPlan
>
cross
=
new
OrderCrossover
();
Mutation
<
HealingPlan
>
mutation
=
new
NoMutation
();
FitnessEvaluation
<
HealingPlan
>
fitness
=
new
RandomFitness
();
Heuristic
<
HealingPlan
>
heuristic
=
new
RandomHeuristic
(
HealingMethods
.
getAvailableHealingMethods
());
GeneticAlgorithm
<
HealingPlan
>
ga
=
GeneticAlgorithm
.
of
(
cross
,
mutation
,
heuristic
,
fitness
);
ga
.
run
();
assertNotNull
(
ga
.
getResult
());
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/test/java/de/hft/stuttgart/citydoctor2/healer/genetic/MetaFitnessValues.java
0 → 100644
View file @
97a65114
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
public
class
MetaFitnessValues
{
int
numberOfPolygonsWithPlanarityIssues
=
0
;
int
numberOfPolygonsWithoutPlanarityIssues
=
0
;
int
numberOfPolygonsWithOtherErrors
=
0
;
int
numberOfPolygonsWithNoErrors
=
0
;
public
void
reset
()
{
numberOfPolygonsWithPlanarityIssues
=
0
;
numberOfPolygonsWithoutPlanarityIssues
=
0
;
numberOfPolygonsWithOtherErrors
=
0
;
numberOfPolygonsWithNoErrors
=
0
;
}
public
MetaFitnessValues
copy
()
{
MetaFitnessValues
copy
=
new
MetaFitnessValues
();
copy
.
numberOfPolygonsWithNoErrors
=
numberOfPolygonsWithNoErrors
;
copy
.
numberOfPolygonsWithOtherErrors
=
numberOfPolygonsWithOtherErrors
;
copy
.
numberOfPolygonsWithoutPlanarityIssues
=
numberOfPolygonsWithoutPlanarityIssues
;
copy
.
numberOfPolygonsWithPlanarityIssues
=
numberOfPolygonsWithPlanarityIssues
;
return
copy
;
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/test/java/de/hft/stuttgart/citydoctor2/healer/genetic/NonPlanarGenetic.java
0 → 100644
View file @
97a65114
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
java.io.BufferedWriter
;
import
java.io.IOException
;
import
java.io.UncheckedIOException
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.nio.file.StandardOpenOption
;
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
org.junit.Test
;
import
Jama.EigenvalueDecomposition
;
import
de.hft.stuttgart.citydoctor2.check.AbstractCheck
;
import
de.hft.stuttgart.citydoctor2.check.CheckError
;
import
de.hft.stuttgart.citydoctor2.check.Checker
;
import
de.hft.stuttgart.citydoctor2.check.ValidationConfiguration
;
import
de.hft.stuttgart.citydoctor2.check.error.NonPlanarPolygonDistancePlaneError
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface
;
import
de.hft.stuttgart.citydoctor2.datastructure.Installation
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
import
de.hft.stuttgart.citydoctor2.math.CovarianceMatrix
;
import
de.hft.stuttgart.citydoctor2.math.OrthogonalRegressionPlane
;
import
de.hft.stuttgart.citydoctor2.math.Plane
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
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.utils.Copy
;
public
class
NonPlanarGenetic
{
private
static
final
int
ERROR_PENALTY
=
100000
;
private
Random
r
=
new
Random
();
private
Map
<
Integer
,
List
<
Long
>>
durationMap
=
new
HashMap
<>();
@Test
public
void
findVerticesForNonPlanarTest
()
throws
CityGmlParseException
,
InvalidGmlFileException
,
IOException
{
ValidationConfiguration
config
=
ValidationConfiguration
.
loadStandardValidationConfig
();
config
.
setNumberOfRoundingPlacesInGlobalParameters
(
8
);
config
.
setSchematronFilePathInGlobalParameters
(
null
);
config
.
getParserConfiguration
().
setUseLowMemoryConsumption
(
false
);
List
<
Path
>
gmlFiles
=
getPathsForGmlFiles
();
for
(
Path
gmlFile
:
gmlFiles
)
{
System
.
out
.
println
(
"Parsing File: "
+
gmlFile
);
CityDoctorModel
model
=
CityGmlParser
.
parseCityGmlFile
(
gmlFile
.
toString
(),
config
.
getParserConfiguration
());
Checker
c
=
new
Checker
(
config
,
model
);
c
.
runChecks
();
List
<
CheckError
>
errors
=
new
ArrayList
<>();
model
.
createFeatureStream
().
forEach
(
co
->
co
.
collectContainedErrors
(
errors
));
assertFalse
(
errors
.
isEmpty
());
NonPlanarPolygonDistancePlaneError
planarError
=
null
;
for
(
CheckError
err
:
errors
)
{
if
(
err
instanceof
NonPlanarPolygonDistancePlaneError
)
{
planarError
=
(
NonPlanarPolygonDistancePlaneError
)
err
;
break
;
}
}
if
(
planarError
==
null
)
{
throw
new
IllegalStateException
(
"File "
+
gmlFile
+
" does not contain a planarity error"
);
}
CityObject
feature
=
getFeature
(
planarError
.
getPolygon
());
Polygon
polygon
=
planarError
.
getPolygon
();
// ensure a gml id has been generated
polygon
.
getGmlId
();
int
vertexCount
=
polygon
.
getExteriorRing
().
getVertices
().
size
();
List
<
Vertex
>
subList
=
polygon
.
getExteriorRing
().
getVertices
().
subList
(
0
,
vertexCount
-
1
);
System
.
out
.
println
(
"Computing polygon: "
+
polygon
.
getGmlId
()
+
" with "
+
subList
.
size
()
+
" Vertices"
);
FitnessEvaluation
<
PolygonVertexList
>
fitnessFunction
=
createFitnessEvaluationFunction
(
c
,
feature
);
// complete calculation of all possibilities
if
(
subList
.
size
()
==
7
)
{
System
.
out
.
println
();
}
Individual
<
PolygonVertexList
>
bestOfBoth
=
null
;
if
(
subList
.
size
()
>
12
)
{
System
.
out
.
println
(
"Skipping complete calculation, too many vertices"
);
bestOfBoth
=
doGeneticAlgorithmCalculation
(
polygon
,
subList
,
fitnessFunction
);
}
else
{
bestOfBoth
=
doCompleteCalculation
(
polygon
,
fitnessFunction
,
vertexCount
,
subList
);
}
System
.
out
.
println
();
// abstands diff, ebene ohne punkt und normale ausgleichsebene
// if (bestOfBoth.getFitness() > -9000) {
// write only those that do not have errors in neighbor polygons
// errors in neighbors mean -10000 so check for higher than 9000 to be sure
try
(
BufferedWriter
writer
=
Files
.
newBufferedWriter
(
Paths
.
get
(
"result.txt"
),
StandardOpenOption
.
APPEND
,
StandardOpenOption
.
CREATE
))
{
for
(
int
i
=
0
;
i
<
bestOfBoth
.
getObject
().
getUseVertex
().
length
;
i
++)
{
boolean
used
=
bestOfBoth
.
getObject
().
getUseVertex
()[
i
];
Vertex
v
=
bestOfBoth
.
getObject
().
getVertices
().
get
(
i
);
int
numberOfAdjacentPolygons
=
0
;
int
numberOfPolygonsWithPlanarityIssues
=
0
;
int
numberOfPolygonsWithOtherErrors
=
0
;
double
distanceToPlane
=
planarError
.
getPlane
().
getDistance
(
v
);
Set
<
Polygon
>
adjacentPolygons
=
v
.
getAdjacentPolygons
(
polygon
.
getParent
());
numberOfAdjacentPolygons
=
adjacentPolygons
.
size
();
for
(
Polygon
adjacentPolygon
:
adjacentPolygons
)
{
List
<
CheckError
>
adjacentPolygonErrors
=
new
ArrayList
<>();
adjacentPolygon
.
collectContainedErrors
(
adjacentPolygonErrors
);
// impossible to have duplicate errors so no Set filter on top
for
(
CheckError
err
:
adjacentPolygonErrors
)
{
if
(
err
instanceof
NonPlanarPolygonDistancePlaneError
)
{
numberOfPolygonsWithPlanarityIssues
++;
}
else
{
numberOfPolygonsWithOtherErrors
++;
}
}
}
if
(
used
)
{
writer
.
write
(
"1"
);
}
else
{
writer
.
write
(
"0"
);
}
List
<
Vertex
>
vertices
=
new
ArrayList
<>();
for
(
Vertex
vertexForPlan
:
subList
)
{
if
(
vertexForPlan
==
v
)
{
continue
;
}
vertices
.
add
(
vertexForPlan
);
}
Vector3d
centroid
=
CovarianceMatrix
.
getCentroid
(
vertices
);
EigenvalueDecomposition
ed
=
OrthogonalRegressionPlane
.
decompose
(
vertices
,
centroid
);
Vector3d
eigenvalues
=
OrthogonalRegressionPlane
.
getEigenvalues
(
ed
);
Plane
plane
=
OrthogonalRegressionPlane
.
calculatePlane
(
centroid
,
ed
,
eigenvalues
);
double
distanceDifferenceWithoutPoint
=
distanceToPlane
-
plane
.
getDistance
(
v
);
writer
.
write
(
" 1:"
);
writer
.
write
(
Integer
.
toString
(
numberOfAdjacentPolygons
));
writer
.
write
(
" 2:"
);
writer
.
write
(
Integer
.
toString
(
numberOfPolygonsWithPlanarityIssues
));
writer
.
write
(
" 3:"
);
writer
.
write
(
Integer
.
toString
(
numberOfPolygonsWithOtherErrors
));
writer
.
write
(
" 4:"
);
writer
.
write
(
Double
.
toString
(
distanceToPlane
));
writer
.
write
(
" 5:"
);
writer
.
write
(
Double
.
toString
(
distanceDifferenceWithoutPoint
));
writer
.
write
(
'\n'
);
}
}
// }
}
for
(
Entry
<
Integer
,
List
<
Long
>>
e
:
durationMap
.
entrySet
())
{
long
sum
=
0
;
for
(
Long
l
:
e
.
getValue
())
{
sum
+=
l
;
}
System
.
out
.
println
(
e
.
getKey
()
+
" Vertices took on average: "
+
(
sum
/
(
float
)
e
.
getValue
().
size
())
+
"ms"
);
}
}
private
Individual
<
PolygonVertexList
>
doGeneticAlgorithmCalculation
(
Polygon
polygon
,
List
<
Vertex
>
subList
,
FitnessEvaluation
<
PolygonVertexList
>
fitnessFunction
)
throws
IOException
{
Mutation
<
PolygonVertexList
>
mutation
=
createMutationFunction
();
Crossover
<
PolygonVertexList
>
crossOver
=
createCrossoverFunction
();
Heuristic
<
PolygonVertexList
>
randomHeuristic
=
createHeursiticFunction
(
polygon
,
subList
);
GeneticAlgorithm
<
PolygonVertexList
>
algo
=
GeneticAlgorithm
.
of
(
crossOver
,
mutation
,
randomHeuristic
,
fitnessFunction
);
long
startGen
=
System
.
currentTimeMillis
();
algo
.
run
();
long
deltaGen
=
System
.
currentTimeMillis
()
-
startGen
;
System
.
out
.
println
(
"Genetic Algo took: "
+
deltaGen
+
" ms"
);
durationMap
.
compute
(
subList
.
size
(),
(
key
,
value
)
->
{
if
(
value
==
null
)
{
value
=
new
ArrayList
<>();
}
value
.
add
(
deltaGen
);
return
value
;
});
PolygonVertexList
result
=
algo
.
getResult
().
getObject
();
printUsage
(
result
.
getUseVertex
());
return
algo
.
getResult
();
}
private
Heuristic
<
PolygonVertexList
>
createHeursiticFunction
(
Polygon
polygon
,
List
<
Vertex
>
subList
)
{
Heuristic
<
PolygonVertexList
>
randomHeuristic
=
()
->
{
PolygonVertexList
vertexList
=
new
PolygonVertexList
(
polygon
,
subList
);
boolean
[]
useVertex
=
vertexList
.
getUseVertex
();
for
(
int
i
=
0
;
i
<
useVertex
.
length
;
i
++)
{
useVertex
[
i
]
=
r
.
nextBoolean
();
}
validateIndividual
(
vertexList
);
return
vertexList
;
};
return
randomHeuristic
;
}
private
Crossover
<
PolygonVertexList
>
createCrossoverFunction
()
{
Crossover
<
PolygonVertexList
>
crossOver
=
(
p1
,
p2
)
->
{
PolygonVertexList
result
=
new
PolygonVertexList
(
p1
.
getPolygon
(),
p1
.
getVertices
());
int
splitIndex
=
r
.
nextInt
(
p1
.
getUseVertex
().
length
);
boolean
[]
array
=
result
.
getUseVertex
();
for
(
int
i
=
0
;
i
<
splitIndex
;
i
++)
{
array
[
i
]
=
p1
.
getUseVertex
()[
i
];
}
for
(
int
i
=
splitIndex
;
i
<
array
.
length
;
i
++)
{
array
[
i
]
=
p2
.
getUseVertex
()[
i
];
}
validateIndividual
(
result
);
return
result
;
};
return
crossOver
;
}
private
Mutation
<
PolygonVertexList
>
createMutationFunction
()
{
Mutation
<
PolygonVertexList
>
mutation
=
p
->
{
int
doSomethingValue
=
r
.
nextInt
(
100
);
if
(
doSomethingValue
>
50
)
{
// don't do anything
return
p
;
}
int
index
=
r
.
nextInt
(
p
.
getUseVertex
().
length
);
p
.
getUseVertex
()[
index
]
=
!
p
.
getUseVertex
()[
index
];
validateIndividual
(
p
);
return
p
;
};
return
mutation
;
}
private
Individual
<
PolygonVertexList
>
doCompleteCalculation
(
Polygon
polygon
,
FitnessEvaluation
<
PolygonVertexList
>
fitnessFunction
,
int
vertexCount
,
List
<
Vertex
>
subList
)
{
System
.
out
.
println
(
"Doing complete calculation"
);
long
startComplete
=
System
.
currentTimeMillis
();
double
highestFitness
=
Double
.
NEGATIVE_INFINITY
;
int
computeCount
=
0
;
PolygonVertexList
bestIndividual
=
null
;
for
(
int
i
=
7
;
i
<
Math
.
pow
(
2
,
vertexCount
-
1
)
-
1
;
i
++)
{
PolygonVertexList
individual
=
new
PolygonVertexList
(
polygon
,
subList
);
int
usedVertexCount
=
0
;
boolean
[]
useVertices
=
individual
.
getUseVertex
();
for
(
int
j
=
0
;
j
<
vertexCount
-
1
;
j
++)
{
long
l
=
(
i
>>
j
)
&
1
;
if
(
l
==
1
)
{
usedVertexCount
++;
useVertices
[
j
]
=
true
;
}
else
{
useVertices
[
j
]
=
false
;
}
}
if
(
usedVertexCount
>=
3
)
{
double
fitnessValue
=
fitnessFunction
.
evaluate
(
individual
);
computeCount
++;
if
(
fitnessValue
>
highestFitness
)
{
highestFitness
=
fitnessValue
;
System
.
out
.
println
(
"Best Fitness: "
+
highestFitness
);
bestIndividual
=
individual
;
}
}
if
(
usedVertexCount
==
vertexCount
-
1
)
{
throw
new
IllegalStateException
(
"All values should not be computed"
);
}
}
long
deltaComplete
=
System
.
currentTimeMillis
()
-
startComplete
;
System
.
out
.
println
(
"End. Best Fitness: "
+
highestFitness
+
" Individual: "
+
bestIndividual
);
System
.
out
.
println
(
"Computed "
+
computeCount
+
" individuals"
);
if
(
bestIndividual
!=
null
)
{
printUsage
(
bestIndividual
.
getUseVertex
());
}
System
.
out
.
println
(
"Complete calculation took: "
+
deltaComplete
+
"ms"
);
durationMap
.
compute
(
subList
.
size
(),
(
key
,
value
)
->
{
if
(
value
==
null
)
{
value
=
new
ArrayList
<>();
}
value
.
add
(
deltaComplete
);
return
value
;
});
Individual
<
PolygonVertexList
>
bestResult
=
new
Individual
<
PolygonVertexList
>(
bestIndividual
);
bestResult
.
setFitness
(
highestFitness
);
return
bestResult
;
}
private
FitnessEvaluation
<
PolygonVertexList
>
createFitnessEvaluationFunction
(
Checker
c
,
CityObject
feature
)
{
FitnessEvaluation
<
PolygonVertexList
>
fitness
=
p
->
{
List
<
Vertex
>
vertices
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
p
.
getVertices
().
size
();
i
++)
{
if
(
p
.
getUseVertex
()[
i
])
{
vertices
.
add
(
p
.
getVertices
().
get
(
i
));
}
}
Vector3d
centroid
=
CovarianceMatrix
.
getCentroid
(
vertices
);
EigenvalueDecomposition
ed
=
OrthogonalRegressionPlane
.
decompose
(
vertices
,
centroid
);
Vector3d
eigenvalues
=
OrthogonalRegressionPlane
.
getEigenvalues
(
ed
);
Plane
plane
=
OrthogonalRegressionPlane
.
calculatePlane
(
centroid
,
ed
,
eigenvalues
);
// check if it produces errors somewhere else
// first repair
// only repair clone
CityObject
copy
=
Copy
.
copy
(
feature
);
Polygon
copyP
=
findPolygonInFeature
(
copy
,
p
.
getPolygon
());
Set
<
Vertex
>
allVertices
=
new
HashSet
<>();
// collect all vertices, eliminating duplicates
collectVertices
(
copyP
,
allVertices
);
// project each vertex to the plane and change the coordinates of existing
// vertices
for
(
Vertex
v
:
allVertices
)
{
Vector3d
newPoint
=
plane
.
projectPointToPlane
(
v
);
v
.
setX
(
newPoint
.
getX
());
v
.
setY
(
newPoint
.
getY
());
v
.
setZ
(
newPoint
.
getZ
());
}
// update edges
copy
.
prepareForChecking
();
// recheck
c
.
executeChecksForCheckable
(
copy
);
List
<
CheckError
>
remainingErrors
=
new
ArrayList
<>();
for
(
Polygon
poly
:
collectNeighborPolygons
(
copyP
))
{
poly
.
collectContainedErrors
(
remainingErrors
);
}
double
distanceSum
=
0
;
distanceSum
=
remainingErrors
.
size
()
*
ERROR_PENALTY
;
// check the distance of the original vertices to calculate distance
allVertices
=
new
HashSet
<>();
// collect all vertices, eliminating duplicates
collectVertices
(
p
.
getPolygon
(),
allVertices
);
for
(
Vertex
v
:
allVertices
)
{
double
distance
=
plane
.
getDistance
(
v
);
distanceSum
+=
distance
;
}
// negative, as higher is better but more distance is worse
return
-
distanceSum
;
};
return
fitness
;
}
public
long
factorial
(
int
n
)
{
long
fact
=
1
;
for
(
int
i
=
2
;
i
<=
n
;
i
++)
{
fact
=
fact
*
i
;
}
return
fact
;
}
private
List
<
Path
>
getPathsForGmlFiles
()
throws
IOException
{
Path
entry
=
Paths
.
get
(
"C:/Job/CityGML Files/GE_P_NON_PLANAR_POLYGON_DISTANCE_PLANE"
);
List
<
Path
>
paths
=
new
ArrayList
<>();
Files
.
list
(
entry
).
forEach
(
path
->
collectGmlFiles
(
path
,
paths
));
return
paths
;
}
private
void
collectGmlFiles
(
Path
path
,
List
<
Path
>
paths
)
{
if
(
Files
.
isRegularFile
(
path
)
&&
path
.
getFileName
().
toString
().
endsWith
(
"gml"
))
{
paths
.
add
(
path
);
}
else
if
(
Files
.
isDirectory
(
path
))
{
try
{
Files
.
list
(
path
).
forEach
(
p
->
collectGmlFiles
(
p
,
paths
));
}
catch
(
IOException
e
)
{
throw
new
UncheckedIOException
(
e
);
}
}
}
private
void
printUsage
(
boolean
[]
useVertex
)
{
System
.
out
.
println
(
createUseString
(
useVertex
));
}
private
String
createUseString
(
boolean
[]
useVertex
)
{
StringBuilder
builder
=
new
StringBuilder
();
for
(
boolean
b
:
useVertex
)
{
if
(
b
)
{
builder
.
append
(
'1'
);
}
else
{
builder
.
append
(
'0'
);
}
}
return
builder
.
toString
();
}
private
void
validateIndividual
(
PolygonVertexList
p
)
{
int
index
;
// count the number of used vertices
int
useCount
=
0
;
for
(
boolean
b
:
p
.
getUseVertex
())
{
if
(
b
)
{
useCount
++;
}
}
if
(
useCount
<
3
)
{
// at least 3 points should be used
for
(
int
i
=
0
;
i
<
3
-
useCount
;
i
++)
{
index
=
r
.
nextInt
(
p
.
getUseVertex
().
length
);
// search for a false index all the time
while
(
p
.
getUseVertex
()[
index
])
{
index
=
r
.
nextInt
(
p
.
getUseVertex
().
length
);
}
p
.
getUseVertex
()[
index
]
=
true
;
}
}
else
if
(
useCount
==
p
.
getVertices
().
size
())
{
// not all vertices should be used
// flip one randomly back
index
=
r
.
nextInt
(
p
.
getUseVertex
().
length
);
p
.
getUseVertex
()[
index
]
=
false
;
}
}
private
Polygon
findPolygonInFeature
(
CityObject
copy
,
Polygon
polygon
)
{
Polygon
[]
result
=
new
Polygon
[
1
];
copy
.
accept
(
new
AbstractCheck
()
{
@Override
public
void
check
(
Polygon
p
)
{
if
(
p
.
getGmlId
().
equals
(
polygon
.
getGmlId
()))
{
result
[
0
]
=
p
;
}
}
});
return
result
[
0
];
}
private
CityObject
getFeature
(
Polygon
polygon
)
{
CityObject
parent
=
polygon
.
getParent
().
getParent
();
if
(
parent
instanceof
BoundarySurface
)
{
BoundarySurface
bs
=
(
BoundarySurface
)
parent
;
parent
=
bs
.
getParent
();
if
(
parent
instanceof
Installation
)
{
Installation
bi
=
(
Installation
)
parent
;
parent
=
bi
.
getParent
();
}
}
else
if
(
parent
instanceof
Installation
)
{
Installation
bi
=
(
Installation
)
parent
;
parent
=
bi
.
getParent
();
}
return
parent
;
}
private
Set
<
Polygon
>
collectNeighborPolygons
(
Polygon
polygon
)
{
Geometry
geometry
;
if
(
polygon
.
isLinkedTo
())
{
geometry
=
polygon
.
getLinkedFromPolygon
().
getParent
();
}
else
{
geometry
=
polygon
.
getParent
();
}
Set
<
Polygon
>
polygons
=
new
HashSet
<>();
for
(
Vertex
v
:
polygon
.
getExteriorRing
().
getVertices
())
{
polygons
.
addAll
(
v
.
getAdjacentPolygons
(
geometry
));
}
return
polygons
;
}
private
void
collectVertices
(
Polygon
p
,
Set
<
Vertex
>
vertices
)
{
collectVertices
(
p
.
getExteriorRing
(),
vertices
);
for
(
LinearRing
lr
:
p
.
getInnerRings
())
{
collectVertices
(
lr
,
vertices
);
}
}
private
void
collectVertices
(
LinearRing
ring
,
Set
<
Vertex
>
vertices
)
{
for
(
Vertex
v
:
ring
.
getVertices
())
{
vertices
.
add
(
v
);
}
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/test/java/de/hft/stuttgart/citydoctor2/healer/genetic/PolygonVertexList.java
0 → 100644
View file @
97a65114
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
public
class
PolygonVertexList
{
private
Polygon
polygon
;
private
List
<
Vertex
>
vertices
;
private
boolean
[]
useVertex
;
public
PolygonVertexList
(
Polygon
polygon
,
List
<
Vertex
>
vertices
)
{
this
.
polygon
=
polygon
;
this
.
vertices
=
vertices
;
useVertex
=
new
boolean
[
vertices
.
size
()];
}
public
Polygon
getPolygon
()
{
return
polygon
;
}
public
List
<
Vertex
>
getVertices
()
{
return
vertices
;
}
public
boolean
[]
getUseVertex
()
{
return
useVertex
;
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/test/java/de/hft/stuttgart/citydoctor2/healer/genetic/gui/ImageComparisonTest.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.healer.genetic.gui
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
org.junit.Test
;
import
javafx.scene.image.Image
;
public
class
ImageComparisonTest
{
@Test
public
void
test
()
{
Image
image
=
new
Image
(
getClass
().
getResourceAsStream
(
"genetic.png"
));
assertEquals
(
1.0
,
ImageComparison
.
compare
(
image
,
image
),
0.001
);
}
}
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/test/resources/SimpleSolid_SrefBS.gml
0 → 100644
View file @
97a65114
<?xml version="1.0" encoding="utf-8"?>
<core:CityModel
xmlns:core=
"http://www.opengis.net/citygml/2.0"
xmlns:gen=
"http://www.opengis.net/citygml/generics/2.0"
xmlns:bldg=
"http://www.opengis.net/citygml/building/2.0"
xmlns:app=
"http://www.opengis.net/citygml/appearance/2.0"
xmlns:dem=
"http://www.opengis.net/citygml/relief/2.0"
xmlns:gml=
"http://www.opengis.net/gml"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://www.opengis.net/citygml/building/2.0 http://schemas.opengis.net/citygml/building/2.0/building.xsd http://www.opengis.net/citygml/appearance/2.0 http://schemas.opengis.net/citygml/appearance/2.0/appearance.xsd http://www.opengis.net/citygml/relief/2.0 http://schemas.opengis.net/citygml/relief/2.0/relief.xsd http://www.opengis.net/citygml/2.0 http://schemas.opengis.net/citygml/2.0/cityGMLBase.xsd http://www.opengis.net/citygml/generics/2.0 http://schemas.opengis.net/citygml/generics/2.0/generics.xsd"
>
<!--
Einfaches Gebäude mit Grundriss 3m x 5m und Satteldach, Traufhöhe 3m, Firsthöhe 4,5m
Modelliert mit Begrenzungsflächen (eine Dachfläche, 4 Wandflächen, 1 Grundfläche),
die Gebäudegeometrie als Solid, der auf die Polygone der Begrenzungsflächen referenziert
CityGML 2.0
Gebäudevolumen: 56,25 m3
10.5.2017
Author: V. Coors, HFT Stuttgart
Lizenz:
-->
<core:cityObjectMember>
<bldg:Building
gml:id=
"_Simple_BD.1"
>
<bldg:lod2Solid>
<gml:Solid>
<gml:exterior>
<gml:CompositeSurface>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.1"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.2"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.3"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.4"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.5"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.6"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.7"
/>
</gml:CompositeSurface>
</gml:exterior>
</gml:Solid>
</bldg:lod2Solid>
<bldg:boundedBy>
<bldg:WallSurface
gml:id=
"_Simple_BD.1_WallSurface_1"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.2"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.2_LR.1"
>
<gml:posList
srsDimension=
"3"
>
13.0 15.0 0.0
13.0 15.0 3.0
13.0 10.0 3.0
13.0 10.0 0.0
13.0 15.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:WallSurface
gml:id=
"_Simple_BD.1_WallSurface_2"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.3"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.3_LR.1"
>
<gml:posList
srsDimension=
"3"
>
10.0 15.0 0.0
10.0 15.0 3.0
11.5 15.0 4.5
13.0 15.0 3.0
13.0 15.0 0.0
10.0 15.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:WallSurface
gml:id=
"_Simple_BD.1_WallSurface_3"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.4"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.4_LR.1"
>
<gml:posList
srsDimension=
"3"
>
10.0 10.0 3.0
10.0 15.0 3.0
10.0 15.0 0.0
10.0 10.0 0.0
10.0 10.0 3.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:WallSurface
gml:id=
"_Simple_BD.1_WallSurface_4"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.5"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.5_LR.1"
>
<gml:posList
srsDimension=
"3"
>
13.0 10.0 0.0
13.0 10.0 3.0
11.5 10.0 4.5
10.0 10.0 3.0
10.0 10.0 0.0
13.0 10.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:RoofSurface
gml:id=
"_Simple_BD.1_RoofSurface_1"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.6"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.6_LR.1"
>
<gml:posList
srsDimension=
"3"
>
10.0 10.0 3.0
11.5 10.0 4.5
11.5 15.0 4.5
10.0 15.0 3.0
10.0 10.0 3.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.7"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.7_LR.1"
>
<gml:posList
srsDimension=
"3"
>
11.5 10.0 4.5
13.0 10.0 3.0
13.0 15.0 3.0
11.5 15.0 4.5
11.5 10.0 4.5
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:RoofSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:GroundSurface
gml:id=
"_Simple_BD.1_GroundSurface_1"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.1"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.1_LR.1"
>
<gml:posList
srsDimension=
"3"
>
10.0 10.0 0.0
10.0 15.0 0.0
13.0 15.0 0.0
13.0 10.0 0.0
10.0 10.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:GroundSurface>
</bldg:boundedBy>
</bldg:Building>
</core:cityObjectMember>
</core:CityModel>
\ No newline at end of file
CityDoctorParent/Extensions/CityDoctorHealerGenetic/src/test/resources/TestBuilding3.gml
0 → 100644
View file @
97a65114
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<core:CityModel
xmlns:xAL=
"urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"
xmlns:gml=
"http://www.opengis.net/gml"
xmlns:wtr=
"http://www.opengis.net/citygml/waterbody/2.0"
xmlns:app=
"http://www.opengis.net/citygml/appearance/2.0"
xmlns:tex=
"http://www.opengis.net/citygml/texturedsurface/2.0"
xmlns:core=
"http://www.opengis.net/citygml/2.0"
xmlns:veg=
"http://www.opengis.net/citygml/vegetation/2.0"
xmlns:dem=
"http://www.opengis.net/citygml/relief/2.0"
xmlns:tran=
"http://www.opengis.net/citygml/transportation/2.0"
xmlns:bldg=
"http://www.opengis.net/citygml/building/2.0"
xmlns:grp=
"http://www.opengis.net/citygml/cityobjectgroup/2.0"
xmlns:tun=
"http://www.opengis.net/citygml/tunnel/2.0"
xmlns:frn=
"http://www.opengis.net/citygml/cityfurniture/2.0"
xmlns:brid=
"http://www.opengis.net/citygml/bridge/2.0"
xmlns:gen=
"http://www.opengis.net/citygml/generics/2.0"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
xmlns:luse=
"http://www.opengis.net/citygml/landuse/2.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://www.opengis.net/citygml/waterbody/2.0 http://schemas.opengis.net/citygml/waterbody/2.0/waterBody.xsd http://www.opengis.net/citygml/appearance/2.0 http://schemas.opengis.net/citygml/appearance/2.0/appearance.xsd http://www.opengis.net/citygml/texturedsurface/2.0 http://schemas.opengis.net/citygml/texturedsurface/2.0/texturedSurface.xsd http://www.opengis.net/citygml/vegetation/2.0 http://schemas.opengis.net/citygml/vegetation/2.0/vegetation.xsd http://www.opengis.net/citygml/relief/2.0 http://schemas.opengis.net/citygml/relief/2.0/relief.xsd http://www.opengis.net/citygml/transportation/2.0 http://schemas.opengis.net/citygml/transportation/2.0/transportation.xsd http://www.opengis.net/citygml/building/2.0 http://schemas.opengis.net/citygml/building/2.0/building.xsd http://www.opengis.net/citygml/cityobjectgroup/2.0 http://schemas.opengis.net/citygml/cityobjectgroup/2.0/cityObjectGroup.xsd http://www.opengis.net/citygml/tunnel/2.0 http://schemas.opengis.net/citygml/tunnel/2.0/tunnel.xsd http://www.opengis.net/citygml/cityfurniture/2.0 http://schemas.opengis.net/citygml/cityfurniture/2.0/cityFurniture.xsd http://www.opengis.net/citygml/bridge/2.0 http://schemas.opengis.net/citygml/bridge/2.0/bridge.xsd http://www.opengis.net/citygml/generics/2.0 http://schemas.opengis.net/citygml/generics/2.0/generics.xsd http://www.opengis.net/citygml/landuse/2.0 http://schemas.opengis.net/citygml/landuse/2.0/landUse.xsd"
>
<core:cityObjectMember>
<bldg:Building
gml:id=
"CityDoctor_1554214838753_127"
>
<bldg:lod2Solid>
<gml:Solid>
<gml:exterior>
<gml:CompositeSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838751_87"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838751_88"
>
<gml:posList
srsDimension=
"3"
>
14.287969134242111 6.980188861133052 11.705669515625218 8.176969134266791 11.854188861900461 17.075669515625194 8.176969134266791 11.854188861900461 17.075669515625194 8.513969134266326 6.604188861900462 11.705669515625218 9.511969134229538 6.669188861378921 11.705669515625218 14.287969134242111 6.980188861133052 11.705669515625218
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838751_89"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838751_90"
>
<gml:posList
srsDimension=
"3"
>
8.176969134266791 11.854188861900461 17.075669515625194 8.176969134266791 11.854188861900461 17.075669515625194 14.287969134242111 6.980188861133052 11.705669515625218 13.9599691342626 12.015188861282063 16.851669515625204 13.9599691342626 12.015188861282063 16.851669515625204 13.94496913424863 12.234188861788702 17.075669515625194 13.94496913424863 12.234188861788702 17.075669515625194 8.176969134266791 11.854188861900461 17.075669515625194
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838751_91"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838751_92"
>
<gml:posList
srsDimension=
"3"
>
7.835969134251889 17.16018886176635 11.705669515625218 10.890969134244905 14.697188861311865 14.390669515625191 13.94496913424863 12.234188861788702 17.075669515625194 13.94496913424863 12.234188861788702 17.075669515625194 13.59996913427657 17.532188861274612 11.705669515625218 7.835969134251889 17.16018886176635 11.705669515625218
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838751_93"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838751_94"
>
<gml:posList
srsDimension=
"3"
>
10.890969134244905 14.697188861311865 14.390669515625191 7.835969134251889 17.16018886176635 11.705669515625218 8.176969134266791 11.854188861900461 17.075669515625194 8.176969134266791 11.854188861900461 17.075669515625194 13.94496913424863 12.234188861788702 17.075669515625194 13.94496913424863 12.234188861788702 17.075669515625194 10.890969134244905 14.697188861311865 14.390669515625191
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838751_95"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_96"
>
<gml:posList
srsDimension=
"3"
>
14.287969134242111 6.980188861133052 16.845669515625204 13.9599691342626 12.015188861282063 16.851669515625204 13.9599691342626 12.015188861282063 16.851669515625204 9.511969134229538 6.669188861378921 11.705669515625218 14.287969134242111 6.980188861133052 16.845669515625204 14.287969134242111 6.980188861133052 16.845669515625204
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_97"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_98"
>
<gml:posList
srsDimension=
"3"
>
11.757969134272379 16.75918886122991 14.390669515625191 11.757969134272379 16.75918886122991 14.390669515625191 9.761969134229538 16.627188861013842 14.390669515625191 9.761969134229538 16.627188861013842 14.390669515625191 9.892969134281692 14.631188861669493 14.390669515625191 9.892969134281692 14.631188861669493 14.390669515625191 11.888969134266326 14.76318886188556 14.390669515625191 11.888969134266326 14.76318886188556 14.390669515625191 11.757969134272379 16.75918886122991 14.390669515625191
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_99"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_100"
>
<gml:posList
srsDimension=
"3"
>
7.835969134251889 17.16018886176635 6.105669515625194 13.59996913427657 17.532188861274612 6.105669515625194 14.287969134242111 6.980188861133052 6.105669515625194 8.513969134266326 6.604188861900462 6.105669515625194 7.835969134251889 17.16018886176635 6.105669515625194
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_101"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_102"
>
<gml:posList
srsDimension=
"3"
>
13.59996913427657 17.532188861274612 11.705669515625218 7.835969134251889 17.16018886176635 11.705669515625218 8.513969134266326 6.604188861900462 11.705669515625218 9.511969134229538 6.669188861378921 11.705669515625218 14.287969134242111 6.980188861133052 11.705669515625218 13.59996913427657 17.532188861274612 11.705669515625218
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_103"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_104"
>
<gml:posList
srsDimension=
"3"
>
13.59996913427657 17.532188861274612 6.105669515625194 7.835969134251889 17.16018886176635 6.105669515625194 7.835969134251889 17.16018886176635 11.705669515625218 13.59996913427657 17.532188861274612 11.705669515625218 13.59996913427657 17.532188861274612 6.105669515625194
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_105"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_106"
>
<gml:posList
srsDimension=
"3"
>
14.287969134242111 6.980188861133052 6.105669515625194 13.59996913427657 17.532188861274612 6.105669515625194 13.59996913427657 17.532188861274612 11.705669515625218 14.287969134242111 6.980188861133052 11.705669515625218 14.287969134242111 6.980188861133052 6.105669515625194
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_107"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_108"
>
<gml:posList
srsDimension=
"3"
>
8.513969134266326 6.604188861900462 6.105669515625194 14.287969134242111 6.980188861133052 6.105669515625194 14.287969134242111 6.980188861133052 11.705669515625218 9.511969134229538 6.669188861378921 11.705669515625218 8.513969134266326 6.604188861900462 11.705669515625218 8.513969134266326 6.604188861900462 6.105669515625194
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_109"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_110"
>
<gml:posList
srsDimension=
"3"
>
7.835969134251889 17.16018886176635 6.105669515625194 8.513969134266326 6.604188861900462 6.105669515625194 8.513969134266326 6.604188861900462 11.705669515625218 7.835969134251889 17.16018886176635 11.705669515625218 7.835969134251889 17.16018886176635 6.105669515625194
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_111"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_112"
>
<gml:posList
srsDimension=
"3"
>
8.176969134266791 11.854188861900461 17.075669515625194 8.176969134266791 11.854188861900461 17.075669515625194 7.835969134251889 17.16018886176635 11.705669515625218 8.513969134266326 6.604188861900462 11.705669515625218 8.176969134266791 11.854188861900461 17.075669515625194
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_113"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_114"
>
<gml:posList
srsDimension=
"3"
>
13.94496913424863 12.234188861788702 17.075669515625194 13.94496913424863 12.234188861788702 17.075669515625194 13.9599691342626 12.015188861282063 16.851669515625204 13.9599691342626 12.015188861282063 16.851669515625204 14.287969134242111 6.980188861133052 11.705669515625218 13.59996913427657 17.532188861274612 11.705669515625218 13.94496913424863 12.234188861788702 17.075669515625194
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_115"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_116"
>
<gml:posList
srsDimension=
"3"
>
13.9599691342626 12.015188861282063 16.851669515625204 13.9599691342626 12.015188861282063 16.851669515625204 9.511969134229538 6.669188861378921 11.705669515625218 14.287969134242111 6.980188861133052 11.705669515625218 13.9599691342626 12.015188861282063 16.851669515625204
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_117"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_118"
>
<gml:posList
srsDimension=
"3"
>
13.9599691342626 12.015188861282063 16.851669515625204 13.9599691342626 12.015188861282063 16.851669515625204 14.287969134242111 6.980188861133052 16.845669515625204 14.287969134242111 6.980188861133052 16.845669515625204 14.287969134242111 6.980188861133052 11.705669515625218 13.9599691342626 12.015188861282063 16.851669515625204
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_119"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838752_120"
>
<gml:posList
srsDimension=
"3"
>
11.757969134272379 16.75918886122991 14.390669515625191 11.757969134272379 16.75918886122991 14.390669515625191 11.757969134272379 16.75918886122991 12.36666951562519 9.761969134229538 16.627188861013842 12.3686695156252 9.761969134229538 16.627188861013842 14.390669515625191 9.761969134229538 16.627188861013842 14.390669515625191 11.757969134272379 16.75918886122991 14.390669515625191
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838752_121"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838753_122"
>
<gml:posList
srsDimension=
"3"
>
9.761969134229538 16.627188861013842 12.3686695156252 9.892969134281692 14.631188861669493 14.390669515625191 9.892969134281692 14.631188861669493 14.390669515625191 9.761969134229538 16.627188861013842 14.390669515625191 9.761969134229538 16.627188861013842 14.390669515625191 9.761969134229538 16.627188861013842 12.3686695156252
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838753_123"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838753_124"
>
<gml:posList
srsDimension=
"3"
>
14.287969134242111 6.980188861133052 11.705669515625218 14.287969134242111 6.980188861133052 16.845669515625204 14.287969134242111 6.980188861133052 16.845669515625204 14.287969134242111 6.980188861133052 16.845669515625204 9.511969134229538 6.669188861378921 11.705669515625218 14.287969134242111 6.980188861133052 11.705669515625218
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"CityDoctor_1554214838753_125"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"CityDoctor_1554214838753_126"
>
<gml:posList
srsDimension=
"3"
>
11.757969134272379 16.75918886122991 12.36666951562519 11.757969134272379 16.75918886122991 14.390669515625191 11.757969134272379 16.75918886122991 14.390669515625191 11.757969134272379 16.75918886122991 14.390669515625191 11.888969134266326 14.76318886188556 14.390669515625191 11.888969134266326 14.76318886188556 14.390669515625191 11.757969134272379 16.75918886122991 12.36666951562519
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:CompositeSurface>
</gml:exterior>
</gml:Solid>
</bldg:lod2Solid>
</bldg:Building>
</core:cityObjectMember>
</core:CityModel>
\ No newline at end of file
CityDoctorParent/Extensions/CityDoctorWebService/DBScripts/pgpass.conf
0 → 100644
View file @
97a65114
localhost
:
5432
:*:
postgres
:
admin
\ No newline at end of file
CityDoctorParent/Extensions/CityDoctorWebService/pom.xml
0 → 100644
View file @
97a65114
<?xml version="1.0" encoding="utf-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"https://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
de.hft.stuttgart
</groupId>
<artifactId>
CityDoctorParent
</artifactId>
<version>
3.15.0
</version>
<relativePath>
../../pom.xml
</relativePath>
</parent>
<artifactId>
CityDoctorWebService
</artifactId>
<packaging>
war
</packaging>
<name>
CityDoctorWebService
</name>
<dependencies>
<dependency>
<groupId>
de.hft.stuttgart
</groupId>
<artifactId>
CityDoctorModel
</artifactId>
</dependency>
<dependency>
<groupId>
de.hft.stuttgart
</groupId>
<artifactId>
CityDoctorValidation
</artifactId>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.apache.httpcomponents
</groupId>
<artifactId>
httpclient
</artifactId>
<version>
4.5.9
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.apache.httpcomponents
</groupId>
<artifactId>
httpmime
</artifactId>
<version>
4.5.9
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.json
</groupId>
<artifactId>
json
</artifactId>
<version>
20180813
</version>
</dependency>
<dependency>
<groupId>
javax.servlet
</groupId>
<artifactId>
javax.servlet-api
</artifactId>
<version>
3.1.0
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
org.postgresql
</groupId>
<artifactId>
postgresql
</artifactId>
<version>
42.2.6
</version>
</dependency>
<dependency>
<groupId>
org.glassfish.jersey.containers
</groupId>
<artifactId>
jersey-container-servlet
</artifactId>
<version>
2.29
</version>
</dependency>
<dependency>
<groupId>
org.glassfish.jersey.inject
</groupId>
<artifactId>
jersey-hk2
</artifactId>
<version>
2.29
</version>
</dependency>
<dependency>
<groupId>
org.glassfish.jersey.media
</groupId>
<artifactId>
jersey-media-json-jackson
</artifactId>
<version>
2.29
</version>
</dependency>
<dependency>
<groupId>
org.glassfish.jersey.media
</groupId>
<artifactId>
jersey-media-multipart
</artifactId>
<version>
2.29
</version>
</dependency>
<dependency>
<groupId>
org.hibernate
</groupId>
<artifactId>
hibernate-core
</artifactId>
</dependency>
<dependency>
<groupId>
org.hibernate
</groupId>
<artifactId>
hibernate-search-orm
</artifactId>
</dependency>
<dependency>
<groupId>
org.apache.logging.log4j
</groupId>
<artifactId>
log4j-api
</artifactId>
</dependency>
<dependency>
<groupId>
org.apache.logging.log4j
</groupId>
<artifactId>
log4j-core
</artifactId>
</dependency>
</dependencies>
<build>
<finalName>
CityDoctorWebService
</finalName>
<plugins>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-war-plugin
</artifactId>
<version>
3.3.1
</version>
</plugin>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-surefire-plugin
</artifactId>
<configuration>
<skipTests>
true
</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
CityDoctorParent/Extensions/CityDoctorWebService/src/main/java/de/hft/stuttgart/citydoctor2/webservice/AuthenticationException.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.webservice
;
public
class
AuthenticationException
extends
Exception
{
private
static
final
long
serialVersionUID
=
1734788211196618632L
;
public
AuthenticationException
()
{
super
();
}
public
AuthenticationException
(
String
message
,
Throwable
cause
,
boolean
enableSuppression
,
boolean
writableStackTrace
)
{
super
(
message
,
cause
,
enableSuppression
,
writableStackTrace
);
}
public
AuthenticationException
(
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
}
public
AuthenticationException
(
String
message
)
{
super
(
message
);
}
public
AuthenticationException
(
Throwable
cause
)
{
super
(
cause
);
}
}
CityDoctorParent/Extensions/CityDoctorWebService/src/main/java/de/hft/stuttgart/citydoctor2/webservice/CityDoctorWebService.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.webservice
;
import
javax.ws.rs.ApplicationPath
;
import
org.glassfish.jersey.media.multipart.MultiPartFeature
;
import
org.glassfish.jersey.server.ResourceConfig
;
import
de.hft.stuttgart.citydoctor2.webservice.endpoints.BuildingEndpoint
;
import
de.hft.stuttgart.citydoctor2.webservice.endpoints.ChecksEndpoint
;
import
de.hft.stuttgart.citydoctor2.webservice.endpoints.LoginEndpoint
;
import
de.hft.stuttgart.citydoctor2.webservice.endpoints.LogoutEndpoint
;
import
de.hft.stuttgart.citydoctor2.webservice.endpoints.ModelsEndpoint
;
import
de.hft.stuttgart.citydoctor2.webservice.endpoints.RegisterEndpoint
;
import
de.hft.stuttgart.citydoctor2.webservice.endpoints.ValidationEndpoint
;
@ApplicationPath
(
"/rest"
)
public
class
CityDoctorWebService
extends
ResourceConfig
{
public
CityDoctorWebService
()
{
register
(
LoginEndpoint
.
class
);
register
(
RegisterEndpoint
.
class
);
register
(
ModelsEndpoint
.
class
);
register
(
MultiPartFeature
.
class
);
register
(
BuildingEndpoint
.
class
);
register
(
ValidationEndpoint
.
class
);
register
(
LogoutEndpoint
.
class
);
register
(
ChecksEndpoint
.
class
);
}
}
CityDoctorParent/Extensions/CityDoctorWebService/src/main/java/de/hft/stuttgart/citydoctor2/webservice/ServletInitListener.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.webservice
;
import
java.sql.Driver
;
import
java.sql.DriverManager
;
import
java.sql.SQLException
;
import
java.util.Enumeration
;
import
javax.servlet.ServletContextEvent
;
import
javax.servlet.ServletContextListener
;
import
javax.servlet.annotation.WebListener
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
de.hft.stuttgart.citydoctor2.webservice.database.ModelQueries
;
import
de.hft.stuttgart.citydoctor2.webservice.utils.HibernateUtils
;
@WebListener
public
class
ServletInitListener
implements
ServletContextListener
{
private
static
Logger
logger
=
LogManager
.
getLogger
(
ServletInitListener
.
class
);
@Override
public
void
contextInitialized
(
ServletContextEvent
sce
)
{
HibernateUtils
.
init
();
logger
.
info
(
"Removing models in state 'parsing'"
);
ModelQueries
.
cleanup
();
}
@Override
public
void
contextDestroyed
(
ServletContextEvent
sce
)
{
HibernateUtils
.
shutdown
();
ClassLoader
cl
=
Thread
.
currentThread
().
getContextClassLoader
();
Enumeration
<
Driver
>
drivers
=
DriverManager
.
getDrivers
();
while
(
drivers
.
hasMoreElements
())
{
Driver
driver
=
drivers
.
nextElement
();
if
(
driver
.
getClass
().
getClassLoader
()
==
cl
)
{
try
{
DriverManager
.
deregisterDriver
(
driver
);
logger
.
info
(
"Deregistering JDBC driver: {}"
,
driver
);
}
catch
(
SQLException
e
)
{
logger
.
error
(
"Error deregistering driver {}"
,
driver
);
logger
.
error
(
""
,
e
);
}
}
}
}
}
CityDoctorParent/Extensions/CityDoctorWebService/src/main/java/de/hft/stuttgart/citydoctor2/webservice/UnknownUserException.java
0 → 100644
View file @
97a65114
package
de.hft.stuttgart.citydoctor2.webservice
;
public
class
UnknownUserException
extends
Exception
{
private
static
final
long
serialVersionUID
=
-
8582004030128118170L
;
public
UnknownUserException
()
{
super
();
}
public
UnknownUserException
(
String
message
,
Throwable
cause
,
boolean
enableSuppression
,
boolean
writableStackTrace
)
{
super
(
message
,
cause
,
enableSuppression
,
writableStackTrace
);
}
public
UnknownUserException
(
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
}
public
UnknownUserException
(
String
message
)
{
super
(
message
);
}
public
UnknownUserException
(
Throwable
cause
)
{
super
(
cause
);
}
}
Prev
1
…
21
22
23
24
25
26
27
28
29
30
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