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/README.md +59 -0
- data/Rakefile +47 -0
- data/doc/Interface.html +558 -0
- data/doc/Interface.rd +498 -0
- data/doc/style.css +136 -0
- data/ext/shapelib_ext/depend +49 -0
- data/ext/shapelib_ext/extconf.rb +19 -0
- data/ext/shapelib_ext/main.c +102 -0
- data/ext/shapelib_ext/sfcode.h +284 -0
- data/ext/shapelib_ext/sflist.h +21 -0
- data/ext/shapelib_ext/shpplus.c +588 -0
- data/ext/shapelib_ext/shpplus.h +86 -0
- data/ext/shapelib_ext/spcode.h +704 -0
- data/ext/shapelib_ext/splist.h +71 -0
- data/ext/shapelib_ext/spwkt.h +219 -0
- data/ext/shapelib_ext/valconv.h +313 -0
- data/lib/shapelib.rb +2 -0
- data/lib/shapelib/shape.rb +14 -0
- data/lib/shapelib/version.rb +3 -0
- data/test/libtest.rb +80 -0
- data/test/zsample1.rb +168 -0
- data/test/ztest1.rb +253 -0
- metadata +103 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
|
2
|
+
static VALUE sp_to_h(VALUE obj)
|
3
|
+
{
|
4
|
+
VALUE h;
|
5
|
+
h = rb_hash_new();
|
6
|
+
rb_hash_aset(h, CSTR2SYM("shape_type"), sp_shape_type(obj));
|
7
|
+
rb_hash_aset(h, CSTR2SYM("shape_id"), sp_shape_id(obj));
|
8
|
+
rb_hash_aset(h, CSTR2SYM("maxbound"), sp_maxbound(obj));
|
9
|
+
rb_hash_aset(h, CSTR2SYM("minbound"), sp_minbound(obj));
|
10
|
+
rb_hash_aset(h, CSTR2SYM("mvals"), sp_mvals(obj));
|
11
|
+
rb_hash_aset(h, CSTR2SYM("n_parts"), sp_n_parts(obj));
|
12
|
+
rb_hash_aset(h, CSTR2SYM("n_vertices"), sp_n_vertices(obj));
|
13
|
+
rb_hash_aset(h, CSTR2SYM("part_start"), sp_part_start(obj));
|
14
|
+
rb_hash_aset(h, CSTR2SYM("part_type"), sp_part_type(obj));
|
15
|
+
rb_hash_aset(h, CSTR2SYM("shape_id"), sp_shape_id(obj));
|
16
|
+
rb_hash_aset(h, CSTR2SYM("shape_type"), sp_shape_type(obj));
|
17
|
+
rb_hash_aset(h, CSTR2SYM("xvals"), sp_xvals(obj));
|
18
|
+
rb_hash_aset(h, CSTR2SYM("yvals"), sp_yvals(obj));
|
19
|
+
rb_hash_aset(h, CSTR2SYM("zvals"), sp_zvals(obj));
|
20
|
+
Attr_to_Hash(h, obj);
|
21
|
+
return h;
|
22
|
+
}
|
23
|
+
|
24
|
+
static VALUE sp_inspect(VALUE obj)
|
25
|
+
{
|
26
|
+
VALUE tos;
|
27
|
+
static ID inspect = 0;
|
28
|
+
static ID id_plus, id_class, id_to_s;
|
29
|
+
static VALUE classnm;
|
30
|
+
if (inspect == 0) {
|
31
|
+
inspect = rb_intern("inspect");
|
32
|
+
id_plus = rb_intern("+");
|
33
|
+
id_class = rb_intern("class");
|
34
|
+
id_to_s = rb_intern("to_s");
|
35
|
+
}
|
36
|
+
classnm = rb_funcall(rb_funcall(obj, id_class, 0), id_to_s, 0);
|
37
|
+
tos = rb_funcall(sp_to_h(obj), inspect, 0);
|
38
|
+
return rb_funcall(classnm, id_plus, 1, tos);
|
39
|
+
}
|
40
|
+
|
41
|
+
static method_table_entry sp_methods[] = {
|
42
|
+
{ "[]", sp_field_get, 1 },
|
43
|
+
{ "[]=", sp_field_set, 2 },
|
44
|
+
{ "inspect", sp_inspect, 0 },
|
45
|
+
{ "maxbound", sp_maxbound, 0 },
|
46
|
+
{ "minbound", sp_minbound, 0 },
|
47
|
+
{ "mvals", sp_mvals, 0 },
|
48
|
+
{ "n_parts", sp_n_parts, 0 },
|
49
|
+
{ "n_vertices", sp_n_vertices, 0 },
|
50
|
+
{ "part_start", sp_part_start, 0 },
|
51
|
+
{ "part_type", sp_part_type, 0 },
|
52
|
+
{ "shape_type", sp_shape_type, 0 },
|
53
|
+
{ "shape_id", sp_shape_id, 0 },
|
54
|
+
{ "to_h", sp_to_h, 0 },
|
55
|
+
{ "to_s", sp_wkt, 0 },
|
56
|
+
{ "rewind_polygon", sp_rewind, 0 },
|
57
|
+
{ "wkt", sp_wkt, 0 },
|
58
|
+
{ "xvals", sp_xvals, 0 },
|
59
|
+
{ "yvals", sp_yvals, 0 },
|
60
|
+
{ "zvals", sp_zvals, 0 },
|
61
|
+
{ NULL, NULL, 0 }
|
62
|
+
};
|
63
|
+
|
64
|
+
static method_table_entry pt_methods[] = {
|
65
|
+
{ "m", pt_m, 0 },
|
66
|
+
{ "wkt", pt_wkt, 0 },
|
67
|
+
{ "x", pt_x, 0 },
|
68
|
+
{ "y", pt_y, 0 },
|
69
|
+
{ "z", pt_z, 0 },
|
70
|
+
{ NULL, NULL, 0 }
|
71
|
+
};
|
@@ -0,0 +1,219 @@
|
|
1
|
+
|
2
|
+
/* safer substitute of strcat(3). I believe strcat is too dangerous.
|
3
|
+
*/
|
4
|
+
static char *StringCat(char *buf, char *src, char *stop)
|
5
|
+
{
|
6
|
+
if (*buf)
|
7
|
+
buf = buf + strlen(buf);
|
8
|
+
strncpy(buf, src, stop - buf);
|
9
|
+
*stop = '\0';
|
10
|
+
return buf + strlen(buf);
|
11
|
+
}
|
12
|
+
|
13
|
+
/* 123..........45678 */
|
14
|
+
/* -0.1234567890e-100 */
|
15
|
+
static int wkt_dlen = 18;
|
16
|
+
static char wkt_dfmt[16] = "%1.10g";
|
17
|
+
|
18
|
+
static char *DblFmtCat(char *buf, double x, char *stop)
|
19
|
+
{
|
20
|
+
char fbuf[512];
|
21
|
+
sprintf(fbuf, wkt_dfmt, x);
|
22
|
+
return StringCat(buf, fbuf, stop);
|
23
|
+
}
|
24
|
+
|
25
|
+
static VALUE pt_wkt(VALUE obj)
|
26
|
+
{
|
27
|
+
shape_t *self;
|
28
|
+
size_t buflen;
|
29
|
+
char *buf, *cur, *stop;
|
30
|
+
VALUE wkt;
|
31
|
+
Data_Get_Struct(obj, shape_t, self);
|
32
|
+
buflen = wkt_dlen * 2 + 9;
|
33
|
+
cur = buf = xmalloc(buflen + 1);
|
34
|
+
stop = buf + buflen;
|
35
|
+
strcpy(cur, "POINT(");
|
36
|
+
cur = DblFmtCat(cur, self->obj->padfX[0], stop);
|
37
|
+
cur = StringCat(cur, " ", stop);
|
38
|
+
cur = DblFmtCat(cur, self->obj->padfY[0], stop);
|
39
|
+
cur = StringCat(cur, ")", stop);
|
40
|
+
wkt = rb_str_new(buf, strlen(buf));
|
41
|
+
free(buf);
|
42
|
+
return wkt;
|
43
|
+
}
|
44
|
+
|
45
|
+
static VALUE mp_wkt(VALUE obj)
|
46
|
+
{
|
47
|
+
shape_t *self;
|
48
|
+
VALUE wkt;
|
49
|
+
size_t buflen;
|
50
|
+
char *buf, *cur, *stop;
|
51
|
+
int iv;
|
52
|
+
Data_Get_Struct(obj, shape_t, self);
|
53
|
+
buflen = (2 * wkt_dlen + 3) * self->obj->nVertices + 11;
|
54
|
+
cur = buf = xmalloc(buflen + 1);
|
55
|
+
stop = buf + buflen;
|
56
|
+
strcpy(buf, "MULTIPOINT(");
|
57
|
+
for (iv = 0; iv < self->obj->nVertices; iv++) {
|
58
|
+
if (iv)
|
59
|
+
StringCat(cur, ", ", stop);
|
60
|
+
cur = DblFmtCat(cur, self->obj->padfX[iv], stop);
|
61
|
+
cur = StringCat(cur, " ", stop);
|
62
|
+
cur = DblFmtCat(cur, self->obj->padfY[iv], stop);
|
63
|
+
}
|
64
|
+
StringCat(cur, ")", stop);
|
65
|
+
wkt = rb_str_new(buf, strlen(buf));
|
66
|
+
free(buf);
|
67
|
+
return wkt;
|
68
|
+
}
|
69
|
+
|
70
|
+
static VALUE WKTSinglePolygon(SHPObject *obj)
|
71
|
+
{
|
72
|
+
size_t buflen;
|
73
|
+
VALUE wkt;
|
74
|
+
char *buf, *cur, *stop;
|
75
|
+
int ipart, endvert, ivert;
|
76
|
+
buflen = (2 * wkt_dlen + 3) * obj->nVertices + obj->nParts * 2 + 9;
|
77
|
+
cur = buf = xmalloc(buflen + 1);
|
78
|
+
stop = cur + buflen;
|
79
|
+
strcpy(buf, "POLYGON(");
|
80
|
+
for (ipart = 0; ipart < obj->nParts; ipart++) {
|
81
|
+
if (ipart == obj->nParts - 1) {
|
82
|
+
endvert = obj->nVertices;
|
83
|
+
} else {
|
84
|
+
endvert = obj->panPartStart[ipart + 1];
|
85
|
+
}
|
86
|
+
if (ipart)
|
87
|
+
cur = StringCat(cur, ", ", stop);
|
88
|
+
cur = StringCat(cur, "(", stop);
|
89
|
+
for (ivert = obj->panPartStart[ipart]; ivert < endvert; ivert++) {
|
90
|
+
if (ivert > obj->panPartStart[ipart])
|
91
|
+
cur = StringCat(cur, ", ", stop);
|
92
|
+
cur = DblFmtCat(cur, obj->padfX[ivert], stop);
|
93
|
+
cur = StringCat(cur, " ", stop);
|
94
|
+
cur = DblFmtCat(cur, obj->padfY[ivert], stop);
|
95
|
+
}
|
96
|
+
cur = StringCat(cur, ")", stop);
|
97
|
+
}
|
98
|
+
cur = StringCat(cur, ")", stop);
|
99
|
+
wkt = rb_str_new(buf, strlen(buf));
|
100
|
+
free(buf);
|
101
|
+
return wkt;
|
102
|
+
}
|
103
|
+
|
104
|
+
static VALUE pl_wkt(VALUE obj)
|
105
|
+
{
|
106
|
+
shape_t *self;
|
107
|
+
Data_Get_Struct(obj, shape_t, self);
|
108
|
+
/* === BUG ===
|
109
|
+
* following code doesn't consider the possibilities:
|
110
|
+
* - there may be multiple outer loop in a Polygon Shape.
|
111
|
+
* in such a case, it must generate MULTIPOLYGON WKT.
|
112
|
+
* - inner loop (hole) may come before outer loop.
|
113
|
+
*/
|
114
|
+
return WKTSinglePolygon(self->obj);
|
115
|
+
#if 0
|
116
|
+
return WKTMultiPolygon(self->obj);
|
117
|
+
#endif
|
118
|
+
}
|
119
|
+
|
120
|
+
static VALUE WKTSingleArc(SHPObject *obj)
|
121
|
+
{
|
122
|
+
size_t buflen;
|
123
|
+
VALUE wkt;
|
124
|
+
char *buf, *cur, *stop;
|
125
|
+
int ivert;
|
126
|
+
buflen = (2 * wkt_dlen + 3) * obj->nVertices + 10;
|
127
|
+
cur = buf = xmalloc(buflen + 1);
|
128
|
+
stop = cur + buflen;
|
129
|
+
strcpy(buf, "LINESTRING(");
|
130
|
+
for (ivert = 0; ivert < obj->nVertices; ivert++) {
|
131
|
+
if (ivert)
|
132
|
+
cur = StringCat(cur, ", ", stop);
|
133
|
+
cur = DblFmtCat(cur, obj->padfX[ivert], stop);
|
134
|
+
cur = StringCat(cur, " ", stop);
|
135
|
+
cur = DblFmtCat(cur, obj->padfY[ivert], stop);
|
136
|
+
}
|
137
|
+
cur = StringCat(cur, ")", stop);
|
138
|
+
wkt = rb_str_new(buf, strlen(buf));
|
139
|
+
free(buf);
|
140
|
+
return wkt;
|
141
|
+
}
|
142
|
+
|
143
|
+
static VALUE WKTMultiArc(SHPObject *obj)
|
144
|
+
{
|
145
|
+
size_t buflen;
|
146
|
+
VALUE wkt;
|
147
|
+
char *buf, *cur, *stop;
|
148
|
+
int ipart, endvert, ivert;
|
149
|
+
buflen = (2 * wkt_dlen + 3) * obj->nVertices + obj->nParts * 1 + 16;
|
150
|
+
cur = buf = xmalloc(buflen + 1);
|
151
|
+
stop = cur + buflen;
|
152
|
+
strcpy(buf, "MULTILINESTRING(");
|
153
|
+
for (ipart = 0; ipart < obj->nParts; ipart++) {
|
154
|
+
if (ipart == obj->nParts - 1) {
|
155
|
+
endvert = obj->nVertices;
|
156
|
+
} else {
|
157
|
+
endvert = obj->panPartStart[ipart + 1];
|
158
|
+
}
|
159
|
+
if (ipart)
|
160
|
+
cur = StringCat(cur, ", ", stop);
|
161
|
+
cur = StringCat(cur, "(", stop);
|
162
|
+
for (ivert = obj->panPartStart[ipart]; ivert < endvert; ivert++) {
|
163
|
+
if (ivert > obj->panPartStart[ipart])
|
164
|
+
cur = StringCat(cur, ", ", stop);
|
165
|
+
cur = DblFmtCat(cur, obj->padfX[ivert], stop);
|
166
|
+
cur = StringCat(cur, " ", stop);
|
167
|
+
cur = DblFmtCat(cur, obj->padfY[ivert], stop);
|
168
|
+
}
|
169
|
+
cur = StringCat(cur, ")", stop);
|
170
|
+
}
|
171
|
+
cur = StringCat(cur, ")", stop);
|
172
|
+
wkt = rb_str_new(buf, strlen(buf));
|
173
|
+
free(buf);
|
174
|
+
return wkt;
|
175
|
+
}
|
176
|
+
|
177
|
+
static VALUE arc_wkt(VALUE obj)
|
178
|
+
{
|
179
|
+
shape_t *self;
|
180
|
+
Data_Get_Struct(obj, shape_t, self);
|
181
|
+
if (self->obj->nParts > 1) {
|
182
|
+
return WKTMultiArc(self->obj);
|
183
|
+
} else {
|
184
|
+
return WKTSingleArc(self->obj);
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
static VALUE sp_wkt(VALUE obj)
|
189
|
+
{
|
190
|
+
shape_t *self;
|
191
|
+
Data_Get_Struct(obj, shape_t, self);
|
192
|
+
switch (self->obj->nSHPType) {
|
193
|
+
case SHPT_POINT:
|
194
|
+
case SHPT_POINTM:
|
195
|
+
case SHPT_POINTZ:
|
196
|
+
return pt_wkt(obj);
|
197
|
+
break;
|
198
|
+
case SHPT_ARC:
|
199
|
+
case SHPT_ARCM:
|
200
|
+
case SHPT_ARCZ:
|
201
|
+
return arc_wkt(obj);
|
202
|
+
break;
|
203
|
+
case SHPT_POLYGON:
|
204
|
+
case SHPT_POLYGONM:
|
205
|
+
case SHPT_POLYGONZ:
|
206
|
+
return pl_wkt(obj);
|
207
|
+
break;
|
208
|
+
case SHPT_MULTIPOINT:
|
209
|
+
case SHPT_MULTIPOINTM:
|
210
|
+
case SHPT_MULTIPOINTZ:
|
211
|
+
return mp_wkt(obj);
|
212
|
+
break;
|
213
|
+
case SHPT_MULTIPATCH:
|
214
|
+
return pl_wkt(obj);
|
215
|
+
break;
|
216
|
+
}
|
217
|
+
rb_bug("invalid shape type %d", self->obj->nSHPType);
|
218
|
+
return Qnil;
|
219
|
+
}
|
@@ -0,0 +1,313 @@
|
|
1
|
+
/* valconv.h */
|
2
|
+
|
3
|
+
#define SECURE(obj) SecureObject((obj), #obj)
|
4
|
+
|
5
|
+
#define SHP_NODATA_LIM -1.0e-38
|
6
|
+
#define SHP_NODATA -2.0e-38
|
7
|
+
#define SHP_NUM2DBL(value) (NIL_P(value) ? SHP_NODATA : NUM2DBL(value))
|
8
|
+
#define SHP_FLOAT_NEW(f) (((f) < SHP_NODATA_LIM) ? Qnil : rb_float_new((f)))
|
9
|
+
#define CSTR2SYM(s) (ID2SYM(rb_intern((s))))
|
10
|
+
static int NUM2INT_nil(VALUE v) { return NIL_P(v) ? -1 : NUM2INT(v); }
|
11
|
+
|
12
|
+
static const_table_entry sl_consts[] = {
|
13
|
+
{ "String", INT2FIX((int)FTString) },
|
14
|
+
{ "Integer", INT2FIX((int)FTInteger) },
|
15
|
+
{ "Float", INT2FIX((int)FTDouble) },
|
16
|
+
{ "Logical", INT2FIX((int)FTLogical) },
|
17
|
+
{ NULL, Qnil }
|
18
|
+
};
|
19
|
+
|
20
|
+
static ID *ShapeTypeNameTable(void)
|
21
|
+
{
|
22
|
+
static ID ids[SHPT_MULTIPATCH + 1];
|
23
|
+
if (ids[SHPT_NULL] != 0) {
|
24
|
+
return ids;
|
25
|
+
}
|
26
|
+
ids[SHPT_NULL] = rb_intern("Null");
|
27
|
+
ids[SHPT_POINT] = rb_intern("Point");
|
28
|
+
ids[SHPT_POINTM] = rb_intern("PointM");
|
29
|
+
ids[SHPT_POINTZ] = rb_intern("PointZ");
|
30
|
+
ids[SHPT_ARC] = rb_intern("Arc");
|
31
|
+
ids[SHPT_ARCM] = rb_intern("ArcM");
|
32
|
+
ids[SHPT_ARCZ] = rb_intern("ArcZ");
|
33
|
+
ids[SHPT_POLYGON] = rb_intern("Polygon");
|
34
|
+
ids[SHPT_POLYGONM] = rb_intern("PolygonM");
|
35
|
+
ids[SHPT_POLYGONZ] = rb_intern("PolygonZ");
|
36
|
+
ids[SHPT_MULTIPOINT] = rb_intern("MultiPoint");
|
37
|
+
ids[SHPT_MULTIPOINTM] = rb_intern("MultiPointM");
|
38
|
+
ids[SHPT_MULTIPOINTZ] = rb_intern("MultiPointZ");
|
39
|
+
ids[SHPT_MULTIPATCH] = rb_intern("MultiPatch");
|
40
|
+
return ids;
|
41
|
+
}
|
42
|
+
|
43
|
+
static ID *FieldTypeNameTable(void)
|
44
|
+
{
|
45
|
+
static ID ids[FTInvalid + 1];
|
46
|
+
if (ids[FTString] != 0) {
|
47
|
+
return ids;
|
48
|
+
}
|
49
|
+
ids[FTString] = rb_intern("String");
|
50
|
+
ids[FTInteger] = rb_intern("Integer");
|
51
|
+
ids[FTDouble] = rb_intern("Float");
|
52
|
+
ids[FTLogical] = rb_intern("Logical");
|
53
|
+
ids[FTInvalid] = rb_intern("Invalid");
|
54
|
+
return ids;
|
55
|
+
}
|
56
|
+
|
57
|
+
#define SHPP_RING 5
|
58
|
+
|
59
|
+
static ID *PartTypeNameTable(void)
|
60
|
+
{
|
61
|
+
static ID ids[6];
|
62
|
+
if (ids[0] != 0) {
|
63
|
+
return ids;
|
64
|
+
}
|
65
|
+
ids[0] = rb_intern("TriangleStrip");
|
66
|
+
ids[1] = rb_intern("TriangleFan");
|
67
|
+
ids[2] = rb_intern("OuterRing");
|
68
|
+
ids[3] = rb_intern("InnerRing");
|
69
|
+
ids[4] = rb_intern("FirstRing");
|
70
|
+
ids[5] = rb_intern("Ring");
|
71
|
+
return ids;
|
72
|
+
}
|
73
|
+
|
74
|
+
static int Ruby2PartType(VALUE ptype)
|
75
|
+
{
|
76
|
+
ID given, *ids;
|
77
|
+
int i;
|
78
|
+
switch (TYPE(ptype)) {
|
79
|
+
case T_STRING:
|
80
|
+
case T_SYMBOL:
|
81
|
+
given = rb_to_id(ptype);
|
82
|
+
ids = PartTypeNameTable();
|
83
|
+
for (i = 0; i < 6; i++) {
|
84
|
+
if (ids[i] == given)
|
85
|
+
return i;
|
86
|
+
}
|
87
|
+
return -1;
|
88
|
+
break;
|
89
|
+
case T_FIXNUM:
|
90
|
+
return FIX2INT(ptype);
|
91
|
+
default:
|
92
|
+
return NUM2INT(ptype);
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
static VALUE PartType2Ruby(int part_type)
|
97
|
+
{
|
98
|
+
if (part_type < 0 || part_type > 5) {
|
99
|
+
return INT2NUM(part_type);
|
100
|
+
} else {
|
101
|
+
ID *ids;
|
102
|
+
ids = PartTypeNameTable();
|
103
|
+
return ID2SYM(ids[part_type]);
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
static DBFFieldType Ruby2FieldType(VALUE obj)
|
108
|
+
{
|
109
|
+
if (FIXNUM_P(obj)) {
|
110
|
+
int ft = FIX2INT(obj);
|
111
|
+
switch (ft) {
|
112
|
+
case FTString:
|
113
|
+
case FTInteger:
|
114
|
+
case FTDouble:
|
115
|
+
case FTLogical:
|
116
|
+
case FTInvalid:
|
117
|
+
return ft;
|
118
|
+
default:
|
119
|
+
rb_raise(rb_eArgError, "bad field_type %d", ft);
|
120
|
+
}
|
121
|
+
} else if (TYPE(obj) == T_STRING || TYPE(obj) == T_SYMBOL) {
|
122
|
+
ID given, *table;
|
123
|
+
int i;
|
124
|
+
given = rb_to_id(obj);
|
125
|
+
table = FieldTypeNameTable();
|
126
|
+
for (i = 0; i < FTInvalid; i++) {
|
127
|
+
if (given == table[i])
|
128
|
+
return i;
|
129
|
+
}
|
130
|
+
}
|
131
|
+
rb_raise(rb_eArgError, "bad field_type");
|
132
|
+
}
|
133
|
+
|
134
|
+
static VALUE FieldType2Ruby(DBFFieldType ftype)
|
135
|
+
{
|
136
|
+
int ft;
|
137
|
+
ft = ftype;
|
138
|
+
if (ft < 0 || ft >= FTInvalid)
|
139
|
+
return INT2FIX(ft);
|
140
|
+
return ID2SYM(FieldTypeNameTable()[ft]);
|
141
|
+
}
|
142
|
+
|
143
|
+
static VALUE ShapeType2Class(int nSHPType, VALUE klass)
|
144
|
+
{
|
145
|
+
switch (nSHPType) {
|
146
|
+
case SHPT_POINT: return cPoint;
|
147
|
+
case SHPT_POINTM: return cPointM;
|
148
|
+
case SHPT_POINTZ: return cPointZ;
|
149
|
+
case SHPT_ARC: return cArc;
|
150
|
+
case SHPT_ARCM: return cArcM;
|
151
|
+
case SHPT_ARCZ: return cArcZ;
|
152
|
+
case SHPT_POLYGON: return cPolygon;
|
153
|
+
case SHPT_POLYGONM: return cPolygonM;
|
154
|
+
case SHPT_POLYGONZ: return cPolygonZ;
|
155
|
+
case SHPT_MULTIPOINT: return cMultiPoint;
|
156
|
+
case SHPT_MULTIPOINTM: return cMultiPointM;
|
157
|
+
case SHPT_MULTIPOINTZ: return cMultiPointZ;
|
158
|
+
case SHPT_MULTIPATCH: return cMultiPatch;
|
159
|
+
case SHPT_NULL:
|
160
|
+
default:
|
161
|
+
return klass;
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
static VALUE ShapeType2Ruby(int nSHPType)
|
166
|
+
{
|
167
|
+
ID *ids;
|
168
|
+
switch (nSHPType) {
|
169
|
+
case SHPT_NULL:
|
170
|
+
case SHPT_POINT: case SHPT_POINTM: case SHPT_POINTZ:
|
171
|
+
case SHPT_ARC: case SHPT_ARCM: case SHPT_ARCZ:
|
172
|
+
case SHPT_POLYGON: case SHPT_POLYGONM: case SHPT_POLYGONZ:
|
173
|
+
case SHPT_MULTIPOINT: case SHPT_MULTIPOINTM: case SHPT_MULTIPOINTZ:
|
174
|
+
case SHPT_MULTIPATCH:
|
175
|
+
ids = ShapeTypeNameTable();
|
176
|
+
return ID2SYM(ids[nSHPType]);
|
177
|
+
default:
|
178
|
+
return INT2FIX(nSHPType);
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
static int ClassIs(VALUE a, VALUE b)
|
183
|
+
{
|
184
|
+
VALUE r;
|
185
|
+
static ID le = 0;
|
186
|
+
if (le == 0) {
|
187
|
+
le = rb_intern("<=");
|
188
|
+
}
|
189
|
+
r = rb_funcall(a, le, 1, b);
|
190
|
+
switch (TYPE(r)) {
|
191
|
+
case T_TRUE:
|
192
|
+
return 1;
|
193
|
+
case T_FALSE:
|
194
|
+
case T_NIL:
|
195
|
+
return 0;
|
196
|
+
default:
|
197
|
+
return -1;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
static int ShapeClass_to_Int(VALUE klass)
|
202
|
+
{
|
203
|
+
if (ClassIs(klass, cPoint)) {
|
204
|
+
if (ClassIs(klass, cPointZ)) {
|
205
|
+
return SHPT_POINTZ;
|
206
|
+
} else if (ClassIs(klass, cPointM)) {
|
207
|
+
return SHPT_POINTM;
|
208
|
+
}
|
209
|
+
return SHPT_POINT;
|
210
|
+
} else if (ClassIs(klass, cArc)) {
|
211
|
+
if (ClassIs(klass, cArcZ)) {
|
212
|
+
return SHPT_ARCZ;
|
213
|
+
} else if (ClassIs(klass, cArcM)) {
|
214
|
+
return SHPT_ARCM;
|
215
|
+
}
|
216
|
+
return SHPT_ARC;
|
217
|
+
} else if (ClassIs(klass, cPolygon)) {
|
218
|
+
if (ClassIs(klass, cPolygonZ)) {
|
219
|
+
return SHPT_POLYGONZ;
|
220
|
+
} else if (ClassIs(klass, cPolygonM)) {
|
221
|
+
return SHPT_POLYGONM;
|
222
|
+
}
|
223
|
+
return SHPT_POLYGON;
|
224
|
+
} else if (ClassIs(klass, cMultiPoint)) {
|
225
|
+
if (ClassIs(klass, cMultiPointZ)) {
|
226
|
+
return SHPT_MULTIPOINTZ;
|
227
|
+
} else if (ClassIs(klass, cMultiPointM)) {
|
228
|
+
return SHPT_MULTIPOINTM;
|
229
|
+
}
|
230
|
+
return SHPT_MULTIPOINT;
|
231
|
+
} else if (ClassIs(klass, cMultiPatch)) {
|
232
|
+
return SHPT_MULTIPATCH;
|
233
|
+
} else {
|
234
|
+
rb_raise(rb_eArgError, "invalid class");
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
static int ShapeSym_to_Int(VALUE stype)
|
239
|
+
{
|
240
|
+
ID arg, *ids;
|
241
|
+
int i;
|
242
|
+
ids = ShapeTypeNameTable();
|
243
|
+
arg = rb_to_id(stype);
|
244
|
+
for (i = 0; i <= SHPT_MULTIPATCH; i++) {
|
245
|
+
if (arg == ids[i])
|
246
|
+
return i;
|
247
|
+
}
|
248
|
+
rb_raise(rb_eArgError, "invalid shape class name");
|
249
|
+
return -1;
|
250
|
+
}
|
251
|
+
|
252
|
+
static int Ruby2ShapeType(VALUE stype)
|
253
|
+
{
|
254
|
+
switch (TYPE(stype)) {
|
255
|
+
case T_FIXNUM:
|
256
|
+
return FIX2INT(stype);
|
257
|
+
case T_CLASS:
|
258
|
+
return ShapeClass_to_Int(stype);
|
259
|
+
case T_STRING:
|
260
|
+
case T_SYMBOL:
|
261
|
+
return ShapeSym_to_Int(stype);
|
262
|
+
default:
|
263
|
+
rb_raise(rb_eArgError, "shape_type is Integer/String/Symbol/Class");
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
static VALUE DoubleUnpack(double *dp, unsigned num)
|
268
|
+
{
|
269
|
+
VALUE ary;
|
270
|
+
int i;
|
271
|
+
ary = rb_ary_new2(num);
|
272
|
+
for (i = 0; i < num; i++) {
|
273
|
+
rb_ary_push(ary, rb_float_new(dp[i]));
|
274
|
+
}
|
275
|
+
return ary;
|
276
|
+
}
|
277
|
+
|
278
|
+
static VALUE DoubleUnpackM(double *dp, unsigned num, int mpos)
|
279
|
+
{
|
280
|
+
VALUE ary;
|
281
|
+
int i;
|
282
|
+
ary = rb_ary_new2(num);
|
283
|
+
for (i = 0; i < num; i++) {
|
284
|
+
if ((mpos == -1) || (i == mpos)) {
|
285
|
+
rb_ary_push(ary, SHP_FLOAT_NEW(dp[i]));
|
286
|
+
} else {
|
287
|
+
rb_ary_push(ary, rb_float_new(dp[i]));
|
288
|
+
}
|
289
|
+
}
|
290
|
+
return ary;
|
291
|
+
}
|
292
|
+
|
293
|
+
static VALUE IntUnpack(int *up, unsigned num)
|
294
|
+
{
|
295
|
+
static ID unpackid;
|
296
|
+
static VALUE unpackfmt = 0;
|
297
|
+
VALUE buf;
|
298
|
+
if (unpackfmt == 0) {
|
299
|
+
unpackid = rb_intern("unpack");
|
300
|
+
unpackfmt = rb_str_new2("i*");
|
301
|
+
rb_global_variable(&unpackfmt);
|
302
|
+
}
|
303
|
+
buf = rb_str_new((char *)up, sizeof(int) * num);
|
304
|
+
return rb_funcall(buf, unpackid, 1, unpackfmt);
|
305
|
+
}
|
306
|
+
|
307
|
+
static VALUE SecureObject(VALUE obj, const char *name) {
|
308
|
+
if (OBJ_TAINTED(obj) && rb_safe_level() >= 1) {
|
309
|
+
rb_raise(rb_eSecurityError, "tainted %s", name);
|
310
|
+
}
|
311
|
+
return obj;
|
312
|
+
}
|
313
|
+
|