librtree 0.9.1 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +80 -0
- data/COPYING +21 -0
- data/README.md +87 -0
- data/ext/rtree/extconf.rb +37 -19
- data/ext/rtree/lib/README.md +9 -0
- data/ext/rtree/lib/bindex.c +157 -0
- data/ext/rtree/lib/bindex.h +31 -0
- data/ext/rtree/lib/bounds.h +21 -0
- data/ext/rtree/lib/branch.c +51 -0
- data/ext/rtree/lib/branches.c +17 -0
- data/ext/rtree/lib/bsrt.c +704 -0
- data/ext/rtree/lib/bsrt.h +16 -0
- data/ext/rtree/lib/constants.h +19 -0
- data/ext/rtree/lib/csv.c +81 -0
- data/ext/rtree/lib/csv.h +16 -0
- data/ext/rtree/lib/endianness.h +83 -0
- data/ext/rtree/lib/error.c +47 -0
- data/ext/rtree/lib/json.c +491 -0
- data/ext/rtree/lib/json.h +16 -0
- data/ext/rtree/lib/mk/Hdr.mk +3 -0
- data/ext/rtree/lib/mk/MakeDepend +25 -0
- data/ext/rtree/lib/mk/Obj.mk +3 -0
- data/ext/rtree/lib/node.c +736 -0
- data/ext/rtree/lib/package.c +11 -0
- data/ext/rtree/lib/page.c +47 -0
- data/ext/rtree/lib/page.h +13 -0
- data/ext/rtree/lib/postscript.c +543 -0
- data/ext/rtree/lib/rect.c +139 -0
- data/ext/rtree/lib/rectf.c +219 -0
- data/ext/rtree/lib/rtree/branch.h +105 -0
- data/ext/rtree/lib/rtree/branches.h +38 -0
- data/ext/rtree/lib/rtree/error.h +42 -0
- data/ext/rtree/lib/rtree/extent.h +20 -0
- data/ext/rtree/lib/rtree/node.h +96 -0
- data/ext/rtree/lib/rtree/package.h +14 -0
- data/ext/rtree/lib/rtree/postscript.h +66 -0
- data/ext/rtree/lib/rtree/rect.h +38 -0
- data/ext/rtree/lib/rtree/rectf.h +34 -0
- data/ext/rtree/lib/rtree/search.h +27 -0
- data/ext/rtree/lib/rtree/state.h +113 -0
- data/ext/rtree/lib/rtree/types.h +14 -0
- data/ext/rtree/lib/rtree-base.c +197 -0
- data/ext/rtree/lib/rtree.h +62 -0
- data/ext/rtree/lib/search.c +54 -0
- data/ext/rtree/lib/split.c +710 -0
- data/ext/rtree/lib/split.h +15 -0
- data/ext/rtree/lib/spvol.c +48 -0
- data/ext/rtree/lib/spvol.h +13 -0
- data/ext/rtree/lib/state.c +169 -0
- data/ext/rtree/rtree.c +11 -0
- data/lib/rtree.rb +4 -4
- metadata +65 -3
@@ -0,0 +1,139 @@
|
|
1
|
+
#ifdef HAVE_CONFIG_H
|
2
|
+
#include "config.h"
|
3
|
+
#endif
|
4
|
+
|
5
|
+
#include "rtree/rect.h"
|
6
|
+
#include "rtree/error.h"
|
7
|
+
|
8
|
+
#ifdef HAVE_TGMATH_H
|
9
|
+
#include <tgmath.h>
|
10
|
+
#else
|
11
|
+
#include <math.h>
|
12
|
+
#endif
|
13
|
+
|
14
|
+
#ifdef HAVE_FEATURES_H
|
15
|
+
#include <features.h>
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#include <string.h>
|
19
|
+
#include <errno.h>
|
20
|
+
|
21
|
+
int rect_init(const state_t *state, rtree_coord_t *rect)
|
22
|
+
{
|
23
|
+
if (rect == NULL)
|
24
|
+
return RTREE_ERR_INVAL;
|
25
|
+
|
26
|
+
#ifdef __STDC_IEC_559__
|
27
|
+
|
28
|
+
memset(rect, 0, state_rect_size(state));
|
29
|
+
|
30
|
+
#else
|
31
|
+
|
32
|
+
const size_t dims = state_dims(state);
|
33
|
+
|
34
|
+
for (size_t i = 0 ; i < 2 * dims ; i++)
|
35
|
+
rect[i] = 0;
|
36
|
+
|
37
|
+
#endif
|
38
|
+
|
39
|
+
return RTREE_OK;
|
40
|
+
}
|
41
|
+
|
42
|
+
bool rect_intersect(const state_t *state,
|
43
|
+
const rtree_coord_t *a, const rtree_coord_t *b)
|
44
|
+
{
|
45
|
+
const size_t dims = state_dims(state);
|
46
|
+
|
47
|
+
for (size_t dim = 0 ; dim < dims ; dim++)
|
48
|
+
{
|
49
|
+
const size_t
|
50
|
+
low = dim,
|
51
|
+
high = dim + dims;
|
52
|
+
|
53
|
+
if ((a[high] < b[low]) || (a[low] > b[high]))
|
54
|
+
return false;
|
55
|
+
}
|
56
|
+
|
57
|
+
return true;
|
58
|
+
}
|
59
|
+
|
60
|
+
rtree_coord_t rect_volume(const state_t *state, const rtree_coord_t *rect)
|
61
|
+
{
|
62
|
+
const size_t dims = state_dims(state);
|
63
|
+
rtree_coord_t v = rect[dims] - rect[0];
|
64
|
+
|
65
|
+
for (size_t i = 1 ; i < dims ; i++)
|
66
|
+
v *= (rect[dims + i] - rect[i]);
|
67
|
+
|
68
|
+
return v;
|
69
|
+
}
|
70
|
+
|
71
|
+
rtree_coord_t rect_spherical_volume(const state_t *state,
|
72
|
+
const rtree_coord_t *rect)
|
73
|
+
{
|
74
|
+
return state_rsv(state, rect);
|
75
|
+
}
|
76
|
+
|
77
|
+
void rect_copy(const state_t *state, const rtree_coord_t *src,
|
78
|
+
rtree_coord_t *dest)
|
79
|
+
{
|
80
|
+
memcpy(dest, src, state_rect_size(state));
|
81
|
+
}
|
82
|
+
|
83
|
+
|
84
|
+
void rect_combine(const state_t *state,
|
85
|
+
const rtree_coord_t *restrict rect0,
|
86
|
+
const rtree_coord_t *restrict rect1,
|
87
|
+
rtree_coord_t *restrict rect2)
|
88
|
+
{
|
89
|
+
state_rc(state, rect0, rect1, rect2);
|
90
|
+
}
|
91
|
+
|
92
|
+
void rect_merge(const state_t *state,
|
93
|
+
const rtree_coord_t *rect0,
|
94
|
+
rtree_coord_t *rect1)
|
95
|
+
{
|
96
|
+
state_rc(state, rect0, rect1, rect1);
|
97
|
+
}
|
98
|
+
|
99
|
+
bool rect_identical(const state_t *state,
|
100
|
+
const rtree_coord_t *rect0,
|
101
|
+
const rtree_coord_t *rect1)
|
102
|
+
{
|
103
|
+
for (size_t i = 0 ; i < 2 * state_dims(state) ; i++)
|
104
|
+
if (rect0[i] != rect1[i]) return false;
|
105
|
+
return true;
|
106
|
+
}
|
107
|
+
|
108
|
+
/*
|
109
|
+
Allocates n rectangles (as rtree_coord_t*) and assigns them to the
|
110
|
+
elements of the array rects, which should already be allocated (so
|
111
|
+
one would pass 'array' declared as rtree_coord_t *array[2], for
|
112
|
+
example).
|
113
|
+
*/
|
114
|
+
|
115
|
+
int rects_alloc(const state_t *state, size_t n, rtree_coord_t **rects)
|
116
|
+
{
|
117
|
+
const size_t
|
118
|
+
dims = state_dims(state),
|
119
|
+
rect_size = state_rect_size(state);
|
120
|
+
rtree_coord_t *floats;
|
121
|
+
|
122
|
+
if ((floats = calloc(n, rect_size)) == NULL)
|
123
|
+
return RTREE_ERR_NOMEM;
|
124
|
+
|
125
|
+
*rects = floats;
|
126
|
+
|
127
|
+
for (size_t i = 1 ; i < n ; i++)
|
128
|
+
rects[i] = floats + 2 * i * dims;
|
129
|
+
|
130
|
+
return RTREE_OK;
|
131
|
+
}
|
132
|
+
|
133
|
+
void rects_free(size_t n, rtree_coord_t **rects)
|
134
|
+
{
|
135
|
+
free(*rects);
|
136
|
+
|
137
|
+
for (size_t i = 0 ; i < n ; i++)
|
138
|
+
rects[i] = NULL;
|
139
|
+
}
|
@@ -0,0 +1,219 @@
|
|
1
|
+
#ifdef HAVE_CONFIG_H
|
2
|
+
#include "config.h"
|
3
|
+
#endif
|
4
|
+
|
5
|
+
#include "rtree/rectf.h"
|
6
|
+
|
7
|
+
#ifdef HAVE_TGMATH_H
|
8
|
+
#include <tgmath.h>
|
9
|
+
#else
|
10
|
+
#include <math.h>
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#ifdef HAVE_XMMINTRIN_H
|
14
|
+
#include <xmmintrin.h>
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#ifdef HAVE_IMMINTRIN_H
|
18
|
+
#include <immintrin.h>
|
19
|
+
#endif
|
20
|
+
|
21
|
+
/*
|
22
|
+
rect_spherical_volume has some simplifications for small dimensions
|
23
|
+
(one need not call pow(), for example), and it gets called a lot so
|
24
|
+
worth selecting which to use just the once.
|
25
|
+
*/
|
26
|
+
|
27
|
+
#pragma GCC diagnostic push
|
28
|
+
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
29
|
+
|
30
|
+
rtree_coord_t rectf_rsv1(size_t dims, const rtree_coord_t *rect)
|
31
|
+
{
|
32
|
+
return 0.5 * fabs(rect[1] - rect[0]);
|
33
|
+
}
|
34
|
+
|
35
|
+
rtree_coord_t rectf_rsv2(size_t dims, const rtree_coord_t *rect)
|
36
|
+
{
|
37
|
+
rtree_coord_t
|
38
|
+
hx1 = rect[2] - rect[0],
|
39
|
+
hx2 = rect[3] - rect[1],
|
40
|
+
r2 = hx1 * hx1 + hx2 * hx2;
|
41
|
+
|
42
|
+
return 0.25 * r2;
|
43
|
+
}
|
44
|
+
|
45
|
+
#pragma GCC diagnostic pop
|
46
|
+
|
47
|
+
rtree_coord_t rectf_rsvd(size_t dims, const rtree_coord_t *rect)
|
48
|
+
{
|
49
|
+
rtree_coord_t
|
50
|
+
hx = rect[dims] - rect[0],
|
51
|
+
r2 = hx * hx;
|
52
|
+
|
53
|
+
for (size_t i = 1 ; i < dims ; i++)
|
54
|
+
{
|
55
|
+
hx = rect[i + dims] - rect[i];
|
56
|
+
r2 += hx * hx;
|
57
|
+
}
|
58
|
+
|
59
|
+
return pow(0.25 * r2, 0.5 * dims);
|
60
|
+
}
|
61
|
+
|
62
|
+
rectf_rsv_t* rectf_spherical_volume(size_t dims)
|
63
|
+
{
|
64
|
+
switch (dims)
|
65
|
+
{
|
66
|
+
case 1:
|
67
|
+
return rectf_rsv1;
|
68
|
+
case 2:
|
69
|
+
return rectf_rsv2;
|
70
|
+
default:
|
71
|
+
return rectf_rsvd;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
/*
|
76
|
+
rect_combine is performance-critical, and we use the same trick
|
77
|
+
for cases where the entire rectangle fits in a wide register:
|
78
|
+
the 128-bit register (SSE2) in the dim-2 float case, the 256
|
79
|
+
register (AVX) in the dim-3, -4 float and dim-2 double case. for
|
80
|
+
the first, We XOR with the "sign-mask" { 0, 0, -0, -0 } to sign
|
81
|
+
change the last two values, then find the min, then XOR again.
|
82
|
+
The result is the min of the bottom two values, the max of the
|
83
|
+
top two.
|
84
|
+
|
85
|
+
The dim-4 float and dim-2 double cases are similar, the dim-3
|
86
|
+
float version is the trickiest since we need to load 6 floats
|
87
|
+
into an 8-float register, so we need a mask (which is an AVX
|
88
|
+
facility).
|
89
|
+
*/
|
90
|
+
|
91
|
+
void rectf_rcd(size_t dims,
|
92
|
+
const rtree_coord_t *rect0,
|
93
|
+
const rtree_coord_t *rect1,
|
94
|
+
rtree_coord_t *rect2)
|
95
|
+
{
|
96
|
+
for (size_t i = 0 ; i < dims ; i++)
|
97
|
+
{
|
98
|
+
const size_t j = i + dims;
|
99
|
+
const rtree_coord_t
|
100
|
+
x0 = rect0[i], x1 = rect1[i],
|
101
|
+
y0 = rect0[j], y1 = rect1[j];
|
102
|
+
|
103
|
+
rect2[i] = fmin(x0, x1);
|
104
|
+
rect2[j] = fmax(y0, y1);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
#pragma GCC diagnostic push
|
109
|
+
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
110
|
+
|
111
|
+
#if SIZEOF_RTREE_COORD_T == 4
|
112
|
+
|
113
|
+
#ifdef HAVE_SSE2
|
114
|
+
|
115
|
+
void rectf_rc2(size_t dims,
|
116
|
+
const rtree_coord_t *rect0,
|
117
|
+
const rtree_coord_t *rect1,
|
118
|
+
rtree_coord_t *rect2)
|
119
|
+
{
|
120
|
+
const __m128
|
121
|
+
sm = { 0.0f, 0.0f, -0.0f, -0.0f },
|
122
|
+
sr0 = _mm_loadu_ps(rect0),
|
123
|
+
sr1 = _mm_loadu_ps(rect1),
|
124
|
+
srmin = _mm_min_ps(_mm_xor_ps(sm, sr0), _mm_xor_ps(sm, sr1)),
|
125
|
+
res = _mm_xor_ps(sm, srmin);
|
126
|
+
|
127
|
+
_mm_storeu_ps(rect2, res);
|
128
|
+
}
|
129
|
+
|
130
|
+
|
131
|
+
#endif
|
132
|
+
|
133
|
+
#ifdef HAVE_AVX
|
134
|
+
|
135
|
+
void rectf_rc3(size_t dims,
|
136
|
+
const rtree_coord_t *rect0,
|
137
|
+
const rtree_coord_t *rect1,
|
138
|
+
rtree_coord_t *rect2)
|
139
|
+
{
|
140
|
+
const __m256i
|
141
|
+
mask = _mm256_setr_epi32(-1, -1, -1, -1, -1, -1, 0, 0);
|
142
|
+
const __m256
|
143
|
+
sm = { 0.0f, 0.0f, 0.0f, -0.0f, -0.0f, -0.0f, 0.0f, 0.0f },
|
144
|
+
sr0 = _mm256_maskload_ps(rect0, mask),
|
145
|
+
sr1 = _mm256_maskload_ps(rect1, mask),
|
146
|
+
srmin = _mm256_min_ps(_mm256_xor_ps(sm, sr0), _mm256_xor_ps(sm, sr1)),
|
147
|
+
res = _mm256_xor_ps(sm, srmin);
|
148
|
+
|
149
|
+
_mm256_maskstore_ps(rect2, mask, res);
|
150
|
+
}
|
151
|
+
|
152
|
+
void rectf_rc4(size_t dims,
|
153
|
+
const rtree_coord_t *rect0,
|
154
|
+
const rtree_coord_t *rect1,
|
155
|
+
rtree_coord_t *rect2)
|
156
|
+
{
|
157
|
+
const __m256
|
158
|
+
sm = { 0.0f, 0.0f, 0.0f, 0.0f, -0.0f, -0.0f, -0.0f, -0.0f },
|
159
|
+
sr0 = _mm256_loadu_ps(rect0),
|
160
|
+
sr1 = _mm256_loadu_ps(rect1),
|
161
|
+
srmin = _mm256_min_ps(_mm256_xor_ps(sm, sr0), _mm256_xor_ps(sm, sr1)),
|
162
|
+
res = _mm256_xor_ps(sm, srmin);
|
163
|
+
|
164
|
+
_mm256_storeu_ps(rect2, res);
|
165
|
+
}
|
166
|
+
|
167
|
+
#endif
|
168
|
+
|
169
|
+
#elif SIZEOF_RTREE_COORD_T == 8
|
170
|
+
|
171
|
+
#ifdef HAVE_AVX
|
172
|
+
|
173
|
+
void rectf_rc2(size_t dims,
|
174
|
+
const rtree_coord_t *rect0,
|
175
|
+
const rtree_coord_t *rect1,
|
176
|
+
rtree_coord_t *rect2)
|
177
|
+
{
|
178
|
+
const __m256d
|
179
|
+
sm = { 0.0, 0.0, -0.0, -0.0 },
|
180
|
+
sr0 = _mm256_loadu_pd(rect0),
|
181
|
+
sr1 = _mm256_loadu_pd(rect1),
|
182
|
+
srmin = _mm256_min_pd(_mm256_xor_pd(sm, sr0), _mm256_xor_pd(sm, sr1)),
|
183
|
+
res = _mm256_xor_pd(sm, srmin);
|
184
|
+
|
185
|
+
_mm256_storeu_pd(rect2, res);
|
186
|
+
}
|
187
|
+
|
188
|
+
#endif
|
189
|
+
|
190
|
+
#else
|
191
|
+
#error "strange size for rtree_coord_t"
|
192
|
+
#endif
|
193
|
+
|
194
|
+
#pragma GCC diagnostic pop
|
195
|
+
|
196
|
+
rectf_rc_t* rectf_combine(size_t dims)
|
197
|
+
{
|
198
|
+
switch (dims)
|
199
|
+
{
|
200
|
+
|
201
|
+
#if SIZEOF_RTREE_COORD_T == 4
|
202
|
+
# ifdef HAVE_SSE2
|
203
|
+
case 2: return rectf_rc2;
|
204
|
+
# endif
|
205
|
+
# ifdef HAVE_AVX
|
206
|
+
case 3: return rectf_rc3;
|
207
|
+
case 4: return rectf_rc4;
|
208
|
+
# endif
|
209
|
+
#elif SIZEOF_RTREE_COORD_T == 8
|
210
|
+
# ifdef HAVE_AVX
|
211
|
+
case 2: return rectf_rc2;
|
212
|
+
# endif
|
213
|
+
#else
|
214
|
+
# error "strange size for rtree_coord_t"
|
215
|
+
#endif
|
216
|
+
|
217
|
+
default: return rectf_rcd;
|
218
|
+
}
|
219
|
+
}
|
@@ -0,0 +1,105 @@
|
|
1
|
+
/*
|
2
|
+
rtree/branch.h
|
3
|
+
Copyright (c) J.J. Green 2019
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_BRANCH_H
|
7
|
+
#define RTREE_BRANCH_H
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#include <stdlib.h>
|
14
|
+
|
15
|
+
typedef struct branch_t branch_t;
|
16
|
+
|
17
|
+
#include <rtree/types.h>
|
18
|
+
#include <rtree/state.h>
|
19
|
+
#include <rtree/node.h>
|
20
|
+
#include <rtree/rect.h>
|
21
|
+
|
22
|
+
/*
|
23
|
+
The union is either a pointer to the child-node in the tree, or
|
24
|
+
if we are at level zero, the id payload. The latter may as well
|
25
|
+
be the size of a pointer.
|
26
|
+
|
27
|
+
The rect is big enough to hold 2 * dims floats, understood to be
|
28
|
+
[x0, y0, ..., x1, y1, ...] corresponding to the (hyper-)rectangle
|
29
|
+
x0 < x < x1, y0 < y < y1, ..., this must be at the end of the
|
30
|
+
struct (since variable).
|
31
|
+
|
32
|
+
For the sake of SSE, we would like the rect member to be 16-byte
|
33
|
+
aligned, and this could be done with
|
34
|
+
|
35
|
+
rtree_coord_t alignas(16) rect[];
|
36
|
+
|
37
|
+
but this would force the size of branch_t to be a multiple of 16,
|
38
|
+
so for the dimension 2 case with rtree_coord_t a float increases
|
39
|
+
branch size from 24 to 32 bytes, essentially increasing the size
|
40
|
+
of the tree by 20%. So we don't do that, and use non-aligned
|
41
|
+
variants for SSE load/save (apparently on recent CPUs the penalty
|
42
|
+
is pretty small).
|
43
|
+
*/
|
44
|
+
|
45
|
+
struct branch_t
|
46
|
+
{
|
47
|
+
union {
|
48
|
+
node_t *child;
|
49
|
+
rtree_id_t id;
|
50
|
+
};
|
51
|
+
rtree_coord_t rect[];
|
52
|
+
};
|
53
|
+
|
54
|
+
size_t branch_sizeof(size_t);
|
55
|
+
int branch_init(const state_t*, branch_t*);
|
56
|
+
branch_t* branch_copy(const state_t*, const branch_t*, branch_t*);
|
57
|
+
|
58
|
+
/* inline accessors */
|
59
|
+
|
60
|
+
inline void branch_set_child(branch_t *branch, node_t *child)
|
61
|
+
{
|
62
|
+
branch->child = child;
|
63
|
+
}
|
64
|
+
|
65
|
+
inline const node_t* branch_get_child(const branch_t *branch)
|
66
|
+
{
|
67
|
+
return branch->child;
|
68
|
+
}
|
69
|
+
|
70
|
+
inline node_t* branch_get_child_mutable(branch_t *branch)
|
71
|
+
{
|
72
|
+
return branch->child;
|
73
|
+
}
|
74
|
+
|
75
|
+
inline void branch_set_id(branch_t *branch, rtree_id_t id)
|
76
|
+
{
|
77
|
+
branch->id = id;
|
78
|
+
}
|
79
|
+
|
80
|
+
inline rtree_id_t branch_get_id(const branch_t *branch)
|
81
|
+
{
|
82
|
+
return branch->id;
|
83
|
+
}
|
84
|
+
|
85
|
+
inline void branch_set_rect(const state_t *state, branch_t *branch,
|
86
|
+
const rtree_coord_t *rect)
|
87
|
+
{
|
88
|
+
rect_copy(state, rect, branch->rect);
|
89
|
+
}
|
90
|
+
|
91
|
+
inline const rtree_coord_t* branch_get_rect(const branch_t *branch)
|
92
|
+
{
|
93
|
+
return branch->rect;
|
94
|
+
}
|
95
|
+
|
96
|
+
inline rtree_coord_t* branch_get_rect_mutable(branch_t *branch)
|
97
|
+
{
|
98
|
+
return branch->rect;
|
99
|
+
}
|
100
|
+
|
101
|
+
#ifdef __cplusplus
|
102
|
+
}
|
103
|
+
#endif
|
104
|
+
|
105
|
+
#endif
|
@@ -0,0 +1,38 @@
|
|
1
|
+
/*
|
2
|
+
rtree/branches.h
|
3
|
+
Copyright (c) J.J. Green 2020
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_BRANCHES_H
|
7
|
+
#define RTREE_BRANCHES_H
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#include <stdlib.h>
|
14
|
+
#include <errno.h>
|
15
|
+
#include <string.h>
|
16
|
+
|
17
|
+
#include <rtree/state.h>
|
18
|
+
#include <rtree/branch.h>
|
19
|
+
#include <rtree/error.h>
|
20
|
+
|
21
|
+
inline branch_t* branches_get(const state_t *state, void *buffer, size_t i)
|
22
|
+
{
|
23
|
+
const size_t branch_size = state_branch_size(state);
|
24
|
+
char *bytes = (char*)buffer;
|
25
|
+
return (branch_t*)(bytes + i * branch_size);
|
26
|
+
}
|
27
|
+
|
28
|
+
inline void branches_set(const state_t *state, void *buffer, size_t i,
|
29
|
+
const branch_t *src)
|
30
|
+
{
|
31
|
+
memcpy(branches_get(state, buffer, i), src, state_branch_size(state));
|
32
|
+
}
|
33
|
+
|
34
|
+
#ifdef __cplusplus
|
35
|
+
}
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#endif
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/*
|
2
|
+
rtree/error.h
|
3
|
+
Copyright (c) J.J. Green 2020
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_ERROR_H
|
7
|
+
#define RTREE_ERROR_H
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#define RTREE_OK 0
|
14
|
+
#define RTREE_ERR_INVAL 1
|
15
|
+
#define RTREE_ERR_DOM 2
|
16
|
+
#define RTREE_ERR_NOMEM 3
|
17
|
+
#define RTREE_ERR_CSVPARSE 4
|
18
|
+
#define RTREE_ERR_NOCSV 5
|
19
|
+
#define RTREE_ERR_JANSSON 6
|
20
|
+
#define RTREE_ERR_NOJSON 7
|
21
|
+
#define RTREE_ERR_NOBSRT 8
|
22
|
+
#define RTREE_ERR_GETBRANCH 9
|
23
|
+
#define RTREE_ERR_GETCHILD 10
|
24
|
+
#define RTREE_ERR_NODECLONE 11
|
25
|
+
#define RTREE_ERR_PICKBRANCH 12
|
26
|
+
#define RTREE_ERR_ADDRECT 13
|
27
|
+
#define RTREE_ERR_NOSUCHSPLIT 14
|
28
|
+
#define RTREE_ERR_DIMS 15
|
29
|
+
#define RTREE_ERR_EMPTY 16
|
30
|
+
#define RTREE_ERR_BUFFER 17
|
31
|
+
#define RTREE_ERR_POSTSCRIPT 18
|
32
|
+
#define RTREE_ERR_USER 19
|
33
|
+
#define RTREE_ERR_FWRITE 20
|
34
|
+
#define RTREE_ERR_SPLIT 21
|
35
|
+
|
36
|
+
const char* strerror_rtree(int);
|
37
|
+
|
38
|
+
#ifdef __cplusplus
|
39
|
+
}
|
40
|
+
#endif
|
41
|
+
|
42
|
+
#endif
|
@@ -0,0 +1,20 @@
|
|
1
|
+
/*
|
2
|
+
rtree/extent.h
|
3
|
+
Just an enum indicating a choice of axis (direction)
|
4
|
+
Copyright (c) J.J. Green 2020
|
5
|
+
*/
|
6
|
+
|
7
|
+
#ifndef RTREE_EXTENT_H
|
8
|
+
#define RTREE_EXTENT_H
|
9
|
+
|
10
|
+
#ifdef __cplusplus
|
11
|
+
extern "C" {
|
12
|
+
#endif
|
13
|
+
|
14
|
+
typedef enum { axis_width, axis_height } extent_axis_t;
|
15
|
+
|
16
|
+
#ifdef __cplusplus
|
17
|
+
}
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#endif
|
@@ -0,0 +1,96 @@
|
|
1
|
+
/*
|
2
|
+
rtree/node.h
|
3
|
+
Copyright (c) J.J. Green 2019
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_NODE_H
|
7
|
+
#define RTREE_NODE_H
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#if 0
|
12
|
+
}
|
13
|
+
#endif
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#include <stdint.h>
|
17
|
+
#include <stdbool.h>
|
18
|
+
#include <stddef.h>
|
19
|
+
|
20
|
+
typedef uint16_t node_level_t;
|
21
|
+
typedef uint16_t node_count_t;
|
22
|
+
typedef uint16_t node_height_t;
|
23
|
+
|
24
|
+
#define NODE_LEVEL_MAX UINT16_MAX
|
25
|
+
#define NODE_COUNT_MAX UINT16_MAX
|
26
|
+
|
27
|
+
typedef struct node_t node_t;
|
28
|
+
|
29
|
+
#include <rtree/types.h>
|
30
|
+
#include <rtree/state.h>
|
31
|
+
#include <rtree/branch.h>
|
32
|
+
|
33
|
+
struct node_t
|
34
|
+
{
|
35
|
+
node_level_t level;
|
36
|
+
node_count_t count;
|
37
|
+
char branches[];
|
38
|
+
};
|
39
|
+
|
40
|
+
typedef int (rtree_update_t)(rtree_id_t, rtree_coord_t*, void*);
|
41
|
+
typedef int (nbe_cb_t)(const state_t*, const branch_t*, void*);
|
42
|
+
|
43
|
+
int node_init(const state_t*, node_t*);
|
44
|
+
node_t* node_new(const state_t*);
|
45
|
+
void node_destroy(const state_t*, node_t*);
|
46
|
+
node_t* node_clone(const state_t*, const node_t*);
|
47
|
+
int node_branch_each(const state_t*, const node_t*, nbe_cb_t*, void*);
|
48
|
+
int node_branch_each_level(const state_t*, const node_t*, node_level_t,
|
49
|
+
nbe_cb_t*, void*);
|
50
|
+
size_t node_num_branch(size_t, size_t);
|
51
|
+
int node_detach_branch(const state_t*, node_t*, size_t);
|
52
|
+
node_t* node_add_branch(const state_t*, node_t*, branch_t*);
|
53
|
+
int node_envelope(const state_t*, const node_t*, rtree_coord_t*);
|
54
|
+
node_t* node_add_rect(const state_t*, rtree_id_t, rtree_coord_t*,
|
55
|
+
node_t*, node_level_t);
|
56
|
+
int node_update(const state_t*, const node_t*, rtree_update_t*, void*);
|
57
|
+
bool node_identical(const state_t*, const node_t*, const node_t*);
|
58
|
+
node_height_t node_height(const state_t*, const node_t*);
|
59
|
+
size_t node_bytes(const state_t*, const node_t*);
|
60
|
+
bool node_nonempty(const state_t*, const node_t*);
|
61
|
+
|
62
|
+
inline node_count_t node_count(const node_t *node)
|
63
|
+
{
|
64
|
+
return node->count;
|
65
|
+
}
|
66
|
+
|
67
|
+
inline void node_count_increment(node_t *node)
|
68
|
+
{
|
69
|
+
node->count++;
|
70
|
+
}
|
71
|
+
|
72
|
+
inline void node_count_decrement(node_t *node)
|
73
|
+
{
|
74
|
+
node->count--;
|
75
|
+
}
|
76
|
+
|
77
|
+
inline node_level_t node_level(const node_t *node)
|
78
|
+
{
|
79
|
+
return node->level;
|
80
|
+
}
|
81
|
+
|
82
|
+
inline void node_set_level(node_t *node, node_level_t level)
|
83
|
+
{
|
84
|
+
node->level = level;
|
85
|
+
}
|
86
|
+
|
87
|
+
inline void* node_get_branches(node_t *node)
|
88
|
+
{
|
89
|
+
return node->branches;
|
90
|
+
}
|
91
|
+
|
92
|
+
#ifdef __cplusplus
|
93
|
+
}
|
94
|
+
#endif
|
95
|
+
|
96
|
+
#endif
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/*
|
2
|
+
rtree/package.h
|
3
|
+
Copyright (c) J.J. Green 2021
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RTREE_PACKAGE_H
|
7
|
+
#define RTREE_PACKAGE_H
|
8
|
+
|
9
|
+
extern const char rtree_package_version[];
|
10
|
+
extern const char rtree_package_name[];
|
11
|
+
extern const char rtree_package_url[];
|
12
|
+
extern const char rtree_package_bugreport[];
|
13
|
+
|
14
|
+
#endif
|