Commit 3dac795e authored by Riegel's avatar Riegel
Browse files

Merge branch 'dev' into 'master'

Version 3.17.0 Release

See merge request !28
1 merge request!28Version 3.17.0 Release
Pipeline #11012 passed with stage
in 1 minute and 10 seconds
Showing with 1310 additions and 190 deletions
+1310 -190
......@@ -33,7 +33,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
/**
* Tesselator to create triangles out of polygons.
* Tesselator to create triangles out of polygons. Uses JOGL implementation.
*
* @author Matthias Betz
*
......@@ -102,6 +102,10 @@ public class JoglTesselator {
}
public static TesselatedPolygon tesselatePolygon(Polygon p) {
return tesselatePolygon(p, true);
}
public static TesselatedPolygon tesselatePolygon(Polygon p, boolean discardDegeneratedTriangles) {
ArrayList<Vector3d> vertices = new ArrayList<>();
Vector3d normal = p.calculateNormalNormalized();
synchronized (tess) {
......@@ -121,7 +125,7 @@ public class JoglTesselator {
GLU.gluTessEndPolygon(tess);
ArrayList<Integer> indices = new ArrayList<>();
for (Primitive primitive : primitives) {
primitive.fillListWithIndices(indices);
primitive.fillListWithIndices(indices, discardDegeneratedTriangles);
}
primitives.clear();
return new TesselatedPolygon(vertices, indices, p);
......@@ -137,7 +141,7 @@ public class JoglTesselator {
GLU.gluTessEndContour(tess);
}
public static TesselatedRing tesselateRing(LinearRing r) {
public static TesselatedRing tesselateRing(LinearRing r, boolean discardDegeneratedTriangles) {
ArrayList<Vector3d> vertices = new ArrayList<>();
Vector3d normal = r.calculateNormal();
synchronized (tess) {
......@@ -147,13 +151,17 @@ public class JoglTesselator {
GLU.gluTessEndPolygon(tess);
ArrayList<Integer> indices = new ArrayList<>();
for (Primitive primitive : primitives) {
primitive.fillListWithIndices(indices);
primitive.fillListWithIndices(indices, discardDegeneratedTriangles);
}
primitives.clear();
return new TesselatedRing(vertices, indices, r);
}
}
public static TesselatedRing tesselateRing(LinearRing r) {
return tesselateRing(r, true);
}
private JoglTesselator() {
// only static useage
}
......
......@@ -49,30 +49,34 @@ public class Primitive {
this.type = type;
}
public void fillListWithIndices(List<Integer> indices) {
public void fillListWithIndices(List<Integer> indices, boolean discardDegeneratedTriangles) {
switch (type) {
case GL.GL_TRIANGLES:
for (int i = 0; i < pIndices.size(); i += 3) {
addToListIfAreaNonNull(pIndices.get(i), pIndices.get(i + 1), pIndices.get(i + 2), indices);
addToListIfAreaNonNull(pIndices.get(i), pIndices.get(i + 1), pIndices.get(i + 2), indices,
discardDegeneratedTriangles);
}
break;
case GL.GL_TRIANGLE_STRIP:
for (int i = 0; i < pIndices.size() - 2; i++) {
if (i % 2 == 0) {
addToListIfAreaNonNull(pIndices.get(i), pIndices.get(i + 1), pIndices.get(i + 2), indices);
addToListIfAreaNonNull(pIndices.get(i), pIndices.get(i + 1), pIndices.get(i + 2), indices,
discardDegeneratedTriangles);
} else {
addToListIfAreaNonNull(pIndices.get(i), pIndices.get(i + 2), pIndices.get(i + 1), indices);
addToListIfAreaNonNull(pIndices.get(i), pIndices.get(i + 2), pIndices.get(i + 1), indices,
discardDegeneratedTriangles);
}
}
break;
case GL.GL_TRIANGLE_FAN:
Integer first = pIndices.get(0);
for (int i = 0; i < pIndices.size() - 2; i++) {
addToListIfAreaNonNull(first, pIndices.get(i + 1), pIndices.get(i + 2), indices);
addToListIfAreaNonNull(first, pIndices.get(i + 1), pIndices.get(i + 2), indices,
discardDegeneratedTriangles);
}
break;
default:
throw new IllegalStateException("unknown type found: " + type);
throw new IllegalStateException("unknown triangle type found: " + type);
}
}
......@@ -80,17 +84,18 @@ public class Primitive {
pIndices.add(i);
}
private void addToListIfAreaNonNull(Integer i1, Integer i2, Integer i3, List<Integer> indices) {
private void addToListIfAreaNonNull(Integer i1, Integer i2, Integer i3, List<Integer> indices,
boolean discardDegeneratedTriangles) {
Vector3d v1 = vertices.get(i1);
Vector3d v2 = vertices.get(i2);
Vector3d v3 = vertices.get(i3);
double area = Math.abs(calculateAreaOfTriangle(v1, v2, v3));
if (area > AREA_EPSILON) {
if (discardDegeneratedTriangles && Math.abs(calculateAreaOfTriangle(v1, v2, v3)) <= AREA_EPSILON) {
// switch to discard degenerated triangles is enabled and triangle has nearly no area
logger.trace("Tesselator created degenerated triangle, ignoring");
} else {
indices.add(i1);
indices.add(i2);
indices.add(i3);
} else {
logger.trace("Tesselator created degenerated triangle, ignoring");
}
}
......
package de.hft.stuttgart.citydoctor2.utils;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ArchivePacker {
private static final Logger logger = LogManager.getLogger(ArchivePacker.class);
private ArchivePacker(){}
public static void packArchive(String targetPath, CityGmlZipArchive archive){
Path outputPath = Path.of(targetPath);
outputPath = outputPath.getParent().resolve(
FilenameUtils.removeExtension(outputPath.getFileName().toString()) + ".zip");
Path tmpDir = null;
try{
tmpDir = Files.createTempDirectory("zipTmp");
tmpDir.toFile().deleteOnExit();
for (CityGmlZipEntry entry : archive.getEntries()) {
if (entry.getErrorType() != null || !entry.isLoaded()) {
continue;
}
CityDoctorModel model = entry.getModel();
Path filePath = tmpDir.resolve(entry.getEntrySubPath());
Files.createDirectories(filePath.getParent());
model.saveAs(filePath.toString(), model.isValidated());
}
zipFolder(tmpDir.toFile(), outputPath.toFile());
}catch (Exception e){
logger.error(e);
} finally {
if (tmpDir != null) {
try {
FileUtils.deleteDirectory(tmpDir.toFile());
} catch (IOException e) {
logger.error(e);
}
}
}
}
public static void zipFolder(File folder, File zipFile) throws IOException {
zipFolder(folder, new FileOutputStream(zipFile));
}
public static void zipFolder(File folder, OutputStream outputStream) throws IOException {
try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
processFolder(folder, zipOutputStream, folder.getPath().length() + 1);
}
}
private static void processFolder(File folder, ZipOutputStream zipOutputStream, int prefixLength)
throws IOException {
for (File file : folder.listFiles()) {
if (file.isFile()) {
ZipEntry zipEntry = new ZipEntry(file.getPath().substring(prefixLength));
zipOutputStream.putNextEntry(zipEntry);
try (FileInputStream inputStream = new FileInputStream(file)) {
IOUtils.copy(inputStream, zipOutputStream);
}
zipOutputStream.closeEntry();
} else if (file.isDirectory()) {
processFolder(file, zipOutputStream, prefixLength);
}
}
}
public static void packAndDeleteDirectory(String directoryPath) throws IOException {
Path sourcePath = Path.of(directoryPath);
if (!Files.exists(sourcePath)) {
throw new IllegalStateException("Directory " + directoryPath + " does not exist");
}
if (!Files.isDirectory(sourcePath)) {
throw new IllegalStateException("Path " + directoryPath + " is not a directory");
}
Path outputPath = sourcePath.getParent().resolve(sourcePath.getFileName() + ".zip");
zipFolder(sourcePath.toFile(), outputPath.toFile());
FileUtils.deleteDirectory(sourcePath.toFile());
}
}
......@@ -26,6 +26,10 @@ import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.TopLevelTransportFeature;
import de.hft.stuttgart.citydoctor2.datastructure.TrafficSpaceObject;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationSpace;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
......@@ -49,7 +53,7 @@ public class BoundingBoxCalculator {
* Only the exterior rings of the polygons is used as inner rings should be
* within the exterior or they are faulty.
*
* @param a list of polygons containing the vertices
* @param polygons a list of polygons containing the vertices
* @return an BoundingBox containing the two end points of the bounding box.
*/
public static BoundingBox calculateBoundingBox(Collection<? extends Polygon> polygons) {
......@@ -98,12 +102,16 @@ public class BoundingBoxCalculator {
Vector3d low = new Vector3d(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
Vector3d high = new Vector3d(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
//TODO: Rework this using visitors
findMinMax(low, high, model.getBuildings());
findMinMax(low, high, model.getBridges());
findMinMax(low, high, model.getLand());
findMinMax(low, high, model.getTransportation());
findMinMaxTransport(low, high, model.getTransportation());
findMinMax(low, high, model.getWater());
findMinMax(low, high, model.getVegetation());
findMinMax(low, high, model.getTunnels());
findMinMax(low, high, model.getCityFurniture());
findMinMax(low, high, model.getGenericCityObjects());
Vector3d[] result = new Vector3d[2];
result[0] = low;
......@@ -151,6 +159,23 @@ public class BoundingBoxCalculator {
}
}
//TODO: Implement this properly with visitor. Quick and dirty fix for the renderer
private static void findMinMaxTransport(Vector3d low, Vector3d high, List<? extends TransportationObject> features) {
for (TransportationObject to : features) {
findMinMax(low, high, to);
if (to instanceof TransportationSpace ts) {
findMinMaxTransport(low, high, ts.getTrafficSpaces());
findMinMaxTransport(low, high, ts.getAuxTrafficSpaces());
if (to instanceof TopLevelTransportFeature top) {
findMinMaxTransport(low, high, top.getSections());
findMinMaxTransport(low, high, top.getIntersections());
}
} else if (to instanceof TrafficSpaceObject tso) {
findMinMaxTransport(low, high, tso.getTrafficAreas());
}
}
}
private static void findMinMax(Vector3d low, Vector3d high, CityObject co) {
for (Geometry geom : co.getGeometries()) {
if (geom.getVertices() == null) {
......
......@@ -25,6 +25,7 @@ import java.util.List;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.math.Segment3d;
import de.hft.stuttgart.citydoctor2.math.Triangle3d;
/**
* Result of a polygon polygon intersection.
......@@ -38,7 +39,7 @@ public class PolygonIntersection implements Serializable {
private static final long serialVersionUID = -6301963226688351725L;
public enum IntersectionType {
NONE, LINE, POLYGON
NONE, LINE, POLYGON, TRIANGLES
}
private final IntersectionType type;
......@@ -48,10 +49,30 @@ public class PolygonIntersection implements Serializable {
private Polygon p1;
private Polygon p2;
private Triangle3d t1;
private Triangle3d t2;
public static PolygonIntersection none() {
return new PolygonIntersection(IntersectionType.NONE);
}
public static PolygonIntersection triangles(Triangle3d t1, Triangle3d t2) {
PolygonIntersection poly = new PolygonIntersection(IntersectionType.TRIANGLES);
poly.p1 = t1.getPartOf().getOriginal();
poly.p2 = t2.getPartOf().getOriginal();
poly.t1 = t1;
poly.t2 = t2;
return poly;
}
public static PolygonIntersection any(Polygon p1, Polygon p2) {
PolygonIntersection poly = new PolygonIntersection(IntersectionType.POLYGON);
poly.p1 = p1;
poly.p2 = p2;
return poly;
}
public static PolygonIntersection lines(List<Segment3d> lines, Polygon p1, Polygon p2) {
PolygonIntersection poly = new PolygonIntersection(IntersectionType.LINE);
poly.lines = lines;
......@@ -76,6 +97,14 @@ public class PolygonIntersection implements Serializable {
return p2;
}
public Triangle3d getT1() {
return t1;
}
public Triangle3d getT2() {
return t2;
}
private PolygonIntersection(IntersectionType type) {
this.type = type;
}
......
......@@ -31,7 +31,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.core.AbstractCityObjectProperty;
import org.citygml4j.core.model.core.AbstractFeatureProperty;
import org.citygml4j.core.model.core.CityModel;
......
package de.hft.stuttgart.citydoctor2.zip;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.ArchivePacker;
import de.hft.stuttgart.citydoctor2.utils.Localization;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serial;
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.ZipFile;
import java.util.zip.ZipInputStream;
/**
* This class serves as a representation of a ZIP-archive containing CityGml files. The contained files are represented
* by {@link CityGmlZipEntry} objects.
*/
public class CityGmlZipArchive implements Serializable {
private static final Logger logger = LogManager.getLogger(CityGmlZipArchive.class);
@Serial
private static final long serialVersionUID = 2168389511043362615L;
private List<CityGmlZipEntry> entries;
private final Path archivePath;
private final String archiveNameRE;
/**
* Registers a ZIP-file as an archive. All contained XML and GML files will be registered as {@link CityGmlZipEntry} objects.
*
* @param zipFile path of the ZIP-file
* @return A {@link CityGmlZipArchive} object representing the archive, or null if read-access for the ZIP-file was denied
* @throws MalformedZipFileException if the ZIP-file has encoding errors
*/
public static CityGmlZipArchive register(String zipFile) throws MalformedZipFileException {
ArrayList<CityGmlZipEntry> archiveEntries = new ArrayList<>();
CityGmlZipArchive cgmlArchive = new CityGmlZipArchive(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") || ze.getName().endsWith(".xml")) {
// Ignore report files generated by CityDoctor
if (ze.getName().endsWith("_report.xml")) {
continue;
}
archiveEntries.add(CityGmlZipEntry.register(ze, cgmlArchive));
}
}
cgmlArchive.setEntries(archiveEntries);
return cgmlArchive;
} catch (IOException e) {
logger.error(Localization.getText("CityGmlZipArchive.ioError"));
logger.debug(e.getMessage(), e);
return null;
} catch (IllegalArgumentException e) {
logger.error(Localization.getText("CityGmlZipArchive.malformedZipFile"));
throw new MalformedZipFileException(Localization.getText("CityGmlZipArchive.malformedZipFile"));
} catch (Exception e) {
logger.error(Localization.getText("CityGmlZipArchive.generalException"));
logger.debug(e.getMessage(), e);
throw (e);
}
}
/**
* Attempts to load all contained {@link CityGmlZipEntry} objects into memory.
*
* @param config Parser configuration for the entries
*/
public void mountArchive(ParserConfiguration config) {
try (ZipFile zip = new ZipFile(archivePath.toFile())) {
for (CityGmlZipEntry entry : entries) {
entry.loadEntry(config);
}
} catch (IOException e) {
logger.error(e);
}
}
private CityGmlZipArchive(Path archivePath) {
this.archivePath = archivePath;
this.archiveNameRE = archivePath.getFileName().toString().replace(".zip", "") + File.separator;
}
private void setEntries(List<CityGmlZipEntry> entries) {
this.entries = entries;
}
/**
* Saves this archive as a ZIP-file.
* @param path target path for the export
*/
public void exportToZipFile(String path) {
ArchivePacker.packArchive(path, this);
}
/**
* Gets an entry in this archive by its subpath.
*
* @param subpath subpath to the entry from this archive's root directory
* @return the corresponding entry, or null if entry could not be found
*/
public CityGmlZipEntry getEntry(String subpath) {
subpath = stripArchivePath(subpath);
for (CityGmlZipEntry entry : entries) {
String entryName = stripArchivePath(entry.getEntrySubPath());
if (entryName.equals(subpath)) {
return entry;
}
}
return null;
}
/**
* Strips the root directory name of this archive from an entry subpath.
* @param path the relative path to the entry
* @return String of the path without the root directory
*/
private String stripArchivePath(String path) {
Path systemPath = Path.of(path);
return systemPath.toString().replace(archiveNameRE, "");
}
/**
* Gets the path to the ZIP-file associated with this archive.
* @return path of the ZIP-file
*/
public Path getArchivePath() {
return archivePath;
}
/**
* Gets the entry list of this archive.
* @return the entry list
*/
public List<CityGmlZipEntry> getEntries() {
return entries;
}
}
package de.hft.stuttgart.citydoctor2.zip;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParser;
import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.parser.ProgressListener;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.io.Serial;
import java.io.Serializable;
import java.nio.file.Path;
import java.util.zip.ZipEntry;
/**
* This class serves as a representation of a CityGml file in a ZIP archive.
* <p/>
* The {@link CityDoctorModel} of the associated file can only be accessed after loading the corresponding entry.
*/
public class CityGmlZipEntry implements Serializable {
private static final Logger logger = LogManager.getLogger(CityGmlZipEntry.class);
@Serial
private static final long serialVersionUID = -5732913269959043262L;
private final Path filePath;
private final String fileName;
private final String displayName;
private transient CityDoctorModel model;
private CityGmlZipArchive parentArchive;
private boolean inMemory;
private long fileSize = -1L;
private static final long MB = 1024 * 1024L;
private ZipEntryErrorType errorType = null;
/**
* Attempts to parse the CityGML model associated with this entry and loads it into memory.
* <p/>
* In the event of a parsing error, the entry will be flagged by assigning the appropriate
* {@link ZipEntryErrorType} to the errorType field.
*
* @param config Parser configuration for this model
*/
public void loadEntry(ParserConfiguration config) {
loadEntry(config, null);
}
/**
* Attempts to parse the CityGML model associated with this entry and loads it into memory.
* <p/>
* In the event of a parsing error, the entry will be flagged by assigning the appropriate
* {@link ZipEntryErrorType} to the errorType field.
*
* @param config Parser configuration for this model
* @param l ProgressListener for tracking parsing progress
*/
public void loadEntry(ParserConfiguration config, ProgressListener l) {
if (inMemory) {
return;
}
if (errorType != null) {
logger.warn("Tried loading erroneous CityGmlZipEntry");
return;
}
try {
this.model = CityGmlParser.parseCityGmlZipEntry(this, config, l);
this.inMemory = true;
} catch (CityGmlParseException | InvalidGmlFileException e) {
logger.error(e);
this.errorType = ZipEntryErrorType.INVALID_CITY_GML_FILE;
} catch (IOException e) {
logger.error(e);
this.errorType = ZipEntryErrorType.IO_ERROR;
}
}
/**
* Registers a {@link ZipEntry ZipEntry} in a ZIP-archive as a {@link CityGmlZipEntry}.
* <p/>
* If the filesize of the associated file exceeds the total available system memory, or read access is denied,
* the entry will be flagged by assigning the appropriate {@link ZipEntryErrorType} to the errorType field.
*
* @param entry The ZipEntry object
* @param parentArchive The parent archive for this entry
* @return A corresponding CityGmlZipEntry object
*/
public static CityGmlZipEntry register(ZipEntry entry, CityGmlZipArchive parentArchive) {
CityGmlZipEntry cgzEntry = new CityGmlZipEntry(entry, parentArchive, false);
try {
if (!cgzEntry.entrySizeWithinMemoryLimits()) {
cgzEntry.errorType = ZipEntryErrorType.EXCESSIVE_FILESIZE;
}
} catch (IOException e) {
logger.error(e);
cgzEntry.errorType = ZipEntryErrorType.IO_ERROR;
}
return cgzEntry;
}
/**
* Checks if the filesize of this entry would exceed the system's available memory.
*
* @return true if within limits, false otherwise
* @throws IOException if read access to the ZIP-archive is denied
*/
private boolean entrySizeWithinMemoryLimits() throws IOException {
long memoryLimit = (long) Math.ceil(((double) Runtime.getRuntime().maxMemory() / MB) * 0.9);
if (fileSize == -1L) {
try (CityGmlZipEntryFile entryFile = new CityGmlZipEntryFile(this)) {
long filesize = entryFile.getFileSize();
if (filesize != -1) {
this.fileSize = filesize;
} else {
return false;
}
} catch (Exception e) {
throw new IOException(e);
}
}
return memoryLimit > (fileSize / MB);
}
private CityGmlZipEntry(ZipEntry entry, CityGmlZipArchive parentArchive, boolean inMemory) {
this.fileName = entry.getName();
this.filePath = Path.of(entry.getName());
this.displayName = filePath.getFileName().toString();
if (entry.getSize() != -1) {
this.fileSize = entry.getSize();
}
this.model = null;
this.inMemory = inMemory;
this.parentArchive = parentArchive;
}
/**
* Gets the parent archive of this entry.
* @return the archive
*/
public CityGmlZipArchive getArchive() {
return parentArchive;
}
/**
* Gets the sub-path in the archive of the file associated with this entry.
*
* @return the relative sub-path from the archive root directory
*/
public String getEntrySubPath() {
return fileName;
}
/**
* Gets the name of the file associated with this entry.
* @return the filename
*/
public String getDisplayName() {
return displayName;
}
/**
* Gets the {@link ZipEntryErrorType} of this entry.
* @return the error type, or null if this entry is not erroneous
*/
public ZipEntryErrorType getErrorType() {
return errorType;
}
/**
* Gets the {@link CityDoctorModel} of this entry.
* @return The model, or null if the entry has not been loaded or is erroneous
*/
public CityDoctorModel getModel() {
return model;
}
public void setFileSize(long size) {
fileSize = size;
}
/**
* Resolves the reference path of a {@link de.hft.stuttgart.citydoctor2.datastructure.LibraryObject LibraryObject}
* in the {@link CityDoctorModel} of this entry.
* @param libraryObjectPath The reference path to the LibraryObject's CityGml file
* @return Relative sub-path within the archive to the CityGml file
*/
public Path resolveLibraryObjectPath(String libraryObjectPath) {
return filePath.getParent().resolve(libraryObjectPath);
}
/**
* Checks if the {@link CityDoctorModel} of this entry has been loaded into memory.
*
* @return true if it is loaded, false otherwise
*/
public boolean isLoaded() {
return inMemory;
}
/**
* Returns the estimated uncompressed filesize of this entry.
*
* @return filesize in bytes, -1L if filesize is unknown
*/
public long getFileSize() {
return fileSize;
}
}
package de.hft.stuttgart.citydoctor2.zip;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* This class serves as a resource for read-access to the file that is being represented by
* a CityGmlZipEntry object.
* <p/>
* Does not decompress the file or the parent ZIP-archive.
*/
public class CityGmlZipEntryFile implements AutoCloseable {
private final ZipFile zip;
private final ZipEntry zipEntry;
private final CityGmlZipEntry cgmlZipEntry;
private boolean closed = false;
/**
* Creates a {@link CityGmlZipEntryFile} for a {@link CityGmlZipEntry} object's referenced file.
*
* @param entry the requested entry
* @throws IOException if read access to the ZIP-archive is denied.
*/
public CityGmlZipEntryFile(CityGmlZipEntry entry) throws IOException {
CityGmlZipArchive archive = entry.getArchive();
zip = new ZipFile(archive.getArchivePath().toFile());
zipEntry = zip.getEntry(entry.getEntrySubPath());
this.cgmlZipEntry = entry;
}
/**
* Gets a new InputStream of this file.
* <p/>
* Returned streams are independent of each other, but will all be closed when the {@link CityGmlZipEntryFile} object
* is closed.
* @return an InputStream of this file.
* @throws IOException when this method is called after the file has been closed.
*/
public InputStream getInputStream() throws IOException {
if (closed){
throw new IOException("CityGmlZipEntryFile closed");
}
return zip.getInputStream(zipEntry);
}
/**
* Gets an estimation of this file's filesize.
* @return filesize in bytes, -1L if unknown
* @throws IOException when this method is called after the file has been closed.
*/
public long getFileSize() throws IOException {
if (closed){
throw new IOException("CityGmlZipEntryFile closed");
}
if (cgmlZipEntry.getFileSize() == -1L) {
if (zipEntry.getSize() == -1) {
long bytes = 0;
InputStream is = new BufferedInputStream(this.getInputStream());
for (int i = is.read(); i != -1; i = is.read()) {
bytes++;
}
cgmlZipEntry.setFileSize(bytes);
} else {
cgmlZipEntry.setFileSize(zipEntry.getSize());
}
}
return cgmlZipEntry.getFileSize();
}
@Override
public void close() throws IOException {
zip.close();
closed = true;
}
}
package de.hft.stuttgart.citydoctor2.zip;
import java.util.zip.ZipException;
/**
* Signals that a ZIP-file is corrupted and couldn't be parsed.
*/
public class MalformedZipFileException extends ZipException {
public MalformedZipFileException() {
super();
}
public MalformedZipFileException(String message) {
super(message);
}
}
package de.hft.stuttgart.citydoctor2.zip;
/**
* Error types for {@link CityGmlZipEntry} objects.
*/
public enum ZipEntryErrorType {
INVALID_CITY_GML_FILE, EXCESSIVE_FILESIZE, IO_ERROR
}
package de.hft.stuttgart.citydoctor2.zip;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ZipParser {
private static final Logger logger = LogManager.getLogger(ZipParser.class);
}
......@@ -18,6 +18,9 @@ CheckDialog.parameterValue=Value
CheckDialog.parameterUnit=Unit
CityDoctorController.noDatamodel=Datamodel is null, no checks could be done
CityDoctorController.noSourceFile=Source file is null, no checks could be done
CityDoctorController.noZipFile=ZIP archive is null, no checks could be done
CityDoctorController.exportSuccess=Successfully exported feature
CityDoctorController.saveZipArchiveReports=Successfully exported validation reports!
ExceptionDialog.stacktrace=The exception stacktrace was:
FilterPane.buildings=Buildings
FilterPane.bridges=Bridges
......@@ -32,6 +35,7 @@ MainToolBar.executeChecks=Execute Checks
MainToolBar.showWorld=Show entire city model
MainToolBar.resetCamera=Reset view
MainToolBar.hideRoof=Show/Hide roof BoundarySurfaces
MainToolBar.zip=Open zip-entry selection window
MainWindow.missingConfig=Could not find configuration file.
MainWindow.loadGivenFile=Loading given file, please wait
MainWindow.finishedLoading=Finished loading
......@@ -43,7 +47,12 @@ MainWindow.finishedPdf=Finished pdf report
MainWindow.loadFailed=Failed to load given gml file: {}
MainWindow.all=All
MainWindow.withErrors=With errors
MainWindow.export=Export
MainWindow.export=Export feature
MainWindow.copyId=Copy GML-ID
MainWindow.delete=Delete feature
MainWindow.infoTopLevelExport=Only top-level object can be exported!
MainWindow.infoTopLevelCopyID=GML-ID can only be copied from top-level object!
mainWindow.warnCopyIdFailed=Could not copy GML-ID!
OpenFileDialog.select=Select CityGML file
MainWindow.languageChange=For the change in language to apply, restart CityDoctor2.
MainWindow.buildingsTab=Buildings
......@@ -67,6 +76,7 @@ MainWindow.verticesTab=Vertices
MainWindow.attributeTab=Attributes
MainWindow.logTab=Log
MainWindow.globalErrorsTab=Global Errors
MainWindow.focusCityObject=Focus object
OpenFileDialog.fileLabel=File:
OpenFileDialog.selectBtn=Select
OpenFileDialog.loadBtn=Load
......@@ -96,6 +106,37 @@ CheckDialog.schematronFileLabel=Schematron File:
CheckDialog.selectBtn=Select
CheckDialog.checkBtn=Check
CheckDialog.cancelBtn=Cancel
CheckDialog.streamCheckOption=Use low memory mode
CheckDialog.streamCheckLabel=Citymodels are not loaded and kept in memory. Check results are saved to the QualityADE in copies of the input files.
CheckDialog.outputPathLabel=Output directory (Required):
CheckDialog.outputPathBtn=Select
CheckDialog.pdfReportsOption=Create PDF reports
CheckDialog.xmlReportsOption=Create XML reports
CheckDialog.noPathError=Output path is missing!
ZipEntryManager.title=Zip-entry manager
ZipEntryManager.entryListTitle=Zip-entries
ZipEntryManager.metadata=Metadata
ZipEntryManager.subpathLbl=Subpath:
ZipEntryManager.erroneousLbl=Erroneous:
ZipEntryManager.excessiveFileSize=Filesize exceeds memory
ZipEntryManager.invalidCityGml=Invalid CityGML file
ZipEntryManager.ioError=Unable to access file
ZipEntryManager.filesizeLbl=Filesize:
ZipEntryManager.validatedLbl=Validated:
ZipEntryManager.objectCountLbl=Object count:
ZipEntryManager.loadBtn=Load CityGML model
ZipEntryManager.decompressBtn=Unpack file
ZipEntryManager.decompressAllBtn=Unpack all files
ZipEntryManager.checkAllBtn=Check all files
ZipEntryManager.showReportBtn=Show error statistic
ZipEntryManager.saveBtn=Export validation results
ZipEntryManager.cancelBtn=Cancel
ZipEntryManager.unknownValue=N/A
ZipEntryManager.yes=Yes
ZipEntryManager.no=No
CityGmlZipArchive.ioError=Accessing the ZIP archive failed
CityGmlZipArchive.malformedZipFile=Parsing of ZIP archive aborted, ZIP file is malformed!
CityGmlZipArchive.generalException=Encountered an unexpected error while reading the ZIP archive
WriteReportDialog.writeBtn=Save
WriteReportDialog.cancelBtn=Cancel
WriteReportDialog.errorStatisticsLabel=Error Statistics
......@@ -114,9 +155,19 @@ CityGmlParser.notValidGmlFile=This is not a valid GML-File\n
CityGmlParser.errorReadingGmlFile=Error while reading city gml file\n{}
CityGmlParser.errorWritingGmlFile=Error while writing city gml file\n{}
CityGmlParser.noConversionNeeded=Coordinate system is in meters, no conversion done
CityGmlParser.noEPSG=Could not read EPSG code, assuming metric system
CityGmlParser.failedEPSGParse=Could not read EPSG code, fallback to metric system
CityGmlParser.missingEPSGCode=No EPSG code found, assuming metric system
OpenFileDialog.loadFailed=Failed to load CityGML File
MainWindow.memoryLabel=Memory:
CheckDialog.checksReenabledAlert=Some checks have been reenabled so that other wanted checks can be executed\nSee the log for more information.
MainWindow.availableLabel=Available:
OpenFileDialog.lowMemoryLabel=Low Memory Consumption Mode
ErrorItemVisitor.intersection=Intersection
ErrorItemVisitor.component=Component
ErrorItemVisitor.nameOfAttribute=Name of attribute
ErrorItemVisitor.childId=Child id
ErrorItemVisitor.distance=Distance
ErrorItemVisitor.pointTouchesEdge=Point touches edge
ErrorItemVisitor.degeneratedRing=Degenerated ring
ErrorItemVisitor.deviation=Deviation
ErrorItemVisitor.triangles=Triangles
\ No newline at end of file
......@@ -16,6 +16,9 @@ CheckDialog.parameterValue=Wert
CheckDialog.parameterUnit=Einheit
CityDoctorController.noDatamodel=Datenmodell ist null, keine Pr\u00fcfungen konnten ausgef\u00fchrt werden
CityDoctorController.noSourceFile=Quelldatei ist null, keine Pr\u00fcfungen konnten ausgef\u00fchrt werden
CityDoctorController.noZipFile=ZIP-Archiv ist null, keine Pr\u00fcfungen konnten ausgef\u00fchrt werden
CityDoctorController.exportSuccess=Feature export erfolgreich abgeschlossen
CityDoctorController.saveZipArchiveReports=Validierungsberichte erfolgreich exportiert!
ExceptionDialog.stacktrace=Der Stacktrace des Fehlers war:
FilterPane.buildings=Geb\u00e4ude
FilterPane.bridges=Br\u00fccken
......@@ -30,6 +33,7 @@ MainToolBar.executeChecks=F\u00fchre Pr\u00fcfungen aus
MainToolBar.showWorld=Gesamtes Stadtmodell anzeigen
MainToolBar.resetCamera=Ansicht zur\u00fccksetzen
MainToolBar.hideRoof=Zeige/Verstecke Dach BoundarySurfaces
MainToolBar.zip=Zip-eintrag Auswahlfenster \u00f6ffnen
MainWindow.missingConfig=Konnte Konfigurationsdatei nicht finden.
MainWindow.loadGivenFile=Lade vorhandene Datei, bitte warten
MainWindow.finishedLoading=Fertig geladen
......@@ -41,7 +45,12 @@ MainWindow.finishedPdf=Pdf Report abgeschlossen
MainWindow.loadFailed=Konnte GML-Datei nicht laden: {}
MainWindow.all=Alle
MainWindow.withErrors=Mit Fehlern
MainWindow.export=Exportieren
MainWindow.export=Feature Exportieren
MainWindow.copyId=GML-ID kopieren
MainWindow.delete=Feature L\u00f6schen
MainWindow.infoTopLevelExport=Export ist nur f\u00fcr Featureobjekt basis m\u00f6glich!
MainWindow.infoTopLevelCopyID=GML-ID kann nur von Featureobjekt basis kopiert werden!
mainWindow.warnCopyIdFailed=Kopieren der ID fehlgeschlagen!
OpenFileDialog.select=W\u00e4hle CityGML Datei aus
MainWindow.languageChange=Um die Spracheinstellung zu \u00fcbernehmen muss CityDoctor2 neugestartet werden.
MainWindow.buildingsTab=Geb\u00e4ude
......@@ -65,6 +74,7 @@ MainWindow.verticesTab=Punkte
MainWindow.attributeTab=Attribute
MainWindow.logTab=Log
MainWindow.globalErrorsTab=Globale Fehler
MainWindow.focusCityObject=Objekt fokussieren
OpenFileDialog.fileLabel=Datei:
OpenFileDialog.selectBtn=Ausw\u00e4hlen
OpenFileDialog.loadBtn=Laden
......@@ -94,6 +104,37 @@ CheckDialog.schematronFileLabel=Schematron Datei
CheckDialog.selectBtn=Ausw\u00e4hlen
CheckDialog.checkBtn=Pr\u00fcfen
CheckDialog.cancelBtn=Abbrechen
CheckDialog.streamCheckOption=Niedrigen Arbeitsspeicherverbrauchsmodus aktivieren
CheckDialog.streamCheckLabel=Stadtmodelle werden nicht in den Arbeitsspeicher geladen. Ergebnisse werden in der QualityADE in Kopien der Eingangsdateien gespeichert.
CheckDialog.outputPathLabel=Ausgabeordner (Pflichtfeld):
CheckDialog.outputPathBtn=Ausw\u00e4hlen
CheckDialog.pdfReportsOption=PDF Berichte erstellen
CheckDialog.xmlReportsOption=XML Berichte erstellen
CheckDialog.noPathError=Ausgabepfad wurde nicht gesetzt!
ZipEntryManager.title=Zipeintrag Manager
ZipEntryManager.entryListTitle=Zipeintr\u00e4ge
ZipEntryManager.metadata=Metadaten
ZipEntryManager.subpathLbl=Unterpfad:
ZipEntryManager.erroneousLbl=Fehlerhaft:
ZipEntryManager.excessiveFileSize=Datei zu gro\u00DF
ZipEntryManager.invalidCityGml=Ung\u00fcltige CityGML Datei
ZipEntryManager.ioError=Dateizugriff fehlgeschlagen
ZipEntryManager.filesizeLbl=Dateigr\u00f6\u00DFe:
ZipEntryManager.validatedLbl=Validiert:
ZipEntryManager.objectCountLbl=Objektanzahl:
ZipEntryManager.loadBtn=CityGML Modell laden
ZipEntryManager.decompressBtn=Datei entpacken
ZipEntryManager.decompressAllBtn=Alle Dateien entpacken
ZipEntryManager.checkAllBtn=Alle Dateien pr\u00fcfen
ZipEntryManager.showReportBtn=Fehlerstatistik anzeigen
ZipEntryManager.saveBtn=Validierungsergebnisse exportieren
ZipEntryManager.cancelBtn=Abbruch
ZipEntryManager.unknownValue=Unbekannt
ZipEntryManager.yes=Ja
ZipEntryManager.no=Nein
CityGmlZipArchive.ioError=Zugriff auf ZIP-Datei fehlgeschlagen
CityGmlZipArchive.malformedZipFile=Einlesen des ZIP-Archivs abgebrochen, ZIP-Datei ist fehlerhaft!
CityGmlZipArchive.generalException=Unerwarteter Fehler beim Einlesen des ZIP-Archivs
WriteReportDialog.writeBtn=Speichern
WriteReportDialog.cancelBtn=Abbrechen
WriteReportDialog.errorStatisticsLabel=Fehler Statistik
......@@ -104,7 +145,7 @@ WriteReportDialog.xAxisLabel=Fehler
WriteReportDialog.yAxisLabel=Anzahl
Unit.Radian=Radiant
Unit.Degree=Grad
FeatureMapper.polygonUnreferenced=Polygon {} ist referenziert wurde aber nicht gefunden
FeatureMapper.polygonUnreferenced=Polygon {} ist referenziert, konnte aber nicht gefunden werden
GeometryMapper.emptyPolygon=Polygon ohne externen Ring gefunden, ignoriere
CityGmlParser.parsedObjects=Modell mit {} Objekten gelesen
CityGmlParser.chunkReadFailed=Konnte Datei nicht in St\u00fccken lesen, versuche komplett zu lesen
......@@ -112,9 +153,19 @@ CityGmlParser.notValidGmlFile=Dies ist keine korrekte CityGML Datei\n
CityGmlParser.errorReadingGmlFile=Fehler beim lesen der CityGML Datei\n{}
CityGmlParser.errorWritingGmlFile=Fehler beim schreiben der CityGML Datei\n{}
CityGmlParser.noConversionNeeded=Koordinatensystem in Metern, keine Konvertierung notwendig
CityGmlParser.noEPSG=Konnte EPSG Code nicht lesen, nehme metrisches System an
CityGmlParser.failedEPSGParse=Lesen des EPSG Codes fehlgeschlagen, greife auf metrisches System zur\u00fcck
CityGmlParser.missingEPSGCode=Kein EPSG Code gefunden, nehme metrisches System an
OpenFileDialog.loadFailed=Konnte CityGML Datei nicht laden
MainWindow.memoryLabel=Speicher:
CheckDialog.checksReenabledAlert=Manche Pr\u00fcfungen wurden reaktiviert damit andere gewollte Pr\u00fcfungen durchgef\u00fchrt werden k\u00f6nnen\nMehr Details sind im Log geschrieben
MainWindow.availableLabel=Verf\u00fcgbar:
OpenFileDialog.lowMemoryLabel=Reduzierter Speicherverbrauchsmodus
ErrorItemVisitor.intersection=Verschneidung
ErrorItemVisitor.component=Komponente
ErrorItemVisitor.nameOfAttribute=Name des Attributs
ErrorItemVisitor.childId=Kind ID
ErrorItemVisitor.distance=Distanz
ErrorItemVisitor.pointTouchesEdge=Punkt ber\u00fchrt Kante
ErrorItemVisitor.degeneratedRing=Degenerierter Ring
ErrorItemVisitor.deviation=Abweichung
ErrorItemVisitor.triangles=Dreiecke
\ No newline at end of file
......@@ -348,6 +348,11 @@ public class AbstractBuildingTest {
return null;
}
@Override
public CityObject getTopLevelCityObject(){
return null;
}
};
return ab;
}
......
......@@ -47,7 +47,7 @@ public class BridgeObjectTest {
@Test
public void testAccept() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
bo.addBoundarySurface(new BoundarySurface(null));
AtomicInteger boCounter = new AtomicInteger(0);
AtomicInteger bsCounter = new AtomicInteger(0);
......@@ -75,7 +75,7 @@ public class BridgeObjectTest {
@Test
public void testPrepareForChecking() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
BoundarySurface bsMock = mock(BoundarySurface.class);
bo.addBoundarySurface(bsMock);
bo.prepareForChecking();
......@@ -84,7 +84,7 @@ public class BridgeObjectTest {
@Test
public void testClearMetaInformation() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
BoundarySurface bsMock = mock(BoundarySurface.class);
bo.addBoundarySurface(bsMock);
bo.clearMetaInformation();
......@@ -93,7 +93,7 @@ public class BridgeObjectTest {
@Test
public void testContainsError() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
assertFalse(bo.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
bo.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(bo.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
......@@ -101,7 +101,7 @@ public class BridgeObjectTest {
@Test
public void testContainsError2() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
BoundarySurface bsMock = mock(BoundarySurface.class);
bo.addBoundarySurface(bsMock);
assertFalse(bo.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
......@@ -111,7 +111,7 @@ public class BridgeObjectTest {
@Test
public void testClearAllContainedCheckResults() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
BoundarySurface bsMock = mock(BoundarySurface.class);
bo.addBoundarySurface(bsMock);
bo.clearAllContainedCheckResults();
......@@ -120,7 +120,7 @@ public class BridgeObjectTest {
@Test
public void testContainsAnyError() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
BoundarySurface bsMock = mock(BoundarySurface.class);
bo.addBoundarySurface(bsMock);
bo.containsAnyError();
......@@ -129,14 +129,14 @@ public class BridgeObjectTest {
when(bsMock.containsAnyError()).thenReturn(true);
assertTrue(bo.containsAnyError());
BridgeObject bo2 = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo2 = new BridgeObject(mock(AbstractBridge.class));
bo2.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(bo2.containsAnyError());
}
@Test
public void testCollectContainedErrors() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
BoundarySurface bsMock = mock(BoundarySurface.class);
bo.addBoundarySurface(bsMock);
ArrayList<CheckError> errors = new ArrayList<>();
......@@ -146,7 +146,7 @@ public class BridgeObjectTest {
@Test
public void testReCreateGeometries() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
BoundarySurface bsMock = mock(BoundarySurface.class);
bo.addBoundarySurface(bsMock);
GeometryFactory factoryMock = mock(GeometryFactory.class);
......@@ -157,7 +157,7 @@ public class BridgeObjectTest {
@Test
public void testReCreateGeometriesMultiSurfaceLod1() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
Geometry geom = GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1);
AbstractBridge ab = new Bridge();
bo.setGmlObject(ab);
......@@ -172,7 +172,7 @@ public class BridgeObjectTest {
@Test
public void testReCreateGeometriesMultiSurfaceLod2() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
Geometry geom = GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2);
AbstractBridge ab = new Bridge();
bo.setGmlObject(ab);
......@@ -186,7 +186,7 @@ public class BridgeObjectTest {
@Test
public void testReCreateGeometriesMultiSurfaceLod3() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
Geometry geom = GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3);
AbstractBridge ab = new Bridge();
bo.setGmlObject(ab);
......@@ -200,7 +200,7 @@ public class BridgeObjectTest {
@Test
public void testReCreateGeometriesMultiSurfaceLod4() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
Geometry geom = GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4);
AbstractBridge ab = new Bridge();
bo.setGmlObject(ab);
......@@ -214,7 +214,7 @@ public class BridgeObjectTest {
@Test
public void testReCreateGeometriesSolidLod1() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
Geometry geom = GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD1);
AbstractBridge ab = new Bridge();
bo.setGmlObject(ab);
......@@ -228,7 +228,7 @@ public class BridgeObjectTest {
@Test
public void testReCreateGeometriesSolidLod2() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
Geometry geom = GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD2);
AbstractBridge ab = new Bridge();
bo.setGmlObject(ab);
......@@ -242,7 +242,7 @@ public class BridgeObjectTest {
@Test
public void testReCreateGeometriesSolidLod3() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
Geometry geom = GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD3);
AbstractBridge ab = new Bridge();
bo.setGmlObject(ab);
......@@ -256,7 +256,7 @@ public class BridgeObjectTest {
@Test
public void testReCreateGeometriesSolidLod4() {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, mock(AbstractBridge.class));
BridgeObject bo = new BridgeObject(mock(AbstractBridge.class));
Geometry geom = GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD4);
AbstractBridge ab = new Bridge();
bo.setGmlObject(ab);
......@@ -273,7 +273,7 @@ public class BridgeObjectTest {
AbstractBridge abMock = mock(AbstractBridge.class);
DeprecatedPropertiesOfAbstractBridge propsMock = mock(DeprecatedPropertiesOfAbstractBridge.class);
when(abMock.getDeprecatedProperties()).thenReturn(propsMock);
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, abMock);
BridgeObject bo = new BridgeObject(abMock);
BoundarySurface bsMock = mock(BoundarySurface.class);
bo.addBoundarySurface(bsMock);
......@@ -293,14 +293,14 @@ public class BridgeObjectTest {
@Test
public void testGetFeatureType() {
AbstractBridge abMock = mock(AbstractBridge.class);
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, abMock);
BridgeObject bo = new BridgeObject(abMock);
assertEquals(FeatureType.BRIDGE, bo.getFeatureType());
}
@Test
public void testGetType() {
AbstractBridge abMock = mock(AbstractBridge.class);
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, abMock);
BridgeObject bo = new BridgeObject( abMock);
assertEquals(BridgeType.BRIDGE, bo.getType());
bo.setType(BridgeType.BRIDGE_PART);
assertEquals(BridgeType.BRIDGE_PART, bo.getType());
......@@ -309,7 +309,7 @@ public class BridgeObjectTest {
@Test
public void testGetGmlObject() {
AbstractBridge abMock = mock(AbstractBridge.class);
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, abMock);
BridgeObject bo = new BridgeObject(abMock);
assertEquals(abMock, bo.getGmlObject());
AbstractBridge abMock2 = mock(AbstractBridge.class);
bo.setGmlObject(abMock2);
......
......@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
......@@ -30,16 +31,21 @@ import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.citygml4j.core.model.deprecated.core.DeprecatedPropertiesOfAbstractCityObject;
import org.citygml4j.core.model.deprecated.core.DeprecatedPropertiesOfAbstractThematicSurface;
import org.citygml4j.core.model.deprecated.transportation.DeprecatedPropertiesOfAbstractTransportationSpace;
import org.citygml4j.core.model.deprecated.transportation.TransportationComplex;
import org.citygml4j.core.model.transportation.AuxiliaryTrafficArea;
import org.citygml4j.core.model.transportation.AuxiliaryTrafficSpace;
import org.citygml4j.core.model.transportation.AuxiliaryTrafficSpaceProperty;
import org.citygml4j.core.model.transportation.Intersection;
import org.citygml4j.core.model.transportation.Railway;
import org.citygml4j.core.model.transportation.Road;
import org.citygml4j.core.model.transportation.Section;
import org.citygml4j.core.model.transportation.Square;
import org.citygml4j.core.model.transportation.Track;
import org.citygml4j.core.model.transportation.TrafficArea;
import org.citygml4j.core.model.transportation.TrafficSpace;
import org.citygml4j.core.model.transportation.Waterway;
import org.citygml4j.core.util.geometry.GeometryFactory;
import org.junit.Test;
import org.mockito.Mockito;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import de.hft.stuttgart.citydoctor2.check.CheckError;
......@@ -53,227 +59,477 @@ public class TransportationObjectTest {
@Test
public void testGetFeatureType() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
TopLevelTransportFeature to = TopLevelTransportFeature.from(Mockito.mock(Road.class));
assertEquals(FeatureType.TRANSPORTATION, to.getFeatureType());
}
@Test
public void testObjectConstruction() {
TopLevelTransportFeature road = TopLevelTransportFeature.from(Mockito.mock(Road.class));
assertEquals(TransportationType.ROAD, road.getTransportationType());
TopLevelTransportFeature track = TopLevelTransportFeature.from(Mockito.mock(Track.class));
assertEquals(TransportationType.TRACK, track.getTransportationType());
TopLevelTransportFeature waterway = TopLevelTransportFeature.from(Mockito.mock(Waterway.class));
assertEquals(TransportationType.WATERWAY, waterway.getTransportationType());
TopLevelTransportFeature railway = TopLevelTransportFeature.from(Mockito.mock(Railway.class));
assertEquals(TransportationType.RAILWAY, railway.getTransportationType());
TopLevelTransportFeature square = TopLevelTransportFeature.from(Mockito.mock(Square.class));
assertEquals(TransportationType.SQUARE, square.getTransportationType());
}
@Test(expected = IllegalStateException.class)
public void testReCreateGeometriesSolid() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
TopLevelTransportFeature to = TopLevelTransportFeature.from(Mockito.mock(Road.class));
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD1));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
}
@Test
public void testReCreateGeometriesWithComposedOf() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
TransportationComplex tcMock = new TransportationComplex();
to.setGmlObject(tcMock);
TransportationObject ataTo = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_SPACE);
AuxiliaryTrafficSpace ataMock = mock(AuxiliaryTrafficSpace.class);
ataTo.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
ataTo.setGmlObject(ataMock);
tcMock.getAuxiliaryTrafficSpaces().add(new AuxiliaryTrafficSpaceProperty(ataMock));
to.addChild(ataTo);
public void testReCreateGeometriesTransportationSpace() {
Road roadMock = mock(Road.class);
TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
top.setGmlObject(roadMock);
TransportSection sectionMock = Mockito.mock(TransportSection.class);
TransportSection intersectionMock = Mockito.mock(TransportSection.class);
TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class);
TrafficSpaceObject auxTsMock = Mockito.mock(TrafficSpaceObject.class);
top.addSection(sectionMock);
top.addIntersection(intersectionMock);
top.addTrafficSpace(tsMock);
top.addAuxTrafficSpace(auxTsMock);
top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(ataMock).setLod2MultiSurface(any());
top.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(roadMock).setLod2MultiSurface(any());
verify(sectionMock).reCreateGeometries(any(), any());
verify(intersectionMock).reCreateGeometries(any(), any());
verify(tsMock).reCreateGeometries(any(), any());
verify(auxTsMock).reCreateGeometries(any(), any());
}
@Test
public void testReCreateGeometriesTrafficSpace() {
TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficSpace tsMock = mock(TrafficSpace.class);
tso.setGmlObject(tsMock);
TrafficAreaObject taoMock = Mockito.mock(TrafficAreaObject.class);
tso.addTrafficArea(taoMock);
tso.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
GeometryFactory factory = GeometryFactory.newInstance();
tso.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(tsMock).setLod2MultiSurface(any());
verify(taoMock).reCreateGeometries(any(), any());
}
@Test
public void testReCreateGeometriesTrafficArea() {
TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea taMock = mock(TrafficArea.class);
tao.setGmlObject(taMock);
tao.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
GeometryFactory factory = GeometryFactory.newInstance();
tao.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(taMock).setLod2MultiSurface(any());
}
@Test
public void testReCreateGeometriesMultiSurfaceLod0() {
Road roadMock = mock(Road.class);
TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
top.setGmlObject(roadMock);
TrafficSpaceObject ts = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficSpace trafficSpaceMock = mock(TrafficSpace.class);
ts.setGmlObject(trafficSpaceMock);
TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea trafficAreaMock = mock(TrafficArea.class);
ta.setGmlObject(trafficAreaMock);
top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0));
ts.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0));
ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0));
GeometryFactory factory = GeometryFactory.newInstance();
top.reCreateGeometries(factory, mock(ParserConfiguration.class));
ts.reCreateGeometries(factory, mock(ParserConfiguration.class));
ta.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(roadMock).setLod0MultiSurface(any());
verify(trafficSpaceMock).setLod0MultiSurface(any());
verify(trafficAreaMock).setLod0MultiSurface(any());
}
@Test
public void testReCreateGeometriesMultiSurfaceLod1() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
Road roadMock = mock(Road.class);
TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
top.setGmlObject(roadMock);
TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea trafficAreaMock = mock(TrafficArea.class);
ta.setGmlObject(trafficAreaMock);
DeprecatedPropertiesOfAbstractTransportationSpace dSpace = mock(DeprecatedPropertiesOfAbstractTransportationSpace.class);
when(roadMock.getDeprecatedProperties()).thenReturn(dSpace);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1));
try {
top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1));
} catch (IllegalArgumentException e) {
fail("Casting of original GML object to AbstractTransportationSpace should work");
}
ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
top.reCreateGeometries(factory, mock(ParserConfiguration.class));
ta.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(dSpace).setLod1MultiSurface(any());
verify(trafficAreaMock).setLod1MultiSurface(any());
}
@Test
public void testReCreateGeometriesMultiSurfaceLod2() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
Road roadMock = mock(Road.class);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
top.setGmlObject(roadMock);
TrafficSpaceObject ts = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficSpace trafficSpaceMock = mock(TrafficSpace.class);
ts.setGmlObject(trafficSpaceMock);
TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea trafficAreaMock = mock(TrafficArea.class);
ta.setGmlObject(trafficAreaMock);
top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
ts.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
top.reCreateGeometries(factory, mock(ParserConfiguration.class));
ts.reCreateGeometries(factory, mock(ParserConfiguration.class));
ta.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(roadMock).setLod2MultiSurface(any());
verify(trafficSpaceMock).setLod2MultiSurface(any());
verify(trafficAreaMock).setLod2MultiSurface(any());
}
@Test
public void testReCreateGeometriesMultiSurfaceLod3() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
Road roadMock = mock(Road.class);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3));
TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
top.setGmlObject(roadMock);
TrafficSpaceObject ts = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficSpace trafficSpaceMock = mock(TrafficSpace.class);
ts.setGmlObject(trafficSpaceMock);
TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea trafficAreaMock = mock(TrafficArea.class);
ta.setGmlObject(trafficAreaMock);
top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3));
ts.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3));
ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
top.reCreateGeometries(factory, mock(ParserConfiguration.class));
ts.reCreateGeometries(factory, mock(ParserConfiguration.class));
ta.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(roadMock).setLod3MultiSurface(any());
verify(trafficSpaceMock).setLod3MultiSurface(any());
verify(trafficAreaMock).setLod3MultiSurface(any());
}
@Test
public void testReCreateGeometriesMultiSurfaceLod4() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
Road roadMock = mock(Road.class);
TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
top.setGmlObject(roadMock);
TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea trafficAreaMock = mock(TrafficArea.class);
ta.setGmlObject(trafficAreaMock);
DeprecatedPropertiesOfAbstractTransportationSpace dSpace = mock(DeprecatedPropertiesOfAbstractTransportationSpace.class);
when(roadMock.getDeprecatedProperties()).thenReturn(dSpace);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4));
DeprecatedPropertiesOfAbstractThematicSurface dArea = mock(DeprecatedPropertiesOfAbstractThematicSurface.class);
when(trafficAreaMock.getDeprecatedProperties()).thenReturn(dArea);
ta.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4));
try {
top.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4));
} catch (IllegalArgumentException e) {
fail("Casting of original GML object to AbstractTransportationSpace should work");
}
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
top.reCreateGeometries(factory, mock(ParserConfiguration.class));
ta.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(dSpace).setLod4MultiSurface(any());
verify(dArea).setLod4MultiSurface(any());
}
@Test(expected = IllegalStateException.class)
public void testReCreateGeometriesMultiSurfaceLod0() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
@Test
public void testContainsErrorTransportationSpace() {
Road roadMock = mock(Road.class);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
top.setGmlObject(roadMock);
TransportSection sectionMock = Mockito.mock(TransportSection.class);
TransportSection intersectionMock = Mockito.mock(TransportSection.class);
TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class);
TrafficSpaceObject auxTsMock = Mockito.mock(TrafficSpaceObject.class);
top.addSection(sectionMock);
top.addIntersection(intersectionMock);
top.addTrafficSpace(tsMock);
top.addAuxTrafficSpace(auxTsMock);
top.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(top.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
assertFalse(top.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED));
verify(sectionMock).containsError(any());
verify(intersectionMock).containsError(any());
verify(tsMock).containsError(any());
verify(auxTsMock).containsError(any());
}
@Test(expected = IllegalStateException.class)
public void testReCreateGeometriesTrafficAreaMultiSurfaceLod1() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
TrafficArea roadMock = mock(TrafficArea.class);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
@Test
public void testContainsErrorTrafficSpace() {
TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficSpace tsMock = mock(TrafficSpace.class);
tso.setGmlObject(tsMock);
TrafficAreaObject taMock = mock(TrafficAreaObject.class);
tso.addTrafficArea(taMock);
tso.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
assertFalse(tso.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED));
verify(taMock).containsError(any());
}
@Test
public void testReCreateGeometriesTrafficAreaMultiSurfaceLod2() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
TrafficArea roadMock = mock(TrafficArea.class);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(roadMock).setLod2MultiSurface(any());
public void testContainsErrorTrafficArea() {
TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea taMock = mock(TrafficArea.class);
tao.setGmlObject(taMock);
tao.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(tao.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
assertFalse(tao.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED));
}
@Test
public void testReCreateGeometriesTrafficAreaMultiSurfaceLod3() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
TrafficArea roadMock = mock(TrafficArea.class);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(roadMock).setLod3MultiSurface(any());
public void testClearAllContainedCheckResultsTransportationSpace() {
Road roadMock = mock(Road.class);
TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
top.setGmlObject(roadMock);
TransportSection sectionMock = Mockito.mock(TransportSection.class);
TransportSection intersectionMock = Mockito.mock(TransportSection.class);
TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class);
TrafficSpaceObject auxTsMock = Mockito.mock(TrafficSpaceObject.class);
top.addSection(sectionMock);
top.addIntersection(intersectionMock);
top.addTrafficSpace(tsMock);
top.addAuxTrafficSpace(auxTsMock);
assertFalse(top.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
top.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(top.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
top.clearAllContainedCheckResults();
assertFalse(top.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
verify(sectionMock).clearAllContainedCheckResults();
verify(intersectionMock).clearAllContainedCheckResults();
verify(tsMock).clearAllContainedCheckResults();
verify(auxTsMock).clearAllContainedCheckResults();
}
@Test
public void testReCreateGeometriesTrafficAreaMultiSurfaceLod4() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
TrafficArea roadMock = mock(TrafficArea.class);
DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class);
when(roadMock.getDeprecatedProperties()).thenReturn(dSpace);
to.setGmlObject(roadMock);
to.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4));
GeometryFactory factory = GeometryFactory.newInstance();
to.reCreateGeometries(factory, mock(ParserConfiguration.class));
verify(dSpace).setLod4MultiSurface(any());
public void testClearAllContainedCheckResultsTrafficSpace() {
TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficSpace tsMock = mock(TrafficSpace.class);
tso.setGmlObject(tsMock);
TrafficAreaObject taMock = mock(TrafficAreaObject.class);
tso.addTrafficArea(taMock);
assertFalse(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
tso.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
tso.clearAllContainedCheckResults();
assertFalse(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
verify(taMock).clearAllContainedCheckResults();
}
@Test
public void testContainsError() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
to.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
assertFalse(to.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED));
public void testClearAllContainedCheckResultsTrafficArea() {
TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea taMock = mock(TrafficArea.class);
tao.setGmlObject(taMock);
assertFalse(tao.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
tao.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(tao.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
tao.clearAllContainedCheckResults();
assertFalse(tao.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
}
@Test
public void testContainsErrorInComposesOf() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
TransportationObject to2 = new TransportationObject(TransportationType.TRACK);
to.addChild(to2);
to2.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
assertFalse(to.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED));
public void testCollectContainedErrorsTransportationSpace() {
Road roadMock = mock(Road.class);
TopLevelTransportFeature top = TopLevelTransportFeature.from(roadMock);
top.setGmlObject(roadMock);
TransportSection sectionMock = Mockito.mock(TransportSection.class);
TransportSection intersectionMock = Mockito.mock(TransportSection.class);
TrafficSpaceObject tsMock = Mockito.mock(TrafficSpaceObject.class);
TrafficSpaceObject auxTsMock = Mockito.mock(TrafficSpaceObject.class);
top.addSection(sectionMock);
top.addIntersection(intersectionMock);
top.addTrafficSpace(tsMock);
top.addAuxTrafficSpace(auxTsMock);
top.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
List<CheckError> errors = new ArrayList<>();
top.collectContainedErrors(errors);
assertEquals(1, errors.size());
verify(sectionMock).collectContainedErrors(errors);
verify(intersectionMock).collectContainedErrors(errors);
verify(tsMock).collectContainedErrors(errors);
verify(auxTsMock).collectContainedErrors(errors);
}
@Test
public void testClearAllContainedCheckResults() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
TransportationObject to2 = mock(TransportationObject.class);
to.addChild(to2);
assertFalse(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
to.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
to.clearAllContainedCheckResults();
assertFalse(to.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
verify(to2).clearAllContainedCheckResults();
public void testCollectContainedErrorsTrafficSpace() {
TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficSpace tsMock = mock(TrafficSpace.class);
tso.setGmlObject(tsMock);
TrafficAreaObject taMock = mock(TrafficAreaObject.class);
tso.addTrafficArea(taMock);
tso.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
List<CheckError> errors = new ArrayList<>();
tso.collectContainedErrors(errors);
assertEquals(1, errors.size());
verify(taMock).collectContainedErrors(errors);
}
@Test
public void testCollectContainedErrors() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
TransportationObject to2 = mock(TransportationObject.class);
to.addChild(to2);
to.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
public void testCollectContainedErrorsTrafficArea() {
TrafficAreaObject tao = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea taMock = mock(TrafficArea.class);
tao.setGmlObject(taMock);
tao.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
List<CheckError> errors = new ArrayList<>();
to.collectContainedErrors(errors);
tao.collectContainedErrors(errors);
assertEquals(1, errors.size());
verify(to2).collectContainedErrors(errors);
}
@Test
public void testUnsetGmlGeometriesRoad() {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
public void testUnsetGmlGeometriesTransportationSpace() {
Road r = mock(Road.class);
to.setGmlObject(r);
TopLevelTransportFeature top = TopLevelTransportFeature.from(r);
top.setGmlObject(r);
TransportSection mockSection = mock(TransportSection.class);
TransportSection mockInterestSection = mock(TransportSection.class);
TrafficSpaceObject mockSpace = mock(TrafficSpaceObject.class);
TrafficSpaceObject auxMockSpace = mock(TrafficSpaceObject.class);
top.addSection(mockSection);
top.addIntersection(mockInterestSection);
top.addTrafficSpace(mockSpace);
top.addAuxTrafficSpace(auxMockSpace);
DeprecatedPropertiesOfAbstractTransportationSpace dSpace = mock(DeprecatedPropertiesOfAbstractTransportationSpace.class);
when(r.getDeprecatedProperties()).thenReturn(dSpace);
dSpace.setLod1MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod2MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod3MultiSurface(mock(MultiSurfaceProperty.class));
dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class));
to.unsetGmlGeometries();
top.unsetGmlGeometries();
assertNull(dSpace.getLod1MultiSurface());
assertNull(r.getLod2MultiSurface());
assertNull(r.getLod3MultiSurface());
assertNull(dSpace.getLod4MultiSurface());
verify(mockSection).unsetGmlGeometries();
verify(mockInterestSection).unsetGmlGeometries();
verify(mockSpace).unsetGmlGeometries();
verify(auxMockSpace).unsetGmlGeometries();
}
@Test
public void testUnsetGmlGeometriesTrafficArea() {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
TrafficArea r = mock(TrafficArea.class);
to.setGmlObject(r);
DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class);
when(r.getDeprecatedProperties()).thenReturn(dSpace);
r.setLod2MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod3MultiSurface(mock(MultiSurfaceProperty.class));
dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class));
to.unsetGmlGeometries();
assertNull(r.getLod2MultiSurface());
assertNull(r.getLod3MultiSurface());
assertNull(dSpace.getLod4MultiSurface());
public void testUnsetGmlGeometriesTrafficSpace() {
TrafficSpaceObject tso = new TrafficSpaceObject(TrafficSpaceObject.TrafficSpaceType.TRAFFIC_SPACE);
TrafficSpace t = mock(TrafficSpace.class);
tso.setGmlObject(t);
TrafficAreaObject mockArea = mock(TrafficAreaObject.class);
tso.addTrafficArea(mockArea);
DeprecatedPropertiesOfAbstractCityObject dSpace = mock(DeprecatedPropertiesOfAbstractCityObject.class);
when(t.getDeprecatedProperties()).thenReturn(dSpace);
t.setLod0MultiSurface(mock(MultiSurfaceProperty.class));
t.setLod2MultiSurface(mock(MultiSurfaceProperty.class));
t.setLod3MultiSurface(mock(MultiSurfaceProperty.class));
tso.unsetGmlGeometries();
assertNull(t.getLod0MultiSurface());
assertNull(t.getLod2MultiSurface());
assertNull(t.getLod3MultiSurface());
verify(mockArea).unsetGmlGeometries();
}
@Test
public void testUnsetGmlGeometriesAuxilliaryTrafficArea() {
TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_AREA);
AuxiliaryTrafficArea r = mock(AuxiliaryTrafficArea.class);
to.setGmlObject(r);
public void testUnsetGmlGeometriesTrafficArea() {
TrafficAreaObject ta = new TrafficAreaObject(TrafficAreaObject.TrafficAreaType.TRAFFIC_AREA);
TrafficArea r = mock(TrafficArea.class);
ta.setGmlObject(r);
DeprecatedPropertiesOfAbstractThematicSurface dSpace = mock(DeprecatedPropertiesOfAbstractThematicSurface.class);
when(r.getDeprecatedProperties()).thenReturn(dSpace);
r.setLod0MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod1MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod2MultiSurface(mock(MultiSurfaceProperty.class));
r.setLod3MultiSurface(mock(MultiSurfaceProperty.class));
dSpace.setLod4MultiSurface(mock(MultiSurfaceProperty.class));
to.unsetGmlGeometries();
ta.unsetGmlGeometries();
assertNull(r.getLod0MultiSurface());
assertNull(r.getLod1MultiSurface());
assertNull(r.getLod2MultiSurface());
assertNull(r.getLod3MultiSurface());
assertNull(dSpace.getLod4MultiSurface());
......
package de.hft.stuttgart.citydoctor2.zip;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class ZipTest {
ParserConfiguration config = new ParserConfiguration(8, false);
@Test
public void testUnzipping() throws MalformedZipFileException {
CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/mock_archive.zip");
assertNotNull(cgmlArch);
cgmlArch.mountArchive(config);
checkMockArchive(cgmlArch);
}
private void checkMockArchive(CityGmlZipArchive cgmlArch) {
assertEquals(5, cgmlArch.getEntries().size());
for (CityGmlZipEntry entry : cgmlArch.getEntries()) {
assertNotNull(entry);
assertTrue(entry.getEntrySubPath().matches("^mock[1-5].gml$"));
assertNull(entry.getErrorType());
assertNotNull(entry.getModel());
assertEquals(1, entry.getModel().getNumberOfFeatures());
}
}
@Test
public void testZipping() throws IOException {
CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/mock_archive.zip");
assertNotNull(cgmlArch);
cgmlArch.mountArchive(config);
Path tmpDir = null;
try {
tmpDir = Files.createTempDirectory("testTmp");
tmpDir.toFile().deleteOnExit();
String expPath = tmpDir + "/export.zip";
cgmlArch.exportToZipFile(expPath);
CityGmlZipArchive cgmlExport = CityGmlZipArchive.register(expPath);
assertNotNull(cgmlExport);
cgmlExport.mountArchive(config);
checkMockArchive(cgmlExport);
} finally {
if (tmpDir != null) {
FileUtils.deleteDirectory(tmpDir.toFile());
}
}
}
@Test
public void testEpsgParsing() throws MalformedZipFileException {
CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/epsg.zip");
assertNotNull(cgmlArch);
cgmlArch.mountArchive(config);
CityGmlZipEntry entry = cgmlArch.getEntry("epsg1.gml");
assertNotNull(entry);
String srsName = entry.getModel().getCityModel().getBoundedBy().getEnvelope().getSrsName().split(":")[6];
assertEquals("25832", srsName);
entry = cgmlArch.getEntry("epsg2.gml");
assertNotNull(entry);
srsName = entry.getModel().getCityModel().getBoundedBy().getEnvelope().getSrsName().split(":")[6];
assertEquals("7415", srsName);
}
@Test
public void testXMLValidation() throws MalformedZipFileException {
ParserConfiguration valConfig = new ParserConfiguration(8, true);
CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/validate.zip");
assertNotNull(cgmlArch);
cgmlArch.mountArchive(valConfig);
assertNull(cgmlArch.getEntry("valCorrect.gml").getErrorType());
assertEquals(ZipEntryErrorType.INVALID_CITY_GML_FILE, cgmlArch.getEntry("valFaulty.gml").getErrorType());
}
@Test
public void testImplicitParsing() throws MalformedZipFileException {
CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/implicit.zip");
assertNotNull(cgmlArch);
cgmlArch.mountArchive(config);
CityDoctorModel mainModel = cgmlArch.getEntry("Main_model.gml").getModel();
assertEquals(18, mainModel.getGenericCityObjects().size());
}
}
File added
<?xml version="1.0" encoding="utf-8"?>
<core:CityModel xmlns:core="http://www.opengis.net/citygml/2.0" xmlns:gen="http://www.opengis.net/citygml/generics/2.0" xmlns:bldg="http://www.opengis.net/citygml/building/2.0" xmlns:app="http://www.opengis.net/citygml/appearance/2.0" xmlns:dem="http://www.opengis.net/citygml/relief/2.0" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/citygml/building/2.0 http://schemas.opengis.net/citygml/building/2.0/building.xsd http://www.opengis.net/citygml/appearance/2.0 http://schemas.opengis.net/citygml/appearance/2.0/appearance.xsd http://www.opengis.net/citygml/relief/2.0 http://schemas.opengis.net/citygml/relief/2.0/relief.xsd http://www.opengis.net/citygml/2.0 http://schemas.opengis.net/citygml/2.0/cityGMLBase.xsd http://www.opengis.net/citygml/generics/2.0 http://schemas.opengis.net/citygml/generics/2.0/generics.xsd">
<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: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