2010-06-16 2 views
5

Ich versuche, Unterstützung für Standorte in meiner Anwendung zu bauen und ich erwarte Benutzer gps Koordinaten in einer Vielzahl von Möglichkeiten eingeben. Ich muss alle folgenden in: Breite - Richtung (N/s), Grad, Minuten, Sekunden; Länge (E/W) - Grad, Minuten, Sekunden.konvertieren GPS Breite/Länge von verschiedenen Formaten zu einem Format (in PHP)

Beachten Sie, dass sich jede Benutzereingabe in einer einzelnen Zeile befindet. Ich würde meine Benutzer zur Eingabe mag nur in einer einzigen Art und Weise, aber ppl wird auf jeden Fall als einer der folgenden ... eingeben:

zB: 9.182, -39,140625
9,182/-39,140625
9,182, -39,140625
9,182 -39,140625
21 ° 16' 674S [some_separator] 27 ° 30' 318E
21 16 674S [some_separator] 27 30 318E

[some_separator] kann ein einzelner Raum als gut ...

Das endgültige Format muss beas:
latitude.direction = Süden
latitude.degrees = 21
latitude.minutes = 16
latitude.seconds = 674
longitude.direction = Ost
longitude.degrees = 27
longitude.minutes = 30
longitude.seconds = 318

(a), was ist der einfachste Weg gewöhnlichen nicht-Tech-Benutzer zur Eingabe des Fragens der GPS Koordina te? s
(b) Wie konvertiere ich das oben genannte zum endgültigen Format? irgendwelche eingebauten Funktionen, die diese Variationen in der Dateneingabe handhaben?

Ich habe GPS format in PHP gesehen - aber ich muss einen vielfältigeren Eingang handhaben.

Antwort

11

Ich habe damit weiter gearbeitet (und ich merke, dass Sie Ihre Frage bearbeitet haben).

A) Was ist die einfachste Art, Benutzer von normalen Nicht-Technikern zu bitten, die GPS-Koordinaten einzugeben?

Die einfachste und benutzerfreundlichste Methode, um Nichttechniker zur Eingabe von Details zu bewegen, wäre die Verwendung von Google Maps. Auf diese Weise können Sie den Google Geocoder verwenden, um ihre Eingaben zu analysieren (und eine standardisierte und formatierte Ausgabe bereitzustellen). Wenn der Ort, den der Benutzer eingibt, sein aktueller Standort ist, könnten Sie sich außerdem die Geolocation-Funktionalität einiger moderner Browser ansehen.

B) Wie konvertiere ich das oben genannte in das endgültige Format? Irgendwelche eingebauten Funktionen, die diese Variationen in der Dateneingabe handhaben?

Basierend auf Ihren Testdaten habe ich einen regulären PHP-Ausdruck formuliert, um ihn zu parsen und eine vorhersehbare und standardisierte Ausgabe zu liefern.

$rexp = '/^(\-?\d+(?:\.\d+)?)(?:\D+(\d+)\D+(\d+)([NS]?))?[^\d\-]+(\-?\d+(?:\.\d+)?)(?:\D+(\d+)\D+(\d+)([EW]?))?$/i'; 

$data = array(
    "21° 16' 674S, 27° 30' 318E" , 
    '21 16 674S, 27 30 318E' , 
    '9.182, -39.140625' , 
    '9.182/-39.140625' , 
    '9.182,-39.140625' , 
    '9.182 -39.140625' 
); 

foreach($data as $test) { 
    if(!preg_match($rexp , $test , $matches)) { 
    echo '<b>Failed</b>'; 
    } else { 
    // Match Found 
    } 
} 

Ausgänge:

array(
    [0] => Matched Text , 
    [1] => Full Degrees , 
    [2] => Minutes , 
    [3] => Seconds , 
    [4] => Hemisphere (N or S) , 
    [5] => Full Degrees , 
    [6] => Minutes , 
    [7] => Seconds , 
    [8] => Hemisphere (E or W) 
) 

Beispiel:

// Matching 21° 16' 674S, 27° 30' 318E 
array(
    [0] => "21° 16' 674S, 27° 30' 318E" , 
    [1] => "21" , [2] => "16" , [3] => "674" , [4] => "S" , 
    [5] => "27" , [6] => "30" , [7] => "318" , [8] => "E" 
) 

// Matching 21 16 674S, 27 30 318E 
array(
    [0]=> "21 16 674S, 27 30 318E" , 
    [1]=> "21" , [2]=> "16" , [3]=> "674" , [4]=> "S" , 
    [5]=> "27" , [6]=> "30" , [7]=> "318" , [8]=> "E" 
) 

// Matching 9.182, -39.140625 
array(
    [0]=> "9.182, -39.140625" , 
    [1]=> "9.182" , [2]=> "" , [3]=> "" , [4]=> "" , 
    [5]=> "-39.140625" , [6]=> "" , [7]=> "" , [8]=> "" 
) 

// Matching 9.182/-39.140625 
array(
    [0]=> "9.182/-39.140625" , 
    [1]=> "9.182" , [2]=> "" , [3]=> "" , [4]=> "" , 
    [5]=> "-39.140625" , [6]=> "" , [7]=> "" , [8]=> "" 
) 

// Matching 9.182,-39.140625 
array(
    [0]=> "9.182,-39.140625" , 
    [1]=> "9.182" , [2]=> "" , [3]=> "" , [4]=> "" , 
    [5]=> "-39.140625" , [6]=> "" , [7]=> "" , [8]=> "" 
) 

// Matching 9.182 -39.140625 
array(
    [0]=> "9.182 -39.140625" , 
    [1]=> "9.182" , [2]=> "" , [3]=> "" , [4]=> "" , 
    [5]=> "-39.140625" , [6]=> "" , [7]=> "" , [8]=> "" 
) 

