Skip to content

Commit

Permalink
MultiLineString
Browse files Browse the repository at this point in the history
  • Loading branch information
trasch committed Aug 8, 2024
1 parent 0368e73 commit 26b2fb9
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 20 deletions.
10 changes: 8 additions & 2 deletions Sources/GISTools/Algorithms/LineOverlap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ extension GeoJson {
///
/// - Returns: All segments that at least overlap with one other segment. Each segment will only be
/// in the result once.
public func overlappingSegments(tolerance: CLLocationDistance = 0.0) -> [LineSegment] {
public func overlappingSegments(tolerance: CLLocationDistance = 0.0) -> MultiLineString? {
let tolerance = abs(tolerance)
let sortedSegments: [LineSegment] = lineSegments
.map { lineSegment in
Expand Down Expand Up @@ -284,7 +284,13 @@ extension GeoJson {
}
}

return result.map { sortedSegments[$0] }
var lineStrings: [LineString] = []

for range in result.rangeView {
lineStrings.append(LineString(range.map { sortedSegments[$0] })!)
}

return MultiLineString(lineStrings)
}

}
46 changes: 28 additions & 18 deletions Tests/GISToolsTests/Algorithms/LineOverlapTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,10 @@ final class LineOverlapTests: XCTestCase {
Coordinate3D(latitude: 12.0, longitude: 12.0),
])!

let overlapping = lineString.overlappingSegments()
XCTAssertEqual(overlapping.count, 0)
XCTAssertNil(lineString.overlappingSegments()?.lineStrings)
}

func testSelfOverlap1() {
func testSelfOverlap1() throws {
let lineString = LineString([
Coordinate3D(latitude: 0.0, longitude: 0.0),
Coordinate3D(latitude: 1.0, longitude: 1.0), // overlap
Expand All @@ -155,32 +154,33 @@ final class LineOverlapTests: XCTestCase {
Coordinate3D(latitude: 0.0, longitude: 1.0), // "
])!

let overlapping = lineString.overlappingSegments()
let overlapping = try XCTUnwrap(lineString.overlappingSegments()?.lineStrings)
XCTAssertEqual(overlapping.count, 3)
}

func testSelfOverlap2() {
func testSelfOverlap2() throws {
let lineString = LineString([
Coordinate3D(latitude: 0.0, longitude: 0.0),
Coordinate3D(latitude: 8.0, longitude: -8.0),
Coordinate3D(latitude: 0.0, longitude: 0.0), // overlap
Coordinate3D(latitude: 8.0, longitude: -8.0), // "
Coordinate3D(latitude: 7.0, longitude: -9.0),
Coordinate3D(latitude: 6.0, longitude: -9.0),
Coordinate3D(latitude: 6.0, longitude: -6.0),
Coordinate3D(latitude: 5.0, longitude: -5.0),
Coordinate3D(latitude: 6.0, longitude: -6.0), // overlap
Coordinate3D(latitude: 5.0, longitude: -5.0), // "
Coordinate3D(latitude: 5.0, longitude: -7.0),
Coordinate3D(latitude: 4.0, longitude: -7.0),
Coordinate3D(latitude: 4.0, longitude: -4.0),
Coordinate3D(latitude: 3.0, longitude: -3.0),
Coordinate3D(latitude: 4.0, longitude: -4.0), // overlap
Coordinate3D(latitude: 3.0, longitude: -3.0), // "
Coordinate3D(latitude: 3.0, longitude: -1.0),
Coordinate3D(latitude: 1.0, longitude: -1.0),
Coordinate3D(latitude: 0.0, longitude: 0.0),
Coordinate3D(latitude: 1.0, longitude: -1.0), // overlap
Coordinate3D(latitude: 0.0, longitude: 0.0), // "
])!

let overlapping = lineString.overlappingSegments()
let overlapping = try XCTUnwrap(lineString.overlappingSegments()?.lineStrings)
FeatureCollection(overlapping).dump()
XCTAssertEqual(overlapping.count, 4)
}

func testSelfOverlap3() {
func testSelfOverlap3() throws {
let lineString = LineString([
Coordinate3D(latitude: 0.0, longitude: 0.0),
Coordinate3D(latitude: 2.0, longitude: 0.0),
Expand All @@ -194,11 +194,11 @@ final class LineOverlapTests: XCTestCase {
Coordinate3D(latitude: 0.0, longitude: 0.0),
])!

let overlapping = lineString.overlappingSegments()
let overlapping = try XCTUnwrap(lineString.overlappingSegments()?.lineStrings)
XCTAssertEqual(overlapping.count, 3)
}

func testSelfOverlap3WithSegments() {
func testSelfOverlap3WithSegments() throws {
let lineString = LineString([
Coordinate3D(latitude: 0.0, longitude: 0.0),
Coordinate3D(latitude: 2.0, longitude: 0.0),
Expand All @@ -212,8 +212,18 @@ final class LineOverlapTests: XCTestCase {
Coordinate3D(latitude: 0.0, longitude: 0.0),
])!

let overlapping = lineString.overlappingSegments()
let overlapping = try XCTUnwrap(lineString.overlappingSegments()?.lineStrings)
XCTAssertEqual(overlapping.count, 3)
}

func testLongRouteSelfOverlap() throws {
let lineString = try XCTUnwrap(TestData.featureCollection(package: "LineOverlap", name: "LongRoute").features.first)

let overlapping = try XCTUnwrap(lineString.overlappingSegments(tolerance: 10.0)?.lineStrings)
print(overlapping.count)
print(overlapping.reduce(0.0, { $0 + $1.length }))
print(lineString.length)

}

}

0 comments on commit 26b2fb9

Please sign in to comment.