shapelib 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|