---------------------------------------------------------------------------------------------
[版权申明:本文系作者原创,转载请注明出处]
文章出处:https://blog.csdn.net/sdksdk0/article/details/83068473
作者:朱培 ID:sdksdk0
--------------------------------------------------------------------------------------------
大数据时代,深度“数据挖掘”高级分析技术成为大势所趋,对于旅游景区来说,谁先掌握互联网平台、善用大数据,谁就最有可能先人一步破除体制壁垒与管理围墙,实现转型升级和跨越式发展。通过在旅游景区部署移动信号监测设备,就可以发现该群体游客的相关属性,例如在一个区县,在不同景点之间部署,可以发现游客移动的轨迹是怎么样,本文主要就是用于分析游客在不同景点之间的浏览情况,这样可以更加合理的设计景区与景区之间的交通路线,销售相关旅游产品和应急预案等方面的东西。本文所涉及的内容使用mysql+springboot来实现。
首先来看一下清洗完成后的数据:浏览线路的格式为: 景区A=>景区C=>景区B=>景区D。
现在有数据格式如下(完整的数据集在文末提供下载链接):
第一列为id,第二列为景区编号,第三列为用户编号,第四列为时间,第五列为景区名称。
1 18C8E750176E 3478D7E2C139 20180503000000 嵩溪村
2 18C8E750182A C46699E01080 20180503000000 江南第一家花海
3 18C8E750180E 084ACF3E591F 20180503000000 水晶城
4 18C8E75017DA 386EA2788110 20180503000000 高速路
5 18C8E7501806 205D479A3020 20180503000001 翠湖
6 18C8E750181E 442C05543BED 20180503000001 水晶城
7 18C8E750182E F06D781D8FAF 20180503000002 通济桥水库大坝
8 18C8E75017EE B4EFFAC7D0C7 20180503000002 汽车客运站
9 18C8E75017EE 6C5C14743F6F 20180503000002 汽车客运站
10 18C8E75017A6 F4B7B356B876 20180503000003 檀溪镇
11 18C8E750181A 4C0FC7DF8C8E 20180503000003 金狮湖
12 18C8E750180A B436A9063032 20180503000003 翠湖
下载需要统计的就是同一个用户去了哪些景区,按时间维度进行排列,即可得出单个游客的移动轨迹。然后将所有游客的轨迹在一个List中进行合并处理,相同游客轨迹的数量加1,最终即可全部游客的移动轨迹。因为全部数据量在非常大,所以数据从数据仓库中选取了某一天的部分数据量来这里做演示。
1、在mysql数据库中创建表orbit_data,将数据集导入进去(文末提供数据集下载链接)
2、创建bean,OrbitData.java,里面包含和数据库表结构相对应的字段
private Integer id;
private String probMac;
private String devcMac;
private String inTime;
private String name;
3、mybatiss中查询
<select id="selectByMapAllList" resultType="OrbitData">
select * from orbit_data where 1=1
and devcMac in
(select devcMac from orbit_data where 1=1
and length(devcMac)>=10
<if test="beginTime != null and beginTime != '' ">
and inTime <![CDATA[ >= ]]> #{beginTime}
</if>
<if test="endTime != null and endTime != '' ">
and inTime <![CDATA[ <=]]> #{endTime}
</if>
group by devcMac
having count(*)>1
)
<if test="beginTime != null and beginTime != '' ">
and inTime <![CDATA[ >= ]]> #{beginTime}
</if>
<if test="endTime != null and endTime != '' ">
and inTime <![CDATA[ <=]]> #{endTime}
</if>
order by devcMac,inTime asc
</select>
4、因为这个轨迹分析计算是离线处理的,每天只需要运行一次即可,所以处理逻辑如下:
log.info("游客轨迹分析定时任务,开始...");
//获取总人数
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
String dayId = DateUtil.format(cal.getTime(), "yyyyMMdd");
String beginTime = dayId + "000000";
String endTime = dayId+"235959";
List<OrbitData> orbitList = orbitMapper.selectByMapAllList(beginTime,endTime);
List<Map<String, Object>> lineList = new ArrayList<Map<String, Object>>();
String tempLine="";
for(int i=0;i<orbitList.size();i++){
Map<String, Object> lineMap=new HashMap<String,Object>();
OrbitData orbit = orbitList.get(i);
if(i==0){
tempLine = orbitList.get(i).getName()+"=>";
location += "("+orbitList.get(i).getLongitude()+","+orbitList.get(i).getLatitude()+"),";
}else if(i>0 && i<orbitList.size()){
//如果相等,说明是同一个人
if(orbit.getDevcMac().equals(orbitList.get(i-1).getDevcMac())){
if(!orbitList.get(i-1).getName().equals(orbit.getName())){
BigDecimal a= new BigDecimal(orbitList.get(i-1).getInTime().toString().trim());
BigDecimal b= new BigDecimal(orbitList.get(i).getInTime().toString().trim());
BigDecimal cc=b.subtract(a);
//不同景点之间需要间隔10分钟以上的才属于有效数据
if( cc.compareTo(new BigDecimal(1000))>-1){
tempLine += orbitList.get(i).getName()+"=>";
}else if(i+1<orbitList.size()){
if(!orbit.getDevcMac().equals(orbitList.get(i+1).getDevcMac())){
tempLine += orbitList.get(i).getName()+"=>";
}
}
}
}else{
String[] split = tempLine.split("=>");
if(split.length>1){
tempLine=tempLine.substring(0,tempLine.length()-2);
lineMap.put("track", tempLine);
lineMap.put("day_id", DateUtil.format(cal.getTime(), "yyyy-MM-dd"));
lineMap.put("num", 1);
lineList.add(lineMap);
}
tempLine="";
location="";
tempLine += orbitList.get(i).getName()+"=>";
}
}
}
//lineList合并处理
List<Map<String, Object>> countList = new ArrayList<Map<String, Object>>();// 用于存放最后的结果
for (int i = 0; i < lineList.size(); i++) {
String track = lineList.get(i).get("track").toString();
String day_id = lineList.get(i).get("day_id").toString();
int flag = 0;// 0为新增数据,1为增加count
for (int j = 0; j < countList.size(); j++) {
String track_ = countList.get(j).get("track").toString();
String day_id_ = countList.get(j).get("day_id").toString();
if (track.equals(track_) && day_id.equals(day_id_)) {
int sum = Integer.parseInt(lineList.get(i).get("num").toString())
+ Integer.parseInt(countList.get(j).get("num").toString());
countList.get(j).put("num", sum + "");
flag = 1;
continue;
}
}
if (flag == 0) {
countList.add(lineList.get(i));
}
}
if(countList.size()>0){
//将查询出来的结果存放到数据库中
personStayLineMapper.insertBatch(countList);
}
log.info("游客轨迹分析定时任务,结束...");
5、处理完成的结果如下
处理完成之后有的有轨迹至少要有2个景区,同时会存在有多个景点情况
数据集下载地址为:https://download.csdn.net/download/sdksdk0/10723169