我们正在开发一个应用程序,该应用程序涉及根据PostgreSQL表中存储的多边形计算给定点的最短距离。
我们正在使用PostgreSQL数据库中的ST_距离函数。
当我们将计算出的距离与Google Earth进行比较时,两者之间存在着巨大的差异。
当然,谷歌和PostgreSQL都不可能是错的(或者是错的?),所以我们显然遗漏了一些东西。
你知道怎么回事吗?
我在下面给出了我们用PostgreSQL测试的示例查询,以及Google Earth的屏幕截图。
SELECT ST_Distance(Place1, Place2) As Place1ToPlace2
, ST_Distance(Place1, Spot1) As Place1ToSpot1
, ST_Distance(Place1, Spot2) As Place1ToSpot2
, ST_Distance(Place2, Spot1) As Place2ToSpot1
, ST_Distance(Place2, Spot2) As Place2ToSpot2
FROM (SELECT
ST_PolygonFromText('SRID=4326;POLYGON((-74.0050636293915 40.75265123968514,-74.00500355126653 40.75268991743845,-74.00498169169283 40.75267084386348,-74.00503571044075 40.75263867886528,-74.0050636293915 40.75265123968514))') as Spot1
,ST_PolygonFromText('SRID=4326;POLYGON((-74.00503571044075 40.75263867886528,-74.00498225451273 40.75267084385684,-74.00495878551709 40.75265859837483,-74.00501023946696 40.75262521978885,-74.00503571044075 40.75263867886528))') as Spot2
,ST_GeogFromText('SRID=4326;POINT(-74.00489 40.752894)') As Place1
,ST_GeogFromText('SRID=4326;POINT(-74.004774 40.752846)') As Place2
) As foo ;
它会产生以下值:
place1toplace2 |place1tospot1 |place1tospot2 |place2tospot1 |place2tospot2 |
---------------|--------------|--------------|--------------|--------------|
11.152362504 |24.608417285 |25.977083731 |26.004190091 |26.011579435 |
以下是谷歌地球的截图:
提前谢谢!!
以下是从Google Earth导出的KML:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>Spot 1.kml</name>
<Style id="inline">
<LineStyle>
<color>ff0000ff</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<fill>0</fill>
</PolyStyle>
</Style>
<Style id="inline0">
<LineStyle>
<color>ff0000ff</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<fill>0</fill>
</PolyStyle>
</Style>
<StyleMap id="inline1">
<Pair>
<key>normal</key>
<styleUrl>#inline</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#inline0</styleUrl>
</Pair>
</StyleMap>
<Placemark>
<name>Spot 1</name>
<styleUrl>#inline1</styleUrl>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-74.0050636293915,40.75265123968514,0 -74.00500355126653,40.75268991743845,0 -74.00498169169283,40.75267084386348,0 -74.00503571044075,40.75263867886528,0 -74.0050636293915,40.75265123968514,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>Spot 2.kml</name>
<Style id="inline">
<LineStyle>
<color>ff0000ff</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<fill>0</fill>
</PolyStyle>
</Style>
<StyleMap id="inline0">
<Pair>
<key>normal</key>
<styleUrl>#inline1</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#inline</styleUrl>
</Pair>
</StyleMap>
<Style id="inline1">
<LineStyle>
<color>ff0000ff</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<fill>0</fill>
</PolyStyle>
</Style>
<Placemark>
<name>Spot 2</name>
<styleUrl>#inline0</styleUrl>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-74.00503571044075,40.75263867886528,0 -74.00498225451273,40.75267084385684,0 -74.00495878551709,40.75265859837483,0 -74.00501023946696,40.75262521978885,0 -74.00503571044075,40.75263867886528,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>
!编辑2!
我还试过一件事。我已经从Spot1中选取了视觉上最接近位置1的点,并将其标记为位置3。
当我们在地图上查看时,看起来Place3比Place2更接近Place1,但是当使用查询进行检查时,到Place3的距离给出了更高的值。
我已检查以下查询:
SELECT ST_Distance(Place1, Place2) As Place1ToPlace2
,ST_Distance(Place1, Place3) As Place1ToPlace3
FROM (SELECT
ST_GeogFromText('SRID=4326;POINT(-74.00489 40.752894)') As Place1
,ST_GeogFromText('SRID=4326;POINT(-74.004774 40.752846)') As Place2
,ST_GeogFromText('SRID=4326;POINT(-74.00500355126653 40.75268991743845)') As Place3
) As foo;
并给出如下结果:
place1toplace2 |place1toplace3 |
---------------|---------------|
11.152362504 |24.608417285 |
而在地图上:Place1ToPlace3
以下是Place1、Place2和Place3的KML(我已经从KML中删除了与样式相关的标记)
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>Distance Comparison.kml</name>
<Folder>
<name>Distance Comparison</name>
<open>1</open>
<Style>
<ListStyle>
<listItemType>check</listItemType>
<bgColor>00ffffff</bgColor>
<maxSnippetLines>2</maxSnippetLines>
</ListStyle>
</Style>
<Placemark>
<name>Place 1 - 40°45'9.78"N 74° 0'18.07"W (40.752894, -74.00489)</name>
<open>1</open>
<LookAt>
<longitude>-74.00500758183839</longitude>
<latitude>40.75269419172616</latitude>
<altitude>0</altitude>
<heading>-0.0008536233435993688</heading>
<tilt>29.8433509629012</tilt>
<range>47.16429940085073</range>
<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
</LookAt>
<styleUrl>#msn_1</styleUrl>
<Point>
<gx:drawOrder>1</gx:drawOrder>
<coordinates>-74.00501944444444,40.75271666666666,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Place 2 - 40°45'9.54"N 74° 0'17.70"W (40.752846, -74.004774)</name>
<open>1</open>
<LookAt>
<longitude>-74.00500758183839</longitude>
<latitude>40.75269419172616</latitude>
<altitude>0</altitude>
<heading>-0.0008536233435993688</heading>
<tilt>29.8433509629012</tilt>
<range>47.16429940085073</range>
<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
</LookAt>
<styleUrl>#msn_2</styleUrl>
<Point>
<gx:drawOrder>1</gx:drawOrder>
<coordinates>-74.00491666666667,40.75265,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Place 3 - 40°45'9.68"N 74° 0'18.01"W (40.75268991743845 -74.00500355126653)</name>
<open>1</open>
<styleUrl>#msn_3</styleUrl>
<Point>
<coordinates>-74.00500277777778,40.75268888888889,0</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
您在PostGIS中的功能似乎与谷歌中的功能不同。。。这是我通过想象得到的。
现在还有两个问题。第一,几何学和地理学的区别。第二,距离计算。
地理位置上的st_距离返回以米为单位的值。这就是为什么考虑到要素的位置,第一次查询的输出基本上是您所期望的(因为您的点是地理位置,Postgres为您将多边形投射到地理位置)。但是,几何体上的st_distance以基础投影的单位返回值,在本例中为度。这就解释了第二个查询的输出。
关于距离计算。这里尽量简洁,但影响你计算的最大的东西是潜在的投影。根据我的理解,地理类型更适合更大的区域——你会在你分析的区域的适当投影中使用几何图形得到更准确的结果。“合适的投影”取决于你在看世界的什么地方,你的目的是什么。
另外,不要假设谷歌的数据是正确的——我做了一个快速搜索,但没有找到任何关于他们如何计算距离的信息。如果他们使用不同的方法,你会得到不同的答案。。。
编辑这里是查询,坐标显示在屏幕截图中。请注意坐标值中的差异!另外,请注意,屏幕截图中显示的度数分秒与括号中的十进制度数值不匹配!
SELECT ST_Distance(Place1, Place2) As Place1ToPlace2
, ST_Distance(Place1, Spot1) As Place1ToSpot1
, ST_Distance(Place1, Spot2) As Place1ToSpot2
, ST_Distance(Place2, Spot1) As Place2ToSpot1
, ST_Distance(Place2, Spot2) As Place2ToSpot2
FROM (SELECT
ST_PolygonFromText('SRID=4326;POLYGON((-74.0050636293915 40.75265123968514,-74.00500355126653 40.75268991743845,-74.00498169169283 40.75267084386348,-74.00503571044075 40.75263867886528,-74.0050636293915 40.75265123968514))') as Spot1
,ST_PolygonFromText('SRID=4326;POLYGON((-74.00503571044075 40.75263867886528,-74.00498225451273 40.75267084385684,-74.00495878551709 40.75265859837483,-74.00501023946696 40.75262521978885,-74.00503571044075 40.75263867886528))') as Spot2
,ST_GeogFromText('SRID=4326;POINT( -74.005019 40.752717)') As Place1
,ST_GeogFromText('SRID=4326;POINT(-74.004917 40.752650)') As Place2
) As foo ;
返回的值为11.38223433、3.27827391、5.99175215、5.93327383、3.65564537。它们与谷歌的搜索结果相差不到厘米。
好吧,为了大学,我正在做一些SQL作业,但是我不知道这里有什么问题...坚持了几个小时。 所以在这里我创建了一个函数: 然后我尝试插入一个新行: 继续获取此错误: 错误:函数ins_notitie(未知,带时区的时间戳,未知,带时区的时间戳)不存在 第1行:选择ins_notitie('100001',now(),'Test note',now()) 错误:函数ins_notitie(未知,带时区
此SQL生成以下内容: 此SQL生成以下内容: 基本上,我希望得到这样的结果,按城市分组,以及相同城市出现的次数。像这样的 我不是联接、子查询方面的专家,这会有帮助吗?提前谢谢。
本文向大家介绍PostgreSQL数据库中窗口函数的语法与使用,包括了PostgreSQL数据库中窗口函数的语法与使用的使用技巧和注意事项,需要的朋友参考一下 什么是窗口函数? 一个窗口函数在一系列与当前行有某种关联的表行上执行一种计算。这与一个聚集函数所完成的计算有可比之处。但是窗口函数并不会使多行被聚集成一个单独的输出行,这与通常的非窗口聚集函数不同。取而代之,行保留它们独立的标识。在这些现象
我有3列(时间,值,结果)的度量表。时间和值是时间序列数据库需要的基础。结果列标记可以具有以下值之一(成功/硬失败/软失败/未知)。 我想在给定的时间窗口内跟踪成功率(成功/总成功率)(因为我将在grafana上使用它,时间窗口可能会改变,并且应该支持动态时间范围查询) 我在流入量0.9上尝试过的东西: Grafana有一个百分比堆栈选项来显示计数值。不幸的是,它不显示百分比值。它只是显示了分布的
我很难找到正确的语法,我总是有错误#1064。 错误:#1064-您的SQL语法有错误;查看与您的MariaDB服务器版本对应的手册,以了解使用near'的正确语法; 这就是代码; 定界符$$ 删除函数如果存在$$ 创建函数(iq INT, sq INT, ig INT)返回INT 开始 结束$$ 分隔符; 我在网上搜索答案,我找不到。我的语法有什么问题?