shapes 0.1 → 0.2

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.
@@ -5,12 +5,43 @@
5
5
  #include "shapes.h"
6
6
 
7
7
  void Init_shapeslib() {
8
- VALUE shapesModule = rb_define_module("ShapesLib");
8
+ VALUE shapesModule = rb_define_module("ShapesLib"); //Create ShapesLib module
9
+
10
+ //Define some classes to store our C data in
9
11
  shapeClass = rb_define_class_under(shapesModule,"ShapeFile",rb_cObject);
12
+ dbfClass = rb_define_class_under(shapesModule,"DBF",rb_cObject);
13
+
14
+ // Bridge for ShapeFile IO
10
15
  rb_define_module_function(shapesModule,"open_shape",OpenSHP,1);
11
16
  rb_define_module_function(shapesModule,"close_shape",CloseSHP,1);
12
17
  rb_define_module_function(shapesModule,"create_shape",CreateSHP,2);
18
+
19
+ // ShapeFile manipulation
13
20
  rb_define_module_function(shapesModule,"create_object",CreateObject,6);
21
+
22
+ // DBF IO
23
+ rb_define_module_function(shapesModule,"open_dbf",OpenDBF,1);
24
+ rb_define_module_function(shapesModule,"create_dbf",CreateDBF,1);
25
+ rb_define_module_function(shapesModule,"close_dbf",CloseDBF,1);
26
+
27
+ // DBF manipulation
28
+ rb_define_module_function(shapesModule,"dbf_field_count",RDBFFieldCount,1);
29
+ rb_define_module_function(shapesModule,"dbf_record_count",RDBFRecordCount,1);
30
+ rb_define_module_function(shapesModule,"dbf_field_index",RDBFFieldIndex,2);
31
+ rb_define_module_function(shapesModule,"dbf_field_type",RDBFGetFieldType,2);
32
+ rb_define_module_function(shapesModule,"dbf_add_field",RDBFAddField,5);
33
+
34
+ //Attribute read / write
35
+ rb_define_module_function(shapesModule,"dbf_read_int",RDBFReadInt,3);
36
+ rb_define_module_function(shapesModule,"dbf_read_double",RDBFReadDouble,3);
37
+ rb_define_module_function(shapesModule,"dbf_read_string",RDBFReadString,3);
38
+ rb_define_module_function(shapesModule,"dbf_attribute_null?",RDBFIsAttributeNull,3);
39
+ rb_define_module_function(shapesModule,"dbf_write_integer",RDBFWriteInt,4);
40
+ rb_define_module_function(shapesModule,"dbf_write_double",RDBFWriteDouble,4);
41
+ rb_define_module_function(shapesModule,"dbf_write_string",RDBFWriteString,4);
42
+ rb_define_module_function(shapesModule,"dbf_write_null",RDBFWriteNull,3);
43
+ rb_define_module_function(shapesModule,"dbf_record_deleted?",RDBFIsRecordDeleted,2);
44
+ rb_define_module_function(shapesModule,"dbf_delete_record",RDBFDeleteRecord,3);
14
45
  }
15
46
 
