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},
pointOn := points[len(points)/2] IndexOptions{Kind: RTreeCompressed, MinPoints: 64},
IndexOptions{Kind: RTree, MinPoints: 64},
// ioutil.WriteFile(label+".svg", []byte(tools.SVG(tree.(*baseSeries).tree)), 0666)
expect(t, ringContainsPoint(simple, pointIn, true).hit)
expect(t, ringContainsPoint(tree, pointIn, 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" {
lotsa.Output = os.Stderr
fmt.Printf(label + "/simp/in ")
lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(simple, pointIn, true)
})
fmt.Printf(label + "/tree/in ")
lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(tree, pointIn, true)
})
fmt.Printf(label + "/simp/on ")
lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(simple, pointOn, true)
})
fmt.Printf(label + "/tree/on ")
lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(tree, pointOn, 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)
})
} }
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]
// tests
expect(t, ringContainsPoint(ring, pointIn, true).hit)
expect(t, ringContainsPoint(ring, pointOn, true).hit)
expect(t, !ringContainsPoint(ring, pointOn, false).hit)
expect(t, !ringContainsPoint(ring, pointOut, true).hit)
if os.Getenv("PIPBENCH") == "1" {
fmt.Printf("%s/%s ", label, opts.Kind.shortString())
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) {
ringContainsPoint(ring, pointIn, true)
})
fmt.Printf("%s/%s/on ", label, opts.Kind.shortString())
lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(ring, pointOn, true)
})
fmt.Printf("%s/%s/out ", label, opts.Kind.shortString())
lotsa.Ops(N, T, func(_, _ int) {
ringContainsPoint(ring, pointOut, true)
})
fmt.Printf("%s/%s/rnd ", label, opts.Kind.shortString())
lotsa.Ops(N, T, func(i, _ int) {
ringContainsPoint(ring, randPoints[i], 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,