librtree 0.9.1 → 1.0.1

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +80 -0
  3. data/COPYING +21 -0
  4. data/README.md +87 -0
  5. data/ext/rtree/extconf.rb +37 -19
  6. data/ext/rtree/lib/README.md +9 -0
  7. data/ext/rtree/lib/bindex.c +157 -0
  8. data/ext/rtree/lib/bindex.h +31 -0
  9. data/ext/rtree/lib/bounds.h +21 -0
  10. data/ext/rtree/lib/branch.c +51 -0
  11. data/ext/rtree/lib/branches.c +17 -0
  12. data/ext/rtree/lib/bsrt.c +704 -0
  13. data/ext/rtree/lib/bsrt.h +16 -0
  14. data/ext/rtree/lib/constants.h +19 -0
  15. data/ext/rtree/lib/csv.c +81 -0
  16. data/ext/rtree/lib/csv.h +16 -0
  17. data/ext/rtree/lib/endianness.h +83 -0
  18. data/ext/rtree/lib/error.c +47 -0
  19. data/ext/rtree/lib/json.c +491 -0
  20. data/ext/rtree/lib/json.h +16 -0
  21. data/ext/rtree/lib/mk/Hdr.mk +3 -0
  22. data/ext/rtree/lib/mk/MakeDepend +25 -0
  23. data/ext/rtree/lib/mk/Obj.mk +3 -0
  24. data/ext/rtree/lib/node.c +736 -0
  25. data/ext/rtree/lib/package.c +11 -0
  26. data/ext/rtree/lib/page.c +47 -0
  27. data/ext/rtree/lib/page.h +13 -0
  28. data/ext/rtree/lib/postscript.c +543 -0
  29. data/ext/rtree/lib/rect.c +139 -0
  30. data/ext/rtree/lib/rectf.c +219 -0
  31. data/ext/rtree/lib/rtree/branch.h +105 -0
  32. data/ext/rtree/lib/rtree/branches.h +38 -0
  33. data/ext/rtree/lib/rtree/error.h +42 -0
  34. data/ext/rtree/lib/rtree/extent.h +20 -0
  35. data/ext/rtree/lib/rtree/node.h +96 -0
  36. data/ext/rtree/lib/rtree/package.h +14 -0
  37. data/ext/rtree/lib/rtree/postscript.h +66 -0
  38. data/ext/rtree/lib/rtree/rect.h +38 -0
  39. data/ext/rtree/lib/rtree/rectf.h +34 -0
  40. data/ext/rtree/lib/rtree/search.h +27 -0
  41. data/ext/rtree/lib/rtree/state.h +113 -0
  42. data/ext/rtree/lib/rtree/types.h +14 -0
  43. data/ext/rtree/lib/rtree-base.c +197 -0
  44. data/ext/rtree/lib/rtree.h +62 -0
  45. data/ext/rtree/lib/search.c +54 -0
  46. data/ext/rtree/lib/split.c +710 -0
  47. data/ext/rtree/lib/split.h +15 -0
  48. data/ext/rtree/lib/spvol.c +48 -0
  49. data/ext/rtree/lib/spvol.h +13 -0
  50. data/ext/rtree/lib/state.c +169 -0
  51. data/ext/rtree/rtree.c +11 -0
  52. data/lib/rtree.rb +4 -4
  53. metadata +65 -3
