2012-10-02 10 views
8

道路やホテルに関するデータを保存するのにMySQL Spatial Extensionsを使用しています。 LineDataとして道路データを保存している間、ホテルデータをPointとして保存します。テーブルは、インスタンスの可視化は、このようになります。このMySQL Spatial Extensionsを使用してN点から最も近い線ストリング

CREATE TABLE IF NOT EXISTS `Hotels` (
    `id` int unsigned NOT NULL AUTO_INCREMENT, 
    `name` text, 
    `coordinate` point NOT NULL, 
    PRIMARY KEY (`id`), 
    SPATIAL KEY `coordinate` (`coordinate`), 
) 

CREATE TABLE IF NOT EXISTS `Roads` (
    `id` int unsigned NOT NULL AUTO_INCREMENT, 
    `name` text, 
    `route` linestring NOT NULL, 
    PRIMARY KEY (`id`), 
    SPATIAL KEY `coordinate` (`route`), 
) 

のように見えます。

http://i.stack.imgur.com/8IVVA.png

私の問題は、数Nと点P、点PからN最寄りの道路を見つけるためのSQLクエリは何で与えられていますか?距離は、上の図のような点と道路の線分との間の最小垂直距離によって定義されます。 (現実的には、最寄りの距離は高速道路のゲートとホテルの間でなければなりませんが、この場合は任意の地点から高速道路に入ることができます)P

問題、仲介SQL問合せ、および後処理が私にとって受け入れられます。しかし、効率的なSQLクエリとデータの後処理方法は何でしょうか?

あなたは、データベース内の二つの機能を作成することができます
+0

まだ回答がありませんか? :) – bonCodigo

+0

MySQL 5.5を使用していることを確認してください。さもなければ、空間的な機能があなたの質問に答えるのに十分に実装されていません – TheSteve0

答えて

2

  1. 距離:これは二つの点
  2. 間、あなたの距離を与える
  3. DistanceFromLine:ここでの距離は、ラインの各点から計算され、あなたを与えるだろう最短距離。

ポイントとラインの距離を比較し、最も短いものを選択します。

ここでここで距離機能


delimiter // 

CREATE FUNCTION distance (latA double, lonA double, latB double, LonB double) 
RETURNS double DETERMINISTIC 
    BEGIN 
     SET @RlatA = radians(latA); 
     SET @RlonA = radians(lonA); 
     SET @RlatB = radians(latB); 
     SET @RlonB = radians(LonB); 
     SET @deltaLat = @RlatA - @RlatB; 
     SET @deltaLon = @RlonA - @RlonB; 
     SET @d = SIN(@deltaLat/2) * SIN(@deltaLat/2) + 
     COS(@RlatA) * COS(@RlatB) * SIN(@deltaLon/2)*SIN(@deltaLon/2); 
     RETURN 2 * ASIN(SQRT(@d)) * 637101; 
    END// 

がDistanceFromLine関数である:


DROP function IF EXISTS `DistanceFromLine`; 
delimiter // 
    CREATE FUNCTION `DistanceFromLine`(
    route LINESTRING, point1 POINT 
    ) RETURNS INT DETERMINISTIC 
     BEGIN 
     DECLARE a INT Default 0 ; 
     DECLARE minDistance INT Default 0; 
     DECLARE currentDistance INT Default 0; 
     DECLARE currentpoint point ; 
     DECLARE size INT Default 0 ; 
     SET size = NumPoints(route); 
       simple_loop: LOOP 
     SET a = a+1; 
     SET currentpoint = PointN(route,a); 
     SET currentDistance = Distance(X(point1), Y(point1),  
       X(currentpoint),Y(currentpoint)); 

     IF a = 1 THEN 
     SET minDistance = currentDistance; 
      END IF; 

     IF currentDistance < minDistance THEN 
     SET minDistance = currentDistance; 
     END IF; 
     IF a=size THEN 
       LEAVE simple_loop; 
     END IF; 
      END LOOP simple_loop; 
    RETURN (minDistance); 
END// 

0

これは非常に便利だったAN私のためにswerを使っていますが、私はより進んだ、あるいはちょうど異なるジオクエリ関数を持つMySQL 5.7.18を使用しています。 ST_Distance_Sphereを使用して、転記された距離関数はもう必要ありません。そこでここでは、現代に準拠DistanceFromLine(5.7.6+)MySQLを作るために同じコードの更新は...だ

DROP function IF EXISTS `DistanceFromLine`; 
delimiter // 
    CREATE FUNCTION `DistanceFromLine`(
    route LINESTRING, point1 POINT 
    ) RETURNS INT DETERMINISTIC 
     BEGIN 
     DECLARE a INT Default 0 ; 
     DECLARE minDistance INT Default 0; 
     DECLARE currentDistance INT Default 0; 
     DECLARE currentpoint point ; 
     DECLARE size INT Default 0 ; 
     SET size = ST_NumPoints(route); 
       simple_loop: LOOP 
     SET a = a+1; 
     SET currentpoint = ST_PointN(route,a); 
     SET currentDistance = ST_Distance_Sphere(point1,currentpoint); 

     IF a = 1 THEN 
     SET minDistance = currentDistance; 
      END IF; 

     IF currentDistance < minDistance THEN 
     SET minDistance = currentDistance; 
     END IF; 
     IF a=size THEN 
       LEAVE simple_loop; 
     END IF; 
      END LOOP simple_loop; 
    RETURN (minDistance); 
END// 
0

また、私はこの問題に取り組んでいますが、残念ながらホテルのために最寄りの道を見つけることですされています好ましくない解決策。道路の入り口が決定的な答えであることが分かりました。言い換えれば、住所。 これは、住所表を持ち、一致する点がに最も近い住所の道路であることを意味します。

関連する問題