Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7cea9d6
Improvements to finding corner points in `IdCoordinateSource`.
staudtMarius Feb 21, 2024
1bbf944
Updating docs.
staudtMarius Feb 21, 2024
d218cb5
Updating docs.
staudtMarius Feb 21, 2024
a8c5c26
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
staudtMarius Feb 21, 2024
6222b43
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
staudtMarius Feb 23, 2024
4f2cef7
Enhancing `IdCoordinateSource` with new method.
staudtMarius Feb 23, 2024
bf29239
Merge remote-tracking branch 'origin/ms/#1016-improvements-to-finding…
staudtMarius Feb 23, 2024
9ad22b9
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
staudtMarius Feb 28, 2024
0da041b
Enhancing docs.
staudtMarius Feb 28, 2024
a140934
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
staudtMarius Mar 1, 2024
289aab8
Enhancing docs.
staudtMarius Mar 1, 2024
83232d1
Fix table error in docs.
staudtMarius Mar 1, 2024
d8074ba
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
staudtMarius Apr 3, 2024
47bff19
Adapting to changes.
staudtMarius Apr 3, 2024
61d7fb9
Fixing `Codacy` issue.
staudtMarius Apr 4, 2024
cba1f07
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
staudtMarius Apr 9, 2024
a3afad2
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
staudtMarius Apr 15, 2024
dbd3575
Fixing `CHANGELOG`.
staudtMarius Apr 15, 2024
e3055e7
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
staudtMarius Apr 23, 2024
f05b897
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
staudtMarius Apr 25, 2024
2e69461
Merge branch 'dev' into ms/#1016-improvements-to-finding-corner-point…
danielfeismann Apr 30, 2024
41b8a79
Adapting docs.
staudtMarius May 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated contributing.md [#737](https://github.com/ie3-institute/PowerSystemDataModel/issues/737)
- Don't throw exceptions for not yet implemented validations [#879](https://github.com/ie3-institute/PowerSystemDataModel/issues/879)
- `CsvDataSource` throws exceptions on error [#954](https://github.com/ie3-institute/PowerSystemDataModel/issues/954)
- Improvements to the search for corner points in `IdCoordinateSource` [#1016](https://github.com/ie3-institute/PowerSystemDataModel/issues/1016)

## [4.1.0] - 2023-11-02

Expand Down
18 changes: 8 additions & 10 deletions docs/readthedocs/models/input/additionaldata/idcoordinatesource.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,16 @@ return less than n coordinates.

## Finding and returning the closest corner coordinates:
In most cases we need four corner coordinates for our given coordinate. Therefor the
IdCoordinateSource contains a method that will use the calculated distances to find the closest
IdCoordinateSource contains methods that will use the calculated distances to find the closest
corner coordinates for the given coordinate.

``` java
List<CoordinateDistance> restrictToBoundingBox(
Point coordinate,
Collection<CoordinateDistance> distances,
int numberOfPoints
)
List<CoordinateDistance> findCornerPoints(Point coordinate, Collection<CoordinateDistance> distances)
List<CoordinateDistance> enrichedCornerPoints(Point coordinate, Collection<CoordinateDistance> distances, int numberOfPoints)
```

For a given set of coordinates, the closest four corner coordinates plus more close points if n > 4
are returned. If n < 4 the method will return the closest n corner coordinates. If the set of
coordinates contains a coordinate that matches the given coordinate, only this one coordinate is
returned. If n > number of coordinates in the set, all coordinates are returned.
1. If a coordinate matches the given coordinate, only this coordinate is returned. If no coordinate matches the given
coordinate, this method tries to return four corner points.

2. This method uses the first to calculate the corner points. After that this method tries to enrich the found points to
match the set number of points.
64 changes: 40 additions & 24 deletions src/main/java/edu/ie3/datamodel/io/source/IdCoordinateSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,17 @@ default List<CoordinateDistance> calculateCoordinateDistances(
if (coordinates != null && !coordinates.isEmpty()) {
SortedSet<CoordinateDistance> sortedDistances =
GeoUtils.calcOrderedCoordinateDistances(coordinate, coordinates);
return restrictToBoundingBox(coordinate, sortedDistances, n);
return enrichedCornerPoints(coordinate, sortedDistances, n);
} else {
return Collections.emptyList();
}
}

/**
* Method for evaluating the found points. This method tries to return the four corner points of
* the bounding box of the given coordinate. If one of the found points matches the given
* coordinate, only this point is returned. If the given number of searched points is less than
* four, this method will only return the nearest n corner points. If the given number of searched
* points is greater than four, this method will return the four corner points plus the nearest n
* points to match the number of searched points.
* Method for evaluating the found points. This method uses {@link #findCornerPoints(Point,
* Collection)} to find the corner points. After the points are found the difference between the
* size of the corners and the expected number of points is calculated. If the difference is
* {@code != 0} the list of corner points is enriched with other found points.
*
* <p>To work properly, the given collection of {@link CoordinateDistance}'s should already be
* sorted by distance.
Expand All @@ -119,27 +117,56 @@ default List<CoordinateDistance> calculateCoordinateDistances(
* @param numberOfPoints that should be returned
* @return list of distances
*/
default List<CoordinateDistance> restrictToBoundingBox(
default List<CoordinateDistance> enrichedCornerPoints(
Point coordinate, Collection<CoordinateDistance> distances, int numberOfPoints) {
// tries to find the corner points
List<CoordinateDistance> corners = new ArrayList<>(findCornerPoints(coordinate, distances));

// check if n distances are found
int diff = numberOfPoints - corners.size();

if (diff > 0) {
// calculates the points that are not in the collection
distances.stream().filter(c -> !corners.contains(c)).limit(diff).forEach(corners::add);
} else if (diff < 0) {
return corners.stream().limit(numberOfPoints).toList();
}

return corners;
}

/**
* Method for finding the corner points of a given coordinate. If a point matches the given
* coordinate, only this point is returned.
*
* <p>The max. number of returned corner points is set by the implementation (default: 4).
*
* <p>To work properly, the given collection of {@link CoordinateDistance}'s should already be
* sorted by distance.
*
* @param coordinate at the center
* @param coordinateDistances list of fount points with their distances
* @return either a list with one exact match or a list of corner points (default implementation:
* max. 4 points)
*/
default List<CoordinateDistance> findCornerPoints(
Point coordinate, Collection<CoordinateDistance> coordinateDistances) {
boolean topLeft = false;
boolean topRight = false;
boolean bottomLeft = false;
boolean bottomRight = false;

List<CoordinateDistance> resultingDistances = new ArrayList<>();
List<CoordinateDistance> other = new ArrayList<>();

// search for smallest bounding box
for (CoordinateDistance distance : distances) {
for (CoordinateDistance distance : coordinateDistances) {
Point point = distance.getCoordinateB();

// check for bounding box
if (coordinate.equalsExact(point, 1e-6)) {
// if current point is matching the given coordinate, we need to return only the current
// point
resultingDistances.clear();
resultingDistances.add(distance);
return resultingDistances;
return List.of(distance);
} else if (!topLeft
&& (point.getX() < coordinate.getX() && point.getY() > coordinate.getY())) {
resultingDistances.add(distance);
Expand All @@ -156,20 +183,9 @@ default List<CoordinateDistance> restrictToBoundingBox(
&& (point.getX() > coordinate.getX() && point.getY() < coordinate.getY())) {
resultingDistances.add(distance);
bottomRight = true;
} else {
other.add(distance);
}
}

// check if n distances are found
int diff = numberOfPoints - resultingDistances.size();

if (diff > 0) {
resultingDistances.addAll(other.stream().limit(diff).toList());
} else if (diff < 0) {
return resultingDistances.stream().limit(numberOfPoints).toList();
}

return resultingDistances;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ class IdCoordinateSourceTest extends Specification {
private final IdCoordinateSourceMock coordinateSourceMock = new IdCoordinateSourceMock()

private final Point point0 = GeoUtils.buildPoint(52.5, 7.5)
private final Point point1 = GeoUtils.buildPoint(53, 8)
private final Point point1 = GeoUtils.buildPoint(53, 7.9)
private final Point point2 = GeoUtils.buildPoint(53, 7)
private final Point point3 = GeoUtils.buildPoint(53, 6)
private final Point point4 = GeoUtils.buildPoint(52, 8)
private final Point point3 = GeoUtils.buildPoint(53, 6.2)
private final Point point4 = GeoUtils.buildPoint(52, 7.9)
private final Point point5 = GeoUtils.buildPoint(52, 7)
private final Point point6 = GeoUtils.buildPoint(52, 6)
private final Point point7 = GeoUtils.buildPoint(51, 8)
private final Point point6 = GeoUtils.buildPoint(52, 6.2)
private final Point point7 = GeoUtils.buildPoint(51, 7.9)
private final Point point8 = GeoUtils.buildPoint(51, 7)
private final Point point9 = GeoUtils.buildPoint(51, 6)
private final Point point9 = GeoUtils.buildPoint(51, 6.2)

private final List<Point> points = [
point1,
Expand All @@ -36,36 +36,54 @@ class IdCoordinateSourceTest extends Specification {
point9
]

def "IdCoordinateSource should return correct number of corner points restricted to the bounding box"() {
def "IdCoordinateSource should find and return correct number of corner points"() {
given:
List<Point> expectedPoints = [
point1,
point2,
point3,
point4,
point5,
point6,
point8
point6
]

when:
List<CoordinateDistance> distances = coordinateSourceMock.calculateCoordinateDistances(point0, 9, points)
List<CoordinateDistance> result = coordinateSourceMock.restrictToBoundingBox(point0, distances, 4)
SortedSet<CoordinateDistance> distances = GeoUtils.calcOrderedCoordinateDistances(point0, points)
List<CoordinateDistance> result = coordinateSourceMock.enrichedCornerPoints(point0, distances, 6)

then:
for (CoordinateDistance value: result) {
expectedPoints.contains(value.coordinateB)
}
result.size() == expectedPoints.size()
result.collect { it.coordinateB }.containsAll(expectedPoints)
}

def "IdCoordinateSource should return only one point of the bounding box if the starting coordinate exactly matched the found coordinate"() {
def "IdCoordinateSource should return only the corner points of a collection of coordinate distances"() {
given:
List<Point> expectedPoints = [
point1,
point2,
point4,
point5
]

when:
SortedSet<CoordinateDistance> distances = GeoUtils.calcOrderedCoordinateDistances(point0, points)
List<CoordinateDistance> result = coordinateSourceMock.findCornerPoints(point0, distances)

then:
result.size() == expectedPoints.size()
result.collect { it.coordinateB }.containsAll(expectedPoints)
}

def "IdCoordinateSource should return only one point if the starting coordinate exactly matched the found coordinate"() {
given:
Point matchingPoint = GeoUtils.buildPoint(52.5, 7.5)

when:
List<Point> withExactMatch = new ArrayList<>(points)
withExactMatch.addAll(matchingPoint)

List<CoordinateDistance> distances = coordinateSourceMock.calculateCoordinateDistances(point0, 9, withExactMatch)
List<CoordinateDistance> result = coordinateSourceMock.restrictToBoundingBox(point0, distances, 4)
SortedSet<CoordinateDistance> distances = GeoUtils.calcOrderedCoordinateDistances(point0, withExactMatch)
List<CoordinateDistance> result = coordinateSourceMock.findCornerPoints(point0, distances)

then:
result.size() == 1
Expand Down