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
我正在使用 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