您的位置:首页 > 其它

整合百度地图,显示停车场位置,停车位详情,使用WebSocket实现动态刷新

2019-01-02 17:16 281 查看

我会在近段时间内把之前的项目上遇到的一些我觉得需要记录的需求、问题给写下来,来弥补之前没有写博客的习惯。

需求:当管理员登录智慧停车项目后台时,首页需要展示当前地区的停车场信息,以及每个停车场的停车位详情。
初期效果图如下:

以上需要实现的功能有:
将停车场作为标注点显示在地图上,根据停车场的剩余车位数改变标注点的颜色,绿色的为车位充足,以此类推。
当鼠标移动到标注点上时,显示停车场信息,点击标注点或详情时展示该停车场的停车位详情。
点击车位展示停放车辆详细信息。
由于项目后期会添加大量的停车场和停车位,但是如何保证页面实时展示每个停车场,每个停车位的最新信息,这里使用的是WebSocket来动态和后台交换数据,实现动态刷新部分停车场、停车位信息。(由于项目尚未正式上线,效果中无法演示)
首先是页面部分:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="ctx" value="${pageContext.request.contextPath}" />
<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
<html>
<head>
<title>百度地图</title>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=填写你的ak"></script>
<title>停车场地图展示</title>
<script src="${ctxStatic}/js/2.1.1-jquery.min.js"></script>
<script type="text/javascript" src="${ctxStatic}/layer/layer.js"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/GeoUtils/1.2/src/GeoUtils_min.js"></script>
<style>

.fix-rt{
width: 474px;
height: 100%;
background: #eee;
position: fixed;
right: -474px;
top: 0;
}
.btn-close{
display: block;
width: 0;
height: 0;
border: 16px solid transparent;
border-left:16px solid #666;
position: absolute;
top: 50%;
left: 5px;
font-size: 0;
}

</style>
</head>
<body>
<div id="allmap" style="width:100%;height:100%"></div>
<input type="hidden" id="cityName" value="${cityName}">
<div id="pri" style=" display: none;" area="" city ="" qu ="" areainfo=""></div>
<div class="fix-rt">
<a href="#" class="btn-close">关闭</a>
<iframe id="detail" src="" width="106%" height="99%" frameborder="0"></iframe>
</div>
</body>
<script type="text/javascript">
var map = new BMap.Map("allmap");
var cityName=$("#cityName").val();

var Longitude = "113.634865";//设置经度的初始值
var Atitude = "34.754389";//设置纬度的初始值
var point = new BMap.Point(Longitude,Atitude);
map.centerAndZoom(point,13);
map.setMapStyle({style:'googlelite'});

这一步你需要先申请一个百度开发者账号,然后去申请秘钥,这一步直接百度就行,非常简单详细。
到这里页面已经加载一个郑州市的地图,这里我的经纬度是写死的,当然也可以根据需要灵活配置。

接下来,要向后台发送请求获取停车场信息,得到后台返回的数据:

var overlays = [];
var parkList = [];
$.ajax({
async:false,
type:"POST",
url:"${ctx}/test",
dataType:"JSON",
success:function (data) {
parkList=data;
}
})

for(var i=0;i<parkList.length;i++){
var Longitude=parkList[i].longitude;
var Atitude=parkList[i].latitude;
var point = new BMap.Point(Longitude,Atitude);
overlays.push(point);
var spaces = parkList[i].spaces;	//停车场车位数
var spacesLast = parkList[i].spacesLast;	//停车场剩余车位数
var rate= spacesLast/spaces;
var greIcon = new BMap.Icon("${ctxStatic}/images/gre.png", new BMap.Size(35,37));
var redIcon = new BMap.Icon("${ctxStatic}/images/red.png", new BMap.Size(35,37));
var orangeIcon = new BMap.Icon("${ctxStatic}/images/orange.png", new BMap.Size(35,37));
if(rate > 0.5){
var marker = new BMap.Marker(point,{icon:greIcon});
}else if(rate > 0 && rate < 0.5){
var marker = new BMap.Marker(point,{icon:orangeIcon});
}else{
var marker = new BMap.Marker(point,{icon:redIcon});
}
console.log(rate);
if(rate<0.5){
console.log("warning");
}
var label = new BMap.Label(parkList[i].spacesLast, {
offset : new BMap.Size(6, 4)
});
var color='';
if(rate > 0.5){
color='green';
}else if(rate > 0 && rate < 0.5){
color='orange';
}else{
color='#ff0000';
}
label.setStyle({
background:'none',color:color,border:'none'//只要对label样式进行设置就可达到在标注图标上显示数字的效果
});

marker.setLabel(label);//显示标注中的剩余车位数字
map.addOverlay(marker);    //增加点
//marker.addEventListener("click",attribute);//增加点的单击事件
addClickHandler(parkList[i],marker);

}

