mirror of https://github.com/tidwall/tile38.git
Added BOUNDS command
It's now possible to get the combined minimum bounding rectangle for all objects in a key by issuing the command "BOUNDS key".
This commit is contained in:
parent
6e4977ac0f
commit
1d427c849f
|
@ -86,6 +86,11 @@ func (c *Collection) TotalWeight() int {
|
|||
return c.weight
|
||||
}
|
||||
|
||||
// Bounds returns the bounds of all the items in the collection.
|
||||
func (c *Collection) Bounds() (minX, minY, maxX, maxY float64) {
|
||||
return c.index.Bounds()
|
||||
}
|
||||
|
||||
// ReplaceOrInsert adds or replaces an object in the collection and returns the fields array.
|
||||
// If an item with the same id is already in the collection then the new item will adopt the old item's fields.
|
||||
// The fields argument is optional.
|
||||
|
|
|
@ -333,7 +333,7 @@ func (c *Controller) handleInputCommand(conn *server.Conn, msg *server.Message,
|
|||
if c.config.ReadOnly {
|
||||
return writeErr(errors.New("read only"))
|
||||
}
|
||||
case "get", "keys", "scan", "nearby", "within", "intersects", "hooks", "search", "ttl":
|
||||
case "get", "keys", "scan", "nearby", "within", "intersects", "hooks", "search", "ttl", "bounds":
|
||||
// read operations
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
|
@ -444,6 +444,8 @@ func (c *Controller) command(msg *server.Message, w io.Writer) (res string, d co
|
|||
res, err = c.cmdIntersects(msg)
|
||||
case "search":
|
||||
res, err = c.cmdSearch(msg)
|
||||
case "bounds":
|
||||
res, err = c.cmdBounds(msg)
|
||||
case "get":
|
||||
res, err = c.cmdGet(msg)
|
||||
case "keys":
|
||||
|
|
|
@ -47,6 +47,63 @@ func orderFields(fmap map[string]int, fields []float64) []fvt {
|
|||
sort.Sort(byField(fvs))
|
||||
return fvs
|
||||
}
|
||||
func (c *Controller) cmdBounds(msg *server.Message) (string, error) {
|
||||
start := time.Now()
|
||||
vs := msg.Values[1:]
|
||||
|
||||
var ok bool
|
||||
var key string
|
||||
if vs, key, ok = tokenval(vs); !ok || key == "" {
|
||||
return "", errInvalidNumberOfArguments
|
||||
}
|
||||
if len(vs) != 0 {
|
||||
return "", errInvalidNumberOfArguments
|
||||
}
|
||||
|
||||
col := c.getCol(key)
|
||||
if col == nil {
|
||||
if msg.OutputType == server.RESP {
|
||||
return "$-1\r\n", nil
|
||||
}
|
||||
return "", errKeyNotFound
|
||||
}
|
||||
|
||||
vals := make([]resp.Value, 0, 2)
|
||||
var buf bytes.Buffer
|
||||
if msg.OutputType == server.JSON {
|
||||
buf.WriteString(`{"ok":true`)
|
||||
}
|
||||
bbox := geojson.New2DBBox(col.Bounds())
|
||||
if msg.OutputType == server.JSON {
|
||||
buf.WriteString(`,"bounds":`)
|
||||
buf.WriteString(bbox.ExternalJSON())
|
||||
} else {
|
||||
vals = append(vals, resp.ArrayValue([]resp.Value{
|
||||
resp.ArrayValue([]resp.Value{
|
||||
resp.FloatValue(bbox.Min.Y),
|
||||
resp.FloatValue(bbox.Min.X),
|
||||
}),
|
||||
resp.ArrayValue([]resp.Value{
|
||||
resp.FloatValue(bbox.Max.Y),
|
||||
resp.FloatValue(bbox.Max.X),
|
||||
}),
|
||||
}))
|
||||
}
|
||||
switch msg.OutputType {
|
||||
case server.JSON:
|
||||
buf.WriteString(`,"elapsed":"` + time.Now().Sub(start).String() + "\"}")
|
||||
return buf.String(), nil
|
||||
case server.RESP:
|
||||
var oval resp.Value
|
||||
oval = vals[0]
|
||||
data, err := oval.MarshalRESP()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (c *Controller) cmdGet(msg *server.Message) (string, error) {
|
||||
start := time.Now()
|
||||
|
|
|
@ -176,6 +176,18 @@
|
|||
"since": "1.0.0",
|
||||
"group": "keys"
|
||||
},
|
||||
"BOUNDS": {
|
||||
"summary": "Get the combined bounds of all the objects in a key",
|
||||
"complexity": "O(1)",
|
||||
"arguments":[
|
||||
{
|
||||
"name": "key",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"since": "1.3.0",
|
||||
"group": "keys"
|
||||
},
|
||||
"GET": {
|
||||
"summary": "Get the object of an id",
|
||||
"complexity": "O(1)",
|
||||
|
|
|
@ -338,6 +338,18 @@ var commandsJSON = `{
|
|||
"since": "1.0.0",
|
||||
"group": "keys"
|
||||
},
|
||||
"BOUNDS": {
|
||||
"summary": "Get the combined bounds of all the objects in a key",
|
||||
"complexity": "O(1)",
|
||||
"arguments":[
|
||||
{
|
||||
"name": "key",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"since": "1.3.0",
|
||||
"group": "keys"
|
||||
},
|
||||
"GET": {
|
||||
"summary": "Get the object of an id",
|
||||
"complexity": "O(1)",
|
||||
|
|
|
@ -99,6 +99,11 @@ func (ix *Index) Count() int {
|
|||
return count
|
||||
}
|
||||
|
||||
// Bounds returns the minimum bounding rectangle of all items in the index.
|
||||
func (ix *Index) Bounds() (MinX, MinY, MaxX, MaxY float64) {
|
||||
return ix.r.Bounds()
|
||||
}
|
||||
|
||||
// RemoveAll removes all items from the index.
|
||||
func (ix *Index) RemoveAll() {
|
||||
ix.r.RemoveAll()
|
||||
|
|
Loading…
Reference in New Issue