mirror of https://github.com/tidwall/tile38.git
better multipolygon detection
This commit is contained in:
parent
3bdcfd10da
commit
dc1cc76247
|
@ -196,9 +196,6 @@ func (g Feature) Within(o Object) bool {
|
||||||
func(v Polygon) bool {
|
func(v Polygon) bool {
|
||||||
return g.Geometry.Within(o)
|
return g.Geometry.Within(o)
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
return g.Geometry.Within(o)
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,9 +205,6 @@ func (g Feature) Intersects(o Object) bool {
|
||||||
func(v Polygon) bool {
|
func(v Polygon) bool {
|
||||||
return g.Geometry.Intersects(o)
|
return g.Geometry.Intersects(o)
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
return g.Geometry.Intersects(o)
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,17 +190,6 @@ func (g FeatureCollection) Within(o Object) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Features) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, f := range g.Features {
|
|
||||||
if !f.Within(o) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,17 +207,6 @@ func (g FeatureCollection) Intersects(o Object) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Features) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, f := range g.Features {
|
|
||||||
if f.Intersects(o) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,17 +189,6 @@ func (g GeometryCollection) Within(o Object) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Geometries) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, g := range g.Geometries {
|
|
||||||
if !g.Within(o) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,17 +206,6 @@ func (g GeometryCollection) Intersects(o Object) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Geometries) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, g := range g.Geometries {
|
|
||||||
if g.Intersects(o) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,14 +102,6 @@ func (g LineString) Within(o Object) bool {
|
||||||
func(v Polygon) bool {
|
func(v Polygon) bool {
|
||||||
return polyPositions(g.Coordinates).Inside(polyExteriorHoles(v.Coordinates))
|
return polyPositions(g.Coordinates).Inside(polyExteriorHoles(v.Coordinates))
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if !polyPositions(g.Coordinates).Inside(polyExteriorHoles(c)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,14 +111,6 @@ func (g LineString) Intersects(o Object) bool {
|
||||||
func(v Polygon) bool {
|
func(v Polygon) bool {
|
||||||
return polyPositions(g.Coordinates).LineStringIntersects(polyExteriorHoles(v.Coordinates))
|
return polyPositions(g.Coordinates).LineStringIntersects(polyExteriorHoles(v.Coordinates))
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if polyPositions(g.Coordinates).LineStringIntersects(polyExteriorHoles(c)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,19 +141,6 @@ func (g MultiLineString) Within(o Object) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Coordinates) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, ls := range g.Coordinates {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if !polyPositions(ls).Inside(polyExteriorHoles(c)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,19 +158,6 @@ func (g MultiLineString) Intersects(o Object) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Coordinates) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, ls := range g.Coordinates {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if polyPositions(ls).Intersects(polyExteriorHoles(c)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,19 +120,6 @@ func (g MultiPoint) Within(o Object) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Coordinates) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
for _, p := range g.Coordinates {
|
|
||||||
if !poly.Point(p).Inside(polyExteriorHoles(c)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,19 +137,6 @@ func (g MultiPoint) Intersects(o Object) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Coordinates) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
for _, p := range g.Coordinates {
|
|
||||||
if poly.Point(p).Intersects(polyExteriorHoles(c)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,21 +144,6 @@ func (g MultiPolygon) Within(o Object) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Coordinates) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, p := range g.Coordinates {
|
|
||||||
if len(p) > 0 {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if !polyPositions(p[0]).Inside(polyExteriorHoles(c)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,21 +163,6 @@ func (g MultiPolygon) Intersects(o Object) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Coordinates) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, p := range g.Coordinates {
|
|
||||||
if len(p) > 0 {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if polyPositions(p[0]).Intersects(polyExteriorHoles(c)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package geojson
|
package geojson
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestMultiPolygon(t *testing.T) {
|
func TestMultiPolygon(t *testing.T) {
|
||||||
testJSON(t, `
|
testJSON(t, `
|
||||||
|
@ -221,3 +223,19 @@ func TestMultiPolygon(t *testing.T) {
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
func TestIssue244(t *testing.T) {
|
||||||
|
json := `{"type":"MultiPolygon","coordinates":[[[[180.0,40.0],[180.0,50.0],[170.0,50.0],[170.0,40.0],[180.0,40.0]]],[[[-170.0,40.0],[-170.0,50.0],[-180.0,50.0],[-180.0,40.0],[-170.0,40.0]]]]}`
|
||||||
|
g := testJSON(t, json).(MultiPolygon)
|
||||||
|
if !(SimplePoint{180.0, 40.0}).Within(g) {
|
||||||
|
t.Fatal("!")
|
||||||
|
}
|
||||||
|
if !(SimplePoint{179.0, 45.0}).Within(g) {
|
||||||
|
t.Fatal("!")
|
||||||
|
}
|
||||||
|
if !(SimplePoint{179.0, 45.0}).Within(Polygon{Coordinates: g.Coordinates[0]}) {
|
||||||
|
t.Fatal("!")
|
||||||
|
}
|
||||||
|
if (SimplePoint{179.0, 45.0}).Within(Polygon{Coordinates: g.Coordinates[1]}) {
|
||||||
|
t.Fatal("!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ func objectMap(json string, from int) (Object, error) {
|
||||||
return o, err
|
return o, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func withinObjectShared(g Object, o Object, pin func(v Polygon) bool, mpin func(v MultiPolygon) bool) bool {
|
func withinObjectShared(g Object, o Object, pin func(v Polygon) bool) bool {
|
||||||
bbp := o.bboxPtr()
|
bbp := o.bboxPtr()
|
||||||
if bbp != nil {
|
if bbp != nil {
|
||||||
if !g.WithinBBox(*bbp) {
|
if !g.WithinBBox(*bbp) {
|
||||||
|
@ -205,10 +205,12 @@ func withinObjectShared(g Object, o Object, pin func(v Polygon) bool, mpin func(
|
||||||
}
|
}
|
||||||
return pin(v)
|
return pin(v)
|
||||||
case MultiPolygon:
|
case MultiPolygon:
|
||||||
if len(v.Coordinates) == 0 {
|
for _, coords := range v.Coordinates {
|
||||||
return false
|
if pin(Polygon{Coordinates: coords}) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return mpin(v)
|
return false
|
||||||
case Feature:
|
case Feature:
|
||||||
return g.Within(v.Geometry)
|
return g.Within(v.Geometry)
|
||||||
case FeatureCollection:
|
case FeatureCollection:
|
||||||
|
@ -234,7 +236,7 @@ func withinObjectShared(g Object, o Object, pin func(v Polygon) bool, mpin func(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func intersectsObjectShared(g Object, o Object, pin func(v Polygon) bool, mpin func(v MultiPolygon) bool) bool {
|
func intersectsObjectShared(g Object, o Object, pin func(v Polygon) bool) bool {
|
||||||
bbp := o.bboxPtr()
|
bbp := o.bboxPtr()
|
||||||
if bbp != nil {
|
if bbp != nil {
|
||||||
if !g.IntersectsBBox(*bbp) {
|
if !g.IntersectsBBox(*bbp) {
|
||||||
|
@ -257,10 +259,12 @@ func intersectsObjectShared(g Object, o Object, pin func(v Polygon) bool, mpin f
|
||||||
}
|
}
|
||||||
return pin(v)
|
return pin(v)
|
||||||
case MultiPolygon:
|
case MultiPolygon:
|
||||||
if len(v.Coordinates) == 0 {
|
for _, coords := range v.Coordinates {
|
||||||
return false
|
if pin(Polygon{Coordinates: coords}) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return mpin(v)
|
return false
|
||||||
case Feature:
|
case Feature:
|
||||||
return g.Intersects(v.Geometry)
|
return g.Intersects(v.Geometry)
|
||||||
case FeatureCollection:
|
case FeatureCollection:
|
||||||
|
|
|
@ -109,14 +109,6 @@ func (g Point) Within(o Object) bool {
|
||||||
func(v Polygon) bool {
|
func(v Polygon) bool {
|
||||||
return poly.Point(g.Coordinates).Inside(polyExteriorHoles(v.Coordinates))
|
return poly.Point(g.Coordinates).Inside(polyExteriorHoles(v.Coordinates))
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if !poly.Point(g.Coordinates).Inside(polyExteriorHoles(c)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,14 +118,6 @@ func (g Point) Intersects(o Object) bool {
|
||||||
func(v Polygon) bool {
|
func(v Polygon) bool {
|
||||||
return poly.Point(g.Coordinates).Intersects(polyExteriorHoles(v.Coordinates))
|
return poly.Point(g.Coordinates).Intersects(polyExteriorHoles(v.Coordinates))
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if poly.Point(g.Coordinates).Intersects(polyExteriorHoles(c)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,17 +142,6 @@ func (g Polygon) Within(o Object) bool {
|
||||||
}
|
}
|
||||||
return polyPositions(g.Coordinates[0]).Inside(polyExteriorHoles(v.Coordinates))
|
return polyPositions(g.Coordinates[0]).Inside(polyExteriorHoles(v.Coordinates))
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Coordinates) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if !polyPositions(g.Coordinates[0]).Inside(polyExteriorHoles(c)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,17 +154,6 @@ func (g Polygon) Intersects(o Object) bool {
|
||||||
}
|
}
|
||||||
return polyPositions(g.Coordinates[0]).Intersects(polyExteriorHoles(v.Coordinates))
|
return polyPositions(g.Coordinates[0]).Intersects(polyExteriorHoles(v.Coordinates))
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
if len(g.Coordinates) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if polyPositions(g.Coordinates[0]).Intersects(polyExteriorHoles(c)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,14 +91,6 @@ func (g SimplePoint) Within(o Object) bool {
|
||||||
func(v Polygon) bool {
|
func(v Polygon) bool {
|
||||||
return poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).Inside(polyExteriorHoles(v.Coordinates))
|
return poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).Inside(polyExteriorHoles(v.Coordinates))
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if !poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).Inside(polyExteriorHoles(c)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,14 +100,6 @@ func (g SimplePoint) Intersects(o Object) bool {
|
||||||
func(v Polygon) bool {
|
func(v Polygon) bool {
|
||||||
return poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).Intersects(polyExteriorHoles(v.Coordinates))
|
return poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).Intersects(polyExteriorHoles(v.Coordinates))
|
||||||
},
|
},
|
||||||
func(v MultiPolygon) bool {
|
|
||||||
for _, c := range v.Coordinates {
|
|
||||||
if poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).Intersects(polyExteriorHoles(c)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue