• Stars
    star
    8,655
  • Rank 4,230 (Top 0.09 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Real-time Geospatial and Geofencing

Tile38

Slack Channel Docker Pulls

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 at https://tile38.com.

Nearby Within Intersects Geofencing Roaming Geofences

Features

Components

  • tile38-server: The server
  • tile38-cli: Command line interface tool
  • tile38-benchmark: Server benchmark tool

Getting Started

Getting Tile38

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 GitHub releases page.

Docker

To run the latest stable version of Tile38:

docker pull tile38/tile38
docker run -p 9851:9851 tile38/tile38

Visit the Tile38 hub page for more information.

Homebrew (macOS)

Install Tile38 using Homebrew

brew install tile38
tile38-server

Building Tile38

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:

$ make

To test:

$ make test

Running

For command line options invoke:

$ ./tile38-server -h

To run a single server:

$ ./tile38-server

# The tile38 shell connects to localhost:9851
$ ./tile38-cli
> help

Prometheus Metrics

Tile38 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 metrics
curl http://127.0.0.1:4321/metrics

If you need to access the /metrics endpoint from a different host you'll have to set the flag accordingly, e.g. set it to 0.0.0.0:<<port>> to listen on all interfaces.

Use the redis_exporter for more advanced use cases like extracting key values or running a lua script.

Playing with Tile38

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 all 

Tile38 has a ton of great commands.

Fields

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.2693

To set a field when an object already exists:

> fset fleet truck1 speed 90

Searching

Tile38 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.

Search Within

Within

WITHIN searches a collection for objects that are fully contained inside a specified bounding area.

Search Intersects

Intersects

INTERSECTS searches a collection for objects that intersect a specified bounding area.

Search Nearby

Nearby

NEARBY searches a collection for objects that intersect a specified radius.

Search options

WHERE - This option allows for filtering out results based on field values. For example
nearby 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 radius and have a field named speed that is greater than 70.

Multiple WHEREs are concatenated as and clauses. WHERE speed 70 +inf WHERE age -inf 24 would be interpreted as speed is over 70 and age is less than 24.

The default value for a field is always 0. Thus if you do a WHERE on the field speed and an object does not have that field set, the server will pretend that the object does and that the value is Zero.

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 radius and have an object id that starts with truck. There can be multiple MATCH options in a single search. The MATCH value is a simple glob 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.

Geofencing

Geofence animation

A geofence 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 for Webhooks to be assigned to Geofences.


A simple example:

> nearby fleet fence point 33.462 -112.268 6000

This 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 around 33.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 the command is del | set | drop.

  • del notifies the client that an object has been deleted from the collection that is being fenced.
  • drop notifies the client that the entire collection is dropped.
  • set notifies the client that an object has been added or updated, and when it's position is detected by the fence.

The detect may be one of the following values.

  • inside is when an object is inside the specified area.
  • outside is when an object is outside the specified area.
  • enter is when an object that was not previously in the fence has entered the area.
  • exit is when an object that was previously in the fence has exited the area.
  • cross is when an object that was not previously in the fence has entered and exited the area.

These can be used when establishing a geofence, to pre-filter responses. For instance, to limit responses to enter and exit detections:

> nearby fleet fence detect enter,exit point 33.462 -112.268 6000

Pub/sub channels

Tile38 supports delivering geofence notications 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 the busstop channel:

> setchan busstop nearby buses fence point 33.5123 -112.2693 200

Subscribe on the busstop channel:

> subscribe busstop

Object types

All 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.

Lat/lon point

The most basic object type is a point that is composed of a latitude and a longitude. There is an optional z member that may be used for auxiliary data such as elevation or a timestamp.

set fleet truck1 point 33.5123 -112.2693     # plain lat/lon
set fleet truck1 point 33.5123 -112.2693 225 # lat/lon with z member

Bounding box

A 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 -100

Geohash

A geohash 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

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]]]}

XYZ Tile

An XYZ tile is rectangle bounding area on earth that is represented by an X, Y coordinate and a Z (zoom) level. Check out maptiler.org for an interactive example.

QuadKey

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 checkout The Bing Maps Tile System.

Network protocols

It's recommended to use a client library or the Tile38 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.

HTTP

One of the simplest ways to call a tile38 command is to use HTTP. From the command line you can use curl. For example:

# call with request in the body
curl --data "set fleet truck3 point 33.4762 -112.10923" localhost:9851

# call with request in the url path
curl localhost:9851/set+fleet+truck3+point+33.4762+-112.10923

