- Notifications
You must be signed in to change notification settings - Fork608
Real-time Geospatial and Geofencing
License
tidwall/tile38
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Tile38 is an open source (MIT licensed), in-memory geolocation data store, spatial index, and realtime geofencing server.It supports a variety of object types including lat/lon points, bounding boxes, XYZ tiles, Geohashes, and GeoJSON.
This README is quick start document. You can find detailed documentation athttps://tile38.com.




- Spatial index withsearch methods such as Nearby, Within, and Intersects.
- Realtimegeofencing throughwebhooks orpub/sub channels.
- Object types oflat/lon,bbox,Geohash,GeoJSON,QuadKey, andXYZ tile.
- Support for lots ofClients Libraries written in many different languages.
- Variety of protocols, includinghttp (curl),websockets,telnet, and theRedis RESP.
- Server responses areRESP orJSON.
- Fullcommand line interface.
- Leader / followerreplication.
- In-memory database that persists on disk.
- tile38-server: The server
- tile38-cli: Command line interface tool
- tile38-benchmark: Server benchmark tool
Perhaps the easiest way to get the latest Tile38 is to use one of the pre-built release binaries which are available for OSX, Linux, FreeBSD, and Windows. Instructions for using these binaries are on the GitHubreleases page.
To run the latest stable version of Tile38:
docker pull tile38/tile38docker run -p 9851:9851 tile38/tile38Visit theTile38 hub page for more information.
Install Tile38 usingHomebrew
brew install tile38tile38-server
Tile38 can be compiled and used on Linux, OSX, Windows, FreeBSD, and probably others since the codebase is 100% Go. We support both 32 bit and 64 bit systems.Go must be installed on the build machine.
To build everything simply:
$ makeTo test:
$ make testFor command line options invoke:
$ ./tile38-server -hTo run a single server:
$ ./tile38-server# The tile38 shell connects to localhost:9851$ ./tile38-cli> helpTile38 can natively export Prometheus metrics by setting the--metrics-addr command line flag (disabled by default). This example exposes the HTTP metrics server on port 4321:
# start server and enable Prometheus metrics, listen on local interface only./tile38-server --metrics-addr=127.0.0.1:4321# access metricscurl http://127.0.0.1:4321/metricsIf you need to access the/metrics endpoint from a different host you'll have to set the flag accordingly, e.g. set it to0.0.0.0:<<port>> to listen on all interfaces.
Use theredis_exporter for more advanced use cases like extracting key values or running a lua script.
Basic operations:
$ ./tile38-cli# add a couple of points named 'truck1' and 'truck2' to a collection named 'fleet'.> set fleet truck1 point 33.5123 -112.2693 # on the Loop 101 in Phoenix> set fleet truck2 point 33.4626 -112.1695 # on the I-10 in Phoenix# search the 'fleet' collection.> scan fleet # returns both trucks in 'fleet'> nearby fleet point 33.462 -112.268 6000 # search 6 kilometers around a point. returns one truck.# key value operations> get fleet truck1 # returns 'truck1'> del fleet truck2 # deletes 'truck2'> drop fleet # removes allTile38 has a ton ofgreat commands.
Fields are extra data that belongs to an object. A field is always a double precision floating point. There is no limit to the number of fields that an object can have.
To set a field when setting an object:
> set fleet truck1 field speed 90 point 33.5123 -112.2693 > set fleet truck1 field speed 90 field age 21 point 33.5123 -112.2693To set a field when an object already exists:
> fset fleet truck1 speed 90To get a field when an object already exists:
> fget fleet truck1 speedTile38 has support to search for objects and points that are within or intersects other objects. All object types can be searched including Polygons, MultiPolygons, GeometryCollections, etc.
WITHIN searches a collection for objects that are fully contained inside a specified bounding area.
INTERSECTS searches a collection for objects that intersect a specified bounding area.
NEARBY searches a collection for objects that intersect a specified radius.
WHERE - This option allows for filtering out results based onfield values. For examplenearby fleet where speed 70 +inf point 33.462 -112.268 6000 will return only the objects in the 'fleet' collection that are within the 6 km radiusand have a field namedspeed that is greater than70.
Multiple WHEREs are concatenated asand clauses.WHERE speed 70 +inf WHERE age -inf 24 would be interpreted asspeed is over 70and age is less than 24.
The default value for a field is always0. Thus if you do a WHERE on the fieldspeed and an object does not have that field set, the server will pretend that the object does and that the value is Zero.
WHERE expressions support the=~ operator for regex matching. It uses Go's re2 regular expression engine to match string values in fields or GeoJSON properties within objects. For example,WHERE properties.name =~ 'truck.*' filters objects where the 'name' property matches the pattern, andWHERE field_name =~ 'value.*' works similarly for fields.
MATCH - MATCH is similar to WHERE except that it works on the object id instead of fields.nearby fleet match truck* point 33.462 -112.268 6000 will return only the objects in the 'fleet' collection that are within the 6 km radiusand have an object id that starts withtruck. There can be multiple MATCH options in a single search. The MATCH value is a simpleglob pattern.
CURSOR - CURSOR is used to iterate though many objects from the search results. An iteration begins when the CURSOR is set to Zero or not included with the request, and completes when the cursor returned by the server is Zero.
NOFIELDS - NOFIELDS tells the server that you do not want field values returned with the search results.
LIMIT - LIMIT can be used to limit the number of objects returned for a single search request.
Ageofence is a virtual boundary that can detect when an object enters or exits the area. This boundary can be a radius, bounding box, or a polygon. Tile38 can turn any standard search into a geofence monitor by adding the FENCE keyword to the search.Tile38 also allows forWebhooks to be assigned to Geofences.
A simple example:
> nearby fleet fence point 33.462 -112.268 6000This command opens a geofence that monitors the 'fleet' collection. The server will respond with:
{"ok":true,"live":true}And the connection will be kept open. If any object enters or exits the 6 km radius around33.462,-112.268 the server will respond in realtime with a message such as:
{"command":"set","detect":"enter","id":"truck02","object":{"type":"Point","coordinates":[-112.2695,33.4626]}}The server will notify the client if thecommand isdel | set | drop.
delnotifies the client that an object has been deleted from the collection that is being fenced.dropnotifies the client that the entire collection is dropped.setnotifies the client that an object has been added or updated, and when it's position is detected by the fence.
Thedetect may be one of the following values.
insideis when an object is inside the specified area.outsideis when an object is outside the specified area.enteris when an object thatwas not previously in the fence has entered the area.exitis when an object thatwas previously in the fence has exited the area.crossis when an object thatwas not previously in the fence has enteredand exited the area.
These can be used when establishing a geofence, to pre-filter responses. For instance, to limit responses toenter andexit detections:
> nearby fleet fence detect enter,exit point 33.462 -112.268 6000Tile38 supports delivering geofence notifications over pub/sub channels.
To create a static geofence that sends notifications when a bus is within 200 meters of a point and sends to thebusstop channel:
> setchan busstop nearby buses fence point 33.5123 -112.2693 200Subscribe on thebusstop channel:
> subscribe busstopAll object types except for XYZ Tiles and QuadKeys can be stored in a collection. XYZ Tiles and QuadKeys are reserved for the SEARCH keyword only.
The most basic object type is a point that is composed of a latitude and a longitude. There is an optionalz member that may be used for auxiliary data such as elevation or a timestamp.
set fleet truck1 point 33.5123 -112.2693 # plain lat/lonset fleet truck1 point 33.5123 -112.2693 225 # lat/lon with z memberA bounding box consists of two points. The first being the southwestern most point and the second is the northeastern most point.
set fleet truck1 bounds 30 -110 40 -100Ageohash is a string representation of a point. With the length of the string indicating the precision of the point.
set fleet truck1 hash 9tbnthxzr # this would be equivalent to 'point 33.5123 -112.2693'GeoJSON is an industry standard format for representing a variety of object types including a point, multipoint, linestring, multilinestring, polygon, multipolygon, geometrycollection, feature, and featurecollection.
* All ignored members will not persist.
Important to note that all coordinates are in Longitude, Latitude order.
set city tempe object {"type":"Polygon","coordinates":[[[0,0],[10,10],[10,0],[0,0]]]}An XYZ tile is rectangle bounding area on earth that is represented by an X, Y coordinate and a Z (zoom) level.Check outmaptiler.org for an interactive example.
A QuadKey used the same coordinate system as an XYZ tile except that the string representation is a string characters composed of 0, 1, 2, or 3. For a detailed explanation checkoutThe Bing Maps Tile System.
It's recommended to use aclient library or theTile38 CLI, but there are times when only HTTP is available or when you need to test from a remote terminal. In those cases we provide an HTTP and telnet options.
One of the simplest ways to call a tile38 command is to use HTTP. From the command line you can usecurl. For example:
# call with request in the bodycurl --data "set fleet truck3 point 33.4762 -112.10923" localhost:9851# call with request in the url pathcurl localhost:9851/set+fleet+truck3+point+33.4762+-112.10923Websockets can be used when you need to Geofence and keep the connection alive. It works just like the HTTP example above, with the exception that the connection stays alive and the data is sent from the server as text websocket messages.
There is the option to use a plain telnet connection. The default output through telnet isRESP.
telnet localhost 9851set fleet truck3 point 33.4762 -112.10923+OKThe server will respond inJSON orRESP depending on which protocol is used when initiating the first command.
- HTTP and Websockets use JSON.
- Telnet and RESP clients use RESP.
The following clients are built specifically for Tile38.
Clients that support most Tile38 features are marked with a ⭐️.
- ⭐️ Go:xjem/t38c
- ⭐️ Node.js:node-tile38 (example code)
- ⭐️ Python:pyle38
- ⭐️ TypeScript:tile38-ts
- Go:cjkreklow/t38c
- Python:pytile38
- Rust:nazar
- Swift:Talon
- Java:tile38-client-java
- Java:tile38-client
Tile38 uses theRedis RESP protocol natively.Therefore most clients that support basic Redis commands will also support Tile38.
- C:hiredis
- C#:StackExchange.Redis
- C++:redox
- Clojure:carmine
- Common Lisp:CL-Redis
- Erlang:Eredis
- Go:go-redis (example code)
- Go:redigo (example code)
- Haskell:hedis
- Java:lettuce (example code)
- Node.js:node_redis (example code)
- Perl:perl-redis
- PHP:tinyredisclient (example code)
- PHP:phpredis
- Python:redis-py (example code)
- Ruby:redic (example code)
- Ruby:redis-rb (example code)
- Rust:redis-rs
- Scala:scala-redis
- Swift:Redbird
Josh Baker@tidwall
Tile38 source code is available under the MITLicense.
About
Real-time Geospatial and Geofencing
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.