Commit 81dc206d authored by Riegel's avatar Riegel
Browse files

Refactor!: Move zip-parsing classes into CityDoctorModel

2 merge requests!28Version 3.17.0 Release,!26Add ZIP-archive support
Showing with 3725 additions and 37 deletions
+3725 -37
......@@ -58,7 +58,13 @@
<groupId>org.locationtech.proj4j</groupId>
<artifactId>proj4j</artifactId>
</dependency>
</dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
......
......@@ -203,7 +203,7 @@ public class CityGmlParser {
}
}
InputStream is = archive.getInputStream(entry);
return parseCityGmlStream(is, config, context);
return parseCityGmlStream(is, archive, config, context);
}
private static List<String> validateStream(InputStream vis, CityGMLContext context) throws CityGmlParseException {
......@@ -239,12 +239,12 @@ public class CityGmlParser {
}
}
public static CityDoctorModel parseCityGmlStream(InputStream is, ParserConfiguration config, CityGMLContext context)
public static CityDoctorModel parseCityGmlStream(InputStream is, ZipFile archive ,ParserConfiguration config, CityGMLContext context)
throws CityGmlParseException {
return parseCityGmlStream(is, config, null, context);
return parseCityGmlStream(is, archive, config, null, context);
}
public static CityDoctorModel parseCityGmlStream(InputStream is, ParserConfiguration config, ProgressListener l, CityGMLContext context)
public static CityDoctorModel parseCityGmlStream(InputStream is, ZipFile archive, ParserConfiguration config, ProgressListener l, CityGMLContext context)
throws CityGmlParseException {
try {
......@@ -256,13 +256,18 @@ public class CityGmlParser {
if (l != null){
ois.addListener(l::updateProgress);
}
return readAndKeepFeatures(config, Path.of(""), in, ois);
return readAndKeepFeatures(config, Path.of(archive.getName()), in, ois);
}
} catch (CityGMLReadException | IOException e) {
throw new CityGmlParseException("Failed to read CityGML file", e);
}
}
private static CityDoctorModel readAndKeepFeatures(ZipFile archive, ParserConfiguration config,
CityGMLInputFactory inputFactory, ObservedInputStream ois) throws CityGMLReadException {
return readAndKeepModel(new Citygml3FeatureMapper(config, Path.of(archive.getName())), inputFactory, ois);
}
private static void readEpsgCodeFromInputStream(BufferedInputStream bis, ParserConfiguration config) throws CityGmlParseException {
try{
// Mark start position of GML-"file"
......@@ -422,8 +427,12 @@ public class CityGmlParser {
private static CityDoctorModel readAndKeepFeatures(ParserConfiguration config, Path file,
CityGMLInputFactory inputFactory, ObservedInputStream ois) throws CityGMLReadException {
return readAndKeepModel(new Citygml3FeatureMapper(config, file), inputFactory, ois);
}
private static CityDoctorModel readAndKeepModel(Citygml3FeatureMapper mapper, 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
......
package de.hft.stuttgart.citydoctor2.ziploader.utils;
package de.hft.stuttgart.citydoctor2.utils;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.ziploader.CityGmlArchive;
import de.hft.stuttgart.citydoctor2.ziploader.CityGmlZipEntry;
import de.hft.stuttgart.citydoctor2.ziploader.ErroneousEntry;
import de.hft.stuttgart.citydoctor2.zip.CityGmlArchive;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import de.hft.stuttgart.citydoctor2.zip.ErroneousEntry;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......
package de.hft.stuttgart.citydoctor2.ziploader;
package de.hft.stuttgart.citydoctor2.zip;
import de.hft.stuttgart.citydoctor2.check.Checker;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.ziploader.utils.ArchivePacker;
import de.hft.stuttgart.citydoctor2.utils.ArchivePacker;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serial;
import java.io.*;
import java.io.Serializable;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
......@@ -26,13 +23,14 @@ public class CityGmlArchive implements Serializable {
@Serial
private static final long serialVersionUID = 2168389511043362615L;
private final List<CityGmlZipEntry> entries;
private List<CityGmlZipEntry> entries;
private final Path archivePath;
private ZipFile zipFile;
public static CityGmlArchive fromZipFile(String zipFile, ParserConfiguration config) {
ArrayList<CityGmlZipEntry> archiveEntries = new ArrayList<>();
ZipFile zip = null;
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));) {
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
zip = new ZipFile(zipFile);
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null )
......@@ -59,23 +57,76 @@ public class CityGmlArchive implements Serializable {
return new CityGmlArchive(archiveEntries, Path.of(zipFile));
}
public static CityGmlArchive register(String zipFile) {
ArrayList<CityGmlZipEntry> archiveEntries = new ArrayList<>();
CityGmlArchive cgmlArchive = new CityGmlArchive(Path.of(zipFile));
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null )
{
if (ze.isDirectory()) {
continue;
}
if (ze.getName().endsWith(".gml")) {
archiveEntries.add(CityGmlZipEntry.register(ze));
}
}
cgmlArchive.setEntries(archiveEntries);
return cgmlArchive;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void mountArchive(ParserConfiguration config){
try (ZipFile zip = new ZipFile(archivePath.toFile())) {
zipFile = zip;
for (CityGmlZipEntry entry : entries){
entry.loadEntry(zip, config);
}
} catch (IOException e) {
logger.error(e);
} finally {
zipFile = null;
}
}
private CityGmlArchive(Path archivePath){
this.archivePath = archivePath;
}
private CityGmlArchive(List<CityGmlZipEntry> entries, Path archivePath) {
setEntries(entries);
this.archivePath = archivePath;
}
private void setEntries(List<CityGmlZipEntry> entries) {
this.entries = entries;
entries.forEach(e -> e.setArchive(this));
this.archivePath = archivePath;
}
public void exportToZipFile(String path) {
ArchivePacker.packArchive(path, this);
}
public void checkEntries(){
public InputStream getInputStream(CityGmlZipEntry entry) throws IOException {
if(zipFile == null){
throw new ZipException("Requested InputStream from unmounted CityGmlArchive");
}
return zipFile.getInputStream(zipFile.getEntry(entry.getFileName()));
}
public CityGmlZipEntry getEntry(String fileName) {
for(CityGmlZipEntry entry : entries){
Checker checker = new Checker(entry.getModel());
checker.runChecks();
if(entry.getFileName().equals(fileName)){
return entry;
}
}
return null;
}
public Path getArchivePath() {
return archivePath;
}
......
package de.hft.stuttgart.citydoctor2.ziploader;
package de.hft.stuttgart.citydoctor2.zip;
import de.hft.stuttgart.citydoctor2.check.Checker;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParser;
......@@ -9,6 +8,7 @@ import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
......@@ -19,38 +19,88 @@ public class CityGmlZipEntry {
private static final Logger logger = LogManager.getLogger(CityGmlZipEntry.class);
private final String fileName;
private final CityDoctorModel model;
private CityDoctorModel model;
private CityGmlArchive parentArchive;
private boolean validated = false;
private ZipEntryErrorType errorType = null;
private boolean decompressed = false;
private long size = -1L;
public static CityGmlZipEntry of(ZipEntry entry, ZipFile archive, ParserConfiguration config){
if ((double) entry.getSize() /1024/1024 > 20) {
return new ErroneousEntry(entry, ZipEntryErrorType.EXCESSIVE_FILESIZE);
} else {
try {
CityGmlParser.gagLogger(true);
CityDoctorModel model = CityGmlParser.parseCityGmlZipEntry(entry, archive, config);
return new CityGmlZipEntry(entry, model);
} catch (CityGmlParseException | InvalidGmlFileException e) {
logger.error(e);
return new ErroneousEntry(entry, ZipEntryErrorType.INVALID_CITY_GML_FILE);
} catch (IOException e){
logger.error(e);
return new ErroneousEntry(entry, ZipEntryErrorType.IO_ERROR);
CityGmlZipEntry ze = CityGmlZipEntry.register(entry);
return ze.loadEntry(archive, config);
}
public CityGmlZipEntry loadEntry(ZipFile zip ,ParserConfiguration config){
if (decompressed){
return this;
}
ZipEntry ze = zip.getEntry(fileName);
try {
if (!entrySizeWithinMemoryLimits(ze,zip)) {
return new ErroneousEntry(ze, ZipEntryErrorType.EXCESSIVE_FILESIZE);
}
CityGmlParser.gagLogger(true);
this.model = CityGmlParser.parseCityGmlZipEntry(ze, zip, config);
this.decompressed = true;
return this;
} catch (CityGmlParseException | InvalidGmlFileException e) {
logger.error(e);
return new ErroneousEntry(ze, ZipEntryErrorType.INVALID_CITY_GML_FILE);
} catch (IOException e){
logger.error(e);
return new ErroneousEntry(ze, ZipEntryErrorType.IO_ERROR);
}
}
public static CityGmlZipEntry register(ZipEntry entry){
return new CityGmlZipEntry(entry, false);
}
private boolean entrySizeWithinMemoryLimits(ZipEntry ze, ZipFile zip) throws IOException {
long mb = 1024 * 1024L;
long maxMemory = (long) Math.ceil(((double) Runtime.getRuntime().maxMemory() / mb)*0.9);
if (size != -1L){
return maxMemory > size;
}
if (ze.getSize() == -1L){
//unknown filesize, check by streaming file
InputStream is = zip.getInputStream(ze);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(int i = is.read(); i != -1;i=is.read()) {
baos.write(i);
if ((baos.size() / mb) + 1 > maxMemory) {
//Entry will exceed available memory
return false;
}
}
// end of stream reached
this.size = baos.size();
return true;
} else {
size = (long) Math.ceil((double) ze.getSize() / mb);
return maxMemory > size;
}
}
private CityGmlZipEntry(ZipEntry entry, CityDoctorModel model){
this.fileName = entry.getName().substring(entry.getName().lastIndexOf('/') + 1);
this.fileName = entry.getName();
this.model = model;
}
protected CityGmlZipEntry(ZipEntry entry) {
this.fileName = entry.getName().substring(entry.getName().lastIndexOf('/') + 1);
protected CityGmlZipEntry(ZipEntry entry, boolean decompressed) {
this.fileName = entry.getName();
this.model = null;
this.decompressed = decompressed;
}
private static int calculateEntrySize(ZipEntry entry, ZipFile archive) {
try {
InputStream is = archive.getInputStream(entry);
} catch (IOException e) {
throw new RuntimeException(e);
}
return 0;
}
public void setArchive(CityGmlArchive archive){
......@@ -61,11 +111,6 @@ public class CityGmlZipEntry {
return parentArchive;
}
public void validateModel(){
Checker checker = new Checker(this.getModel());
checker.runChecks();
validated = true;
}
public boolean isValidated(){
return validated;
......
package de.hft.stuttgart.citydoctor2.ziploader;
package de.hft.stuttgart.citydoctor2.zip;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
......@@ -9,14 +9,10 @@ public class ErroneousEntry extends CityGmlZipEntry {
private ZipEntryErrorType errorType = null;
public ErroneousEntry(ZipEntry entry, ZipEntryErrorType errorType){
super(entry);
super(entry, true);
this.errorType = errorType;
}
@Override
public void validateModel(){
/* Erroneous entries could not parse their CityModel and thus skip validation */
}
@Override
public CityDoctorModel getModel(){
......
package de.hft.stuttgart.citydoctor2.ziploader;
package de.hft.stuttgart.citydoctor2.zip;
public enum ZipEntryErrorType {
INVALID_CITY_GML_FILE, EXCESSIVE_FILESIZE, IO_ERROR
......
package de.hft.stuttgart.citydoctor2.ziploader;
package de.hft.stuttgart.citydoctor2.zip;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class ZipParser {
private static final Logger logger = LogManager.getLogger(ZipParser.class);
......
package de.hft.stuttgart.citydoctor2.ziploader;
package de.hft.stuttgart.citydoctor2.zip;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import org.apache.commons.io.FileUtils;
......@@ -23,7 +23,7 @@ public class ZipTest {
@Test
public void testUnzipping() {
CityGmlArchive cgmlArch = CityGmlArchive.fromZipFile("src/test/resources/mock_archive.zip", config);
CityGmlArchive cgmlArch = CityGmlArchive.fromZipFile("src/test/resources/zip/mock_archive.zip", config);
checkMockArchive(cgmlArch);
}
......@@ -41,7 +41,7 @@ public class ZipTest {
@Test
public void testZipping() throws IOException {
CityGmlArchive cgmlArch = CityGmlArchive.fromZipFile("src/test/resources/mock_archive.zip", config);
CityGmlArchive cgmlArch = CityGmlArchive.fromZipFile("src/test/resources/zip/mock_archive.zip", config);
Path tmpDir = null;
try {
tmpDir = Files.createTempDirectory("testTmp");
......@@ -62,7 +62,7 @@ public class ZipTest {
@Test
public void testEpsgParsing() {
CityGmlArchive cgmlArch = CityGmlArchive.fromZipFile("src/test/resources/epsg.zip", config);
CityGmlArchive cgmlArch = CityGmlArchive.fromZipFile("src/test/resources/zip/epsg.zip", config);
assertNotNull(cgmlArch);
List<String> epsgs = new ArrayList<>(2);
epsgs.add("25832");
......@@ -78,11 +78,11 @@ public class ZipTest {
@Test
public void testValidation(){
ParserConfiguration valConfig = new ParserConfiguration(8,true);
CityGmlArchive cgmlArch = CityGmlArchive.fromZipFile("src/test/resources/validate.zip", valConfig);
CityGmlArchive cgmlArch = CityGmlArchive.fromZipFile("src/test/resources/zip/validate.zip", valConfig);
int faultyFiles = 0;
for (CityGmlZipEntry entry : cgmlArch.getEntries()) {
if (entry instanceof ErroneousEntry errEntry) {
assertTrue(entry.getFileName().matches("^valFaulty.gml$"));
assertTrue(entry.getFileName().matches("validate/valFaulty.gml$"));
assertEquals(ZipEntryErrorType.INVALID_CITY_GML_FILE, errEntry.getErrorType());
faultyFiles++;
}
......
File added
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<core:CityModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:core="http://www.opengis.net/citygml/2.0"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:tran="http://www.opengis.net/citygml/transportation/2.0"
xmlns:wtr="http://www.opengis.net/citygml/waterbody/2.0"
xmlns:smil20lang="http://www.w3.org/2001/SMIL20/Language"
xmlns:grp="http://www.opengis.net/citygml/cityobjectgroup/2.0"
xmlns:luse="http://www.opengis.net/citygml/landuse/2.0"
xmlns:frn="http://www.opengis.net/citygml/cityfurniture/2.0"
xmlns:app="http://www.opengis.net/citygml/appearance/2.0"
xmlns:tex="http://www.opengis.net/citygml/texturedsurface/2.0"
xmlns:smil20="http://www.w3.org/2001/SMIL20/"
xmlns:xAL="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"
xmlns:bldg="http://www.opengis.net/citygml/building/2.0"
xmlns:dem="http://www.opengis.net/citygml/relief/2.0"
xmlns:veg="http://www.opengis.net/citygml/vegetation/2.0"
xmlns:brid="http://www.opengis.net/citygml/bridge/2.0"
xmlns:tun="http://www.opengis.net/citygml/tunnel/2.0"
xmlns:gen="http://www.opengis.net/citygml/generics/2.0"
xmlns:wfs="http://www.opengis.net/wfs"
xsi:schemaLocation="http://www.opengis.net/citygml/landuse/2.0 http://schemas.opengis.net/citygml/landuse/2.0/landUse.xsd http://www.opengis.net/citygml/cityfurniture/2.0 http://schemas.opengis.net/citygml/cityfurniture/2.0/cityFurniture.xsd http://www.opengis.net/citygml/appearance/2.0 http://schemas.opengis.net/citygml/appearance/2.0/appearance.xsd http://www.opengis.net/citygml/texturedsurface/2.0 http://schemas.opengis.net/citygml/texturedsurface/2.0/texturedSurface.xsd http://www.opengis.net/citygml/transportation/2.0 http://schemas.opengis.net/citygml/transportation/2.0/transportation.xsd http://www.opengis.net/citygml/waterbody/2.0 http://schemas.opengis.net/citygml/waterbody/2.0/waterBody.xsd http://www.opengis.net/citygml/building/2.0 http://schemas.opengis.net/citygml/building/2.0/building.xsd http://www.opengis.net/citygml/relief/2.0 http://schemas.opengis.net/citygml/relief/2.0/relief.xsd http://www.opengis.net/citygml/vegetation/2.0 http://schemas.opengis.net/citygml/vegetation/2.0/vegetation.xsd http://www.opengis.net/citygml/cityobjectgroup/2.0 http://schemas.opengis.net/citygml/cityobjectgroup/2.0/cityObjectGroup.xsd http://www.opengis.net/citygml/bridge/2.0 http://schemas.opengis.net/citygml/bridge/2.0/bridge.xsd http://www.opengis.net/citygml/tunnel/2.0 http://schemas.opengis.net/citygml/tunnel/2.0/tunnel.xsd http://www.opengis.net/citygml/generics/2.0 http://schemas.opengis.net/citygml/generics/2.0/generics.xsd">
<gml:description>G:\62\GIS_tui\Produkte\3D\Zusammenarbeit_Universitäten\HFT Stuttgart\Testdatensatz_28062022\Export_Wiesdorf.gml</gml:description>
<gml:name>G:\62\GIS_tui\Produkte\3D\Zusammenarbeit_Universitäten\HFT Stuttgart\Testdatensatz_28062022\Export_Wiesdorf.gml</gml:name>
<gml:boundedBy>
<gml:Envelope srsDimension="3" srsName="urn:ogc:def:crs:EPSG::25832">
<gml:lowerCorner>357978.09 5654873.32 0.00</gml:lowerCorner>
<gml:upperCorner>359213.91 5656013.49 0.00</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC40f8b818-84e2-4bf7-bbfa-22af5f20f9f3">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>359134.053 5655248.918 46.90999985</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC40f8b818-84e2-4bf7-bbfa-22af5f20f9f3"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC40f8b818-84e2-4bf7-bbfa-22af5f20f9f3"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC40f8b818-84e2-4bf7-bbfa-22af5f20f9f3"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC18370283-fc17-4a8d-812e-ac677b3cc6aa">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358805.594 5655223.78 46.59999847</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC18370283-fc17-4a8d-812e-ac677b3cc6aa"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC18370283-fc17-4a8d-812e-ac677b3cc6aa"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC18370283-fc17-4a8d-812e-ac677b3cc6aa"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="ICf9ac1d5a-4be4-466c-934e-58cdce2cb082">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358528.544 5655634.731 44.45999908</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#ICf9ac1d5a-4be4-466c-934e-58cdce2cb082"/>
<gen:lod3ImplicitRepresentation xlink:href="#ICf9ac1d5a-4be4-466c-934e-58cdce2cb082"/>
<gen:lod4ImplicitRepresentation xlink:href="#ICf9ac1d5a-4be4-466c-934e-58cdce2cb082"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC1f5d078e-869e-4adc-95bf-6e1ada98105d">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358921.258 5655754.859 44.00999832</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC1f5d078e-869e-4adc-95bf-6e1ada98105d"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC1f5d078e-869e-4adc-95bf-6e1ada98105d"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC1f5d078e-869e-4adc-95bf-6e1ada98105d"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC15f429a4-4997-4e7f-8eca-e5c6087ed869">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358566.979 5655138.757 46.36000061</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC15f429a4-4997-4e7f-8eca-e5c6087ed869"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC15f429a4-4997-4e7f-8eca-e5c6087ed869"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC15f429a4-4997-4e7f-8eca-e5c6087ed869"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="ICf9cb14cc-99a2-4bf2-ac68-75e876aebe1a">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358503.967 5655267.126 46.91999817</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#ICf9cb14cc-99a2-4bf2-ac68-75e876aebe1a"/>
<gen:lod3ImplicitRepresentation xlink:href="#ICf9cb14cc-99a2-4bf2-ac68-75e876aebe1a"/>
<gen:lod4ImplicitRepresentation xlink:href="#ICf9cb14cc-99a2-4bf2-ac68-75e876aebe1a"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC2df38958-7c1d-4804-aaea-93ea742e62c1">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>359055.978 5655849.151 42.93000031</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC2df38958-7c1d-4804-aaea-93ea742e62c1"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC2df38958-7c1d-4804-aaea-93ea742e62c1"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC2df38958-7c1d-4804-aaea-93ea742e62c1"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC6cd916e8-1916-4e68-ae19-2b48b02a3cd9">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358551.225 5655559.56 44.58000183</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC6cd916e8-1916-4e68-ae19-2b48b02a3cd9"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC6cd916e8-1916-4e68-ae19-2b48b02a3cd9"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC6cd916e8-1916-4e68-ae19-2b48b02a3cd9"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC9926fd28-fa21-4a5c-8829-9baf2100ee74">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>359050.629 5655010.897 45.25999832</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC9926fd28-fa21-4a5c-8829-9baf2100ee74"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC9926fd28-fa21-4a5c-8829-9baf2100ee74"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC9926fd28-fa21-4a5c-8829-9baf2100ee74"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC860511a3-6d12-4d5e-9ecc-c8c8ab866d48">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358445.815 5655744.757 43.90999985</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC860511a3-6d12-4d5e-9ecc-c8c8ab866d48"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC860511a3-6d12-4d5e-9ecc-c8c8ab866d48"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC860511a3-6d12-4d5e-9ecc-c8c8ab866d48"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC9a67f98b-ea7c-4650-a76b-70ddf055693e">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>357980.349 5655498.896 46.88999939</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC9a67f98b-ea7c-4650-a76b-70ddf055693e"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC9a67f98b-ea7c-4650-a76b-70ddf055693e"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC9a67f98b-ea7c-4650-a76b-70ddf055693e"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC574549b9-5daf-4404-922f-ad143f772cf5">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358828.134 5655492.423 45.84000015</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC574549b9-5daf-4404-922f-ad143f772cf5"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC574549b9-5daf-4404-922f-ad143f772cf5"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC574549b9-5daf-4404-922f-ad143f772cf5"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC16de12fd-a52a-4c99-91e1-6466bf223c35">
<core:transformationMatrix>
1.0 0.0 0 0
-0.0 1.0 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit2.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358872.807 5655511.242 45.72999954</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC16de12fd-a52a-4c99-91e1-6466bf223c35"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC16de12fd-a52a-4c99-91e1-6466bf223c35"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC16de12fd-a52a-4c99-91e1-6466bf223c35"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC06c0a1de-c757-41d1-8142-eb43b941c06e">
<core:transformationMatrix>
0.9444916824817261 -0.3285353279676911 0 0
0.3285353279676911 0.9444916824817261 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit1.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358600.899 5655436.227 46.47575902257221</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC06c0a1de-c757-41d1-8142-eb43b941c06e"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC06c0a1de-c757-41d1-8142-eb43b941c06e"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC06c0a1de-c757-41d1-8142-eb43b941c06e"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="ICe37a46d4-dd5c-4da4-bc63-4fd64104fa7f">
<core:transformationMatrix>
-0.9667328231176867 0.2557882888384602 0 0
-0.2557882888384602 -0.9667328231176867 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit1.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358564.214 5655406.122 46.67377932584644</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#ICe37a46d4-dd5c-4da4-bc63-4fd64104fa7f"/>
<gen:lod3ImplicitRepresentation xlink:href="#ICe37a46d4-dd5c-4da4-bc63-4fd64104fa7f"/>
<gen:lod4ImplicitRepresentation xlink:href="#ICe37a46d4-dd5c-4da4-bc63-4fd64104fa7f"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="ICd0cefddc-7ed8-44c4-8ef2-a7f517e374c5">
<core:transformationMatrix>
0.4199574315257782 0.9075438037396715 0 0
-0.9075438037396715 0.4199574315257782 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>Implicit1.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358996.371 5655511.698 47.731653352198045</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#ICd0cefddc-7ed8-44c4-8ef2-a7f517e374c5"/>
<gen:lod3ImplicitRepresentation xlink:href="#ICd0cefddc-7ed8-44c4-8ef2-a7f517e374c5"/>
<gen:lod4ImplicitRepresentation xlink:href="#ICd0cefddc-7ed8-44c4-8ef2-a7f517e374c5"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="IC8f1f5e1b-2612-49d8-b3a1-76a304142566">
<core:transformationMatrix>
-0.3960952573399263 -0.9182094244304061 0 0
0.9182094244304061 -0.3960952573399263 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>subdir/Implicit3.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358965.209 5655485.702 47.407838617376704</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#IC8f1f5e1b-2612-49d8-b3a1-76a304142566"/>
<gen:lod3ImplicitRepresentation xlink:href="#IC8f1f5e1b-2612-49d8-b3a1-76a304142566"/>
<gen:lod4ImplicitRepresentation xlink:href="#IC8f1f5e1b-2612-49d8-b3a1-76a304142566"/>
</gen:GenericCityObject>
</core:cityObjectMember>
<core:cityObjectMember>
<gen:GenericCityObject>
<gen:lod1ImplicitRepresentation>
<core:ImplicitGeometry gml:id="ICe80df500-b965-49be-b06a-3993f02370ce">
<core:transformationMatrix>
-0.35611833267672716 -0.9344408665782699 0 0
0.9344408665782699 -0.35611833267672716 0 0
0 0 1.0 0
0 0 0 1
</core:transformationMatrix>
<core:libraryObject>subdir/Implicit3.gml</core:libraryObject>
<core:referencePoint>
<gml:Point>
<gml:pos>358973.349 5655464.637 47.32017288640677</gml:pos>
</gml:Point>
</core:referencePoint>
</core:ImplicitGeometry>
</gen:lod1ImplicitRepresentation>
<gen:lod2ImplicitRepresentation xlink:href="#ICe80df500-b965-49be-b06a-3993f02370ce"/>
<gen:lod3ImplicitRepresentation xlink:href="#ICe80df500-b965-49be-b06a-3993f02370ce"/>
<gen:lod4ImplicitRepresentation xlink:href="#ICe80df500-b965-49be-b06a-3993f02370ce"/>
</gen:GenericCityObject>
</core:cityObjectMember>
</core:CityModel>
\ No newline at end of file
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