Commit 660255ab authored by Riegel's avatar Riegel
Browse files

Merge branch 'dev_gui_features_zip_loading' into 'dev'

TransportationObject model rework

See merge request !27
parents 2459496d 7c62b358
Pipeline #11009 passed with stage
in 1 minute and 12 seconds
Showing with 1901 additions and 610 deletions
+1901 -610
...@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. ...@@ -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/), 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). 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 ### Added
......
...@@ -50,6 +50,7 @@ public class ConcretePolygon extends Polygon { ...@@ -50,6 +50,7 @@ public class ConcretePolygon extends Polygon {
private BoundarySurface partOfSurface; private BoundarySurface partOfSurface;
private Installation partfOfInstallation; private Installation partfOfInstallation;
private CompositeCollection partOfComposite = null; private CompositeCollection partOfComposite = null;
private PatchCollection partOfPatch = null;
private Geometry parent; private Geometry parent;
private LinkedPolygon linkedFromPolygon; private LinkedPolygon linkedFromPolygon;
...@@ -141,6 +142,18 @@ public class ConcretePolygon extends Polygon { ...@@ -141,6 +142,18 @@ public class ConcretePolygon extends Polygon {
this.partOfComposite = comp; 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() { public CompositeCollection getPartOfComposite() {
return partOfComposite; return partOfComposite;
} }
......
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);
}
}
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);
}
}
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() + "]";
}
}
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);
}
}
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);
}
}
}
...@@ -43,190 +43,33 @@ import java.util.List; ...@@ -43,190 +43,33 @@ import java.util.List;
* *
* @author Matthias Betz * @author Matthias Betz
*/ */
public class TransportationObject extends CityObject { public abstract class TransportationObject extends CityObject {
@Serial @Serial
private static final long serialVersionUID = -2698907271726700390L; private static final long serialVersionUID = -2698907271726700390L;
public enum TransportationType { 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 AbstractCityObject ato;
private final List<TransportationObject> composesOf = new ArrayList<>(1); protected TransportationType type;
private final TransportationType type;
public TransportationObject(TransportationType type) { public TransportationObject(TransportationType type) {
this.type = type; this.type = type;
} }
@Override protected TransportationObject() {
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) { void setType(TransportationType type) {
switch (lod) { this.type = type;
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;
}
@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;
} }
@Override @Override
public void accept(Check c) { public FeatureType getFeatureType() {
super.accept(c); return FeatureType.TRANSPORTATION;
if (c.canExecute(this)) {
c.check(this);
}
for (TransportationObject to : composesOf) {
to.accept(c);
}
} }
@Override @Override
...@@ -234,55 +77,11 @@ public class TransportationObject extends CityObject { ...@@ -234,55 +77,11 @@ public class TransportationObject extends CityObject {
return ato; 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) { public void setGmlObject(AbstractCityObject tc) {
ato = tc; ato = tc;
} }
public void addChild(TransportationObject subTrans) {
composesOf.add(subTrans);
}
public List<TransportationObject> getChildren() {
return composesOf;
}
public TransportationType getTransportationType() { public TransportationType getTransportationType() {
return type; return type;
...@@ -293,43 +92,17 @@ public class TransportationObject extends CityObject { ...@@ -293,43 +92,17 @@ public class TransportationObject extends CityObject {
return "TransportationObject [id=" + getGmlId() + "]"; 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 @Override
public void fillValues(Copyable original, CopyHandler handler) { public void fillValues(Copyable original, CopyHandler handler) {
super.fillValues(original, handler); super.fillValues(original, handler);
TransportationObject originalTo = (TransportationObject) original; TransportationObject originalTo = (TransportationObject) original;
for (TransportationObject to : originalTo.composesOf) {
composesOf.add(handler.getCopyInstance(to));
}
ato = originalTo.ato; ato = originalTo.ato;
} }
@Override @Override
public Copyable createCopyInstance() { public Copyable createCopyInstance() {
return new TransportationObject(type); return null;
} }
} }
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);
}
}
}
...@@ -30,7 +30,6 @@ import de.hft.stuttgart.citydoctor2.datastructure.Polygon; ...@@ -30,7 +30,6 @@ import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelConstructiveElement; import de.hft.stuttgart.citydoctor2.datastructure.TunnelConstructiveElement;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelFurniture; import de.hft.stuttgart.citydoctor2.datastructure.TunnelFurniture;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelPart; 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.datastructure.Vegetation.VegetationType;
import de.hft.stuttgart.citydoctor2.math.graph.KDTree; import de.hft.stuttgart.citydoctor2.math.graph.KDTree;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
...@@ -658,26 +657,52 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -658,26 +657,52 @@ public class Citygml3FeatureMapper extends ObjectWalker {
} }
@Override @Override
public void visit(AuxiliaryTrafficArea ata) { public void visit(Track track) {
TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_AREA); TopLevelTransportFeature top = TopLevelTransportFeature.from(track);
mapAbstractThematicSurface(ata, to); mapSectionsAndIntersections(track.getSections(), track.getIntersections(), top);
finishTransportationMapping(to); mapAbstractTransportationSpace(track, top);
finishTransportationMapping(top);
} }
@Override @Override
public void visit(TrafficArea ta) { public void visit(Road road) {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); TopLevelTransportFeature top = TopLevelTransportFeature.from(road);
mapAbstractThematicSurface(ta, to); mapSectionsAndIntersections(road.getSections(), road.getIntersections(), top);
finishTransportationMapping(to); mapAbstractTransportationSpace(road, top);
finishTransportationMapping(top);
} }
@Override @Override
public void visit(Road road) { public void visit(Waterway waterway) {
TransportationObject to = new TransportationObject(TransportationType.ROAD); TopLevelTransportFeature top = TopLevelTransportFeature.from(waterway);
mapAbstractTransportationSpace(road, to); mapSectionsAndIntersections(waterway.getSections(), waterway.getIntersections(), top);
finishTransportationMapping(to); 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) { private void mapAbstractThematicSurface(AbstractThematicSurface ats, CityObject co) {
mapAbstractSpaceBoundary(ats, co); mapAbstractSpaceBoundary(ats, co);
parseAndAddMultiSurface(ats.getLod0MultiSurface(), Lod.LOD0, co); parseAndAddMultiSurface(ats.getLod0MultiSurface(), Lod.LOD0, co);
...@@ -707,33 +732,6 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -707,33 +732,6 @@ public class Citygml3FeatureMapper extends ObjectWalker {
parseId(ag, to); 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) { private void finishTransportationMapping(TransportationObject to) {
finishCityObjectConstruction(to); finishCityObjectConstruction(to);
...@@ -746,39 +744,97 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -746,39 +744,97 @@ public class Citygml3FeatureMapper extends ObjectWalker {
updateEdgesAndVertices(co); updateEdgesAndVertices(co);
} }
private void mapAbstractTransportationSpace(AbstractTransportationSpace ats, TransportationObject to) { private void mapAbstractTransportationSpace(AbstractTransportationSpace ats, TransportationSpace trsp) {
to.setGmlObject(ats); parseAbstractTransportationSpaceGeometries(ats, trsp);
parseAbstractTransportationSpaceGeometries(ats, to);
for (TrafficSpaceProperty tsp : ats.getTrafficSpaces()) { for (TrafficSpaceProperty tsp : ats.getTrafficSpaces()) {
if (tsp.isSetObject()) { if (tsp.isSetObject()) {
TransportationObject trafficSpace = new TransportationObject(TransportationType.TRAFFIC_SPACE); TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
mapTrafficSpace(tsp.getObject(), trafficSpace); mapTrafficSpace(tsp.getObject(), tso);
finishTransportationMapping(trafficSpace); trsp.addTrafficSpace(tso);
to.getChildren().add(trafficSpace);
} }
} }
for (AuxiliaryTrafficSpaceProperty auxTrafficProp : ats.getAuxiliaryTrafficSpaces()) { for (AuxiliaryTrafficSpaceProperty atsp : ats.getAuxiliaryTrafficSpaces()) {
if (auxTrafficProp.isSetObject()) { if (atsp.isSetObject()) {
TransportationObject trafficSpace = parseAuxiliaryTrafficSpace(auxTrafficProp.getObject()); TrafficSpaceObject atso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.AUXILIARY_TRAFFIC_SPACE);
finishTransportationMapping(trafficSpace); mapAuxiliaryTrafficSpace(atsp.getObject(), atso);
to.addChild(trafficSpace); trsp.addTrafficSpace(atso);
} }
} }
} }
private void mapTrafficSpace(TrafficSpace ts, TransportationObject to) { private void mapSectionsAndIntersections(List<SectionProperty> sectionProps, List<IntersectionProperty> intersectionProps,
mapAbstractUnoccupiedSpace(ts, to); 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) { private void mapAuxiliaryTrafficSpace(AuxiliaryTrafficSpace ats, TrafficSpaceObject tso) {
TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_SPACE); tso.setGmlObject(ats);
parseAbstractSpaceGeometries(ats, to); mapAbstractUnoccupiedSpace(ats, tso);
finishCityObjectConstruction(to); for (AbstractSpaceBoundaryProperty boundary : ats.getBoundaries()) {
return to; 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) { private void parseAbstractTransportationSpaceGeometries(AbstractTransportationSpace space, CityObject co) {
......
...@@ -63,6 +63,51 @@ public class Citygml3GeometryMapper extends GeometryWalker { ...@@ -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) { private void parsePolygon(String id, AbstractRingProperty exterior, List<AbstractRingProperty> interior) {
if (exterior == null || exterior.getObject() == null) { if (exterior == null || exterior.getObject() == null) {
if (logger.isWarnEnabled()) { if (logger.isWarnEnabled()) {
......
...@@ -26,6 +26,10 @@ import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; ...@@ -26,6 +26,10 @@ import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject; import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; 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.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.Vector3d; import de.hft.stuttgart.citydoctor2.math.Vector3d;
...@@ -49,7 +53,7 @@ public class BoundingBoxCalculator { ...@@ -49,7 +53,7 @@ public class BoundingBoxCalculator {
* Only the exterior rings of the polygons is used as inner rings should be * Only the exterior rings of the polygons is used as inner rings should be
* within the exterior or they are faulty. * 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. * @return an BoundingBox containing the two end points of the bounding box.
*/ */
public static BoundingBox calculateBoundingBox(Collection<? extends Polygon> polygons) { public static BoundingBox calculateBoundingBox(Collection<? extends Polygon> polygons) {
...@@ -98,12 +102,16 @@ public class BoundingBoxCalculator { ...@@ -98,12 +102,16 @@ public class BoundingBoxCalculator {
Vector3d low = new Vector3d(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); 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); 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.getBuildings());
findMinMax(low, high, model.getBridges()); findMinMax(low, high, model.getBridges());
findMinMax(low, high, model.getLand()); findMinMax(low, high, model.getLand());
findMinMax(low, high, model.getTransportation()); findMinMaxTransport(low, high, model.getTransportation());
findMinMax(low, high, model.getWater()); findMinMax(low, high, model.getWater());
findMinMax(low, high, model.getVegetation()); 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]; Vector3d[] result = new Vector3d[2];
result[0] = low; result[0] = low;
...@@ -151,6 +159,23 @@ public class BoundingBoxCalculator { ...@@ -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) { private static void findMinMax(Vector3d low, Vector3d high, CityObject co) {
for (Geometry geom : co.getGeometries()) { for (Geometry geom : co.getGeometries()) {
if (geom.getVertices() == null) { if (geom.getVertices() == null) {
......
...@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals; ...@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
...@@ -30,16 +31,21 @@ import static org.mockito.Mockito.when; ...@@ -30,16 +31,21 @@ import static org.mockito.Mockito.when;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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.core.DeprecatedPropertiesOfAbstractThematicSurface;
import org.citygml4j.core.model.deprecated.transportation.DeprecatedPropertiesOfAbstractTransportationSpace; import org.citygml4j.core.model.deprecated.transportation.DeprecatedPropertiesOfAbstractTransportationSpace;
import org.citygml4j.core.model.deprecated.transportation.TransportationComplex; import org.citygml4j.core.model.transportation.Intersection;
import org.citygml4j.core.model.transportation.AuxiliaryTrafficArea; import org.citygml4j.core.model.transportation.Railway;
import org.citygml4j.core.model.transportation.AuxiliaryTrafficSpace;
import org.citygml4j.core.model.transportation.AuxiliaryTrafficSpaceProperty;
import org.citygml4j.core.model.transportation.Road; 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.TrafficArea;
import org.citygml4j.core.model.transportation.TrafficSpace;
import org.citygml4j.core.model.transportation.Waterway;
import org.citygml4j.core.util.geometry.GeometryFactory; import org.citygml4j.core.util.geometry.GeometryFactory;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
...@@ -53,227 +59,477 @@ public class TransportationObjectTest { ...@@ -53,227 +59,477 @@ public class TransportationObjectTest {
@Test @Test
public void testGetFeatureType() { public void testGetFeatureType() {
TransportationObject to = new TransportationObject(TransportationType.ROAD); TopLevelTransportFeature to = TopLevelTransportFeature.from(Mockito.mock(Road.class));
assertEquals(FeatureType.TRANSPORTATION, to.getFeatureType()); 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) @Test(expected = IllegalStateException.class)
public void testReCreateGeometriesSolid() { 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)); to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD1));
GeometryFactory factory = GeometryFactory.newInstance(); GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class)); to.reCreateGeometries(factory, mock(ParserConfiguration.class));
} }
@Test @Test
public void testReCreateGeometriesWithComposedOf() { public void testReCreateGeometriesTransportationSpace() {
TransportationObject to = new TransportationObject(TransportationType.ROAD); Road roadMock = mock(Road.class);
TransportationComplex tcMock = new TransportationComplex(); TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
to.setGmlObject(tcMock); top.setGmlObject(roadMock);
TransportationObject ataTo = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_SPACE); TransportSection sectionMock = Mockito.mock(TransportSection.class);
AuxiliaryTrafficSpace ataMock = mock(AuxiliaryTrafficSpace.class); TransportSection intersectionMock = Mockito.mock(TransportSection.class);
ataTo.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class);
ataTo.setGmlObject(ataMock); TrafficSpaceObject auxTsMock = Mockito.mock(TrafficSpaceObject.class);
tcMock.getAuxiliaryTrafficSpaces().add(new AuxiliaryTrafficSpaceProperty(ataMock));
top.addSection(sectionMock);
to.addChild(ataTo); top.addIntersection(intersectionMock);
top.addTrafficSpace(tsMock);
top.addAuxTrafficSpace(auxTsMock);
top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
GeometryFactory factory = GeometryFactory.newInstance(); GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class)); top.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(ataMock).setLod2MultiSurface(any());
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 @Test
public void testReCreateGeometriesMultiSurfaceLod1() { public void testReCreateGeometriesMultiSurfaceLod1() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
Road roadMock = mock(Road.class); 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); DeprecatedPropertiesOfAbstractTransportationSpace dSpace = mock(DeprecatedPropertiesOfAbstractTransportationSpace.class);
when(roadMock.getDeprecatedProperties()).thenReturn(dSpace); 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(); 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(dSpace).setLod1MultiSurface(any());
verify(trafficAreaMock).setLod1MultiSurface(any());
} }
@Test @Test
public void testReCreateGeometriesMultiSurfaceLod2() { public void testReCreateGeometriesMultiSurfaceLod2() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
Road roadMock = mock(Road.class); Road roadMock = mock(Road.class);
to.setGmlObject(roadMock); TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2)); 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(); 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(roadMock).setLod2MultiSurface(any());
verify(trafficSpaceMock).setLod2MultiSurface(any());
verify(trafficAreaMock).setLod2MultiSurface(any());
} }
@Test @Test
public void testReCreateGeometriesMultiSurfaceLod3() { public void testReCreateGeometriesMultiSurfaceLod3() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
Road roadMock = mock(Road.class); Road roadMock = mock(Road.class);
to.setGmlObject(roadMock); TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3)); 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(); 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(roadMock).setLod3MultiSurface(any());
verify(trafficSpaceMock).setLod3MultiSurface(any());
verify(trafficAreaMock).setLod3MultiSurface(any());
} }
@Test @Test
public void testReCreateGeometriesMultiSurfaceLod4() { public void testReCreateGeometriesMultiSurfaceLod4() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
Road roadMock = mock(Road.class); 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); DeprecatedPropertiesOfAbstractTransportationSpace dSpace = mock(DeprecatedPropertiesOfAbstractTransportationSpace.class);
when(roadMock.getDeprecatedProperties()).thenReturn(dSpace); when(roadMock.getDeprecatedProperties()).thenReturn(dSpace);
to.setGmlObject(roadMock); DeprecatedPropertiesOfAbstractThematicSurface dArea = mock(DeprecatedPropertiesOfAbstractThematicSurface.class);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4)); 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(); 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(dSpace).setLod4MultiSurface(any());
verify(dArea).setLod4MultiSurface(any());
} }
@Test(expected = IllegalStateException.class)
public void testReCreateGeometriesMultiSurfaceLod0() { @Test
TransportationObject to = new TransportationObject(TransportationType.ROAD); public void testContainsErrorTransportationSpace() {
Road roadMock = mock(Road.class); Road roadMock = mock(Road.class);
to.setGmlObject(roadMock); TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0)); top.setGmlObject(roadMock);
GeometryFactory factory = GeometryFactory.newInstance(); TransportSection sectionMock = Mockito.mock(TransportSection.class);
to.reCreateGeometries(factory, mock(ParserConfiguration.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) @Test
public void testReCreateGeometriesTrafficAreaMultiSurfaceLod1() { public void testContainsErrorTrafficSpace() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficArea roadMock = mock(TrafficArea.class); TrafficSpace tsMock = mock(TrafficSpace.class);
to.setGmlObject(roadMock); tso.setGmlObject(tsMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1)); TrafficAreaObject taMock = mock(TrafficAreaObject.class);
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.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 @Test
public void testReCreateGeometriesTrafficAreaMultiSurfaceLod2() { public void testContainsErrorTrafficArea() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea roadMock = mock(TrafficArea.class); TrafficArea taMock = mock(TrafficArea.class);
to.setGmlObject(roadMock); tao.setGmlObject(taMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
GeometryFactory factory = GeometryFactory.newInstance(); tao.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
to.reCreateGeometries(factory, mock(ParserConfiguration.class)); assertTrue(tao.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
verify(roadMock).setLod2MultiSurface(any()); assertFalse(tao.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED));
} }
@Test @Test
public void testReCreateGeometriesTrafficAreaMultiSurfaceLod3() { public void testClearAllContainedCheckResultsTransportationSpace() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); Road roadMock = mock(Road.class);
TrafficArea roadMock = mock(TrafficArea.class); TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
to.setGmlObject(roadMock); top.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3)); TransportSection sectionMock = Mockito.mock(TransportSection.class);
GeometryFactory factory = GeometryFactory.newInstance(); TransportSection intersectionMock = Mockito.mock(TransportSection.class);
to.reCreateGeometries(factory, mock(ParserConfiguration.class)); TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class);
verify(roadMock).setLod3MultiSurface(any()); 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 @Test
public void testReCreateGeometriesTrafficAreaMultiSurfaceLod4() { public void testClearAllContainedCheckResultsTrafficSpace() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficArea roadMock = mock(TrafficArea.class); TrafficSpace tsMock = mock(TrafficSpace.class);
DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class); tso.setGmlObject(tsMock);
when(roadMock.getDeprecatedProperties()).thenReturn(dSpace); TrafficAreaObject taMock = mock(TrafficAreaObject.class);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4)); tso.addTrafficArea(taMock);
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class)); assertFalse(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
verify(dSpace).setLod4MultiSurface(any()); 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 @Test
public void testContainsError() { public void testClearAllContainedCheckResultsTrafficArea() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
to.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); TrafficArea taMock = mock(TrafficArea.class);
assertTrue(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); tao.setGmlObject(taMock);
assertFalse(to.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED));
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 @Test
public void testContainsErrorInComposesOf() { public void testCollectContainedErrorsTransportationSpace() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); Road roadMock = mock(Road.class);
TransportationObject to2 = new TransportationObject(TransportationType.TRACK); TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
to.addChild(to2); top.setGmlObject(roadMock);
to2.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); TransportSection sectionMock = Mockito.mock(TransportSection.class);
assertTrue(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); TransportSection intersectionMock = Mockito.mock(TransportSection.class);
assertFalse(to.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED)); 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 @Test
public void testClearAllContainedCheckResults() { public void testCollectContainedErrorsTrafficSpace() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TransportationObject to2 = mock(TransportationObject.class); TrafficSpace tsMock = mock(TrafficSpace.class);
to.addChild(to2); tso.setGmlObject(tsMock);
assertFalse(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); TrafficAreaObject taMock = mock(TrafficAreaObject.class);
to.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); tso.addTrafficArea(taMock);
to.clearAllContainedCheckResults();
assertFalse(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); tso.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
verify(to2).clearAllContainedCheckResults(); List<CheckError> errors = new ArrayList<>();
tso.collectContainedErrors(errors);
assertEquals(1, errors.size());
verify(taMock).collectContainedErrors(errors);
} }
@Test @Test
public void testCollectContainedErrors() { public void testCollectContainedErrorsTrafficArea() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TransportationObject to2 = mock(TransportationObject.class); TrafficArea taMock = mock(TrafficArea.class);
to.addChild(to2); tao.setGmlObject(taMock);
to.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
tao.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
List<CheckError> errors = new ArrayList<>(); List<CheckError> errors = new ArrayList<>();
to.collectContainedErrors(errors); tao.collectContainedErrors(errors);
assertEquals(1, errors.size()); assertEquals(1, errors.size());
verify(to2).collectContainedErrors(errors);
} }
@Test @Test
public void testUnsetGmlGeometriesRoad() { public void testUnsetGmlGeometriesTransportationSpace() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
Road r = mock(Road.class); 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); DeprecatedPropertiesOfAbstractTransportationSpace dSpace = mock(DeprecatedPropertiesOfAbstractTransportationSpace.class);
when(r.getDeprecatedProperties()).thenReturn(dSpace); when(r.getDeprecatedProperties()).thenReturn(dSpace);
dSpace.setLod1MultiSurface(mock(MultiSurfaceProperty.class)); dSpace.setLod1MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod2MultiSurface(mock(MultiSurfaceProperty.class)); r.setLod2MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod3MultiSurface(mock(MultiSurfaceProperty.class)); r.setLod3MultiSurface(mock(MultiSurfaceProperty.class));
dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class)); dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class));
to.unsetGmlGeometries();
top.unsetGmlGeometries();
assertNull(dSpace.getLod1MultiSurface()); assertNull(dSpace.getLod1MultiSurface());
assertNull(r.getLod2MultiSurface()); assertNull(r.getLod2MultiSurface());
assertNull(r.getLod3MultiSurface()); assertNull(r.getLod3MultiSurface());
assertNull(dSpace.getLod4MultiSurface()); assertNull(dSpace.getLod4MultiSurface());
verify(mockSection).unsetGmlGeometries();
verify(mockInterestSection).unsetGmlGeometries();
verify(mockSpace).unsetGmlGeometries();
verify(auxMockSpace).unsetGmlGeometries();
} }
@Test @Test
public void testUnsetGmlGeometriesTrafficArea() { public void testUnsetGmlGeometriesTrafficSpace() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA); TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficArea r = mock(TrafficArea.class); TrafficSpace t = mock(TrafficSpace.class);
to.setGmlObject(r); tso.setGmlObject(t);
DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class); TrafficAreaObject mockArea = mock(TrafficAreaObject.class);
when(r.getDeprecatedProperties()).thenReturn(dSpace);
r.setLod2MultiSurface(mock(MultiSurfaceProperty.class)); tso.addTrafficArea(mockArea);
r.setLod3MultiSurface(mock(MultiSurfaceProperty.class));
dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class)); DeprecatedPropertiesOfAbstractCityObject dSpace = mock(DeprecatedPropertiesOfAbstractCityObject.class);
to.unsetGmlGeometries(); when(t.getDeprecatedProperties()).thenReturn(dSpace);
assertNull(r.getLod2MultiSurface());
assertNull(r.getLod3MultiSurface()); t.setLod0MultiSurface(mock(MultiSurfaceProperty.class));
assertNull(dSpace.getLod4MultiSurface()); 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 @Test
public void testUnsetGmlGeometriesAuxilliaryTrafficArea() { public void testUnsetGmlGeometriesTrafficArea() {
TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_AREA); TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
AuxiliaryTrafficArea r = mock(AuxiliaryTrafficArea.class); TrafficArea r = mock(TrafficArea.class);
to.setGmlObject(r); ta.setGmlObject(r);
DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class); DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class);
when(r.getDeprecatedProperties()).thenReturn(dSpace); when(r.getDeprecatedProperties()).thenReturn(dSpace);
r.setLod0MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod1MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod2MultiSurface(mock(MultiSurfaceProperty.class)); r.setLod2MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod3MultiSurface(mock(MultiSurfaceProperty.class)); r.setLod3MultiSurface(mock(MultiSurfaceProperty.class));
dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class)); dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class));
to.unsetGmlGeometries();
ta.unsetGmlGeometries();
assertNull(r.getLod0MultiSurface());
assertNull(r.getLod1MultiSurface());
assertNull(r.getLod2MultiSurface()); assertNull(r.getLod2MultiSurface());
assertNull(r.getLod3MultiSurface()); assertNull(r.getLod3MultiSurface());
assertNull(dSpace.getLod4MultiSurface()); assertNull(dSpace.getLod4MultiSurface());
......
...@@ -286,9 +286,6 @@ public class PdfStreamReporter implements StreamReporter { ...@@ -286,9 +286,6 @@ public class PdfStreamReporter implements StreamReporter {
} }
writeErrorForCityObject(co, tSection); writeErrorForCityObject(co, tSection);
TransportationObject to = (TransportationObject) co; TransportationObject to = (TransportationObject) co;
for (TransportationObject transO : to.getChildren()) {
writeCheckResultForTransportationObject(transO, tSection);
}
} }
private void reportVegetation(CityObject co, boolean hasError) { private void reportVegetation(CityObject co, boolean hasError) {
......
...@@ -179,7 +179,7 @@ public class CheckerTest { ...@@ -179,7 +179,7 @@ public class CheckerTest {
cgmlArch.mountArchive(new ParserConfiguration(8, false)); cgmlArch.mountArchive(new ParserConfiguration(8, false));
ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig(); ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig();
FeatureCheckedListener l = co -> { FeatureCheckedListener l = co -> {
assertTrue(co.isValidated()); assertTrue("CityObject should be validated", co.isValidated());
}; };
for (CityGmlZipEntry entry : cgmlArch.getEntries()) { for (CityGmlZipEntry entry : cgmlArch.getEntries()) {
Checker.streamCheck(entry, null, null, config, l, null); Checker.streamCheck(entry, null, null, config, l, null);
......
...@@ -71,7 +71,7 @@ public class CityDoctorController { ...@@ -71,7 +71,7 @@ public class CityDoctorController {
private AtomicInteger waterChunkNr = new AtomicInteger(0); private AtomicInteger waterChunkNr = new AtomicInteger(0);
private AtomicInteger landChunkNr = new AtomicInteger(0); private AtomicInteger landChunkNr = new AtomicInteger(0);
private AtomicInteger cityFurnitureChunkNr = 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) { public CityDoctorController(MainWindow mainWindow, HighlightController highlightController, Renderer renderer) {
this.mainWindow = mainWindow; this.mainWindow = mainWindow;
...@@ -288,7 +288,7 @@ public class CityDoctorController { ...@@ -288,7 +288,7 @@ public class CityDoctorController {
waterChunkNr.set(0); waterChunkNr.set(0);
landChunkNr.set(0); landChunkNr.set(0);
cityFurnitureChunkNr.set(0); cityFurnitureChunkNr.set(0);
otherObjectsChunkNr.set(0); genericCityObjectsChunkNr.set(0);
} }
private void buildLand(CityDoctorModel model) { private void buildLand(CityDoctorModel model) {
...@@ -359,12 +359,12 @@ public class CityDoctorController { ...@@ -359,12 +359,12 @@ public class CityDoctorController {
if (model.getGenericCityObjects().isEmpty()) { if (model.getGenericCityObjects().isEmpty()) {
return; return;
} }
TreeView<Renderable> otherObjectsView = mainWindow.getOtherObjectsView(); TreeView<Renderable> otherObjectsView = mainWindow.getGenericCityObjectView();
TreeItem<Renderable> otherObjectsRoot = new TreeItem<>(new AllOtherObjectsNode(model.getGenericCityObjects())); TreeItem<Renderable> otherObjectsRoot = new TreeItem<>(new AllOtherObjectsNode(model.getGenericCityObjects()));
otherObjectsRoot.setExpanded(true); otherObjectsRoot.setExpanded(true);
otherObjectsView.setRoot(otherObjectsRoot); otherObjectsView.setRoot(otherObjectsRoot);
buildTreeFromList(model.getGenericCityObjects(), otherObjectsView.getRoot(), otherObjectsChunkNr); buildTreeFromList(model.getGenericCityObjects(), otherObjectsView.getRoot(), genericCityObjectsChunkNr);
addMoreButtonIfNecessary(model.getGenericCityObjects(), otherObjectsView, otherObjectsRoot, otherObjectsChunkNr); addMoreButtonIfNecessary(model.getGenericCityObjects(), otherObjectsView, otherObjectsRoot, genericCityObjectsChunkNr);
} }
private void buildWater(CityDoctorModel model) { private void buildWater(CityDoctorModel model) {
...@@ -399,7 +399,7 @@ public class CityDoctorController { ...@@ -399,7 +399,7 @@ public class CityDoctorController {
TreeItem<Renderable> transRoot = new TreeItem<>(new AllTransportationNode(model.getTransportation())); TreeItem<Renderable> transRoot = new TreeItem<>(new AllTransportationNode(model.getTransportation()));
transRoot.setExpanded(true); transRoot.setExpanded(true);
transView.setRoot(transRoot); transView.setRoot(transRoot);
buildTreeFromList(trans, transView.getRoot(), transportationChunkNr); buildTransportationTreeFromList(trans, transView.getRoot());
addMoreButtonIfNecessary(trans, transView, transRoot, transportationChunkNr); addMoreButtonIfNecessary(trans, transView, transRoot, transportationChunkNr);
} }
...@@ -543,7 +543,7 @@ public class CityDoctorController { ...@@ -543,7 +543,7 @@ public class CityDoctorController {
mainWindow.getWaterView().setRoot(null); mainWindow.getWaterView().setRoot(null);
mainWindow.getTerrainView().setRoot(null); mainWindow.getTerrainView().setRoot(null);
mainWindow.getCityFurnitureView().setRoot(null); mainWindow.getCityFurnitureView().setRoot(null);
mainWindow.getOtherObjectsView().setRoot(null); mainWindow.getGenericCityObjectView().setRoot(null);
mainWindow.getErrorTree().getRoot().getChildren().clear(); mainWindow.getErrorTree().getRoot().getChildren().clear();
mainWindow.getAttributeView().getRoot().getChildren().clear(); mainWindow.getAttributeView().getRoot().getChildren().clear();
mainWindow.getGlobalErrorsView().getItems().clear(); mainWindow.getGlobalErrorsView().getItems().clear();
...@@ -597,6 +597,163 @@ public class CityDoctorController { ...@@ -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) { private void buildTunnelTreeFromList(List<Tunnel> list, TreeItem<Renderable> root) {
int tunnelChunk = tunnelChunkNr.get(); int tunnelChunk = tunnelChunkNr.get();
for (int i = tunnelChunk * MAX_FEATURES_PER_CHUNK; i < (tunnelChunk + 1) * MAX_FEATURES_PER_CHUNK && i < list.size(); i++) { 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 { ...@@ -1062,7 +1219,7 @@ public class CityDoctorController {
updateTree(mainWindow.getCityFurnitureView().getRoot()); updateTree(mainWindow.getCityFurnitureView().getRoot());
updateTree(mainWindow.getTransportationView().getRoot()); updateTree(mainWindow.getTransportationView().getRoot());
updateTree(mainWindow.getWaterView().getRoot()); updateTree(mainWindow.getWaterView().getRoot());
updateTree(mainWindow.getOtherObjectsView().getRoot()); updateTree(mainWindow.getGenericCityObjectView().getRoot());
updateTree(mainWindow.getTunnelView().getRoot()); updateTree(mainWindow.getTunnelView().getRoot());
renderer.updateErrors(); renderer.updateErrors();
} }
...@@ -1175,7 +1332,22 @@ public class CityDoctorController { ...@@ -1175,7 +1332,22 @@ public class CityDoctorController {
} }
mainWindow.unselectEverything(); mainWindow.unselectEverything();
resetFeatureChunks(); resetFeatureChunks();
if (selectedTab == FeatureType.BUILDING) { 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()); List<Building> foundBuildings = filterFeatures(searchString, model.getBuildings());
TreeView<Renderable> buildingsView = mainWindow.getBuildingsView(); TreeView<Renderable> buildingsView = mainWindow.getBuildingsView();
TreeItem<Renderable> root = buildingsView.getRoot(); TreeItem<Renderable> root = buildingsView.getRoot();
...@@ -1183,77 +1355,82 @@ public class CityDoctorController { ...@@ -1183,77 +1355,82 @@ public class CityDoctorController {
buildBuildingTreeFromList(foundBuildings, root); buildBuildingTreeFromList(foundBuildings, root);
updateTree(root); updateTree(root);
addMoreButtonToBuildingsIfNecessary(foundBuildings, buildingsView, root, buildingChunkNr); addMoreButtonToBuildingsIfNecessary(foundBuildings, buildingsView, root, buildingChunkNr);
} else if (selectedTab == FeatureType.BRIDGE){ }
private void filterBridgeTree(String searchString) {
List<BridgeObject> foundBridges = filterFeatures(searchString, model.getBridges()); List<BridgeObject> foundBridges = filterFeatures(searchString, model.getBridges());
TreeView<Renderable> brigdeView = mainWindow.getBridgeView(); TreeView<Renderable> bridgeView = mainWindow.getBridgeView();
TreeItem<Renderable> root = brigdeView.getRoot(); TreeItem<Renderable> root = bridgeView.getRoot();
root.getChildren().clear(); root.getChildren().clear();
buildBridgeTreeFromList(foundBridges, root); buildBridgeTreeFromList(foundBridges, root);
updateTree(root); updateTree(root);
addMoreButtonIfNecessary(foundBridges, brigdeView, root, bridgeChunkNr); addMoreButtonIfNecessary(foundBridges, bridgeView, root, bridgeChunkNr);
} else if (selectedTab == FeatureType.TUNNEL){ }
private void filterTunnelTree(String searchString) {
List<Tunnel> foundTunnel = filterFeatures(searchString, model.getTunnels()); List<Tunnel> foundTunnel = filterFeatures(searchString, model.getTunnels());
TreeView<Renderable> tunnelView = mainWindow.getTunnelView(); TreeView<Renderable> tunnelView = mainWindow.getTunnelView();
TreeItem<Renderable> root = tunnelView.getRoot(); TreeItem<Renderable> root = tunnelView.getRoot();
root.getChildren().clear(); root.getChildren().clear();
buildTunnelTreeFromList(foundTunnel, root); buildTunnelTreeFromList(foundTunnel, root);
updateTree(root); updateTree(root);
addMoreButtonIfNecessary(foundTunnel, tunnelView, root, bridgeChunkNr); addMoreButtonIfNecessary(foundTunnel, tunnelView, root, tunnelChunkNr);
} }
else{
TreeView<Renderable> view; private void filterVegetationTree(String searchString) {
List<? extends CityObject> cos; List<Vegetation> foundVegetation = filterFeatures(searchString, model.getVegetation());
AtomicInteger chunkCounter; TreeView<Renderable> vegetationView = mainWindow.getVegetationView();
switch (selectedTab) { TreeItem<Renderable> root = vegetationView.getRoot();
case VEGETATION: root.getChildren().clear();
view = mainWindow.getVegetationView(); buildVegetationTreeFromList(foundVegetation, root);
cos = filterFeatures(searchString, model.getVegetation()); updateTree(root);
chunkCounter = vegetationChunkNr; addMoreButtonIfNecessary(foundVegetation, vegetationView, root, 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();
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(); root.getChildren().clear();
buildTreeFromList(cos, root, chunkCounter); buildTransportationTreeFromList(foundTransportation, root);
updateTree(root); updateTree(root);
addMoreButtonIfNecessary(cos, view, root, chunkCounter); 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) { private <T extends CityObject> List<T> filterFeatures(String searchString, List<T> features) {
...@@ -1270,72 +1447,7 @@ public class CityDoctorController { ...@@ -1270,72 +1447,7 @@ public class CityDoctorController {
if (model == null) { if (model == null) {
return; return;
} }
resetFeatureChunks(); buildTrees();
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);
}
} }
public Series<String, Number> createErrorSeries() { public Series<String, Number> createErrorSeries() {
...@@ -1406,12 +1518,12 @@ public class CityDoctorController { ...@@ -1406,12 +1518,12 @@ public class CityDoctorController {
model.getCityFurniture(), cityFurnitureChunkNr); model.getCityFurniture(), cityFurnitureChunkNr);
} }
public void fillTreeViewWithErrorOtherObjects() { public void fillTreeViewWithErrorGenericCityObjects() {
if (model == null) { if (model == null) {
return; return;
} }
fillTreeViewWithErrorCityObjects(mainWindow.getOtherObjectsView(), fillTreeViewWithErrorCityObjects(mainWindow.getGenericCityObjectView(),
model.getGenericCityObjects(), otherObjectsChunkNr); model.getGenericCityObjects(), genericCityObjectsChunkNr);
} }
public void fillTreeViewWithErrorTransportation() { public void fillTreeViewWithErrorTransportation() {
...@@ -1484,7 +1596,9 @@ public class CityDoctorController { ...@@ -1484,7 +1596,9 @@ public class CityDoctorController {
case TUNNEL: case TUNNEL:
buildTunnel(model.getTunnels()); buildTunnel(model.getTunnels());
updateTree(mainWindow.getTunnelView().getRoot()); updateTree(mainWindow.getTunnelView().getRoot());
break;
case WATER: case WATER:
buildWater(model); buildWater(model);
updateTree(mainWindow.getWaterView().getRoot()); updateTree(mainWindow.getWaterView().getRoot());
break; break;
...@@ -1494,7 +1608,7 @@ public class CityDoctorController { ...@@ -1494,7 +1608,7 @@ public class CityDoctorController {
break; break;
case GENERIC_CITY_OBJECT: case GENERIC_CITY_OBJECT:
buildOtherCityObjects(model); buildOtherCityObjects(model);
updateTree(mainWindow.getOtherObjectsView().getRoot()); updateTree(mainWindow.getGenericCityObjectView().getRoot());
break; break;
default: default:
throw new IllegalStateException(); throw new IllegalStateException();
...@@ -1588,7 +1702,7 @@ public class CityDoctorController { ...@@ -1588,7 +1702,7 @@ public class CityDoctorController {
fillTreeViewWithErrorCityFurniture(); fillTreeViewWithErrorCityFurniture();
break; break;
case GENERIC_CITY_OBJECT: case GENERIC_CITY_OBJECT:
fillTreeViewWithErrorOtherObjects(); fillTreeViewWithErrorGenericCityObjects();
break; break;
default: default:
throw new IllegalStateException("Unknown selected feature tab: " + mainWindow.getSelectedTab()); throw new IllegalStateException("Unknown selected feature tab: " + mainWindow.getSelectedTab());
......
...@@ -19,13 +19,11 @@ import javafx.application.Application; ...@@ -19,13 +19,11 @@ import javafx.application.Application;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.embed.swing.SwingFXUtils; import javafx.embed.swing.SwingFXUtils;
import javafx.event.Event;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.*; import javafx.scene.*;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.skin.VirtualFlow;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage; import javafx.scene.image.WritableImage;
...@@ -1026,7 +1024,7 @@ public class MainWindow extends Application { ...@@ -1026,7 +1024,7 @@ public class MainWindow extends Application {
return attributeView; return attributeView;
} }
public TreeView<Renderable> getOtherObjectsView() { public TreeView<Renderable> getGenericCityObjectView() {
return otherObjectsView; return otherObjectsView;
} }
......
...@@ -366,6 +366,35 @@ public class Renderer { ...@@ -366,6 +366,35 @@ public class Renderer {
return polygons; 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) { public void render(Tunnel tunnel) {
refresher = () -> { refresher = () -> {
Set<ConcretePolygon> setupTunnelPolygons = setupTunnelPolygons(tunnel); Set<ConcretePolygon> setupTunnelPolygons = setupTunnelPolygons(tunnel);
...@@ -578,6 +607,20 @@ public class Renderer { ...@@ -578,6 +607,20 @@ public class Renderer {
return polygons; 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) { public void render(BoundarySurface bs) {
refresher = () -> { refresher = () -> {
Set<ConcretePolygon> setupBoundarySurfacePolygons = setupBoundarySurfacePolygons(bs); Set<ConcretePolygon> setupBoundarySurfacePolygons = setupBoundarySurfacePolygons(bs);
...@@ -827,8 +870,34 @@ public class Renderer { ...@@ -827,8 +870,34 @@ public class Renderer {
renderCityObjects(vegetation, Color.LIGHTGREEN); renderCityObjects(vegetation, Color.LIGHTGREEN);
} }
public void renderTransportation(List<TransportationObject> transportation) { public void renderTransportation(List<? extends TransportationObject> transportation) {
renderCityObjects(transportation, Color.YELLOW); 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) { public void renderBridges(List<BridgeObject> bridges) {
......
...@@ -78,7 +78,7 @@ public class TriangulatedGeometry { ...@@ -78,7 +78,7 @@ public class TriangulatedGeometry {
addPointsFromBuildings(model.getBuildings(), points); addPointsFromBuildings(model.getBuildings(), points);
addPointsFromCityObject(model.getBridges(), points); addPointsFromCityObject(model.getBridges(), points);
addPointsFromCityObject(model.getLand(), points); addPointsFromCityObject(model.getLand(), points);
addPointsFromCityObject(model.getTransportation(), points); addPointsFromTransportationObjects(model.getTransportation(), points);
addPointsFromCityObject(model.getVegetation(), points); addPointsFromCityObject(model.getVegetation(), points);
addPointsFromCityObject(model.getWater(), points); addPointsFromCityObject(model.getWater(), points);
...@@ -90,7 +90,7 @@ public class TriangulatedGeometry { ...@@ -90,7 +90,7 @@ public class TriangulatedGeometry {
addPolygonDataFromBuildings(model.getBuildings(), triGeom, filters); addPolygonDataFromBuildings(model.getBuildings(), triGeom, filters);
addPolygonDataFromBridges(model.getBridges(), triGeom, filters); addPolygonDataFromBridges(model.getBridges(), triGeom, filters);
addPolygonDataFromCityObjects(model.getLand(), triGeom, Color.BROWN, 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.getVegetation(), triGeom, Color.LIGHTGREEN, filters);
addPolygonDataFromCityObjects(model.getWater(), triGeom, Color.LIGHTSKYBLUE, filters); addPolygonDataFromCityObjects(model.getWater(), triGeom, Color.LIGHTSKYBLUE, filters);
addPolygonDataFromCityObjects(model.getCityFurniture(), triGeom, Color.BLUEVIOLET, filters); addPolygonDataFromCityObjects(model.getCityFurniture(), triGeom, Color.BLUEVIOLET, filters);
...@@ -132,6 +132,45 @@ public class TriangulatedGeometry { ...@@ -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, private static void addPolygonDataFromBoundarySurfaces(List<BoundarySurface> boundarySurfaces,
TriangulatedGeometry triGeom, List<ViewFilter> filters) { TriangulatedGeometry triGeom, List<ViewFilter> filters) {
for (BoundarySurface bs : boundarySurfaces) { for (BoundarySurface bs : boundarySurfaces) {
...@@ -187,6 +226,29 @@ public class TriangulatedGeometry { ...@@ -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) { private static void addPointsFromCityObject(List<? extends CityObject> cos, List<Vector3d> points) {
for (CityObject co : cos) { for (CityObject co : cos) {
addPoints(co, points); addPoints(co, points);
......
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);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment