mirror of https://github.com/tidwall/tile38.git
Optimize point in ring
This commit is contained in:
parent
5162ac5fd7
commit
b3dc025545
2
go.mod
2
go.mod
|
@ -28,7 +28,7 @@ require (
|
|||
github.com/tidwall/buntdb v1.1.0
|
||||
github.com/tidwall/cities v0.0.0-20190730194520-dbe1ae0b862c // indirect
|
||||
github.com/tidwall/geoindex v1.1.0
|
||||
github.com/tidwall/geojson v1.1.12
|
||||
github.com/tidwall/geojson v1.1.13
|
||||
github.com/tidwall/gjson v1.3.2
|
||||
github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb // indirect
|
||||
github.com/tidwall/lotsa v0.0.0-20180225195211-a03631ac7f1c // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -67,6 +67,8 @@ github.com/tidwall/geojson v1.1.10 h1:ALzsrTn62pq65DudSQpYDjjCUaq6dP1XQm51GVYgJy
|
|||
github.com/tidwall/geojson v1.1.10/go.mod h1:tBjfxeALRFLc25LLpjtWzy2nIrNmW1ze1EAhLtd8+QQ=
|
||||
github.com/tidwall/geojson v1.1.12 h1:Ol83kqH2zeYJHP16xteZtr8VRukIXeF/TqVvJodM41M=
|
||||
github.com/tidwall/geojson v1.1.12/go.mod h1:tBjfxeALRFLc25LLpjtWzy2nIrNmW1ze1EAhLtd8+QQ=
|
||||
github.com/tidwall/geojson v1.1.13 h1:P7f58SrQgyb9k3HjKStRLug4i/0U+1MJ00f/4Z92wcM=
|
||||
github.com/tidwall/geojson v1.1.13/go.mod h1:tBjfxeALRFLc25LLpjtWzy2nIrNmW1ze1EAhLtd8+QQ=
|
||||
github.com/tidwall/gjson v1.3.2 h1:+7p3qQFaH3fOMXAJSrdZwGKcOO/lYdGS0HqGhPqDdTI=
|
||||
github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
||||
github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb h1:5NSYaAdrnblKByzd7XByQEJVT8+9v0W/tIY0Oo4OwrE=
|
||||
|
|
|
@ -24,30 +24,59 @@ type ringResult struct {
|
|||
}
|
||||
|
||||
func ringContainsPoint(ring Ring, point Point, allowOnEdge bool) ringResult {
|
||||
// println("A")
|
||||
var idx = -1
|
||||
// find all intersecting segments on the y-axis
|
||||
var in bool
|
||||
var idx int
|
||||
rect := Rect{Point{math.Inf(-1), point.Y}, Point{math.Inf(+1), point.Y}}
|
||||
if bs, ok := ring.(*baseSeries); ok {
|
||||
in, idx = ringContainsPointBaseSeries(rect, bs, point, allowOnEdge)
|
||||
} else {
|
||||
in, idx = ringContainsPointGeneric(rect, ring, point, allowOnEdge)
|
||||
}
|
||||
return ringResult{hit: in, idx: idx}
|
||||
}
|
||||
|
||||
func containsPointSearcher(point Point, allowOnEdge bool, idx *int, in *bool, seg Segment, index int) bool {
|
||||
// perform a raycast operation on the segments
|
||||
res := seg.Raycast(point)
|
||||
if res.On {
|
||||
*in = allowOnEdge
|
||||
*idx = index
|
||||
return false
|
||||
}
|
||||
if res.In {
|
||||
*in = !*in
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NOTE: Although it may seem that ringContainsPointBaseSeries and ringContainsPointGeneric
|
||||
// are the same, they are not. Because the type of the `ring` argument is known in
|
||||
// ringContainsPointBaseSeries, the compiler can prove that the closure passed to
|
||||
// ring.Search does not escape, and hence save us 3 heap allocations and ~6% runtime.
|
||||
|
||||
func ringContainsPointBaseSeries(rect Rect, ring *baseSeries, point Point, allowOnEdge bool) (bool, int) {
|
||||
var idx = -1
|
||||
var in bool
|
||||
|
||||
ring.Search(
|
||||
Rect{Point{math.Inf(-1), point.Y}, Point{math.Inf(+1), point.Y}},
|
||||
rect,
|
||||
func(seg Segment, index int) bool {
|
||||
// fmt.Printf("%v %v\n", point, seg)
|
||||
// perform a raycast operation on the segments
|
||||
res := seg.Raycast(point)
|
||||
if res.On {
|
||||
// println(1)
|
||||
in = allowOnEdge
|
||||
idx = index
|
||||
return false
|
||||
}
|
||||
if res.In {
|
||||
// println(2)
|
||||
in = !in
|
||||
}
|
||||
return true
|
||||
return containsPointSearcher(point, allowOnEdge, &idx, &in, seg, index)
|
||||
},
|
||||
)
|
||||
return ringResult{hit: in, idx: idx}
|
||||
return in, idx
|
||||
}
|
||||
|
||||
func ringContainsPointGeneric(rect Rect, ring Ring, point Point, allowOnEdge bool) (bool, int) {
|
||||
var idx = -1
|
||||
var in bool
|
||||
ring.Search(
|
||||
rect,
|
||||
func(seg Segment, index int) bool {
|
||||
return containsPointSearcher(point, allowOnEdge, &idx, &in, seg, index)
|
||||
},
|
||||
)
|
||||
return in, idx
|
||||
}
|
||||
|
||||
func ringIntersectsPoint(ring Ring, point Point, allowOnEdge bool) ringResult {
|
||||
|
|
|
@ -81,7 +81,7 @@ github.com/tidwall/buntdb
|
|||
# github.com/tidwall/geoindex v1.1.0
|
||||
github.com/tidwall/geoindex
|
||||
github.com/tidwall/geoindex/child
|
||||
# github.com/tidwall/geojson v1.1.12
|
||||
# github.com/tidwall/geojson v1.1.13
|
||||
github.com/tidwall/geojson
|
||||
github.com/tidwall/geojson/geo
|
||||
github.com/tidwall/geojson/geometry
|
||||
|
|
Loading…
Reference in New Issue