-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeog585_ch03.py
131 lines (102 loc) · 4.06 KB
/
geog585_ch03.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# Trim the Philadelphia Base Layers shapefiles to the clipFeature/city_limits geometry,
# reproject the shapefile geometry from EPSG:4326 to EPSG:3857 and load resulting
# layers into PostGIS tables in the geog585 schema.
import ogr, osr
import os
from glob import glob
ogr.UseExceptions()
# PostGIS geometry type modifiers.
def postgis_geom_type(type):
return 'Geometry' if type == 0 else ogr.GeometryTypeToName(type).replace(' ', '')
src_dir = '../../Mapping/geog585/ch03/PhiladelphiaBaseLayers'
src_srid = 4326
dest_schema = 'geog585'
dest_srid = 3857
trim_shapefile = 'clipFeature/city_limits.shp'
DSN = 'PG: host=localhost dbname=postgis_scratch user=postgres password=pg'
# SRS transform to project geometry: 4326 -> 3857
src_srs = osr.SpatialReference()
src_srs.ImportFromEPSG(src_srid)
dest_srs = osr.SpatialReference()
dest_srs.ImportFromEPSG(dest_srid)
srsTransform = osr.CoordinateTransformation(src_srs, dest_srs)
# Open a connection to PostgreSQL.
destDS = ogr.Open(DSN, 1)
# Driver for reading source shapefiles.
srcDriver = ogr.GetDriverByName('ESRI Shapefile')
os.chdir(src_dir)
# Get trim geometry.
trimDS = srcDriver.Open(trim_shapefile, 0)
trimLayer = trimDS.GetLayer()
trimFeature = trimLayer.GetFeature(0)
trimGeom = trimFeature.GetGeometryRef()
for shapefile in glob('*.shp'):
srcDS = srcDriver.Open(shapefile, 0)
srcLayer = srcDS.GetLayer()
srcLayer.SetSpatialFilter(trimGeom)
layer_name = srcLayer.GetName()
geom_type = postgis_geom_type(srcLayer.GetGeomType())
feature_count = srcLayer.GetFeatureCount()
print('{0}: {1} count = {2}'.format(layer_name, geom_type, feature_count))
# Common layer format.
qstr = """
DROP TABLE IF EXISTS {schema}.{layer};
CREATE TABLE {schema}.{layer} (
gid serial NOT NULL,
osm_id bigint,
name character varying(48),
type character varying(48),
geom geometry({geom_type}, {srid}),
CONSTRAINT {layer}_pkey PRIMARY KEY (gid))
WITH (OIDS=FALSE);
""".format(schema=dest_schema, layer=layer_name, geom_type=geom_type, srid=dest_srid)
# Special processing for specific layers.
if layer_name == 'roads':
qstr += """
ALTER TABLE {schema}.{layer}
ADD COLUMN ref character varying(48),
ADD COLUMN oneway integer,
ADD COLUMN bridge integer,
ALTER COLUMN geom SET DATA TYPE geometry(MultiLineString, {srid});
""".format(schema=dest_schema, layer=layer_name, srid=dest_srid)
elif layer_name == 'places':
qstr += """
ALTER TABLE {schema}.{layer}
ADD COLUMN population integer;
""".format(schema=dest_schema, layer=layer_name)
elif layer_name == 'waterways':
qstr += """
ALTER TABLE {schema}.{layer}
ADD COLUMN width integer;
""".format(schema=dest_schema, layer=layer_name)
destDS.ExecuteSQL(qstr)
destLayer = destDS.GetLayerByName(dest_schema + '.' + layer_name)
destFeatureDefn = destLayer.GetLayerDefn()
for srcFeature in srcLayer:
destFeature = ogr.Feature(destFeatureDefn)
# Common fields for all layers.
field_names = ['osm_id', 'name', 'type']
# Extra fields for specific layers.
if layer_name == 'roads':
field_names += ['ref', 'oneway', 'bridge']
elif layer_name == 'waterways':
field_names += ['width']
elif layer_name == 'places':
field_names += ['population']
for field in field_names:
destFeature.SetField(field, srcFeature.GetField(field))
geom = srcFeature.GetGeometryRef()
geom.Transform(srsTransform)
# Convert road geometry to MultiLineString.
if layer_name == 'roads':
geom = ogr.ForceToMultiLineString(geom)
destFeature.SetGeometry(geom)
destLayer.CreateFeature(destFeature)
# Change road columns 'oneway' and 'bridge' to boolean.
qstr = """
ALTER TABLE {schema}.roads
ALTER oneway TYPE boolean USING oneway::boolean,
ALTER bridge TYPE boolean USING bridge::boolean;
""".format(schema=dest_schema)
destDS.ExecuteSQL(qstr)
destDS = None