@@ -0,0 +1,704 @@
1
+ #ifdef HAVE_CONFIG_H
2
+ #include "config.h"
3
+ #endif
4
+
5
+ #include "bsrt.h"
6
+
7
+ #include "rtree/error.h"
8
+ #include "rtree/branches.h"
9
+
10
+ #include <errno.h>
11
+ #include <string.h>
12
+
13
+ #ifdef WITH_BSRT
14
+
15
+ #include "endianness.h"
16
+ #include "bounds.h"
17
+
18
+ #define BSRT_MAGIC "BSRt"
19
+ #define BSRT_FOOTER "fin"
20
+ #define BSRT_VERSION 2
21
+
22
+ /* magic number, 4 bytes */
23
+
24
+ static int write_magic(FILE *stream)
25
+ {
26
+ if (fwrite(BSRT_MAGIC, 1, 4, stream) != 4)
27
+ return RTREE_ERR_FWRITE;
28
+
29
+ return RTREE_OK;
30
+ }
31
+
32
+ /* version, 2 bytes */
33
+
34
+ static int write_version(FILE *stream)
35
+ {
36
+ uint16_t v = htole16(BSRT_VERSION);
37
+
38
+ if (fwrite(&v, 2, 1, stream) != 1)
39
+ return RTREE_ERR_FWRITE;
40
+
41
+ return RTREE_OK;
42
+ }
43
+
44
+ /* state, 12 bytes */
45
+
46
+ static int write_state(state_t *state, FILE *stream)
47
+ {
48
+ uint16_t v[6] =
49
+ {
50
+ htole16(state_dims(state)),
51
+ htole16(state_page_size(state)),
52
+ htole16(SIZEOF_RTREE_COORD_T),
53
+ htole16(state_rect_size(state)),
54
+ htole16(state_branch_size(state)),
55
+ htole16(state_node_size(state))
56
+ };
57
+
58
+ if (fwrite(&v, 2, 6, stream) != 6)
59
+ return RTREE_ERR_FWRITE;
60
+
61
+ return RTREE_OK;
62
+ }
63
+
64
+ /*
65
+ each node has a 4-byte header, the level (positive for an internal
66
+ node, zero for a leaf node) and the count of branches.
67
+ */
68
+
69
+ static int write_header(uint16_t level, uint16_t count, FILE *stream)
70
+ {
71
+ uint16_t v;
72
+
73
+ v = htole16(level);
74
+
75
+ if (fwrite(&v, 2, 1, stream) != 1)
76
+ return RTREE_ERR_FWRITE;
77
+
78
+ v = htole16(count);
79
+
80
+ if (fwrite(&v, 2, 1, stream) != 1)
81
+ return RTREE_ERR_FWRITE;
82
+
83
+ return RTREE_OK;
84
+ }
85
+
86
+ static int write_id(rtree_id_t id, FILE *stream)
87
+ {
88
+ #if SIZEOF_RTREE_ID_T == 2
89
+ uint16_t v = htole16(id);
90
+ #elif SIZEOF_RTREE_ID_T == 4
91
+ uint32_t v = htole32(id);
92
+ #elif SIZEOF_RTREE_ID_T == 8
93
+ uint64_t v = htole64(id);
94
+ #else
95
+ #error rtree_id_t size not handled
96
+ #endif
97
+
98
+ if (fwrite(&v, SIZEOF_RTREE_ID_T, 1, stream) != 1)
99
+ return RTREE_ERR_FWRITE;
100
+
101
+ return RTREE_OK;
102
+ }
103
+
104
+ /*
105
+ Here we only byte-swap if we establish that the host float
106
+ byte-order is big-endian, this saves time on little-endian
107
+ hardware. Note that in the big-endian case, we call htole32()
108
+ which converts from the host integer byte-order to little-endian,
109
+ this will only be correct if integer and float endianess are
110
+ the same, this is not true in general (!), there exists real
111
+ hardware with big-endian floats and little-endian integers.
112
+ So it would be better to use be32tole32() here, but that does
113
+ not exist (one could make it with htole32(be32toh()), but
114
+ these are macros not functions, one would need to test this on
115
+ real hardware first).
116
+ */
117
+
118
+ static int write_rect(const state_t *state,
119
+ const rtree_coord_t *rect,
120
+ FILE *stream)
121
+ {
122
+ size_t
123
+ n = 2 * state_dims(state),
124
+ k = SIZEOF_RTREE_COORD_T;
125
+
126
+ #ifdef FLOAT_WORDS_BIGENDIAN
127
+
128
+ rtree_coord_t buffer[n];
129
+
130
+ for (size_t i = 0 ; i < n ; i++)
131
+ {
132
+ /*
133
+ The type-punning to/from char* here is legal (the standard
134
+ makes an explicit exception), but cppcheck warns anyway, so
135
+ we suppress those warnings
136
+ */
137
+
138
+ char p[k];
139
+
140
+ /* cppcheck-suppress invalidPointerCast */
141
+ *(rtree_coord_t*)p = rect[i];
142
+
143
+ #if SIZEOF_RTREE_COORD_T == 4
144
+ /* cppcheck-suppress invalidPointerCast */
145
+ *(uint32_t*)p = htole32(*(uint32_t*)p);
146
+ #elif SIZEOF_RTREE_COORD_T == 8
147
+ /* cppcheck-suppress invalidPointerCast */
148
+ *(uint64_t*)p = htole64(*(uint64_t*)p);
149
+ #else
150
+ #error rtree_coord_t size not handled
151
+ #endif
152
+
153
+ /* cppcheck-suppress invalidPointerCast */
154
+ buffer[i] = *(rtree_coord_t*)p;
155
+ }
156
+
157
+ if (fwrite(buffer, k, n, stream) != n)
158
+ return RTREE_ERR_FWRITE;
159
+ return RTREE_OK;
160
+
161
+ #else
162
+
163
+ if (fwrite(rect, k, n, stream) != n)
164
+ return RTREE_ERR_FWRITE;
165
+ return RTREE_OK;
166
+
167
+ #endif
168
+ }
169
+
170
+ static int write_node(const state_t*, const node_t*, FILE*);
171
+
172
+ /* callbacks passed to node_branch_each() */
173
+
174
+ static int write_internal_branch(const state_t *state,
175
+ const branch_t *branch,
176
+ void *arg)
177
+ {
178
+ FILE *stream = arg;
179
+ int err;
180
+
181
+ if ((err = write_rect(state, branch->rect, stream)) != 0)
182
+ return err;
183
+
184
+ const node_t *child = branch_get_child(branch);
185
+
186
+ if ((err = write_node(state, child, stream)) != 0)
187
+ return err;
188
+
189
+ return 0;
190
+ }
191
+
192
+ static int write_leaf_branch(const state_t *state,
193
+ const branch_t *branch,
194
+ void *arg)
195
+ {
196
+ FILE *stream = arg;
197
+ int err;
198
+
199
+ if ((err = write_rect(state, branch->rect, stream)) != 0)
200
+ return err;
201
+
202
+ rtree_id_t id = branch_get_id(branch);
203
+
204
+ if ((err = write_id(id, stream)) != 0)
205
+ return err;
206
+
207
+ return 0;
208
+ }
209
+
210
+ /* write internal/leaf nodes */
211
+
212
+ static int write_internal_node(const state_t *state,
213
+ const node_t *node,
214
+ FILE *stream)
215
+ {
216
+ int err;
217
+
218
+ if ((err = write_header(node_level(node), node_count(node), stream)) != 0)
219
+ return err;
220
+
221
+ return node_branch_each(state, node, write_internal_branch, stream);
222
+ }
223
+
224
+ static int write_leaf_node(const state_t *state,
225
+ const node_t *node,
226
+ FILE *stream)
227
+ {
228
+ int err;
229
+
230
+ if ((err = write_header(node_level(node), node_count(node), stream)) != 0)
231
+ return err;
232
+
233
+ return node_branch_each(state, node, write_leaf_branch, stream);
234
+ }
235
+
236
+ static int write_node(const state_t *state,
237
+ const node_t *node,
238
+ FILE *stream)
239
+ {
240
+ int err;
241
+
242
+ if (node_level(node) > 0)
243
+ err = write_internal_node(state, node, stream);
244
+ else
245
+ err = write_leaf_node(state, node, stream);
246
+
247
+ return err;
248
+ }
249
+
250
+ static int write_footer(FILE *stream)
251
+ {
252
+ size_t n = strlen(BSRT_FOOTER);
253
+ if (fwrite(BSRT_FOOTER, 1, n, stream) != n)
254
+ return RTREE_ERR_FWRITE;
255
+ return RTREE_OK;
256
+ }
257
+
258
+ int bsrt_rtree_write(const rtree_t *rtree, FILE *stream)
259
+ {
260
+ int err;
261
+
262
+ if ((err = write_magic(stream)) != 0)
263
+ return err;
264
+
265
+ if ((err = write_version(stream)) != 0)
266
+ return err;
267
+
268
+ if ((err = write_state(rtree->state, stream)) != 0)
269
+ return err;
270
+
271
+ if ((err = write_node(rtree->state, rtree->root, stream)) != 0)
272
+ return err;
273
+
274
+ if ((err = write_footer(stream)) != 0)
275
+ return err;
276
+
277
+ return RTREE_OK;
278
+ }
279
+
280
+ /*
281
+ reader functions, unlike the writer, all functions acting on
282
+ file content after the version are version qualified, the idea
283
+ being that later versions of the library should be able to
284
+ read all previous versions of the format.
285
+ */
286
+
287
+ static int read_magic(FILE *stream)
288
+ {
289
+ char buffer[4];
290
+
291
+ if (fread(buffer, 1, 4, stream) != 4)
292
+ return 1;
293
+
294
+ if (memcmp(buffer, BSRT_MAGIC, 4) == 0)
295
+ return 0;
296
+
297
+ errno = EINVAL;
298
+ return 1;
299
+ }
300
+
301
+ static int read_version(FILE *stream, uint16_t *v)
302
+ {
303
+ if (fread(v, 2, 1, stream) != 1)
304
+ return 1;
305
+
306
+ *v = le16toh(*v);
307
+
308
+ return 0;
309
+ }
310
+
311
+ /* read v1 */
312
+
313
+ static int read_v1_header(FILE *stream, uint16_t v[5])
314
+ {
315
+ if (fread(v, 2, 5, stream) != 5)
316
+ return 1;
317
+
318
+ for (size_t i = 0 ; i < 5 ; i++)
319
+ v[i] = le16toh(v[i]);
320
+
321
+ return 0;
322
+ }
323
+
324
+ static bool read_v1_state_consistent(uint16_t v[5], const state_t *state)
325
+ {
326
+ return
327
+ (v[0] == state_dims(state)) &&
328
+ (v[1] == state_page_size(state)) &&
329
+ (v[2] == SIZEOF_RTREE_COORD_T) &&
330
+ (v[3] == state_rect_size(state)) &&
331
+ (v[4] == state_branch_size(state));
332
+ }
333
+
334
+ /* see note above on float/double endianness */
335
+
336
+ static int read_v1_rect(FILE *stream,
337
+ const state_t *state,
338
+ rtree_coord_t *rect)
339
+ {
340
+ size_t
341
+ n = 2 * state_dims(state),
342
+ k = SIZEOF_RTREE_COORD_T;
343
+
344
+ #ifdef FLOAT_WORDS_BIGENDIAN
345
+
346
+ char buffer[n * k];
347
+
348
+ if (fread(buffer, k, n, stream) != n)
349
+ return 1;
350
+
351
+ for (size_t i = 0 ; i < n ; i++)
352
+ {
353
+ char *p = buffer + i * k;
354
+
355
+ #if SIZEOF_RTREE_COORD_T == 4
356
+ *(uint32_t*)p = le32toh(*(uint32_t*)p);
357
+ #elif SIZEOF_RTREE_COORD_T == 8
358
+ *(uint64_t*)p = le64toh(*(uint64_t*)p);
359
+ #else
360
+ #error rtree_coord_t size not handled
361
+ #endif
362
+
363
+ /* cppcheck-suppress invalidPointerCast */
364
+
365
+ rect[i] = *(rtree_coord_t*)p;
366
+ }
367
+
368
+ #else
369
+
370
+ if (fread(rect, k, n, stream) != n)
371
+ return 1;
372
+
373
+ #endif
374
+
375
+ return 0;
376
+ }
377
+
378
+ static int read_v1_id(FILE *stream, rtree_id_t *id)
379
+ {
380
+ if (fread(id, SIZEOF_RTREE_ID_T, 1, stream) != 1)
381
+ return 1;
382
+
383
+ #if SIZEOF_RTREE_ID_T == 8
384
+ *id = le64toh(*id);
385
+ #elif SIZEOF_RTREE_ID_T == 4
386
+ *id = le32toh(*id);
387
+ #elif SIZEOF_RTREE_ID_T == 2
388
+ *id = le16toh(*id);
389
+ #else
390
+ #error rtree_id_t size not handled
391
+ #endif
392
+
393
+ return 0;
394
+ }
395
+
396
+ static node_t* read_v1_node(FILE*, const state_t*);
397
+
398
+ static int read_v1_branch_internal(FILE *stream,
399
+ const state_t *state,
400
+ branch_t *branch)
401
+ {
402
+ if (branch_init(state, branch) != 0)
403
+ return 1;
404
+
405
+ if (read_v1_rect(stream, state, branch_get_rect_mutable(branch)) != 0)
406
+ return 1;
407
+
408
+ node_t *child;
409
+
410
+ if ((child = read_v1_node(stream, state)) == NULL)
411
+ return 1;
412
+
413
+ branch_set_child(branch, child);
414
+
415
+ return 0;
416
+ }
417
+
418
+ static int read_v1_branch_leaf(FILE *stream,
419
+ const state_t *state,
420
+ branch_t *branch)
421
+ {
422
+ if (branch_init(state, branch) != 0)
423
+ return 1;
424
+
425
+ if (read_v1_rect(stream, state, branch_get_rect_mutable(branch)) != 0)
426
+ return 1;
427
+
428
+ rtree_id_t id;
429
+
430
+ if (read_v1_id(stream, &id) != 0)
431
+ return 1;
432
+
433
+ branch_set_id(branch, id);
434
+
435
+ return 0;
436
+ }
437
+
438
+ typedef int (branch_read_t)(FILE*, const state_t*, branch_t*);
439
+
440
+ static node_t* read_v1_node_generic(FILE *stream,
441
+ branch_read_t *f,
442
+ const state_t *state,
443
+ uint16_t n)
444
+ {
445
+ if (n > state_branching_factor(state))
446
+ {
447
+ errno = EINVAL;
448
+ return NULL;
449
+ }
450
+
451
+ node_t *node;
452
+
453
+ if ((node = node_new(state)) != NULL)
454
+ {
455
+ void *branches = node_get_branches(node);
456
+
457
+ for (size_t i = 0 ; i < n ; i++)
458
+ {
459
+ branch_t *branch = branches_get(state, branches, i);
460
+ if (f(stream, state, branch) != 0)
461
+ break;
462
+ node_count_increment(node);
463
+ }
464
+
465
+ if (node_count(node) == n)
466
+ return node;
467
+
468
+ errno = EINVAL;
469
+ node_destroy(state, node);
470
+ }
471
+
472
+ return NULL;
473
+ }
474
+
475
+ static node_t* read_v1_node_internal(FILE *stream,
476
+ const state_t *state,
477
+ uint16_t n)
478
+ {
479
+ return read_v1_node_generic(stream, read_v1_branch_internal, state, n);
480
+ }
481
+
482
+ static node_t* read_v1_node_leaf(FILE *stream,
483
+ const state_t *state,
484
+ uint16_t n)
485
+ {
486
+ return read_v1_node_generic(stream, read_v1_branch_leaf, state, n);
487
+ }
488
+
489
+ static node_t* read_v1_node(FILE *stream, const state_t *state)
490
+ {
491
+ uint16_t level;
492
+
493
+ if (fread(&level, 2, 1, stream) != 1)
494
+ return NULL;
495
+ level = le16toh(level);
496
+ if (level > RTREE_LEVELS_MAX)
497
+ return NULL;
498
+
499
+ uint16_t count;
500
+
501
+ if (fread(&count, 2, 1, stream) != 1)
502
+ return NULL;
503
+ count = le16toh(count);
504
+ if (count > RTREE_BRANCHES_MAX)
505
+ return NULL;
506
+
507
+ node_t *node;
508
+
509
+ if (level > 0)
510
+ node = read_v1_node_internal(stream, state, count);
511
+ else
512
+ node = read_v1_node_leaf(stream, state, count);
513
+
514
+ if (node != NULL)
515
+ node_set_level(node, level);
516
+
517
+ return node;
518
+ }
519
+
520
+ static int read_v1_footer(FILE *stream)
521
+ {
522
+ size_t n = strlen(BSRT_FOOTER);
523
+ char buffer[n];
524
+
525
+ if (fread(buffer, 1, n, stream) != n)
526
+ return 1;
527
+
528
+ if (memcmp(buffer, BSRT_FOOTER, n) == 0)
529
+ return 0;
530
+ else
531
+ {
532
+ errno = EINVAL;
533
+ return 1;
534
+ }
535
+ }
536
+
537
+ static rtree_t* read_v1(FILE *stream)
538
+ {
539
+ uint16_t v[5];
540
+
541
+ if (read_v1_header(stream, v) != 0)
542
+ return NULL;
543
+
544
+ size_t dims = v[0];
545
+
546
+ if (dims > RTREE_DIMS_MAX)
547
+ return NULL;
548
+
549
+ state_t *state;
550
+
551
+ if ((state = state_new(dims, RTREE_NODE_PAGE(1))) != NULL)
552
+ {
553
+ if (read_v1_state_consistent(v, state))
554
+ {
555
+ node_t *root;
556
+
557
+ if ((root = read_v1_node(stream, state)) != NULL)
558
+ {
559
+ if (read_v1_footer(stream) == 0)
560
+ {
561
+ rtree_t *rtree;
562
+
563
+ if ((rtree = rtree_alloc()) != NULL)
564
+ {
565
+ rtree->state = state;
566
+ rtree->root = root;
567
+ return rtree;
568
+ }
569
+ }
570
+ node_destroy(state, root);
571
+ }
572
+ }
573
+ else
574
+ errno = EINVAL;
575
+
576
+ state_destroy(state);
577
+ }
578
+
579
+ return NULL;
580
+ }
581
+
582
+ /* read v2 */
583
+
584
+ static int read_v2_header(FILE *stream, uint16_t v[6])
585
+ {
586
+ if (fread(v, 2, 6, stream) != 6)
587
+ return 1;
588
+
589
+ for (size_t i = 0 ; i < 6 ; i++)
590
+ v[i] = le16toh(v[i]);
591
+
592
+ return 0;
593
+ }
594
+
595
+ static bool read_v2_state_consistent(uint16_t v[6], const state_t *state)
596
+ {
597
+ return
598
+ (v[0] == state_dims(state)) &&
599
+ (v[1] == state_page_size(state)) &&
600
+ (v[2] == SIZEOF_RTREE_COORD_T) &&
601
+ (v[3] == state_rect_size(state)) &&
602
+ (v[4] == state_branch_size(state)) &&
603
+ (v[5] == state_node_size(state));
604
+ }
605
+
606
+ static node_t* read_v2_node(FILE *stream, const state_t *state)
607
+ {
608
+ return read_v1_node(stream, state);
609
+ }
610
+
611
+ static int read_v2_footer(FILE *stream)
612
+ {
613
+ return read_v1_footer(stream);
614
+ }
615
+
616
+ static rtree_t* read_v2(FILE *stream)
617
+ {
618
+ uint16_t v[6];
619
+
620
+ if (read_v2_header(stream, v) != 0)
621
+ return NULL;
622
+
623
+ if ((v[5] == 0) || (v[1] < v[5]))
624
+ return NULL;
625
+
626
+ size_t
627
+ dims = v[0],
628
+ node_page = v[1] / v[5];
629
+ state_t *state;
630
+
631
+ if ((state = state_new(dims, RTREE_NODE_PAGE(node_page))) != NULL)
632
+ {
633
+ if (read_v2_state_consistent(v, state))
634
+ {
635
+ node_t *root;
636
+
637
+ if ((root = read_v2_node(stream, state)) != NULL)
638
+ {
639
+ if (read_v2_footer(stream) == 0)
640
+ {
641
+ rtree_t *rtree;
642
+
643
+ if ((rtree = rtree_alloc()) != NULL)
644
+ {
645
+ rtree->state = state;
646
+ rtree->root = root;
647
+ return rtree;
648
+ }
649
+ }
650
+ node_destroy(state, root);
651
+ }
652
+ }
653
+ else
654
+ errno = EINVAL;
655
+
656
+ state_destroy(state);
657
+ }
658
+
659
+ return NULL;
660
+ }
661
+
662
+ rtree_t* bsrt_rtree_read(FILE *stream)
663
+ {
664
+ if (read_magic(stream) != 0)
665
+ return NULL;
666
+
667
+ uint16_t version;
668
+
669
+ if (read_version(stream, &version) != 0)
670
+ return NULL;
671
+
672
+ switch (version)
673
+ {
674
+ case 1:
675
+ return read_v1(stream);
676
+ case 2:
677
+ return read_v2(stream);
678
+ default:
679
+ errno = EINVAL;
680
+ return NULL;
681
+ }
682
+ }
683
+
684
+ #else
685
+
686
+ #pragma GCC diagnostic push
687
+ #pragma GCC diagnostic ignored "-Wunused-parameter"
688
+ int bsrt_rtree_write(const rtree_t *rtree, FILE *stream)
689
+ {
690
+ errno = ENOSYS;
691
+ return RTREE_ERR_NOBSRT;
692
+ }
693
+ #pragma GCC diagnostic pop
694
+
695
+ #pragma GCC diagnostic push
696
+ #pragma GCC diagnostic ignored "-Wunused-parameter"
697
+ rtree_t* bsrt_rtree_read(FILE *stream)
698
+ {
699
+ errno = ENOSYS;
700
+ return NULL;
701
+ }
702
+ #pragma GCC diagnostic pop
703
+
704
+ #endif
@@ -0,0 +1,16 @@
1
+ /*
2
+ bsrt.h
3
+ Copyright (c) J.J. Green 2019
4
+ */
5
+
6
+ #ifndef BSRT_H
7
+ #define BSRT_H
8
+
9
+ #include <stdio.h>
10
+
11
+ #include <rtree.h>
12
+
13
+ int bsrt_rtree_write(const rtree_t*, FILE*);
14
+ rtree_t* bsrt_rtree_read(FILE*);
15
+
16
+ #endif
@@ -0,0 +1,19 @@
1
+ /*
2
+ constants.h
3
+ Copyright (c) J.J. Green 2019
4
+ */
5
+
6
+ #ifndef CONSTANTS_H
7
+ #define CONSTANTS_H
8
+
9
+ #include <math.h>
10
+
11
+ #ifndef M_PI
12
+ #define M_PI 3.14159265358979323846
13
+ #endif
14
+
15
+ #ifndef M_LOG_PI
16
+ #define M_LOG_PI 1.1447298858494002
17
+ #endif
18
+
19
+ #endif