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 是否相交