一、需求描述
在实际项目开发中,需要接入多目标的实时位置点,然后根据位置点进行空间展示,如普通货车辆监控定位,渔船定位监控、运输特种物品车辆监控等,主要的目的是接收实时上传的位置点在地图上进行显示和更新,但是有时候没有现成的数据接入服务,想要达到前端的快速数据模拟与开发就成为了问题,这里就介绍一种实战中操作的数据模拟方法。
二、数据获取
数据大家可以从这个地址下载获取:
https://github.com/weizhimin/data/blob/master/lines-bus.json
数据解析,参考第三部分代码中的GetMsg方法
三、实现方法和关键代码
这里是用C#代码实现的,大家可以根据自己的需求调整,主要实现思路如下:
1.解析线路数据,存储到相应的字典中
2.启动一个线程,依次发送每条路线中的第n个点,如第一次循环,发送所有线路的第一个点
3.记录每条线路当前发送点的位置,如果全部发送完毕,则逆向发送
4.重复动作3,如果又逆向回到第一个点开始发送
这里需要建三个字典,分布存储:
1.线路上所有点
2.每条线路发送的偏移量
3.每条线路的方向(正反)
详细代码如下:
public class BusConsumer
{
//存储所有线路点
Dictionary<int, List<Bus>> _dict = new Dictionary<int, List<Bus>>();
//偏移量
Dictionary<int, int> _dictoffset = new Dictionary<int, int>();
//方向-正反
Dictionary<int, bool> _dictdirection = new Dictionary<int, bool>();
private int timespan = 2000;
public BusConsumer()
{
GetMsg();
}
private void GetMsg()
{
//数据解析
string json = File.ReadAllText("./Data/aitraffic/lines-bus.json");
JArray ja = JArray.Parse(json);
if (ja.Count > 0)
{
for (int i = 0; i < ja.Count; i++)
{
List<Bus> buslist = new List<Bus>();
JArray jarray = ja[i] as JArray;
double basex = 0;
double basey = 0;
for (int j = 0; j < jarray.Count; j += 2)
{
Bus bus = new Bus();
bus.lineindex = i;
bus.stationindex = j;
double x = double.Parse(jarray[j].ToString());
double y = double.Parse(jarray[j + 1].ToString());
if (j > 0)
{
x = basex + x;
y = basey + y;
}
basex = x;
basey = y;
bus.lon = x / 10000;
bus.lat = y / 10000;
double[] lonlat = Coordtransform.GCJ02ToWGS84(bus.lon, bus.lat);
bus.lon = lonlat[0];
bus.lat = lonlat[1];
buslist.Add(bus);
}
_dict.Add(i, buslist);
_dictoffset.Add(i, -1 * buslist.Count);
_dictdirection.Add(i, true);
}
}
}
/// <summary>
/// 消费数据
/// </summary>
public void Consume()
{
isdispose = false;
Task.Run(() =>
{
//全量发送
while (!isdispose)
{
foreach (var item in _dict)
{
int cnt = item.Value.Count;
int key = item.Key;
int offset = _dictoffset[key];
if (offset < 0)
{
//发送当前点
RenderTracePoint(item.Value[_dictoffset[key] + cnt]);
offset++;
_dictoffset[key] = offset;
}
else if (offset == 0)
{
_dictdirection[key] = !_dictdirection[key];
if (_dictdirection[key])
{
offset = -1 * cnt;
}
else
{
offset = cnt;
}
_dictoffset[key] = offset;
}
else
{
offset--;
_dictoffset[key] = offset;
RenderTracePoint(item.Value[_dictoffset[key]]);
}
}
Thread.Sleep(timespan);
}
});
}
public void Dispose()
{
isdispose = true;
}
/// <summary>
/// 渲染实时轨迹
/// </summary>
/// <param name="msg">位置点</param>
public void RenderTracePoint(Bus msg)
{
}
}
四、结果与延展
通过实际的调试和空间地图展示,发现效果能够满足当前项目的需求,极大的提高了开发效率,数据的质量也是比较好,通过控制线程休眠的时间间隔,可以调整发送的频率,当前这个是针对特定数据的解析和发送,大家可以根据实际的数据格式进行定制化改造。
当前方法在项目中的可视化效果如下:
大比例尺下的车辆监控
小比例尺下的车辆监控