Commit 5e5e7ad6 authored by Riegel's avatar Riegel
Browse files

Add support for CityFurniture objects

Showing with 313 additions and 2 deletions
+313 -2
......@@ -57,6 +57,7 @@ public class CityDoctorModel {
private final List<Building> buildings;
private final List<Vegetation> vegetation;
private final List<BridgeObject> bridges;
private final List<CityFurniture> cityfurniture;
private final List<CityObject> land;
private final List<TransportationObject> roads;
private final List<WaterObject> water;
......@@ -82,6 +83,7 @@ public class CityDoctorModel {
land = new ArrayList<>();
roads = new ArrayList<>();
water = new ArrayList<>();
cityfurniture = new ArrayList<>();
globalErrors = new ArrayList<>();
}
......@@ -224,6 +226,7 @@ public class CityDoctorModel {
collectErrorsFromList(errors, land);
collectErrorsFromList(errors, roads);
collectErrorsFromList(errors, water);
collectErrorsFromList(errors, cityfurniture);
return new HashSet<>(errors);
}
......@@ -253,6 +256,14 @@ public class CityDoctorModel {
return bridges;
}
public List<CityFurniture> getCityFurniture() {
return cityfurniture;
}
public void addCityFurniture(CityFurniture coFurniture) {
cityfurniture.add(coFurniture);
}
public void setCityModel(CityModel cModel) {
this.cModel = cModel;
}
......@@ -314,6 +325,8 @@ public class CityDoctorModel {
replaceLandObject(currentFeature, nextFeature);
} else if (nextFeature instanceof WaterObject) {
replaceWaterObject(currentFeature, nextFeature);
} else if (nextFeature instanceof CityFurniture) {
replaceCityFurniture(currentFeature, nextFeature);
}
}
......@@ -341,6 +354,14 @@ public class CityDoctorModel {
vegetation.set(index, (Vegetation) nextFeature);
}
private void replaceCityFurniture(CityObject currentFeature, CityObject nextFeature) {
int index = cityfurniture.indexOf(currentFeature);
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in vegetation");
}
cityfurniture.set(index, (CityFurniture) nextFeature);
}
private void replaceTransportationObject(CityObject currentFeature, CityObject nextFeature) {
int index = roads.indexOf(currentFeature);
if (index == -1) {
......
package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.check.Check;
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.AbstractCityObject;
import org.citygml4j.core.util.geometry.GeometryFactory;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import org.xmlobjects.gml.model.geometry.primitives.Solid;
import org.xmlobjects.gml.model.geometry.primitives.SolidProperty;
import java.io.Serial;
public class CityFurniture extends CityObject{
@Serial
private static final long serialVersionUID = 3325661061543962473L;
private org.citygml4j.core.model.cityfurniture.CityFurniture cgmlCityFurniture;
@Override
public void accept(Check c) {
super.accept(c);
if (c.canExecute(this)) {
c.check(this);
}
}
@Override
public AbstractCityObject getGmlObject() {
return cgmlCityFurniture;
}
public void setGmlObject(org.citygml4j.core.model.cityfurniture.CityFurniture gmlCityFurniture) {
cgmlCityFurniture = gmlCityFurniture;
}
@Override
public void unsetGmlGeometries() {
cgmlCityFurniture.setLod0MultiSurface(null);
cgmlCityFurniture.setLod2MultiSurface(null);
cgmlCityFurniture.setLod3MultiSurface(null);
cgmlCityFurniture.setLod1Solid(null);
cgmlCityFurniture.setLod2Solid(null);
cgmlCityFurniture.setLod3Solid(null);
cgmlCityFurniture.getDeprecatedProperties().setLod4Geometry(null);
}
@Override
public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) {
for (Geometry geom : getGeometries()) {
if (geom.getType() == GeometryType.MULTI_SURFACE) {
MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
setMultiSurfaceAccordingToLod(geom, ms);
} else {
Solid solid = CityGmlUtils.createSolid(geom, factory, config);
setSolidAccordingToLod(geom, solid);
}
}
}
private void setMultiSurfaceAccordingToLod(Geometry geom, MultiSurface ms) {
switch (geom.getLod()) {
case LOD0:
cgmlCityFurniture.setLod0MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD2:
cgmlCityFurniture.setLod2MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD3:
cgmlCityFurniture.setLod3MultiSurface(new MultiSurfaceProperty(ms));
break;
default:
throw new IllegalStateException("Cannot add " + geom.getLod() + " multi surface to buildings");
}
}
private void setSolidAccordingToLod(Geometry geom, Solid solid) {
switch (geom.getLod()) {
case LOD1:
cgmlCityFurniture.setLod1Solid(new SolidProperty(solid));
break;
case LOD2:
cgmlCityFurniture.setLod2Solid(new SolidProperty(solid));
break;
case LOD3:
cgmlCityFurniture.setLod3Solid(new SolidProperty(solid));
break;
default:
throw new IllegalStateException("Cannot add " + geom.getLod() + " solid to buildings");
}
}
@Override
public FeatureType getFeatureType() {
return FeatureType.CITY_FURNITURE;
}
@Override
public Copyable createCopyInstance() {
return new CityFurniture();
}
@Override
public void fillValues(Copyable original, CopyHandler handler) {
super.fillValues(original, handler);
CityFurniture originalCF = (CityFurniture) original;
cgmlCityFurniture = originalCF.cgmlCityFurniture;
}
}
......@@ -27,6 +27,6 @@ package de.hft.stuttgart.citydoctor2.datastructure;
public enum FeatureType {
BUILDING, TRANSPORTATION, VEGETATION, BRIDGE, LAND, WATER, BOUNDARY_SURFACE, INSTALLATION, OPENING,
BUILDING_PART, BRIDGE_CONSTRUCTION_ELEMENT, BRIDGE_INSTALLATION, ROOM, FURNITURE
BUILDING_PART, BRIDGE_CONSTRUCTION_ELEMENT, BRIDGE_INSTALLATION, ROOM, FURNITURE, CITY_FURNITURE
}
......@@ -117,6 +117,22 @@ public class Citygml3FeatureMapper extends ObjectWalker {
}
@Override
public void visit(org.citygml4j.core.model.cityfurniture.CityFurniture gmlCityFurniture) {
CityFurniture cf = new CityFurniture();
cf.setGmlObject(gmlCityFurniture);
mapAbstractOccupiedSpace(gmlCityFurniture, cf);
resolveAndClearReferences();
cf.unsetGmlGeometries();
updateEdgesAndVertices(cf);
model.addCityFurniture(cf);
}
public void visit(org.citygml4j.core.model.generics.GenericOccupiedSpace gos){
System.out.println(gos.toString());
}
@Override
public void visit(org.citygml4j.core.model.building.Building gmlBuilding) {
Building cdBuilding = new Building();
......
......@@ -49,6 +49,7 @@ MainWindow.transportationTab=Transportation
MainWindow.bridgeTab=Bridges
MainWindow.waterTab=Water
MainWindow.terrainTab=Terrain
MainWindow.cityfurnitureTab=CityFurniture
MainWindow.viewLabel=View
MainWindow.showLabel=Show:
MainWindow.searchLabel=Search:
......
......@@ -47,6 +47,7 @@ MainWindow.transportationTab=Verkehrsobjekte
MainWindow.bridgeTab=Br\u00fccken
MainWindow.waterTab=Gew\u00e4sser
MainWindow.terrainTab=Gel\u00e4nde
MainWindow.cityfurnitureTab=Stadtm\u00f6bel
MainWindow.viewLabel=Ansicht
MainWindow.showLabel=Zeige:
MainWindow.searchLabel=Suche:
......
......@@ -66,6 +66,7 @@ public class CityDoctorController {
private AtomicInteger bridgeChunkNr = new AtomicInteger(0);
private AtomicInteger waterChunkNr = new AtomicInteger(0);
private AtomicInteger landChunkNr = new AtomicInteger(0);
private AtomicInteger cityFurnitureChunkNr = new AtomicInteger(0);
public CityDoctorController(MainWindow mainWindow, HighlightController highlightController, Renderer renderer) {
this.mainWindow = mainWindow;
......@@ -149,6 +150,7 @@ public class CityDoctorController {
buildBridges(model);
buildWater(model);
buildLand(model);
buildCityFurniture(model);
}
private void resetFeatureChunks() {
......@@ -158,6 +160,7 @@ public class CityDoctorController {
bridgeChunkNr.set(0);
waterChunkNr.set(0);
landChunkNr.set(0);
cityFurnitureChunkNr.set(0);
}
private void buildLand(CityDoctorModel model) {
......@@ -212,6 +215,18 @@ public class CityDoctorController {
}
}
private void buildCityFurniture(CityDoctorModel model){
if (model.getCityFurniture().isEmpty()){
return;
}
TreeView<Renderable> cityFurnitureView = mainWindow.getCityFurnitureView();
TreeItem<Renderable> cityFurnitureRoot = new TreeItem<>(new AllCityFurnitureNode(model.getCityFurniture()));
cityFurnitureRoot.setExpanded(true);
cityFurnitureView.setRoot(cityFurnitureRoot);
buildTreeFromList(model.getCityFurniture(), cityFurnitureView.getRoot(), cityFurnitureChunkNr);
addMoreButtonIfNecessary(model.getCityFurniture(), cityFurnitureView, cityFurnitureRoot, cityFurnitureChunkNr);
}
private void buildWater(CityDoctorModel model) {
if (model.getWater().isEmpty()) {
return;
......@@ -375,6 +390,7 @@ public class CityDoctorController {
mainWindow.getBridgeView().setRoot(null);
mainWindow.getWaterView().setRoot(null);
mainWindow.getTerrainView().setRoot(null);
mainWindow.getCityFurnitureView().setRoot(null);
mainWindow.getErrorTree().getRoot().getChildren().clear();
mainWindow.getGlobalErrorsView().getItems().clear();
clearGeometryTrees();
......@@ -788,6 +804,11 @@ public class CityDoctorController {
cos = filterFeatures(searchString, model.getLand());
chunkCounter = landChunkNr;
break;
case CITY_FURNITURE:
view = mainWindow.getCityFurnitureView();
cos = filterFeatures(searchString, model.getLand());
chunkCounter = cityFurnitureChunkNr;
break;
default:
throw new IllegalStateException("Unknown selected feature tab");
}
......@@ -855,6 +876,11 @@ public class CityDoctorController {
cos = model.getLand();
chunkCounter = landChunkNr;
break;
case CITY_FURNITURE:
view = mainWindow.getCityFurnitureView();
cos = model.getCityFurniture();
chunkCounter = cityFurnitureChunkNr;
break;
default:
throw new IllegalStateException("Unknown selected feature tab");
}
......@@ -926,6 +952,14 @@ public class CityDoctorController {
fillTreeViewWithErrorCityObjects(mainWindow.getTerrainView(), model.getLand(), landChunkNr);
}
public void fillTreeViewWithErrorCityFurniture(){
if (model == null) {
return;
}
fillTreeViewWithErrorCityObjects(mainWindow.getCityFurnitureView(),
model.getCityFurniture(), cityFurnitureChunkNr);
}
public void fillTreeViewWithErrorTransportation() {
if (model == null) {
return;
......@@ -990,6 +1024,10 @@ public class CityDoctorController {
buildWater(model);
updateTree(mainWindow.getWaterView().getRoot());
break;
case CITY_FURNITURE:
buildCityFurniture(model);
updateTree(mainWindow.getCityFurnitureView().getRoot());
break;
default:
throw new IllegalStateException();
}
......@@ -1077,6 +1115,9 @@ public class CityDoctorController {
case WATER:
fillTreeViewWithErrorWater();
break;
case CITY_FURNITURE:
fillTreeViewWithErrorCityFurniture();
break;
default:
throw new IllegalStateException("Unknown selected feature tab: " + mainWindow.getSelectedTab());
}
......
......@@ -104,6 +104,9 @@ public class MainWindow extends Application {
@FXML
private TreeView<Renderable> terrainView;
@FXML
private TreeView<Renderable> cityFurnitureView;
@FXML
private TreeView<Renderable> polygonView;
......@@ -179,6 +182,9 @@ public class MainWindow extends Application {
@FXML
private Tab terrainTab;
@FXML
private Tab cityFurnitureTab;
@FXML
private Tab errorsTab;
......@@ -417,6 +423,7 @@ public class MainWindow extends Application {
bridgeTab.setText(Localization.getText("MainWindow.bridgeTab"));
waterTab.setText(Localization.getText("MainWindow.waterTab"));
terrainTab.setText(Localization.getText("MainWindow.terrainTab"));
cityFurnitureTab.setText(Localization.getText("MainWindow.cityfurnitureTab"));
viewLabel.setText(Localization.getText("MainWindow.viewLabel"));
showLabel.setText(Localization.getText("MainWindow.showLabel"));
searchLabel.setText(Localization.getText("MainWindow.searchLabel"));
......@@ -632,6 +639,9 @@ public class MainWindow extends Application {
case 5:
selectedTab = FeatureType.LAND;
break;
case 6:
selectedTab = FeatureType.CITY_FURNITURE;
break;
default:
throw new IllegalStateException("Unknown tab index: " + index);
}
......@@ -713,6 +723,10 @@ public class MainWindow extends Application {
setupSelectListener(terrainView);
terrainView.setCellFactory(param -> new RenderableTreeCell());
cityFurnitureView.setShowRoot(true);
setupSelectListener(cityFurnitureView);
cityFurnitureView.setCellFactory(param -> new RenderableTreeCell());
setupSelectListener(vertexView);
vertexView.setRoot(new TreeItem<>());
vertexView.setCellFactory(param -> new RenderableTreeCell());
......@@ -852,6 +866,10 @@ public class MainWindow extends Application {
return terrainView;
}
public TreeView<Renderable> getCityFurnitureView() {
return cityFurnitureView;
}
public TreeView<Renderable> getPolygonsView() {
return polygonView;
}
......@@ -898,6 +916,7 @@ public class MainWindow extends Application {
transView.getSelectionModel().clearSelection();
waterView.getSelectionModel().clearSelection();
terrainView.getSelectionModel().clearSelection();
cityFurnitureView.getSelectionModel().clearSelection();
bridgeView.getSelectionModel().clearSelection();
polygonView.getSelectionModel().clearSelection();
edgeView.getSelectionModel().clearSelection();
......
......@@ -382,6 +382,25 @@ public class Renderer {
return polygons;
}
public void render(CityFurniture cf) {
refresher = () -> {
Set<ConcretePolygon> setupCityFurniturePolygons = setupCityFurniturePolygons(cf);
mainWindow.zoomOutForBoundingBox(BoundingBox.of(setupCityFurniturePolygons));
render(setupCityFurniturePolygons);
Platform.runLater(() -> {
errorUpdater = () -> displayErrors(cf);
errorUpdater.run();
});
};
refresher.run();
}
private Set<ConcretePolygon> setupCityFurniturePolygons(CityFurniture cf) {
Set<ConcretePolygon> polygons = new HashSet<>();
addPolygons(cf, polygons);
return polygons;
}
public void render(BoundarySurface bs) {
refresher = () -> {
Set<ConcretePolygon> setupBoundarySurfacePolygons = setupBoundarySurfacePolygons(bs);
......@@ -624,6 +643,10 @@ public class Renderer {
renderCityObjects(water, Color.LIGHTSKYBLUE);
}
public void renderCityFurniture(List<CityFurniture> cityFurniture){
renderCityObjects(cityFurniture, Color.CYAN);
}
public void renderTerrain(List<CityObject> land) {
renderLandObjects(land, Color.BROWN);
}
......
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.CityFurniture;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
import java.util.List;
public class AllCityFurnitureNode extends Renderable{
private final List<CityFurniture> cityFurnitures;
public AllCityFurnitureNode(List<CityFurniture> cityFurnitures) {
this.cityFurnitures = cityFurnitures;
}
@Override
public void refreshTextColor() {
// no color changes
}
@Override
public String getText() {
return "CityFurniture";
}
@Override
public void visit(Renderer renderer) {
renderer.renderCityFurniture(cityFurnitures);
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractRoom;
import de.hft.stuttgart.citydoctor2.datastructure.CityFurniture;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class CityFurnitureNode extends Renderable{
private final CityFurniture cityFurniture;
public CityFurnitureNode(CityFurniture cityFurniture) {
this.cityFurniture = cityFurniture;
}
@Override
public String getText() {
return cityFurniture.getGmlId().getGmlString();
}
@Override
public void visit(Renderer renderer) {
renderer.render(cityFurniture);
}
@Override
public void refreshTextColor() {
if (!cityFurniture.isValidated()) {
setStatus(CheckStatus.NOT_CHECKED);
} else if (cityFurniture.containsAnyError()) {
setStatus(CheckStatus.ERROR);
} else {
setStatus(CheckStatus.OK);
}
}
}
......@@ -19,7 +19,7 @@
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<BorderPane fx:id="mainPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="400.0" minWidth="400.0" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml">
<BorderPane fx:id="mainPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="400.0" minWidth="400.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1">
<center>
<SplitPane fx:id="mainContainer" dividerPositions="0.47069431920649235" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minWidth="300.0" prefHeight="600.0" prefWidth="1100.0">
<items>
......@@ -88,6 +88,11 @@
<TreeView id="terrainTree" fx:id="terrainView" prefHeight="200.0" prefWidth="200.0" showRoot="false" />
</content>
</Tab>
<Tab fx:id="cityFurnitureTab" text="CityFurniture">
<content>
<TreeView id="cityFurnitureTree" fx:id="cityFurnitureView" prefHeight="200.0" prefWidth="200.0" showRoot="false" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
......
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