From a10cd1956a444bea10594773cecc3c6109768fe9 Mon Sep 17 00:00:00 2001 From: Matthias Betz Date: Wed, 11 Nov 2020 15:56:53 +0100 Subject: [PATCH] low memory consumption mode implementation, when loading a complete model --- .../citydoctor2/check/Checkable.java | 17 ++++++++++++-- .../datastructure/AbstractBuilding.java | 22 +++++++++++++++++++ .../datastructure/BoundarySurface.java | 16 ++++++++++++++ .../datastructure/BridgeObject.java | 16 ++++++++++++++ .../citydoctor2/datastructure/Building.java | 16 ++++++++++++++ .../datastructure/BuildingInstallation.java | 16 ++++++++++++++ .../citydoctor2/datastructure/CityObject.java | 14 ++++++++++++ .../datastructure/ConcretePolygon.java | 10 +++++++++ .../citydoctor2/datastructure/Geometry.java | 12 ++++++++++ .../citydoctor2/datastructure/LinearRing.java | 11 +++++++++- .../datastructure/LinkedPolygon.java | 10 +++++++++ .../datastructure/TransportationObject.java | 18 ++++++++++++++- .../citydoctor2/mapper/FeatureMapper.java | 13 ++++++++--- .../parser/ParserConfiguration.java | 10 +++++++++ .../CityDoctorLocalization.properties | 3 ++- .../CityDoctorLocalization_de.properties | 3 ++- .../stuttgart/citydoctor2/check/Checker.java | 9 ++++++++ 17 files changed, 207 insertions(+), 9 deletions(-) diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Checkable.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Checkable.java index 6f1c035d..fa3be69f 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Checkable.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Checkable.java @@ -42,11 +42,11 @@ public abstract class Checkable implements Serializable { private EnumMap checkResults = new EnumMap<>(CheckId.class); private boolean isValidated = false; - + protected void setValidated(boolean validated) { isValidated = validated; } - + public boolean isValidated() { return isValidated; } @@ -75,6 +75,19 @@ public abstract class Checkable implements Serializable { */ public abstract GmlId getGmlId(); + /** + * This should be called before executing a check if low memory consumption + * method has been enabled. This should create edges and additional meta + * information necessary to perform checks. + */ + public abstract void prepareForChecking(); + + /** + * This should be called after checking has been done. This should remove any + * created meta information like edges to free up additional memory space + */ + public abstract void clearMetaInformation(); + /** * This method checks if the object or any object contained within this * checkable has an error. It counts as an error if the result status if the diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/AbstractBuilding.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/AbstractBuilding.java index 7b1442ec..b753f181 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/AbstractBuilding.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/AbstractBuilding.java @@ -257,4 +257,26 @@ public abstract class AbstractBuilding extends CityObject { public List getBuildingInstallations() { return buildingInstallations; } + + @Override + public void prepareForChecking() { + super.prepareForChecking(); + for (BuildingInstallation bi : buildingInstallations) { + bi.prepareForChecking(); + } + for (BoundarySurface bs : boundarySurfaceList) { + bs.prepareForChecking(); + } + } + + @Override + public void clearMetaInformation() { + super.clearMetaInformation(); + for (BuildingInstallation bi : buildingInstallations) { + bi.clearMetaInformation(); + } + for (BoundarySurface bs : boundarySurfaceList) { + bs.clearMetaInformation(); + } + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurface.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurface.java index ba4a1d1c..2674457a 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurface.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurface.java @@ -295,4 +295,20 @@ public class BoundarySurface extends CityObject { opening.setPartOfSurface(this); } + @Override + public void prepareForChecking() { + super.prepareForChecking(); + for (Opening o : openings) { + o.prepareForChecking(); + } + } + + @Override + public void clearMetaInformation() { + super.clearMetaInformation(); + for (Opening o : openings) { + o.clearMetaInformation(); + } + } + } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObject.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObject.java index 6b8dbd53..c155ab8b 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObject.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObject.java @@ -214,5 +214,21 @@ public class BridgeObject extends CityObject { public String toString() { return "BridgeObject [type=" + type + ", id=" + getGmlId() + "]"; } + + @Override + public void prepareForChecking() { + super.prepareForChecking(); + for (BoundarySurface bs : boundarySurfaces) { + bs.prepareForChecking(); + } + } + + @Override + public void clearMetaInformation() { + super.clearMetaInformation(); + for (BoundarySurface bs : boundarySurfaces) { + bs.clearMetaInformation(); + } + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Building.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Building.java index fea355ea..7b7190dd 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Building.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Building.java @@ -134,4 +134,20 @@ public class Building extends AbstractBuilding { } setCityGmlBuilding(gmlB); } + + @Override + public void clearMetaInformation() { + super.clearMetaInformation(); + for (BuildingPart part : buildingParts) { + part.clearMetaInformation(); + } + } + + @Override + public void prepareForChecking() { + super.prepareForChecking(); + for (BuildingPart part : buildingParts) { + part.prepareForChecking(); + } + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingInstallation.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingInstallation.java index 9d302fdd..031c2acb 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingInstallation.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingInstallation.java @@ -193,6 +193,22 @@ public class BuildingInstallation extends CityObject { return boundarySurfaces; } + @Override + public void clearMetaInformation() { + super.clearMetaInformation(); + for (BoundarySurface bs : boundarySurfaces) { + bs.clearMetaInformation(); + } + } + + @Override + public void prepareForChecking() { + super.prepareForChecking(); + for (BoundarySurface bs : boundarySurfaces) { + bs.prepareForChecking(); + } + } + } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CityObject.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CityObject.java index c1b5c95e..3aaeafe7 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CityObject.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CityObject.java @@ -172,4 +172,18 @@ public abstract class CityObject extends GmlElement { } return null; } + + @Override + public void prepareForChecking() { + for (Geometry geom : geometryList) { + geom.prepareForChecking(); + } + } + + @Override + public void clearMetaInformation() { + for (Geometry geom : geometryList) { + geom.clearMetaInformation(); + } + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ConcretePolygon.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ConcretePolygon.java index a673ba10..55650771 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ConcretePolygon.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ConcretePolygon.java @@ -440,4 +440,14 @@ public class ConcretePolygon extends Polygon { void setLinkedTo(LinkedPolygon linkedPolygon) { linkedFromPolygon = linkedPolygon; } + + @Override + public void prepareForChecking() { + parent.prepareForChecking(); + } + + @Override + public void clearMetaInformation() { + parent.clearMetaInformation(); + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Geometry.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Geometry.java index fe6ce305..ec554b63 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Geometry.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Geometry.java @@ -405,4 +405,16 @@ public class Geometry extends GmlElement { public Geometry copy() { return (Geometry) super.copy(); } + + @Override + public void prepareForChecking() { + updateEdgesAndVertices(); + } + + @Override + public void clearMetaInformation() { + edges = null; + vertices = null; + edgeMap = null; + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinearRing.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinearRing.java index 8e2645ed..e7b3051d 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinearRing.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinearRing.java @@ -246,5 +246,14 @@ public class LinearRing extends GmlElement { public void addAllVertices(List extRing) { vertices.addAll(extRing); } - + + @Override + public void prepareForChecking() { + parent.getParent().prepareForChecking(); + } + + @Override + public void clearMetaInformation() { + parent.getParent().clearMetaInformation(); + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinkedPolygon.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinkedPolygon.java index 23d053aa..1c2784ae 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinkedPolygon.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinkedPolygon.java @@ -246,5 +246,15 @@ public class LinkedPolygon extends Polygon { public ConcretePolygon getOriginal() { return poly; } + + @Override + public void prepareForChecking() { + poly.prepareForChecking(); + } + + @Override + public void clearMetaInformation() { + poly.clearMetaInformation(); + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationObject.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationObject.java index f24d072e..3487869b 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationObject.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationObject.java @@ -51,7 +51,7 @@ public class TransportationObject extends CityObject { } private AbstractTransportationObject ato; - private List composesOf = new ArrayList<>(); + private List composesOf = new ArrayList<>(1); private TransportationType type; public TransportationObject(TransportationType type) { @@ -253,5 +253,21 @@ public class TransportationObject extends CityObject { public String toString() { return "TransportationObject [id=" + getGmlId() + "]"; } + + @Override + public void prepareForChecking() { + super.prepareForChecking(); + for (TransportationObject child : composesOf) { + child.prepareForChecking(); + } + } + + @Override + public void clearMetaInformation() { + super.clearMetaInformation(); + for (TransportationObject child : composesOf) { + child.clearMetaInformation(); + } + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/FeatureMapper.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/FeatureMapper.java index 989c4f68..ebf0821a 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/FeatureMapper.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/FeatureMapper.java @@ -154,7 +154,6 @@ public class FeatureMapper extends FeatureWalker { } private void updateEdgesAndVertices(CityObject co) { - for (Geometry geom : co.getGeometries()) { geom.updateVertices(); KDTree tree = new KDTree(); @@ -170,8 +169,16 @@ public class FeatureMapper extends FeatureWalker { v.addNeighbor(neighbor); } } - - geom.updateEdges(); + + if (config.useLowMemoryConsumption()) { + // do not create edges and vertices + // vertices were already created because they were needed for the kd tree + // remove them again + geom.clearMetaInformation(); + } else { + // create edges + geom.updateEdges(); + } } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/ParserConfiguration.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/ParserConfiguration.java index 415dc50b..139bfd54 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/ParserConfiguration.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/ParserConfiguration.java @@ -46,15 +46,21 @@ public class ParserConfiguration implements Serializable { private String targetTransformString; private String originalTransformString; private boolean hasTransformation = false; + private boolean useLowMemoryConsumption = false; private transient double fromMetres = 1.0; public ParserConfiguration(int numberOfRoundingPlaces, boolean validate) { + this(numberOfRoundingPlaces, validate, false); + } + + public ParserConfiguration(int numberOfRoundingPlaces, boolean validate, boolean lowMemory) { if (numberOfRoundingPlaces < 0) { throw new IllegalArgumentException("Number of rounding places must be a positive value"); } roundingPlaces = numberOfRoundingPlaces; this.validate = validate; + useLowMemoryConsumption = lowMemory; } public boolean getValidate() { @@ -107,5 +113,9 @@ public class ParserConfiguration implements Serializable { public double getFromMetres() { return fromMetres; } + + public boolean useLowMemoryConsumption() { + return useLowMemoryConsumption; + } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization.properties b/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization.properties index 4ff2f4ac..92600e47 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization.properties +++ b/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization.properties @@ -110,4 +110,5 @@ CityGmlParser.noEPSG=Could not read EPSG code, assuming metric system OpenFileDialog.loadFailed=Failed to load CityGML File MainWindow.memoryLabel=Memory: CheckDialog.checksReenabledAlert=Some checks have been reenabled so that other wanted checks can be executed\nSee the log for more information. -MainWindow.availableLabel=Available: \ No newline at end of file +MainWindow.availableLabel=Available: +OpenFileDialog.lowMemoryLabel=Low Memory Consumption Mode \ No newline at end of file diff --git a/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization_de.properties b/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization_de.properties index be6efc30..735fa1be 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization_de.properties +++ b/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization_de.properties @@ -108,4 +108,5 @@ CityGmlParser.noEPSG=Konnte EPSG Code nicht lesen, nehme metrisches System an OpenFileDialog.loadFailed=Konnte CityGML Datei nicht laden MainWindow.memoryLabel=Speicher: CheckDialog.checksReenabledAlert=Manche Pr\u00fcfungen wurden reaktiviert damit andere gewollte Pr\u00fcfungen durchgef\u00fchrt werden k\u00f6nnen\nMehr Details sind im Log geschrieben -MainWindow.availableLabel=Verf\u00fcgbar: \ No newline at end of file +MainWindow.availableLabel=Verf\u00fcgbar: +OpenFileDialog.lowMemoryLabel=Reduzierter Speicherverbrauchsmodus \ No newline at end of file diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java index f5d142d3..c406ae62 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java @@ -362,8 +362,17 @@ public class Checker { // stupid lamda with final variable restrictions int[] currentFeature = new int[1]; features.forEach(co -> { + if (config.getParserConfiguration().useLowMemoryConsumption()) { + // no edges have been created yet, create them + co.prepareForChecking(); + } // check every feature executeChecksForCityObject(co); + + if (config.getParserConfiguration().useLowMemoryConsumption()) { + // low memory consumption, remove edges again + co.clearMetaInformation(); + } if (l != null) { currentFeature[0]++; l.updateProgress(currentFeature[0] / featureSum); -- GitLab