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,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
+