Skip to content

Commit ea85c4f

Browse files
author
Jeffrey Whitaker
committed
add new utility for processing GSHHS shapefiles.
1 parent 596d813 commit ea85c4f

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

utils/readboundaries_shp.py

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import numpy as np
2+
from mpl_toolkits.basemap.shapefile import Reader
3+
4+
lsd = 5
5+
6+
def quantize(data,least_significant_digit):
7+
"""
8+
9+
quantize data to improve compression. data is quantized using
10+
around(scale*data)/scale, where scale is 2**bits, and bits is determined
11+
from the least_significant_digit. For example, if
12+
least_significant_digit=1, bits will be 4.
13+
14+
This function is pure python.
15+
16+
"""
17+
precision = pow(10.,-least_significant_digit)
18+
exp = np.log10(precision)
19+
if exp < 0:
20+
exp = int(np.floor(exp))
21+
else:
22+
exp = int(np.ceil(exp))
23+
bits = np.ceil(np.log2(pow(10.,-exp)))
24+
scale = pow(2.,bits)
25+
return np.around(scale*data)/scale
26+
27+
def get_coast_polygons(resolution):
28+
polymeta = []; polybounds = []
29+
for level in [1,2,3,4]:
30+
filename = 'GSHHS_shp/%s/GSHHS_%s_L%s' % (resolution, resolution, level)
31+
#filename = 'WDBII_shp/%s/WDBII_border_%s_L%s' % (resolution, resolution, level)
32+
print filename
33+
shf = Reader(filename)
34+
fields = shf.fields
35+
try:
36+
shf.shapeRecords()
37+
except:
38+
continue
39+
for shprec in shf.shapeRecords():
40+
shp = shprec.shape; rec = shprec.record
41+
parts = shp.parts.tolist()
42+
if parts != [0]:
43+
print 'multipart polygon'
44+
raise SystemExit
45+
verts = shp.points
46+
lons, lats = list(zip(*verts))
47+
north = max(lats); south = min(lats)
48+
attdict={}
49+
for r,key in zip(rec,fields[1:]):
50+
attdict[key[0]]=r
51+
area = attdict['area']
52+
id = attdict['id']
53+
polymeta.append([level,area,south,north,len(lons),id])
54+
b = np.empty((len(lons),2),np.float32)
55+
b[:,0] = lons; b[:,1] = lats
56+
if lsd is not None:
57+
b = quantize(b,lsd)
58+
polybounds.append(b)
59+
return polybounds, polymeta
60+
61+
def get_wdb_boundaries(resolution,level,rivers=False):
62+
polymeta = []; polybounds = []
63+
if rivers:
64+
filename = 'WDBII_shp/%s/WDBII_river_%s_L%02i' % (resolution, resolution, level)
65+
else:
66+
filename = 'WDBII_shp/%s/WDBII_border_%s_L%s' % (resolution, resolution, level)
67+
print filename
68+
shf = Reader(filename)
69+
fields = shf.fields
70+
for shprec in shf.shapeRecords():
71+
shp = shprec.shape; rec = shprec.record
72+
parts = shp.parts.tolist()
73+
if parts != [0]:
74+
print 'multipart polygon'
75+
raise SystemExit
76+
verts = shp.points
77+
lons, lats = list(zip(*verts))
78+
north = max(lats); south = min(lats)
79+
attdict={}
80+
for r,key in zip(rec,fields[1:]):
81+
attdict[key[0]]=r
82+
area = -1
83+
id = attdict['id']
84+
polymeta.append([-1,-1,south,north,len(lons),id])
85+
b = np.empty((len(lons),2),np.float32)
86+
b[:,0] = lons; b[:,1] = lats
87+
if lsd is not None:
88+
b = quantize(b,lsd)
89+
polybounds.append(b)
90+
return polybounds, polymeta
91+
92+
# read in coastline data (only those polygons whose area > area_thresh).
93+
for resolution in ['c','l','i','h','f']:
94+
poly, polymeta = get_coast_polygons(resolution)
95+
f = open('gshhs_'+resolution+'.dat','wb')
96+
f2 = open('gshhsmeta_'+resolution+'.dat','w')
97+
offset = 0
98+
for p,pm in zip(poly,polymeta):
99+
typ = pm[0]; area = pm[1]; south = pm[2]; north = pm[3]; npts = pm[4]
100+
id = pm[5]
101+
bstring = p.tostring()
102+
f.write(bstring)
103+
f2.write('%s %s %s %9.5f %9.5f %s %s %s\n' % (typ, area, npts, south,\
104+
north, offset, len(bstring),id))
105+
offset = offset + len(bstring)
106+
f.close()
107+
f2.close()
108+
raise SystemExit
109+
110+
for resolution in ['c','l','i','h','f']:
111+
poly, polymeta = get_wdb_boundaries(resolution,1)
112+
f = open('countries_'+resolution+'.dat','wb')
113+
f2 = open('countriesmeta_'+resolution+'.dat','w')
114+
offset = 0
115+
for p,pm in zip(poly,polymeta):
116+
typ = pm[0]; area = pm[1]; south = pm[2]; north = pm[3]; npts = pm[4]
117+
id = pm[5]
118+
bstring = p.tostring()
119+
f.write(bstring)
120+
f2.write('%s %s %s %9.5f %9.5f %s %s %s\n' % (typ, area, npts, south,\
121+
north, offset, len(bstring),id))
122+
offset = offset + len(bstring)
123+
f.close()
124+
f2.close()
125+
126+
for resolution in ['c','l','i','h','f']:
127+
poly, polymeta = get_wdb_boundaries(resolution,2)
128+
f = open('states_'+resolution+'.dat','wb')
129+
f2 = open('statesmeta_'+resolution+'.dat','w')
130+
offset = 0
131+
for p,pm in zip(poly,polymeta):
132+
typ = pm[0]; area = pm[1]; south = pm[2]; north = pm[3]; npts = pm[4]
133+
id = pm[5]
134+
bstring = p.tostring()
135+
f.write(bstring)
136+
f2.write('%s %s %s %9.5f %9.5f %s %s %s\n' % (typ, area, npts, south,\
137+
north, offset, len(bstring),id))
138+
offset = offset + len(bstring)
139+
f.close()
140+
f2.close()
141+
142+
for resolution in ['c','l','i','h','f']:
143+
f = open('rivers_'+resolution+'.dat','wb')
144+
f2 = open('riversmeta_'+resolution+'.dat','w')
145+
for level in range(1,12):
146+
poly, polymeta = get_wdb_boundaries(resolution,level,rivers=True)
147+
offset = 0
148+
for p,pm in zip(poly,polymeta):
149+
typ = pm[0]; area = pm[1]; south = pm[2]; north = pm[3]; npts = pm[4]
150+
id = pm[5]
151+
bstring = p.tostring()
152+
f.write(bstring)
153+
f2.write('%s %s %s %9.5f %9.5f %s %s %s\n' % (typ, area, npts, south,\
154+
north, offset, len(bstring),id))
155+
offset = offset + len(bstring)
156+
f.close()
157+
f2.close()

0 commit comments

Comments
 (0)