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.
- data/ext/shapes/shapes.c +359 -1
- data/ext/shapes/shapes.h +42 -1
- data/lib/shapes/geometry.rb +17 -6
- data/lib/shapes/shape_file.rb +71 -17
- data/lib/shapes/version.rb +1 -1
- metadata +2 -2
data/ext/shapes/shapes.c
CHANGED
@@ -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
|
}
|
data/ext/shapes/shapes.h
CHANGED
@@ -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
|
-
|
51
|
+
void freeDBF(struct rbDBF *f);
|
52
|
+
int ShapeFromString(const char *cShapeType);
|
53
|
+
DBFFieldType FieldTypeFromString(const char *cFieldType);
|
data/lib/shapes/geometry.rb
CHANGED
@@ -1,22 +1,33 @@
|
|
1
1
|
module Shapes
|
2
|
-
class
|
3
|
-
attr_accessor :
|
2
|
+
class GeoObject
|
3
|
+
attr_accessor :attributes
|
4
4
|
|
5
|
-
def initialize(
|
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.
|
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)
|
data/lib/shapes/shape_file.rb
CHANGED
@@ -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
|
-
|
21
|
-
return
|
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
|
-
|
30
|
+
inst.close
|
31
|
+
return true
|
29
32
|
end
|
30
33
|
|
31
34
|
def self.open(filename,&block)
|
32
|
-
|
33
|
-
return
|
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
|
-
|
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
|
data/lib/shapes/version.rb
CHANGED
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.
|
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-
|
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:
|