Comments (6)
The prepared geometry capability of GEOS would likely be a good fit for your use case. GEOSwift doesn't expose those APIs yet, but I'll consider this issue a feature request to add them!
from geoswift.
Could you give #264 a try and let me know how it works?
The usage will be something likeβ¦
- Map the geometry of each of your features to a
PreparedGeometry
by calling the newmakePrepared()
method, and store those values somewhere alongside the original features/properties. - At each location update use one of the new contains methods on
PreparedGeometry
to test for containment.
This is the first time I've tried prepared geometry, and it's a little different than the rest of GEOSwift in that the underly GEOS context escapes the scope of a single method call. I need to do a bit more testing & investigation to make sure that's not going to cause any problems, but in the mean time, please give it a try and let me know if you have any feedback.
from geoswift.
I also wonder whether the STRtree APIs in GEOS might be an even better fit. I will explore that as well (though I'm out of time for today).
from geoswift.
Thanks so much! I've implemented your pull request and at this stage (Fingers crossed) with test locations, it seems to work extremely fast and with accuracy however I am yet to test in a live location update sense (During a journey).
Implementation:
`
import Foundation
import MapKit
import GEOSwift
import CoreLocation
import Combine
class SpeedLimitStore: ObservableObject {
@Published var geoJSON: GeoJSON? = nil
var preparedGeometries: [PreparedGeometry] = []
var featureProperties: [[String: Any]] = []
init() {
loadSpeedLimits { features in
self.geoJSON = GeoJSON.featureCollection(FeatureCollection(features: features))
self.prepareGeometriesAndStoreProperties(features: features)
}
}
struct SpeedLimit {
let geometry: Geometry
let speedLimit: Int
}
func loadSpeedLimits(completion: @escaping ([Feature]) -> Void) {
guard let geoJSONURL = Bundle.main.url(forResource: "speed_limits", withExtension: "geojson") else {
print("GeoJSON file not found")
return
}
do {
let data = try Data(contentsOf: geoJSONURL)
let geoJSON = try JSONDecoder().decode(GeoJSON.self, from: data)
if case let .featureCollection(featureCollection) = geoJSON {
print("Loaded \(featureCollection.features.count) speed limit features")
completion(featureCollection.features)
} else {
print("Error: GeoJSON data is not a FeatureCollection")
}
} catch {
print("Error parsing GeoJSON data: \(error.localizedDescription)")
}
}
func prepareGeometriesAndStoreProperties(features: [Feature]) {
for feature in features {
guard let geometry = feature.geometry,
let properties = feature.properties else {
continue
}
do {
let preparedGeometry = try geometry.makePrepared()
preparedGeometries.append(preparedGeometry)
featureProperties.append(properties)
} catch {
print("Error preparing geometry: \(error)")
}
}
}
}
`
And
`
func findSpeedLimit(location: CLLocationCoordinate2D, preparedGeometries: [PreparedGeometry], featureProperties: [[String: Any]]) -> Int? {
// Create a Point object from the location coordinates
let point = Point(x: location.longitude, y: location.latitude)
// Loop through the prepared geometries
for (index, preparedGeometry) in preparedGeometries.enumerated() {
do {
// Check if the prepared geometry contains the point
if try preparedGeometry.contains(point) {
// Check if the properties have a speedLimitZoneValue key
let properties = featureProperties[index]
if let speedLimit = properties["speedLimitZoneValue"] {
let speedLimitString = String(describing: speedLimit)
if let number = Int(speedLimitString.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()) {
return number
}
} else {
print("Feature \(index) has no 'speedLimitZoneValue' property")
}
}
} catch {
print("Error checking if prepared geometry contains point: \(error)")
}
}
return nil
}
`
As I said before at this stage it looks miles quicker for simple test locations however I will need to test it in a live updating context.
from geoswift.
I will mention though that the bootup time of the program still is incredibly slow (and was even before the changes). Is this usual with the GeoSwift library. See my current loadspeedlimits function. I do call it in the App.swift file could that be the issue?
`
@main
struct SafeDrivingMapsApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var speedLimitStore = SpeedLimitStore()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(speedLimitStore)
}
}
}
`
from geoswift.
Fixed the bootup time by loading the data asynchronously in the background. At this stage prepared geometry seems to be working perfectly.
from geoswift.
Related Issues (20)
- [SPM] dyld[10829]: Library not loaded: @rpath/geos.framework/geos HOT 1
- Xcode Cloud: Unable to verify project that links GEOSwift using SPM HOT 2
- Inaccurate heatmap output. Maybe My Code is Wrong? HOT 3
- Question: Storing large GeoJSON Files for usage with GEOSwift HOT 2
- Update for Swift Concurrency
- Confused about `distance(to:)` usage or units HOT 2
- No access to LineStringSnapper HOT 6
- Expose Hausdorff Distance functions
- Support Z coordinates HOT 1
- CI is broken HOT 1
- Request: concave hull support HOT 12
- Support for fixing invalid geometries with GeometryFixer/GEOSMakeValidWithParams HOT 3
- Getting at coordinates after a Polygon is buffered HOT 3
- Get struct out of GEOSwift.JSON HOT 4
- PreparedGeometry branch Library Not Loaded HOT 9
- Prepared Geometry Codable or Public Base Access
- Compiling with Xcode 15.0 beta 5 for "My Mac (Mac Catalyst)" fails with "ld: Undefined symbols:..." HOT 3
- Split MultiPoint into multiple Points ? HOT 2
- How to get WKT string from a geometry HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from geoswift.