Types and utilities for working with 2d geometry in Golang

Overview

orb CI codecov Go Report Card Go Reference

Package orb defines a set of types for working with 2d geo and planar/projected geometric data in Golang. There are a set of sub-packages that use these types to do interesting things. They each provider their own README with extra info.

Interesting features

  • Simple types - allow for natural operations using the make, append, len, [s:e] builtins.
  • GeoJSON - support as part of the geojson sub-package.
  • Mapbox Vector Tile - encoding and decoding as part of the encoding/mvt sub-package.
  • Direct to type from DB query results - by scanning WKB data directly into types.
  • Rich set of sub-packages - including clipping, simplifing, quadtree and more.

Type definitions

type Point [2]float64
type MultiPoint []Point

type LineString []Point
type MultiLineString []LineString

type Ring LineString
type Polygon []Ring
type MultiPolygon []Polygon

type Collection []Geometry

type Bound struct { Min, Max Point }

Defining the types as slices allows them to be accessed in an idiomatic way using Go's built-in functions such at make, append, len and with slice notation like [s:e]. For example:

ls := make(orb.LineString, 0, 100)
ls = append(ls, orb.Point{1, 1})
point := ls[0]

Shared Geometry interface

All of the base types implement the orb.Geometry interface defined as:

type Geometry interface {
	GeoJSONType() string
	Dimensions() int // e.g. 0d, 1d, 2d
	Bound() Bound
}

This interface is accepted by functions in the sub-packages which then act on the base types correctly. For example:

l := clip.Geometry(bound, geom)

will use the appropriate clipping algorithm depending on if the input is 1d or 2d, e.g. a orb.LineString or a orb.Polygon.

Only a few methods are defined directly on these type, for example Clone, Equal, GeoJSONType. Other operation that depend on geo vs. planar contexts are defined in the respective sub-package. For example:

  • Computing the geo distance between two point:

      p1 := orb.Point{-72.796408, -45.407131}
      p2 := orb.Point{-72.688541, -45.384987}
    
      geo.Distance(p1, p2)
    
  • Compute the planar area and centroid of a polygon:

      poly := orb.Polygon{...}
      centroid, area := planar.CentroidArea(poly)
    

GeoJSON

The geojson sub-package implements Marshalling and Unmarshalling of GeoJSON data. Features are defined as:

type Feature struct {
	ID         interface{}  `json:"id,omitempty"`
	Type       string       `json:"type"`
	Geometry   orb.Geometry `json:"geometry"`
	Properties Properties   `json:"properties"`
}

Defining the geometry as an orb.Geometry interface along with sub-package functions accepting geometries allows them to work together to create easy to follow code. For example, clipping all the geometries in a collection:

fc, err := geojson.UnmarshalFeatureCollection(data)
for _, f := range fc {
	f.Geometry = clip.Geometry(bound, f.Geometry)
}

Mapbox Vector Tiles

The encoding/mvt sub-package implements Marshalling and Unmarshalling MVT data. This package uses sets of geojson.FeatureCollection to define the layers, keyed by the layer name. For example:

collections := map[string]*geojson.FeatureCollection{}

// Convert to a layers object and project to tile coordinates.
layers := mvt.NewLayers(collections)
layers.ProjectToTile(maptile.New(x, y, z))

// In order to be used as source for MapboxGL geometries need to be clipped
// to max allowed extent. (uncomment next line)
// layers.Clip(mvt.MapboxGLDefaultExtentBound)

// Simplify the geometry now that it's in tile coordinate space.
layers.Simplify(simplify.DouglasPeucker(1.0))

// Depending on use-case remove empty geometry, those too small to be
// represented in this tile space.
// In this case lines shorter than 1, and areas smaller than 2.
layers.RemoveEmpty(1.0, 2.0)

// encoding using the Mapbox Vector Tile protobuf encoding.
data, err := layers.Marshal() // this data is NOT gzipped.

// Sometimes MVT data is stored and transfered gzip compressed. In that case:
data, err := layers.MarshalGzipped()

Decoding WKB from a database query

Geometries are usually returned from databases in WKB format. The encoding/wkb sub-package offers helpers to "scan" the data into the base types directly. For example:

row := db.QueryRow("SELECT ST_AsBinary(point_column) FROM postgis_table")

var p orb.Point
err := row.Scan(wkb.Scanner(&p))

db.Exec("INSERT INTO table (point_column) VALUES (ST_GeomFromWKB(?))", wkb.Value(p))

