有啥方法可以从作为 LAT/LONG 作为 PostGIS 中的地理数据类型插入的 GPS 坐标中恢复数据?
Posted
技术标签:
【中文标题】有啥方法可以从作为 LAT/LONG 作为 PostGIS 中的地理数据类型插入的 GPS 坐标中恢复数据?【英文标题】:Any way to recover data from GPS coordinates that were inserted as LAT/LONG as geography data type in PostGIS?有什么方法可以从作为 LAT/LONG 作为 PostGIS 中的地理数据类型插入的 GPS 坐标中恢复数据? 【发布时间】:2021-12-30 17:29:42 【问题描述】:我将所有数据点作为“POINT(43.870683 -112.359383)”插入到地理字段中,即先经纬度。现在,当我尝试使用 ST_X 和 ST_Y 提取坐标时,X 坐标看起来是正确的,但是 Y 坐标让我在大西洋中出路。我假设 PostGIS 不考虑纬度,并试图推断经度。我从该插入中得到的要点是:
st_x | st_y
-----------+------------
43.870683 | -67.640617
有没有办法恢复正确的坐标?
编辑:版本信息
postgis_version
---------------------------------------
3.0 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
PostgreSQL 13.3
gps
----------------------------------------------------
0101000020E61000007217618A72EF4540BF1072DEFFE850C0
gps | geography(Point,4326)
插入查询(现在我知道这是错误的顺序,我能以某种方式恢复数据吗?)
insert into buildings (gps) values('POINT(43.870683 -112.359383)')
select ST_X(gps::geometry), ST_Y(gps::geometry) from buildings
st_x | st_y
-----------+------------
43.870683 | -67.640617
^^^^^^^^^ very wrong, not what I input
【问题讨论】:
在您的问题中添加 Postgres 版本、Postgis 版本和您正在使用的实际查询。 你的积分倒退了。当参考地球表面的点时,X 映射到经度,Y 映射到纬度。因此点数据总是先解释经度,再解释纬度;你的定义应该是POINT( -112.359383 43.870683)
@Belayer - PostGIS 可能确实如此,但在 GIS 世界中远未普及。
@Belayer 我明白,这就是为什么我问我是否可以通过某种方式从 PostGIS 恢复正确的 GPS 坐标。我会用版本信息更新问题。
@IanTurton 你是对的。由于 OP 实际上指定了 PostGIS,这只是一个未说明的假设,对我不利。我应该说:因此 PostGIS 中的点数据总是被解释...。感谢您指出。
【参考方案1】:
你最初以 -67.640617 结尾让我很困惑,这怎么可能?好吧,我可以得出那个确切的值(我确信它不完全是如何得到的,并且可能不是一个通用公式)。考虑纬度(Y 坐标)是 -90 ,负值表示 赤道以南,但在 -90 之后继续沿同一条运动线移动向北移动剩下的东西。您所拥有的值可以推导出为:注意:180 距离赤道 -> 南极 -> 赤道 = 180 纬度经过。
with on_earth (gps) as
( values ( POINT(43.870683, -112.359383)) )
select ST_Y(gps::geometry) "Latitude"
, sign( ST_Y(gps::geometry) ) * (180 - abs( ST_Y(gps::geometry))) "Derived Latitude"
from on_earth;
现在这引出了 2 个问题:
-
您如何插入值:直接 SQL 或通过某些接口 (ORM/API);
转换是在输入期间还是在输出时发生的。
使用 Postgres 14.1 和 PostGIS 3.1.4 运行直接 SQL 我没有在插入 -112.359383 后获得纬度 -67.640617。 除了#2之外,以上都没有真正解决您的问题,而是试图理解结果。如果答案 #2 是在输入期间发生的转换,而 -67 是存储的值,那么您只需重新加载数据。不是你想要的答案,而是你将要面对的。然而,如果这是一个显示输出转换,那么恢复就是一个简单的更新语句。 Postgres(和 AFAIK 所有其他数据库)您可以使用旧数据值,直到至少语句复杂化。您只需选择反向反转的列即可反转您的列;即为 X 选择 ST_Y,为 Y 选择 ST_X。所以尝试:
update building
set gps = point( st_y(gps::geometry) -- move Y value to X
, st_x(gps::geometry) -- move X value to Y
);
它在我的环境中工作,beploy 是我的完整测试序列。我通常会创建一个小提琴,但 db<>fiddle 和 SQL Fiddle 都不支持 PostGIS。
create table building(id integer generated always as identity
, gps point
);
insert into building(gps) values (POINT(43.870683, -112.359383));
select * from building;
/* Result
* id | gps
* 1 | (43.870683,-112.359383)
*/
update building
set gps = point( st_y(gps::geometry) -- move Y value to X
, st_x(gps::geometry) -- move X value to Y
);
select * from building;
/* Result
* id | gps
* 1 | (-112.359383,43.870683)
*/
如果数据值的转换发生在输入(插入)时,这将不会恢复实际值。但看起来你没有什么可失去的,可能会获得巨大的收益。值得一试!
【讨论】:
抱歉回复晚了!这是一个很好的答案;是的,它发生在输入上。因此,我正在考虑重新加载所有 GPS 数据。在使用 PostGIS 之前,我读过一本关于 PostGIS 的小书,从来没有遇到过需要按照与谷歌地图相反的顺序输入 lon/lat。哦,好吧,现在我知道了!感谢您提供信息丰富且详细的回答。以上是关于有啥方法可以从作为 LAT/LONG 作为 PostGIS 中的地理数据类型插入的 GPS 坐标中恢复数据?的主要内容,如果未能解决你的问题,请参考以下文章
从 1600 万+ lat/long 获取 FIPS 块代码
根据当前地理位置 ios app javascript 从 lat / long 列表中返回值
使用 Jinja 将数据作为 JSON 对象从 Python 发送到 Javascript [重复]
Blob 存储上的 Azure 触发器,从图像 (Blob) 中提取 EXIF (lat/long/direction...) 数据