tile38/vendor/github.com/tidwall/geojson/geometry/series_test.go

383 lines
9.9 KiB
Go
Raw Normal View History

// Copyright 2018 Joshua J Baker. All rights reserved.
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
package geometry
import (
"reflect"
"testing"
)
func seriesForEachSegment(ring Ring, iter func(seg Segment) bool) {
n := ring.NumSegments()
for i := 0; i < n; i++ {
if !iter(ring.SegmentAt(i)) {
return
}
}
}
func seriesForEachPoint(ring Ring, iter func(point Point) bool) {
n := ring.NumPoints()
for i := 0; i < n; i++ {
if !iter(ring.PointAt(i)) {
return
}
}
}
func TestSeriesEmpty(t *testing.T) {
var series *baseSeries
expect(t, series.Empty())
series2 := makeSeries(nil, false, false, 0)
expect(t, series2.Empty())
}
func TestSeriesClockwise(t *testing.T) {
var series baseSeries
series = makeSeries([]Point{
P(0, 0), P(10, 0), P(10, 10), P(0, 10), P(0, 0),
}, true, true, DefaultIndex)
expect(t, !series.Clockwise())
series = makeSeries([]Point{
P(0, 0), P(10, 0), P(10, 10), P(0, 10),
}, true, true, DefaultIndex)
expect(t, !series.Clockwise())
series = makeSeries([]Point{
P(0, 0), P(10, 0), P(10, 10),
}, true, true, DefaultIndex)
expect(t, !series.Clockwise())
series = makeSeries([]Point{
P(0, 0), P(0, 10), P(10, 10), P(10, 0), P(0, 0),
}, true, true, DefaultIndex)
expect(t, series.Clockwise())
series = makeSeries([]Point{
P(0, 0), P(0, 10), P(10, 10), P(10, 0),
}, true, true, DefaultIndex)
expect(t, series.Clockwise())
series = makeSeries([]Point{
P(0, 0), P(0, 10), P(10, 10),
}, true, true, DefaultIndex)
expect(t, series.Clockwise())
}
func TestSeriesConvex(t *testing.T) {
t.Run("1", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(4, 0), P(4, 4), P(0, 4), P(0, 0),
}, true, true, DefaultIndex)
expect(t, series.Convex())
})
t.Run("2", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(4, 0), P(4, 4), P(3, 4), P(1, 4), P(0, 4), P(0, 0),
}, true, true, DefaultIndex)
expect(t, series.Convex())
})
t.Run("3", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(4, 0), P(4, 4), P(2, 5), P(0, 4), P(0, 0),
}, true, true, DefaultIndex)
expect(t, series.Convex())
})
t.Run("4", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(4, 0), P(4, 4),
P(3, 4), P(2, 5), P(1, 4),
P(0, 4), P(0, 0),
}, true, true, DefaultIndex)
expect(t, !series.Convex())
})
t.Run("5", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(4, 0), P(4, 4),
P(3, 4), P(2, 3), P(1, 4),
P(0, 4), P(0, 0),
}, true, true, DefaultIndex)
expect(t, !series.Convex())
})
t.Run("5", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(4, 0), P(4, 4), P(0, 4),
P(-1, 2), P(0, 0),
}, true, true, DefaultIndex)
expect(t, series.Convex())
})
t.Run("6", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(4, 0), P(4, 4), P(0, 4), P(0, 3),
P(-1, 2), P(0, 0),
}, true, true, DefaultIndex)
expect(t, !series.Convex())
})
t.Run("6", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(4, 0), P(4, 4), P(0, 4),
P(-1, 2), P(0, 1), P(0, 0),
}, true, true, DefaultIndex)
expect(t, !series.Convex())
})
t.Run("7", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(4, 0), P(4, 4),
P(3, 3), P(2, 5), P(1, 3), P(0, 4),
P(0, 0),
}, true, true, DefaultIndex)
expect(t, !series.Convex())
})
t.Run("8", func(t *testing.T) {
series := makeSeries([]Point{
P(0, 0), P(0, 4), P(1, 3), P(4, 4), P(2, 5), P(3, 3), P(4, 0),
P(0, 0),
}, true, true, DefaultIndex)
expect(t, !series.Convex())
})
}
func testScanSeries(
t *testing.T, series *baseSeries, index bool,
expectSegmentCount int, expectedEmpty bool,
) []Segment {
t.Helper()
if index {
series.buildTree()
} else {
series.tree = nil
}
var segs1 []Segment
seriesForEachSegment(series, func(seg Segment) bool {
segs1 = append(segs1, seg)
return true
})
var segs2Count int
segs2 := make([]Segment, len(segs1))
series.Search(series.Rect(), func(seg Segment, idx int) bool {
segs2[idx] = seg
segs2Count++
return true
})
expect(t, segs2Count == len(segs2))
expect(t, len(segs1) == len(segs2))
if len(segs1) != 0 {
expect(t, reflect.DeepEqual(segs1, segs2))
}
expect(t, expectSegmentCount == len(segs1))
expect(t, series.Empty() == expectedEmpty)
return segs1
}
func TestSeriesBasic(t *testing.T) {
series := makeSeries(octagon, true, true, DefaultIndex)
expect(t, reflect.DeepEqual(seriesCopyPoints(&series), octagon))
expect(t, series.Convex())
expect(t, series.Rect() == R(0, 0, 10, 10))
expect(t, series.Closed())
series = makeSeries(octagon, false, true, DefaultIndex)
expect(t, reflect.DeepEqual(seriesCopyPoints(&series), octagon))
series = makeSeries(ri, true, true, DefaultIndex)
testScanSeries(t, &series, true, len(ri)-1, false)
testScanSeries(t, &series, false, len(ri)-1, false)
// small lines
series = makeSeries([]Point{}, true, false, DefaultIndex)
testScanSeries(t, &series, true, 0, true)
testScanSeries(t, &series, false, 0, true)
series = makeSeries([]Point{P(5, 5)}, true, false, DefaultIndex)
testScanSeries(t, &series, true, 0, true)
testScanSeries(t, &series, false, 0, true)
series = makeSeries([]Point{P(5, 5), P(10, 10)}, true, false, DefaultIndex)
testScanSeries(t, &series, true, 1, false)
testScanSeries(t, &series, false, 1, false)
// small rings
series = makeSeries([]Point{}, true, true, DefaultIndex)
testScanSeries(t, &series, true, 0, true)
testScanSeries(t, &series, false, 0, true)
series = makeSeries([]Point{P(5, 5)}, true, true, DefaultIndex)
testScanSeries(t, &series, true, 0, true)
testScanSeries(t, &series, false, 0, true)
series = makeSeries([]Point{P(5, 5), P(10, 10)}, true, true, DefaultIndex)
testScanSeries(t, &series, true, 0, true)
testScanSeries(t, &series, false, 0, true)
series = makeSeries([]Point{P(5, 5), P(10, 10), P(10, 5)}, true, true, DefaultIndex)
testScanSeries(t, &series, true, 3, false)
testScanSeries(t, &series, false, 3, false)
}
func TestSeriesSearch(t *testing.T) {
series := makeSeries(octagon, true, true, DefaultIndex)
var segs []Segment
series.Search(R(0, 0, 0, 0), func(seg Segment, _ int) bool {
segs = append(segs, seg)
return true
})
segsExpect := []Segment{
S(0, 3, 3, 0),
}
expect(t, checkSegsDups(segsExpect, segs))
segs = nil
series.Search(R(0, 0, 0, 10), func(seg Segment, _ int) bool {
segs = append(segs, seg)
return true
})
segsExpect = []Segment{
S(3, 10, 0, 7),
S(0, 7, 0, 3),
S(0, 3, 3, 0),
}
expect(t, checkSegsDups(segsExpect, segs))
segs = nil
series.Search(R(0, 0, 5, 10), func(seg Segment, _ int) bool {
segs = append(segs, seg)
return true
})
segsExpect = []Segment{
S(3, 0, 7, 0),
S(7, 10, 3, 10),
S(3, 10, 0, 7),
S(0, 7, 0, 3),
S(0, 3, 3, 0),
}
expect(t, checkSegsDups(segsExpect, segs))
var seg2sA []Segment
series.Search(R(0, 0, 10, 10), func(seg Segment, idx int) bool {
seg2sA = append(seg2sA, seg)
return true
})
var seg2sB []Segment
seriesForEachSegment(&series, func(seg Segment) bool {
seg2sB = append(seg2sB, seg)
return true
})
expect(t, checkSegsDups(seg2sA, seg2sB))
var first Segment
var once bool
series.Search(R(0, 0, 10, 10), func(seg Segment, idx int) bool {
expect(t, !once)
first = seg
once = true
return false
})
expect(t, first == seg2sA[0])
}
func TestSeriesBig(t *testing.T) {
t.Run("Closed", func(t *testing.T) {
// clip off the last point to force an auto closure
series := makeSeries(ri[:len(ri)-1], true, true, DefaultIndex)
var seg2sA []Segment
series.Search(series.Rect(), func(seg Segment, idx int) bool {
seg2sA = append(seg2sA, seg)
return true
})
var seg2sB []Segment
seriesForEachSegment(&series, func(seg Segment) bool {
seg2sB = append(seg2sB, seg)
return true
})
expect(t, checkSegsDups(seg2sA, seg2sB))
// use all points
series2 := makeSeries(ri, true, true, DefaultIndex)
var seg2sC []Segment
seriesForEachSegment(&series2, func(seg Segment) bool {
seg2sC = append(seg2sC, seg)
return true
})
expect(t, checkSegsDups(seg2sA, seg2sC))
var first Segment
var once bool
series.Search(series.Rect(), func(seg Segment, idx int) bool {
expect(t, !once)
first = seg
once = true
return false
})
expect(t, first == seg2sA[0])
})
t.Run("Opened", func(t *testing.T) {
series := makeSeries(az, true, false, DefaultIndex)
var seg2sA []Segment
series.Search(series.Rect(), func(seg Segment, idx int) bool {
seg2sA = append(seg2sA, seg)
return true
})
var seg2sB []Segment
seriesForEachSegment(&series, func(seg Segment) bool {
seg2sB = append(seg2sB, seg)
return true
})
expect(t, checkSegsDups(seg2sA, seg2sB))
})
}
func TestSeriesReverse(t *testing.T) {
shapes := [][]Point{octagon, concave1, concave2, concave3, concave4}
for _, shape := range shapes {
var rev []Point
for i := len(shape) - 1; i >= 0; i-- {
rev = append(rev, shape[i])
}
series := makeSeries(rev, true, true, DefaultIndex)
var seg2sA []Segment
series.Search(series.Rect(), func(seg Segment, idx int) bool {
seg2sA = append(seg2sA, seg)
return true
})
var seg2sB []Segment
seriesForEachSegment(&series, func(seg Segment) bool {
seg2sB = append(seg2sB, seg)
return true
})
}
}
func checkSegsDups(a, b []Segment) bool {
if len(a) != len(b) {
return false
}
for _, a := range a {
var found bool
for _, b := range b {
if a == b {
found = true
break
}
}
if !found {
return false
}
}
return true
}
func TestSeriesMove(t *testing.T) {
shapes := [][]Point{ri, octagon}
for _, shape := range shapes {
series := makeSeries(shape, true, true, DefaultIndex)
series.tree = nil
series2 := series.Move(60, 70)
expect(t, series2.NumPoints() == len(shape))
for i := 0; i < len(shape); i++ {
expect(t, series2.PointAt(i) == shape[i].Move(60, 70))
}
series.buildTree()
series2 = series.Move(60, 70)
expect(t, series2.NumPoints() == len(shape))
for i := 0; i < len(shape); i++ {
expect(t, series2.PointAt(i) == shape[i].Move(60, 70))
}
}
}