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