2012-07-11 2 views
6

Mon but est d'utiliser mysql POINT (lat, long) pour trouver des entités proches dans la base de données. J'essaie de faire quelque chose comme dans le fond de ce tutoriel http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL. Voici ce que j'ai:Distance spatiale Mysql utilisant POINT - Ne fonctionne pas

Tableau:

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; 

insérant des données de test:

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'); 

Déclarant la fonction de distance:

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

Essayer d'utiliser la fonction pour rechercher ex .:

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

ou:

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

Le problème que je reçois est: erreur 1367 (22007): Illegal non géométrique 'aswkb (un @ 0)' valeur trouvée lors de l'analyse syntaxique ou erreur 1416 (22003): Impossible d'obtenir l'objet géométrique à partir des données que vous envoyez au champ GEOMETRY

Je ne parviens pas à résoudre ce problème. L'important est que la fonction 'distance' puisse être utilisée dynamiquement.

J'ai aussi essayé cette solution: Find the distance between two points in MYSQL. (using the Point Datatype)

Ceci est ma version mysql mysql Ver 14,14 Distrib 5.5.23, pour Linux (x86_64) en utilisant readline 5.1

espoir expertise peut me someones aider. À votre santé!

+1

Essayez 'tour (glength (LineStringFromWKB (LineString (GeomFromText (AsText (a)), GeomFromText (astext (b)))))) ' – acraig5075

+0

@ acraig5075 - Merci pour la suggestion, j'ai fini avec presque le même résultat. – OMA

Répondre

7

donc j'ai fini avec cette requête comme pour le calcul de la distance, un exemple:

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

Je multipliant par 100 pour obtenir une approximation en kilomètres. Le résultat n'est pas exact, mais "ok". Si quelqu'un connaît un meilleur moyen, n'hésitez pas à commenter.

3

définir une fonction personnalisée

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 

puis appelez

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

résultat est en mètres