-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
7 changed files
with
406 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
// | ||
// BoundingBox2D.swift | ||
// SwiftGeo | ||
// | ||
// Created by Rémi Bardon on 02/02/2022. | ||
// Copyright © 2022 Rémi Bardon. All rights reserved. | ||
// | ||
|
||
public struct BoundingBox2D: Hashable { | ||
|
||
public var southWest: Coordinate2D | ||
public var width: Longitude | ||
public var height: Latitude | ||
|
||
public var southLatitude: Latitude { | ||
southWest.latitude | ||
} | ||
public var northLatitude: Latitude { | ||
southLatitude + height | ||
} | ||
public var centerLatitude: Latitude { | ||
southLatitude + (height / 2.0) | ||
} | ||
public var westLongitude: Longitude { | ||
southWest.longitude | ||
} | ||
public var eastLongitude: Longitude { | ||
let longitude = westLongitude + width | ||
|
||
if longitude > .halfRotation { | ||
return longitude - .fullRotation | ||
} else { | ||
return longitude | ||
} | ||
} | ||
public var centerLongitude: Longitude { | ||
let longitude = westLongitude + (width / 2.0) | ||
|
||
if longitude > .halfRotation { | ||
return longitude - .fullRotation | ||
} else { | ||
return longitude | ||
} | ||
} | ||
|
||
public var northEast: Coordinate2D { | ||
Coordinate2D(latitude: northLatitude, longitude: eastLongitude) | ||
} | ||
public var northWest: Coordinate2D { | ||
Coordinate2D(latitude: northLatitude, longitude: westLongitude) | ||
} | ||
public var southEast: Coordinate2D { | ||
Coordinate2D(latitude: southLatitude, longitude: westLongitude) | ||
} | ||
public var center: Coordinate2D { | ||
Coordinate2D(latitude: centerLatitude, longitude: centerLongitude) | ||
} | ||
|
||
public var south: Coordinate2D { | ||
southAtLongitude(centerLongitude) | ||
} | ||
public var north: Coordinate2D { | ||
northAtLongitude(centerLongitude) | ||
} | ||
public var west: Coordinate2D { | ||
westAtLatitude(centerLatitude) | ||
} | ||
public var east: Coordinate2D { | ||
eastAtLatitude(centerLatitude) | ||
} | ||
|
||
public var crosses180thMeridian: Bool { | ||
westLongitude > eastLongitude | ||
} | ||
|
||
public init( | ||
southWest: Coordinate2D, | ||
width: Longitude, | ||
height: Latitude | ||
) { | ||
self.southWest = southWest | ||
self.width = width | ||
self.height = height | ||
} | ||
|
||
public init( | ||
southWest: Coordinate2D, | ||
northEast: Coordinate2D | ||
) { | ||
self.init( | ||
southWest: southWest, | ||
width: northEast.longitude - southWest.longitude, | ||
height: northEast.latitude - southWest.latitude | ||
) | ||
} | ||
|
||
public func southAtLongitude(_ longitude: Longitude) -> Coordinate2D { | ||
Coordinate2D(latitude: northEast.latitude, longitude: longitude) | ||
} | ||
public func northAtLongitude(_ longitude: Longitude) -> Coordinate2D { | ||
Coordinate2D(latitude: southWest.latitude, longitude: longitude) | ||
} | ||
public func westAtLatitude(_ latitude: Latitude) -> Coordinate2D { | ||
Coordinate2D(latitude: latitude, longitude: southWest.longitude) | ||
} | ||
public func eastAtLatitude(_ latitude: Latitude) -> Coordinate2D { | ||
Coordinate2D(latitude: latitude, longitude: northEast.longitude) | ||
} | ||
|
||
public func offsetBy(dLat: Latitude = .zero, dLong: Longitude = .zero) -> BoundingBox2D { | ||
Self.init( | ||
southWest: southWest.offsetBy(dLat: dLat, dLong: dLong), | ||
width: width, | ||
height: height | ||
) | ||
} | ||
public func offsetBy(dx: Coordinate2D.X = .zero, dy: Coordinate2D.Y = .zero) -> BoundingBox2D { | ||
Self.init( | ||
southWest: southWest.offsetBy(dx: dx, dy: dy), | ||
width: width, | ||
height: height | ||
) | ||
} | ||
|
||
} | ||
|
||
extension BoundingBox2D: BoundingBox { | ||
|
||
public static var zero: BoundingBox2D { | ||
Self.init(southWest: .zero, width: .zero, height: .zero) | ||
} | ||
|
||
/// The union of bounding boxes gives a new bounding box that encloses the given two. | ||
public func union(_ other: BoundingBox2D) -> BoundingBox2D { | ||
Self.init( | ||
southWest: Coordinate2D( | ||
latitude: min(self.southLatitude, other.southLatitude), | ||
longitude: min(self.westLongitude, other.westLongitude) | ||
), | ||
northEast: Coordinate2D( | ||
latitude: max(self.northLatitude, other.northLatitude), | ||
longitude: max(self.eastLongitude, other.eastLongitude) | ||
) | ||
) | ||
} | ||
|
||
} | ||
|
||
extension BoundingBox2D { | ||
|
||
public func union(_ bbox3d: BoundingBox3D) -> BoundingBox3D { bbox3d.union(self) } | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// | ||
// BoundingBox3D.swift | ||
// SwiftGeo | ||
// | ||
// Created by Rémi Bardon on 08/02/2022. | ||
// Copyright © 2022 Rémi Bardon. All rights reserved. | ||
// | ||
|
||
public struct BoundingBox3D: Hashable { | ||
|
||
public var twoDimensions: BoundingBox2D | ||
public var lowAltitude: Altitude | ||
public var zHeight: Altitude | ||
|
||
public var highAltitude: Altitude { | ||
lowAltitude + zHeight | ||
} | ||
public var centerAltitude: Altitude { | ||
lowAltitude + (zHeight / 2.0) | ||
} | ||
|
||
public var southWestLow: Coordinate3D { | ||
Coordinate3D(twoDimensions.southWest, altitude: lowAltitude) | ||
} | ||
public var northEastHigh: Coordinate3D { | ||
Coordinate3D(twoDimensions.northEast, altitude: highAltitude) | ||
} | ||
public var center: Coordinate3D { | ||
Coordinate3D(twoDimensions.center, altitude: centerAltitude) | ||
} | ||
|
||
public var crosses180thMeridian: Bool { | ||
twoDimensions.crosses180thMeridian | ||
} | ||
|
||
public init(_ boundingBox2d: BoundingBox2D, lowAltitude: Altitude, zHeight: Altitude) { | ||
self.twoDimensions = boundingBox2d | ||
self.lowAltitude = lowAltitude | ||
self.zHeight = zHeight | ||
} | ||
|
||
public init( | ||
southWestLow: Coordinate3D, | ||
width: Longitude, | ||
height: Latitude, | ||
zHeight: Altitude | ||
) { | ||
self.init( | ||
BoundingBox2D(southWest: southWestLow.twoDimensions, width: width, height: height), | ||
lowAltitude: southWestLow.altitude, | ||
zHeight: zHeight | ||
) | ||
} | ||
|
||
public init( | ||
southWestLow: Coordinate3D, | ||
northEastHigh: Coordinate3D | ||
) { | ||
self.init( | ||
southWestLow: southWestLow, | ||
width: northEastHigh.longitude - southWestLow.longitude, | ||
height: northEastHigh.latitude - southWestLow.latitude, | ||
zHeight: northEastHigh.altitude - southWestLow.altitude | ||
) | ||
} | ||
|
||
public func offsetBy( | ||
dLat: Latitude = .zero, | ||
dLong: Longitude = .zero, | ||
dAlt: Altitude = .zero | ||
) -> BoundingBox3D { | ||
Self.init( | ||
twoDimensions.offsetBy(dLat: dLat, dLong: dLong), | ||
lowAltitude: lowAltitude + dAlt, | ||
zHeight: zHeight | ||
) | ||
} | ||
public func offsetBy( | ||
dx: Coordinate3D.X = .zero, | ||
dy: Coordinate3D.Y = .zero, | ||
dz: Coordinate3D.Z = .zero | ||
) -> BoundingBox3D { | ||
Self.init( | ||
twoDimensions.offsetBy(dx: dx, dy: dy), | ||
lowAltitude: lowAltitude + dz, | ||
zHeight: zHeight | ||
) | ||
} | ||
|
||
} | ||
|
||
extension BoundingBox3D: BoundingBox { | ||
|
||
public static var zero: BoundingBox3D { | ||
BoundingBox3D(.zero, lowAltitude: .zero, zHeight: .zero) | ||
} | ||
|
||
/// The union of bounding boxes gives a new bounding box that encloses the given two. | ||
public func union(_ other: BoundingBox3D) -> BoundingBox3D { | ||
BoundingBox3D( | ||
southWestLow: Coordinate3D( | ||
self.twoDimensions.union(other.twoDimensions).southWest, | ||
altitude: min(self.lowAltitude, other.lowAltitude) | ||
), | ||
northEastHigh: Coordinate3D( | ||
self.twoDimensions.union(other.twoDimensions).northEast, | ||
altitude: max(self.highAltitude, other.highAltitude) | ||
) | ||
) | ||
} | ||
|
||
} | ||
|
||
extension BoundingBox3D { | ||
|
||
public func union(_ bbox2d: BoundingBox2D) -> BoundingBox3D { | ||
let other = BoundingBox3D(bbox2d, lowAltitude: self.lowAltitude, zHeight: .zero) | ||
return self.union(other) | ||
} | ||
|
||
} |
Oops, something went wrong.