Skip to content

Commit cfa5256

Browse files
committed
🚧 WIP Boundable (2) [Not compiling]
1 parent 28e5e9f commit cfa5256

File tree

6 files changed

+95
-62
lines changed

6 files changed

+95
-62
lines changed

‎Sources/GeodeticGeometry/Toolbox/Iterable.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,25 @@ public protocol Iterable<Element> {
1414
func makeIterator() -> Iterator
1515
}
1616

17-
public protocol NonEmptyIterable<Base>: Iterable {
17+
public protocol NonEmptyIterable<Base>: Iterable
18+
where Iterator == NonEmptyIterator<Base>
19+
{
1820
associatedtype Base: NonEmptyProtocol
19-
func makeIterator() -> NonEmptyIterator<Base>
2021
}
2122

2223
public struct NonEmptyIterator<Base: NonEmptyProtocol>: IteratorProtocol {
23-
private let _first: Base.Element
24+
public typealias Element = Base.Element
25+
26+
private let _first: Element
2427
private var base: Base.Iterator
2528
private var firstElementAccessed: Bool = false
2629

27-
init(base: Base) {
30+
public init(base: Base) {
2831
self._first = base.first
2932
self.base = base.makeIterator()
3033
}
3134

32-
public mutating func first() -> Base.Element {
35+
public mutating func first() -> Element {
3336
if self.firstElementAccessed {
3437
return self._first
3538
} else {
@@ -39,7 +42,13 @@ public struct NonEmptyIterator<Base: NonEmptyProtocol>: IteratorProtocol {
3942
return self._first
4043
}
4144
}
42-
public mutating func next() -> Base.Element? {
45+
public mutating func next() -> Element? {
4346
self.base.next()
4447
}
4548
}
49+
50+
// MARK: - Standard types conformances
51+
52+
extension Array: Iterable {}
53+
extension Set: Iterable {}
54+
extension Slice: Iterable {}

‎Sources/TurfCore/Boundable.swift

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// Copyright © 2022 Rémi Bardon. All rights reserved.
77
//
88

9-
//import NonEmpty
109
import GeodeticGeometry
1110

1211
public protocol Boundable<BoundingBox> {
@@ -31,41 +30,27 @@ extension GeodeticGeometry.Point where Self.Coordinates: Boundable {
3130
public var bbox: Self.Coordinates.BoundingBox { self.coordinates.bbox }
3231
}
3332

34-
extension GeodeticGeometry.Line where Self.GeometricSystem: GeometricSystemAlgebra {
35-
public var bbox: Self.GeometricSystem.BoundingBox {
36-
Self.GeometricSystem.bbox(forCollection: self.points)
33+
// MARK: Iterable types
34+
35+
extension Iterable
36+
where Self.Element: Boundable,
37+
Self.Element.BoundingBox.GeometricSystem: GeometricSystemAlgebra,
38+
Self.Element.BoundingBox == Self.Element.BoundingBox.GeometricSystem.BoundingBox
39+
{
40+
public var bbox: Self.Element.BoundingBox? {
41+
Self.Element.BoundingBox.GeometricSystem.bbox(forIterable: self)
3742
}
3843
}
3944

40-
//extension Line2D: Boundable {
41-
//
42-
// public var bbox: BoundingBox2D {
43-
// Turf.naiveBBox(forCollection: self.points) ?? BoundingBox2D(southWest: self.points.first, width: .zero, height: .zero)
44-
// }
45-
//
46-
//}
47-
//
48-
//extension Line3D: Boundable {
49-
//
50-
// public var bbox: BoundingBox3D {
51-
// Turf.naiveBBox(forNonEmptyCollection: self.points)
52-
// }
53-
//
54-
//}
55-
//
56-
//extension BoundingBox2D: Boundable {
57-
//
58-
// public var bbox: BoundingBox2D { self }
59-
//
60-
//}
61-
//
62-
//extension BoundingBox3D: Boundable {
63-
//
64-
// public var bbox: BoundingBox3D { self }
65-
//
66-
//}
67-
68-
// MARK: Sequences
45+
extension NonEmptyIterable
46+
where Self.Element: Boundable,
47+
Self.Element.BoundingBox.GeometricSystem: GeometricSystemAlgebra,
48+
Self.Element.BoundingBox == Self.Element.BoundingBox.GeometricSystem.BoundingBox
49+
{
50+
public var bbox: Self.Element.BoundingBox {
51+
Self.Element.BoundingBox.GeometricSystem.bbox(forNonEmptyIterable: self)
52+
}
53+
}
6954

7055
extension Sequence where Self.Element: Boundable, Self.Element.BoundingBox: Boundable {
7156
public var bbox: Self.Element.BoundingBox {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by Rémi Bardon on 28/11/2022.
6+
//
7+
8+
import GeodeticGeometry
9+
10+
public extension MultiPoint {
11+
func makeIterator() -> NonEmptyIterator<Self.Points> {
12+
NonEmptyIterator(base: self.points)
13+
}
14+
}

‎Sources/TurfCore/GeodeticGeometry+Turf.swift

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ public extension GeometricSystemAlgebra {
1919
Self.BoundingBox(origin: point.coordinates, size: .zero)
2020
}
2121

22-
static func bbox<C>(forNonEmptyCollection elements: C) -> Self.BoundingBox
23-
where C: NonEmptyProtocol, C.Element: Boundable<Self.BoundingBox>
24-
{
25-
Self.bbox(forCollection: elements) ?? elements.first.bbox
26-
}
27-
2822
static func bbox<Iterator>(forIterator iterator: inout Iterator) -> Self.BoundingBox?
2923
where Iterator: IteratorProtocol, Iterator.Element: Boundable<Self.BoundingBox>
3024
{
@@ -40,8 +34,8 @@ public extension GeometricSystemAlgebra {
4034

4135
static func bbox<S>(
4236
forNonEmptyIterator iterator: inout NonEmptyIterator<S>
43-
) -> Self.BoundingBox?
44-
where S: Sequence, S.Element: Boundable<Self.BoundingBox>
37+
) -> Self.BoundingBox
38+
where S.Element: Boundable<Self.BoundingBox>
4539
{
4640
var bbox: Self.BoundingBox = iterator.first().bbox
4741
while let element = iterator.next() {
@@ -50,11 +44,18 @@ public extension GeometricSystemAlgebra {
5044
return bbox
5145
}
5246

53-
static func bbox<MultiPoint>(forMultiPoint multiPoint: MultiPoint) -> Self.BoundingBox
54-
where MultiPoint: GeodeticGeometry.MultiPoint,
55-
MultiPoint.Points.Element: Boundable<Self.BoundingBox>
47+
static func bbox<C>(forIterable elements: C) -> Self.BoundingBox?
48+
where C: Iterable, C.Element: Boundable<Self.BoundingBox>
5649
{
57-
Self.bbox(forCollection: multiPoint.points) ?? multiPoint.points.first.bbox
50+
var iterator = elements.makeIterator()
51+
return Self.bbox(forIterator: &iterator)
52+
}
53+
54+
static func bbox<C>(forNonEmptyIterable elements: C) -> Self.BoundingBox
55+
where C: NonEmptyIterable, C.Element: Boundable<Self.BoundingBox>
56+
{
57+
var iterator = elements.makeIterator()
58+
return Self.bbox(forIterator: &iterator) ?? iterator.first().bbox
5859
}
5960

6061
static func geographicBBox<C: Collection>(forCollection coordinates: C) -> Self.BoundingBox?
@@ -70,12 +71,12 @@ public extension GeometricSystemAlgebra {
7071
return self.geographicBBox(forCollection: multiPoint.points)
7172
?? self.bbox(forPoint: multiPoint.points.first)
7273
}
73-
74-
static func center<Points: Collection>(forCollection points: Points) -> Self.Coordinates?
75-
where Points.Element == Self.Point
74+
75+
76+
static func center<C>(forIterable elements: C) -> Self.Coordinates?
77+
where C: Iterable, C.Element == Self.Point
7678
{
77-
return Self.bbox(forCollection: points)
78-
.flatMap(Self.center(forBBox:))
79+
Self.bbox(forIterable: elements).flatMap(Self.center(forBBox:))
7980
}
8081

8182
static func centroid<Points: Collection>(forCollection points: Points) -> Self.Coordinates?

‎Sources/TurfCore/GeometricSystemAlgebra.swift

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,46 @@ import ValueWithUnit
1313

1414
#warning("TODO: Replace all the `bbox` by one or two using `Boundable`")
1515

16-
public protocol GeometricSystemAlgebra: GeodeticGeometry.GeometricSystem {
16+
public protocol GeometricSystemAlgebra: GeodeticGeometry.GeometricSystem
17+
where Self.BoundingBox: Boundable<Self.BoundingBox>,
18+
Self.Point: Boundable<Self.BoundingBox>
19+
{
1720

1821
// MARK: Bounding box
1922

20-
static func bbox(forPoint point: Self.Point) -> Self.BoundingBox
23+
/// Returns a naive [bounding box](https://en.wikipedia.org/wiki/Minimum_bounding_box)
24+
/// enclosing a cluster of geometrical elements.
25+
/// - Warning: This does not take into account the curvature of the Earth.
26+
/// - Warning: This is a naive implementation, not taking into account the angular coordinate system
27+
/// (i.e. a cluster around 0°N 180°E will have a bounding box around 0°N 0°E).
28+
static func bbox<Iterator>(forIterator iterator: inout Iterator) -> Self.BoundingBox?
29+
where Iterator: IteratorProtocol, Iterator.Element: Boundable<Self.BoundingBox>
30+
31+
/// Returns a naive [bounding box](https://en.wikipedia.org/wiki/Minimum_bounding_box)
32+
/// enclosing a cluster of geometrical elements.
33+
/// - Warning: This does not take into account the curvature of the Earth.
34+
/// - Warning: This is a naive implementation, not taking into account the angular coordinate system
35+
/// (i.e. a cluster around 0°N 180°E will have a bounding box around 0°N 0°E).
36+
static func bbox<Base>(
37+
forNonEmptyIterator iterator: inout NonEmptyIterator<Base>
38+
) -> Self.BoundingBox
39+
where Base.Element: Boundable<Self.BoundingBox>
2140

2241
/// Returns a naive [bounding box](https://en.wikipedia.org/wiki/Minimum_bounding_box)
2342
/// enclosing a cluster of geometrical elements.
2443
/// - Warning: This does not take into account the curvature of the Earth.
2544
/// - Warning: This is a naive implementation, not taking into account the angular coordinate system
2645
/// (i.e. a cluster around 0°N 180°E will have a bounding box around 0°N 0°E).
27-
static func bbox<C>(forCollection elements: C) -> Self.BoundingBox?
28-
where C: Collection, C.Element: Boundable
46+
static func bbox<C>(forIterable elements: C) -> Self.BoundingBox?
47+
where C: Iterable, C.Element: Boundable<Self.BoundingBox>
2948

3049
/// Returns a naive [bounding box](https://en.wikipedia.org/wiki/Minimum_bounding_box)
3150
/// enclosing a cluster of geometrical elements.
3251
/// - Warning: This does not take into account the curvature of the Earth.
3352
/// - Warning: This is a naive implementation, not taking into account the angular coordinate system
3453
/// (i.e. a cluster around 0°N 180°E will have a bounding box around 0°N 0°E).
35-
static func bbox<C>(forNonEmptyCollection elements: C) -> Self.BoundingBox
36-
where C: NonEmptyProtocol, C.Element: Boundable
54+
static func bbox<C>(forNonEmptyIterable elements: C) -> Self.BoundingBox
55+
where C: NonEmptyIterable, C.Element: Boundable<Self.BoundingBox>
3756

3857
/// Returns a naive [bounding box](https://en.wikipedia.org/wiki/Minimum_bounding_box)
3958
/// enclosing a cluster of points.

‎Sources/WGS84Turf/WGS84+Turf.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,19 @@
77
//
88

99
import SwiftGeoToolbox
10+
import TurfCore
1011
import protocol Turf.GeometricSystemAlgebra
1112
import enum WGS84Geometry.WGS842D
1213
import enum WGS84Geometry.WGS843D
1314

15+
extension WGS842D.BoundingBox: Boundable {}
16+
extension WGS842D.Point: Boundable {}
17+
1418
extension WGS842D: GeometricSystemAlgebra {
1519
public static func center(forBBox bbox: Self.BoundingBox) -> Self.Coordinates {
1620
let offset: Self.Size = bbox.size / 2
1721
return bbox.origin.offsetBy(offset.rawValue)
1822
}
1923
}
24+
2025
extension WGS843D: GeometricSystemAlgebra {}

0 commit comments

Comments
 (0)