shapelib 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/doc/Interface.rd ADDED
@@ -0,0 +1,498 @@
1
+ =begin
2
+ = module ShapeLib
3
+
4
+ This module is a wrapper of C Shapefile Library
5
+ (also called ((<ShapeLib|URL:http://shapelib.maptools.org/>))).
6
+ It consists of basically two classes:
7
+ ((<ShapeFile|class ShapeFile>)) and ((<Shape|class Shape>)).
8
+ If you are unfamiliar with object-oriented programming,
9
+ please see ((<Appendix A: C to Ruby equivalence table>)).
10
+
11
+ A extension library (({shapelib})) must be required before using this module:
12
+
13
+ require 'shapelib'
14
+
15
+ == module functions
16
+ Following three functions construct a point object.
17
+ It can be used like top level function after (({include})):
18
+
19
+ include ShapeLib
20
+ pt = new_point(1, 2)
21
+
22
+ Arguments ((|x|)), ((|y|)), ((|z|)), and ((|m|)) ((<should be Float>)).
23
+
24
+ --- ShapeLib.new_point x, y
25
+ creates a ((<class Point>)) object.
26
+ --- ShapeLib.new_point x, y, m
27
+ creates a ((<class PointM>)) object.
28
+ --- ShapeLib.new_point x, y, m, z
29
+ creates a ((<class PointZ>)) object.
30
+
31
+ == class ShapeFile
32
+ === class methods
33
+ Following two class methods (({new})) and (({open}))
34
+ return an instance of ((<class ShapeFile>)) if succeeded.
35
+ Exception is raised on failure.
36
+ It is recommended to call ((<shapefile.close>))
37
+ when each shapefile is no longer used.
38
+
39
+ --- ShapeFile::open filename, access = 'rb'
40
+ --- ShapeFile::open(filename, access = 'rb') { |fp| ... }
41
+ The (({open})) method opens an existing shapefile.
42
+
43
+ Argument ((|filename|)) should be
44
+ either fullname (like "(({basename.shp}))")
45
+ or just basename (like "(({basename}))").
46
+ Suffix (({.shp})) must be lowercase if specified.
47
+ Both (({.shp})) and (({.shx})) files must exist at the specified path.
48
+
49
+ Argument ((|access|)) are passed to (({fopen(3)})) through
50
+ ((<ShapeLib>)) (({SHPOpen()})) function.
51
+ Either '(({rb}))' or '(({rb+}))' should be used.
52
+
53
+ If a block is given to these constructors,
54
+ the opened shapefile object is yielded like File::open.
55
+ The shapefile is closed at the end of block,
56
+ and the constructor returns (({nil})).
57
+
58
+ # example
59
+ ShapeLib::ShapeFile.open(filename) { |fp|
60
+ print "#{filename} has #{fp.size} records.\n"
61
+ }
62
+
63
+ --- ShapeFile::new filename, shapetype, attrs
64
+ --- ShapeFile::new(filename, shapetype, attrs) { |fp| ... }
65
+ The (({new})) method creates a shapefile.
66
+ All three files ((({.shp})), (({.shx})), and (({.dbf}))) are created.
67
+ Argument ((|shapetype|)) specifies the ((<type of shapes>))
68
+ to be stored in the shapefile.
69
+ Argument ((|attrs|)) is an array of arrays
70
+ that specifies ((|field_name|)), ((|field_type|)), ((|width|)),
71
+ and optional ((|decimal|)) as in
72
+ ((<shapefile.add_field|shapefile.add_field field_name, field_type, width, decimal = 0>))
73
+ .
74
+
75
+ # example
76
+ fp = ShapeFile::new('city.shp', :Point,
77
+ [['name', :String, 32],
78
+ ['population', :Integer, 9],
79
+ ['height', :Float, 9, 1]])
80
+
81
+ === instance methods
82
+
83
+ --- shapefile.add_field field_name, field_type, width, decimal = 0
84
+ Adds an attribute field to the shapefile (that must be newly created by
85
+ ((<ShapeFile::new|ShapeFile::new filename, shapetype, attrs>))).
86
+ Argument ((|field_name|)) is a String for field name;
87
+ ((|field_type|)) specifies ((<field type>));
88
+ ((|width|)) is nonnegative Integer for field width in characters; and
89
+ ((|decimal|)) is nonnegative Integer for decimal points.
90
+ Only Float field requires ((|decimal|)); otherwise it can be missing.
91
+
92
+ # example
93
+ fp.add_field 'name', :String, 32
94
+ fp.add_field 'height', "Float", 9, 1
95
+
96
+ --- shapefile.each { |shape| ... }
97
+ yields all shapes in the shapefile.
98
+ Equivalent to the following code:
99
+
100
+ shapefile.rewind
101
+ while shape = shapefile.read
102
+ ...
103
+ end
104
+
105
+ --- shapefile.field_count
106
+ returns the number of attribute fields made on the DBF file.
107
+
108
+ --- shapefile.field_decimals field
109
+ returns the width of the ((<attribute field>)).
110
+ Zero is returned for non-Float fields.
111
+
112
+ --- shapefile.field_index name
113
+ returns the index of the attribute field matching ((|name|)), or nil on failure.
114
+
115
+ --- shapefile.field_name index
116
+ returns the name of the attribute field with ((|index|)), or nil on failure.
117
+
118
+ --- shapefile.field_type field
119
+ returns the type of the ((<attribute field>)).
120
+ The result is Symbol
121
+ (one of :String, :Integer, :Float, :Logical, or :Invalid)
122
+ or nil on failure.
123
+
124
+ --- shapefile.field_width field
125
+ returns the width of the ((<attribute field>)).
126
+
127
+ --- shapefile.fields
128
+ returns an Array containing a list of attribute field name.
129
+
130
+ --- shapefile.maxbound
131
+ returns the maximum values for x, y, m, z coordinates.
132
+ Note: the order is M then Z, not Z then M.
133
+
134
+ --- shapefile.minbound
135
+ returns the minimum values for x, y, m, z coordinates.
136
+
137
+ --- shapefile.read rec = -1
138
+ reads the shape/record ((|rec|)) from shapefile.
139
+ If ((|rec|)) is missing,
140
+ the next record to previously read one
141
+ (or the first record #0 for the first time) is used.
142
+ An instance of ((<class Shape>)) is returned,
143
+ including all attributes written on the DBF.
144
+ On error (({nil})) is returned.
145
+
146
+ --- shapefile.rewind
147
+ After that, ((<shapefile.read|shapefile.read rec = -1>))
148
+ without argument will return the first shape/record of the shapefile.
149
+
150
+ --- shapefile.shape_type
151
+ returns the type of shape by Symbol.
152
+
153
+ --- shapefile.size
154
+ returns the number of records (or shapes) in the shapefile.
155
+ ((-If DBF file has different number of records,
156
+ warning message is shown in $VERBOSE mode.-))
157
+
158
+ --- shapefile.write shape, rec = nil
159
+ writes ((|shape|)) into shapefile at record number ((|rec|)).
160
+ The ((|shape|)) must be a instance of ((<class Shape>)) or subclass.
161
+ Attributes attached to ((|shape|)) are stored into DBF file.
162
+ If ((|rec|)) is missing, the record is appended at the end of shapefile.
163
+
164
+ --- shapefile.close
165
+ The (({close})) method flushes all information
166
+ into the shapefile and release related resources.
167
+ After that the instance cannot be used.
168
+
169
+ It is recommended to call it at the end of processing
170
+ to reduce the risk of trouble,
171
+ although it is called automatically
172
+ at the time of garbage collecting or at the end of interpreter.
173
+
174
+ == class Shape
175
+ Shape consists of a geometric shape (written in SHP file)
176
+ and attributes attached to the shape (written in DBF file).
177
+ Instance of these subclasses are obtained from
178
+ ((<ShapeFile#read|shapefile.read rec = -1>))
179
+ or constructor like ((<Point::new|class Point>)).
180
+
181
+ Every instance of the class Shape belongs to one of subclasses,
182
+ depending on the type of shape.
183
+
184
+ === structure of subclasses
185
+
186
+ * ((<class Shape>))
187
+ * ((<class Point>))
188
+ * ((<class PointM>))
189
+ * ((<class PointZ>))
190
+ * ((<class Arc>))
191
+ * ((<class ArcM>))
192
+ * ((<class ArcZ>))
193
+ * ((<class Polygon>))
194
+ * ((<class PolygonM>))
195
+ * ((<class PolygonZ>))
196
+ * ((<class MultiPoint>))
197
+ * ((<class MultiPointM>))
198
+ * ((<class MultiPointZ>))
199
+ * ((<class MultiPatch>))
200
+
201
+ === class method
202
+ --- Shape::new hash
203
+ Argument ((|hash|)) is a hash (or ((<something behaves like a hash>)))
204
+ that contains the attributes of the shape.
205
+ Hash returned by ((<shape.to_h>)) can be used as ((|hash|)).
206
+
207
+ === instance methods
208
+ --- shape [field]
209
+ value of the ((<attribute|attribute field>)) ((|field|))
210
+ related to the shape.
211
+ --- shape [field] = value
212
+ sets ((<attribute|attribute field>)) ((|field|)) to ((|value|)).
213
+ --- shape.inspect
214
+ currently similar to ((<shape.to_h>))(({.to_s})).
215
+ --- shape.maxbound
216
+ returns the maximum values for x, y, m, z coordinates.
217
+ Note: the order is M then Z, not Z then M.
218
+ --- shape.minbound
219
+ returns the minimum values for x, y, m, z coordinates.
220
+ --- shape.part_start
221
+ returns an array of Integer that indicates beginning offset
222
+ for each part in ((<shape.xvals>)) etc.
223
+ --- shape.part_type
224
+ returns an array containing ((<part type>)) by Symbol.
225
+ Point or multipoint returns (({nil})).
226
+ --- shape.rewind_polygon
227
+ "This function will reverse any rings necessary
228
+ in order to enforce the shapefile restrictions
229
+ on the required order of inner and outer rings
230
+ in the Shapefile specification.
231
+ It returns (({true})) if a change is made and
232
+ (({false})) if no change is made.
233
+ Only polygon objects will be affected though any object may be passed."
234
+ ((-taken from ((<ShapeLib>)) document.-))
235
+ --- shape.shape_id
236
+ returns the number of record by which the shape is read from a shapefile.
237
+ Nil is returned if the shape is not read from file.
238
+
239
+ --- shape.shape_type
240
+ returns the ((<type of shape|type of shapes>)) by Symbol.
241
+
242
+ --- shape.to_h
243
+ returns a hash that contains all attributes and geometry information.
244
+ Each attribute have a key of String,
245
+ while geometry information has keys of Symbol.
246
+ pt = ShapeLib::Point::new(1, 2, 'name' => 'Madison')
247
+ pt.to_h => {"name"=>"Madison", :zvals=>[0.0], :n_parts=>0,
248
+ :n_vertices=>1, :maxbound=>[1.0, 2.0, 0.0, 0.0],
249
+ :part_start=>nil, :part_type=>nil, :xvals=>[1.0],
250
+ :minbound=>[1.0, 2.0, 0.0, 0.0], :shape_type=>:Point,
251
+ :yvals=>[2.0], :mvals=>[0.0], :shape_id=>nil}
252
+
253
+ --- shape.to_s
254
+ current implementation is identical to ((<shape.wkt>)).
255
+ Note that this lose information.
256
+
257
+ --- shape.wkt
258
+ returns WKT (well known text) representation of geometry
259
+ as defined in ((<ISO 19125-1>)).
260
+ ((*Caution: current implementation does not always handle Polygon[MZ] and MultiPatch correctly.*))
261
+
262
+ ShapeLib::Arc.new([1, 2], [3, 4], [5, 6]).wkt
263
+ => "LINESTRING(1 2, 3 4, 5 6)"
264
+ ShapeLib::Arc.new([[1, 2], [3, 4]], [[5, 6], [7, 8]]).wkt
265
+ => "MULTILINESTRING((1 2, 3 4), (5 6, 7 8))"
266
+
267
+ --- shape.xvals
268
+ returns an array of x values.
269
+
270
+ ShapeLib::Arc.new([1, 2], [3, 4], [5, 6]).xvals
271
+ => [1.0, 3.0, 5.0]
272
+
273
+ Multipart shape results flattened array (all parts joined).
274
+
275
+ ShapeLib::Arc.new([[1, 2], [3, 4]], [[5, 6], [7, 8]]).xvals
276
+ => [1.0, 3.0, 5.0, 7.0]
277
+
278
+ --- shape.yvals
279
+ returns an array of y values.
280
+
281
+ ShapeLib::Arc.new([1, 2], [3, 4], [5, 6]).xvals
282
+ => [2.0, 4.0, 6.0]
283
+
284
+ --- shape.mvals
285
+ returns an array of m values. Nil is returned for missing value.
286
+
287
+ ShapeLib::Arc.new([1, 2], [3, 4], [5, 6]).mvals
288
+ => [nil, nil, nil]
289
+ ShapeLib::ArcM.new([1, 2, 3], [4, 5, 6], [7, 8, 9]).mvals
290
+ => [3, 6, 9]
291
+
292
+ --- shape.zvals
293
+ returns an array of z values.
294
+
295
+ == class Point
296
+
297
+ Point is a geometric point that has two coordinates x and y.
298
+
299
+ --- Point::new x, y, attrs = {}
300
+ creates a new point instance with coordinates ((|x|)) and ((|y|))
301
+ (both are converted to Float).
302
+ Optional argument ((|attrs|)) is a hash containing attributes
303
+ such as (({{"key1"=>value1, "key2"=>value2, ...}})).
304
+ --- point.x
305
+ returns a Float x value.
306
+ --- point.y
307
+ returns a Float y value.
308
+ --- point.m
309
+ returns a Float m (height) value.
310
+ --- point.z
311
+ returns a Float z (elevation) value.
312
+
313
+ == class PointM
314
+ Point is a geometric point that has three coordinates x, y and m.
315
+ --- PointM::new x, y, m, attrs = {}
316
+
317
+ == class PointZ
318
+ Point is a geometric point that has four coordinates x, y, m and z.
319
+ --- PointZ::new x, y, m, z, attrs = {}
320
+
321
+ == class Arc
322
+ Arc is consists of a set of (two or more) points.
323
+ Each point has two coordinates x and y.
324
+ It is also called polyline.
325
+
326
+ --- Arc::new point, point, ...
327
+ Constructs a single arc.
328
+ ((|point|)) is array of numerals, or ((<class Point>)).
329
+
330
+ --- Arc::new [point, point, ...], [point, point, ...], ...
331
+ Constructs a multipart arc that represents two disconnected polyline.
332
+
333
+ == class ArcM
334
+ ArcM is similar to Arc, but points also have m (measure) coordinates.
335
+
336
+ == class ArcZ
337
+ ArcZ is similar to ArcM, but points also have z coordinates.
338
+
339
+ == class Polygon
340
+ Polygon is one (or more) closed arc.
341
+ --- Polygon::new point, point, ...
342
+ Constructs a object with single polygon.
343
+ --- Polygon::new [point, point, ...], [point, point, ...], ...
344
+ Constructs a object with multiple polygons.
345
+
346
+ == class PolygonM
347
+ PolygonM is similar to Polygon, but points also have m (measure) coordinates.
348
+
349
+ == class PolygonZ
350
+ PolygonZ is similar to PolygonM, but points also have z coordinates.
351
+
352
+ == class MultiPoint
353
+ MultiPoint is a set of points.
354
+ --- MultiPoint::new point, point, ...
355
+ --- MultiPoint::new [point, point, ...]
356
+ Above two are the same.
357
+
358
+ == class MultiPointM
359
+ MultiPointM is similar to MultiPoint, but points also have m (measure) coordinates.
360
+
361
+ == class MultiPointZ
362
+ MultiPointZ is similar to MultiPointM, but points also have z coordinates.
363
+
364
+ == class MultiPatch
365
+ --- MultiPatch::new [part_type, point, point, ...], [part_type, point, ...], ...
366
+ Constructs a MultiPatch object.
367
+ Note that the first element of each array must be ((<part type>)).
368
+
369
+ == constants
370
+ === Field Type Constants
371
+ --- ShapeLib::String
372
+ --- ShapeLib::Integer
373
+ --- ShapeLib::Float
374
+
375
+ == Appendix A: C to Ruby equivalence table
376
+ * DBFHandle:
377
+ ((<class ShapeFile>)) contains DBFHandle.
378
+ * SHPHandle:
379
+ ((<class ShapeFile>)) contains SHPHandle.
380
+ * SHPObject:
381
+ ((<class Shape>)) contains SHPObject and attributes stored in DBF.
382
+ Access to members of the structure can be translated using ((<shape.to_h>)).
383
+ * SHPOpen():
384
+ called in ((<ShapeFile::open|ShapeFile::open filename, access = 'rb'>))
385
+ * SHPGetInfo():
386
+ ((<shapefile.size>)),
387
+ ((<shapefile.shape_type>)),
388
+ ((<shapefile.minbound>)), and
389
+ ((<shapefile.maxbound>)).
390
+ * SHPReadObject():
391
+ ((<shapefile.read|shapefile.read rec = -1>))
392
+ * SHPClose():
393
+ ((<shapefile.close>))
394
+ * SHPCreate():
395
+ called in ((<ShapeFile::new|ShapeFile::new filename, shapetype, attrs>))
396
+ * SHPCreateSimpleObject() and SHPCreateObject():
397
+ ((<Shape::new|Shape::new hash>)) and (({new})) method of its subclasses
398
+ * SHPComputeExtents():
399
+ there is no need to call it, since the current version of
400
+ ruby-shapelib does not allow users to change geometry of a shape
401
+ once it is created.
402
+ * SHPWriteObject():
403
+ ((<shapefile.write|shapefile.write shape, rec = nil>))
404
+ * SHPDestroyObject():
405
+ called automatically while the ruby interpreter does garbage collection.
406
+ * SHPRewindObject():
407
+ ((<shape.rewind_polygon>))
408
+ * DBFOpen():
409
+ called in ((<ShapeFile::open|ShapeFile::open filename, access = 'rb'>))
410
+ * DBFCreate():
411
+ called in ((<ShapeFile::new|ShapeFile::new filename, shapetype, attrs>))
412
+ * DBFGetFieldCount():
413
+ ((<shapefile.field_count>))
414
+ * DBFGetRecordCount():
415
+ There is no need to call it if shapefile is properly created,
416
+ i.e. *.SHP and *.DBF files have the same number of records.
417
+ See also ((<shapefile.size>)).
418
+ * DBFGetFieldIndex():
419
+ ((<shapefile.field_index|shapefile.field_index name>))
420
+ * DBFGetFieldInfo():
421
+ ((<shapefile.field_decimals|shapefile.field_decimals field>)),
422
+ ((<shapefile.field_name|shapefile.field_name index>)),
423
+ ((<shapefile.field_type|shapefile.field_type field>)), and
424
+ ((<shapefile.field_width|shapefile.field_width field>))
425
+ * DBFAddField():
426
+ ((<shapefile.add_field|shapefile.add_field field_name, field_type, width, decimal = 0>))
427
+ * DBFReadIntegerAttribute(), DBFReadDoubleAttribute(), and
428
+ DBFReadStringAttribute():
429
+ ((<shape [field]>))
430
+ * DBFIsAttributeNULL():
431
+ called in ((<shape [field]>)).
432
+ Nil is returned if the attribute is null.
433
+ * DBFWriteIntegerAttribute(), DBFWriteDoubleAttribute(), and
434
+ DBFWriteStringAttribute():
435
+ ((<shape [field] = value>))
436
+ * DBFWriteNULLAttribute():
437
+ called if (({nil})) is given to ((<shape [field] = value>)).
438
+ * DBFGetNativeFieldType():
439
+ not implemented in ruby-shapelib.
440
+ Does anyone know how to interpret the return value properly?
441
+
442
+ == Appendix B: Flexible argument
443
+ Some method arguments take various objects for convenience.
444
+ This appendix discusses the detail of acceptable value.
445
+
446
+ : should be Float
447
+ Any object that respond to (({to_f})) is converted to Float.
448
+ String is not acceptable.
449
+ (({nil})) is treated as -2e-38 (NODATA) for ((|m|)) (measure) coordinate,
450
+ or as 0.0 otherwise.
451
+
452
+ : type of shapes
453
+ For ((<ShapeFile::new|ShapeFile::new filename, shapetype, attrs>))
454
+ and ((<Shape::new|Shape::new hash>)),
455
+ acceptable values for ((|shapetype|)) are:
456
+ * Class object like ShapeLib::Point (listed in ((<structure of subclasses>)))
457
+ * String such as (({"Point"})) or (({"PolygonZ"}))
458
+ (the same list, but do not include "ShapeLib::")
459
+ * Symbol such as (({:Point})) or (({:PolygonZ}))
460
+ (result of ((<shapefile.shape_type>)) and ((<shape.shape_type>))),
461
+ or
462
+ * Integer code
463
+ (please see ((<ESRI Whitepaper>)))
464
+
465
+ : field type
466
+ For ((<shapefile.add_field|shapefile.add_field field_name, field_type, width, decimal = 0>)),
467
+ acceptable values for ((|field_type|)) are:
468
+ * String "String", "Integer", or "Float", or
469
+ * Symbol :String, :Integer, or :Float
470
+ (result of ((<shapefile.field_type|shapefile.field_type field>))).
471
+ * Integer constants listed ((<above|Field Type Constants>)).
472
+
473
+ : part type
474
+ acceptable values are
475
+ * String "TriangleStrip", "TriangleFan", "OuterRing", "InnerRing",
476
+ "FirstRing", or "Ring"
477
+ * corresponding Symbol :TriangleStrip etc.
478
+
479
+ : attribute field
480
+ For many shapefile methods like ((<shapefile.field_type field>)),
481
+ both String name and Integer index are acceptable.
482
+
483
+ : something behaves like a hash
484
+ For ((<Shape::new hash>)), the argument ((|hash|))
485
+ * must respond to [((|key|))] method with a Symbol as a ((|key|))
486
+ * should respond to (({to_a})) method, so that attributes be loaded
487
+
488
+
489
+ == References
490
+ : ShapeLib
491
+ ((<URL:http://shapelib.maptools.org/shp_api.html>))
492
+ ((<URL:http://shapelib.maptools.org/dbf_api.html>))
493
+ : ESRI Whitepaper
494
+ ((<URL:http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf>))
495
+ or ((<URL:http://shapelib.maptools.org/dl/shapefile.pdf>))
496
+ : ISO 19125-1
497
+ ((<Found on opengeospatial.org|URL:http://portal.opengeospatial.org/modules/admin/license_agreement.php?suppressHeaders=0&access_license_id=3&target=http://portal.opengeospatial.org/files/index.php?artifact_id=13227>)).
498
+ =end