librtree 0.9.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -0
  3. data/COPYING +21 -0
  4. data/README.md +86 -0
  5. data/ext/rtree/extconf.rb +37 -19
  6. data/ext/rtree/lib/bindex.c +157 -0
  7. data/ext/rtree/lib/bindex.h +31 -0
  8. data/ext/rtree/lib/bounds.h +21 -0
  9. data/ext/rtree/lib/branch.c +51 -0
  10. data/ext/rtree/lib/branches.c +17 -0
  11. data/ext/rtree/lib/bsrt.c +704 -0
  12. data/ext/rtree/lib/bsrt.h +16 -0
  13. data/ext/rtree/lib/constants.h +19 -0
  14. data/ext/rtree/lib/csv.c +81 -0
  15. data/ext/rtree/lib/csv.h +16 -0
  16. data/ext/rtree/lib/endianness.h +83 -0
  17. data/ext/rtree/lib/error.c +47 -0
  18. data/ext/rtree/lib/json.c +491 -0
  19. data/ext/rtree/lib/json.h +16 -0
  20. data/ext/rtree/lib/mk/Hdr.mk +3 -0
  21. data/ext/rtree/lib/mk/MakeDepend +25 -0
  22. data/ext/rtree/lib/mk/Obj.mk +3 -0
  23. data/ext/rtree/lib/node.c +708 -0
  24. data/ext/rtree/lib/package.c +11 -0
  25. data/ext/rtree/lib/page.c +47 -0
  26. data/ext/rtree/lib/page.h +13 -0
  27. data/ext/rtree/lib/postscript.c +543 -0
  28. data/ext/rtree/lib/rect.c +139 -0
  29. data/ext/rtree/lib/rectf.c +219 -0
  30. data/ext/rtree/lib/rtree/branch.h +105 -0
  31. data/ext/rtree/lib/rtree/branches.h +38 -0
  32. data/ext/rtree/lib/rtree/error.h +42 -0
  33. data/ext/rtree/lib/rtree/extent.h +20 -0
  34. data/ext/rtree/lib/rtree/node.h +92 -0
  35. data/ext/rtree/lib/rtree/package.h +14 -0
  36. data/ext/rtree/lib/rtree/postscript.h +66 -0
  37. data/ext/rtree/lib/rtree/rect.h +38 -0
  38. data/ext/rtree/lib/rtree/rectf.h +34 -0
  39. data/ext/rtree/lib/rtree/search.h +27 -0
  40. data/ext/rtree/lib/rtree/state.h +113 -0
  41. data/ext/rtree/lib/rtree/types.h +14 -0
  42. data/ext/rtree/lib/rtree-base.c +190 -0
  43. data/ext/rtree/lib/rtree.h +61 -0
  44. data/ext/rtree/lib/search.c +54 -0
  45. data/ext/rtree/lib/split.c +710 -0
  46. data/ext/rtree/lib/split.h +15 -0
  47. data/ext/rtree/lib/spvol.c +48 -0
  48. data/ext/rtree/lib/spvol.h +13 -0
  49. data/ext/rtree/lib/state.c +169 -0
  50. metadata +50 -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,190 @@
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
+ }
@@ -0,0 +1,61 @@
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
+
57
+ #ifdef __cplusplus
58
+ }
59
+ #endif
60
+
61
+ #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
+ }