rgeo

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 26, 2023 License: Apache-2.0 Imports: 12 Imported by: 0

README

rgeo

Codecov Release go.dev reference

Rgeo is a fast, simple solution for local reverse geocoding, Rather than relying on external software or online APIs, rgeo packages all of the data it needs in your binary. This means it will only ever work down to the level of cities , but if that's all you need then this is the library for you.

Rgeo uses data from naturalearthdata.com, if your coordinates are going to be near specific borders I would advise checking the data beforehand (links to which are in the files). If you want to use your own dataset, check out datagen.

Key Features

  • Fast - So I haven't actually benchmarked other reverse geocoding tools but on my laptop rgeo can run at under 800ns/op.
  • Local - Rgeo doesn't require pinging some API, most of which either cost money to use or have severe rate limits.
  • Lightweight - The rgeo repo is 32MB, which is large for a Go package but compared to the 800GB needed for a full planet install of Nominatim it's miniscule.

Installation

Download with

go get github.com/sams96/rgeo

and add

import "github.com/sams96/rgeo"

to the top of your Go file to include it in your project.

Usage

r, err := New(Provinces10, Cities10)
if err != nil {
	// Handle error
}

loc, err := r.ReverseGeocode([]float64{141.35, 43.07})
if err != nil {
	// Handle error
}

fmt.Println(loc)
// Output: <Location> Sapporo, Hokkaidō, Japan (JPN), Asia

First initialise rgeo using rgeo.New,

func New(datasets ...func() []byte) (*Rgeo, error)

which takes any non-zero number of datasets as arguments. The included datasets are:

  • Countries110 - Just country information, smallest and lowest detail of the included datasets.
  • Countries10 - The same as above but with more detail.
  • Provinces10 - Includes province information as well as country, so can still be used alone.
  • Cities10 - Just city information, if you want provinces and/or countries as well use one of the above datasets with it. Once initialised you can use ReverseGeocode on the value returned by New, with your coordinates to get the location information. See the Go Docs for more information on usage.

Then use ReverseGeocode to get the location information of the given coordinate.

func (r *Rgeo) ReverseGeocode(loc geom.Coord) (Location, error)

The input is a geom.Coord, which is just a []float64 with the longitude in the zeroth position and the latitude in the first position (i.e. []float64{lon, lat}). ReverseGeocode returns a Location, which looks like this:

type Location struct {
	// Commonly used country name
	Country string `json:"country,omitempty"`

	// Formal name of country
	CountryLong string `json:"country_long,omitempty"`

	// ISO 3166-1 alpha-1 and alpha-2 codes
	CountryCode2 string `json:"country_code_2,omitempty"`
	CountryCode3 string `json:"country_code_3,omitempty"`

	Continent string `json:"continent,omitempty"`
	Region    string `json:"region,omitempty"`
	SubRegion string `json:"subregion,omitempty"`

	Province string `json:"province,omitempty"`

	// ISO 3166-2 code
	ProvinceCode string `json:"province_code,omitempty"`

	City string `json:"city,omitempty"`
}

So, to put it all together:

r, err := rgeo.New(Countries110)
if err != nil {
	// Handle error
}

loc, err := r.ReverseGeocode([]float64{0, 52})
if err != nil {
	// Handle error
}

fmt.Printf("%s\n", loc.Country)
fmt.Printf("%s\n", loc.CountryLong)
fmt.Printf("%s\n", loc.CountryCode2)
fmt.Printf("%s\n", loc.CountryCode3)
fmt.Printf("%s\n", loc.Continent)
fmt.Printf("%s\n", loc.Region)
fmt.Printf("%s\n", loc.SubRegion)

// Output: United Kingdom
// United Kingdom of Great Britain and Northern Ireland
// GB
// GBR
// Europe
// Europe
// Northern Europe

Contributing

Contributions are welcome, I haven't got any guidelines or anything so maybe just make an issue first.

Projects using rgeo

Documentation

Overview

Package rgeo is a fast, simple solution for local reverse geocoding.

Rather than relying on external software or online APIs, rgeo packages all of the data it needs in your binary. This means it will only works down to the level of cities, but if that's all you need then this is the library for you.

rgeo uses data from https://naturalearthdata.com, if your coordinates are going to be near specific borders I would advise checking the data beforehand (links to which are in the files). If you want to use your own dataset, check out the datagen folder.

Installation

go get github.com/sams96/rgeo

Contributing

