Domanda

In PHP, ho il seguente codice per calcolare la distanza tra due posizioni:

<?php
function distance($lat1, $long1, $lat2, $long2) {
    // DEGREE TO RADIAN
    $latitude1 = $lat1/180*pi();
    $longitude1 = $long1/180*pi();
    $latitude2 = $lat2/180*pi();
    $longitude2 = $long2/180*pi();
    // FORMULA: e = ARCCOS ( SIN(Latitude1) * SIN(Latitude2) + COS(Latitude1) * COS(Latitude2) * COS(Longitude2-Longitude1) ) * EARTH_RADIUS
    $distance = acos(sin($latitude1)*sin($latitude2)+cos($latitude1)*cos($latitude2)*cos($longitude2-$longitude1))*6371;
    return $distance;
}
echo distance(9.9921962, 53.5534074, 9.1807688, 48.7771056); // Hamburg, DE - Stuttgart, DE
?>

Ma ora, voglio selezionare la zona intorno a un determinato luogo tramite PHP dal mio database MySQL:

  • L'utente inserisce la sua città natale
  • Il mio script ottiene la latitudine / longitudine valori tramite l'API di Google
  • Nel mio database, ho circa 200 posizioni con un campo per il valore di latitudine e di un campo per il valore di longitudine
  • Ho bisogno di un codice per PHP e MySQL per selezionare le 10 posizioni più vicine alla città natale dell'utente

Spero che mi può aiutare. Grazie in anticipo!

È stato utile?

Soluzione

MySQL distanza ortodromica (Haversine formula) fa esattamente quello che ti serve .

Con solo 200 record tuttavia si può anche semplicemente li caricare e controllare con il codice. Il set di dati è davvero troppo piccolo per essere troppo preoccuparsi del database vs codice o eventuali altre ottimizzazioni.

distanza tra codici di avviamento postale in PHP ha un paio di Calcolo implementazioni PHP di questo algoritmo.

Geo prossimità Cerca è più o meno lo stesso identico problema che avete.

Altri suggerimenti

Forse qualcosa di simile

SELECT field1, field2, ...,
    ACOS(SIN(latitude / 180 * PI()) * SIN(:1) + COS(latitude / 180 * PI()) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

o

SELECT field1, field2, ...,
    ACOS(SIN(RADIANS(latitude)) * SIN(:1) + COS(RADIANS(latitude)) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

(direttamente tradotto dal codice PHP)

:1 e :2 è $lat2/180*pi() e $long2/180*pi() rispettivamente.

Questa è la formula Haversine. È possibile tradurre il PHP direttamente in SQL in modo da poter interrogare il database spazialmente (l'alternativa è quello di tirare fuori ogni record del DB ed eseguire i dati attraverso PHP). MySQL fornisce tutte le funzioni matematiche di cui avete bisogno.

Ho fatto questo per un sito web commerciale che ha fornito pubblicare / CAP basato le ricerche a distanza, quindi la sua certamente possibile senza funzioni GIS specifici.

Ci sono funzioni di MySQL disponibili per fare esattamente questo.

http://dev.mysql.com/doc /refman/5.0/en/gis-introduction.html

MySQL ha la capacità di righe di indice geospaziali. Potrebbe non essere necessario fare questo per la matematica da soli (si può solo chiedere MySQL per calcolare la distanza tra due oggetti geo e ordina per quello ..).

See: http://forums.mysql.com/read.php ? 23,159205,159205

appena arrivato una croce questo argomento. Forse qualcuno sarà interessato a questa funzione, testato in MySql 5.7:

    create function GetDistance(lat1 real, lng1 real, lat2 real, lng2 real) returns real no sql
    return ATAN2(SQRT(POW(COS(RADIANS(lat2)) * SIN(RADIANS(lng1 - lng2)), 2) + 
                POW(COS(RADIANS(lat1)) * SIN(RADIANS(lat2)) - SIN(RADIANS(lat1)) *
                COS(RADIANS(lat2)) *  COS(RADIANS(lng1 - lng2)), 2)), 
                (SIN(RADIANS(lat1)) * SIN(RADIANS(lat2)) + COS(RADIANS(lat1)) *
                COS(RADIANS(lat2)) * COS(RADIANS(lng1 - lng2)))) * 6372.795;

Calling:

select GetDistance(your_latitude, your_longitude, table_field_lat,
                   table_field_lng) as dist from [your_table] limit 5;

Perché non si utilizzano le funzionalità geospaziali di MySQL ...? No, sto scherzando.

Se i 200 record sono luoghi reali come le città, ecc quindi in alternativa potresti utilizzare API GeoNames'?

Il seguente webservice fornirà i 10 luoghi più vicini alla GNL lat e fornito:

http://ws.geonames.org/findNearby?lat=47.3&lng = 9

Fonte: http://www.geonames.org/export/web -services.html # findNearbyPlaceName

La lista intera: http://www.geonames.org/export/ws- overview.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top