Websockets

Websockets 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.

Telnet

There is the option to use a plain telnet connection. The default output through telnet is RESP.

telnet localhost 9851
set fleet truck3 point 33.4762 -112.10923
+OK

The server will respond in JSON or RESP depending on which protocol is used when initiating the first command.

  • HTTP and Websockets use JSON.
  • Telnet and RESP clients use RESP.

Tile38 Client Libraries

The following clients are built specifically for Tile38.
Clients that support most Tile38 features are marked with a ⭐️.

Redis Client Libraries

Tile38 uses the Redis RESP protocol natively. Therefore most clients that support basic Redis commands will also support Tile38.

Contact

Josh Baker @tidwall

License

Tile38 source code is available under the MIT License.

More Repositories

1

gjson

Get JSON values quickly - JSON parser for Go
Go
12,768
star
2

evio

Fast event-loop networking for Go
Go
5,747
star
3

buntdb

BuntDB is an embeddable, in-memory key/value database for Go with custom indexing and geospatial support
Go
4,196
star
4

redcon

Redis compatible server framework for Go
Go
2,005
star
5

sjson

Set JSON values very quickly in Go
Go
1,978
star
6

SwiftWebSocket

Fast Websockets in Swift for iOS and OSX
Swift
1,532
star
7

summitdb

In-memory NoSQL database with ACID transactions, Raft consensus, and Redis API
Go
1,394
star
8

jj

JSON Stream Editor (command line utility)
Go
1,293
star
9

btree

B-tree implementation for Go
Go
937
star
10

hashmap.c

Hash map implementation in C.
C
631
star
11

uhaha

High Availability Raft Framework for Go
Go
579
star
12

pinhole

3D Wireframe Drawing Library for Go
Go
554
star
13

finn

Fast Raft framework using the Redis protocol for Go
Go
541
star
14

wal

Write ahead log for Go.
Go
525
star
15

tg

Geometry library for C - Fast point-in-polygon
C
502
star
16

Safe

Modern Concurrency and Synchronization for Swift.
Swift
417
star
17

pretty

Efficient JSON beautifier and compactor for Go
Go
354
star
18

chanx

A simple interface wrapper around a Go channel.
Go
321
star
19

rtree

An R-tree implementation for Go
Go
285
star
20

btree.c

B-tree implementation in C
C
246
star
21

GoSwift

Go Goodies for Swift. Including goroutines, channels, defer, and panic.
Swift
234
star
22

shardmap

A simple and efficient thread-safe sharded hashmap for Go
Go
211
star
23

hashmap

A simple and efficient hashmap package for Go. Open addressing, robin hood hashing, and xxh3 algorithm. Supports generics.
Go
203
star
24

celltree

A fast in-memory prefix tree that uses uint64 for keys and allows for duplicate entries.
Go
201
star
25

gjson.rs

Get JSON values quickly - JSON parser for Rust
Rust
195
star
26

cities

10,000 Cities with Latitude, Longitude, and Elevation in Go
Go
161
star
27

tinylru

A fast little LRU cache for Go
Go
144
star
28

Avios

Realtime H264 decoding library for iOS.
Swift
129
star
29

jd

Interactive JSON Editor
Go
128
star
30

pinhole-js

3D Wireframe Drawing Library for HTML Canvas
JavaScript
119
star
31

mmap

Load file-backed memory
Go
117
star
32

geojson

GeoJSON for Go. Used by Tile38
Go
116
star
33

doppio

Doppio is a fast LRU cache on top of Ristretto, Redcon, and Evio. Support for the Redis protocol.
Go
115
star
34

rtree.rs

A fast R-tree for Rust
Rust
112
star
35

match

Simple string pattern matcher for Go
Go
97
star
36

rtree.c

An R-tree implementation in C
C
96
star
37

tinybtree

Just an itsy bitsy b-tree in Go
Go
94
star
38

jsonc

Parse json with comments and trailing commas.
Go
79
star
39

rhh

A simple and efficient hashmap package for Go. Uses open addressing, Robin Hood hashing, and xxhash algorithm.
Go
79
star
40

kvnode

key value server. redis api, leveldb storage, raft support
Go
79
star
41

raft-fastlog

Raft in-memory backend implementation with persistence
Go
78
star
42

resp

Reader, Writer, and Server implementation for the Redis RESP Protocol.
Go
78
star
43

modern-server

Basic web server framework with HTTP/2 and Let's Encrypt.
Go
76
star
44

