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,525 @@
|
|
|
1
|
+
/**********************************************************************
|
|
2
|
+
* $Id: lwline.c 3639 2009-02-04 00:28:37Z pramsey $
|
|
3
|
+
*
|
|
4
|
+
* PostGIS - Spatial Types for PostgreSQL
|
|
5
|
+
* http://postgis.refractions.net
|
|
6
|
+
* Copyright 2001-2006 Refractions Research Inc.
|
|
7
|
+
*
|
|
8
|
+
* This is free software; you can redistribute and/or modify it under
|
|
9
|
+
* the terms of the GNU General Public Licence. See the COPYING file.
|
|
10
|
+
*
|
|
11
|
+
**********************************************************************/
|
|
12
|
+
|
|
13
|
+
/* basic LWLINE functions */
|
|
14
|
+
|
|
15
|
+
#include <stdio.h>
|
|
16
|
+
#include <stdlib.h>
|
|
17
|
+
#include <string.h>
|
|
18
|
+
#include "liblwgeom.h"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Construct a new LWLINE. points will *NOT* be copied
|
|
24
|
+
* use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
|
|
25
|
+
*/
|
|
26
|
+
LWLINE *
|
|
27
|
+
lwline_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points)
|
|
28
|
+
{
|
|
29
|
+
LWLINE *result;
|
|
30
|
+
result = (LWLINE*) lwalloc(sizeof(LWLINE));
|
|
31
|
+
|
|
32
|
+
LWDEBUG(2, "lwline_construct called.");
|
|
33
|
+
|
|
34
|
+
result->type = lwgeom_makeType_full(
|
|
35
|
+
TYPE_HASZ(points->dims),
|
|
36
|
+
TYPE_HASM(points->dims),
|
|
37
|
+
(SRID!=-1), LINETYPE,
|
|
38
|
+
0);
|
|
39
|
+
|
|
40
|
+
LWDEBUGF(3, "lwline_construct type=%d", result->type);
|
|
41
|
+
|
|
42
|
+
result->SRID = SRID;
|
|
43
|
+
result->points = points;
|
|
44
|
+
result->bbox = bbox;
|
|
45
|
+
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
* given the LWGEOM serialized form (or a pointer into a muli* one)
|
|
51
|
+
* construct a proper LWLINE.
|
|
52
|
+
* serialized_form should point to the 8bit type format (with type = 2)
|
|
53
|
+
* See serialized form doc
|
|
54
|
+
*/
|
|
55
|
+
LWLINE *
|
|
56
|
+
lwline_deserialize(uchar *serialized_form)
|
|
57
|
+
{
|
|
58
|
+
uchar type;
|
|
59
|
+
LWLINE *result;
|
|
60
|
+
uchar *loc =NULL;
|
|
61
|
+
uint32 npoints;
|
|
62
|
+
POINTARRAY *pa;
|
|
63
|
+
|
|
64
|
+
type = (uchar) serialized_form[0];
|
|
65
|
+
|
|
66
|
+
if ( lwgeom_getType(type) != LINETYPE)
|
|
67
|
+
{
|
|
68
|
+
lwerror("lwline_deserialize: attempt to deserialize a line which is really a %s", lwgeom_typename(type));
|
|
69
|
+
return NULL;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
result = (LWLINE*) lwalloc(sizeof(LWLINE)) ;
|
|
73
|
+
result->type = type;
|
|
74
|
+
|
|
75
|
+
loc = serialized_form+1;
|
|
76
|
+
|
|
77
|
+
if (lwgeom_hasBBOX(type))
|
|
78
|
+
{
|
|
79
|
+
LWDEBUG(3, "lwline_deserialize: input has bbox");
|
|
80
|
+
|
|
81
|
+
result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
|
|
82
|
+
memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
|
|
83
|
+
loc += sizeof(BOX2DFLOAT4);
|
|
84
|
+
}
|
|
85
|
+
else
|
|
86
|
+
{
|
|
87
|
+
result->bbox = NULL;
|
|
88
|
+
/*lwnotice("line has NO bbox"); */
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if ( lwgeom_hasSRID(type))
|
|
92
|
+
{
|
|
93
|
+
/*lwnotice("line has srid"); */
|
|
94
|
+
result->SRID = lw_get_int32(loc);
|
|
95
|
+
loc +=4; /* type + SRID */
|
|
96
|
+
}
|
|
97
|
+
else
|
|
98
|
+
{
|
|
99
|
+
/*lwnotice("line has NO srid"); */
|
|
100
|
+
result->SRID = -1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* we've read the type (1 byte) and SRID (4 bytes, if present) */
|
|
104
|
+
|
|
105
|
+
npoints = lw_get_uint32(loc);
|
|
106
|
+
/*lwnotice("line npoints = %d", npoints); */
|
|
107
|
+
loc +=4;
|
|
108
|
+
pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), npoints);
|
|
109
|
+
result->points = pa;
|
|
110
|
+
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
* convert this line into its serialize form
|
|
116
|
+
* result's first char will be the 8bit type. See serialized form doc
|
|
117
|
+
*/
|
|
118
|
+
uchar *
|
|
119
|
+
lwline_serialize(LWLINE *line)
|
|
120
|
+
{
|
|
121
|
+
size_t size, retsize;
|
|
122
|
+
uchar * result;
|
|
123
|
+
|
|
124
|
+
if (line == NULL) lwerror("lwline_serialize:: given null line");
|
|
125
|
+
|
|
126
|
+
size = lwline_serialize_size(line);
|
|
127
|
+
result = lwalloc(size);
|
|
128
|
+
lwline_serialize_buf(line, result, &retsize);
|
|
129
|
+
|
|
130
|
+
if ( retsize != size )
|
|
131
|
+
{
|
|
132
|
+
lwerror("lwline_serialize_size returned %d, ..serialize_buf returned %d", size, retsize);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/*
|
|
139
|
+
* convert this line into its serialize form writing it into
|
|
140
|
+
* the given buffer, and returning number of bytes written into
|
|
141
|
+
* the given int pointer.
|
|
142
|
+
* result's first char will be the 8bit type. See serialized form doc
|
|
143
|
+
*/
|
|
144
|
+
void
|
|
145
|
+
lwline_serialize_buf(LWLINE *line, uchar *buf, size_t *retsize)
|
|
146
|
+
{
|
|
147
|
+
char hasSRID;
|
|
148
|
+
uchar *loc;
|
|
149
|
+
int ptsize;
|
|
150
|
+
size_t size;
|
|
151
|
+
|
|
152
|
+
LWDEBUGF(2, "lwline_serialize_buf(%p, %p, %p) called",
|
|
153
|
+
line, buf, retsize);
|
|
154
|
+
|
|
155
|
+
if (line == NULL)
|
|
156
|
+
lwerror("lwline_serialize:: given null line");
|
|
157
|
+
|
|
158
|
+
if ( TYPE_GETZM(line->type) != TYPE_GETZM(line->points->dims) )
|
|
159
|
+
lwerror("Dimensions mismatch in lwline");
|
|
160
|
+
|
|
161
|
+
ptsize = pointArray_ptsize(line->points);
|
|
162
|
+
|
|
163
|
+
hasSRID = (line->SRID != -1);
|
|
164
|
+
|
|
165
|
+
buf[0] = (uchar) lwgeom_makeType_full(
|
|
166
|
+
TYPE_HASZ(line->type), TYPE_HASM(line->type),
|
|
167
|
+
hasSRID, LINETYPE, line->bbox ? 1 : 0);
|
|
168
|
+
loc = buf+1;
|
|
169
|
+
|
|
170
|
+
LWDEBUGF(3, "lwline_serialize_buf added type (%d)", line->type);
|
|
171
|
+
|
|
172
|
+
if (line->bbox)
|
|
173
|
+
{
|
|
174
|
+
memcpy(loc, line->bbox, sizeof(BOX2DFLOAT4));
|
|
175
|
+
loc += sizeof(BOX2DFLOAT4);
|
|
176
|
+
|
|
177
|
+
LWDEBUG(3, "lwline_serialize_buf added BBOX");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (hasSRID)
|
|
181
|
+
{
|
|
182
|
+
memcpy(loc, &line->SRID, sizeof(int32));
|
|
183
|
+
loc += sizeof(int32);
|
|
184
|
+
|
|
185
|
+
LWDEBUG(3, "lwline_serialize_buf added SRID");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
memcpy(loc, &line->points->npoints, sizeof(uint32));
|
|
189
|
+
loc += sizeof(uint32);
|
|
190
|
+
|
|
191
|
+
LWDEBUGF(3, "lwline_serialize_buf added npoints (%d)",
|
|
192
|
+
line->points->npoints);
|
|
193
|
+
|
|
194
|
+
/*copy in points */
|
|
195
|
+
size = line->points->npoints*ptsize;
|
|
196
|
+
memcpy(loc, getPoint_internal(line->points, 0), size);
|
|
197
|
+
loc += size;
|
|
198
|
+
|
|
199
|
+
LWDEBUGF(3, "lwline_serialize_buf copied serialized_pointlist (%d bytes)",
|
|
200
|
+
ptsize * line->points->npoints);
|
|
201
|
+
|
|
202
|
+
if (retsize) *retsize = loc-buf;
|
|
203
|
+
|
|
204
|
+
/*printBYTES((uchar *)result, loc-buf); */
|
|
205
|
+
|
|
206
|
+
LWDEBUGF(3, "lwline_serialize_buf returning (loc: %p, size: %d)",
|
|
207
|
+
loc, loc-buf);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/*
|
|
211
|
+
* Find bounding box (standard one)
|
|
212
|
+
* zmin=zmax=NO_Z_VALUE if 2d
|
|
213
|
+
*/
|
|
214
|
+
BOX3D *
|
|
215
|
+
lwline_compute_box3d(LWLINE *line)
|
|
216
|
+
{
|
|
217
|
+
BOX3D *ret;
|
|
218
|
+
|
|
219
|
+
if (line == NULL) return NULL;
|
|
220
|
+
|
|
221
|
+
ret = ptarray_compute_box3d(line->points);
|
|
222
|
+
return ret;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* find length of this deserialized line */
|
|
226
|
+
size_t
|
|
227
|
+
lwline_serialize_size(LWLINE *line)
|
|
228
|
+
{
|
|
229
|
+
size_t size = 1; /* type */
|
|
230
|
+
|
|
231
|
+
LWDEBUG(2, "lwline_serialize_size called");
|
|
232
|
+
|
|
233
|
+
if ( line->SRID != -1 ) size += 4; /* SRID */
|
|
234
|
+
if ( line->bbox ) size += sizeof(BOX2DFLOAT4);
|
|
235
|
+
|
|
236
|
+
size += 4; /* npoints */
|
|
237
|
+
size += pointArray_ptsize(line->points)*line->points->npoints;
|
|
238
|
+
|
|
239
|
+
LWDEBUGF(3, "lwline_serialize_size returning %d", size);
|
|
240
|
+
|
|
241
|
+
return size;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
void lwline_free (LWLINE *line)
|
|
245
|
+
{
|
|
246
|
+
if ( line->bbox )
|
|
247
|
+
lwfree(line->bbox);
|
|
248
|
+
|
|
249
|
+
ptarray_free(line->points);
|
|
250
|
+
lwfree(line);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* find length of this serialized line */
|
|
254
|
+
size_t
|
|
255
|
+
lwgeom_size_line(const uchar *serialized_line)
|
|
256
|
+
{
|
|
257
|
+
int type = (uchar) serialized_line[0];
|
|
258
|
+
uint32 result = 1; /*type */
|
|
259
|
+
const uchar *loc;
|
|
260
|
+
uint32 npoints;
|
|
261
|
+
|
|
262
|
+
LWDEBUG(2, "lwgeom_size_line called");
|
|
263
|
+
|
|
264
|
+
if ( lwgeom_getType(type) != LINETYPE)
|
|
265
|
+
lwerror("lwgeom_size_line::attempt to find the length of a non-line");
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
loc = serialized_line+1;
|
|
269
|
+
|
|
270
|
+
if (lwgeom_hasBBOX(type))
|
|
271
|
+
{
|
|
272
|
+
loc += sizeof(BOX2DFLOAT4);
|
|
273
|
+
result +=sizeof(BOX2DFLOAT4);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if ( lwgeom_hasSRID(type))
|
|
277
|
+
{
|
|
278
|
+
loc += 4; /* type + SRID */
|
|
279
|
+
result +=4;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* we've read the type (1 byte) and SRID (4 bytes, if present) */
|
|
283
|
+
npoints = lw_get_uint32(loc);
|
|
284
|
+
result += sizeof(uint32); /* npoints */
|
|
285
|
+
|
|
286
|
+
result += TYPE_NDIMS(type) * sizeof(double) * npoints;
|
|
287
|
+
|
|
288
|
+
LWDEBUGF(3, "lwgeom_size_line returning %d", result);
|
|
289
|
+
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
void printLWLINE(LWLINE *line)
|
|
294
|
+
{
|
|
295
|
+
lwnotice("LWLINE {");
|
|
296
|
+
lwnotice(" ndims = %i", (int)TYPE_NDIMS(line->type));
|
|
297
|
+
lwnotice(" SRID = %i", (int)line->SRID);
|
|
298
|
+
printPA(line->points);
|
|
299
|
+
lwnotice("}");
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
int
|
|
303
|
+
lwline_compute_box2d_p(LWLINE *line, BOX2DFLOAT4 *box)
|
|
304
|
+
{
|
|
305
|
+
return ptarray_compute_box2d_p(line->points, box);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* Clone LWLINE object. POINTARRAY is not copied. */
|
|
309
|
+
LWLINE *
|
|
310
|
+
lwline_clone(const LWLINE *g)
|
|
311
|
+
{
|
|
312
|
+
LWLINE *ret = lwalloc(sizeof(LWLINE));
|
|
313
|
+
|
|
314
|
+
LWDEBUGF(2, "lwline_clone called with %p", g);
|
|
315
|
+
|
|
316
|
+
memcpy(ret, g, sizeof(LWLINE));
|
|
317
|
+
if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
|
|
318
|
+
return ret;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/*
|
|
322
|
+
* Add 'what' to this line at position 'where'.
|
|
323
|
+
* where=0 == prepend
|
|
324
|
+
* where=-1 == append
|
|
325
|
+
* Returns a MULTILINE or a GEOMETRYCOLLECTION
|
|
326
|
+
*/
|
|
327
|
+
LWGEOM *
|
|
328
|
+
lwline_add(const LWLINE *to, uint32 where, const LWGEOM *what)
|
|
329
|
+
{
|
|
330
|
+
LWCOLLECTION *col;
|
|
331
|
+
LWGEOM **geoms;
|
|
332
|
+
int newtype;
|
|
333
|
+
|
|
334
|
+
if ( where != -1 && where != 0 )
|
|
335
|
+
{
|
|
336
|
+
lwerror("lwline_add only supports 0 or -1 as second argument, got %d", where);
|
|
337
|
+
return NULL;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/* dimensions compatibility are checked by caller */
|
|
341
|
+
|
|
342
|
+
/* Construct geoms array */
|
|
343
|
+
geoms = lwalloc(sizeof(LWGEOM *)*2);
|
|
344
|
+
if ( where == -1 ) /* append */
|
|
345
|
+
{
|
|
346
|
+
geoms[0] = lwgeom_clone((LWGEOM *)to);
|
|
347
|
+
geoms[1] = lwgeom_clone(what);
|
|
348
|
+
}
|
|
349
|
+
else /* prepend */
|
|
350
|
+
{
|
|
351
|
+
geoms[0] = lwgeom_clone(what);
|
|
352
|
+
geoms[1] = lwgeom_clone((LWGEOM *)to);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/* reset SRID and wantbbox flag from component types */
|
|
356
|
+
geoms[0]->SRID = geoms[1]->SRID = -1;
|
|
357
|
+
TYPE_SETHASSRID(geoms[0]->type, 0);
|
|
358
|
+
TYPE_SETHASSRID(geoms[1]->type, 0);
|
|
359
|
+
TYPE_SETHASBBOX(geoms[0]->type, 0);
|
|
360
|
+
TYPE_SETHASBBOX(geoms[1]->type, 0);
|
|
361
|
+
|
|
362
|
+
/* Find appropriate geom type */
|
|
363
|
+
if ( TYPE_GETTYPE(what->type) == LINETYPE ) newtype = MULTILINETYPE;
|
|
364
|
+
else newtype = COLLECTIONTYPE;
|
|
365
|
+
|
|
366
|
+
col = lwcollection_construct(newtype,
|
|
367
|
+
to->SRID, NULL,
|
|
368
|
+
2, geoms);
|
|
369
|
+
|
|
370
|
+
return (LWGEOM *)col;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
void
|
|
374
|
+
lwline_release(LWLINE *lwline)
|
|
375
|
+
{
|
|
376
|
+
lwgeom_release(lwline_as_lwgeom(lwline));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
void
|
|
380
|
+
lwline_reverse(LWLINE *line)
|
|
381
|
+
{
|
|
382
|
+
ptarray_reverse(line->points);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
LWLINE *
|
|
386
|
+
lwline_segmentize2d(LWLINE *line, double dist)
|
|
387
|
+
{
|
|
388
|
+
return lwline_construct(line->SRID, NULL,
|
|
389
|
+
ptarray_segmentize2d(line->points, dist));
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* check coordinate equality */
|
|
393
|
+
char
|
|
394
|
+
lwline_same(const LWLINE *l1, const LWLINE *l2)
|
|
395
|
+
{
|
|
396
|
+
return ptarray_same(l1->points, l2->points);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/*
|
|
400
|
+
* Construct a LWLINE from an array of LWPOINTs
|
|
401
|
+
* LWLINE dimensions are large enough to host all input dimensions.
|
|
402
|
+
*/
|
|
403
|
+
LWLINE *
|
|
404
|
+
lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points)
|
|
405
|
+
{
|
|
406
|
+
int zmflag=0;
|
|
407
|
+
unsigned int i;
|
|
408
|
+
POINTARRAY *pa;
|
|
409
|
+
uchar *newpoints, *ptr;
|
|
410
|
+
size_t ptsize, size;
|
|
411
|
+
|
|
412
|
+
/*
|
|
413
|
+
* Find output dimensions, check integrity
|
|
414
|
+
*/
|
|
415
|
+
for (i=0; i<npoints; i++)
|
|
416
|
+
{
|
|
417
|
+
if ( TYPE_GETTYPE(points[i]->type) != POINTTYPE )
|
|
418
|
+
{
|
|
419
|
+
lwerror("lwline_from_lwpointarray: invalid input type: %s",
|
|
420
|
+
lwgeom_typename(TYPE_GETTYPE(points[i]->type)));
|
|
421
|
+
return NULL;
|
|
422
|
+
}
|
|
423
|
+
if ( TYPE_HASZ(points[i]->type) ) zmflag |= 2;
|
|
424
|
+
if ( TYPE_HASM(points[i]->type) ) zmflag |= 1;
|
|
425
|
+
if ( zmflag == 3 ) break;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if ( zmflag == 0 ) ptsize=2*sizeof(double);
|
|
429
|
+
else if ( zmflag == 3 ) ptsize=4*sizeof(double);
|
|
430
|
+
else ptsize=3*sizeof(double);
|
|
431
|
+
|
|
432
|
+
/*
|
|
433
|
+
* Allocate output points array
|
|
434
|
+
*/
|
|
435
|
+
size = ptsize*npoints;
|
|
436
|
+
newpoints = lwalloc(size);
|
|
437
|
+
memset(newpoints, 0, size);
|
|
438
|
+
|
|
439
|
+
ptr=newpoints;
|
|
440
|
+
for (i=0; i<npoints; i++)
|
|
441
|
+
{
|
|
442
|
+
size=pointArray_ptsize(points[i]->point);
|
|
443
|
+
memcpy(ptr, getPoint_internal(points[i]->point, 0), size);
|
|
444
|
+
ptr+=ptsize;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, npoints);
|
|
448
|
+
|
|
449
|
+
return lwline_construct(SRID, NULL, pa);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/*
|
|
453
|
+
* Construct a LWLINE from a LWMPOINT
|
|
454
|
+
*/
|
|
455
|
+
LWLINE *
|
|
456
|
+
lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint)
|
|
457
|
+
{
|
|
458
|
+
unsigned int i;
|
|
459
|
+
POINTARRAY *pa;
|
|
460
|
+
char zmflag = TYPE_GETZM(mpoint->type);
|
|
461
|
+
size_t ptsize, size;
|
|
462
|
+
uchar *newpoints, *ptr;
|
|
463
|
+
|
|
464
|
+
if ( zmflag == 0 ) ptsize=2*sizeof(double);
|
|
465
|
+
else if ( zmflag == 3 ) ptsize=4*sizeof(double);
|
|
466
|
+
else ptsize=3*sizeof(double);
|
|
467
|
+
|
|
468
|
+
/* Allocate space for output points */
|
|
469
|
+
size = ptsize*mpoint->ngeoms;
|
|
470
|
+
newpoints = lwalloc(size);
|
|
471
|
+
memset(newpoints, 0, size);
|
|
472
|
+
|
|
473
|
+
ptr=newpoints;
|
|
474
|
+
for (i=0; i<mpoint->ngeoms; i++)
|
|
475
|
+
{
|
|
476
|
+
memcpy(ptr,
|
|
477
|
+
getPoint_internal(mpoint->geoms[i]->point, 0),
|
|
478
|
+
ptsize);
|
|
479
|
+
ptr+=ptsize;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
pa = pointArray_construct(newpoints, zmflag&2, zmflag&1,
|
|
483
|
+
mpoint->ngeoms);
|
|
484
|
+
|
|
485
|
+
LWDEBUGF(3, "lwline_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag);
|
|
486
|
+
|
|
487
|
+
return lwline_construct(SRID, NULL, pa);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
LWLINE *
|
|
491
|
+
lwline_addpoint(LWLINE *line, LWPOINT *point, unsigned int where)
|
|
492
|
+
{
|
|
493
|
+
POINTARRAY *newpa;
|
|
494
|
+
LWLINE *ret;
|
|
495
|
+
|
|
496
|
+
newpa = ptarray_addPoint(line->points,
|
|
497
|
+
getPoint_internal(point->point, 0),
|
|
498
|
+
TYPE_NDIMS(point->type), where);
|
|
499
|
+
|
|
500
|
+
ret = lwline_construct(line->SRID, NULL, newpa);
|
|
501
|
+
|
|
502
|
+
return ret;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
LWLINE *
|
|
506
|
+
lwline_removepoint(LWLINE *line, unsigned int index)
|
|
507
|
+
{
|
|
508
|
+
POINTARRAY *newpa;
|
|
509
|
+
LWLINE *ret;
|
|
510
|
+
|
|
511
|
+
newpa = ptarray_removePoint(line->points, index);
|
|
512
|
+
|
|
513
|
+
ret = lwline_construct(line->SRID, NULL, newpa);
|
|
514
|
+
|
|
515
|
+
return ret;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/*
|
|
519
|
+
* Note: input will be changed, make sure you have permissions for this.
|
|
520
|
+
*/
|
|
521
|
+
void
|
|
522
|
+
lwline_setPoint4d(LWLINE *line, unsigned int index, POINT4D *newpoint)
|
|
523
|
+
{
|
|
524
|
+
setPoint4d(line->points, index, newpoint);
|
|
525
|
+
}
|