Update geojson package

This commit is contained in:
tidwall 2018-10-22 05:40:56 -07:00
parent 7cc4008442
commit a9a1612972
3 changed files with 94 additions and 55 deletions

4
Gopkg.lock generated
View File

@ -227,7 +227,7 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:9fcbc64769ddda5230be91f192aa87aa8233f9776053108c1c89e1263f2c4a98" digest = "1:c0012e273a29ef7c490e8a4d28c23f2135b8aa9980121a65bdc032163d7cbfd5"
name = "github.com/tidwall/geojson" name = "github.com/tidwall/geojson"
packages = [ packages = [
".", ".",
@ -235,7 +235,7 @@
"geometry", "geometry",
] ]
pruneopts = "" pruneopts = ""
revision = "2d2f7893c3d92f36cef52047d457573ed44d6f04" revision = "a1db67ca0ab0c8e59a5fc9d03d0e1d88f87b6902"
[[projects]] [[projects]]
digest = "1:3ddca2bd5496c6922a2a9e636530e178a43c2a534ea6634211acdc7d10222794" digest = "1:3ddca2bd5496c6922a2a9e636530e178a43c2a534ea6634211acdc7d10222794"

View File

@ -6,63 +6,102 @@ package geometry
import ( import (
"fmt" "fmt"
"math/rand"
"os" "os"
"runtime"
"runtime/debug"
"testing" "testing"
"time"
"github.com/tidwall/lotsa" "github.com/tidwall/lotsa"
) )
func (kind IndexKind) shortString() string {
switch kind {
default:
return "unkn"
case None:
return "none"
case RTree:
return "rtre"
case RTreeCompressed:
return "rtrc"
case QuadTree:
return "quad"
case QuadTreeCompressed:
return "quac"
}
}
func testBig( func testBig(
t *testing.T, label string, points []Point, pointIn, pointOut Point, t *testing.T, label string, points []Point, pointIn, pointOut Point,
) { ) {
N, T := 100000, 4 N, T := 100000, 4
simple := newRing(points, DefaultIndexOptions) opts := []IndexOptions{
simple.(*baseSeries).clearIndex() IndexOptions{Kind: None, MinPoints: 64},
tree := newRing(points, DefaultIndexOptions) IndexOptions{Kind: QuadTreeCompressed, MinPoints: 64},
tree.(*baseSeries).buildIndex() IndexOptions{Kind: QuadTree, MinPoints: 64},
IndexOptions{Kind: RTreeCompressed, MinPoints: 64},
IndexOptions{Kind: RTree, MinPoints: 64},
}
for _, opts := range opts {
var ms1, ms2 runtime.MemStats
runtime.GC()
debug.FreeOSMemory()
runtime.ReadMemStats(&ms1)
start := time.Now()
ring := newRing(points, &opts)
dur := time.Since(start)
runtime.GC()
debug.FreeOSMemory()
runtime.ReadMemStats(&ms2)
var randPoints []Point
if os.Getenv("PIPBENCH") == "1" {
rect := ring.Rect()
randPoints = make([]Point, N)
for i := 0; i < N; i++ {
randPoints[i] = Point{
X: (rect.Max.X-rect.Min.X)*rand.Float64() + rect.Min.X,
Y: (rect.Max.Y-rect.Min.Y)*rand.Float64() + rect.Min.Y,
}
}
}
pointOn := points[len(points)/2] pointOn := points[len(points)/2]
// ioutil.WriteFile(label+".svg", []byte(tools.SVG(tree.(*baseSeries).tree)), 0666) // tests
expect(t, ringContainsPoint(ring, pointIn, true).hit)
expect(t, ringContainsPoint(simple, pointIn, true).hit) expect(t, ringContainsPoint(ring, pointOn, true).hit)
expect(t, ringContainsPoint(tree, pointIn, true).hit) expect(t, !ringContainsPoint(ring, pointOn, false).hit)
expect(t, !ringContainsPoint(ring, pointOut, true).hit)
expect(t, ringContainsPoint(simple, pointOn, true).hit)
expect(t, ringContainsPoint(tree, pointOn, true).hit)
expect(t, !ringContainsPoint(simple, pointOn, false).hit)
expect(t, !ringContainsPoint(tree, pointOn, false).hit)
expect(t, !ringContainsPoint(simple, pointOut, true).hit)
expect(t, !ringContainsPoint(tree, pointOut, true).hit)
if os.Getenv("PIPBENCH") == "1" { if os.Getenv("PIPBENCH") == "1" {
lotsa.Output = os.Stderr fmt.Printf("%s/%s ", label, opts.Kind.shortString())
fmt.Printf(label + "/simp/in ") mem := ms2.Alloc - ms1.Alloc
fmt.Printf("created in %s using %d bytes\n", dur, mem)
lotsa.Output = os.Stdout
fmt.Printf("%s/%s/in ", label, opts.Kind.shortString())
lotsa.Ops(N, T, func(_, _ int) { lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(simple, pointIn, true) ringContainsPoint(ring, pointIn, true)
}) })
fmt.Printf(label + "/tree/in ") fmt.Printf("%s/%s/on ", label, opts.Kind.shortString())
lotsa.Ops(N, T, func(_, _ int) { lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(tree, pointIn, true) ringContainsPoint(ring, pointOn, true)
}) })
fmt.Printf(label + "/simp/on ") fmt.Printf("%s/%s/out ", label, opts.Kind.shortString())
lotsa.Ops(N, T, func(_, _ int) { lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(simple, pointOn, true) ringContainsPoint(ring, pointOut, true)
}) })
fmt.Printf(label + "/tree/on ") fmt.Printf("%s/%s/rnd ", label, opts.Kind.shortString())
lotsa.Ops(N, T, func(_, _ int) { lotsa.Ops(N, T, func(i, _ int) {
ringContainsPoint(tree, pointOn, true) ringContainsPoint(ring, randPoints[i], true)
})
fmt.Printf(label + "/simp/out ")
lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(simple, pointOut, true)
})
fmt.Printf(label + "/tree/out ")
lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(tree, pointOut, true)
}) })
} }
}
} }
func TestBigArizona(t *testing.T) { func TestBigArizona(t *testing.T) {

View File

@ -279,6 +279,14 @@ func appendFloat(dst []byte, num float64) []byte {
return append(dst, buf[:]...) return append(dst, buf[:]...)
} }
func (tr *rTree) compress(dst []byte) []byte {
if tr.root.data == nil {
return dst
}
dst = append(dst, byte(tr.height))
return tr.root.compress(dst, tr.height)
}
func (r *rRect) compress(dst []byte, height int) []byte { func (r *rRect) compress(dst []byte, height int) []byte {
n := r.data.(*rNode) n := r.data.(*rNode)
dst = appendFloat(dst, r.min[0]) dst = appendFloat(dst, r.min[0])
@ -312,14 +320,6 @@ func (r *rRect) compress(dst []byte, height int) []byte {
return dst return dst
} }
func (tr *rTree) compress(dst []byte) []byte {
if tr.root.data == nil {
return dst
}
dst = append(dst, byte(tr.height))
return tr.root.compress(dst, tr.height)
}
func rCompressSearch( func rCompressSearch(
data []byte, data []byte,
addr int, addr int,