umkreissuche in swift realisieren

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

  • umkreissuche in swift realisieren

    Hi , nachdem ich wohl einen gewaltigen Knoten im Kopf habe frage ich Euch, und hoffe auf Hilfe.

    folgendes Problem:

    ich lese die aktuellen Geokoordinaten des Iphone aus und will wissen ob ich mich in der Nähe eines Gewässers befinde.

    über die genauen Positionsdaten bekomme ich natürlich über das placemark.inlandWater keine Ausgabe da ich ja nicht IM Wasser mein Handy dabei habe.

    bin ich jetzt am Ufer muss ich also eine Umkreissuche durchführen. Ich dachte ich nehme einfach meinen Längen und Breitengrad und verändere diese bis

    das placemark.inlandWater einen Inhalt hat. Das ganze mit einer While - Schleife: while Gewaesser.isEmpty { ... längen und Breitengrad ändern und neu abfragen ob da ein Gewässer ist }

    funktioniert aber leider nicht.

    p.s.: die schleife habe ich jedesmal in die Funktion locationManager(didUpdateLocations) eingebaut. auf mit einer for schleife funktioniert es nicht die veränderten längen und Breitengrade zu übergeben. :(( macht auch keinen sinn (in meinen Augen) warum soll ich feste durchläufe haben wenn er mit while abbricht sobald die Bedingung nicht mehr erfüllt ist.

    natürlich kann ich das händisch erledigen : 10 m nach Norden -> abfragen , 10 m nach Süden -> abfragen , 10 m nach Westen -> abfragen , 10 m nach Osten -> abfragen
    das kann aber nicht die Lösung sein zumal man ja den radius bei negativmeldungen jeweils erhöhen muss




    wo ist der Denkfehler?

    hier mein code:

    import UIKit
    import CoreLocation

    var long = 11.738053// <---- Nordufer Heimstettener See , Ergebnis : Seename ist nil
    var lat = 48.157318
    var gewaesser = ""

    // var lat = 48.156274 // <--- Heimstettener See
    // var long = 11.738846



    class FirstViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var lblSeename: UILabel!
    @IBOutlet weak var lblLongitude: UILabel!
    @IBOutlet weak var lblLatitude: UILabel!
    let manager = CLLocationManager()
    let geocoder = CLGeocoder()

    // MARK: -- ViewController Lebenszirkel

    override func viewDidLoad() {
    super.viewDidLoad()
    self.manager.requestAlwaysAuthorization()
    self.manager.delegate = self
    self.manager.desiredAccuracy = kCLLocationAccuracyBest

    self.manager.startUpdatingLocation()
    }

    // MARK: -- CLLocationManagerDelegate

    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    println("Error! \(error.localizedDescription)")
    }

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
    {
    let locationOne = CLLocation(latitude: lat , longitude: long)
    // let locationOne = manager.location
    // var lat = locationOne.coordinate.latitude
    // var long = locationOne.coordinate.longitude
    CLGeocoder().reverseGeocodeLocation(locationOne, completionHandler:
    {(placemarks, error)->Void in

    if (error != nil)
    {
    println("Error: \(error.localizedDescription)")
    return
    }
    if placemarks.count > 0
    {
    let pm = placemarks[0] as! CLPlacemark
    self.displayLocationInfo(pm)
    self.lblLatitude.text = "\(lat)"
    self.lblLongitude.text = "\(long)"
    }
    else
    {
    println("Datenfehler!")
    }


    })
    }

    func displayLocationInfo(placemark: CLPlacemark)
    {
    if placemark.inlandWater != nil {
    self.manager.stopUpdatingLocation()
    lblSeename.text = placemark.inlandWater
    gewaesser = placemark.inlandWater
    } else {
    lblSeename.text = placemark.locality

    }
    }

    // END of code

    }

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von cochris () aus folgendem Grund: p.s: der code ist natürlich ohne die schleife ,.... diese habe ich jedesmal in die Funktion locationManager (didUpdateLocations) eingebaut.

  • Was meinst Du genau mit 'funktioniert aber nicht'?

    Einen Code mit Deinem Ansatz sehe ich jedenfalls nicht.
    Im Übrigen finde ich den Ansatz an sich merkwürdig.
    1. Jedes ReverseGeocoding ist ein Request ins Netz.
      Wenn Du den Ansatz mit der Koordinatenanpassung zu grob wählst, findest Du schlicht nichts, wenn Du ihn zu fein wählst, feuerst Du 800 Requests ab.
      Mal abgesehen davon, dass Du damit dezent sinnlos den Akku leer lutscht, zeichnen sich viele Gewässer dadurch aus, in ihrer Nähe keinen Empfang zu haben.

    2. Die Umwandlung von Metern in Latitude/Longitude ist alles Andere als trivial, da sich bei der gängigen Mercator Projektion die Distanzen zwischen den Sekunden mit steigender Entfernung zum Äquator erhöhen.
      Mit anderen Worten: Wenn in Deutschland 1" == 10m wären, können im Norden Schwedens bereits 1" == 25m gelten.


    Insgesamt scheint der Ansatz sehr unpräzise und mit sehr viel Rechenaufwand verbunden.

    Sinnvoller wäre es, für die Berechnungen die Geokoordinaten in das UTM Koordinatensystem umzurechnen, die Entfernungen hinzuzufügen und dann wieder in Geokoordinaten umzuwandeln.
    Das kostet aber immer noch Zeit und generiert immer noch Netzwerkverkehr.

    Eine lokale Datenbank mit allen Gewässern wäre eine Möglichkeit, ob der schieren Menge an Daten aber mindestens unrealistisch.

    Insofern: Warum willst Du wissen, ob sich das iPhone in der Nähe eines Gewässers befindet?
    Wenn der Nutzer Angler oder Wassersportler ist, wird er sicherlich nicht mit kompletter Ausrüstung ziellos durch die Gegend eiern und es dem Zufall überlassen, ob er die Ausrüstung einsetzen wird.
    Wenn der Nutzer nur spazieren geht, dürfte ihm die Existenz eines Gewässers im näheren Umfeld egal sein, er wird schon nicht reinfallen.

    Will sagen: Entweder man bewegt sich gezielt auf ein Gewässer zu, oder es ist einem stumpf egal.
    Wozu soll die App also dem Anwender mitteilen können, dass er sich in der Nähe eines Gewässers befindet?
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • hallo, auch Dir danke ich für die Antwort,

    Nein,... das ist der Code ohne Schleifen,.... mit den Geokoordinaten eines Sees bei München (wenn ich am Ufer liege (und er dann Kirchheim als Gemeindegebiet zurück gibt) oder den Koordinaten der Seemitte (--> was zur Ausgabe des Seenamens im inlandWater führt) ... Das habe ich so geschrieben um beide Ausgaben kontrollieren / simulieren zu können.

    Ja, jedes ReverseGeocoding ist ein Request ins Netz. Aber es ist zeitsparender und speicherschonender als eine Datenbank.

    Was findest du an dem Ansatz der Schleife merkwürdig? (...nicht falsch verstehen, ich will ja wissen was ich falsch mache oder ob ich zu "krumm" denke)

    zu deinem Punkt 2) danke dafür, dass wusste ich nicht...

    letztendlich geht es darum: ich will nicht alle 360 grad im Radius von jeweils 5 Metern um mich herum "abtasten" ob sich dort ein gewisser befindet , das ist auch unnötig.

    Zu deiner Frage warum ich wissen will ob mein iPhone sich an einem Gewässer befindet:

    Ich bleibe bei Deinem Beispiel mit dem Fischer. ... ich möchte wissen , welche Gewässer sich im Umkreis von 20 km um mich herum befinden.... und wenn ich bereits an einem gewässer bin... wie dieses heisst ... ich will sagen können: " Den Karpfen habe ich im ..... gefangen "


    die while schleife hatte ich in die Funktion eingebaut:

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
    {

    while seename.isEmty {

    let locationOne = CLLocation(latitude: lat , longitude: long)
    // let locationOne = manager.location
    // var lat = locationOne.coordinate.latitude
    // var long = locationOne.coordinate.longitude

    CLGeocoder().reverseGeocodeLocation(locationOne, completionHandler:
    {(placemarks, error)->Void in

    if (error != nil)
    {
    println("Error: \(error.localizedDescription)")
    return
    }
    if placemarks.count > 0
    {
    let pm = placemarks[0] as! CLPlacemark
    self.displayLocationInfo(pm)
    self.lblLatitude.text = "\(lat)"
    self.lblLongitude.text = "\(long)"
    }
    else
    {
    println("Datenfehler!")
    }

    })

    lat = lat + 0.001
    long = long + 0.001

    }
  • Labertäsch,

    nehmen wir das fiktive Realweltproblem:

    1) auf der ganzen Welt gibt es Handy/Internetempfang und keine Funklöcher (da Google seine Ballone hat steigen lassen)

    2) ich stürze irgendwo mit dem Flieger ab

    3) mein Handy hat , wie ich, den Absturz überlebt und genug Akku

    4) mein Überleben hängt davon ab dass ich genug trinke... vor lauter Urwald sehe ich das Wasser 30 Meter neben mir nicht.... oder ich weiss nicht dass sich in einem Kilometer ein Gewässer befindet

    5) mein Handy aber schon ;) --> und ich will es nicht über Maps sehen, sondern über eine eigene App

    es ist nur so ein Gedanke, und den möchte ich einfach lernen umsetzen zu können, um o.g. "Problem" zu lösen,... unabhängig davon ob es sinnvoll ist oder nicht,... es muss vernünftig lösbar sein... und ich komme leider nicht weiter
  • wie kommst du drauf dass tausende requests akkuschonender sind als das durchsuchen einer lokalen datenbank oder eben nur ein request an den server der dann die arbeit übernimmt in der datenbank zu suchen.

    wenn du jetzt gesagt hättest dass du in 20 meter umkreis gewässer finden willst, dann wären das doch schon sehr viele:
    die fläche wären dann ca 1200 qm, wenn du alle 4 qm eine abfrage sendest, dann wären das 300 abfragen!!! willst du das ganze für 20 km machen, sind es 300.000.000 abfragen. natürlich kannst du das raster auch größer wählen aber dann findest du bäche die schmaler als 2 meter sind eben nicht (und auch aus denen kann man trinken oder fische fangen...)
  • cochris schrieb:

    Ich bleibe bei Deinem Beispiel mit dem Fischer. ... ich möchte wissen , welche Gewässer sich im Umkreis von 20 km um mich herum befinden.... und wenn ich bereits an einem gewässer bin... wie dieses heisst ... ich will sagen können: " Den Karpfen habe ich im ..... gefangen "
    Das steht doch an jedem (offiziellen) angel-gewässer groß dran...

    ich finde, wie einige andere hier, dass deine Anwendungsfälle sehr weit her geholt scheinen und nichts desto trotz mit Bordmitteln in Sekunden für den Anwender selber zu lösen sind.
    Man kann alles schaffen. Man muss es nur wollen ;)
    www.regetskcob.github.io
  • DanielBocksteger95 schrieb:

    cochris schrieb:

    Ich bleibe bei Deinem Beispiel mit dem Fischer. ... ich möchte wissen , welche Gewässer sich im Umkreis von 20 km um mich herum befinden.... und wenn ich bereits an einem gewässer bin... wie dieses heisst ... ich will sagen können: " Den Karpfen habe ich im ..... gefangen "
    Das steht doch an jedem (offiziellen) angel-gewässer groß dran...
    ich finde, wie einige andere hier, dass deine Anwendungsfälle sehr weit her geholt scheinen und nichts desto trotz mit Bordmitteln in Sekunden für den Anwender selber zu lösen sind.
    Beantwortet aber immernoch nicht seine Frage!


    cochris schrieb:

    eigentlich brauchte ich nur Hilfe bezüglich der frage warum meine schleife , wenn ich die Geodäten ändere, keinen erneuten request ausführt.
    Was meinst mit Request?
    Btw: Bitte setze deinen Code mal in Code-Tags (wie @gritsch dir schon gesagt hat).
  • import UIKit
    import CoreLocation


    // -- GLOBALE VARIABLEN --
    // --> hier benenne ich einfach mal geokoordinaten die sich am Ufer eines sees befinden

    var long = 11.738053// <---- Nordufer Heimstettener See , Ergebnis : Seename ist nil
    var lat = 48.157318
    var gewaesser = ""

    // --> diese setzte ich ein wenn ich die geokoordinaten inmitten eines Gewässers setze
    // var lat = 48.156274 // <--- Heimstettener See
    // var long = 11.738846



    class FirstViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var lblSeename: UILabel!
    @IBOutlet weak var lblLongitude: UILabel!
    @IBOutlet weak var lblLatitude: UILabel!
    let manager = CLLocationManager()
    let geocoder = CLGeocoder()

    // MARK: -- ViewController Lebenszirkel

    override func viewDidLoad() {
    super.viewDidLoad()
    self.manager.requestAlwaysAuthorization()
    self.manager.delegate = self
    self.manager.desiredAccuracy = kCLLocationAccuracyBest

    self.manager.startUpdatingLocation()
    }

    // MARK: -- CLLocationManagerDelegate

    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    println("Error! \(error.localizedDescription)")
    }

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
    {
    let locationOne = CLLocation(latitude: lat , longitude: long)

    // --> nachfolgende koordinaten wenn ich echtesten verwende

    // let locationOne = manager.location
    // var lat = locationOne.coordinate.latitude
    // var long = locationOne.coordinate.longitude


    CLGeocoder().reverseGeocodeLocation(locationOne, completionHandler:
    {(placemarks, error)->Void in

    if (error != nil)
    {
    println("Error: \(error.localizedDescription)")
    return
    }

    if placemarks.count > 0
    {
    let pm = placemarks[0] as! CLPlacemark
    self.displayLocationInfo(pm)
    self.lblLatitude.text = "\(lat)"
    self.lblLongitude.text = "\(long)"
    }
    else
    {
    println("Datenfehler!")
    }


    })
    }

    func displayLocationInfo(placemark: CLPlacemark)
    {

    if placemark.inlandWater != nil {

    // wenn ich an den aktuellen geokoordinaten ein gewisser finde :

    self.manager.stopUpdatingLocation() // <---- ENDE Lokalisierung
    lblSeename.text = placemark.inlandWater // <---- Ausgabe des Gewässernamens
    gewaesser = placemark.inlandWater
    } else {
    lblSeename.text = placemark.locality // <--- andernfalls gib den Gemeindenamen aus

    }
    }

    // END of code

    }
  • danke Matz....

    ich hoffe es hilft ein wenig,... ich weiss nicht wie ich es übersichtlicher darstellen soll.

    meine schleife würde eine while schleife sein . In der Funktion :

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)



    --> solange die variable "seename" leer ist:

    ..> erhöhe lat und long um 0.001


    ansonsten:

    --> brich ab und gib aus



    leider hängt er sich dabei jedesmal auf .... es ist kein Tastendruck etc . mehr möglich
  • C-Quellcode

    1. import UIKit
    2. import CoreLocation
    3. // -- GLOBALE VARIABLEN --
    4. // --> hier benenne ich einfach mal geokoordinaten die sich am Ufer eines sees befinden
    5. var long = 11.738053// <---- Nordufer Heimstettener See , Ergebnis : Seename ist nil
    6. var lat = 48.157318
    7. var gewaesser = ""
    8. // --> diese setzte ich ein wenn ich die geokoordinaten inmitten eines Gewässers setze
    9. // var lat = 48.156274 // <--- Heimstettener See
    10. // var long = 11.738846
    11. class FirstViewController: UIViewController, CLLocationManagerDelegate {
    12. @IBOutlet weak var lblSeename: UILabel!
    13. @IBOutlet weak var lblLongitude: UILabel!
    14. @IBOutlet weak var lblLatitude: UILabel!
    15. let manager = CLLocationManager()
    16. let geocoder = CLGeocoder()
    17. // MARK: -- ViewController Lebenszirkel
    18. override func viewDidLoad() {
    19. super.viewDidLoad()
    20. self.manager.requestAlwaysAuthorization()
    21. self.manager.delegate = self
    22. self.manager.desiredAccuracy = kCLLocationAccuracyBest
    23. self.manager.startUpdatingLocation()
    24. }
    25. // MARK: -- CLLocationManagerDelegate
    26. func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    27. println("Error! \(error.localizedDescription)")
    28. }
    29. func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
    30. {
    31. while gewaesser.isEmty {
    32. let locationOne = CLLocation(latitude: lat , longitude: long)
    33. // --> nachfolgende koordinaten wenn ich echtesten verwende
    34. // let locationOne = manager.location
    35. // var lat = locationOne.coordinate.latitude
    36. // var long = locationOne.coordinate.longitude
    37. CLGeocoder().reverseGeocodeLocation(locationOne, completionHandler:
    38. {(placemarks, error)->Void in
    39. if (error != nil)
    40. {
    41. println("Error: \(error.localizedDescription)")
    42. return
    43. }
    44. if placemarks.count > 0
    45. {
    46. let pm = placemarks[0] as! CLPlacemark
    47. self.displayLocationInfo(pm)
    48. self.lblLatitude.text = "\(lat)"
    49. self.lblLongitude.text = "\(long)"
    50. }
    51. else
    52. {
    53. println("Datenfehler!")
    54. }
    55. })
    56. lat = lat + 0.001
    57. long = long + 0.001
    58. }
    59. }
    60. func displayLocationInfo(placemark: CLPlacemark) -> String!
    61. {
    62. if placemark.inlandWater != nil {
    63. // wenn ich an den aktuellen geokoordinaten ein gewisser finde :
    64. self.manager.stopUpdatingLocation() // <---- ENDE Lokalisierung
    65. lblSeename.text = placemark.inlandWater // <---- Ausgabe des Gewässernamens
    66. gewaesser = placemark.inlandWater
    67. return gewaesser
    68. } else {
    69. lblSeename.text = placemark.locality // <--- andernfalls gib den Gemeindenamen aus
    70. gewaesser =""
    71. return gewaesser
    72. }
    73. }
    74. // END of code
    75. }
    Alles anzeigen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von cochris ()