背景
最近在做一个gps区域搜索相关的功能,需要实时监测多个指定的gps设备是否在划定的区域范围之内;这个功能里面有两个难点:
- 划定的区域形状多样,有可能是圆形、矩形或者多边形;
- 如何计算某个不断变化的经纬度坐标是否离开划定的区域;
经过多方查找,终于找到了tile38这个神器,tile38是基于golang编写,用于地理空间和实时地理围栏应用的高性能数据库。所以我们的这个功能就可以使用到这个工具来辅助实现了。
安装tile38
version: "3.7" services: tile38: image: tile38/tile38 # 开放端口,以便客户端通信 ports: - "9851:9851" # 数据存储路径 volumes: - "./tile38/data:/data" 复制代码
通过docker-compose up -d tile38
命令启动容器实例。
其他安装方式可以查看tile38官网
配置文件
一般直接启动的话,tile38会在/data文件夹中创建默认的配置文件config
文件,启动成功后,里面会有一个配置项server_id
,我们如果还想添加其他配置项,可以先停止当前服务,把需要添加的配置项补充进去,再重新启动。
配置项 | 描述 |
requirepass |
设置服务端密码,默认是没有密码 |
leaderauth |
如果leader设置了密码,那么follower必须要设置leaderauth 来连接目标leader 服务 |
protected-mode |
tile38只允许经过身份验证的客户端或来自本地主机的连接。默认是开启保护模式的。默认值为yes |
maxmemory |
以字节为单位设置最大内存。可以使用单位kb/mb/gb |
autogc |
执行一次垃圾收集的时间,单位秒,默认为 0,没有垃圾收集 |
keep_alive |
客户端连接存活时长,默认值:300,单位秒 |
follow_host |
leader 服务的ip或域名 |
follow_port |
leader 服务的端口 |
follow_pos |
leader 服务的aof文件同步偏移点 |
follow_id |
leader 服务的id |
server_id |
当前服务的id |
read_only |
是否只读 |
logconfig |
日志配置;使用json格式的zap.Config文件 |
启动本机客户端
在容器实例启动成功后,我们可以执行以下命令启动tile38-cli客户端工具:
- 进入tile38容器中
docker exec -it ${容器id} /bin/sh 复制代码
- 开启本机客户端
进入容器实例内后,执行下面命令:
tile38-cli 复制代码
- 进入客户端后,我们就可以使用客户端来与tile38服务进行交互了;下面我们来使用这个工具创建一些对象。
对象类型
Point
类型
SET fleet truck1 POINT 33.5123 -112.2693 SET fleet truck1 POINT 33.5123 -112.2693 225 复制代码
- 以上命令就是创建一个Point类型的数据,命令格式如下:
SET [key] [field] POINT 经度 纬度 [附加数据]
我们可以把以上命令理解成redis中的哈希结构,我们可以在key里面设置多个POINT数据,只要保证field
名称不同即可。 Bound
类型
SET fleet truck1 BOUNDS 30 -110 40 -100 复制代码
- 命令格式如下:
SET [key] [field] BOUNDS 经度1 维度1 经度2 维度2
上面命令通过两个点构建了一个边界框,类似矩形。 Geohash
类型
SET fleet truck1 HASH 9tbnthxzr 复制代码
- 命令格式如下:
SET [key] [field] HASH hash值
其中的hash值
相当于一个坐标点,所以这个命令相当于创建了一个POINT数据。
Geohash相关知识可以参考en.wikipedia.org/wiki/Geohas…。 GeoJSON
类型
SET city tempe OBJECT '{"type":"Polygon","coordinates":[[[-111.9787,33.4411],[-111.8902,33.4377],[-111.8950,33.2892],[-111.9739,33.2932],[-111.9787,33.4411]]]}' 复制代码
- 命令格式如下:
SET [key] [field] OBJECT '{"type":"Polygon","coordinates":[坐标组]}'
上面的命令就是通过一组坐标系创建一个多边形区域。里面有两个需要注意的点:
- 如果设置的时候报错
invalid coordinates
,请检查数组中第一个经纬度是否与最后一个经纬度一致,GeoJSON要求最后一个点一定要回到起始点。 - GEOJson区域的点的顺序是(纬度,经度)。
- 上面命令中的type支持以下类型:
Point
、LineString
、Polygon
、MultiPoint
、MultiLineString
和MultiPolygon
另外,附上GeoJSON格式规范
下面两个类型都无法直接在服务中提前定义,只有在需要使用的时候才能定义:
CIRCLE
圆形
WITHIN fleet CIRCLE 122.1 30 10000 复制代码
- 这个命令的意思是,查询fleet中有哪些点或区域是在后面的圆形范围内。这个圆形就是以
122.1 30
为圆心,10000米为半径的范围。 Sector
扇形
WITHIN fleet SECTOR 33.5123 -112.2693 1000 0 90 复制代码
- 这个命令也和上面的圆形一样,这个是扇形;以
33.5123 -112.2693
为中心,1000米范围内,夹角为0度到90度范围。