【发布时间】:2020-04-03 15:00:08
【问题描述】:
我在谷歌地图上画了一个多边形
new google.maps.Polygon({
paths: [
{ lat: 52.474617867242515, lng: -1.8111903062499923 },
{ lat: 51.527748727453975, lng: -2.7340418687499923 },
{ lat: 51.41825758811742, lng: -0.40494030624999233 },
],
fillColor: '#FFC107',
}).setMap(map);
我还可以单击在地图上放置新标记,将坐标传递给服务器,然后显示一个彩色标记:如果在多边形内部,则为绿色,如果在外部则为红色。
google.maps.event.addListener(drawingManager, 'overlaycomplete', (e) => {
axios.post('/home/testmarker', e.overlay.getPosition()).then((response) => {
e.overlay.setIcon('http://maps.google.com/mapfiles/ms/icons/' + response.data + '-dot.png');
});
});
在我的服务器上,我检查新标记是否落在我的多边形内。最终会有很多多边形需要检查,现在我已经在存储过程中硬编码了一个多边形的副本
CREATE PROCEDURE [dbo].[TestMarker]
@lat varchar(20),
@lng varchar(20)
AS
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('POLYGON((-1.8111903062499923 52.474617867242515, -2.7340418687499923 51.527748727453975, -0.40494030624999233 51.41825758811742, -1.8111903062499923 52.474617867242515))', 4326);
SET @h = geography::STGeomFromText('POINT(' + @lng + ' ' + @lat + ')', 4326);
SELECT @g.STContains(@h);
在拐角处,我的标记被准确地识别为多边形内部或外部。
但是,双方是另一回事。在每条边的中间选取一个点,标记不再被准确地识别为多边形内部或外部。
我也尝试过使用几何数据类型,所以我的 SP 看起来像
...
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON((-1.8111903062499923 52.474617867242515, -2.7340418687499923 51.527748727453975, -0.40494030624999233 51.41825758811742, -1.8111903062499923 52.474617867242515))', 0);
SET @h = geometry::STGeomFromText('POINT(' + @lng + ' ' + @lat + ')', 0);
...
注意,我已将 SRID 更改为 0
边角和以前一样准确,但侧面的准确度发生了变化,底部边缘的准确度发生了显着变化
在第一张和第三张图片中,顶行标记是使用“地理”识别的先前标记,底行是使用“几何”计算的新标记。
有谁知道需要做什么来解决这个问题?
我怀疑这与带有地理的 SRID 以及 Google 地图使用的方法有关。在我的第一个示例中,我使用了似乎被广泛推荐的 4326。 I found that Google should be using this as well,虽然他们也使用名为 3857 的东西,但我在 SQL Server 中似乎没有——至少默认情况下没有。我没有以前存储的数据,因此如果需要,我可以轻松更改存储和比较数据的方式来完成这项工作。
【问题讨论】:
-
尚未检查您的代码,但您不能在前端使用几何库和
containsLocationmethod 进行检查吗? -
并在后端释放所有功能,包括地理空间索引?
-
@TomTom 他在前端使用 API 来创建或渲染标记和多边形,并且相同的 API 有一种方法来检查一个点是否位于多边形内(这似乎成为OP想要做的)。这与在后端丢失任何东西有什么关系?
-
@MrUpsidown 最终目标类似于商店定位器,因此将传入一个点(例如邮政编码),可以将其与大量可能的多边形进行比较以找到“覆盖”的记录'那一点。我认为将所有数据传回以使浏览器能够解决问题是不可行的。
-
在您的测试中,您似乎在干扰一堆点以查看它横向移动的位置。对于误报,
@g.STDistance(@h)给出了什么?
标签: sql-server google-maps geospatial