tile38/pkg/geojson/detect_test.go

363 lines
11 KiB
Go

package geojson
import (
"testing"
"github.com/tidwall/gjson"
)
// https://gist.github.com/tidwall/5524c468fa4212b89e9c3532a5b1f355
var detectJSON = `{"type":"FeatureCollection","features":[
{"type":"Feature","properties":{"id":"point1"},"geometry":{"type":"Point","coordinates":[-73.98549556732178,40.72198994979771]}},
{"type":"Feature","properties":{"id":"polygon1"},"geometry":{"type":"Polygon","coordinates":[[[-74.0035629272461,40.71994085251552],[-73.98914337158203,40.71994085251552],[-73.98914337158203,40.72755146730012],[-74.0035629272461,40.72755146730012],[-74.0035629272461,40.71994085251552]]]}},
{"type":"Feature","properties":{"id":"linestring1"},"geometry":{"type":"LineString","coordinates":[[-73.98382186889648,40.73652697126574],[-73.98821868896482,40.73652697126574],[-73.97420883178711,40.72943772441242]]}},
{"type":"Feature","properties":{"id":"linestring2"},"geometry":{"type":"LineString","coordinates":[[-73.98146152496338,40.72716120053256],[-73.99098873138428,40.724754504892424]]}},
{"type":"Feature","properties":{"id":"linestring3"},"geometry":{"type":"LineString","coordinates":[[-73.98386478424072,40.72696606629052],[-73.98090362548828,40.72501469240076],[-73.97837162017821,40.72621804639551]]}},
{"type":"Feature","properties":{"id":"polygon2","fill":"#0433ff"},"geometry":{"type":"Polygon","coordinates":[[[-73.98661136627197,40.72540497175607],[-73.99064540863037,40.71938791069558],[-73.98807048797607,40.71779411151556],[-73.97571086883545,40.72338850378556],[-73.98017406463623,40.72960033028089],[-73.98661136627197,40.72540497175607]]]}},
{"type":"Feature","properties":{"id":"polygon3"},"geometry":{"type":"Polygon","coordinates":[[[-73.98352146148682,40.72550254123727],[-73.98579597473145,40.72088409560772],[-73.97914409637451,40.72251034541217],[-73.98017406463623,40.72599038649773],[-73.98352146148682,40.72550254123727]],[[-73.98300647735596,40.72439674540761],[-73.98111820220947,40.72446179272971],[-73.98141860961913,40.7221525738643],[-73.98300647735596,40.72439674540761]]]}},
{"type":"Feature","properties":{"id":"multipoint1","marker-color":"#941751"},"geometry":{"type":"MultiPoint","coordinates":[[-73.98957252502441,40.72049378974239],[-73.9897871017456,40.720233584560724],[-73.9897871017456,40.721664700472566],[-73.99085998535155,40.720916620993194],[-73.9912462234497,40.720331161623065]]}},
{"type":"Feature","properties":{"id":"multilinestring1","stroke":"#941751"},"geometry":{"type":"MultiLineString","coordinates":[[[-73.98442268371582,40.72459188718318],[-73.98463726043701,40.72384384060296],[-73.98382186889648,40.72355112443509]],[[-73.9850664138794,40.72358364851732],[-73.98476600646973,40.72485207532725],[-73.9854097366333,40.72491712220435]]]}},
{"type":"Feature","properties":{"id":"multipolygon1","fill":"#941751"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-73.98021697998047,40.72429917430525],[-73.97892951965332,40.7250472157678],[-73.98000240325926,40.72524235563617],[-73.98021697998047,40.72429917430525]]],[[[-73.97901535034178,40.72452683998823],[-73.9788007736206,40.72345355209305],[-73.97764205932617,40.72410403167144],[-73.97901535034178,40.72452683998823]]]]}},
{"type":"Feature","properties":{"id":"point2"},"geometry":{"type":"Point","coordinates":[-73.98326396942139,40.723681220668624]}},
{"type":"Feature","properties":{"id":"point3"},"geometry":{"type":"Point","coordinates":[-73.98196396942139,40.723681220668624]}},
{"type":"Feature","properties":{"id":"point4"},"geometry":{"type":"Point","coordinates":[-73.9785396942139,40.7238220668624]}}
]}`
func getByID(id string) Object {
var r gjson.Result
gjson.Get(detectJSON, "features").ForEach(func(_, v gjson.Result) bool {
if v.Get("properties.id").String() == id {
r = v.Get("geometry")
return false
}
return true
})
if !r.Exists() {
panic("not found '" + id + "'")
}
o, err := ObjectJSON(r.String())
if err != nil {
panic(err)
}
if p, ok := o.(SimplePoint); ok {
o = Point{Coordinates: Position{X: p.X, Y: p.Y}}
}
return o
}
func toSimplePoint(p Object) Object {
return SimplePoint{X: p.(Point).Coordinates.X, Y: p.(Point).Coordinates.Y}
}
// Basic geometry detections
// Point -> Point
// Point -> MultiPoint
// Point -> LineString
// Point -> MultiLineString
// Point -> Polygon
// Point -> MultiPolygon
// MultiPoint -> Point
// MultiPoint -> MultiPoint
// MultiPoint -> LineString
// MultiPoint -> MultiLineString
// MultiPoint -> Polygon
// MultiPoint -> MultiPolygon
// LineString -> Point
// LineString -> MultiPoint
// LineString -> LineString
// LineString -> MultiLineString
// LineString -> Polygon
// LineString -> MultiPolygon
// MultiLineString -> Point
// MultiLineString -> MultiPoint
// MultiLineString -> LineString
// MultiLineString -> MultiLineString
// MultiLineString -> Polygon
// MultiLineString -> MultiPolygon
// Polygon -> Point
// Polygon -> MultiPoint
// Polygon -> LineString
// Polygon -> MultiLineString
// Polygon -> Polygon
// Polygon -> MultiPolygon
// MultiPolygon -> Point
// MultiPolygon -> MultiPoint
// MultiPolygon -> LineString
// MultiPolygon -> MultiLineString
// MultiPolygon -> Polygon
// MultiPolygon -> MultiPolygon
func TestDetectSimplePointSimplePoint(t *testing.T) {
p1 := toSimplePoint(getByID("point1"))
p2 := toSimplePoint(getByID("point2"))
if p1.Intersects(p2) {
t.Fatal("expected false")
}
if !p1.Intersects(p1) {
t.Fatal("expected true")
}
if p1.Within(p2) {
t.Fatal("expected false")
}
if !p1.Within(p1) {
t.Fatal("expected true")
}
}
func TestDetectPointPoint(t *testing.T) {
p1 := getByID("point1")
p2 := getByID("point2")
if p1.Intersects(p2) {
t.Fatal("expected false")
}
if !p1.Intersects(p1) {
t.Fatal("expected true")
}
if p1.Within(p2) {
t.Fatal("expected false")
}
if !p1.Within(p1) {
t.Fatal("expected true")
}
}
func TestDetectPointMultPoint(t *testing.T) {
p1 := getByID("point1")
mp1 := getByID("multipoint1")
if p1.Intersects(mp1) {
t.Fatal("expected false")
}
if p1.Within(mp1) {
t.Fatal("expected false")
}
pp := Point{Coordinates: mp1.(MultiPoint).Coordinates[0]}
if !pp.Intersects(mp1) {
t.Fatal("expected true")
}
if !pp.Within(mp1) {
t.Fatal("expected true")
}
}
func TestDetectPointLineString(t *testing.T) {
p1 := getByID("point1")
ls1 := getByID("linestring1")
if p1.Intersects(ls1) {
t.Fatal("expected false")
}
if p1.Within(ls1) {
t.Fatal("expected false")
}
pp := Point{Coordinates: ls1.(LineString).Coordinates[0]}
if !pp.Intersects(ls1) {
t.Fatal("expected true")
}
if !pp.Within(ls1) {
t.Fatal("expected true")
}
}
func TestDetectPointMultiLineString(t *testing.T) {
p1 := getByID("point1")
mls1 := getByID("multilinestring1")
if p1.Intersects(mls1) {
t.Fatal("expected false")
}
if p1.Within(mls1) {
t.Fatal("expected false")
}
pp := Point{Coordinates: mls1.(MultiLineString).Coordinates[0][1]}
if !pp.Intersects(mls1) {
t.Fatal("expected true")
}
if !pp.Within(mls1) {
t.Fatal("expected true")
}
}
func TestDetectPointPolygon(t *testing.T) {
p1 := getByID("point1")
pl3 := getByID("polygon3")
if p1.Intersects(pl3) {
t.Fatal("expected false")
}
if p1.Within(pl3) {
t.Fatal("expected false")
}
p2 := getByID("point2")
if !p2.Intersects(pl3) {
t.Fatal("expected true")
}
if !p2.Within(pl3) {
t.Fatal("expected true")
}
p3 := getByID("point3")
if p3.Intersects(pl3) {
t.Fatal("expected false")
}
if p3.Within(pl3) {
t.Fatal("expected false")
}
}
func TestDetectPointMultiPolygon(t *testing.T) {
p3 := getByID("point3")
p4 := getByID("point4")
mp1 := getByID("multipolygon1")
if p3.Intersects(mp1) {
t.Fatal("expected false")
}
if p3.Within(mp1) {
t.Fatal("expected false")
}
if !p4.Intersects(mp1) {
t.Fatal("expected true")
}
if !p4.Within(mp1) {
t.Fatal("expected true")
}
}
func TestDetectMultiPointPoint(t *testing.T) {
p1 := getByID("point1")
mp1 := getByID("multipoint1")
if mp1.Intersects(p1) {
t.Fatal("expected false")
}
if mp1.Within(p1) {
t.Fatal("expected false")
}
pp := Point{Coordinates: mp1.(MultiPoint).Coordinates[0]}
if !mp1.Intersects(pp) {
t.Fatal("expected true")
}
if mp1.Within(pp) {
t.Fatal("expected false")
}
}
func TestDetectMultiPointPolygon(t *testing.T) {
mp1 := getByID("multipoint1")
pl1 := getByID("polygon1")
pl2 := getByID("polygon2")
pl3 := getByID("polygon3")
if !mp1.Intersects(pl1) {
t.Fatal("expected true")
}
if !mp1.Within(pl1) {
t.Fatal("expected true")
}
if !mp1.Intersects(pl2) {
t.Fatal("expected true")
}
if mp1.Within(pl2) {
t.Fatal("expected false")
}
if mp1.Intersects(pl3) {
t.Fatal("expected false")
}
if mp1.Within(pl3) {
t.Fatal("expected false")
}
}
func TestDetectLineStringLineString(t *testing.T) {
ls1 := getByID("linestring1")
ls2 := getByID("linestring2")
ls3 := getByID("linestring3")
if ls1.Intersects(ls2) {
t.Fatal("expected false")
}
if ls2.Intersects(ls1) {
t.Fatal("expected false")
}
if !ls2.Intersects(ls3) {
t.Fatal("expected true")
}
if !ls2.Intersects(ls3) {
t.Fatal("expected true")
}
}
func TestDetectLineStringPolygon(t *testing.T) {
ls1 := getByID("linestring1")
ls2 := getByID("linestring2")
ls3 := getByID("linestring3")
pl1 := getByID("polygon1")
pl2 := getByID("polygon2")
pl3 := getByID("polygon3")
if ls1.Intersects(pl1) {
t.Fatal("expected false")
}
if pl1.Intersects(ls1) {
t.Fatal("expected false")
}
if ls1.Intersects(pl3) {
t.Fatal("expected false")
}
if pl3.Intersects(ls1) {
t.Fatal("expected false")
}
if !ls2.Intersects(pl1) {
t.Fatal("expected true")
}
if !pl2.Intersects(ls2) {
t.Fatal("expected true")
}
if ls2.Within(pl1) {
t.Fatal("expected false")
}
if ls2.Intersects(pl3) {
t.Fatal("expected false")
}
if pl3.Intersects(ls2) {
t.Fatal("expected false")
}
if !ls3.Intersects(pl2) {
t.Fatal("expected true")
}
if !pl2.Intersects(ls3) {
t.Fatal("expected true")
}
if !ls3.Within(pl2) {
t.Fatal("expected true")
}
if ls2.Intersects(pl3) {
t.Fatal("expected false")
}
if pl3.Intersects(ls2) {
t.Fatal("expected false")
}
if ls2.Intersects(pl3) {
t.Fatal("expected false")
}
if pl3.Intersects(ls2) {
t.Fatal("expected false")
}
if !ls3.Intersects(pl3) {
t.Fatal("expected true")
}
if !pl3.Intersects(ls3) {
t.Fatal("expected true")
}
}
func TestDetectMultiLineStringPolygon(t *testing.T) {
mls1 := getByID("multilinestring1")
pl1 := getByID("polygon1")
pl2 := getByID("polygon2")
pl3 := getByID("polygon3")
if mls1.Intersects(pl1) {
t.Fatal("expected false")
}
if mls1.Within(pl1) {
t.Fatal("expected false")
}
if !mls1.Intersects(pl2) {
t.Fatal("expected true")
}
if !mls1.Within(pl2) {
t.Fatal("expected true")
}
if !mls1.Intersects(pl3) {
t.Fatal("expected true")
}
if mls1.Within(pl3) {
t.Fatal("expected false")
}
}