Commit 9e161477 authored by Riegel's avatar Riegel
Browse files

Format code

parent 6b536067
Pipeline #10248 passed with stage
in 1 minute and 13 seconds
...@@ -45,1133 +45,1133 @@ import javafx.stage.FileChooser.ExtensionFilter; ...@@ -45,1133 +45,1133 @@ import javafx.stage.FileChooser.ExtensionFilter;
public class CityDoctorController { public class CityDoctorController {
private static final int MAX_FEATURES_PER_CHUNK = 200; private static final int MAX_FEATURES_PER_CHUNK = 200;
private static final Logger logger = LogManager.getLogger(CityDoctorController.class); private static final Logger logger = LogManager.getLogger(CityDoctorController.class);
private MainWindow mainWindow; private MainWindow mainWindow;
private CityDoctorModel model; private CityDoctorModel model;
private ParserConfiguration currentConfig; private ParserConfiguration currentConfig;
private String sourceFile; private String sourceFile;
private Checker currentChecker; private Checker currentChecker;
private HighlightController highlightController; private HighlightController highlightController;
private Renderer renderer; private Renderer renderer;
private AtomicInteger buildingChunkNr = new AtomicInteger(0); private AtomicInteger buildingChunkNr = new AtomicInteger(0);
private AtomicInteger vegetationChunkNr = new AtomicInteger(0); private AtomicInteger vegetationChunkNr = new AtomicInteger(0);
private AtomicInteger transportationChunkNr = new AtomicInteger(0); private AtomicInteger transportationChunkNr = new AtomicInteger(0);
private AtomicInteger bridgeChunkNr = new AtomicInteger(0); private AtomicInteger bridgeChunkNr = new AtomicInteger(0);
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 otherObjectsChunkNr = 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;
this.highlightController = highlightController; this.highlightController = highlightController;
this.renderer = renderer; this.renderer = renderer;
} }
public void loadCityGml(String path, int numberOfRoundingPlaces, ProgressListener l, boolean useValidation) public void loadCityGml(String path, int numberOfRoundingPlaces, ProgressListener l, boolean useValidation)
throws CityGmlParseException, InvalidGmlFileException { throws CityGmlParseException, InvalidGmlFileException {
loadCityGml(path, numberOfRoundingPlaces, l, useValidation, false); loadCityGml(path, numberOfRoundingPlaces, l, useValidation, false);
} }
public void loadCityGml(String path, int numberOfRoundingPlaces, ProgressListener l, boolean useValidation, public void loadCityGml(String path, int numberOfRoundingPlaces, ProgressListener l, boolean useValidation,
boolean lowMemory) throws CityGmlParseException, InvalidGmlFileException { boolean lowMemory) throws CityGmlParseException, InvalidGmlFileException {
try { try {
Platform.runLater(() -> { Platform.runLater(() -> {
mainWindow.getOpenBtn().setDisable(true); mainWindow.getOpenBtn().setDisable(true);
mainWindow.getWriteReportButton().setDisable(true); mainWindow.getWriteReportButton().setDisable(true);
mainWindow.getMeshGroup().getChildren().clear(); mainWindow.getMeshGroup().getChildren().clear();
clearTrees(); clearTrees();
mainWindow.resetSearchBar(); mainWindow.resetSearchBar();
mainWindow.resetFilterComboBox(); mainWindow.resetFilterComboBox();
}); });
currentChecker = null; currentChecker = null;
currentConfig = new ParserConfiguration(numberOfRoundingPlaces, useValidation, lowMemory); currentConfig = new ParserConfiguration(numberOfRoundingPlaces, useValidation, lowMemory);
GMLValidationHandler handler = null; GMLValidationHandler handler = null;
List<String> validationIssues = new ArrayList<>(); List<String> validationIssues = new ArrayList<>();
if (useValidation) { if (useValidation) {
handler = new GMLValidationHandler() { handler = new GMLValidationHandler() {
@Override @Override
public void error(SAXParseException exception) { public void error(SAXParseException exception) {
if (exception.getLineNumber() >= 0) { if (exception.getLineNumber() >= 0) {
String s = "In line " + exception.getLineNumber() + ":"; String s = "In line " + exception.getLineNumber() + ":";
validationIssues.add(s); validationIssues.add(s);
} }
validationIssues.add(exception.getMessage()); validationIssues.add(exception.getMessage());
} }
@Override @Override
public void warning(SAXParseException exception) { public void warning(SAXParseException exception) {
error(exception); error(exception);
} }
@Override @Override
public void fatalError(SAXParseException exception) { public void fatalError(SAXParseException exception) {
error(exception); error(exception);
} }
}; };
} }
model = CityGmlParser.parseCityGmlFile(path, currentConfig, l, handler); model = CityGmlParser.parseCityGmlFile(path, currentConfig, l, handler);
if (!validationIssues.isEmpty()) { if (!validationIssues.isEmpty()) {
StringJoiner sj = new StringJoiner("\n"); StringJoiner sj = new StringJoiner("\n");
validationIssues.stream().forEach(sj::add); validationIssues.stream().forEach(sj::add);
throw new InvalidGmlFileException(sj.toString()); throw new InvalidGmlFileException(sj.toString());
} }
mainWindow.getClickHandler().setConfig(currentConfig); mainWindow.getClickHandler().setConfig(currentConfig);
sourceFile = path; sourceFile = path;
renderer.reset(); renderer.reset();
Platform.runLater(() -> { Platform.runLater(() -> {
mainWindow.addFileNameToTitle(path); mainWindow.addFileNameToTitle(path);
mainWindow.getCheckButton().setDisable(false); mainWindow.getCheckButton().setDisable(false);
mainWindow.getLod1Btn().setDisable(false); mainWindow.getLod1Btn().setDisable(false);
mainWindow.getLod2Btn().setDisable(false); mainWindow.getLod2Btn().setDisable(false);
mainWindow.getLod3Btn().setDisable(false); mainWindow.getLod3Btn().setDisable(false);
mainWindow.getLod4Btn().setDisable(false); mainWindow.getLod4Btn().setDisable(false);
mainWindow.getWorldBtn().setDisable(false); mainWindow.getWorldBtn().setDisable(false);
mainWindow.getSaveBtn().setDisable(false); mainWindow.getSaveBtn().setDisable(false);
buildTrees(); buildTrees();
}); });
} finally { } finally {
Platform.runLater(() -> mainWindow.getOpenBtn().setDisable(false)); Platform.runLater(() -> mainWindow.getOpenBtn().setDisable(false));
} }
} }
public void buildTrees() { public void buildTrees() {
resetFeatureChunks(); resetFeatureChunks();
buildBuildings(model); buildBuildings(model);
buildVegetation(model.getVegetation()); buildVegetation(model.getVegetation());
buildTransportation(model.getTransportation()); buildTransportation(model.getTransportation());
buildBridges(model); buildBridges(model);
buildWater(model); buildWater(model);
buildLand(model); buildLand(model);
buildCityFurniture(model); buildCityFurniture(model);
buildOtherCityObjects(model); buildOtherCityObjects(model);
} }
private void resetFeatureChunks() { private void resetFeatureChunks() {
buildingChunkNr.set(0); buildingChunkNr.set(0);
vegetationChunkNr.set(0); vegetationChunkNr.set(0);
transportationChunkNr.set(0); transportationChunkNr.set(0);
bridgeChunkNr.set(0); bridgeChunkNr.set(0);
waterChunkNr.set(0); waterChunkNr.set(0);
landChunkNr.set(0); landChunkNr.set(0);
cityFurnitureChunkNr.set(0); cityFurnitureChunkNr.set(0);
otherObjectsChunkNr.set(0); otherObjectsChunkNr.set(0);
} }
private void buildLand(CityDoctorModel model) { private void buildLand(CityDoctorModel model) {
if (model.getLand().isEmpty()) { if (model.getLand().isEmpty()) {
return; return;
} }
TreeView<Renderable> landView = mainWindow.getTerrainView(); TreeView<Renderable> landView = mainWindow.getTerrainView();
TreeItem<Renderable> landRoot = new TreeItem<>(new AllTerrainNode(model.getLand())); TreeItem<Renderable> landRoot = new TreeItem<>(new AllTerrainNode(model.getLand()));
landRoot.setExpanded(true); landRoot.setExpanded(true);
landView.setRoot(landRoot); landView.setRoot(landRoot);
buildLandFromList(model.getLand(), landView.getRoot()); buildLandFromList(model.getLand(), landView.getRoot());
addMoreButtonIfNecessary(model.getLand(), landView, landRoot, landChunkNr); addMoreButtonIfNecessary(model.getLand(), landView, landRoot, landChunkNr);
} }
private void buildLandFromList(List<CityObject> list, TreeItem<Renderable> root) { private void buildLandFromList(List<CityObject> list, TreeItem<Renderable> root) {
int landChunk = landChunkNr.get(); int landChunk = landChunkNr.get();
for (int i = landChunk * MAX_FEATURES_PER_CHUNK; i < (landChunk + 1) * MAX_FEATURES_PER_CHUNK for (int i = landChunk * MAX_FEATURES_PER_CHUNK; i < (landChunk + 1) * MAX_FEATURES_PER_CHUNK
&& i < list.size(); i++) { && i < list.size(); i++) {
CityObject land = list.get(i); CityObject land = list.get(i);
Renderable node; Renderable node;
if (land instanceof ReliefObject relief) { if (land instanceof ReliefObject relief) {
node = new ReliefNode(relief); node = new ReliefNode(relief);
} else if (land instanceof TinObject tin) { } else if (land instanceof TinObject tin) {
node = new TinNode(tin); node = new TinNode(tin);
} else { } else {
node = new LandUseNode((LandObject) land); node = new LandUseNode((LandObject) land);
} }
TreeItem<Renderable> item = new TreeItem<>(node); TreeItem<Renderable> item = new TreeItem<>(node);
item.setExpanded(true); item.setExpanded(true);
root.getChildren().add(item); root.getChildren().add(item);
createGeometryNodes(land, item); createGeometryNodes(land, item);
if (land instanceof ReliefObject relief) { if (land instanceof ReliefObject relief) {
createTinNodes(relief, item); createTinNodes(relief, item);
} }
} }
} }
private void createTinNodes(ReliefObject relief, TreeItem<Renderable> item) { private void createTinNodes(ReliefObject relief, TreeItem<Renderable> item) {
if (relief.getComponents().isEmpty()) { if (relief.getComponents().isEmpty()) {
return; return;
} }
AllTinNode allTinText = new AllTinNode(relief.getComponents()); AllTinNode allTinText = new AllTinNode(relief.getComponents());
TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allTinText); TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allTinText);
item.getChildren().add(allBpsTextItem); item.getChildren().add(allBpsTextItem);
for (TinObject tin : relief.getComponents()) { for (TinObject tin : relief.getComponents()) {
TinNode tinNode = new TinNode(tin); TinNode tinNode = new TinNode(tin);
TreeItem<Renderable> tinNodeItem = new TreeItem<>(tinNode); TreeItem<Renderable> tinNodeItem = new TreeItem<>(tinNode);
tinNodeItem.setExpanded(true); tinNodeItem.setExpanded(true);
allBpsTextItem.getChildren().add(tinNodeItem); allBpsTextItem.getChildren().add(tinNodeItem);
createGeometryNodes(tin, tinNodeItem); createGeometryNodes(tin, tinNodeItem);
} }
} }
private void buildCityFurniture(CityDoctorModel model){ private void buildCityFurniture(CityDoctorModel model) {
if (model.getCityFurniture().isEmpty()){ if (model.getCityFurniture().isEmpty()) {
return; return;
} }
TreeView<Renderable> cityFurnitureView = mainWindow.getCityFurnitureView(); TreeView<Renderable> cityFurnitureView = mainWindow.getCityFurnitureView();
TreeItem<Renderable> cityFurnitureRoot = new TreeItem<>(new AllCityFurnitureNode(model.getCityFurniture())); TreeItem<Renderable> cityFurnitureRoot = new TreeItem<>(new AllCityFurnitureNode(model.getCityFurniture()));
cityFurnitureRoot.setExpanded(true); cityFurnitureRoot.setExpanded(true);
cityFurnitureView.setRoot(cityFurnitureRoot); cityFurnitureView.setRoot(cityFurnitureRoot);
buildTreeFromList(model.getCityFurniture(), cityFurnitureView.getRoot(), cityFurnitureChunkNr); buildTreeFromList(model.getCityFurniture(), cityFurnitureView.getRoot(), cityFurnitureChunkNr);
addMoreButtonIfNecessary(model.getCityFurniture(), cityFurnitureView, cityFurnitureRoot, cityFurnitureChunkNr); addMoreButtonIfNecessary(model.getCityFurniture(), cityFurnitureView, cityFurnitureRoot, cityFurnitureChunkNr);
} }
private void buildOtherCityObjects(CityDoctorModel model){ private void buildOtherCityObjects(CityDoctorModel model) {
if (model.getGenericCityObjects().isEmpty()){ if (model.getGenericCityObjects().isEmpty()) {
return; return;
} }
TreeView<Renderable> otherObjectsView = mainWindow.getOtherObjectsView(); TreeView<Renderable> otherObjectsView = mainWindow.getOtherObjectsView();
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(), otherObjectsChunkNr);
addMoreButtonIfNecessary(model.getGenericCityObjects(), otherObjectsView, otherObjectsRoot, otherObjectsChunkNr); addMoreButtonIfNecessary(model.getGenericCityObjects(), otherObjectsView, otherObjectsRoot, otherObjectsChunkNr);
} }
private void buildWater(CityDoctorModel model) { private void buildWater(CityDoctorModel model) {
if (model.getWater().isEmpty()) { if (model.getWater().isEmpty()) {
return; return;
} }
TreeView<Renderable> waterView = mainWindow.getWaterView(); TreeView<Renderable> waterView = mainWindow.getWaterView();
TreeItem<Renderable> waterRoot = new TreeItem<>(new AllWaterNode(model.getWater())); TreeItem<Renderable> waterRoot = new TreeItem<>(new AllWaterNode(model.getWater()));
waterRoot.setExpanded(true); waterRoot.setExpanded(true);
waterView.setRoot(waterRoot); waterView.setRoot(waterRoot);
buildTreeFromList(model.getWater(), waterView.getRoot(), waterChunkNr); buildTreeFromList(model.getWater(), waterView.getRoot(), waterChunkNr);
addMoreButtonIfNecessary(model.getWater(), waterView, waterRoot, waterChunkNr); addMoreButtonIfNecessary(model.getWater(), waterView, waterRoot, waterChunkNr);
} }
private void buildBridges(CityDoctorModel model) { private void buildBridges(CityDoctorModel model) {
if (model.getBridges().isEmpty()) { if (model.getBridges().isEmpty()) {
return; return;
} }
TreeView<Renderable> bridgeView = mainWindow.getBridgeView(); TreeView<Renderable> bridgeView = mainWindow.getBridgeView();
TreeItem<Renderable> bridgeRoot = new TreeItem<>(new AllBridgesNode(model.getBridges())); TreeItem<Renderable> bridgeRoot = new TreeItem<>(new AllBridgesNode(model.getBridges()));
bridgeRoot.setExpanded(true); bridgeRoot.setExpanded(true);
bridgeView.setRoot(bridgeRoot); bridgeView.setRoot(bridgeRoot);
buildBridgeTreeFromList(model.getBridges(), bridgeView.getRoot()); buildBridgeTreeFromList(model.getBridges(), bridgeView.getRoot());
addMoreButtonIfNecessary(model.getBridges(), bridgeView, bridgeRoot, bridgeChunkNr); addMoreButtonIfNecessary(model.getBridges(), bridgeView, bridgeRoot, bridgeChunkNr);
} }
private void buildTransportation(List<TransportationObject> trans) { private void buildTransportation(List<TransportationObject> trans) {
if (trans.isEmpty()) { if (trans.isEmpty()) {
return; return;
} }
TreeView<Renderable> transView = mainWindow.getTransportationView(); TreeView<Renderable> transView = mainWindow.getTransportationView();
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); buildTreeFromList(trans, transView.getRoot(), transportationChunkNr);
addMoreButtonIfNecessary(trans, transView, transRoot, transportationChunkNr); addMoreButtonIfNecessary(trans, transView, transRoot, transportationChunkNr);
} }
private void buildVegetation(List<Vegetation> veg) { private void buildVegetation(List<Vegetation> veg) {
if (veg.isEmpty()) { if (veg.isEmpty()) {
return; return;
} }
TreeView<Renderable> vegetationsView = mainWindow.getVegetationView(); TreeView<Renderable> vegetationsView = mainWindow.getVegetationView();
TreeItem<Renderable> vegRoot = new TreeItem<>(new AllVegetationNode(model.getVegetation())); TreeItem<Renderable> vegRoot = new TreeItem<>(new AllVegetationNode(model.getVegetation()));
vegRoot.setExpanded(true); vegRoot.setExpanded(true);
vegetationsView.setRoot(vegRoot); vegetationsView.setRoot(vegRoot);
buildTreeFromListWithProducer(veg, vegetationsView.getRoot(), vegetationChunkNr, VegetationNode::new); buildTreeFromListWithProducer(veg, vegetationsView.getRoot(), vegetationChunkNr, VegetationNode::new);
addMoreButtonIfNecessary(veg, vegetationsView, vegRoot, vegetationChunkNr); addMoreButtonIfNecessary(veg, vegetationsView, vegRoot, vegetationChunkNr);
} }
private void addMoreButtonIfNecessary(List<? extends CityObject> list, TreeView<Renderable> view, private void addMoreButtonIfNecessary(List<? extends CityObject> list, TreeView<Renderable> view,
TreeItem<Renderable> root, AtomicInteger chunkCounter) { TreeItem<Renderable> root, AtomicInteger chunkCounter) {
if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < list.size()) { if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < list.size()) {
Runnable run = new Runnable() { Runnable run = new Runnable() {
public void run() { public void run() {
// 29 is the height of one item // 29 is the height of one item
int numberOfDisplayedItems = (int) (view.getHeight() / 29); int numberOfDisplayedItems = (int) (view.getHeight() / 29);
int selectedIndex = view.getSelectionModel().getSelectedIndex(); int selectedIndex = view.getSelectionModel().getSelectedIndex();
// remove button node // remove button node
root.getChildren().remove(root.getChildren().size() - 1); root.getChildren().remove(root.getChildren().size() - 1);
chunkCounter.incrementAndGet(); chunkCounter.incrementAndGet();
int visibleFeatures = countVisibleNodes(view); int visibleFeatures = countVisibleNodes(view);
buildTreeFromList(list, root, chunkCounter); buildTreeFromList(list, root, chunkCounter);
updateTree(root); updateTree(root);
if (selectedIndex >= 0) { if (selectedIndex >= 0) {
view.getSelectionModel().select(selectedIndex); view.getSelectionModel().select(selectedIndex);
} }
if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < list.size()) { if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < list.size()) {
root.getChildren().add(new TreeItem<>(new ButtonRenderable(this))); root.getChildren().add(new TreeItem<>(new ButtonRenderable(this)));
} }
view.scrollTo(visibleFeatures - numberOfDisplayedItems + 1); view.scrollTo(visibleFeatures - numberOfDisplayedItems + 1);
} }
}; };
// add button for expansion // add button for expansion
root.getChildren().add(new TreeItem<>(new ButtonRenderable(run))); root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
} }
} }
private void buildBuildings(CityDoctorModel model) { private void buildBuildings(CityDoctorModel model) {
if (model.getBuildings().isEmpty()) { if (model.getBuildings().isEmpty()) {
return; return;
} }
TreeView<Renderable> buildingsView = mainWindow.getBuildingsView(); TreeView<Renderable> buildingsView = mainWindow.getBuildingsView();
TreeItem<Renderable> root = new TreeItem<>(new AllBuildingsNode(model.getBuildings())); TreeItem<Renderable> root = new TreeItem<>(new AllBuildingsNode(model.getBuildings()));
root.setExpanded(true); root.setExpanded(true);
buildBuildingTreeFromList(model.getBuildings(), root); buildBuildingTreeFromList(model.getBuildings(), root);
addMoreButtonToBuildingsIfNecessary(model.getBuildings(), buildingsView, root, buildingChunkNr); addMoreButtonToBuildingsIfNecessary(model.getBuildings(), buildingsView, root, buildingChunkNr);
buildingsView.setRoot(root); buildingsView.setRoot(root);
} }
private void addMoreButtonToBuildingsIfNecessary(List<Building> list, TreeView<Renderable> view, private void addMoreButtonToBuildingsIfNecessary(List<Building> list, TreeView<Renderable> view,
TreeItem<Renderable> root, AtomicInteger chunkCounter) { TreeItem<Renderable> root, AtomicInteger chunkCounter) {
if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < list.size()) { if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < list.size()) {
Runnable run = new Runnable() { Runnable run = new Runnable() {
public void run() { public void run() {
// 29 is the height of one item // 29 is the height of one item
int numberOfDisplayedItems = (int) (view.getHeight() / 29); int numberOfDisplayedItems = (int) (view.getHeight() / 29);
int selectedIndex = view.getSelectionModel().getSelectedIndex(); int selectedIndex = view.getSelectionModel().getSelectedIndex();
// remove button node // remove button node
root.getChildren().remove(root.getChildren().size() - 1); root.getChildren().remove(root.getChildren().size() - 1);
chunkCounter.getAndIncrement(); chunkCounter.getAndIncrement();
int visibleFeatures = countVisibleNodes(view); int visibleFeatures = countVisibleNodes(view);
buildBuildingTreeFromList(list, root); buildBuildingTreeFromList(list, root);
updateTree(root); updateTree(root);
if (selectedIndex >= 0) { if (selectedIndex >= 0) {
view.getSelectionModel().select(selectedIndex); view.getSelectionModel().select(selectedIndex);
} }
if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < list.size()) { if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < list.size()) {
root.getChildren().add(new TreeItem<>(new ButtonRenderable(this))); root.getChildren().add(new TreeItem<>(new ButtonRenderable(this)));
} }
view.scrollTo(visibleFeatures - numberOfDisplayedItems + 1); view.scrollTo(visibleFeatures - numberOfDisplayedItems + 1);
} }
}; };
// add button for expansion // add button for expansion
root.getChildren().add(new TreeItem<>(new ButtonRenderable(run))); root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
} }
} }
private static int countVisibleNodes(TreeView<Renderable> view) { private static int countVisibleNodes(TreeView<Renderable> view) {
return countVisibleNodes(view.getRoot()) + 1; return countVisibleNodes(view.getRoot()) + 1;
} }
private static int countVisibleNodes(TreeItem<Renderable> root) { private static int countVisibleNodes(TreeItem<Renderable> root) {
int visibleFeatures = root.getChildren().size(); int visibleFeatures = root.getChildren().size();
for (TreeItem<Renderable> child : root.getChildren()) { for (TreeItem<Renderable> child : root.getChildren()) {
if (!child.getChildren().isEmpty() && child.isExpanded()) { if (!child.getChildren().isEmpty() && child.isExpanded()) {
visibleFeatures += countVisibleNodes(child); visibleFeatures += countVisibleNodes(child);
} }
} }
return visibleFeatures; return visibleFeatures;
} }
private void buildTreeFromList(List<? extends CityObject> cos, TreeItem<Renderable> root, private void buildTreeFromList(List<? extends CityObject> cos, TreeItem<Renderable> root,
AtomicInteger chunkCounter) { AtomicInteger chunkCounter) {
int chunk = chunkCounter.get(); int chunk = chunkCounter.get();
for (int i = chunk * MAX_FEATURES_PER_CHUNK; i < (chunk + 1) * MAX_FEATURES_PER_CHUNK && i < cos.size(); i++) { for (int i = chunk * MAX_FEATURES_PER_CHUNK; i < (chunk + 1) * MAX_FEATURES_PER_CHUNK && i < cos.size(); i++) {
CityObject co = cos.get(i); CityObject co = cos.get(i);
CityObjectNode node = new CityObjectNode(co); CityObjectNode node = new CityObjectNode(co);
TreeItem<Renderable> nodeItem = new TreeItem<>(node); TreeItem<Renderable> nodeItem = new TreeItem<>(node);
nodeItem.setExpanded(true); nodeItem.setExpanded(true);
root.getChildren().add(nodeItem); root.getChildren().add(nodeItem);
createGeometryNodes(co, nodeItem); createGeometryNodes(co, nodeItem);
} }
} }
private <T extends CityObject> void buildTreeFromListWithProducer(List<T> cos, TreeItem<Renderable> root, private <T extends CityObject> void buildTreeFromListWithProducer(List<T> cos, TreeItem<Renderable> root,
AtomicInteger chunkCounter, Function<T, Renderable> nodeProducer) { AtomicInteger chunkCounter, Function<T, Renderable> nodeProducer) {
int chunk = chunkCounter.get(); int chunk = chunkCounter.get();
for (int i = chunk * MAX_FEATURES_PER_CHUNK; i < (chunk + 1) * MAX_FEATURES_PER_CHUNK && i < cos.size(); i++) { for (int i = chunk * MAX_FEATURES_PER_CHUNK; i < (chunk + 1) * MAX_FEATURES_PER_CHUNK && i < cos.size(); i++) {
T co = cos.get(i); T co = cos.get(i);
Renderable node = nodeProducer.apply(co); Renderable node = nodeProducer.apply(co);
TreeItem<Renderable> nodeItem = new TreeItem<>(node); TreeItem<Renderable> nodeItem = new TreeItem<>(node);
nodeItem.setExpanded(true); nodeItem.setExpanded(true);
root.getChildren().add(nodeItem); root.getChildren().add(nodeItem);
createGeometryNodes(co, nodeItem); createGeometryNodes(co, nodeItem);
} }
} }
private void clearTrees() { private void clearTrees() {
mainWindow.getBuildingsView().setRoot(null); mainWindow.getBuildingsView().setRoot(null);
mainWindow.getVegetationView().setRoot(null); mainWindow.getVegetationView().setRoot(null);
mainWindow.getTransportationView().setRoot(null); mainWindow.getTransportationView().setRoot(null);
mainWindow.getBridgeView().setRoot(null); mainWindow.getBridgeView().setRoot(null);
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.getOtherObjectsView().setRoot(null);
mainWindow.getErrorTree().getRoot().getChildren().clear(); mainWindow.getErrorTree().getRoot().getChildren().clear();
mainWindow.getGlobalErrorsView().getItems().clear(); mainWindow.getGlobalErrorsView().getItems().clear();
clearGeometryTrees(); clearGeometryTrees();
} }
private void clearGeometryTrees() { private void clearGeometryTrees() {
highlightController.clearHighlights(); highlightController.clearHighlights();
mainWindow.getPolygonsView().getRoot().getChildren().clear(); mainWindow.getPolygonsView().getRoot().getChildren().clear();
mainWindow.getEdgeView().getRoot().getChildren().clear(); mainWindow.getEdgeView().getRoot().getChildren().clear();
mainWindow.getVertexView().getRoot().getChildren().clear(); mainWindow.getVertexView().getRoot().getChildren().clear();
} }
private void buildBuildingTreeFromList(List<Building> list, TreeItem<Renderable> root) { private void buildBuildingTreeFromList(List<Building> list, TreeItem<Renderable> root) {
int buildingChunk = buildingChunkNr.get(); int buildingChunk = buildingChunkNr.get();
for (int i = buildingChunk * MAX_FEATURES_PER_CHUNK; i < (buildingChunk + 1) * MAX_FEATURES_PER_CHUNK for (int i = buildingChunk * MAX_FEATURES_PER_CHUNK; i < (buildingChunk + 1) * MAX_FEATURES_PER_CHUNK
&& i < list.size(); i++) { && i < list.size(); i++) {
Building b = list.get(i); Building b = list.get(i);
BuildingNode node = new BuildingNode(b); BuildingNode node = new BuildingNode(b);
TreeItem<Renderable> item = new TreeItem<>(node); TreeItem<Renderable> item = new TreeItem<>(node);
item.setExpanded(true); item.setExpanded(true);
root.getChildren().add(item); root.getChildren().add(item);
createGeometryNodes(b, item); createGeometryNodes(b, item);
createBoundarySurfaceNodes(b.getBoundarySurfaces(), item); createBoundarySurfaceNodes(b.getBoundarySurfaces(), item);
createBuildingInstallationNodes(b, item); createBuildingInstallationNodes(b, item);
createBuildingRoomNodes(b, item); createBuildingRoomNodes(b, item);
createBuildingFurnitureNodes(b, item); createBuildingFurnitureNodes(b, item);
createBuildingPartNodes(b, item); createBuildingPartNodes(b, item);
} }
} }
private void buildBridgeTreeFromList(List<BridgeObject> list, TreeItem<Renderable> root) { private void buildBridgeTreeFromList(List<BridgeObject> list, TreeItem<Renderable> root) {
int bridgeChunk = bridgeChunkNr.get(); int bridgeChunk = bridgeChunkNr.get();
for (int i = bridgeChunk * MAX_FEATURES_PER_CHUNK; i < (bridgeChunk + 1) * MAX_FEATURES_PER_CHUNK for (int i = bridgeChunk * MAX_FEATURES_PER_CHUNK; i < (bridgeChunk + 1) * MAX_FEATURES_PER_CHUNK
&& i < list.size(); i++) { && i < list.size(); i++) {
BridgeObject bridge = list.get(i); BridgeObject bridge = list.get(i);
BridgeNode node = new BridgeNode(bridge); BridgeNode node = new BridgeNode(bridge);
TreeItem<Renderable> item = new TreeItem<>(node); TreeItem<Renderable> item = new TreeItem<>(node);
item.setExpanded(true); item.setExpanded(true);
root.getChildren().add(item); root.getChildren().add(item);
createGeometryNodes(bridge, item); createGeometryNodes(bridge, item);
createBoundarySurfaceNodes(bridge.getBoundarySurfaces(), item); createBoundarySurfaceNodes(bridge.getBoundarySurfaces(), item);
createBridgeInstallationNodes(bridge, item); createBridgeInstallationNodes(bridge, item);
createConstructiveElementsNodes(bridge, item); createConstructiveElementsNodes(bridge, item);
createBridgePartNodes(bridge, item); createBridgePartNodes(bridge, item);
} }
} }
private void createBridgeInstallationNodes(BridgeObject bridge, TreeItem<Renderable> root) { private void createBridgeInstallationNodes(BridgeObject bridge, TreeItem<Renderable> root) {
createInstallationNodes(bridge.getBridgeInstallations(), root); createInstallationNodes(bridge.getBridgeInstallations(), root);
} }
private void createConstructiveElementsNodes(BridgeObject bridge, TreeItem<Renderable> item) { private void createConstructiveElementsNodes(BridgeObject bridge, TreeItem<Renderable> item) {
if (bridge.getConstructiveElements().isEmpty()) { if (bridge.getConstructiveElements().isEmpty()) {
return; return;
} }
AllBridgeConstructiveElementsNode allBceNode = new AllBridgeConstructiveElementsNode( AllBridgeConstructiveElementsNode allBceNode = new AllBridgeConstructiveElementsNode(
bridge.getConstructiveElements()); bridge.getConstructiveElements());
TreeItem<Renderable> allBceNodeTextItem = new TreeItem<>(allBceNode); TreeItem<Renderable> allBceNodeTextItem = new TreeItem<>(allBceNode);
item.getChildren().add(allBceNodeTextItem); item.getChildren().add(allBceNodeTextItem);
for (BridgeConstructiveElement bce : bridge.getConstructiveElements()) { for (BridgeConstructiveElement bce : bridge.getConstructiveElements()) {
BridgeConstructiveElementNode bceNode = new BridgeConstructiveElementNode(bce); BridgeConstructiveElementNode bceNode = new BridgeConstructiveElementNode(bce);
TreeItem<Renderable> bpNodeItem = new TreeItem<>(bceNode); TreeItem<Renderable> bpNodeItem = new TreeItem<>(bceNode);
bpNodeItem.setExpanded(true); bpNodeItem.setExpanded(true);
allBceNodeTextItem.getChildren().add(bpNodeItem); allBceNodeTextItem.getChildren().add(bpNodeItem);
createGeometryNodes(bce, bpNodeItem); createGeometryNodes(bce, bpNodeItem);
createBoundarySurfaceNodes(bce.getBoundarySurfaces(), bpNodeItem); createBoundarySurfaceNodes(bce.getBoundarySurfaces(), bpNodeItem);
} }
} }
private void createBridgePartNodes(BridgeObject bridge, TreeItem<Renderable> item) { private void createBridgePartNodes(BridgeObject bridge, TreeItem<Renderable> item) {
if (bridge.getParts().isEmpty()) { if (bridge.getParts().isEmpty()) {
return; return;
} }
AllBridgePartsNode allBpsText = new AllBridgePartsNode(bridge.getParts()); AllBridgePartsNode allBpsText = new AllBridgePartsNode(bridge.getParts());
TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allBpsText); TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allBpsText);
item.getChildren().add(allBpsTextItem); item.getChildren().add(allBpsTextItem);
for (BridgeObject bp : bridge.getParts()) { for (BridgeObject bp : bridge.getParts()) {
BridgeNode bpNode = new BridgeNode(bp); BridgeNode bpNode = new BridgeNode(bp);
TreeItem<Renderable> bpNodeItem = new TreeItem<>(bpNode); TreeItem<Renderable> bpNodeItem = new TreeItem<>(bpNode);
bpNodeItem.setExpanded(true); bpNodeItem.setExpanded(true);
allBpsTextItem.getChildren().add(bpNodeItem); allBpsTextItem.getChildren().add(bpNodeItem);
createGeometryNodes(bp, bpNodeItem); createGeometryNodes(bp, bpNodeItem);
createBoundarySurfaceNodes(bp.getBoundarySurfaces(), bpNodeItem); createBoundarySurfaceNodes(bp.getBoundarySurfaces(), bpNodeItem);
} }
} }
private void createBuildingInstallationNodes(Building ab, TreeItem<Renderable> root) { private void createBuildingInstallationNodes(Building ab, TreeItem<Renderable> root) {
createInstallationNodes(ab.getBuildingInstallations(), root); createInstallationNodes(ab.getBuildingInstallations(), root);
} }
private void createInstallationNodes(List<Installation> installations, TreeItem<Renderable> root) { private void createInstallationNodes(List<Installation> installations, TreeItem<Renderable> root) {
if (installations.isEmpty()) { if (installations.isEmpty()) {
return; return;
} }
AllInstallationsNode allBiNode = new AllInstallationsNode(installations); AllInstallationsNode allBiNode = new AllInstallationsNode(installations);
TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allBiNode); TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allBiNode);
root.getChildren().add(allBpsTextItem); root.getChildren().add(allBpsTextItem);
for (Installation bi : installations) { for (Installation bi : installations) {
InstallationNode biNode = new InstallationNode(bi); InstallationNode biNode = new InstallationNode(bi);
TreeItem<Renderable> biItem = new TreeItem<>(biNode); TreeItem<Renderable> biItem = new TreeItem<>(biNode);
biItem.setExpanded(true); biItem.setExpanded(true);
allBpsTextItem.getChildren().add(biItem); allBpsTextItem.getChildren().add(biItem);
createGeometryNodes(bi, biItem); createGeometryNodes(bi, biItem);
createBoundarySurfaceNodes(bi.getBoundarySurfaces(), biItem); createBoundarySurfaceNodes(bi.getBoundarySurfaces(), biItem);
} }
} }
private void createBuildingRoomNodes(Building ab, TreeItem<Renderable> root) { private void createBuildingRoomNodes(Building ab, TreeItem<Renderable> root) {
createRoomNodes(ab.getBuildingRooms(), root); createRoomNodes(ab.getBuildingRooms(), root);
} }
private void createRoomNodes(List<? extends AbstractRoom> rooms, TreeItem<Renderable> root) { private void createRoomNodes(List<? extends AbstractRoom> rooms, TreeItem<Renderable> root) {
if (rooms.isEmpty()) { if (rooms.isEmpty()) {
return; return;
} }
AllRoomsNode allRoNode = new AllRoomsNode(rooms); AllRoomsNode allRoNode = new AllRoomsNode(rooms);
TreeItem<Renderable> allRoNodeTextItem = new TreeItem<>(allRoNode); TreeItem<Renderable> allRoNodeTextItem = new TreeItem<>(allRoNode);
root.getChildren().add(allRoNodeTextItem); root.getChildren().add(allRoNodeTextItem);
for (AbstractRoom room : rooms) { for (AbstractRoom room : rooms) {
RoomNode roomNode = new RoomNode(room); RoomNode roomNode = new RoomNode(room);
TreeItem<Renderable> roomNodeTextItem = new TreeItem<>(roomNode); TreeItem<Renderable> roomNodeTextItem = new TreeItem<>(roomNode);
roomNodeTextItem.setExpanded(true); roomNodeTextItem.setExpanded(true);
allRoNodeTextItem.getChildren().add(roomNodeTextItem); allRoNodeTextItem.getChildren().add(roomNodeTextItem);
createGeometryNodes(room, roomNodeTextItem); createGeometryNodes(room, roomNodeTextItem);
createBoundarySurfaceNodes(room.getBoundarySurfaceList(), roomNodeTextItem); createBoundarySurfaceNodes(room.getBoundarySurfaceList(), roomNodeTextItem);
} }
} }
private void createBuildingFurnitureNodes(Building ab, TreeItem<Renderable> root) { private void createBuildingFurnitureNodes(Building ab, TreeItem<Renderable> root) {
createFurnitureNodes(ab.getBuildingRoomFurnitureList(),root); createFurnitureNodes(ab.getBuildingRoomFurnitureList(), root);
} }
private void createFurnitureNodes(List<? extends AbstractFurniture> furniture, TreeItem<Renderable> root){ private void createFurnitureNodes(List<? extends AbstractFurniture> furniture, TreeItem<Renderable> root) {
if(furniture.isEmpty()) { if (furniture.isEmpty()) {
return; return;
} }
AllFurnitureNode allFnNode = new AllFurnitureNode(furniture); AllFurnitureNode allFnNode = new AllFurnitureNode(furniture);
TreeItem<Renderable> allFnNodeTextItem = new TreeItem<>(allFnNode); TreeItem<Renderable> allFnNodeTextItem = new TreeItem<>(allFnNode);
root.getChildren().add(allFnNodeTextItem); root.getChildren().add(allFnNodeTextItem);
for (AbstractFurniture fn : furniture) { for (AbstractFurniture fn : furniture) {
FurnitureNode fnNode = new FurnitureNode(fn); FurnitureNode fnNode = new FurnitureNode(fn);
TreeItem<Renderable> fnNodeTextItem = new TreeItem<>(fnNode); TreeItem<Renderable> fnNodeTextItem = new TreeItem<>(fnNode);
fnNodeTextItem.setExpanded(true); fnNodeTextItem.setExpanded(true);
allFnNodeTextItem.getChildren().add(fnNodeTextItem); allFnNodeTextItem.getChildren().add(fnNodeTextItem);
createGeometryNodes(fn, fnNodeTextItem); createGeometryNodes(fn, fnNodeTextItem);
createBoundarySurfaceNodes(fn.getBoundarySurfaceList(), fnNodeTextItem); createBoundarySurfaceNodes(fn.getBoundarySurfaceList(), fnNodeTextItem);
} }
} }
private void createBoundarySurfaceNodes(List<BoundarySurface> bsList, TreeItem<Renderable> root) { private void createBoundarySurfaceNodes(List<BoundarySurface> bsList, TreeItem<Renderable> root) {
if (bsList.isEmpty()) { if (bsList.isEmpty()) {
return; return;
} }
AllBoundarySurfacesNode allBsText = new AllBoundarySurfacesNode(bsList); AllBoundarySurfacesNode allBsText = new AllBoundarySurfacesNode(bsList);
TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allBsText); TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allBsText);
root.getChildren().add(allBpsTextItem); root.getChildren().add(allBpsTextItem);
allBpsTextItem.getChildren().add(new TreeItem<>()); allBpsTextItem.getChildren().add(new TreeItem<>());
allBpsTextItem.expandedProperty().addListener((obs, old, newV) -> { allBpsTextItem.expandedProperty().addListener((obs, old, newV) -> {
if (Boolean.TRUE.equals(newV) && allBpsTextItem.getChildren().size() == 1) { if (Boolean.TRUE.equals(newV) && allBpsTextItem.getChildren().size() == 1) {
Platform.runLater(() -> { Platform.runLater(() -> {
allBpsTextItem.getChildren().clear(); allBpsTextItem.getChildren().clear();
for (BoundarySurface bs : bsList) { for (BoundarySurface bs : bsList) {
BoundarySurfaceNode bsText = new BoundarySurfaceNode(bs); BoundarySurfaceNode bsText = new BoundarySurfaceNode(bs);
TreeItem<Renderable> bsTextItem = new TreeItem<>(bsText); TreeItem<Renderable> bsTextItem = new TreeItem<>(bsText);
bsTextItem.setExpanded(true); bsTextItem.setExpanded(true);
allBpsTextItem.getChildren().add(bsTextItem); allBpsTextItem.getChildren().add(bsTextItem);
createGeometryNodes(bs, bsTextItem); createGeometryNodes(bs, bsTextItem);
createOpeningNodes(bs.getOpenings(), bsTextItem); createOpeningNodes(bs.getOpenings(), bsTextItem);
} }
updateTree(allBpsTextItem); updateTree(allBpsTextItem);
}); });
} }
}); });
} }
private void createOpeningNodes(List<Opening> openings, TreeItem<Renderable> root) { private void createOpeningNodes(List<Opening> openings, TreeItem<Renderable> root) {
if (openings == null || openings.isEmpty()) { if (openings == null || openings.isEmpty()) {
return; return;
} }
AllOpeningsNode allOpeningsNode = new AllOpeningsNode(openings); AllOpeningsNode allOpeningsNode = new AllOpeningsNode(openings);
TreeItem<Renderable> allOpeningsItem = new TreeItem<>(allOpeningsNode); TreeItem<Renderable> allOpeningsItem = new TreeItem<>(allOpeningsNode);
for (Opening o : openings) { for (Opening o : openings) {
OpeningNode openingNode = new OpeningNode(o); OpeningNode openingNode = new OpeningNode(o);
TreeItem<Renderable> openingsItem = new TreeItem<>(openingNode); TreeItem<Renderable> openingsItem = new TreeItem<>(openingNode);
allOpeningsItem.getChildren().add(openingsItem); allOpeningsItem.getChildren().add(openingsItem);
} }
root.getChildren().add(allOpeningsItem); root.getChildren().add(allOpeningsItem);
} }
private void createBuildingPartNodes(Building ab, TreeItem<Renderable> item) { private void createBuildingPartNodes(Building ab, TreeItem<Renderable> item) {
if (ab.getBuildingParts().isEmpty()) { if (ab.getBuildingParts().isEmpty()) {
return; return;
} }
AllBuildingPartsNode allBpsText = new AllBuildingPartsNode(ab.getBuildingParts()); AllBuildingPartsNode allBpsText = new AllBuildingPartsNode(ab.getBuildingParts());
TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allBpsText); TreeItem<Renderable> allBpsTextItem = new TreeItem<>(allBpsText);
item.getChildren().add(allBpsTextItem); item.getChildren().add(allBpsTextItem);
for (BuildingPart bp : ab.getBuildingParts()) { for (BuildingPart bp : ab.getBuildingParts()) {
BuildingPartNode bpNode = new BuildingPartNode(bp); BuildingPartNode bpNode = new BuildingPartNode(bp);
TreeItem<Renderable> bpNodeItem = new TreeItem<>(bpNode); TreeItem<Renderable> bpNodeItem = new TreeItem<>(bpNode);
bpNodeItem.setExpanded(true); bpNodeItem.setExpanded(true);
allBpsTextItem.getChildren().add(bpNodeItem); allBpsTextItem.getChildren().add(bpNodeItem);
createGeometryNodes(bp, bpNodeItem); createGeometryNodes(bp, bpNodeItem);
createBoundarySurfaceNodes(bp.getBoundarySurfaces(), bpNodeItem); createBoundarySurfaceNodes(bp.getBoundarySurfaces(), bpNodeItem);
} }
} }
private void createGeometryNodes(CityObject co, TreeItem<Renderable> item) { private void createGeometryNodes(CityObject co, TreeItem<Renderable> item) {
for (Geometry geom : co.getGeometries()) { for (Geometry geom : co.getGeometries()) {
GeometryNode geomNode = new GeometryNode(geom); GeometryNode geomNode = new GeometryNode(geom);
TreeItem<Renderable> geomItem = new TreeItem<>(geomNode); TreeItem<Renderable> geomItem = new TreeItem<>(geomNode);
item.getChildren().add(geomItem); item.getChildren().add(geomItem);
} }
} }
public void startChecks(ValidationConfiguration config, ProgressListener l) { public void startChecks(ValidationConfiguration config, ProgressListener l) {
if (model == null) { if (model == null) {
logger.warn(Localization.getText("CityDoctorController.noDatamodel")); logger.warn(Localization.getText("CityDoctorController.noDatamodel"));
return; return;
} }
if (sourceFile == null) { if (sourceFile == null) {
logger.warn(Localization.getText("CityDoctorController.noSourceFile")); logger.warn(Localization.getText("CityDoctorController.noSourceFile"));
return; return;
} }
try { try {
Platform.runLater(() -> { Platform.runLater(() -> {
mainWindow.getCheckButton().setDisable(true); mainWindow.getCheckButton().setDisable(true);
mainWindow.getErrorTree().getRoot().getChildren().clear(); mainWindow.getErrorTree().getRoot().getChildren().clear();
mainWindow.getGlobalErrorsView().getItems().clear(); mainWindow.getGlobalErrorsView().getItems().clear();
}); });
config.setNumberOfRoundingPlacesInGlobalParameters(currentConfig.getNumberOfRoundingPlaces()); config.setNumberOfRoundingPlacesInGlobalParameters(currentConfig.getNumberOfRoundingPlaces());
config.setParserConfig(currentConfig); config.setParserConfig(currentConfig);
currentChecker = new Checker(config, model); currentChecker = new Checker(config, model);
currentChecker.runChecks(l); currentChecker.runChecks(l);
Platform.runLater(() -> { Platform.runLater(() -> {
// apply check results to tree views // apply check results to tree views
updateFeatureTrees(); updateFeatureTrees();
updateTree(mainWindow.getPolygonsView().getRoot()); updateTree(mainWindow.getPolygonsView().getRoot());
for (CheckError e : model.getGlobalErrors()) { for (CheckError e : model.getGlobalErrors()) {
if (e instanceof SchematronError se) { if (e instanceof SchematronError se) {
mainWindow.getGlobalErrorsView().getItems().add(se.getErrorIdString()); mainWindow.getGlobalErrorsView().getItems().add(se.getErrorIdString());
} }
} }
renderer.refresh(); renderer.refresh();
mainWindow.getWriteReportButton().setDisable(false); mainWindow.getWriteReportButton().setDisable(false);
}); });
} finally { } finally {
Platform.runLater(() -> mainWindow.getCheckButton().setDisable(false)); Platform.runLater(() -> mainWindow.getCheckButton().setDisable(false));
} }
} }
void updateFeatureTrees() { void updateFeatureTrees() {
updateTree(mainWindow.getBuildingsView().getRoot()); updateTree(mainWindow.getBuildingsView().getRoot());
updateTree(mainWindow.getVegetationView().getRoot()); updateTree(mainWindow.getVegetationView().getRoot());
updateTree(mainWindow.getBridgeView().getRoot()); updateTree(mainWindow.getBridgeView().getRoot());
updateTree(mainWindow.getTerrainView().getRoot()); updateTree(mainWindow.getTerrainView().getRoot());
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.getOtherObjectsView().getRoot());
renderer.updateErrors(); renderer.updateErrors();
} }
private void updateTree(TreeItem<Renderable> root) { private void updateTree(TreeItem<Renderable> root) {
if (root == null) { if (root == null) {
return; return;
} }
for (TreeItem<Renderable> item : root.getChildren()) { for (TreeItem<Renderable> item : root.getChildren()) {
updateItem(item); updateItem(item);
} }
} }
private void updateItem(TreeItem<Renderable> item) { private void updateItem(TreeItem<Renderable> item) {
if (item.getValue() == null) { if (item.getValue() == null) {
return; return;
} }
item.getValue().refreshTextColor(); item.getValue().refreshTextColor();
for (TreeItem<Renderable> child : item.getChildren()) { for (TreeItem<Renderable> child : item.getChildren()) {
updateItem(child); updateItem(child);
} }
} }
public void writePdfReport(File pdfFile) { public void writePdfReport(File pdfFile) {
if (currentChecker == null) { if (currentChecker == null) {
return; return;
} }
currentChecker.writePdfReport(pdfFile.getAbsolutePath()); currentChecker.writePdfReport(pdfFile.getAbsolutePath());
} }
public void writeXmlReport(File xmlFile) { public void writeXmlReport(File xmlFile) {
if (currentChecker == null) { if (currentChecker == null) {
return; return;
} }
currentChecker.writeXmlReport(xmlFile.getAbsolutePath()); currentChecker.writeXmlReport(xmlFile.getAbsolutePath());
} }
private Map<ErrorId, ErrorStat> getErrorStats() { private Map<ErrorId, ErrorStat> getErrorStats() {
Map<ErrorId, ErrorStat> stats = new HashMap<>(); Map<ErrorId, ErrorStat> stats = new HashMap<>();
addErrorStats(stats, model.getBridges()); addErrorStats(stats, model.getBridges());
addErrorStats(stats, model.getBuildings()); addErrorStats(stats, model.getBuildings());
addErrorStats(stats, model.getLand()); addErrorStats(stats, model.getLand());
addErrorStats(stats, model.getTransportation()); addErrorStats(stats, model.getTransportation());
addErrorStats(stats, model.getVegetation()); addErrorStats(stats, model.getVegetation());
addErrorStats(stats, model.getWater()); addErrorStats(stats, model.getWater());
addErrorStats(stats, model.getCityFurniture()); addErrorStats(stats, model.getCityFurniture());
addErrorStats(stats, model.getGenericCityObjects()); addErrorStats(stats, model.getGenericCityObjects());
return stats; return stats;
} }
private void addErrorStats(Map<ErrorId, ErrorStat> stats, List<? extends CityObject> cos) { private void addErrorStats(Map<ErrorId, ErrorStat> stats, List<? extends CityObject> cos) {
List<CheckError> errors = new ArrayList<>(); List<CheckError> errors = new ArrayList<>();
for (CityObject co : cos) { for (CityObject co : cos) {
co.collectContainedErrors(errors); co.collectContainedErrors(errors);
} }
Set<CheckError> filteredErrors = new HashSet<>(errors); Set<CheckError> filteredErrors = new HashSet<>(errors);
for (CheckError error : filteredErrors) { for (CheckError error : filteredErrors) {
ErrorStat stat = stats.computeIfAbsent(error.getErrorId(), ErrorStat::new); ErrorStat stat = stats.computeIfAbsent(error.getErrorId(), ErrorStat::new);
stat.incrementCount(); stat.incrementCount();
} }
} }
public void export(Building b) { public void export(Building b) {
if (model == null) { if (model == null) {
return; return;
} }
CityDoctorModel newModel = new CityDoctorModel(model.getParserConfig(), model.getFile()); CityDoctorModel newModel = new CityDoctorModel(model.getParserConfig(), model.getFile());
newModel.setCityModel(new CityModel()); newModel.setCityModel(new CityModel());
newModel.addBuilding(b); newModel.addBuilding(b);
FileChooser fc = new FileChooser(); FileChooser fc = new FileChooser();
fc.getExtensionFilters().add(new ExtensionFilter("CityGML", "*.gml")); fc.getExtensionFilters().add(new ExtensionFilter("CityGML", "*.gml"));
fc.getExtensionFilters().add(new ExtensionFilter("OFF - Object File Format", "*.off")); fc.getExtensionFilters().add(new ExtensionFilter("OFF - Object File Format", "*.off"));
File dir = new File(Settings.get(Settings.LAST_OPEN_FOLDER, "")); File dir = new File(Settings.get(Settings.LAST_OPEN_FOLDER, ""));
if (dir.exists() && dir.isDirectory()) { if (dir.exists() && dir.isDirectory()) {
fc.setInitialDirectory(dir); fc.setInitialDirectory(dir);
} else { } else {
Settings.set(Settings.LAST_OPEN_FOLDER, ""); Settings.set(Settings.LAST_OPEN_FOLDER, "");
} }
File f = fc.showSaveDialog(mainWindow.getMainStage()); File f = fc.showSaveDialog(mainWindow.getMainStage());
if (f != null) { if (f != null) {
Settings.set(Settings.LAST_OPEN_FOLDER, f.getParent()); Settings.set(Settings.LAST_OPEN_FOLDER, f.getParent());
try { try {
newModel.saveAs(f.getAbsolutePath(), true); newModel.saveAs(f.getAbsolutePath(), true);
} catch (CityDoctorWriteException e) { } catch (CityDoctorWriteException e) {
logger.error(e); logger.error(e);
} }
} }
} }
public void showWorld() { public void showWorld() {
if (model != null) { if (model != null) {
renderer.render(model); renderer.render(model);
} }
} }
public void storeModel(File f, boolean saveQualityAde) throws CityDoctorWriteException { public void storeModel(File f, boolean saveQualityAde) throws CityDoctorWriteException {
if (model == null) { if (model == null) {
return; return;
} }
model.saveAs(f.getAbsolutePath(), saveQualityAde); model.saveAs(f.getAbsolutePath(), saveQualityAde);
} }
public void searchFeature(String searchString, FeatureType selectedTab) { public void searchFeature(String searchString, FeatureType selectedTab) {
if (model == null || searchString == null || searchString.trim().isEmpty()) { if (model == null || searchString == null || searchString.trim().isEmpty()) {
return; return;
} }
mainWindow.unselectEverything(); mainWindow.unselectEverything();
resetFeatureChunks(); resetFeatureChunks();
if (selectedTab == FeatureType.BUILDING) { if (selectedTab == FeatureType.BUILDING) {
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();
root.getChildren().clear(); root.getChildren().clear();
buildBuildingTreeFromList(foundBuildings, root); buildBuildingTreeFromList(foundBuildings, root);
updateTree(root); updateTree(root);
addMoreButtonToBuildingsIfNecessary(foundBuildings, buildingsView, root, buildingChunkNr); addMoreButtonToBuildingsIfNecessary(foundBuildings, buildingsView, root, buildingChunkNr);
} else { } else {
TreeView<Renderable> view; TreeView<Renderable> view;
List<? extends CityObject> cos; List<? extends CityObject> cos;
AtomicInteger chunkCounter; AtomicInteger chunkCounter;
switch (selectedTab) { switch (selectedTab) {
case VEGETATION: case VEGETATION:
view = mainWindow.getVegetationView(); view = mainWindow.getVegetationView();
cos = filterFeatures(searchString, model.getVegetation()); cos = filterFeatures(searchString, model.getVegetation());
chunkCounter = vegetationChunkNr; chunkCounter = vegetationChunkNr;
break; break;
case BRIDGE: case BRIDGE:
view = mainWindow.getBridgeView(); view = mainWindow.getBridgeView();
cos = filterFeatures(searchString, model.getBridges()); cos = filterFeatures(searchString, model.getBridges());
chunkCounter = bridgeChunkNr; chunkCounter = bridgeChunkNr;
break; break;
case TRANSPORTATION: case TRANSPORTATION:
view = mainWindow.getTransportationView(); view = mainWindow.getTransportationView();
cos = filterFeatures(searchString, model.getTransportation()); cos = filterFeatures(searchString, model.getTransportation());
chunkCounter = transportationChunkNr; chunkCounter = transportationChunkNr;
break; break;
case WATER: case WATER:
view = mainWindow.getWaterView(); view = mainWindow.getWaterView();
cos = filterFeatures(searchString, model.getWater()); cos = filterFeatures(searchString, model.getWater());
chunkCounter = waterChunkNr; chunkCounter = waterChunkNr;
break; break;
case LAND: case LAND:
view = mainWindow.getTerrainView(); view = mainWindow.getTerrainView();
cos = filterFeatures(searchString, model.getLand()); cos = filterFeatures(searchString, model.getLand());
chunkCounter = landChunkNr; chunkCounter = landChunkNr;
break; break;
case CITY_FURNITURE: case CITY_FURNITURE:
view = mainWindow.getCityFurnitureView(); view = mainWindow.getCityFurnitureView();
cos = filterFeatures(searchString, model.getCityFurniture()); cos = filterFeatures(searchString, model.getCityFurniture());
chunkCounter = cityFurnitureChunkNr; chunkCounter = cityFurnitureChunkNr;
break; break;
case GENERIC_CITY_OBJECT: case GENERIC_CITY_OBJECT:
view = mainWindow.getOtherObjectsView(); view = mainWindow.getOtherObjectsView();
cos = filterFeatures(searchString, model.getGenericCityObjects()); cos = filterFeatures(searchString, model.getGenericCityObjects());
chunkCounter = otherObjectsChunkNr; chunkCounter = otherObjectsChunkNr;
break; break;
default: default:
throw new IllegalStateException("Unknown selected feature tab"); throw new IllegalStateException("Unknown selected feature tab");
} }
TreeItem<Renderable> root = view.getRoot(); TreeItem<Renderable> root = view.getRoot();
root.getChildren().clear(); root.getChildren().clear();
buildTreeFromList(cos, root, chunkCounter); buildTreeFromList(cos, root, chunkCounter);
updateTree(root); updateTree(root);
addMoreButtonIfNecessary(cos, view, root, chunkCounter); addMoreButtonIfNecessary(cos, view, root, chunkCounter);
} }
} }
private <T extends CityObject> List<T> filterFeatures(String searchString, List<T> features) { private <T extends CityObject> List<T> filterFeatures(String searchString, List<T> features) {
List<T> foundFeatures = new ArrayList<>(); List<T> foundFeatures = new ArrayList<>();
for (T t : features) { for (T t : features) {
if (t.getGmlId().getGmlString().contains(searchString)) { if (t.getGmlId().getGmlString().contains(searchString)) {
foundFeatures.add(t); foundFeatures.add(t);
} }
} }
return foundFeatures; return foundFeatures;
} }
public void resetSearch(FeatureType selectedTab) { public void resetSearch(FeatureType selectedTab) {
if (model == null) { if (model == null) {
return; return;
} }
resetFeatureChunks(); resetFeatureChunks();
if (selectedTab == FeatureType.BUILDING) { if (selectedTab == FeatureType.BUILDING) {
// buildings are handled differently, because of surface and building // buildings are handled differently, because of surface and building
// installations // installations
TreeItem<Renderable> root = mainWindow.getBuildingsView().getRoot(); TreeItem<Renderable> root = mainWindow.getBuildingsView().getRoot();
if (root != null) { if (root != null) {
root.getChildren().clear(); root.getChildren().clear();
buildBuildingTreeFromList(model.getBuildings(), root); buildBuildingTreeFromList(model.getBuildings(), root);
updateTree(root); updateTree(root);
addMoreButtonToBuildingsIfNecessary(model.getBuildings(), mainWindow.getBuildingsView(), root, addMoreButtonToBuildingsIfNecessary(model.getBuildings(), mainWindow.getBuildingsView(), root,
buildingChunkNr); buildingChunkNr);
} }
} else { } else {
TreeView<Renderable> view; TreeView<Renderable> view;
List<? extends CityObject> cos; List<? extends CityObject> cos;
AtomicInteger chunkCounter; AtomicInteger chunkCounter;
switch (selectedTab) { switch (selectedTab) {
case VEGETATION: case VEGETATION:
view = mainWindow.getVegetationView(); view = mainWindow.getVegetationView();
cos = model.getVegetation(); cos = model.getVegetation();
chunkCounter = vegetationChunkNr; chunkCounter = vegetationChunkNr;
break; break;
case BRIDGE: case BRIDGE:
view = mainWindow.getBridgeView(); view = mainWindow.getBridgeView();
cos = model.getBridges(); cos = model.getBridges();
chunkCounter = bridgeChunkNr; chunkCounter = bridgeChunkNr;
break; break;
case TRANSPORTATION: case TRANSPORTATION:
view = mainWindow.getTransportationView(); view = mainWindow.getTransportationView();
cos = model.getTransportation(); cos = model.getTransportation();
chunkCounter = transportationChunkNr; chunkCounter = transportationChunkNr;
break; break;
case WATER: case WATER:
view = mainWindow.getWaterView(); view = mainWindow.getWaterView();
cos = model.getWater(); cos = model.getWater();
chunkCounter = waterChunkNr; chunkCounter = waterChunkNr;
break; break;
case LAND: case LAND:
view = mainWindow.getTerrainView(); view = mainWindow.getTerrainView();
cos = model.getLand(); cos = model.getLand();
chunkCounter = landChunkNr; chunkCounter = landChunkNr;
break; break;
case CITY_FURNITURE: case CITY_FURNITURE:
view = mainWindow.getCityFurnitureView(); view = mainWindow.getCityFurnitureView();
cos = model.getCityFurniture(); cos = model.getCityFurniture();
chunkCounter = cityFurnitureChunkNr; chunkCounter = cityFurnitureChunkNr;
break; break;
case GENERIC_CITY_OBJECT: case GENERIC_CITY_OBJECT:
view = mainWindow.getOtherObjectsView(); view = mainWindow.getOtherObjectsView();
cos = model.getGenericCityObjects(); cos = model.getGenericCityObjects();
chunkCounter = otherObjectsChunkNr; chunkCounter = otherObjectsChunkNr;
break; break;
default: default:
throw new IllegalStateException("Unknown selected feature tab"); throw new IllegalStateException("Unknown selected feature tab");
} }
TreeItem<Renderable> root = view.getRoot(); TreeItem<Renderable> root = view.getRoot();
root.getChildren().clear(); root.getChildren().clear();
buildTreeFromList(cos, root, chunkCounter); buildTreeFromList(cos, root, chunkCounter);
updateTree(root); updateTree(root);
addMoreButtonIfNecessary(cos, view, root, chunkCounter); addMoreButtonIfNecessary(cos, view, root, chunkCounter);
} }
} }
public Series<String, Number> createErrorSeries() { public Series<String, Number> createErrorSeries() {
Series<String, Number> series = new Series<>(); Series<String, Number> series = new Series<>();
if (model == null) { if (model == null) {
return series; return series;
} }
Map<ErrorId, ErrorStat> errorStats = getErrorStats(); Map<ErrorId, ErrorStat> errorStats = getErrorStats();
for (ErrorStat es : errorStats.values()) { for (ErrorStat es : errorStats.values()) {
series.getData().add(new Data<>(es.getErrorId().toString(), es.getCount())); series.getData().add(new Data<>(es.getErrorId().toString(), es.getCount()));
} }
return series; return series;
} }
public String getFileName() { public String getFileName() {
return model.getFileName(); return model.getFileName();
} }
public void fillTreeViewWithErrorBuildings() { public void fillTreeViewWithErrorBuildings() {
TreeView<Renderable> buildingsView = mainWindow.getBuildingsView(); TreeView<Renderable> buildingsView = mainWindow.getBuildingsView();
TreeItem<Renderable> root = buildingsView.getRoot(); TreeItem<Renderable> root = buildingsView.getRoot();
if (model == null) { if (model == null) {
return; return;
} }
if (root == null) { if (root == null) {
return; return;
} }
mainWindow.resetSearchBar(); mainWindow.resetSearchBar();
root.getChildren().clear(); root.getChildren().clear();
List<Building> errorBuildings = new ArrayList<>(); List<Building> errorBuildings = new ArrayList<>();
for (Building b : model.getBuildings()) { for (Building b : model.getBuildings()) {
if (b.containsAnyError()) { if (b.containsAnyError()) {
errorBuildings.add(b); errorBuildings.add(b);
} }
} }
resetFeatureChunks(); resetFeatureChunks();
buildBuildingTreeFromList(errorBuildings, root); buildBuildingTreeFromList(errorBuildings, root);
updateTree(root); updateTree(root);
addMoreButtonToBuildingsIfNecessary(errorBuildings, buildingsView, root, buildingChunkNr); addMoreButtonToBuildingsIfNecessary(errorBuildings, buildingsView, root, buildingChunkNr);
} }
public void fillTreeViewWithErrorVegetation() { public void fillTreeViewWithErrorVegetation() {
if (model == null) { if (model == null) {
return; return;
} }
fillTreeViewWithErrorCityObjects(mainWindow.getVegetationView(), model.getVegetation(), vegetationChunkNr); fillTreeViewWithErrorCityObjects(mainWindow.getVegetationView(), model.getVegetation(), vegetationChunkNr);
} }
public void fillTreeViewWithErrorBridges() { public void fillTreeViewWithErrorBridges() {
if (model == null) { if (model == null) {
return; return;
} }
fillTreeViewWithErrorCityObjects(mainWindow.getBridgeView(), model.getBridges(), bridgeChunkNr); fillTreeViewWithErrorCityObjects(mainWindow.getBridgeView(), model.getBridges(), bridgeChunkNr);
} }
public void fillTreeViewWithErrorLand() { public void fillTreeViewWithErrorLand() {
if (model == null) { if (model == null) {
return; return;
} }
fillTreeViewWithErrorCityObjects(mainWindow.getTerrainView(), model.getLand(), landChunkNr); fillTreeViewWithErrorCityObjects(mainWindow.getTerrainView(), model.getLand(), landChunkNr);
} }
public void fillTreeViewWithErrorCityFurniture(){ public void fillTreeViewWithErrorCityFurniture() {
if (model == null) { if (model == null) {
return; return;
} }
fillTreeViewWithErrorCityObjects(mainWindow.getCityFurnitureView(), fillTreeViewWithErrorCityObjects(mainWindow.getCityFurnitureView(),
model.getCityFurniture(), cityFurnitureChunkNr); model.getCityFurniture(), cityFurnitureChunkNr);
} }
public void fillTreeViewWithErrorOtherObjects(){ public void fillTreeViewWithErrorOtherObjects() {
if (model == null) { if (model == null) {
return; return;
} }
fillTreeViewWithErrorCityObjects(mainWindow.getOtherObjectsView(), fillTreeViewWithErrorCityObjects(mainWindow.getOtherObjectsView(),
model.getGenericCityObjects(), otherObjectsChunkNr); model.getGenericCityObjects(), otherObjectsChunkNr);
} }
public void fillTreeViewWithErrorTransportation() { public void fillTreeViewWithErrorTransportation() {
if (model == null) { if (model == null) {
return; return;
} }
fillTreeViewWithErrorCityObjects(mainWindow.getTransportationView(), model.getTransportation(), fillTreeViewWithErrorCityObjects(mainWindow.getTransportationView(), model.getTransportation(),
transportationChunkNr); transportationChunkNr);
} }
public void fillTreeViewWithErrorWater() { public void fillTreeViewWithErrorWater() {
if (model == null) { if (model == null) {
return; return;
} }
fillTreeViewWithErrorCityObjects(mainWindow.getWaterView(), model.getWater(), waterChunkNr); fillTreeViewWithErrorCityObjects(mainWindow.getWaterView(), model.getWater(), waterChunkNr);
} }
private void fillTreeViewWithErrorCityObjects(TreeView<Renderable> treeView, List<? extends CityObject> objects, private void fillTreeViewWithErrorCityObjects(TreeView<Renderable> treeView, List<? extends CityObject> objects,
AtomicInteger chunkCounter) { AtomicInteger chunkCounter) {
TreeItem<Renderable> root = treeView.getRoot(); TreeItem<Renderable> root = treeView.getRoot();
if (root == null) { if (root == null) {
return; return;
} }
mainWindow.resetSearchBar(); mainWindow.resetSearchBar();
root.getChildren().clear(); root.getChildren().clear();
List<CityObject> errorObjects = new ArrayList<>(); List<CityObject> errorObjects = new ArrayList<>();
for (CityObject co : objects) { for (CityObject co : objects) {
if (co.containsAnyError()) { if (co.containsAnyError()) {
errorObjects.add(co); errorObjects.add(co);
} }
} }
buildTreeFromList(errorObjects, root, chunkCounter); buildTreeFromList(errorObjects, root, chunkCounter);
updateTree(root); updateTree(root);
addMoreButtonIfNecessary(errorObjects, treeView, root, chunkCounter); addMoreButtonIfNecessary(errorObjects, treeView, root, chunkCounter);
} }
public void fillTreeViewFromFeatures(FeatureType selectedTab) { public void fillTreeViewFromFeatures(FeatureType selectedTab) {
if (model == null) { if (model == null) {
return; return;
} }
mainWindow.resetSearchBar(); mainWindow.resetSearchBar();
switch (selectedTab) { switch (selectedTab) {
case BUILDING: case BUILDING:
buildBuildings(model); buildBuildings(model);
updateTree(mainWindow.getBuildingsView().getRoot()); updateTree(mainWindow.getBuildingsView().getRoot());
break; break;
case VEGETATION: case VEGETATION:
buildVegetation(model.getVegetation()); buildVegetation(model.getVegetation());
updateTree(mainWindow.getVegetationView().getRoot()); updateTree(mainWindow.getVegetationView().getRoot());
break; break;
case BRIDGE: case BRIDGE:
buildBridges(model); buildBridges(model);
updateTree(mainWindow.getBridgeView().getRoot()); updateTree(mainWindow.getBridgeView().getRoot());
break; break;
case LAND: case LAND:
buildLand(model); buildLand(model);
updateTree(mainWindow.getTerrainView().getRoot()); updateTree(mainWindow.getTerrainView().getRoot());
break; break;
case TRANSPORTATION: case TRANSPORTATION:
buildTransportation(model.getTransportation()); buildTransportation(model.getTransportation());
updateTree(mainWindow.getTransportationView().getRoot()); updateTree(mainWindow.getTransportationView().getRoot());
break; break;
case WATER: case WATER:
buildWater(model); buildWater(model);
updateTree(mainWindow.getWaterView().getRoot()); updateTree(mainWindow.getWaterView().getRoot());
break; break;
case CITY_FURNITURE: case CITY_FURNITURE:
buildCityFurniture(model); buildCityFurniture(model);
updateTree(mainWindow.getCityFurnitureView().getRoot()); updateTree(mainWindow.getCityFurnitureView().getRoot());
break; break;
case GENERIC_CITY_OBJECT: case GENERIC_CITY_OBJECT:
buildOtherCityObjects(model); buildOtherCityObjects(model);
updateTree(mainWindow.getOtherObjectsView().getRoot()); updateTree(mainWindow.getOtherObjectsView().getRoot());
break; break;
default: default:
throw new IllegalStateException(); throw new IllegalStateException();
} }
} }
public CityDoctorModel getModel() { public CityDoctorModel getModel() {
return model; return model;
} }
public void showView(View v) { public void showView(View v) {
v.fireOnShowEvent(model, currentChecker, mainWindow); v.fireOnShowEvent(model, currentChecker, mainWindow);
} }
public void askAndSave() { public void askAndSave() {
boolean saveWithQualityAde = true; boolean saveWithQualityAde = true;
if (model.isValidated()) { if (model.isValidated()) {
ButtonType yesBtn = ButtonType.YES; ButtonType yesBtn = ButtonType.YES;
ButtonType noBtn = ButtonType.NO; ButtonType noBtn = ButtonType.NO;
Dialog<ButtonType> dialog = new Dialog<>(); Dialog<ButtonType> dialog = new Dialog<>();
dialog.setTitle("Save with QualityADE?"); dialog.setTitle("Save with QualityADE?");
dialog.setContentText("Save with QualityADE information?"); dialog.setContentText("Save with QualityADE information?");
dialog.getDialogPane().getButtonTypes().add(yesBtn); dialog.getDialogPane().getButtonTypes().add(yesBtn);
dialog.getDialogPane().getButtonTypes().add(noBtn); dialog.getDialogPane().getButtonTypes().add(noBtn);
Optional<ButtonType> result = dialog.showAndWait(); Optional<ButtonType> result = dialog.showAndWait();
if (result.isPresent() && result.get() == ButtonType.NO) { if (result.isPresent() && result.get() == ButtonType.NO) {
saveWithQualityAde = false; saveWithQualityAde = false;
} }
} }
FileChooser fc = new FileChooser(); FileChooser fc = new FileChooser();
fc.getExtensionFilters().add(new ExtensionFilter("CityGML", "*.gml")); fc.getExtensionFilters().add(new ExtensionFilter("CityGML", "*.gml"));
fc.getExtensionFilters().add(new ExtensionFilter("OFF - Object File Format", "*.off")); fc.getExtensionFilters().add(new ExtensionFilter("OFF - Object File Format", "*.off"));
File dir = new File(Settings.get(Settings.LAST_OPEN_FOLDER, "")); File dir = new File(Settings.get(Settings.LAST_OPEN_FOLDER, ""));
if (dir.exists() && dir.isDirectory()) { if (dir.exists() && dir.isDirectory()) {
fc.setInitialDirectory(dir); fc.setInitialDirectory(dir);
} else { } else {
Settings.set(Settings.LAST_OPEN_FOLDER, ""); Settings.set(Settings.LAST_OPEN_FOLDER, "");
} }
File f = fc.showSaveDialog(mainWindow.getMainStage()); File f = fc.showSaveDialog(mainWindow.getMainStage());
if (f != null) { if (f != null) {
Settings.set(Settings.LAST_OPEN_FOLDER, f.getParent()); Settings.set(Settings.LAST_OPEN_FOLDER, f.getParent());
try { try {
storeModel(f, saveWithQualityAde); storeModel(f, saveWithQualityAde);
} catch (CityDoctorWriteException e) { } catch (CityDoctorWriteException e) {
mainWindow.showExceptionDialog(e); mainWindow.showExceptionDialog(e);
} }
} }
} }
public void delete(TreeItem<Renderable> selectedItem) { public void delete(TreeItem<Renderable> selectedItem) {
if (model == null) { if (model == null) {
return; return;
} }
Renderable render = selectedItem.getValue(); Renderable render = selectedItem.getValue();
if (render instanceof BuildingNode node) { if (render instanceof BuildingNode node) {
model.getBuildings().remove(node.getBuilding()); model.getBuildings().remove(node.getBuilding());
mainWindow.getBuildingsView().getRoot().getChildren().remove(selectedItem); mainWindow.getBuildingsView().getRoot().getChildren().remove(selectedItem);
} }
} }
public void errorFilterIndexChanged(Number newV) { public void errorFilterIndexChanged(Number newV) {
mainWindow.getMeshGroup().getChildren().clear(); mainWindow.getMeshGroup().getChildren().clear();
mainWindow.unselectEverything(); mainWindow.unselectEverything();
if (newV.intValue() == 0) { if (newV.intValue() == 0) {
fillTreeViewFromFeatures(mainWindow.getSelectedTab()); fillTreeViewFromFeatures(mainWindow.getSelectedTab());
} else if (newV.intValue() == 1) { } else if (newV.intValue() == 1) {
switch (mainWindow.getSelectedTab()) { switch (mainWindow.getSelectedTab()) {
case BUILDING: case BUILDING:
fillTreeViewWithErrorBuildings(); fillTreeViewWithErrorBuildings();
break; break;
case VEGETATION: case VEGETATION:
fillTreeViewWithErrorVegetation(); fillTreeViewWithErrorVegetation();
break; break;
case BRIDGE: case BRIDGE:
fillTreeViewWithErrorBridges(); fillTreeViewWithErrorBridges();
break; break;
case LAND: case LAND:
fillTreeViewWithErrorLand(); fillTreeViewWithErrorLand();
break; break;
case TRANSPORTATION: case TRANSPORTATION:
fillTreeViewWithErrorTransportation(); fillTreeViewWithErrorTransportation();
break; break;
case WATER: case WATER:
fillTreeViewWithErrorWater(); fillTreeViewWithErrorWater();
break; break;
case CITY_FURNITURE: case CITY_FURNITURE:
fillTreeViewWithErrorCityFurniture(); fillTreeViewWithErrorCityFurniture();
break; break;
case GENERIC_CITY_OBJECT: case GENERIC_CITY_OBJECT:
fillTreeViewWithErrorOtherObjects(); fillTreeViewWithErrorOtherObjects();
break; break;
default: default:
throw new IllegalStateException("Unknown selected feature tab: " + mainWindow.getSelectedTab()); throw new IllegalStateException("Unknown selected feature tab: " + mainWindow.getSelectedTab());
} }
} else { } else {
throw new IllegalStateException("Unknown filter index selected: " + newV); throw new IllegalStateException("Unknown filter index selected: " + newV);
} }
} }
public ParserConfiguration getCurrentConfig() { public ParserConfiguration getCurrentConfig() {
return currentConfig; return currentConfig;
} }
} }
...@@ -80,937 +80,937 @@ import javafx.stage.Stage; ...@@ -80,937 +80,937 @@ import javafx.stage.Stage;
public class MainWindow extends Application { public class MainWindow extends Application {
private static final Logger logger = LogManager.getLogger(MainWindow.class); private static final Logger logger = LogManager.getLogger(MainWindow.class);
private static final double CAMERA_TRANSLATE_Z = -100.0; private static final double CAMERA_TRANSLATE_Z = -100.0;
private static final double CAMERA_INITIAL_X_ANGLE = 20.0; private static final double CAMERA_INITIAL_X_ANGLE = 20.0;
private static final double CAMERA_INITIAL_Y_ANGLE = 120.0; private static final double CAMERA_INITIAL_Y_ANGLE = 120.0;
@FXML @FXML
private TreeView<Renderable> buildingsView; private TreeView<Renderable> buildingsView;
@FXML @FXML
private TreeView<Renderable> vegetationView; private TreeView<Renderable> vegetationView;
@FXML @FXML
private TreeView<Renderable> transView; private TreeView<Renderable> transView;
@FXML @FXML
private TreeView<Renderable> bridgeView; private TreeView<Renderable> bridgeView;
@FXML @FXML
private TreeView<Renderable> waterView; private TreeView<Renderable> waterView;
@FXML @FXML
private TreeView<Renderable> terrainView; private TreeView<Renderable> terrainView;
@FXML @FXML
private TreeView<Renderable> cityFurnitureView; private TreeView<Renderable> cityFurnitureView;
@FXML @FXML
TreeView<Renderable> otherObjectsView; TreeView<Renderable> otherObjectsView;
@FXML @FXML
private TreeView<Renderable> polygonView; private TreeView<Renderable> polygonView;
@FXML @FXML
private TreeView<Renderable> edgeView; private TreeView<Renderable> edgeView;
@FXML @FXML
private TreeView<Renderable> vertexView; private TreeView<Renderable> vertexView;
@FXML @FXML
private Pane meshView; private Pane meshView;
@FXML @FXML
private SplitPane mainContainer; private SplitPane mainContainer;
@FXML @FXML
private TabPane detailsTabPane; private TabPane detailsTabPane;
@FXML @FXML
private TabPane featurePane; private TabPane featurePane;
@FXML @FXML
private TextField searchField; private TextField searchField;
@FXML @FXML
private TreeView<Renderable> errorView; private TreeView<Renderable> errorView;
@FXML @FXML
private Button clearBtn; private Button clearBtn;
@FXML @FXML
private Button searchBtn; private Button searchBtn;
@FXML @FXML
private ToggleButton allButton; private ToggleButton allButton;
@FXML @FXML
private ToggleButton errorButton; private ToggleButton errorButton;
@FXML @FXML
private ComboBox<String> showCityObjectsCombo; private ComboBox<String> showCityObjectsCombo;
@FXML @FXML
private HBox viewPane; private HBox viewPane;
@FXML @FXML
private ListView<String> globalErrorsView; private ListView<String> globalErrorsView;
@FXML @FXML
private BorderPane mainPane; private BorderPane mainPane;
@FXML @FXML
private HBox viewButtonBox; private HBox viewButtonBox;
@FXML @FXML
private ComboBox<Locale> languageSelector; private ComboBox<Locale> languageSelector;
@FXML @FXML
private Tab buildingsTab; private Tab buildingsTab;
@FXML @FXML
private Tab vegetationTab; private Tab vegetationTab;
@FXML @FXML
private Tab transportationTab; private Tab transportationTab;
@FXML @FXML
private Tab bridgeTab; private Tab bridgeTab;
@FXML @FXML
private Tab waterTab; private Tab waterTab;
@FXML @FXML
private Tab terrainTab; private Tab terrainTab;
@FXML @FXML
private Tab cityFurnitureTab; private Tab cityFurnitureTab;
@FXML @FXML
private Tab otherObjectsTab; private Tab otherObjectsTab;
@FXML @FXML
private Tab errorsTab; private Tab errorsTab;
@FXML @FXML
private Tab polygonsTab; private Tab polygonsTab;
@FXML @FXML
private Tab edgesTab; private Tab edgesTab;
@FXML @FXML
private Tab verticesTab; private Tab verticesTab;
@FXML @FXML
private Tab logTab; private Tab logTab;
@FXML @FXML
private Tab globalErrorsTab; private Tab globalErrorsTab;
@FXML @FXML
private Label viewLabel; private Label viewLabel;
@FXML @FXML
private Label showLabel; private Label showLabel;
@FXML @FXML
private Label searchLabel; private Label searchLabel;
@FXML @FXML
private Label memoryLabel; private Label memoryLabel;
@FXML @FXML
private ProgressBar memoryBar; private ProgressBar memoryBar;
@FXML @FXML
private Label memoryConsumptionLabel; private Label memoryConsumptionLabel;
@FXML @FXML
private Label availableLabel; private Label availableLabel;
private Group meshGroup; private Group meshGroup;
private Group world; private Group world;
private PerspectiveCamera camera; private PerspectiveCamera camera;
private Rotate cameraXRotation = new Rotate(); private Rotate cameraXRotation = new Rotate();
private Rotate cameraZRotation = new Rotate(); private Rotate cameraZRotation = new Rotate();
private double dragX; private double dragX;
private double dragY; private double dragY;
private double cameraXRot = CAMERA_INITIAL_X_ANGLE; private double cameraXRot = CAMERA_INITIAL_X_ANGLE;
private double cameraYRot = CAMERA_INITIAL_Y_ANGLE; private double cameraYRot = CAMERA_INITIAL_Y_ANGLE;
private double translateZ = CAMERA_TRANSLATE_Z; private double translateZ = CAMERA_TRANSLATE_Z;
private double[] clickStart = new double[2]; private double[] clickStart = new double[2];
@FXML @FXML
private TextArea logArea; private TextArea logArea;
@FXML @FXML
private ToolBar viewBar; private ToolBar viewBar;
private Stage stage; private Stage stage;
private ExceptionDialog exceptionDialog; private ExceptionDialog exceptionDialog;
private Renderer renderer; private Renderer renderer;
private CityDoctorController controller; private CityDoctorController controller;
private HighlightController highlightController; private HighlightController highlightController;
private FeatureType selectedTab = FeatureType.BUILDING; private FeatureType selectedTab = FeatureType.BUILDING;
private MainToolBar mainToolBar; private MainToolBar mainToolBar;
private SubScene geomScene; private SubScene geomScene;
private static boolean loadFileAtStartup = false; private static boolean loadFileAtStartup = false;
private static String inputFile; private static String inputFile;
private static String xmlOutput; private static String xmlOutput;
private static String pdfOutput; private static String pdfOutput;
private static ValidationConfiguration config; private static ValidationConfiguration config;
private VertexClickHandler clickHandler; private VertexClickHandler clickHandler;
private ChangeListener<Number> filterChangeListener; private ChangeListener<Number> filterChangeListener;
public static void main(String[] args) { public static void main(String[] args) {
setLocaleFromSettings(); setLocaleFromSettings();
ArgumentParser argParser = new ArgumentParser(args); ArgumentParser argParser = new ArgumentParser(args);
inputFile = CityDoctorValidation.getInputFile(argParser, true); inputFile = CityDoctorValidation.getInputFile(argParser, true);
if (inputFile != null) { if (inputFile != null) {
loadFileAtStartup = true; loadFileAtStartup = true;
xmlOutput = CityDoctorValidation.getXmlOutput(argParser); xmlOutput = CityDoctorValidation.getXmlOutput(argParser);
pdfOutput = CityDoctorValidation.getPdfOutput(argParser); pdfOutput = CityDoctorValidation.getPdfOutput(argParser);
try { try {
config = CityDoctorValidation.getValidationConfig(argParser, true); config = CityDoctorValidation.getValidationConfig(argParser, true);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Platform.runLater(() -> { Platform.runLater(() -> {
List<String> configFiles = argParser.getValues("config"); List<String> configFiles = argParser.getValues("config");
Alert alert = new Alert(AlertType.ERROR); Alert alert = new Alert(AlertType.ERROR);
alert.setContentText(Localization.getText("MainWindow.missingConfig") + configFiles); alert.setContentText(Localization.getText("MainWindow.missingConfig") + configFiles);
alert.showAndWait(); alert.showAndWait();
}); });
System.exit(4); System.exit(4);
} }
} }
Application.launch(args); Application.launch(args);
} }
private static void setLocaleFromSettings() { private static void setLocaleFromSettings() {
String localeString = Settings.get(Settings.LANGUAGE); String localeString = Settings.get(Settings.LANGUAGE);
if (localeString != null) { if (localeString != null) {
try { try {
Locale loc = new Locale(localeString); Locale loc = new Locale(localeString);
Locale.setDefault(loc); Locale.setDefault(loc);
} catch (Exception e) { } catch (Exception e) {
logger.warn("Could not set language to {}, using system language", localeString); logger.warn("Could not set language to {}, using system language", localeString);
} }
} }
} }
@Override @Override
public void start(Stage stage) throws IOException { public void start(Stage stage) throws IOException {
this.stage = stage; this.stage = stage;
stage.getIcons().add(new Image(MainWindow.class.getResourceAsStream("icons/citydoctor_logo.png"))); stage.getIcons().add(new Image(MainWindow.class.getResourceAsStream("icons/citydoctor_logo.png")));
FXMLLoader loader = new FXMLLoader(MainWindow.class.getResource("MainWindow.fxml")); FXMLLoader loader = new FXMLLoader(MainWindow.class.getResource("MainWindow.fxml"));
loader.setController(this); loader.setController(this);
BorderPane bp = loader.load(); BorderPane bp = loader.load();
highlightController = new HighlightController(world); highlightController = new HighlightController(world);
renderer = new Renderer(this, highlightController); renderer = new Renderer(this, highlightController);
clickHandler = new VertexClickHandler(errorView, renderer, stage); clickHandler = new VertexClickHandler(errorView, renderer, stage);
controller = new CityDoctorController(this, highlightController, renderer); controller = new CityDoctorController(this, highlightController, renderer);
mainToolBar = new MainToolBar(stage, controller, featurePane, renderer, this); mainToolBar = new MainToolBar(stage, controller, featurePane, renderer, this);
viewPane.getChildren().add(mainToolBar.getToolBar()); viewPane.getChildren().add(mainToolBar.getToolBar());
HBox.setHgrow(mainToolBar.getToolBar(), Priority.ALWAYS); HBox.setHgrow(mainToolBar.getToolBar(), Priority.ALWAYS);
ValidationView valView = new ValidationView(this, controller); ValidationView valView = new ValidationView(this, controller);
ViewRegistration.registerView(valView); ViewRegistration.registerView(valView);
setupViews(valView); setupViews(valView);
createLanguageSelector(); createLanguageSelector();
setLabelsInCorrectLanguage(); setLabelsInCorrectLanguage();
Scene scene = new Scene(bp, 1280, 800); Scene scene = new Scene(bp, 1280, 800);
createDropTarget(scene, valView); createDropTarget(scene, valView);
String version = Localization.getText(Localization.VERSION); String version = Localization.getText(Localization.VERSION);
stage.setTitle("CityDoctor " + version); stage.setTitle("CityDoctor " + version);
stage.setScene(scene); stage.setScene(scene);
stage.show(); stage.show();
checkForStartupLoading(); checkForStartupLoading();
memoryBar.setOnMouseClicked(me -> System.gc()); memoryBar.setOnMouseClicked(me -> System.gc());
Timer timer = new Timer(true); Timer timer = new Timer(true);
// check memory every second // check memory every second
TimerTask task = new TimerTask() { TimerTask task = new TimerTask() {
Runtime runtime = Runtime.getRuntime(); Runtime runtime = Runtime.getRuntime();
@Override @Override
public void run() { public void run() {
long totalMemory = runtime.totalMemory(); long totalMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory(); long freeMemory = runtime.freeMemory();
long usedMemory = totalMemory - freeMemory; long usedMemory = totalMemory - freeMemory;
double percentage = usedMemory / (double) totalMemory; double percentage = usedMemory / (double) totalMemory;
if (totalMemory / 1024 / 1024 >= 1024) { if (totalMemory / 1024 / 1024 >= 1024) {
// gb // gb
double totalMemoryGb = totalMemory / (1024d * 1024d * 1024d); double totalMemoryGb = totalMemory / (1024d * 1024d * 1024d);
double usedMemoryGb = usedMemory / (1024d * 1024d * 1024d); double usedMemoryGb = usedMemory / (1024d * 1024d * 1024d);
String memoryString = String.format("%.1f GB / %.1f GB", usedMemoryGb, totalMemoryGb); String memoryString = String.format("%.1f GB / %.1f GB", usedMemoryGb, totalMemoryGb);
Platform.runLater(() -> { Platform.runLater(() -> {
memoryConsumptionLabel.setText(memoryString); memoryConsumptionLabel.setText(memoryString);
memoryBar.setProgress(percentage); memoryBar.setProgress(percentage);
}); });
} else if (totalMemory / 1024 >= 1024) { } else if (totalMemory / 1024 >= 1024) {
// mb // mb
double totalMemoryMb = totalMemory / (1024d * 1024d); double totalMemoryMb = totalMemory / (1024d * 1024d);
double usedMemoryMb = usedMemory / (1024d * 1024d); double usedMemoryMb = usedMemory / (1024d * 1024d);
String memoryString = String.format("%.1f MB / %.1f MB", usedMemoryMb, totalMemoryMb); String memoryString = String.format("%.1f MB / %.1f MB", usedMemoryMb, totalMemoryMb);
Platform.runLater(() -> { Platform.runLater(() -> {
memoryConsumptionLabel.setText(memoryString); memoryConsumptionLabel.setText(memoryString);
memoryBar.setProgress(percentage); memoryBar.setProgress(percentage);
}); });
} }
} }
}; };
timer.schedule(task, 0, 1000); timer.schedule(task, 0, 1000);
} }
private void createDropTarget(Scene scene, ValidationView valView) { private void createDropTarget(Scene scene, ValidationView valView) {
setDragOverInteraction(scene, valView); setDragOverInteraction(scene, valView);
scene.setOnDragDropped(event -> { scene.setOnDragDropped(event -> {
if (ViewRegistration.getCurrentActiveView() != valView) { if (ViewRegistration.getCurrentActiveView() != valView) {
return; return;
} }
Dragboard db = event.getDragboard(); Dragboard db = event.getDragboard();
boolean success = false; boolean success = false;
if (db.hasFiles() && db.getFiles().size() == 1) { if (db.hasFiles() && db.getFiles().size() == 1) {
File f = db.getFiles().get(0); File f = db.getFiles().get(0);
Thread t = new Thread(() -> { Thread t = new Thread(() -> {
try { try {
controller.loadCityGml(f.getAbsolutePath(), 8, (ProgressListener) null, false); controller.loadCityGml(f.getAbsolutePath(), 8, (ProgressListener) null, false);
} catch (Exception e) { } catch (Exception e) {
if (logger.isErrorEnabled()) { if (logger.isErrorEnabled()) {
logger.error(Localization.getText("OpenFileDialog.loadFailed"), e); logger.error(Localization.getText("OpenFileDialog.loadFailed"), e);
} }
Platform.runLater(() -> { Platform.runLater(() -> {
ExceptionDialog exDialog = new ExceptionDialog(); ExceptionDialog exDialog = new ExceptionDialog();
exDialog.show(e); exDialog.show(e);
}); });
} }
}); });
t.start(); t.start();
success = true; success = true;
} }
// let the source know whether the string was successfully transferred and used // let the source know whether the string was successfully transferred and used
event.setDropCompleted(success); event.setDropCompleted(success);
event.consume(); event.consume();
}); });
} }
private void setDragOverInteraction(Scene scene, ValidationView valView) { private void setDragOverInteraction(Scene scene, ValidationView valView) {
scene.setOnDragOver(event -> { scene.setOnDragOver(event -> {
if (ViewRegistration.getCurrentActiveView() != valView) { if (ViewRegistration.getCurrentActiveView() != valView) {
return; return;
} }
if (event.getGestureSource() != scene && event.getDragboard().hasFiles() if (event.getGestureSource() != scene && event.getDragboard().hasFiles()
&& event.getDragboard().getFiles().size() == 1) { && event.getDragboard().getFiles().size() == 1) {
// allow for both copying and moving, whatever user chooses // allow for both copying and moving, whatever user chooses
event.acceptTransferModes(TransferMode.LINK); event.acceptTransferModes(TransferMode.LINK);
} }
event.consume(); event.consume();
}); });
} }
private void setLabelsInCorrectLanguage() { private void setLabelsInCorrectLanguage() {
buildingsTab.setText(Localization.getText("MainWindow.buildingsTab")); buildingsTab.setText(Localization.getText("MainWindow.buildingsTab"));
vegetationTab.setText(Localization.getText("MainWindow.vegetationTab")); vegetationTab.setText(Localization.getText("MainWindow.vegetationTab"));
transportationTab.setText(Localization.getText("MainWindow.transportationTab")); transportationTab.setText(Localization.getText("MainWindow.transportationTab"));
bridgeTab.setText(Localization.getText("MainWindow.bridgeTab")); bridgeTab.setText(Localization.getText("MainWindow.bridgeTab"));
waterTab.setText(Localization.getText("MainWindow.waterTab")); waterTab.setText(Localization.getText("MainWindow.waterTab"));
terrainTab.setText(Localization.getText("MainWindow.terrainTab")); terrainTab.setText(Localization.getText("MainWindow.terrainTab"));
cityFurnitureTab.setText(Localization.getText("MainWindow.cityfurnitureTab")); cityFurnitureTab.setText(Localization.getText("MainWindow.cityfurnitureTab"));
otherObjectsTab.setText(Localization.getText("MainWindow.otherObjectsTab")); otherObjectsTab.setText(Localization.getText("MainWindow.otherObjectsTab"));
viewLabel.setText(Localization.getText("MainWindow.viewLabel")); viewLabel.setText(Localization.getText("MainWindow.viewLabel"));
showLabel.setText(Localization.getText("MainWindow.showLabel")); showLabel.setText(Localization.getText("MainWindow.showLabel"));
searchLabel.setText(Localization.getText("MainWindow.searchLabel")); searchLabel.setText(Localization.getText("MainWindow.searchLabel"));
searchBtn.setText(Localization.getText("MainWindow.searchBtn")); searchBtn.setText(Localization.getText("MainWindow.searchBtn"));
clearBtn.setText(Localization.getText("MainWindow.clearBtn")); clearBtn.setText(Localization.getText("MainWindow.clearBtn"));
errorsTab.setText(Localization.getText("MainWindow.errorsTab")); errorsTab.setText(Localization.getText("MainWindow.errorsTab"));
polygonsTab.setText(Localization.getText("MainWindow.polygonsTab")); polygonsTab.setText(Localization.getText("MainWindow.polygonsTab"));
edgesTab.setText(Localization.getText("MainWindow.edgesTab")); edgesTab.setText(Localization.getText("MainWindow.edgesTab"));
verticesTab.setText(Localization.getText("MainWindow.verticesTab")); verticesTab.setText(Localization.getText("MainWindow.verticesTab"));
logTab.setText(Localization.getText("MainWindow.logTab")); logTab.setText(Localization.getText("MainWindow.logTab"));
globalErrorsTab.setText(Localization.getText("MainWindow.globalErrorsTab")); globalErrorsTab.setText(Localization.getText("MainWindow.globalErrorsTab"));
memoryLabel.setText(Localization.getText("MainWindow.memoryLabel")); memoryLabel.setText(Localization.getText("MainWindow.memoryLabel"));
availableLabel.setText(String.format("%s %.1f GB", Localization.getText("MainWindow.availableLabel"), availableLabel.setText(String.format("%s %.1f GB", Localization.getText("MainWindow.availableLabel"),
Runtime.getRuntime().maxMemory() / 1024d / 1024d / 1024d)); Runtime.getRuntime().maxMemory() / 1024d / 1024d / 1024d));
} }
private void createLanguageSelector() { private void createLanguageSelector() {
languageSelector.setButtonCell(new LanguageSelectorCell()); languageSelector.setButtonCell(new LanguageSelectorCell());
languageSelector.setCellFactory(view -> new LanguageSelectorCell()); languageSelector.setCellFactory(view -> new LanguageSelectorCell());
languageSelector.getItems().add(Locale.GERMAN); languageSelector.getItems().add(Locale.GERMAN);
languageSelector.getItems().add(Locale.ENGLISH); languageSelector.getItems().add(Locale.ENGLISH);
if (Locale.getDefault().getLanguage().equals(Locale.GERMAN.getLanguage())) { if (Locale.getDefault().getLanguage().equals(Locale.GERMAN.getLanguage())) {
languageSelector.getSelectionModel().select(Locale.GERMAN); languageSelector.getSelectionModel().select(Locale.GERMAN);
} else if (Locale.getDefault().getLanguage().equals(Locale.ENGLISH.getLanguage())) { } else if (Locale.getDefault().getLanguage().equals(Locale.ENGLISH.getLanguage())) {
languageSelector.getSelectionModel().select(Locale.ENGLISH); languageSelector.getSelectionModel().select(Locale.ENGLISH);
} else { } else {
languageSelector.getSelectionModel().select(Locale.ENGLISH); languageSelector.getSelectionModel().select(Locale.ENGLISH);
Settings.set(Settings.LANGUAGE, Locale.ENGLISH.getLanguage()); Settings.set(Settings.LANGUAGE, Locale.ENGLISH.getLanguage());
} }
languageSelector.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> { languageSelector.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> {
Alert alert = new Alert(AlertType.CONFIRMATION, Localization.getText("MainWindow.languageChange"), Alert alert = new Alert(AlertType.CONFIRMATION, Localization.getText("MainWindow.languageChange"),
ButtonType.OK); ButtonType.OK);
alert.showAndWait(); alert.showAndWait();
Settings.set(Settings.LANGUAGE, newV.getLanguage()); Settings.set(Settings.LANGUAGE, newV.getLanguage());
}); });
} }
private void checkForStartupLoading() { private void checkForStartupLoading() {
if (loadFileAtStartup) { if (loadFileAtStartup) {
logger.info(Localization.getText("MainWindow.loadGivenFile")); logger.info(Localization.getText("MainWindow.loadGivenFile"));
Thread t = new Thread(() -> { Thread t = new Thread(() -> {
try { try {
// wait a bit for the gui to show // wait a bit for the gui to show
Thread.sleep(500); Thread.sleep(500);
} catch (InterruptedException e) { } catch (InterruptedException e) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
try { try {
controller.loadCityGml(inputFile, config.getNumberOfRoundingPlaces(), null, controller.loadCityGml(inputFile, config.getNumberOfRoundingPlaces(), null,
config.isXmlValidation()); config.isXmlValidation());
logger.info(Localization.getText("MainWindow.finishedLoading")); logger.info(Localization.getText("MainWindow.finishedLoading"));
logger.info(Localization.getText("MainWindow.checking")); logger.info(Localization.getText("MainWindow.checking"));
controller.startChecks(config, null); controller.startChecks(config, null);
if (xmlOutput != null) { if (xmlOutput != null) {
logger.info(Localization.getText("MainWindow.writeXml")); logger.info(Localization.getText("MainWindow.writeXml"));
controller.writeXmlReport(new File(xmlOutput)); controller.writeXmlReport(new File(xmlOutput));
logger.info(Localization.getText("MainWindow.finishedXml")); logger.info(Localization.getText("MainWindow.finishedXml"));
} }
if (pdfOutput != null) { if (pdfOutput != null) {
logger.info(Localization.getText("MainWindow.writePdf")); logger.info(Localization.getText("MainWindow.writePdf"));
controller.writePdfReport(new File(pdfOutput)); controller.writePdfReport(new File(pdfOutput));
logger.info(Localization.getText("MainWindow.finishedPdf")); logger.info(Localization.getText("MainWindow.finishedPdf"));
} }
} catch (CityGmlParseException | InvalidGmlFileException e) { } catch (CityGmlParseException | InvalidGmlFileException e) {
logger.error(Localization.getText("MainWindow.loadFailed"), e.getMessage()); logger.error(Localization.getText("MainWindow.loadFailed"), e.getMessage());
} }
}); });
t.start(); t.start();
} }
} }
private void setupViews(ValidationView valView) { private void setupViews(ValidationView valView) {
ToggleGroup group = new ToggleGroup(); ToggleGroup group = new ToggleGroup();
for (View v : ViewRegistration.getRegisteredViews()) { for (View v : ViewRegistration.getRegisteredViews()) {
RadioButton radioButton = new RadioButton(); RadioButton radioButton = new RadioButton();
radioButton.getStyleClass().remove("radio-button"); radioButton.getStyleClass().remove("radio-button");
radioButton.getStyleClass().add("toggle-button"); radioButton.getStyleClass().add("toggle-button");
ImageView view = new ImageView(v.getViewLogo()); ImageView view = new ImageView(v.getViewLogo());
view.setFitHeight(32); view.setFitHeight(32);
view.setFitWidth(32); view.setFitWidth(32);
radioButton.setGraphic(view); radioButton.setGraphic(view);
group.getToggles().add(radioButton); group.getToggles().add(radioButton);
if (v == valView) { if (v == valView) {
ViewRegistration.setCurrentActiveView(valView); ViewRegistration.setCurrentActiveView(valView);
group.selectToggle(radioButton); group.selectToggle(radioButton);
} }
viewButtonBox.getChildren().add(radioButton); viewButtonBox.getChildren().add(radioButton);
radioButton.selectedProperty().addListener((obs, oldV, newV) -> { radioButton.selectedProperty().addListener((obs, oldV, newV) -> {
if (Boolean.TRUE.equals(newV)) { if (Boolean.TRUE.equals(newV)) {
showView(v); showView(v);
ViewRegistration.setCurrentActiveView(v); ViewRegistration.setCurrentActiveView(v);
} else { } else {
v.onHide(); v.onHide();
} }
}); });
} }
} }
private void showView(View v) { private void showView(View v) {
viewPane.getChildren().clear(); viewPane.getChildren().clear();
controller.showView(v); controller.showView(v);
Optional<HBox> toolbar = v.getToolbar(); Optional<HBox> toolbar = v.getToolbar();
if (toolbar.isPresent()) { if (toolbar.isPresent()) {
viewPane.getChildren().add(toolbar.get()); viewPane.getChildren().add(toolbar.get());
HBox.setHgrow(toolbar.get(), Priority.ALWAYS); HBox.setHgrow(toolbar.get(), Priority.ALWAYS);
} else { } else {
HBox placeHolderToolbar = new HBox(); HBox placeHolderToolbar = new HBox();
placeHolderToolbar.setMaxHeight(Double.MAX_VALUE); placeHolderToolbar.setMaxHeight(Double.MAX_VALUE);
viewPane.getChildren().add(placeHolderToolbar); viewPane.getChildren().add(placeHolderToolbar);
HBox.setHgrow(placeHolderToolbar, Priority.ALWAYS); HBox.setHgrow(placeHolderToolbar, Priority.ALWAYS);
} }
mainPane.setCenter(v.getMainScreen()); mainPane.setCenter(v.getMainScreen());
} }
public void initialize() { public void initialize() {
GuiLogger.setTextArea(logArea); GuiLogger.setTextArea(logArea);
loadFrameConfig(); loadFrameConfig();
setup3dView(); setup3dView();
setupTrees(); setupTrees();
setupSearchField(); setupSearchField();
setupSearchButtons(); setupSearchButtons();
setupShowCityComboBox(); setupShowCityComboBox();
detailsTabPane.getSelectionModel().selectedIndexProperty() detailsTabPane.getSelectionModel().selectedIndexProperty()
.addListener((ov, oldI, newI) -> Platform.runLater(() -> { .addListener((ov, oldI, newI) -> Platform.runLater(() -> {
if (newI.intValue() == 0 && errorView.getSelectionModel().getSelectedItem() != null) { if (newI.intValue() == 0 && errorView.getSelectionModel().getSelectedItem() != null) {
// the first tab is selected, meaning the error tab // the first tab is selected, meaning the error tab
// redisplay the selected error // redisplay the selected error
errorView.getSelectionModel().getSelectedItem().getValue().visit(renderer); errorView.getSelectionModel().getSelectedItem().getValue().visit(renderer);
} }
})); }));
} }
private void setupShowCityComboBox() { private void setupShowCityComboBox() {
showCityObjectsCombo.getItems().addAll(Localization.getText("MainWindow.all"), showCityObjectsCombo.getItems().addAll(Localization.getText("MainWindow.all"),
Localization.getText("MainWindow.withErrors")); Localization.getText("MainWindow.withErrors"));
showCityObjectsCombo.getSelectionModel().selectFirst(); showCityObjectsCombo.getSelectionModel().selectFirst();
showCityObjectsCombo.setCellFactory(param -> new ListCell<>() { showCityObjectsCombo.setCellFactory(param -> new ListCell<>() {
@Override @Override
public void updateItem(String item, boolean empty) { public void updateItem(String item, boolean empty) {
super.updateItem(item, empty); super.updateItem(item, empty);
if (item != null) { if (item != null) {
setText(item); setText(item);
if (item.contentEquals(Localization.getText("MainWindow.withErrors"))) { if (item.contentEquals(Localization.getText("MainWindow.withErrors"))) {
setTextFill(Color.RED); setTextFill(Color.RED);
} }
} else { } else {
setText(null); setText(null);
} }
} }
}); });
filterChangeListener = setupFilterSelectionListener(); filterChangeListener = setupFilterSelectionListener();
showCityObjectsCombo.getSelectionModel().selectedIndexProperty().addListener(filterChangeListener); showCityObjectsCombo.getSelectionModel().selectedIndexProperty().addListener(filterChangeListener);
} }
public void resetFilterComboBox() { public void resetFilterComboBox() {
showCityObjectsCombo.getSelectionModel().selectedIndexProperty().removeListener(filterChangeListener); showCityObjectsCombo.getSelectionModel().selectedIndexProperty().removeListener(filterChangeListener);
showCityObjectsCombo.getSelectionModel().selectFirst(); showCityObjectsCombo.getSelectionModel().selectFirst();
showCityObjectsCombo.getSelectionModel().selectedIndexProperty().addListener(filterChangeListener); showCityObjectsCombo.getSelectionModel().selectedIndexProperty().addListener(filterChangeListener);
} }
private ChangeListener<Number> setupFilterSelectionListener() { private ChangeListener<Number> setupFilterSelectionListener() {
return (obs, oldV, newV) -> controller.errorFilterIndexChanged(newV); return (obs, oldV, newV) -> controller.errorFilterIndexChanged(newV);
} }
private void setupSearchButtons() { private void setupSearchButtons() {
searchBtn.setOnAction(ae -> controller.searchFeature(searchField.getText(), selectedTab)); searchBtn.setOnAction(ae -> controller.searchFeature(searchField.getText(), selectedTab));
clearBtn.setOnAction(ae -> { clearBtn.setOnAction(ae -> {
if (searchField.getText().isEmpty()) { if (searchField.getText().isEmpty()) {
// do not reset search if nothing has bee searched // do not reset search if nothing has bee searched
return; return;
} }
controller.resetSearch(selectedTab); controller.resetSearch(selectedTab);
searchField.setText(""); searchField.setText("");
}); });
} }
private void setupSearchField() { private void setupSearchField() {
searchField.textProperty().addListener((obs, oldV, newV) -> { searchField.textProperty().addListener((obs, oldV, newV) -> {
if (newV.isEmpty()) { if (newV.isEmpty()) {
controller.resetSearch(selectedTab); controller.resetSearch(selectedTab);
} }
}); });
featurePane.getSelectionModel().selectedIndexProperty().addListener((obs, oldV, newV) -> { featurePane.getSelectionModel().selectedIndexProperty().addListener((obs, oldV, newV) -> {
if (!searchField.getText().isEmpty()) { if (!searchField.getText().isEmpty()) {
resetSearchBar(); resetSearchBar();
controller.resetSearch(selectedTab); controller.resetSearch(selectedTab);
} }
int index = newV.intValue(); int index = newV.intValue();
switch (index) { switch (index) {
case 0: case 0:
selectedTab = FeatureType.BUILDING; selectedTab = FeatureType.BUILDING;
break; break;
case 1: case 1:
selectedTab = FeatureType.VEGETATION; selectedTab = FeatureType.VEGETATION;
break; break;
case 2: case 2:
selectedTab = FeatureType.TRANSPORTATION; selectedTab = FeatureType.TRANSPORTATION;
break; break;
case 3: case 3:
selectedTab = FeatureType.BRIDGE; selectedTab = FeatureType.BRIDGE;
break; break;
case 4: case 4:
selectedTab = FeatureType.WATER; selectedTab = FeatureType.WATER;
break; break;
case 5: case 5:
selectedTab = FeatureType.LAND; selectedTab = FeatureType.LAND;
break; break;
case 6: case 6:
selectedTab = FeatureType.CITY_FURNITURE; selectedTab = FeatureType.CITY_FURNITURE;
break; break;
case 7: case 7:
selectedTab = FeatureType.GENERIC_CITY_OBJECT; selectedTab = FeatureType.GENERIC_CITY_OBJECT;
break; break;
default: default:
throw new IllegalStateException("Unknown tab index: " + index); throw new IllegalStateException("Unknown tab index: " + index);
} }
}); });
} }
public void resetSearchBar() { public void resetSearchBar() {
searchField.setText(""); searchField.setText("");
} }
private void loadFrameConfig() { private void loadFrameConfig() {
stage.setMaximized(Boolean.valueOf(Settings.get(Settings.MAXIMIZED, Boolean.FALSE.toString()))); stage.setMaximized(Boolean.valueOf(Settings.get(Settings.MAXIMIZED, Boolean.FALSE.toString())));
stage.maximizedProperty() stage.maximizedProperty()
.addListener((obs, oldV, newV) -> Settings.set(Settings.MAXIMIZED, Boolean.toString(newV))); .addListener((obs, oldV, newV) -> Settings.set(Settings.MAXIMIZED, Boolean.toString(newV)));
String widthString = Settings.get(Settings.FRAME_WIDTH); String widthString = Settings.get(Settings.FRAME_WIDTH);
if (widthString != null) { if (widthString != null) {
stage.setWidth(Double.parseDouble(widthString)); stage.setWidth(Double.parseDouble(widthString));
} }
stage.widthProperty().addListener( stage.widthProperty().addListener(
(obs, oldV, newV) -> Settings.set(Settings.FRAME_WIDTH, Double.toString(newV.doubleValue()))); (obs, oldV, newV) -> Settings.set(Settings.FRAME_WIDTH, Double.toString(newV.doubleValue())));
String heightString = Settings.get(Settings.FRAME_HEIGHT); String heightString = Settings.get(Settings.FRAME_HEIGHT);
if (heightString != null) { if (heightString != null) {
stage.setHeight(Double.parseDouble(heightString)); stage.setHeight(Double.parseDouble(heightString));
} }
stage.heightProperty().addListener( stage.heightProperty().addListener(
(obs, oldV, newV) -> Settings.set(Settings.FRAME_HEIGHT, Double.toString(newV.doubleValue()))); (obs, oldV, newV) -> Settings.set(Settings.FRAME_HEIGHT, Double.toString(newV.doubleValue())));
} }
public void showExceptionDialog(Throwable e) { public void showExceptionDialog(Throwable e) {
if (exceptionDialog == null) { if (exceptionDialog == null) {
exceptionDialog = new ExceptionDialog(); exceptionDialog = new ExceptionDialog();
} }
exceptionDialog.show(e); exceptionDialog.show(e);
} }
private void setupTrees() { private void setupTrees() {
setupSelectListener(errorView); setupSelectListener(errorView);
errorView.setRoot(new TreeItem<>()); errorView.setRoot(new TreeItem<>());
errorView.setCellFactory(param -> new RenderableTreeCell()); errorView.setCellFactory(param -> new RenderableTreeCell());
buildingsView.setShowRoot(true); buildingsView.setShowRoot(true);
setupSelectListener(buildingsView); setupSelectListener(buildingsView);
buildingsView.setCellFactory(param -> new RenderableTreeCell()); buildingsView.setCellFactory(param -> new RenderableTreeCell());
ContextMenu cMenu = new ContextMenu(); ContextMenu cMenu = new ContextMenu();
MenuItem mi = new MenuItem(Localization.getText("MainWindow.export")); MenuItem mi = new MenuItem(Localization.getText("MainWindow.export"));
mi.setOnAction(ea -> { mi.setOnAction(ea -> {
Renderable render = buildingsView.getSelectionModel().getSelectedItem().getValue(); Renderable render = buildingsView.getSelectionModel().getSelectedItem().getValue();
if (render instanceof BuildingNode node) { if (render instanceof BuildingNode node) {
controller.export(node.getBuilding()); controller.export(node.getBuilding());
} }
}); });
cMenu.getItems().add(mi); cMenu.getItems().add(mi);
MenuItem deleteMi = new MenuItem("Delete"); MenuItem deleteMi = new MenuItem("Delete");
deleteMi.setOnAction(ae -> controller.delete(buildingsView.getSelectionModel().getSelectedItem())); deleteMi.setOnAction(ae -> controller.delete(buildingsView.getSelectionModel().getSelectedItem()));
cMenu.getItems().add(deleteMi); cMenu.getItems().add(deleteMi);
buildingsView.setContextMenu(cMenu); buildingsView.setContextMenu(cMenu);
vegetationView.setShowRoot(true); vegetationView.setShowRoot(true);
setupSelectListener(vegetationView); setupSelectListener(vegetationView);
vegetationView.setCellFactory(param -> new RenderableTreeCell()); vegetationView.setCellFactory(param -> new RenderableTreeCell());
transView.setShowRoot(true); transView.setShowRoot(true);
setupSelectListener(transView); setupSelectListener(transView);
transView.setCellFactory(param -> new RenderableTreeCell()); transView.setCellFactory(param -> new RenderableTreeCell());
bridgeView.setShowRoot(true); bridgeView.setShowRoot(true);
setupSelectListener(bridgeView); setupSelectListener(bridgeView);
bridgeView.setCellFactory(param -> new RenderableTreeCell()); bridgeView.setCellFactory(param -> new RenderableTreeCell());
waterView.setShowRoot(true); waterView.setShowRoot(true);
setupSelectListener(waterView); setupSelectListener(waterView);
waterView.setCellFactory(param -> new RenderableTreeCell()); waterView.setCellFactory(param -> new RenderableTreeCell());
terrainView.setShowRoot(true); terrainView.setShowRoot(true);
setupSelectListener(terrainView); setupSelectListener(terrainView);
terrainView.setCellFactory(param -> new RenderableTreeCell()); terrainView.setCellFactory(param -> new RenderableTreeCell());
cityFurnitureView.setShowRoot(true); cityFurnitureView.setShowRoot(true);
setupSelectListener(cityFurnitureView); setupSelectListener(cityFurnitureView);
cityFurnitureView.setCellFactory(param -> new RenderableTreeCell()); cityFurnitureView.setCellFactory(param -> new RenderableTreeCell());
otherObjectsView.setShowRoot(true); otherObjectsView.setShowRoot(true);
setupSelectListener(otherObjectsView); setupSelectListener(otherObjectsView);
otherObjectsView.setCellFactory(param -> new RenderableTreeCell()); otherObjectsView.setCellFactory(param -> new RenderableTreeCell());
setupSelectListener(vertexView); setupSelectListener(vertexView);
vertexView.setRoot(new TreeItem<>()); vertexView.setRoot(new TreeItem<>());
vertexView.setCellFactory(param -> new RenderableTreeCell()); vertexView.setCellFactory(param -> new RenderableTreeCell());
setupSelectListener(polygonView); setupSelectListener(polygonView);
polygonView.setRoot(new TreeItem<>()); polygonView.setRoot(new TreeItem<>());
polygonView.setCellFactory(param -> new RenderableTreeCell()); polygonView.setCellFactory(param -> new RenderableTreeCell());
setupSelectListener(edgeView); setupSelectListener(edgeView);
edgeView.setRoot(new TreeItem<>()); edgeView.setRoot(new TreeItem<>());
edgeView.setCellFactory(param -> new RenderableTreeCell()); edgeView.setCellFactory(param -> new RenderableTreeCell());
} }
private void setupSelectListener(TreeView<Renderable> view) { private void setupSelectListener(TreeView<Renderable> view) {
view.getSelectionModel().selectedItemProperty().addListener((obs, oldI, newI) -> { view.getSelectionModel().selectedItemProperty().addListener((obs, oldI, newI) -> {
if (newI != null) { if (newI != null) {
newI.getValue().visit(renderer); newI.getValue().visit(renderer);
} }
}); });
} }
private void setup3dView() { private void setup3dView() {
Group root = new Group(); Group root = new Group();
geomScene = new SubScene(root, 500, 300, true, SceneAntialiasing.BALANCED); geomScene = new SubScene(root, 500, 300, true, SceneAntialiasing.BALANCED);
geomScene.heightProperty().bind(meshView.heightProperty()); geomScene.heightProperty().bind(meshView.heightProperty());
geomScene.widthProperty().bind(meshView.widthProperty()); geomScene.widthProperty().bind(meshView.widthProperty());
geomScene.setFill(Color.AZURE); geomScene.setFill(Color.AZURE);
meshView.getChildren().add(geomScene); meshView.getChildren().add(geomScene);
geomScene.addEventFilter(MouseEvent.MOUSE_PRESSED, me -> { geomScene.addEventFilter(MouseEvent.MOUSE_PRESSED, me -> {
clickStart[0] = me.getScreenX(); clickStart[0] = me.getScreenX();
clickStart[1] = me.getScreenY(); clickStart[1] = me.getScreenY();
}); });
geomScene.addEventFilter(MouseEvent.MOUSE_RELEASED, me -> { geomScene.addEventFilter(MouseEvent.MOUSE_RELEASED, me -> {
if (Math.abs(clickStart[0] - me.getScreenX()) > 3 || Math.abs(clickStart[1] - me.getScreenY()) > 3) { if (Math.abs(clickStart[0] - me.getScreenX()) > 3 || Math.abs(clickStart[1] - me.getScreenY()) > 3) {
// skip when mouse moved too much // skip when mouse moved too much
return; return;
} }
Node node = me.getPickResult().getIntersectedNode(); Node node = me.getPickResult().getIntersectedNode();
if (node != null) { if (node != null) {
Object o = node.getUserData(); Object o = node.getUserData();
if (o instanceof ClickDispatcher cd) { if (o instanceof ClickDispatcher cd) {
cd.click(me, clickHandler); cd.click(me, clickHandler);
} }
} }
}); });
world = new Group(); world = new Group();
root.getChildren().add(world); root.getChildren().add(world);
meshGroup = new Group(); meshGroup = new Group();
world.getChildren().add(meshGroup); world.getChildren().add(meshGroup);
AmbientLight al = new AmbientLight(Color.WHITE); AmbientLight al = new AmbientLight(Color.WHITE);
root.getChildren().add(al); root.getChildren().add(al);
buildCamera(); buildCamera();
cameraXRotation.setAxis(Rotate.X_AXIS); cameraXRotation.setAxis(Rotate.X_AXIS);
cameraZRotation.setAxis(Rotate.Z_AXIS); cameraZRotation.setAxis(Rotate.Z_AXIS);
world.getTransforms().add(cameraXRotation); world.getTransforms().add(cameraXRotation);
world.getTransforms().add(cameraZRotation); world.getTransforms().add(cameraZRotation);
root.getChildren().add(camera); root.getChildren().add(camera);
geomScene.setCamera(camera); geomScene.setCamera(camera);
setupMeshViewControls(); setupMeshViewControls();
} }
private void setupMeshViewControls() { private void setupMeshViewControls() {
meshView.setOnMousePressed(me -> { meshView.setOnMousePressed(me -> {
if (me.getButton() == MouseButton.PRIMARY) { if (me.getButton() == MouseButton.PRIMARY) {
dragX = me.getScreenX(); dragX = me.getScreenX();
dragY = me.getScreenY(); dragY = me.getScreenY();
} }
}); });
meshView.setOnScroll(se -> { meshView.setOnScroll(se -> {
if (se.getDeltaY() < 0) { if (se.getDeltaY() < 0) {
translateZ += translateZ * 0.05; translateZ += translateZ * 0.05;
} else { } else {
translateZ -= translateZ * 0.05; translateZ -= translateZ * 0.05;
} }
camera.setTranslateZ(translateZ); camera.setTranslateZ(translateZ);
highlightController.changeScaling(translateZ); highlightController.changeScaling(translateZ);
}); });
meshView.setOnMouseDragged(me -> { meshView.setOnMouseDragged(me -> {
if (me.getButton() == MouseButton.PRIMARY) { if (me.getButton() == MouseButton.PRIMARY) {
double deltaX = me.getScreenX() - dragX; double deltaX = me.getScreenX() - dragX;
double deltaY = me.getScreenY() - dragY; double deltaY = me.getScreenY() - dragY;
dragX = me.getScreenX(); dragX = me.getScreenX();
dragY = me.getScreenY(); dragY = me.getScreenY();
cameraXRot += (deltaX / 3d) % 360; cameraXRot += (deltaX / 3d) % 360;
cameraYRot += (deltaY / 3d) % 360; cameraYRot += (deltaY / 3d) % 360;
cameraZRotation.setAngle(cameraXRot); cameraZRotation.setAngle(cameraXRot);
cameraXRotation.setAngle(cameraYRot); cameraXRotation.setAngle(cameraYRot);
} }
}); });
} }
private void buildCamera() { private void buildCamera() {
camera = new PerspectiveCamera(true); camera = new PerspectiveCamera(true);
camera.setNearClip(0.1); camera.setNearClip(0.1);
camera.setFarClip(10000d); camera.setFarClip(10000d);
camera.setTranslateZ(translateZ); camera.setTranslateZ(translateZ);
cameraZRotation.setAngle(cameraXRot); cameraZRotation.setAngle(cameraXRot);
cameraXRotation.setAngle(cameraYRot); cameraXRotation.setAngle(cameraYRot);
} }
public void addFileNameToTitle(String fileName) { public void addFileNameToTitle(String fileName) {
String version = Localization.getText(Localization.VERSION); String version = Localization.getText(Localization.VERSION);
stage.setTitle("CityDoctor " + version + " - " + fileName); stage.setTitle("CityDoctor " + version + " - " + fileName);
} }
public TreeView<Renderable> getBuildingsView() { public TreeView<Renderable> getBuildingsView() {
return buildingsView; return buildingsView;
} }
public TreeView<Renderable> getVegetationView() { public TreeView<Renderable> getVegetationView() {
return vegetationView; return vegetationView;
} }
public TreeView<Renderable> getTransportationView() { public TreeView<Renderable> getTransportationView() {
return transView; return transView;
} }
public TreeView<Renderable> getBridgeView() { public TreeView<Renderable> getBridgeView() {
return bridgeView; return bridgeView;
} }
public TreeView<Renderable> getWaterView() { public TreeView<Renderable> getWaterView() {
return waterView; return waterView;
} }
public TreeView<Renderable> getTerrainView() { public TreeView<Renderable> getTerrainView() {
return terrainView; return terrainView;
} }
public TreeView<Renderable> getCityFurnitureView() { public TreeView<Renderable> getCityFurnitureView() {
return cityFurnitureView; return cityFurnitureView;
} }
public TreeView<Renderable> getOtherObjectsView(){ public TreeView<Renderable> getOtherObjectsView() {
return otherObjectsView; return otherObjectsView;
} }
public TreeView<Renderable> getPolygonsView() { public TreeView<Renderable> getPolygonsView() {
return polygonView; return polygonView;
} }
public TreeView<Renderable> getEdgeView() { public TreeView<Renderable> getEdgeView() {
return edgeView; return edgeView;
} }
public TreeView<Renderable> getVertexView() { public TreeView<Renderable> getVertexView() {
return vertexView; return vertexView;
} }
public Button getCheckButton() { public Button getCheckButton() {
return mainToolBar.getCheckButton(); return mainToolBar.getCheckButton();
} }
public ToggleButton getGridButton() { public ToggleButton getGridButton() {
return mainToolBar.getGridButton(); return mainToolBar.getGridButton();
} }
public Group getMeshGroup() { public Group getMeshGroup() {
return meshGroup; return meshGroup;
} }
public ToggleButton getCullingButton() { public ToggleButton getCullingButton() {
return mainToolBar.getCullingButton(); return mainToolBar.getCullingButton();
} }
public Button getWriteReportButton() { public Button getWriteReportButton() {
return mainToolBar.getWriteReportButton(); return mainToolBar.getWriteReportButton();
} }
public TreeView<Renderable> getErrorTree() { public TreeView<Renderable> getErrorTree() {
return errorView; return errorView;
} }
public Stage getMainStage() { public Stage getMainStage() {
return stage; return stage;
} }
public void unselectEverything() { public void unselectEverything() {
buildingsView.getSelectionModel().clearSelection(); buildingsView.getSelectionModel().clearSelection();
vegetationView.getSelectionModel().clearSelection(); vegetationView.getSelectionModel().clearSelection();
transView.getSelectionModel().clearSelection(); transView.getSelectionModel().clearSelection();
waterView.getSelectionModel().clearSelection(); waterView.getSelectionModel().clearSelection();
terrainView.getSelectionModel().clearSelection(); terrainView.getSelectionModel().clearSelection();
cityFurnitureView.getSelectionModel().clearSelection(); cityFurnitureView.getSelectionModel().clearSelection();
otherObjectsView.getSelectionModel().clearSelection(); otherObjectsView.getSelectionModel().clearSelection();
bridgeView.getSelectionModel().clearSelection(); bridgeView.getSelectionModel().clearSelection();
polygonView.getSelectionModel().clearSelection(); polygonView.getSelectionModel().clearSelection();
edgeView.getSelectionModel().clearSelection(); edgeView.getSelectionModel().clearSelection();
vertexView.getSelectionModel().clearSelection(); vertexView.getSelectionModel().clearSelection();
errorView.getSelectionModel().clearSelection(); errorView.getSelectionModel().clearSelection();
} }
public ToggleButton getLod1Btn() { public ToggleButton getLod1Btn() {
return mainToolBar.getLod1Btn(); return mainToolBar.getLod1Btn();
} }
public ToggleButton getLod2Btn() { public ToggleButton getLod2Btn() {
return mainToolBar.getLod2Btn(); return mainToolBar.getLod2Btn();
} }
public ToggleButton getLod3Btn() { public ToggleButton getLod3Btn() {
return mainToolBar.getLod3Btn(); return mainToolBar.getLod3Btn();
} }
public ToggleButton getLod4Btn() { public ToggleButton getLod4Btn() {
return mainToolBar.getLod4Btn(); return mainToolBar.getLod4Btn();
} }
public Button getWorldBtn() { public Button getWorldBtn() {
return mainToolBar.getWorldBtn(); return mainToolBar.getWorldBtn();
} }
public Button getSaveBtn() { public Button getSaveBtn() {
return mainToolBar.getSaveBtn(); return mainToolBar.getSaveBtn();
} }
public SplitPane getMainContainer() { public SplitPane getMainContainer() {
return mainContainer; return mainContainer;
} }
public ListView<String> getGlobalErrorsView() { public ListView<String> getGlobalErrorsView() {
return globalErrorsView; return globalErrorsView;
} }
public void takeViewScreenshot() throws IOException { public void takeViewScreenshot() throws IOException {
WritableImage snapshot = geomScene.snapshot(null, null); WritableImage snapshot = geomScene.snapshot(null, null);
File outputFile = new File("img.png"); File outputFile = new File("img.png");
BufferedImage bImage = SwingFXUtils.fromFXImage(snapshot, null); BufferedImage bImage = SwingFXUtils.fromFXImage(snapshot, null);
ImageIO.write(bImage, "png", outputFile); ImageIO.write(bImage, "png", outputFile);
} }
public void zoomOutForBoundingBox(BoundingBox b) { public void zoomOutForBoundingBox(BoundingBox b) {
double longestSide = b.getDiagonalLength() * 0.4; double longestSide = b.getDiagonalLength() * 0.4;
double d = longestSide / Math.tan(Math.toRadians(30) / 2); double d = longestSide / Math.tan(Math.toRadians(30) / 2);
translateZ = -d; translateZ = -d;
camera.setTranslateZ(translateZ); camera.setTranslateZ(translateZ);
highlightController.changeScaling(-translateZ); highlightController.changeScaling(-translateZ);
} }
public MainToolBar getMainToolbar() { public MainToolBar getMainToolbar() {
return mainToolBar; return mainToolBar;
} }
public void clearHighlights() { public void clearHighlights() {
highlightController.clearHighlights(); highlightController.clearHighlights();
} }
public CityDoctorController getController() { public CityDoctorController getController() {
return controller; return controller;
} }
public Button getOpenBtn() { public Button getOpenBtn() {
return mainToolBar.getOpenBtn(); return mainToolBar.getOpenBtn();
} }
public VertexClickHandler getClickHandler() { public VertexClickHandler getClickHandler() {
return clickHandler; return clickHandler;
} }
public FeatureType getSelectedTab() { public FeatureType getSelectedTab() {
return selectedTab; return selectedTab;
} }
} }
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