'How to Convert Geohash to Geometry in BigQuery?

PostGIS has this function ST_GeomFromGeoHash to get the bounding box geometry of the geohash area (https://postgis.net/docs/ST_GeomFromGeoHash.html), but it has not been ported to BigQuery yet. Is there any workaround?



Solution 1:[1]

I've implemented the following BigQuery UDF that converts a geohash of arbitrary precision to a bounding box geometry:

CREATE OR REPLACE FUNCTION predictwise.geohash_to_bbox(geohash STRING) 
RETURNS STRING 
LANGUAGE js AS """
var BASE32_CODES = "0123456789bcdefghjkmnpqrstuvwxyz";
var BASE32_CODES_DICT = {};
for (var i = 0; i < BASE32_CODES.length; i++) {
  BASE32_CODES_DICT[BASE32_CODES.charAt(i)] = i;
}
var ENCODE_AUTO = 'auto';
var MIN_LAT = -90;
var MAX_LAT = 90;
var MIN_LON = -180;
var MAX_LON = 180;
var decode_bbox = function (hash_string) {
  var isLon = true,
    maxLat = MAX_LAT,
    minLat = MIN_LAT,
    maxLon = MAX_LON,
    minLon = MIN_LON,
    mid;
  var hashValue = 0;
  for (var i = 0, l = hash_string.length; i < l; i++) {
    var code = hash_string[i].toLowerCase();
    hashValue = BASE32_CODES_DICT[code];
    for (var bits = 4; bits >= 0; bits--) {
      var bit = (hashValue >> bits) & 1;
      if (isLon) {
        mid = (maxLon + minLon) / 2;
        if (bit === 1) {
          minLon = mid;
        } else {
          maxLon = mid;
        }
      } else {
        mid = (maxLat + minLat) / 2;
        if (bit === 1) {
          minLat = mid;
        } else {
          maxLat = mid;
        }
      }
      isLon = !isLon;
    }
  }
  
  return "POLYGON (( " + minLon + " " + minLat + ", " + maxLon + " " + minLat + ", " + maxLon + " " + maxLat + ", " + minLon + " " + maxLat + ", " + minLon + " " + minLat + "))";
};
return decode_bbox(geohash);
""";

Example usage:

select <dataset>.geohash_to_geom("ttnfv2u");

>> POLYGON((77.2119140625 28.6083984375, 77.2119140625 28.65234375, 77.255859375 28.65234375, 77.255859375 28.6083984375, 77.2119140625 28.6083984375)) 

Solution 2:[2]

BigQuery has ST_GEOGPOINTFROMGEOHASH which returns the central point. There is currently no function that returns the box though. The UDF in another answer is often a reasonable workaround, but you should be aware of its usage limitation.

GeoHash normally represents a rectangle on a flat 2D map. BigQuery works with Geography, with geodesic edges, so an edge between two points with same latitude does not follow the parallel, but being geodesic line is a shorter route closer to the pole. So the BigQuery polygon is a bit different from 2D box. You can often ignore the differences, but it might give you wrong results depending on how you use this polygon.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Michael Entin