PostGIS  2.5.2dev-r@@SVN_REVISION@@
lwgeom_in_geohash.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * PostGIS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * PostGIS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  **********************************************************************
20  *
21  * Copyright 2012 J Smith <dark.panda@gmail.com>
22  *
23  **********************************************************************/
24 
25 
26 #include <assert.h>
27 
28 #include "postgres.h"
29 #include "utils/builtins.h"
30 
31 #include "../postgis_config.h"
32 #include "lwgeom_pg.h"
33 #include "liblwgeom.h"
34 #include "liblwgeom_internal.h"/* for decode_geohash_bbox */
35 
36 Datum box2d_from_geohash(PG_FUNCTION_ARGS);
37 Datum point_from_geohash(PG_FUNCTION_ARGS);
38 
39 static void geohash_lwpgerror(char *msg, __attribute__((__unused__)) int error_code)
40 {
41  POSTGIS_DEBUGF(3, "ST_Box2dFromGeoHash ERROR %i", error_code);
42  lwpgerror("%s", msg);
43 }
44 
45 #include "lwgeom_export.h"
46 
47 static GBOX*
48 parse_geohash(char *geohash, int precision)
49 {
50  GBOX *box = NULL;
51  double lat[2], lon[2];
52 
53  POSTGIS_DEBUG(2, "parse_geohash called.");
54 
55  if (NULL == geohash)
56  {
57  geohash_lwpgerror("invalid GeoHash representation", 2);
58  }
59 
60  decode_geohash_bbox(geohash, lat, lon, precision);
61 
62  POSTGIS_DEBUGF(2, "ST_Box2dFromGeoHash sw: %.20f, %.20f", lon[0], lat[0]);
63  POSTGIS_DEBUGF(2, "ST_Box2dFromGeoHash ne: %.20f, %.20f", lon[1], lat[1]);
64 
65  box = gbox_new(gflags(0, 0, 1));
66 
67  box->xmin = lon[0];
68  box->ymin = lat[0];
69 
70  box->xmax = lon[1];
71  box->ymax = lat[1];
72 
73  POSTGIS_DEBUG(2, "parse_geohash finished.");
74  return box;
75 }
76 
78 Datum box2d_from_geohash(PG_FUNCTION_ARGS)
79 {
80  GBOX *box = NULL;
81  text *geohash_input = NULL;
82  char *geohash = NULL;
83  int precision = -1;
84 
85  if (PG_ARGISNULL(0))
86  {
87  PG_RETURN_NULL();
88  }
89 
90  if (!PG_ARGISNULL(1))
91  {
92  precision = PG_GETARG_INT32(1);
93  }
94 
95  geohash_input = PG_GETARG_TEXT_P(0);
96  geohash = text_to_cstring(geohash_input);
97 
98  box = parse_geohash(geohash, precision);
99 
100  PG_RETURN_POINTER(box);
101 }
102 
104 Datum point_from_geohash(PG_FUNCTION_ARGS)
105 {
106  GBOX *box = NULL;
107  LWPOINT *point = NULL;
108  GSERIALIZED *result = NULL;
109  text *geohash_input = NULL;
110  char *geohash = NULL;
111  double lon, lat;
112  int precision = -1;
113 
114  if (PG_ARGISNULL(0))
115  {
116  PG_RETURN_NULL();
117  }
118 
119  if (!PG_ARGISNULL(1))
120  {
121  precision = PG_GETARG_INT32(1);
122  }
123 
124  geohash_input = PG_GETARG_TEXT_P(0);
125  geohash = text_to_cstring(geohash_input);
126 
127  box = parse_geohash(geohash, precision);
128 
129  lon = box->xmin + (box->xmax - box->xmin) / 2;
130  lat = box->ymin + (box->ymax - box->ymin) / 2;
131 
132  point = lwpoint_make2d(SRID_UNKNOWN, lon, lat);
133  result = geometry_serialize((LWGEOM *) point);
134 
135  lwfree(box);
136 
137  PG_RETURN_POINTER(result);
138 }
char * text_to_cstring(const text *textptr)
GBOX * gbox_new(uint8_t flags)
Create a new gbox with the dimensionality indicated by the flags.
Definition: g_box.c:39
void lwfree(void *mem)
Definition: lwutil.c:244
LWPOINT * lwpoint_make2d(int srid, double x, double y)
Definition: lwpoint.c:163
#define __attribute__(x)
Definition: liblwgeom.h:200
double xmax
Definition: liblwgeom.h:295
void decode_geohash_bbox(char *geohash, double *lat, double *lon, int precision)
Definition: lwalgorithm.c:713
Datum point_from_geohash(PG_FUNCTION_ARGS)
static void geohash_lwpgerror(char *msg, __attribute__((__unused__)) int error_code)
PG_FUNCTION_INFO_V1(box2d_from_geohash)
double ymin
Definition: liblwgeom.h:296
double xmin
Definition: liblwgeom.h:294
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:187
uint8_t precision
Definition: cu_in_twkb.c:25
double ymax
Definition: liblwgeom.h:297
Datum box2d_from_geohash(PG_FUNCTION_ARGS)
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
static GBOX * parse_geohash(char *geohash, int precision)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
This library is the generic geometry handling section of PostGIS.