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

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

CHG: Saving progress on MATLAB -> Python translations; cleanup

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