Dan
Dan

Reputation: 12074

Determine all geohashes for a given level

I am using the R package geohashTools and I'd like to know all possible geohashes for a given level/precision. One way to do this is brute force.

# All possible coordinates                                            
coord <- expand.grid(lon = seq(-180, 180, 0.1),                     
                     lat = seq(-90, 89.9, 0.1))                       
                                                                      
# Load library                                                        
library(geohashTools)                                                 
                                                                      
# Get all unique geohashes                                            
geohashes <- unique(gh_encode(coord$lat, coord$lon, precision = 2L))  
                                                                      

While this works, I'm guessing at what the resolution of my grid needs to be and, consequently, I could miss geohashes if it is too coarse or it could be really inefficient if the grid is too fine.

Q: Is there a more efficient and effective way of determining all geohashes at a given level?

Upvotes: 2

Views: 548

Answers (1)

gvan
gvan

Reputation: 523

Using the possible characters from the 32-bit list used by geohashTools, you can construct the next level hash-codes by pasting each value onto the given prefix. A function like this works.

library(data.table)    

gh_fill <- function(geohashes, precision){
  if(uniqueN(nchar(geohashes)) > 1){
    stop("Input Geohashes must all have the same precision level.")
  }
  if(sum(grepl("['ailo]", geohashes)) > 0){
    stop("Invalid Geohash; Valid characters: [0123456789bcdefghjkmnpqrstuvwxyz]")
  }
  
  new_levels <- precision - nchar(geohashes[1])
  
  base32 <- unlist(strsplit("0123456789bcdefghjkmnpqrstuvwxyz", split = ""))
  
  grid <- do.call(CJ, append(list(geohashes), replicate(new_levels, base32, FALSE)))
  
  do.call(paste0, grid)
  
}

# Run like so: 
gh_fill("c6", 3L)
# or 
gh_fill(c("c6", "c7"), 3L)

Upvotes: 1

Related Questions