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,541 @@
1
+ /**********************************************************************
2
+ * $Id: lwcollection.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
+ #define CHECK_LWGEOM_ZM 1
20
+
21
+ void
22
+ lwcollection_release(LWCOLLECTION *lwcollection)
23
+ {
24
+ lwgeom_release(lwcollection_as_lwgeom(lwcollection));
25
+ }
26
+
27
+
28
+ LWCOLLECTION *
29
+ lwcollection_construct(unsigned int type, int SRID, BOX2DFLOAT4 *bbox,
30
+ unsigned int ngeoms, LWGEOM **geoms)
31
+ {
32
+ LWCOLLECTION *ret;
33
+ int hasz, hasm;
34
+ #ifdef CHECK_LWGEOM_ZM
35
+ char zm;
36
+ unsigned int i;
37
+ #endif
38
+
39
+ LWDEBUGF(2, "lwcollection_construct called with %d, %d, %p, %d, %p.", type, SRID, bbox, ngeoms, geoms);
40
+
41
+ hasz = 0;
42
+ hasm = 0;
43
+ if ( ngeoms > 0 )
44
+ {
45
+ hasz = TYPE_HASZ(geoms[0]->type);
46
+ hasm = TYPE_HASM(geoms[0]->type);
47
+ #ifdef CHECK_LWGEOM_ZM
48
+ zm = TYPE_GETZM(geoms[0]->type);
49
+
50
+ LWDEBUGF(3, "lwcollection_construct type[0]=%d", geoms[0]->type);
51
+
52
+ for (i=1; i<ngeoms; i++)
53
+ {
54
+ LWDEBUGF(3, "lwcollection_construct type=[%d]=%d", i, geoms[i]->type);
55
+
56
+ if ( zm != TYPE_GETZM(geoms[i]->type) )
57
+ lwerror("lwcollection_construct: mixed dimension geometries: %d/%d", zm, TYPE_GETZM(geoms[i]->type));
58
+ }
59
+ #endif
60
+ }
61
+
62
+
63
+ ret = lwalloc(sizeof(LWCOLLECTION));
64
+ ret->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1),
65
+ type, 0);
66
+ ret->SRID = SRID;
67
+ ret->ngeoms = ngeoms;
68
+ ret->geoms = geoms;
69
+ ret->bbox = bbox;
70
+
71
+ return ret;
72
+ }
73
+
74
+ LWCOLLECTION *
75
+ lwcollection_construct_empty(int SRID, char hasz, char hasm)
76
+ {
77
+ LWCOLLECTION *ret;
78
+
79
+ ret = lwalloc(sizeof(LWCOLLECTION));
80
+ ret->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1),
81
+ COLLECTIONTYPE, 0);
82
+ ret->SRID = SRID;
83
+ ret->ngeoms = 0;
84
+ ret->geoms = NULL;
85
+ ret->bbox = NULL;
86
+
87
+ return ret;
88
+ }
89
+
90
+
91
+ LWCOLLECTION *
92
+ lwcollection_deserialize(uchar *srl)
93
+ {
94
+ LWCOLLECTION *result;
95
+ LWGEOM_INSPECTED *insp;
96
+ char typefl = srl[0];
97
+ int type = lwgeom_getType(typefl);
98
+ int i;
99
+
100
+ if ( type != COLLECTIONTYPE )
101
+ {
102
+ lwerror("lwcollection_deserialize called on NON geometrycollection: %d", type);
103
+ return NULL;
104
+ }
105
+
106
+ insp = lwgeom_inspect(srl);
107
+
108
+ result = lwalloc(sizeof(LWCOLLECTION));
109
+ result->type = typefl;
110
+ result->SRID = insp->SRID;
111
+ result->ngeoms = insp->ngeometries;
112
+
113
+ if (lwgeom_hasBBOX(srl[0]))
114
+ {
115
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
116
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
117
+ }
118
+ else result->bbox = NULL;
119
+
120
+
121
+ if ( insp->ngeometries )
122
+ {
123
+ result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries);
124
+ for (i=0; i<insp->ngeometries; i++)
125
+ {
126
+ result->geoms[i] =
127
+ lwgeom_deserialize(insp->sub_geoms[i]);
128
+ }
129
+ }
130
+
131
+ return result;
132
+ }
133
+
134
+ LWGEOM *
135
+ lwcollection_getsubgeom(LWCOLLECTION *col, int gnum)
136
+ {
137
+ return (LWGEOM *)col->geoms[gnum];
138
+ }
139
+
140
+ /* find serialized size of this collection */
141
+ size_t
142
+ lwcollection_serialize_size(LWCOLLECTION *col)
143
+ {
144
+ size_t size = 5; /* type + nsubgeoms */
145
+ int i;
146
+
147
+ if ( col->SRID != -1 ) size += 4; /* SRID */
148
+ if ( col->bbox ) size += sizeof(BOX2DFLOAT4);
149
+
150
+ LWDEBUGF(2, "lwcollection_serialize_size[%p]: start size: %d", col, size);
151
+
152
+
153
+ for (i=0; i<col->ngeoms; i++)
154
+ {
155
+ size += lwgeom_serialize_size(col->geoms[i]);
156
+
157
+ LWDEBUGF(3, "lwcollection_serialize_size[%p]: with geom%d: %d", col, i, size);
158
+ }
159
+
160
+ LWDEBUGF(3, "lwcollection_serialize_size[%p]: returning %d", col, size);
161
+
162
+ return size;
163
+ }
164
+
165
+ /*
166
+ * convert this collectoin into its serialize form writing it into
167
+ * the given buffer, and returning number of bytes written into
168
+ * the given int pointer.
169
+ */
170
+ void
171
+ lwcollection_serialize_buf(LWCOLLECTION *coll, uchar *buf, size_t *retsize)
172
+ {
173
+ size_t size=1; /* type */
174
+ size_t subsize=0;
175
+ char hasSRID;
176
+ uchar *loc;
177
+ int i;
178
+
179
+ LWDEBUGF(2, "lwcollection_serialize_buf called (%s with %d elems)",
180
+ lwgeom_typename(TYPE_GETTYPE(coll->type)), coll->ngeoms);
181
+
182
+ hasSRID = (coll->SRID != -1);
183
+
184
+ buf[0] = lwgeom_makeType_full(
185
+ TYPE_HASZ(coll->type), TYPE_HASM(coll->type),
186
+ hasSRID, TYPE_GETTYPE(coll->type), coll->bbox ? 1 : 0);
187
+ loc = buf+1;
188
+
189
+ /* Add BBOX if requested */
190
+ if ( coll->bbox )
191
+ {
192
+ memcpy(loc, coll->bbox, sizeof(BOX2DFLOAT4));
193
+ size += sizeof(BOX2DFLOAT4);
194
+ loc += sizeof(BOX2DFLOAT4);
195
+ }
196
+
197
+ /* Add SRID if requested */
198
+ if (hasSRID)
199
+ {
200
+ memcpy(loc, &coll->SRID, 4);
201
+ size += 4;
202
+ loc += 4;
203
+ }
204
+
205
+ /* Write number of subgeoms */
206
+ memcpy(loc, &coll->ngeoms, 4);
207
+ size += 4;
208
+ loc += 4;
209
+
210
+ /* Serialize subgeoms */
211
+ for (i=0; i<coll->ngeoms; i++)
212
+ {
213
+ lwgeom_serialize_buf(coll->geoms[i], loc, &subsize);
214
+ size += subsize;
215
+ loc += subsize;
216
+ }
217
+
218
+ if (retsize) *retsize = size;
219
+
220
+ LWDEBUG(3, "lwcollection_serialize_buf returning");
221
+ }
222
+
223
+ int
224
+ lwcollection_compute_box2d_p(LWCOLLECTION *col, BOX2DFLOAT4 *box)
225
+ {
226
+ BOX2DFLOAT4 boxbuf;
227
+ uint32 i;
228
+
229
+ if ( ! col->ngeoms ) return 0;
230
+ if ( ! lwgeom_compute_box2d_p(col->geoms[0], box) ) return 0;
231
+ for (i=1; i<col->ngeoms; i++)
232
+ {
233
+ if ( ! lwgeom_compute_box2d_p(col->geoms[i], &boxbuf) )
234
+ return 0;
235
+ if ( ! box2d_union_p(box, &boxbuf, box) ) return 0;
236
+ }
237
+ return 1;
238
+ }
239
+
240
+ /*
241
+ * Clone LWCOLLECTION object. POINTARRAY are not copied.
242
+ * Bbox is cloned if present in input.
243
+ */
244
+ LWCOLLECTION *
245
+ lwcollection_clone(const LWCOLLECTION *g)
246
+ {
247
+ uint32 i;
248
+ LWCOLLECTION *ret = lwalloc(sizeof(LWCOLLECTION));
249
+ memcpy(ret, g, sizeof(LWCOLLECTION));
250
+ if ( g->ngeoms > 0 )
251
+ {
252
+ ret->geoms = lwalloc(sizeof(LWGEOM *)*g->ngeoms);
253
+ for (i=0; i<g->ngeoms; i++)
254
+ {
255
+ ret->geoms[i] = lwgeom_clone(g->geoms[i]);
256
+ }
257
+ if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
258
+ }
259
+ else
260
+ {
261
+ ret->bbox = NULL; /* empty collection */
262
+ ret->geoms = NULL;
263
+ }
264
+ return ret;
265
+ }
266
+
267
+ /*
268
+ * Add 'what' to this collection at position 'where'.
269
+ * where=0 == prepend
270
+ * where=-1 == append
271
+ * Returns a GEOMETRYCOLLECTION
272
+ */
273
+ LWGEOM *
274
+ lwcollection_add(const LWCOLLECTION *to, uint32 where, const LWGEOM *what)
275
+ {
276
+ LWCOLLECTION *col;
277
+ LWGEOM **geoms;
278
+ uint32 i;
279
+
280
+ if ( where == -1 ) where = to->ngeoms;
281
+ else if ( where < -1 || where > to->ngeoms )
282
+ {
283
+ lwerror("lwcollection_add: add position out of range %d..%d",
284
+ -1, to->ngeoms);
285
+ return NULL;
286
+ }
287
+
288
+ /* dimensions compatibility are checked by caller */
289
+
290
+ /* Construct geoms array */
291
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
292
+ for (i=0; i<where; i++)
293
+ {
294
+ geoms[i] = lwgeom_clone(to->geoms[i]);
295
+ lwgeom_dropSRID(geoms[i]);
296
+ lwgeom_drop_bbox(geoms[i]);
297
+ }
298
+ geoms[where] = lwgeom_clone(what);
299
+ lwgeom_dropSRID(geoms[where]);
300
+ lwgeom_drop_bbox(geoms[where]);
301
+ for (i=where; i<to->ngeoms; i++)
302
+ {
303
+ geoms[i+1] = lwgeom_clone(to->geoms[i]);
304
+ lwgeom_dropSRID(geoms[i+1]);
305
+ lwgeom_drop_bbox(geoms[i+1]);
306
+ }
307
+
308
+ col = lwcollection_construct(COLLECTIONTYPE,
309
+ to->SRID, NULL,
310
+ to->ngeoms+1, geoms);
311
+
312
+ return (LWGEOM *)col;
313
+
314
+ }
315
+
316
+ LWCOLLECTION *
317
+ lwcollection_segmentize2d(LWCOLLECTION *col, double dist)
318
+ {
319
+ unsigned int i;
320
+ LWGEOM **newgeoms;
321
+
322
+ if ( ! col->ngeoms ) return col;
323
+
324
+ newgeoms = lwalloc(sizeof(LWGEOM *)*col->ngeoms);
325
+ for (i=0; i<col->ngeoms; i++)
326
+ newgeoms[i] = lwgeom_segmentize2d(col->geoms[i], dist);
327
+
328
+ return lwcollection_construct(col->type, col->SRID, NULL,
329
+ col->ngeoms, newgeoms);
330
+ }
331
+
332
+ /* check for same geometry composition */
333
+ char
334
+ lwcollection_same(const LWCOLLECTION *c1, const LWCOLLECTION *c2)
335
+ {
336
+ unsigned int i, j;
337
+ unsigned int *hit;
338
+
339
+ LWDEBUG(2, "lwcollection_same called");
340
+
341
+ if ( TYPE_GETTYPE(c1->type) != TYPE_GETTYPE(c2->type) ) return 0;
342
+ if ( c1->ngeoms != c2->ngeoms ) return 0;
343
+
344
+ hit = lwalloc(sizeof(unsigned int)*c1->ngeoms);
345
+ memset(hit, 0, sizeof(unsigned int)*c1->ngeoms);
346
+
347
+ for (i=0; i<c1->ngeoms; i++)
348
+ {
349
+ char found=0;
350
+ for (j=0; j<c2->ngeoms; j++)
351
+ {
352
+ if ( hit[j] ) continue;
353
+ if ( lwgeom_same(c1->geoms[i], c2->geoms[j]) )
354
+ {
355
+ hit[j] = 1;
356
+ found=1;
357
+ break;
358
+ }
359
+ }
360
+ if ( ! found ) return 0;
361
+ }
362
+ return 1;
363
+ }
364
+
365
+ int lwcollection_ngeoms(const LWCOLLECTION *col)
366
+ {
367
+ int i;
368
+ int ngeoms = 0;
369
+
370
+ if( ! col ) {
371
+ lwerror("Null input geometry.");
372
+ return 0;
373
+ }
374
+
375
+ for( i = 0; i < col->ngeoms; i++ )
376
+ {
377
+ if( col->geoms[i]) {
378
+ switch(TYPE_GETTYPE(col->geoms[i]->type)) {
379
+ case POINTTYPE:
380
+ case LINETYPE:
381
+ case CIRCSTRINGTYPE:
382
+ case POLYGONTYPE:
383
+ ngeoms += 1;
384
+ break;
385
+ case MULTIPOINTTYPE:
386
+ case MULTILINETYPE:
387
+ case MULTICURVETYPE:
388
+ case MULTIPOLYGONTYPE:
389
+ ngeoms += col->ngeoms;
390
+ break;
391
+ case COLLECTIONTYPE:
392
+ ngeoms += lwcollection_ngeoms((LWCOLLECTION*)col->geoms[i]);
393
+ break;
394
+ }
395
+ }
396
+ }
397
+ return ngeoms;
398
+ }
399
+
400
+ /*
401
+ ** Given a generic collection, return the "simplest" form.
402
+ ** eg: GEOMETRYCOLLECTION(MULTILINESTRING()) => MULTELINESTRING()
403
+ ** GEOMETRYCOLLECTION(MULTILINESTRING(), MULTILINESTRING(), POINT()) => GEOMETRYCOLLECTION(MULTILINESTRING(), MULTIPOINT())
404
+ **
405
+ ** In general, if the subcomponents are homogeneous, return a properly typed collection.
406
+ ** Otherwise, return a generic collection, with the subtypes in minimal typed collections.
407
+ LWCOLLECTION *lwcollection_homogenize(const LWCOLLECTION *c1)
408
+ {
409
+ TODO: pramsey
410
+ }
411
+ */
412
+
413
+ /*
414
+ ** Given a generic collection, extract and return just the desired types.
415
+ LWGEOM *lwcollection_extract(const LWCOLLECTION *col, char type)
416
+ {
417
+ LWGEOM **extracted_geoms;
418
+ extracted_geoms = lwalloc(sizeof(void*)*col->ngeoms);
419
+ extracted_curgeom = 0;
420
+ char reqtype = TYPE_GETTYPE(type);
421
+ for ( i = 0; i < col->ngeoms; i++ )
422
+ {
423
+ if( col->geoms[i] )
424
+ char geomtype = TYPE_GETTYPE(col->geoms[i]->type);
425
+ if ( geomtype == reqtype ) {
426
+ extracted_geoms[extracted_curgeom] = col->geoms[i];
427
+ extracted_curgeom++;
428
+ continue;
429
+ }
430
+ else {
431
+ if ( geomtype == COLLECTIONTYPE ) {
432
+ LWGEOM *colgeom;
433
+ colgeom = lwcollection_extract(col->geoms[i], type);
434
+ extracted_geoms[extracted_curgeom] = colgeom->geoms;
435
+ extracted_curgeom++;
436
+ if( colgeom->bbox ) lwfree(colgeom->bbox);
437
+ lwfree(colgeom);
438
+ continue;
439
+ }
440
+ }
441
+ TODO: pramsey
442
+ }
443
+ */
444
+
445
+
446
+
447
+ void lwcollection_free(LWCOLLECTION *col)
448
+ {
449
+ int i;
450
+ if( col->bbox )
451
+ {
452
+ lwfree(col->bbox);
453
+ }
454
+ for ( i = 0; i < col->ngeoms; i++ )
455
+ {
456
+ if( col->geoms[i] ) {
457
+ switch( TYPE_GETTYPE(col->geoms[i]->type) )
458
+ {
459
+ case POINTTYPE:
460
+ lwpoint_free((LWPOINT*)col->geoms[i]);
461
+ break;
462
+ case LINETYPE:
463
+ lwline_free((LWLINE*)col->geoms[i]);
464
+ break;
465
+ case POLYGONTYPE:
466
+ lwpoly_free((LWPOLY*)col->geoms[i]);
467
+ break;
468
+ case MULTIPOINTTYPE:
469
+ lwmpoint_free((LWMPOINT*)col->geoms[i]);
470
+ break;
471
+ case MULTILINETYPE:
472
+ lwmline_free((LWMLINE*)col->geoms[i]);
473
+ break;
474
+ case MULTIPOLYGONTYPE:
475
+ lwmpoly_free((LWMPOLY*)col->geoms[i]);
476
+ break;
477
+ case COLLECTIONTYPE:
478
+ lwcollection_free((LWCOLLECTION*)col->geoms[i]);
479
+ break;
480
+ }
481
+ }
482
+ }
483
+ if( col->geoms )
484
+ {
485
+ lwfree(col->geoms);
486
+ }
487
+ lwfree(col);
488
+
489
+ };
490
+
491
+ BOX3D *lwcollection_compute_box3d(LWCOLLECTION *col)
492
+ {
493
+ int i;
494
+ BOX3D *boxfinal = NULL;
495
+ BOX3D *boxtmp1 = NULL;
496
+ BOX3D *boxtmp2 = NULL;
497
+ for ( i = 0; i < col->ngeoms; i++ )
498
+ {
499
+ if( col->geoms[i] ) {
500
+ switch( TYPE_GETTYPE(col->geoms[i]->type) )
501
+ {
502
+ case POINTTYPE:
503
+ boxtmp1 = lwpoint_compute_box3d((LWPOINT*)(col->geoms[i]));
504
+ break;
505
+ case LINETYPE:
506
+ boxtmp1 = lwline_compute_box3d((LWLINE*)(col->geoms[i]));
507
+ break;
508
+ case POLYGONTYPE:
509
+ boxtmp1 = lwpoly_compute_box3d((LWPOLY*)(col->geoms[i]));
510
+ break;
511
+ case CIRCSTRINGTYPE:
512
+ boxtmp1 = lwcircstring_compute_box3d((LWCIRCSTRING *)(col->geoms[i]));
513
+ break;
514
+ case COMPOUNDTYPE:
515
+ case CURVEPOLYTYPE:
516
+ case MULTIPOINTTYPE:
517
+ case MULTILINETYPE:
518
+ case MULTIPOLYGONTYPE:
519
+ case MULTICURVETYPE:
520
+ case MULTISURFACETYPE:
521
+ case COLLECTIONTYPE:
522
+ boxtmp1 = lwcollection_compute_box3d((LWCOLLECTION*)(col->geoms[i]));
523
+ boxfinal = box3d_union(boxtmp1, boxtmp2);
524
+ break;
525
+ }
526
+ boxtmp2 = boxfinal;
527
+ boxfinal = box3d_union(boxtmp1, boxtmp2);
528
+ if( boxtmp1 && boxtmp1 != boxfinal )
529
+ {
530
+ lwfree(boxtmp1);
531
+ boxtmp1 = NULL;
532
+ }
533
+ if( boxtmp2 && boxtmp2 != boxfinal )
534
+ {
535
+ lwfree(boxtmp2);
536
+ boxtmp2 = NULL;
537
+ }
538
+ }
539
+ }
540
+ return boxfinal;
541
+ }