diff --git a/.gitlab/.gitmessage b/.gitlab/.gitmessage new file mode 100644 index 0000000000000000000000000000000000000000..b9db7232635742a00a55a87d627ca9a9c08ccb7f --- /dev/null +++ b/.gitlab/.gitmessage @@ -0,0 +1,23 @@ +# Title: Summary, imperative, start upper case, don't end with a period +# No more than 50 chars. #### 50 chars is here: # + +# Remember blank line between title and body. + +# Body: Explain *what* and *why* (not *how*). Include task ID (Jira issue). +# Wrap at 72 chars. ################################## which is here: # + + +# At the end: Include Co-authored-by for all contributors. +# Include at least one empty line before it. Format: +# Co-authored-by: name +# +# How to Write a Git Commit Message: +# https://chris.beams.io/posts/git-commit/ +# +# 1. Separate subject from body with a blank line +# 2. Limit the subject line to 50 characters +# 3. Capitalize the subject line +# 4. Do not end the subject line with a period +# 5. Use the imperative mood in the subject line +# 6. Wrap the body at 72 characters +# 7. Use the body to explain what and why vs. how \ No newline at end of file diff --git a/.gitlab/VULNERABILTIY CLASSIFICATION GUIDE.md b/.gitlab/VULNERABILTIY CLASSIFICATION GUIDE.md new file mode 100644 index 0000000000000000000000000000000000000000..e32bb92a3b115ef88c31eea7a5848c0806358391 --- /dev/null +++ b/.gitlab/VULNERABILTIY CLASSIFICATION GUIDE.md @@ -0,0 +1,14 @@ +## Classification Score + +Disclosed vulnerabilities are evaluated by using the [Common Vulnerability Scoring System](https://www.first.org/cvss/v4.0/user-guide). + +The calculator can be found [here](https://www.first.org/cvss/calculator/4.0). + + +## Vulnerability Severities + +**Critical:** ~"Vulnerability::Critical" Vulnerabilities with a Score >= 9, or vulnerabilities which enable remote code execution. + +**High:** ~"Vulnerability::High" Vulnerabilities with a Score >= 5. + +**Minor:** ~"Vulnerability::Minor" Vulnerabilities with a Score < 5, or which require physical access to the system. \ No newline at end of file diff --git a/.gitlab/changelog_config.yml b/.gitlab/changelog_config.yml new file mode 100644 index 0000000000000000000000000000000000000000..f589acdbea3c22d71fa6458d725c5d1718782928 --- /dev/null +++ b/.gitlab/changelog_config.yml @@ -0,0 +1,38 @@ +--- +# Settings for generating changelogs using the GitLab API. See +# https://docs.gitlab.com/ee/api/repositories.html#generate-changelog-data for +# more information. +categories: + added: Added + fixed: Fixed + changed: Changed + deprecated: Deprecated + removed: Removed + security: Security + performance: Performance + other: Other +template: | + {% if categories %} + {% each categories %} + ### {{ title }} ({% if single_change %}1 change{% else %}{{ count }} changes{% end %}) + + {% each entries %} + - [{{ title }}]({{ commit.web_url }})\ + {% if author.credit %} by {{ author.reference }}{% end %}\ + {% if commit.trailers.MR %}\ + ([merge request]({{ commit.trailers.MR }}))\ + {% else %}\ + {% if merge_request %}\ + ([merge request]({{ merge_request.web_url }}))\ + {% end %}\ + {% end %}\ + {% if commit.trailers.EE %}\ + **GitLab Enterprise Edition**\ + {% end %} + + {% end %} + + {% end %} + {% else %} + No changes. + {% end %} diff --git a/.gitlab/issue_templates/bug_report.md b/.gitlab/issue_templates/bug_report.md new file mode 100644 index 0000000000000000000000000000000000000000..621c58ebee00038d465b76581814fb2d1dab3422 --- /dev/null +++ b/.gitlab/issue_templates/bug_report.md @@ -0,0 +1,27 @@ +## Summary + + + +## Steps to reproduce + + + + +## What is the current bug behavior? + + + +## What is the expected correct behavior? + + + +## Relevant logs and/or screenshots + + + +## Possible cause + + + +/label Bug \ No newline at end of file diff --git a/.gitlab/issue_templates/documentation.md b/.gitlab/issue_templates/documentation.md new file mode 100644 index 0000000000000000000000000000000000000000..b30eef6943e227298a771b1cbef0f600d795cf02 --- /dev/null +++ b/.gitlab/issue_templates/documentation.md @@ -0,0 +1,14 @@ +## Short description + + + +## Content + + + +## Location + + + + +/label Type::Documentation \ No newline at end of file diff --git a/.gitlab/issue_templates/feature_request.md b/.gitlab/issue_templates/feature_request.md new file mode 100644 index 0000000000000000000000000000000000000000..877fac13545947228ea48141ede07fb0c792647b --- /dev/null +++ b/.gitlab/issue_templates/feature_request.md @@ -0,0 +1,14 @@ +## Summary + + + +## What is the function? + + + +## Why is it requested? + + + + +/label Type::Feature Request \ No newline at end of file diff --git a/.gitlab/issue_templates/user_story.md b/.gitlab/issue_templates/user_story.md new file mode 100644 index 0000000000000000000000000000000000000000..4bb52398846a795c5d43b8f21a6434a1eb859333 --- /dev/null +++ b/.gitlab/issue_templates/user_story.md @@ -0,0 +1,26 @@ +## Description + + + +**As a:** + +**I want:** + +**So that:** + +## Acceptance Criteria + + + +**Scenario X: Title of scenario** + +--- +**Given** + +**When** + + +**Then** + + +/label Type::Feature Request \ No newline at end of file diff --git a/.gitlab/issue_templates/vulnerability_disclosure.md b/.gitlab/issue_templates/vulnerability_disclosure.md new file mode 100644 index 0000000000000000000000000000000000000000..4dfbd18b2bd8120027a2ff01a245b002fcbe3cce --- /dev/null +++ b/.gitlab/issue_templates/vulnerability_disclosure.md @@ -0,0 +1,28 @@ +## Summary + + + +## Steps to reproduce + + + + +## What is the current bug behavior? + + + +## What is the expected correct behavior? + + + +## Relevant logs and/or screenshots + + + +## Possible cause + + + +/label Type::Bug Vulnerability::Unclassified +/confidential \ No newline at end of file diff --git a/.gitlab/merge_request_templates/Default.md b/.gitlab/merge_request_templates/Default.md new file mode 100644 index 0000000000000000000000000000000000000000..72041d1481f6f9d454eb57280105a2879c5a1172 --- /dev/null +++ b/.gitlab/merge_request_templates/Default.md @@ -0,0 +1,21 @@ + + + +## What does this MR do? + + + + +## Related issues + + + +## Checklist + +- [ ] Commits squashed, following the message-template and containing changelog-trailers +- [ ] MR title and description are up to date, accurate, and descriptive. +- [ ] MR targeting the appropriate branch. +- [ ] Latest Merge Result pipeline is green. + + + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..fd1b8fe4a3822d0bde27b8da32f40bc11002bf88 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + +## [3.15.0] (2024-09-03) + +### Added (7 changes) + +- Add CityDoctorAutoPro extension. +- Add CityDoctorGUI extension. +- Add CityDoctorHealer extension. +- Add CityDoctorHealerGUI extension. +- Add CityDoctorHealerGenetic extension. +- Add CityDoctorWebService extension. +- Add Documentation for extension modules. + +### Fixed (1 change) + +- Fix false positives for Solid self-intersections. + +### Changed (1 change) + +- Update Maven dependencies: Include JavaFX + +### Security (1 change) + +- Upgrade SnakeYAML to version 2.0 + +## [3.14.0] (2024-03-20) + +Official Release of CityDoctor2 diff --git a/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/DebugUtils.java b/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/DebugUtils.java index e165ea445539fa38535b76e77af6dbe7d39829a9..6c46fbe25004449b562b704b61e67abe80db8a00 100644 --- a/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/DebugUtils.java +++ b/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/DebugUtils.java @@ -210,7 +210,84 @@ public class DebugUtils { System.out.println("CDPolygonNs* p" + counter + " = new CDPolygonNs(coords" + firstListCounter + ");"); return counterArr[0]; } - + + public static void printFPSelfIntersectionTestCaseCode(PolygonPolygonIntersection... intersectionResults){ + for (PolygonPolygonIntersection intersection : intersectionResults) { + printFPSelfIntersectionTestCaseCode(intersection.getPolygon1(), intersection.getPolygon2()); + } + } + + public static void printFPSelfIntersectionTestCaseCode(EdgePolygon polygon1, EdgePolygon polygon2) { + Locale.setDefault(Locale.US); + System.out.println("-----------------------------------------------------"); + System.out.println(""); + + System.out.println("@Test"); + System.out.println("public void testFalsePositiveCASENAME() {"); + printTabbedLine("Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);"); + System.out.println(""); + + printTestCasePolygonCode(polygon1, polygon2); + + + printTabbedLine("CDPolygonNs edgePoly1 = CDPolygonNs.of(p1, new HashMap<>());"); + printTabbedLine("CDPolygonNs edgePoly2 = CDPolygonNs.of(p2, new HashMap<>());"); + printTabbedLine("List intersectPolygons;"); + printTabbedLine("intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);"); + printTabbedLine("assertNotNull(intersectPolygons);"); + printTabbedLine("assertTrue(intersectPolygons.isEmpty());"); + System.out.println(""); + + + printTabbedLine("intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);"); + printTabbedLine("assertNotNull(intersectPolygons);"); + printTabbedLine("assertTrue(intersectPolygons.isEmpty());"); + System.out.println("}"); + } + + private static void printTabbedLine(String line){ + Locale.setDefault(Locale.US); + String format = "\t%s\n"; + System.out.format(format, line); + } + + private static void printTestCasePolygonCode(EdgePolygon polygon1, EdgePolygon polygon2) { + printTabbedLine("Polygon p1 = new ConcretePolygon();"); + printTabbedLine("geom.addPolygon(p1);"); + printTabbedLine("LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);"); + printTabbedLine("p1.setExteriorRing(ext);"); + printTabbedLine("List vertices= new ArrayList<>();"); + printTestCasePolygonVertices(polygon1); + System.out.println(""); + + printTabbedLine("Polygon p2 = new ConcretePolygon();"); + printTabbedLine("geom.addPolygon(p2);"); + printTabbedLine("ext = new LinearRing(LinearRingType.EXTERIOR);"); + printTabbedLine("p2.setExteriorRing(ext);"); + printTabbedLine("vertices= new ArrayList<>();"); + printTestCasePolygonVertices(polygon2); + System.out.println(""); + + } + + private static void printTestCasePolygonVertices(EdgePolygon polygon) { + List coordList = polygon.getCoordinates(); + NumberFormat nf = NumberFormat.getNumberInstance(); + nf.setMaximumFractionDigits(30); + + String vertexFormat = "vertices.add(new Vertex(%s,%s,%s));"; + for (Coordinate3d coordinate3d : coordList) { + Point3d point = coordinate3d.getPoint(); + printTabbedLine(String.format(vertexFormat, + nf.format(point.getX()), nf.format(point.getY()), nf.format(point.getZ()))); + } + // close ring + Point3d point = coordList.get(0).getPoint(); + printTabbedLine(String.format(vertexFormat,point.getX(),point.getY(),point.getZ())); + printTabbedLine("ext.addAllVertices(vertices);"); + } + + public static int printCityDoctorPolygons(Polygon... polygons) { Locale.setDefault(Locale.US); NumberFormat nf = NumberFormat.getNumberInstance(); diff --git a/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/IntersectPlanarPolygons.java b/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/IntersectPlanarPolygons.java index 290b264797fa972d9c75ca085a83326bd35b0c3e..65d915c58e601b08da03062d7d0e2ce2803a4ef3 100644 --- a/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/IntersectPlanarPolygons.java +++ b/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/IntersectPlanarPolygons.java @@ -154,7 +154,8 @@ public class IntersectPlanarPolygons { List intersections, double epsilon) { // check if both polygons have this point in common if (!sharingBothPolygonsThisPoint(p1, p2, point, epsilon)) { - PolyLine pPL = new PolyLine(new Coordinate3d(point), new Coordinate3d(point)); + Coordinate3d realPointCoordinate = new Coordinate3d(point); + PolyLine pPL = new PolyLine(realPointCoordinate, realPointCoordinate); PolygonPolygonIntersection pPPI = new PolygonPolygonIntersection(p1, p2, pPL); intersections.add(pPPI); } diff --git a/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/PolyLine.java b/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/PolyLine.java index 5cea520a3e2673e08e3b537611f8977d7dc7e05f..0a7494eb048f9669316341d8fedf1b2c7664216c 100644 --- a/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/PolyLine.java +++ b/CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/PolyLine.java @@ -79,7 +79,7 @@ public class PolyLine extends BaseEntity { } public boolean isNullLine() { - return isNullLine(0.00); + return isNullLine(0.0000001); } @@ -88,6 +88,13 @@ public class PolyLine extends BaseEntity { if (mpFirst == null || mpLast == null) { return true; } + // Check if same point object is start and end + if (mpFirst == mpLast){ + Point3d start = mpFirst.getStart().getPoint(); + Point3d end = mpLast.getEnd().getPoint(); + // If start- and endpoint same object: -> not null line, intersection on a vertex + if(start == end) return false; + } PolyLineSegment currentSegment = mpFirst; double length = 0.00; // Add length of all segments, starting from mpFirst @@ -108,7 +115,7 @@ public class PolyLine extends BaseEntity { length += segmentLength; } // Check if total length is less than the set tolerance - return length <= tolerance; + return length < tolerance; }