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.
- data/Gemfile +12 -0
- data/Gemfile.lock +32 -0
- data/History.txt +6 -0
- data/Makefile +13 -0
- data/Manifest.txt +18 -0
- data/README.rdoc +197 -0
- data/Rakefile +53 -0
- data/TODO.txt +8 -0
- data/VERSION +1 -0
- data/bin/build_indexes +8 -0
- data/bin/rebuild_cluster +22 -0
- data/bin/rebuild_metaphones +23 -0
- data/bin/tiger_import +59 -0
- data/demos/demo/app/ext/geocodewrap.rb +84 -0
- data/demos/demo/app/views/index.builder +13 -0
- data/demos/demo/app/views/index.erb +71 -0
- data/demos/demo/config.ru +12 -0
- data/demos/demo/config/bootstraps.rb +130 -0
- data/demos/demo/config/geoenvironment.rb +25 -0
- data/demos/demo/geocoder_helper.rb +12 -0
- data/demos/demo/geocom_geocode.rb +10 -0
- data/demos/demo/main.rb +3 -0
- data/demos/demo/rakefile.rb +17 -0
- data/demos/demo/tmp/restart.txt +0 -0
- data/demos/simpledemo/views/index.builder +13 -0
- data/demos/simpledemo/views/index.erb +69 -0
- data/demos/simpledemo/ws.rb +83 -0
- data/doc/Makefile +7 -0
- data/doc/html4css1.css +279 -0
- data/doc/lookup.rst +193 -0
- data/doc/parsing.rst +125 -0
- data/doc/voidspace.css +147 -0
- data/geo_coder.gemspec +172 -0
- data/lib/geocoder/us.rb +21 -0
- data/lib/geocoder/us/address.rb +290 -0
- data/lib/geocoder/us/constants.rb +670 -0
- data/lib/geocoder/us/database.rb +745 -0
- data/lib/geocoder/us/import.rb +181 -0
- data/lib/geocoder/us/import/tiger.rb +13 -0
- data/lib/geocoder/us/numbers.rb +58 -0
- data/navteq/README +4 -0
- data/navteq/convert.sql +37 -0
- data/navteq/navteq_import +39 -0
- data/navteq/prepare.sql +92 -0
- data/sql/cluster.sql +16 -0
- data/sql/convert.sql +80 -0
- data/sql/create.sql +37 -0
- data/sql/index.sql +12 -0
- data/sql/place.csv +104944 -0
- data/sql/place.sql +104948 -0
- data/sql/setup.sql +78 -0
- data/src/Makefile +13 -0
- data/src/README +14 -0
- data/src/liblwgeom/Makefile +75 -0
- data/src/liblwgeom/box2d.c +54 -0
- data/src/liblwgeom/lex.yy.c +4799 -0
- data/src/liblwgeom/liblwgeom.h +1405 -0
- data/src/liblwgeom/lwalgorithm.c +946 -0
- data/src/liblwgeom/lwalgorithm.h +52 -0
- data/src/liblwgeom/lwcircstring.c +759 -0
- data/src/liblwgeom/lwcollection.c +541 -0
- data/src/liblwgeom/lwcompound.c +118 -0
- data/src/liblwgeom/lwcurvepoly.c +86 -0
- data/src/liblwgeom/lwgeom.c +886 -0
- data/src/liblwgeom/lwgeom_api.c +2201 -0
- data/src/liblwgeom/lwgparse.c +1219 -0
- data/src/liblwgeom/lwgunparse.c +1054 -0
- data/src/liblwgeom/lwline.c +525 -0
- data/src/liblwgeom/lwmcurve.c +125 -0
- data/src/liblwgeom/lwmline.c +137 -0
- data/src/liblwgeom/lwmpoint.c +138 -0
- data/src/liblwgeom/lwmpoly.c +141 -0
- data/src/liblwgeom/lwmsurface.c +129 -0
- data/src/liblwgeom/lwpoint.c +439 -0
- data/src/liblwgeom/lwpoly.c +579 -0
- data/src/liblwgeom/lwsegmentize.c +1047 -0
- data/src/liblwgeom/lwutil.c +369 -0
- data/src/liblwgeom/measures.c +861 -0
- data/src/liblwgeom/postgis_config.h +93 -0
- data/src/liblwgeom/ptarray.c +847 -0
- data/src/liblwgeom/vsprintf.c +179 -0
- data/src/liblwgeom/wktparse.h +126 -0
- data/src/liblwgeom/wktparse.lex +74 -0
- data/src/liblwgeom/wktparse.tab.c +2353 -0
- data/src/liblwgeom/wktparse.tab.h +145 -0
- data/src/liblwgeom/wktparse.y +385 -0
- data/src/libsqlite3_geocoder/Makefile +22 -0
- data/src/libsqlite3_geocoder/Makefile.nix +15 -0
- data/src/libsqlite3_geocoder/Makefile.redhat +15 -0
- data/src/libsqlite3_geocoder/extension.c +121 -0
- data/src/libsqlite3_geocoder/extension.h +13 -0
- data/src/libsqlite3_geocoder/levenshtein.c +42 -0
- data/src/libsqlite3_geocoder/metaphon.c +278 -0
- data/src/libsqlite3_geocoder/util.c +37 -0
- data/src/libsqlite3_geocoder/wkb_compress.c +54 -0
- data/src/metaphone/Makefile +7 -0
- data/src/metaphone/README +49 -0
- data/src/metaphone/extension.c +37 -0
- data/src/metaphone/metaphon.c +251 -0
- data/src/shp2sqlite/Makefile +37 -0
- data/src/shp2sqlite/Makefile.nix +36 -0
- data/src/shp2sqlite/Makefile.redhat +35 -0
- data/src/shp2sqlite/dbfopen.c +1595 -0
- data/src/shp2sqlite/getopt.c +695 -0
- data/src/shp2sqlite/getopt.h +127 -0
- data/src/shp2sqlite/shapefil.h +500 -0
- data/src/shp2sqlite/shp2sqlite.c +1974 -0
- data/src/shp2sqlite/shpopen.c +1894 -0
- data/tests/address.rb +236 -0
- data/tests/benchmark.rb +20 -0
- data/tests/constants.rb +57 -0
- data/tests/data/address-sample.csv +52 -0
- data/tests/data/db-test.csv +57 -0
- data/tests/data/locations.csv +4 -0
- data/tests/database.rb +137 -0
- data/tests/generate.rb +34 -0
- data/tests/numbers.rb +46 -0
- data/tests/run.rb +11 -0
- metadata +237 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**********************************************************************
|
|
2
|
+
* $Id: lwmsurface.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
|
+
LWMSURFACE *
|
|
20
|
+
lwmsurface_deserialize(uchar *srl)
|
|
21
|
+
{
|
|
22
|
+
LWMSURFACE *result;
|
|
23
|
+
LWGEOM_INSPECTED *insp;
|
|
24
|
+
int stype;
|
|
25
|
+
int type = lwgeom_getType(srl[0]);
|
|
26
|
+
int i;
|
|
27
|
+
|
|
28
|
+
LWDEBUG(2, "lwmsurface_deserialize called");
|
|
29
|
+
|
|
30
|
+
if(type != MULTISURFACETYPE)
|
|
31
|
+
{
|
|
32
|
+
lwerror("lwmsurface_deserialize called on a non-multisurface: %d", type);
|
|
33
|
+
return NULL;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
insp = lwgeom_inspect(srl);
|
|
37
|
+
|
|
38
|
+
result = lwalloc(sizeof(LWMSURFACE));
|
|
39
|
+
result->type = insp->type;
|
|
40
|
+
result->SRID = insp->SRID;
|
|
41
|
+
result->ngeoms = insp->ngeometries;
|
|
42
|
+
result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
|
|
43
|
+
|
|
44
|
+
if(lwgeom_hasBBOX(srl[0]))
|
|
45
|
+
{
|
|
46
|
+
result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
|
|
47
|
+
memcpy(result->bbox, srl + 1, sizeof(BOX2DFLOAT4));
|
|
48
|
+
}
|
|
49
|
+
else result->bbox = NULL;
|
|
50
|
+
|
|
51
|
+
for(i = 0; i < insp->ngeometries; i++)
|
|
52
|
+
{
|
|
53
|
+
stype = lwgeom_getType(insp->sub_geoms[i][0]);
|
|
54
|
+
if(stype == POLYGONTYPE)
|
|
55
|
+
{
|
|
56
|
+
result->geoms[i] = (LWGEOM *)lwpoly_deserialize(insp->sub_geoms[i]);
|
|
57
|
+
}
|
|
58
|
+
else if(stype == CURVEPOLYTYPE)
|
|
59
|
+
{
|
|
60
|
+
result->geoms[i] = (LWGEOM *)lwcurvepoly_deserialize(insp->sub_geoms[i]);
|
|
61
|
+
}
|
|
62
|
+
else
|
|
63
|
+
{
|
|
64
|
+
lwerror("Only Polygons and Curved Polygons are supported in a MultiSurface.");
|
|
65
|
+
lwfree(result);
|
|
66
|
+
lwfree(insp);
|
|
67
|
+
return NULL;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type))
|
|
71
|
+
{
|
|
72
|
+
lwerror("Mixed dimensions (multisurface: %d, surface %d:%d",
|
|
73
|
+
TYPE_NDIMS(result->type), i,
|
|
74
|
+
TYPE_NDIMS(result->geoms[i]->type));
|
|
75
|
+
lwfree(result);
|
|
76
|
+
lwfree(insp);
|
|
77
|
+
return NULL;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/*
|
|
84
|
+
* Add 'what' to this multisurface at position 'where'
|
|
85
|
+
* where=0 == prepend
|
|
86
|
+
* where=-1 == append
|
|
87
|
+
* Returns a MULTISURFACE or a COLLECTION
|
|
88
|
+
*/
|
|
89
|
+
LWGEOM *
|
|
90
|
+
lwmsurface_add(const LWMSURFACE *to, uint32 where, const LWGEOM *what)
|
|
91
|
+
{
|
|
92
|
+
LWCOLLECTION *col;
|
|
93
|
+
LWGEOM **geoms;
|
|
94
|
+
int newtype;
|
|
95
|
+
uint32 i;
|
|
96
|
+
|
|
97
|
+
if(where == -1) where = to->ngeoms;
|
|
98
|
+
else if(where < -1 || where > to->ngeoms)
|
|
99
|
+
{
|
|
100
|
+
lwerror("lwmsurface_add: add position out of range %d..%d",
|
|
101
|
+
-1, to->ngeoms);
|
|
102
|
+
return NULL;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* dimensions compatibility are checked by caller */
|
|
106
|
+
|
|
107
|
+
/* Construct geoms array */
|
|
108
|
+
geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
|
|
109
|
+
for(i = 0; i < where; i++)
|
|
110
|
+
{
|
|
111
|
+
geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
|
|
112
|
+
}
|
|
113
|
+
geoms[where] = lwgeom_clone(what);
|
|
114
|
+
for(i = where; i < to->ngeoms; i++)
|
|
115
|
+
{
|
|
116
|
+
geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if(TYPE_GETTYPE(what->type) == POLYGONTYPE
|
|
120
|
+
|| TYPE_GETTYPE(what->type) == CURVEPOLYTYPE)
|
|
121
|
+
newtype = MULTISURFACETYPE;
|
|
122
|
+
else newtype = COLLECTIONTYPE;
|
|
123
|
+
|
|
124
|
+
col = lwcollection_construct(newtype,
|
|
125
|
+
to->SRID, NULL, to->ngeoms + 1, geoms);
|
|
126
|
+
|
|
127
|
+
return (LWGEOM *)col;
|
|
128
|
+
}
|
|
129
|
+
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**********************************************************************
|
|
2
|
+
* $Id: lwpoint.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
|
+
/*
|
|
20
|
+
* Convert this point into its serialize form
|
|
21
|
+
* result's first char will be the 8bit type. See serialized form doc
|
|
22
|
+
*/
|
|
23
|
+
uchar *
|
|
24
|
+
lwpoint_serialize(LWPOINT *point)
|
|
25
|
+
{
|
|
26
|
+
size_t size, retsize;
|
|
27
|
+
uchar *result;
|
|
28
|
+
|
|
29
|
+
size = lwpoint_serialize_size(point);
|
|
30
|
+
result = lwalloc(size);
|
|
31
|
+
lwpoint_serialize_buf(point, result, &retsize);
|
|
32
|
+
|
|
33
|
+
if ( retsize != size )
|
|
34
|
+
{
|
|
35
|
+
lwerror("lwpoint_serialize_size returned %d, ..serialize_buf returned %d", size, retsize);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
* Convert this point into its serialize form writing it into
|
|
43
|
+
* the given buffer, and returning number of bytes written into
|
|
44
|
+
* the given int pointer.
|
|
45
|
+
* result's first char will be the 8bit type. See serialized form doc
|
|
46
|
+
*/
|
|
47
|
+
void
|
|
48
|
+
lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *retsize)
|
|
49
|
+
{
|
|
50
|
+
int size=1;
|
|
51
|
+
char hasSRID;
|
|
52
|
+
uchar *loc;
|
|
53
|
+
int ptsize = pointArray_ptsize(point->point);
|
|
54
|
+
|
|
55
|
+
if ( TYPE_GETZM(point->type) != TYPE_GETZM(point->point->dims) )
|
|
56
|
+
lwerror("Dimensions mismatch in lwpoint");
|
|
57
|
+
|
|
58
|
+
LWDEBUGF(2, "lwpoint_serialize_buf(%p, %p) called", point, buf);
|
|
59
|
+
/*printLWPOINT(point); */
|
|
60
|
+
|
|
61
|
+
hasSRID = (point->SRID != -1);
|
|
62
|
+
|
|
63
|
+
if (hasSRID) size +=4; /*4 byte SRID */
|
|
64
|
+
if (point->bbox) size += sizeof(BOX2DFLOAT4); /* bvol */
|
|
65
|
+
|
|
66
|
+
size += sizeof(double)*TYPE_NDIMS(point->type);
|
|
67
|
+
|
|
68
|
+
buf[0] = (uchar) lwgeom_makeType_full(
|
|
69
|
+
TYPE_HASZ(point->type), TYPE_HASM(point->type),
|
|
70
|
+
hasSRID, POINTTYPE, point->bbox?1:0);
|
|
71
|
+
loc = buf+1;
|
|
72
|
+
|
|
73
|
+
if (point->bbox)
|
|
74
|
+
{
|
|
75
|
+
memcpy(loc, point->bbox, sizeof(BOX2DFLOAT4));
|
|
76
|
+
loc += sizeof(BOX2DFLOAT4);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (hasSRID)
|
|
80
|
+
{
|
|
81
|
+
memcpy(loc, &point->SRID, sizeof(int32));
|
|
82
|
+
loc += 4;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* copy in points */
|
|
86
|
+
memcpy(loc, getPoint_internal(point->point, 0), ptsize);
|
|
87
|
+
|
|
88
|
+
if (retsize) *retsize = size;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/*
|
|
92
|
+
* Find bounding box (standard one)
|
|
93
|
+
* zmin=zmax=NO_Z_VALUE if 2d
|
|
94
|
+
*/
|
|
95
|
+
BOX3D *
|
|
96
|
+
lwpoint_compute_box3d(LWPOINT *point)
|
|
97
|
+
{
|
|
98
|
+
LWDEBUGF(2, "lwpoint_compute_box3d called with point %p", point);
|
|
99
|
+
|
|
100
|
+
if (point == NULL)
|
|
101
|
+
{
|
|
102
|
+
LWDEBUG(3, "lwpoint_compute_box3d returning NULL");
|
|
103
|
+
|
|
104
|
+
return NULL;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
LWDEBUG(3, "lwpoint_compute_box3d returning ptarray_compute_box3d return");
|
|
108
|
+
|
|
109
|
+
return ptarray_compute_box3d(point->point);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
* Convenience functions to hide the POINTARRAY
|
|
114
|
+
* TODO: obsolete this
|
|
115
|
+
*/
|
|
116
|
+
int
|
|
117
|
+
lwpoint_getPoint2d_p(const LWPOINT *point, POINT2D *out)
|
|
118
|
+
{
|
|
119
|
+
return getPoint2d_p(point->point, 0, out);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* convenience functions to hide the POINTARRAY */
|
|
123
|
+
int
|
|
124
|
+
lwpoint_getPoint3dz_p(const LWPOINT *point, POINT3DZ *out)
|
|
125
|
+
{
|
|
126
|
+
return getPoint3dz_p(point->point,0,out);
|
|
127
|
+
}
|
|
128
|
+
int
|
|
129
|
+
lwpoint_getPoint3dm_p(const LWPOINT *point, POINT3DM *out)
|
|
130
|
+
{
|
|
131
|
+
return getPoint3dm_p(point->point,0,out);
|
|
132
|
+
}
|
|
133
|
+
int
|
|
134
|
+
lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
|
|
135
|
+
{
|
|
136
|
+
return getPoint4d_p(point->point,0,out);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* find length of this deserialized point */
|
|
140
|
+
size_t
|
|
141
|
+
lwpoint_serialize_size(LWPOINT *point)
|
|
142
|
+
{
|
|
143
|
+
size_t size = 1; /* type */
|
|
144
|
+
|
|
145
|
+
LWDEBUG(2, "lwpoint_serialize_size called");
|
|
146
|
+
|
|
147
|
+
if ( point->SRID != -1 ) size += 4; /* SRID */
|
|
148
|
+
if ( point->bbox ) size += sizeof(BOX2DFLOAT4);
|
|
149
|
+
|
|
150
|
+
size += TYPE_NDIMS(point->type) * sizeof(double); /* point */
|
|
151
|
+
|
|
152
|
+
LWDEBUGF(3, "lwpoint_serialize_size returning %d", size);
|
|
153
|
+
|
|
154
|
+
return size;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/*
|
|
158
|
+
* Construct a new point. point will not be copied
|
|
159
|
+
* use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
|
|
160
|
+
*/
|
|
161
|
+
LWPOINT *
|
|
162
|
+
lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *point)
|
|
163
|
+
{
|
|
164
|
+
LWPOINT *result ;
|
|
165
|
+
|
|
166
|
+
if (point == NULL)
|
|
167
|
+
return NULL; /* error */
|
|
168
|
+
|
|
169
|
+
result = lwalloc(sizeof(LWPOINT));
|
|
170
|
+
result->type = lwgeom_makeType_full(TYPE_HASZ(point->dims), TYPE_HASM(point->dims), (SRID!=-1), POINTTYPE, 0);
|
|
171
|
+
result->SRID = SRID;
|
|
172
|
+
result->point = point;
|
|
173
|
+
result->bbox = bbox;
|
|
174
|
+
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
LWPOINT *
|
|
179
|
+
make_lwpoint2d(int SRID, double x, double y)
|
|
180
|
+
{
|
|
181
|
+
POINT2D p;
|
|
182
|
+
POINTARRAY *pa = ptarray_construct(0, 0, 1);
|
|
183
|
+
|
|
184
|
+
p.x = x;
|
|
185
|
+
p.y = y;
|
|
186
|
+
|
|
187
|
+
memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT2D));
|
|
188
|
+
|
|
189
|
+
return lwpoint_construct(SRID, NULL, pa);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
LWPOINT *
|
|
193
|
+
make_lwpoint3dz(int SRID, double x, double y, double z)
|
|
194
|
+
{
|
|
195
|
+
POINT3DZ p;
|
|
196
|
+
POINTARRAY *pa = ptarray_construct(1, 0, 1);
|
|
197
|
+
|
|
198
|
+
p.x = x;
|
|
199
|
+
p.y = y;
|
|
200
|
+
p.z = z;
|
|
201
|
+
|
|
202
|
+
memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DZ));
|
|
203
|
+
|
|
204
|
+
return lwpoint_construct(SRID, NULL, pa);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
LWPOINT *
|
|
208
|
+
make_lwpoint3dm(int SRID, double x, double y, double m)
|
|
209
|
+
{
|
|
210
|
+
POINTARRAY *pa = ptarray_construct(0, 1, 1);
|
|
211
|
+
POINT3DM p;
|
|
212
|
+
|
|
213
|
+
p.x = x;
|
|
214
|
+
p.y = y;
|
|
215
|
+
p.m = m;
|
|
216
|
+
|
|
217
|
+
memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DM));
|
|
218
|
+
|
|
219
|
+
return lwpoint_construct(SRID, NULL, pa);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
LWPOINT *
|
|
223
|
+
make_lwpoint4d(int SRID, double x, double y, double z, double m)
|
|
224
|
+
{
|
|
225
|
+
POINTARRAY *pa = ptarray_construct(1, 1, 1);
|
|
226
|
+
POINT4D p;
|
|
227
|
+
|
|
228
|
+
p.x = x;
|
|
229
|
+
p.y = y;
|
|
230
|
+
p.z = z;
|
|
231
|
+
p.m = m;
|
|
232
|
+
|
|
233
|
+
memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT4D));
|
|
234
|
+
|
|
235
|
+
return lwpoint_construct(SRID, NULL, pa);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/*
|
|
239
|
+
* Given the LWPOINT serialized form (or a pointer into a muli* one)
|
|
240
|
+
* construct a proper LWPOINT.
|
|
241
|
+
* serialized_form should point to the 8bit type format (with type = 1)
|
|
242
|
+
* See serialized form doc
|
|
243
|
+
*/
|
|
244
|
+
LWPOINT *
|
|
245
|
+
lwpoint_deserialize(uchar *serialized_form)
|
|
246
|
+
{
|
|
247
|
+
uchar type;
|
|
248
|
+
int geom_type;
|
|
249
|
+
LWPOINT *result;
|
|
250
|
+
uchar *loc = NULL;
|
|
251
|
+
POINTARRAY *pa;
|
|
252
|
+
|
|
253
|
+
LWDEBUG(2, "lwpoint_deserialize called");
|
|
254
|
+
|
|
255
|
+
result = (LWPOINT*) lwalloc(sizeof(LWPOINT)) ;
|
|
256
|
+
|
|
257
|
+
type = serialized_form[0];
|
|
258
|
+
geom_type = lwgeom_getType(type);
|
|
259
|
+
|
|
260
|
+
if ( geom_type != POINTTYPE)
|
|
261
|
+
{
|
|
262
|
+
lwerror("lwpoint_deserialize: attempt to deserialize a point which is really a %s", lwgeom_typename(geom_type));
|
|
263
|
+
return NULL;
|
|
264
|
+
}
|
|
265
|
+
result->type = type;
|
|
266
|
+
|
|
267
|
+
loc = serialized_form+1;
|
|
268
|
+
|
|
269
|
+
if (lwgeom_hasBBOX(type))
|
|
270
|
+
{
|
|
271
|
+
LWDEBUG(3, "lwpoint_deserialize: input has bbox");
|
|
272
|
+
|
|
273
|
+
result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
|
|
274
|
+
memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
|
|
275
|
+
loc += sizeof(BOX2DFLOAT4);
|
|
276
|
+
}
|
|
277
|
+
else
|
|
278
|
+
{
|
|
279
|
+
result->bbox = NULL;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if ( lwgeom_hasSRID(type))
|
|
283
|
+
{
|
|
284
|
+
LWDEBUG(3, "lwpoint_deserialize: input has SRID");
|
|
285
|
+
|
|
286
|
+
result->SRID = lw_get_int32(loc);
|
|
287
|
+
loc += 4; /* type + SRID */
|
|
288
|
+
}
|
|
289
|
+
else
|
|
290
|
+
{
|
|
291
|
+
result->SRID = -1;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* we've read the type (1 byte) and SRID (4 bytes, if present) */
|
|
295
|
+
|
|
296
|
+
pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), 1);
|
|
297
|
+
|
|
298
|
+
result->point = pa;
|
|
299
|
+
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
void lwpoint_free(LWPOINT *pt)
|
|
304
|
+
{
|
|
305
|
+
if(pt->point)
|
|
306
|
+
ptarray_free(pt->point);
|
|
307
|
+
lwfree(pt);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
void printLWPOINT(LWPOINT *point)
|
|
311
|
+
{
|
|
312
|
+
lwnotice("LWPOINT {");
|
|
313
|
+
lwnotice(" ndims = %i", (int)TYPE_NDIMS(point->type));
|
|
314
|
+
lwnotice(" BBOX = %i", TYPE_HASBBOX(point->type) ? 1 : 0 );
|
|
315
|
+
lwnotice(" SRID = %i", (int)point->SRID);
|
|
316
|
+
printPA(point->point);
|
|
317
|
+
lwnotice("}");
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
int
|
|
321
|
+
lwpoint_compute_box2d_p(LWPOINT *point, BOX2DFLOAT4 *box)
|
|
322
|
+
{
|
|
323
|
+
return ptarray_compute_box2d_p(point->point, box);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/* Clone LWPOINT object. POINTARRAY is not copied. */
|
|
327
|
+
LWPOINT *
|
|
328
|
+
lwpoint_clone(const LWPOINT *g)
|
|
329
|
+
{
|
|
330
|
+
LWPOINT *ret = lwalloc(sizeof(LWPOINT));
|
|
331
|
+
|
|
332
|
+
LWDEBUG(2, "lwpoint_clone called");
|
|
333
|
+
|
|
334
|
+
memcpy(ret, g, sizeof(LWPOINT));
|
|
335
|
+
if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
|
|
336
|
+
return ret;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/*
|
|
340
|
+
* Add 'what' to this point at position 'where'.
|
|
341
|
+
* where=0 == prepend
|
|
342
|
+
* where=-1 == append
|
|
343
|
+
* Returns a MULTIPOINT or a GEOMETRYCOLLECTION
|
|
344
|
+
*/
|
|
345
|
+
LWGEOM *
|
|
346
|
+
lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what)
|
|
347
|
+
{
|
|
348
|
+
LWCOLLECTION *col;
|
|
349
|
+
LWGEOM **geoms;
|
|
350
|
+
int newtype;
|
|
351
|
+
|
|
352
|
+
if ( where != -1 && where != 0 )
|
|
353
|
+
{
|
|
354
|
+
lwerror("lwpoint_add only supports 0 or -1 as second argument, got %d", where);
|
|
355
|
+
return NULL;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/* dimensions compatibility are checked by caller */
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
/* Construct geoms array */
|
|
362
|
+
geoms = lwalloc(sizeof(LWGEOM *)*2);
|
|
363
|
+
if ( where == -1 ) /* append */
|
|
364
|
+
{
|
|
365
|
+
geoms[0] = lwgeom_clone((LWGEOM *)to);
|
|
366
|
+
geoms[1] = lwgeom_clone(what);
|
|
367
|
+
}
|
|
368
|
+
else /* prepend */
|
|
369
|
+
{
|
|
370
|
+
geoms[0] = lwgeom_clone(what);
|
|
371
|
+
geoms[1] = lwgeom_clone((LWGEOM *)to);
|
|
372
|
+
}
|
|
373
|
+
/* reset SRID and wantbbox flag from component types */
|
|
374
|
+
lwgeom_dropSRID(geoms[0]);
|
|
375
|
+
lwgeom_drop_bbox(geoms[0]);
|
|
376
|
+
lwgeom_dropSRID(geoms[1]);
|
|
377
|
+
lwgeom_drop_bbox(geoms[1]);
|
|
378
|
+
|
|
379
|
+
/* Find appropriate geom type */
|
|
380
|
+
if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE;
|
|
381
|
+
else newtype = COLLECTIONTYPE;
|
|
382
|
+
|
|
383
|
+
col = lwcollection_construct(newtype,
|
|
384
|
+
to->SRID, NULL,
|
|
385
|
+
2, geoms);
|
|
386
|
+
|
|
387
|
+
return (LWGEOM *)col;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/* Find length of this serialized point */
|
|
391
|
+
size_t
|
|
392
|
+
lwgeom_size_point(const uchar *serialized_point)
|
|
393
|
+
{
|
|
394
|
+
uint32 result = 1;
|
|
395
|
+
uchar type;
|
|
396
|
+
const uchar *loc;
|
|
397
|
+
|
|
398
|
+
type = serialized_point[0];
|
|
399
|
+
|
|
400
|
+
if ( lwgeom_getType(type) != POINTTYPE) return 0;
|
|
401
|
+
|
|
402
|
+
LWDEBUGF(2, "lwgeom_size_point called (%d)", result);
|
|
403
|
+
|
|
404
|
+
loc = serialized_point+1;
|
|
405
|
+
|
|
406
|
+
if (lwgeom_hasBBOX(type))
|
|
407
|
+
{
|
|
408
|
+
loc += sizeof(BOX2DFLOAT4);
|
|
409
|
+
result +=sizeof(BOX2DFLOAT4);
|
|
410
|
+
|
|
411
|
+
LWDEBUGF(3, "lwgeom_size_point: has bbox (%d)", result);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if ( lwgeom_hasSRID(type))
|
|
415
|
+
{
|
|
416
|
+
LWDEBUGF(3, "lwgeom_size_point: has srid (%d)", result);
|
|
417
|
+
|
|
418
|
+
loc +=4; /* type + SRID */
|
|
419
|
+
result +=4;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
result += lwgeom_ndims(type)*sizeof(double);
|
|
423
|
+
|
|
424
|
+
return result;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
void
|
|
428
|
+
lwpoint_release(LWPOINT *lwpoint)
|
|
429
|
+
{
|
|
430
|
+
lwgeom_release(lwpoint_as_lwgeom(lwpoint));
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
/* check coordinate equality */
|
|
435
|
+
char
|
|
436
|
+
lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
|
|
437
|
+
{
|
|
438
|
+
return ptarray_same(p1->point, p2->point);
|
|
439
|
+
}
|