1 | /* -*- c-basic-offset: 2 -*- */ |
2 | /* |
3 | Copyright(C) 2009-2016 Brazil |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License version 2.1 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with this library; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | #pragma once |
20 | |
21 | #include "grn.h" |
22 | #include "grn_ii.h" |
23 | #include "grn_db.h" |
24 | |
25 | #if defined(WIN32) || defined(__sun) |
26 | # define _USE_MATH_DEFINES |
27 | # ifndef MAX |
28 | # define MAX(a, b) ((a) > (b) ? (a) : (b)) |
29 | # endif |
30 | |
31 | # ifndef MIN |
32 | # define MIN(a, b) ((a) < (b) ? (a) : (b)) |
33 | # endif |
34 | #endif /* WIN32 or __sun */ |
35 | #include <math.h> |
36 | |
37 | #ifdef __cplusplus |
38 | extern "C" { |
39 | #endif |
40 | |
41 | #define GRN_GEO_RESOLUTION 3600000 |
42 | #define GRN_GEO_RADIUS 6357303 |
43 | #define GRN_GEO_BES_C1 6334834 |
44 | #define GRN_GEO_BES_C2 6377397 |
45 | #define GRN_GEO_BES_C3 0.006674 |
46 | #define GRN_GEO_GRS_C1 6335439 |
47 | #define GRN_GEO_GRS_C2 6378137 |
48 | #define GRN_GEO_GRS_C3 0.006694 |
49 | #define GRN_GEO_INT2RAD(x) ((M_PI / (GRN_GEO_RESOLUTION * 180)) * (x)) |
50 | #define GRN_GEO_RAD2INT(x) ((int)(((GRN_GEO_RESOLUTION * 180) / M_PI) * (x))) |
51 | |
52 | #define GRN_GEO_MAX_LATITUDE 324000000 /* 90 * 60 * 60 * 1000 */ |
53 | #define GRN_GEO_MAX_LONGITUDE (648000000 - 1) /* 180 * 60 * 60 * 1000 - 1 */ |
54 | #define GRN_GEO_MIN_LATITUDE -GRN_GEO_MAX_LATITUDE |
55 | #define GRN_GEO_MIN_LONGITUDE -GRN_GEO_MAX_LONGITUDE |
56 | |
57 | #define GRN_GEO_POINT_VALUE_RAW(obj) (grn_geo_point *)GRN_BULK_HEAD(obj) |
58 | #define GRN_GEO_POINT_VALUE_RADIUS(obj,_latitude,_longitude) do {\ |
59 | grn_geo_point *_val = (grn_geo_point *)GRN_BULK_HEAD(obj);\ |
60 | _latitude = GRN_GEO_INT2RAD(_val->latitude);\ |
61 | _longitude = GRN_GEO_INT2RAD(_val->longitude);\ |
62 | } while (0) |
63 | |
64 | #define GRN_GEO_KEY_MAX_BITS 64 |
65 | |
66 | typedef enum { |
67 | GRN_GEO_APPROXIMATE_RECTANGLE, |
68 | GRN_GEO_APPROXIMATE_SPHERE, |
69 | GRN_GEO_APPROXIMATE_ELLIPSOID |
70 | } grn_geo_approximate_type; |
71 | |
72 | typedef enum { |
73 | GRN_GEO_CURSOR_ENTRY_STATUS_NONE = 0, |
74 | GRN_GEO_CURSOR_ENTRY_STATUS_TOP_INCLUDED = 1 << 0, |
75 | GRN_GEO_CURSOR_ENTRY_STATUS_BOTTOM_INCLUDED = 1 << 1, |
76 | GRN_GEO_CURSOR_ENTRY_STATUS_LEFT_INCLUDED = 1 << 2, |
77 | GRN_GEO_CURSOR_ENTRY_STATUS_RIGHT_INCLUDED = 1 << 3, |
78 | GRN_GEO_CURSOR_ENTRY_STATUS_LATITUDE_INNER = 1 << 4, |
79 | GRN_GEO_CURSOR_ENTRY_STATUS_LONGITUDE_INNER = 1 << 5 |
80 | } grn_geo_cursor_entry_status_flag; |
81 | |
82 | typedef enum { |
83 | GRN_GEO_AREA_NORTH_EAST, |
84 | GRN_GEO_AREA_NORTH_WEST, |
85 | GRN_GEO_AREA_SOUTH_WEST, |
86 | GRN_GEO_AREA_SOUTH_EAST, |
87 | GRN_GEO_AREA_LAST |
88 | } grn_geo_area_type; |
89 | |
90 | #define GRN_GEO_N_AREAS GRN_GEO_AREA_LAST |
91 | |
92 | typedef struct { |
93 | uint8_t key[sizeof(grn_geo_point)]; |
94 | int target_bit; |
95 | int status_flags; |
96 | } grn_geo_cursor_entry; |
97 | |
98 | typedef struct { |
99 | grn_geo_point top_left; |
100 | grn_geo_point bottom_right; |
101 | uint8_t top_left_key[sizeof(grn_geo_point)]; |
102 | uint8_t bottom_right_key[sizeof(grn_geo_point)]; |
103 | int current_entry; |
104 | grn_geo_cursor_entry entries[GRN_GEO_KEY_MAX_BITS]; |
105 | } grn_geo_cursor_area; |
106 | |
107 | typedef struct { |
108 | grn_db_obj obj; |
109 | grn_obj *pat; |
110 | grn_obj *index; |
111 | grn_geo_point top_left; |
112 | grn_geo_point bottom_right; |
113 | grn_geo_point current; |
114 | grn_table_cursor *pat_cursor; |
115 | grn_ii_cursor *ii_cursor; |
116 | int offset; |
117 | int rest; |
118 | int minimum_reduce_bit; |
119 | grn_geo_area_type current_area; |
120 | grn_geo_cursor_area areas[GRN_GEO_N_AREAS]; |
121 | } grn_geo_cursor_in_rectangle; |
122 | |
123 | grn_rc grn_geo_cursor_close(grn_ctx *ctx, grn_obj *geo_cursor); |
124 | |
125 | |
126 | grn_rc grn_geo_resolve_approximate_type(grn_ctx *ctx, grn_obj *type_name, |
127 | grn_geo_approximate_type *type); |
128 | |
129 | /** |
130 | * grn_geo_select_in_circle: |
131 | * @index: the index column for TokyoGeoPoint or WGS84GeoPpoint type. |
132 | * @center_point: the center point of the target circle. (ShortText, Text, |
133 | * LongText, TokyoGeoPoint or WGS84GeoPoint) |
134 | * @distance: the radius of the target circle (Int32, |
135 | * UInt32, Int64, UInt64 or Float) or the point |
136 | * on the circumference of the target circle. (ShortText, Text, LongText, |
137 | * TokyoGeoPoint or WGS84GeoPoint) |
138 | * @approximate_type: the approximate type to compute |
139 | * distance. |
140 | * @res: the table to store found record IDs. It must be |
141 | * GRN_TABLE_HASH_KEY type table. |
142 | * @op: the operator for matched records. |
143 | * |
144 | * It selects records that are in the circle specified by |
145 | * @center_point and @distance from @center_point. Records |
146 | * are searched by @index. Found records are added to @res |
147 | * table with @op operation. |
148 | **/ |
149 | grn_rc grn_geo_select_in_circle(grn_ctx *ctx, |
150 | grn_obj *index, |
151 | grn_obj *center_point, |
152 | grn_obj *distance, |
153 | grn_geo_approximate_type approximate_type, |
154 | grn_obj *res, |
155 | grn_operator op); |
156 | |
157 | grn_rc grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *table, grn_obj *index, |
158 | int nargs, grn_obj **args, |
159 | grn_obj *res, grn_operator op); |
160 | grn_rc grn_selector_geo_in_rectangle(grn_ctx *ctx, |
161 | grn_obj *table, grn_obj *index, |
162 | int nargs, grn_obj **args, |
163 | grn_obj *res, grn_operator op); |
164 | |
165 | GRN_API grn_bool grn_geo_in_circle(grn_ctx *ctx, grn_obj *point, grn_obj *center, |
166 | grn_obj *radius_or_point, |
167 | grn_geo_approximate_type approximate_type); |
168 | GRN_API grn_bool grn_geo_in_rectangle(grn_ctx *ctx, grn_obj *point, |
169 | grn_obj *top_left, grn_obj *bottom_right); |
170 | grn_bool grn_geo_in_rectangle_raw(grn_ctx *ctx, grn_geo_point *point, |
171 | grn_geo_point *top_left, |
172 | grn_geo_point *bottom_right); |
173 | double grn_geo_distance(grn_ctx *ctx, grn_obj *point1, grn_obj *point2, |
174 | grn_geo_approximate_type type); |
175 | GRN_API double grn_geo_distance_rectangle(grn_ctx *ctx, grn_obj *point1, |
176 | grn_obj *point2); |
177 | GRN_API double grn_geo_distance_sphere(grn_ctx *ctx, grn_obj *point1, |
178 | grn_obj *point2); |
179 | GRN_API double grn_geo_distance_ellipsoid(grn_ctx *ctx, grn_obj *point1, |
180 | grn_obj *point2); |
181 | double grn_geo_distance_rectangle_raw(grn_ctx *ctx, |
182 | grn_geo_point *point1, |
183 | grn_geo_point *point2); |
184 | double grn_geo_distance_sphere_raw(grn_ctx *ctx, |
185 | grn_geo_point *point1, |
186 | grn_geo_point *point2); |
187 | double grn_geo_distance_ellipsoid_raw(grn_ctx *ctx, |
188 | grn_geo_point *point1, |
189 | grn_geo_point *point2, |
190 | int c1, int c2, double c3); |
191 | double grn_geo_distance_ellipsoid_raw_tokyo(grn_ctx *ctx, |
192 | grn_geo_point *point1, |
193 | grn_geo_point *point2); |
194 | double grn_geo_distance_ellipsoid_raw_wgs84(grn_ctx *ctx, |
195 | grn_geo_point *point1, |
196 | grn_geo_point *point2); |
197 | |
198 | #ifdef __cplusplus |
199 | } |
200 | #endif |
201 | |