fdbgeo

package module
v0.0.0-...-3e3ace4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2018 License: ISC Imports: 5 Imported by: 0

README

go-fdbgeo

GoDoc Go Report Card

go get -u github.com/umpc/go-fdbgeo

Package fdbgeo contains tools for building geospatial layers using FoundationDB with Geohash-encoded keys.

This package uses its complimentary zrange package, for performing geospatial range queries using FoundationDB with Geohash-encoded keys and a search radius.

The RadialRange method appears to be sufficient for range queries of around 5,000km or less. Changes that efficiently add support for larger query ranges are welcome here.

Note: As of 5/26/2018, changes from apple/foundationdb PR #408 must be applied to use this package, or a runtime panic will occur during subspace encoding.

Example usage

...

rangeParams := fdbgeo.RadialRangeParams{
  Subspace:  dir,
  Radius:    32.18688,
  Latitude:  37.334722,
  Longitude: -122.008889,
}

keyRanges := rangeParams.RadialRange()

fdbRangeOptions := fdb.RangeOptions{
  Mode: fdb.StreamingModeWantAll,
}

ret, err := db.ReadTransact(func(tr fdb.ReadTransaction) (ret interface{}, e error) {
  rangeResults := make([]fdb.RangeResult, len(keyRanges))

  for i, keyRange := range keyRanges {
    rangeResults[i] = tr.GetRange(keyRange, fdbRangeOptions)
  }

  var kvList []fdb.KeyValue
  for _, rangeResult := range rangeResults {
    ri := rangeResult.Iterator()

    for ri.Advance() {
      kv := ri.MustGet()

      geohashID, err := fdbgeo.UnpackUint(kv.Key, -2)
      if err != nil {
        panic(err)
      }

      // Running WithinRadius before value parsing may benefit performance,
      // though it depends on the data model in use.
      if !rangeParams.WithinRadius(geohashID) {
        continue
      }

      kvList = append(kvList, kv)
    }
  }

  return kvList, e
})

...

Note: Geohash range searches are imprecise. Results should be filtered using the input radius where precision is desired.

References

  • The RadialRange method was inspired by the algorithm in the "Search" section of this page.

Documentation

Overview

Package fdbgeo contains tools for building geospatial layers using FoundationDB with Geohash-encoded keys.

This package uses its complimentary "zrange" package: https://github.com/umpc/go-zrange, for performing geospatial range queries using FoundationDB with Geohash-encoded keys and a search radius.

The RadialRange method appears to be sufficient for range queries of around 5,000km or less. Changes that efficiently add support for larger query ranges are welcome here: https://github.com/umpc/go-zrange.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func UnpackUint

func UnpackUint(key fdb.Key, idx int) (uint64, error)

UnpackUint parses and returns a uint64 value from a key. A negative idx value is treated as relative to the end of the parsed key slice.

Types

type RadialRangeParams

type RadialRangeParams struct {
	BitsOfPrecision uint
	Radius,
	Latitude,
	Longitude float64
	Subspace subspace.Subspace
}

RadialRangeParams specifies arguments for the RadialRange method. A subspace will be prepended if one is set.

func (RadialRangeParams) RadialRange

func (params RadialRangeParams) RadialRange() []fdb.KeyRange

RadialRange uses a radius in kilometers, a latitude, and a longitude to return a slice of one or more ranges of keys that can be used to efficiently perform Geohash-based spatial queries.

This method uses an algorithm that was derived from the "Search" section of this page: https://web.archive.org/web/20180526044934/https://github.com/yinqiwen/ardb/wiki/Spatial-Index#search

RadialRange expands upon the ideas referenced above, by:

• Sorting key ranges

• Combining overlapping key ranges

• Handling overflows resulting from bitshifting, such as when querying for: (-90, -180)

func (RadialRangeParams) WithinRadius

func (params RadialRangeParams) WithinRadius(geohashID uint64) bool

WithinRadius determines whether a Geohash is within the specified radius. Running WithinRadius in a RangeIterator loop may double transaction time though make parsing more efficient. Its potential benefits are dependent on the data model in use.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL