geo_coder 0.1.0
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.
- data/Gemfile +12 -0
- data/Gemfile.lock +32 -0
- data/History.txt +6 -0
- data/Makefile +13 -0
- data/Manifest.txt +18 -0
- data/README.rdoc +197 -0
- data/Rakefile +53 -0
- data/TODO.txt +8 -0
- data/VERSION +1 -0
- data/bin/build_indexes +8 -0
- data/bin/rebuild_cluster +22 -0
- data/bin/rebuild_metaphones +23 -0
- data/bin/tiger_import +59 -0
- data/demos/demo/app/ext/geocodewrap.rb +84 -0
- data/demos/demo/app/views/index.builder +13 -0
- data/demos/demo/app/views/index.erb +71 -0
- data/demos/demo/config.ru +12 -0
- data/demos/demo/config/bootstraps.rb +130 -0
- data/demos/demo/config/geoenvironment.rb +25 -0
- data/demos/demo/geocoder_helper.rb +12 -0
- data/demos/demo/geocom_geocode.rb +10 -0
- data/demos/demo/main.rb +3 -0
- data/demos/demo/rakefile.rb +17 -0
- data/demos/demo/tmp/restart.txt +0 -0
- data/demos/simpledemo/views/index.builder +13 -0
- data/demos/simpledemo/views/index.erb +69 -0
- data/demos/simpledemo/ws.rb +83 -0
- data/doc/Makefile +7 -0
- data/doc/html4css1.css +279 -0
- data/doc/lookup.rst +193 -0
- data/doc/parsing.rst +125 -0
- data/doc/voidspace.css +147 -0
- data/geo_coder.gemspec +172 -0
- data/lib/geocoder/us.rb +21 -0
- data/lib/geocoder/us/address.rb +290 -0
- data/lib/geocoder/us/constants.rb +670 -0
- data/lib/geocoder/us/database.rb +745 -0
- data/lib/geocoder/us/import.rb +181 -0
- data/lib/geocoder/us/import/tiger.rb +13 -0
- data/lib/geocoder/us/numbers.rb +58 -0
- data/navteq/README +4 -0
- data/navteq/convert.sql +37 -0
- data/navteq/navteq_import +39 -0
- data/navteq/prepare.sql +92 -0
- data/sql/cluster.sql +16 -0
- data/sql/convert.sql +80 -0
- data/sql/create.sql +37 -0
- data/sql/index.sql +12 -0
- data/sql/place.csv +104944 -0
- data/sql/place.sql +104948 -0
- data/sql/setup.sql +78 -0
- data/src/Makefile +13 -0
- data/src/README +14 -0
- data/src/liblwgeom/Makefile +75 -0
- data/src/liblwgeom/box2d.c +54 -0
- data/src/liblwgeom/lex.yy.c +4799 -0
- data/src/liblwgeom/liblwgeom.h +1405 -0
- data/src/liblwgeom/lwalgorithm.c +946 -0
- data/src/liblwgeom/lwalgorithm.h +52 -0
- data/src/liblwgeom/lwcircstring.c +759 -0
- data/src/liblwgeom/lwcollection.c +541 -0
- data/src/liblwgeom/lwcompound.c +118 -0
- data/src/liblwgeom/lwcurvepoly.c +86 -0
- data/src/liblwgeom/lwgeom.c +886 -0
- data/src/liblwgeom/lwgeom_api.c +2201 -0
- data/src/liblwgeom/lwgparse.c +1219 -0
- data/src/liblwgeom/lwgunparse.c +1054 -0
- data/src/liblwgeom/lwline.c +525 -0
- data/src/liblwgeom/lwmcurve.c +125 -0
- data/src/liblwgeom/lwmline.c +137 -0
- data/src/liblwgeom/lwmpoint.c +138 -0
- data/src/liblwgeom/lwmpoly.c +141 -0
- data/src/liblwgeom/lwmsurface.c +129 -0
- data/src/liblwgeom/lwpoint.c +439 -0
- data/src/liblwgeom/lwpoly.c +579 -0
- data/src/liblwgeom/lwsegmentize.c +1047 -0
- data/src/liblwgeom/lwutil.c +369 -0
- data/src/liblwgeom/measures.c +861 -0
- data/src/liblwgeom/postgis_config.h +93 -0
- data/src/liblwgeom/ptarray.c +847 -0
- data/src/liblwgeom/vsprintf.c +179 -0
- data/src/liblwgeom/wktparse.h +126 -0
- data/src/liblwgeom/wktparse.lex +74 -0
- data/src/liblwgeom/wktparse.tab.c +2353 -0
- data/src/liblwgeom/wktparse.tab.h +145 -0
- data/src/liblwgeom/wktparse.y +385 -0
- data/src/libsqlite3_geocoder/Makefile +22 -0
- data/src/libsqlite3_geocoder/Makefile.nix +15 -0
- data/src/libsqlite3_geocoder/Makefile.redhat +15 -0
- data/src/libsqlite3_geocoder/extension.c +121 -0
- data/src/libsqlite3_geocoder/extension.h +13 -0
- data/src/libsqlite3_geocoder/levenshtein.c +42 -0
- data/src/libsqlite3_geocoder/metaphon.c +278 -0
- data/src/libsqlite3_geocoder/util.c +37 -0
- data/src/libsqlite3_geocoder/wkb_compress.c +54 -0
- data/src/metaphone/Makefile +7 -0
- data/src/metaphone/README +49 -0
- data/src/metaphone/extension.c +37 -0
- data/src/metaphone/metaphon.c +251 -0
- data/src/shp2sqlite/Makefile +37 -0
- data/src/shp2sqlite/Makefile.nix +36 -0
- data/src/shp2sqlite/Makefile.redhat +35 -0
- data/src/shp2sqlite/dbfopen.c +1595 -0
- data/src/shp2sqlite/getopt.c +695 -0
- data/src/shp2sqlite/getopt.h +127 -0
- data/src/shp2sqlite/shapefil.h +500 -0
- data/src/shp2sqlite/shp2sqlite.c +1974 -0
- data/src/shp2sqlite/shpopen.c +1894 -0
- data/tests/address.rb +236 -0
- data/tests/benchmark.rb +20 -0
- data/tests/constants.rb +57 -0
- data/tests/data/address-sample.csv +52 -0
- data/tests/data/db-test.csv +57 -0
- data/tests/data/locations.csv +4 -0
- data/tests/database.rb +137 -0
- data/tests/generate.rb +34 -0
- data/tests/numbers.rb +46 -0
- data/tests/run.rb +11 -0
- metadata +237 -0
|
@@ -0,0 +1,1405 @@
|
|
|
1
|
+
/**********************************************************************
|
|
2
|
+
* $Id: liblwgeom.h 3812 2009-03-09 14:36:15Z pramsey $
|
|
3
|
+
*
|
|
4
|
+
* PostGIS - Spatial Types for PostgreSQL
|
|
5
|
+
* http://postgis.refractions.net
|
|
6
|
+
* Copyright 2001-2006 Refractions Research Inc.
|
|
7
|
+
* Copyright 2007-2008 Mark Cave-Ayland
|
|
8
|
+
* Copyright 2008 Paul Ramsey <pramsey@cleverelephant.ca>
|
|
9
|
+
*
|
|
10
|
+
* This is free software; you can redistribute and/or modify it under
|
|
11
|
+
* the terms of the GNU General Public Licence. See the COPYING file.
|
|
12
|
+
*
|
|
13
|
+
**********************************************************************/
|
|
14
|
+
|
|
15
|
+
#ifndef _LIBLWGEOM_H
|
|
16
|
+
#define _LIBLWGEOM_H 1
|
|
17
|
+
|
|
18
|
+
#include "postgis_config.h"
|
|
19
|
+
#include <stdarg.h>
|
|
20
|
+
#include <stdio.h>
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @file liblwgeom.h
|
|
24
|
+
*
|
|
25
|
+
* This library is the generic geometry handling section of PostGIS. The geometry
|
|
26
|
+
* objects, constructors, destructors, and a set of spatial processing functions,
|
|
27
|
+
* are implemented here.
|
|
28
|
+
*
|
|
29
|
+
* The library is designed for use in non-PostGIS applications if necessary. The
|
|
30
|
+
* units tests at cunit/cu_tester.c and the loader/dumper programs at
|
|
31
|
+
* ../loader/shp2pgsql.c are examples of non-PostGIS applications using liblwgeom.
|
|
32
|
+
*
|
|
33
|
+
* Programs using this library should set up the default memory managers and error
|
|
34
|
+
* handlers by implementing an lwgeom_init_allocators() function, which can be as
|
|
35
|
+
* a wrapper around the lwgeom_install_default_allocators() function if you want
|
|
36
|
+
* no special handling for memory management and error reporting.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
#define INTEGRITY_CHECKS 1
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
* Floating point comparitors.
|
|
43
|
+
*/
|
|
44
|
+
#define PGIS_EPSILON 1e-12
|
|
45
|
+
#define FP_MAX(A, B) ((A > B) ? A : B)
|
|
46
|
+
#define FP_MIN(A, B) ((A < B) ? A : B)
|
|
47
|
+
#define FP_LT(A, B) ((A + PGIS_EPSILON) < B)
|
|
48
|
+
#define FP_LTEQ(A, B) ((A - PGIS_EPSILON) <= B)
|
|
49
|
+
#define FP_GT(A, B) ((A - PGIS_EPSILON) > B)
|
|
50
|
+
#define FP_GTEQ(A, B) ((A + PGIS_EPSILON) >= B)
|
|
51
|
+
#define FP_CONTAINS_TOP(A, X, B) (FP_LT(A, X) && FP_LTEQ(X, B))
|
|
52
|
+
#define FP_CONTAINS_BOTTOM(A, X, B) (FP_LTEQ(A, X) && FP_LT(X, B))
|
|
53
|
+
#define FP_CONTAINS_INCL(A, X, B) (FP_LTEQ(A, X) && FP_LTEQ(X, B))
|
|
54
|
+
#define FP_CONTAINS_EXCL(A, X, B) (FP_LT(A, X) && FP_LT(X, B))
|
|
55
|
+
#define FP_CONTAINS(A, X, B) FP_CONTAINS_EXCL(A, X, B)
|
|
56
|
+
#define LW_TRUE 1
|
|
57
|
+
#define LW_FALSE 0
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
* this will change to NaN when I figure out how to
|
|
61
|
+
* get NaN in a platform-independent way
|
|
62
|
+
*/
|
|
63
|
+
#define NO_VALUE 0.0
|
|
64
|
+
#define NO_Z_VALUE NO_VALUE
|
|
65
|
+
#define NO_M_VALUE NO_VALUE
|
|
66
|
+
|
|
67
|
+
#ifndef C_H
|
|
68
|
+
|
|
69
|
+
typedef unsigned int uint32;
|
|
70
|
+
typedef int int32;
|
|
71
|
+
|
|
72
|
+
#endif
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Global functions for memory/logging handlers.
|
|
76
|
+
*/
|
|
77
|
+
typedef void* (*lwallocator)(size_t size);
|
|
78
|
+
typedef void* (*lwreallocator)(void *mem, size_t size);
|
|
79
|
+
typedef void (*lwfreeor)(void* mem);
|
|
80
|
+
typedef void (*lwreporter)(const char* fmt, va_list ap);
|
|
81
|
+
extern lwreallocator lwrealloc_var;
|
|
82
|
+
extern lwallocator lwalloc_var;
|
|
83
|
+
extern lwfreeor lwfree_var;
|
|
84
|
+
extern lwreporter lwerror_var;
|
|
85
|
+
extern lwreporter lwnotice_var;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Supply the memory management and error handling functions you want your
|
|
89
|
+
* application to use.
|
|
90
|
+
* @ingroup system
|
|
91
|
+
*/
|
|
92
|
+
extern void lwgeom_init_allocators(void);
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Apply the default memory management (malloc() and free()) and error handlers.
|
|
96
|
+
* Called inside lwgeom_init_allocators() generally.
|
|
97
|
+
* @ingroup system
|
|
98
|
+
*/
|
|
99
|
+
extern void lwgeom_install_default_allocators(void);
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Write a notice out to the notice handler. Uses standard printf() substitutions.
|
|
103
|
+
* Use for messages you always want output. For debugging, use LWDEBUG() or LWDEBUGF().
|
|
104
|
+
* @ingroup logging
|
|
105
|
+
*/
|
|
106
|
+
void lwnotice(const char *fmt, ...);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Write a notice out to the error handler. Uses standard printf() substitutions.
|
|
110
|
+
* Use for errors you always want output. For debugging, use LWDEBUG() or LWDEBUGF().
|
|
111
|
+
* @ingroup logging
|
|
112
|
+
*/
|
|
113
|
+
void lwerror(const char *fmt, ...);
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The default memory/logging handlers installed by lwgeom_install_default_allocators()
|
|
117
|
+
*/
|
|
118
|
+
void *default_allocator(size_t size);
|
|
119
|
+
void *default_reallocator(void *mem, size_t size);
|
|
120
|
+
void default_freeor(void *ptr);
|
|
121
|
+
void default_errorreporter(const char *fmt, va_list ap);
|
|
122
|
+
void default_noticereporter(const char *fmt, va_list ap);
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
extern int lw_vasprintf (char **result, const char *format, va_list args);
|
|
126
|
+
|
|
127
|
+
/* Debug macros */
|
|
128
|
+
#if POSTGIS_DEBUG_LEVEL > 0
|
|
129
|
+
|
|
130
|
+
/* Display a notice at the given debug level */
|
|
131
|
+
#define LWDEBUG(level, msg) \
|
|
132
|
+
do { \
|
|
133
|
+
if (POSTGIS_DEBUG_LEVEL >= level) \
|
|
134
|
+
lwnotice("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__); \
|
|
135
|
+
} while (0);
|
|
136
|
+
|
|
137
|
+
/* Display a formatted notice at the given debug level (like printf, with variadic arguments) */
|
|
138
|
+
#define LWDEBUGF(level, msg, ...) \
|
|
139
|
+
do { \
|
|
140
|
+
if (POSTGIS_DEBUG_LEVEL >= level) \
|
|
141
|
+
lwnotice("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__, __VA_ARGS__); \
|
|
142
|
+
} while (0);
|
|
143
|
+
|
|
144
|
+
#else
|
|
145
|
+
|
|
146
|
+
/* Empty prototype that can be optimised away by the compiler for non-debug builds */
|
|
147
|
+
#define LWDEBUG(level, msg) \
|
|
148
|
+
((void) 0)
|
|
149
|
+
|
|
150
|
+
/* Empty prototype that can be optimised away by the compiler for non-debug builds */
|
|
151
|
+
#define LWDEBUGF(level, msg, ...) \
|
|
152
|
+
((void) 0)
|
|
153
|
+
|
|
154
|
+
#endif
|
|
155
|
+
|
|
156
|
+
/******************************************************************/
|
|
157
|
+
|
|
158
|
+
typedef unsigned char uchar;
|
|
159
|
+
|
|
160
|
+
typedef struct
|
|
161
|
+
{
|
|
162
|
+
float xmin;
|
|
163
|
+
float ymin;
|
|
164
|
+
float xmax;
|
|
165
|
+
float ymax;
|
|
166
|
+
} BOX2DFLOAT4;
|
|
167
|
+
|
|
168
|
+
typedef struct
|
|
169
|
+
{
|
|
170
|
+
double xmin, ymin, zmin;
|
|
171
|
+
double xmax, ymax, zmax;
|
|
172
|
+
} BOX3D;
|
|
173
|
+
|
|
174
|
+
typedef struct chiptag
|
|
175
|
+
{
|
|
176
|
+
int size; /* unused (for use by postgresql) */
|
|
177
|
+
|
|
178
|
+
int endian_hint; /* the number 1 in the endian of this datastruct */
|
|
179
|
+
|
|
180
|
+
BOX3D bvol;
|
|
181
|
+
int SRID;
|
|
182
|
+
char future[4];
|
|
183
|
+
float factor; /* Usually 1.0.
|
|
184
|
+
* Integer values are multiplied by this number
|
|
185
|
+
* to get the actual height value
|
|
186
|
+
* (for sub-meter accuracy height data).
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
int datatype; /* 1 = float32,
|
|
190
|
+
* 5 = 24bit integer,
|
|
191
|
+
* 6 = 16bit integer (short)
|
|
192
|
+
* 7 = 16bit ???
|
|
193
|
+
* 8 = 8bit ???
|
|
194
|
+
* 101 = float32 (NDR),
|
|
195
|
+
* 105 = 24bit integer (NDR),
|
|
196
|
+
* 106 = 16bit int (NDR)
|
|
197
|
+
* 107 = 16bit ??? (NDR)
|
|
198
|
+
* 108 = 8bit ??? (NDR) (this doesn't make sense)
|
|
199
|
+
*/
|
|
200
|
+
int height;
|
|
201
|
+
int width;
|
|
202
|
+
int compression; /* 0 = no compression, 1 = differencer
|
|
203
|
+
* 0x80 = new value
|
|
204
|
+
* 0x7F = nodata
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
/*
|
|
208
|
+
* this is provided for convenience, it should be set to
|
|
209
|
+
* sizeof(chip) bytes into the struct because the serialized form is:
|
|
210
|
+
* <header><data>
|
|
211
|
+
* NULL when serialized
|
|
212
|
+
*/
|
|
213
|
+
void *data; /* data[0] = bottm left,
|
|
214
|
+
* data[width] = 1st pixel, 2nd row (uncompressed)
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
} CHIP;
|
|
218
|
+
|
|
219
|
+
/*
|
|
220
|
+
* standard definition of an ellipsoid (what wkt calls a spheroid)
|
|
221
|
+
* f = (a-b)/a
|
|
222
|
+
* e_sq = (a*a - b*b)/(a*a)
|
|
223
|
+
* b = a - fa
|
|
224
|
+
*/
|
|
225
|
+
typedef struct
|
|
226
|
+
{
|
|
227
|
+
double a; /* semimajor axis */
|
|
228
|
+
double b; /* semiminor axis */
|
|
229
|
+
double f; /* flattening */
|
|
230
|
+
double e; /* eccentricity (first) */
|
|
231
|
+
double e_sq; /* eccentricity (first), squared */
|
|
232
|
+
char name[20]; /* name of ellipse */
|
|
233
|
+
} SPHEROID;
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
/*
|
|
237
|
+
* ALL LWGEOM structures will use POINT3D as an abstract point.
|
|
238
|
+
* This means a 2d geometry will be stored as (x,y) in its serialized
|
|
239
|
+
* form, but all functions will work on (x,y,0). This keeps all the
|
|
240
|
+
* analysis functions simple.
|
|
241
|
+
* NOTE: for GEOS integration, we'll probably set z=NaN
|
|
242
|
+
* so look out - z might be NaN for 2d geometries!
|
|
243
|
+
*/
|
|
244
|
+
typedef struct { double x,y,z; } POINT3DZ;
|
|
245
|
+
typedef struct { double x,y,z; } POINT3D; /* alias for POINT3DZ */
|
|
246
|
+
typedef struct { double x,y,m; } POINT3DM;
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
/*
|
|
250
|
+
* type for 2d points. When you convert this to 3d, the
|
|
251
|
+
* z component will be either 0 or NaN.
|
|
252
|
+
*/
|
|
253
|
+
typedef struct
|
|
254
|
+
{
|
|
255
|
+
double x;
|
|
256
|
+
double y;
|
|
257
|
+
} POINT2D;
|
|
258
|
+
|
|
259
|
+
typedef struct
|
|
260
|
+
{
|
|
261
|
+
double x;
|
|
262
|
+
double y;
|
|
263
|
+
double z;
|
|
264
|
+
double m;
|
|
265
|
+
} POINT4D;
|
|
266
|
+
|
|
267
|
+
/******************************************************************/
|
|
268
|
+
|
|
269
|
+
/*
|
|
270
|
+
* Point array abstracts a lot of the complexity of points and point lists.
|
|
271
|
+
* It handles miss-alignment in the serialized form, 2d/3d translation
|
|
272
|
+
* (2d points converted to 3d will have z=0 or NaN)
|
|
273
|
+
* DONT MIX 2D and 3D POINTS! *EVERYTHING* is either one or the other
|
|
274
|
+
*/
|
|
275
|
+
typedef struct
|
|
276
|
+
{
|
|
277
|
+
/* array of POINT 2D, 3D or 4D. probably missaligned. */
|
|
278
|
+
uchar *serialized_pointlist;
|
|
279
|
+
|
|
280
|
+
/* use TYPE_* macros to handle */
|
|
281
|
+
uchar dims;
|
|
282
|
+
|
|
283
|
+
uint32 npoints;
|
|
284
|
+
} POINTARRAY;
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
/*
|
|
288
|
+
* Use the following to build pointarrays
|
|
289
|
+
* when number of points in output is not
|
|
290
|
+
* known in advance
|
|
291
|
+
*/
|
|
292
|
+
typedef struct {
|
|
293
|
+
POINTARRAY *pa;
|
|
294
|
+
size_t ptsize;
|
|
295
|
+
size_t capacity; /* given in points */
|
|
296
|
+
} DYNPTARRAY;
|
|
297
|
+
|
|
298
|
+
/* Create a new dynamic pointarray */
|
|
299
|
+
extern DYNPTARRAY *dynptarray_create(size_t initial_capacity, int dims);
|
|
300
|
+
|
|
301
|
+
/*
|
|
302
|
+
* Add a POINT4D to the dynamic pointarray.
|
|
303
|
+
*
|
|
304
|
+
* The dynamic pointarray may be of any dimension, only
|
|
305
|
+
* accepted dimensions will be copied.
|
|
306
|
+
*
|
|
307
|
+
* If allow_duplicates is set to 0 (false) a check
|
|
308
|
+
* is performed to see if last point in array is equal to the
|
|
309
|
+
* provided one. NOTE that the check is 4d based, with missing
|
|
310
|
+
* ordinates in the pointarray set to NO_Z_VALUE and NO_M_VALUE
|
|
311
|
+
* respectively.
|
|
312
|
+
*/
|
|
313
|
+
extern int dynptarray_addPoint4d(DYNPTARRAY *dpa, POINT4D *p4d,
|
|
314
|
+
int allow_duplicates);
|
|
315
|
+
|
|
316
|
+
/******************************************************************
|
|
317
|
+
*
|
|
318
|
+
* LWGEOM (any type)
|
|
319
|
+
*
|
|
320
|
+
******************************************************************/
|
|
321
|
+
|
|
322
|
+
typedef struct
|
|
323
|
+
{
|
|
324
|
+
uchar type;
|
|
325
|
+
BOX2DFLOAT4 *bbox;
|
|
326
|
+
uint32 SRID; /* -1 == unneeded */
|
|
327
|
+
void *data;
|
|
328
|
+
} LWGEOM;
|
|
329
|
+
|
|
330
|
+
/* POINTYPE */
|
|
331
|
+
typedef struct
|
|
332
|
+
{
|
|
333
|
+
uchar type; /* POINTTYPE */
|
|
334
|
+
BOX2DFLOAT4 *bbox;
|
|
335
|
+
uint32 SRID;
|
|
336
|
+
POINTARRAY *point; /* hide 2d/3d (this will be an array of 1 point) */
|
|
337
|
+
} LWPOINT; /* "light-weight point" */
|
|
338
|
+
|
|
339
|
+
/* LINETYPE */
|
|
340
|
+
typedef struct
|
|
341
|
+
{
|
|
342
|
+
uchar type; /* LINETYPE */
|
|
343
|
+
BOX2DFLOAT4 *bbox;
|
|
344
|
+
uint32 SRID;
|
|
345
|
+
POINTARRAY *points; /* array of POINT3D */
|
|
346
|
+
} LWLINE; /* "light-weight line" */
|
|
347
|
+
|
|
348
|
+
/* POLYGONTYPE */
|
|
349
|
+
typedef struct
|
|
350
|
+
{
|
|
351
|
+
uchar type; /* POLYGONTYPE */
|
|
352
|
+
BOX2DFLOAT4 *bbox;
|
|
353
|
+
uint32 SRID;
|
|
354
|
+
int nrings;
|
|
355
|
+
POINTARRAY **rings; /* list of rings (list of points) */
|
|
356
|
+
} LWPOLY; /* "light-weight polygon" */
|
|
357
|
+
|
|
358
|
+
/* MULTIPOINTTYPE */
|
|
359
|
+
typedef struct
|
|
360
|
+
{
|
|
361
|
+
uchar type;
|
|
362
|
+
BOX2DFLOAT4 *bbox;
|
|
363
|
+
uint32 SRID;
|
|
364
|
+
int ngeoms;
|
|
365
|
+
LWPOINT **geoms;
|
|
366
|
+
} LWMPOINT;
|
|
367
|
+
|
|
368
|
+
/* MULTILINETYPE */
|
|
369
|
+
typedef struct
|
|
370
|
+
{
|
|
371
|
+
uchar type;
|
|
372
|
+
BOX2DFLOAT4 *bbox;
|
|
373
|
+
uint32 SRID;
|
|
374
|
+
int ngeoms;
|
|
375
|
+
LWLINE **geoms;
|
|
376
|
+
} LWMLINE;
|
|
377
|
+
|
|
378
|
+
/* MULTIPOLYGONTYPE */
|
|
379
|
+
typedef struct
|
|
380
|
+
{
|
|
381
|
+
uchar type;
|
|
382
|
+
BOX2DFLOAT4 *bbox;
|
|
383
|
+
uint32 SRID;
|
|
384
|
+
int ngeoms;
|
|
385
|
+
LWPOLY **geoms;
|
|
386
|
+
} LWMPOLY;
|
|
387
|
+
|
|
388
|
+
/* COLLECTIONTYPE */
|
|
389
|
+
typedef struct
|
|
390
|
+
{
|
|
391
|
+
uchar type;
|
|
392
|
+
BOX2DFLOAT4 *bbox;
|
|
393
|
+
uint32 SRID;
|
|
394
|
+
int ngeoms;
|
|
395
|
+
LWGEOM **geoms;
|
|
396
|
+
} LWCOLLECTION;
|
|
397
|
+
|
|
398
|
+
/* CIRCSTRINGTYPE */
|
|
399
|
+
typedef struct
|
|
400
|
+
{
|
|
401
|
+
uchar type; /* CIRCSTRINGTYPE */
|
|
402
|
+
BOX2DFLOAT4 *bbox;
|
|
403
|
+
uint32 SRID;
|
|
404
|
+
POINTARRAY *points; /* array of POINT(3D/3DM) */
|
|
405
|
+
} LWCIRCSTRING; /* "light-weight circularstring" */
|
|
406
|
+
|
|
407
|
+
/* COMPOUNDTYPE */
|
|
408
|
+
typedef struct
|
|
409
|
+
{
|
|
410
|
+
uchar type; /* COMPOUNDTYPE */
|
|
411
|
+
BOX2DFLOAT4 *bbox;
|
|
412
|
+
uint32 SRID;
|
|
413
|
+
int ngeoms;
|
|
414
|
+
LWGEOM **geoms;
|
|
415
|
+
} LWCOMPOUND; /* "light-weight compound line" */
|
|
416
|
+
|
|
417
|
+
/* CURVEPOLYTYPE */
|
|
418
|
+
typedef struct
|
|
419
|
+
{
|
|
420
|
+
uchar type; /* CURVEPOLYTYPE */
|
|
421
|
+
BOX2DFLOAT4 *bbox;
|
|
422
|
+
uint32 SRID;
|
|
423
|
+
int nrings;
|
|
424
|
+
LWGEOM **rings; /* list of rings (list of points) */
|
|
425
|
+
} LWCURVEPOLY; /* "light-weight polygon" */
|
|
426
|
+
|
|
427
|
+
/* MULTICURVE */
|
|
428
|
+
typedef struct
|
|
429
|
+
{
|
|
430
|
+
uchar type;
|
|
431
|
+
BOX2DFLOAT4 *bbox;
|
|
432
|
+
uint32 SRID;
|
|
433
|
+
int ngeoms;
|
|
434
|
+
LWGEOM **geoms;
|
|
435
|
+
} LWMCURVE;
|
|
436
|
+
|
|
437
|
+
/* MULTISURFACETYPE */
|
|
438
|
+
typedef struct
|
|
439
|
+
{
|
|
440
|
+
uchar type;
|
|
441
|
+
BOX2DFLOAT4 *bbox;
|
|
442
|
+
uint32 SRID;
|
|
443
|
+
int ngeoms;
|
|
444
|
+
LWGEOM **geoms;
|
|
445
|
+
} LWMSURFACE;
|
|
446
|
+
|
|
447
|
+
/* Casts LWGEOM->LW* (return NULL if cast is illegal) */
|
|
448
|
+
extern LWMPOLY *lwgeom_as_lwmpoly(LWGEOM *lwgeom);
|
|
449
|
+
extern LWMLINE *lwgeom_as_lwmline(LWGEOM *lwgeom);
|
|
450
|
+
extern LWMPOINT *lwgeom_as_lwmpoint(LWGEOM *lwgeom);
|
|
451
|
+
extern LWCOLLECTION *lwgeom_as_lwcollection(LWGEOM *lwgeom);
|
|
452
|
+
extern LWPOLY *lwgeom_as_lwpoly(LWGEOM *lwgeom);
|
|
453
|
+
extern LWLINE *lwgeom_as_lwline(LWGEOM *lwgeom);
|
|
454
|
+
extern LWPOINT *lwgeom_as_lwpoint(LWGEOM *lwgeom);
|
|
455
|
+
extern LWCIRCSTRING *lwgeom_as_lwcircstring(LWGEOM *lwgeom);
|
|
456
|
+
|
|
457
|
+
/* Casts LW*->LWGEOM (always cast) */
|
|
458
|
+
extern LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj);
|
|
459
|
+
extern LWGEOM *lwmline_as_lwgeom(LWMLINE *obj);
|
|
460
|
+
extern LWGEOM *lwmpoint_as_lwgeom(LWMPOINT *obj);
|
|
461
|
+
extern LWGEOM *lwcollection_as_lwgeom(LWCOLLECTION *obj);
|
|
462
|
+
extern LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj);
|
|
463
|
+
extern LWGEOM *lwline_as_lwgeom(LWLINE *obj);
|
|
464
|
+
extern LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj);
|
|
465
|
+
|
|
466
|
+
/*
|
|
467
|
+
* Call this function everytime LWGEOM coordinates
|
|
468
|
+
* change so to invalidate bounding box
|
|
469
|
+
*/
|
|
470
|
+
extern void lwgeom_changed(LWGEOM *lwgeom);
|
|
471
|
+
|
|
472
|
+
/*
|
|
473
|
+
* Call this function to drop BBOX and SRID
|
|
474
|
+
* from LWGEOM. If LWGEOM type is *not* flagged
|
|
475
|
+
* with the HASBBOX flag and has a bbox, it
|
|
476
|
+
* will be released.
|
|
477
|
+
*/
|
|
478
|
+
extern void lwgeom_drop_bbox(LWGEOM *lwgeom);
|
|
479
|
+
|
|
480
|
+
/* Compute a bbox if not already computed */
|
|
481
|
+
extern void lwgeom_add_bbox(LWGEOM *lwgeom);
|
|
482
|
+
|
|
483
|
+
extern void lwgeom_dropSRID(LWGEOM *lwgeom);
|
|
484
|
+
|
|
485
|
+
/* Determine whether a LWGEOM can contain sub-geometries or not */
|
|
486
|
+
extern int lwgeom_contains_subgeoms(int type);
|
|
487
|
+
|
|
488
|
+
/******************************************************************/
|
|
489
|
+
|
|
490
|
+
/*
|
|
491
|
+
* copies a point from the point array into the parameter point
|
|
492
|
+
* will set point's z=0 (or NaN) if pa is 2d
|
|
493
|
+
* will set point's m=0 (or NaN) if pa is 3d or 2d
|
|
494
|
+
* NOTE: point is a real POINT3D *not* a pointer
|
|
495
|
+
*/
|
|
496
|
+
extern POINT4D getPoint4d(const POINTARRAY *pa, int n);
|
|
497
|
+
|
|
498
|
+
/*
|
|
499
|
+
* copies a point from the point array into the parameter point
|
|
500
|
+
* will set point's z=0 (or NaN) if pa is 2d
|
|
501
|
+
* will set point's m=0 (or NaN) if pa is 3d or 2d
|
|
502
|
+
* NOTE: this will modify the point4d pointed to by 'point'.
|
|
503
|
+
*/
|
|
504
|
+
extern int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point);
|
|
505
|
+
|
|
506
|
+
/*
|
|
507
|
+
* copies a point from the point array into the parameter point
|
|
508
|
+
* will set point's z=0 (or NaN) if pa is 2d
|
|
509
|
+
* NOTE: point is a real POINT3D *not* a pointer
|
|
510
|
+
*/
|
|
511
|
+
extern POINT3DZ getPoint3dz(const POINTARRAY *pa, int n);
|
|
512
|
+
extern POINT3DM getPoint3dm(const POINTARRAY *pa, int n);
|
|
513
|
+
|
|
514
|
+
/*
|
|
515
|
+
* copies a point from the point array into the parameter point
|
|
516
|
+
* will set point's z=0 (or NaN) if pa is 2d
|
|
517
|
+
* NOTE: this will modify the point3d pointed to by 'point'.
|
|
518
|
+
*/
|
|
519
|
+
extern int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point);
|
|
520
|
+
extern int getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *point);
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
/*
|
|
524
|
+
* copies a point from the point array into the parameter point
|
|
525
|
+
* z value (if present is not returned)
|
|
526
|
+
* NOTE: point is a real POINT3D *not* a pointer
|
|
527
|
+
*/
|
|
528
|
+
extern POINT2D getPoint2d(const POINTARRAY *pa, int n);
|
|
529
|
+
|
|
530
|
+
/*
|
|
531
|
+
* copies a point from the point array into the parameter point
|
|
532
|
+
* z value (if present is not returned)
|
|
533
|
+
* NOTE: this will modify the point2d pointed to by 'point'.
|
|
534
|
+
*/
|
|
535
|
+
extern int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point);
|
|
536
|
+
|
|
537
|
+
/*
|
|
538
|
+
* set point N to the given value
|
|
539
|
+
* NOTE that the pointarray can be of any
|
|
540
|
+
* dimension, the appropriate ordinate values
|
|
541
|
+
* will be extracted from it
|
|
542
|
+
*
|
|
543
|
+
*/
|
|
544
|
+
extern void setPoint4d(POINTARRAY *pa, int n, POINT4D *p4d);
|
|
545
|
+
|
|
546
|
+
/*
|
|
547
|
+
* get a pointer to nth point of a POINTARRAY
|
|
548
|
+
* You'll need to cast it to appropriate dimensioned point.
|
|
549
|
+
* Note that if you cast to a higher dimensional point you'll
|
|
550
|
+
* possibly corrupt the POINTARRAY.
|
|
551
|
+
*
|
|
552
|
+
* WARNING: Don't cast this to a POINT !
|
|
553
|
+
* it would not be reliable due to memory alignment constraints
|
|
554
|
+
*/
|
|
555
|
+
extern uchar *getPoint_internal(const POINTARRAY *pa, int n);
|
|
556
|
+
|
|
557
|
+
/* --- here is a macro equivalent, for speed... */
|
|
558
|
+
/* #define getPoint(x,n) &( (x)->serialized_pointlist[((x)->ndims*8)*(n)] ) */
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
/*
|
|
562
|
+
* constructs a POINTARRAY.
|
|
563
|
+
* NOTE: points is *not* copied, so be careful about modification
|
|
564
|
+
* (can be aligned/missaligned)
|
|
565
|
+
* NOTE: hasz and hasm are descriptive - it describes what type of data
|
|
566
|
+
* 'points' points to. No data conversion is done.
|
|
567
|
+
*/
|
|
568
|
+
extern POINTARRAY *pointArray_construct(uchar *points, char hasz, char hasm,
|
|
569
|
+
uint32 npoints);
|
|
570
|
+
|
|
571
|
+
/*
|
|
572
|
+
* Calculate the (BOX3D) bounding box of a set of points.
|
|
573
|
+
* Returns an alloced BOX3D or NULL (for empty geom) in the first form.
|
|
574
|
+
* Write result in user-provided BOX3D in second form (return 0 if untouched).
|
|
575
|
+
* If pa is 2d, then box3d's zmin/zmax will be set to NO_Z_VALUE
|
|
576
|
+
*/
|
|
577
|
+
extern BOX3D *ptarray_compute_box3d(const POINTARRAY *pa);
|
|
578
|
+
extern int ptarray_compute_box3d_p(const POINTARRAY *pa, BOX3D *out);
|
|
579
|
+
|
|
580
|
+
/*
|
|
581
|
+
* size of point represeneted in the POINTARRAY
|
|
582
|
+
* 16 for 2d, 24 for 3d, 32 for 4d
|
|
583
|
+
*/
|
|
584
|
+
extern int pointArray_ptsize(const POINTARRAY *pa);
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
#define POINTTYPE 1
|
|
588
|
+
#define LINETYPE 2
|
|
589
|
+
#define POLYGONTYPE 3
|
|
590
|
+
#define MULTIPOINTTYPE 4
|
|
591
|
+
#define MULTILINETYPE 5
|
|
592
|
+
#define MULTIPOLYGONTYPE 6
|
|
593
|
+
#define COLLECTIONTYPE 7
|
|
594
|
+
#define CIRCSTRINGTYPE 8
|
|
595
|
+
#define COMPOUNDTYPE 9
|
|
596
|
+
#define CURVEPOLYTYPE 13
|
|
597
|
+
#define MULTICURVETYPE 14
|
|
598
|
+
#define MULTISURFACETYPE 15
|
|
599
|
+
|
|
600
|
+
#define WKBZOFFSET 0x80000000
|
|
601
|
+
#define WKBMOFFSET 0x40000000
|
|
602
|
+
#define WKBSRIDFLAG 0x20000000
|
|
603
|
+
#define WKBBBOXFLAG 0x10000000
|
|
604
|
+
|
|
605
|
+
/* These macros work on PG_LWGEOM.type, LWGEOM.type and all its subclasses */
|
|
606
|
+
|
|
607
|
+
#define TYPE_SETTYPE(c,t) ((c)=(((c)&0xF0)|(t)))
|
|
608
|
+
#define TYPE_SETZM(t,z,m) ((t)=(((t)&0xCF)|((z)<<5)|((m)<<4)))
|
|
609
|
+
#define TYPE_SETHASBBOX(t,b) ((t)=(((t)&0x7F)|((b)<<7)))
|
|
610
|
+
#define TYPE_SETHASSRID(t,s) ((t)=(((t)&0xBF)|((s)<<6)))
|
|
611
|
+
|
|
612
|
+
#define TYPE_HASZ(t) ( ((t)&0x20)>>5 )
|
|
613
|
+
#define TYPE_HASM(t) ( ((t)&0x10)>>4 )
|
|
614
|
+
#define TYPE_HASBBOX(t) ( ((t)&0x80)>>7 )
|
|
615
|
+
#define TYPE_HASSRID(t) ( (((t)&0x40))>>6 )
|
|
616
|
+
#define TYPE_NDIMS(t) ((((t)&0x20)>>5)+(((t)&0x10)>>4)+2)
|
|
617
|
+
#define TYPE_GETTYPE(t) ((t)&0x0F)
|
|
618
|
+
|
|
619
|
+
/* 0x02==Z 0x01==M */
|
|
620
|
+
#define TYPE_GETZM(t) (((t)&0x30)>>4)
|
|
621
|
+
|
|
622
|
+
extern char lwgeom_hasBBOX(uchar type); /* true iff B bit set */
|
|
623
|
+
extern int lwgeom_ndims(uchar type); /* returns 2,3 or 4 */
|
|
624
|
+
extern int lwgeom_hasZ(uchar type); /* has Z ? */
|
|
625
|
+
extern int lwgeom_hasM(uchar type); /* has M ? */
|
|
626
|
+
extern int lwgeom_getType(uchar type); /* returns the tttt value */
|
|
627
|
+
|
|
628
|
+
extern uchar lwgeom_makeType(char hasZ, char hasM, char hasSRID, int type);
|
|
629
|
+
extern uchar lwgeom_makeType_full(char hasZ, char hasM, char hasSRID, int type, char hasBBOX);
|
|
630
|
+
extern char lwgeom_hasSRID(uchar type); /* true iff S bit is set */
|
|
631
|
+
extern char lwgeom_hasBBOX(uchar type); /* true iff B bit set */
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
/*
|
|
636
|
+
* This is the binary representation of lwgeom compatible
|
|
637
|
+
* with postgresql varlena struct
|
|
638
|
+
*/
|
|
639
|
+
typedef struct {
|
|
640
|
+
uint32 size; /* varlena header (do not touch directly!) */
|
|
641
|
+
uchar type; /* encodes ndims, type, bbox presence,
|
|
642
|
+
srid presence */
|
|
643
|
+
uchar data[1];
|
|
644
|
+
} PG_LWGEOM;
|
|
645
|
+
|
|
646
|
+
/*
|
|
647
|
+
* Construct a full PG_LWGEOM type (including size header)
|
|
648
|
+
* from a serialized form.
|
|
649
|
+
* The constructed PG_LWGEOM object will be allocated using palloc
|
|
650
|
+
* and the serialized form will be copied.
|
|
651
|
+
* If you specify a SRID other then -1 it will be set.
|
|
652
|
+
* If you request bbox (wantbbox=1) it will be extracted or computed
|
|
653
|
+
* from the serialized form.
|
|
654
|
+
*/
|
|
655
|
+
extern PG_LWGEOM *PG_LWGEOM_construct(uchar *serialized, int SRID,
|
|
656
|
+
int wantbbox);
|
|
657
|
+
|
|
658
|
+
/*
|
|
659
|
+
* Compute bbox of serialized geom
|
|
660
|
+
*/
|
|
661
|
+
extern int compute_serialized_box2d_p(uchar *serialized_form, BOX2DFLOAT4 *box);
|
|
662
|
+
extern BOX3D *compute_serialized_box3d(uchar *serialized_form);
|
|
663
|
+
extern int compute_serialized_box3d_p(uchar *serialized_form, BOX3D *box);
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
/*
|
|
667
|
+
* Evaluate with an heuristic if the provided PG_LWGEOM is worth
|
|
668
|
+
* caching a bbox
|
|
669
|
+
*/
|
|
670
|
+
char is_worth_caching_pglwgeom_bbox(const PG_LWGEOM *);
|
|
671
|
+
char is_worth_caching_serialized_bbox(const uchar *);
|
|
672
|
+
char is_worth_caching_lwgeom_bbox(const LWGEOM *);
|
|
673
|
+
|
|
674
|
+
/*
|
|
675
|
+
* Use this macro to extract the char * required
|
|
676
|
+
* by most functions from an PG_LWGEOM struct.
|
|
677
|
+
* (which is an PG_LWGEOM w/out int32 size casted to char *)
|
|
678
|
+
*/
|
|
679
|
+
#define SERIALIZED_FORM(x) ((uchar *)VARDATA((x)))
|
|
680
|
+
|
|
681
|
+
/*
|
|
682
|
+
* This function computes the size in bytes
|
|
683
|
+
* of the serialized geometries.
|
|
684
|
+
*/
|
|
685
|
+
extern size_t lwgeom_size(const uchar *serialized_form);
|
|
686
|
+
extern size_t lwgeom_size_subgeom(const uchar *serialized_form, int geom_number);
|
|
687
|
+
extern size_t lwgeom_size_line(const uchar *serialized_line);
|
|
688
|
+
extern size_t lwgeom_size_circstring(const uchar *serialized_curve);
|
|
689
|
+
extern size_t lwgeom_size_point(const uchar *serialized_point);
|
|
690
|
+
extern size_t lwgeom_size_poly(const uchar *serialized_line);
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
/*--------------------------------------------------------
|
|
694
|
+
* all the base types (point/line/polygon) will have a
|
|
695
|
+
* basic constructor, basic de-serializer, basic serializer,
|
|
696
|
+
* bounding box finder and (TODO) serialized form size finder.
|
|
697
|
+
*--------------------------------------------------------*/
|
|
698
|
+
|
|
699
|
+
/*
|
|
700
|
+
* given the LWPOINT serialized form (or a pointer into a muli* one)
|
|
701
|
+
* construct a proper LWPOINT.
|
|
702
|
+
* serialized_form should point to the 8bit type format (with type = 1)
|
|
703
|
+
* Returns NULL if serialized form is not a point.
|
|
704
|
+
* See serialized form doc
|
|
705
|
+
*/
|
|
706
|
+
extern LWPOINT *lwpoint_deserialize(uchar *serialized_form);
|
|
707
|
+
|
|
708
|
+
/*
|
|
709
|
+
* Find size this point would get when serialized (no BBOX)
|
|
710
|
+
*/
|
|
711
|
+
extern size_t lwpoint_serialize_size(LWPOINT *point);
|
|
712
|
+
|
|
713
|
+
/*
|
|
714
|
+
* convert this point into its serialize form
|
|
715
|
+
* result's first char will be the 8bit type.
|
|
716
|
+
* See serialized form doc
|
|
717
|
+
*/
|
|
718
|
+
extern uchar *lwpoint_serialize(LWPOINT *point);
|
|
719
|
+
|
|
720
|
+
/* same as above, writes to buf */
|
|
721
|
+
extern void lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *size);
|
|
722
|
+
|
|
723
|
+
/*
|
|
724
|
+
* find bounding box (standard one)
|
|
725
|
+
* zmin=zmax=0 if 2d (might change to NaN)
|
|
726
|
+
*/
|
|
727
|
+
extern BOX3D *lwpoint_compute_box3d(LWPOINT *point);
|
|
728
|
+
|
|
729
|
+
/*
|
|
730
|
+
* convenience functions to hide the POINTARRAY
|
|
731
|
+
*/
|
|
732
|
+
extern int lwpoint_getPoint2d_p(const LWPOINT *point, POINT2D *out);
|
|
733
|
+
extern int lwpoint_getPoint3dz_p(const LWPOINT *point, POINT3DZ *out);
|
|
734
|
+
extern int lwpoint_getPoint3dm_p(const LWPOINT *point, POINT3DM *out);
|
|
735
|
+
extern int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out);
|
|
736
|
+
|
|
737
|
+
/******************************************************************
|
|
738
|
+
* LWLINE functions
|
|
739
|
+
******************************************************************/
|
|
740
|
+
|
|
741
|
+
/*
|
|
742
|
+
* given the LWGEOM serialized form (or a pointer into a muli* one)
|
|
743
|
+
* construct a proper LWLINE.
|
|
744
|
+
* serialized_form should point to the 8bit type format (with type = 2)
|
|
745
|
+
* See SERIALIZED_FORM doc
|
|
746
|
+
*/
|
|
747
|
+
extern LWLINE *lwline_deserialize(uchar *serialized_form);
|
|
748
|
+
|
|
749
|
+
/* find the size this line would get when serialized */
|
|
750
|
+
extern size_t lwline_serialize_size(LWLINE *line);
|
|
751
|
+
|
|
752
|
+
/*
|
|
753
|
+
* convert this line into its serialize form
|
|
754
|
+
* result's first char will be the 8bit type. See serialized form doc
|
|
755
|
+
* copies data.
|
|
756
|
+
*/
|
|
757
|
+
extern uchar *lwline_serialize(LWLINE *line);
|
|
758
|
+
|
|
759
|
+
/* same as above, writes to buf */
|
|
760
|
+
extern void lwline_serialize_buf(LWLINE *line, uchar *buf, size_t *size);
|
|
761
|
+
|
|
762
|
+
/*
|
|
763
|
+
* find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN)
|
|
764
|
+
*/
|
|
765
|
+
extern BOX3D *lwline_compute_box3d(LWLINE *line);
|
|
766
|
+
|
|
767
|
+
/******************************************************************
|
|
768
|
+
* LWPOLY functions
|
|
769
|
+
******************************************************************/
|
|
770
|
+
|
|
771
|
+
/*
|
|
772
|
+
* given the LWPOLY serialized form (or a pointer into a muli* one)
|
|
773
|
+
* construct a proper LWPOLY.
|
|
774
|
+
* serialized_form should point to the 8bit type format (with type = 3)
|
|
775
|
+
* See SERIALIZED_FORM doc
|
|
776
|
+
*/
|
|
777
|
+
extern LWPOLY *lwpoly_deserialize(uchar *serialized_form);
|
|
778
|
+
|
|
779
|
+
/* find the size this polygon would get when serialized */
|
|
780
|
+
extern size_t lwpoly_serialize_size(LWPOLY *poly);
|
|
781
|
+
|
|
782
|
+
/*
|
|
783
|
+
* create the serialized form of the polygon
|
|
784
|
+
* result's first char will be the 8bit type. See serialized form doc
|
|
785
|
+
* points copied
|
|
786
|
+
*/
|
|
787
|
+
extern uchar *lwpoly_serialize(LWPOLY *poly);
|
|
788
|
+
|
|
789
|
+
/* same as above, writes to buf */
|
|
790
|
+
extern void lwpoly_serialize_buf(LWPOLY *poly, uchar *buf, size_t *size);
|
|
791
|
+
|
|
792
|
+
/*
|
|
793
|
+
* find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN)
|
|
794
|
+
*/
|
|
795
|
+
extern BOX3D *lwpoly_compute_box3d(LWPOLY *poly);
|
|
796
|
+
|
|
797
|
+
/******************************************************************
|
|
798
|
+
* LWCIRCSTRING functions
|
|
799
|
+
******************************************************************/
|
|
800
|
+
|
|
801
|
+
/*
|
|
802
|
+
* given the LWGEOM serialized form (or a pointer into a muli* one)
|
|
803
|
+
* construct a proper LWCIRCSTRING.
|
|
804
|
+
* serialized_form should point to the 8bit type format (with type = 2)
|
|
805
|
+
* See SERIALIZED_FORM doc
|
|
806
|
+
*/
|
|
807
|
+
extern LWCIRCSTRING *lwcircstring_deserialize(uchar *serialized_form);
|
|
808
|
+
|
|
809
|
+
/* find the size this curve would get when serialized */
|
|
810
|
+
extern size_t lwcircstring_serialize_size(LWCIRCSTRING *curve);
|
|
811
|
+
|
|
812
|
+
/*
|
|
813
|
+
* convert this circularstring into its serialize form
|
|
814
|
+
* result's first char will be the 8bit type. See serialized form doc
|
|
815
|
+
* copies data.
|
|
816
|
+
*/
|
|
817
|
+
extern uchar *lwcircstring_serialize(LWCIRCSTRING *curve);
|
|
818
|
+
|
|
819
|
+
/* same as above, writes to buf */
|
|
820
|
+
extern void lwcircstring_serialize_buf(LWCIRCSTRING *curve, uchar *buf, size_t *size);
|
|
821
|
+
|
|
822
|
+
/*
|
|
823
|
+
* find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN)
|
|
824
|
+
*/
|
|
825
|
+
extern BOX3D *lwcircstring_compute_box3d(LWCIRCSTRING *curve);
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
/******************************************************************
|
|
830
|
+
* LWGEOM functions
|
|
831
|
+
******************************************************************/
|
|
832
|
+
|
|
833
|
+
extern size_t lwgeom_serialize_size(LWGEOM *geom);
|
|
834
|
+
extern size_t lwcollection_serialize_size(LWCOLLECTION *coll);
|
|
835
|
+
extern void lwgeom_serialize_buf(LWGEOM *geom, uchar *buf, size_t *size);
|
|
836
|
+
extern uchar *lwgeom_serialize(LWGEOM *geom);
|
|
837
|
+
extern void lwcollection_serialize_buf(LWCOLLECTION *mcoll, uchar *buf, size_t *size);
|
|
838
|
+
extern int lwcollection_ngeoms(const LWCOLLECTION *col);
|
|
839
|
+
|
|
840
|
+
/*
|
|
841
|
+
* Deserialize an lwgeom serialized form.
|
|
842
|
+
* The deserialized (recursive) structure will store
|
|
843
|
+
* pointers to the serialized form (POINTARRAYs).
|
|
844
|
+
*/
|
|
845
|
+
LWGEOM *lwgeom_deserialize(uchar *serializedform);
|
|
846
|
+
BOX3D *lwgeom_compute_box3d(const LWGEOM *geom);
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
/******************************************************************
|
|
850
|
+
* LWMULTIx and LWCOLLECTION functions
|
|
851
|
+
******************************************************************/
|
|
852
|
+
|
|
853
|
+
LWMPOINT *lwmpoint_deserialize(uchar *serializedform);
|
|
854
|
+
LWMLINE *lwmline_deserialize(uchar *serializedform);
|
|
855
|
+
LWMPOLY *lwmpoly_deserialize(uchar *serializedform);
|
|
856
|
+
LWCOLLECTION *lwcollection_deserialize(uchar *serializedform);
|
|
857
|
+
LWCOMPOUND *lwcompound_deserialize(uchar *serialized_form);
|
|
858
|
+
LWCURVEPOLY *lwcurvepoly_deserialize(uchar *serialized_form);
|
|
859
|
+
LWMCURVE *lwmcurve_deserialize(uchar *serialized_form);
|
|
860
|
+
LWMSURFACE *lwmsurface_deserialize(uchar *serialized_form);
|
|
861
|
+
|
|
862
|
+
LWGEOM *lwcollection_getsubgeom(LWCOLLECTION *col, int gnum);
|
|
863
|
+
BOX3D *lwcollection_compute_box3d(LWCOLLECTION *col);
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
/******************************************************************
|
|
867
|
+
* SERIALIZED FORM functions
|
|
868
|
+
******************************************************************/
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
/******************************************************************
|
|
872
|
+
* Multi-geometries
|
|
873
|
+
*
|
|
874
|
+
* These are all handled equivelently so its easy to write iterator code.
|
|
875
|
+
* NOTE NOTE: you can hand in a non-multigeometry to most of these functions
|
|
876
|
+
* and get usual behavior (ie. get geometry 0 on a POINT
|
|
877
|
+
* will return the point).
|
|
878
|
+
* This makes coding even easier since you dont have to necessarily
|
|
879
|
+
* differenciate between the multi* and non-multi geometries.
|
|
880
|
+
*
|
|
881
|
+
* NOTE: these usually work directly off the serialized form, so
|
|
882
|
+
* they're a little more difficult to handle (and slower)
|
|
883
|
+
* NOTE NOTE: the get functions maybe slow, so we may want to have an
|
|
884
|
+
* "analysed" lwgeom that would just have pointer to the start
|
|
885
|
+
* of each sub-geometry.
|
|
886
|
+
*
|
|
887
|
+
******************************************************************/
|
|
888
|
+
|
|
889
|
+
/* use this version for speed. READ-ONLY! */
|
|
890
|
+
typedef struct
|
|
891
|
+
{
|
|
892
|
+
int SRID;
|
|
893
|
+
const uchar *serialized_form; /* orginal structure */
|
|
894
|
+
uchar type; /* 8-bit type for the LWGEOM */
|
|
895
|
+
int ngeometries; /* number of sub-geometries */
|
|
896
|
+
uchar **sub_geoms; /* list of pointers (into serialized_form)
|
|
897
|
+
of the sub-geoms */
|
|
898
|
+
} LWGEOM_INSPECTED;
|
|
899
|
+
|
|
900
|
+
extern int lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected, int geom_number);
|
|
901
|
+
|
|
902
|
+
/*
|
|
903
|
+
* note - for a simple type (ie. point), this will have
|
|
904
|
+
* sub_geom[0] = serialized_form.
|
|
905
|
+
* for multi-geomtries sub_geom[0] will be a few bytes into the
|
|
906
|
+
* serialized form.
|
|
907
|
+
* This function just computes the length of each sub-object and
|
|
908
|
+
* pre-caches this info.
|
|
909
|
+
* For a geometry collection of multi* geometries, you can inspect
|
|
910
|
+
* the sub-components as well.
|
|
911
|
+
*/
|
|
912
|
+
extern LWGEOM_INSPECTED *lwgeom_inspect(const uchar *serialized_form);
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
/*
|
|
916
|
+
* 1st geometry has geom_number = 0
|
|
917
|
+
* if the actual sub-geometry isnt a POINT, null is returned (see _gettype()).
|
|
918
|
+
* if there arent enough geometries, return null.
|
|
919
|
+
* this is fine to call on a point (with geom_num=0), multipoint
|
|
920
|
+
* or geometrycollection
|
|
921
|
+
*/
|
|
922
|
+
extern LWPOINT *lwgeom_getpoint(uchar *serialized_form, int geom_number);
|
|
923
|
+
extern LWPOINT *lwgeom_getpoint_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
|
|
924
|
+
|
|
925
|
+
/*
|
|
926
|
+
* 1st geometry has geom_number = 0
|
|
927
|
+
* if the actual geometry isnt a LINE, null is returned (see _gettype()).
|
|
928
|
+
* if there arent enough geometries, return null.
|
|
929
|
+
* this is fine to call on a line, multiline or geometrycollection
|
|
930
|
+
*/
|
|
931
|
+
extern LWLINE *lwgeom_getline(uchar *serialized_form, int geom_number);
|
|
932
|
+
extern LWLINE *lwgeom_getline_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
|
|
933
|
+
|
|
934
|
+
/*
|
|
935
|
+
* 1st geometry has geom_number = 0
|
|
936
|
+
* if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
|
|
937
|
+
* if there arent enough geometries, return null.
|
|
938
|
+
* this is fine to call on a polygon, multipolygon or geometrycollection
|
|
939
|
+
*/
|
|
940
|
+
extern LWPOLY *lwgeom_getpoly(uchar *serialized_form, int geom_number);
|
|
941
|
+
extern LWPOLY *lwgeom_getpoly_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
|
|
942
|
+
|
|
943
|
+
/*
|
|
944
|
+
* 1st geometry has geom_number = 0
|
|
945
|
+
* if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
|
|
946
|
+
* if there arent enough geometries, return null.
|
|
947
|
+
* this is fine to call on a polygon, multipolygon or geometrycollection
|
|
948
|
+
*/
|
|
949
|
+
extern LWCIRCSTRING *lwgeom_getcircstring_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
|
|
950
|
+
|
|
951
|
+
extern LWGEOM *lwgeom_getgeom_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
/*
|
|
956
|
+
* this gets the serialized form of a sub-geometry
|
|
957
|
+
* 1st geometry has geom_number = 0
|
|
958
|
+
* if this isnt a multi* geometry, and geom_number ==0 then it returns
|
|
959
|
+
* itself
|
|
960
|
+
* returns null on problems.
|
|
961
|
+
* in the future this is how you would access a muli* portion of a
|
|
962
|
+
* geometry collection.
|
|
963
|
+
* GEOMETRYCOLLECTION(MULTIPOINT(0 0, 1 1), LINESTRING(0 0, 1 1))
|
|
964
|
+
* ie. lwgeom_getpoint( lwgeom_getsubgeometry( serialized, 0), 1)
|
|
965
|
+
* --> POINT(1 1)
|
|
966
|
+
* you can inspect the sub-geometry as well if you wish.
|
|
967
|
+
*/
|
|
968
|
+
extern uchar *lwgeom_getsubgeometry(const uchar *serialized_form, int geom_number);
|
|
969
|
+
extern uchar *lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
|
|
970
|
+
|
|
971
|
+
|
|
972
|
+
/*
|
|
973
|
+
* 1st geometry has geom_number = 0
|
|
974
|
+
* use geom_number = -1 to find the actual type of the serialized form.
|
|
975
|
+
* ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1)
|
|
976
|
+
* --> multipoint
|
|
977
|
+
* ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
|
|
978
|
+
* --> point
|
|
979
|
+
* gets the 8bit type of the geometry at location geom_number
|
|
980
|
+
*/
|
|
981
|
+
extern uchar lwgeom_getsubtype(uchar *serialized_form, int geom_number);
|
|
982
|
+
extern uchar lwgeom_getsubtype_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
/*
|
|
986
|
+
* how many sub-geometries are there?
|
|
987
|
+
* for point,line,polygon will return 1.
|
|
988
|
+
*/
|
|
989
|
+
extern int lwgeom_getnumgeometries(uchar *serialized_form);
|
|
990
|
+
extern int lwgeom_getnumgeometries_inspected(LWGEOM_INSPECTED *inspected);
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
/*
|
|
995
|
+
* set finalType to COLLECTIONTYPE or 0 (0 means choose a best type)
|
|
996
|
+
* (ie. give it 2 points and ask it to be a multipoint)
|
|
997
|
+
* use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
|
|
998
|
+
* all subgeometries must have the same SRID
|
|
999
|
+
* if you want to construct an inspected, call this then inspect the result...
|
|
1000
|
+
*/
|
|
1001
|
+
extern uchar *lwgeom_serialized_construct(int SRID, int finalType, char hasz, char hasm, int nsubgeometries, uchar **serialized_subs);
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
/* construct the empty geometry (GEOMETRYCOLLECTION(EMPTY)) */
|
|
1005
|
+
extern uchar *lwgeom_constructempty(int SRID, char hasz, char hasm);
|
|
1006
|
+
extern void lwgeom_constructempty_buf(int SRID, char hasz, char hasm, uchar *buf, size_t *size);
|
|
1007
|
+
size_t lwgeom_empty_length(int SRID);
|
|
1008
|
+
|
|
1009
|
+
/*
|
|
1010
|
+
* get the SRID from the LWGEOM
|
|
1011
|
+
* none present => -1
|
|
1012
|
+
*/
|
|
1013
|
+
extern int lwgeom_getsrid(uchar *serialized);
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
/*------------------------------------------------------
|
|
1017
|
+
* other stuff
|
|
1018
|
+
*
|
|
1019
|
+
* handle the double-to-float conversion. The results of this
|
|
1020
|
+
* will usually be a slightly bigger box because of the difference
|
|
1021
|
+
* between float8 and float4 representations.
|
|
1022
|
+
*/
|
|
1023
|
+
|
|
1024
|
+
extern BOX2DFLOAT4 *box3d_to_box2df(BOX3D *box);
|
|
1025
|
+
extern int box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *res);
|
|
1026
|
+
|
|
1027
|
+
extern BOX3D box2df_to_box3d(BOX2DFLOAT4 *box);
|
|
1028
|
+
extern void box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *box3d);
|
|
1029
|
+
|
|
1030
|
+
extern BOX3D *box3d_union(BOX3D *b1, BOX3D *b2);
|
|
1031
|
+
extern int box3d_union_p(BOX3D *b1, BOX3D *b2, BOX3D *ubox);
|
|
1032
|
+
|
|
1033
|
+
/*
|
|
1034
|
+
* Returns a pointer to the BBOX internal to the serialized form.
|
|
1035
|
+
* READ-ONLY!
|
|
1036
|
+
* Or NULL if serialized form does not have a BBOX
|
|
1037
|
+
* OBSOLETED to avoid memory alignment problems.
|
|
1038
|
+
*/
|
|
1039
|
+
/*extern BOX2DFLOAT4 *getbox2d_internal(uchar *serialized_form);*/
|
|
1040
|
+
|
|
1041
|
+
/*
|
|
1042
|
+
* this function writes to 'box' and returns 0 if serialized_form
|
|
1043
|
+
* does not have a bounding box (empty geom)
|
|
1044
|
+
*/
|
|
1045
|
+
extern int getbox2d_p(uchar *serialized_form, BOX2DFLOAT4 *box);
|
|
1046
|
+
|
|
1047
|
+
/* Expand given box of 'd' units in all directions */
|
|
1048
|
+
void expand_box2d(BOX2DFLOAT4 *box, double d);
|
|
1049
|
+
void expand_box3d(BOX3D *box, double d);
|
|
1050
|
+
|
|
1051
|
+
/* Check if to boxes are equal (considering FLOAT approximations) */
|
|
1052
|
+
char box2d_same(BOX2DFLOAT4 *box1, BOX2DFLOAT4 *box2);
|
|
1053
|
+
|
|
1054
|
+
|
|
1055
|
+
|
|
1056
|
+
/****************************************************************
|
|
1057
|
+
* MEMORY MANAGEMENT
|
|
1058
|
+
****************************************************************/
|
|
1059
|
+
|
|
1060
|
+
/*
|
|
1061
|
+
* The lwfree_* family of functions frees *all* memory associated
|
|
1062
|
+
* with the pointer, including the serialized__pointlist in the
|
|
1063
|
+
* point arrays. Do not use these on LWGEOMs de-serialized from
|
|
1064
|
+
* PG_LWGEOMs or they will try to free an underlying structure
|
|
1065
|
+
* managed by PgSQL. Only use these on LWGEOMs you have
|
|
1066
|
+
* constructed yourself.
|
|
1067
|
+
*/
|
|
1068
|
+
|
|
1069
|
+
extern void ptarray_free(POINTARRAY *pa);
|
|
1070
|
+
extern void lwpoint_free(LWPOINT *pt);
|
|
1071
|
+
extern void lwline_free(LWLINE *line);
|
|
1072
|
+
extern void lwpoly_free(LWPOLY *poly);
|
|
1073
|
+
extern void lwmpoint_free(LWMPOINT *mpt);
|
|
1074
|
+
extern void lwmline_free(LWMLINE *mline);
|
|
1075
|
+
extern void lwmpoly_free(LWMPOLY *mpoly);
|
|
1076
|
+
extern void lwcollection_free(LWCOLLECTION *col);
|
|
1077
|
+
extern void lwcircstring_free(LWCIRCSTRING *curve);
|
|
1078
|
+
extern void lwgeom_free(LWGEOM *geom);
|
|
1079
|
+
|
|
1080
|
+
extern void lwinspected_release(LWGEOM_INSPECTED *inspected); /* TODO: make this deep free... */
|
|
1081
|
+
|
|
1082
|
+
/*
|
|
1083
|
+
* The *_release family of functions frees the LWGEOM structures
|
|
1084
|
+
* surrounding the POINTARRAYs but leaves the POINTARRAYs
|
|
1085
|
+
* intact. Use these on LWGEOMs that have been de-serialized
|
|
1086
|
+
* from PG_LWGEOMs. Do not use these on LWGEOMs you have
|
|
1087
|
+
* constructed yourself, or you will leak lots of memory.
|
|
1088
|
+
*/
|
|
1089
|
+
|
|
1090
|
+
extern void lwpoint_release(LWPOINT *lwpoint);
|
|
1091
|
+
extern void lwline_release(LWLINE *lwline);
|
|
1092
|
+
extern void lwpoly_release(LWPOLY *lwpoly);
|
|
1093
|
+
extern void lwmpoint_release(LWMPOINT *lwpoint);
|
|
1094
|
+
extern void lwmline_release(LWMLINE *lwline);
|
|
1095
|
+
extern void lwmpoly_release(LWMPOLY *lwpoly);
|
|
1096
|
+
extern void lwcollection_release(LWCOLLECTION *lwcollection);
|
|
1097
|
+
extern void lwgeom_release(LWGEOM *lwgeom);
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
/****************************************************************
|
|
1101
|
+
* utility
|
|
1102
|
+
****************************************************************/
|
|
1103
|
+
|
|
1104
|
+
extern uint32 lw_get_uint32(const uchar *loc);
|
|
1105
|
+
extern int32 lw_get_int32(const uchar *loc);
|
|
1106
|
+
extern void printBOX3D(BOX3D *b);
|
|
1107
|
+
extern void printPA(POINTARRAY *pa);
|
|
1108
|
+
extern void printLWPOINT(LWPOINT *point);
|
|
1109
|
+
extern void printLWLINE(LWLINE *line);
|
|
1110
|
+
extern void printLWPOLY(LWPOLY *poly);
|
|
1111
|
+
extern void printBYTES(uchar *a, int n);
|
|
1112
|
+
extern void printMULTI(uchar *serialized);
|
|
1113
|
+
extern void printType(uchar str);
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
extern float LWGEOM_Minf(float a, float b);
|
|
1117
|
+
extern float LWGEOM_Maxf(float a, float b);
|
|
1118
|
+
extern double LWGEOM_Mind(double a, double b);
|
|
1119
|
+
extern double LWGEOM_Maxd(double a, double b);
|
|
1120
|
+
|
|
1121
|
+
extern float nextDown_f(double d);
|
|
1122
|
+
extern float nextUp_f(double d);
|
|
1123
|
+
extern double nextDown_d(float d);
|
|
1124
|
+
extern double nextUp_d(float d);
|
|
1125
|
+
|
|
1126
|
+
extern float nextafterf_custom(float x, float y);
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
#define LW_MAX(a,b) ((a) > (b) ? (a) : (b))
|
|
1130
|
+
#define LW_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
|
1131
|
+
#define LW_ABS(a) ((a) < (0) ? (-a) : (a))
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
/* general utilities */
|
|
1135
|
+
extern double lwgeom_polygon_area(LWPOLY *poly);
|
|
1136
|
+
extern double lwgeom_polygon_perimeter(LWPOLY *poly);
|
|
1137
|
+
extern double lwgeom_polygon_perimeter2d(LWPOLY *poly);
|
|
1138
|
+
extern double lwgeom_pointarray_length2d(POINTARRAY *pts);
|
|
1139
|
+
extern double lwgeom_pointarray_length(POINTARRAY *pts);
|
|
1140
|
+
extern void lwgeom_force2d_recursive(uchar *serialized, uchar *optr, size_t *retsize);
|
|
1141
|
+
extern void lwgeom_force3dz_recursive(uchar *serialized, uchar *optr, size_t *retsize);
|
|
1142
|
+
extern void lwgeom_force3dm_recursive(uchar *serialized, uchar *optr, size_t *retsize);
|
|
1143
|
+
extern void lwgeom_force4d_recursive(uchar *serialized, uchar *optr, size_t *retsize);
|
|
1144
|
+
extern double distance2d_pt_pt(POINT2D *p1, POINT2D *p2);
|
|
1145
|
+
extern double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B);
|
|
1146
|
+
extern double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D);
|
|
1147
|
+
extern double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa);
|
|
1148
|
+
extern double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2);
|
|
1149
|
+
extern int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring);
|
|
1150
|
+
extern int pt_in_poly_2d(POINT2D *p, LWPOLY *poly);
|
|
1151
|
+
extern double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly);
|
|
1152
|
+
extern double distance2d_point_point(LWPOINT *point1, LWPOINT *point2);
|
|
1153
|
+
extern double distance2d_point_line(LWPOINT *point, LWLINE *line);
|
|
1154
|
+
extern double distance2d_line_line(LWLINE *line1, LWLINE *line2);
|
|
1155
|
+
extern double distance2d_point_poly(LWPOINT *point, LWPOLY *poly);
|
|
1156
|
+
extern double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2);
|
|
1157
|
+
extern double distance2d_line_poly(LWLINE *line, LWPOLY *poly);
|
|
1158
|
+
extern int azimuth_pt_pt(POINT2D *p1, POINT2D *p2, double *ret);
|
|
1159
|
+
extern double lwgeom_mindistance2d_recursive(uchar *lw1, uchar *lw2);
|
|
1160
|
+
extern double lwgeom_mindistance2d_recursive_tolerance(uchar *lw1, uchar *lw2, double tolerance);
|
|
1161
|
+
extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
|
|
1162
|
+
extern int32 lwgeom_npoints(uchar *serialized);
|
|
1163
|
+
extern char ptarray_isccw(const POINTARRAY *pa);
|
|
1164
|
+
extern void lwgeom_reverse(LWGEOM *lwgeom);
|
|
1165
|
+
extern void lwline_reverse(LWLINE *line);
|
|
1166
|
+
extern void lwpoly_reverse(LWPOLY *poly);
|
|
1167
|
+
extern void lwpoly_forceRHR(LWPOLY *poly);
|
|
1168
|
+
extern void lwgeom_forceRHR(LWGEOM *lwgeom);
|
|
1169
|
+
extern char *lwgeom_summary(LWGEOM *lwgeom, int offset);
|
|
1170
|
+
extern const char *lwgeom_typename(int type);
|
|
1171
|
+
extern int ptarray_compute_box2d_p(const POINTARRAY *pa, BOX2DFLOAT4 *result);
|
|
1172
|
+
extern BOX2DFLOAT4 *ptarray_compute_box2d(const POINTARRAY *pa);
|
|
1173
|
+
extern int lwpoint_compute_box2d_p(LWPOINT *point, BOX2DFLOAT4 *box);
|
|
1174
|
+
extern int lwline_compute_box2d_p(LWLINE *line, BOX2DFLOAT4 *box);
|
|
1175
|
+
extern int lwpoly_compute_box2d_p(LWPOLY *poly, BOX2DFLOAT4 *box);
|
|
1176
|
+
extern int lwcollection_compute_box2d_p(LWCOLLECTION *col, BOX2DFLOAT4 *box);
|
|
1177
|
+
extern int lwcircstring_compute_box2d_p(LWCIRCSTRING *curve, BOX2DFLOAT4 *box);
|
|
1178
|
+
extern BOX2DFLOAT4 *lwgeom_compute_box2d(LWGEOM *lwgeom);
|
|
1179
|
+
|
|
1180
|
+
extern void interpolate_point4d(POINT4D *A, POINT4D *B, POINT4D *I, double F);
|
|
1181
|
+
|
|
1182
|
+
/* return alloced memory */
|
|
1183
|
+
extern BOX2DFLOAT4 *box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2);
|
|
1184
|
+
|
|
1185
|
+
/* args may overlap ! */
|
|
1186
|
+
extern int box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox);
|
|
1187
|
+
extern int lwgeom_compute_box2d_p(LWGEOM *lwgeom, BOX2DFLOAT4 *box);
|
|
1188
|
+
void lwgeom_longitude_shift(LWGEOM *lwgeom);
|
|
1189
|
+
|
|
1190
|
+
/* Is lwgeom1 geometrically equal to lwgeom2 ? */
|
|
1191
|
+
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2);
|
|
1192
|
+
char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2);
|
|
1193
|
+
char lwpoint_same(const LWPOINT *p1, const LWPOINT *p2);
|
|
1194
|
+
char lwline_same(const LWLINE *p1, const LWLINE *p2);
|
|
1195
|
+
char lwpoly_same(const LWPOLY *p1, const LWPOLY *p2);
|
|
1196
|
+
char lwcollection_same(const LWCOLLECTION *p1, const LWCOLLECTION *p2);
|
|
1197
|
+
|
|
1198
|
+
/*
|
|
1199
|
+
* Add 'what' to 'to' at position 'where'.
|
|
1200
|
+
* where=0 == prepend
|
|
1201
|
+
* where=-1 == append
|
|
1202
|
+
* Mix of dimensions is not allowed (TODO: allow it?).
|
|
1203
|
+
* Returns a newly allocated LWGEOM (with NO BBOX)
|
|
1204
|
+
*/
|
|
1205
|
+
extern LWGEOM *lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what);
|
|
1206
|
+
|
|
1207
|
+
LWGEOM *lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what);
|
|
1208
|
+
LWGEOM *lwline_add(const LWLINE *to, uint32 where, const LWGEOM *what);
|
|
1209
|
+
LWGEOM *lwpoly_add(const LWPOLY *to, uint32 where, const LWGEOM *what);
|
|
1210
|
+
LWGEOM *lwmpoly_add(const LWMPOLY *to, uint32 where, const LWGEOM *what);
|
|
1211
|
+
LWGEOM *lwmline_add(const LWMLINE *to, uint32 where, const LWGEOM *what);
|
|
1212
|
+
LWGEOM *lwmpoint_add(const LWMPOINT *to, uint32 where, const LWGEOM *what);
|
|
1213
|
+
LWGEOM *lwcollection_add(const LWCOLLECTION *to, uint32 where, const LWGEOM *what);
|
|
1214
|
+
LWGEOM *lwcompound_add(const LWCOMPOUND *to, uint32 where, const LWGEOM *what);
|
|
1215
|
+
LWGEOM *lwcurvepoly_add(const LWCURVEPOLY *to, uint32 where, const LWGEOM *what);
|
|
1216
|
+
LWGEOM *lwmcurve_add(const LWMCURVE *to, uint32 where, const LWGEOM *what);
|
|
1217
|
+
LWGEOM *lwmsurface_add(const LWMSURFACE *to, uint32 where, const LWGEOM *what);
|
|
1218
|
+
LWGEOM *lwcircstring_add(const LWCIRCSTRING *to, uint32 where, const LWGEOM *what);
|
|
1219
|
+
|
|
1220
|
+
/*
|
|
1221
|
+
* Clone an LWGEOM
|
|
1222
|
+
* pointarray are not copied.
|
|
1223
|
+
* BBOXes are copied
|
|
1224
|
+
*/
|
|
1225
|
+
extern LWGEOM *lwgeom_clone(const LWGEOM *lwgeom);
|
|
1226
|
+
extern LWPOINT *lwpoint_clone(const LWPOINT *lwgeom);
|
|
1227
|
+
extern LWLINE *lwline_clone(const LWLINE *lwgeom);
|
|
1228
|
+
extern LWPOLY *lwpoly_clone(const LWPOLY *lwgeom);
|
|
1229
|
+
extern LWCOLLECTION *lwcollection_clone(const LWCOLLECTION *lwgeom);
|
|
1230
|
+
extern LWCIRCSTRING *lwcircstring_clone(const LWCIRCSTRING *curve);
|
|
1231
|
+
extern BOX2DFLOAT4 *box2d_clone(const BOX2DFLOAT4 *lwgeom);
|
|
1232
|
+
extern POINTARRAY *ptarray_clone(const POINTARRAY *ptarray);
|
|
1233
|
+
|
|
1234
|
+
/*
|
|
1235
|
+
* Geometry constructors
|
|
1236
|
+
* Take ownership of arguments
|
|
1237
|
+
*/
|
|
1238
|
+
extern LWPOINT *lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox,
|
|
1239
|
+
POINTARRAY *point);
|
|
1240
|
+
extern LWLINE *lwline_construct(int SRID, BOX2DFLOAT4 *bbox,
|
|
1241
|
+
POINTARRAY *points);
|
|
1242
|
+
|
|
1243
|
+
/*
|
|
1244
|
+
* Construct a new LWPOLY. arrays (points/points per ring) will NOT be copied
|
|
1245
|
+
* use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
|
|
1246
|
+
*/
|
|
1247
|
+
extern LWPOLY *lwpoly_construct(int SRID, BOX2DFLOAT4 *bbox,
|
|
1248
|
+
unsigned int nrings, POINTARRAY **points);
|
|
1249
|
+
|
|
1250
|
+
extern LWCOLLECTION *lwcollection_construct(unsigned int type, int SRID,
|
|
1251
|
+
BOX2DFLOAT4 *bbox, unsigned int ngeoms, LWGEOM **geoms);
|
|
1252
|
+
extern LWCOLLECTION *lwcollection_construct_empty(int SRID,
|
|
1253
|
+
char hasZ, char hasM);
|
|
1254
|
+
|
|
1255
|
+
/*
|
|
1256
|
+
* Construct a new LWCIRCSTRING. arrays (points/points per ring) will NOT be copied
|
|
1257
|
+
* use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
|
|
1258
|
+
*/
|
|
1259
|
+
extern LWCIRCSTRING *lwcircstring_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points);
|
|
1260
|
+
|
|
1261
|
+
/* Other constructors */
|
|
1262
|
+
extern LWPOINT *make_lwpoint2d(int SRID, double x, double y);
|
|
1263
|
+
extern LWPOINT *make_lwpoint3dz(int SRID, double x, double y, double z);
|
|
1264
|
+
extern LWPOINT *make_lwpoint3dm(int SRID, double x, double y, double m);
|
|
1265
|
+
extern LWPOINT *make_lwpoint4d(int SRID, double x, double y, double z, double m);
|
|
1266
|
+
extern LWLINE *lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points);
|
|
1267
|
+
extern LWLINE *lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint);
|
|
1268
|
+
extern LWLINE *lwline_addpoint(LWLINE *line, LWPOINT *point, unsigned int where);
|
|
1269
|
+
extern LWLINE *lwline_removepoint(LWLINE *line, unsigned int which);
|
|
1270
|
+
extern void lwline_setPoint4d(LWLINE *line, unsigned int which, POINT4D *newpoint);
|
|
1271
|
+
extern LWPOLY *lwpoly_from_lwlines(const LWLINE *shell, unsigned int nholes, const LWLINE **holes);
|
|
1272
|
+
|
|
1273
|
+
/* Return a char string with ASCII versionf of type flags */
|
|
1274
|
+
extern const char *lwgeom_typeflags(uchar type);
|
|
1275
|
+
|
|
1276
|
+
/* Construct an empty pointarray */
|
|
1277
|
+
extern POINTARRAY *ptarray_construct(char hasz, char hasm, unsigned int npoints);
|
|
1278
|
+
|
|
1279
|
+
/*
|
|
1280
|
+
* extern POINTARRAY *ptarray_construct2d(uint32 npoints, const POINT2D *pts);
|
|
1281
|
+
* extern POINTARRAY *ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts);
|
|
1282
|
+
* extern POINTARRAY *ptarray_construct3dm(uint32 npoints, const POINT3DM *pts);
|
|
1283
|
+
* extern POINTARRAY *ptarray_construct4d(uint32 npoints, const POINT4D *pts);
|
|
1284
|
+
*/
|
|
1285
|
+
|
|
1286
|
+
extern POINTARRAY *ptarray_addPoint(POINTARRAY *pa, uchar *p, size_t pdims,
|
|
1287
|
+
unsigned int where);
|
|
1288
|
+
extern POINTARRAY *ptarray_removePoint(POINTARRAY *pa, unsigned int where);
|
|
1289
|
+
|
|
1290
|
+
extern int ptarray_isclosed2d(const POINTARRAY *pa);
|
|
1291
|
+
|
|
1292
|
+
extern void ptarray_longitude_shift(POINTARRAY *pa);
|
|
1293
|
+
|
|
1294
|
+
extern int32 lwgeom_nrings_recursive(uchar *serialized);
|
|
1295
|
+
extern void ptarray_reverse(POINTARRAY *pa);
|
|
1296
|
+
extern POINTARRAY *ptarray_substring(POINTARRAY *, double, double);
|
|
1297
|
+
extern double ptarray_locate_point(POINTARRAY *, POINT2D *);
|
|
1298
|
+
extern void closest_point_on_segment(POINT2D *p, POINT2D *A, POINT2D *B, POINT2D *ret);
|
|
1299
|
+
|
|
1300
|
+
/*
|
|
1301
|
+
* Ensure every segment is at most 'dist' long.
|
|
1302
|
+
* Returned LWGEOM might is unchanged if a POINT.
|
|
1303
|
+
*/
|
|
1304
|
+
extern LWGEOM *lwgeom_segmentize2d(LWGEOM *line, double dist);
|
|
1305
|
+
extern POINTARRAY *ptarray_segmentize2d(POINTARRAY *ipa, double dist);
|
|
1306
|
+
extern LWLINE *lwline_segmentize2d(LWLINE *line, double dist);
|
|
1307
|
+
extern LWPOLY *lwpoly_segmentize2d(LWPOLY *line, double dist);
|
|
1308
|
+
extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
|
|
1309
|
+
|
|
1310
|
+
extern uchar parse_hex(char *str);
|
|
1311
|
+
extern void deparse_hex(uchar str, char *result);
|
|
1312
|
+
|
|
1313
|
+
/* Parser check flags */
|
|
1314
|
+
#define PARSER_CHECK_MINPOINTS 1
|
|
1315
|
+
#define PARSER_CHECK_ODD 2
|
|
1316
|
+
#define PARSER_CHECK_CLOSURE 4
|
|
1317
|
+
|
|
1318
|
+
#define PARSER_CHECK_NONE 0
|
|
1319
|
+
#define PARSER_CHECK_ALL (PARSER_CHECK_MINPOINTS | PARSER_CHECK_ODD | PARSER_CHECK_CLOSURE)
|
|
1320
|
+
|
|
1321
|
+
/*
|
|
1322
|
+
* Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM
|
|
1323
|
+
*/
|
|
1324
|
+
typedef struct struct_lwgeom_parser_result
|
|
1325
|
+
{
|
|
1326
|
+
const char *wkinput; /* Copy of pointer to input WKT/WKB */
|
|
1327
|
+
uchar *serialized_lwgeom; /* Pointer to serialized LWGEOM */
|
|
1328
|
+
int size; /* Size of serialized LWGEOM in bytes */
|
|
1329
|
+
const char *message; /* Error/warning message */
|
|
1330
|
+
int errlocation; /* Location of error */
|
|
1331
|
+
} LWGEOM_PARSER_RESULT;
|
|
1332
|
+
|
|
1333
|
+
/*
|
|
1334
|
+
* Parser error messages (these must match the message array in lwgparse.c)
|
|
1335
|
+
*/
|
|
1336
|
+
#define PARSER_ERROR_MOREPOINTS 1
|
|
1337
|
+
#define PARSER_ERROR_ODDPOINTS 2
|
|
1338
|
+
#define PARSER_ERROR_UNCLOSED 3
|
|
1339
|
+
#define PARSER_ERROR_MIXDIMS 4
|
|
1340
|
+
#define PARSER_ERROR_INVALIDGEOM 5
|
|
1341
|
+
#define PARSER_ERROR_INVALIDWKBTYPE 6
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
/*
|
|
1345
|
+
* Unparser result structure: returns the result of attempting to convert LWGEOM to (E)WKT/(E)WKB
|
|
1346
|
+
*/
|
|
1347
|
+
typedef struct struct_lwgeom_unparser_result
|
|
1348
|
+
{
|
|
1349
|
+
uchar *serialized_lwgeom; /* Copy of pointer to input serialized LWGEOM */
|
|
1350
|
+
char *wkoutput; /* Pointer to WKT or WKB output */
|
|
1351
|
+
int size; /* Size of serialized LWGEOM in bytes */
|
|
1352
|
+
const char *message; /* Error/warning message */
|
|
1353
|
+
int errlocation; /* Location of error */
|
|
1354
|
+
} LWGEOM_UNPARSER_RESULT;
|
|
1355
|
+
|
|
1356
|
+
/*
|
|
1357
|
+
* Unparser error messages (these must match the message array in lwgunparse.c)
|
|
1358
|
+
*/
|
|
1359
|
+
#define UNPARSER_ERROR_MOREPOINTS 1
|
|
1360
|
+
#define UNPARSER_ERROR_ODDPOINTS 2
|
|
1361
|
+
#define UNPARSER_ERROR_UNCLOSED 3
|
|
1362
|
+
|
|
1363
|
+
|
|
1364
|
+
/* Parser access routines */
|
|
1365
|
+
extern char *lwgeom_to_ewkt(LWGEOM *lwgeom, int flags);
|
|
1366
|
+
extern char *lwgeom_to_hexwkb(LWGEOM *lwgeom, int flags, unsigned int byteorder);
|
|
1367
|
+
extern LWGEOM *lwgeom_from_ewkb(uchar *ewkb, int flags, size_t ewkblen);
|
|
1368
|
+
extern LWGEOM *lwgeom_from_ewkt(char *ewkt, int flags);
|
|
1369
|
+
extern uchar *lwgeom_to_ewkb(LWGEOM *lwgeom, int flags, char byteorder, size_t *ewkblen);
|
|
1370
|
+
|
|
1371
|
+
extern int serialized_lwgeom_to_ewkt(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar *serialized, int flags);
|
|
1372
|
+
extern int serialized_lwgeom_from_ewkt(LWGEOM_PARSER_RESULT *lwg_parser_result, char *wkt_input, int flags);
|
|
1373
|
+
extern int serialized_lwgeom_to_hexwkb(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar *serialized, int flags, unsigned int byteorder);
|
|
1374
|
+
extern int serialized_lwgeom_from_hexwkb(LWGEOM_PARSER_RESULT *lwg_parser_result, char *hexwkb_input, int flags);
|
|
1375
|
+
extern int serialized_lwgeom_to_ewkb(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar *serialized, int flags, unsigned int byteorder);
|
|
1376
|
+
|
|
1377
|
+
extern void *lwalloc(size_t size);
|
|
1378
|
+
extern void *lwrealloc(void *mem, size_t size);
|
|
1379
|
+
extern void lwfree(void *mem);
|
|
1380
|
+
|
|
1381
|
+
/* Utilities */
|
|
1382
|
+
extern void trim_trailing_zeros(char *num);
|
|
1383
|
+
extern char *lwmessage_truncate(char *str, int startpos, int endpos, int maxlength, int truncdirection);
|
|
1384
|
+
|
|
1385
|
+
/* Machine endianness */
|
|
1386
|
+
#define XDR 0
|
|
1387
|
+
#define NDR 1
|
|
1388
|
+
extern char getMachineEndian(void);
|
|
1389
|
+
|
|
1390
|
+
void errorIfSRIDMismatch(int srid1, int srid2);
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
/*******************************************************************************
|
|
1394
|
+
* SQLMM internal functions - TODO: Move into separate header files
|
|
1395
|
+
******************************************************************************/
|
|
1396
|
+
|
|
1397
|
+
uint32 has_arc(LWGEOM *geom);
|
|
1398
|
+
double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
|
|
1399
|
+
LWGEOM *lwgeom_segmentize(LWGEOM *geom, uint32 perQuad);
|
|
1400
|
+
LWGEOM *lwgeom_desegmentize(LWGEOM *geom);
|
|
1401
|
+
extern double lwgeom_curvepolygon_area(LWCURVEPOLY *curvepoly);
|
|
1402
|
+
double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
|
|
1403
|
+
|
|
1404
|
+
#endif /* !defined _LIBLWGEOM_H */
|
|
1405
|
+
|