有什么方法可以从 GPS 坐标中恢复数据,这些坐标在 PostGIS 中作为地理数据类型插入 LAT/LONG?
Any way to recover data from GPS coordinates that were inserted as LAT/LONG as geography data type in PostGIS?
我将我所有的数据点插入到地理字段中作为 '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
你以 -67.640617 开始让我感到困惑,这怎么可能?好吧,我可以推导出那个确切的值(我确信它不是它是如何得到的,而且可能不是一个通用公式)。考虑纬度(Y 坐标)是 -90 <= latitude <= 90 负值表示 赤道以南 但继续在同一行-90 之后的运动你开始向北移动剩下的部分。您所拥有的值可以推导为:注:180 from equator -> south pole -> equator = 180 degrees of latitor traversed.
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 none 实际上解决了你的问题,就像试图理解结果一样。如果答案 #2 是输入期间发生的转换,而 -67 是存储的值,那么您只需重新加载数据。不是你想要的答案,而是你将要面对的。但是,如果这是一个显示输出转换,那么恢复就是一个简单的更新语句。
Postgres(和 AFAIK 所有其他数据库)您可以使用旧数据值,直到至少语句复杂化。您可以通过 select 反转列来反转列;即 select ST_Y 代表 X 和 ST_X 代表 Y。所以试试:
update building
set gps = point( st_y(gps::geometry) -- move Y value to X
, st_x(gps::geometry) -- move X value to Y
);
它在我的环境中工作,beploy 是我的完整测试序列。我通常会创建一个 fiddle 但 db<>fiddle nor 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)
*/
如果数据值的转换发生在输入(插入)时,这将不会恢复实际值。但看起来你没有什么可失去的,可能会有很大的收获。值得一试!
我将我所有的数据点插入到地理字段中作为 '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
你以 -67.640617 开始让我感到困惑,这怎么可能?好吧,我可以推导出那个确切的值(我确信它不是它是如何得到的,而且可能不是一个通用公式)。考虑纬度(Y 坐标)是 -90 <= latitude <= 90 负值表示 赤道以南 但继续在同一行-90 之后的运动你开始向北移动剩下的部分。您所拥有的值可以推导为:注:180 from equator -> south pole -> equator = 180 degrees of latitor traversed.
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 none 实际上解决了你的问题,就像试图理解结果一样。如果答案 #2 是输入期间发生的转换,而 -67 是存储的值,那么您只需重新加载数据。不是你想要的答案,而是你将要面对的。但是,如果这是一个显示输出转换,那么恢复就是一个简单的更新语句。
Postgres(和 AFAIK 所有其他数据库)您可以使用旧数据值,直到至少语句复杂化。您可以通过 select 反转列来反转列;即 select ST_Y 代表 X 和 ST_X 代表 Y。所以试试:
update building
set gps = point( st_y(gps::geometry) -- move Y value to X
, st_x(gps::geometry) -- move X value to Y
);
它在我的环境中工作,beploy 是我的完整测试序列。我通常会创建一个 fiddle 但 db<>fiddle nor 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)
*/
如果数据值的转换发生在输入(插入)时,这将不会恢复实际值。但看起来你没有什么可失去的,可能会有很大的收获。值得一试!