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.
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,125 @@
1
+ /**********************************************************************
2
+ * $Id: lwmcurve.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
+ LWMCURVE *
19
+ lwmcurve_deserialize(uchar *srl)
20
+ {
21
+ LWMCURVE *result;
22
+ LWGEOM_INSPECTED *insp;
23
+ int stype;
24
+ int type = lwgeom_getType(srl[0]);
25
+ int i;
26
+
27
+ if(type != MULTICURVETYPE)
28
+ {
29
+ lwerror("lwmcurve_deserialize called on NON multicurve: %d", type);
30
+ return NULL;
31
+ }
32
+
33
+ insp = lwgeom_inspect(srl);
34
+
35
+ result = lwalloc(sizeof(LWMCURVE));
36
+ result->type = insp->type;
37
+ result->SRID = insp->SRID;
38
+ result->ngeoms = insp->ngeometries;
39
+ result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries);
40
+
41
+ if(lwgeom_hasBBOX(srl[0]))
42
+ {
43
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
44
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
45
+ }
46
+ else result->bbox = NULL;
47
+
48
+ for(i = 0; i < insp->ngeometries; i++)
49
+ {
50
+ stype = lwgeom_getType(insp->sub_geoms[i][0]);
51
+ if(stype == CIRCSTRINGTYPE)
52
+ {
53
+ result->geoms[i] = (LWGEOM *)lwcircstring_deserialize(insp->sub_geoms[i]);
54
+ }
55
+ else if(stype == LINETYPE)
56
+ {
57
+ result->geoms[i] = (LWGEOM *)lwline_deserialize(insp->sub_geoms[i]);
58
+ }
59
+ else
60
+ {
61
+ lwerror("Only Circular and Line strings are currenly permitted in a MultiCurve.");
62
+ lwfree(result);
63
+ lwfree(insp);
64
+ return NULL;
65
+ }
66
+
67
+ if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type))
68
+ {
69
+ lwerror("Mixed dimensions (multicurve: %d, curve %d:%d)",
70
+ TYPE_NDIMS(result->type), i,
71
+ TYPE_NDIMS(result->geoms[i]->type));
72
+ lwfree(result);
73
+ lwfree(insp);
74
+ return NULL;
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+
80
+ /*
81
+ * Add 'what' to this multicurve at position 'where'.
82
+ * where=0 == prepend
83
+ * where=-1 == append
84
+ * Returns a MULTICURVE or a COLLECTION
85
+ */
86
+ LWGEOM *
87
+ lwmcurve_add(const LWMCURVE *to, uint32 where, const LWGEOM *what)
88
+ {
89
+ LWCOLLECTION *col;
90
+ LWGEOM **geoms;
91
+ int newtype;
92
+ uint32 i;
93
+
94
+ if(where == -1) where = to->ngeoms;
95
+ else if(where < -1 || where > to->ngeoms)
96
+ {
97
+ lwerror("lwmcurve_add: add position out of range %d..%d",
98
+ -1, to->ngeoms);
99
+ return NULL;
100
+ }
101
+
102
+ /* dimensions compatibility are checked by caller */
103
+
104
+ /* Construct geoms array */
105
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
106
+ for(i = 0; i < where; i++)
107
+ {
108
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
109
+ }
110
+ geoms[where] = lwgeom_clone(what);
111
+ for(i = where; i < to->ngeoms; i++)
112
+ {
113
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
114
+ }
115
+
116
+ if(TYPE_GETTYPE(what->type) == CIRCSTRINGTYPE) newtype = MULTICURVETYPE;
117
+ else newtype = COLLECTIONTYPE;
118
+
119
+ col = lwcollection_construct(newtype,
120
+ to->SRID, NULL,
121
+ to->ngeoms + 1, geoms);
122
+
123
+ return (LWGEOM *)col;
124
+ }
125
+
@@ -0,0 +1,137 @@
1
+ /**********************************************************************
2
+ * $Id: lwmline.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
+ void
19
+ lwmline_release(LWMLINE *lwmline)
20
+ {
21
+ lwgeom_release(lwmline_as_lwgeom(lwmline));
22
+ }
23
+
24
+ LWMLINE *
25
+ lwmline_deserialize(uchar *srl)
26
+ {
27
+ LWMLINE *result;
28
+ LWGEOM_INSPECTED *insp;
29
+ int type = lwgeom_getType(srl[0]);
30
+ int i;
31
+
32
+ if ( type != MULTILINETYPE )
33
+ {
34
+ lwerror("lwmline_deserialize called on NON multiline: %d",
35
+ type);
36
+ return NULL;
37
+ }
38
+
39
+ insp = lwgeom_inspect(srl);
40
+
41
+ result = lwalloc(sizeof(LWMLINE));
42
+ result->type = insp->type;
43
+ result->SRID = insp->SRID;
44
+ result->ngeoms = insp->ngeometries;
45
+ result->geoms = lwalloc(sizeof(LWLINE *)*insp->ngeometries);
46
+
47
+ if (lwgeom_hasBBOX(srl[0]))
48
+ {
49
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
50
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
51
+ }
52
+ else result->bbox = NULL;
53
+
54
+
55
+ for (i=0; i<insp->ngeometries; i++)
56
+ {
57
+ result->geoms[i] = lwline_deserialize(insp->sub_geoms[i]);
58
+ if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) )
59
+ {
60
+ lwerror("Mixed dimensions (multiline:%d, line%d:%d)",
61
+ TYPE_NDIMS(result->type), i,
62
+ TYPE_NDIMS(result->geoms[i]->type)
63
+ );
64
+ return NULL;
65
+ }
66
+ }
67
+
68
+ return result;
69
+ }
70
+
71
+ /*
72
+ * Add 'what' to this multiline at position 'where'.
73
+ * where=0 == prepend
74
+ * where=-1 == append
75
+ * Returns a MULTILINE or a COLLECTION
76
+ */
77
+ LWGEOM *
78
+ lwmline_add(const LWMLINE *to, uint32 where, const LWGEOM *what)
79
+ {
80
+ LWCOLLECTION *col;
81
+ LWGEOM **geoms;
82
+ int newtype;
83
+ uint32 i;
84
+
85
+ if ( where == -1 ) where = to->ngeoms;
86
+ else if ( where < -1 || where > to->ngeoms )
87
+ {
88
+ lwerror("lwmline_add: add position out of range %d..%d",
89
+ -1, to->ngeoms);
90
+ return NULL;
91
+ }
92
+
93
+ /* dimensions compatibility are checked by caller */
94
+
95
+ /* Construct geoms array */
96
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
97
+ for (i=0; i<where; i++)
98
+ {
99
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
100
+ }
101
+ geoms[where] = lwgeom_clone(what);
102
+ for (i=where; i<to->ngeoms; i++)
103
+ {
104
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
105
+ }
106
+
107
+ if ( TYPE_GETTYPE(what->type) == LINETYPE ) newtype = MULTILINETYPE;
108
+ else newtype = COLLECTIONTYPE;
109
+
110
+ col = lwcollection_construct(newtype,
111
+ to->SRID, NULL,
112
+ to->ngeoms+1, geoms);
113
+
114
+ return (LWGEOM *)col;
115
+
116
+ }
117
+
118
+ void lwmline_free(LWMLINE *mline)
119
+ {
120
+ int i;
121
+ if( mline->bbox )
122
+ {
123
+ lwfree(mline->bbox);
124
+ }
125
+ for ( i = 0; i < mline->ngeoms; i++ )
126
+ {
127
+ if( mline->geoms[i] ) {
128
+ lwline_free(mline->geoms[i]);
129
+ }
130
+ }
131
+ if( mline->geoms )
132
+ {
133
+ lwfree(mline->geoms);
134
+ }
135
+ lwfree(mline);
136
+
137
+ };
@@ -0,0 +1,138 @@
1
+ /**********************************************************************
2
+ * $Id: lwmpoint.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
+ void
19
+ lwmpoint_release(LWMPOINT *lwmpoint)
20
+ {
21
+ lwgeom_release(lwmpoint_as_lwgeom(lwmpoint));
22
+ }
23
+
24
+
25
+ LWMPOINT *
26
+ lwmpoint_deserialize(uchar *srl)
27
+ {
28
+ LWMPOINT *result;
29
+ LWGEOM_INSPECTED *insp;
30
+ int type = lwgeom_getType(srl[0]);
31
+ int i;
32
+
33
+ if ( type != MULTIPOINTTYPE )
34
+ {
35
+ lwerror("lwmpoint_deserialize called on NON multipoint: %d",
36
+ type);
37
+ return NULL;
38
+ }
39
+
40
+ insp = lwgeom_inspect(srl);
41
+
42
+ result = lwalloc(sizeof(LWMPOINT));
43
+ result->type = insp->type;
44
+ result->SRID = insp->SRID;
45
+ result->ngeoms = insp->ngeometries;
46
+ result->geoms = lwalloc(sizeof(LWPOINT *)*result->ngeoms);
47
+
48
+ if (lwgeom_hasBBOX(srl[0]))
49
+ {
50
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
51
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
52
+ }
53
+ else result->bbox = NULL;
54
+
55
+ for (i=0; i<insp->ngeometries; i++)
56
+ {
57
+ result->geoms[i] = lwpoint_deserialize(insp->sub_geoms[i]);
58
+ if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) )
59
+ {
60
+ lwerror("Mixed dimensions (multipoint:%d, point%d:%d)",
61
+ TYPE_NDIMS(result->type), i,
62
+ TYPE_NDIMS(result->geoms[i]->type)
63
+ );
64
+ return NULL;
65
+ }
66
+ }
67
+
68
+ return result;
69
+ }
70
+
71
+ /*
72
+ * Add 'what' to this multipoint at position 'where'.
73
+ * where=0 == prepend
74
+ * where=-1 == append
75
+ * Returns a MULTIPOINT or a COLLECTION
76
+ */
77
+ LWGEOM *
78
+ lwmpoint_add(const LWMPOINT *to, uint32 where, const LWGEOM *what)
79
+ {
80
+ LWCOLLECTION *col;
81
+ LWGEOM **geoms;
82
+ int newtype;
83
+ uint32 i;
84
+
85
+ if ( where == -1 ) where = to->ngeoms;
86
+ else if ( where < -1 || where > to->ngeoms )
87
+ {
88
+ lwerror("lwmpoint_add: add position out of range %d..%d",
89
+ -1, to->ngeoms);
90
+ return NULL;
91
+ }
92
+
93
+ /* dimensions compatibility are checked by caller */
94
+
95
+ /* Construct geoms array */
96
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
97
+ for (i=0; i<where; i++)
98
+ {
99
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
100
+ }
101
+ geoms[where] = lwgeom_clone(what);
102
+ for (i=where; i<to->ngeoms; i++)
103
+ {
104
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
105
+ }
106
+
107
+ if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE;
108
+ else newtype = COLLECTIONTYPE;
109
+
110
+ col = lwcollection_construct(newtype,
111
+ to->SRID, NULL,
112
+ to->ngeoms+1, geoms);
113
+
114
+ return (LWGEOM *)col;
115
+
116
+ }
117
+
118
+ void lwmpoint_free(LWMPOINT *mpt)
119
+ {
120
+ int i;
121
+ if( mpt->bbox )
122
+ {
123
+ lwfree(mpt->bbox);
124
+ }
125
+ for ( i = 0; i < mpt->ngeoms; i++ )
126
+ {
127
+ if( mpt->geoms[i] ) {
128
+ lwpoint_free(mpt->geoms[i]);
129
+ }
130
+ }
131
+ if( mpt->geoms )
132
+ {
133
+ lwfree(mpt->geoms);
134
+ }
135
+ lwfree(mpt);
136
+
137
+ };
138
+
@@ -0,0 +1,141 @@
1
+ /**********************************************************************
2
+ * $Id: lwmpoly.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
+ void
20
+ lwmpoly_release(LWMPOLY *lwmpoly)
21
+ {
22
+ lwgeom_release(lwmpoly_as_lwgeom(lwmpoly));
23
+ }
24
+
25
+
26
+ LWMPOLY *
27
+ lwmpoly_deserialize(uchar *srl)
28
+ {
29
+ LWMPOLY *result;
30
+ LWGEOM_INSPECTED *insp;
31
+ int type = lwgeom_getType(srl[0]);
32
+ int i;
33
+
34
+ LWDEBUG(2, "lwmpoly_deserialize called");
35
+
36
+ if ( type != MULTIPOLYGONTYPE )
37
+ {
38
+ lwerror("lwmpoly_deserialize called on NON multipoly: %d",
39
+ type);
40
+ return NULL;
41
+ }
42
+
43
+ insp = lwgeom_inspect(srl);
44
+
45
+ result = lwalloc(sizeof(LWMPOLY));
46
+ result->type = insp->type;
47
+ result->SRID = insp->SRID;
48
+ result->ngeoms = insp->ngeometries;
49
+ result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
50
+
51
+ if (lwgeom_hasBBOX(srl[0]))
52
+ {
53
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
54
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
55
+ }
56
+ else result->bbox = NULL;
57
+
58
+ for (i=0; i<insp->ngeometries; i++)
59
+ {
60
+ result->geoms[i] = lwpoly_deserialize(insp->sub_geoms[i]);
61
+ if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) )
62
+ {
63
+ lwerror("Mixed dimensions (multipoly:%d, poly%d:%d)",
64
+ TYPE_NDIMS(result->type), i,
65
+ TYPE_NDIMS(result->geoms[i]->type)
66
+ );
67
+ return NULL;
68
+ }
69
+ }
70
+
71
+ return result;
72
+ }
73
+
74
+ /*
75
+ * Add 'what' to this multiline at position 'where'.
76
+ * where=0 == prepend
77
+ * where=-1 == append
78
+ * Returns a MULTIPOLY or a COLLECTION
79
+ */
80
+ LWGEOM *
81
+ lwmpoly_add(const LWMPOLY *to, uint32 where, const LWGEOM *what)
82
+ {
83
+ LWCOLLECTION *col;
84
+ LWGEOM **geoms;
85
+ int newtype;
86
+ uint32 i;
87
+
88
+ if ( where == -1 ) where = to->ngeoms;
89
+ else if ( where < -1 || where > to->ngeoms )
90
+ {
91
+ lwerror("lwmline_add: add position out of range %d..%d",
92
+ -1, to->ngeoms);
93
+ return NULL;
94
+ }
95
+
96
+ /* dimensions compatibility are checked by caller */
97
+
98
+ /* Construct geoms array */
99
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
100
+ for (i=0; i<where; i++)
101
+ {
102
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
103
+ }
104
+ geoms[where] = lwgeom_clone(what);
105
+ for (i=where; i<to->ngeoms; i++)
106
+ {
107
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
108
+ }
109
+
110
+ if ( TYPE_GETTYPE(what->type) == POLYGONTYPE ) newtype = MULTIPOLYGONTYPE;
111
+ else newtype = COLLECTIONTYPE;
112
+
113
+ col = lwcollection_construct(newtype,
114
+ to->SRID, NULL,
115
+ to->ngeoms+1, geoms);
116
+
117
+ return (LWGEOM *)col;
118
+
119
+ }
120
+
121
+ void lwmpoly_free(LWMPOLY *mpoly)
122
+ {
123
+ int i;
124
+ if( mpoly->bbox )
125
+ {
126
+ lwfree(mpoly->bbox);
127
+ }
128
+ for ( i = 0; i < mpoly->ngeoms; i++ )
129
+ {
130
+ if( mpoly->geoms[i] ) {
131
+ lwpoly_free(mpoly->geoms[i]);
132
+ }
133
+ }
134
+ if( mpoly->geoms )
135
+ {
136
+ lwfree(mpoly->geoms);
137
+ }
138
+ lwfree(mpoly);
139
+
140
+ };
141
+