Skip to content

Commit

Permalink
Mostly Prep work for Validate Polygon code
Browse files Browse the repository at this point in the history
This is mostly prep work for the IsValidate and MakeValidate functions we need
for polygons. I think this is one of the issues with the polygons, that the
multipolygons we get are not always OGC complient and we are making the assumption
that is the case. It has also been pointed out that after scaling it is possible
for certain small polygons to flip directions, so we need to insure this does
not happen.
  • Loading branch information
gdey committed Mar 17, 2017
1 parent 5337b15 commit d5515c7
Show file tree
Hide file tree
Showing 10 changed files with 760 additions and 36 deletions.
39 changes: 18 additions & 21 deletions basic/line.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,24 @@ import (
type Line []Point

// Just to make basic collection only usable with basic types.
func (Line) basicType() {}
func (Line) String() string { return "Line" }
func (l Line) direction() maths.WindingOrder {
sum := 0
var npt Point
for i, pt := range l {

if i == (len(l) - 1) {
npt = l[0]
} else {
npt = l[i+1]
}
sum += int((npt.X() - pt.X()) * (npt.Y() + pt.Y()))
}
if sum < 0 {
return maths.Clockwise
}
return maths.CounterClockwise
}
func (Line) basicType() {}
func (Line) String() string { return "Line" }
func (l Line) Direction() maths.WindingOrder { return maths.WindingOrderOfLine(l) }
func (l Line) GoString() string {
str := fmt.Sprintf("[%v--%v]{", len(l), l.direction())
str := fmt.Sprintf("\n[%v--%v]{\n\t", len(l), l.Direction())
count := 0
for i, p := range l {
if i != 0 {
str += ","
}
str += fmt.Sprintf("(%v,%v)", p[0], p[1])
if count == 10 {
str += "\n\t"
count = 0
}
count++
}
str += "}"
str += "\n}"
return str
}

Expand All @@ -64,6 +54,13 @@ func NewLineFromPt(points ...maths.Pt) Line {
return line
}

func CloneLine(line tegola.LineString) (l Line) {
for _, pt := range line.Subpoints() {
l = append(l, Point{pt.X(), pt.Y()})
}
return l
}

// Subpoints return the points in a line.
func (l Line) Subpoints() (points []tegola.Point) {
points = make([]tegola.Point, 0, len(l))
Expand Down
12 changes: 11 additions & 1 deletion basic/polygon.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package basic

import (
"fmt"

"github.com/terranodo/tegola"
"github.com/terranodo/tegola/maths"
)
Expand All @@ -22,6 +24,14 @@ func (p Polygon) Sublines() (slines []tegola.LineString) {
func (Polygon) String() string {
return "Polygon"
}
func (p Polygon) GoString() string {
str := fmt.Sprintf("\nPolygon[%v]{\n", len(p))
for _, l := range p {
str += fmt.Sprintf("%#", l)
}
str += "}\n"
return str
}

// MultiPolygon describes a set of polygons.
type MultiPolygon []Polygon
Expand All @@ -38,7 +48,7 @@ func (mp MultiPolygon) Polygons() (polygons []tegola.Polygon) {
return polygons
}
func (MultiPolygon) String() string {
return "Polygon"
return "MultiPolygon"
}

func NewPolygon(main []maths.Pt, clines ...[]maths.Pt) Polygon {
Expand Down
30 changes: 21 additions & 9 deletions cmd/printwkb/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ func print(srid int, geostr string, tile tegola.BoundingBox) {
rd1 := strings.NewReader(geostr)
geo, err := wkb.Decode(rd1)
if err != nil {
fmt.Fprintf(os.Stderr, "Error decoding goe(road1): %v", err)
fmt.Fprintf(os.Stderr, "Error decoding goemetry: %v", err)
os.Exit(2)
}
if geo == nil {
fmt.Fprintf(os.Stderr, "Geo is nil.")
os.Exit(0)
}
gwm, err := basic.ToWebMercator(srid, geo)
c := mvt.NewCursor(tile, 4096)
g := c.ScaleGeo(gwm.Geometry)
Expand All @@ -33,7 +37,6 @@ func print(srid int, geostr string, tile tegola.BoundingBox) {
panic(err)
}
fmt.Printf("Clip GEO:%T: %#[1]v\n", cg)

}

var configFile string
Expand Down Expand Up @@ -77,6 +80,7 @@ type ProviderLayer struct {
password string
host string
geoField string
geoID string
table string
}

Expand Down Expand Up @@ -133,11 +137,17 @@ func LoadProvider(configfile string, providerlayer string) (pl ProviderLayer, er
}
}
var ok bool
srid, ok := provider["srid"].(int64)
if !ok {
return pl, fmt.Errorf("Cound not convert %T", provider["srid"])

if _, ok = provider["srid"]; ok {
srid, ok := provider["srid"].(int64)
if !ok {
return pl, fmt.Errorf("Cound not convert %T", provider["srid"])
}
pl.srid = int(srid)
} else {
pl.srid = 4326
}
pl.srid = int(srid)

port, ok := provider["port"].(int64)
if !ok {
return pl, fmt.Errorf("Cound not convert %T", provider["port"])
Expand Down Expand Up @@ -174,9 +184,11 @@ func LoadProvider(configfile string, providerlayer string) (pl ProviderLayer, er
if pl.geoField, ok = providerLayer["geometry_fieldname"].(string); !ok {
return pl, fmt.Errorf("was not able to convert geometry_fieldsname to string %v.", providerLayer["geometry_fieldname"])
}
pl.table = layerName
if tbln, ok := providerLayer["tablename"].(string); ok && tbln != "" {
pl.table = tbln
if pl.geoID, ok = providerLayer["id_fieldname"].(string); !ok || pl.geoID == "" {
pl.geoID = "gid"
}
if pl.table, ok = providerLayer["tablename"].(string); !ok || pl.table == "" {
pl.table = layerName
}
return pl, nil
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/tegola/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.toml
tegola
static/debug
static/landuse2
158 changes: 158 additions & 0 deletions isequal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package tegola

// IsPointEqual will check to see if the two tegola points are equal.
func IsPointEqual(p1, p2 Point) bool {
if p1 == nil || p2 == nil {
return p1 == p2
}
return p1.X() == p2.X() && p1.Y() == p2.Y()
}

// IsPoint3Equal will check to see if the two 3d tegola points are equal.
func IsPoint3Equal(p1, p2 Point3) bool {
return p1.X() == p2.X() && p1.Y() == p2.Y() && p1.Z() == p2.Z()
}

// IsMultiPointEqual will check to see if the two provided multipoints are equal
func IsMultiPointEqual(mp1, mp2 MultiPoint) bool {
pts1, pts2 := mp1.Points(), mp2.Points()
if len(pts1) != len(pts2) {
return false
}
for i, pt := range pts1 {
if !IsPointEqual(pt, pts2[i]) {
return false
}
}
return true
}

// IsLineStringEqual will check to see if the two linesstrings provided are equal.
func IsLineStringEqual(l1, l2 LineString) bool {
pts1, pts2 := l1.Subpoints(), l2.Subpoints()
if len(pts1) != len(pts2) {
return false
}
for i, pt := range pts1 {
if !IsPointEqual(pt, pts2[i]) {
return false
}
}
return true
}

// IsMultiLineEqual will check to see if the two Multilines that are provided are equal.
func IsMultiLineEqual(ml1, ml2 MultiLine) bool {
lns1, lns2 := ml1.Lines(), ml2.Lines()
if len(lns1) != len(lns2) {
return false
}
for i, ln := range lns1 {
if !IsLineStringEqual(ln, lns2[i]) {
return false
}
}
return true
}

// PolygonIsEqual will check to see if the two provided polygons are equal.
func IsPolygonEqual(p1, p2 Polygon) bool {
lns1, lns2 := p1.Sublines(), p2.Sublines()
if len(lns1) != len(lns2) {
return false
}
for i, ln := range lns1 {
if !IsLineStringEqual(ln, lns2[i]) {
return false
}
}
return true
}

// MultiPolygonIsEqual will check to see if the two provided multi-polygons are equal.
func IsMultiPolygonEqual(mp1, mp2 MultiPolygon) bool {
pgs1, pgs2 := mp1.Polygons(), mp2.Polygons()
if len(pgs1) != len(pgs2) {
return false
}
for i, pg := range pgs1 {
if !IsPolygonEqual(pg, pgs2[i]) {
return false
}
}
return true
}

// GeometryIsEqual will check to see if the two given geometeries are equal. This function does not check to see if there are any
// recursive structures if there are any recursive structures it will hang. If the type of the geometry is unknown, it is assumed
// that it does not match any other geometries.
func IsGeometryEqual(g1, g2 Geometry) bool {
switch geo1 := g1.(type) {
case Point:
geo2, ok := g2.(Point)
if !ok {
return false
}
return IsPointEqual(geo1, geo2)
case Point3:
geo2, ok := g2.(Point3)
if !ok {
return false
}
return IsPoint3Equal(geo1, geo2)
case MultiPoint:
geo2, ok := g2.(MultiPoint)
if !ok {
return false
}
return IsMultiPointEqual(geo1, geo2)
case LineString:
geo2, ok := g2.(LineString)
if !ok {
return false
}
return IsLineStringEqual(geo1, geo2)
case MultiLine:
geo2, ok := g2.(MultiLine)
if !ok {
return false
}
return IsMultiLineEqual(geo1, geo2)
case Polygon:
geo2, ok := g2.(Polygon)
if !ok {
return false
}
return IsPolygonEqual(geo1, geo2)
case MultiPolygon:
geo2, ok := g2.(MultiPolygon)
if !ok {
return false
}
return IsMultiPolygonEqual(geo1, geo2)
case Collection:
geo2, ok := g2.(Collection)
if !ok {
return false
}
return IsCollectionEqual(geo1, geo2)
}
// If we don't know the type, we will assume they don't match.
return false
}

// CollectionIsEqual will check to see if the provided collections are equal. This function does not check to see if the collections
// contain any recursive structures, and if there are any recursive structures it will hang. If the collections contains any unknown
// geometries it will be assumed to not match.
func IsCollectionEqual(c1, c2 Collection) bool {
geos1, geos2 := c1.Geometries(), c2.Geometries()
if len(geos1) != len(geos2) {
return false
}
for i, geo := range geos1 {
if !IsGeometryEqual(geo, geos2[i]) {
return false
}
}
return true
}
Loading

0 comments on commit d5515c7

Please sign in to comment.