Alberto Bonsanto
Alberto Bonsanto

Reputation: 18022

How to efficiently convert a set of geohashes into a polygon?

I have been looking for a efficient way to convert a set of geohashes into polygons in Python, besides sometimes I obtain multipolygons instead of polygons, probably because some inner geohashes are missing. I am currently using python-geohash and shapely and my approach consists in the following steps:

  1. I convert each geohash into a polygon by extracting its corner coordinates.

    def to_polygon(geohash):
        box = Geohash.bbox(geohash)
        return Polygon([(box['e'], box['n']), (box['w'], box['n']), (box['w'], box['s']), (box['e'], box['s'])])
    
  2. Then I map over the iterable of geohashes performing previous explained transformation.

    polygons = [to_polygon(geohash) for geohash in geohashes]
    
  3. Finally, I combine all those polygons into a single one, by using polygon's method union.

    polygon = functools.reduce(lambda a, b: a.union(b), polygons)
    

If the set of geohashes is around some thousands it may take few minutes.

Upvotes: 4

Views: 7371

Answers (3)

CaRnAgE
CaRnAgE

Reputation: 63

Taking inspiration from the polygon_geohasher library Alberto Bonsanto mentioned, I rewrote it in Rust since that pure python version did not scale very well as the size of the input polygon increased. It's called rusty-polygon-geohasher (available on pypy), and is more than 3 times faster.

import geohash_polygon

polygon = shapely.geometry.Polygon([
    (-99.1795917, 19.432134), (-99.1656847, 19.429034),
    (-99.1776492, 19.414236), (-99.1795917, 19.432134)])

# returns {'9g3qr', '9g3qx'}
geohash_polygon.polygon_to_geohashes(polygon, 5, inner=False)

Upvotes: 0

Alberto Bonsanto
Alberto Bonsanto

Reputation: 18022

I created a library (polygon-geohasher) to achieve this:

from polygon_geohasher.polygon_geohasher import geohashes_to_polygon

geohashes = ['9bc1db2',
             '9bc1db6', 
             '9bc1db1', 
             '9bc1db0',
             '9bc1db4',
             '9bc1db9', 
             '9bc1db8',
             '9bc1dbd', 
             '9bc1db3']
polygon = geohashes_to_polygon(geohashes)
print(polygon) 
# POLYGON ((-99.71878051757812 4.483795166015625, -99.71878051757812 4.482421875, -99.72015380859375 4.482421875, -99.72152709960938 4.482421875, -99.722900390625 4.482421875, -99.722900390625 4.483795166015625, -99.722900390625 4.48516845703125, -99.722900390625 4.486541748046875, -99.72152709960938 4.486541748046875, -99.72015380859375 4.486541748046875, -99.71878051757812 4.486541748046875, -99.71878051757812 4.48516845703125, -99.71878051757812 4.483795166015625))

Upvotes: 6

Jorge Estevez
Jorge Estevez

Reputation: 31

Use geohashlite

# GeoHash to GeoJSON
converter_1 = geohashlite.GeoJsonHasher()
x = ['u09k', 'u095', 'u08g', 'u09h', 'u09e', 'u097']
converter_1.geohash_codes = x
converter_1.decode_geohash(multipolygon=True)
print(converter_1.geojson)

Upvotes: 3

Related Questions