2012-07-11 17 views
6

Il mio obiettivo è utilizzare mysql POINT (lat, long) per trovare le entità vicine nel database. Sto cercando di fare qualcosa di simile in fondo a questo tutorial http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL. Ecco quello che ho ottenuto:Distanza spaziale Mysql utilizzando POINT - Non funziona

Tabella:

CREATE TABLE mark (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
name VARCHAR(20) DEFAULT NULL, 
loc POINT NOT NULL, 
SPATIAL KEY loc (loc) 
) ENGINE=MyISAM; 

Inserimento di alcuni test-dati:

INSERT INTO mark (loc,name) VALUES (POINT(59.388433,10.415039), 'Somewhere 1'); 
INSERT INTO mark (loc,name) VALUES (POINT(63.41972,10.39856), 'Somewhere 2'); 

Dichiarare la funzione di distanza:

DELIMITER $$ 
CREATE FUNCTION `distance` 
(a POINT, b POINT) 
RETURNS double DETERMINISTIC 
BEGIN 
RETURN 
round(glength(linestringfromwkb(linestring(asbinary(a), 
asbinary(b))))); 
END $$ 
DELIMITER;  

Cercando di utilizzare la funzione per cercare es .:

SELECT name, distance(mark.loc, GeomFromText(' POINT(31.5 42.2) ')) AS cdist 
FROM mark 
ORDER BY 
cdist limit 10; 

o:

SELECT DISTINCT 
dest.name, 
distance(orig.loc, dest.loc) as sdistance 
FROM 
mark orig, 
mark dest 
having sdistance < 10 
ORDER BY 
sdistance limit 10; 

Il problema che sto ottenendo è: ERROR 1367 (22007): Illegal non geometrica 'aswkb (un @ 0)' valore trovato durante l'analisi, o ERROR 1416 (22003): Impossibile ottenere oggetto geometria dai dati inviati al campo GEOMETRIA

Non riesco a capire come risolvere questo problema. L'importante è che la funzione "distanza" possa essere utilizzata dinamicamente.

Ho anche provato questa soluzione: Find the distance between two points in MYSQL. (using the Point Datatype)

Questa è la mia versione MySQL MySQL Ver 14.14 Distrib 5.5.23, per Linux (x86_64) usando readline 5.1

speranza di qualcuno esperienza mi può aiutare. Saluti!

+1

Prova 'round (glength (LineStringFromWKB (LineString (GeomFromText (astext (a)), GeomFromText (astext (b)))))) ' – acraig5075

+0

@ acraig5075 - Grazie per il suggerimento, ho finito per ottenere quasi lo stesso risultato. – OMA

risposta

7

Così ho finito con questo come query per il calcolo della distanza, un esempio:

SELECT glength(LineStringFromWKB(LineString(GeomFromText(astext(PointFromWKB(POINT(63.424818,10.402457)))),GeomFromText(astext(PointFromWKB(POINT(663.422238,10.398996)))))))*100 
AS distance; 

sto moltiplicandolo per 100 per ottenere un'approssimazione in chilometri. Il risultato non è esatto, ma "ok". Se qualcuno sapesse un modo migliore, sentiti libero di commentare.

3

definiscono una funzione personalizzata

CREATE DEFINER=`test`@`%` FUNCTION `geoDistance`(`lon1` DOUBLE, `lat1` DOUBLE, `lon2` DOUBLE, `lat2` DOUBLE) 
    RETURNS double 
    LANGUAGE SQL 
    DETERMINISTIC 
    NO SQL 
    SQL SECURITY DEFINER 
    COMMENT '' 
    BEGIN 
    DECLARE v DOUBLE; 
    SELECT cos(radians(lat1)) 
     * cos(radians(lat2)) 
     * cos(radians(lon2) - radians(lon1)) 
     + sin(radians(lat1)) 
     * sin(radians(lat2)) INTO v; 
    RETURN IF(v > 1, 0, 6371000 * acos(v)); 
END 

quindi chiamare

SELECT geoDistance(X(point1), Y(point1), X(spoint2), Y(point2)) 

risultato arriva in metri

Problemi correlati