diff --git a/CHANGELOG.md b/CHANGELOG.md index cbd3a0e8b69629fdaf5483780e60b0591f83436f..743f2c2775f500ac47fa89336067a62fe96d1cca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [3.17.0] (TBD) +## [3.17.0] (2025-03-13) ### Added 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 a654fd4cce5ea15e2d6f1ab1b1b4f13d26b750b0..d0c3ea97b117ca4bf6ed240278ceb6576534bba5 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 @@ -50,6 +50,7 @@ public class ConcretePolygon extends Polygon { private BoundarySurface partOfSurface; private Installation partfOfInstallation; private CompositeCollection partOfComposite = null; + private PatchCollection partOfPatch = null; private Geometry parent; private LinkedPolygon linkedFromPolygon; @@ -141,6 +142,18 @@ public class ConcretePolygon extends Polygon { this.partOfComposite = comp; } + protected void setPartOfPatch(PatchCollection pc) { + this.partOfPatch = pc; + } + + public PatchCollection getPartOfPatch(PatchCollection pc) { + return partOfPatch; + } + + public boolean isPatchMember() { + return partOfPatch != null; + } + public CompositeCollection getPartOfComposite() { return partOfComposite; } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/PatchCollection.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/PatchCollection.java new file mode 100644 index 0000000000000000000000000000000000000000..5671c4a8b4f79edf81cf7046b7e8fc2d941d6d47 --- /dev/null +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/PatchCollection.java @@ -0,0 +1,25 @@ +package de.hft.stuttgart.citydoctor2.datastructure; + +import java.io.Serial; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + + +public final class PatchCollection implements Serializable { + + @Serial + private static final long serialVersionUID = -1748657379840997228L; + + private List<ConcretePolygon> patchMembers = new ArrayList<>(); + + public void addPatchMember(ConcretePolygon patchMember) { + patchMembers.add(patchMember); + patchMember.setPartOfPatch(this); + } + + public List<ConcretePolygon> getPatchMembers() { + return new ArrayList<>(patchMembers); + } + +} diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TopLevelTransportFeature.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TopLevelTransportFeature.java new file mode 100644 index 0000000000000000000000000000000000000000..7097ffd6cc019358faf57c3a05cd8d194cf6491d --- /dev/null +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TopLevelTransportFeature.java @@ -0,0 +1,242 @@ +package de.hft.stuttgart.citydoctor2.datastructure; + +import de.hft.stuttgart.citydoctor2.check.Check; +import de.hft.stuttgart.citydoctor2.check.CheckError; +import de.hft.stuttgart.citydoctor2.check.CheckId; +import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; +import de.hft.stuttgart.citydoctor2.utils.CopyHandler; +import de.hft.stuttgart.citydoctor2.utils.Copyable; +import org.citygml4j.core.model.deprecated.transportation.TransportationComplex; +import org.citygml4j.core.model.transportation.Railway; +import org.citygml4j.core.model.transportation.Road; +import org.citygml4j.core.model.transportation.Square; +import org.citygml4j.core.model.transportation.Track; +import org.citygml4j.core.model.transportation.Waterway; +import org.citygml4j.core.util.geometry.GeometryFactory; + +import java.util.ArrayList; +import java.util.List; + +public class TopLevelTransportFeature extends TransportationSpace { + + private final List<TransportSection> sections = new ArrayList<>(); + private final List<TransportSection> intersections = new ArrayList<>(); + + public static TopLevelTransportFeature from(Track t) { + TopLevelTransportFeature top = new TopLevelTransportFeature(TransportationType.TRACK); + top.setGmlObject(t); + return top; + } + + public static TopLevelTransportFeature from(Road r) { + TopLevelTransportFeature top = new TopLevelTransportFeature(TransportationType.ROAD); + top.setGmlObject(r); + return top; + } + + public static TopLevelTransportFeature from(Waterway w) { + TopLevelTransportFeature top = new TopLevelTransportFeature(TransportationType.WATERWAY); + top.setGmlObject(w); + return top; + } + + public static TopLevelTransportFeature from(Railway r) { + TopLevelTransportFeature top = new TopLevelTransportFeature(TransportationType.RAILWAY); + top.setGmlObject(r); + return top; + } + + public static TopLevelTransportFeature from(Square s) { + TopLevelTransportFeature top = new TopLevelTransportFeature(TransportationType.SQUARE); + top.setGmlObject(s); + return top; + } + + public static TopLevelTransportFeature from(TransportationComplex tc) { + TopLevelTransportFeature top = new TopLevelTransportFeature(TransportationType.TRANSPORTATION_COMPLEX); + top.setGmlObject(tc); + return top; + } + + private TopLevelTransportFeature(TransportationType type) { + super(type); + } + + + public void addSection(TransportSection section) { + sections.add(section); + } + + public void addIntersection(TransportSection section) { + intersections.add(section); + } + + public List<TransportSection> getSections() { + return sections; + } + + public List<TransportSection> getIntersections() { + return intersections; + } + + @Override + public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) { + super.reCreateGeometries(factory, config); + for (TransportSection section : sections) { + section.reCreateGeometries(factory, config); + } + for (TransportSection section : intersections) { + section.reCreateGeometries(factory, config); + } + } + + + @Override + public boolean containsError(CheckId checkIdentifier) { + boolean hasError = super.containsError(checkIdentifier); + if (hasError) { + return true; + } + for (TransportSection section : sections) { + if (section.containsError(checkIdentifier)) { + return true; + } + } + for (TransportSection section : intersections) { + if (section.containsError(checkIdentifier)) { + return true; + } + } + return false; + } + + @Override + public void clearAllContainedCheckResults() { + super.clearAllContainedCheckResults(); + for (TransportSection section : sections) { + section.clearAllContainedCheckResults(); + } + for (TransportSection section : intersections) { + section.clearAllContainedCheckResults(); + } + } + + @Override + public void collectContainedErrors(List<CheckError> errors) { + super.collectContainedErrors(errors); + for (TransportSection section : sections) { + section.collectContainedErrors(errors); + } + for (TransportSection section : intersections) { + section.collectContainedErrors(errors); + } + } + + @Override + public boolean containsAnyError() { + boolean hasError = super.containsAnyError(); + if (hasError) { + return true; + } + for (TransportSection section : sections) { + if (section.containsAnyError()) { + return true; + } + } + for (TransportSection section : intersections) { + if (section.containsAnyError()) { + return true; + } + } + return false; + } + + @Override + public void accept(Check c) { + super.accept(c); + if (c.canExecute(this)) { + c.check(this); + } + for (TransportSection section : sections) { + section.accept(c); + } + for (TransportSection section : intersections) { + section.accept(c); + } + } + + + @Override + public void unsetGmlGeometries() { + super.unsetGmlGeometries(); + for (TransportSection section : sections) { + section.unsetGmlGeometries(); + } + for (TransportSection section : intersections) { + section.unsetGmlGeometries(); + } + } + + @Override + public CityObject getTopLevelCityObject() { + return this; + } + + + @Override + public String toString() { + return "TopLevelTransportFeature [id=" + getGmlId() + "]"; + } + + @Override + public void prepareForChecking() { + super.prepareForChecking(); + for (TransportSection section : sections) { + section.prepareForChecking(); + } + for (TransportSection section : intersections) { + section.prepareForChecking(); + } + } + + @Override + public void clearMetaInformation() { + super.clearMetaInformation(); + for (TransportSection section : sections) { + section.clearMetaInformation(); + } + for (TransportSection section : intersections) { + section.clearMetaInformation(); + } + } + + @Override + public void collectInstances(CopyHandler handler) { + super.collectInstances(handler); + for (TransportSection section : sections) { + section.collectInstances(handler); + } + for (TransportSection section : intersections) { + section.collectInstances(handler); + } + } + + @Override + public void fillValues(Copyable original, CopyHandler handler) { + super.fillValues(original, handler); + TransportationObject originalTo = (TransportationObject) original; + for (TransportSection section : sections) { + section.fillValues(originalTo, handler); + } + for (TransportSection section : intersections) { + section.fillValues(originalTo, handler); + } + } + + @Override + public Copyable createCopyInstance() { + return new TopLevelTransportFeature(type); + } + + +} diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TrafficAreaObject.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TrafficAreaObject.java new file mode 100644 index 0000000000000000000000000000000000000000..28341a4c7a6a45baad8b54c38dc34d1b211371ff --- /dev/null +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TrafficAreaObject.java @@ -0,0 +1,128 @@ +package de.hft.stuttgart.citydoctor2.datastructure; + +import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; +import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils; +import org.citygml4j.core.model.transportation.AuxiliaryTrafficArea; +import org.citygml4j.core.model.transportation.TrafficArea; +import org.citygml4j.core.util.geometry.GeometryFactory; +import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface; +import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; + + +public class TrafficAreaObject extends TransportationObject { + + public enum TrafficAreaType { + TRAFFIC_AREA, AUXILIARY_TRAFFIC_AREA + } + + public TrafficAreaObject(TrafficAreaType trafficAreaType) { + if (trafficAreaType == TrafficAreaType.TRAFFIC_AREA) { + setType(TransportationType.TRAFFIC_AREA); + } else { + setType(TransportationType.AUXILLIARY_TRAFFIC_AREA); + } + } + + @Override + public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) { + for (Geometry geom : getGeometries()) { + if (geom instanceof ImplicitGeometryHolder) { + continue; + } + if (geom.getType() == GeometryType.MULTI_SURFACE) { + MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config); + switch (type) { + case TRAFFIC_AREA: + TrafficArea ta = (TrafficArea) super.getGmlObject(); + setMultiSurfaceAccordingToLod(ta, ms, geom.getLod()); + break; + case AUXILLIARY_TRAFFIC_AREA: + AuxiliaryTrafficArea ata = (AuxiliaryTrafficArea) super.getGmlObject(); + setMultiSurfaceAccordingToLod(ata, ms, geom.getLod()); + break; + } + } else { + throw new IllegalStateException("Geometry in TransportationObject cannot be of type " + geom.getType() + + ". Only MultiSurface allowed"); + } + } + } + + + private void setMultiSurfaceAccordingToLod(AuxiliaryTrafficArea ata, MultiSurface ms, Lod lod) { + switch (lod) { + case LOD0: + ata.setLod0MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD1: + ata.setLod1MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD2: + ata.setLod2MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD3: + ata.setLod3MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD4: + ata.getDeprecatedProperties().setLod4MultiSurface(new MultiSurfaceProperty(ms)); + break; + default: + throw new IllegalStateException("cannot set geometry with LOD for AuxiliaryTrafficArea: " + lod); + } + } + + private void setMultiSurfaceAccordingToLod(TrafficArea ta, MultiSurface ms, Lod lod) { + switch (lod) { + case LOD0: + ta.setLod0MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD1: + ta.setLod1MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD2: + ta.setLod2MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD3: + ta.setLod3MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD4: + ta.getDeprecatedProperties().setLod4MultiSurface(new MultiSurfaceProperty(ms)); + break; + default: + throw new IllegalStateException("cannot set geometry with LOD for TrafficArea: " + lod); + } + } + + + @Override + public void unsetGmlGeometries() { + switch (type) { + case TRAFFIC_AREA: + TrafficArea ta = (TrafficArea) super.getGmlObject(); + ta.setLod2MultiSurface(null); + ta.setLod3MultiSurface(null); + ta.getDeprecatedProperties().setLod4MultiSurface(null); + break; + case AUXILLIARY_TRAFFIC_AREA: + AuxiliaryTrafficArea ata = (AuxiliaryTrafficArea) super.getGmlObject(); + ata.setLod0MultiSurface(null); + ata.setLod1MultiSurface(null); + ata.setLod2MultiSurface(null); + ata.setLod3MultiSurface(null); + ata.getDeprecatedProperties().setLod4MultiSurface(null); + break; + } + } + + @Override + public CityObject getTopLevelCityObject() { + return this; + } + + @Override + public String toString() { + return "TrafficArea [id=" + getGmlId() + "]"; + } + + +} diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TrafficSpaceObject.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TrafficSpaceObject.java new file mode 100644 index 0000000000000000000000000000000000000000..fb07843361a55d741b2ecf8c004d6198697ce1d6 --- /dev/null +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TrafficSpaceObject.java @@ -0,0 +1,190 @@ +package de.hft.stuttgart.citydoctor2.datastructure; + +import de.hft.stuttgart.citydoctor2.check.Check; +import de.hft.stuttgart.citydoctor2.check.CheckError; +import de.hft.stuttgart.citydoctor2.check.CheckId; +import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; +import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils; +import de.hft.stuttgart.citydoctor2.utils.CopyHandler; +import de.hft.stuttgart.citydoctor2.utils.Copyable; +import org.citygml4j.core.model.core.AbstractSpace; +import org.citygml4j.core.util.geometry.GeometryFactory; +import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface; +import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; + +import java.util.ArrayList; +import java.util.List; + +public class TrafficSpaceObject extends TransportationObject { + + private final List<TrafficAreaObject> trafficAreas = new ArrayList<>(); + + public enum TrafficSpaceType { + TRAFFIC_SPACE, AUXILIARY_TRAFFIC_SPACE + } + + public TrafficSpaceObject(TrafficSpaceType trafficSpaceType) { + if (trafficSpaceType == TrafficSpaceType.TRAFFIC_SPACE) { + super.setType(TransportationType.TRAFFIC_SPACE); + } else { + super.setType(TransportationType.AUXILLIARY_TRAFFIC_SPACE); + } + } + + public List<TrafficAreaObject> getTrafficAreas() { + return trafficAreas; + } + + public void addTrafficArea(TrafficAreaObject trafficAreaObject) { + trafficAreas.add(trafficAreaObject); + } + + @Override + public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) { + for (Geometry geom : getGeometries()) { + if (geom instanceof ImplicitGeometryHolder) { + continue; + } + MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config); + AbstractSpace ats = (AbstractSpace) super.getGmlObject(); + setMultiSurfaceAccordingToLod(ats, ms, geom.getLod()); + } + for (TrafficAreaObject tao : trafficAreas) { + tao.reCreateGeometries(factory, config); + } + } + + private void setMultiSurfaceAccordingToLod(AbstractSpace ats, MultiSurface ms, Lod lod) { + switch (lod) { + case LOD0: + ats.setLod0MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD2: + ats.setLod2MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD3: + ats.setLod3MultiSurface(new MultiSurfaceProperty(ms)); + break; + default: + throw new IllegalStateException("cannot set geometry with LOD for AuxiliaryTrafficSpace: " + lod); + } + } + + @Override + public boolean containsError(CheckId checkIdentifier) { + boolean hasError = super.containsError(checkIdentifier); + if (hasError) { + return true; + } + for (TrafficAreaObject tao : trafficAreas) { + if (tao.containsError(checkIdentifier)) { + return true; + } + } + return false; + } + + @Override + public void clearAllContainedCheckResults() { + super.clearAllContainedCheckResults(); + for (TrafficAreaObject tao : trafficAreas) { + tao.clearAllContainedCheckResults(); + } + } + + @Override + public void collectContainedErrors(List<CheckError> errors) { + super.collectContainedErrors(errors); + for (TrafficAreaObject tao : trafficAreas) { + tao.collectContainedErrors(errors); + } + } + + @Override + public boolean containsAnyError() { + boolean hasError = super.containsAnyError(); + if (hasError) { + return true; + } + for (TrafficAreaObject tao : trafficAreas) { + if (tao.containsAnyError()) { + return true; + } + } + return false; + } + + @Override + public void accept(Check c) { + super.accept(c); + if (c.canExecute(this)) { + c.check(this); + } + for (TrafficAreaObject tao : trafficAreas) { + tao.accept(c); + } + } + + @Override + public void unsetGmlGeometries() { + AbstractSpace ats = (AbstractSpace) super.getGmlObject(); + ats.setLod0MultiSurface(null); + ats.setLod2MultiSurface(null); + ats.setLod3MultiSurface(null); + for (TrafficAreaObject tao : trafficAreas) { + tao.unsetGmlGeometries(); + } + } + + @Override + public CityObject getTopLevelCityObject() { + return this; + } + + + @Override + public String toString() { + return "TransportationSpaceObject [id=" + getGmlId() + "]"; + } + + @Override + public void prepareForChecking() { + super.prepareForChecking(); + for (TrafficAreaObject tao : trafficAreas) { + tao.prepareForChecking(); + } + } + + @Override + public void clearMetaInformation() { + super.clearMetaInformation(); + for (TrafficAreaObject tao : trafficAreas) { + tao.clearMetaInformation(); + } + } + + @Override + public void collectInstances(CopyHandler handler) { + super.collectInstances(handler); + for (TrafficAreaObject tao : trafficAreas) { + handler.addInstance(tao); + } + } + + @Override + public void fillValues(Copyable original, CopyHandler handler) { + super.fillValues(original, handler); + TrafficSpaceObject originalTao = (TrafficSpaceObject) original; + for (TrafficAreaObject tao : originalTao.trafficAreas) { + trafficAreas.add(handler.getCopyInstance(tao)); + } + super.setGmlObject(originalTao.getGmlObject()); + } + + @Override + public Copyable createCopyInstance() { + return new TrafficSpaceObject(null); + } + + +} diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportSection.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportSection.java new file mode 100644 index 0000000000000000000000000000000000000000..86631f6630c4602f3520cf5d7b1ca28f4b5ae149 --- /dev/null +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportSection.java @@ -0,0 +1,17 @@ +package de.hft.stuttgart.citydoctor2.datastructure; + +public class TransportSection extends TransportationSpace { + + public enum SectionType { + SECTION, INTERSECTION + } + + public TransportSection(SectionType sectionType) { + super(TransportationType.SECTION); + if (sectionType == SectionType.INTERSECTION) { + super.setType(TransportationType.INTERSECTION); + } + } + + +} 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 8cd16b6c5f07b34d1db7e513df63e8857ec65afd..9ca662ddbeb90d4022cb17b3532a571d248d4abd 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 @@ -43,190 +43,33 @@ import java.util.List; * * @author Matthias Betz */ -public class TransportationObject extends CityObject { +public abstract class TransportationObject extends CityObject { @Serial private static final long serialVersionUID = -2698907271726700390L; public enum TransportationType { - ROAD, TRACK, RAILWAY, TRAFFIC_AREA, AUXILLIARY_TRAFFIC_AREA, TRANSPORTATION_COMPLEX, SQUARE, AUXILLIARY_TRAFFIC_SPACE, TRAFFIC_SPACE + ROAD, TRACK, RAILWAY, TRAFFIC_AREA, AUXILLIARY_TRAFFIC_AREA, TRANSPORTATION_COMPLEX, SQUARE, AUXILLIARY_TRAFFIC_SPACE, + TRAFFIC_SPACE, WATERWAY, SECTION, INTERSECTION } private AbstractCityObject ato; - private final List<TransportationObject> composesOf = new ArrayList<>(1); - private final TransportationType type; + protected TransportationType type; public TransportationObject(TransportationType type) { this.type = type; } - @Override - public FeatureType getFeatureType() { - return FeatureType.TRANSPORTATION; - } - - @Override - public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) { - for (Geometry geom : getGeometries()) { - if (geom instanceof ImplicitGeometryHolder) { - continue; - } - if (geom.getType() == GeometryType.MULTI_SURFACE) { - MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config); - switch (type) { - case ROAD, TRACK, RAILWAY, SQUARE, TRANSPORTATION_COMPLEX: - AbstractTransportationSpace tc = (AbstractTransportationSpace) ato; - setMultiSurfaceAccordingToLod(tc, ms, geom.getLod()); - break; - case TRAFFIC_AREA: - TrafficArea ta = (TrafficArea) ato; - setMultiSurfaceAccordingToLod(ta, ms, geom.getLod()); - break; - case AUXILLIARY_TRAFFIC_AREA: - AuxiliaryTrafficArea ata = (AuxiliaryTrafficArea) ato; - setMultiSurfaceAccordingToLod(ata, ms, geom.getLod()); - break; - case AUXILLIARY_TRAFFIC_SPACE, TRAFFIC_SPACE: - AbstractSpace ats = (AbstractSpace) ato; - setMultiSurfaceAccordingToLod(ats, ms, geom.getLod()); - break; - } - } else { - throw new IllegalStateException("Geometry in TransportationObject cannot be of type " + geom.getType() - + ". Only MultiSurface allowed"); - } - } - for (TransportationObject children : composesOf) { - children.reCreateGeometries(factory, config); - } - } - - private void setMultiSurfaceAccordingToLod(AbstractSpace ats, MultiSurface ms, Lod lod) { - switch (lod) { - case LOD0: - ats.setLod0MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD2: - ats.setLod2MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD3: - ats.setLod3MultiSurface(new MultiSurfaceProperty(ms)); - break; - default: - throw new IllegalStateException("cannot set geometry with LOD for AuxiliaryTrafficSpace: " + lod); - } - } - - private void setMultiSurfaceAccordingToLod(AbstractTransportationSpace tc, MultiSurface ms, Lod lod) { - switch (lod) { - case LOD1: - tc.getDeprecatedProperties().setLod1MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD2: - tc.setLod2MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD3: - tc.setLod3MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD4: - tc.getDeprecatedProperties().setLod4MultiSurface(new MultiSurfaceProperty(ms)); - break; - default: - throw new IllegalStateException("cannot set geometry with LOD for TransportationComplex: " + lod); - } - } - - private void setMultiSurfaceAccordingToLod(AuxiliaryTrafficArea ata, MultiSurface ms, Lod lod) { - switch (lod) { - case LOD0: - ata.setLod0MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD1: - ata.setLod1MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD2: - ata.setLod2MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD3: - ata.setLod3MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD4: - ata.getDeprecatedProperties().setLod4MultiSurface(new MultiSurfaceProperty(ms)); - break; - default: - throw new IllegalStateException("cannot set geometry with LOD for AuxiliaryTrafficArea: " + lod); - } - } - - private void setMultiSurfaceAccordingToLod(TrafficArea ta, MultiSurface ms, Lod lod) { - switch (lod) { - case LOD2: - ta.setLod2MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD3: - ta.setLod3MultiSurface(new MultiSurfaceProperty(ms)); - break; - case LOD4: - ta.getDeprecatedProperties().setLod4MultiSurface(new MultiSurfaceProperty(ms)); - break; - default: - throw new IllegalStateException("cannot set geometry with LOD for TrafficArea: " + lod); - } - } - - @Override - public boolean containsError(CheckId checkIdentifier) { - boolean hasError = super.containsError(checkIdentifier); - if (hasError) { - return true; - } - for (TransportationObject to : composesOf) { - if (to.containsError(checkIdentifier)) { - return true; - } - } - return false; + protected TransportationObject() { } - @Override - public void clearAllContainedCheckResults() { - super.clearAllContainedCheckResults(); - for (TransportationObject to : composesOf) { - to.clearAllContainedCheckResults(); - } - } - - @Override - public void collectContainedErrors(List<CheckError> errors) { - super.collectContainedErrors(errors); - for (TransportationObject to : composesOf) { - to.collectContainedErrors(errors); - } - } - - @Override - public boolean containsAnyError() { - boolean hasError = super.containsAnyError(); - if (hasError) { - return true; - } - for (TransportationObject to : composesOf) { - if (to.containsAnyError()) { - return true; - } - } - return false; + void setType(TransportationType type) { + this.type = type; } @Override - public void accept(Check c) { - super.accept(c); - if (c.canExecute(this)) { - c.check(this); - } - for (TransportationObject to : composesOf) { - to.accept(c); - } + public FeatureType getFeatureType() { + return FeatureType.TRANSPORTATION; } @Override @@ -234,55 +77,11 @@ public class TransportationObject extends CityObject { return ato; } - @Override - public void unsetGmlGeometries() { - switch (type) { - case ROAD, TRACK, RAILWAY, SQUARE, TRANSPORTATION_COMPLEX: - AbstractTransportationSpace tc = (AbstractTransportationSpace) ato; - tc.getDeprecatedProperties().setLod1MultiSurface(null); - tc.setLod2MultiSurface(null); - tc.setLod3MultiSurface(null); - tc.getDeprecatedProperties().setLod4MultiSurface(null); - break; - case TRAFFIC_AREA: - TrafficArea ta = (TrafficArea) ato; - ta.setLod2MultiSurface(null); - ta.setLod3MultiSurface(null); - ta.getDeprecatedProperties().setLod4MultiSurface(null); - break; - case AUXILLIARY_TRAFFIC_AREA: - AuxiliaryTrafficArea ata = (AuxiliaryTrafficArea) ato; - ata.setLod0MultiSurface(null); - ata.setLod1MultiSurface(null); - ata.setLod2MultiSurface(null); - ata.setLod3MultiSurface(null); - ata.getDeprecatedProperties().setLod4MultiSurface(null); - break; - case AUXILLIARY_TRAFFIC_SPACE, TRAFFIC_SPACE: - AbstractSpace ats = (AbstractSpace) ato; - ats.setLod0MultiSurface(null); - ats.setLod2MultiSurface(null); - ats.setLod3MultiSurface(null); - break; - } - } - - @Override - public CityObject getTopLevelCityObject() { - return this; - } public void setGmlObject(AbstractCityObject tc) { ato = tc; } - public void addChild(TransportationObject subTrans) { - composesOf.add(subTrans); - } - - public List<TransportationObject> getChildren() { - return composesOf; - } public TransportationType getTransportationType() { return type; @@ -293,43 +92,17 @@ public class TransportationObject extends CityObject { 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(); - } - } - - @Override - public void collectInstances(CopyHandler handler) { - super.collectInstances(handler); - for (TransportationObject to : composesOf) { - handler.addInstance(to); - } - } @Override public void fillValues(Copyable original, CopyHandler handler) { super.fillValues(original, handler); TransportationObject originalTo = (TransportationObject) original; - for (TransportationObject to : originalTo.composesOf) { - composesOf.add(handler.getCopyInstance(to)); - } ato = originalTo.ato; } @Override public Copyable createCopyInstance() { - return new TransportationObject(type); + return null; } } diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationSpace.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationSpace.java new file mode 100644 index 0000000000000000000000000000000000000000..c2c73715c8eea13f3a1c274e5016cd33c9c03e21 --- /dev/null +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationSpace.java @@ -0,0 +1,246 @@ +package de.hft.stuttgart.citydoctor2.datastructure; + +import de.hft.stuttgart.citydoctor2.check.Check; +import de.hft.stuttgart.citydoctor2.check.CheckError; +import de.hft.stuttgart.citydoctor2.check.CheckId; +import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; +import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils; +import de.hft.stuttgart.citydoctor2.utils.CopyHandler; +import de.hft.stuttgart.citydoctor2.utils.Copyable; +import org.citygml4j.core.model.core.AbstractSpace; +import org.citygml4j.core.model.transportation.AbstractTransportationSpace; +import org.citygml4j.core.util.geometry.GeometryFactory; +import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface; +import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; + +import java.util.ArrayList; +import java.util.List; + +public abstract class TransportationSpace extends TransportationObject { + + private final List<TrafficSpaceObject> trafficSpaces = new ArrayList<>(); + private final List<TrafficSpaceObject> auxTrafficSpaces = new ArrayList<>(); + + protected TransportationSpace(TransportationType type) { + super(type); + } + + public List<TrafficSpaceObject> getTrafficSpaces() { + return trafficSpaces; + } + + public List<TrafficSpaceObject> getAuxTrafficSpaces() { + return auxTrafficSpaces; + } + + public void addTrafficSpace(TrafficSpaceObject t) { + trafficSpaces.add(t); + } + + public void addAuxTrafficSpace(TrafficSpaceObject t) { + auxTrafficSpaces.add(t); + } + + @Override + public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) { + for (Geometry geom : getGeometries()) { + if (geom instanceof ImplicitGeometryHolder) { + continue; + } + if (geom.getType() == GeometryType.MULTI_SURFACE) { + MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config); + if (super.getGmlObject() instanceof AbstractTransportationSpace ats) { + setMultiSurfaceAccordingToLod(ats, ms, geom.getLod()); + } else { + AbstractSpace as = (AbstractSpace) super.getGmlObject(); + setMultiSurfaceAccordingToLod(as, ms, geom.getLod()); + } + } else { + throw new IllegalStateException("Geometry in TransportationObject cannot be of type " + geom.getType() + + ". Only MultiSurface allowed"); + } + } + for (TrafficSpaceObject spaces : trafficSpaces) { + spaces.reCreateGeometries(factory, config); + } + for (TrafficSpaceObject spaces : auxTrafficSpaces) { + spaces.reCreateGeometries(factory, config); + } + } + + private void setMultiSurfaceAccordingToLod(AbstractTransportationSpace ats, MultiSurface ms, Lod lod) { + switch (lod) { + case LOD0 -> ats.setLod0MultiSurface(new MultiSurfaceProperty(ms)); + case LOD1 -> ats.getDeprecatedProperties().setLod1MultiSurface(new MultiSurfaceProperty(ms)); + case LOD2 -> ats.setLod2MultiSurface(new MultiSurfaceProperty(ms)); + case LOD3 -> ats.setLod3MultiSurface(new MultiSurfaceProperty(ms)); + case LOD4 -> ats.getDeprecatedProperties().setLod4MultiSurface(new MultiSurfaceProperty(ms)); + default -> + throw new IllegalStateException("cannot set geometry with LOD for AuxiliaryTrafficSpace: " + lod); + } + } + + private void setMultiSurfaceAccordingToLod(AbstractSpace as, MultiSurface ms, Lod lod) { + switch (lod) { + case LOD0: + as.setLod0MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD2: + as.setLod2MultiSurface(new MultiSurfaceProperty(ms)); + break; + case LOD3: + as.setLod3MultiSurface(new MultiSurfaceProperty(ms)); + break; + default: + throw new IllegalStateException("cannot set geometry with LOD for AuxiliaryTrafficSpace: " + lod); + } + } + + + @Override + public boolean containsError(CheckId checkIdentifier) { + boolean hasError = super.containsError(checkIdentifier); + if (hasError) { + return true; + } + for (TrafficSpaceObject to : trafficSpaces) { + if (to.containsError(checkIdentifier)) { + return true; + } + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + if (to.containsError(checkIdentifier)) { + return true; + } + } + return false; + } + + @Override + public void clearAllContainedCheckResults() { + super.clearAllContainedCheckResults(); + for (TrafficSpaceObject to : trafficSpaces) { + to.clearAllContainedCheckResults(); + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + to.clearAllContainedCheckResults(); + } + } + + @Override + public void collectContainedErrors(List<CheckError> errors) { + super.collectContainedErrors(errors); + for (TrafficSpaceObject to : trafficSpaces) { + to.collectContainedErrors(errors); + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + to.collectContainedErrors(errors); + } + } + + @Override + public boolean containsAnyError() { + boolean hasError = super.containsAnyError(); + if (hasError) { + return true; + } + for (TrafficSpaceObject to : trafficSpaces) { + if (to.containsAnyError()) { + return true; + } + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + if (to.containsAnyError()) { + return true; + } + } + return false; + } + + @Override + public void accept(Check c) { + super.accept(c); + if (c.canExecute(this)) { + c.check(this); + } + for (TrafficSpaceObject to : trafficSpaces) { + to.accept(c); + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + to.accept(c); + } + } + + + @Override + public void unsetGmlGeometries() { + AbstractSpace ats = (AbstractSpace) super.getGmlObject(); + ats.setLod0MultiSurface(null); + ats.setLod2MultiSurface(null); + ats.setLod3MultiSurface(null); + for (TrafficSpaceObject to : trafficSpaces) { + to.unsetGmlGeometries(); + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + to.unsetGmlGeometries(); + } + } + + @Override + public CityObject getTopLevelCityObject() { + return this; + } + + + @Override + public String toString() { + return "TransportationSpace [id=" + getGmlId() + "]"; + } + + @Override + public void prepareForChecking() { + super.prepareForChecking(); + for (TrafficSpaceObject to : trafficSpaces) { + to.prepareForChecking(); + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + to.prepareForChecking(); + } + } + + @Override + public void clearMetaInformation() { + super.clearMetaInformation(); + for (TrafficSpaceObject to : trafficSpaces) { + to.clearMetaInformation(); + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + to.clearMetaInformation(); + } + } + + @Override + public void collectInstances(CopyHandler handler) { + super.collectInstances(handler); + for (TrafficSpaceObject to : trafficSpaces) { + to.collectInstances(handler); + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + to.collectInstances(handler); + } + } + + @Override + public void fillValues(Copyable original, CopyHandler handler) { + super.fillValues(original, handler); + TransportationObject originalTo = (TransportationObject) original; + for (TrafficSpaceObject to : trafficSpaces) { + to.fillValues(originalTo, handler); + } + for (TrafficSpaceObject to : auxTrafficSpaces) { + to.fillValues(originalTo, handler); + } + } + + +} diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java index 3fe786ff5f15c94bfda3ca5e06cee0f0e12f9dba..f3744e4dd46359aa6b95f75c4fcf059375442160 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java @@ -30,7 +30,6 @@ import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.TunnelConstructiveElement; import de.hft.stuttgart.citydoctor2.datastructure.TunnelFurniture; import de.hft.stuttgart.citydoctor2.datastructure.TunnelPart; -import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject.TransportationType; import de.hft.stuttgart.citydoctor2.datastructure.Vegetation.VegetationType; import de.hft.stuttgart.citydoctor2.math.graph.KDTree; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; @@ -658,26 +657,52 @@ public class Citygml3FeatureMapper extends ObjectWalker { } @Override - public void visit(AuxiliaryTrafficArea ata) { - TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_AREA); - mapAbstractThematicSurface(ata, to); - finishTransportationMapping(to); + public void visit(Track track) { + TopLevelTransportFeature top = TopLevelTransportFeature.from(track); + mapSectionsAndIntersections(track.getSections(), track.getIntersections(), top); + mapAbstractTransportationSpace(track, top); + finishTransportationMapping(top); } @Override - public void visit(TrafficArea ta) { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - mapAbstractThematicSurface(ta, to); - finishTransportationMapping(to); + public void visit(Road road) { + TopLevelTransportFeature top = TopLevelTransportFeature.from(road); + mapSectionsAndIntersections(road.getSections(), road.getIntersections(), top); + mapAbstractTransportationSpace(road, top); + finishTransportationMapping(top); } @Override - public void visit(Road road) { - TransportationObject to = new TransportationObject(TransportationType.ROAD); - mapAbstractTransportationSpace(road, to); - finishTransportationMapping(to); + public void visit(Waterway waterway) { + TopLevelTransportFeature top = TopLevelTransportFeature.from(waterway); + mapSectionsAndIntersections(waterway.getSections(), waterway.getIntersections(), top); + mapAbstractTransportationSpace(waterway, top); + finishTransportationMapping(top); + } + + @Override + public void visit(Railway railway) { + TopLevelTransportFeature top = TopLevelTransportFeature.from(railway); + mapSectionsAndIntersections(railway.getSections(), railway.getIntersections(), top); + mapAbstractTransportationSpace(railway, top); + finishTransportationMapping(top); } + @Override + public void visit(Square square) { + TopLevelTransportFeature top = TopLevelTransportFeature.from(square); + mapAbstractTransportationSpace(square, top); + finishTransportationMapping(top); + } + + @Override + public void visit(TransportationComplex tc) { + TopLevelTransportFeature top = TopLevelTransportFeature.from(tc); + mapAbstractTransportationSpace(tc, top); + finishTransportationMapping(top); + } + + private void mapAbstractThematicSurface(AbstractThematicSurface ats, CityObject co) { mapAbstractSpaceBoundary(ats, co); parseAndAddMultiSurface(ats.getLod0MultiSurface(), Lod.LOD0, co); @@ -707,33 +732,6 @@ public class Citygml3FeatureMapper extends ObjectWalker { parseId(ag, to); } - @Override - public void visit(Railway railway) { - TransportationObject to = new TransportationObject(TransportationType.RAILWAY); - mapAbstractTransportationSpace(railway, to); - finishTransportationMapping(to); - } - - @Override - public void visit(Square square) { - TransportationObject to = new TransportationObject(TransportationType.SQUARE); - mapAbstractTransportationSpace(square, to); - finishTransportationMapping(to); - } - - @Override - public void visit(Track track) { - TransportationObject to = new TransportationObject(TransportationType.TRACK); - mapAbstractTransportationSpace(track, to); - finishTransportationMapping(to); - } - - @Override - public void visit(TransportationComplex transportationComplex) { - TransportationObject to = new TransportationObject(TransportationType.TRANSPORTATION_COMPLEX); - mapAbstractTransportationSpace(transportationComplex, to); - finishTransportationMapping(to); - } private void finishTransportationMapping(TransportationObject to) { finishCityObjectConstruction(to); @@ -746,39 +744,97 @@ public class Citygml3FeatureMapper extends ObjectWalker { updateEdgesAndVertices(co); } - private void mapAbstractTransportationSpace(AbstractTransportationSpace ats, TransportationObject to) { - to.setGmlObject(ats); - parseAbstractTransportationSpaceGeometries(ats, to); + private void mapAbstractTransportationSpace(AbstractTransportationSpace ats, TransportationSpace trsp) { + parseAbstractTransportationSpaceGeometries(ats, trsp); for (TrafficSpaceProperty tsp : ats.getTrafficSpaces()) { if (tsp.isSetObject()) { - TransportationObject trafficSpace = new TransportationObject(TransportationType.TRAFFIC_SPACE); - mapTrafficSpace(tsp.getObject(), trafficSpace); - finishTransportationMapping(trafficSpace); - to.getChildren().add(trafficSpace); + TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + mapTrafficSpace(tsp.getObject(), tso); + trsp.addTrafficSpace(tso); } } - for (AuxiliaryTrafficSpaceProperty auxTrafficProp : ats.getAuxiliaryTrafficSpaces()) { - if (auxTrafficProp.isSetObject()) { - TransportationObject trafficSpace = parseAuxiliaryTrafficSpace(auxTrafficProp.getObject()); - finishTransportationMapping(trafficSpace); - to.addChild(trafficSpace); + for (AuxiliaryTrafficSpaceProperty atsp : ats.getAuxiliaryTrafficSpaces()) { + if (atsp.isSetObject()) { + TrafficSpaceObject atso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.AUXILIARY_TRAFFIC_SPACE); + mapAuxiliaryTrafficSpace(atsp.getObject(), atso); + trsp.addTrafficSpace(atso); } } } - private void mapTrafficSpace(TrafficSpace ts, TransportationObject to) { - mapAbstractUnoccupiedSpace(ts, to); + private void mapSectionsAndIntersections(List<SectionProperty> sectionProps, List<IntersectionProperty> intersectionProps, + TopLevelTransportFeature top) { + for (SectionProperty sectionProp : sectionProps) { + if (sectionProp.isSetObject()) { + TransportSection sect = new TransportSection(TransportSection.SectionType.SECTION); + sect.setGmlObject(sectionProp.getObject()); + mapAbstractTransportationSpace(sectionProp.getObject(), sect); + finishCityObjectConstruction(sect); + top.addSection(sect); + } + } + for (IntersectionProperty intersectionProp : intersectionProps) { + if (intersectionProp.isSetObject()) { + TransportSection isect = new TransportSection(TransportSection.SectionType.INTERSECTION); + isect.setGmlObject(intersectionProp.getObject()); + mapAbstractTransportationSpace(intersectionProp.getObject(), isect); + finishCityObjectConstruction(isect); + top.addIntersection(isect); + } + } } - private void mapAbstractUnoccupiedSpace(AbstractUnoccupiedSpace aus, CityObject co) { - mapAbstractPhysicalSpace(aus, co); + + private void mapTrafficSpace(TrafficSpace ts, TrafficSpaceObject tso) { + tso.setGmlObject(ts); + mapAbstractUnoccupiedSpace(ts, tso); + for (AbstractSpaceBoundaryProperty boundary : ts.getBoundaries()) { + if (boundary.isSetObject()) { + TrafficArea area = (TrafficArea) boundary.getObject(); + TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + mapTrafficArea(area, tao); + tso.addTrafficArea(tao); + } + } + finishCityObjectConstruction(tso); } - private TransportationObject parseAuxiliaryTrafficSpace(AuxiliaryTrafficSpace ats) { - TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_SPACE); - parseAbstractSpaceGeometries(ats, to); - finishCityObjectConstruction(to); - return to; + private void mapAuxiliaryTrafficSpace(AuxiliaryTrafficSpace ats, TrafficSpaceObject tso) { + tso.setGmlObject(ats); + mapAbstractUnoccupiedSpace(ats, tso); + for (AbstractSpaceBoundaryProperty boundary : ats.getBoundaries()) { + if (boundary.isSetObject()) { + AuxiliaryTrafficArea area = (AuxiliaryTrafficArea) boundary.getObject(); + TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.AUXILIARY_TRAFFIC_AREA); + mapAuxiliaryTrafficArea(area, tao); + tso.addTrafficArea(tao); + } + } + finishCityObjectConstruction(tso); + } + + private void mapTrafficArea(TrafficArea ta, TrafficAreaObject tao) { + tao.setGmlObject(ta); + parseAndAddMultiSurface(ta.getLod0MultiSurface(), Lod.LOD0, tao); + parseAndAddMultiSurface(ta.getLod1MultiSurface(), Lod.LOD1, tao); + parseAndAddMultiSurface(ta.getLod2MultiSurface(), Lod.LOD2, tao); + parseAndAddMultiSurface(ta.getLod3MultiSurface(), Lod.LOD3, tao); + parseAndAddMultiSurface(ta.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, tao); + finishCityObjectConstruction(tao); + } + + private void mapAuxiliaryTrafficArea(AuxiliaryTrafficArea ats, TrafficAreaObject tao) { + tao.setGmlObject(ats); + parseAndAddMultiSurface(ats.getLod0MultiSurface(), Lod.LOD0, tao); + parseAndAddMultiSurface(ats.getLod1MultiSurface(), Lod.LOD1, tao); + parseAndAddMultiSurface(ats.getLod2MultiSurface(), Lod.LOD2, tao); + parseAndAddMultiSurface(ats.getLod3MultiSurface(), Lod.LOD3, tao); + parseAndAddMultiSurface(ats.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, tao); + finishCityObjectConstruction(tao); + } + + private void mapAbstractUnoccupiedSpace(AbstractUnoccupiedSpace aus, CityObject co) { + mapAbstractPhysicalSpace(aus, co); } private void parseAbstractTransportationSpaceGeometries(AbstractTransportationSpace space, CityObject co) { diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3GeometryMapper.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3GeometryMapper.java index 10fc35331dc3364ecf21a484721b2cb583895bde..1c9bf3403ef8f72d3e33e8691d96af0e3c9beae8 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3GeometryMapper.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3GeometryMapper.java @@ -63,6 +63,51 @@ public class Citygml3GeometryMapper extends GeometryWalker { } } + @Override + public void visit(Surface surface) { + if (surface.getPatches() != null && !surface.getPatches().isSetObjects()) { + logger.warn("Surface {} has no PolygonPatches.", surface.getId()); + return; + } + + PatchCollection patchCollection = new PatchCollection(); + GeometryWalker patchCollector = new GeometryWalker() { + @Override + public void visit(PolygonPatch patch) { + parsePolygonPatch(patch, patchCollection); + } + }; + surface.getPatches().getObjects().forEach(abstractSurfacePatch -> abstractSurfacePatch.accept(patchCollector)); + } + + private void parsePolygonPatch(PolygonPatch patch, PatchCollection collection) { + AbstractRingProperty exterior = patch.getExterior(); + List<AbstractRingProperty> interior = patch.getInterior(); + if (exterior == null || exterior.getObject() == null) { + if (logger.isWarnEnabled()) { + logger.warn(Localization.getText("GeometryMapper.emptyPolygon")); + } + return; + } + ConcretePolygon conc = new ConcretePolygon(); + polygons.add(conc); + + currentRing = new LinearRing(LinearRingType.EXTERIOR); + exterior.getObject().accept(this); + conc.setExteriorRing(currentRing); + for (AbstractRingProperty interiorGmlRing : interior) { + AbstractRing gmlRing = interiorGmlRing.getObject(); + if (gmlRing == null) { + continue; + } + currentRing = new LinearRing(LinearRingType.INTERIOR); + gmlRing.accept(this); + conc.addInteriorRing(currentRing); + } + collection.addPatchMember(conc); + polygons.add(conc); + } + private void parsePolygon(String id, AbstractRingProperty exterior, List<AbstractRingProperty> interior) { if (exterior == null || exterior.getObject() == null) { if (logger.isWarnEnabled()) { diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java index 5beb83fe2cd48e7349a8207a4a2cb3646e449a61..94a65d45c1c497343cf56f271cdd745aef0fdbc3 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java @@ -26,6 +26,10 @@ 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.Polygon; +import de.hft.stuttgart.citydoctor2.datastructure.TopLevelTransportFeature; +import de.hft.stuttgart.citydoctor2.datastructure.TrafficSpaceObject; +import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject; +import de.hft.stuttgart.citydoctor2.datastructure.TransportationSpace; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.math.Vector3d; @@ -48,8 +52,8 @@ public class BoundingBoxCalculator { * empty array is returned. This is considered an axis aligned bounding box. * Only the exterior rings of the polygons is used as inner rings should be * within the exterior or they are faulty. - * - * @param a list of polygons containing the vertices + * + * @param polygons a list of polygons containing the vertices * @return an BoundingBox containing the two end points of the bounding box. */ public static BoundingBox calculateBoundingBox(Collection<? extends Polygon> polygons) { @@ -98,12 +102,16 @@ public class BoundingBoxCalculator { Vector3d low = new Vector3d(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); Vector3d high = new Vector3d(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); + //TODO: Rework this using visitors findMinMax(low, high, model.getBuildings()); findMinMax(low, high, model.getBridges()); findMinMax(low, high, model.getLand()); - findMinMax(low, high, model.getTransportation()); + findMinMaxTransport(low, high, model.getTransportation()); findMinMax(low, high, model.getWater()); findMinMax(low, high, model.getVegetation()); + findMinMax(low, high, model.getTunnels()); + findMinMax(low, high, model.getCityFurniture()); + findMinMax(low, high, model.getGenericCityObjects()); Vector3d[] result = new Vector3d[2]; result[0] = low; @@ -151,6 +159,23 @@ public class BoundingBoxCalculator { } } + //TODO: Implement this properly with visitor. Quick and dirty fix for the renderer + private static void findMinMaxTransport(Vector3d low, Vector3d high, List<? extends TransportationObject> features) { + for (TransportationObject to : features) { + findMinMax(low, high, to); + if (to instanceof TransportationSpace ts) { + findMinMaxTransport(low, high, ts.getTrafficSpaces()); + findMinMaxTransport(low, high, ts.getAuxTrafficSpaces()); + if (to instanceof TopLevelTransportFeature top) { + findMinMaxTransport(low, high, top.getSections()); + findMinMaxTransport(low, high, top.getIntersections()); + } + } else if (to instanceof TrafficSpaceObject tso) { + findMinMaxTransport(low, high, tso.getTrafficAreas()); + } + } + } + private static void findMinMax(Vector3d low, Vector3d high, CityObject co) { for (Geometry geom : co.getGeometries()) { if (geom.getVertices() == null) { diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationObjectTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationObjectTest.java index 0d12628f7e166c8875d271f63aa4fe4b0d0ecf7e..b558cfe88f38c4be4e1f8cb510afe07c7c14637c 100644 --- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationObjectTest.java +++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/TransportationObjectTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -30,16 +31,21 @@ import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; +import org.citygml4j.core.model.deprecated.core.DeprecatedPropertiesOfAbstractCityObject; import org.citygml4j.core.model.deprecated.core.DeprecatedPropertiesOfAbstractThematicSurface; import org.citygml4j.core.model.deprecated.transportation.DeprecatedPropertiesOfAbstractTransportationSpace; -import org.citygml4j.core.model.deprecated.transportation.TransportationComplex; -import org.citygml4j.core.model.transportation.AuxiliaryTrafficArea; -import org.citygml4j.core.model.transportation.AuxiliaryTrafficSpace; -import org.citygml4j.core.model.transportation.AuxiliaryTrafficSpaceProperty; +import org.citygml4j.core.model.transportation.Intersection; +import org.citygml4j.core.model.transportation.Railway; import org.citygml4j.core.model.transportation.Road; +import org.citygml4j.core.model.transportation.Section; +import org.citygml4j.core.model.transportation.Square; +import org.citygml4j.core.model.transportation.Track; import org.citygml4j.core.model.transportation.TrafficArea; +import org.citygml4j.core.model.transportation.TrafficSpace; +import org.citygml4j.core.model.transportation.Waterway; import org.citygml4j.core.util.geometry.GeometryFactory; import org.junit.Test; +import org.mockito.Mockito; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; import de.hft.stuttgart.citydoctor2.check.CheckError; @@ -53,227 +59,477 @@ public class TransportationObjectTest { @Test public void testGetFeatureType() { - TransportationObject to = new TransportationObject(TransportationType.ROAD); + TopLevelTransportFeature to = TopLevelTransportFeature.from(Mockito.mock(Road.class)); assertEquals(FeatureType.TRANSPORTATION, to.getFeatureType()); } + + @Test + public void testObjectConstruction() { + TopLevelTransportFeature road = TopLevelTransportFeature.from(Mockito.mock(Road.class)); + assertEquals(TransportationType.ROAD, road.getTransportationType()); + TopLevelTransportFeature track = TopLevelTransportFeature.from(Mockito.mock(Track.class)); + assertEquals(TransportationType.TRACK, track.getTransportationType()); + TopLevelTransportFeature waterway = TopLevelTransportFeature.from(Mockito.mock(Waterway.class)); + assertEquals(TransportationType.WATERWAY, waterway.getTransportationType()); + TopLevelTransportFeature railway = TopLevelTransportFeature.from(Mockito.mock(Railway.class)); + assertEquals(TransportationType.RAILWAY, railway.getTransportationType()); + TopLevelTransportFeature square = TopLevelTransportFeature.from(Mockito.mock(Square.class)); + assertEquals(TransportationType.SQUARE, square.getTransportationType()); + } @Test(expected = IllegalStateException.class) public void testReCreateGeometriesSolid() { - TransportationObject to = new TransportationObject(TransportationType.ROAD); + TopLevelTransportFeature to = TopLevelTransportFeature.from(Mockito.mock(Road.class)); to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD1)); GeometryFactory factory = GeometryFactory.newInstance(); to.reCreateGeometries(factory, mock(ParserConfiguration.class)); } - + + @Test - public void testReCreateGeometriesWithComposedOf() { - TransportationObject to = new TransportationObject(TransportationType.ROAD); - TransportationComplex tcMock = new TransportationComplex(); - to.setGmlObject(tcMock); - TransportationObject ataTo = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_SPACE); - AuxiliaryTrafficSpace ataMock = mock(AuxiliaryTrafficSpace.class); - ataTo.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); - ataTo.setGmlObject(ataMock); - tcMock.getAuxiliaryTrafficSpaces().add(new AuxiliaryTrafficSpaceProperty(ataMock)); - - to.addChild(ataTo); + public void testReCreateGeometriesTransportationSpace() { + Road roadMock = mock(Road.class); + TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock); + top.setGmlObject(roadMock); + TransportSection sectionMock = Mockito.mock(TransportSection.class); + TransportSection intersectionMock = Mockito.mock(TransportSection.class); + TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class); + TrafficSpaceObject auxTsMock = Mockito.mock(TrafficSpaceObject.class); + + top.addSection(sectionMock); + top.addIntersection(intersectionMock); + top.addTrafficSpace(tsMock); + top.addAuxTrafficSpace(auxTsMock); + + top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); - verify(ataMock).setLod2MultiSurface(any()); + top.reCreateGeometries(factory, mock(ParserConfiguration.class)); + + verify(roadMock).setLod2MultiSurface(any()); + verify(sectionMock).reCreateGeometries(any(), any()); + verify(intersectionMock).reCreateGeometries(any(), any()); + verify(tsMock).reCreateGeometries(any(), any()); + verify(auxTsMock).reCreateGeometries(any(), any()); + } + + @Test + public void testReCreateGeometriesTrafficSpace() { + TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + TrafficSpace tsMock = mock(TrafficSpace.class); + tso.setGmlObject(tsMock); + TrafficAreaObject taoMock = Mockito.mock(TrafficAreaObject.class); + + tso.addTrafficArea(taoMock); + + tso.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); + GeometryFactory factory = GeometryFactory.newInstance(); + tso.reCreateGeometries(factory, mock(ParserConfiguration.class)); + + verify(tsMock).setLod2MultiSurface(any()); + verify(taoMock).reCreateGeometries(any(), any()); + } + + @Test + public void testReCreateGeometriesTrafficArea() { + TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea taMock = mock(TrafficArea.class); + tao.setGmlObject(taMock); + + tao.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); + GeometryFactory factory = GeometryFactory.newInstance(); + tao.reCreateGeometries(factory, mock(ParserConfiguration.class)); + + verify(taMock).setLod2MultiSurface(any()); } + @Test + public void testReCreateGeometriesMultiSurfaceLod0() { + Road roadMock = mock(Road.class); + TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock); + top.setGmlObject(roadMock); + + TrafficSpaceObject ts = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + TrafficSpace trafficSpaceMock = mock(TrafficSpace.class); + ts.setGmlObject(trafficSpaceMock); + + TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea trafficAreaMock = mock(TrafficArea.class); + ta.setGmlObject(trafficAreaMock); + + top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0)); + ts.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0)); + ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0)); + + GeometryFactory factory = GeometryFactory.newInstance(); + top.reCreateGeometries(factory, mock(ParserConfiguration.class)); + ts.reCreateGeometries(factory, mock(ParserConfiguration.class)); + ta.reCreateGeometries(factory, mock(ParserConfiguration.class)); + + verify(roadMock).setLod0MultiSurface(any()); + verify(trafficSpaceMock).setLod0MultiSurface(any()); + verify(trafficAreaMock).setLod0MultiSurface(any()); + } @Test public void testReCreateGeometriesMultiSurfaceLod1() { - TransportationObject to = new TransportationObject(TransportationType.ROAD); Road roadMock = mock(Road.class); + TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock); + top.setGmlObject(roadMock); + + TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea trafficAreaMock = mock(TrafficArea.class); + ta.setGmlObject(trafficAreaMock); + DeprecatedPropertiesOfAbstractTransportationSpace dSpace = mock(DeprecatedPropertiesOfAbstractTransportationSpace.class); when(roadMock.getDeprecatedProperties()).thenReturn(dSpace); - to.setGmlObject(roadMock); - to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1)); + + try { + top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1)); + } catch (IllegalArgumentException e) { + fail("Casting of original GML object to AbstractTransportationSpace should work"); + } + + ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1)); GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); + top.reCreateGeometries(factory, mock(ParserConfiguration.class)); + ta.reCreateGeometries(factory, mock(ParserConfiguration.class)); + verify(dSpace).setLod1MultiSurface(any()); + verify(trafficAreaMock).setLod1MultiSurface(any()); } + @Test public void testReCreateGeometriesMultiSurfaceLod2() { - TransportationObject to = new TransportationObject(TransportationType.ROAD); Road roadMock = mock(Road.class); - to.setGmlObject(roadMock); - to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); + TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock); + top.setGmlObject(roadMock); + + TrafficSpaceObject ts = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + TrafficSpace trafficSpaceMock = mock(TrafficSpace.class); + ts.setGmlObject(trafficSpaceMock); + + TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea trafficAreaMock = mock(TrafficArea.class); + ta.setGmlObject(trafficAreaMock); + + top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); + ts.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); + ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); + GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); + top.reCreateGeometries(factory, mock(ParserConfiguration.class)); + ts.reCreateGeometries(factory, mock(ParserConfiguration.class)); + ta.reCreateGeometries(factory, mock(ParserConfiguration.class)); + verify(roadMock).setLod2MultiSurface(any()); + verify(trafficSpaceMock).setLod2MultiSurface(any()); + verify(trafficAreaMock).setLod2MultiSurface(any()); } @Test public void testReCreateGeometriesMultiSurfaceLod3() { - TransportationObject to = new TransportationObject(TransportationType.ROAD); Road roadMock = mock(Road.class); - to.setGmlObject(roadMock); - to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3)); + TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock); + top.setGmlObject(roadMock); + + TrafficSpaceObject ts = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + TrafficSpace trafficSpaceMock = mock(TrafficSpace.class); + ts.setGmlObject(trafficSpaceMock); + + TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea trafficAreaMock = mock(TrafficArea.class); + ta.setGmlObject(trafficAreaMock); + + top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3)); + ts.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3)); + ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3)); + GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); + top.reCreateGeometries(factory, mock(ParserConfiguration.class)); + ts.reCreateGeometries(factory, mock(ParserConfiguration.class)); + ta.reCreateGeometries(factory, mock(ParserConfiguration.class)); + verify(roadMock).setLod3MultiSurface(any()); + verify(trafficSpaceMock).setLod3MultiSurface(any()); + verify(trafficAreaMock).setLod3MultiSurface(any()); } @Test public void testReCreateGeometriesMultiSurfaceLod4() { - TransportationObject to = new TransportationObject(TransportationType.ROAD); Road roadMock = mock(Road.class); + TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock); + top.setGmlObject(roadMock); + + TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea trafficAreaMock = mock(TrafficArea.class); + ta.setGmlObject(trafficAreaMock); + DeprecatedPropertiesOfAbstractTransportationSpace dSpace = mock(DeprecatedPropertiesOfAbstractTransportationSpace.class); when(roadMock.getDeprecatedProperties()).thenReturn(dSpace); - to.setGmlObject(roadMock); - to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4)); + DeprecatedPropertiesOfAbstractThematicSurface dArea = mock(DeprecatedPropertiesOfAbstractThematicSurface.class); + when(trafficAreaMock.getDeprecatedProperties()).thenReturn(dArea); + + ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4)); + try { + top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4)); + } catch (IllegalArgumentException e) { + fail("Casting of original GML object to AbstractTransportationSpace should work"); + } + GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); + top.reCreateGeometries(factory, mock(ParserConfiguration.class)); + ta.reCreateGeometries(factory, mock(ParserConfiguration.class)); + verify(dSpace).setLod4MultiSurface(any()); + verify(dArea).setLod4MultiSurface(any()); } - - @Test(expected = IllegalStateException.class) - public void testReCreateGeometriesMultiSurfaceLod0() { - TransportationObject to = new TransportationObject(TransportationType.ROAD); + + + @Test + public void testContainsErrorTransportationSpace() { Road roadMock = mock(Road.class); - to.setGmlObject(roadMock); - to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0)); - GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); + TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock); + top.setGmlObject(roadMock); + TransportSection sectionMock = Mockito.mock(TransportSection.class); + TransportSection intersectionMock = Mockito.mock(TransportSection.class); + TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class); + TrafficSpaceObject auxTsMock = Mockito.mock(TrafficSpaceObject.class); + + top.addSection(sectionMock); + top.addIntersection(intersectionMock); + top.addTrafficSpace(tsMock); + top.addAuxTrafficSpace(auxTsMock); + + top.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); + assertTrue(top.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + assertFalse(top.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED)); + + verify(sectionMock).containsError(any()); + verify(intersectionMock).containsError(any()); + verify(tsMock).containsError(any()); + verify(auxTsMock).containsError(any()); } - - @Test(expected = IllegalStateException.class) - public void testReCreateGeometriesTrafficAreaMultiSurfaceLod1() { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - TrafficArea roadMock = mock(TrafficArea.class); - to.setGmlObject(roadMock); - to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1)); - GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); + + @Test + public void testContainsErrorTrafficSpace() { + TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + TrafficSpace tsMock = mock(TrafficSpace.class); + tso.setGmlObject(tsMock); + TrafficAreaObject taMock = mock(TrafficAreaObject.class); + + tso.addTrafficArea(taMock); + + tso.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); + assertTrue(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + assertFalse(tso.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED)); + + verify(taMock).containsError(any()); } - + @Test - public void testReCreateGeometriesTrafficAreaMultiSurfaceLod2() { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - TrafficArea roadMock = mock(TrafficArea.class); - to.setGmlObject(roadMock); - to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); - GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); - verify(roadMock).setLod2MultiSurface(any()); + public void testContainsErrorTrafficArea() { + TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea taMock = mock(TrafficArea.class); + tao.setGmlObject(taMock); + + tao.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); + assertTrue(tao.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + assertFalse(tao.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED)); } - + @Test - public void testReCreateGeometriesTrafficAreaMultiSurfaceLod3() { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - TrafficArea roadMock = mock(TrafficArea.class); - to.setGmlObject(roadMock); - to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3)); - GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); - verify(roadMock).setLod3MultiSurface(any()); + public void testClearAllContainedCheckResultsTransportationSpace() { + Road roadMock = mock(Road.class); + TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock); + top.setGmlObject(roadMock); + TransportSection sectionMock = Mockito.mock(TransportSection.class); + TransportSection intersectionMock = Mockito.mock(TransportSection.class); + TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class); + TrafficSpaceObject auxTsMock = Mockito.mock(TrafficSpaceObject.class); + + top.addSection(sectionMock); + top.addIntersection(intersectionMock); + top.addTrafficSpace(tsMock); + top.addAuxTrafficSpace(auxTsMock); + + assertFalse(top.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + top.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); + assertTrue(top.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + top.clearAllContainedCheckResults(); + assertFalse(top.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + + verify(sectionMock).clearAllContainedCheckResults(); + verify(intersectionMock).clearAllContainedCheckResults(); + verify(tsMock).clearAllContainedCheckResults(); + verify(auxTsMock).clearAllContainedCheckResults(); } - + @Test - public void testReCreateGeometriesTrafficAreaMultiSurfaceLod4() { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - TrafficArea roadMock = mock(TrafficArea.class); - DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class); - when(roadMock.getDeprecatedProperties()).thenReturn(dSpace); - to.setGmlObject(roadMock); - to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4)); - GeometryFactory factory = GeometryFactory.newInstance(); - to.reCreateGeometries(factory, mock(ParserConfiguration.class)); - verify(dSpace).setLod4MultiSurface(any()); + public void testClearAllContainedCheckResultsTrafficSpace() { + TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + TrafficSpace tsMock = mock(TrafficSpace.class); + tso.setGmlObject(tsMock); + TrafficAreaObject taMock = mock(TrafficAreaObject.class); + + tso.addTrafficArea(taMock); + + assertFalse(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + tso.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); + assertTrue(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + tso.clearAllContainedCheckResults(); + assertFalse(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + + verify(taMock).clearAllContainedCheckResults(); } - + @Test - public void testContainsError() { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - to.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); - assertTrue(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); - assertFalse(to.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED)); + public void testClearAllContainedCheckResultsTrafficArea() { + TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea taMock = mock(TrafficArea.class); + tao.setGmlObject(taMock); + + assertFalse(tao.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + tao.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); + assertTrue(tao.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + tao.clearAllContainedCheckResults(); + assertFalse(tao.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); + } - + @Test - public void testContainsErrorInComposesOf() { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - TransportationObject to2 = new TransportationObject(TransportationType.TRACK); - to.addChild(to2); - to2.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); - assertTrue(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); - assertFalse(to.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED)); + public void testCollectContainedErrorsTransportationSpace() { + Road roadMock = mock(Road.class); + TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock); + top.setGmlObject(roadMock); + TransportSection sectionMock = Mockito.mock(TransportSection.class); + TransportSection intersectionMock = Mockito.mock(TransportSection.class); + TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class); + TrafficSpaceObject auxTsMock = Mockito.mock(TrafficSpaceObject.class); + + top.addSection(sectionMock); + top.addIntersection(intersectionMock); + top.addTrafficSpace(tsMock); + top.addAuxTrafficSpace(auxTsMock); + + top.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); + List<CheckError> errors = new ArrayList<>(); + top.collectContainedErrors(errors); + assertEquals(1, errors.size()); + + verify(sectionMock).collectContainedErrors(errors); + verify(intersectionMock).collectContainedErrors(errors); + verify(tsMock).collectContainedErrors(errors); + verify(auxTsMock).collectContainedErrors(errors); } - + @Test - public void testClearAllContainedCheckResults() { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - TransportationObject to2 = mock(TransportationObject.class); - to.addChild(to2); - assertFalse(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); - to.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); - assertTrue(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); - to.clearAllContainedCheckResults(); - assertFalse(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); - verify(to2).clearAllContainedCheckResults(); + public void testCollectContainedErrorsTrafficSpace() { + TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + TrafficSpace tsMock = mock(TrafficSpace.class); + tso.setGmlObject(tsMock); + TrafficAreaObject taMock = mock(TrafficAreaObject.class); + + tso.addTrafficArea(taMock); + + tso.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); + List<CheckError> errors = new ArrayList<>(); + tso.collectContainedErrors(errors); + assertEquals(1, errors.size()); + + verify(taMock).collectContainedErrors(errors); } - + @Test - public void testCollectContainedErrors() { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - TransportationObject to2 = mock(TransportationObject.class); - to.addChild(to2); - to.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); + public void testCollectContainedErrorsTrafficArea() { + TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea taMock = mock(TrafficArea.class); + tao.setGmlObject(taMock); + + tao.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); List<CheckError> errors = new ArrayList<>(); - to.collectContainedErrors(errors); + tao.collectContainedErrors(errors); assertEquals(1, errors.size()); - verify(to2).collectContainedErrors(errors); } - + @Test - public void testUnsetGmlGeometriesRoad() { - TransportationObject to = new TransportationObject(TransportationType.ROAD); + public void testUnsetGmlGeometriesTransportationSpace() { Road r = mock(Road.class); - to.setGmlObject(r); + TopLevelTransportFeature top = TopLevelTransportFeature.from(r); + top.setGmlObject(r); + TransportSection mockSection = mock(TransportSection.class); + TransportSection mockInterestSection = mock(TransportSection.class); + TrafficSpaceObject mockSpace = mock(TrafficSpaceObject.class); + TrafficSpaceObject auxMockSpace = mock(TrafficSpaceObject.class); + + top.addSection(mockSection); + top.addIntersection(mockInterestSection); + top.addTrafficSpace(mockSpace); + top.addAuxTrafficSpace(auxMockSpace); + DeprecatedPropertiesOfAbstractTransportationSpace dSpace = mock(DeprecatedPropertiesOfAbstractTransportationSpace.class); when(r.getDeprecatedProperties()).thenReturn(dSpace); + dSpace.setLod1MultiSurface(mock(MultiSurfaceProperty.class)); r.setLod2MultiSurface(mock(MultiSurfaceProperty.class)); r.setLod3MultiSurface(mock(MultiSurfaceProperty.class)); dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class)); - to.unsetGmlGeometries(); + + top.unsetGmlGeometries(); assertNull(dSpace.getLod1MultiSurface()); assertNull(r.getLod2MultiSurface()); assertNull(r.getLod3MultiSurface()); assertNull(dSpace.getLod4MultiSurface()); + + verify(mockSection).unsetGmlGeometries(); + verify(mockInterestSection).unsetGmlGeometries(); + verify(mockSpace).unsetGmlGeometries(); + verify(auxMockSpace).unsetGmlGeometries(); + } - + @Test - public void testUnsetGmlGeometriesTrafficArea() { - TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); - TrafficArea r = mock(TrafficArea.class); - to.setGmlObject(r); - DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class); - when(r.getDeprecatedProperties()).thenReturn(dSpace); - r.setLod2MultiSurface(mock(MultiSurfaceProperty.class)); - r.setLod3MultiSurface(mock(MultiSurfaceProperty.class)); - dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class)); - to.unsetGmlGeometries(); - assertNull(r.getLod2MultiSurface()); - assertNull(r.getLod3MultiSurface()); - assertNull(dSpace.getLod4MultiSurface()); + public void testUnsetGmlGeometriesTrafficSpace() { + TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + TrafficSpace t = mock(TrafficSpace.class); + tso.setGmlObject(t); + TrafficAreaObject mockArea = mock(TrafficAreaObject.class); + + tso.addTrafficArea(mockArea); + + DeprecatedPropertiesOfAbstractCityObject dSpace = mock(DeprecatedPropertiesOfAbstractCityObject.class); + when(t.getDeprecatedProperties()).thenReturn(dSpace); + + t.setLod0MultiSurface(mock(MultiSurfaceProperty.class)); + t.setLod2MultiSurface(mock(MultiSurfaceProperty.class)); + t.setLod3MultiSurface(mock(MultiSurfaceProperty.class)); + + tso.unsetGmlGeometries(); + assertNull(t.getLod0MultiSurface()); + assertNull(t.getLod2MultiSurface()); + assertNull(t.getLod3MultiSurface()); + + verify(mockArea).unsetGmlGeometries(); + } - + @Test - public void testUnsetGmlGeometriesAuxilliaryTrafficArea() { - TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_AREA); - AuxiliaryTrafficArea r = mock(AuxiliaryTrafficArea.class); - to.setGmlObject(r); + public void testUnsetGmlGeometriesTrafficArea() { + TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + TrafficArea r = mock(TrafficArea.class); + ta.setGmlObject(r); DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class); when(r.getDeprecatedProperties()).thenReturn(dSpace); + + r.setLod0MultiSurface(mock(MultiSurfaceProperty.class)); + r.setLod1MultiSurface(mock(MultiSurfaceProperty.class)); r.setLod2MultiSurface(mock(MultiSurfaceProperty.class)); r.setLod3MultiSurface(mock(MultiSurfaceProperty.class)); dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class)); - to.unsetGmlGeometries(); + + ta.unsetGmlGeometries(); + assertNull(r.getLod0MultiSurface()); + assertNull(r.getLod1MultiSurface()); assertNull(r.getLod2MultiSurface()); assertNull(r.getLod3MultiSurface()); assertNull(dSpace.getLod4MultiSurface()); diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfStreamReporter.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfStreamReporter.java index d86328287065e6fc189de4a9854aceb127d5f9da..45a5fc722f8c97ea4dd16bb40a118bb60a84cead 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfStreamReporter.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfStreamReporter.java @@ -286,9 +286,6 @@ public class PdfStreamReporter implements StreamReporter { } writeErrorForCityObject(co, tSection); TransportationObject to = (TransportationObject) co; - for (TransportationObject transO : to.getChildren()) { - writeCheckResultForTransportationObject(transO, tSection); - } } private void reportVegetation(CityObject co, boolean hasError) { diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java index 324977e980dd577a3e196d4b35b160e8cabfeef0..799b27307361491671017a36ef2a3b328ef713dd 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java @@ -179,7 +179,7 @@ public class CheckerTest { cgmlArch.mountArchive(new ParserConfiguration(8, false)); ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig(); FeatureCheckedListener l = co -> { - assertTrue(co.isValidated()); + assertTrue("CityObject should be validated", co.isValidated()); }; for (CityGmlZipEntry entry : cgmlArch.getEntries()) { Checker.streamCheck(entry, null, null, config, l, null); diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CityDoctorController.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CityDoctorController.java index 8e219672a22600e073ef4fca805c74c58c1538f2..d47aea6dd7444220c0ad85628ea91818433e799e 100644 --- a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CityDoctorController.java +++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CityDoctorController.java @@ -71,7 +71,7 @@ public class CityDoctorController { private AtomicInteger waterChunkNr = new AtomicInteger(0); private AtomicInteger landChunkNr = new AtomicInteger(0); private AtomicInteger cityFurnitureChunkNr = new AtomicInteger(0); - private AtomicInteger otherObjectsChunkNr = new AtomicInteger(0); + private AtomicInteger genericCityObjectsChunkNr = new AtomicInteger(0); public CityDoctorController(MainWindow mainWindow, HighlightController highlightController, Renderer renderer) { this.mainWindow = mainWindow; @@ -288,7 +288,7 @@ public class CityDoctorController { waterChunkNr.set(0); landChunkNr.set(0); cityFurnitureChunkNr.set(0); - otherObjectsChunkNr.set(0); + genericCityObjectsChunkNr.set(0); } private void buildLand(CityDoctorModel model) { @@ -359,12 +359,12 @@ public class CityDoctorController { if (model.getGenericCityObjects().isEmpty()) { return; } - TreeView<Renderable> otherObjectsView = mainWindow.getOtherObjectsView(); + TreeView<Renderable> otherObjectsView = mainWindow.getGenericCityObjectView(); TreeItem<Renderable> otherObjectsRoot = new TreeItem<>(new AllOtherObjectsNode(model.getGenericCityObjects())); otherObjectsRoot.setExpanded(true); otherObjectsView.setRoot(otherObjectsRoot); - buildTreeFromList(model.getGenericCityObjects(), otherObjectsView.getRoot(), otherObjectsChunkNr); - addMoreButtonIfNecessary(model.getGenericCityObjects(), otherObjectsView, otherObjectsRoot, otherObjectsChunkNr); + buildTreeFromList(model.getGenericCityObjects(), otherObjectsView.getRoot(), genericCityObjectsChunkNr); + addMoreButtonIfNecessary(model.getGenericCityObjects(), otherObjectsView, otherObjectsRoot, genericCityObjectsChunkNr); } private void buildWater(CityDoctorModel model) { @@ -399,7 +399,7 @@ public class CityDoctorController { TreeItem<Renderable> transRoot = new TreeItem<>(new AllTransportationNode(model.getTransportation())); transRoot.setExpanded(true); transView.setRoot(transRoot); - buildTreeFromList(trans, transView.getRoot(), transportationChunkNr); + buildTransportationTreeFromList(trans, transView.getRoot()); addMoreButtonIfNecessary(trans, transView, transRoot, transportationChunkNr); } @@ -543,7 +543,7 @@ public class CityDoctorController { mainWindow.getWaterView().setRoot(null); mainWindow.getTerrainView().setRoot(null); mainWindow.getCityFurnitureView().setRoot(null); - mainWindow.getOtherObjectsView().setRoot(null); + mainWindow.getGenericCityObjectView().setRoot(null); mainWindow.getErrorTree().getRoot().getChildren().clear(); mainWindow.getAttributeView().getRoot().getChildren().clear(); mainWindow.getGlobalErrorsView().getItems().clear(); @@ -597,6 +597,163 @@ public class CityDoctorController { } + private void buildTransportationTreeFromList(List<TransportationObject> list, TreeItem<Renderable> root) { + int transportChunk = transportationChunkNr.get(); + for (int i = transportChunk * MAX_FEATURES_PER_CHUNK; i < (transportChunk + 1) * MAX_FEATURES_PER_CHUNK + && i < list.size(); i++) { + TransportationObject t = list.get(i); + TransportationObjectNode node = new TransportationObjectNode(t); + TreeItem<Renderable> item = new TreeItem<>(node); + item.setExpanded(true); + root.getChildren().add(item); + createGeometryNodes(t, item); + createTransportSectionNodes(t, item); + createTrafficSpacesNodes(t, item); + } + } + + private void buildVegetationTreeFromList(List<Vegetation> list, TreeItem<Renderable> root) { + int vegetationChunk = vegetationChunkNr.get(); + for (int i = vegetationChunk * MAX_FEATURES_PER_CHUNK; i < (vegetationChunk + 1) * MAX_FEATURES_PER_CHUNK + && i < list.size(); i++) { + Vegetation v = list.get(i); + VegetationNode node = new VegetationNode(v); + TreeItem<Renderable> item = new TreeItem<>(node); + item.setExpanded(true); + root.getChildren().add(item); + createGeometryNodes(v, item); + } + } + + private void buildWaterTreeFromList(List<WaterObject> list, TreeItem<Renderable> root) { + int waterChunk = waterChunkNr.get(); + for (int i = waterChunk * MAX_FEATURES_PER_CHUNK; i < (waterChunk + 1) * MAX_FEATURES_PER_CHUNK + && i < list.size(); i++) { + WaterObject w = list.get(i); + CityObjectNode node = new CityObjectNode(w); + TreeItem<Renderable> item = new TreeItem<>(node); + item.setExpanded(true); + root.getChildren().add(item); + createGeometryNodes(w, item); + } + } + + private void buildCityFurnitureTreeFromList(List<CityFurniture> list, TreeItem<Renderable> root) { + int cityFurnChunk = cityFurnitureChunkNr.get(); + for (int i = cityFurnChunk * MAX_FEATURES_PER_CHUNK; i < (cityFurnChunk + 1) * MAX_FEATURES_PER_CHUNK + && i < list.size(); i++) { + CityFurniture cf = list.get(i); + CityObjectNode node = new CityObjectNode(cf); + TreeItem<Renderable> item = new TreeItem<>(node); + item.setExpanded(true); + root.getChildren().add(item); + createGeometryNodes(cf, item); + } + } + + private void buildGenericCityObjectTreeFromList(List<GenericCityObject> list, TreeItem<Renderable> root) { + int genericObjectChunk = genericCityObjectsChunkNr.get(); + for (int i = genericObjectChunk * MAX_FEATURES_PER_CHUNK; i < (genericObjectChunk + 1) * MAX_FEATURES_PER_CHUNK + && i < list.size(); i++) { + GenericCityObject goc = list.get(i); + CityObjectNode node = new CityObjectNode(goc); + TreeItem<Renderable> item = new TreeItem<>(node); + item.setExpanded(true); + root.getChildren().add(item); + createGeometryNodes(goc, item); + } + } + + private void createTransportSectionNodes(TransportationObject t, TreeItem<Renderable> root) { + if (t instanceof TopLevelTransportFeature top) { + if (!top.getSections().isEmpty()) { + AllTransportSectionNode allSectionsNode = new AllTransportSectionNode(top.getSections(), + TransportSection.SectionType.SECTION); + TreeItem<Renderable> allSectionsNodeTextItem = new TreeItem<>(allSectionsNode); + root.getChildren().add(allSectionsNodeTextItem); + + for (TransportSection ts : top.getSections()) { + TransportationObjectNode tsNode = new TransportationObjectNode(ts); + TreeItem<Renderable> tsNodeItem = new TreeItem<>(tsNode); + tsNodeItem.setExpanded(false); + allSectionsNodeTextItem.getChildren().add(tsNodeItem); + createGeometryNodes(ts, tsNodeItem); + createTrafficSpacesNodes(ts, tsNodeItem); + } + + } + if (!top.getIntersections().isEmpty()) { + AllTransportSectionNode allIntersectionsNode = new AllTransportSectionNode(top.getIntersections(), + TransportSection.SectionType.INTERSECTION); + TreeItem<Renderable> allIntersectionsNodeTextItem = new TreeItem<>(allIntersectionsNode); + root.getChildren().add(allIntersectionsNodeTextItem); + + for (TransportSection ts : top.getIntersections()) { + TransportationObjectNode tsNode = new TransportationObjectNode(ts); + TreeItem<Renderable> tsNodeItem = new TreeItem<>(tsNode); + tsNodeItem.setExpanded(false); + allIntersectionsNodeTextItem.getChildren().add(tsNodeItem); + createGeometryNodes(ts, tsNodeItem); + createTrafficSpacesNodes(ts, tsNodeItem); + } + } + } + } + + private void createTrafficSpacesNodes(TransportationObject t, TreeItem<Renderable> root) { + if (t instanceof TransportationSpace space) { + if (!space.getTrafficSpaces().isEmpty()) { + AllTrafficSpacesNode allTSNode = new AllTrafficSpacesNode(space.getTrafficSpaces(), + TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE); + TreeItem<Renderable> allTSNodeTextItem = new TreeItem<>(allTSNode); + root.getChildren().add(allTSNodeTextItem); + allTSNodeTextItem.setExpanded(true); + + for (TrafficSpaceObject tso : space.getTrafficSpaces()) { + TransportationObjectNode tsoNode = new TransportationObjectNode(tso); + TreeItem<Renderable> tsoNodeItem = new TreeItem<>(tsoNode); + tsoNodeItem.setExpanded(false); + allTSNodeTextItem.getChildren().add(tsoNodeItem); + createGeometryNodes(tso, tsoNodeItem); + createTrafficAreaNodes(tso, tsoNodeItem, TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA); + } + } + if (!space.getAuxTrafficSpaces().isEmpty()) { + AllTrafficSpacesNode allTSNode = new AllTrafficSpacesNode(space.getAuxTrafficSpaces(), + TrafficSpaceObject.TrafficSpaceType.AUXILIARY_TRAFFIC_SPACE); + TreeItem<Renderable> allTSNodeTextItem = new TreeItem<>(allTSNode); + root.getChildren().add(allTSNodeTextItem); + allTSNodeTextItem.setExpanded(true); + + for (TrafficSpaceObject atso : space.getAuxTrafficSpaces()) { + TransportationObjectNode atsoNode = new TransportationObjectNode(atso); + TreeItem<Renderable> atsoNodeItem = new TreeItem<>(atsoNode); + atsoNodeItem.setExpanded(false); + allTSNodeTextItem.getChildren().add(atsoNodeItem); + createGeometryNodes(atso, atsoNodeItem); + createTrafficAreaNodes(atso, atsoNodeItem, TrafficAreaObject.TrafficAreaType.AUXILIARY_TRAFFIC_AREA); + } + } + } + } + + public void createTrafficAreaNodes(TransportationObject t, TreeItem<Renderable> root, TrafficAreaObject.TrafficAreaType type) { + if (t instanceof TrafficSpaceObject space && !space.getTrafficAreas().isEmpty()) { + AllTrafficAreaNode allTANode = new AllTrafficAreaNode(space.getTrafficAreas(), type); + TreeItem<Renderable> allTANodeTextItem = new TreeItem<>(allTANode); + root.getChildren().add(allTANodeTextItem); + allTANodeTextItem.setExpanded(true); + for (TrafficAreaObject tao : space.getTrafficAreas()) { + TransportationObjectNode taoNode = new TransportationObjectNode(tao); + TreeItem<Renderable> taoNodeTextItem = new TreeItem<>(taoNode); + taoNodeTextItem.setExpanded(true); + allTANodeTextItem.getChildren().add(taoNodeTextItem); + createGeometryNodes(tao, taoNodeTextItem); + } + } + + } + private void buildTunnelTreeFromList(List<Tunnel> list, TreeItem<Renderable> root) { int tunnelChunk = tunnelChunkNr.get(); for (int i = tunnelChunk * MAX_FEATURES_PER_CHUNK; i < (tunnelChunk + 1) * MAX_FEATURES_PER_CHUNK && i < list.size(); i++) { @@ -1062,7 +1219,7 @@ public class CityDoctorController { updateTree(mainWindow.getCityFurnitureView().getRoot()); updateTree(mainWindow.getTransportationView().getRoot()); updateTree(mainWindow.getWaterView().getRoot()); - updateTree(mainWindow.getOtherObjectsView().getRoot()); + updateTree(mainWindow.getGenericCityObjectView().getRoot()); updateTree(mainWindow.getTunnelView().getRoot()); renderer.updateErrors(); } @@ -1175,85 +1332,105 @@ public class CityDoctorController { } mainWindow.unselectEverything(); resetFeatureChunks(); - if (selectedTab == FeatureType.BUILDING) { - List<Building> foundBuildings = filterFeatures(searchString, model.getBuildings()); - TreeView<Renderable> buildingsView = mainWindow.getBuildingsView(); - TreeItem<Renderable> root = buildingsView.getRoot(); - root.getChildren().clear(); - buildBuildingTreeFromList(foundBuildings, root); - updateTree(root); - addMoreButtonToBuildingsIfNecessary(foundBuildings, buildingsView, root, buildingChunkNr); - } else if (selectedTab == FeatureType.BRIDGE){ - List<BridgeObject> foundBridges = filterFeatures(searchString, model.getBridges()); - TreeView<Renderable> brigdeView = mainWindow.getBridgeView(); - TreeItem<Renderable> root = brigdeView.getRoot(); - root.getChildren().clear(); - buildBridgeTreeFromList(foundBridges, root); - updateTree(root); - addMoreButtonIfNecessary(foundBridges, brigdeView, root, bridgeChunkNr); - } else if (selectedTab == FeatureType.TUNNEL){ - List<Tunnel> foundTunnel = filterFeatures(searchString, model.getTunnels()); - TreeView<Renderable> tunnelView = mainWindow.getTunnelView(); - TreeItem<Renderable> root = tunnelView.getRoot(); - root.getChildren().clear(); - buildTunnelTreeFromList(foundTunnel, root); - updateTree(root); - addMoreButtonIfNecessary(foundTunnel, tunnelView, root, bridgeChunkNr); - } - else{ - TreeView<Renderable> view; - List<? extends CityObject> cos; - AtomicInteger chunkCounter; - switch (selectedTab) { - case VEGETATION: - view = mainWindow.getVegetationView(); - cos = filterFeatures(searchString, model.getVegetation()); - chunkCounter = vegetationChunkNr; - break; - case BRIDGE: - view = mainWindow.getBridgeView(); - cos = filterFeatures(searchString, model.getBridges()); - chunkCounter = bridgeChunkNr; - break; - case TRANSPORTATION: - view = mainWindow.getTransportationView(); - cos = filterFeatures(searchString, model.getTransportation()); - chunkCounter = transportationChunkNr; - break; - case TUNNEL: - view = mainWindow.getTunnelView(); - cos = model.getTunnels(); - chunkCounter = tunnelChunkNr; - break; - case WATER: - view = mainWindow.getWaterView(); - cos = filterFeatures(searchString, model.getWater()); - chunkCounter = waterChunkNr; - break; - case LAND: - view = mainWindow.getTerrainView(); - cos = filterFeatures(searchString, model.getLand()); - chunkCounter = landChunkNr; - break; - case CITY_FURNITURE: - view = mainWindow.getCityFurnitureView(); - cos = filterFeatures(searchString, model.getCityFurniture()); - chunkCounter = cityFurnitureChunkNr; - break; - case GENERIC_CITY_OBJECT: - view = mainWindow.getOtherObjectsView(); - cos = filterFeatures(searchString, model.getGenericCityObjects()); - chunkCounter = otherObjectsChunkNr; - break; - default: - throw new IllegalStateException("Unknown selected feature tab"); - } - TreeItem<Renderable> root = view.getRoot(); - root.getChildren().clear(); - buildTreeFromList(cos, root, chunkCounter); - updateTree(root); - addMoreButtonIfNecessary(cos, view, root, chunkCounter); + switch (selectedTab) { + case BUILDING -> filterBuildingTree(searchString); + case BRIDGE -> filterBridgeTree(searchString); + case TUNNEL -> filterTunnelTree(searchString); + case VEGETATION -> filterVegetationTree(searchString); + case TRANSPORTATION -> filterTransportationTree(searchString); + case WATER -> filterWaterTree(searchString); + case LAND -> filterLandTree(searchString); + case CITY_FURNITURE -> filterCityFurnitureTree(searchString); + case GENERIC_CITY_OBJECT -> filterGenericCityObjectTree(searchString); } + + + } + + private void filterBuildingTree(String searchString) { + List<Building> foundBuildings = filterFeatures(searchString, model.getBuildings()); + TreeView<Renderable> buildingsView = mainWindow.getBuildingsView(); + TreeItem<Renderable> root = buildingsView.getRoot(); + root.getChildren().clear(); + buildBuildingTreeFromList(foundBuildings, root); + updateTree(root); + addMoreButtonToBuildingsIfNecessary(foundBuildings, buildingsView, root, buildingChunkNr); + } + + private void filterBridgeTree(String searchString) { + List<BridgeObject> foundBridges = filterFeatures(searchString, model.getBridges()); + TreeView<Renderable> bridgeView = mainWindow.getBridgeView(); + TreeItem<Renderable> root = bridgeView.getRoot(); + root.getChildren().clear(); + buildBridgeTreeFromList(foundBridges, root); + updateTree(root); + addMoreButtonIfNecessary(foundBridges, bridgeView, root, bridgeChunkNr); + } + + private void filterTunnelTree(String searchString) { + List<Tunnel> foundTunnel = filterFeatures(searchString, model.getTunnels()); + TreeView<Renderable> tunnelView = mainWindow.getTunnelView(); + TreeItem<Renderable> root = tunnelView.getRoot(); + root.getChildren().clear(); + buildTunnelTreeFromList(foundTunnel, root); + updateTree(root); + addMoreButtonIfNecessary(foundTunnel, tunnelView, root, tunnelChunkNr); + } + + private void filterVegetationTree(String searchString) { + List<Vegetation> foundVegetation = filterFeatures(searchString, model.getVegetation()); + TreeView<Renderable> vegetationView = mainWindow.getVegetationView(); + TreeItem<Renderable> root = vegetationView.getRoot(); + root.getChildren().clear(); + buildVegetationTreeFromList(foundVegetation, root); + updateTree(root); + addMoreButtonIfNecessary(foundVegetation, vegetationView, root, vegetationChunkNr); + } + + private void filterTransportationTree(String searchString) { + List<TransportationObject> foundTransportation = filterFeatures(searchString, model.getTransportation()); + TreeView<Renderable> transportationView = mainWindow.getTransportationView(); + TreeItem<Renderable> root = transportationView.getRoot(); + root.getChildren().clear(); + buildTransportationTreeFromList(foundTransportation, root); + updateTree(root); + addMoreButtonIfNecessary(foundTransportation, transportationView, root, transportationChunkNr); + } + + private void filterWaterTree(String searchString) { + List<WaterObject> foundWater = filterFeatures(searchString, model.getWater()); + TreeView<Renderable> waterView = mainWindow.getWaterView(); + TreeItem<Renderable> root = waterView.getRoot(); + root.getChildren().clear(); + buildWaterTreeFromList(foundWater, root); + addMoreButtonIfNecessary(foundWater, waterView, root, waterChunkNr); + } + + private void filterLandTree(String searchString) { + List<CityObject> foundLand = filterFeatures(searchString, model.getLand()); + TreeView<Renderable> landView = mainWindow.getTerrainView(); + TreeItem<Renderable> root = landView.getRoot(); + root.getChildren().clear(); + buildLandFromList(foundLand, root); + addMoreButtonIfNecessary(foundLand, landView, root, landChunkNr); + } + + private void filterCityFurnitureTree(String searchString) { + List<CityFurniture> foundCityFurniture = filterFeatures(searchString, model.getCityFurniture()); + TreeView<Renderable> cityFurnitureView = mainWindow.getCityFurnitureView(); + TreeItem<Renderable> root = cityFurnitureView.getRoot(); + root.getChildren().clear(); + buildCityFurnitureTreeFromList(foundCityFurniture, root); + addMoreButtonIfNecessary(foundCityFurniture, cityFurnitureView, root, cityFurnitureChunkNr); + } + + private void filterGenericCityObjectTree(String searchString) { + List<GenericCityObject> foundGenericCityObject = filterFeatures(searchString, model.getGenericCityObjects()); + TreeView<Renderable> genericCityObjectView = mainWindow.getGenericCityObjectView(); + TreeItem<Renderable> root = genericCityObjectView.getRoot(); + root.getChildren().clear(); + buildGenericCityObjectTreeFromList(foundGenericCityObject, root); + addMoreButtonIfNecessary(foundGenericCityObject, genericCityObjectView, root, genericCityObjectsChunkNr); } private <T extends CityObject> List<T> filterFeatures(String searchString, List<T> features) { @@ -1270,72 +1447,7 @@ public class CityDoctorController { if (model == null) { return; } - resetFeatureChunks(); - if (selectedTab == FeatureType.BUILDING) { - // buildings are handled differently, because of surface and building - // installations - TreeItem<Renderable> root = mainWindow.getBuildingsView().getRoot(); - if (root != null) { - root.getChildren().clear(); - buildBuildingTreeFromList(model.getBuildings(), root); - updateTree(root); - addMoreButtonToBuildingsIfNecessary(model.getBuildings(), mainWindow.getBuildingsView(), root, - buildingChunkNr); - } - } else { - TreeView<Renderable> view; - List<? extends CityObject> cos; - AtomicInteger chunkCounter; - switch (selectedTab) { - case VEGETATION: - view = mainWindow.getVegetationView(); - cos = model.getVegetation(); - chunkCounter = vegetationChunkNr; - break; - case BRIDGE: - view = mainWindow.getBridgeView(); - cos = model.getBridges(); - chunkCounter = bridgeChunkNr; - break; - case TRANSPORTATION: - view = mainWindow.getTransportationView(); - cos = model.getTransportation(); - chunkCounter = transportationChunkNr; - break; - case TUNNEL: - view = mainWindow.getTunnelView(); - cos = model.getTunnels(); - chunkCounter = tunnelChunkNr; - break; - case WATER: - view = mainWindow.getWaterView(); - cos = model.getWater(); - chunkCounter = waterChunkNr; - break; - case LAND: - view = mainWindow.getTerrainView(); - cos = model.getLand(); - chunkCounter = landChunkNr; - break; - case CITY_FURNITURE: - view = mainWindow.getCityFurnitureView(); - cos = model.getCityFurniture(); - chunkCounter = cityFurnitureChunkNr; - break; - case GENERIC_CITY_OBJECT: - view = mainWindow.getOtherObjectsView(); - cos = model.getGenericCityObjects(); - chunkCounter = otherObjectsChunkNr; - break; - default: - throw new IllegalStateException("Unknown selected feature tab"); - } - TreeItem<Renderable> root = view.getRoot(); - root.getChildren().clear(); - buildTreeFromList(cos, root, chunkCounter); - updateTree(root); - addMoreButtonIfNecessary(cos, view, root, chunkCounter); - } + buildTrees(); } public Series<String, Number> createErrorSeries() { @@ -1406,12 +1518,12 @@ public class CityDoctorController { model.getCityFurniture(), cityFurnitureChunkNr); } - public void fillTreeViewWithErrorOtherObjects() { + public void fillTreeViewWithErrorGenericCityObjects() { if (model == null) { return; } - fillTreeViewWithErrorCityObjects(mainWindow.getOtherObjectsView(), - model.getGenericCityObjects(), otherObjectsChunkNr); + fillTreeViewWithErrorCityObjects(mainWindow.getGenericCityObjectView(), + model.getGenericCityObjects(), genericCityObjectsChunkNr); } public void fillTreeViewWithErrorTransportation() { @@ -1484,7 +1596,9 @@ public class CityDoctorController { case TUNNEL: buildTunnel(model.getTunnels()); updateTree(mainWindow.getTunnelView().getRoot()); + break; case WATER: + buildWater(model); updateTree(mainWindow.getWaterView().getRoot()); break; @@ -1494,7 +1608,7 @@ public class CityDoctorController { break; case GENERIC_CITY_OBJECT: buildOtherCityObjects(model); - updateTree(mainWindow.getOtherObjectsView().getRoot()); + updateTree(mainWindow.getGenericCityObjectView().getRoot()); break; default: throw new IllegalStateException(); @@ -1588,7 +1702,7 @@ public class CityDoctorController { fillTreeViewWithErrorCityFurniture(); break; case GENERIC_CITY_OBJECT: - fillTreeViewWithErrorOtherObjects(); + fillTreeViewWithErrorGenericCityObjects(); break; default: throw new IllegalStateException("Unknown selected feature tab: " + mainWindow.getSelectedTab()); diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/MainWindow.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/MainWindow.java index fee59f569c91708963fc7fa834b21245712b9940..055556f9c0ddf7f9b950e7f1be412da5409782c1 100644 --- a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/MainWindow.java +++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/MainWindow.java @@ -19,13 +19,11 @@ import javafx.application.Application; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.embed.swing.SwingFXUtils; -import javafx.event.Event; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.*; import javafx.scene.control.*; import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.skin.VirtualFlow; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.image.WritableImage; @@ -1026,7 +1024,7 @@ public class MainWindow extends Application { return attributeView; } - public TreeView<Renderable> getOtherObjectsView() { + public TreeView<Renderable> getGenericCityObjectView() { return otherObjectsView; } diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/Renderer.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/Renderer.java index a9d6b4c34f8263b5a0c70c384bd5cc747ed8137e..d86e5445a32901a71bf953d345a02b417090ab16 100644 --- a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/Renderer.java +++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/Renderer.java @@ -366,6 +366,35 @@ public class Renderer { return polygons; } + private Set<ConcretePolygon> setupTransportationObjectPolygons(TransportationObject to) { + Set<ConcretePolygon> polygons = new HashSet<>(); + addPolygons(to, polygons); + + if (to instanceof TransportationSpace ts) { + if (ts instanceof TopLevelTransportFeature top) { + for (TransportSection sect : top.getSections()) { + polygons.addAll(setupTransportationObjectPolygons(sect)); + } + for (TransportSection isect : top.getIntersections()) { + polygons.addAll(setupTransportationObjectPolygons(isect)); + } + } + for (TrafficSpaceObject tso : ts.getTrafficSpaces()) { + polygons.addAll(setupTransportationObjectPolygons(tso)); + } + for (TrafficSpaceObject atso : ts.getAuxTrafficSpaces()) { + polygons.addAll(setupTransportationObjectPolygons(atso)); + } + } + + if (to instanceof TrafficSpaceObject tso) { + for (TrafficAreaObject tao : tso.getTrafficAreas()) { + polygons.addAll(setupTransportationObjectPolygons(tao)); + } + } + return polygons; + } + public void render(Tunnel tunnel) { refresher = () -> { Set<ConcretePolygon> setupTunnelPolygons = setupTunnelPolygons(tunnel); @@ -578,6 +607,20 @@ public class Renderer { return polygons; } + public void render(TransportationObject to) { + refresher = () -> { + Set<ConcretePolygon> setupTransportationPolygons = setupTransportationObjectPolygons(to); + mainWindow.zoomOutForBoundingBox(BoundingBox.of(setupTransportationPolygons)); + render(setupTransportationPolygons); + Platform.runLater(() -> { + errorUpdater = () -> displayErrors(to); + errorUpdater.run(); + addGenericAttributesToView(to); + }); + }; + refresher.run(); + } + public void render(BoundarySurface bs) { refresher = () -> { Set<ConcretePolygon> setupBoundarySurfacePolygons = setupBoundarySurfacePolygons(bs); @@ -827,8 +870,34 @@ public class Renderer { renderCityObjects(vegetation, Color.LIGHTGREEN); } - public void renderTransportation(List<TransportationObject> transportation) { - renderCityObjects(transportation, Color.YELLOW); + public void renderTransportation(List<? extends TransportationObject> transportation) { + errorUpdater = null; + refresher = () -> { + Platform.runLater(() -> { + loadingDialog.show(); + clearGeometryTrees(); + clearAttributes(); + }); + Thread t = new Thread(() -> { + Set<ConcretePolygon> polygons = new HashSet<>(); + for (TransportationObject to : transportation) { + polygons.addAll(setupTransportationObjectPolygons(to)); + } + currentTriGeom = TriangulatedGeometry.of(polygons, Color.YELLOW); + errVisitor.setGeometry(currentTriGeom); + Platform.runLater(() -> { + setupRenderState(); + mainWindow.zoomOutForBoundingBox(BoundingBox.of(polygons)); + loadingDialog.hide(); + }); + }); + t.setUncaughtExceptionHandler((thread, e) -> { + Platform.runLater(() -> loadingDialog.hide()); + logger.catching(e); + }); + t.start(); + }; + refresher.run(); } public void renderBridges(List<BridgeObject> bridges) { diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/TriangulatedGeometry.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/TriangulatedGeometry.java index 360f730254086293b142f505bd4737d6231fb1a9..5279c8a57e92e01f63708dfc5f5ba74bf39ecbba 100644 --- a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/TriangulatedGeometry.java +++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/TriangulatedGeometry.java @@ -78,7 +78,7 @@ public class TriangulatedGeometry { addPointsFromBuildings(model.getBuildings(), points); addPointsFromCityObject(model.getBridges(), points); addPointsFromCityObject(model.getLand(), points); - addPointsFromCityObject(model.getTransportation(), points); + addPointsFromTransportationObjects(model.getTransportation(), points); addPointsFromCityObject(model.getVegetation(), points); addPointsFromCityObject(model.getWater(), points); @@ -90,7 +90,7 @@ public class TriangulatedGeometry { addPolygonDataFromBuildings(model.getBuildings(), triGeom, filters); addPolygonDataFromBridges(model.getBridges(), triGeom, filters); addPolygonDataFromCityObjects(model.getLand(), triGeom, Color.BROWN, filters); - addPolygonDataFromCityObjects(model.getTransportation(), triGeom, Color.YELLOW, filters); + addPolygonDataFromTransportationObjects(model.getTransportation(), triGeom, filters); addPolygonDataFromCityObjects(model.getVegetation(), triGeom, Color.LIGHTGREEN, filters); addPolygonDataFromCityObjects(model.getWater(), triGeom, Color.LIGHTSKYBLUE, filters); addPolygonDataFromCityObjects(model.getCityFurniture(), triGeom, Color.BLUEVIOLET, filters); @@ -132,6 +132,45 @@ public class TriangulatedGeometry { } } + private static void addPolygonDataFromTransportationObjects(List<TransportationObject> tos, TriangulatedGeometry triGeom, + List<ViewFilter> filters) { + for (TransportationObject to : tos) { + if (to instanceof TransportationSpace tsp) { + addPolygonDataFromTransportationSpace(tsp, triGeom, filters); + if (tsp instanceof TopLevelTransportFeature top) { + for (TransportSection tse : top.getSections()) { + addPolygonDataFromTransportationSpace(tse, triGeom, filters); + } + for (TransportSection tse : top.getIntersections()) { + addPolygonDataFromTransportationSpace(tse, triGeom, filters); + } + } + } else { + addPolygonData(to, triGeom, Color.YELLOW, filters); + } + } + } + + private static void addPolygonDataFromTransportationSpace(TransportationSpace ts, TriangulatedGeometry triGeom, + List<ViewFilter> filters) { + addPolygonData(ts, triGeom, Color.YELLOW, filters); + addPolygonDataFromTrafficSpaces(ts.getTrafficSpaces(), triGeom, filters); + addPolygonDataFromTrafficSpaces(ts.getAuxTrafficSpaces(), triGeom, filters); + } + + private static void addPolygonDataFromTrafficSpaces(List<TrafficSpaceObject> spaces, TriangulatedGeometry triGeom, + List<ViewFilter> filters) { + for (TrafficSpaceObject space : spaces) { + addPolygonData(space, triGeom, Color.YELLOW, filters); + for (TrafficAreaObject area : space.getTrafficAreas()) { + addPolygonData(area, triGeom, Color.YELLOW, filters); + } + } + } + + + + private static void addPolygonDataFromBoundarySurfaces(List<BoundarySurface> boundarySurfaces, TriangulatedGeometry triGeom, List<ViewFilter> filters) { for (BoundarySurface bs : boundarySurfaces) { @@ -187,6 +226,29 @@ public class TriangulatedGeometry { } } + private static void addPointsFromTransportationObjects(List<? extends TransportationObject> tos, List<Vector3d> points) { + for (TransportationObject to : tos) { + addPoints(to, points); + if (to instanceof TransportationSpace ts) { + addPointsFromTrafficSpace(ts.getTrafficSpaces(), points); + addPointsFromTrafficSpace(ts.getAuxTrafficSpaces(), points); + if (ts instanceof TopLevelTransportFeature top) { + addPointsFromTransportationObjects(top.getSections(), points); + addPointsFromTransportationObjects(top.getIntersections(), points); + } + } + } + } + + private static void addPointsFromTrafficSpace(List<TrafficSpaceObject> tos, List<Vector3d> points) { + for (TrafficSpaceObject to : tos) { + addPoints(to, points); + for (TrafficAreaObject area : to.getTrafficAreas()) { + addPoints(area, points); + } + } + } + private static void addPointsFromCityObject(List<? extends CityObject> cos, List<Vector3d> points) { for (CityObject co : cos) { addPoints(co, points); diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/AllTrafficAreaNode.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/AllTrafficAreaNode.java new file mode 100644 index 0000000000000000000000000000000000000000..e0b59d1fe3681249166b3481a14850282a7cd241 --- /dev/null +++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/AllTrafficAreaNode.java @@ -0,0 +1,35 @@ +package de.hft.stuttgart.citydoctor2.gui.tree; + +import de.hft.stuttgart.citydoctor2.datastructure.TrafficAreaObject; +import de.hft.stuttgart.citydoctor2.gui.Renderer; + +import java.util.List; + +public class AllTrafficAreaNode extends Renderable { + + private final List<TrafficAreaObject> areas; + + private final String text; + + public AllTrafficAreaNode(List<TrafficAreaObject> areas, TrafficAreaObject.TrafficAreaType type) { + this.areas = areas; + this.text = type.toString(); + + } + + @Override + public void refreshTextColor() { + // no use + } + + @Override + public String getText() { + return this.text; + } + + @Override + public void visit(Renderer renderer) { + renderer.renderTransportation(areas); + } + +} diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/AllTrafficSpacesNode.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/AllTrafficSpacesNode.java new file mode 100644 index 0000000000000000000000000000000000000000..e6e7b1b8cf07a6c128d04e86d9d62ff5bc306440 --- /dev/null +++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/AllTrafficSpacesNode.java @@ -0,0 +1,35 @@ +package de.hft.stuttgart.citydoctor2.gui.tree; + +import de.hft.stuttgart.citydoctor2.datastructure.TrafficSpaceObject; + +import de.hft.stuttgart.citydoctor2.gui.Renderer; + +import java.util.List; + +public class AllTrafficSpacesNode extends Renderable { + + private final List<TrafficSpaceObject> spaces; + + private final String text; + + public AllTrafficSpacesNode(List<TrafficSpaceObject> sections, TrafficSpaceObject.TrafficSpaceType type) { + this.spaces = sections; + this.text = type.toString(); + + } + + @Override + public void refreshTextColor() { + // no use + } + + @Override + public String getText() { + return this.text; + } + + @Override + public void visit(Renderer renderer) { + renderer.renderTransportation(spaces); + } +} diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/AllTransportSectionNode.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/AllTransportSectionNode.java new file mode 100644 index 0000000000000000000000000000000000000000..465ebaf71b32c7e01793fcb86a5d6da7b8d7718d --- /dev/null +++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/AllTransportSectionNode.java @@ -0,0 +1,34 @@ +package de.hft.stuttgart.citydoctor2.gui.tree; + +import de.hft.stuttgart.citydoctor2.datastructure.TransportSection; +import de.hft.stuttgart.citydoctor2.gui.Renderer; + +import java.util.List; + +public class AllTransportSectionNode extends Renderable { + + private final List<TransportSection> sections; + + private final String text; + + public AllTransportSectionNode(List<TransportSection> sections, TransportSection.SectionType type) { + this.sections = sections; + this.text = type.toString(); + + } + + @Override + public void refreshTextColor() { + // no use + } + + @Override + public String getText() { + return this.text; + } + + @Override + public void visit(Renderer renderer) { + renderer.renderTransportation(sections); + } +} diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/TransportationObjectNode.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/TransportationObjectNode.java new file mode 100644 index 0000000000000000000000000000000000000000..a54cdf27bced613280640ea06deb831972bf7803 --- /dev/null +++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/tree/TransportationObjectNode.java @@ -0,0 +1,35 @@ +package de.hft.stuttgart.citydoctor2.gui.tree; + +import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject; +import de.hft.stuttgart.citydoctor2.gui.CheckStatus; +import de.hft.stuttgart.citydoctor2.gui.Renderer; + +public class TransportationObjectNode extends Renderable { + + private final TransportationObject to; + + public TransportationObjectNode(TransportationObject to) { + this.to = to; + } + + @Override + public String getText() { + return to.getGmlId().getGmlString(); + } + + @Override + public void visit(Renderer renderer) { + renderer.render(to); + } + + @Override + public void refreshTextColor() { + if (!to.isValidated()) { + setStatus(CheckStatus.NOT_CHECKED); + } else if (to.containsAnyError()) { + setStatus(CheckStatus.ERROR); + } else { + setStatus(CheckStatus.OK); + } + } +}