shapefile 数据导入及空间查询
导入数据
范例数据 包含纽约市的街道、地铁站等信息,路径: nyc_shapefile
使用 shp2pgsql导入数据
导入 nyc_census_blocks 数据
shp2pgsql \
-D \
-I \
-s 26918 \
nyc_census_blocks.shp \
nyc_census_blocks \
| gsql dbname=yukontutorial
其中:
-D: 使用dump format方式,这个要比默认的insert format快很多。-I: 加载数据完成后,为 geometry 类型的列创建一个索引-s: 数据的 srid 值。nyc_census_blocks.shp: 要加载的数据集nyc_census_blocks: 加载后在数据库中创建的表名gsql dbname=yukontutorial: 将数据导入到yukontutorial数据库中
当你看到有如下输出时,则说明数据导入成功
Field popn_total is an FTDouble with width 11 and precision 0
Field popn_white is an FTDouble with width 11 and precision 0
Field popn_black is an FTDouble with width 11 and precision 0
Field popn_nativ is an FTDouble with width 11 and precision 0
Field popn_asian is an FTDouble with width 11 and precision 0
Field popn_other is an FTDouble with width 11 and precision 0
Shapefile type: Polygon
Postgis type: MULTIPOLYGON[2]
SET
SET
BEGIN
NOTICE: CREATE TABLE will create implicit sequence "nyc_census_blocks_gid_seq" for serial column "nyc_census_blocks.gid"
CREATE TABLE
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "nyc_census_blocks_pkey" for table "nyc_census_blocks"
ALTER TABLE
addgeometrycolumn
--------------------------------------------------------------------
public.nyc_census_blocks.geom SRID:26918 TYPE:MULTIPOLYGON DIMS:2
(1 row)
CREATE INDEX
COMMIT
ANALYZE
然后重新连接到 yukontutorial 数据库,输入 \d 查看新创建的表:
yukontutorial=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+---------------------------+----------+-------+----------------------------------
public | geography_columns | view | omm |
public | geometry_columns | view | omm |
public | geomodel_columns | view | omm |
public | nyc_census_blocks | table | omm | {orientation=row,compression=no}
public | nyc_census_blocks_gid_seq | sequence | omm |
public | raster_columns | view | omm |
public | raster_overviews | view | omm |
public | spatial_ref_sys | table | omm | {orientation=row,compression=no}
(8 rows)
同理,依次导入剩余的数据集:
nyc_neighborhoods.shp
nyc_streets.shp
nyc_subway_stations.shp
你可能会好奇 .shp 文件到底是什么?
通常来说 shp 文件一般指的是 .shp, .shx,.dbf
还有一些其他类型文件且前缀名称一致的文件集合。shp 即 shape file
,通常单独的一个 shp
文件时没有什么用的,必须和其他类型的文件结合使用。
必要文件:
.shp:存储地理要素的几何信息.shx:存储要素几何图形的索引信息.dbf: 存储地理要素的属性信息(非几何信息)
可选文件:
.prj:存储空间参考信息,即地理坐标系统信息和投影坐标系统信息。使用 well-known 文本格式进行描述。
那 SRID 又是什么?
大多数导入过程都是不言自明的,但即使是经验丰富的 GIS 专业人员也可能被 SRID 难倒。
SRID 表示
Spatial Reference IDentifier(空间参考标识符)。它定义了我们数据的地理坐标系统和投影的所有参数。
SRID 很方便,因为它将有关地图投影的所有信息(可能非常复杂)打包(更具体的说应该是映射)到一个数字中。
你可以在以下链接中查找我们在上面使用的投影的定义:SRID
数据操作
我们想知道纽约市街道的总长度是多少应该怎么做?
select SUM(ST_LENGTH(GEOM)) from nyc_streets;
你可以看到如下输出:
yukontutorial=# select SUM(ST_LENGTH(GEOM)) from nyc_streets ;
sum
---------------
10418904.7172
(1 row)
这样我们就可以知道纽约市街道总长度为 10418904.7172m
ST_Length(geometry geom):如果 geom 的类型是 LineString 或者
MultiLineString,那么就返回这个 geometry 的长度。
sum:聚合函数,可以计算 nyc_streets 表中每一行 geometry
对象长度的总和。
我们想知道纽约市最西边的地铁站是哪一个?
select st_x(geom),name from nyc_subway_stations order by st_x(geom) limit 1;
输出结果:
yukontutorial=# select st_x(geom),name from nyc_subway_stations order by st_x(geom) limit 1;
st_x | name
------------------+-------------
563292.117258056 | Tottenville
(1 row)
ST_X(geometry a_point);: 如果 geometry 是一个点,则返回它的 x
坐标,否则返回 NULL。
现在我们知道位于纽约市最西边的地铁站是 Tottenville。
我们想知道距离 Broad St 地铁站 10m 范围内的街道有那些?
我们可以先查询一下 Broad St 地铁站的具体位置:
select st_astext(geom) from nyc_subway_stations where name='Broad St';
输出结果:
yukontutorial=# select st_astext(geom) from nyc_subway_stations where name='Broad St';
st_astext
------------------------------------------
POINT(583571.905921312 4506714.34119218)
(1 row)
现在我们知道了 Borad St 地铁站的具体地点为
POINT(583571.905921312 4506714.34119218),
接下来可以查询距离地铁站 10m 范围内的街道了。
SELECT name
FROM nyc_streets
WHERE ST_DWithin(
geom,
ST_GeomFromText('POINT(583571.905921312 4506714.34119218)',26918),
10
);
输出结果:
name
-----------
Wall St
Broad St
Nassau St
(3 rows)
现在我们可以知道距离 Broad St 地铁站 10m 内的街道有这 3 个。
ST_AsText(geometry g1): 返回 WKT 形式的 geometry 数据。
ST_GeomFromText(text WKT, integer srid); : 返回由 WKT 形式表示的
geometry 数据类型。同时指定它的 SRID。
ST_DWithin(geometry g1, geometry g2, double precision distance_of_srid)
: 如果 g1 和 g2 相距 distance_of_srid 之内,则返回真,否则返回假。
我们想知道纽约市人口密度最大的社区是哪一个?
SELECT
n.name,
Sum(c.popn_total) / (ST_Area(n.geom) / 1000000.0) AS popn_per_sqkm
FROM nyc_census_blocks AS c
JOIN nyc_neighborhoods AS n
ON ST_Intersects(c.geom, n.geom)
GROUP BY n.name, n.geom
ORDER BY 2 DESC limit 1;
输出结果:
name | popn_per_sqkm
-------------------+------------------
North Sutton Area | 68435.1328377268
(1 row)
从结果中我们可以看到 North Sutton Area 的人口密度是最大的。
ST_Intersects( geometry geomA , geometry geomB ): 返回 geomA 和
geomB 是否相交