16
47
  VALUE OpenSHP(VALUE klass,VALUE filename) {
@@ -111,12 +142,321 @@ VALUE CloseSHP(VALUE klass,VALUE handle) {
111
142
  return Qtrue;
112
143
  }
113
144
 
145
+ //DBF IO
146
+ VALUE OpenDBF(VALUE klass,VALUE filename) {
147
+ VALUE rubyObject;
148
+ struct rbDBF *openedFile;
149
+ rubyObject = Data_Make_Struct(dbfClass,struct rbDBF,NULL,freeDBF,openedFile);
150
+
151
+ const char *cFileName = StringValueCStr(filename);
152
+ openedFile->fileHandle = DBFOpen(cFileName,"rb+");
153
+ openedFile->open = 1;
154
+
155
+ rb_obj_call_init(rubyObject,0,0);
156
+ return rubyObject;
157
+ }
158
+
159
+ VALUE CreateDBF(VALUE klass,VALUE filename) {
160
+ VALUE rubyObject;
161
+ struct rbDBF *createdFile;
162
+ rubyObject = Data_Make_Struct(dbfClass,struct rbDBF,NULL,freeDBF,createdFile);
163
+
164
+ const char *cFileName = StringValueCStr(filename);
165
+
166
+ createdFile->fileHandle = DBFCreate(cFileName);
167
+ createdFile->open = 1;
168
+
169
+ rb_obj_call_init(rubyObject,0,0);
170
+ return rubyObject;
171
+ }
172
+
173
+ VALUE CloseDBF(VALUE klass,VALUE handle) {
174
+ struct rbDBF *dbfFile;
175
+ Data_Get_Struct(handle,struct rbDBF,dbfFile);
176
+ DBFHandle fileHandle = dbfFile->fileHandle;
177
+ dbfFile->open = 0;
178
+ DBFClose(fileHandle);
179
+ return Qtrue;
180
+ }
181
+
182
+ //DBF Manipulation
183
+
184
+ VALUE RDBFFieldCount(VALUE klass,VALUE handle) {
185
+ struct rbDBF *dbf;
186
+ Data_Get_Struct(handle,struct rbDBF,dbf);
187
+ DBFHandle d = dbf->fileHandle;
188
+
189
+ int fieldCount = DBFGetFieldCount(d);
190
+ VALUE rv = INT2NUM(fieldCount);
191
+
192
+ return rv;
193
+ }
194
+
195
+ VALUE RDBFRecordCount(VALUE klass,VALUE handle) {
196
+ struct rbDBF *dbf;
197
+ Data_Get_Struct(handle,struct rbDBF,dbf);
198
+ DBFHandle d = dbf->fileHandle;
199
+
200
+ int recordCount = DBFGetRecordCount(d);
201
+ VALUE rv = INT2NUM(recordCount);
202
+
203
+ return rv;
204
+ }
205
+
206
+ VALUE RDBFFieldIndex(VALUE klass,VALUE handle,VALUE fieldName) {
207
+ struct rbDBF *dbf;
208
+ Data_Get_Struct(handle,struct rbDBF,dbf);
209
+ DBFHandle d = dbf->fileHandle;
210
+
211
+ const char *cFieldName = StringValueCStr(fieldName);
212
+
213
+ int index = DBFGetFieldIndex(d,cFieldName);
214
+ VALUE rv = INT2NUM(index);
215
+
216
+ return rv;
217
+ }
218
+
219
+ VALUE RDBFGetFieldType(VALUE klass,VALUE handle,VALUE fieldIndex) {
220
+ struct rbDBF *dbf;
221
+ Data_Get_Struct(handle,struct rbDBF,dbf);
222
+ DBFHandle d = dbf->fileHandle;
223
+
224
+ int cFieldIndex = NUM2INT(fieldIndex);
225
+
226
+ DBFFieldType fieldType = DBFGetFieldInfo(d,cFieldIndex,NULL,NULL,NULL);
227
+
228
+ VALUE fieldSymbol;
229
+
230
+ switch (fieldType) {
231
+ case FTString:
232
+ fieldSymbol = ID2SYM(rb_intern("string"));
233
+ break;
234
+ case FTInteger:
235
+ fieldSymbol = ID2SYM(rb_intern("integer"));
236
+ break;
237
+ case FTDouble:
238
+ fieldSymbol = ID2SYM(rb_intern("double"));
239
+ break;
240
+ case FTLogical:
241
+ fieldSymbol = ID2SYM(rb_intern("logical"));
242
+ break;
243
+ case FTInvalid:
244
+ fieldSymbol = ID2SYM(rb_intern("invalid"));
245
+ break;
246
+ }
247
+
248
+ return fieldSymbol;
249
+ }
250
+
251
+ VALUE RDBFAddField(VALUE klass,VALUE handle,VALUE fieldName,VALUE fieldType,VALUE width,VALUE decimals) {
252
+ struct rbDBF *dbf;
253
+ Data_Get_Struct(handle,struct rbDBF,dbf);
254
+ DBFHandle d = dbf->fileHandle;
255
+
256
+ const char *cFieldName = StringValueCStr(fieldName);
257
+ const char *cFieldType = StringValueCStr(fieldType);
258
+
259
+ int cWidth = NUM2INT(width);
260
+ int cDecimals = NUM2INT(decimals);
261
+
262
+ DBFFieldType ft = FieldTypeFromString(cFieldType);
263
+ int fieldNumber = DBFAddField(d,cFieldName,ft,cWidth,cDecimals);
264
+ VALUE rv = INT2NUM(fieldNumber);
265
+
266
+ return rv;
267
+ }
268
+
269
+ VALUE RDBFReadInt(VALUE klass,VALUE handle,VALUE row,VALUE field) {
270
+ struct rbDBF *dbf;
271
+ Data_Get_Struct(handle,struct rbDBF,dbf);
272
+ DBFHandle d = dbf->fileHandle;
273
+
274
+ int cRow = NUM2INT(row);
275
+ int cField = NUM2INT(field);
276
+
277
+ int r = DBFReadIntegerAttribute(d,cRow,cField);
278
+ VALUE rv = INT2NUM(r);
279
+
280
+ return rv;
281
+ }
282
+
283
+ VALUE RDBFReadDouble(VALUE klass,VALUE handle,VALUE row,VALUE field) {
284
+ struct rbDBF *dbf;
285
+ Data_Get_Struct(handle,struct rbDBF,dbf);
286
+ DBFHandle d = dbf->fileHandle;
287
+
288
+ int cRow = NUM2INT(row);
289
+ int cField = NUM2INT(field);
290
+
291
+ double r = DBFReadDoubleAttribute(d,cRow,cField);
292
+ VALUE rv = DOUBLE2NUM(r);
293
+
294
+ return rv;
295
+ }
296
+
297
+ VALUE RDBFReadString(VALUE klass,VALUE handle,VALUE row,VALUE field) {
298
+ struct rbDBF *dbf;
299
+ Data_Get_Struct(handle,struct rbDBF,dbf);
300
+ DBFHandle d = dbf->fileHandle;
301
+
302
+ int cRow = NUM2INT(row);
303
+ int cField = NUM2INT(field);
304
+
305
+ const char *r = DBFReadStringAttribute(d,cRow,cField);
306
+ VALUE rv = rb_str_new2(r);
307
+
308
+ return rv;
309
+ }
310
+
311
+ VALUE RDBFIsAttributeNull(VALUE klass,VALUE handle,VALUE row,VALUE field) {
312
+ struct rbDBF *dbf;
313
+ Data_Get_Struct(handle,struct rbDBF,dbf);
314
+ DBFHandle d = dbf->fileHandle;
315
+
316
+ int cRow = NUM2INT(row);
317
+ int cField = NUM2INT(field);
318
+
319
+ VALUE rv = Qfalse;
320
+
321
+ if (DBFIsAttributeNull(d,cRow,cField) == TRUE) {
322
+ rv = Qtrue;
323
+ }
324
+
325
+ return rv;
326
+ }
327
+
328
+ VALUE RDBFWriteInt(VALUE klass,VALUE handle,VALUE row,VALUE field,VALUE val) {
329
+ struct rbDBF *dbf;
330
+ Data_Get_Struct(handle,struct rbDBF,dbf);
331
+ DBFHandle d = dbf->fileHandle;
332
+
333
+ int cRow = NUM2INT(row);
334
+ int cField = NUM2INT(field);
335
+ int cVal = NUM2INT(val);
336
+
337
+ VALUE rv;
338
+
339
+ if (DBFWriteIntegerAttribute(d,cRow,cField,cVal) == TRUE) {
340
+ rv = Qtrue;
341
+ } else {
342
+ rv = Qfalse;
343
+ }
344
+
345
+ return rv;
346
+ }
347
+
348
+ VALUE RDBFWriteDouble(VALUE klass,VALUE handle,VALUE row,VALUE field,VALUE val) {
349
+ struct rbDBF *dbf;
350
+ Data_Get_Struct(handle,struct rbDBF,dbf);
351
+ DBFHandle d = dbf->fileHandle;
352
+
353
+ int cRow = NUM2INT(row);
354
+ int cField = NUM2INT(field);
355
+ double cVal = NUM2DBL(val);
356
+
357
+ VALUE rv;
358
+
359
+ if (DBFWriteDoubleAttribute(d,cRow,cField,cVal) == TRUE) {
360
+ rv = Qtrue;
361
+ } else {
362
+ rv = Qfalse;
363
+ }
364
+
365
+ return rv;
366
+ }
367
+
368
+ VALUE RDBFWriteString(VALUE klass,VALUE handle,VALUE row,VALUE field,VALUE val) {
369
+ struct rbDBF *dbf;
370
+ Data_Get_Struct(handle,struct rbDBF,dbf);
371
+ DBFHandle d = dbf->fileHandle;
372
+
373
+ int cRow = NUM2INT(row);
374
+ int cField = NUM2INT(field);
375
+ const char *cVal = StringValueCStr(val);
376
+
377
+ VALUE rv;
378
+
379
+ if (DBFWriteStringAttribute(d,cRow,cField,cVal) == TRUE) {
380
+ rv = Qtrue;
381
+ } else {
382
+ rv = Qfalse;
383
+ }
384
+
385
+ return rv;
386
+ }
387
+
388
+ VALUE RDBFWriteNull(VALUE klass,VALUE handle,VALUE row,VALUE field) {
389
+ struct rbDBF *dbf;
390
+ Data_Get_Struct(handle,struct rbDBF,dbf);
391
+ DBFHandle d = dbf->fileHandle;
392
+
393
+ int cRow = NUM2INT(row);
394
+ int cField = NUM2INT(field);
395
+
396
+ VALUE rv;
397
+
398
+ if (DBFWriteNULLAttribute(d,cRow,cField) == TRUE) {
399
+ rv = Qtrue;
400
+ } else {
401
+ rv = Qfalse;
402
+ }
403
+
404
+ return rv;
405
+ }
406
+
407
+ VALUE RDBFIsRecordDeleted(VALUE klass,VALUE handle,VALUE row) {
408
+ struct rbDBF *dbf;
409
+ Data_Get_Struct(handle,struct rbDBF,dbf);
410
+ DBFHandle d = dbf->fileHandle;
411
+
412
+ int cRow = NUM2INT(row);
413
+
414
+ VALUE rv;
415
+
416
+ if (DBFIsRecordDeleted(d,cRow) == TRUE) {
417
+ rv = Qtrue;
418
+ } else {
419
+ rv = Qfalse;
420
+ }
421
+
422
+ return rv;
423
+ }
424
+
425
+ VALUE RDBFDeleteRecord(VALUE klass,VALUE handle,VALUE row,VALUE val) {
426
+ struct rbDBF *dbf;
427
+ Data_Get_Struct(handle,struct rbDBF,dbf);
428
+ DBFHandle d = dbf->fileHandle;
429
+
430
+ int cRow = NUM2INT(row);
431
+ int cVal = NUM2INT(val);
432
+
433
+ int deleted = DBFMarkRecordDeleted(d,cRow,cVal);
434
+
435
+ VALUE rv;
436
+
437
+ if (deleted == TRUE) {
438
+ rv = Qtrue;
439
+ } else {
440
+ rv = Qfalse;
441
+ }
442
+
443
+ return rv;
444
+ }
445
+
114
446
  void freeShapeFile(struct rbShapeFile *f) {
115
447
  if (f->open) {
448
+ f->open = 0;
116
449
  SHPClose(f->fileHandle);
117
450
  }
118
451
  }
119
452
 
453
+ void freeDBF(struct rbDBF *f) {
454
+ if (f->open) {
455
+ f->open = 0;
456
+ DBFClose(f->fileHandle);
457
+ }
458
+ }
459
+
120
460
  int ShapeFromString(const char *cShapeType) {
121
461
  int shape;
122
462
 
@@ -133,4 +473,22 @@ int ShapeFromString(const char *cShapeType) {
133
473
  }
134
474
 
135
475
  return shape;
476
+ }
477
+
478
+ DBFFieldType FieldTypeFromString(const char *cFieldType) {
479
+ DBFFieldType fieldType;
480
+
481
+ if (strcmp(cFieldType,"string") == 0) {
482
+ fieldType = FTString;
483
+ } else if (strcmp(cFieldType,"integer") == 0) {
484
+ fieldType = FTInteger;
485
+ } else if (strcmp(cFieldType,"double") == 0) {
486
+ fieldType = FTDouble;
487
+ } else if (strcmp(cFieldType,"logical") == 0) {
488
+ fieldType = FTLogical;
489
+ } else {
490
+ fieldType = FTInvalid;
491
+ }
492
+
493
+ return fieldType;
136
494
  }
@@ -1,12 +1,53 @@
1
+ #define TRUE 1
2
+ #define FALSE 0
3
+
1
4
  struct rbShapeFile {
2
5
  int open;
3
6
  SHPHandle fileHandle;
4
7
  };
5
8
 
9
+ struct rbDBF {
10
+ int open;
11
+ DBFHandle fileHandle;
12
+ };
13
+
6
14
  VALUE shapeClass;
15
+ VALUE dbfClass;
16
+
17
+ // ShapeFile IO
7
18
  VALUE OpenSHP(VALUE klass,VALUE filename);
8
19
  VALUE CreateSHP(VALUE klass,VALUE filename,VALUE shapeType);
9
20
  VALUE CloseSHP(VALUE klass,VALUE handle);
21
+
22
+ //ShapeFile manipulation
10
23
  VALUE CreateObject(VALUE klass,VALUE handle,VALUE shapeType,VALUE numVertices,VALUE x,VALUE y,VALUE z);
24
+
25
+ //DBF IO
26
+ VALUE OpenDBF(VALUE klass,VALUE filename);
27
+ VALUE CreateDBF(VALUE klass,VALUE filename);
28
+ VALUE CloseDBF(VALUE klass,VALUE handle);
29
+
30
+ //DBF Manipulation
31
+
32
+ VALUE RDBFFieldCount(VALUE klass,VALUE handle);
33
+ VALUE RDBFRecordCount(VALUE klass,VALUE handle);
34
+ VALUE RDBFFieldIndex(VALUE klass,VALUE handle,VALUE fieldName);
35
+ VALUE RDBFGetFieldType(VALUE klass,VALUE handle,VALUE fieldIndex);
36
+ VALUE RDBFAddField(VALUE klass,VALUE handle,VALUE fieldName,VALUE fieldType,VALUE width,VALUE decimals);
37
+
38
+ // DBF read / write
39
+ VALUE RDBFReadInt(VALUE klass,VALUE handle,VALUE row,VALUE field);
40
+ VALUE RDBFReadDouble(VALUE klass,VALUE handle,VALUE row,VALUE field);
41
+ VALUE RDBFReadString(VALUE klass,VALUE handle,VALUE row,VALUE field);
42
+ VALUE RDBFIsAttributeNull(VALUE klass,VALUE handle,VALUE row,VALUE field);
43
+ VALUE RDBFWriteInt(VALUE klass,VALUE handle,VALUE row,VALUE field,VALUE val);
44
+ VALUE RDBFWriteDouble(VALUE klass,VALUE handle,VALUE row,VALUE field,VALUE val);
45
+ VALUE RDBFWriteString(VALUE klass,VALUE handle,VALUE row,VALUE field,VALUE val);
46
+ VALUE RDBFWriteNull(VALUE klass,VALUE handle,VALUE row,VALUE field);
47
+ VALUE RDBFIsRecordDeleted(VALUE klass,VALUE handle,VALUE row);
48
+ VALUE RDBFDeleteRecord(VALUE klass,VALUE handle,VALUE row,VALUE val);
49
+
11
50
  void freeShapeFile(struct rbShapeFile *f);
12
- int ShapeFromString(const char *cShapeType);
51
+ void freeDBF(struct rbDBF *f);
52
+ int ShapeFromString(const char *cShapeType);
53
+ DBFFieldType FieldTypeFromString(const char *cFieldType);
@@ -1,22 +1,33 @@
1
1
  module Shapes
2
- class Point
3
- attr_accessor :longitude, :latitude, :altitude, :projection
2
+ class GeoObject
3
+ attr_accessor :attributes
4
4
 
5
- def initialize(lat = nil,long = nil,alt = nil,proj = :wgs84)
5
+ def initialize(*args)
6
+ self.attributes = Hash.new
7
+ end
8
+ end
9
+
10
+ class Point < GeoObject
11
+ attr_accessor :longitude, :latitude, :altitude
12
+
13
+ def initialize(lat = nil,long = nil,alt = nil,attributes = {})
14
+ super
6
15
  self.latitude = lat
7
16
  self.longitude = long
8
17
  self.altitude = alt
9
- self.projection = proj
18
+ self.attributes = attributes
10
19
  end
11
20
  end
12
21
 
13
- class Polygon
22
+ class Polygon < GeoObject
14
23
  attr_accessor :vertices, :num_vertices
15
24
 
16
- def initialize(vertices = nil,num_vertices = 4)
25
+ def initialize(vertices = nil,num_vertices = 4,attributes = {})
26
+ super
17
27
  self.vertices = vertices if Array === vertices
18
28
  self.vertices ||= []
19
29
  self.num_vertices = num_vertices
30
+ self.attributes = {}
20
31
  end
21
32
 
22
33
  def add_point(p)
@@ -1,63 +1,117 @@
1
1
  module Shapes
2
2
  class ShapeFile
3
- attr_accessor :handle
3
+ attr_accessor :handle, :dbf_handle, :fields
4
4
 
5
5
  def initialize(afile = nil,stype = nil)
6
6
  if afile and stype
7
7
  self.handle = ShapesLib::create_shape afile, stype.to_s
8
+ self.dbf_handle = ShapesLib::create_dbf afile
8
9
  elsif afile
9
10
  self.handle = ShapesLib::open_shape afile
11
+ self.dbf_handle = Shapeslib::open_dbf afile
10
12
  else
11
13
  return self # get out of the function if no handle was passed
12
14
  end
13
15
 
16
+ self.fields = Hash.new
17
+
14
18
  # but if we attempted to create a handle, make sure
15
19
  # it actually returned something valid
16
20
  return self.handle unless self.handle
21
+ return self.dbf_handle unless self.dbf_handle
17
22
  end
18
23
 
19
24
  def self.create(filename,shape_type,&block)
20
- shape_handle = ShapesLib::create_shape filename, shape_type.to_s
21
- return shape_handle unless shape_handle
22
-
23
- inst = new
24
- inst.handle = shape_handle
25
+ inst = new filename, shape_type
26
+ return inst unless inst
25
27
 
26
28
  inst.define(&block)
27
29
 
28
- ShapesLib::close_shape shape_handle
30
+ inst.close
31
+ return true
29
32
  end
30
33
 
31
34
  def self.open(filename,&block)
32
- shape_handle = ShapesLib::open_shape filename
33
- return shape_handle unless shape_handle
34
-
35
- inst = new
36
- inst.handle = shape_handle
35
+ inst = new filename
36
+ return inst unless inst
37
37
 
38
38
  inst.define(&block)
39
39
 
40
- ShapesLib::close_shape shape_handle
40
+ inst.close
41
+ return true
42
+ end
43
+
44
+ def add_field(field_name,field_type,width = 255,decimals = 0)
45
+ rv = ShapesLib::dbf_add_field self.dbf_handle, field_name.to_s, field_type.to_s, width, decimals
46
+ self.fields[field_name] = {
47
+ name: field_name,
48
+ type: field_type,
49
+ width: width,
50
+ decimals: decimals,
51
+ field_number: rv
52
+ }
53
+ return rv
54
+ end
55
+
56
+ def close
57
+ ShapesLib::close_shape self.handle
58
+ ShapesLib::close_dbf self.dbf_handle
41
59
  end
42
60
 
43
61
  def define(&block)
44
62
  instance_eval(&block)
45
63
  end
46
64
 
65
+ def save_attribute(key,value,row)
66
+ return false if self.fields[key].nil?
67
+
68
+ d = self.dbf_handle
69
+ field_info = self.fields[key]
70
+ field_name = key.to_s
71
+ field_type = field_info[:type]
72
+ field_number = field_info[:field_number]
73
+ width = field_info[:width]
74
+ decimals = field_info[:decimals]
75
+
76
+ saved = case field_type
77
+ when :string then ShapesLib::dbf_write_string d, row, field_number, value.to_s
78
+ when :integer then ShapesLib::dbf_write_integer d, row, field_number, value.to_i
79
+ when :double then ShapesLib::dbf_write_double d, row, field_number, value.to_f
80
+ end
81
+
82
+ return saved
83
+ end
84
+
47
85
  def point(p)
48
- ShapesLib::create_object self.handle, 'point', 1, [p.longitude], [p.latitude], [p.altitude]
86
+ i = ShapesLib::create_object self.handle, 'point', 1, [p.longitude], [p.latitude], [p.altitude]
87
+ attrs = p.attributes
88
+
89
+ attrs.each {|key,val| save_attribute(key,val,i) }
90
+ return i
49
91
  end
50
92
 
51
93
  def polygon(p)
52
- ShapesLib::create_object self.handle, 'polygon', p.num_vertices, p.xs, p.ys, p.zs
94
+ i = ShapesLib::create_object self.handle, 'polygon', p.num_vertices, p.xs, p.ys, p.zs
95
+ attrs = p.attributes
96
+
97
+ attrs.each {|key,val| save_attribute(key,val,i) }
98
+ return i
53
99
  end
54
100
 
55
101
  def arc(a)
56
- ShapesLib::create_object self.handle, 'arc', a.num_vertices, a.xs, p.ys, p.zs
102
+ i = ShapesLib::create_object self.handle, 'arc', a.num_vertices, a.xs, p.ys, p.zs
103
+ attrs = a.attributes
104
+
105
+ attrs.each {|key,val| save_attribute(key,val,i)}
106
+ return i
57
107
  end
58
108
 
59
109
  def multipoint(mp)
60
- ShapesLib::create_object self.handle, 'multipoint', mp.num_vertices, mp.xs, mp.ys, mp.zs
110
+ i = ShapesLib::create_object self.handle, 'multipoint', mp.num_vertices, mp.xs, mp.ys, mp.zs
111
+ attrs = mp.attributes
112
+
113
+ attrs.each {|key,val| save_attribute(key,val,i) }
114
+ return i
61
115
  end
62
116
  end
63
117
  end
@@ -1,3 +1,3 @@
1
1
  module Shapes
2
- VERSION = "0.1"
2
+ VERSION = "0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shapes
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-30 00:00:00.000000000 Z
12
+ date: 2012-12-31 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A simple ruby library for writing shape files
15
15
  email: