diff --git a/core/commands.json b/core/commands.json index 93372653..26c9ed69 100644 --- a/core/commands.json +++ b/core/commands.json @@ -1,5 +1,5 @@ { - "SET":{ + "SET": { "summary": "Sets the value of an id", "complexity": "O(1)", "arguments": [ @@ -35,14 +35,14 @@ { "name": "XX" } - ] + ] }, - { - "name": "value", + { + "name": "value", "enumargs": [ { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -51,7 +51,7 @@ }, { "name": "POINT", - "arguments":[ + "arguments": [ { "name": "lat", "type": "double" @@ -69,7 +69,7 @@ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -90,7 +90,7 @@ }, { "name": "HASH", - "arguments":[ + "arguments": [ { "name": "geohash", "type": "geohash" @@ -99,7 +99,7 @@ }, { "name": "STRING", - "arguments":[ + "arguments": [ { "name": "value", "type": "string" @@ -115,7 +115,7 @@ "EXPIRE": { "summary": "Set a timeout on an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -135,7 +135,7 @@ "TTL": { "summary": "Get a timeout on an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -151,7 +151,7 @@ "PERSIST": { "summary": "Remove the existing timeout on an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -167,7 +167,7 @@ "FSET": { "summary": "Set the value for one or more fields of an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -183,12 +183,12 @@ "optional": true }, { - "name": ["field","value"], - "type": ["string","double"] + "name": ["field", "value"], + "type": ["string", "double"] }, { - "name": ["field","value"], - "type": ["string","double"], + "name": ["field", "value"], + "type": ["string", "double"], "multiple": true, "optional": true } @@ -199,7 +199,7 @@ "BOUNDS": { "summary": "Get the combined bounds of all the objects in a key", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -211,7 +211,7 @@ "GET": { "summary": "Get the object of an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -257,7 +257,7 @@ "DEL": { "summary": "Delete an id from a key", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -273,7 +273,7 @@ "DROP": { "summary": "Remove a key from the database", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -317,7 +317,7 @@ "KEYS": { "summary": "Finds all keys matching the given pattern", "complexity": "O(N) where N is the number of keys in the database", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -329,7 +329,7 @@ "STATS": { "summary": "Show stats for one or more keys", "complexity": "O(N) where N is the number of keys being requested", - "arguments":[ + "arguments": [ { "name": "key", "type": "string", @@ -342,7 +342,7 @@ "SEARCH": { "summary": "Search for string values in a key", "complexity": "O(N) where N is the number of values in the key", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -375,35 +375,35 @@ { "name": "DESC" } - ] - }, + ] + }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -433,7 +433,7 @@ "SCAN": { "summary": "Incrementally iterate though a key", "complexity": "O(N) where N is the number of ids in the key", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -466,35 +466,35 @@ { "name": "DESC" } - ] - }, + ] + }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -542,7 +542,7 @@ "NEARBY": { "summary": "Searches for ids that are nearby a point", "complexity": "O(log(N)) where N is the number of ids in the area", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -579,31 +579,31 @@ }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -684,7 +684,7 @@ }, { "name": "ROAM", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -708,7 +708,7 @@ "WITHIN": { "summary": "Searches for ids that completely within the area", "complexity": "O(log(N)) where N is the number of ids in the area", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -739,31 +739,31 @@ }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -840,7 +840,7 @@ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -861,7 +861,7 @@ }, { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -887,7 +887,7 @@ }, { "name": "TILE", - "arguments":[ + "arguments": [ { "name": "x", "type": "double" @@ -904,7 +904,7 @@ }, { "name": "QUADKEY", - "arguments":[ + "arguments": [ { "name": "quadkey", "type": "string" @@ -919,6 +919,31 @@ "type": "geohash" } ] + }, + { + "name": "SECTOR", + "arguments": [ + { + "name": "lat", + "type": "double" + }, + { + "name": "lon", + "type": "double" + }, + { + "name": "radius", + "type": "double" + }, + { + "name": "startBearing", + "type": "double" + }, + { + "name": "endBearing", + "type": "double" + } + ] } ] } @@ -929,7 +954,7 @@ "INTERSECTS": { "summary": "Searches for ids that intersect an area", "complexity": "O(log(N)) where N is the number of ids in the area", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -960,31 +985,31 @@ }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -1067,7 +1092,7 @@ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -1088,7 +1113,7 @@ }, { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -1114,7 +1139,7 @@ }, { "name": "TILE", - "arguments":[ + "arguments": [ { "name": "x", "type": "double" @@ -1131,7 +1156,7 @@ }, { "name": "QUADKEY", - "arguments":[ + "arguments": [ { "name": "quadkey", "type": "string" @@ -1146,6 +1171,31 @@ "type": "geohash" } ] + }, + { + "name": "SECTOR", + "arguments": [ + { + "name": "lat", + "type": "double" + }, + { + "name": "lon", + "type": "double" + }, + { + "name": "radius", + "type": "double" + }, + { + "name": "startBearing", + "type": "double" + }, + { + "name": "endBearing", + "type": "double" + } + ] } ] } @@ -1155,7 +1205,7 @@ }, "CONFIG GET": { "summary": "Get the value of a configuration parameter", - "arguments":[ + "arguments": [ { "name": "parameter", "type": "string" @@ -1165,7 +1215,7 @@ }, "CONFIG SET": { "summary": "Set a configuration parameter to the given value", - "arguments":[ + "arguments": [ { "name": "parameter", "type": "string" @@ -1180,18 +1230,18 @@ }, "CONFIG REWRITE": { "summary": "Rewrite the configuration file with the in memory configuration", - "arguments":[], + "arguments": [], "group": "server" }, "SERVER": { - "summary":"Show server stats and details", + "summary": "Show server stats and details", "complexity": "O(1)", "arguments": [], "since": "1.0.0", "group": "server" }, "GC": { - "summary":"Forces a garbage collection", + "summary": "Forces a garbage collection", "complexity": "O(1)", "arguments": [], "since": "1.0.0", @@ -1202,14 +1252,14 @@ "complexity": "O(1)", "arguments": [ { - "enum": ["yes","no"] + "enum": ["yes", "no"] } ], "since": "1.0.0", "group": "server" }, "FLUSHDB": { - "summary":"Removes all keys", + "summary": "Removes all keys", "complexity": "O(1)", "arguments": [], "since": "1.0.0", @@ -1335,7 +1385,7 @@ "name": ["name", "value"], "type": ["string", "string"], "optional": true, - "multiple": true + "multiple": true }, { "command": "EX", @@ -1373,7 +1423,6 @@ "type": "string", "variadic": true } - ], "group": "webhook" }, @@ -1389,7 +1438,7 @@ }, "HOOKS": { "summary": "Finds all hooks matching a pattern", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -1399,7 +1448,7 @@ }, "PDELHOOK": { "summary": "Removes all hooks matching a pattern", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -1420,7 +1469,7 @@ "name": ["name", "value"], "type": ["string", "string"], "optional": true, - "multiple": true + "multiple": true }, { "command": "EX", @@ -1458,7 +1507,6 @@ "type": "string", "variadic": true } - ], "group": "pubsub" }, @@ -1474,7 +1522,7 @@ }, "CHANS": { "summary": "Finds all channels matching a pattern", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -1484,7 +1532,7 @@ }, "PDELCHAN": { "summary": "Removes all channels matching a pattern", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -1494,7 +1542,7 @@ }, "SUBSCRIBE": { "summary": "Subscribe to a geofence channel", - "arguments":[ + "arguments": [ { "name": "channel", "type": "string", @@ -1505,7 +1553,7 @@ }, "PSUBSCRIBE": { "summary": "Subscribes the client to the given patterns", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern", @@ -1516,12 +1564,12 @@ }, "PDEL": { "summary": "Removes all objects matching a pattern", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" }, - { + { "name": "pattern", "type": "pattern" } @@ -1531,7 +1579,7 @@ "JGET": { "summary": "Get a value from a JSON document", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -1556,7 +1604,7 @@ "JSET": { "summary": "Set a value in a JSON document", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -1591,7 +1639,7 @@ "JDEL": { "summary": "Delete a value from a JSON document", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -1607,7 +1655,7 @@ ], "group": "keys" }, - "EVAL":{ + "EVAL": { "summary": "Evaluates a Lua script", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1635,7 +1683,7 @@ "since": "1.10.0", "group": "scripting" }, - "EVALSHA":{ + "EVALSHA": { "summary": "Evaluates a Lua script cached on the server by its SHA1 digest", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1663,7 +1711,7 @@ "since": "1.10.0", "group": "scripting" }, - "EVALRO":{ + "EVALRO": { "summary": "Evaluates a read-only Lua script", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1691,7 +1739,7 @@ "since": "1.10.0", "group": "scripting" }, - "EVALROSHA":{ + "EVALROSHA": { "summary": "Evaluates a read-only Lua script cached on the server by its SHA1 digest", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1719,7 +1767,7 @@ "since": "1.10.0", "group": "scripting" }, - "EVALNA":{ + "EVALNA": { "summary": "Evaluates a Lua script in a non-atomic fashion", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1747,7 +1795,7 @@ "since": "1.10.0", "group": "scripting" }, - "EVALNASHA":{ + "EVALNASHA": { "summary": "Evaluates, in a non-atomic fashion, a Lua script cached on the server by its SHA1 digest", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1775,7 +1823,7 @@ "since": "1.10.0", "group": "scripting" }, - "SCRIPT EXISTS":{ + "SCRIPT EXISTS": { "summary": "Returns information about the existence of the scripts in server cache", "complexity": "O(N) where N is the number of provided sha1 arguments", "arguments": [ @@ -1788,7 +1836,7 @@ "since": "1.10.0", "group": "scripting" }, - "SCRIPT LOAD":{ + "SCRIPT LOAD": { "summary": "Loads the compiled version of a script into the server cache, without executing", "complexity": "O(N) where N is the number of bytes in the script", "arguments": [ @@ -1800,13 +1848,13 @@ "since": "1.10.0", "group": "scripting" }, - "SCRIPT FLUSH":{ + "SCRIPT FLUSH": { "summary": "Flushes the server cache of Lua scripts", "complexity": "O(1)", "since": "1.10.0", "group": "scripting" }, - "TEST":{ + "TEST": { "summary": "Performs spatial test", "complexity": "One test per command, complexity depends on the test", "arguments": [ @@ -1841,7 +1889,7 @@ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -1862,7 +1910,7 @@ }, { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -1888,7 +1936,7 @@ }, { "name": "TILE", - "arguments":[ + "arguments": [ { "name": "x", "type": "double" @@ -1905,7 +1953,7 @@ }, { "name": "QUADKEY", - "arguments":[ + "arguments": [ { "name": "quadkey", "type": "string" @@ -1971,7 +2019,7 @@ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -1992,7 +2040,7 @@ }, { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -2018,7 +2066,7 @@ }, { "name": "TILE", - "arguments":[ + "arguments": [ { "name": "x", "type": "double" @@ -2035,7 +2083,7 @@ }, { "name": "QUADKEY", - "arguments":[ + "arguments": [ { "name": "quadkey", "type": "string" diff --git a/core/commands_gen.go b/core/commands_gen.go index e4a4a884..4e40941a 100644 --- a/core/commands_gen.go +++ b/core/commands_gen.go @@ -165,7 +165,7 @@ var Commands = func() map[string]Command { }() var commandsJSON = `{ - "SET":{ + "SET": { "summary": "Sets the value of an id", "complexity": "O(1)", "arguments": [ @@ -201,14 +201,14 @@ var commandsJSON = `{ { "name": "XX" } - ] + ] }, - { - "name": "value", + { + "name": "value", "enumargs": [ { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -217,7 +217,7 @@ var commandsJSON = `{ }, { "name": "POINT", - "arguments":[ + "arguments": [ { "name": "lat", "type": "double" @@ -235,7 +235,7 @@ var commandsJSON = `{ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -256,7 +256,7 @@ var commandsJSON = `{ }, { "name": "HASH", - "arguments":[ + "arguments": [ { "name": "geohash", "type": "geohash" @@ -265,7 +265,7 @@ var commandsJSON = `{ }, { "name": "STRING", - "arguments":[ + "arguments": [ { "name": "value", "type": "string" @@ -281,7 +281,7 @@ var commandsJSON = `{ "EXPIRE": { "summary": "Set a timeout on an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -301,7 +301,7 @@ var commandsJSON = `{ "TTL": { "summary": "Get a timeout on an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -317,7 +317,7 @@ var commandsJSON = `{ "PERSIST": { "summary": "Remove the existing timeout on an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -333,7 +333,7 @@ var commandsJSON = `{ "FSET": { "summary": "Set the value for one or more fields of an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -349,12 +349,12 @@ var commandsJSON = `{ "optional": true }, { - "name": ["field","value"], - "type": ["string","double"] + "name": ["field", "value"], + "type": ["string", "double"] }, { - "name": ["field","value"], - "type": ["string","double"], + "name": ["field", "value"], + "type": ["string", "double"], "multiple": true, "optional": true } @@ -365,7 +365,7 @@ var commandsJSON = `{ "BOUNDS": { "summary": "Get the combined bounds of all the objects in a key", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -377,7 +377,7 @@ var commandsJSON = `{ "GET": { "summary": "Get the object of an id", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -423,7 +423,7 @@ var commandsJSON = `{ "DEL": { "summary": "Delete an id from a key", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -439,7 +439,7 @@ var commandsJSON = `{ "DROP": { "summary": "Remove a key from the database", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -483,7 +483,7 @@ var commandsJSON = `{ "KEYS": { "summary": "Finds all keys matching the given pattern", "complexity": "O(N) where N is the number of keys in the database", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -495,7 +495,7 @@ var commandsJSON = `{ "STATS": { "summary": "Show stats for one or more keys", "complexity": "O(N) where N is the number of keys being requested", - "arguments":[ + "arguments": [ { "name": "key", "type": "string", @@ -508,7 +508,7 @@ var commandsJSON = `{ "SEARCH": { "summary": "Search for string values in a key", "complexity": "O(N) where N is the number of values in the key", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -541,35 +541,35 @@ var commandsJSON = `{ { "name": "DESC" } - ] - }, + ] + }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -599,7 +599,7 @@ var commandsJSON = `{ "SCAN": { "summary": "Incrementally iterate though a key", "complexity": "O(N) where N is the number of ids in the key", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -632,35 +632,35 @@ var commandsJSON = `{ { "name": "DESC" } - ] - }, + ] + }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -708,7 +708,7 @@ var commandsJSON = `{ "NEARBY": { "summary": "Searches for ids that are nearby a point", "complexity": "O(log(N)) where N is the number of ids in the area", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -745,31 +745,31 @@ var commandsJSON = `{ }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -850,7 +850,7 @@ var commandsJSON = `{ }, { "name": "ROAM", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -874,7 +874,7 @@ var commandsJSON = `{ "WITHIN": { "summary": "Searches for ids that completely within the area", "complexity": "O(log(N)) where N is the number of ids in the area", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -905,31 +905,31 @@ var commandsJSON = `{ }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -1006,7 +1006,7 @@ var commandsJSON = `{ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -1027,7 +1027,7 @@ var commandsJSON = `{ }, { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -1053,7 +1053,7 @@ var commandsJSON = `{ }, { "name": "TILE", - "arguments":[ + "arguments": [ { "name": "x", "type": "double" @@ -1070,7 +1070,7 @@ var commandsJSON = `{ }, { "name": "QUADKEY", - "arguments":[ + "arguments": [ { "name": "quadkey", "type": "string" @@ -1085,6 +1085,31 @@ var commandsJSON = `{ "type": "geohash" } ] + }, + { + "name": "SECTOR", + "arguments": [ + { + "name": "lat", + "type": "double" + }, + { + "name": "lon", + "type": "double" + }, + { + "name": "radius", + "type": "double" + }, + { + "name": "startBearing", + "type": "double" + }, + { + "name": "endBearing", + "type": "double" + } + ] } ] } @@ -1095,7 +1120,7 @@ var commandsJSON = `{ "INTERSECTS": { "summary": "Searches for ids that intersect an area", "complexity": "O(log(N)) where N is the number of ids in the area", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -1126,31 +1151,31 @@ var commandsJSON = `{ }, { "command": "WHERE", - "name": ["field","min","max"], - "type": ["string","double","double"], + "name": ["field", "min", "max"], + "type": ["string", "double", "double"], "optional": true, "multiple": true }, { "command": "WHEREIN", - "name": ["field","count","value"], - "type": ["string","integer","double"], + "name": ["field", "count", "value"], + "type": ["string", "integer", "double"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVAL", - "name": ["script","numargs","arg"], - "type": ["string","integer","string"], + "name": ["script", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true }, { "command": "WHEREEVALSHA", - "name": ["sha1","numargs","arg"], - "type": ["string","integer","string"], + "name": ["sha1", "numargs", "arg"], + "type": ["string", "integer", "string"], "optional": true, "multiple": true, "variadic": true @@ -1233,7 +1258,7 @@ var commandsJSON = `{ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -1254,7 +1279,7 @@ var commandsJSON = `{ }, { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -1280,7 +1305,7 @@ var commandsJSON = `{ }, { "name": "TILE", - "arguments":[ + "arguments": [ { "name": "x", "type": "double" @@ -1297,7 +1322,7 @@ var commandsJSON = `{ }, { "name": "QUADKEY", - "arguments":[ + "arguments": [ { "name": "quadkey", "type": "string" @@ -1312,6 +1337,31 @@ var commandsJSON = `{ "type": "geohash" } ] + }, + { + "name": "SECTOR", + "arguments": [ + { + "name": "lat", + "type": "double" + }, + { + "name": "lon", + "type": "double" + }, + { + "name": "radius", + "type": "double" + }, + { + "name": "startBearing", + "type": "double" + }, + { + "name": "endBearing", + "type": "double" + } + ] } ] } @@ -1321,7 +1371,7 @@ var commandsJSON = `{ }, "CONFIG GET": { "summary": "Get the value of a configuration parameter", - "arguments":[ + "arguments": [ { "name": "parameter", "type": "string" @@ -1331,7 +1381,7 @@ var commandsJSON = `{ }, "CONFIG SET": { "summary": "Set a configuration parameter to the given value", - "arguments":[ + "arguments": [ { "name": "parameter", "type": "string" @@ -1346,18 +1396,18 @@ var commandsJSON = `{ }, "CONFIG REWRITE": { "summary": "Rewrite the configuration file with the in memory configuration", - "arguments":[], + "arguments": [], "group": "server" }, "SERVER": { - "summary":"Show server stats and details", + "summary": "Show server stats and details", "complexity": "O(1)", "arguments": [], "since": "1.0.0", "group": "server" }, "GC": { - "summary":"Forces a garbage collection", + "summary": "Forces a garbage collection", "complexity": "O(1)", "arguments": [], "since": "1.0.0", @@ -1368,14 +1418,14 @@ var commandsJSON = `{ "complexity": "O(1)", "arguments": [ { - "enum": ["yes","no"] + "enum": ["yes", "no"] } ], "since": "1.0.0", "group": "server" }, "FLUSHDB": { - "summary":"Removes all keys", + "summary": "Removes all keys", "complexity": "O(1)", "arguments": [], "since": "1.0.0", @@ -1501,7 +1551,7 @@ var commandsJSON = `{ "name": ["name", "value"], "type": ["string", "string"], "optional": true, - "multiple": true + "multiple": true }, { "command": "EX", @@ -1539,7 +1589,6 @@ var commandsJSON = `{ "type": "string", "variadic": true } - ], "group": "webhook" }, @@ -1555,7 +1604,7 @@ var commandsJSON = `{ }, "HOOKS": { "summary": "Finds all hooks matching a pattern", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -1565,7 +1614,7 @@ var commandsJSON = `{ }, "PDELHOOK": { "summary": "Removes all hooks matching a pattern", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -1586,7 +1635,7 @@ var commandsJSON = `{ "name": ["name", "value"], "type": ["string", "string"], "optional": true, - "multiple": true + "multiple": true }, { "command": "EX", @@ -1624,7 +1673,6 @@ var commandsJSON = `{ "type": "string", "variadic": true } - ], "group": "pubsub" }, @@ -1640,7 +1688,7 @@ var commandsJSON = `{ }, "CHANS": { "summary": "Finds all channels matching a pattern", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -1650,7 +1698,7 @@ var commandsJSON = `{ }, "PDELCHAN": { "summary": "Removes all channels matching a pattern", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern" @@ -1660,7 +1708,7 @@ var commandsJSON = `{ }, "SUBSCRIBE": { "summary": "Subscribe to a geofence channel", - "arguments":[ + "arguments": [ { "name": "channel", "type": "string", @@ -1671,7 +1719,7 @@ var commandsJSON = `{ }, "PSUBSCRIBE": { "summary": "Subscribes the client to the given patterns", - "arguments":[ + "arguments": [ { "name": "pattern", "type": "pattern", @@ -1682,12 +1730,12 @@ var commandsJSON = `{ }, "PDEL": { "summary": "Removes all objects matching a pattern", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" }, - { + { "name": "pattern", "type": "pattern" } @@ -1697,7 +1745,7 @@ var commandsJSON = `{ "JGET": { "summary": "Get a value from a JSON document", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -1722,7 +1770,7 @@ var commandsJSON = `{ "JSET": { "summary": "Set a value in a JSON document", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -1757,7 +1805,7 @@ var commandsJSON = `{ "JDEL": { "summary": "Delete a value from a JSON document", "complexity": "O(1)", - "arguments":[ + "arguments": [ { "name": "key", "type": "string" @@ -1773,7 +1821,7 @@ var commandsJSON = `{ ], "group": "keys" }, - "EVAL":{ + "EVAL": { "summary": "Evaluates a Lua script", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1801,7 +1849,7 @@ var commandsJSON = `{ "since": "1.10.0", "group": "scripting" }, - "EVALSHA":{ + "EVALSHA": { "summary": "Evaluates a Lua script cached on the server by its SHA1 digest", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1829,7 +1877,7 @@ var commandsJSON = `{ "since": "1.10.0", "group": "scripting" }, - "EVALRO":{ + "EVALRO": { "summary": "Evaluates a read-only Lua script", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1857,7 +1905,7 @@ var commandsJSON = `{ "since": "1.10.0", "group": "scripting" }, - "EVALROSHA":{ + "EVALROSHA": { "summary": "Evaluates a read-only Lua script cached on the server by its SHA1 digest", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1885,7 +1933,7 @@ var commandsJSON = `{ "since": "1.10.0", "group": "scripting" }, - "EVALNA":{ + "EVALNA": { "summary": "Evaluates a Lua script in a non-atomic fashion", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1913,7 +1961,7 @@ var commandsJSON = `{ "since": "1.10.0", "group": "scripting" }, - "EVALNASHA":{ + "EVALNASHA": { "summary": "Evaluates, in a non-atomic fashion, a Lua script cached on the server by its SHA1 digest", "complexity": "Depends on the evaluated script", "arguments": [ @@ -1941,7 +1989,7 @@ var commandsJSON = `{ "since": "1.10.0", "group": "scripting" }, - "SCRIPT EXISTS":{ + "SCRIPT EXISTS": { "summary": "Returns information about the existence of the scripts in server cache", "complexity": "O(N) where N is the number of provided sha1 arguments", "arguments": [ @@ -1954,7 +2002,7 @@ var commandsJSON = `{ "since": "1.10.0", "group": "scripting" }, - "SCRIPT LOAD":{ + "SCRIPT LOAD": { "summary": "Loads the compiled version of a script into the server cache, without executing", "complexity": "O(N) where N is the number of bytes in the script", "arguments": [ @@ -1966,13 +2014,13 @@ var commandsJSON = `{ "since": "1.10.0", "group": "scripting" }, - "SCRIPT FLUSH":{ + "SCRIPT FLUSH": { "summary": "Flushes the server cache of Lua scripts", "complexity": "O(1)", "since": "1.10.0", "group": "scripting" }, - "TEST":{ + "TEST": { "summary": "Performs spatial test", "complexity": "One test per command, complexity depends on the test", "arguments": [ @@ -2007,7 +2055,7 @@ var commandsJSON = `{ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -2028,7 +2076,7 @@ var commandsJSON = `{ }, { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -2054,7 +2102,7 @@ var commandsJSON = `{ }, { "name": "TILE", - "arguments":[ + "arguments": [ { "name": "x", "type": "double" @@ -2071,7 +2119,7 @@ var commandsJSON = `{ }, { "name": "QUADKEY", - "arguments":[ + "arguments": [ { "name": "quadkey", "type": "string" @@ -2137,7 +2185,7 @@ var commandsJSON = `{ }, { "name": "BOUNDS", - "arguments":[ + "arguments": [ { "name": "minlat", "type": "double" @@ -2158,7 +2206,7 @@ var commandsJSON = `{ }, { "name": "OBJECT", - "arguments":[ + "arguments": [ { "name": "geojson", "type": "geojson" @@ -2184,7 +2232,7 @@ var commandsJSON = `{ }, { "name": "TILE", - "arguments":[ + "arguments": [ { "name": "x", "type": "double" @@ -2201,7 +2249,7 @@ var commandsJSON = `{ }, { "name": "QUADKEY", - "arguments":[ + "arguments": [ { "name": "quadkey", "type": "string" diff --git a/go.mod b/go.mod index ff78dd07..82383ee6 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/eclipse/paho.mqtt.golang v1.3.1 github.com/golang/protobuf v1.4.3 github.com/gomodule/redigo v1.8.3 + github.com/iwpnd/sectr v0.1.2 github.com/mmcloughlin/geohash v0.10.0 github.com/nats-io/nats-server/v2 v2.2.0 // indirect github.com/nats-io/nats.go v1.10.1-0.20210228004050-ed743748acac diff --git a/go.sum b/go.sum index 6afff4ac..1c8bfaff 100644 --- a/go.sum +++ b/go.sum @@ -214,6 +214,8 @@ github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmK github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/iwpnd/sectr v0.1.2 h1:FauaPRn5C2tC42HTF7gM3FJZXvGXWc6jabBbIxzTMag= +github.com/iwpnd/sectr v0.1.2/go.mod h1:Dm6YXDJCRx1NTfMX/1RMIkGfVp2ORjCY/cQGfbknz4c= github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= diff --git a/internal/server/search.go b/internal/server/search.go index c662915d..c37cc975 100644 --- a/internal/server/search.go +++ b/internal/server/search.go @@ -3,10 +3,12 @@ package server import ( "bytes" "errors" + "fmt" "strconv" "strings" "time" + "github.com/iwpnd/sectr" "github.com/mmcloughlin/geohash" "github.com/tidwall/geojson" "github.com/tidwall/geojson/geometry" @@ -214,6 +216,67 @@ func (server *Server) cmdSearchArgs( switch ltyp { case "point": fallthrough + case "sector": + if s.clip { + err = errInvalidArgument("cannot clip with " + ltyp) + return + } + var slat, slon, smeters, sb1, sb2 string + if vs, slat, ok = tokenval(vs); !ok || slat == "" { + err = errInvalidNumberOfArguments + return + } + if vs, slon, ok = tokenval(vs); !ok || slon == "" { + err = errInvalidNumberOfArguments + return + } + if vs, smeters, ok = tokenval(vs); !ok || smeters == "" { + err = errInvalidNumberOfArguments + return + } + if vs, sb1, ok = tokenval(vs); !ok || sb1 == "" { + err = errInvalidNumberOfArguments + return + } + if vs, sb2, ok = tokenval(vs); !ok || sb2 == "" { + err = errInvalidNumberOfArguments + return + } + var lat, lon, meters, b1, b2 float64 + if lat, err = strconv.ParseFloat(slat, 64); err != nil { + err = errInvalidArgument(slat) + return + } + if lon, err = strconv.ParseFloat(slon, 64); err != nil { + err = errInvalidArgument(slon) + return + } + if meters, err = strconv.ParseFloat(smeters, 64); err != nil { + err = errInvalidArgument(smeters) + return + } + if b1, err = strconv.ParseFloat(sb1, 64); err != nil { + err = errInvalidArgument(sb1) + return + } + if b2, err = strconv.ParseFloat(sb2, 64); err != nil { + err = errInvalidArgument(sb2) + return + } + + if b1 == b2 { + err = fmt.Errorf("equal bearings (%s == %s), use CIRCLE instead", sb1, sb2) + return + } + + origin := sectr.Point{Lng: lon, Lat: lat} + sector := sectr.NewSector(origin, meters, b1, b2) + + s.obj, err = geojson.Parse(string(sector.JSON()), &server.geomParseOpts) + if err != nil { + return + } + case "circle": if s.clip { err = errInvalidArgument("cannot clip with " + ltyp) @@ -379,7 +442,8 @@ func (server *Server) cmdSearchArgs( var nearbyTypes = []string{"point"} var withinOrIntersectsTypes = []string{ - "geo", "bounds", "hash", "tile", "quadkey", "get", "object", "circle"} + "geo", "bounds", "hash", "tile", "quadkey", "get", "object", "circle", "sector", +} func (server *Server) cmdNearby(msg *Message) (res resp.Value, err error) { start := time.Now() diff --git a/internal/server/test.go b/internal/server/test.go index 520babd6..01c7a604 100644 --- a/internal/server/test.go +++ b/internal/server/test.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/iwpnd/sectr" "github.com/mmcloughlin/geohash" "github.com/tidwall/geojson" "github.com/tidwall/geojson/geometry" @@ -47,6 +48,67 @@ func (s *Server) parseArea(ovs []string, doClip bool) (vs []string, o geojson.Ob return } o = geojson.NewPoint(geometry.Point{X: lon, Y: lat}) + case "sector": + if doClip { + err = errInvalidArgument("cannot clip with " + ltyp) + return + } + var slat, slon, smeters, sb1, sb2 string + if vs, slat, ok = tokenval(vs); !ok || slat == "" { + err = errInvalidNumberOfArguments + return + } + if vs, slon, ok = tokenval(vs); !ok || slon == "" { + err = errInvalidNumberOfArguments + return + } + if vs, smeters, ok = tokenval(vs); !ok || smeters == "" { + err = errInvalidNumberOfArguments + return + } + if vs, sb1, ok = tokenval(vs); !ok || sb1 == "" { + err = errInvalidNumberOfArguments + return + } + if vs, sb2, ok = tokenval(vs); !ok || sb2 == "" { + err = errInvalidNumberOfArguments + return + } + var lat, lon, meters, b1, b2 float64 + if lat, err = strconv.ParseFloat(slat, 64); err != nil { + err = errInvalidArgument(slat) + return + } + if lon, err = strconv.ParseFloat(slon, 64); err != nil { + err = errInvalidArgument(slon) + return + } + if meters, err = strconv.ParseFloat(smeters, 64); err != nil { + err = errInvalidArgument(smeters) + return + } + if b1, err = strconv.ParseFloat(sb1, 64); err != nil { + err = errInvalidArgument(sb1) + return + } + if b2, err = strconv.ParseFloat(sb2, 64); err != nil { + err = errInvalidArgument(sb2) + return + } + + if b1 == b2 { + err = fmt.Errorf("equal bearings (%s == %s), use CIRCLE instead", sb1, sb2) + return + } + + origin := sectr.Point{Lng: lon, Lat: lat} + sector := sectr.NewSector(origin, meters, b1, b2) + + o, err = geojson.Parse(string(sector.JSON()), &s.geomParseOpts) + if err != nil { + return + } + case "circle": if doClip { err = fmt.Errorf("invalid clip type '%s'", typ) diff --git a/internal/server/token.go b/internal/server/token.go index a0207906..30d25bae 100644 --- a/internal/server/token.go +++ b/internal/server/token.go @@ -763,7 +763,7 @@ loop: ae = &areaExpression{op: OR, children: []*areaExpression{ae}} } vsout = nvs - case "point", "circle", "object", "bounds", "hash", "quadkey", "tile", "get": + case "point", "circle", "object", "bounds", "hash", "quadkey", "tile", "get", "sector": parsedVs, parsedObj, areaErr := s.parseArea(vsout, doClip) if areaErr != nil { err = areaErr diff --git a/tests/testcmd_test.go b/tests/testcmd_test.go index 761c3923..5556b084 100644 --- a/tests/testcmd_test.go +++ b/tests/testcmd_test.go @@ -40,10 +40,12 @@ func testcmd_WITHIN_test(mc *mockServer) error { {"SET", "mykey", "poly8", "OBJECT", poly8}, {"OK"}, {"TEST", "GET", "mykey", "point1", "WITHIN", "OBJECT", poly}, {"1"}, + {"TEST", "GET", "mykey", "point1", "WITHIN", "SECTOR", "37.72999", "-122.44760", "1000", "0", "90"}, {"1"}, {"TEST", "GET", "mykey", "line3", "WITHIN", "OBJECT", poly}, {"1"}, {"TEST", "GET", "mykey", "poly4", "WITHIN", "OBJECT", poly}, {"1"}, {"TEST", "GET", "mykey", "multipoly5", "WITHIN", "OBJECT", poly}, {"1"}, {"TEST", "GET", "mykey", "poly8", "WITHIN", "OBJECT", poly}, {"1"}, + {"TEST", "GET", "mykey", "poly8", "WITHIN", "SECTOR", "37.72999", "-122.44760", "1000", "0", "90"}, {"1"}, {"TEST", "GET", "mykey", "point6", "WITHIN", "OBJECT", poly}, {"0"}, {"TEST", "GET", "mykey", "point7", "WITHIN", "OBJECT", poly}, {"0"}, diff --git a/vendor/github.com/iwpnd/sectr/.gitignore b/vendor/github.com/iwpnd/sectr/.gitignore new file mode 100644 index 00000000..398949e8 --- /dev/null +++ b/vendor/github.com/iwpnd/sectr/.gitignore @@ -0,0 +1,19 @@ +.ipynb_checkpoints/ +/tmp/ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +.DS_Store + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ diff --git a/vendor/github.com/iwpnd/sectr/.gitlint b/vendor/github.com/iwpnd/sectr/.gitlint new file mode 100644 index 00000000..47c85054 --- /dev/null +++ b/vendor/github.com/iwpnd/sectr/.gitlint @@ -0,0 +1,119 @@ +# Edit this file as you like. +# +# All these sections are optional. Each section with the exception of [general] represents +# one rule and each key in it is an option for that specific rule. +# +# Rules and sections can be referenced by their full name or by id. For example +# section "[body-max-line-length]" could also be written as "[B1]". Full section names are +# used in here for clarity. +# +[general] +# Ignore certain rules, this example uses both full name and id +# ignore=title-trailing-punctuation, T3 + +# verbosity should be a value between 1 and 3, the commandline -v flags take precedence over this +# verbosity = 2 + +# By default gitlint will ignore merge, revert, fixup and squash commits. +# ignore-merge-commits=true +# ignore-revert-commits=true +# ignore-fixup-commits=true +# ignore-squash-commits=true + +# Ignore any data send to gitlint via stdin +# ignore-stdin=true + +# Fetch additional meta-data from the local repository when manually passing a +# commit message to gitlint via stdin or --commit-msg. Disabled by default. +# staged=true + +# Enable debug mode (prints more output). Disabled by default. +# debug=true + +# Enable community contributed rules +# See http://jorisroovers.github.io/gitlint/contrib_rules for details +contrib=contrib-title-conventional-commits + +# Set the extra-path where gitlint will search for user defined rules +# See http://jorisroovers.github.io/gitlint/user_defined_rules for details +# extra-path=examples/ + +# This is an example of how to configure the "title-max-length" rule and +# set the line-length it enforces to 80 +# [title-max-length] +# line-length=50 + +# Conversely, you can also enforce minimal length of a title with the +# "title-min-length" rule: +# [title-min-length] +# min-length=5 + +# [title-must-not-contain-word] +# Comma-separated list of words that should not occur in the title. Matching is case +# insensitive. It's fine if the keyword occurs as part of a larger word (so "WIPING" +# will not cause a violation, but "WIP: my title" will. +# words=wip + +# [title-match-regex] +# python-style regex that the commit-msg title must match +# Note that the regex can contradict with other rules if not used correctly +# (e.g. title-must-not-contain-word). +# regex=^US[0-9]* + +# [body-max-line-length] +# line-length=72 + +# [body-min-length] +# min-length=5 + +#[body-is-missing] +# Whether to ignore this rule on merge commits (which typically only have a title) +# default = True +#ignore-merge-commits=false + +# [body-changed-file-mention] +# List of files that need to be explicitly mentioned in the body when they are changed +# This is useful for when developers often erroneously edit certain files or git submodules. +# By specifying this rule, developers can only change the file when they explicitly reference +# it in the commit message. +# files=gitlint/rules.py,README.md + +# [body-match-regex] +# python-style regex that the commit-msg body must match. +# E.g. body must end in My-Commit-Tag: foo +# regex=My-Commit-Tag: foo$ + +# [author-valid-email] +# python-style regex that the commit author email address must match. +# For example, use the following regex if you only want to allow email addresses from foo.com +# regex=[^@]+@foo.com + +# [ignore-by-title] +# Ignore certain rules for commits of which the title matches a regex +# E.g. Match commit titles that start with "Release" +# regex=^Release(.*) + +# Ignore certain rules, you can reference them by their id or by their full name +# Use 'all' to ignore all rules +ignore=B6,CC1 + +# [ignore-by-body] +# Ignore certain rules for commits of which the body has a line that matches a regex +# E.g. Match bodies that have a line that that contain "release" +# regex=(.*)release(.*) +# +# Ignore certain rules, you can reference them by their id or by their full name +# Use 'all' to ignore all rules +# ignore=T1,body-min-length + +# [ignore-body-lines] +# Ignore certain lines in a commit body that match a regex. +# E.g. Ignore all lines that start with 'Co-Authored-By' +# regex=^Co-Authored-By + +# This is a contrib rule - a community contributed rule. These are disabled by default. +# You need to explicitly enable them one-by-one by adding them to the "contrib" option +# under [general] section above. +# [contrib-title-conventional-commits] +# Specify allowed commit types. For details see: https://www.conventionalcommits.org/ + #types = feat,fix,refactor,docs,ci,chore diff --git a/vendor/github.com/iwpnd/sectr/.pre-commit-config.yaml b/vendor/github.com/iwpnd/sectr/.pre-commit-config.yaml new file mode 100644 index 00000000..2191cec1 --- /dev/null +++ b/vendor/github.com/iwpnd/sectr/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +repos: +- repo: git://github.com/dnephin/pre-commit-golang + rev: v0.4.0 + hooks: + - id: go-fmt + - id: go-vet + - id: go-lint + - id: go-imports + - id: go-mod-tidy +- repo: https://github.com/jorisroovers/gitlint + rev: v0.15.1 + hooks: + - id: gitlint diff --git a/vendor/github.com/iwpnd/sectr/go.mod b/vendor/github.com/iwpnd/sectr/go.mod new file mode 100644 index 00000000..2678b25e --- /dev/null +++ b/vendor/github.com/iwpnd/sectr/go.mod @@ -0,0 +1,3 @@ +module github.com/iwpnd/sectr + +go 1.16 diff --git a/vendor/github.com/iwpnd/sectr/readme.md b/vendor/github.com/iwpnd/sectr/readme.md new file mode 100644 index 00000000..fa662df1 --- /dev/null +++ b/vendor/github.com/iwpnd/sectr/readme.md @@ -0,0 +1,71 @@ +# sectr 🍕 + +Build a circular sector (pizza piece 😅 ) spanning the angle between two given bearings, a radius and a center point. + +## installation + +``` +go get -u github.com/iwpnd/sectr +``` + +## usage + +Logo + +```go +package main + +import ( + "fmt" + + "github.com/iwpnd/sectr" + ) + +func main() { + p := sectr.Point{Lat: 52.25, Lng: 13.37} + sector := sectr.NewSector(p, 100, 0, 90) + + fmt.Printf("%s", sector.JSON()) +} + +>> { + "type": "Polygon", + "coordinates": [ + [ + [13.37,52.25], + [13.37,52.25089932], + [13.37012803,52.2508959], + [13.3702803,52.2508828], + [13.37040491,52.25086448], + [13.37055029,52.25083383], + [13.37068965,52.25079405], + [13.37080006,52.25075423], + [13.37092446,52.2506989], + [13.37103872,52.25063591], + [13.3711253,52.25057807], + [13.37121783,52.25050289], + [13.37128479,52.25043599], + [13.37135219,52.25035138], + [13.37140478,52.25026293], + [13.37143686,52.25018697], + [13.37146091,52.250094], + [13.37146896,52.24999999], + [13.37,52.25] + ] + ] +} +``` + +## License + +MIT + +## Acknowledgement + +[Chris Veness](https://github.com/chrisveness) for refreshing my university left-overs with this blog [moveable-type](https://www.movable-type.co.uk/scripts/latlong.html) + +## Maintainer + +Benjamin Ramser - [@iwpnd](https://github.com/iwpnd) + +Project Link: [https://github.com/iwpnd/sectr](https://github.com/iwpnd/sectr) diff --git a/vendor/github.com/iwpnd/sectr/sectr.go b/vendor/github.com/iwpnd/sectr/sectr.go new file mode 100644 index 00000000..44658259 --- /dev/null +++ b/vendor/github.com/iwpnd/sectr/sectr.go @@ -0,0 +1,160 @@ +package sectr + +import ( + "encoding/json" + "math" +) + +const earthRadius = 6371008.8 // earth radius + +// Point ... +type Point struct { + Lng, Lat float64 +} + +// Sector ... +type Sector struct { + coordinates [][][]float64 + origin Point + radius float64 + bearing1 float64 + bearing2 float64 +} + +// SectorGeometry ... +type SectorGeometry struct { + Type string `json:"type"` + Coordinates [][][]float64 `json:"coordinates"` +} + +func radToDegree(rad float64) float64 { + return rad * 180 / math.Pi +} + +func degreeToRad(degree float64) float64 { + return degree * math.Pi / 180 +} + +func distanceToRadians(distance float64) float64 { + const r = earthRadius + + return distance / r +} + +// terminal calculates the terminal position travelling a distance +// from a given origin +// see https://www.movable-type.co.uk/scripts/latlong.html +func terminal(start Point, distance, bearing float64) Point { + φ1 := degreeToRad(start.Lat) + λ1 := degreeToRad(start.Lng) + bearingRad := degreeToRad(bearing) + distanceRad := distanceToRadians(distance) + + φ2 := math.Asin( + math.Sin(φ1)* + math.Cos(distanceRad) + + math.Cos(φ1)* + math.Sin(distanceRad)* + math.Cos(bearingRad)) + + λ2 := λ1 + math.Atan2( + math.Sin(bearingRad)* + math.Sin(distanceRad)* + math.Cos(φ1), + math.Cos(distanceRad)- + math.Sin(φ1)* + math.Sin(φ2)) + + // cap decimals at .00000001 degree ~= 1.11mm + lng := math.Round(radToDegree(λ2)*100000000) / 100000000 + lat := math.Round(radToDegree(φ2)*100000000) / 100000000 + + return Point{Lng: lng, Lat: lat} +} + +func bearingToAngle(bearing float64) float64 { + angle := math.Mod(bearing, 360) + + if angle < 0 { + angle = angle + 360 + } + + return angle +} + +// NewSector creates a sector from a given origin point, a radius and two bearings +func NewSector(origin Point, radius, bearing1, bearing2 float64) *Sector { + + // to cap the maximum positions in a sector/circle to 64 + // the higher the smoother, yet the bigger the coordinate array + const steps = 64 + + s := &Sector{ + origin: origin, + bearing1: bearing1, + bearing2: bearing2, + radius: radius, + } + + angle1 := bearingToAngle(bearing1) + angle2 := bearingToAngle(bearing2) + + // if angle1 == angle2 return circle + if angle1 == angle2 { + for i := 1; i < steps; i++ { + α := float64(i * -360 / steps) + t := terminal(origin, radius, α) + s.addPoint(t) + } + + s.coordinates[0] = append(s.coordinates[0], s.coordinates[0][0]) + + return s + } + + var endDegree float64 + startDegree := angle1 + + if angle1 < angle2 { + endDegree = angle2 + } else { + endDegree = angle2 + 360 + } + + α := startDegree + + s.addPoint(origin) + + for i := 1; ; i++ { + if α < endDegree { + t := terminal(origin, radius, α) + s.addPoint(t) + α = startDegree + float64((i*360)/steps) + } + + if α >= endDegree { + t := terminal(origin, radius, endDegree) + s.addPoint(t) + s.addPoint(origin) + + return s + } + } +} + +func (s *Sector) addPoint(p Point) { + if len(s.coordinates) == 0 { + s.coordinates = append(s.coordinates, [][]float64{{p.Lng, p.Lat}}) + return + } + + s.coordinates[0] = append(s.coordinates[0], []float64{p.Lng, p.Lat}) +} + +// JSON exports the Sector as json +func (s Sector) JSON() []byte { + f := SectorGeometry{Type: "Polygon", Coordinates: s.coordinates} + j, _ := json.Marshal(f) + + return j +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 2572508a..274d9cd2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -103,6 +103,9 @@ github.com/googleapis/gax-go/v2 github.com/gorilla/websocket # github.com/hashicorp/go-uuid v1.0.2 github.com/hashicorp/go-uuid +# github.com/iwpnd/sectr v0.1.2 +## explicit +github.com/iwpnd/sectr # github.com/jcmturner/gofork v1.0.0 github.com/jcmturner/gofork/encoding/asn1 github.com/jcmturner/gofork/x/crypto/pbkdf2