geo_coder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data/Gemfile +12 -0
  2. data/Gemfile.lock +32 -0
  3. data/History.txt +6 -0
  4. data/Makefile +13 -0
  5. data/Manifest.txt +18 -0
  6. data/README.rdoc +197 -0
  7. data/Rakefile +53 -0
  8. data/TODO.txt +8 -0
  9. data/VERSION +1 -0
  10. data/bin/build_indexes +8 -0
  11. data/bin/rebuild_cluster +22 -0
  12. data/bin/rebuild_metaphones +23 -0
  13. data/bin/tiger_import +59 -0
  14. data/demos/demo/app/ext/geocodewrap.rb +84 -0
  15. data/demos/demo/app/views/index.builder +13 -0
  16. data/demos/demo/app/views/index.erb +71 -0
  17. data/demos/demo/config.ru +12 -0
  18. data/demos/demo/config/bootstraps.rb +130 -0
  19. data/demos/demo/config/geoenvironment.rb +25 -0
  20. data/demos/demo/geocoder_helper.rb +12 -0
  21. data/demos/demo/geocom_geocode.rb +10 -0
  22. data/demos/demo/main.rb +3 -0
  23. data/demos/demo/rakefile.rb +17 -0
  24. data/demos/demo/tmp/restart.txt +0 -0
  25. data/demos/simpledemo/views/index.builder +13 -0
  26. data/demos/simpledemo/views/index.erb +69 -0
  27. data/demos/simpledemo/ws.rb +83 -0
  28. data/doc/Makefile +7 -0
  29. data/doc/html4css1.css +279 -0
  30. data/doc/lookup.rst +193 -0
  31. data/doc/parsing.rst +125 -0
  32. data/doc/voidspace.css +147 -0
  33. data/geo_coder.gemspec +172 -0
  34. data/lib/geocoder/us.rb +21 -0
  35. data/lib/geocoder/us/address.rb +290 -0
  36. data/lib/geocoder/us/constants.rb +670 -0
  37. data/lib/geocoder/us/database.rb +745 -0
  38. data/lib/geocoder/us/import.rb +181 -0
  39. data/lib/geocoder/us/import/tiger.rb +13 -0
  40. data/lib/geocoder/us/numbers.rb +58 -0
  41. data/navteq/README +4 -0
  42. data/navteq/convert.sql +37 -0
  43. data/navteq/navteq_import +39 -0
  44. data/navteq/prepare.sql +92 -0
  45. data/sql/cluster.sql +16 -0
  46. data/sql/convert.sql +80 -0
  47. data/sql/create.sql +37 -0
  48. data/sql/index.sql +12 -0
  49. data/sql/place.csv +104944 -0
  50. data/sql/place.sql +104948 -0
  51. data/sql/setup.sql +78 -0
  52. data/src/Makefile +13 -0
  53. data/src/README +14 -0
  54. data/src/liblwgeom/Makefile +75 -0
  55. data/src/liblwgeom/box2d.c +54 -0
  56. data/src/liblwgeom/lex.yy.c +4799 -0
  57. data/src/liblwgeom/liblwgeom.h +1405 -0
  58. data/src/liblwgeom/lwalgorithm.c +946 -0
  59. data/src/liblwgeom/lwalgorithm.h +52 -0
  60. data/src/liblwgeom/lwcircstring.c +759 -0
  61. data/src/liblwgeom/lwcollection.c +541 -0
  62. data/src/liblwgeom/lwcompound.c +118 -0
  63. data/src/liblwgeom/lwcurvepoly.c +86 -0
  64. data/src/liblwgeom/lwgeom.c +886 -0
  65. data/src/liblwgeom/lwgeom_api.c +2201 -0
  66. data/src/liblwgeom/lwgparse.c +1219 -0
  67. data/src/liblwgeom/lwgunparse.c +1054 -0
  68. data/src/liblwgeom/lwline.c +525 -0
  69. data/src/liblwgeom/lwmcurve.c +125 -0
  70. data/src/liblwgeom/lwmline.c +137 -0
  71. data/src/liblwgeom/lwmpoint.c +138 -0
  72. data/src/liblwgeom/lwmpoly.c +141 -0
  73. data/src/liblwgeom/lwmsurface.c +129 -0
  74. data/src/liblwgeom/lwpoint.c +439 -0
  75. data/src/liblwgeom/lwpoly.c +579 -0
  76. data/src/liblwgeom/lwsegmentize.c +1047 -0
  77. data/src/liblwgeom/lwutil.c +369 -0
  78. data/src/liblwgeom/measures.c +861 -0
  79. data/src/liblwgeom/postgis_config.h +93 -0
  80. data/src/liblwgeom/ptarray.c +847 -0
  81. data/src/liblwgeom/vsprintf.c +179 -0
  82. data/src/liblwgeom/wktparse.h +126 -0
  83. data/src/liblwgeom/wktparse.lex +74 -0
  84. data/src/liblwgeom/wktparse.tab.c +2353 -0
  85. data/src/liblwgeom/wktparse.tab.h +145 -0
  86. data/src/liblwgeom/wktparse.y +385 -0
  87. data/src/libsqlite3_geocoder/Makefile +22 -0
  88. data/src/libsqlite3_geocoder/Makefile.nix +15 -0
  89. data/src/libsqlite3_geocoder/Makefile.redhat +15 -0
  90. data/src/libsqlite3_geocoder/extension.c +121 -0
  91. data/src/libsqlite3_geocoder/extension.h +13 -0
  92. data/src/libsqlite3_geocoder/levenshtein.c +42 -0
  93. data/src/libsqlite3_geocoder/metaphon.c +278 -0
  94. data/src/libsqlite3_geocoder/util.c +37 -0
  95. data/src/libsqlite3_geocoder/wkb_compress.c +54 -0
  96. data/src/metaphone/Makefile +7 -0
  97. data/src/metaphone/README +49 -0
  98. data/src/metaphone/extension.c +37 -0
  99. data/src/metaphone/metaphon.c +251 -0
  100. data/src/shp2sqlite/Makefile +37 -0
  101. data/src/shp2sqlite/Makefile.nix +36 -0
  102. data/src/shp2sqlite/Makefile.redhat +35 -0
  103. data/src/shp2sqlite/dbfopen.c +1595 -0
  104. data/src/shp2sqlite/getopt.c +695 -0
  105. data/src/shp2sqlite/getopt.h +127 -0
  106. data/src/shp2sqlite/shapefil.h +500 -0
  107. data/src/shp2sqlite/shp2sqlite.c +1974 -0
  108. data/src/shp2sqlite/shpopen.c +1894 -0
  109. data/tests/address.rb +236 -0
  110. data/tests/benchmark.rb +20 -0
  111. data/tests/constants.rb +57 -0
  112. data/tests/data/address-sample.csv +52 -0
  113. data/tests/data/db-test.csv +57 -0
  114. data/tests/data/locations.csv +4 -0
  115. data/tests/database.rb +137 -0
  116. data/tests/generate.rb +34 -0
  117. data/tests/numbers.rb +46 -0
  118. data/tests/run.rb +11 -0
  119. metadata +237 -0
