Skip to content

Commit

Permalink
Mega commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gdey committed Jul 5, 2016
1 parent 4a86c1a commit 39725bc
Show file tree
Hide file tree
Showing 41 changed files with 6,982 additions and 76 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Tegola aims to be a high performance vector tile server delivering [Mapbox Vector Tiles](https://github.com/mapbox/vector-tile-spec). The project aims to be written in pure Go.

## Near term goals
- [x] Support for transcoding WKB to MVT.
- [X] Support for transcoding WKB to MVT.
- [ ] Support for `/z/x/y` web mapping URL scheme.
- [ ] Support for PostGIS data provider.

Expand All @@ -12,4 +12,4 @@ Tegola aims to be a high performance vector tile server delivering [Mapbox Vecto
- [Mapbox Vector Tile (MVT) 2.1](https://github.com/mapbox/vector-tile-spec/tree/master/2.1)

## License
See [license](LICENSE.md) file in repo.
See (license)[LICENSE.md] file in repo.
4 changes: 4 additions & 0 deletions basic/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ func (c *Collection) Geometeries() (geometeries []tegola.Geometry) {
}
return geometeries
}

func (Collection) String() string {
return "Collectioin"
}
63 changes: 63 additions & 0 deletions basic/geometry_math.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package basic

import (
"fmt"

"github.com/terranodo/tegola"
)

func RehomeGeometry(geometery tegola.Geometry, ulx, uly float64) (tegola.Geometry, error) {
switch geo := geometery.(type) {
default:
return nil, fmt.Errorf("Unknown Geometry: %+v", geometery)
case tegola.Point:
return &Point{int(geo.X() - ulx), int(geo.Y() - uly)}, nil
case tegola.Point3:
return &Point3{int(geo.X() - ulx), int(geo.Y() - uly), int(geo.Z())}, nil
case tegola.MultiPoint:
var pts MultiPoint
for _, pt := range geo.Points() {
pts = append(pts, Point{int(pt.X() - ulx), int(pt.Y() - uly)})
}
return pts, nil
case tegola.LineString:
var line Line
for _, ptGeo := range geo.Subpoints() {
line = append(line, Point{int(ptGeo.X() - ulx), int(ptGeo.Y() - uly)})
}
return &line, nil
case tegola.MultiLine:
var line MultiLine
for i, lineGeo := range geo.Lines() {
geoLine, err := RehomeGeometry(lineGeo, ulx, uly)
if err != nil {
return nil, fmt.Errorf("Got error converting line(%v) of multiline: %v", i, err)
}
ln, _ := geoLine.(Line)
line = append(line, ln)
}
return line, nil
case tegola.Polygon:
var poly Polygon
for i, line := range geo.Sublines() {
geoLine, err := RehomeGeometry(line, ulx, uly)
if err != nil {
return nil, fmt.Errorf("Got error converting line(%v) of polygon: %v", i, err)
}
ln, _ := geoLine.(Line)
poly = append(poly, ln)
}
return &poly, nil
case tegola.MultiPolygon:
var mpoly MultiPolygon
for i, poly := range geo.Polygons() {
geoPoly, err := RehomeGeometry(poly, ulx, uly)
if err != nil {
return nil, fmt.Errorf("Got error converting poly(%v) of multipolygon: %v", i, err)
}
p, _ := geoPoly.(Polygon)
mpoly = append(mpoly, p)
}
return &mpoly, nil
}
}
5 changes: 4 additions & 1 deletion basic/line.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import "github.com/terranodo/tegola"
type Line []Point

// Just to make basic collection only usable with basic types.
func (Line) basicType() {}
func (Line) basicType() {}
func (Line) String() string { return "Line" }

// Subpoints return the points in a line.
func (l *Line) Subpoints() (points []tegola.Point) {
Expand All @@ -22,6 +23,8 @@ func (l *Line) Subpoints() (points []tegola.Point) {
// MultiLine is a set of lines.
type MultiLine []Line

func (MultiLine) String() string { return "Line" }

// Just to make basic collection only usable with basic types.
func (MultiLine) basicType() {}

Expand Down
13 changes: 13 additions & 0 deletions basic/point.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ func (bp *Point) Y() float64 {
return float64(bp[1])
}

func (*Point) String() string {
return "Point"
}

// Point3 describes a simple 3d point
type Point3 [3]int

Expand All @@ -28,6 +32,9 @@ func (Point3) basicType() {}
func (bp *Point3) X() float64 {
return float64(bp[0])
}
func (*Point3) String() string {
return "Point"
}

// Y is the y coordinate
func (bp *Point3) Y() float64 {
Expand All @@ -44,6 +51,9 @@ type MultiPoint []Point

// Just to make basic collection only usable with basic types.
func (MultiPoint) basicType() {}
func (*MultiPoint) String() string {
return "Point"
}

// Points are the points that make up the set
func (v *MultiPoint) Points() (points []tegola.Point) {
Expand All @@ -52,6 +62,9 @@ func (v *MultiPoint) Points() (points []tegola.Point) {
}
return points
}
func (*MultiPoint3) String() string {
return "Point"
}

// MultiPoint3 describes a simple set of 3d points
type MultiPoint3 []Point3
Expand Down
6 changes: 6 additions & 0 deletions basic/polygon.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ func (p *Polygon) Sublines() (slines []tegola.LineString) {
}
return slines
}
func (Polygon) String() string {
return "Polygon"
}

// MultiPolygon describes a set of polygons.
type MultiPolygon []Polygon
Expand All @@ -31,3 +34,6 @@ func (mp *MultiPolygon) Polygons() (polygons []tegola.Polygon) {
}
return polygons
}
func (MultiPolygon) String() string {
return "Polygon"
}
59 changes: 47 additions & 12 deletions mvt/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/terranodo/tegola"
"github.com/terranodo/tegola/mvt/vector_tile"
"github.com/terranodo/tegola/wkb"
)

// errors
Expand All @@ -30,6 +31,14 @@ type Feature struct {
Geometry tegola.Geometry
}

func (f Feature) String() string {
g := wkb.WKT(f.Geometry)
if f.ID != nil {
return fmt.Sprintf("{Feature: %v, GEO: %v, Tags: %+v}", *f.ID, g, f.Tags)
}
return fmt.Sprintf("{Feature: GEO: %v, Tags: %+v}", g, f.Tags)
}

//NewFeatures returns one or more features for the given Geometry
// TODO: Should we consider supporting validation of polygons and multiple polygons here?
func NewFeatures(geo tegola.Geometry, tags map[string]interface{}) (f []Feature) {
Expand All @@ -52,14 +61,14 @@ func NewFeatures(geo tegola.Geometry, tags map[string]interface{}) (f []Feature)
}

// VTileFeature will return a vectorTile.Feature that would represent the Feature
func (f *Feature) VTileFeature(keyMap []string, valMap []interface{}) (tf *vectorTile.Tile_Feature, err error) {
func (f *Feature) VTileFeature(keyMap []string, valMap []interface{}, trx, try float64, extent int) (tf *vectorTile.Tile_Feature, err error) {
tf = new(vectorTile.Tile_Feature)
tf.Id = f.ID
if tf.Tags, err = keyvalTagsMap(keyMap, valMap, f); err != nil {
return tf, err
}

geo, gtype, err := encodeGeometry(f.Geometry)
geo, gtype, err := encodeGeometry(f.Geometry, trx, try, extent)
if err != nil {
return tf, err
}
Expand All @@ -68,6 +77,7 @@ func (f *Feature) VTileFeature(keyMap []string, valMap []interface{}) (tf *vecto
return tf, nil
}

// These values came from: https://github.com/mapbox/vector-tile-spec/tree/master/2.1
const (
cmdMoveTo uint32 = 1
cmdLineTo uint32 = 2
Expand All @@ -81,11 +91,29 @@ const (
type cursor struct {
X int64
Y int64
// This is the upper left coord for the X coordinate. This value will be substracted
// from each point, before applying it to the movement commands
TLX float64
// This is the upper left coord for the Y coordinate. This value will be substracted
// from each point, before applying it to the movement commands
TLY float64
extent int
}

func encodeZigZag(i int64) uint32 {
return uint32((i << 1) ^ (i >> 31))
}
func (c *cursor) NormalizePoint(p tegola.Point) (nx, ny int64) {
nx = int64(p.X() - c.TLX)
ny = int64(p.Y() - c.TLY)
if nx > int64(c.extent) {
log.Printf("Point is greater then extent: %v — %v", nx, c.extent)
}
if ny > int64(c.extent) {
log.Printf("Point is greater then extent: %v — %v", ny, c.extent)
}
return nx, ny
}

func (c *cursor) MoveTo(points ...tegola.Point) []uint32 {
if len(points) == 0 {
Expand All @@ -99,13 +127,14 @@ func (c *cursor) MoveTo(points ...tegola.Point) []uint32 {

// range through our points
for _, p := range points {
ix, iy := c.NormalizePoint(p)
// computer our point delta
dx := int64(p.X()) - c.X
dy := int64(p.Y()) - c.Y
dx := ix - c.X
dy := iy - c.Y

// update our cursor
c.X = int64(p.X())
c.Y = int64(p.Y())
c.X = ix
c.Y = iy

// encode our delta point
g = append(g, encodeZigZag(dx), encodeZigZag(dy))
Expand All @@ -119,10 +148,11 @@ func (c *cursor) LineTo(points ...tegola.Point) []uint32 {
g := make([]uint32, 0, (2*len(points))+1)
g = append(g, (cmdLineTo&0x7)|(uint32(len(points))<<3))
for _, p := range points {
dx := int64(p.X()) - c.X
dy := int64(p.Y()) - c.Y
c.X = int64(p.X())
c.Y = int64(p.Y())
ix, iy := c.NormalizePoint(p)
dx := ix - c.X
dy := iy - c.Y
c.X = ix
c.Y = iy
g = append(g, encodeZigZag(dx), encodeZigZag(dy))
}
return g
Expand All @@ -134,8 +164,12 @@ func (c *cursor) ClosePath() uint32 {

// encodeGeometry will take a tegola.Geometry type and encode it according to the
// mapbox vector_tile spec.
func encodeGeometry(geo tegola.Geometry) (g []uint32, vtyp vectorTile.Tile_GeomType, err error) {
var c cursor
func encodeGeometry(geo tegola.Geometry, tlx, tly float64, extent int) (g []uint32, vtyp vectorTile.Tile_GeomType, err error) {
c := cursor{
TLX: tlx,
TLY: tly,
extent: extent,
}
switch t := geo.(type) {
case tegola.Point:
g = append(g, c.MoveTo(t)...)
Expand Down Expand Up @@ -188,6 +222,7 @@ func encodeGeometry(geo tegola.Geometry) (g []uint32, vtyp vectorTile.Tile_GeomT
return g, vectorTile.Tile_POLYGON, nil

default:
log.Printf("Geo: %v : %T", wkb.WKT(geo), geo)
return nil, vectorTile.Tile_UNKNOWN, ErrUnknownGeometryType
}
}
Expand Down
2 changes: 1 addition & 1 deletion mvt/feature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func TestEncodeGeometry(t *testing.T) {
},
}
for _, tcase := range testcases {
g, gtype, err := encodeGeometry(tcase.geo)
g, gtype, err := encodeGeometry(tcase.geo, 0, 0, 4096)
if tcase.eerr != err {
t.Errorf("Expected error (%v) got (%v) instead", tcase.eerr, err)
}
Expand Down
9 changes: 3 additions & 6 deletions mvt/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,19 @@ func valMapToVTileValue(valMap []interface{}) (vt []*vectorTile.Tile_Value) {
}

// VTileLayer returns a vectorTile Tile_Layer object that represents this Layer.
func (l *Layer) VTileLayer() (*vectorTile.Tile_Layer, error) {
func (l *Layer) VTileLayer(tlx, tly float64) (*vectorTile.Tile_Layer, error) {
kmap, vmap, err := keyvalMapsFromFeatures(l.features)
if err != nil {
return nil, err
}
valmap := valMapToVTileValue(vmap)
var features = make([]*vectorTile.Tile_Feature, 0, len(l.features))
for _, f := range l.features {
vtf, err := f.VTileFeature(kmap, vmap)
vtf, err := f.VTileFeature(kmap, vmap, tlx, tly, l.Extent())
if err != nil {
return nil, err
return nil, fmt.Errorf("Error getting VTileFeature: %v", err)
}
features = append(features, vtf)
if err != nil {
return nil, err
}
}
ext := uint32(l.Extent())
version := uint32(l.Version())
Expand Down
2 changes: 1 addition & 1 deletion mvt/layer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestLayer(t *testing.T) {
},
}
for i, tcase := range testcases {
vt, err := tcase.layer.VTileLayer()
vt, err := tcase.layer.VTileLayer(0, 0)
if err != tcase.eerr {
t.Errorf("For Test %v: Got unexpected error. Expected %v Got %v", i, tcase.eerr, err)
}
Expand Down
6 changes: 3 additions & 3 deletions mvt/tile.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ func (t *Tile) Layers() (l []Layer) {

// VTile returns a tile object according to the Google Protobuff def. This function
// does the hard work of converting everthing to the standard.
func (t *Tile) VTile() (vt *vectorTile.Tile, err error) {
func (t *Tile) VTile(ulx, uly float64) (vt *vectorTile.Tile, err error) {
vt = new(vectorTile.Tile)
for _, l := range t.layers {
vtl, err := l.VTileLayer()
vtl, err := l.VTileLayer(ulx, uly)
if err != nil {
return nil, err
return nil, fmt.Errorf("Error Getting VTileLayer: %v", err)
}
vt.Layers = append(vt.Layers, vtl)
}
Expand Down
Loading

0 comments on commit 39725bc

Please sign in to comment.