1
/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include "myisamdef.h"
22
static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims,
23
uchar byte_order, double *mbr);
24
static int sp_get_point_mbr(uchar *(*wkb), uchar *end, uint n_dims,
25
uchar byte_order, double *mbr);
26
static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims,
27
uchar byte_order, double *mbr);
28
static int sp_get_polygon_mbr(uchar *(*wkb), uchar *end, uint n_dims,
29
uchar byte_order, double *mbr);
30
static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims,
31
double *mbr, int top);
32
static int sp_mbr_from_wkb(uchar (*wkb), uint size, uint n_dims, double *mbr);
34
uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key,
35
const uchar *record, my_off_t filepos)
38
MI_KEYDEF *keyinfo = &info->s->keyinfo[keynr];
43
double mbr[SPDIMS * 2];
46
keyseg = &keyinfo->seg[-1];
47
pos = (uchar*)record + keyseg->start;
49
dlen = _mi_calc_blob_length(keyseg->bit_start, pos);
50
memcpy_fixed(&dptr, pos + keyseg->bit_start, sizeof(char*));
53
my_errno= HA_ERR_NULL_IN_SPATIAL;
56
sp_mbr_from_wkb(dptr + 4, dlen - 4, SPDIMS, mbr); /* SRID */
58
for (i = 0, keyseg = keyinfo->seg; keyseg->type; keyseg++, i++)
60
uint length = keyseg->length, start= keyseg->start;
63
DBUG_ASSERT(length == sizeof(double));
64
DBUG_ASSERT(!(start % sizeof(double)));
65
DBUG_ASSERT(start < sizeof(mbr));
66
DBUG_ASSERT(keyseg->type == HA_KEYTYPE_DOUBLE);
68
val= mbr[start / sizeof (double)];
79
if (keyseg->flag & HA_SWAP_KEY)
81
uchar buf[sizeof(double)];
83
float8store(buf, val);
90
float8store((uchar *)key, val);
95
_mi_dpointer(info, key, filepos);
100
Calculate minimal bounding rectangle (mbr) of the spatial object
101
stored in "well-known binary representation" (wkb) format.
103
static int sp_mbr_from_wkb(uchar *wkb, uint size, uint n_dims, double *mbr)
107
for (i=0; i < n_dims; ++i)
109
mbr[i * 2] = DBL_MAX;
110
mbr[i * 2 + 1] = -DBL_MAX;
113
return sp_get_geometry_mbr(&wkb, wkb + size, n_dims, mbr, 1);
117
Add one point stored in wkb to mbr
120
static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims,
121
uchar byte_order __attribute__((unused)),
125
double *mbr_end= mbr + n_dims * 2;
127
while (mbr < mbr_end)
129
if ((*wkb) > end - 8)
131
float8get(ord, (const uchar*) *wkb);
144
static int sp_get_point_mbr(uchar *(*wkb), uchar *end, uint n_dims,
145
uchar byte_order, double *mbr)
147
return sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr);
151
static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims,
152
uchar byte_order, double *mbr)
156
n_points = uint4korr(*wkb);
158
for (; n_points > 0; --n_points)
160
/* Add next point to mbr */
161
if (sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr))
168
static int sp_get_polygon_mbr(uchar *(*wkb), uchar *end, uint n_dims,
169
uchar byte_order, double *mbr)
174
n_linear_rings = uint4korr((*wkb));
177
for (; n_linear_rings > 0; --n_linear_rings)
179
n_points = uint4korr((*wkb));
181
for (; n_points > 0; --n_points)
183
/* Add next point to mbr */
184
if (sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr))
191
static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims,
192
double *mbr, int top)
198
byte_order = *(*wkb);
201
wkb_type = uint4korr((*wkb));
204
switch ((enum wkbType) wkb_type)
207
res = sp_get_point_mbr(wkb, end, n_dims, byte_order, mbr);
210
res = sp_get_linestring_mbr(wkb, end, n_dims, byte_order, mbr);
213
res = sp_get_polygon_mbr(wkb, end, n_dims, byte_order, mbr);
218
n_items = uint4korr((*wkb));
220
for (; n_items > 0; --n_items)
222
byte_order = *(*wkb);
225
if (sp_get_point_mbr(wkb, end, n_dims, byte_order, mbr))
231
case wkbMultiLineString:
234
n_items = uint4korr((*wkb));
236
for (; n_items > 0; --n_items)
238
byte_order = *(*wkb);
241
if (sp_get_linestring_mbr(wkb, end, n_dims, byte_order, mbr))
247
case wkbMultiPolygon:
250
n_items = uint4korr((*wkb));
252
for (; n_items > 0; --n_items)
254
byte_order = *(*wkb);
257
if (sp_get_polygon_mbr(wkb, end, n_dims, byte_order, mbr))
263
case wkbGeometryCollection:
270
n_items = uint4korr((*wkb));
272
for (; n_items > 0; --n_items)
274
if (sp_get_geometry_mbr(wkb, end, n_dims, mbr, 0))
286
#endif /*HAVE_SPATIAL*/