Umkreissuche für Annotations

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Umkreissuche für Annotations

    Hallo zusammen,

    ich versuche eine Umkreissuche für meine App zu entwickeln und komme hier absolut nicht weiter. Ich brauche dringen Hilfe, da ich gefühlt schon das ganz Netz durchsucht habe.
    Mein gedanklicher Aufbau ist wie folgt:

    - geladen wird ein Array aus Dictionaries aus einer plist (getMapAnnotations())
    - dieses Array wird durch die Funktion (UmkreissucheFilter()) nach dem Sliderwert (kommt aus den Einstellungen) gefiltert (alle Punkte die eine geringere Distanz haben als der Sliderwert, werden in das neue Array übernommen)
    - als letztes wird das neue Array im MapView dargestellt

    Mein Problem ist, dass ich es nicht schaffe den Wert für annotaionsLat und annotationsLong aus dem Array einzusetzen und somit das Array nicht gefiltert bekomme.
    Ich würde mich sehr freuen wenn mir jemand helfen könnte, da ich noch nicht so lange dabei bin und hier wirklich nicht weiter komme.

    Screenshot 2017-02-18 20.45.43.jpeg[Blockierte Grafik: https://www.dropbox.com/s/bih8kqgerszh294/Screenshot%202017-02-18%2020.45.43.jpeg?dl=0]



    Quellcode

    1. //MARK: - Annotations
    2. func getMapAnnotations() -> [UmkreissucheAnnotation] {
    3. var annotations:Array = [UmkreissucheAnnotation]()
    4. //MARK: - load plist file
    5. var stations: NSArray?
    6. if let path = Bundle.main.path(forResource: "Gesamt", ofType: "plist") {
    7. stations = NSArray(contentsOfFile: path)
    8. }
    9. if let items = stations {
    10. for item in items {
    11. let lat = (item as AnyObject).value(forKey: "inlat") as! Double
    12. let long = (item as AnyObject).value(forKey: "inlong")as! Double
    13. let outlatitude = (item as AnyObject).value(forKey: "outlat") as? Double
    14. let outlongitude = (item as AnyObject).value(forKey: "outlong") as? Double
    15. let poiart = (item as AnyObject).value(forKey: "poiart")as! String
    16. let WWpruef = (item as AnyObject).value(forKey: "wwpruef")as! String
    17. let annotation = UmkreissucheAnnotation(wwpruef: WWpruef, identifier: poiart, inlatitude: lat, inlongitude: long, outlatitude: outlatitude!, outlongitude: outlongitude!)
    18. annotation.title = (item as AnyObject).value(forKey: "titel") as? String
    19. annotation.subtitle = (item as AnyObject).value(forKey: "land") as? String
    20. annotation.In = (item as AnyObject).value(forKey: "in") as? String
    21. annotation.Flussname = (item as AnyObject).value(forKey: "flussname") as? String
    22. annotation.Von = (item as AnyObject).value(forKey: "von") as? String
    23. annotation.Bis = (item as AnyObject).value(forKey: "bis") as? String
    24. annotation.Out = (item as AnyObject).value(forKey: "out") as? String
    25. annotation.Land = (item as AnyObject).value(forKey: "land") as? String
    26. annotation.POIart = (item as AnyObject).value(forKey: "poiart") as? String
    27. annotation.KM = (item as AnyObject).value(forKey: "km") as? String
    28. annotation.WWvon = (item as AnyObject).value(forKey: "wwvon") as? String
    29. annotation.WWbis = (item as AnyObject).value(forKey: "wwbis") as? String
    30. annotation.hoehe = (item as AnyObject).value(forKey: "hoehe")as? String
    31. annotation.mindestpegel = (item as AnyObject).value(forKey: "mindestpegel")as? String
    32. annotation.Charakter = (item as AnyObject).value(forKey: "charakter") as? String
    33. annotation.Besonderheiten = (item as AnyObject).value(forKey: "besonderheiten") as? String
    34. annotation.Beschreibungslink = (item as AnyObject).value(forKey: "beschreibungslink") as? String
    35. annotation.Pegellink = (item as AnyObject).value(forKey: "pegellink") as? String
    36. annotation.Fotolink = (item as AnyObject).value(forKey: "fotolink") as? String
    37. annotations.append(annotation)
    38. }
    39. }
    40. return annotations
    41. }
    42. //MARK: - Filter Fuctions
    43. func UmkreissucheFilter() {
    44. //MARK: - Distance from Sliver Value
    45. let SliderValueDefaults = UserDefaults.standard.double(forKey: "SliderValue")
    46. //MARK: - locations from Array
    47. let annotations = getMapAnnotations()
    48. let annotationsLat = 50.8691 // ersetzen durch Array latitude
    49. let annotationsLong = 9.7095 // ersetzen durch Array longitude
    50. let annotationsLoc = CLLocation (latitude: annotationsLat, longitude: annotationsLong)
    51. //MARK: - Users current location
    52. let currentLat = self.locationManager.location?.coordinate.latitude
    53. let currentLong = self.locationManager.location?.coordinate.longitude
    54. let myLocation = CLLocation (latitude: currentLat!, longitude: currentLong!)
    55. //MARK: - distance calculation
    56. let distance = annotationsLoc.distance(from: myLocation)
    57. let distanceKM = distance / 1000
    58. let distancefilter = annotations.filter {_ in distanceKM < SliderValueDefaults}
    59. //MARK: - Alternative Lösung
    60. //if distanceKM > 1 && distanceKM < SliderValueDefaults {
    61. // MapView.addAnnotations(annotations)
    62. //print("Annotation wird angezeigt")
    63. //}
    64. // else {
    65. // print("Annotation wird nicht angezeigt")
    66. //}
    67. MapView.addAnnotations(distancefilter)
    68. }
    Alles anzeigen
  • Hallo,
    vielen Dank schon mal für die schnellen antworten.

    Ich habe jetzt nochmal nach dem Filtern von Arrays gesucht, komme aber nicht auf die Lösung. Ich glaube das ich mittlerweile den Wald vor lauter Bäumen nicht mehr sehe.
    Könnt ihr mir denn sagen ob ich wenigstens auf dem richtigen Weg bin?

    Ich weiß, das ist sehr wahrscheinlich eine der blöderen Fragen und es tut mir echt leid eure Zeit in Anspruch zu nehmen, jedoch komme ich nicht weiter und brauche einfach mal den Austausch.

    @gritsch: ich versuche meine Werte für Latitude und Longitude, die aus der plist kommen, durch die Methode CLLocationdistance auf ihre Entfernung zur aktuellen Position überprüfen zu lassen. Ich bekomme es aber nicht hin, die Werte aus der Funktion getMapAnnotaions() für Latitude und Longitude in der Funktion UmkreissucheFilter einzusetzen. ich habe für die Funktion getMapAnnotaions() folgende Struktur:


    Quellcode

    1. import UIKit
    2. import MapKit
    3. import CoreLocation
    4. class Umkreissuche: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
    5. @IBOutlet weak var MapView: MKMapView!
    6. //MARK: - Annotations
    7. func getMapAnnotations() -> [UmkreissucheAnnotation] {
    8. var annotations:Array = [UmkreissucheAnnotation]()
    9. //MARK: - load plist file
    10. var stations: NSArray?
    11. if let path = Bundle.main.path(forResource: "Gesamt", ofType: "plist") {
    12. stations = NSArray(contentsOfFile: path)
    13. }
    14. if let items = stations {
    15. for item in items {
    16. let lat = (item as AnyObject).value(forKey: "inlat") as! Double
    17. let long = (item as AnyObject).value(forKey: "inlong")as! Double
    18. let outlatitude = (item as AnyObject).value(forKey: "outlat") as? Double
    19. let outlongitude = (item as AnyObject).value(forKey: "outlong") as? Double
    20. let poiart = (item as AnyObject).value(forKey: "poiart")as! String
    21. let WWpruef = (item as AnyObject).value(forKey: "wwpruef")as! String
    22. let annotation = UmkreissucheAnnotation(wwpruef: WWpruef, identifier: poiart, inlatitude: lat, inlongitude: long, outlatitude: outlatitude!, outlongitude: outlongitude!)
    23. annotation.title = (item as AnyObject).value(forKey: "titel") as? String
    24. annotation.subtitle = (item as AnyObject).value(forKey: "land") as? String
    25. annotation.In = (item as AnyObject).value(forKey: "in") as? String
    26. annotation.Flussname = (item as AnyObject).value(forKey: "flussname") as? String
    27. annotation.Von = (item as AnyObject).value(forKey: "von") as? String
    28. annotation.Bis = (item as AnyObject).value(forKey: "bis") as? String
    29. annotation.Out = (item as AnyObject).value(forKey: "out") as? String
    30. annotation.Land = (item as AnyObject).value(forKey: "land") as? String
    31. annotation.POIart = (item as AnyObject).value(forKey: "poiart") as? String
    32. annotation.KM = (item as AnyObject).value(forKey: "km") as? String
    33. annotation.WWvon = (item as AnyObject).value(forKey: "wwvon") as? String
    34. annotation.WWbis = (item as AnyObject).value(forKey: "wwbis") as? String
    35. annotation.hoehe = (item as AnyObject).value(forKey: "hoehe")as? String
    36. annotation.mindestpegel = (item as AnyObject).value(forKey: "mindestpegel")as? String
    37. annotation.Charakter = (item as AnyObject).value(forKey: "charakter") as? String
    38. annotation.Besonderheiten = (item as AnyObject).value(forKey: "besonderheiten") as? String
    39. annotation.Beschreibungslink = (item as AnyObject).value(forKey: "beschreibungslink") as? String
    40. annotation.Pegellink = (item as AnyObject).value(forKey: "pegellink") as? String
    41. annotation.Fotolink = (item as AnyObject).value(forKey: "fotolink") as? String
    42. annotations.append(annotation)
    43. }
    44. }
    45. return annotations
    46. }
    Alles anzeigen

    Quellcode

    1. import MapKit
    2. class UmkreissucheAnnotation: NSObject, MKAnnotation {
    3. var title: String?
    4. var subtitle: String?
    5. var identifier: String
    6. var In: String?
    7. var inlatitude: Double
    8. var inlongitude:Double
    9. var Flussname: String?
    10. var Von: String?
    11. var Bis: String?
    12. var Out: String?
    13. var outlatitude: Double
    14. var outlongitude: Double
    15. var Land: String?
    16. var POIart: String?
    17. var KM:String?
    18. var WWvon: String?
    19. var WWbis: String?
    20. var WWpruef: String?
    21. var hoehe: String?
    22. var mindestpegel: String?
    23. var Charakter: String?
    24. var Besonderheiten: String?
    25. var Beschreibungslink: String?
    26. var Pegellink: String?
    27. var Fotolink: String?
    28. var coordinate: CLLocationCoordinate2D {
    29. return CLLocationCoordinate2D(latitude: inlatitude, longitude: inlongitude)
    30. }
    31. init(wwpruef: String, identifier: String, inlatitude: Double, inlongitude: Double, outlatitude: Double, outlongitude: Double) {
    32. self.inlatitude = inlatitude
    33. self.inlongitude = inlongitude
    34. self.outlatitude = outlatitude
    35. self.outlongitude = outlongitude
    36. self.identifier = identifier
    37. self.WWpruef = wwpruef
    38. }
    39. }
    Alles anzeigen
  • Ich kann Dir nur ein Beispiel in Objective-C geben. Dies würde dann in etwa so aussehen:

    Quellcode

    1. - (NSArray *)storesAtLocation:(CLLocation *)location withMaxDistance:(CLLocationDistance)maxDistance
    2. {
    3. NSMutableArray *storesAtLocation = [NSMutableArray array];
    4. for (Store *store in self.stores)
    5. {
    6. // Distanz zur gewünschten Location berechnen
    7. CLLocationDistance distance = [store.location distanceFromLocation:location];
    8. // Kleiner als max. Distanz?
    9. if (distance <= maxDistance)
    10. // Store hinzufügen
    11. [storesAtLocation addObject:store];
    12. }
    13. // Optional: Hier werden die Stores aufsteigend nach Distanz sortiert
    14. [storesAtLocation sortUsingComparator:^NSComparisonResult(Store *store1, Store *store2) {
    15. CLLocationDistance distance1 = [store1.location distanceFromLocation:location];
    16. CLLocationDistance distance2 = [store2.location distanceFromLocation:location];
    17. return [[NSNumber numberWithDouble:distance1] compare:[NSNumber numberWithDouble:distance2]];
    18. }];
    19. return [NSArray arrayWithArray:storesAtLocation];
    20. }
    Alles anzeigen

    Das Beispiel ist ohne Predicates und sollte sich somit leicht in Swift nachbauen lassen. ;)
  • Ich habe das spaßeshalber aus Jux und Tollerei einmal transkribiert, wie es ungefähr in Swift aussehen könnte.

    Quellcode

    1. func stores(AtLocation location: CLLocation, withMaxDistanceToNearestStore maxDistance: CLLocationDistance) -> [Store] {
    2. var storesAtLocation = [Store]()
    3. for store in self.stores {
    4. // Distanz zur gewünschten Location berechnen
    5. distance = store.location.distanceFromLocation(location)
    6. // Kleiner als max. Distanz?
    7. if distance <= maxDistance {
    8. // Store hinzufügen
    9. storesAtLocation.append(store)
    10. }
    11. }
    12. // Optional: Hier werden die Stores aufsteigend nach Distanz sortiert
    13. storesAtLocation.sort(by:){ $0.location.distanceFromLocation(location) < $1.location.distanceFromLocation(location) }
    14. return storesAtLocation
    15. }
    Alles anzeigen

    Interessiert keinen. Klar. Ich wollte nur mal für mich den Vergleich sehen. Trotzdem. Früher habe ich mich an der Objective-C-Klammerung nie gestört, aber wenn ich mir das jetzt so im Vergleich angucke, dann sehe ich da inzwischen doch ein gehöriges, unnötiges, störendes Zeichen-Grundrauschen. [:]; Das habe ich früher nie so wahrgenommen. Fand das immer albern, wenn Objective-C-Frischlinge sich an so etwas gestört haben...

    Sei's drum. Der Ausdruck, um das Array zu sortieren, läßt mich jedoch echt etwas grübeln. Geht das in Objective-C/Foundation nicht eleganter? Ist echt sehr lange her, daß ich da selber....
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • *lach* Ja natürlich. :)
    Ich muß gestehen, ich habe etwas gebraucht, um zu verstehen, was Du meinst.
    Aber ja, je nach Kontext, ginge das natürlich auch in einem 'Einzeiler'

    Quellcode

    1. func stores(AtLocation location: CLLocation, withMaxDistanceToNearestStore maxDistance: CLLocationDistance) -> [Store] {
    2. return stores.filter{ $0.location.distanceFromLocation(location) <= maxDistance}.sort(by:){ $0.location.distanceFromLocation(location) < $1.location.distanceFromLocation(location) }
    3. }
    Wie konnte ich das nur übersehen!? :D

    PS: Erica Sadun wäre das ein Blogeintrag wert... ;)
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von torquato ()