Skip to content

Commit 653aea6

Browse files
committed
Expose geojson PROPERTIES to whereeval
This commit adds a new Lua variable named PROPERTIES that provides the GeoJSON 'properties' member as a decoded Lua table. For example, take this geojson object. { "type": "Feature", "geometry": { "type": Point, "coordinates": [ -112, 33 ] }, "properties": { "speed": 85 } } Now the Tile38 command can be used to filter on object SCAN fleet WHEREEVAL 'return PROPERTIES.speed > 75'
1 parent 6b98734 commit 653aea6

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

internal/server/scanner.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,16 +271,18 @@ func (sw *scanWriter) fieldMatch(o *object.Object) (bool, error) {
271271
}
272272
if len(sw.whereevals) > 0 {
273273
fieldNames := make(map[string]field.Value)
274+
var props string
274275
if objIsSpatial(o.Geo()) {
275276
z := extractZCoordinate(o.Geo())
276277
fieldNames["z"] = field.ValueOf(strconv.FormatFloat(z, 'f', -1, 64))
278+
props = gjson.Get(o.Geo().Members(), "properties").Raw
277279
}
278280
o.Fields().Scan(func(f field.Field) bool {
279281
fieldNames[f.Name()] = f.Value()
280282
return true
281283
})
282284
for _, whereval := range sw.whereevals {
283-
match, err := whereval.match(fieldNames)
285+
match, err := whereval.match(fieldNames, o.ID(), props)
284286
if err != nil {
285287
return false, err
286288
}

internal/server/token.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/tidwall/tile38/internal/field"
1111
lua "github.com/yuin/gopher-lua"
12+
luajson "layeh.com/gopher-json"
1213
)
1314

1415
const defaultSearchOutput = outputObjects
@@ -158,18 +159,33 @@ func luaSetField(tbl *lua.LTable, name string, val field.Value) {
158159
tbl.RawSetString(name, lval)
159160
}
160161

161-
func (whereeval whereevalT) match(fieldsWithNames map[string]field.Value) (bool, error) {
162+
func (whereeval whereevalT) match(fieldsWithNames map[string]field.Value,
163+
id string, props string) (bool, error,
164+
) {
162165
fieldsTbl := whereeval.luaState.CreateTable(0, len(fieldsWithNames))
163166
for name, val := range fieldsWithNames {
164167
luaSetField(fieldsTbl, name, val)
165168
}
169+
var lprops lua.LValue
170+
if props != "" {
171+
var err error
172+
lprops, err = luajson.Decode(whereeval.luaState, []byte(props))
173+
if err != nil {
174+
lprops = lua.LNil
175+
}
176+
}
177+
// lua.LTString
166178
luaSetRawGlobals(
167179
whereeval.luaState, map[string]lua.LValue{
168-
"FIELDS": fieldsTbl,
180+
"ID": lua.LString(id),
181+
"FIELDS": fieldsTbl,
182+
"PROPERTIES": lprops,
169183
})
170184
defer luaSetRawGlobals(
171185
whereeval.luaState, map[string]lua.LValue{
172-
"FIELDS": lua.LNil,
186+
"ID": lua.LNil,
187+
"FIELDS": lua.LNil,
188+
"PROPERTIES": lua.LNil,
173189
})
174190

175191
whereeval.luaState.Push(whereeval.fn)

0 commit comments

Comments
 (0)