2012-07-11 10 views
6

Mein Ziel ist es, mit mysql POINT (lat, long) in der Nähe befindliche Entitäten in der Datenbank zu finden. Ich versuche etwas wie am Ende dieses Tutorials zu tun http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL. Hier ist, was ich habe:Mysql räumliche Entfernung mit POINT - funktioniert nicht

Tabelle:

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; 

Einfügen einige Test-Daten:

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

der Distanzfunktion Deklarieren:

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

Der Versuch, die Funktion zu verwenden, zu suchen ex .:

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

oder:

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

Das Problem Ich erhalte ist: ERROR 1367 (22007): Illegal nicht geometrisch 'aswkb (a @ 0)' Wert während der Analyse oder ERROR 1416 (22003) gefunden: Geometrieobjekt kann nicht von Daten empfangen werden, die Sie an das GEOMETRY-Feld senden

Ich kann nicht herausfinden, wie ich das lösen kann. Wichtig ist, dass die Funktion "distance" dynamisch verwendet werden kann.

Ich habe auch diese Lösung versucht: Find the distance between two points in MYSQL. (using the Point Datatype)

Dies ist meine MySQL-Version MySQL Ver 14.14 Distrib 5.5.23 für Linux (x86_64) mit Readline- 5.1

Hoffnung someones Expertise mir helfen kann. Prost!

+1

Try 'round (glength (LineStringFromWKB (Linestring (GeomFromText (ASTEXT (a)) nennen, GeomFromText (astext (b)))))) ' – acraig5075

+0

@ acraig5075 - Danke für den Vorschlag, ich endete mit fast dem gleichen Ergebnis. – OMA

Antwort

7

So landete ich mit diesem als Abfrage für die Berechnung der Entfernung, in denen ein Beispiel:

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

ich es um 100 bin Multiplizieren eine Annäherung in Kilometern zu bekommen. Das Ergebnis ist nicht exakt, aber "ok". Wenn jemand einen besseren Weg wüsste, kannst du ihn gerne kommentieren.

3

definieren eine benutzerdefinierte Funktion

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 

dann

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

Ergebnis kommt in Metern