A spatial analysis library written in Swift for native iOS, macOS, tvOS, watchOS, and Linux applications, ported from Turf.js.

Overview

Turf for Swift

📱 iOS     🖥 💻 macOS     📺 tvOS     ⌚️ watchOS     Linux     Documentation     Carthage compatible     CocoaPods     SPM compatible    

A spatial analysis library written in Swift for native iOS, macOS, tvOS, watchOS, and Linux applications, ported from Turf.js.

Requirements

Turf requires Xcode 12.0 or above and supports the following minimum deployment targets:

  • iOS 10.0 and above
  • macOS 10.12 (Sierra) and above
  • tvOS 10.0 and above
  • watchOS 3.0 and above

Alternatively, you can incorporate Turf into a command line tool without Xcode on any platform that Swift supports, including Linux.

If your project is written in Objective-C, you’ll need to write a compatibility layer between turf-swift and your Objective-C code. If your project is written in Objective-C++, you may be able to use spatial-algorithms as an alternative to Turf.

Installation

Although a stable release of this library is not yet available, prereleases are available for installation using any of the popular Swift dependency managers.

CocoaPods

To install Turf using CocoaPods:

  1. Specify the following dependency in your Podfile:
    pod 'Turf', '~> 2.4'
  2. Run pod repo update if you haven’t lately.
  3. Run pod install and open the resulting Xcode workspace.
  4. Add import Turf to any Swift file in your application target.

Carthage

To install Turf using Carthage:

  1. Add the following dependency to your Cartfile:
    2.4">
    github "mapbox/turf-swift" ~> 2.4
    
  2. Run carthage bootstrap.
  3. Follow the rest of Carthage’s integration instructions. Your application target’s Embedded Frameworks should include Turf.framework.
  4. Add import Turf to any Swift file in your application target.

Swift Package Manager

To install Turf using the Swift Package Manager, add the following package to the dependencies in your Package.swift file:

.package(url: "https://github.com/mapbox/turf-swift.git", from: "2.4.0")

Then import Turf in any Swift file in your module.

Available functionality

This work-in-progress port of Turf.js contains the following functionality:

Turf.js Turf for Swift
turf-along#along LineString.coordinateFromStart(distance:)
turf-area#area Polygon.area
turf-bearing#bearing CLLocationCoordinate2D.direction(to:)
LocationCoordinate2D.direction(to:) on Linux
RadianCoordinate2D.direction(to:)
turf-bezier-spline#bezierSpline LineString.bezier(resolution:sharpness:)
turf-boolean-point-in-polygon#booleanPointInPolygon Polygon.contains(_:ignoreBoundary:)
turf-center#center Polygon.center
turf-center-of-mass#centerOfMass Polygon.centerOfMass
turf-centroid#centroid Polygon.centroid
turf-circle#circle Polygon(center:radius:vertices:)
turf-destination#destination CLLocationCoordinate2D.coordinate(at:facing:)
LocationCoordinate2D.coordinate(at:facing:) on Linux
RadianCoordinate2D.coordinate(at:facing:)
turf-distance#distance CLLocationCoordinate2D.distance(to:)
LocationCoordinate2D.distance(to:) on Linux
RadianCoordinate2D.distance(to:)
turf-helpers#polygon Polygon(_:)
turf-helpers#lineString LineString(_:)
turf-helpers#degreesToRadians CLLocationDegrees.toRadians()
LocationDegrees.toRadians() on Linux
turf-helpers#radiansToDegrees CLLocationDegrees.toDegrees()
LocationDegrees.toDegrees() on Linux
turf-helpers#convertLength
turf-helpers#convertArea
Measurement.converted(to:)
turf-length#length LineString.distance(from:to:)
turf-line-intersect#lineIntersect LineString.intersections(with:)
turf-line-slice#lineSlice LineString.sliced(from:to:)
turf-line-slice-along#lineSliceAlong LineString.trimmed(from:to:)
turf-midpoint#midpoint mid(_:_:)
turf-nearest-point-on-line#nearestPointOnLine LineString.closestCoordinate(to:)
turf-polygon-to-line#polygonToLine LineString(_:)
MultiLineString(_:)
turf-simplify#simplify LineString.simplify(tolerance:highestQuality:)
LineString.simplified(tolerance:highestQuality:)
turf-polygon-smooth#polygonSmooth Polygon.smooth(iterations:)
CLLocationDirection.difference(from:)
LocationDirection.difference(from:) on Linux
CLLocationDirection.wrap(min:max:)
LocationDirection.wrap(min:max:) on Linux

GeoJSON

turf-swift also contains a GeoJSON encoder/decoder with support for Codable.

// Decode an unknown GeoJSON object.
let geojson = try JSONDecoder().decode(GeoJSONObject.self, from: data)
guard case let .feature(feature) = geojson,
      case let .point(point) = feature.geometry else {
    return
}

// Decode a known GeoJSON object.
let featureCollection = try JSONDecoder().decode(FeatureCollection.self, from: data)

