创建一个新数据库来存储地理空间数据:
psql pglab -c "create database geodb"
创建扩展:
psql geodb -c "create extension postgis;"
psql geodb -c "create extension pgrouting;"
确保扩展程序安装正确:
psql geodb -c "select * from pg_available_extensions where name in ('postgis','pgrouting');"
shapefile 是指名称以 .shp、.shx、.dbf
结尾且具有公共前缀名称(例如 nyc_hotspots)的文件集合:
可选文件包括:
本节我们将:
NYC OpenData
平台下载 NYC 数据集。使用shp2pgsql
程序将 shapefile 转换为几何格式插入到 PostgreSQL/PostGIS
数据库的 SQL执行以下命令:
sudo yum -y install postgis curl
cd $HOME/environment
mkdir postgis && cd postgis
aws s3 cp s3://nyc-tlc/csv_backup/yellow_tripdata_2015-12.csv .
curl -L -o boros.zip https://data.cityofnewyork.us/api/geospatial/tqmj-j8zm?method=export\&format=Shapefile
unzip -o boros.zip -d boros
# `shp2pgsql`程序通过将形状数据从二进制数据转换为一系列 SQL 命令,然后在数据库中运行以加载数据,使形状数据可在 PostGIS 中使用。 `-s`标志告诉程序`spatial reference identifier (SRID)`数据是什么
shp2pgsql -c -D -s 4326-i -I boros/geo_export*.shp public.nyc_boros > nyc_boros.sql
curl -L -o subwaylines.zip https://data.cityofnewyork.us/api/geospatial/3qz8-muuu?method=export\&format=Shapefile
unzip -o subwaylines.zip -d subwaylines
shp2pgsql -c -D -s 4326 -i -I subwaylines/geo_export*.shp public.nyc_subwaylines > nyc_subwaylines.sql
curl -L -o nyc_subways.zip https://data.cityofnewyork.us/api/geospatial/arq3-7z49?method=export\&format=Shapefile
unzip -o nyc_subways.zip -d nyc_subways
shp2pgsql -c -D -s 4326 -i -I nyc_subways/geo_export*.shp public.nyc_subways > nyc_subways.sql
curl -L -o nyc_streets.zip https://data.cityofnewyork.us/api/geospatial/exjm-f27b?method=export\&format=Shapefile
unzip -o nyc_streets.zip -d nyc_streets
shp2pgsql -c -D -s 4326 -i -I nyc_streets/geo_export*shp public.nyc_streetlines > nyc_streetlines.sql
curl -L -o neighbor.zip https://data.cityofnewyork.us/api/geospatial/cpf4-rkhq?method=export\&format=Shapefile
unzip -o neighbor.zip -d neighbor
shp2pgsql -c -D -s 4326 -i -I neighbor/geo_export*.shp public.nyc_neighborhood > nyc_neighborhood.sql
curl -L -o nyc_hotspots.zip https://data.cityofnewyork.us/api/geospatial/a9we-mtpn?method=export\&format=Shapefile
unzip -o nyc_hotspots.zip -d nyc_hotspots
shp2pgsql -c -D -s 4326 -i -I nyc_hotspots/geo_export*.shp public.nyc_hotspots > nyc_hotspots.sql
我们可以使用Spatial Reference IDentifier (SRID)
shapefile 来查询在线数据库以获取地图的定义。SRID 很方便,因为它将有关地图投影(可能非常复杂)的所有信息打包到一个数字中。
可以通过在在线数据库查找来查看地图投影的定义,打开https://epsg.io/4326
或者直接在 PostGIS 数据库中对表spatial_ref_sys
进行查询:
psql geodb -c "select srtext from spatial_ref_sys where srid = 4326;"
在数据库中创建表trips
:
psql geodb
CREATE TABLE trips (
id serial primary key,
vendor_id text,
pickup_datetime timestamp without time zone,
dropoff_datetime timestamp without time zone,
passenger_count numeric,
trip_distance numeric,
pickup_longitude numeric,
pickup_latitude numeric,
rate_code text,
store_and_fwd_flag text,
dropoff_longitude numeric,
dropoff_latitude numeric,
payment_type text,
fare_amount numeric,
surcharge numeric,
mta_tax numeric,
tip_amount numeric,
tolls_amount numeric,
improvement_surcharge numeric,
total_amount numeric,
pickup_location geometry(Point, 4326),
dropoff_location geometry(Point, 4326)
);
\q
使用 shp2pgsql
命令生成的 sql 文件创建其他表:
psql geodb -f nyc_boros.sql
psql geodb -f nyc_subwaylines.sql
psql geodb -f nyc_subways.sql
psql geodb -f nyc_streetlines.sql
psql geodb -f nyc_neighborhood.sql
psql geodb -f nyc_hotspots.sql
使用COPY
命令将出租车行程数据加载到表中, 可能需要几分钟才能完成:
cd ~/environment/postgis
cat yellow_tripdata_2015-12.csv | psql geodb -c "COPY trips(vendor_id, pickup_datetime, dropoff_datetime, passenger_count, trip_distance, pickup_longitude, pickup_latitude, rate_code, store_and_fwd_flag, dropoff_longitude, dropoff_latitude, payment_type, fare_amount, surcharge, mta_tax, tip_amount, tolls_amount, improvement_surcharge, total_amount) FROM stdin CSV HEADER;"
目前所有经纬度数据均为NUMBER格式,需要转换为PostGIS Geometry以供进一步分析。以下命令将更新整个表, 可能需要几分钟才能完成:
psql geodb
update trips set pickup_location = ST_SetSRID(ST_MakePoint(pickup_longitude, pickup_latitude), 4326),
dropoff_location = ST_SetSRID(ST_MakePoint(dropoff_longitude, dropoff_latitude), 4326);
\q
在表trips
的列上创建索引dropoff_datetime
以加快搜索速度:
psql geodb
create index trips_dropoff_datetime on trips (date_trunc('day',dropoff_datetime));
\q
该nyc_streetlines
表加载了来自 geom 列的 MULTILINESTRING 数据。对于额外的路由计算,我们将添加额外的列, 以将 MULTILINESTRING
数据转换为 LINESTRING
数据
psql geodb
alter table nyc_streetlines add geomline geometry;
update nyc_streetlines set geomline = ST_LineMerge(geom);
\q
在表中创建拓扑nyc_streetlines
以绘制街道地图。pgRouting
扩展了 PostGIS/PostgreSQL 地理空间数据库以提供地理空间路由和其他分析功能。pgRouting 的 pgr_createTopology
功能提供了一种创建路由网络拓扑的方法:
psql geodb
ALTER TABLE nyc_streetlines ADD COLUMN source integer;
ALTER TABLE nyc_streetlines ADD COLUMN target integer;
CREATE INDEX nyc_streetlines_source_idx ON nyc_streetlines (source);
CREATE INDEX nyc_streetlines_target_idx ON nyc_streetlines (target);
SELECT pgr_createTopology('nyc_streetlines', 0.0001, 'geomline', 'gid');
\q
列出创建的所有表:
psql geodb -c "\dt"
在本节中我们下载了 shapefile,并使用 shp2pgsql 实用程序加载了 shapefile, 创建了多个表。