有什么方法可以从 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 个问题:

  1. 您如何插入值:直接 SQL 或通过某些接口 (ORM/API);
  2. 转换是在输入过程中发生还是在输出过程中发生。

运行 使用 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) 
*/

如果数据值的转换发生在输入(插入)时,这将不会恢复实际值。但看起来你没有什么可失去的,可能会有很大的收获。值得一试!