mirror of https://github.com/tidwall/tile38.git
363 lines
11 KiB
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")
|
||
|
}
|
||
|
}
|