// Initialize a Point feature and encode it as GeoJSON.
let coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 1)
let point = Point(coordinate)
let pointFeature = Feature(geometry: .point(point))
let data = try JSONEncoder().encode(pointFeature)
let json = String(data: data, encoding: .utf8)
print(json)

/*
{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [
      1,
      0
    ]
  }
}
*/
Comments
  • Polyline struct

    Polyline struct

    Assuming we aren’t overly concerned about Objective-C compatibility, we should encapsulate the concept of a “polygon” in a struct named Polyline or Line (to use Turf.js terminology), instead of assuming that any array of CLLocationCoordinate2Ds is intended to be connected sequentially. We could then place most of the freestanding functions under Polyline as instance methods.

    Is there a more Swiftian representation than a struct that would allow client code to take advantage of all the Array methods more directly?

    /cc @frederoni @bsudekum

    opened by 1ec5 5
  • Sane JSON Representations

    Sane JSON Representations

    There are places in turf-swift where we currently represent a JSON object with [String:AnyJSONType] as opposed to the more common [String:Any] regularly found in iOS frameworks.

    As mentioned elsewhere, [AnyJSONType] isn't really worth the hassle of keeping around, since you still have to type-cast for the value at the point-of-use.

    https://github.com/mapbox/turf-swift/blob/093d9cb4fce73b14f4f9ceb5766a313e4d8972be/Sources/Turf/Codable.swift#L23-L70

    Let's get a PR going where we remove the replace the bespoke representation with a standard one.

    /cc @mapbox/navigation-ios

    op-ex backwards incompatible 
    opened by JThramer 4
  • Added midpoint func

    Added midpoint func

    Modeled after midpoint function in Turfjs (https://github.com/Turfjs/turf/blob/17002ccd57e04e84ddb38d7e3ac8ede35b019c58/packages/turf-midpoint/index.js). See also, http://turfjs.org/docs#midpoint

    I've tested this against several coordinate pairs and get the same results as with Turfjs (but I wouldn't say it was exhaustive). It would be helpful to have this function to mirror what's in Turfjs.

    improvement JS parity Java parity 
    opened by stonetip 4
  • Inconsistent results from Polyline.distance

    Inconsistent results from Polyline.distance

    I'm getting small inconsistencies from Polyline.distance. By tracing intermediate points along a polyline from start to end - including between vertices - the resulting distance(to: point) doesn't consistently increment from 0 to (total distance), but jumps up and down.

    My suspicion is that there's something screwy going on with the interaction with closestCoordinate but I've not been able to nail it down.

    For my purposes I only need the distance to a point from the start of the polyline, so I was able to get round it by hacking a baseIndex property onto closestCoordinate which always contains the value of index (not index+1) and then building this round it:

    let slice = polyline.coordinates[0 ... coord.baseIndex]
    let zipped = zip(slice.prefix(upTo: slice.count - 1), slice.suffix(from: 1))
    return zipped.map { $0.distance(to: $1) }.reduce(0, +) +
    	polyline.coordinates[coord.baseIndex].distance(to: coord.coordinate)
    

    but I thought it worth flagging in case anyone else encounters this.

    opened by systemed 4
  • Geometric types should conform to common protocol that converts to Geometry

    Geometric types should conform to common protocol that converts to Geometry

    GEOSwift defines a GeometryConvertible protocol that makes it possible to initialize a Feature without redundantly specifying both the Geometry case and the geometric type’s initializer at the same time. Turf’s GeoJSONObject and Geometry enumerations should have something similar. For example:

    var geoJSON = Feature(geometry: .point(Point(coordinate)))
    

    would become simply:

    var geoJSON = Feature(geometry: Point(coordinate))
    

    It’s similar to the initializers and literals that #154 added to JSONValue, but this protocol distributes the implementation across each type:

    https://github.com/mapbox/turf-swift/blob/007896bb945432d4683e114fcf2f089edff4ceeb/Sources/Turf/JSON.swift#L49-L52

    /cc @macdrevx

    improvement 
    opened by 1ec5 3
  • 新版swift不支持问题

    新版swift不支持问题

    Xcode12.3 error, your library does not support new Version of Compiled Swift language Module with Swift 5.3 cannot be imported by the SWIFT 5.3.2 Compiler

    opened by fenghedemo1 3
  • Path is little off from the center of the road

    Path is little off from the center of the road

    When path is sliced then sometimes it gets off from route. Please see the screenshot.

    // Expected Behaviour

    Path shouldn't be off from the center of the road

    // Actual Behavior

    Path is off from the center of the road.

    Code to trim the path turfPolyline.sliced(from: coordinate, to: turfPolyline.coordinates.last)

    bug 
    opened by rohit-aq 3
  • Add property to Point or LineString

    Add property to Point or LineString

    Hello. I want parse map.osm to geoJSON with Turf... And in openstreetmap use tag: <tag k="shop" v="convenience"/>

    How can i add this tag in geoJSON file? Thank you

    question 
    opened by aSeniyants 2
  • Improve performance of trimmed(from:,to:)

    Improve performance of trimmed(from:,to:)

    So, I found the performance of the LineString.trimmed(from:to:) to be unusably slow and that it's caused by this distance calculation.

    Calculating the distance between coordinates i and i+1 can be done with a simple/cheap distance(to:), but instead the LineString.distance(from:to:) is used, which kills performance because it allows from/to to not be on the line and has to calculate which line coordinate is closest using closestCoordinate(to:), a O(n) operation, which leaves trimmed(from:to:) at a terrible O(n^2).

    Please let me know if I'm missing anything.

    performance 
    opened by jonkan 2
  • Optionally avoid decoding or encoding foreign members

    Optionally avoid decoding or encoding foreign members

    ForeignMemberContainer’s Codable implementation can be very slow for complex GeoJSON because it needs to iterate over allKeys and convert each individual coding key. The Codable implementations of ForeignMemberContainer-containing types should short-circuit foreign member encoding and decoding when the encoder or decoder’s userInfo contains a flag suppressing this step.

    /ref https://github.com/mapbox/mapbox-directions-swift/pull/669#discussion_r842877486 /cc @mapbox/navigation-ios @macdrevx

    op-ex performance 
    opened by 1ec5 2
  • Add conversions between enumerations and associated values

    Add conversions between enumerations and associated values

    Added protocol-based initializers to Geometry and GeoJSONObject that accept each case’s associated value as an initializer argument. This makes the enumerations more consistent with the JSONValue and FeatureIdentifier enumerations and simplifies some common workflows.

    JSONValue and FeatureIdentifier now conform to the Hashable protocol. These types are likely to be used as dictionary keys or set members, and it’s pretty easy to make them hashable.

    Fixes #158.

    /cc @mapbox/navigation-ios @mapbox/maps-ios

    improvement 
    opened by 1ec5 2
  • Enabling automatic test discovery on Linux

    Enabling automatic test discovery on Linux

    PR updates swift version used on Travis CI linux job which enables automatic test discovery on Linux platform. Unit tests and SPM target corrected with found errors. Had to update Linux distributive from Trusty to Xenial since Ubuntu 14.04 does not come with Swift 5.4 support, and minimal supported version is Ubuntu 16.04 (as found here) which is represented with Xenial dist on Travis.

    op-ex 
    opened by Udumft 0
  • v2.5.0 documentation lacks method signatures

    v2.5.0 documentation lacks method signatures

    The published documentation for v2.5.0 lacks method signatures, and anchors to specific sections of the pages are broken. Compare the LineString.intersection(with:) documentation between v2.4.0 and v2.5.0:

    v2.4.0 v2.5.0

    This is a symptom of missing USRs. jazzy probably outputs a warning indicating the problem.

    /cc @mapbox/navigation-ios

    bug documentation build jira-sync-complete 
    opened by 1ec5 0
  • Add property for self-intersections (kinks) in polygons

    Add property for self-intersections (kinks) in polygons

    We have been working on trying to detect if a polygon intersects itself when a user is drawing a polygon on the map in realtime or after a user completes the polygon. We tried to implement our own method using multiple approaches with this being one of them but all seem to have false positives.

    Is there a plan to port this over from Turf.js? Has anyone implemented this in the past where you didn't receive false positives?

    JS parity feature jira-sync-complete 
    opened by Sean12oshea 1
  • Convert between GeoJSON and WKT

    Convert between GeoJSON and WKT

    This library’s GeoJSON types should have initializers that take WKT-formatted strings and properties that return WKT-formatted strings. This format is more compact than GeoJSON but more expressive than the Encoded Polyline format, supporting the full Simple Features specification, making it ideal for URL query parameters.

    The Turf.js project declined to support WKT conversion in Turfjs/turf#2057. However, this library has a slightly different scope, given that it defines its own types for in-memory representations of GeoJSON, something the JavaScript library inherently has no need for. The WKT format isn’t terribly complex, but we can port the wellknown library as a starting point.

    /cc @Guardiola31337

    JS parity feature jira-sync-complete 
    opened by 1ec5 1
  • Port geosimplify-js

    Port geosimplify-js

    LineString.simplify(tolerance:highestQuality:) and simplified(tolerance:highQuality:) are based on simplify-js, which is fine for certain simplification use cases. However, sampling the input to a map matching algorithm requires interpolating points along a straightaway: https://github.com/mapbox/mapbox-directions-swift/issues/661#issuecomment-1063184448. The standard Ramer–Douglas–Peucker algorithm can easily create a space between vertices large enough to result in a gap according to the map matching algorithm.

    geosimplify-js is a derivative of simplify-js that preserves points along straightaways. It could be ported to Swift as an alternative to the usual simplification algorithm. Suggested method signatures:

    mutating func simplify(minimumOffset: LocationDistance, minimumGap: LocationDistance)
    func simplified(minimumOffset: LocationDistance, minimumGap: LocationDistance)
    

    /cc @danpat @Guardiola31337

    JS parity feature jira-sync-complete 
    opened by 1ec5 1
  • Add method to divide LineString into equal chunks

    Add method to divide LineString into equal chunks

    The lineChunk method should be ported to this library:

    Divides a LineString into chunks of a specified length. If the line is shorter than the segment length then the original line is returned.

    This method would be useful for sampling a geometry before passing the simplified geometry into a map matching algorithm: https://github.com/mapbox/mapbox-directions-swift/issues/661#issuecomment-1063184448.

    Suggested LineString method signatures:

    func dividedIntoChunks(of length: LocationDistance, reversed: Bool) -> MultiLineString
    

    /cc @danpat @Guardiola31337

    JS parity feature jira-sync-complete 
    opened by 1ec5 2
