librtree 0.8.6 → 0.8.7
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.
- checksums.yaml +4 -4
- data/ext/rtree/rtree.c +204 -93
- data/lib/rtree.rb +149 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b33e172341a9e44682c139df3a6b92198b3dd83059340da9fb8752444afbac70
|
|
4
|
+
data.tar.gz: 7ba6d8c71b6afeb8e5dedde55ff08074db758fa7ea150a67195ff07ca426a312
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d4440a12038bd07dcb458ff993269fd72ac3826753f6e2757b86f19913a1cc748d7af1f37a7355e015d5a6dd3a750b8335a6f87d2a1dbdc5e4ef5387f9424f6a
|
|
7
|
+
data.tar.gz: ce193b26ab45e5ca2cab29c0c145a9432440355585e5cc5e226bbe0e762b3d4c33bcd693626ccd3f60eaad11513c94d3e8246e86cf8b703a7d89f19b22090d1b
|
data/ext/rtree/rtree.c
CHANGED
|
@@ -4,48 +4,33 @@
|
|
|
4
4
|
|
|
5
5
|
#include <rtree.h>
|
|
6
6
|
#include <rtree/package.h>
|
|
7
|
+
#include <rtree/postscript.h>
|
|
7
8
|
|
|
8
9
|
#include <errno.h>
|
|
9
10
|
#include <stdint.h>
|
|
10
11
|
|
|
12
|
+
static rb_data_type_t style_type;
|
|
13
|
+
static rb_data_type_t rtree_type;
|
|
11
14
|
|
|
12
|
-
static void
|
|
15
|
+
static void rt_dfree(void *p)
|
|
13
16
|
{
|
|
14
17
|
rtree_destroy((rtree_t*)p);
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
static size_t
|
|
20
|
+
static size_t rt_dsize(const void *p)
|
|
18
21
|
{
|
|
19
22
|
return rtree_bytes((const rtree_t*)p);
|
|
20
23
|
}
|
|
21
24
|
|
|
22
|
-
static
|
|
23
|
-
.wrap_struct_name = "rtree-wrap",
|
|
24
|
-
.function = {
|
|
25
|
-
.dmark = NULL,
|
|
26
|
-
.dfree = lrt_dfree,
|
|
27
|
-
.dsize = lrt_dsize,
|
|
28
|
-
#if RUBY_API_VERSION_CODE < 20700
|
|
29
|
-
.reserved = { NULL, NULL }
|
|
30
|
-
#else
|
|
31
|
-
.dcompact = NULL,
|
|
32
|
-
.reserved = { NULL }
|
|
33
|
-
#endif
|
|
34
|
-
},
|
|
35
|
-
.parent = NULL,
|
|
36
|
-
.data = NULL,
|
|
37
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
static VALUE lrt_alloc(VALUE cls)
|
|
25
|
+
static VALUE rt_alloc(VALUE cls)
|
|
41
26
|
{
|
|
42
27
|
rtree_t *rtree;;
|
|
43
28
|
if ((rtree = rtree_alloc()) == NULL)
|
|
44
29
|
rb_raise(rb_eNoMemError, "failed to alloc rtree");
|
|
45
|
-
return TypedData_Wrap_Struct(cls, &
|
|
30
|
+
return TypedData_Wrap_Struct(cls, &rtree_type, rtree);
|
|
46
31
|
}
|
|
47
32
|
|
|
48
|
-
static VALUE
|
|
33
|
+
static VALUE rt_init(VALUE self, VALUE dim_obj, VALUE flags_obj)
|
|
49
34
|
{
|
|
50
35
|
Check_Type(dim_obj, T_FIXNUM);
|
|
51
36
|
size_t dim = FIX2ULONG(dim_obj);
|
|
@@ -54,7 +39,7 @@ static VALUE lrt_init(VALUE self, VALUE dim_obj, VALUE flags_obj)
|
|
|
54
39
|
state_flags_t flags = FIX2UINT(flags_obj);
|
|
55
40
|
|
|
56
41
|
rtree_t *rtree;
|
|
57
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
42
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
58
43
|
|
|
59
44
|
if ((rtree_init(rtree, dim, flags)) != 0)
|
|
60
45
|
rb_raise(rb_eNoMemError, "failed to init rtree");
|
|
@@ -62,28 +47,28 @@ static VALUE lrt_init(VALUE self, VALUE dim_obj, VALUE flags_obj)
|
|
|
62
47
|
return self;
|
|
63
48
|
}
|
|
64
49
|
|
|
65
|
-
static VALUE
|
|
50
|
+
static VALUE rt_release(VALUE self)
|
|
66
51
|
{
|
|
67
52
|
rtree_t *rtree;
|
|
68
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
53
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
69
54
|
rtree_destroy(rtree);
|
|
70
55
|
return self;
|
|
71
56
|
}
|
|
72
57
|
|
|
73
|
-
static VALUE
|
|
58
|
+
static VALUE rt_height(VALUE self)
|
|
74
59
|
{
|
|
75
60
|
rtree_t *rtree;
|
|
76
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
61
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
77
62
|
return INT2NUM(rtree_height(rtree));
|
|
78
63
|
}
|
|
79
64
|
|
|
80
|
-
static VALUE
|
|
65
|
+
static VALUE rt_add_rect(VALUE self, VALUE id_obj, VALUE coord_obj)
|
|
81
66
|
{
|
|
82
67
|
Check_Type(coord_obj, T_ARRAY);
|
|
83
68
|
Check_Type(id_obj, T_FIXNUM);
|
|
84
69
|
|
|
85
70
|
rtree_t *rtree;
|
|
86
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
71
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
87
72
|
|
|
88
73
|
rtree_id_t
|
|
89
74
|
id = FIX2ULONG(id_obj);
|
|
@@ -135,13 +120,13 @@ static int update_cb(rtree_id_t id, rtree_coord_t *coord, void *context)
|
|
|
135
120
|
return 0;
|
|
136
121
|
}
|
|
137
122
|
|
|
138
|
-
static VALUE
|
|
123
|
+
static VALUE rt_update(VALUE self)
|
|
139
124
|
{
|
|
140
125
|
if (!rb_block_given_p())
|
|
141
126
|
rb_raise(rb_eArgError, "Expected block");
|
|
142
127
|
|
|
143
128
|
rtree_t *rtree;
|
|
144
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
129
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
145
130
|
|
|
146
131
|
size_t len = 2 * state_dims(rtree->state);
|
|
147
132
|
int err = rtree_update(rtree, update_cb, &len);
|
|
@@ -169,7 +154,7 @@ static int search_cb(rtree_id_t id, void *context)
|
|
|
169
154
|
return 0;
|
|
170
155
|
}
|
|
171
156
|
|
|
172
|
-
static VALUE
|
|
157
|
+
static VALUE rt_search(VALUE self, VALUE coord_obj)
|
|
173
158
|
{
|
|
174
159
|
if (!rb_block_given_p())
|
|
175
160
|
rb_raise(rb_eArgError, "Expected block");
|
|
@@ -177,7 +162,7 @@ static VALUE lrt_search(VALUE self, VALUE coord_obj)
|
|
|
177
162
|
Check_Type(coord_obj, T_ARRAY);
|
|
178
163
|
|
|
179
164
|
rtree_t *rtree;
|
|
180
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
165
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
181
166
|
|
|
182
167
|
size_t
|
|
183
168
|
len = RARRAY_LEN(coord_obj),
|
|
@@ -220,21 +205,21 @@ static VALUE deserialise(VALUE cls, VALUE io_obj, deserialise_t *f)
|
|
|
220
205
|
rb_raise(rb_eRuntimeError, "Failed read from stream");
|
|
221
206
|
}
|
|
222
207
|
|
|
223
|
-
return TypedData_Wrap_Struct(cls, &
|
|
208
|
+
return TypedData_Wrap_Struct(cls, &rtree_type, rtree);
|
|
224
209
|
}
|
|
225
210
|
|
|
226
|
-
static VALUE
|
|
211
|
+
static VALUE rt_json_read(VALUE cls, VALUE io_obj)
|
|
227
212
|
{
|
|
228
213
|
return deserialise(cls, io_obj, rtree_json_read);
|
|
229
214
|
}
|
|
230
215
|
|
|
231
|
-
static VALUE
|
|
216
|
+
static VALUE rt_bsrt_read(VALUE cls, VALUE io_obj)
|
|
232
217
|
{
|
|
233
218
|
return deserialise(cls, io_obj, rtree_bsrt_read);
|
|
234
219
|
}
|
|
235
220
|
|
|
236
|
-
static VALUE
|
|
237
|
-
|
|
221
|
+
static VALUE rt_csv_read(VALUE cls,
|
|
222
|
+
VALUE io_obj, VALUE dim_obj, VALUE flags_obj)
|
|
238
223
|
{
|
|
239
224
|
Check_Type(io_obj, T_FILE);
|
|
240
225
|
rb_io_t *io;
|
|
@@ -259,7 +244,7 @@ static VALUE lrt_csv_read(VALUE cls,
|
|
|
259
244
|
rb_raise(rb_eRuntimeError, "Failed read from stream");
|
|
260
245
|
}
|
|
261
246
|
|
|
262
|
-
return TypedData_Wrap_Struct(cls, &
|
|
247
|
+
return TypedData_Wrap_Struct(cls, &rtree_type, rtree);
|
|
263
248
|
}
|
|
264
249
|
|
|
265
250
|
/* serialisation */
|
|
@@ -277,7 +262,7 @@ static VALUE serialise(VALUE self, VALUE io_obj, serialise_t *f)
|
|
|
277
262
|
FILE *fp = rb_io_stdio_file(io);
|
|
278
263
|
|
|
279
264
|
rtree_t *rtree;
|
|
280
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
265
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
281
266
|
|
|
282
267
|
int err = f(rtree, fp);
|
|
283
268
|
if (err != 0)
|
|
@@ -286,22 +271,22 @@ static VALUE serialise(VALUE self, VALUE io_obj, serialise_t *f)
|
|
|
286
271
|
return self;
|
|
287
272
|
}
|
|
288
273
|
|
|
289
|
-
static VALUE
|
|
274
|
+
static VALUE rt_json_write(VALUE self, VALUE io_obj)
|
|
290
275
|
{
|
|
291
276
|
return serialise(self, io_obj, rtree_json_write);
|
|
292
277
|
}
|
|
293
278
|
|
|
294
|
-
static VALUE
|
|
279
|
+
static VALUE rt_bsrt_write(VALUE self, VALUE io_obj)
|
|
295
280
|
{
|
|
296
281
|
return serialise(self, io_obj, rtree_bsrt_write);
|
|
297
282
|
}
|
|
298
283
|
|
|
299
|
-
static VALUE
|
|
284
|
+
static VALUE rt_identical(VALUE self, VALUE other)
|
|
300
285
|
{
|
|
301
286
|
rtree_t *rtree_self, *rtree_other;
|
|
302
287
|
|
|
303
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
304
|
-
TypedData_Get_Struct(other, rtree_t, &
|
|
288
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree_self);
|
|
289
|
+
TypedData_Get_Struct(other, rtree_t, &rtree_type, rtree_other);
|
|
305
290
|
|
|
306
291
|
if (rtree_identical(rtree_self, rtree_other))
|
|
307
292
|
return Qtrue;
|
|
@@ -309,10 +294,10 @@ static VALUE lrt_identical(VALUE self, VALUE other)
|
|
|
309
294
|
return Qfalse;
|
|
310
295
|
}
|
|
311
296
|
|
|
312
|
-
static VALUE
|
|
297
|
+
static VALUE rt_clone(VALUE self)
|
|
313
298
|
{
|
|
314
299
|
rtree_t *rtree;
|
|
315
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
300
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
316
301
|
|
|
317
302
|
rtree_t *clone;
|
|
318
303
|
errno = 0;
|
|
@@ -324,105 +309,231 @@ static VALUE lrt_clone(VALUE self)
|
|
|
324
309
|
rb_raise(rb_eRuntimeError, "Failed clone");
|
|
325
310
|
}
|
|
326
311
|
|
|
327
|
-
return TypedData_Wrap_Struct(CLASS_OF(self), &
|
|
312
|
+
return TypedData_Wrap_Struct(CLASS_OF(self), &rtree_type, clone);
|
|
328
313
|
}
|
|
329
314
|
|
|
330
315
|
static VALUE state_size_access(VALUE self, size_t (*f)(const state_t*))
|
|
331
316
|
{
|
|
332
317
|
rtree_t *rtree;
|
|
333
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
318
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
334
319
|
return INT2NUM(f(rtree->state));
|
|
335
320
|
}
|
|
336
321
|
|
|
337
|
-
static VALUE
|
|
322
|
+
static VALUE rt_dim(VALUE self)
|
|
338
323
|
{
|
|
339
324
|
return state_size_access(self, state_dims);
|
|
340
325
|
}
|
|
341
326
|
|
|
342
|
-
static VALUE
|
|
327
|
+
static VALUE rt_page_size(VALUE self)
|
|
343
328
|
{
|
|
344
329
|
return state_size_access(self, state_page_size);
|
|
345
330
|
}
|
|
346
331
|
|
|
347
|
-
static VALUE
|
|
332
|
+
static VALUE rt_node_size(VALUE self)
|
|
348
333
|
{
|
|
349
334
|
return state_size_access(self, state_node_size);
|
|
350
335
|
}
|
|
351
336
|
|
|
352
|
-
static VALUE
|
|
337
|
+
static VALUE rt_rect_size(VALUE self)
|
|
353
338
|
{
|
|
354
339
|
return state_size_access(self, state_rect_size);
|
|
355
340
|
}
|
|
356
341
|
|
|
357
|
-
static VALUE
|
|
342
|
+
static VALUE rt_branch_size(VALUE self)
|
|
358
343
|
{
|
|
359
344
|
return state_size_access(self, state_branch_size);
|
|
360
345
|
}
|
|
361
346
|
|
|
362
|
-
static VALUE
|
|
347
|
+
static VALUE rt_branching_factor(VALUE self)
|
|
363
348
|
{
|
|
364
349
|
return state_size_access(self, state_branching_factor);
|
|
365
350
|
}
|
|
366
351
|
|
|
367
|
-
static VALUE
|
|
352
|
+
static VALUE rt_unit_sphere_volume(VALUE self)
|
|
368
353
|
{
|
|
369
354
|
rtree_t *rtree;
|
|
370
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
355
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
371
356
|
return DBL2NUM(state_unit_sphere_volume(rtree->state));
|
|
372
357
|
}
|
|
373
358
|
|
|
374
|
-
static VALUE
|
|
359
|
+
static VALUE rt_size(VALUE self)
|
|
375
360
|
{
|
|
376
361
|
rtree_t *rtree;
|
|
377
|
-
TypedData_Get_Struct(self, rtree_t, &
|
|
362
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
378
363
|
return INT2NUM(rtree_bytes(rtree));
|
|
379
364
|
}
|
|
380
365
|
|
|
381
|
-
static VALUE
|
|
366
|
+
static VALUE rt_version(VALUE self)
|
|
382
367
|
{
|
|
383
368
|
return rb_str_new_cstr(rtree_package_version);
|
|
384
369
|
}
|
|
385
370
|
|
|
386
|
-
static VALUE
|
|
371
|
+
static VALUE rt_bugreport(VALUE self)
|
|
387
372
|
{
|
|
388
373
|
return rb_str_new_cstr(rtree_package_bugreport);
|
|
389
374
|
}
|
|
390
375
|
|
|
391
|
-
static VALUE
|
|
376
|
+
static VALUE rt_url(VALUE self)
|
|
392
377
|
{
|
|
393
378
|
return rb_str_new_cstr(rtree_package_url);
|
|
394
379
|
}
|
|
395
380
|
|
|
381
|
+
static VALUE rt_postscript(VALUE self,
|
|
382
|
+
VALUE style_obj,
|
|
383
|
+
VALUE axis_obj,
|
|
384
|
+
VALUE extent_obj,
|
|
385
|
+
VALUE margin_obj,
|
|
386
|
+
VALUE io_obj)
|
|
387
|
+
{
|
|
388
|
+
rtree_t *rtree;
|
|
389
|
+
TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
|
|
390
|
+
|
|
391
|
+
style_t *style;
|
|
392
|
+
TypedData_Get_Struct(style_obj, style_t, &style_type, style);
|
|
393
|
+
|
|
394
|
+
Check_Type(io_obj, T_FILE);
|
|
395
|
+
rb_io_t *io;
|
|
396
|
+
GetOpenFile(io_obj, io);
|
|
397
|
+
rb_io_check_initialized(io);
|
|
398
|
+
rb_io_check_writable(io);
|
|
399
|
+
FILE *fp = rb_io_stdio_file(io);
|
|
400
|
+
|
|
401
|
+
float
|
|
402
|
+
extent = NUM2DBL(extent_obj),
|
|
403
|
+
margin = NUM2DBL(margin_obj);
|
|
404
|
+
|
|
405
|
+
Check_Type(axis_obj, T_FIXNUM);
|
|
406
|
+
extent_axis_t axis = FIX2UINT(axis_obj);
|
|
407
|
+
|
|
408
|
+
rtree_postscript_t opt =
|
|
409
|
+
{
|
|
410
|
+
.style = style,
|
|
411
|
+
.axis = axis,
|
|
412
|
+
.extent = extent,
|
|
413
|
+
.margin = margin,
|
|
414
|
+
.title = "librtree-ruby output"
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
int err;
|
|
418
|
+
if ((err = rtree_postscript(rtree, &opt, fp)) != 0)
|
|
419
|
+
rb_raise(rb_eRuntimeError, "librtree: %s", rtree_strerror(err));
|
|
420
|
+
|
|
421
|
+
return Qnil;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
static rb_data_type_t rtree_type = {
|
|
425
|
+
.wrap_struct_name = "rtree-wrap",
|
|
426
|
+
.function = {
|
|
427
|
+
.dmark = NULL,
|
|
428
|
+
.dfree = rt_dfree,
|
|
429
|
+
.dsize = rt_dsize,
|
|
430
|
+
#if RUBY_API_VERSION_CODE < 20700
|
|
431
|
+
.reserved = { NULL, NULL }
|
|
432
|
+
#else
|
|
433
|
+
.dcompact = NULL,
|
|
434
|
+
.reserved = { NULL }
|
|
435
|
+
#endif
|
|
436
|
+
},
|
|
437
|
+
.parent = NULL,
|
|
438
|
+
.data = NULL,
|
|
439
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
/* RTree::Style */
|
|
443
|
+
|
|
444
|
+
static void st_dfree(void *p)
|
|
445
|
+
{
|
|
446
|
+
postscript_style_destroy((style_t*)p);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
static VALUE st_release(VALUE self)
|
|
450
|
+
{
|
|
451
|
+
style_t *style;
|
|
452
|
+
TypedData_Get_Struct(self, style_t, &style_type, style);
|
|
453
|
+
postscript_style_destroy(style);
|
|
454
|
+
return self;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
static VALUE st_json_read(VALUE cls, VALUE io_obj)
|
|
458
|
+
{
|
|
459
|
+
Check_Type(io_obj, T_FILE);
|
|
460
|
+
|
|
461
|
+
rb_io_t *io;
|
|
462
|
+
GetOpenFile(io_obj, io);
|
|
463
|
+
rb_io_check_initialized(io);
|
|
464
|
+
rb_io_check_readable(io);
|
|
465
|
+
FILE *fp = rb_io_stdio_file(io);
|
|
466
|
+
|
|
467
|
+
style_t *style;
|
|
468
|
+
errno = 0;
|
|
469
|
+
|
|
470
|
+
if ((style = postscript_style_read(fp)) == NULL)
|
|
471
|
+
{
|
|
472
|
+
if (errno)
|
|
473
|
+
rb_sys_fail(__func__);
|
|
474
|
+
else
|
|
475
|
+
rb_raise(rb_eRuntimeError, "Failed read from stream");
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
return TypedData_Wrap_Struct(cls, &style_type, style);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
static rb_data_type_t style_type = {
|
|
482
|
+
.wrap_struct_name = "style-wrap",
|
|
483
|
+
.function = {
|
|
484
|
+
.dmark = NULL,
|
|
485
|
+
.dfree = st_dfree,
|
|
486
|
+
.dsize = NULL,
|
|
487
|
+
#if RUBY_API_VERSION_CODE < 20700
|
|
488
|
+
.reserved = { NULL, NULL }
|
|
489
|
+
#else
|
|
490
|
+
.dcompact = NULL,
|
|
491
|
+
.reserved = { NULL }
|
|
492
|
+
#endif
|
|
493
|
+
},
|
|
494
|
+
.parent = NULL,
|
|
495
|
+
.data = NULL,
|
|
496
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
497
|
+
};
|
|
498
|
+
|
|
396
499
|
void Init_rtree(void)
|
|
397
500
|
{
|
|
398
|
-
VALUE
|
|
399
|
-
|
|
400
|
-
rb_define_alloc_func(
|
|
401
|
-
rb_define_method(
|
|
402
|
-
rb_define_method(
|
|
403
|
-
rb_define_method(
|
|
404
|
-
rb_define_method(
|
|
405
|
-
rb_define_method(
|
|
406
|
-
rb_define_method(
|
|
407
|
-
rb_define_method(
|
|
408
|
-
rb_define_method(
|
|
409
|
-
rb_define_method(
|
|
410
|
-
rb_define_method(
|
|
411
|
-
rb_define_method(
|
|
412
|
-
rb_define_method(
|
|
413
|
-
rb_define_method(
|
|
414
|
-
rb_define_method(
|
|
415
|
-
rb_define_method(
|
|
416
|
-
rb_define_method(
|
|
417
|
-
rb_define_method(
|
|
418
|
-
rb_define_method(
|
|
419
|
-
|
|
420
|
-
rb_define_singleton_method(
|
|
421
|
-
rb_define_singleton_method(
|
|
422
|
-
rb_define_singleton_method(
|
|
423
|
-
rb_define_singleton_method(
|
|
424
|
-
rb_define_singleton_method(
|
|
425
|
-
|
|
426
|
-
rb_define_const(
|
|
427
|
-
rb_define_const(
|
|
501
|
+
VALUE cRTree = rb_const_get(rb_cObject, rb_intern("RTreeC"));
|
|
502
|
+
|
|
503
|
+
rb_define_alloc_func(cRTree, rt_alloc);
|
|
504
|
+
rb_define_method(cRTree, "initialize", rt_init, 2);
|
|
505
|
+
rb_define_method(cRTree, "free", rt_release, 0);
|
|
506
|
+
rb_define_method(cRTree, "clone", rt_clone, 0);
|
|
507
|
+
rb_define_method(cRTree, "update!", rt_update, 0);
|
|
508
|
+
rb_define_method(cRTree, "height", rt_height, 0);
|
|
509
|
+
rb_define_method(cRTree, "add_rect", rt_add_rect, 2);
|
|
510
|
+
rb_define_method(cRTree, "search", rt_search, 1);
|
|
511
|
+
rb_define_method(cRTree, "json_write", rt_json_write, 1);
|
|
512
|
+
rb_define_method(cRTree, "bsrt_write", rt_bsrt_write, 1);
|
|
513
|
+
rb_define_method(cRTree, "eq?", rt_identical, 1);
|
|
514
|
+
rb_define_method(cRTree, "dim", rt_dim, 0);
|
|
515
|
+
rb_define_method(cRTree, "size", rt_size, 0);
|
|
516
|
+
rb_define_method(cRTree, "page_size", rt_page_size, 0);
|
|
517
|
+
rb_define_method(cRTree, "node_size", rt_node_size, 0);
|
|
518
|
+
rb_define_method(cRTree, "rect_size", rt_rect_size, 0);
|
|
519
|
+
rb_define_method(cRTree, "branch_size", rt_branch_size, 0);
|
|
520
|
+
rb_define_method(cRTree, "branching_factor", rt_branching_factor, 0);
|
|
521
|
+
rb_define_method(cRTree, "unit_sphere_volume", rt_unit_sphere_volume, 0);
|
|
522
|
+
rb_define_method(cRTree, "postscript", rt_postscript, 5);
|
|
523
|
+
rb_define_singleton_method(cRTree, "version", rt_version, 0);
|
|
524
|
+
rb_define_singleton_method(cRTree, "bugreport", rt_bugreport, 0);
|
|
525
|
+
rb_define_singleton_method(cRTree, "url", rt_url, 0);
|
|
526
|
+
rb_define_singleton_method(cRTree, "json_read", rt_json_read, 1);
|
|
527
|
+
rb_define_singleton_method(cRTree, "bsrt_read", rt_bsrt_read, 1);
|
|
528
|
+
rb_define_singleton_method(cRTree, "csv_read", rt_csv_read, 3);
|
|
529
|
+
rb_define_const(cRTree, "SPLIT_QUADRATIC", INT2NUM(RTREE_SPLIT_QUADRATIC));
|
|
530
|
+
rb_define_const(cRTree, "SPLIT_LINEAR", INT2NUM(RTREE_SPLIT_LINEAR));
|
|
531
|
+
rb_define_const(cRTree, "SPLIT_GREENE", INT2NUM(RTREE_SPLIT_GREENE));
|
|
532
|
+
rb_define_const(cRTree, "AXIS_HEIGHT", INT2NUM(axis_height));
|
|
533
|
+
rb_define_const(cRTree, "AXIS_WIDTH", INT2NUM(axis_width));
|
|
534
|
+
|
|
535
|
+
VALUE cStyle = rb_define_class_under(cRTree, "StyleC", rb_cObject);
|
|
536
|
+
|
|
537
|
+
rb_define_method(cStyle, "free", st_release, 0);
|
|
538
|
+
rb_define_singleton_method(cStyle, "json_read", st_json_read, 1);
|
|
428
539
|
}
|
data/lib/rtree.rb
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
# The Ruby/C interface
|
|
2
|
-
|
|
1
|
+
# The Ruby/C interface to RTree, not documented in YARD.
|
|
2
|
+
#
|
|
3
|
+
class RTreeC
|
|
4
|
+
# The Ruby/C interface to RTree::Style, not documented in YARD.
|
|
5
|
+
#
|
|
6
|
+
class StyleC ; end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'json'
|
|
3
10
|
|
|
4
11
|
# @author RTree J. J. Green
|
|
5
12
|
#
|
|
@@ -61,6 +68,7 @@ class RTree < RTreeC
|
|
|
61
68
|
# @see #json_write
|
|
62
69
|
# @example Read from file
|
|
63
70
|
# rtree = File.open('rtree.json', 'r') { |io| RTree.json_read(io) }
|
|
71
|
+
#
|
|
64
72
|
def json_read(io)
|
|
65
73
|
super
|
|
66
74
|
end
|
|
@@ -69,6 +77,7 @@ class RTree < RTreeC
|
|
|
69
77
|
# @param json [String] a JSON string
|
|
70
78
|
# @return [RTree] the newly instantiated RTree
|
|
71
79
|
# @see #to_json
|
|
80
|
+
#
|
|
72
81
|
def from_json(json)
|
|
73
82
|
deserialise(json, Encoding::UTF_8) { |io| json_read(io) }
|
|
74
83
|
end
|
|
@@ -80,6 +89,7 @@ class RTree < RTreeC
|
|
|
80
89
|
# @see #bsrt_write
|
|
81
90
|
# @example Read from file
|
|
82
91
|
# rtree = File.open('rtree.bsrt', 'r') { |io| RTree.bsrt_read(io) }
|
|
92
|
+
#
|
|
83
93
|
def bsrt_read(io)
|
|
84
94
|
super
|
|
85
95
|
end
|
|
@@ -89,6 +99,7 @@ class RTree < RTreeC
|
|
|
89
99
|
# @param bsrt [String] a binary encoded string
|
|
90
100
|
# @return [RTree] the newly instantiated RTree
|
|
91
101
|
# @see #to_bsrt
|
|
102
|
+
#
|
|
92
103
|
def from_bsrt(bsrt)
|
|
93
104
|
deserialise(bsrt, Encoding::BINARY) { |io| bsrt_read(io) }
|
|
94
105
|
end
|
|
@@ -104,6 +115,7 @@ class RTree < RTreeC
|
|
|
104
115
|
# Extra columns may be present and will be ignored (this
|
|
105
116
|
# useful feature is the reason that the dimension is a required
|
|
106
117
|
# argument).
|
|
118
|
+
#
|
|
107
119
|
def csv_read(io, dim, split: :quadratic, node_page: 0)
|
|
108
120
|
flags = split_flag(split) | node_page_flag(node_page)
|
|
109
121
|
super(io, dim, flags)
|
|
@@ -114,6 +126,7 @@ class RTree < RTreeC
|
|
|
114
126
|
# @param dim [Integer] the dimension of the tree
|
|
115
127
|
# @param kwarg [Hash] As for {.csv_read}
|
|
116
128
|
# @return [RTree] the newly built RTree
|
|
129
|
+
#
|
|
117
130
|
def from_csv(csv, dim, **kwarg)
|
|
118
131
|
deserialise(csv, Encoding::UTF_8) do |io|
|
|
119
132
|
csv_read(io, dim, **kwarg)
|
|
@@ -121,21 +134,25 @@ class RTree < RTreeC
|
|
|
121
134
|
end
|
|
122
135
|
|
|
123
136
|
# @return [Array<Integer>] version of librtree
|
|
137
|
+
#
|
|
124
138
|
def version
|
|
125
139
|
@version ||= super.split('.').map(&:to_i)
|
|
126
140
|
end
|
|
127
141
|
|
|
128
142
|
# @return [String] email address for librtree bug reports
|
|
143
|
+
#
|
|
129
144
|
def bugreport
|
|
130
145
|
super
|
|
131
146
|
end
|
|
132
147
|
|
|
133
148
|
# @return [String] librtree homepage
|
|
149
|
+
#
|
|
134
150
|
def url
|
|
135
151
|
super
|
|
136
152
|
end
|
|
137
153
|
|
|
138
154
|
# @!visibility private
|
|
155
|
+
#
|
|
139
156
|
def split_flag(split)
|
|
140
157
|
case split
|
|
141
158
|
when :quadratic
|
|
@@ -150,6 +167,7 @@ class RTree < RTreeC
|
|
|
150
167
|
end
|
|
151
168
|
|
|
152
169
|
# @!visibility private
|
|
170
|
+
#
|
|
153
171
|
def node_page_flag(node_page)
|
|
154
172
|
node_page << 2
|
|
155
173
|
end
|
|
@@ -184,7 +202,7 @@ class RTree < RTreeC
|
|
|
184
202
|
# @param dim [Integer] the dimension of the tree
|
|
185
203
|
# @param split [:linear, :quadratic, :greene] determines the splitting
|
|
186
204
|
# strategy, the linear strategy is faster to build, the quadratic
|
|
187
|
-
# and greene strategies
|
|
205
|
+
# and greene strategies produce better-quality R-trees which are
|
|
188
206
|
# faster to query.
|
|
189
207
|
# @param node_page [Integer] the nodes-per-page value. This value can
|
|
190
208
|
# affect performance quite dramatically, particularly build time. A
|
|
@@ -195,6 +213,7 @@ class RTree < RTreeC
|
|
|
195
213
|
# You may get better performance for your use-case by manual
|
|
196
214
|
# experimentation, but zero is a good place to start.
|
|
197
215
|
# @return [RTree] the newly instantiated RTree
|
|
216
|
+
#
|
|
198
217
|
def initialize(dim, split: :quadratic, node_page: 0)
|
|
199
218
|
@split = split
|
|
200
219
|
@node_page = node_page
|
|
@@ -203,6 +222,7 @@ class RTree < RTreeC
|
|
|
203
222
|
|
|
204
223
|
# Create a deep copy
|
|
205
224
|
# @return [RTree] a deep copy of the RTree
|
|
225
|
+
#
|
|
206
226
|
def clone
|
|
207
227
|
super
|
|
208
228
|
end
|
|
@@ -219,6 +239,7 @@ class RTree < RTreeC
|
|
|
219
239
|
# @example Add a rectangle to a dimension two RTree
|
|
220
240
|
# rtree = RTree.new(2)
|
|
221
241
|
# rtree.add_rect(7, [0, 0, 1, 1])
|
|
242
|
+
#
|
|
222
243
|
def add_rect(id, coords)
|
|
223
244
|
super
|
|
224
245
|
end
|
|
@@ -228,6 +249,7 @@ class RTree < RTreeC
|
|
|
228
249
|
# @return [Array<Integer>] the ids of all rectangles which intersect
|
|
229
250
|
# the search rectangle. If a block is given then these values will
|
|
230
251
|
# be yielded to the block (one at a time).
|
|
252
|
+
#
|
|
231
253
|
def search(coords)
|
|
232
254
|
if block_given? then
|
|
233
255
|
super
|
|
@@ -253,18 +275,21 @@ class RTree < RTreeC
|
|
|
253
275
|
# block and then convert the returned Ruby Floats to C; so we would
|
|
254
276
|
# expect that it loses much of its competitive advantage when
|
|
255
277
|
# compared to an R-tree rebuild.
|
|
278
|
+
#
|
|
256
279
|
def update!
|
|
257
280
|
super
|
|
258
281
|
end
|
|
259
282
|
|
|
260
283
|
# The height to the tree in the usual mathematical sense
|
|
261
284
|
# @return [Integer] the tree height
|
|
285
|
+
#
|
|
262
286
|
def height
|
|
263
287
|
super
|
|
264
288
|
end
|
|
265
289
|
|
|
266
290
|
# Whether the RTree has any rectangles or not
|
|
267
291
|
# @return [Boolean] true if the RTree is empty
|
|
292
|
+
#
|
|
268
293
|
def empty?
|
|
269
294
|
height == 0
|
|
270
295
|
end
|
|
@@ -275,6 +300,7 @@ class RTree < RTreeC
|
|
|
275
300
|
# @see .json_read
|
|
276
301
|
# @example Write to file
|
|
277
302
|
# File.open('rtree.json', 'w') { |io| rtree.json_write(io) }
|
|
303
|
+
#
|
|
278
304
|
def json_write(io)
|
|
279
305
|
super
|
|
280
306
|
end
|
|
@@ -285,6 +311,7 @@ class RTree < RTreeC
|
|
|
285
311
|
# @see .bsrt_read
|
|
286
312
|
# @example Write to file
|
|
287
313
|
# File.open('rtree.bsrt', 'w') { |io| rtree.bsrt_write(io) }
|
|
314
|
+
#
|
|
288
315
|
def bsrt_write(io)
|
|
289
316
|
super
|
|
290
317
|
end
|
|
@@ -292,6 +319,7 @@ class RTree < RTreeC
|
|
|
292
319
|
# Serialise to JSON string
|
|
293
320
|
# @return [String] the UTF-8 encoded JSON
|
|
294
321
|
# @see .from_json
|
|
322
|
+
#
|
|
295
323
|
def to_json
|
|
296
324
|
serialise(Encoding::UTF_8) { |io| json_write(io) }
|
|
297
325
|
end
|
|
@@ -299,12 +327,14 @@ class RTree < RTreeC
|
|
|
299
327
|
# Serialise to BSRT string
|
|
300
328
|
# @return [String] the binary encoded BSRT
|
|
301
329
|
# @see .from_bsrt
|
|
330
|
+
#
|
|
302
331
|
def to_bsrt
|
|
303
332
|
serialise(Encoding::BINARY) { |io| bsrt_write(io) }
|
|
304
333
|
end
|
|
305
334
|
|
|
306
335
|
# The RTree structure in hash form
|
|
307
336
|
# @return [Hash]
|
|
337
|
+
#
|
|
308
338
|
def to_h
|
|
309
339
|
JSON.parse(to_json, symbolize_names: true)
|
|
310
340
|
end
|
|
@@ -314,6 +344,7 @@ class RTree < RTreeC
|
|
|
314
344
|
# must be in the same order. Certainly {#clone} will produce
|
|
315
345
|
# an instance which is equal in this sense.
|
|
316
346
|
# @return [Boolean] true if the instances are identical
|
|
347
|
+
#
|
|
317
348
|
def eq?(other)
|
|
318
349
|
super
|
|
319
350
|
end
|
|
@@ -321,6 +352,7 @@ class RTree < RTreeC
|
|
|
321
352
|
alias_method(:==, :eq?)
|
|
322
353
|
|
|
323
354
|
# @return [Integer] the dimension of the R-tree
|
|
355
|
+
#
|
|
324
356
|
def dim
|
|
325
357
|
super
|
|
326
358
|
end
|
|
@@ -331,41 +363,74 @@ class RTree < RTreeC
|
|
|
331
363
|
# running count). Performance-minded users may wish to
|
|
332
364
|
# cache this value (invalidating the cache when calling
|
|
333
365
|
# {#add_rect} of course).
|
|
366
|
+
#
|
|
334
367
|
def size
|
|
335
368
|
super
|
|
336
369
|
end
|
|
337
370
|
|
|
338
371
|
# @return [Integer] the bytes in a page of memory
|
|
372
|
+
#
|
|
339
373
|
def page_size
|
|
340
374
|
super
|
|
341
375
|
end
|
|
342
376
|
|
|
343
377
|
# @return [Integer] the size in bytes of a node
|
|
378
|
+
#
|
|
344
379
|
def node_size
|
|
345
380
|
super
|
|
346
381
|
end
|
|
347
382
|
|
|
348
383
|
# @return [Integer] the size in bytes of a rectangle
|
|
384
|
+
#
|
|
349
385
|
def rect_size
|
|
350
386
|
super
|
|
351
387
|
end
|
|
352
388
|
|
|
353
389
|
# @return [Integer] the size in bytes of a branch
|
|
390
|
+
#
|
|
354
391
|
def branch_size
|
|
355
392
|
super
|
|
356
393
|
end
|
|
357
394
|
|
|
358
395
|
# @return [Integer] the number of branches from each node
|
|
396
|
+
#
|
|
359
397
|
def branching_factor
|
|
360
398
|
super
|
|
361
399
|
end
|
|
362
400
|
|
|
363
401
|
# @return [Float] the volume of the unit sphere in the R-tree's
|
|
364
402
|
# dimension
|
|
403
|
+
#
|
|
365
404
|
def unit_sphere_volume
|
|
366
405
|
super
|
|
367
406
|
end
|
|
368
407
|
|
|
408
|
+
# Create a PostScript plot of the RTree
|
|
409
|
+
# @param io [IO] a writeable stream object
|
|
410
|
+
# @param style [RTree::Style] a style object describing the fill
|
|
411
|
+
# colour and stroke width and colour for each level of the tree.
|
|
412
|
+
# @param height [Float] the height of the plot in units of PostScript
|
|
413
|
+
# point (1/72 inch)
|
|
414
|
+
# @param width [Float] the width of the plot in units of PostScript
|
|
415
|
+
# point (1/72 inch), if neither height nor width is given then a
|
|
416
|
+
# width of 216 (3 inches) will be taken as default
|
|
417
|
+
# @param margin [Float] extra space around the plot in units of
|
|
418
|
+
# PostScript point (1/72 inch), default zero
|
|
419
|
+
#
|
|
420
|
+
def postscript(io, style, height: nil, width: nil, margin: 0)
|
|
421
|
+
if height && width then
|
|
422
|
+
raise ArgumentError, 'cannot specify both height and width'
|
|
423
|
+
end
|
|
424
|
+
if height then
|
|
425
|
+
axis = AXIS_HEIGHT
|
|
426
|
+
extent = height
|
|
427
|
+
else
|
|
428
|
+
axis = AXIS_WIDTH
|
|
429
|
+
extent = width || 216
|
|
430
|
+
end
|
|
431
|
+
super(style, axis, extent, margin, io)
|
|
432
|
+
end
|
|
433
|
+
|
|
369
434
|
private
|
|
370
435
|
|
|
371
436
|
attr_reader :split, :node_page
|
|
@@ -397,8 +462,89 @@ class RTree < RTreeC
|
|
|
397
462
|
end
|
|
398
463
|
result
|
|
399
464
|
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
class RTree < RTreeC
|
|
469
|
+
class Style < RTreeC::StyleC
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
# @author RTree::Style J. J. Green
|
|
474
|
+
#
|
|
475
|
+
# A Ruby wrapper around RTree styles, used in PostScript plotting.
|
|
476
|
+
# in particular by {RTree#postscript}.
|
|
477
|
+
#
|
|
478
|
+
class RTree::Style
|
|
479
|
+
|
|
480
|
+
class << self
|
|
400
481
|
|
|
482
|
+
# Create a new Style instance from JSON stream
|
|
483
|
+
# @param io [IO] a readable stream object
|
|
484
|
+
# @return [RTree::Style] the newly instantiated Style
|
|
485
|
+
# @example Read from file
|
|
486
|
+
# style = File.open('some.style', 'r') do |io|
|
|
487
|
+
# RTree::Style.json_read(io)
|
|
488
|
+
# end
|
|
489
|
+
#
|
|
490
|
+
def json_read(io)
|
|
491
|
+
super
|
|
492
|
+
end
|
|
401
493
|
|
|
494
|
+
# Create a new Style instance from JSON string
|
|
495
|
+
# @param json [String] a JSON string
|
|
496
|
+
# @return [RTree::Style] the newly instantiated Style
|
|
497
|
+
# @see .json_read
|
|
498
|
+
#
|
|
499
|
+
def from_json(json)
|
|
500
|
+
raise TypeError unless json.is_a? String
|
|
501
|
+
rd, wr = IO.pipe(Encoding::UTF_8)
|
|
502
|
+
if fork then
|
|
503
|
+
wr.close
|
|
504
|
+
begin
|
|
505
|
+
result = json_read(rd)
|
|
506
|
+
ensure
|
|
507
|
+
rd.close
|
|
508
|
+
Process.wait
|
|
509
|
+
end
|
|
510
|
+
else
|
|
511
|
+
rd.close
|
|
512
|
+
begin
|
|
513
|
+
wr.write(json)
|
|
514
|
+
ensure
|
|
515
|
+
wr.close
|
|
516
|
+
exit!
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
result
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
# Create a new Style instance from array of Hash
|
|
523
|
+
# @param array [Array] an array of hash, this will be converted
|
|
524
|
+
# to JSON and read by .from_json
|
|
525
|
+
# @return [RTree::Style] the newly instantiated Style
|
|
526
|
+
# @see .from_json
|
|
527
|
+
# @example Create a simple one-level style:
|
|
528
|
+
# style = RTree::Style.from_a(
|
|
529
|
+
# [
|
|
530
|
+
# {
|
|
531
|
+
# fill: {
|
|
532
|
+
# rgb: [0.5, 0.5, 0.5]
|
|
533
|
+
# },
|
|
534
|
+
# stroke: {
|
|
535
|
+
# rgb: [0, 0, 1],
|
|
536
|
+
# width: 3
|
|
537
|
+
# }
|
|
538
|
+
# }
|
|
539
|
+
# ]
|
|
540
|
+
# )
|
|
541
|
+
#
|
|
542
|
+
def from_a(array)
|
|
543
|
+
from_json(array.to_json)
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
alias_method :from_array, :from_a
|
|
547
|
+
end
|
|
402
548
|
end
|
|
403
549
|
|
|
404
550
|
require 'rtree/rtree'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: librtree
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- J.J. Green
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-06-
|
|
11
|
+
date: 2021-06-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|