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

Merge branch 'dev_GUI' into 'dev'

Open source release of CityDoctorGUI and other extensions.

See merge request !6
parents 12d96d95 5a4d0a74
Pipeline #10056 passed with stage
in 1 minute and 6 seconds
package de.hft.stuttgart.citydoctor2.webservice.endpoints;
public class LoginValues {
private String token;
private int id;
public LoginValues(String token, int id) {
super();
this.token = token;
this.id = id;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package de.hft.stuttgart.citydoctor2.webservice.endpoints;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import javax.ws.rs.core.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.HttpClients;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.junit.Ignore;
import org.junit.Test;
public class ModelsEndpointTest {
@Test
public void testRetrievingModels() throws ClientProtocolException, IOException {
HttpClient client = HttpClients.createMinimal();
LoginValues login = TestUtils.login(client);
HttpGet get = new HttpGet("http://localhost:8080/CityDoctorWebService/rest/models");
get.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + login.getToken());
HttpResponse response = client.execute(get);
assertEquals(200, response.getStatusLine().getStatusCode());
JSONTokener tokener = TestUtils.tokenizeReponse(response);
JSONArray models = new JSONArray(tokener);
for (Object o : models) {
assertTrue(o instanceof JSONObject);
}
assertNotNull(models);
}
@Test
public void testUploadModel() throws ClientProtocolException, IOException {
HttpClient client = HttpClients.createMinimal();
LoginValues login = TestUtils.login(client);
HttpPost post = new HttpPost("http://localhost:8080/CityDoctorWebService/rest/models");
post.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + login.getToken());
File file = new File("C:\\Job\\CityGML Files\\1-stoeckach_multisurface_only.xml");
// File configFile = new File("src\\test\\resources\\testConfig.yml");
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
entityBuilder.addBinaryBody("file", file);
// entityBuilder.addBinaryBody("configFile", configFile);
post.setEntity(entityBuilder.build());
HttpResponse response = client.execute(post);
int httpStatus = response.getStatusLine().getStatusCode();
assertEquals(200, httpStatus);
JSONTokener tokener = TestUtils.tokenizeReponse(response);
JSONObject model = new JSONObject(tokener);
assertNotNull(model);
assertEquals("1-stoeckach_multisurface_only.xml", model.getString("name"));
}
@Ignore
@Test
public void downloadPdfFile() throws ClientProtocolException, IOException {
HttpClient client = HttpClients.createMinimal();
LoginValues login = TestUtils.login(client);
HttpGet get = new HttpGet(
"http://localhost:8080/CityDoctorWebService/rest/" + login.getId() + "/models/15/pdf");
get.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + login.getToken());
HttpResponse response = client.execute(get);
assertEquals(200, response.getStatusLine().getStatusCode());
Path path = Files.createTempFile(null, null);
Files.copy(response.getEntity().getContent(), path, StandardCopyOption.REPLACE_EXISTING);
assertTrue(path.toFile().exists());
}
@Ignore
@Test
public void downloadXmlFile() throws ClientProtocolException, IOException {
HttpClient client = HttpClients.createMinimal();
LoginValues login = TestUtils.login(client);
HttpGet get = new HttpGet(
"http://localhost:8080/CityDoctorWebService/rest/" + login.getId() + "/models/15/xml");
get.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + login.getToken());
HttpResponse response = client.execute(get);
assertEquals(200, response.getStatusLine().getStatusCode());
Path path = Files.createTempFile(null, null);
Files.copy(response.getEntity().getContent(), path, StandardCopyOption.REPLACE_EXISTING);
assertTrue(path.toFile().exists());
}
@Test
public void testGetBuildings() throws ClientProtocolException, IOException {
HttpClient client = HttpClients.createMinimal();
LoginValues login = TestUtils.login(client);
HttpGet get = new HttpGet("http://localhost:8080/CityDoctorWebService/rest/models/5/buildings?from=0");
get.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + login.getToken());
HttpResponse response = client.execute(get);
String readCompleteReponse = TestUtils.readCompleteReponse(response);
System.out.println(readCompleteReponse);
// JSONTokener tokener = TestUtils.tokenizeReponse(response);
// JSONArray models = new JSONArray(tokener);
// for (Object o : models) {
// System.out.println(o);
// }
}
}
package de.hft.stuttgart.citydoctor2.webservice.endpoints;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.junit.Test;
import de.hft.stuttgart.citydoctor2.webservice.database.UserQueries;
import de.hft.stuttgart.citydoctor2.webservice.utils.HibernateUtils;
public class RegisterEndpointTest {
@Test
public void testRegisterExistingUser() throws ClientProtocolException, IOException {
HttpClient client = HttpClients.createMinimal();
HttpPost post = new HttpPost("http://localhost:8080/CityDoctorWebService/rest/register");
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("username", "Test"));
params.add(new BasicNameValuePair("password", "TestPassword"));
post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpResponse response = client.execute(post);
assertEquals(409, response.getStatusLine().getStatusCode());
}
@Test
public void testRegisterNewUser() throws ClientProtocolException, IOException {
HttpClient client = HttpClients.createMinimal();
HttpPost post = new HttpPost("http://localhost:8080/CityDoctorWebService/rest/register");
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("username", "TestNotExisting"));
params.add(new BasicNameValuePair("password", "TestPassword"));
post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpResponse response = client.execute(post);
assertEquals(200, response.getStatusLine().getStatusCode());
EntityManager manager = HibernateUtils.createManager();
UserQueries.deleteUser(UserQueries.getUserForUsername("TestNotExisting", manager), manager);
manager.close();
}
}
package de.hft.stuttgart.citydoctor2.webservice.endpoints;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
public class TestUtils {
private TestUtils() {
// only static use
}
public static LoginValues login(HttpClient client) throws ClientProtocolException, IOException {
HttpPost post = new HttpPost("http://localhost:8080/CityDoctorWebService/rest/login");
List<NameValuePair> params = new ArrayList<>(2);
params.add(new BasicNameValuePair("username", "Test"));
params.add(new BasicNameValuePair("password", "TestPassword"));
post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpResponse response = client.execute(post);
String text = readCompleteReponse(response);
try {
JSONTokener tokener = new JSONTokener(text);
JSONObject o = new JSONObject(tokener);
String token = o.getString("token");
int id = o.getInt("userId");
return new LoginValues(token, id);
} catch (JSONException e) {
System.out.println(text);
throw e;
}
}
public static String readCompleteReponse(HttpResponse response) throws IOException {
InputStreamReader reader = new InputStreamReader(response.getEntity().getContent());
char[] buffer = new char[1000];
int readChars = -1;
StringBuilder sb = new StringBuilder();
while ((readChars = reader.read(buffer)) != -1) {
sb.append(buffer, 0, readChars);
}
return sb.toString();
}
public static JSONTokener tokenizeReponse(HttpResponse response) throws IOException {
return new JSONTokener(readCompleteReponse(response));
}
}
package de.hft.stuttgart.citydoctor2.webservice.endpoints;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import javax.ws.rs.core.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.junit.Test;
public class ValidationEndpointTest {
@Test
public void testRetrieveXmlReport() throws ClientProtocolException, IOException {
HttpClient client = HttpClients.createMinimal();
LoginValues login = TestUtils.login(client);
HttpGet get = new HttpGet("http://localhost:8080/CityDoctorWebService/rest/models/validations/5/xml");
get.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + login.getToken());
HttpResponse response = client.execute(get);
File file = new File("C:/WebService/test.xml");
Files.copy(response.getEntity().getContent(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
assertTrue(file.exists());
}
@Test
public void testRetrievePdfReport() throws ClientProtocolException, IOException {
HttpClient client = HttpClients.createMinimal();
LoginValues login = TestUtils.login(client);
HttpGet get = new HttpGet("http://localhost:8080/CityDoctorWebService/rest/models/validations/5/pdf");
get.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + login.getToken());
HttpResponse response = client.execute(get);
File file = new File("C:/WebService/test.pdf");
Files.copy(response.getEntity().getContent(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
assertTrue(file.exists());
}
}
minVertexDistance: 1.0E-4
useStreaming: false
xmlValidation: false
checks:
C_GE_R_TOO_FEW_POINTS:
enabled: true
C_GE_R_NOT_CLOSED:
enabled: true
C_GE_R_DUPLICATE_POINT:
enabled: true
C_GE_R_SELF_INTERSECTION:
enabled: true
C_GE_S_MULTIPLE_CONNECTED_COMPONENTS:
enabled: true
C_GE_P_INTERIOR_DISCONNECTED:
enabled: true
C_GE_P_INTERSECTING_RINGS:
enabled: true
C_GE_P_NON_PLANAR:
enabled: false
parameters:
# one of ("distance", "angle", "both")
type: distance
distanceTolerance: 0.01
angleTolerance: 0.1
C_GE_P_HOLE_OUTSIDE:
enabled: true
C_GE_P_ORIENTATION_RINGS_SAME:
enabled: true
C_GE_P_INNER_RINGS_NESTED:
enabled: true
C_GE_S_TOO_FEW_POLYGONS:
enabled: true
C_GE_S_NOT_CLOSED:
enabled: true
C_GE_S_NON_MANIFOLD_EDGE:
enabled: true
C_GE_S_POLYGON_WRONG_ORIENTATION:
enabled: true
C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION:
enabled: true
C_GE_S_NON_MANIFOLD_VERTEX:
enabled: true
C_GE_S_SELF_INTERSECTION:
enabled: true
\ No newline at end of file
# CityDoctor2 Extensions
Extension modules to the core functionality of CityDoctor2.
# Loading
Except for CityDoctorGUI, all extension modules are not loaded into the Maven project by default.
Loading an extension module can be done by either loading the Maven module directly, or by adjusting the CityDoctorParent
pom.xml and moving the respective modules out of the comment-block in the module list found at the end of the file.
# Building
If the modules are loaded by including them in the CityDoctorParent pom, Maven will
automatically build them while building CityDoctor2.
If the modules are loaded directly, they need to be built directly with Maven.
After building, the jars can be found in the **/target** subdirectory of each respective extension module.
# Module Information
## CityDoctorAutoPro
![Maintenance Level: Deprecated](../resources/Badges/MaintenanceLevel_Deprecated.svg)
The AutoPro (short for automated processing) module is an interface for the conversion of the internal data model to a C++
representation, to allow use of advanced functionalities of CGAL with CityDoctor2.
### Usage
> ⚠ The AutoPro module is deprecated and will be removed in a future release, once the CGAL functionalities have been ported to Java.
AutoPro requires a collection of .dll-files to run, some of which are not available as FOSS and thus cannot be
distributed with this project.
Access to the collection, or information about the required .dll-files, can be granted upon request for a valid reason.
Contact a Maintainer of this project for further information in this regard.
---
## CityDoctorGUI
![Maintenance Level: Actively Maintained](../resources/Badges/MaintenanceLevel_ActivelyMaintained.svg)
The GUI module offers a graphical user interface for CityDoctor2, including a model viewer allowing for visual
inspection of validation results and found errors.
### View-Plugins
The GUI is expandable via plugins, enabling the creation of views for custom functionalities or extensions of the CityDoctor2 core.
Custom views can be created by extending the Abstract class `View` of the CityDoctorGUI and need to be registered by calling
`ViewRegistration.registerView(View view);` before starting the GUI.
### Usage
> ⚠ CityDoctorGUI requires a JDK/JRE containing the JavaFX library to run.
Prebuilt binaries for the GUI are available in [CityDoctorReleases](https://transfer.hft-stuttgart.de/gitlab/citydoctor/citydoctorreleases).
After extracting the archive the GUI can be started with **start.bat**.
Binaries can be built with Maven using the create-binaries profile from the CityDoctorParent directory:
```
mvn install -P create-binaries
```
Lastly, the GUI can also be started by calling `MainWindow.main(args[])`.
---
## CityDoctorHealer
![Maintenance Level: Inactively Maintained](../resources/Badges/MaintenanceLevel_InactivelyMaintained.svg)
CityDoctorHealer implements functionalities for the automated repair of geometries containing errors.
The healer uses naive approaches to fix geometrical errors, and thus, it cannot be guaranteed that semantical
correctness is maintained after the healing process.
### Usage
Usage of CityDoctorHealer is similar to [CityDoctor](https://transfer.hft-stuttgart.de/gitlab/citydoctor/citydoctor2/-/tree/dev_GUI#usage).
An example start command looks like this:
```
java -classpath libs/*;plugins/*;CityDoctorHealer-<version>.jar de.hft.stuttgart.citydoctor2.CityDoctorHealer -in <path-to-gml-file>.gml -config <path-to-validation-config>.yml -xmlReport <path-to-xml-output>.xml -pdfReport <path-to-pdf-output>.pdf -out <path-to-output-gml>.gml
```
Note: Unlike CityDoctor core, the _-out_ argument is required.
The -xml-output and -pdfReport arguments are still optional.
To prevent infinite loops the `Healer` class has a limit for the number of healing iterations (default: 200). This limit
can be changed by calling `Healer.setNumberOfIterations(int limit)`.
---
## CityDoctorHealerGenetic
![Maintenance Level: Abandoned](../resources/Badges/MaintenanceLevel_Abandoned.svg)
CityDoctorHealerGenetic uses a genetical algorithm to establish an optimal CityDoctorHealer healing-plan for geometries containing errors.
### Usage
> ⚠ This module has been abandoned. As of writing the module is still functional, but it may break at any time.
>Issues, bug reports and suggestions for this module will not be processed. Use at your own discretion.
Usage is nearly identical to CityDoctorHealer, only requiring changing the classpath to the HealerGenetic jar.
A View for usage with CityDoctorGUI is included.
---
## CityDoctorHealerGUI
![Maintenance Level: Inactively Maintained](../resources/Badges/MaintenanceLevel_InactivelyMaintained.svg)
CityDoctorGUI-view for CityDoctorHealer. Allows fine control over the automated healing steps, including a preview of the
result of each healing step.
### Usage
See [CityDoctorGUI View-plugins](#view-plugins)
---
## CityDoctorWebService
![Maintenance Level: Abandoned](../resources/Badges/MaintenanceLevel_Abandoned.svg)
Contains a web service implementation for CityDoctor2.
### Usage
> ⚠ This module has been abandoned. As of writing the module is still functional, but it may break at any time.
>Issues, bug reports and suggestions for this module will not be processed. Use at your own discretion.
> ⚠ CityDoctorWebservice requires connection to a PostgreSQL Server. Connection parameters need to be set in the
pgpass.conf file found in the /DBScripts directory.
>
The PostgreSQL Server needs to contain a database called "CityDoctorDB" with a schema called "citydoctordb".
The required tables will be automatically created by the web service if they're missing.
To run the web service, build the module and [deploy CityDoctorWebService.war](https://tomcat.apache.org/tomcat-9.0-doc/deployer-howto.html)
to a Tomcat server (version 8 or 9).
---
## License
[LGPL](http://www.gnu.org/licenses/lgpl-3.0.de.html)
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId>
<version>3.14.1</version>
<packaging>pom</packaging>
<name>CityDoctorParent</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<log4j.version>2.18.0</log4j.version>
<revision>${project.version}</revision>
<nonMavenLibsPath>${project.baseUri}../non-maven-libs</nonMavenLibsPath>
<jre-version-short>17.0.10</jre-version-short>
<jre-version>${jre-version-short}+13</jre-version>
</properties>
<repositories>
<repository>
<id>non-maven-libs</id>
<url>${nonMavenLibsPath}</url>
</repository>
<repository>
<id>sonartype</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
</repositories>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<testFailureIgnore>false</testFailureIgnore>
<excludes>
<exclude>**/SolidSelfIntCheckFalsePositiveBigMeshTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorModel</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorAutoPro</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorValidation</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorGUI</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorEdge</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorCheckResult</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorHealer</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>12.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.9.Final</version>
</dependency>
<dependency>
<groupId>org.citygml4j</groupId>
<artifactId>citygml4j-core</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.citygml4j</groupId>
<artifactId>citygml4j-xml</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>citygml4j-quality-ade</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom2</artifactId>
<version>2.0.6.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jogamp.gluegen</groupId>
<artifactId>gluegen-rt-main</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>gov.nist.math</groupId>
<artifactId>jama</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.jogamp.jogl</groupId>
<artifactId>jogl-all-main</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.30</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j18-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.locationtech.proj4j</groupId>
<artifactId>proj4j</artifactId>
<version>1.1.5</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.11.9.Final</version>
</dependency>
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.19.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.6.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<modules>
<module>CityDoctorModel</module>
<module>CityDoctorValidation</module>
<module>CityDoctorEdge</module>
<module>CityDoctorCheckResult</module>
</modules>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId>
<version>3.14.1</version>
<packaging>pom</packaging>
<name>CityDoctorParent</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<log4j.version>2.18.0</log4j.version>
<revision>${project.version}</revision>
<nonMavenLibsPath>${project.baseUri}../non-maven-libs</nonMavenLibsPath>
<jre-version-short>17.0.10</jre-version-short>
<jre-version>${jre-version-short}+13</jre-version>
</properties>
<repositories>
<repository>
<id>non-maven-libs</id>
<url>${nonMavenLibsPath}</url>
</repository>
<repository>
<id>sonartype</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
</repositories>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<testFailureIgnore>false</testFailureIgnore>
<excludes>
<exclude>**/SolidSelfIntCheckFalsePositiveBigMeshTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-api</artifactId>
<version>2.15.0</version>
</plugin>
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-manager</artifactId>
<version>2.15.0</version>
</plugin>
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-eclipse</artifactId>
<version>2.15.0</version>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorModel</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorAutoPro</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorValidation</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorGUI</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorEdge</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorCheckResult</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorHealer</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>12.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.9.Final</version>
</dependency>
<dependency>
<groupId>org.citygml4j</groupId>
<artifactId>citygml4j-core</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.citygml4j</groupId>
<artifactId>citygml4j-xml</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>citygml4j-quality-ade</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom2</artifactId>
<version>2.0.6.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jogamp.gluegen</groupId>
<artifactId>gluegen-rt-main</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>gov.nist.math</groupId>
<artifactId>jama</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.jogamp.jogl</groupId>
<artifactId>jogl-all-main</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j18-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.locationtech.proj4j</groupId>
<artifactId>proj4j</artifactId>
<version>1.1.5</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.11.9.Final</version>
</dependency>
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.19.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>17.0.2</version>
</dependency>
</dependencies>
<modules>
<!--CityDoctor2 Core Modules-->
<module>CityDoctorModel</module>
<module>CityDoctorValidation</module>
<module>CityDoctorEdge</module>
<module>CityDoctorCheckResult</module>
<!--CityDoctor2 Extension Modules-->
<module>Extensions/CityDoctorGUI</module>
<!--
<module>Extensions/CityDoctorAutoPro</module>
<module>Extensions/CityDoctorHealer</module>
<module>Extensions/CityDoctorHealerGenetic</module>
<module>Extensions/CityDoctorHealerGUI</module>
<module>Extensions/CityDoctorWebService</module>
-->
</modules>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="194" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="anybadge_1">
<rect width="194" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#anybadge_1)">
<path fill="#555" d="M0 0h121v20H0z"/>
<path fill="#FF0000" d="M121 0h73v20H121z"/>
<path fill="url(#b)" d="M0 0h194v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="61.5" y="15" fill="#010101" fill-opacity=".3">Maintenance Level</text>
<text x="60.5" y="14">Maintenance Level</text>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="158.5" y="15" fill="#010101" fill-opacity=".3">Abandoned</text>
<text x="157.5" y="14">Abandoned</text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="243" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="anybadge_1">
<rect width="243" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#anybadge_1)">
<path fill="#555" d="M0 0h121v20H0z"/>
<path fill="#228B22" d="M121 0h122v20H121z"/>
<path fill="url(#b)" d="M0 0h243v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="61.5" y="15" fill="#010101" fill-opacity=".3">Maintenance Level</text>
<text x="60.5" y="14">Maintenance Level</text>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="183.0" y="15" fill="#010101" fill-opacity=".3">Actively Developed</text>
<text x="182.0" y="14">Actively Developed</text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="248" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="anybadge_1">
<rect width="248" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#anybadge_1)">
<path fill="#555" d="M0 0h121v20H0z"/>
<path fill="#6B8E23" d="M121 0h127v20H121z"/>
<path fill="url(#b)" d="M0 0h248v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="61.5" y="15" fill="#010101" fill-opacity=".3">Maintenance Level</text>
<text x="60.5" y="14">Maintenance Level</text>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="185.5" y="15" fill="#010101" fill-opacity=".3">Actively Maintained</text>
<text x="184.5" y="14">Actively Maintained</text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="198" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="anybadge_1">
<rect width="198" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#anybadge_1)">
<path fill="#555" d="M0 0h121v20H0z"/>
<path fill="#800000" d="M121 0h77v20H121z"/>
<path fill="url(#b)" d="M0 0h198v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="61.5" y="15" fill="#010101" fill-opacity=".3">Maintenance Level</text>
<text x="60.5" y="14">Maintenance Level</text>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="160.5" y="15" fill="#010101" fill-opacity=".3">Deprecated</text>
<text x="159.5" y="14">Deprecated</text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="260" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="anybadge_1">
<rect width="260" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#anybadge_1)">
<path fill="#555" d="M0 0h121v20H0z"/>
<path fill="#A4A61D" d="M121 0h139v20H121z"/>
<path fill="url(#b)" d="M0 0h260v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="61.5" y="15" fill="#010101" fill-opacity=".3">Maintenance Level</text>
<text x="60.5" y="14">Maintenance Level</text>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="191.5" y="15" fill="#010101" fill-opacity=".3">Inactively Maintained</text>
<text x="190.5" y="14">Inactively Maintained</text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="219" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="anybadge_1">
<rect width="219" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#anybadge_1)">
<path fill="#555" d="M0 0h121v20H0z"/>
<path fill="#FF4500" d="M121 0h98v20H121z"/>
<path fill="url(#b)" d="M0 0h219v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="61.5" y="15" fill="#010101" fill-opacity=".3">Maintenance Level</text>
<text x="60.5" y="14">Maintenance Level</text>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="171.0" y="15" fill="#010101" fill-opacity=".3">Not Maintained</text>
<text x="170.0" y="14">Not Maintained</text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="185" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="anybadge_1">
<rect width="185" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#anybadge_1)">
<path fill="#555" d="M0 0h121v20H0z"/>
<path fill="#000000" d="M121 0h64v20H121z"/>
<path fill="url(#b)" d="M0 0h185v20H0z"/>
</g>
<g fill="white" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="61.5" y="15" fill="#010101" fill-opacity=".3">Maintenance Level</text>
<text x="60.5" y="14">Maintenance Level</text>
</g>
<g fill="white" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="154.0" y="15" fill="#010101" fill-opacity=".3">Obsolete</text>
<text x="153.0" y="14">Obsolete</text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="132" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="anybadge_1">
<rect width="132" height="20" rx="10" fill="#fff"/>
</mask>
<g mask="url(#anybadge_1)">
<path fill="#FF0000" d="M0 0h132v20H0z"/>
<path fill="#262626" d="M53 2h70v16H53z"/>
<path fill="#262626" d="M122,18 a1,1 0 0,0 0,-16"/>
<path fill="url(#b)" d="M0 0h132v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="26.5" y="14">Project</text>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="92.5" y="14">CityDoctor2</text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="144" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="anybadge_1">
<rect width="144" height="20" rx="10" fill="#fff"/>
</mask>
<g mask="url(#anybadge_1)">
<path fill="#4169E1" d="M0 0h144v20H0z"/>
<path fill="#262626" d="M53 2h82v16H53z"/>
<path fill="#262626" d="M134,18 a1,1 0 0,0 0,-16"/>
<path fill="url(#b)" d="M0 0h144v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="26.5" y="14">Project</text>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="98.5" y="14">UDigiT-Doctor</text>
</g>
</svg>
# CityDoctor2
[![pipeline status](https://transfer.hft-stuttgart.de/gitlab/betzms/citydoctor2/badges/master/pipeline.svg)](https://transfer.hft-stuttgart.de/gitlab/betzms/citydoctor2/-/commits/master)
[![pipeline status](https://transfer.hft-stuttgart.de/gitlab/betzms/citydoctor2/badges/master/pipeline.svg)](https://transfer.hft-stuttgart.de/gitlab/betzms/citydoctor2/-/commits/master) ![Maintenance Level: Actively Developed](/CityDoctorParent/resources/Badges/MaintenanceLevel_ActivelyDeveloped.svg)
CityDoctor2 is a Java program for validating CityGML files. It checks whether certain criteria for e.g. geometries are met and outputs a report on the results.
......@@ -42,6 +42,10 @@ java -classpath libs/*;plugins/*;CityDoctorValidation-<version>.jar de.hft.stutt
Note:
-xmlReport, -pdfReport and -out are optional
## Extension
Example extensions for CityDoctor are included in this repository, and can be found in the [Extensions subdirectory](./CityDoctorParent/Extensions)
alongside a short description for each respective extension.
## License
[LGPL](http://www.gnu.org/licenses/lgpl-3.0.de.html)
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