Commit ffdae21a authored by Riegel's avatar Riegel
Browse files

Open Source release of CityDoctor GUI

parent a5a82382
Pipeline #10029 failed with stage
in 8 seconds
requirements:
R_GE_R_TOO_FEW_POINTS:
enabled: true
R_GE_R_NOT_CLOSED:
enabled: true
R_GE_R_CONSECUTIVE_POINTS_SAME:
enabled: true
R_GE_R_SELF_INTERSECTION:
enabled: true
R_GE_S_MULTIPLE_CONNECTED_COMPONENTS:
enabled: true
R_GE_P_INTERIOR_DISCONNECTED:
enabled: true
R_GE_P_INTERSECTING_RINGS:
enabled: true
R_GE_P_NON_PLANAR:
enabled: true
parameters:
# one of ("distance", "angle", "both")
type: distance
# in m
distanceTolerance: 0.01
# in degree
angleTolerance: 1
R_GE_P_HOLE_OUTSIDE:
enabled: true
R_GE_P_ORIENTATION_RINGS_SAME:
enabled: true
R_GE_P_INNER_RINGS_NESTED:
enabled: true
R_GE_S_TOO_FEW_POLYGONS:
enabled: true
R_GE_S_NOT_CLOSED:
enabled: true
R_GE_S_NON_MANIFOLD_EDGE:
enabled: true
R_GE_S_POLYGON_WRONG_ORIENTATION:
enabled: true
R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION:
enabled: true
R_GE_S_NON_MANIFOLD_VERTEX:
enabled: true
R_GE_S_SELF_INTERSECTION:
enabled: true
R_SE_BS_IS_WALL:
enabled: false
parameters:
lowerAngle: '45'
upperAngle: '135'
R_SE_BS_IS_FLOOR:
enabled: false
R_SE_BS_GROUND_UNFRAGMENTED:
enabled: false
R_SE_BS_IS_GROUND:
enabled: false
R_SE_BS_IS_CEILING:
enabled: false
globalParameters:
numberOfRoundingPlaces: 8
# in m
minVertexDistance: 0.0001
schematronPath: 'checkForSolid.xml'
useStreaming: true
xmlValidation: false
/** --------------------------------------------------
* Hochschule f�r Technik Stuttgart
* Fachbereich Vermessung , Informatik und Mathematik
* Schellingstr . 24
* D - 70174 Stuttgart
*
* Projekt CityDoktor
*
* Copyright (c) 2011 HFT Stuttgart. All rights reserved.
* HFT Stuttgart and its licensors retain all intellectual property and
* proprietary rights in and to this software and related documentation.
* Any use, reproduction, disclosure, or distribution of this software
* and related documentation without an express license agreement from
* HFT Stuttgart is strictly prohibited.
*
* Please refer to the applicable HFT Stuttgart end user license agreement (EULA)
* associated with this source code for terms and conditions that govern
* your use of this HFT Stuttgart software.
*
* 11.09.2012
* bogdahn
* @author
* @version
*
*/
package de.hft.stuttgart.citydoctor2;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import de.hft.stuttgart.citydoctor2.connect.edge.NativeException;
/**
* @author bogdahn
*
*/
public class CppInitializer {
private static final String SUN_ARCH_DATA_MODEL = "sun.arch.data.model";
private static Logger logger = LogManager.getLogger(CppInitializer.class);
private static native boolean initCppLibrary() throws NativeException;
private static native boolean checkVersions(String jdkVersion) throws NativeException;
public static synchronized void initCpp() {
// init CPP JNI Checks
String dataModel = System.getProperty(SUN_ARCH_DATA_MODEL);
if (dataModel.equals("64")) {
// System.loadLibrary( "CityDoctor2CPP-windows-x64-sgd" ); // debug dll
System.loadLibrary("../CityDoctorHealer/lib/CityDoctor2CPP-windows-x64-s");
// System.loadLibrary("CityDoctor2CPP-windows-x64-s");
// System.loadLibrary("lib/libTestHeal");
} else if (dataModel.equals("32")) {
// System.loadLibrary( "CityDoctor2CPP-windows-x86-sgd" ); // debug dll
// System.loadLibrary("../CityDoctorHealer/lib/CityDoctor2CPP-windows-x86-s");
// System.loadLibrary("CityDoctor2CPP-windows-x86-s");
System.err.println("Load native library failed.");
System.err.println("Unknown architecture: " + dataModel);
System.err.println("Valid values are: \"64\"");
System.err.println("No library will be loaded");
} else {
System.err.println("Load native library failed.");
System.err.println("Unknown architecture: " + dataModel);
System.err.println("Valid values are: \"64\"");
System.err.println("No library will be loaded");
}
try {
if (initCppLibrary()) {
// checkVersions(System.getProperty("java.version")); // TODO : checkVersions
// funktioniert noch nicht!!
}
} catch (NativeException ne) {
System.err.println("Native Exception");
System.err.println(ne.getType());
System.err.println(ne.getMessage());
ne.printStackTrace();
System.exit(1);
} catch (IllegalArgumentException e) {
e.printStackTrace();
System.exit(1);
}
}
private CppInitializer() {
// only static utility
}
}
package de.hft.stuttgart.citydoctor2.connect.edge;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
public class CppHealResult extends CppReferenceHandlingBase {
private native void delete(long ptr);
private native int[] getChangedOrAddedVertexIds(long ptr);
private native double[] getChangedOrAddedVertexValues(long ptr);
private native int[] getChangedOrAddedPolygonIds(long ptr);
private native int[] getChangedOrAddedPolygon(long ptr, int id);
public CppHealResult(long ptr) {
ptrToCppObject = ptr;
}
@Override
public void disposeCppObject() {
if (ptrToCppObject != 0) {
delete(ptrToCppObject);
ptrToCppObject = 0;
}
}
public void mergeIntoGeometry(Geometry geom) {
Map<Integer, Vertex> vertexMap = updateVertices(geom);
int[] changedPolygons = getChangedOrAddedPolygonIds(ptrToCppObject);
List<Polygon> deletedPolygons = new ArrayList<>();
for (int i = 0; i < changedPolygons.length; i++) {
int polyId = changedPolygons[i];
int[] vertices = getChangedOrAddedPolygon(ptrToCppObject, polyId);
if (vertices == null || vertices.length == 0) {
if (polyId >= geom.getPolygons().size()) {
throw new IllegalStateException("Cannot delete a polygon which does not exist");
}
Polygon p = geom.getPolygons().get(polyId);
deletedPolygons.add(p);
} else {
Polygon p;
if (polyId < geom.getPolygons().size()) {
p = geom.getPolygons().get(polyId);
// empty the polygon
p.removeRings();
} else {
p = new ConcretePolygon();
geom.addPolygon(p);
}
createPolygon(geom, vertexMap, vertices, p);
}
}
for (Polygon p : deletedPolygons) {
geom.getPolygons().remove(p);
}
}
private void createPolygon(Geometry geom, Map<Integer, Vertex> vertexMap, int[] vertices, Polygon p) {
LinearRing lr = null;
for (int j = 0; j < vertices.length; j++) {
if (vertices[j] == -1) {
if (p.getExteriorRing() != null) {
throw new IllegalStateException("Cannot create a polygon with more than 1 exterior rings");
}
lr = new LinearRing(LinearRingType.EXTERIOR);
p.setExteriorRing(lr);
} else if (vertices[j] == -2) {
lr = new LinearRing(LinearRingType.INTERIOR);
p.addInteriorRing(lr);
} else {
Objects.requireNonNull(lr, "No ring type specified, before supplying vertices");
int index = vertices[j];
Vertex v;
if (index < geom.getVertices().size()) {
v = geom.getVertices().get(index);
} else {
v = vertexMap.get(index);
}
Objects.requireNonNull(v, "Polygon references vertex, which does not exist");
lr.addVertex(v);
}
}
// close the rings
p.getExteriorRing().addVertex(p.getExteriorRing().getVertices().get(0));
for (LinearRing inner : p.getInnerRings()) {
inner.addVertex(inner.getVertices().get(0));
}
}
private Map<Integer, Vertex> updateVertices(Geometry geom) {
int[] changedVertices = getChangedOrAddedVertexIds(ptrToCppObject);
double[] changedVertexValues = getChangedOrAddedVertexValues(ptrToCppObject);
Map<Integer, Vertex> vertexMap = new HashMap<>();
for (int i = 0; i < changedVertices.length; i++) {
int id = changedVertices[i];
double x = changedVertexValues[i * 3 + 0];
double y = changedVertexValues[i * 3 + 1];
double z = changedVertexValues[i * 3 + 2];
if (id >= geom.getVertices().size()) {
// new vertex
Vertex newV = new Vertex(x, y, z);
vertexMap.put(id, newV);
System.out.println("New Vertex: " + newV);
} else {
// change vertex
Vertex changedV = geom.getVertices().get(id);
System.out.print("Changed Vertex from " + changedV + " to ");
changedV.setX(x);
changedV.setY(y);
changedV.setZ(z);
System.out.println(changedV);
}
}
return vertexMap;
}
public void print() {
int[] changedVertices = getChangedOrAddedVertexIds(ptrToCppObject);
System.out.println("Changed or added vertex ids: " + Arrays.toString(changedVertices));
double[] changedVertexValues = getChangedOrAddedVertexValues(ptrToCppObject);
if (changedVertices.length * 3 != changedVertexValues.length) {
throw new IllegalStateException("Number of indices and number of values do not match");
}
for (int i = 0; i < changedVertices.length; i++) {
System.out.println(String.format("Vertex %d = [%f, %f, %f]", changedVertices[i],
changedVertexValues[i * 3 + 0], changedVertexValues[i * 3 + 1], changedVertexValues[i * 3 + 2]));
}
System.out.println();
int[] changedPolygons = getChangedOrAddedPolygonIds(ptrToCppObject);
System.out.println("Changed or added polygon ids: " + Arrays.toString(changedPolygons));
for (int i = 0; i < changedPolygons.length; i++) {
int polyId = changedPolygons[i];
System.out.println("Polygon " + polyId + ":");
int[] vertices = getChangedOrAddedPolygon(ptrToCppObject, polyId);
if (vertices == null || vertices.length == 0) {
System.out.println("deleted");
} else {
for (int j = 0; j < vertices.length; j++) {
if (vertices[j] == -1) {
System.out.println("Exterior ring:");
} else if (vertices[j] == -2) {
System.out.println("Interior ring:");
} else {
System.out.println(vertices[j]);
}
}
}
}
}
public boolean isEmpty() {
int[] changedVertices = getChangedOrAddedVertexIds(ptrToCppObject);
int[] changedPolygons = getChangedOrAddedPolygonIds(ptrToCppObject);
if(changedVertices.length == 0 && changedPolygons.length == 0)
return true;
return false;
}
}
package de.hft.stuttgart.citydoctor2.connect.edge;
public abstract class CppHealing extends CppReferenceHandlingBase {
// Checks will operate on this VPDFeature
CppFeature feature;
public CppHealing(CppFeature feature) {
this.feature = feature;
}
public CppFeature getNestedFeature() {
return feature;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
//*************************************************************************************
// vorerst auskommentiert, da CppChecks nicht mehr verwendet wird
// @Override
// public boolean equals(Object obj)
// {
// if (obj instanceof CppChecks)
// {
// return (super.equals(obj) && (feature == ((CppChecks)obj).feature));
// }
// else
// {
// return super.equals(obj);
// }
// }
//**************************************************************************************
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int hash = super.hashCode();
hash = hash * 19 + feature.hashCode() * 3;
return hash;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuffer sf = new StringBuffer();
sf.append(super.toString());
sf.append("Feature:\n\t");
sf.append(feature);
return sf.toString();
}
}
\ No newline at end of file
package de.hft.stuttgart.citydoctor2.connect.edge;
public enum CppHealingResultChangeType {
ADD, DELETE, CHANGE, REPLACE
}
package de.hft.stuttgart.citydoctor2.connect.edge;
public enum CppHealingResultType {
VERTEX, POLYGON, EDGE
}
package de.hft.stuttgart.citydoctor2.connect.edge;
// im alten CD:
//
public class CppPolygonHealing extends CppHealing {
// ----- native methods
// create and release stored C++ polygon check object
private native long createCppPolygonHealing(long ptrToCppFeature) throws OutOfMemoryError;
private native void disposeCppPolygonHealing(long ptrToCppFeature) throws NativePointerCastException;
// healing
private native long healPlanarity(long ptrToCppFeature, int[] polyIds)
throws NativeException, IllegalArgumentException;
private native long healSolidNotClosed(long ptrToCppFeature)
throws NativeException, IllegalArgumentException;
public CppPolygonHealing(CppFeature feature) {
super(feature);
}
/**
* Creates an C++ object to use the native solid check methods.
*
* @throws IllegalStateException Thrown if the encapsulated "long-Pointer" isn't
* 0
* @throws OutOfMemoryError If there is no more memory on the native side
*
* @see {@link disposeCppObject}
* @see de.hft.stuttgart.citydoctor.connect.edGe.CppReferenceHandlingBase#createCppObject()
*/
public void createCppObject() throws IllegalStateException, OutOfMemoryError {
if (0L != ptrToCppObject) {
throw new IllegalStateException("Can't create new C++ object, there is allready one!");
}
// Maybe an exception is thrown and there should be no crap in ptrToCppObject
long tmpPointer = createCppPolygonHealing(feature.ptrToCppObject);
ptrToCppObject = tmpPointer;
}
@Override
public void disposeCppObject() throws NativePointerCastException {
if (0L != ptrToCppObject) {
disposeCppPolygonHealing(this.ptrToCppObject);
ptrToCppObject = 0L;
}
}
public CppHealResult healPlanarity(int[] polyIds) throws NativeException, IllegalArgumentException {
checkNullPointer();
return new CppHealResult( healPlanarity( this.feature.ptrToCppObject, polyIds ));
}
public CppHealResult healSolidNotClosed() throws NativeException, IllegalArgumentException{
checkNullPointer();
return new CppHealResult( healSolidNotClosed( this.feature.ptrToCppObject ));
}
}
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