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,66 @@
1
+ /*
2
+ rtree/postscript.h
3
+ Copyright (c) J.J. Green 2020
4
+ */
5
+
6
+ #ifndef RTREE_POSTSCRIPT_H
7
+ #define RTREE_POSTSCRIPT_H
8
+
9
+ #ifdef __cplusplus
10
+ extern "C" {
11
+ #endif
12
+
13
+ typedef struct rtree_postscript_t rtree_postscript_t;
14
+
15
+ #include <stdio.h>
16
+ #include <rtree/node.h>
17
+ #include <rtree/extent.h>
18
+
19
+ typedef enum
20
+ { model_none, model_grey, model_rgb, model_cmyk }
21
+ colour_model_t;
22
+
23
+ typedef struct {
24
+ colour_model_t model;
25
+ union {
26
+ float grey[1];
27
+ float rgb[3];
28
+ float cmyk[4];
29
+ };
30
+ } colour_t;
31
+
32
+ typedef struct {
33
+ struct {
34
+ colour_t colour;
35
+ } fill;
36
+ struct {
37
+ colour_t colour;
38
+ float width;
39
+ } stroke;
40
+ } style_level_t;
41
+
42
+ typedef struct {
43
+ size_t n;
44
+ style_level_t *array;
45
+ } style_t;
46
+
47
+ style_t* postscript_style_read(FILE*);
48
+ void postscript_style_destroy(style_t*);
49
+
50
+ struct rtree_postscript_t
51
+ {
52
+ const style_t *style;
53
+ extent_axis_t axis;
54
+ float extent;
55
+ float margin;
56
+ const char *title;
57
+ };
58
+
59
+ int postscript_write(const state_t*, const node_t*,
60
+ const rtree_postscript_t*, FILE*);
61
+
62
+ #ifdef __cplusplus
63
+ }
64
+ #endif
65
+
66
+ #endif
@@ -0,0 +1,38 @@
1
+ /*
2
+ rtree/rect.h
3
+ Copyright (c) J.J. Green 2019
4
+ */
5
+
6
+ #ifndef RTREE_RECT_H
7
+ #define RTREE_RECT_H
8
+
9
+ #ifdef __cplusplus
10
+ extern "C" {
11
+ #endif
12
+
13
+ #include <stdlib.h>
14
+ #include <stdbool.h>
15
+
16
+ #include <rtree/state.h>
17
+ #include <rtree/types.h>
18
+
19
+ int rect_init(const state_t*, rtree_coord_t*);
20
+
21
+ rtree_coord_t rect_volume(const state_t*, const rtree_coord_t*);
22
+ rtree_coord_t rect_spherical_volume(const state_t*, const rtree_coord_t*);
23
+ void rect_combine(const state_t*,
24
+ const rtree_coord_t *restrict,
25
+ const rtree_coord_t *restrict,
26
+ rtree_coord_t *restrict);
27
+ bool rect_intersect(const state_t*, const rtree_coord_t*, const rtree_coord_t*);
28
+ void rect_merge(const state_t*, const rtree_coord_t*, rtree_coord_t*);
29
+ void rect_copy(const state_t*, const rtree_coord_t*, rtree_coord_t*);
30
+ bool rect_identical(const state_t*, const rtree_coord_t*, const rtree_coord_t*);
31
+ int rects_alloc(const state_t*, size_t, rtree_coord_t**);
32
+ void rects_free(size_t, rtree_coord_t**);
33
+
34
+ #ifdef __cplusplus
35
+ }
36
+ #endif
37
+
38
+ #endif
@@ -0,0 +1,34 @@
1
+ /*
2
+ rtree/rectf.h
3
+ Copyright (c) J.J. Green 2022
4
+ */
5
+
6
+ #ifndef RTREE_RECTF_H
7
+ #define RTREE_RECTF_H
8
+
9
+ #ifdef __cplusplus
10
+ extern "C" {
11
+ #endif
12
+
13
+ #include <rtree/types.h>
14
+ #include <stddef.h>
15
+
16
+ /* rect-spherical-volume */
17
+
18
+ typedef rtree_coord_t (rectf_rsv_t)(size_t, const rtree_coord_t*);
19
+
20
+ rectf_rsv_t* rectf_spherical_volume(size_t);
21
+
22
+ /* rect-combine */
23
+
24
+ typedef void (rectf_rc_t)(size_t,
25
+ const rtree_coord_t*,
26
+ const rtree_coord_t*,
27
+ rtree_coord_t*);
28
+
29
+ rectf_rc_t* rectf_combine(size_t);
30
+
31
+ #ifdef __cplusplus
32
+ }
33
+ #endif
34
+ #endif
@@ -0,0 +1,27 @@
1
+ /*
2
+ rtree/search.h
3
+ Copyright (c) J.J. Green 2020
4
+ */
5
+
6
+ #ifndef RTREE_SEARCH_H
7
+ #define RTREE_SEARCH_H
8
+
9
+ #ifdef __cplusplus
10
+ extern "C" {
11
+ #endif
12
+
13
+ #include <rtree/node.h>
14
+ #include <rtree/types.h>
15
+ #include <rtree/state.h>
16
+
17
+ typedef int (rtree_search_t)(rtree_id_t, void*);
18
+
19
+ int search(const state_t*,
20
+ const rtree_coord_t*, const node_t*,
21
+ rtree_search_t*, void*);
22
+
23
+ #ifdef __cplusplus
24
+ }
25
+ #endif
26
+
27
+ #endif
@@ -0,0 +1,113 @@
1
+ /*
2
+ rtree/state.h
3
+
4
+ This structure is open, but we only access it via accessors,
5
+ often trivial; these are implemented as (C99 standard) inline
6
+ functions, so there's no performance penalty.
7
+
8
+ Copyright (c) J.J. Green 2019
9
+ */
10
+
11
+ #ifndef RTREE_STATE_H
12
+ #define RTREE_STATE_H
13
+
14
+ #ifdef __cplusplus
15
+ extern "C" {
16
+ #endif
17
+
18
+ #include <stdlib.h>
19
+ #include <stdint.h>
20
+ #include <stdbool.h>
21
+
22
+ #include <rtree/types.h>
23
+ #include <rtree/rectf.h>
24
+
25
+ typedef uint32_t state_flags_t;
26
+
27
+ typedef struct
28
+ {
29
+ size_t dims, factor;
30
+ rtree_coord_t volume;
31
+ struct {
32
+ size_t page, branch, node;
33
+ } size;
34
+ struct {
35
+ rectf_rsv_t *spherical_volume;
36
+ rectf_rc_t *combine;
37
+ } rectf;
38
+ state_flags_t flags;
39
+ } state_t;
40
+
41
+ #define RTREE_DEFAULT 0
42
+
43
+ #define RTREE_SPLIT_QUADRATIC 0
44
+ #define RTREE_SPLIT_LINEAR 1
45
+ #define RTREE_SPLIT_GREENE 2
46
+
47
+ #define RTREE_NODE_PAGE(n) ((n) << 2)
48
+
49
+ state_t* state_new(size_t, state_flags_t);
50
+ state_t* state_clone(const state_t*);
51
+ void state_destroy(state_t*);
52
+ state_flags_t state_split(const state_t*);
53
+ state_flags_t state_node_page(const state_t*);
54
+ bool state_identical(const state_t*, const state_t*);
55
+
56
+ inline rtree_coord_t state_rsv(const state_t *state, const rtree_coord_t *rect)
57
+ {
58
+ return state->rectf.spherical_volume(state->dims, rect) * state->volume;
59
+ }
60
+
61
+ inline void state_rc(const state_t *state,
62
+ const rtree_coord_t *rect0,
63
+ const rtree_coord_t *rect1,
64
+ rtree_coord_t *rect2)
65
+ {
66
+ state->rectf.combine(state->dims, rect0, rect1, rect2);
67
+ }
68
+
69
+ inline size_t state_dims(const state_t *state)
70
+ {
71
+ return state->dims;
72
+ }
73
+
74
+ inline size_t state_branch_size(const state_t *state)
75
+ {
76
+ return state->size.branch;
77
+ }
78
+
79
+ inline size_t state_page_size(const state_t *state)
80
+ {
81
+ return state->size.page;
82
+ }
83
+
84
+ inline size_t state_node_size(const state_t *state)
85
+ {
86
+ return state->size.node;
87
+ }
88
+
89
+ inline size_t state_rect_size(const state_t *state)
90
+ {
91
+ return state_dims(state) * 2 * sizeof(rtree_coord_t);
92
+ }
93
+
94
+ inline size_t state_branching_factor(const state_t *state)
95
+ {
96
+ return state->factor;
97
+ }
98
+
99
+ inline double state_unit_sphere_volume(const state_t *state)
100
+ {
101
+ return state->volume;
102
+ }
103
+
104
+ inline size_t state_bytes(const state_t *state)
105
+ {
106
+ return (state ? sizeof(state_t) : 0);
107
+ }
108
+
109
+ #ifdef __cplusplus
110
+ }
111
+ #endif
112
+
113
+ #endif
@@ -0,0 +1,14 @@
1
+ /*
2
+ rtree/types.h
3
+ Copyright (c) J.J. Green 2020
4
+ */
5
+
6
+ #ifndef RTREE_TYPES_H
7
+ #define RTREE_TYPES_H
8
+
9
+ #include <stdint.h>
10
+
11
+ typedef double rtree_coord_t;
12
+ typedef uint64_t rtree_id_t;
13
+
14
+ #endif
@@ -0,0 +1,197 @@
1
+ #ifdef HAVE_CONFIG_H
2
+ #include "config.h"
3
+ #endif
4
+
5
+ #include "rtree.h"
6
+ #include "rtree/error.h"
7
+
8
+ #include "csv.h"
9
+ #include "json.h"
10
+ #include "bsrt.h"
11
+
12
+ #include <errno.h>
13
+ #include <stdlib.h>
14
+
15
+ rtree_t* rtree_alloc(void)
16
+ {
17
+ rtree_t *rtree;
18
+
19
+ if ((rtree = malloc(sizeof(rtree_t))) == NULL)
20
+ errno = ENOMEM;
21
+ else
22
+ {
23
+ rtree->state = NULL;
24
+ rtree->root = NULL;
25
+ }
26
+
27
+ return rtree;
28
+ }
29
+
30
+ int rtree_init(rtree_t *rtree, size_t dims, state_flags_t flags)
31
+ {
32
+ state_t *state;
33
+
34
+ if ((state = state_new(dims, flags)) != NULL)
35
+ {
36
+ node_t *root;
37
+
38
+ if ((root = node_new(state)) != NULL)
39
+ {
40
+ rtree->state = state;
41
+ rtree->root = root;
42
+
43
+ return 0;
44
+ }
45
+
46
+ state_destroy(state);
47
+ }
48
+
49
+ return 1;
50
+ }
51
+
52
+ rtree_t* rtree_new(size_t dims, state_flags_t flags)
53
+ {
54
+ rtree_t *rtree;
55
+
56
+ if ((rtree = rtree_alloc()) != NULL)
57
+ {
58
+ if ((rtree_init(rtree, dims, flags)) == 0)
59
+ return rtree;
60
+
61
+ free(rtree);
62
+ }
63
+
64
+ return NULL;
65
+ }
66
+
67
+ rtree_t* rtree_clone(const rtree_t *src)
68
+ {
69
+ node_t *dest_root;
70
+
71
+ if ((dest_root = node_clone(src->state, src->root)) != NULL)
72
+ {
73
+ state_t *dest_state;
74
+ if ((dest_state = state_clone(src->state)) != NULL)
75
+ {
76
+ rtree_t *dest;
77
+
78
+ if ((dest = rtree_alloc()) == NULL)
79
+ errno = ENOMEM;
80
+ else
81
+ {
82
+ dest->root = dest_root;
83
+ dest->state = dest_state;
84
+ return dest;
85
+ }
86
+ state_destroy(dest_state);
87
+ }
88
+ node_destroy(src->state, dest_root);
89
+ }
90
+ return NULL;
91
+ }
92
+
93
+ void rtree_destroy(rtree_t *rtree)
94
+ {
95
+ if (rtree != NULL)
96
+ {
97
+ node_destroy(rtree->state, rtree->root);
98
+ state_destroy(rtree->state);
99
+ }
100
+ free(rtree);
101
+ }
102
+
103
+ rtree_height_t rtree_height(const rtree_t *rtree)
104
+ {
105
+ return node_height(rtree->state, rtree->root);
106
+ }
107
+
108
+ rtree_t* rtree_csv_read(FILE *stream, size_t dim, state_flags_t flags)
109
+ {
110
+ return csv_rtree_read(stream, dim, flags);
111
+ }
112
+
113
+ int rtree_json_write(const rtree_t *rtree, FILE *stream)
114
+ {
115
+ return json_rtree_write(rtree, stream);
116
+ }
117
+
118
+ rtree_t* rtree_json_read(FILE *stream)
119
+ {
120
+ return json_rtree_read(stream);
121
+ }
122
+
123
+ int rtree_bsrt_write(const rtree_t *rtree, FILE *stream)
124
+ {
125
+ return bsrt_rtree_write(rtree, stream);
126
+ }
127
+
128
+ rtree_t* rtree_bsrt_read(FILE *stream)
129
+ {
130
+ return bsrt_rtree_read(stream);
131
+ }
132
+
133
+ int rtree_add_rect(rtree_t *rtree, rtree_id_t id, rtree_coord_t *rect)
134
+ {
135
+ node_t *node = node_add_rect(rtree->state, id, rect, rtree->root, 0);
136
+
137
+ if (node == NULL)
138
+ return RTREE_ERR_ADDRECT;
139
+
140
+ if (node != rtree->root)
141
+ rtree->root = node;
142
+
143
+ return RTREE_OK;
144
+ }
145
+
146
+ int rtree_update(rtree_t *rtree, rtree_update_t *f, void *context)
147
+ {
148
+ return node_update(rtree->state, rtree->root, f, context);
149
+ }
150
+
151
+ bool rtree_identical(const rtree_t *a, const rtree_t *b)
152
+ {
153
+ if (a && b)
154
+ {
155
+ return
156
+ state_identical(a->state, b->state) &&
157
+ node_identical(a->state, a->root, b->root);
158
+ }
159
+
160
+ return ! (a || b);
161
+ }
162
+
163
+ int rtree_search(const rtree_t *rtree, const rtree_coord_t *rect,
164
+ rtree_search_t *f, void *arg)
165
+ {
166
+ return search(rtree->state, rect, rtree->root, f, arg);
167
+ }
168
+
169
+ int rtree_postscript(const rtree_t *rtree,
170
+ const rtree_postscript_t *options,
171
+ FILE *stream)
172
+ {
173
+ return postscript_write(rtree->state, rtree->root, options, stream);
174
+ }
175
+
176
+ const char* rtree_strerror(int err)
177
+ {
178
+ return strerror_rtree(err);
179
+ }
180
+
181
+ size_t rtree_bytes(const rtree_t *rtree)
182
+ {
183
+ if (rtree == NULL)
184
+ return 0;
185
+ else
186
+ return
187
+ sizeof(rtree_t) +
188
+ state_bytes(rtree->state) +
189
+ node_bytes(rtree->state, rtree->root);
190
+ }
191
+
192
+ bool rtree_empty(const rtree_t *rtree)
193
+ {
194
+ return
195
+ (rtree == NULL) ||
196
+ (! node_nonempty(rtree->state, rtree->root));
197
+ }
@@ -0,0 +1,62 @@
1
+ /*
2
+ rtree.h
3
+
4
+ This is the bottom-level "public" header, it does not
5
+ include all of the rtree headers, just enough to define
6
+ the members of the (atypically) open structure rtree_t.
7
+
8
+ Copyright (c) J.J. Green 2020
9
+ */
10
+
11
+ #ifndef RTREE_H
12
+ #define RTREE_H
13
+
14
+ #ifdef __cplusplus
15
+ extern "C" {
16
+ #endif
17
+
18
+ #include <stdio.h>
19
+ #include <stdint.h>
20
+ #include <stdbool.h>
21
+
22
+ typedef struct rtree_t rtree_t;
23
+ typedef uint16_t rtree_height_t;
24
+
25
+ #include <rtree/types.h>
26
+ #include <rtree/state.h>
27
+ #include <rtree/node.h>
28
+ #include <rtree/postscript.h>
29
+ #include <rtree/search.h>
30
+ #include <rtree/error.h>
31
+
32
+ struct rtree_t
33
+ {
34
+ state_t *state;
35
+ node_t *root;
36
+ };
37
+
38
+ rtree_t* rtree_alloc(void);
39
+ int rtree_init(rtree_t*, size_t, state_flags_t);
40
+ rtree_t* rtree_new(size_t, state_flags_t);
41
+ rtree_t* rtree_clone(const rtree_t*);
42
+ void rtree_destroy(rtree_t*);
43
+ rtree_height_t rtree_height(const rtree_t*);
44
+ int rtree_search(const rtree_t*, const rtree_coord_t*, rtree_search_t*, void*);
45
+ int rtree_add_rect(rtree_t*, rtree_id_t, rtree_coord_t*);
46
+ int rtree_update(rtree_t*, rtree_update_t*, void*);
47
+ bool rtree_identical(const rtree_t*, const rtree_t*);
48
+ rtree_t* rtree_csv_read(FILE*, size_t, state_flags_t);
49
+ int rtree_json_write(const rtree_t*, FILE*);
50
+ rtree_t* rtree_json_read(FILE*);
51
+ int rtree_bsrt_write(const rtree_t*, FILE*);
52
+ rtree_t* rtree_bsrt_read(FILE*);
53
+ int rtree_postscript(const rtree_t*, const rtree_postscript_t*, FILE*);
54
+ const char* rtree_strerror(int);
55
+ size_t rtree_bytes(const rtree_t*);
56
+ bool rtree_empty(const rtree_t*);
57
+
58
+ #ifdef __cplusplus
59
+ }
60
+ #endif
61
+
62
+ #endif
@@ -0,0 +1,54 @@
1
+ #ifdef HAVE_CONFIG_H
2
+ #include "config.h"
3
+ #endif
4
+
5
+ #include "rtree/search.h"
6
+
7
+ #include "rtree/branch.h"
8
+ #include "rtree/error.h"
9
+ #include "rtree/rect.h"
10
+
11
+ typedef struct
12
+ {
13
+ rtree_search_t *callback;
14
+ void *context;
15
+ const rtree_coord_t *rect;
16
+ } search_context_t;
17
+
18
+ static int internal(const state_t *state,
19
+ const branch_t *branch, void *arg)
20
+ {
21
+ int err = RTREE_OK;
22
+ search_context_t *search_context = arg;
23
+ if (rect_intersect(state, branch_get_rect(branch), search_context->rect))
24
+ err = search(state, search_context->rect, branch_get_child(branch),
25
+ search_context->callback, search_context->context);
26
+ return err;
27
+ }
28
+
29
+ static int leaf(const state_t *state,
30
+ const branch_t *branch, void *arg)
31
+ {
32
+ int err = RTREE_OK;
33
+ search_context_t *search_context = arg;
34
+ if (rect_intersect(state, branch_get_rect(branch), search_context->rect))
35
+ err = search_context->callback(branch_get_id(branch),
36
+ search_context->context);
37
+ return err;
38
+ }
39
+
40
+ int search(const state_t *state,
41
+ const rtree_coord_t *rect, const node_t *node,
42
+ rtree_search_t *callback, void *context)
43
+ {
44
+ search_context_t search_context = {
45
+ .callback = callback,
46
+ .context = context,
47
+ .rect = rect
48
+ };
49
+ node_level_t level = node_level(node);
50
+
51
+ return node_branch_each(state, node,
52
+ level > 0 ? internal : leaf,
53
+ &search_context);
54
+ }