limiter

A goroutine limiter for Go
Go
76
star
45

redraft

Redis + Raft server implementation
Go
75
star
46

redcon.rs

Redis compatible server framework for Rust
Rust
72
star
47

rocksdb-server

Fast Redis clone written in C using RocksDB as a backend.
C++
72
star
48

lotsa

Simple Go library for executing lots of operations spread over any number of threads
Go
71
star
49

box

Efficiently box values in Go. Optimized for primitives, strings, and byte slices.
Go
69
star
50

evio-lite

Fast event-loop networking for Go (the lite version)
Go
68
star
51

transform

Using io.Reader for data transformation in Go
Go
67
star
52

uspto-trademark

How to file a USPTO trademark without an attorney for $225
66
star
53

pjson

A JSON stream parser for Go
Go
66
star
54

geodesic

Go package for performing accurate measurements of Earth. Includes the geodesic routines from GeographicLib.
Go
59
star
55

expr

Expression evaluator for Go
Go
58
star
56

json.c

Fast JSON parser for C
C
56
star
57

spinlock

A spinlock implementation for Go.
Go
56
star
58

raft-wal

Write ahead Raft log for Go
Go
55
star
59

rtred

RTree implementation for Go
Go
53
star
60

bfile

A buffer pool file I/O library for Go
Go
53
star
61

mvt

Draw Mapbox Vector Tiles (MVT) in Go
Go
52
star
62

redcon.c

Redis compatible server framework for C
C
47
star
63

cache-server

A minimal key/value server written in Rust with Redis API support.
Rust
46
star
64

spanmap

A fast collection type that uses uint64 for keys.
Go
44
star
65

go-node

Run Javascript in Go using Node.js
Go
42
star
66

ticketd

A distributed service for monotonically increasing tickets.
Go
42
star
67

hexd

Please love the nicely formatted hex.
Go
42
star
68

DeflateSwift

Deflate Compression for Swift
Swift
40
star
69

proximity-chat

Chat app for real-time chats with people within 500 meters.
JavaScript
39
star
70

lru

A simple and efficient LRU cache package for Go
Go
38
star
71

sider

A Redis clone written in Go
Go
36
star
72

xv

An expression evaluator for C
C
34
star
73

geometry

Efficient 2D geometry library for Go.
Go
32
star
74

pkg.sh

A generalized package manager for whatever code.
Shell
32
star
75

rfront

An HTTP protocol frontend for Redis-compatible services.
Go
31
star
76

redis-gis

Redis fork with Geospatial support based on Tile38 commands
C
31
star
77

RetroSwiper

Load classic games from magnetic swipe cards
Rust
31
star
78

uhasql

A high availability Sqlite service
C
30
star
79

redbench

Benchmarking for custom Redis commands and modules
Go
30
star
80

sds

simple data streams for go
Go
29
star
81

spmap

A hashmap for Go that uses crypto random seeds, hash hints, open addressing, and robin hood hashing.
Go
29
star
82

IoniconsSwift

Ionicons for Swift and iOS
Swift
29
star
83

raft-leveldb

Raft backend using LevelDB
Go
28
star
84

evio.c

A framework for building event based networking applications.
C
28
star
85

tinyqueue

Binary heap priority queues in Go
Go
27
star
86

kvbench

Server for benchmarking pure Go key/value databases
Go
26
star
87

gjson-play

A playground for GJSON. Runs in the browser.
JavaScript
25
star
88

randjson

Make random JSON in Go
Go
25
star
89

redlog

Redis style logger for Go
Go
25
star
90

SnapHTTP

An incredibly simple HTTP client library for Swift.
Swift
24
star
91

qtree

jeez it's just a quadtree chill out
Go
24
star
92

rtime

Retrieve the current time from remote servers
Go
21
star
93

fast-spatial-joins

Go vs GPU: Fast Spatial Joins
Go
21
star
94

assert

An assert function for Go that works like the one in C.
Go
20
star
95

pair

create low memory key/value objects in Go
Go
20
star
96

match.c

Simple string pattern matcher for C
C
19
star
97

secret

A simple utility for encrypting and decrypting data in Go (AES-256-CFB)
Go
19
star
98

pony

🌈 🐴 Turn your terminal text into an absolutely beautiful display of dazzling colors....
Go
19
star
99

btree-benchmark

Benchmark utility for the tidwall/btree Go package
Go
19
star
100

lru-server

A convenient LRU cache server that supports REST API and Let's Encrypt.
Go
18
star