Amy*_*ett 3 postgresql postgis spatial-query amazon-web-services amazon-rds
我在 AWS Postgres 服务器中有两个表(我正在使用 DBeaver 进行查询)。
表 1 是我从名为 的 S3 存储桶导入的 shapefile uk_counties,其中列出了英国所有县的几何图形(SRID = 27700 - shapefile 可以在此处找到)。
表 2 被称为demand_origin并 包含字段origin_city(英国的地点)和两个字段latitude和longitude(其中包含 中地点的纬度和经度origin_city)。
通过加入uk_counties(shapefile) 和demand_origin,我想通过查找各自的经度与县的 shapefile 相交的位置,将一个县分配给英国的各个地方。
问题是这个连接一直显示为空。经过大量调查后,shapefile 中的几何图形似乎被映射到几内亚湾(纬度 = 0,经度 = 0 及其周围)。
请参阅莱斯特的 shapefile 作为示例:
我的猜测是,几何图形使用的是北距/西距,而不是纬度/经度,因此 PostGIS 将这些形状映射到 lat=0、long=0 左右,因此可能需要重新校准。
以下是莱斯特和其他县的几何形状的片段:
| ctua23nm | 几何学 |
|---|---|
| 约克 | 多边形 ((464216.99650000036 462110.9015999995, 464266.20299999975 462093.0965999998, 464270.3008000003 462094.3962999992, 46428 9.8992999997 4 |
| 德比 | 多边形 ((434972.3005999997 341311.7999000009, 434986.3008000003 341310.40029999986, 435000.0536000002 341314.6991000008, 435015 .29860000033 3 |
| 剑桥郡 | 多多边形 (((529832.0997000001 300053.7999000009, 529880.2013999997 300039.1041000001, 529903.7987000002 300036.6048000008, 529 914.20399999 |
有什么问题吗?
FWIW,当我从上面的链接下载 Shapefile 并像这样导入它时:
shp2pgsql -I -s 27700 -g geometry CTYUA_MAY_2023_UK_BFC.shp uk_counties | psql -d mydb
Run Code Online (Sandbox Code Playgroud)
我得到了一个非常不同的模式:
\d+ uk_counties
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我可以轻松获得正确的纬度和经度值:
SELECT
ctyua23nm,
long,
lat
FROM
uk_counties
WHERE
ctyua23nm = 'Leicester';
Run Code Online (Sandbox Code Playgroud)
ctyua23nm | long | lat
-----------+---------+---------
Leicester | -1.1304 | 52.6359
(1 row)
Run Code Online (Sandbox Code Playgroud)
重新导入 Shapefile 可能会更容易,因为我不确定你是如何导入它的。
如果您坚持使用当前架构,请继续。
几何图形使用北距/西距,而不是纬度/经度
正确的。
SRID 27700 / EPSG:27700与英国地形测量局国家网格(OSGB) 或更通称的英国国家网格 (BNG)一致。它基本上使用以米为单位的投影东距和北距,而不是以度为单位的纬度和经度。
您可以通过运行看到这一点:
SELECT srtext FROM spatial_ref_sys WHERE srid = 27700;
Run Code Online (Sandbox Code Playgroud)
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"]]
Run Code Online (Sandbox Code Playgroud)
注意UNIT["metre",AXIS["Easting", EAST]和AXIS["Northing", NORTH]。
您很可能希望使用 SRID 4326 / EPSG:4326来投影数据,它符合WGS84,即 GPS 标准。
它是一个二维地理坐标系,即使用纬度和经度。
要将 SRID 27700 表投影到纬度和经度坐标 (SRID 4326),请首先使用 验证列的 SRID 是否geometry设置为 SRID 27700 Find_SRID。
SELECT
Find_SRID ('public', 'uk_counties', 'geometry');
Run Code Online (Sandbox Code Playgroud)
输出应该是:
find_srid
-----------
27700
(1 row)
Run Code Online (Sandbox Code Playgroud)
如果没有,请使用以下命令设置列的 SRID UpdateGeometrySRID:
SELECT
UpdateGeometrySRID ('uk_counties', 'geometry', 27700);
Run Code Online (Sandbox Code Playgroud)
updategeometrysrid
---------------------------------------------------
public.uk_counties.geometry SRID changed to 27700
(1 row)
Run Code Online (Sandbox Code Playgroud)
然后,使用ST_TransformPostGIS中的函数进行转换:
返回一个新的几何图形,其坐标转换为不同的空间参考系统。
ALTER TABLE uk_counties
ALTER COLUMN geometry TYPE geometry(geometry, 4326)
USING ST_Transform (geometry, 4326);
Run Code Online (Sandbox Code Playgroud)
ALTER TABLE
Run Code Online (Sandbox Code Playgroud)
完成后,我们可以通过以下方式从几何图形中获取纬度和经度:
ST_Centroid获取几何体的质心 - 一个点ST_Y函数获取纬度ST_X函数来获取经度。让我们创建 2 个新列来存储数据:
ALTER TABLE uk_counties
ADD COLUMN latitude DOUBLE PRECISION,
ADD COLUMN longitude DOUBLE PRECISION;
Run Code Online (Sandbox Code Playgroud)
ALTER TABLE
Run Code Online (Sandbox Code Playgroud)
然后,填充列...
UPDATE
uk_counties
SET
latitude = ST_Y (ST_Centroid (geometry)),
longitude = ST_X (ST_Centroid (geometry));
Run Code Online (Sandbox Code Playgroud)
UPDATE 218
Run Code Online (Sandbox Code Playgroud)
现在,您有 2 个新列:
latitudelongitude新列应具有正确的值:
UPDATE 218
Run Code Online (Sandbox Code Playgroud)
SELECT
ctyua23nm,
latitude,
longitude
FROM
uk_counties
LIMIT 10;
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的一点是,以莱斯特城为例......
ctyua23nm | latitude | longitude
-----------------------------+--------------------+---------------------
Hartlepool | 54.669449373886266 | -1.2594048655284926
Middlesbrough | 54.54200444097641 | -1.2222619068734741
Redcar and Cleveland | 54.55165165356056 | -1.0206837926504952
Stockton-on-Tees | 54.56161339847885 | -1.3322804311895529
Darlington | 54.548705061498694 | -1.5526287937957188
Halton | 53.345131982125686 | -2.712197804308062
Warrington | 53.399109236880015 | -2.5627669775597606
Blackburn with Darwen | 53.692643404310815 | -2.467582012742445
Blackpool | 53.81779799751382 | -3.029241917065863
Kingston upon Hull, City of | 53.76405945136756 | -0.334854807051097
(10 rows)
Run Code Online (Sandbox Code Playgroud)
SELECT
ctyua23nm,
latitudea,
longitudea
FROM
uk_counties
WHERE
ctyua23nm = 'Leicester';
Run Code Online (Sandbox Code Playgroud)
这里是莱斯特!