2011-01-18 35 views
9

Quiero almacenar valores de latitud y longitud de lugares en una tabla de base de datos mysql. Con el futuro en mente, querré poder encontrar estos lugares dentro de un cierto radio de una ubicación específica. Una vez dicho esto, ¿en qué tipo de datos debo guardar los valores de latitud y longitud? Por favor, ¿podría proporcionar con un guión mesa de crear para las columnas de este modo:configuración de la tabla de latitud y longitud de MySQL

place_id | lat | long 

¿Hay quizá una columna que me falta en la tabla anterior que me va a dar información adicional que no pueda ver lo que necesito en el ¿tiempo actual?

Gracias por cualquier ayuda.

+0

posible duplicado de [¿Cuál es el tipo de datos ideal para usar cuando se almacenan latitudes/longitudes en una base de datos MySQL?] (Http://stackoverflow.com/questions/159255/what-is-the-ideal-data-type -to-use-when-storage-latitude-longitudes-in-a-mysql) – Gajus

Respuesta

21

Debe almacenar los puntos en una columna de la chamusquina del tipo de datos Point que se puede índice con un índice de SPATIAL (si su tipo de tabla es MyISAM):

CREATE SPATIAL INDEX sx_place_location ON place (location) 

SELECT * 
FROM mytable 
WHERE MBRContains 
       (
       LineString 
         (
         Point($x - $radius, $y - $radius), 
         Point($x + $radius, $y + $radius) 
         ) 
       location 
       ) 
     AND Distance(Point($x, $y), location) <= $radius 

Esto mejorará drásticamente la velocidad de consultas como " encuentra todo dentro de un radio dado ".

Tenga en cuenta que es mejor utilizar coordenadas métricas simples TM (easting y northing) en lugar de polar (latitud y longitud). Para radios pequeños, son lo suficientemente precisos, y los cálculos se simplifican enormemente. Si todos sus puntos están en un hemishpere y están lejos de los polos, puede usar un solo meridiano central.

Aún puede usar coordenadas polares, por supuesto, pero las fórmulas para calcular MBR y la distancia serán más complejas.

+1

Todas mis tablas usan InnoDB cuando utilizo claves externas. ¿No es un problema tener tablas tanto en InnoDB como en MyISAM? – Martin

+0

@Martin: 'MyISAM' no tiene transacción y no puede usar las restricciones' FOREIGN KEY' en él. Solo para consultas 'SELECT', no hay problemas con la mezcla de tablas de diferentes tipos. – Quassnoi

+0

Sí, entiendo que las claves externas no funcionan en MyISAM; sin embargo, si tengo una tabla adicional para las coordenadas y tengo eso como MyISAM y todas mis otras tablas son InnoDB ¿no es eso un problema? – Martin

0

He cavado algunas horas a través de toneladas de temas y no podría encontrar ninguna consulta, devolviendo puntos en un radio, definido por km. ST_Distance_Sphere lo hace, sin embargo, el servidor es MariaDB 5.5, no es compatible con ST_Distance_Sphere().

arreglamos para conseguir algo de trabajo, por lo que aquí es mi solución, compatible con la doctrina 2,5 y la Doctrina CrEOF Biblioteca espacial:

$sqlPoint = sprintf('POINT(%f %f)', $lng, $lat); 

    $rsm = new ResultSetMappingBuilder($this->manager); 
    $rsm->addRootEntityFromClassMetadata('ApiBundle\\Entity\\Place', 'p'); 

    $query = $this->manager->createNativeQuery(
     'SELECT p.*, AsBinary(p.location) as location FROM place p ' . 
     'WHERE (6371 * acos(cos(radians(Y(ST_GeomFromText(?)))) ' . 
     '* cos(radians(Y(p.location))) * cos(radians(X(p.location)) ' . 
     '- radians(X(ST_GeomFromText(?)))) + sin(radians(Y(ST_GeomFromText(?)))) * sin(radians(Y(p.location))))) <= ?', 
     $rsm 
    ); 

    $query->setParameter(1, $sqlPoint, 'string'); 
    $query->setParameter(2, $sqlPoint, 'string'); 
    $query->setParameter(3, $sqlPoint, 'string'); 
    $query->setParameter(4, $radius, 'float'); 

    $result = $query->getResult(); 

Suponiendo GNL y lat es XY del punto fijo, Place es la entidad con un campo de "ubicación" de tipo POINT. No pude usar DQL directamente debido a problemas con la vinculación de param de MySQL, es por eso que la consulta nativa de bajo nivel. Se requiere la rsm para mapear resultados en objetos de entidad. Sin embargo, puedes vivir sin eso.

Siéntase libre de usarlo. Espero que te ahorre algo de tiempo.

Cuestiones relacionadas