Contributions are welcome, I haven't got any guidelines or anything so maybe just make an issue first.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrLocationNotFound = errors.New("country not found")

ErrLocationNotFound is returned when no country is found for given coordinates.

Functions

func Cities10

func Cities10() []byte

func Countries10

func Countries10() []byte

func Countries110

func Countries110() []byte

func Provinces10

func Provinces10() []byte

Types

type Location

type Location struct {
	// Commonly used country name
	Country string `json:"country,omitempty"`

	// Formal name of country
	CountryLong string `json:"country_long,omitempty"`

	// ISO 3166-1 alpha-1 and alpha-2 codes
	CountryCode2 string `json:"country_code_2,omitempty"`
	CountryCode3 string `json:"country_code_3,omitempty"`

	Continent string `json:"continent,omitempty"`
	Region    string `json:"region,omitempty"`
	SubRegion string `json:"subregion,omitempty"`

	Province string `json:"province,omitempty"`

	// ISO 3166-2 code
	ProvinceCode string `json:"province_code,omitempty"`

	City string `json:"city,omitempty"`
}

Location is the return type for ReverseGeocode.

func (Location) String

func (l Location) String() string

String method for type Location.

type Rgeo

type Rgeo struct {
	// contains filtered or unexported fields
}

Rgeo is the type used to hold pre-created polygons for reverse geocoding.

func New

func New(datasets ...func() []byte) (*Rgeo, error)

New returns an Rgeo struct which can then be used with ReverseGeocode. It takes any number of datasets as an argument. The included datasets are: Countries110, Countries10, Provinces10 and Cities10. Provinces10 includes all of the country information so if that's all you want don't use Countries as well. Cities10 only includes cities so you'll probably want to use Provinces10 with it.

func (*Rgeo) ReverseGeocode

func (r *Rgeo) ReverseGeocode(loc geom.Coord) (Location, error)

ReverseGeocode returns the country in which the given coordinate is located.

The input is a geom.Coord, which is just a []float64 with the longitude in the zeroth position and the latitude in the first position (i.e. []float64{lon, lat}).

Example
r, err := New(Countries110)
if err != nil {
	// Handle error
}

loc, err := r.ReverseGeocode([]float64{0, 52})
if err != nil {
	// Handle error
}

fmt.Printf("%s\n", loc.Country)
fmt.Printf("%s\n", loc.CountryLong)
fmt.Printf("%s\n", loc.CountryCode2)
fmt.Printf("%s\n", loc.CountryCode3)
fmt.Printf("%s\n", loc.Continent)
fmt.Printf("%s\n", loc.Region)
fmt.Printf("%s\n", loc.SubRegion)
Output:

United Kingdom
United Kingdom of Great Britain and Northern Ireland
GB
GBR
Europe
Europe
Northern Europe
Example (City)
r, err := New(Provinces10, Cities10)
if err != nil {
	// Handle error
}

loc, err := r.ReverseGeocode([]float64{141.35, 43.07})
if err != nil {
	// Handle error
}

fmt.Println(loc)
Output:

<Location> Sapporo, Hokkaidō, Japan (JPN), Asia

func (*Rgeo) ReverseGeocodeSnapping

func (r *Rgeo) ReverseGeocodeSnapping(coord geom.Coord) (Location, error)

func (*Rgeo) SetSnappingDistanceCustom

func (r *Rgeo) SetSnappingDistanceCustom(d float64, radius float64)

SetSnappingDistanceCustom recalculates the underlying ChordAngle for the DistanceLimit of nearest-edge queries via ReverseGeocodeSnapping.

The inputs are the snapping distance on the sphere's surface in kilometers, and the radius of the sphere used in the dataset.

func (*Rgeo) SetSnappingDistanceEarth

func (r *Rgeo) SetSnappingDistanceEarth(d float64)

SetSnappingDistanceEarth sets ReverseGeocodeSnapping snap distance on Earth. Only edges within the defined radius around given points will be considered by ReverseGeocodeSnapping.

The input is the snapping distance in kilometers. Must be positive.

Directories

Path Synopsis
Command datagen converts GeoJSON files into go files containing functions that return the compressed GeoJSON, it can also merge properties from one GeoJSON file into another using the -merge flag (which it does by matching the country names).
Command datagen converts GeoJSON files into go files containing functions that return the compressed GeoJSON, it can also merge properties from one GeoJSON file into another using the -merge flag (which it does by matching the country names).

Jump to

Keyboard shortcuts

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