2

テーブルが与えられると、

+-----+---------+---------+---------+---------+---------+
| user| min_lat | max_lat | min_lng | max_lng |
+-----+---------+---------+---------+---------+---------+
| a   |    46   |     407 |       6 |     367 | 
| b   |   226   |     227 |     186 |     188 | 

また、Point(x、y)は、ポイントがユーザーの最小および最大の緯度と経度の範囲内にあるユーザーを検索します(ここで、最小および最大の経度および緯度=現在の位置から半径を引いた値またはプラスした値)。

最小値は0未満、最大値は360を超えることができます。クエリでは、これらを考慮する必要があります。

たとえば、Point(7,5)を使用したフィルタリングでも、367-360=7のようにユーザーAが返されます。

私がこれを正しく理解しているかどうかはわかりませんが、誰かが私に洞察を与えてくれることを願っています。

4

4 に答える 4

2

テーブルに格納されている緯度と経度の値を [0, 360] の範囲に制限することをお勧めします。挿入と更新の前にトリガーを作成して、mod 360 の同等性を適用し、max-min > 360 の場合は、最小値と最大値をそれぞれ 0 と 360 に設定します。例えば:

delimiter ;;

CREATE TRIGGER normalize_inserted_ranges BEFORE INSERT 
  ON table
  FOR EACH ROW BEGIN
    IF NEW.max_lat - NEW.min_lat >= 360 THEN
        SET NEW.min_lat=0;
        SET NEW.max_lat=360;
    ELSE
        SET NEW.min_lat = NEW.min_lat % 360;
        SET NEW.max_lat = NEW.max_lat % 360;
    END IF;
    IF NEW.max_lng - NEW.min_lng >= 360 THEN
        SET NEW.min_lng=0;
        SET NEW.max_lng=360;
    ELSE
        SET NEW.min_lng = NEW.min_lng % 360;
        SET NEW.max_lng = NEW.max_lng % 360;
    END IF;
  END
;;
delimiter ;

その後、次のクエリを使用できます。

SELECT user FROM table
  WHERE
      IF(min_lng <= max_lng, 
         @x BETWEEN min_lng AND max_lng, 
         @x <= max_lng OR min_lng <= @x)
    AND
      IF(min_lat <= max_lat,
         @y BETWEEN min_lat AND max_lat, 
         @y <= max_lat OR min_lat <= @y)
;
于 2009-11-11T08:22:43.140 に答える
0

質問の一部に答えるために、367 と 7 が同じであると言っている場合、727 も同じであると仮定します。

したがって、360 のモジュラスを使用する必要があります。たとえば、360 で割った余りです。

例 (ここで % は C# および C++ の構文です。おそらく、これを行う SQL の方法を見つけることができます)

7 % 360 = 7
367 % 360 = 7
727 % 360 = 7

あなたが望むようなものは何かのように見えSELECT b MOD 360 from table;ます。

于 2009-11-06T10:59:24.903 に答える
0

もっと洗練された答えがあると思いますが、SQL where 句の制限により、これが少し難しくなっていると思います。

仮定:

  • 0 <= x < 360
  • 0 <= y < 360
  • max_lat - min_lat <= 361
  • max_lng - min_lng <= 361
SELECT user FROM user_location WHERE  
((min_lat <  0 AND ((0 <= y AND y <= max_lat) OR (min_lat + 360 <= y AND y < 360))) OR  
 (min_lat >= 0 AND ((min_lat <= y AND y <= max_lat) OR (0 <= y AND y <= max_lat - 360))))  
AND  
((min_lng <  0 AND ((0 <= x AND x <= max_lng) OR (min_lng + 360 <= x AND x <= 360))) OR  
 (min_lng >= 0 AND ((min_lng <= x AND x <= max_lng) OR (0 <= x AND x <= max_lng - 360))))

1 つの次元では、最小値 < 0 の場合、x は 0 と最大値の間に収まるか、x は最小値 + 360 と 360 の間に収まる必要があります。同様に、最小値 >= 0 の場合、x は最小値と最大値の間に収まるか、0 と最大値の間に収まる必要があります- 360。

上記の形式は、わかりやすくするために示されています。360 の足し算と引き算を x パラメーターと y パラメーターに移動すると、比較が一定になり、おそらくクエリが劇的に高速化されます。

于 2009-11-06T12:37:00.140 に答える