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 {
private static CityGMLContext context;
private static List<QName> chunkProperties = new ArrayList<>();
// Toggle to suppress logger output for parsing of libraryObjects
private static boolean gagged = false;
static {
System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
FACTORY = SAXParserFactory.newInstance();
......@@ -326,20 +329,29 @@ public class CityGmlParser {
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,
CityGMLInputFactory inputFactory, ObservedInputStream ois) throws CityGMLReadException {
try (CityGMLReader reader = inputFactory.createCityGMLReader(ois)) {
Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, file);
CityGMLVersion version = null;
// model is read in chunked mode
// object members are replaced by href in model
// need to remove the refs and re-add unparsed objects
List<AbstractCityObject> acos = new ArrayList<>();
while (reader.hasNext()) {
AbstractFeature chunk = reader.next();
version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI());
if (chunk instanceof CityModel cModel) {
cModel.setCityObjectMembers(null);
mapper.setCityModel(cModel);
CityGMLVersion version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI());
mapper.setCityGMLVersion(version);
} else if (chunk instanceof AbstractCityObject aco) {
acos.add(aco);
......@@ -362,10 +374,14 @@ public class CityGmlParser {
for (AbstractCityObject aco : acos) {
cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco));
}
if (logger.isInfoEnabled()) {
if (logger.isInfoEnabled() && !gagged) {
logger.info(Localization.getText("CityGmlParser.parsedObjects"),
mapper.getModel().getNumberOfFeatures());
} else if (gagged){
// Remove gag
gagged = false;
}
mapper.setCityGMLVersion(version);
return mapper.getModel();
}
}
......
......@@ -18,35 +18,30 @@
*/
package de.hft.stuttgart.citydoctor2.utils;
import java.util.ArrayList;
import java.util.List;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
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.locationtech.proj4j.BasicCoordinateTransform;
import org.locationtech.proj4j.ProjCoordinate;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.complexes.CompositeSurface;
import org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty;
import org.xmlobjects.gml.model.geometry.primitives.Shell;
import org.xmlobjects.gml.model.geometry.primitives.ShellProperty;
import org.xmlobjects.gml.model.geometry.primitives.Solid;
import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
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;
import org.xmlobjects.gml.model.geometry.primitives.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Utility class dedicated to create CityGML4j datastructures.
*
* @author Matthias Betz
*
*/
public final class CityGmlUtils {
private CityGmlUtils() {
// util class
}
......@@ -81,6 +76,22 @@ public final class CityGmlUtils {
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,
ParserConfiguration config, LinearRing lr) {
......@@ -141,12 +152,15 @@ public final class CityGmlUtils {
public static MultiSurface createMultiSurface(Geometry geom, GeometryFactory factory,
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");
}
List<SurfaceProperty> surfaces = new ArrayList<>();
Set<CompositeCollection> compositeCollections = new HashSet<>();
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
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
if (gmlPoly != null) {
......@@ -157,6 +171,9 @@ public final class CityGmlUtils {
surfaces.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString()));
}
}
for (CompositeCollection cdPoly : compositeCollections) {
surfaces.add(new SurfaceProperty(createGmlComposite(factory, cdPoly, config)));
}
if (surfaces.isEmpty()) {
return null;
}
......
......@@ -68,7 +68,7 @@ public class CityGMLWriterUtils {
public static void writeCityModel(String file, CityDoctorModel model) throws CityDoctorWriteException {
CityGMLContext gmlContext = CityGmlParser.getContext();
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))) {
writer.withIndent(" ");
writer.withDefaultPrefixes();
......@@ -92,6 +92,9 @@ public class CityGMLWriterUtils {
storeCityObjects(model.getLand(), gmlFactory, model, cModel, val);
storeCityObjects(model.getTransportation(), 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);
cModel.getCityObjectMembers().clear();
......@@ -169,6 +172,7 @@ public class CityGMLWriterUtils {
if (model.isValidated() && val != null) {
QualityADEUtils.writeQualityAde(co, val);
}
co.reCreateGeometries(gmlFactory, model.getParserConfig());
cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(co.getGmlObject()));
}
......
......@@ -29,6 +29,9 @@ MainToolBar.wireframe=Show/Hide Wireframe
MainToolBar.culling=Enable/Disable Culling
MainToolBar.writeReports=Write Reports
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.loadGivenFile=Loading given file, please wait
MainWindow.finishedLoading=Finished loading
......@@ -46,9 +49,12 @@ MainWindow.languageChange=For the change in language to apply, restart CityDocto
MainWindow.buildingsTab=Buildings
MainWindow.vegetationTab=Vegetation
MainWindow.transportationTab=Transportation
MainWindow.tunnelTab=Tunnels
MainWindow.bridgeTab=Bridges
MainWindow.waterTab=Water
MainWindow.terrainTab=Terrain
MainWindow.cityfurnitureTab=CityFurniture
MainWindow.otherObjectsTab=Other
MainWindow.viewLabel=View
MainWindow.showLabel=Show:
MainWindow.searchLabel=Search:
......@@ -58,6 +64,7 @@ MainWindow.errorsTab=Errors
MainWindow.polygonsTab=Polygons
MainWindow.edgesTab=Edges
MainWindow.verticesTab=Vertices
MainWindow.attributeTab=Attributes
MainWindow.logTab=Log
MainWindow.globalErrorsTab=Global Errors
OpenFileDialog.fileLabel=File:
......
......@@ -27,6 +27,9 @@ MainToolBar.wireframe=Zeige/Verstecke Gitternetz
MainToolBar.culling=Aktiviere/Deaktiviere Entfernen der R\u00fcckseiten
MainToolBar.writeReports=Schreibe Reports
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.loadGivenFile=Lade vorhandene Datei, bitte warten
MainWindow.finishedLoading=Fertig geladen
......@@ -44,9 +47,12 @@ MainWindow.languageChange=Um die Spracheinstellung zu \u00fcbernehmen muss CityD
MainWindow.buildingsTab=Geb\u00e4ude
MainWindow.vegetationTab=Vegetation
MainWindow.transportationTab=Verkehrsobjekte
MainWindow.tunnelTab=Tunnel
MainWindow.bridgeTab=Br\u00fccken
MainWindow.waterTab=Gew\u00e4sser
MainWindow.terrainTab=Gel\u00e4nde
MainWindow.cityfurnitureTab=Stadtm\u00f6bel
MainWindow.otherObjectsTab=Andere
MainWindow.viewLabel=Ansicht
MainWindow.showLabel=Zeige:
MainWindow.searchLabel=Suche:
......@@ -56,6 +62,7 @@ MainWindow.errorsTab=Fehler
MainWindow.polygonsTab=Polygone
MainWindow.edgesTab=Kanten
MainWindow.verticesTab=Punkte
MainWindow.attributeTab=Attribute
MainWindow.logTab=Log
MainWindow.globalErrorsTab=Globale Fehler
OpenFileDialog.fileLabel=Datei:
......
......@@ -28,6 +28,7 @@ import java.util.List;
import java.util.UUID;
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.CityModel;
import org.citygml4j.xml.writer.CityGMLWriteException;
......@@ -131,6 +132,7 @@ public class CityDoctorModelTest {
File f = Mockito.mock(File.class);
ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = new CityDoctorModel(config, f);
model.setParsedCityGMLVersion(CityGMLVersion.v2_0);
CityModel cModel = new CityModel();
model.setCityModel(cModel);
Building b = new Building();
......@@ -156,6 +158,7 @@ public class CityDoctorModelTest {
File f = Mockito.mock(File.class);
ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = new CityDoctorModel(config, f);
model.setParsedCityGMLVersion(CityGMLVersion.v2_0);
CityModel cModel = new CityModel();
ValidationPlan plan = new ValidationPlan();
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