Commit 0f3d9a85 authored by Riegel's avatar Riegel
Browse files

Merge branch 'dev' into 'master'

CityDoctor Release Version 3.16.0

See merge request !11
parents b7b8f5fe b2d40f78
Pipeline #10323 passed with stage
in 1 minute and 25 seconds
...@@ -122,6 +122,9 @@ public class CityGmlParser { ...@@ -122,6 +122,9 @@ public class CityGmlParser {
private static CityGMLContext context; private static CityGMLContext context;
private static List<QName> chunkProperties = new ArrayList<>(); private static List<QName> chunkProperties = new ArrayList<>();
// Toggle to suppress logger output for parsing of libraryObjects
private static boolean gagged = false;
static { static {
System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
FACTORY = SAXParserFactory.newInstance(); FACTORY = SAXParserFactory.newInstance();
...@@ -326,20 +329,29 @@ public class CityGmlParser { ...@@ -326,20 +329,29 @@ public class CityGmlParser {
return writer; return writer;
} }
/**
* Suppresses logger output of {@link #readAndKeepFeatures} for the next parse.
* Used to prevent logging spam while resolving implicit geometries.
*/
public static void gagLogger(boolean value){
gagged = value;
}
private static CityDoctorModel readAndKeepFeatures(ParserConfiguration config, Path file, private static CityDoctorModel readAndKeepFeatures(ParserConfiguration config, Path file,
CityGMLInputFactory inputFactory, ObservedInputStream ois) throws CityGMLReadException { CityGMLInputFactory inputFactory, ObservedInputStream ois) throws CityGMLReadException {
try (CityGMLReader reader = inputFactory.createCityGMLReader(ois)) { try (CityGMLReader reader = inputFactory.createCityGMLReader(ois)) {
Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, file); Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, file);
CityGMLVersion version = null;
// model is read in chunked mode // model is read in chunked mode
// object members are replaced by href in model // object members are replaced by href in model
// need to remove the refs and re-add unparsed objects // need to remove the refs and re-add unparsed objects
List<AbstractCityObject> acos = new ArrayList<>(); List<AbstractCityObject> acos = new ArrayList<>();
while (reader.hasNext()) { while (reader.hasNext()) {
AbstractFeature chunk = reader.next(); AbstractFeature chunk = reader.next();
version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI());
if (chunk instanceof CityModel cModel) { if (chunk instanceof CityModel cModel) {
cModel.setCityObjectMembers(null); cModel.setCityObjectMembers(null);
mapper.setCityModel(cModel); mapper.setCityModel(cModel);
CityGMLVersion version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI());
mapper.setCityGMLVersion(version); mapper.setCityGMLVersion(version);
} else if (chunk instanceof AbstractCityObject aco) { } else if (chunk instanceof AbstractCityObject aco) {
acos.add(aco); acos.add(aco);
...@@ -362,10 +374,14 @@ public class CityGmlParser { ...@@ -362,10 +374,14 @@ public class CityGmlParser {
for (AbstractCityObject aco : acos) { for (AbstractCityObject aco : acos) {
cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco)); cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco));
} }
if (logger.isInfoEnabled()) { if (logger.isInfoEnabled() && !gagged) {
logger.info(Localization.getText("CityGmlParser.parsedObjects"), logger.info(Localization.getText("CityGmlParser.parsedObjects"),
mapper.getModel().getNumberOfFeatures()); mapper.getModel().getNumberOfFeatures());
} else if (gagged){
// Remove gag
gagged = false;
} }
mapper.setCityGMLVersion(version);
return mapper.getModel(); return mapper.getModel();
} }
} }
......
...@@ -18,35 +18,30 @@ ...@@ -18,35 +18,30 @@
*/ */
package de.hft.stuttgart.citydoctor2.utils; package de.hft.stuttgart.citydoctor2.utils;
import java.util.ArrayList; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import java.util.List; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.*;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import org.citygml4j.core.util.geometry.GeometryFactory; import org.citygml4j.core.util.geometry.GeometryFactory;
import org.locationtech.proj4j.BasicCoordinateTransform; import org.locationtech.proj4j.BasicCoordinateTransform;
import org.locationtech.proj4j.ProjCoordinate; import org.locationtech.proj4j.ProjCoordinate;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.complexes.CompositeSurface; import org.xmlobjects.gml.model.geometry.complexes.CompositeSurface;
import org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty; import org.xmlobjects.gml.model.geometry.primitives.*;
import org.xmlobjects.gml.model.geometry.primitives.Shell;
import org.xmlobjects.gml.model.geometry.primitives.ShellProperty; import java.util.ArrayList;
import org.xmlobjects.gml.model.geometry.primitives.Solid; import java.util.HashSet;
import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
/** /**
* Utility class dedicated to create CityGML4j datastructures. * Utility class dedicated to create CityGML4j datastructures.
* *
* @author Matthias Betz * @author Matthias Betz
*
*/ */
public final class CityGmlUtils { public final class CityGmlUtils {
private CityGmlUtils() { private CityGmlUtils() {
// util class // util class
} }
...@@ -81,6 +76,22 @@ public final class CityGmlUtils { ...@@ -81,6 +76,22 @@ public final class CityGmlUtils {
return gmlPoly; return gmlPoly;
} }
public static CompositeSurface createGmlComposite(GeometryFactory factory, CompositeCollection comp,
ParserConfiguration config) {
List<SurfaceProperty> surfaces = new ArrayList<>();
for (ConcretePolygon cd : comp.getNonRecursiveCompositeMembers()) {
surfaces.add(new SurfaceProperty(createGmlPolygon(factory, cd, config)));
}
for (CompositeCollection cc : comp.getChildComposites()) {
surfaces.add(new SurfaceProperty(createGmlComposite(factory, cc, config)));
}
if (surfaces.isEmpty()) {
return null;
}
return new CompositeSurface(surfaces);
}
public static org.xmlobjects.gml.model.geometry.primitives.LinearRing createGmlRing(GeometryFactory factory, public static org.xmlobjects.gml.model.geometry.primitives.LinearRing createGmlRing(GeometryFactory factory,
ParserConfiguration config, LinearRing lr) { ParserConfiguration config, LinearRing lr) {
...@@ -141,12 +152,15 @@ public final class CityGmlUtils { ...@@ -141,12 +152,15 @@ public final class CityGmlUtils {
public static MultiSurface createMultiSurface(Geometry geom, GeometryFactory factory, public static MultiSurface createMultiSurface(Geometry geom, GeometryFactory factory,
ParserConfiguration config) { ParserConfiguration config) {
if (geom.getType() != GeometryType.MULTI_SURFACE) { if (geom.getType() != GeometryType.MULTI_SURFACE && geom.getType() != GeometryType.COMPOSITE_SURFACE) {
throw new IllegalArgumentException("This can only handle MultiSurfaces"); throw new IllegalArgumentException("This can only handle MultiSurfaces");
} }
List<SurfaceProperty> surfaces = new ArrayList<>(); List<SurfaceProperty> surfaces = new ArrayList<>();
Set<CompositeCollection> compositeCollections = new HashSet<>();
for (Polygon cdPoly : geom.getPolygons()) { for (Polygon cdPoly : geom.getPolygons()) {
if (!cdPoly.isLink()) { if (cdPoly instanceof ConcretePolygon conc && conc.isCompositeMember()) {
compositeCollections.add(conc.getPartOfComposite());
} else if (!cdPoly.isLink()) {
// is not part of a boundary surface // is not part of a boundary surface
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config); org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
if (gmlPoly != null) { if (gmlPoly != null) {
...@@ -157,6 +171,9 @@ public final class CityGmlUtils { ...@@ -157,6 +171,9 @@ public final class CityGmlUtils {
surfaces.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString())); surfaces.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString()));
} }
} }
for (CompositeCollection cdPoly : compositeCollections) {
surfaces.add(new SurfaceProperty(createGmlComposite(factory, cdPoly, config)));
}
if (surfaces.isEmpty()) { if (surfaces.isEmpty()) {
return null; return null;
} }
......
...@@ -68,7 +68,7 @@ public class CityGMLWriterUtils { ...@@ -68,7 +68,7 @@ public class CityGMLWriterUtils {
public static void writeCityModel(String file, CityDoctorModel model) throws CityDoctorWriteException { public static void writeCityModel(String file, CityDoctorModel model) throws CityDoctorWriteException {
CityGMLContext gmlContext = CityGmlParser.getContext(); CityGMLContext gmlContext = CityGmlParser.getContext();
CityModel cModel = model.getCityModel(); CityModel cModel = model.getCityModel();
CityGMLOutputFactory factory = gmlContext.createCityGMLOutputFactory(CityGMLVersion.v2_0); CityGMLOutputFactory factory = gmlContext.createCityGMLOutputFactory(model.getCityGMLVersion());
try (CityGMLWriter writer = factory.createCityGMLWriter(new File(file))) { try (CityGMLWriter writer = factory.createCityGMLWriter(new File(file))) {
writer.withIndent(" "); writer.withIndent(" ");
writer.withDefaultPrefixes(); writer.withDefaultPrefixes();
...@@ -92,6 +92,9 @@ public class CityGMLWriterUtils { ...@@ -92,6 +92,9 @@ public class CityGMLWriterUtils {
storeCityObjects(model.getLand(), gmlFactory, model, cModel, val); storeCityObjects(model.getLand(), gmlFactory, model, cModel, val);
storeCityObjects(model.getTransportation(), gmlFactory, model, cModel, val); storeCityObjects(model.getTransportation(), gmlFactory, model, cModel, val);
storeCityObjects(model.getWater(), gmlFactory, model, cModel, val); storeCityObjects(model.getWater(), gmlFactory, model, cModel, val);
storeCityObjects(model.getCityFurniture(), gmlFactory, model, cModel, val);
storeCityObjects(model.getGenericCityObjects(), gmlFactory, model, cModel, val);
storeCityObjects(model.getTunnels(), gmlFactory, model, cModel, val);
writer.write(cModel); writer.write(cModel);
cModel.getCityObjectMembers().clear(); cModel.getCityObjectMembers().clear();
...@@ -169,6 +172,7 @@ public class CityGMLWriterUtils { ...@@ -169,6 +172,7 @@ public class CityGMLWriterUtils {
if (model.isValidated() && val != null) { if (model.isValidated() && val != null) {
QualityADEUtils.writeQualityAde(co, val); QualityADEUtils.writeQualityAde(co, val);
} }
co.reCreateGeometries(gmlFactory, model.getParserConfig()); co.reCreateGeometries(gmlFactory, model.getParserConfig());
cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(co.getGmlObject())); cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(co.getGmlObject()));
} }
......
...@@ -29,6 +29,9 @@ MainToolBar.wireframe=Show/Hide Wireframe ...@@ -29,6 +29,9 @@ MainToolBar.wireframe=Show/Hide Wireframe
MainToolBar.culling=Enable/Disable Culling MainToolBar.culling=Enable/Disable Culling
MainToolBar.writeReports=Write Reports MainToolBar.writeReports=Write Reports
MainToolBar.executeChecks=Execute Checks MainToolBar.executeChecks=Execute Checks
MainToolBar.showWorld=Show entire city model
MainToolBar.resetCamera=Reset view
MainToolBar.hideRoof=Show/Hide roof BoundarySurfaces
MainWindow.missingConfig=Could not find configuration file. MainWindow.missingConfig=Could not find configuration file.
MainWindow.loadGivenFile=Loading given file, please wait MainWindow.loadGivenFile=Loading given file, please wait
MainWindow.finishedLoading=Finished loading MainWindow.finishedLoading=Finished loading
...@@ -46,9 +49,12 @@ MainWindow.languageChange=For the change in language to apply, restart CityDocto ...@@ -46,9 +49,12 @@ MainWindow.languageChange=For the change in language to apply, restart CityDocto
MainWindow.buildingsTab=Buildings MainWindow.buildingsTab=Buildings
MainWindow.vegetationTab=Vegetation MainWindow.vegetationTab=Vegetation
MainWindow.transportationTab=Transportation MainWindow.transportationTab=Transportation
MainWindow.tunnelTab=Tunnels
MainWindow.bridgeTab=Bridges MainWindow.bridgeTab=Bridges
MainWindow.waterTab=Water MainWindow.waterTab=Water
MainWindow.terrainTab=Terrain MainWindow.terrainTab=Terrain
MainWindow.cityfurnitureTab=CityFurniture
MainWindow.otherObjectsTab=Other
MainWindow.viewLabel=View MainWindow.viewLabel=View
MainWindow.showLabel=Show: MainWindow.showLabel=Show:
MainWindow.searchLabel=Search: MainWindow.searchLabel=Search:
...@@ -58,6 +64,7 @@ MainWindow.errorsTab=Errors ...@@ -58,6 +64,7 @@ MainWindow.errorsTab=Errors
MainWindow.polygonsTab=Polygons MainWindow.polygonsTab=Polygons
MainWindow.edgesTab=Edges MainWindow.edgesTab=Edges
MainWindow.verticesTab=Vertices MainWindow.verticesTab=Vertices
MainWindow.attributeTab=Attributes
MainWindow.logTab=Log MainWindow.logTab=Log
MainWindow.globalErrorsTab=Global Errors MainWindow.globalErrorsTab=Global Errors
OpenFileDialog.fileLabel=File: OpenFileDialog.fileLabel=File:
......
...@@ -27,6 +27,9 @@ MainToolBar.wireframe=Zeige/Verstecke Gitternetz ...@@ -27,6 +27,9 @@ MainToolBar.wireframe=Zeige/Verstecke Gitternetz
MainToolBar.culling=Aktiviere/Deaktiviere Entfernen der R\u00fcckseiten MainToolBar.culling=Aktiviere/Deaktiviere Entfernen der R\u00fcckseiten
MainToolBar.writeReports=Schreibe Reports MainToolBar.writeReports=Schreibe Reports
MainToolBar.executeChecks=F\u00fchre Pr\u00fcfungen aus MainToolBar.executeChecks=F\u00fchre Pr\u00fcfungen aus
MainToolBar.showWorld=Gesamtes Stadtmodell anzeigen
MainToolBar.resetCamera=Ansicht zur\u00fccksetzen
MainToolBar.hideRoof=Zeige/Verstecke Dach BoundarySurfaces
MainWindow.missingConfig=Konnte Konfigurationsdatei nicht finden. MainWindow.missingConfig=Konnte Konfigurationsdatei nicht finden.
MainWindow.loadGivenFile=Lade vorhandene Datei, bitte warten MainWindow.loadGivenFile=Lade vorhandene Datei, bitte warten
MainWindow.finishedLoading=Fertig geladen MainWindow.finishedLoading=Fertig geladen
...@@ -44,9 +47,12 @@ MainWindow.languageChange=Um die Spracheinstellung zu \u00fcbernehmen muss CityD ...@@ -44,9 +47,12 @@ MainWindow.languageChange=Um die Spracheinstellung zu \u00fcbernehmen muss CityD
MainWindow.buildingsTab=Geb\u00e4ude MainWindow.buildingsTab=Geb\u00e4ude
MainWindow.vegetationTab=Vegetation MainWindow.vegetationTab=Vegetation
MainWindow.transportationTab=Verkehrsobjekte MainWindow.transportationTab=Verkehrsobjekte
MainWindow.tunnelTab=Tunnel
MainWindow.bridgeTab=Br\u00fccken MainWindow.bridgeTab=Br\u00fccken
MainWindow.waterTab=Gew\u00e4sser MainWindow.waterTab=Gew\u00e4sser
MainWindow.terrainTab=Gel\u00e4nde MainWindow.terrainTab=Gel\u00e4nde
MainWindow.cityfurnitureTab=Stadtm\u00f6bel
MainWindow.otherObjectsTab=Andere
MainWindow.viewLabel=Ansicht MainWindow.viewLabel=Ansicht
MainWindow.showLabel=Zeige: MainWindow.showLabel=Zeige:
MainWindow.searchLabel=Suche: MainWindow.searchLabel=Suche:
...@@ -56,6 +62,7 @@ MainWindow.errorsTab=Fehler ...@@ -56,6 +62,7 @@ MainWindow.errorsTab=Fehler
MainWindow.polygonsTab=Polygone MainWindow.polygonsTab=Polygone
MainWindow.edgesTab=Kanten MainWindow.edgesTab=Kanten
MainWindow.verticesTab=Punkte MainWindow.verticesTab=Punkte
MainWindow.attributeTab=Attribute
MainWindow.logTab=Log MainWindow.logTab=Log
MainWindow.globalErrorsTab=Globale Fehler MainWindow.globalErrorsTab=Globale Fehler
OpenFileDialog.fileLabel=Datei: OpenFileDialog.fileLabel=Datei:
......
...@@ -28,6 +28,7 @@ import java.util.List; ...@@ -28,6 +28,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.citygml4j.core.ade.ADEException; import org.citygml4j.core.ade.ADEException;
import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.core.AbstractFeatureProperty; import org.citygml4j.core.model.core.AbstractFeatureProperty;
import org.citygml4j.core.model.core.CityModel; import org.citygml4j.core.model.core.CityModel;
import org.citygml4j.xml.writer.CityGMLWriteException; import org.citygml4j.xml.writer.CityGMLWriteException;
...@@ -131,6 +132,7 @@ public class CityDoctorModelTest { ...@@ -131,6 +132,7 @@ public class CityDoctorModelTest {
File f = Mockito.mock(File.class); File f = Mockito.mock(File.class);
ParserConfiguration config = new ParserConfiguration(8, false); ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = new CityDoctorModel(config, f); CityDoctorModel model = new CityDoctorModel(config, f);
model.setParsedCityGMLVersion(CityGMLVersion.v2_0);
CityModel cModel = new CityModel(); CityModel cModel = new CityModel();
model.setCityModel(cModel); model.setCityModel(cModel);
Building b = new Building(); Building b = new Building();
...@@ -156,6 +158,7 @@ public class CityDoctorModelTest { ...@@ -156,6 +158,7 @@ public class CityDoctorModelTest {
File f = Mockito.mock(File.class); File f = Mockito.mock(File.class);
ParserConfiguration config = new ParserConfiguration(8, false); ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = new CityDoctorModel(config, f); CityDoctorModel model = new CityDoctorModel(config, f);
model.setParsedCityGMLVersion(CityGMLVersion.v2_0);
CityModel cModel = new CityModel(); CityModel cModel = new CityModel();
ValidationPlan plan = new ValidationPlan(); ValidationPlan plan = new ValidationPlan();
plan.setId("CD_PLAN_" + UUID.randomUUID().toString()); plan.setId("CD_PLAN_" + UUID.randomUUID().toString());
......
This diff is collapsed.
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