Releases(v2.6.1)
  • v2.6.1(Nov 4, 2022)

  • v2.6.0(Nov 3, 2022)

  • v2.6.0-beta.1(Oct 21, 2022)

    Changes since v2.5.0:

    Packaging

    • This library now requires a minimum deployment target of iOS 11.0 or above, macOS 10.13.0 or above, tvOS 11.0 or above, or watchOS 4.0 or above. Older operating system versions are no longer supported. (#198)
    Source code(tar.gz)
    Source code(zip)
  • v2.5.0(Aug 11, 2022)

  • v2.4.0(Apr 12, 2022)

    Changes since v2.3.0:

    • Foreign members in GeoJSON are no longer encoded or decoded by default for performance reasons. To enable encoding or decoding of foreign members, set the CodingUserInfoKey.includesForeignMembers option to true in JSONEncoder.userInfo or JSONDecoder.userInfo, respectively. (#187)

    Documentation is available online or within Xcode.

    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Mar 3, 2022)

  • v2.2.0(Jan 21, 2022)

    Changes since v2.1.0:

    • The Feature, FeatureCollection, GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, and Polygon structs now conform to the ForeignMemberContainer protocol. Foreign members (unrecognized properties outside of properties) are stored in the ForeignMemberContainer.foreignMembers property and round-tripped to JSON. (#175)
    • Ring now conforms to the Codable protocol. (#175)

    Documentation is available online or within Xcode.

    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Nov 11, 2021)

    Changes since v2.0.0:

    • Added LineString.trimmed(from:to:) method that returns a sliced LineString based on the starting and stopping distances.
    • Added Linestring.intersection(with:) method that returns all the intersections of the LineString with another one.

    Documentation is available online or within Xcode.

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Oct 6, 2021)

    Changes since v1.2.0:

    Packaging

    • ⚠️ Turf requires Xcode 12.0 or above to build from source. (#152)
    • ⚠️ When installing this library using Carthage, Carthage builds it with library evolution enabled. (#134)
    • Turf is now 100% documented. A full API reference is available online. (#162)

    Geometry

    • ⚠️ Replaced the Linux-specific definitions of CLLocationCoordinate2D, CLLocationDirection, CLLocationDistance, and CLLocationDegrees with LocationCoordinate2D, LocationDirection, LocationDistance, and LocationDegrees, respectively. On Apple platforms, the new types remain type aliases, so you can continue to use the familiar CL-prefixed Core Location types unless you are writing cross-platform code that supports Linux. (#132)

    • ⚠️ Combined the GeoJSON class and GeoJSON protocol into a unified GeoJSONObject enumeration. Use JSONDecoder instead of the GeoJSON.parse(_:) or GeoJSON.parse<T: GeoJSONObject>(_:from:) method. (#154)

      v1.x
      if let feature = try GeoJSON.parse(data)?.decodedFeature,
         case let .lineString(lineString) = feature.geometry { … }
      
      v2.0.0
      if case let .feature(feature) = try JSONDecoder().decode(GeoJSONObject.self, from: data),
         case let .lineString(lineString) = feature.geometry { … }
      
    • ⚠️ Removed the FeatureCollection.identifier and FeatureCollection.properties properties with no replacement. These properties had been represented in GeoJSON by foreign members, which are not yet implemented. If you had been relying on the identifier or properties foreign members of FeatureCollection objects, move the data to each individual feature in the collection. (#154)

      v1.x
      let uuid = UUID().description
      featureCollection.identifier = .string(uuid)
      
      v2.0.0
      let uuid = UUID().description
      for feature in featureCollection.features {
          $0.identifier = .string(uuid)
      }
      
    • ⚠️ The Feature.properties property is now a JSONObject? (in other words, [String: JSONValue?]?). JSONObject is type-checked at compile time instead of runtime, but you can initialize it using a literal or full-width conversion from Any?. Code that builds a JSON object using literals will have to be modified to either specify a JSONValue case for each value or call the JSONObject(rawValue:) initializer. (#154)

      v1.x
      feature.properties = [
          "name": "Wapakoneta",
          "population": 9_957,
          "favorite": isFavorite,
      ]
      
      let isBigCity = (feature.properties?["population"] as? Double).flatMap { $0 > 10_000 }
      
      v2.0.0
      feature.properties = [
          "name": "Wapakoneta",
          "population": 9_957,
          "favorite": .boolean(isFavorite),
      ]
      
      var isBigCity: Bool?
      if case let .number(population) = feature.properties?["population"] {
          isBigCity = population > 10_000
      }
      
    • ⚠️ The Feature.geometry property is now optional. (#154)

    • ⚠️ Removed the Geometry.type property. Use pattern matching (case let) instead. (#154)

      v1.x
      if geometry.type == .Point { … }
      
      v2.0.0
      if case .point = geometry { … }
      
    • ⚠️ Removed the Geometry.value property. This type erasure is unnecessary and can potentially become a source of bugs. Use pattern matching instead. (#154)

      v1.x
      if let point = geometry.value as? Point { … }
      
      v2.0.0
      if case let .point(point) = geometry { … }
      
    • ⚠️ Removed the Number enumeration in favor of a Double-typed FeatureIdentifier.number(_:) case. JSON doesn’t distinguish between integers and double-precision floating point numbers. Any distinction in the type system or encoded JSON is purely cosmetic. (#154)

      v1.x
      let randomNumber = Int.random(in: 0...255)
      feature.identifier = .number(.int(randomNumber))
      
      if let number = feature.identifier?.value as? Int {
          print("You rolled a \(number)!")
      }
      
      v2.0.0
      let randomNumber = Int.random(in: 0...255)
      feature.identifier = .number(Double(randomNumber))
      
      if let .number(number) = feature.identifier {
          print("You rolled a \(Int(number))!")
      }
      
    • ⚠️ Renamed the BoundingBox(_:_:) initializer to BoundingBox(southWest:northEast:). (#132)

    • Feature and FeatureCollection now conform to the Equatable protocol. (#154)

    • Each geometric type, such as Point, now conforms to the Codable and Equatable protocols. (#154)

    • BoundingBox and FeatureIdentifier now conform to the Hashable protocol. (#154, #159)

    Trigonometry

    • ⚠️ The RadianCoordinate2D.direction(to:) method now returns a Measurement<UnitAngle> instead of a RadianDirection, and the RadianCoordinate2D.coordinate(at:facing:) method now accepts a Measurement<UnitAngle> instance instead of a RadianDirection. The LocationCoordinate2D.coordinate(at:facing:) method can now accept a Measurement<UnitAngle> instance instead of a LocationDirection instance. (#143)
    • Added the Polygon.smooth(iterations:) method for polygon smoothing. (#137)
    • Added the Polygon.simplify(tolerance:highestQuality) method in both non-mutating and mutating forms. (#138)
    • Added the LineString.bezier(resolution:sharpness:) method for calculating a Bézier curve. (#140)
    • Added the Polygon.center, Polygon.centroid, and Polygon.centerOfMass properties. (#148)

    Documentation is available online or within Xcode.

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-rc.2(Sep 29, 2021)

    Changes since v2.0.0-rc.1:

    Packaging

    • ⚠️ Turf requires Xcode 12.0 or above to build from source. (#152)

    Geometry

    • ⚠️ Replaced the GeoJSON class and GeoJSON protocol with a unified GeoJSONObject enumeration. Use JSONDecoder instead of the GeoJSON.parse(_:) or GeoJSON.parse<T: GeoJSONObject>(_:from:) method. (#154)

      v2.0.0-rc.1
      if let feature = try GeoJSON.parse(data)?.decodedFeature,
         case let .lineString(lineString) = feature.geometry { … }
      
      v2.0.0-rc.2
      if case let .feature(feature) = try JSONDecoder().decode(GeoJSONObject.self, from: data),
         case let .lineString(lineString) = feature.geometry { … }
      
    • ⚠️ Removed the FeatureCollection.identifier and FeatureCollection.properties properties with no replacement. These properties had been represented in GeoJSON by foreign members, which are not yet implemented. If you had been relying on the identifier or properties foreign members of FeatureCollection objects, move the data to each individual feature in the collection. (#154)

      v2.0.0-rc.1
      let uuid = UUID().description
      featureCollection.identifier = .string(uuid)
      
      v2.0.0-rc.2
      let uuid = UUID().description
      for feature in featureCollection.features {
          $0.identifier = .string(uuid)
      }
      
    • ⚠️ The Feature.properties property is now a JSONObject? (in other words, [String: JSONValue?]?). JSONObject is type-checked at compile time instead of runtime, but you can initialize it using a literal or full-width conversion from Any?. Code that builds a JSON object using literals will have to be modified to either specify a JSONValue case for each value or call the JSONObject(rawValue:) initializer. (#154)

      v2.0.0-rc.1
      feature.properties = [
          "name": "Wapakoneta",
          "population": 9_957,
          "favorite": isFavorite,
      ]
      
      let isBigCity = (feature.properties?["population"] as? Double).flatMap { $0 > 10_000 }
      
      v2.0.0-rc.2
      feature.properties = [
          "name": "Wapakoneta",
          "population": 9_957,
          "favorite": .boolean(isFavorite),
      ]
      
      var isBigCity: Bool?
      if case let .number(population) = feature.properties?["population"] {
          isBigCity = population > 10_000
      }
      
    • ⚠️ The Feature.geometry property is now optional. (#154)

    • ⚠️ Removed the Geometry.type property. Use pattern matching (case let) instead. (#154)

      v2.0.0-rc.1
      if geometry.type == .Point { … }
      
      v2.0.0-rc.2
      if case .point = geometry { … }
      
    • ⚠️ Removed the Geometry.value property. This type erasure is unnecessary and can potentially become a source of bugs. Use pattern matching instead. (#154)

      v2.0.0-rc.1
      if let point = geometry.value as? Point { … }
      
      v2.0.0-rc.2
      if case let .point(point) = geometry { … }
      
    • ⚠️ Removed the Number enumeration in favor of a Double-typed FeatureIdentifier.number(_:) case. JSON doesn’t distinguish between integers and double-precision floating point numbers. Any distinction in the type system or encoded JSON is purely cosmetic. (#154)

      v2.0.0-rc.1
      let randomNumber = Int.random(in: 0...255)
      feature.identifier = .number(.int(randomNumber))
      
      if let number = feature.identifier?.value as? Int {
          print("You rolled a \(number)!")
      }
      
      v2.0.0-rc.2
      let randomNumber = Int.random(in: 0...255)
      feature.identifier = .number(Double(randomNumber))
      
      if let .number(number) = feature.identifier {
          print("You rolled a \(Int(number))!")
      }
      
    • Feature and FeatureCollection now conform to the Equatable protocol. (#154)

    • Each geometric type, such as Point, now conforms to the Codable and Equatable protocols. (#154)

    • BoundingBox now conforms to the Hashable protocol. (#154)

    Trigonometry

    • Fixed an issue where the LineString.simplify(tolerance:highestQuality:) method returned a highest-quality result even if the highestQuality parameter was set to false. (#152)
    • Fixed an issue where the Polygon.simplify(tolerance:highestQuality:) method incorrectly applied the tolerance. (#152)
    • Fixed an issue where the Polygon.simplify(tolerance:highestQuality:) method failed to simplify the polygon at all if any of the linear rings was a triangle. (#152)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-rc.1(Aug 5, 2021)

  • v2.0.0-beta.1(May 28, 2021)

    Changes since v2.0.0-alpha.3:

    • Added Polygon.smooth(iterations:) for polygon smoothing. (#137)
    • Added Polygon.simplify(tolerance:highestQuality) method in both non-mutating and mutating options. (#138)
    • Changed direction type in RadianCoordinate2D.direction(to:) and RadianCoordinate2D.coordinate(at:facing:) to Measurement<UnitAngle>. (#143)
    • Added LocationCoordinate2D.coordinate(at:facing:) with Measurement<UnitAngle> as direction type. (#143)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-alpha.3(Feb 22, 2021)

    Changes since v2.0.0-alpha.2:

    Packaging

    • Restored support for tvOS, watchOS, and Linux.
    • This library once is once again distributed as source code.
    • When installing this library using Carthage, Carthage builds it with library evolution enabled. (#134)

    Other changes

    • Replaced the Linux-specific definitions of CLLocationCoordinate2D, CLLocationDirection, CLLocationDistance, and CLLocationDegrees with LocationCoordinate2D, LocationDirection, LocationDistance, and LocationDegrees, respectively. On Apple platforms, the new types remain type aliases, so you can continue to use the familiar CL-prefixed Core Location types unless you are writing cross-platform code that supports Linux. (#132)
    • Renamed BoundingBox(_:_:) to BoundingBox(southWest:northEast:). (#132)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-alpha.2(Feb 9, 2021)

  • v1.2.0(Jan 22, 2021)

    Changes since v1.1.0:

    • Application extensions can now link to Turf. (#126)
    • Added the Polygon(center:radius:vertices:) initializer for creating a regular polygon that approximates a circle. (#123)
    • Added the LineString.simplified(tolerance:highestQuality:) and LineString.simplify(tolerance:highestQuality:) methods that apply Ramer–Douglas–Peucker simplification. (#124)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-alpha.1(Jan 19, 2021)

  • v1.2.0-rc.1(Jan 14, 2021)

  • v1.2.0-beta.1(Dec 12, 2020)

    Changes since v1.1.0:

    • Added the Polygon(center:radius:vertices:) initializer for creating a regular polygon that approximates a circle. (#123)
    • Added the LineString.simplified(tolerance:highestQuality:) and LineString.simplify(tolerance:highestQuality:) methods that apply Ramer–Douglas–Peucker simplification. (#124)
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Nov 6, 2020)

    Changes since v1.0.0:

    • Added CLLocationCoordinate2D.latitude and CLLocationCoordinate2D.longitude properties and a CLLocationCoordinate2D(latitude:longitude:) initializer on Linux for consistency with Core Location on Apple platforms. (#120)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Sep 24, 2020)

    Changes since v0.5.0:

    • Turf now requires iOS 10.0 or above, macOS 10.12.0 or above, tvOS 10.0 or above, or watchOS 3.0 or above to run. (#112)
    • Renamed Turf.intersection(_:_:) to intersection(_:_:), working around a compiler error. (#115)
    • Renamed GeoJSON.decodedFeatueCollection to GeoJSON.decodedFeatureCollection. (#111)
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Jun 11, 2020)

    Changes since v0.4.0:

    GeoJSON Representations

    • Exposed all geometries structs coordinates editable (#105)
    • Added convenience initializers for Polygon and MultiPolygon geometries, as well as MultiPolygon.contains(_:ignoreBoundary:) method (#106)

    Bugfixes

    • Fixed BoundingBox to store properties in accordance to GeoJSON RFC7946 (#104)
    • Fixed LineString.closesCoordinate(to:) returned IndexedCoordinate to have correct distance value (#107)
    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jun 5, 2020)

    Changes since v0.3.0:

    Packaging

    • Migrated to Swift 5. (#83)

    GeoJSON representation

    • Replaced the Geometry struct with an enumeration by the same name that has an associated value for each geometry type. (#93)
    • Removed the FeatureVariant enumeration and the series of geometry-specific feature structs such as PointFeature and LineStringFeature in favor of a single Feature struct. For example, instead of creating a PointFeature instance, create a Feature instance and set its Feature.geometry property to a Point instance. (#93)
    • Added the GeometryCollection struct to represent GeoJSON geometry collections. (#93)
    • Removed the JSONType protocol and AnyJSONType struct in favor of making [String: Any?] conform to the Codable protocol. (#95)
    • This library no longer provides Codable conformance for CLLocationCoordinate2D structs, since the appropriate precision may vary from one use case to another. (#96)
    • Removed Polyline as a type alias for LineString. (#93)
    • Added initializers for converting a MultiPolygon to a GeometryCollection, a Ring to a LineString, and a Polygon to a MultiLineString. (#99)

    Spatial operations

    • Added the LineString.bezier(resolution:sharpness:) method for calculating a Bézier spline. (#73)
    • Added the mid(_:_:) function for calculating the point midway between two coordinates, taking the curvature of the Earth into account. (#75)
    • Fixed an issue where LineString.sliced(from:to:) duplicated the last coordinate if to is omitted or equal to the end of the line string. (#79)
    • Fixed an issue where Polygon.contains(_:ignoreBoundary:) returned false for coordinates on a boundary coinciding with the bounding box. (#90)
    • Fixed an issue where the Polygon.contains(_:ignoreBoundary:) misinterpreted the ignoreBoundary argument to result in the opposite behavior. (#90)
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Dec 20, 2018)

    Changes since v0.2.1:

    • Fixed an issue where the index returned by LineString.closestCoordinate(to:) was rounded up instead of down. This in turn fixes unstable return values of LineString.sliced(from:to:) and LineString.distance(from:to:). (#74)
    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Sep 26, 2018)

    • Exposed GeoJSON geometries and feature initializers. #57 #69
    • Ported the turf-boolean-point-in-polygon function and added a BoundingBox. #64 #66
    • Added support for codable null values #63
    • GeoJSONObject.properties is now optionally coded #63
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Jun 21, 2018)

  • v0.1.1(Apr 5, 2018)

  • v0.1.0(Jan 23, 2018)

    Packaging

    • Added support for installing this library using Swift Package Manager. (#30)
    • Added support for deploying on iOS 8.x after installing the library using Carthage. (#32)
    • Added support for deploying on macOS 10.10.x after installing the library using CocoaPods. (#32)
    • Added support for watchOS and tvOS. (#32)
    • Added support for Linux. (#30)

    Other changes

    • Renamed CLLocationDirection.differenceBetween(_:) to CLLocationDirection.difference(from:). (#39)
    • Added a Polygon struct that can calculate its own area. (#21)
    Source code(tar.gz)
    Source code(zip)
  • v0.0.4(Oct 30, 2017)

  • v0.0.3(Sep 29, 2017)

  • v0.0.2(Sep 25, 2017)

Owner
Mapbox
Mapbox is the location data platform for mobile and web applications. We're changing the way people move around cities and explore our world.
Mapbox
Allows you to use custom maps in iphone applications and attempts to mimics some of the behaviour of the MapKit framework

NAMapKit Lets you drop pins or custom annotations onto a standard UIImage or a tiled NATiledImageView. Includes callouts, multi-colored pins, animatio

Neil Ang 263 Jun 29, 2022
JDSwiftMap is an IOS Native MapKit Library. You can easily make a highly customized HeatMap.

JDSwiftMap is an IOS Native MapKit Library. You can easily make a highly customized HeatMap. Installation Cocoapods pod 'JDSWiftHeatMap' Usage JDSwi

郭介騵 135 Dec 26, 2022
Google Directions API helper for iOS, written in Swift

PXGoogleDirections Google Directions API SDK for iOS, entirely written in Swift. ?? Features Supports all features from the Google Directions API as o

Romain L 268 Aug 18, 2022
Use Swift in the macOS command line to build maps.

Use Swift in the macOS command line to build maps. imagefrom A Swift command line utility that gets an image from a URL. Saves the web image as JPEG o

Rob Labs 0 Dec 30, 2021
Location, motion, and activity recording framework for iOS

LocoKit A Machine Learning based location recording and activity detection framework for iOS. Location and Motion Recording Combined, simplified Core

Matt Greenfield 1.5k Jan 2, 2023
An iOS map clustering framework targeting MapKit, Google Maps and Mapbox.

ClusterKit is an elegant and efficiant clustering controller for maps. Its flexible architecture make it very customizable, you can use your own algor

null 502 Dec 25, 2022
A Swift wrapper for forward and reverse geocoding of OpenStreetMap data

Nominatim NominatimKit is a Swift wrapper for forward and reverse geocoding of OpenStreetMap data. Why? Geocoding location data on iOS requires the us

Josef Moser 53 Feb 5, 2022
MSFlightMapView allows you to easily add and animate geodesic flights to Google map

MSFlightMapView Demo Requirements iOS 10.0+ Xcode 9.0+ Installation Just add the MSFlightMapView folder to your project. or use CocoaPods: pod 'MSFlig

Muhammad Abdul Subhan 48 Aug 13, 2022
Demo in SwiftUI of Apple Map, Google Map, and Mapbox map

SNMapServices SNMapServices is a serices for iOS written in SwiftUI. It provides Map capability by subclassing Mapbox, Google map and Apple map. This

Softnoesis 3 Dec 16, 2022
The Swift Geometry Engine.

Easily handle a geometric object model (points, linestrings, polygons etc.) and related topological operations (intersections, overlapping etc.). A ty

GEOSwift 1.4k Dec 25, 2022
Aplicativo criado para estudos de desenvolvimento de Mapa e GPS usando Swift

Onde_estou_iOS Aplicativo criado para estudos de desenvolvimento de Mapa e GPS usando Swift, onde ele pede autorização para usar GPS e localização do

Jeff Araujo 0 Nov 14, 2021
A Swift package for parsing Clang module map files

Clangler is a Swift package used to parse Clang module map files into an abstract syntax tree (AST) representation. Once parsed, you can inspect or manipulate the nodes in the file, then generate and save a new file reflecting your changes.

Dalton Claybrook 9 Apr 7, 2022
GitHub Action for Swift with warning/error annotations.

GitHub Action for Swift This action executes Swift and generates github action annotations from swift warnings/errors. Usage An example to executing S

Jaehong Kang 2 Aug 18, 2022
TraceLog is a highly configurable, flexible, portable, and simple to use debug logging system for Swift and Objective-C applications running on Linux, macOS, iOS, watchOS, and tvOS.

Please star this github repository to stay up to date. TraceLog Introduction TraceLog is a highly configurable, flexible, portable, and simple to use

Tony Stone 52 Oct 28, 2022
A cross-platform library of Swift utils to ease your iOS | macOS | watchOS | tvOS and Linux development.

Mechanica A library of Swift utils to ease your iOS, macOS, watchOS, tvOS and Linux development. Requirements Documentation Installation License Contr

Alessandro 28 Aug 28, 2022
Easy to use and lightweight logger for iOS, macOS, tvOS, watchOS and Linux in Swift.

Lighty Easy to use and lightweight logger for iOS, macOS, tvOS, watchOS and Linux in Swift. Screenshots Requirements Lighty Version Minimum iOS Target

Abdullah Selek 51 Dec 21, 2022
EventBroadcaster is a lightweight event handler framework, written in swift for iOS, macOS, tvOS & watchOS applications.

EventBroadcaster is a lightweight event handler framework, written in swift for iOS, macOS, tvOS & watchOS applications.

Ali Samaiee 4 Oct 5, 2022
AudioKit is an audio synthesis, processing, and analysis platform for iOS, macOS, and tvOS.

AudioKit is an audio synthesis, processing, and analysis platform for iOS, macOS (including Catalyst), and tvOS. Installation To add AudioKit

AudioKit 9.5k Dec 31, 2022
Swift audio synthesis, processing, & analysis platform for iOS, macOS and tvOS

AudioKit AudioKit is an audio synthesis, processing, and analysis platform for iOS, macOS (including Catalyst), and tvOS. Installation To add AudioKit

AudioKit 9.5k Jan 5, 2023
Swift audio synthesis, processing, & analysis platform for iOS, macOS and tvOS

AudioKit AudioKit is an audio synthesis, processing, and analysis platform for iOS, macOS (including Catalyst), and tvOS. Installation To add AudioKit

AudioKit 8.7k Sep 30, 2021