postgresql 为什么在使用PostGIS时,英国的县几何图形会出现在几内亚湾?

e1xvtsh3  于 5个月前  发布在  PostgreSQL
关注(0)|答案(1)|浏览(47)

我在AWS Postgres服务器中有两个表(我使用DBeaver查询)。

  • 表1是我从名为uk_counties的S3存储桶中导入的shapefile,其中列出了英国所有县的几何图形(SRID = 27700 - shapefile可以在here中找到)。
  • 表2称为demand_origin,包含字段origin_city(英国的地点)和两个字段latitudelongitude(包含origin_city中地点的纬度和对数)。

通过连接uk_counties(shapefile)和demand_origin,我想通过查找它们各自的纬度与县的shapefile相交的位置,将县分配给英国的各个地方。
问题是这个连接一直显示为空。经过大量调查,似乎shapefile中的几何图形Map到了几内亚湾(在lat = 0,long = 0的范围内和周围)。
以莱斯特的shapefile为例:
x1c 0d1x的数据
我的猜测是,几何图形使用的是北/西,而不是纬度/经度,因此PostGIS将这些形状Map到纬度=0,经度=0左右,因此可能需要重新校准。
以下是莱斯特和其他县的几何形状的片段:
| 公司简介|几何|
| --|--|
| 约克|POLYGON((464216.99650000036 462110.9015999995,464266.20299999975 462093.0965999998,464270.3008000003 462094.39629999992,464289.8992999997 4|
| 德比|POLYGON((434972.3005999997 341311.7999000009,434986.3008000003 341310.40029999986,435000.053600002 341314.6991000008,435015.29860000033 3 3|
| 剑桥郡|多多边形(529832.0997000001 300053.7999000009,529880.201399997 300039.1041000001,529903.7987000002 300036.6048000008,529914.2039999|
有什么问题吗?

yxyvkwin

yxyvkwin1#

FWIW,当我从上面的链接下载了Shapefile,并导入它这样:

shp2pgsql -I -s 27700 -g geometry CTYUA_MAY_2023_UK_BFC.shp uk_counties | psql -d mydb

字符串
我得到了一个非常不同模式:

\d+ uk_counties
Column   |             Type             | Collation | Nullable |                 Default                  | Storage  | Compression | Stats target | Description
------------+------------------------------+-----------+----------+------------------------------------------+----------+-------------+--------------+-------------
 gid        | integer                      |           | not null | nextval('uk_counties_gid_seq'::regclass) | plain    |             |              |
 ctyua23cd  | character varying(9)         |           |          |                                          | extended |             |              |
 ctyua23nm  | character varying(36)        |           |          |                                          | extended |             |              |
 ctyua23nmw | character varying(24)        |           |          |                                          | extended |             |              |
 bng_e      | double precision             |           |          |                                          | plain    |             |              |
 bng_n      | double precision             |           |          |                                          | plain    |             |              |
 long       | double precision             |           |          |                                          | plain    |             |              |
 lat        | double precision             |           |          |                                          | plain    |             |              |
 globalid   | character varying(38)        |           |          |                                          | extended |             |              |
 geometry   | geometry(MultiPolygon,27700) |           |          |                                          | main     |             |              |
Indexes:
    "uk_counties_pkey" PRIMARY KEY, btree (gid)
    "uk_counties_geometry_idx" gist (geometry)
Access method: heap

的数据
而且我可以很容易地得到一个正确的经纬度值:

SELECT
    ctyua23nm,
    long,
    lat
FROM
    uk_counties
WHERE
    ctyua23nm = 'Leicester';
ctyua23nm |  long   |   lat
-----------+---------+---------
 Leicester | -1.1304 | 52.6359
(1 row)

的字符串
重新导入Shapefile可能会更容易,因为我不确定您是如何导入的。
如果您无法使用当前的模式,请继续。
几何图形使用北距/西距,而不是纬度/经度
正确.
SRID 27700 /EPSG:27700Ordnance Survey National Grid(OSGB)或更常见的英国国家格网(BNG)对齐。它基本上使用以米为单位的投影东距和北距,而不是以度为单位的纬度和经度。
您可以通过运行以下命令来查看:

SELECT srtext FROM spatial_ref_sys WHERE srid = 27700;
PROJCS["OSGB 1936 / British National Grid",
  GEOGCS["OSGB 1936",
    DATUM["OSGB_1936",
      SPHEROID["Airy 1830", 6377563.396, 299.3249646,
        AUTHORITY["EPSG", "7001"]],
      TOWGS84[446.448, -125.157, 542.06, 0.15, 0.247, 0.842, -20.489],
      AUTHORITY["EPSG", "6277"]],
    PRIMEM["Greenwich", 0, AUTHORITY["EPSG", "8901"]],
    UNIT["degree", 0.0174532925199433, AUTHORITY["EPSG", "9122"]],
    AUTHORITY["EPSG", "4277"]],
  PROJECTION["Transverse_Mercator"],
  PARAMETER["latitude_of_origin", 49],
  PARAMETER["central_meridian", -2],
  PARAMETER["scale_factor", 0.9996012717],
  PARAMETER["false_easting", 400000],
  PARAMETER["false_northing", -100000],
  UNIT["metre", 1, AUTHORITY["EPSG", "9001"]],
  AXIS["Easting", EAST],
  AXIS["Northing", NORTH],
  AUTHORITY["EPSG", "27700"]]

的字符串
请注意UNIT["metre"AXIS["Easting", EAST]AXIS["Northing", NORTH]
您很可能希望使用SRID 4326 /EPSG:4326来投影数据,该数据与WGS 84(即GPS标准)一致。
它是一个二维地理坐标系,即使用纬度和经度。
要将SRID 27700表投影到纬度和经度坐标(SRID 4326),请首先使用Find_SRID验证geometry列的SRID是否设置为SRID 27700。

SELECT
    Find_SRID ('public', 'uk_counties', 'geometry');


输出应为:

find_srid
-----------
     27700
(1 row)


如果没有,请使用UpdateGeometrySRID设置列的SRID:

updategeometrysrid
---------------------------------------------------
 public.uk_counties.geometry SRID changed to 27700
(1 row)

的内存
然后,使用PostGIS中的ST_Transform函数进行转换:
返回一个新几何图形,该几何图形的坐标已转换为其他空间参考系。

ALTER TABLE uk_counties
    ALTER COLUMN geometry TYPE geometry(geometry, 4326)
    USING ST_Transform (geometry, 4326);

ALTER TABLE

ALTER TABLE uk_counties
    ALTER COLUMN geometry TYPE geometry(geometry, 4326)
    USING ST_Transform (geometry, 4326);

ALTER TABLE

ALTER TABLE uk_counties
    ALTER COLUMN geometry TYPE geometry(geometry, 4326)
    USING ST_Transform (geometry, 4326);

ALTER TABLE uk_counties
    ALTER COLUMN geometry TYPE geometry(geometry, 4326)
    USING ST_Transform (geometry, 4326);

ALTER TABLE

ALTER TABLE

ALTER TABLE uk_counties
    ALTER COLUMN geometry TYPE geometry(geometry, 4326)
    USING ST_Transform (geometry, 4326);

ALTER TABLE uk_counties
    ALTER COLUMN geometry TYPE geometry(geometry, 4326)
    USING ST_Transform (geometry, 4326);

ALTER TABLE

完成后,我们可以通过以下方法从几何图形中获取经纬度:
1.使用ST_Centroid获取几何图形的质心-点
1.应用ST_Y函数获得纬度
1.应用ST_X函数获取经度。
让我们创建2个新列来存储数据:

ALTER TABLE uk_counties
    ADD COLUMN latitude DOUBLE PRECISION,
    ADD COLUMN longitude DOUBLE PRECISION;

的第一个字符
然后,填充列...

UPDATE
    uk_counties
SET
    latitude = ST_Y (ST_Centroid (geometry)),
    longitude = ST_X (ST_Centroid (geometry));

的数据库
现在,您有两个新列:

  • latitude
  • longitude

新列应具有正确的值:

SELECT
    ctyua23nm,
    latitude,
    longitude
FROM
    uk_counties
LIMIT 10;

的第一个字符
最后但并非最不重要的一点,回到莱斯特的例子...

SELECT
    ctyua23nm,
    latitudea,
    longitudea
FROM
    uk_counties
WHERE
    ctyua23nm = 'Leicester';

ctyua23nm |     latitude      |     longitude
-----------+-------------------+---------------------
 Leicester | 52.63792039053044 | -1.1284845708542661
(1 row)


莱斯特来了!
x1c 0d1x的数据

相关问题