Sie dann könnte anschließend Prozess die Ergebnisse der Regular Expression, einen Schwimmer für die Breite/Länge Link zu erzeugen, so :

// (Replacing the "Match Found" comment) 
    $latitude = $matches[1]+((int)$matches[2]/60)+((int)$matches[3]/3600)*(strtolower($matches[4])=='s'?-1:1); 
    $longitude = $matches[5]+((int)$matches[6]/60)+((int)$matches[7]/3600)*(strtolower($matches[8])=='w'?-1:1); 

Who produziert:

// Matching 21° 16' 674S, 27° 30' 318E 
$latitude = -21.4538888889 
$longitude = 27.5883333333 

// Matching 21 16 674S, 27 30 318E 
$latitude = -21.4538888889 
$longitude = 27.5883333333 

// Matching 9.182, -39.140625 
$latitude = 9.182 
$longitude = -39.140625 

// Matching 9.182/-39.140625 
$latitude = 9.182 
$longitude = -39.140625 

// Matching 9.182,-39.140625 
$latitude = 9.182 
$longitude = -39.140625 

// Matching 9.182 -39.140625 
$latitude = 9.182 
$longitude = -39.140625 
+0

Hut ab nach Lucanos für einen wunderbaren Versuch ...! Ich muss es noch testen, aber ein kurzer Blick zeigt, dass es genau/sehr nah an dem ist, was ich brauche !!! – Dave

+0

Sie verwenden -1 Multiplikation nur für die letzte Komponente beim Übersetzen in float. Ihr Code gibt andere Ergebnisse als die, die Sie in der Antwort aufgelistet haben. Um ihn zu beheben, müssen Sie die Übersetzung in '$ latitude = ändern ($ matches [1] + ((int) $ matches [2]/60) + ((int) $ matches [3]/3600)) * (strtolower ($ matches [4]) == 's'? - 1: 1); $ longitude = ($ Übereinstimmungen [5] + ((int) $ Übereinstimmungen [6]/60) + ((int) $ Übereinstimmungen [7]/3600)) * (strtolower ($ matches [8]) == ' w '? - 1: 1); ' – Kyborek

0
  1. Split Breite und Länge, mit explode() oder preg_split().
  2. Bestimmen Sie für Breiten- und Längengrad, ob es als Float oder mit Minuten angegeben wird.
  3. Wandeln Sie den Wert in Grad (als float)
1

Ich denke, der beste Weg wäre, eine Benutzereingabe so weit wie möglich zu beschränken, so dass sie nur gültige Daten eingeben können. Lassen Sie den Benutzer die Daten in Token für Sie trennen, anstatt zu versuchen, jede einzelne Möglichkeit zu berücksichtigen. Verwenden Sie so viele Textfelder/Dropdowns/etc, wie erforderlich, um den Benutzer zum korrekten Auffüllen der Daten zu zwingen. Ich denke, es wäre wünschenswert, die Menge an Textvarianten zu minimieren, die Sie tun werden.

In welchem ​​Format erhalten die Benutzer ihre Daten? Wenn es nur ein dezimales lat/lang ist, z. B. (50.32.123.55) dann haben Sie einfach zwei numerische Eingaben, die sie ausfüllen können, und enthalten möglicherweise einen Beispielwert in der Box. Wenn die Benutzer ihre Daten in Grad/Minute/Sekunde Format erhalten, dann haben Sie genau diese Felder, die sie für jeden Längen- und Breitengrad ausfüllen müssen. Wenn Sie beide Dezimalstellen & Grad zulassen, sollte es alle Ihre Benutzer abdecken.

Haben Sie so viele Eingaben wie nötig, um die Daten in genügend Token zu zerlegen, die Konsistenz bei der Interpretation in Ihrem Programm gewährleisten!

EDIT: Eine flippige Idee, wenn Sie es für Ihre Website akzeptabel finden, wäre eine Google Map, wo der Benutzer eine Markierung an den gewünschten Ort zieht. Sie können dann die GPS-Koordinaten in konsistenter Weise von diesem Marker erhalten und für die weitere Arbeit, die Sie tun müssen, verwenden!

0

Ihre beste (aber zugegebenermaßen am wenigsten garantierte) Methode besteht darin, das Benutzerverhalten so zu steuern, dass die Daten in einem standardisierten und leicht zu analysierenden Format formatiert werden. Auch wenn Sie nur ein oder zwei einfache Hauptformate haben, um zu versuchen, sie zu einer Konvertierung zu ermutigen, wäre dies ein ausgezeichneter Schritt und würde die Menge an erforderlicher Fehlerkorrektur/Formatierung reduzieren.

Darüber hinaus würde ich vorschlagen, dass die Erstellung von Regulären Ausdrücken und Funktionen hinter diesen RegExps zur Standardisierung der Daten, die Sie verwenden werden, eine Lösung wäre.

Ich habe ein paar RegExps gegen die von Ihnen bereitgestellten Testdaten ausgeführt, habe aber Probleme beim Erstellen einer kugelsicheren Lösung in dieser Hinsicht (es kann sein, dass Sie einige verschiedene Muster für jede Kombination benötigen).

Ich habe sogar versucht, einige der Testdaten durch die Google Geocoding API zur Verfügung gestellt (das ist normalerweise ein ziemlich robustes System, so dass Klartext-Adressierung, sowie mehrere Lat/Long-Formate), aber, keine Freude.

Je mehr Standard die eingehenden Daten sind, desto einfacher ist es, genaue Informationen zu erstellen. Wenn Sie eine Karte (Google Maps oder andere) in die Eingabephase integrieren, können Sie die Eingabe möglicherweise genauer validieren.