]> granicus.if.org Git - postgis/commitdiff
#1818: geohash patch hashbox to geom
authorRegina Obe <lr@pcorp.us>
Fri, 3 May 2013 04:04:22 +0000 (04:04 +0000)
committerRegina Obe <lr@pcorp.us>
Fri, 3 May 2013 04:04:22 +0000 (04:04 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@11341 b70326c6-7e19-0410-871a-916f4a2858ee

doc/reference_output.xml
liblwgeom/liblwgeom_internal.h
liblwgeom/lwalgorithm.c
postgis/Makefile.in
postgis/postgis.sql.in
regress/Makefile.in
utils/postgis_restore.pl.in

index 14ed7761d91dcdfec2e40bbc232b6afc1ed09dad..aeff8cfdfd5a6063f8f02b74c98d7b5597550eb7 100644 (file)
@@ -985,6 +985,172 @@ SELECT ST_GeoHash(ST_SetSRID(ST_MakePoint(-126,48),4326),5);
          </refsection>
        </refentry>
 
+       <refentry id="ST_Box2dFromGeoHash">
+         <refnamediv>
+               <refname>ST_Box2dFromGeoHash</refname>
+
+               <refpurpose>Return a BOX2D from a GeoHash string.</refpurpose>
+         </refnamediv>
+
+         <refsynopsisdiv>
+               <funcsynopsis>
+                       <funcprototype>
+                               <funcdef>box2d <function>ST_Box2dFromGeoHash</function></funcdef>
+                               <paramdef><type>text </type> <parameter>geohash</parameter></paramdef>
+                               <paramdef choice="opt"><type>integer </type> <parameter>precision=full_precision_of_geohash</parameter></paramdef>
+                       </funcprototype>
+               </funcsynopsis>
+         </refsynopsisdiv>
+
+         <refsection>
+               <title>Description</title>
+
+               <para>Return a BOX2D from a GeoHash string.</para>
+
+               <para>If no <varname>precision</varname> is specficified ST_Box2dFromGeoHash returns a BOX2D based on full precision of the input GeoHash string.</para>
+
+               <para>If <varname>precision</varname> is specified ST_Box2dFromGeoHash will use that many characters from the GeoHash to create the BOX2D. Lower precision values results in larger BOX2Ds and larger values increase the precision.</para>
+
+               <para>Availability: 2.1.0</para>
+         </refsection>
+
+         <refsection>
+               <title>Examples</title>
+               <programlisting><![CDATA[SELECT ST_Box2dFromGeoHash('9qqj7nmxncgyy4d0dbxqz0');
+
+                st_geomfromgeohash
+--------------------------------------------------
+ BOX(-115.172816 36.114646,-115.172816 36.114646)
+
+SELECT ST_Box2dFromGeoHash('9qqj7nmxncgyy4d0dbxqz0', 0);
+
+ st_box2dfromgeohash
+----------------------
+ BOX(-180 -90,180 90)
+
+ SELECT ST_Box2dFromGeoHash('9qqj7nmxncgyy4d0dbxqz0', 10);
+                            st_box2dfromgeohash
+---------------------------------------------------------------------------
+ BOX(-115.17282128334 36.1146408319473,-115.172810554504 36.1146461963654)
+               ]]>
+               </programlisting>
+         </refsection>
+        <refsection>
+               <title>See Also</title>
+
+               <para><xref linkend="ST_GeomFromGeoHash" />, <xref linkend="ST_PointFromGeoHash" /></para>
+         </refsection>
+       </refentry>
+
+       <refentry id="ST_PointFromGeoHash">
+         <refnamediv>
+               <refname>ST_PointFromGeoHash</refname>
+
+               <refpurpose>Return a point from a GeoHash string.</refpurpose>
+         </refnamediv>
+
+         <refsynopsisdiv>
+               <funcsynopsis>
+                       <funcprototype>
+                               <funcdef>point <function>ST_PointFromGeoHash</function></funcdef>
+                               <paramdef><type>text </type> <parameter>geohash</parameter></paramdef>
+                               <paramdef choice="opt"><type>integer </type> <parameter>precision=full_precision_of_geohash</parameter></paramdef>
+                       </funcprototype>
+               </funcsynopsis>
+         </refsynopsisdiv>
+
+         <refsection>
+               <title>Description</title>
+
+               <para>Return a point from a GeoHash string. The point represents the center point of the GeoHash.</para>
+
+               <para>If no <varname>precision</varname> is specficified ST_PointFromGeoHash returns a point based on full precision of the input GeoHash string.</para>
+
+               <para>If <varname>precision</varname> is specified ST_PointFromGeoHash will use that many characters from the GeoHash to create the point.</para>
+
+               <para>Availability: 2.1.0</para>
+         </refsection>
+
+         <refsection>
+               <title>Examples</title>
+               <programlisting><![CDATA[SELECT ST_AsText(ST_PointFromGeoHash('9qqj7nmxncgyy4d0dbxqz0'));
+          st_astext
+------------------------------
+ POINT(-115.172816 36.114646)
+
+SELECT ST_AsText(ST_PointFromGeoHash('9qqj7nmxncgyy4d0dbxqz0', 4));
+             st_astext
+-----------------------------------
+ POINT(-115.13671875 36.123046875)
+
+SELECT ST_AsText(ST_PointFromGeoHash('9qqj7nmxncgyy4d0dbxqz0', 10));
+                 st_astext
+-------------------------------------------
+ POINT(-115.172815918922 36.1146435141563)
+               ]]>
+               </programlisting>
+         </refsection>
+        <refsection>
+               <title>See Also</title>
+
+               <para><xref linkend="ST_Box2dFromGeoHash" />, <xref linkend="ST_GeomFromGeoHash" /></para>
+         </refsection>
+       </refentry>
+
+       <refentry id="ST_GeomFromGeoHash">
+         <refnamediv>
+               <refname>ST_GeomFromGeoHash</refname>
+
+               <refpurpose>Return a geometry from a GeoHash string.</refpurpose>
+         </refnamediv>
+
+         <refsynopsisdiv>
+               <funcsynopsis>
+                       <funcprototype>
+                               <funcdef>geometry <function>ST_GeomFromGeoHash</function></funcdef>
+                               <paramdef><type>text </type> <parameter>geohash</parameter></paramdef>
+                               <paramdef choice="opt"><type>integer </type> <parameter>precision=full_precision_of_geohash</parameter></paramdef>
+                       </funcprototype>
+               </funcsynopsis>
+         </refsynopsisdiv>
+
+         <refsection>
+               <title>Description</title>
+
+               <para>Return a geometry from a GeoHash string. The geometry will be a polygon representing the GeoHash bounds.</para>
+
+               <para>If no <varname>precision</varname> is specficified ST_GeomFromGeoHash returns a polygon based on full precision of the input GeoHash string.</para>
+
+               <para>If <varname>precision</varname> is specified ST_GeomFromGeoHash will use that many characters from the GeoHash to create the polygon.</para>
+
+               <para>Availability: 2.1.0</para>
+         </refsection>
+
+         <refsection>
+               <title>Examples</title>
+               <programlisting><![CDATA[SELECT ST_AsText(ST_GeomFromGeoHash('9qqj7nmxncgyy4d0dbxqz0'));
+                                                        st_astext
+--------------------------------------------------------------------------------------------------------------------------
+ POLYGON((-115.172816 36.114646,-115.172816 36.114646,-115.172816 36.114646,-115.172816 36.114646,-115.172816 36.114646))
+
+SELECT ST_AsText(ST_GeomFromGeoHash('9qqj7nmxncgyy4d0dbxqz0', 4));
+                                                          st_astext
+------------------------------------------------------------------------------------------------------------------------------
+ POLYGON((-115.3125 36.03515625,-115.3125 36.2109375,-114.9609375 36.2109375,-114.9609375 36.03515625,-115.3125 36.03515625))
+
+SELECT ST_AsText(ST_GeomFromGeoHash('9qqj7nmxncgyy4d0dbxqz0', 10));
+                                                                                       st_astext
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ POLYGON((-115.17282128334 36.1146408319473,-115.17282128334 36.1146461963654,-115.172810554504 36.1146461963654,-115.172810554504 36.1146408319473,-115.17282128334 36.1146408319473))
+               ]]>
+               </programlisting>
+         </refsection>
+        <refsection>
+               <title>See Also</title>
+
+               <para><xref linkend="ST_Box2dFromGeoHash" />, <xref linkend="ST_PointFromGeoHash" /></para>
+         </refsection>
+       </refentry>
 
        <refentry id="ST_AsText">
                  <refnamediv>
index 5cff2944aa8ceb429ff49812c04226b5bb3c8ce7..0e63d1a09e2445269f1d2360007c33b7600a4081 100644 (file)
@@ -260,6 +260,7 @@ LWCOLLECTION *lwpoint_clip_to_ordinate_range(const LWPOINT *mpoint, char ordinat
 */
 int lwgeom_geohash_precision(GBOX bbox, GBOX *bounds);
 char *geohash_point(double longitude, double latitude, int precision);
+void decode_geohash_bbox(char *geohash, double *lat, double *lon, int precision);
 
 /*
 * Point comparisons
index 17aeadc0b8b07c36a6fd772920e15c17f8c29ca6..db0d7014f4bc8a6927383691a0b616ea3add6f7e 100644 (file)
@@ -687,6 +687,52 @@ unsigned int geohash_point_as_int(POINT2D *pt)
        return ch;
 }
 
+/*
+** Decode a GeoHash into a bounding box. The lat and lon arguments should
+** both be passed as double arrays of length 2 at a minimum where the values
+** set in them will be the southwest and northeast coordinates of the bounding
+** box accordingly. A precision less than 0 indicates that the entire length
+** of the GeoHash should be used.
+*/
+void decode_geohash_bbox(char *geohash, double *lat, double *lon, int precision)
+{
+       int i, j, hashlen;
+       char c, cd, mask, is_even = 1;
+       static char bits[] = {16, 8, 4, 2, 1};
+
+       lat[0] = -90.0;
+       lat[1] = 90.0;
+       lon[0] = -180.0;
+       lon[1] = 180.0;
+
+       hashlen = strlen(geohash);
+
+       if (precision < 0 || precision > hashlen)
+       {
+               precision = hashlen;
+       }
+
+       for (i = 0; i < precision; i++)
+       {
+               c = tolower(geohash[i]);
+               cd = strchr(base32, c) - base32;
+
+               for (j = 0; j < 5; j++)
+               {
+                       mask = bits[j];
+                       if (is_even)
+                       {
+                               lon[!(cd & mask)] = (lon[0] + lon[1]) / 2;
+                       }
+                       else
+                       {
+                               lat[!(cd & mask)] = (lat[0] + lat[1]) / 2;
+                       }
+                       is_even = !is_even;
+               }
+       }
+}
+
 int lwgeom_geohash_precision(GBOX bbox, GBOX *bounds)
 {
        double minx, miny, maxx, maxy;
index cc6b5fde9ecd6533b87307e5b01ec5507221ed44..c0976fd5be565ad06f4875a0a5c28f942bb5ad2a 100644 (file)
@@ -43,6 +43,7 @@ PG_OBJS= \
        lwgeom_export.o \
        lwgeom_in_gml.o \
        lwgeom_in_kml.o \
+       lwgeom_in_geohash.o \
        lwgeom_in_geojson.o \
        lwgeom_triggers.o \
        lwgeom_dump.o \
index 0b8e5fd724593737bbd175129e310ba43c837354..1f7374d10e044a03b37f71eeb71ab7d46e6f556f 100644 (file)
@@ -3664,6 +3664,28 @@ CREATE OR REPLACE FUNCTION ST_GeoHash(geom geometry, maxchars int4 DEFAULT 0)
                AS 'MODULE_PATHNAME', 'ST_GeoHash'
        LANGUAGE 'c' IMMUTABLE STRICT;
 
+-----------------------------------------------------------------------
+-- GeoHash input
+-- Availability: 2.0.?
+-----------------------------------------------------------------------
+-- ST_Box2dFromGeoHash(geohash text, precision int4)
+CREATE OR REPLACE FUNCTION ST_Box2dFromGeoHash(text, int4 DEFAULT NULL)
+       RETURNS box2d
+       AS 'MODULE_PATHNAME','box2d_from_geohash'
+       LANGUAGE 'c' IMMUTABLE;
+
+-- ST_PointFromGeoHash(geohash text, precision int4)
+CREATE OR REPLACE FUNCTION ST_PointFromGeoHash(text, int4 DEFAULT NULL)
+       RETURNS geometry
+       AS 'MODULE_PATHNAME','point_from_geohash'
+       LANGUAGE 'c' IMMUTABLE;
+
+-- ST_GeomFromGeoHash(geohash text, precision int4)
+CREATE OR REPLACE FUNCTION ST_GeomFromGeoHash(text, int4 DEFAULT NULL)
+       RETURNS geometry
+       AS $$ SELECT CAST(ST_Box2dFromGeoHash($1, $2) AS geometry); $$
+       LANGUAGE 'sql' IMMUTABLE;
+
 ------------------------------------------------------------------------
 -- OGC defined
 ------------------------------------------------------------------------
index 63f861df44a06211865a0e151e49095654b49aa3..6560bd33249a5f73c1da4bbb8b3a70cd25544e86 100644 (file)
@@ -96,6 +96,7 @@ TESTS = \
        geography \
        out_geometry \
        out_geography \
+       in_geohash \
        in_gml \
        in_kml \
        iscollection \
index 4aa8c1eefaee862ca705c2b2c507127541f516fa..c14626b2af810724f40c2f1369435c5950747c68 100755 (executable)
@@ -777,6 +777,8 @@ COMMENT FUNCTION st_bdmpolyfromtext(text, integer)
 COMMENT FUNCTION st_bdpolyfromtext(text, integer)
 COMMENT FUNCTION st_boundary(geometry)
 COMMENT FUNCTION st_box2d(geometry)
+COMMENT FUNCTION st_box2dfromgeohash(text)
+COMMENT FUNCTION st_box2dfromgeohash(text, integer)
 COMMENT FUNCTION st_box3d(geometry)
 COMMENT FUNCTION st_buffer(geography, double precision)
 COMMENT FUNCTION st_buffer(geometry, double precision)
@@ -880,6 +882,8 @@ COMMENT FUNCTION st_geometrytype(geometry)
 COMMENT FUNCTION st_geomfromewkb(bytea)
 COMMENT FUNCTION st_geomfromewkt(text)
 COMMENT FUNCTION st_geomfromgeojson(text)
+COMMENT FUNCTION st_geomfromgeohash(text)
+COMMENT FUNCTION st_geomfromgeohash(text, integer)
 COMMENT FUNCTION st_geomfromgml(text)
 COMMENT FUNCTION st_geomfromgml(text, integer)
 COMMENT FUNCTION st_geomfromkml(text)
@@ -1050,6 +1054,8 @@ COMMENT FUNCTION st_pixelaspolygon(rast raster, xinteger, yinteger)
 COMMENT FUNCTION st_pixelheight(raster)
 COMMENT FUNCTION st_pixelwidth(raster)
 COMMENT FUNCTION st_point(double precision, double precision)
+COMMENT FUNCTION st_pointfromgeohash(text)
+COMMENT FUNCTION st_pointfromgeohash(text, integer)
 COMMENT FUNCTION st_pointfromtext(text)
 COMMENT FUNCTION st_pointfromtext(text, integer)
 COMMENT FUNCTION st_point_inside_circle(geometry, double precision, double precision, double precision)