source: issm/trunk-jpl/src/m/shp/shpread.py@ 25065

Last change on this file since 25065 was 25065, checked in by jdquinn, 5 years ago

CHG: Saving progress on SLR/Solid Earth translation

File size: 4.8 KB
Line 
1from os import path
2try:
3 import shapefile
4except ImportError:
5 print("could not import shapefile, PyShp has not been installed, no shapefile reading capabilities enabled")
6
7from pairoptions import pairoptions
8
9
10def shpread(filename, *args): #{{{
11 '''
12 SHPREAD - read a shape file and build a dict
13
14 This routine reads a shape file .shp and builds a dict array containing the
15 fields x and y corresponding to the coordinates, one for the filename
16 of the shp file, for the density, for the nodes, and a field closed to
17 indicate if the domain is closed. If this initial shapefile is point only,
18 the fields closed and points are ommited.
19 The first argument is the .shp file to be read and the second one
20 (optional) indicates if the last point shall be read (1 to read it, 0 not
21 to).
22
23 The current implementation of shpread depends on PyShp.
24
25 Usage:
26 dict = shpread(filename)
27
28 Example:
29 From underling PyShp implementation, "The shapefile format is actually
30 a collection of three files. You specify the base filename of the
31 shapefile or the complete filename of any of the shapefile component
32 files.""
33
34 dict = shpread('domainoutline.shp')
35 OR
36 dict = shpread('domainoutline.dbf')
37 OR
38 dict = shpread('domainoutline')
39
40 "OR any of the other 5+ formats which are potentially part of a
41 shapefile. The library does not care about file extensions". We do,
42 however, check that a file with the base filename or base filename with
43 .shp extension exists.
44
45 See also EXPDOC, EXPWRITEASVERTICES
46
47 Sources:
48 - https://github.com/GeospatialPython/pyshp
49 '''
50
51 #recover options
52 options = pairoptions(*args)
53
54 #some checks
55 if not (path.isfile(filename) or path.isfile(filename + '.shp')):
56 raise RuntimeError('shpread error message: file {} or {}.shp not found!'.format(filename, filename))
57
58 #read shapefile
59 sf = shapefile.Reader(filename)
60
61 Dicts = []
62
63 #retrieve ID (if it exists)
64 fields = sf.fields
65 for i in range(1, len(fields)): # skip over first field, which is "DeletionFlag"
66 if fields[i][0] == 'id':
67 name = str(sf.record(i - 1)[0]) # record index is offset by one, again, because of "DeletionFlag"
68 break
69
70 shapes = sf.shapes()
71 for i in range(len(shapes)):
72 Dict = {}
73 shape = shapes[i]
74 if shape.shapeType == shapefile.POINT:
75 Dict['x'] = shape.points[0][0]
76 Dict['y'] = shape.points[0][1]
77 Dict['density'] = 1
78 Dict['Geometry'] = 'Point'
79 elif shape.shapeType == shapefile.POLYLINE:
80 num_points = len(shape.points)
81 x = []
82 y = []
83 for j in range(num_points):
84 point = shape.points[j]
85 x.append(point[0])
86 y.append(point[1])
87 Dict['x'] = x
88 Dict['y'] = y
89 Dict['nods'] = num_points
90 Dict['density'] = 1
91 Dict['closed'] = 1
92 Dict['BoundingBox'] = shape.bbox
93 Dict['Geometry'] = 'Line'
94 elif shape.shapeType == shapefile.POLYGON:
95 num_points = len(shape.points)
96 x = []
97 y = []
98 for j in range(num_points):
99 point = shape.points[j]
100 x.append(point[0])
101 y.append(point[1])
102 Dict['x'] = x
103 Dict['y'] = y
104 Dict['nods'] = num_points
105 Dict['density'] = 1
106 Dict['closed'] = 1
107 Dict['BoundingBox'] = shape.bbox
108 Dict['Geometry'] = 'Polygon'
109 else:
110 # NOTE: We could do this once before looping over shapes as all
111 # shapes in the file must be of the same type, but we would
112 # need to have a second check anyway in order to know how to
113 # parse the points. So, let's just assume the file is not
114 # malformed.
115 #
116 raise Exception('shpread error: geometry {} is not currently supported'.format(shape.shapeTypeName))
117 name = ''
118 fields = sf.fields
119 for j in range(1, len(fields)): # skip over first field, which is "DeletionFlag"
120 fieldname = fields[j][0]
121 # 'id' field gets special treatment
122 if fieldname == 'id':
123 name = str(sf.record(j - 1)[0]) # record index is offset by one, again, because of "DeletionFlag"
124 else:
125 Dict[fieldname] = sf.record(j - 1)[0]
126 Dict['name'] = name
127 Dicts.append(Dict)
128
129 invert = options.getfieldvalue('invert', 0)
130 if invert:
131 for i in range(len(Dicts)):
132 Dicts[i].x = np.flipud(Dicts[i].x)
133 Dicts[i].y = np.flipud(Dicts[i].y)
134
135 return Dicts
136#}}}
Note: See TracBrowser for help on using the repository browser.