Skip to content

Instantly share code, notes, and snippets.

@Hiyorimi
Created February 7, 2019 12:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hiyorimi/935dd1938b1e1cd652748c32b68b4e74 to your computer and use it in GitHub Desktop.
Save Hiyorimi/935dd1938b1e1cd652748c32b68b4e74 to your computer and use it in GitHub Desktop.
GeoHashingResearch
package main
import (
"bufio"
"flag"
"fmt"
"io"
"log"
"os"
"strconv"
"strings"
"github.com/mmcloughlin/geohash"
)
// ParseFloatsFile loads any number of float64 values from text file, returning
// N x M_i [][]float64 slice, where N is number of lines and M_i — number of floats
// per singline line in the input file.
func ParseFloatsFile(fileNamePtr *string) ([][]float64, error) {
var err error
var floats [][]float64
var lineFloats []float64
// Open the file
txtFile, err := os.Open(*fileNamePtr)
if err != nil {
return floats, err
}
// Parse the file
r := bufio.NewReader(txtFile)
// Iterate through the records
for {
// Read each line from file
lineString, err := r.ReadString('\n')
if err == io.EOF {
break
}
if err != nil {
return floats, err
}
linePoints := strings.Split(lineString, ";")
lineFloats = []float64{}
for _, entry := range linePoints {
if len(entry) > 3 {
trimmededEntry := strings.Trim(entry, "\n\r")
splitLineFloats := strings.Split(trimmededEntry, ",")
for _, valueAsString := range splitLineFloats {
value, conversionError := strconv.ParseFloat(valueAsString, 64)
if conversionError != nil {
return floats, err
}
lineFloats = append(lineFloats, value)
}
}
}
floats = append(floats, lineFloats)
}
return floats, err
}
func testPrecision(coordsSlice [][2]float64, precision uint) int {
var hashesCount map[uint64]int
var hash uint64
var ok bool
hashesCount = make(map[uint64]int)
for _, coordsPair := range coordsSlice {
lat := coordsPair[0]
long := coordsPair[1]
hash = geohash.EncodeIntWithPrecision(lat, long, precision)
_, ok = hashesCount[hash]
if !ok {
hashesCount[hash] = 1
} else {
hashesCount[hash]++
}
}
return len(hashesCount)
}
func main() {
var testValues [][2]float64
testFloatsFile := flag.String("f", "./test_values.txt", "Points to geohash. One pair separated with commas per line. Example: 25.2,22.2")
flag.Parse()
testData, err := ParseFloatsFile(testFloatsFile)
if err != nil {
log.Fatalln("Error parsing, ", err)
}
for _, lineSlice := range testData {
lat := lineSlice[0]
long := lineSlice[1]
testValues = append(testValues, [2]float64{lat, long})
}
fmt.Println("Precision\t# of different hashes\t# of points")
totalCount := len(testValues)
for i := 1; i < 65; i++ {
fmt.Printf("%d\t%d\t%d\n", i, testPrecision(testValues, uint(i)), totalCount)
}
}
59.992309,30.113443
60.096533,30.273693
59.960924,30.539487
59.866867,30.589095
59.726488,30.373295
59.848639,30.089489
59.944573,30.331566
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment