SQL select 边界框内的经纬度点

SQL select latitude and longitude point within bounding box

我正在使用 google 地图,我想查询我的 SQL 以找到边界框内的所有点。

在 google 地图中,我使用这个 javascript 来获取边界矩形

var bounds = map.getBounds();
var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
var args = {
    NW: { lat: ne.lat(), lng: sw.lng() },
    NE: { lat: ne.lat(), lng: ne.lng() },
    SE: { lat: sw.lat(), lng: ne.lng() },
    SW: { lat: sw.lat(), lng: sw.lng() },
}; //NW = North-West, NE = North-East, SE = South-East, SW = South-West

然后,我正在使用 LINQ select 我的 SQL 数据库中的所有位置:

//nw = North-West, ne = North-East, se = South-East, sw = South-West
double minLat = Math.Min(nw.Lat, Math.Min(ne.Lat, Math.Min(se.Lat, sw.Lat)));
double maxLat = Math.Max(nw.Lat, Math.Max(ne.Lat, Math.Max(se.Lat, sw.Lat)));
double minLng = Math.Min(nw.Lng, Math.Min(ne.Lng, Math.Min(se.Lng, sw.Lng)));
double maxLng = Math.Max(nw.Lng, Math.Max(ne.Lng, Math.Max(se.Lng, sw.Lng)));

return (from rec in tblPlaces.AsNoTracking()
        where (rec.Lat >= minLat) && (rec.Lat <= maxLat) && (rec.Lng >= minLng) && (rec.Lng <= maxLng)
        select rec).ToList<tblPlace>();

它在相当大的缩放时效果很好(google 缩放 <= 15)。但是当缩小到国家大小时(即你可以看到整个国家),它在我的数据库中找不到点。

在调试时,我发现经度数比我数据库中的任何点都小。这怎么可能?我拉远了整个国家。

是不是我的方式select经纬度不对?

看了经纬度的教程终于找到答案了

总结:纬度在-90到90之间,经度在-180到180之间

//Latitude
 90 ----------------------  90

  0 ----------------------   0

-90 ---------------------- -90

//Longitude
-180        0        180
  |         |         |
  |         |         |
  |         |         |
  |         |         |
-180        0        180

现在,边界框可以重叠。因此,边界框(矩形)中的左侧可以大于右侧,或者顶部可以大于底部。基于How to search (predefined) locations (Latitude/Longitude) within a Rectangular, using Sql?(见最后一个答案),解决方案是根据边界框的位置简单地合并所有组合。

如果你能找到更好更高效的解决方案,我会把赏金奖励给你:)

干杯

我不是地理专家,但这看起来很简单。让我们从经度开始。边界框可以在一侧或穿过反子午线:

-180         0         +180
  |                      |
  |       +-----+        |
  |   -10 |  x  | +10    |
  |       +-----+        |
  |                      |
  |                   +-----+
  |              +170 |  x  | -170
  |                   +-----+
  |                      |

给定的经度存在于边界框内,如果:

lng1 <= lng2 AND (lng1 <= lng AND lng <= lng2) /* both edges on same side */
OR
lng1 >  lng2 AND (lng1 <= lng OR  lng <= lng2) /* edges on opposite sides */

给定的纬度存在于边界框内,如果:

lat1 >= lat2 AND (lat1 >= lat AND lat >= lat2) /* both edges on same side */
OR
lat1 <  lat2 AND (lat1 >= lat OR  lat >= lat2) /* edges on opposite sides */

如果纬度不环绕,例如在 Google 地图 API 中则不需要对面测试。

Some tests on db<>fiddle and a jsFiddle showing how LatLngBounds work