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