Scanning directly from MySQL columns is supported. By default MySQL returns geometry data as WKB but prefixed with a 4 byte SRID. To support this, if the data is not valid WKB, the code will strip the first 4 bytes, the SRID, and try again. This works for most use cases.

List of sub-package utilities

  • clip - clipping geometry to a bounding box
  • encoding/mvt - encoded and decoding from Mapbox Vector Tiles
  • encoding/wkb - well-known binary as well as helpers to decode from the database queries
  • encoding/wkt - well-known text encoding
  • geojson - working with geojson and the types in this package
  • maptile - working with mercator map tiles
  • project - project geometries between geo and planar contexts
  • quadtree - quadtree implementation using the types in this package
  • resample - resample points in a line string geometry
  • simplify - linear geometry simplifications like Douglas-Peucker
Comments
  • wkb: simplify byte order code

    wkb: simplify byte order code

    this PR refactors encoding/wkb/* to remove the custom type type byteOrder int and replace it with binary.ByteOrder. it also removes the constants const bigEndian and const littleEndian.

    this actually simplifies the code a fair bit since there is no need to write if conditions based on the desired endianness.

    let me know if this is something you'd consider merging and if there's anything else which needs to be done.

    I noticed a fair amount of code duplication between byteOrderType() & readByteOrderType(), I also considered refactoring those functions but didn't go that far in this PR.

    opened by missinglink 8
  • Add support for time data on Features as proposed in geojson-ld

    Add support for time data on Features as proposed in geojson-ld

    Add support for datetime information over Features as discussed at https://github.com/geojson/geojson-ld

    • See discution here: geojson/geojson-ld#9
    • See proposal here: https://gist.github.com/sgillies/11404768

    Example:

    {
      "geometry": {
        "coordinates": [
          0.0,
          0.0
        ],
        "type": "Point"
      },
      "id": "1",
      "properties": {"foo": "bar"},
      "type": "Feature",
      "when": {
        "datetime": "2014-04-24",
        "@type": "Instant"
      }
    }
    
    opened by flaviostutz 8
  • Add support for EWKB/EWKT

    Add support for EWKB/EWKT

    Hi! We're relying a lot at work on this package to handle geometries, and it works like a charm, but we have an issue when storing geometries inside postgis. We need to specify an SRID for the geometry, to obtain meaningful results with certain database operations, and we are currently converting back and forth between the geometries defined in go-geom and the geometries of orb, which is not ideal performance-wise. We still want to rely on orb for in-memory management of geometries, since it has lots of useful in-memory operations implemented.

    If it's ok with you I'd like to try and submit a PR to add support for EWKB/EWKT serialization. I'm just not sure on how to structure it, and how to share code between the current WKB/WKT implementation, so I'm open to suggestions on this topic.

    opened by asmeikal 5
  • Panic when reading geojson with null geometries in UnmarshallJSON()

    Panic when reading geojson with null geometries in UnmarshallJSON()

    I am writing a program using SA2 geometries from the Australian Statistical Standard Geography which I have converted into geojson with the below code snippet.

    curl http://www.ausstats.abs.gov.au/ausstats/subscriber.nsf/0/A09309ACB3FA50B8CA257FED0013D420/\$File/1270055001_sa2_2016_aust_shape.zip -o ../shapefiles/sa2_2016.zip
    
    unzip ../shapefiles/sa2_2016.zip
    unzip ../shapefiles/ste_2016.zip
    ogr2ogr -f Geojson /SA2_2016_AUST.geojson SA2_2016_AUST.shp
    

    When I try to run my code

    SA2b, _ := ioutil.ReadFile(filename)
    SA2, _ := geojson.UnmarshalFeatureCollection(SA2b)
    

    I receive the following panic error

    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    	panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x66961f]
    
    goroutine 1 [running]:
    encoding/json.(*decodeState).unmarshal.func1(0xc4200c5c18)
    	/usr/local/go/src/encoding/json/decode.go:175 +0xd4
    panic(0x6e71c0, 0x8eabd0)
    	/usr/local/go/src/runtime/panic.go:502 +0x229
    github.com/paulmach/orb/geojson.(*Feature).UnmarshalJSON(0xc42069b0e0, 0xc4304cdd1f, 0x1d1, 0x783ae33, 0x0, 0x7f318f62d840)
    	/media/fpmpdrive/fpmp/goyulo/src/github.com/paulmach/orb/geojson/feature.go:86 +0x21f
    encoding/json.(*decodeState).object(0xc4200ba240, 0x6efdc0, 0xc4200dfa00, 0x196)
    	/usr/local/go/src/encoding/json/decode.go:626 +0x1c9d
    encoding/json.(*decodeState).value(0xc4200ba240, 0x6efdc0, 0xc4200dfa00, 0x196)
    	/usr/local/go/src/encoding/json/decode.go:408 +0x2d3
    encoding/json.(*decodeState).array(0xc4200ba240, 0x6c8120, 0xc42530c0a8, 0x197)
    	/usr/local/go/src/encoding/json/decode.go:583 +0x1d0
    encoding/json.(*decodeState).value(0xc4200ba240, 0x6c8120, 0xc42530c0a8, 0x197)
    	/usr/local/go/src/encoding/json/decode.go:405 +0x266
    encoding/json.(*decodeState).object(0xc4200ba240, 0x6e83e0, 0xc42530c080, 0x16)
    	/usr/local/go/src/encoding/json/decode.go:776 +0x132d
    encoding/json.(*decodeState).value(0xc4200ba240, 0x6e83e0, 0xc42530c080, 0x16)
    	/usr/local/go/src/encoding/json/decode.go:408 +0x2d3
    encoding/json.(*decodeState).unmarshal(0xc4200ba240, 0x6e83e0, 0xc42530c080, 0x0, 0x0)
    	/usr/local/go/src/encoding/json/decode.go:189 +0x1e7
    encoding/json.Unmarshal(0xc42bd76000, 0xbf92952, 0xbf92b52, 0x6e83e0, 0xc42530c080, 0xbf92952, 0xbf92b52)
    	/usr/local/go/src/encoding/json/decode.go:108 +0x148
    github.com/paulmach/orb/geojson.UnmarshalFeatureCollection(0xc42bd76000, 0xbf92952, 0xbf92b52, 0xbf92952, 0xbf92b52, 0x0)
    	/media/fpmpdrive/fpmp/goyulo/src/github.com/paulmach/orb/geojson/feature_collection.go:58 +0x6e
    main.main()
    	/media/fpmpdrive/fpmp/goyulo/src/yuloserver/main.go:61 +0x225
    exit status 2
    
    

    This was apparently caused missing geometries in the file (for statistical geographical classifications with no true spatial elements) and subsequently a pointer error when UnmarshallJSON. I fixed this by removing features will missing geometries in Python and resaving the file.

    This scenario may well happen again to other users, especially if other data providers include features without spatial elements. Do you think it wise to put a check in to see if the geometry is present, or provide a specific error message?

    opened by GeoWonk 5
  • incorrect result from Quadkey()

    incorrect result from Quadkey()

    As per bing maps, given tile XY coordinates of (3, 5) at level 3, the result should be a string “213”.

    But Quadkey() from orb package for the same tile returns a uint64 of 39. Why are the results different? func (t Tile) Quadkey() uint64

    opened by rythmkraze 5
  • Would you be open to changing the signatures in maptile/tilecover ?

    Would you be open to changing the signatures in maptile/tilecover ?

    Specifically, changing the return values from maptile.Set to (maptile.Set, error)

    My concern is that the /maptile/tilecover/polygon.go code triggers a panic if it encounters an invalid geometry and it would be helpful for the package to return an error that I can handle in my application code rather than all the scaffolding necessary to trap and recover from a panic.

    I am happy to do the work to produce a PR but figured I would see whether this was interesting to you, first.

    opened by thisisaaronland 4
  • Issue when retrieving postgis geometry

    Issue when retrieving postgis geometry

    I've spend a couple of hours trying to figure out what doesn't work with my use-case (postgreSQL, postGIS, go-pg and orb)

    I have a complicated SELECT query (2 joins and 1 pivot) that I will simplify for this thread. The problem occurs during the Scan of a polygon

    p := orb.Polygon{}
    _, err := b.Database.Query(wkb.Scanner(&p), `SELECT ST_AsBinary(jobs.region,'NDR') FROM jobs LIMIT 1`, id)
    

    The returned error:

    Expected
              <internal.Error>: {
                  s: "wkb: invalid data",
              }
          to be nil
    

    I dig in the code and found that the error occurs here: https://github.com/paulmach/orb/blob/5af0ae28533d2d7038e9e103c43ccc6d8d0d05a6/encoding/wkb/wkb.go#L218-L244

    I added some logs to print the actual data and I got this:

    \x01030000000200000005000000000000000000000000000000000000000000000000002440000000000000000000000000000024400000000000002440000000000000000000000000000024400000000000000000000000000000000005000000000000000000f03f000000000000f03f000000000000f03f0000000000000040000000000000004000000000000000400000000000000040000000000000f03f000000000000f03f000000000000f03f
    

    which seems to be a perfect WKB apart from the leading \x. When I use a online service like https://rodic.fr/blog/online-conversion-between-geometric-formats/ to convert the data it gives exactly what I inserted in the database --> POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 2,2 1,1 1))

    Any ideas ?

    opened by arthurgustin 4
  • Missing check if tile projected coordinates are in larger extent

    Missing check if tile projected coordinates are in larger extent

    In order to use the generated vector tiles as a source for mapbox all coordinates in a tile must not exceed a certain extent. (https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-vector)

    https://github.com/paulmach/orb/blob/1f34bf6ee9935efca353b8cc0e06396d347cf836/encoding/mvt/projection.go#L27-L31 Maybe the projection could also return if the point should be included or not?

    Was this check left out by choice?

    opened by karsten42 4
  • encoding/mvt: stable marshalling

    encoding/mvt: stable marshalling

    Hi! We've been using the library and are big fans. I've noticed one opportunity to (potentially) improve things. I'm trying to take an MD5 hash of the marshaled bytes to use as a fingerprint that I can compare with what the client sends me to see if they match, and it doesn't work quite right.

    Currently, encode_properties iterates over a map to encode. Since there are no guarantees on iteration order for go maps, the output can differ each time for the same input. In practice, I've found the iteration order to be different almost every time.

    func TestStableMarshalling(t *testing.T) { layers := NewLayers(loadGeoJSON(t, maptile.New(17896, 24449, 16))) values := make(map[string]bool)

    for i := 0; i < 100; i++ {
    	marshal, _ := Marshal(layers)
    	checksum := md5.Sum(marshal)
    	sum := hex.EncodeToString(checksum[:])
    	values[sum] = true
    }
    
    if len(values) != 1 {
    	t.Errorf("multiple values (%d) for marshalled bytes", len(values))
    }
    

    } The above test will typically produce 100 different md5 values.

    This change makes encode_properties stable by getting the keys to the map, sorting them, and iterating over them. The benchmark numbers are:

    Unstable:

    BenchmarkMarshal
    BenchmarkMarshal-16          	    1819	    606970 ns/op	  368286 B/op	    4790 allocs/op
    BenchmarkUnmarshal
    BenchmarkUnmarshal-16        	    4959	    245290 ns/op	  208822 B/op	    2468 allocs/op
    BenchmarkProjectToTile
    BenchmarkProjectToTile-16    	   14942	     80458 ns/op	    6672 B/op	     309 allocs/op
    BenchmarkProjectToGeo
    BenchmarkProjectToGeo-16     	   19521	     64411 ns/op	    6672 B/op	     309 allocs/op
    PASS
    

    Stable:

    BenchmarkMarshal
    BenchmarkMarshal-16          	    1363	    817600 ns/op	  411622 B/op	    5354 allocs/op
    BenchmarkUnmarshal
    BenchmarkUnmarshal-16        	    4479	    245967 ns/op	  208905 B/op	    2468 allocs/op
    BenchmarkProjectToTile
    BenchmarkProjectToTile-16    	   15022	     83612 ns/op	    6672 B/op	     309 allocs/op
    BenchmarkProjectToGeo
    BenchmarkProjectToGeo-16     	   19256	     61878 ns/op	    6672 B/op	     309 allocs/op
    PASS
    

    I'm happy to go whatever route you'd prefer here. I understand you may not want to impact the perf since the stability hasn't mattered up to now. I can perhaps add a separate method like MarshalStable?

    Much appreciated!

    opened by travisgrigsby 3
  • fix removal

    fix removal

    Without that extra cleanup step it was possible to create nodes with nil values and non-nil children in the middle of the tree which later lead to the removal of those orphans

    opened by Hades32 3
  • Quadtree KNearest not in sorted order

    Quadtree KNearest not in sorted order

    Inconsistent sorting of results slice with the KNearest function. The reduced test case below produces out of order results despite the recent enhancements in #67. Note that I am not passing the optional maxDistance attribute to KNearest.

    Expected result: results slice in closest to farther ordering Actual result: certain slice elements in unexpected ordering

    package main
    
    import (
    	"testing"
    
    	"github.com/paulmach/orb"
    	"github.com/paulmach/orb/geo"
    	"github.com/paulmach/orb/quadtree"
    )
    
    // place implements the orb.Pointer interface so that it may be added to a QuadTree
    type place struct {
    	Id       string // name of the city
    	Location orb.Point
    }
    
    func (p place) Point() orb.Point {
    	return p.Location
    }
    
    var destinations = []place{
    	{"Portland (Oregon)", orb.Point{-122.6784, 45.5152}},
    	{"Sydney", orb.Point{151.2093, -33.8688}},
    	{"Jakarta", orb.Point{106.8456, -6.200000}},
    	{"Tunis", orb.Point{10.181667, 36.806389}},
    	{"Paris", orb.Point{2.3522, 48.8566}},
    }
    
    func TestQuadtreeKnn(t *testing.T) {
    	qt := quadtree.New(orb.Bound{Min: orb.Point{-180, -90}, Max: orb.Point{180, 90}})
    	for _, dest := range destinations {
    		qt.Add(dest)
    	}
    	maxResults := 5
    
    	// for the following cities, find the maxResults nearest neighbours
    	fromCities := []place{
    		{"London", orb.Point{-0.118092, 51.509865}},
    	}
    
    	for _, from := range fromCities {
    		t.Run(from.Id, func(t *testing.T) {
    			t.Logf("%s : %d nearest places to %v \n", from.Id, maxResults, from.Location)
    			results := qt.KNearest(nil, from.Point(), maxResults)
    			prevKm := 0.0
    			for i, dest := range results {
    				p := dest.(place)
    				dKm := geo.DistanceHaversine(from.Location, p.Location) / 1000
    				t.Logf("[%s] at sorted index %d : %s, %.0f km away (%+v)\n", from.Id, i, p.Id, dKm, p.Location)
    				if prevKm > dKm {
    					t.Errorf("FAIL: Out of order results, previous = %.0f km > this = %.0f km", prevKm, dKm)
    				}
    				prevKm = dKm
    			}
    		})
    	}
    }
    
    opened by s8mathur 3
  • quadtree KNearest search is fickle

    quadtree KNearest search is fickle

    The algorithm fails to return k distinct values, depending of the input. the TestQuadtreeKNearest_sorted can be re-write like below and it will fail to return k distinct nodes :

    func TestQuadtreeKNearest_sorted(t *testing.T) {
    	q := quadtree.New(orb.Bound{Max: orb.Point{8, 8}})
    	q.Add(orb.Point{0, 0})
    	q.Add(orb.Point{1, 1})
    	q.Add(orb.Point{2, 2})
    	q.Add(orb.Point{3, 3})
    	q.Add(orb.Point{4, 4})
    	q.Add(orb.Point{5, 5})
    	q.Add(orb.Point{6, 6})
    	q.Add(orb.Point{7, 7})
    
    	nearest := q.KNearest(nil, orb.Point{5.25, 5.25}, 3)
    
    	expected := []orb.Point{{5, 5}, {6, 6}, {4, 4}}
    	for i, p := range expected {
    		if n := nearest[i].Point(); !n.Equal(p) {
    			t.Errorf("incorrect point %d: %v", i, n)
    		}
    	}
    }
    

    Actually, the algorithm returns this array : [[6 6] [4 4] [4 4]], instead of the correct expected [[5 5] [6 6] [4 4]]

    opened by sapiens-sapide 0
  • Polygon and line intersection coordinates

    Polygon and line intersection coordinates

    Hi!

    I'd like to know, how to rewrite this example from go.geo readme to use orb library:

    path := geo.NewPath()
    path.Push(geo.NewPoint(0, 0))
    path.Push(geo.NewPoint(1, 1))
    
    line := geo.NewLine(geo.NewPoint(0, 1), geo.NewPoint(1, 0))
    
    // intersects does a simpler check for yes/no
    if path.Intersects(line) {
    	// intersection will return the actual points and places on intersection
    	points, segments := path.Intersection(line)
    
    	for i, _ := range points {
    		log.Printf("Intersection %d at %v with path segment %d", i, points[i], segments[i][0])
    	}
    }
    

    In my case I assume path points as polygon coordinates. Thanks!

    opened by lozitskiys 0
  • panic in wkt.Unmarshal

    panic in wkt.Unmarshal

    Hello! I found a panic in the wkt.Unmarshal function.

    Problem Panic occurs when using the wkt.Unmarshal function from orb/encoding/wkt package.

    How to reproduce

    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/paulmach/orb/encoding/wkt"
    )
    
    func main() {
    	input := "LINESTRING"
    	geom, err := wkt.Unmarshal(input)
    	if err != nil {
    		fmt.Printf("can't unmarshal: %v\n", err)
    		os.Exit(0)
    	}
    	fmt.Printf("unmarshaled geom: %v\n", geom)
    }
    

    Expected behavior I expect to get something like an invalid format error, or at least a panic with a message, like:

    can't unmarshal: incorrect WKT format
    

    Current behavior

    panic: runtime error: index out of range [0] with length 0
    
    goroutine 1 [running]:
    github.com/paulmach/orb/encoding/wkt.trimSpaceBrackets({0x0?, 0xa?})
            /home/kirill/go/pkg/mod/github.com/paulmach/[email protected]/encoding/wkt/unmarshal.go:125 +0x9c
    github.com/paulmach/orb/encoding/wkt.Unmarshal({0x4a26bf?, 0x53a780?})
            /home/kirill/go/pkg/mod/github.com/paulmach/[email protected]/encoding/wkt/unmarshal.go:256 +0x4df
    main.main()
            /home/kirill/go/src/github.com/sosiska/wkt/main.go:12 +0x29
    
    Process finished with the exit code 2
    
    opened by sosiska 0
  • The resulting MVT is too big (27MB)

    The resulting MVT is too big (27MB)

    Hi,

    I have a large geojson file (500 MB) that i try to load in mapboxgl for performance reasons I needed to convert into vector tiles.

    The issue is that it still return large mvt tiles size (around 27MB) which causes the mapbox to hang and gets laggy.

    Is there a way to limit the number of features that is projected to a tile ?

    opened by SulimanLab 2
  • copy the original mvt.Layers for reuse

    copy the original mvt.Layers for reuse

    Hi there,

    I am trying to build a tileserver that reads geojson and serve tiles

    I started by reading the json file:

    geojsonData, err := ioutil.ReadFile("./data/large_data.geojson")
    

    then I unmarshal the file to go object:

    r = map[string]*geojson.FeatureCollection{}
    err = json.Unmarshal(geojsonData, &r)
    
    layers := mvt.NewLayers(r)
    

    when serving the tiles the original values of the layers gets mutated, which force me to read and unmarshal the geojson again,

    I tried to copy layers so I don't modify the original layers, but still changing one changes the other.

    How I can copy the layers by value?

    opened by SulimanLab 3
Releases(v0.7.1)
  • v0.7.1(May 16, 2022)

    v0.7.0 initially pointed to the wrong commit. After moving the tag there are some caching issues in GitHub actions. I hope this clears up the issue.

    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(May 10, 2022)

    Breaking Change

    • tilecover now returns an error (vs. panicing) on non-closed 2d geometry by @paulmach in https://github.com/paulmach/orb/pull/87

      This changes the signature of many of the methods in the maptile/tilecover package. To emulate the old behavior replace:

      tiles := tilecover.Geometry(poly, zoom)
      

      with

      tiles, err := tilecover.Geometry(poly, zoom)
      if err != nil {
      	panic(err)
      }
      

    Full Changelog: https://github.com/paulmach/orb/compare/v0.6.0...v0.7.0

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(May 4, 2022)

    What's Changed

    • geo: add correctly spelled LengthHaversine by @paulmach in https://github.com/paulmach/orb/pull/97
    • geojson: add support for "external" json encoders/decoders by @paulmach in https://github.com/paulmach/orb/pull/98
    • Add ewkb encoding/decoding support by @paulmach in https://github.com/paulmach/orb/pull/88

    Full Changelog: https://github.com/paulmach/orb/compare/v0.5.0...v0.6.0

    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Apr 6, 2022)

    What's Changed

    • update protoscan to 0.2.1 by @paulmach in https://github.com/paulmach/orb/pull/83
    • encoding/mvt: stable marshalling by @travisgrigsby in https://github.com/paulmach/orb/pull/93
    • encoding/mvt: support mvt marshal for GeometryCollection by @dadadamarine in https://github.com/paulmach/orb/pull/89
    • quadtree: fix cleanup of nodes during removal by @paulmach in https://github.com/paulmach/orb/pull/94
    • encoding/wkt: various code improvements by @paulmach in https://github.com/paulmach/orb/pull/95

    New Contributors

    • @travisgrigsby made their first contribution in https://github.com/paulmach/orb/pull/93
    • @dadadamarine made their first contribution in https://github.com/paulmach/orb/pull/89

    Full Changelog: https://github.com/paulmach/orb/compare/v0.4.0...v0.5.0

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Nov 12, 2021)

    What's Changed

    • avoid reflect nil value by @nicklasaven in https://github.com/paulmach/orb/pull/78
    • Add functions to calculate points based on distance and bearing by @thzinc in https://github.com/paulmach/orb/pull/76

    New Contributors

    • @nicklasaven made their first contribution in https://github.com/paulmach/orb/pull/78
    • @thzinc made their first contribution in https://github.com/paulmach/orb/pull/76

    Full Changelog: https://github.com/paulmach/orb/compare/v0.3.0...v0.4.0

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Oct 16, 2021)

    What's Changed

    • ring: require >=4 points to return true when calling Closed() by @missinglink in https://github.com/paulmach/orb/pull/70
    • Address panic-ing quadtree.Matching(…) method when finding no closest node by @willsalz in https://github.com/paulmach/orb/pull/73
    • encoding/mvt: verify tile coord does not overflow for z > 20 by @paulmach in https://github.com/paulmach/orb/pull/74
    • quadtree: sort KNearest results closest first by @paulmach in https://github.com/paulmach/orb/pull/75

    New Contributors

    • @missinglink made their first contribution in https://github.com/paulmach/orb/pull/70
    • @willsalz made their first contribution in https://github.com/paulmach/orb/pull/73

    Full Changelog: https://github.com/paulmach/orb/compare/v0.2.2...v0.3.0

    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Jun 6, 2021)

    Fixed issue with dependency resolution in some cases, issue https://github.com/paulmach/orb/issues/65, pr https://github.com/paulmach/orb/pull/66

    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Jan 17, 2021)

    update some dependencies

    • encoding/mvt: upgrade protoscan v0.1 -> v0.2 https://github.com/paulmach/orb/commit/ad31566942027c1cd30dd341f35123fb54676599
    • encoding/mvt: remove github.com/pkg/errors as a dependency https://github.com/paulmach/orb/commit/d2e23529a295a0d973cc787ad2742cb6ccbd5306
    Source code(tar.gz)
    Source code(zip)
  • v0.2(Jan 16, 2021)

    This release has breaking changes involving some GeoJSON edge cases.

    1. Foreign Members in Feature Collections

      Extra attributes in a feature collection object will now be put into featureCollection.ExtraMembers. Similarly, stuff in `ExtraMembers will be marshalled into the feature collection base. The break happens if you were decoding these foreign members using something like

      type MyFeatureCollection struct {
          geojson.FeatureCollection
          Title string `json:"title"`
      }
      

      The above will no longer work in this release and it never supported marshalling. See https://github.com/paulmach/orb/pull/56 for more details.

    2. Features with nil/missing geometry will no longer return an errors

      Previously missing or invalid geometry in a feature collection would return a ErrInvalidGeometry error. However missing geometry is compliant with section 3.2 of the spec. See https://github.com/paulmach/orb/issues/38 and https://github.com/paulmach/orb/pull/58 for more details.

    This release also includes faster unmarshalling for Mapbox Vector Tiles (MVT) see https://github.com/paulmach/orb/pull/57

    9 commits https://github.com/paulmach/orb/compare/v0.1.7...v0.2

    Source code(tar.gz)
    Source code(zip)
  • v0.1.7(Nov 5, 2020)

    A few bug fixes along with major improvements to WKB scanning speed. Highlights:

    • https://github.com/paulmach/orb/commit/23fc488b247767b69fa1cf80b0bc4b94e4e74ce3 - wkb: new fast path for scan/unmarshal, bypass reader interface overhead.
    • https://github.com/paulmach/orb/commit/9d829076404014ff45b1ac219d07977502a8a51d - wkb: support mysql data prefixed by 4 byte srid
    • https://github.com/paulmach/orb/commit/5e61823b5a1ae872ccef374eff03df8d77893229 - fix panics in geojson decoding
    • and more...

    14 commits https://github.com/paulmach/orb/compare/v0.1.6...v0.1.7

    Source code(tar.gz)
    Source code(zip)
  • v0.1.5(Sep 24, 2019)

  • v0.1.2(Feb 15, 2019)

Owner
Paul Mach
Paul Mach
tools for working with streams of data

streamtools 4/1/2015 Development for streamtools has waned as our attention has turned towards developing a language paradigm that embraces blocking,

nytlabs 1.3k Nov 18, 2022
A well tested and comprehensive Golang statistics library package with no dependencies.

Stats - Golang Statistics Package A well tested and comprehensive Golang statistics library / package / module with no dependencies. If you have any s

Montana Flynn 2.6k Nov 22, 2022
:wink: :cyclone: :strawberry: TextRank implementation in Golang with extendable features (summarization, phrase extraction) and multithreading (goroutine) support (Go 1.8, 1.9, 1.10)

TextRank on Go This source code is an implementation of textrank algorithm, under MIT licence. The minimum requred Go version is 1.8. MOTIVATION If th

David Belicza 166 Nov 15, 2022
Implements a simple floating point arithmetic expression evaluator in Go (golang).

evaler https://github.com/soniah/evaler Package evaler implements a simple floating point arithmetic expression evaluator. Evaler uses Dijkstra's Shun

Sonia Hamilton 50 Sep 27, 2022
An ordinary differential equation solving library in golang.

ode An ordinary differential equation solving library in golang. Features Multi-dimensional state vector (i.e. extended states) Channel based stopping

Chris 20 Oct 19, 2022
Golang evasion tool, execute-assembly .Net file

?? Frog For Automatic Scan ?? Doge For Defense Evasion&Offensive Security Doge-Assembly Golang evasion tool, execute-assembly .Net file Intro Are you

TimWhite 83 Nov 22, 2022
DataFrames for Go: For statistics, machine-learning, and data manipulation/exploration

Dataframes are used for statistics, machine-learning, and data manipulation/exploration. You can think of a Dataframe as an excel spreadsheet. This pa

null 905 Nov 22, 2022
Gonum is a set of numeric libraries for the Go programming language. It contains libraries for matrices, statistics, optimization, and more

Gonum Installation The core packages of the Gonum suite are written in pure Go with some assembly. Installation is done using go get. go get -u gonum.

null 6.2k Nov 22, 2022
Package goraph implements graph data structure and algorithms.

goraph Package goraph implements graph data structure and algorithms. go get -v gopkg.in/gyuho/goraph.v2; I have tutorials and visualizations of grap

Gyuho Lee 699 Nov 18, 2022
Sparse matrix formats for linear algebra supporting scientific and machine learning applications

Sparse matrix formats Implementations of selected sparse matrix formats for linear algebra supporting scientific and machine learning applications. Co

James Bowman 136 Sep 27, 2022
2D triangulation library. Allows translating lines and polygons (both based on points) to the language of GPUs.

triangolatte 2D triangulation library. Allows translating lines and polygons (both based on points) to the language of GPUs. Features normal and miter

Tomasz Czajęcki 31 Nov 18, 2022
Polygol - Boolean polygon clipping/overlay operations (union, intersection, difference, xor) on Polygons and MultiPolygons

polygol Boolean polygon clipping/overlay operations (union, intersection, differ

Jon Engelsman 11 Oct 8, 2022
Types and utilities for working with 2d geometry in Golang

orb Package orb defines a set of types for working with 2d geo and planar/projected geometric data in Golang. There are a set of sub-packages that use

Paul Mach 601 Nov 27, 2022
Go types, funcs, and utilities for working with cards, decks, and evaluating poker hands (Holdem, Omaha, Stud, more)

cardrank.io/cardrank Package cardrank.io/cardrank provides a library of types, funcs, and utilities for working with playing cards, decks, and evaluat

null 60 Nov 8, 2022
Plugs module to see different types of plug types needed in different countries, and a comparison tool between two countries plug socket types.

plugs Importing the module: go get github.com/matthewboyd/plugs "github.com/matthewboyd/plugs" How to use the module: There are two functions wi

Matthew Boyd 2 Dec 28, 2021
Package geom implements efficient geometry types for geospatial applications.

go-geom Package geom implements efficient geometry types for geospatial applications. Key features OpenGeo Consortium-style geometries. Support for 2D

Tom Payne 636 Nov 16, 2022
Library providing opanapi3 and Go types for store/validation and transfer of ISO-4217, ISO-3166, and other types.

go-types This library has been created with the purpose to facilitate the store, validation, and transfer of Go ISO-3166/ISO-4217/timezones/emails/URL

Mikalai Konan 15 Nov 9, 2022
Some Golang types based on builtin. Implements interfaces Value / Scan and MarshalJSON / UnmarshalJSON for simple working with database NULL-values and Base64 encoding / decoding.

gotypes Some simple types based on builtin Golang types that implement interfaces for working with DB (Scan / Value) and JSON (Marshal / Unmarshal). N

null 0 Feb 12, 2022
CUE utilities and helpers for working with tree based objects in any combination of CUE, Yaml, and JSON.

Cuetils CUE utilities and helpers for working with tree based objects in any combination of CUE, Yaml, and JSON. Using As a command line binary The cu

_Hofstadter 63 Nov 16, 2022
Go linter that checks types that are json encoded - reports unsupported types and unnecessary error checks

Checks types passed to the json encoding functions. Reports unsupported types and reports occations, where the check for the returned error can be omited.

Lucas Bremgartner 28 Oct 7, 2022