以上实现了为地图添加标注点的功能,addClickHandler方法是为标注点增加单击事件,也就是右边滑出的停车场详情,这一步就不再写了,只是一些js的应用,可以根据具体业务需求实现相关的功能。
接下来是WebSocket
页面代码:

var server=location.hostname;
var port=location.port;
var websocket = null;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://"+server+":"+port+"/parkStationMap");
}
else {
alert('当前浏览器 Not support websocket')
}

//连接发生错误的回调方法
websocket.onerror = function () {
alert("WebSocket连接发生错误");
};

//连接成功建立的回调方法
websocket.onopen = function () {
console.log("WebSocket连接成功");
websocket.send("dwq");
}

//接收到消息的回调方法
websocket.onmessage = function (event) {
//WebSocket可以传送json格式的数据,在这里将json字符串装换成json对象
var s = JSON.parse(event.data);
console.log(s.parkStation.id);
//可以写自己具体的功能代码

}

//连接关闭的回调方法
websocket.onclose = function () {
console.log("WebSocket连接关闭");
}

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
closeWebSocket();
}

//关闭WebSocket连接
function closeWebSocket() {
websocket.close();
}

//发送消息
function send() {
var message = document.getElementById('text').value;
websocket.send(message);
}

接下来是服务器端:

/**
* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
*/
@ServerEndpoint("/parkStationMap")
public class ParkStationMapWebSocket {
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;

private static final Log logger = LogFactory.getLog(ParkStationMapWebSocket.class);

//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
//private static CopyOnWriteArraySet<ParkStationMapWebSocket> webSocketSet = new CopyOnWriteArraySet<ParkStationMapWebSocket>();

//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private ParkStationMapSessionManager parkStationMapSessionManager=new ParkStationMapSessionManager();

/**
* 连接建立成功调用的方法
* @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(Session session){
this.session = session;
parkStationMapSessionManager.addSession(session);     //加入set中
addOnlineCount();           //在线数加1
logger.debug("有新连接加入!当前在线人数为" + getOnlineCount());
}

/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session){
parkStationMapSessionManager.removeSession(session);  //从set中删除
subOnlineCount();           //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}

/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) throws IOException {
System.out.println("来自客户端的消息:" + message);
//MobileController.sessionId=session.getId();

System.out.println("来自客户端的消息:" + session.getId());
//这里展示一下可以传递多种json格式的数据
JSONObject json= new JSONObject();
Demo demo=new Demo();
Demo1 demo1=new Demo1();
demo.setName("yzy");
demo.setSex("nan");
demo1.setName("dwq");
demo.setDemo1(demo1);
Map<String,Object> map=new HashMap<>();
map.put("name","yzy");
map.put("age","15");
map.put("demo",demo);
String s2 = JSON.toJSONString(map);
System.out.println(s2);

//sendMessage(s2);
}

/**
* 发生错误时调用
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
try {
session.close();
logger.error(error.getMessage(),error);
} catch(Exception e) {
logger.error(e.getMessage(),e);
}
}

/**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
System.out.println("sessid:"+this.session.getId());
this.session.getBasicRemote().sendText(message);
//this.sessionManage.getAsyncRemote().sendText(message);
}

public static synchronized int getOnlineCount() {
return onlineCount;
}

public static synchronized void addOnlineCount() {
ParkStationMapWebSocket.onlineCount++;
}

public static synchronized void subOnlineCount() {
ParkStationMapWebSocket.onlineCount--;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