postgis
標簽(空格分隔): 數據庫
[toc]
1. 空間數據庫建表
1. 首先建立一個常規的表格存儲有關城市(cities)的信息。這個表格有兩欄,一個是 ID 編號,一個是城市名:
CREATE TABLE cities ( id int4, name varchar(50) )
2.現在添加一個空間欄用于存儲城市的位置。
習慣上這個欄目叫做 the_geom 。它記錄了數據為什么類型(點、線、面)、有幾維(這里是二維)以及空間坐標系統。此處使用 EPSG:4326 坐標系統。
SELECT AddGeometryColumn ('cities', 'the_geom', 4326, 'POINT', 2)
3.使用 PostGIS 的ST_GeomFromText可以將文本轉化為坐標與參考系號的記錄:
INSERT INTO cities (id, the_geom, name) VALUES (1,ST_GeomFromText('POINT(-0.1257 51.508)',4326),'London, England');
INSERT INTO cities (id, the_geom, name) VALUES (2,ST_GeomFromText('POINT(-81.233 42.983)',4326),'London, Ontario');
INSERT INTO cities (id, the_geom, name) VALUES (3,ST_GeomFromText('POINT(27.91162491 -33.01529)',4326),'East London,SA');
4. 求多邊形層中每個多邊形的中心
SELECT st_astext(ST_Centroid(the_geom)) FROM country;
5. 基本的查詢語句
SELECT * FROM china LIMIT 5;
--SELECT geom FROM china WHERE china."name"='東城區';
--SELECT geom FROM china WHERE china."name"='西城區';
--SELECT * FROM china WHERE china."name"='朝陽區';
--SELECT geom FROM china WHERE china."name"='石景山區';
--SELECT * FROM china WHERE china."name"='通州區';
--SELECT geom FROM china WHERE china."name"='海淀區';
--SELECT geom FROM china WHERE china."name"='豐臺區';
--SELECT geom FROM china WHERE china."name"='大興區';
--SELECT geom FROM china WHERE china."name"='房山區';
--SELECT geom FROM china WHERE china."name"='門頭溝區';
6. 空間關系查詢
1. 是否相連
--SELECT st_disjoint(a.geom, b.geom) from china a, china b where a.name='石景山區' and b."name"='豐臺區';
2. 是否相交
--SELECT st_intersects(a.geom, b.geom) FROM china a,china b where a.name='海淀區' and b."name"='豐臺區';
3. 求距離
--SELECT st_distance(a.geom, b.geom) FROM china a,china b where a.name='海淀區' and b."name"='朝陽區';
4. 是否距離包含
--SELECT st_dwithin(a.geom, b.geom,2) FROM china a,china b where a.name='海淀區' and b."name"='朝陽區';
5. 是否接觸
--SELECT st_touches(a.geom, b.geom) FROM china a,china b where a.name='海淀區' and b."name"='石景山區';
6. 是否重疊
--SELECT st_overlaps(a.geom, b.geom) FROM china a,china b where a.name='豐臺區' and b."name"='海淀區';
7. 求面積
--Geometry Accessors查詢
--SELECT st_area(geom) FROM china where china.name='豐臺區' ;--
8. 求長度
--SELECT st_length(geom) FROM china WHERE china.name='海淀區';
9. 求線上的點數
--SELECT st_numpoints(geom) FROM china where china.name='海淀區';
10. 判斷幾個類型
--SELECT st_geometrytype(geom) FROM china where china.name='漠河縣';
11. 幾何空間數據轉換成空間數據文本格式
--SELECT st_astext(geom) FROM china WHERE china.name='海淀區';
12. 返回當前幾何空間數據的SRID值
SELECT st_srid(geom) FROM china WHERE china.name='海淀區';
13. 判斷是否閉合
--SELECT st_isclosed(geom) FROM china where china.name='海淀區';--
14. 判斷是否為空
--SELECT st_isempty(geom) FROM china where china.name='海淀區';--
15. 判斷起始點和終點坐標是否相同
--SELECT st_isring(geom) FROM china where china.name='海淀區';
16. 判斷是否可用
--SELECT st_isvalid(geom) FROM china where china.name='海淀區';
17. 判斷幾何對象是否不包含特殊點(比如自相交)
--SELECT st_issimple(geom) FROM china where china.name='海淀區';
18. postgis在傳統行業重點應用(優化查詢分析性能)
https://yq.aliyun.com/download/3193?spm=5176.11156381.0.0.20de7775tzg7VW&do=login&accounttraceid=22a1e0a0-3c00-4f10-94df-38b246515a91
19、獲取幾何類型St_GeometryType(geom)
20、獲取單個記錄的幾何個數ST_NumGeometries(geom)
select St_GeometryType(geom) GeomType,ST_NumGeometries(geom) GeomCount from rain;
21. point 和srid
select st_setsrid(st_makepoint(random()*360-180, random()*180-90), 4326)
22. 空間分析實現
將polygon和農田的polygon做st_intersection就行
實例你可以看看這里 https://www.bostongis.com/postgis_intersection_intersects.snippet
23 創建postgis擴展
create extension postgis;
CREATE EXTENSION postgis_topology;
create extension postgis_sfcgal;
create extension pgrouting;
create extension fuzzystrmatch;
create extension postgis_tiger_geocoder;
24 shp2pgsql
通過shape文件導出sql語句
shp2pgsql -s 2353 -c -W "GBK" C:\shape\650102jctb.shp>650102jctb.sql
25 shp2pgsql直接將Shape數據導入到數據表
shp2pgsql -s 2353 -c -W "GBK" C:\shape\650102jctb.shp public.jctbtest | psql -d fhadmin_a -U postgres -W
追加
- shp2pgsql -s 4490 -a -W "GBK" E:\testdata\jbntbhtb\JBNTBHTB_XJ2000.shp public.lxdw | psql -d test -U postgres -W
創建 注意:如果創建提示relation 不存在可能沒有創建postgis擴展,在public模式下執行第23步
shp2pgsql -s 4547 -c -W "UTF-8" D:/資料/freedoTech/2023/商丘/商丘建筑單體底面矢量/商丘全.shp cim.building_model1 | psql -h 192.168.20.236 -d ancient-city -U postgres -W
導出shape文件
示例:pgsql2shp -f C:/WP/wp_dktb.shp -h localhost -u postgres -P 123456 -p 5433 fhadmin_a public.wp_dktb
或
pgsql2shp -f E:/shp/nyc_streets.shp -h localhost -u postgres -P 123456 -p 5433 Testpg "SELECT * from nyc_streets";
26 坐標轉換st_transform
select ST_Transform(geom,4326);
//修改表中geom為4517的幾何數據修改為4490的數據
update tempjbnt set geom= st_transform(st_setsrid(geom,4517),4490)
27 大地坐標系面積計算
select st_area(geom,true); ---與平面坐標的面積有誤差
SELECT st_area(ST_Transform(st_geometryfromtext('POLYGON((116.4679312706 39.9482801227,116.4677961543 39.9486461337,116.4680989087 39.9486998528,116.4682182670 39.9483181633,116.4679312706 39.9482801227))',4490),4517));------與平面坐標的面積相等
大地坐標系距離計算
SELECT st_distance(st_transform(st_geometryfromtext('POINT(116.4677961543 39.9486461337)',4326),3857),st_transform(st_geometryfromtext('POINT(116.4680989087 39.9486998528)',4326),3857));
28 判斷點是在哪個多邊形里
select * from osm_buildings
where ST_Within(st_geomfromtext('point(103.76902131950 36.07270404286)',4326),geom);
29 獲取幾何對象的中心點ST_Centroid
select
st_astext(
ST_Centroid(ST_GeomFromText('MULTIPOLYGON(((116.3822484 39.9032743,110.3822732 39.9034939,110.3824074 36.9036869,110.3824074 36.9036869,116.3822484 39.9032743)))',4326))
)
30.提取面的邊界st_exteriorRing(geom)
Create table boundaries as
Select st_union(st_exteriorRing(geom)) as geom from circles;
-- st_exteriorRing提取面的邊界
31.st_polygonize根據線坐標自動構造面,首尾不閉合的線無法構面會舍棄
create table polys as select nextval('polyseq') as id,
(st_dump(st_polygonize(geom))).geom as geom from boundaries;
-- st_polygonize根據線坐標自動構造面,首尾不閉合的線無法構面會舍棄
32. 判斷幾何數據的有效性
select ST_IsValidDetail(geom),* from lzgd_dktb where ST_IsValid(geom) =false
33.設置geom字段的srid值
ALTER TABLE lzgd_dktb
ALTER COLUMN geom TYPE geometry(MULTIPOLYGON, 4490)
USING ST_SetSRID(geom,4490);
34.判斷幾何是否空:st_isempty(geom A)
35.修改幾何的srid
select UpdateGeometrySRID('t_gis','geom',4326);
36.計算指定范圍的緩沖區
//獲取geom 1000米的緩沖范圍
select st_buffer ( geom :: geography, 1000 ) from wp_dktb
37.postgis 的polygon轉為multiPloygon
SELECT ST_AsText(ST_Multi(ST_GeomFromText('POLYGON((743238 2967416,743238 2967450,743265 2967450,743265.625 2967416,743238 2967416))')));
38.圖形自相交檢查
select st_isvalidreason(geom),* from fnh.dktb where ST_IsValid(geom) = false limit 100
39.圖形簡單檢查
select * from fnh.dktb where ST_IsSimple(geom) =false
40.圖形組合檢查
select * from fnh.dktb where ST_IsSimple(geom) =false
41.壓占分析查詢
WITH g AS ( SELECT st_geomfromtext ( '{the_geom}', 4490 ) AS geom,st_area(st_geomfromtext('{the_geom}',4490),true) as ysarea )
SELECT s.*,(s.area/s.ysarea) as yzbl FROM( SELECT st_area ( ST_Intersection ( t.geom, g.geom ), TRUE ) AS area, t.glid, t.jzlb,g.ysarea FROM public.tb t, g WHERE ST_Intersects ( t.geom, g.geom ) ) s
42.將自相交圖形合法化(ST_MakeValid)
select ST_MakeValid(geom) from tb where is_valid(geom) = false
43.通過st_asgeojson獲取坐標信息
通過st_asgeojson 獲取圖斑的幾何信息時,默認小數位數只保留9位,會損失精度,所以一般設置保留14位小數位數
select st_asgeojson(geom,14) from public.tb
44.關于srid
若沒有設置srid,則會默認srid為0。 srid為0時,PostGIS無法獲知你數據的坐標系,也就無法使用st_transform()函數進行轉換。首先需要設置自己數據的srid
45.按距離排序
CREATE TABLE mylocation (
id SERIAL PRIMARY KEY,
geom GEOMETRY(Point, 4326),
name VARCHAR(128),
x double precision,
y double precision
);
INSERT INTO mylocation (geom,name,x,y) VALUES (
ST_GeomFromText('POINT(0.0001 0)', 4326),'zhangsan',0.0001,0
);
INSERT INTO mylocation (geom,name,x,y) VALUES (
ST_GeomFromText('POINT(0.001 0)', 4326),'zhangsan',0.001,0
);
INSERT INTO mylocation (geom,name,x,y) VALUES (
ST_GeomFromText('POINT(0.001 0)', 4326),'zhangsan',0.001,0
);
INSERT INTO mylocation (geom,name,x,y) VALUES (
ST_GeomFromText('POINT(0.1 0)', 4326),'zhangsan',0.1,0
);
--- 平面坐標查詢
SELECT id, name,geom,x,y, ST_DistanceSphere(
geom,
ST_GeometryFromText('POINT(0 0)')) distance
FROM mylocation
WHERE ST_DWithin(
geom,
ST_GeomFromText('POINT(0 0)', 4326),
0.001
經緯度坐標查詢
SELECT id, name,geom,x,y, ST_DistanceSphere(
geom,
ST_GeometryFromText('POINT(0 0)')) distance
FROM mylocation
WHERE ST_DWithin(
geom::geography,
ST_GeomFromText('POINT(0 0)', 4326)::geography,
1000
) ORDER BY distance asc