@@ -0,0 +1,129 @@
1
+ /**********************************************************************
2
+ * $Id: lwmsurface.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
+ #include <stdio.h>
14
+ #include <stdlib.h>
15
+ #include <string.h>
16
+ #include "liblwgeom.h"
17
+
18
+
19
+ LWMSURFACE *
20
+ lwmsurface_deserialize(uchar *srl)
21
+ {
22
+ LWMSURFACE *result;
23
+ LWGEOM_INSPECTED *insp;
24
+ int stype;
25
+ int type = lwgeom_getType(srl[0]);
26
+ int i;
27
+
28
+ LWDEBUG(2, "lwmsurface_deserialize called");
29
+
30
+ if(type != MULTISURFACETYPE)
31
+ {
32
+ lwerror("lwmsurface_deserialize called on a non-multisurface: %d", type);
33
+ return NULL;
34
+ }
35
+
36
+ insp = lwgeom_inspect(srl);
37
+
38
+ result = lwalloc(sizeof(LWMSURFACE));
39
+ result->type = insp->type;
40
+ result->SRID = insp->SRID;
41
+ result->ngeoms = insp->ngeometries;
42
+ result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
43
+
44
+ if(lwgeom_hasBBOX(srl[0]))
45
+ {
46
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
47
+ memcpy(result->bbox, srl + 1, sizeof(BOX2DFLOAT4));
48
+ }
49
+ else result->bbox = NULL;
50
+
51
+ for(i = 0; i < insp->ngeometries; i++)
52
+ {
53
+ stype = lwgeom_getType(insp->sub_geoms[i][0]);
54
+ if(stype == POLYGONTYPE)
55
+ {
56
+ result->geoms[i] = (LWGEOM *)lwpoly_deserialize(insp->sub_geoms[i]);
57
+ }
58
+ else if(stype == CURVEPOLYTYPE)
59
+ {
60
+ result->geoms[i] = (LWGEOM *)lwcurvepoly_deserialize(insp->sub_geoms[i]);
61
+ }
62
+ else
63
+ {
64
+ lwerror("Only Polygons and Curved Polygons are supported in a MultiSurface.");
65
+ lwfree(result);
66
+ lwfree(insp);
67
+ return NULL;
68
+ }
69
+
70
+ if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type))
71
+ {
72
+ lwerror("Mixed dimensions (multisurface: %d, surface %d:%d",
73
+ TYPE_NDIMS(result->type), i,
74
+ TYPE_NDIMS(result->geoms[i]->type));
75
+ lwfree(result);
76
+ lwfree(insp);
77
+ return NULL;
78
+ }
79
+ }
80
+ return result;
81
+ }
82
+
83
+ /*
84
+ * Add 'what' to this multisurface at position 'where'
85
+ * where=0 == prepend
86
+ * where=-1 == append
87
+ * Returns a MULTISURFACE or a COLLECTION
88
+ */
89
+ LWGEOM *
90
+ lwmsurface_add(const LWMSURFACE *to, uint32 where, const LWGEOM *what)
91
+ {
92
+ LWCOLLECTION *col;
93
+ LWGEOM **geoms;
94
+ int newtype;
95
+ uint32 i;
96
+
97
+ if(where == -1) where = to->ngeoms;
98
+ else if(where < -1 || where > to->ngeoms)
99
+ {
100
+ lwerror("lwmsurface_add: add position out of range %d..%d",
101
+ -1, to->ngeoms);
102
+ return NULL;
103
+ }
104
+
105
+ /* dimensions compatibility are checked by caller */
106
+
107
+ /* Construct geoms array */
108
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
109
+ for(i = 0; i < where; i++)
110
+ {
111
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
112
+ }
113
+ geoms[where] = lwgeom_clone(what);
114
+ for(i = where; i < to->ngeoms; i++)
115
+ {
116
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
117
+ }
118
+
119
+ if(TYPE_GETTYPE(what->type) == POLYGONTYPE
120
+ || TYPE_GETTYPE(what->type) == CURVEPOLYTYPE)
121
+ newtype = MULTISURFACETYPE;
122
+ else newtype = COLLECTIONTYPE;
123
+
124
+ col = lwcollection_construct(newtype,
125
+ to->SRID, NULL, to->ngeoms + 1, geoms);
126
+
127
+ return (LWGEOM *)col;
128
+ }
129
+
@@ -0,0 +1,439 @@
1
+ /**********************************************************************
2
+ * $Id: lwpoint.c 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
+ *
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
+ #include <stdio.h>
14
+ #include <stdlib.h>
15
+ #include <string.h>
16
+ #include "liblwgeom.h"
17
+
18
+
19
+ /*
20
+ * Convert this point into its serialize form
21
+ * result's first char will be the 8bit type. See serialized form doc
22
+ */
23
+ uchar *
24
+ lwpoint_serialize(LWPOINT *point)
25
+ {
26
+ size_t size, retsize;
27
+ uchar *result;
28
+
29
+ size = lwpoint_serialize_size(point);
30
+ result = lwalloc(size);
31
+ lwpoint_serialize_buf(point, result, &retsize);
32
+
33
+ if ( retsize != size )
34
+ {
35
+ lwerror("lwpoint_serialize_size returned %d, ..serialize_buf returned %d", size, retsize);
36
+ }
37
+
38
+ return result;
39
+ }
40
+
41
+ /*
42
+ * Convert this point into its serialize form writing it into
43
+ * the given buffer, and returning number of bytes written into
44
+ * the given int pointer.
45
+ * result's first char will be the 8bit type. See serialized form doc
46
+ */
47
+ void
48
+ lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *retsize)
49
+ {
50
+ int size=1;
51
+ char hasSRID;
52
+ uchar *loc;
53
+ int ptsize = pointArray_ptsize(point->point);
54
+
55
+ if ( TYPE_GETZM(point->type) != TYPE_GETZM(point->point->dims) )
56
+ lwerror("Dimensions mismatch in lwpoint");
57
+
58
+ LWDEBUGF(2, "lwpoint_serialize_buf(%p, %p) called", point, buf);
59
+ /*printLWPOINT(point); */
60
+
61
+ hasSRID = (point->SRID != -1);
62
+
63
+ if (hasSRID) size +=4; /*4 byte SRID */
64
+ if (point->bbox) size += sizeof(BOX2DFLOAT4); /* bvol */
65
+
66
+ size += sizeof(double)*TYPE_NDIMS(point->type);
67
+
68
+ buf[0] = (uchar) lwgeom_makeType_full(
69
+ TYPE_HASZ(point->type), TYPE_HASM(point->type),
70
+ hasSRID, POINTTYPE, point->bbox?1:0);
71
+ loc = buf+1;
72
+
73
+ if (point->bbox)
74
+ {
75
+ memcpy(loc, point->bbox, sizeof(BOX2DFLOAT4));
76
+ loc += sizeof(BOX2DFLOAT4);
77
+ }
78
+
79
+ if (hasSRID)
80
+ {
81
+ memcpy(loc, &point->SRID, sizeof(int32));
82
+ loc += 4;
83
+ }
84
+
85
+ /* copy in points */
86
+ memcpy(loc, getPoint_internal(point->point, 0), ptsize);
87
+
88
+ if (retsize) *retsize = size;
89
+ }
90
+
91
+ /*
92
+ * Find bounding box (standard one)
93
+ * zmin=zmax=NO_Z_VALUE if 2d
94
+ */
95
+ BOX3D *
96
+ lwpoint_compute_box3d(LWPOINT *point)
97
+ {
98
+ LWDEBUGF(2, "lwpoint_compute_box3d called with point %p", point);
99
+
100
+ if (point == NULL)
101
+ {
102
+ LWDEBUG(3, "lwpoint_compute_box3d returning NULL");
103
+
104
+ return NULL;
105
+ }
106
+
107
+ LWDEBUG(3, "lwpoint_compute_box3d returning ptarray_compute_box3d return");
108
+
109
+ return ptarray_compute_box3d(point->point);
110
+ }
111
+
112
+ /*
113
+ * Convenience functions to hide the POINTARRAY
114
+ * TODO: obsolete this
115
+ */
116
+ int
117
+ lwpoint_getPoint2d_p(const LWPOINT *point, POINT2D *out)
118
+ {
119
+ return getPoint2d_p(point->point, 0, out);
120
+ }
121
+
122
+ /* convenience functions to hide the POINTARRAY */
123
+ int
124
+ lwpoint_getPoint3dz_p(const LWPOINT *point, POINT3DZ *out)
125
+ {
126
+ return getPoint3dz_p(point->point,0,out);
127
+ }
128
+ int
129
+ lwpoint_getPoint3dm_p(const LWPOINT *point, POINT3DM *out)
130
+ {
131
+ return getPoint3dm_p(point->point,0,out);
132
+ }
133
+ int
134
+ lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
135
+ {
136
+ return getPoint4d_p(point->point,0,out);
137
+ }
138
+
139
+ /* find length of this deserialized point */
140
+ size_t
141
+ lwpoint_serialize_size(LWPOINT *point)
142
+ {
143
+ size_t size = 1; /* type */
144
+
145
+ LWDEBUG(2, "lwpoint_serialize_size called");
146
+
147
+ if ( point->SRID != -1 ) size += 4; /* SRID */
148
+ if ( point->bbox ) size += sizeof(BOX2DFLOAT4);
149
+
150
+ size += TYPE_NDIMS(point->type) * sizeof(double); /* point */
151
+
152
+ LWDEBUGF(3, "lwpoint_serialize_size returning %d", size);
153
+
154
+ return size;
155
+ }
156
+
157
+ /*
158
+ * Construct a new point. point will not be copied
159
+ * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
160
+ */
161
+ LWPOINT *
162
+ lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *point)
163
+ {
164
+ LWPOINT *result ;
165
+
166
+ if (point == NULL)
167
+ return NULL; /* error */
168
+
169
+ result = lwalloc(sizeof(LWPOINT));
170
+ result->type = lwgeom_makeType_full(TYPE_HASZ(point->dims), TYPE_HASM(point->dims), (SRID!=-1), POINTTYPE, 0);
171
+ result->SRID = SRID;
172
+ result->point = point;
173
+ result->bbox = bbox;
174
+
175
+ return result;
176
+ }
177
+
178
+ LWPOINT *
179
+ make_lwpoint2d(int SRID, double x, double y)
180
+ {
181
+ POINT2D p;
182
+ POINTARRAY *pa = ptarray_construct(0, 0, 1);
183
+
184
+ p.x = x;
185
+ p.y = y;
186
+
187
+ memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT2D));
188
+
189
+ return lwpoint_construct(SRID, NULL, pa);
190
+ }
191
+
192
+ LWPOINT *
193
+ make_lwpoint3dz(int SRID, double x, double y, double z)
194
+ {
195
+ POINT3DZ p;
196
+ POINTARRAY *pa = ptarray_construct(1, 0, 1);
197
+
198
+ p.x = x;
199
+ p.y = y;
200
+ p.z = z;
201
+
202
+ memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DZ));
203
+
204
+ return lwpoint_construct(SRID, NULL, pa);
205
+ }
206
+
207
+ LWPOINT *
208
+ make_lwpoint3dm(int SRID, double x, double y, double m)
209
+ {
210
+ POINTARRAY *pa = ptarray_construct(0, 1, 1);
211
+ POINT3DM p;
212
+
213
+ p.x = x;
214
+ p.y = y;
215
+ p.m = m;
216
+
217
+ memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DM));
218
+
219
+ return lwpoint_construct(SRID, NULL, pa);
220
+ }
221
+
222
+ LWPOINT *
223
+ make_lwpoint4d(int SRID, double x, double y, double z, double m)
224
+ {
225
+ POINTARRAY *pa = ptarray_construct(1, 1, 1);
226
+ POINT4D p;
227
+
228
+ p.x = x;
229
+ p.y = y;
230
+ p.z = z;
231
+ p.m = m;
232
+
233
+ memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT4D));
234
+
235
+ return lwpoint_construct(SRID, NULL, pa);
236
+ }
237
+
238
+ /*
239
+ * Given the LWPOINT serialized form (or a pointer into a muli* one)
240
+ * construct a proper LWPOINT.
241
+ * serialized_form should point to the 8bit type format (with type = 1)
242
+ * See serialized form doc
243
+ */
244
+ LWPOINT *
245
+ lwpoint_deserialize(uchar *serialized_form)
246
+ {
247
+ uchar type;
248
+ int geom_type;
249
+ LWPOINT *result;
250
+ uchar *loc = NULL;
251
+ POINTARRAY *pa;
252
+
253
+ LWDEBUG(2, "lwpoint_deserialize called");
254
+
255
+ result = (LWPOINT*) lwalloc(sizeof(LWPOINT)) ;
256
+
257
+ type = serialized_form[0];
258
+ geom_type = lwgeom_getType(type);
259
+
260
+ if ( geom_type != POINTTYPE)
261
+ {
262
+ lwerror("lwpoint_deserialize: attempt to deserialize a point which is really a %s", lwgeom_typename(geom_type));
263
+ return NULL;
264
+ }
265
+ result->type = type;
266
+
267
+ loc = serialized_form+1;
268
+
269
+ if (lwgeom_hasBBOX(type))
270
+ {
271
+ LWDEBUG(3, "lwpoint_deserialize: input has bbox");
272
+
273
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
274
+ memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
275
+ loc += sizeof(BOX2DFLOAT4);
276
+ }
277
+ else
278
+ {
279
+ result->bbox = NULL;
280
+ }
281
+
282
+ if ( lwgeom_hasSRID(type))
283
+ {
284
+ LWDEBUG(3, "lwpoint_deserialize: input has SRID");
285
+
286
+ result->SRID = lw_get_int32(loc);
287
+ loc += 4; /* type + SRID */
288
+ }
289
+ else
290
+ {
291
+ result->SRID = -1;
292
+ }
293
+
294
+ /* we've read the type (1 byte) and SRID (4 bytes, if present) */
295
+
296
+ pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), 1);
297
+
298
+ result->point = pa;
299
+
300
+ return result;
301
+ }
302
+
303
+ void lwpoint_free(LWPOINT *pt)
304
+ {
305
+ if(pt->point)
306
+ ptarray_free(pt->point);
307
+ lwfree(pt);
308
+ }
309
+
310
+ void printLWPOINT(LWPOINT *point)
311
+ {
312
+ lwnotice("LWPOINT {");
313
+ lwnotice(" ndims = %i", (int)TYPE_NDIMS(point->type));
314
+ lwnotice(" BBOX = %i", TYPE_HASBBOX(point->type) ? 1 : 0 );
315
+ lwnotice(" SRID = %i", (int)point->SRID);
316
+ printPA(point->point);
317
+ lwnotice("}");
318
+ }
319
+
320
+ int
321
+ lwpoint_compute_box2d_p(LWPOINT *point, BOX2DFLOAT4 *box)
322
+ {
323
+ return ptarray_compute_box2d_p(point->point, box);
324
+ }
325
+
326
+ /* Clone LWPOINT object. POINTARRAY is not copied. */
327
+ LWPOINT *
328
+ lwpoint_clone(const LWPOINT *g)
329
+ {
330
+ LWPOINT *ret = lwalloc(sizeof(LWPOINT));
331
+
332
+ LWDEBUG(2, "lwpoint_clone called");
333
+
334
+ memcpy(ret, g, sizeof(LWPOINT));
335
+ if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
336
+ return ret;
337
+ }
338
+
339
+ /*
340
+ * Add 'what' to this point at position 'where'.
341
+ * where=0 == prepend
342
+ * where=-1 == append
343
+ * Returns a MULTIPOINT or a GEOMETRYCOLLECTION
344
+ */
345
+ LWGEOM *
346
+ lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what)
347
+ {
348
+ LWCOLLECTION *col;
349
+ LWGEOM **geoms;
350
+ int newtype;
351
+
352
+ if ( where != -1 && where != 0 )
353
+ {
354
+ lwerror("lwpoint_add only supports 0 or -1 as second argument, got %d", where);
355
+ return NULL;
356
+ }
357
+
358
+ /* dimensions compatibility are checked by caller */
359
+
360
+
361
+ /* Construct geoms array */
362
+ geoms = lwalloc(sizeof(LWGEOM *)*2);
363
+ if ( where == -1 ) /* append */
364
+ {
365
+ geoms[0] = lwgeom_clone((LWGEOM *)to);
366
+ geoms[1] = lwgeom_clone(what);
367
+ }
368
+ else /* prepend */
369
+ {
370
+ geoms[0] = lwgeom_clone(what);
371
+ geoms[1] = lwgeom_clone((LWGEOM *)to);
372
+ }
373
+ /* reset SRID and wantbbox flag from component types */
374
+ lwgeom_dropSRID(geoms[0]);
375
+ lwgeom_drop_bbox(geoms[0]);
376
+ lwgeom_dropSRID(geoms[1]);
377
+ lwgeom_drop_bbox(geoms[1]);
378
+
379
+ /* Find appropriate geom type */
380
+ if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE;
381
+ else newtype = COLLECTIONTYPE;
382
+
383
+ col = lwcollection_construct(newtype,
384
+ to->SRID, NULL,
385
+ 2, geoms);
386
+
387
+ return (LWGEOM *)col;
388
+ }
389
+
390
+ /* Find length of this serialized point */
391
+ size_t
392
+ lwgeom_size_point(const uchar *serialized_point)
393
+ {
394
+ uint32 result = 1;
395
+ uchar type;
396
+ const uchar *loc;
397
+
398
+ type = serialized_point[0];
399
+
400
+ if ( lwgeom_getType(type) != POINTTYPE) return 0;
401
+
402
+ LWDEBUGF(2, "lwgeom_size_point called (%d)", result);
403
+
404
+ loc = serialized_point+1;
405
+
406
+ if (lwgeom_hasBBOX(type))
407
+ {
408
+ loc += sizeof(BOX2DFLOAT4);
409
+ result +=sizeof(BOX2DFLOAT4);
410
+
411
+ LWDEBUGF(3, "lwgeom_size_point: has bbox (%d)", result);
412
+ }
413
+
414
+ if ( lwgeom_hasSRID(type))
415
+ {
416
+ LWDEBUGF(3, "lwgeom_size_point: has srid (%d)", result);
417
+
418
+ loc +=4; /* type + SRID */
419
+ result +=4;
420
+ }
421
+
422
+ result += lwgeom_ndims(type)*sizeof(double);
423
+
424
+ return result;
425
+ }
426
+
427
+ void
428
+ lwpoint_release(LWPOINT *lwpoint)
429
+ {
430
+ lwgeom_release(lwpoint_as_lwgeom(lwpoint));
431
+ }
432
+
433
+
434
+ /* check coordinate equality */
435
+ char
436
+ lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
437
+ {
438
+ return ptarray_same(p1->point, p2->point);
439
+ }