实时定位
使用百度地图api模拟实时定位页面 完整示例
效果:使用百度地图api在页面上显示车辆的实时位置,并有自动刷新和手动刷新两种方式可以选择。每次刷新后,都会在地图上显示车辆的最新位置。
示例运行效果截图:
步骤
1. 首先,我们要创建一个一个main方法,用来往一个txt文件中不断地写新的坐标,来模拟GPS设备不断获取的坐标数据。
所以我们先写一个任务,它的作用是产生一个新的位置坐标,并将其写入一个名为position.txt
的文档中。
package com.icbc.datadisplayService.bean;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;
public class TimerTask extends java.util.TimerTask {
// private Position position;
@Override
public void run() {
//随机生成坐标
//lon的取值范围是121.4600-121.4800
//lat的取值范围是31.2200-31.2800
Random randomLon = new Random();
Random randomLat = new Random();
double lon = ((double)(1214600+randomLon.nextint(200)))/10000;
double lat = ((double)(312200+randomLon.nextInt(600)))/10000;
// this.position.setLon(lon);
// this.position.setLat(lat);
//把他写到文件里
File positionFile = new File("D:\\MyAPPlication\\java\\GPSDataDisplayService\\src\\main\\java\\com\\icbc\\dataDisplayService\\position.txt");//文件路径
try{
FileWriter fw = new FileWriter(positionFile,true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(String.valueOf(lon)+"\n");//这里要写String类型,先写经度
bw.write(String.valueOf(lat)+"\n");//写纬度
bw.flush();
bw.close();
fw.close();
}catch (IOException e){
e.printstacktrace();
}
}
}
注:
- 经度和纬度都是利用随机数生成的,范围最好不要波动太大
- 文件的路径最写成绝对路径,否则有可能找不到。
之后在main方法中定时执行这个任务,我这里设置的时间是5秒,也就是每隔五秒钟向txt文档中写入一个新的坐标点。
package com.icbc.dataDisplayService.bean;
import com.icbc.dataDisplayService.dao.CarDao;
import org.Springframework.context.support.ClassPathXmlApplicationContext;
import java.io.*;
import java.nio.Buffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
public class Main {
public static void main(String[] args) {
Timer timer = new Timer();
System.out.println("创建");
timer.schedule(new TimerTask(),0,5*1000);//每隔5秒将一个新点的坐标写入txt文件
}
}
别忘了创建实体类Positon
package com.icbc.dataDisplayService.bean;
public class Position {
private double lon;
private double lat;
public Position(double lon, double lat) {
this.lon = lon;
this.lat = lat;
}
public double getLon() {
return lon;
}
public void setLon(double lon) {
this.lon = lon;
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
@Override
public String toString() {
return "Position{" +
"lon=" + lon +
", lat=" + lat +
'}';
}
}
2.创建Testcontroller.java
这个Controller用于和前端交互和传递数据,前端页面每发来一次请求,此Controller就去position.txt
中读取最新的一条数据并返回此坐标点。
package com.icbc.dataDisplayService.controller;
import com.icbc.dataDisplayService.bean.Position;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.stereotype.Controller;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.requestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.responseBody;
import sun.rmi.runtime.Log;
//这是一个测试类,会去txt文件中读取数据并返回最新的经纬度给我
@Controller
public class TestController {
//这个方法用来返回视图
@RequestMapping(value = "/currentMap",method = RequestMethod.GET)
public String toCurrentPositionMap(){
return "CurrentPositionMap";
}
//这个方法在前台用ajax调用,返回最新的位置坐标
@RequestMapping(value = "/currentMapFuck",method = RequestMethod.GET)
@ResponseBody
//此方法返回一个最新的位置点给我
public Map<String,Object> getCurrentPosition(){
List<Double> doubleList = new ArrayList<Double>();//用来存储从文件中读取到的数据
File file = new File("D:\\Myapplication\\java\\GPSDataDisplayService\\src\\main\\java\\com\\icbc\\dataDisplayService\\position.txt");
try{
String readData;
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
while ((readData = br.readLine())!=null){//没有读到文件尾的s时候
try{
doubleList.add(Double.parseDouble(readData));
}catch (Exception e){
e.printStackTrace();
}
}
}catch (IOException e){
e.printStackTrace();
}
double lon = doubleList.get(doubleList.size()-2);
double lat = doubleList.get(doubleList.size()-1);
Map<String,Object> modelMap = new HashMap<String, Object>(2);
modelMap.put("data",new Position(lon,lat));
modelMap.put("success","true");
return modelMap;
}
}
注:
- 第二个方法中,
@ResponseBody
一定要写,因为前端要用ajax传递数据。- 由于我只是这里只是模拟,所以选择了将所有数据都读出然后取最后一条这种效率比较低的方法,实际上,如果指定去文件中读最后两条数据会更好。
最后Map中的数据就是返回值,将会在前端页面中进行接收和处理。
3. 前端页面的编写
在编写前端页面之前,首先我们要了解百度地图api的使用方法。
百度地图api官网中有很简单明了的例子。从获取密钥开始,每一步都有教程。大概只需要知道如何创建地图实例、如何设置和清除覆盖物、如何设置覆盖物动画等等这些基本的就行了。
当你已经具备了上述的基本关于百度地图api的使用方法,你就可以开始着手编写页面了。
注:
- 本页面已完成功能为主,并没有经过美化,所以比较丑。
- 除了百度地图api之外,你还需要对JQuery和ajax有基本的了解
首先,我们用ajax向Controller发送请求并拿到最新点的坐标。关于ajax怎样和Controller交互请参考博客。
<%--用ajax从后台contorller拿到数据--%>
<script type="text/JavaScript">
// 写ajax请求,调用TestController中的方法
function getCurrentPosition() {
var position = [];//定义一个数组来储存经纬度
console.log("执行了函数");
jQuery.ajax({
type:'GET',
content:'application/json',
url:'/currentMapFuck',
dataType:'json',
success :function (modelMap) {
console.log("成功");
console.log(modelMap.data.lon);
console.log(modelMap.data.lat);
position.push(modelMap.data.lon);
position.push( modelMap.data.lat);
},
ERROR :function () {
alert("error");
console.log("失败")
}
});
return position;//把这个数返回
}
</script>
能够拿到最新点位置坐标之后,我们就能在地图上做文章了。先导入百度地图js库。
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=您的密钥">
//v3.0版本的引用方式:src="http://api.map.baidu.com/api?v=3.0&ak=您的密钥"
</script>
之后定义一个p作为地图显示的区域。
<%--p的名字只能是container,否则就显示不出来,别问我问什么知道--%>
<p id="container">
</p>
然后利用得到的最新坐标点创建地图实例
<script type="text/javascript">
var map = new BMap.Map("container");//地图的实例
var myPosition = [];
myPosition = getCurrentPosition();
//要把点和marker设置成全局变量
var point;
var marker;
var carIcon = new BMap.Icon("http://lbsyun.baidu.com/jsdemo/img/car.png", new BMap.Size(300,157));//创建一个小车的图标
//让程序停止500毫秒之后在做function中的事情
settimeout(function () {
// 创建地图实例
point = new BMap.Point(myPosition[0], myPosition[1]);//这里已经能得到,就不打印了
// 初始化地图
map.centerAndZoom(point, 13);//地图的中心点和缩放级别
//添加一个marker
marker = new BMap.Marker(point,{icon:carIcon});
map.addoverlay(marker);
},500);
注:
- 由于我模拟的是显示车辆的位置,所以我把marker的图标替换成了小车,你可以根据自己的需要替换成其他的。
- 由于调用的函数里面有网络请求,需要一定的时间,所以可能会出现没有赋值成功的问题,我这里用了一个很蠢的方法,让程序暂停0.5秒保证网络请求结束,建议以后可以用回调函数来改进。
如果不出意外,现在你打开网页,就能看到地图中心有一个小车了,并且这个小车在地图刷新时它的最新位置。接下来就要考虑如何让它的位置能够刷新。
手动刷新比较简单,所以我们从手动刷新入手。
首先写一个用来刷新marker位置的函数
function changeMarkerPosition () {
myPosition = getCurrentPosition();
setTimeout(function () {
point = new BMap.Point(myPosition[0], myPosition[1]);//得到了最新的坐标点
console.log("地图中心:"+myPosition[0]+" "+myPosition[1]);
marker = new BMap.Marker(point,{icon:carIcon});
//map.centerAndZoom(point, 14);
map.clearOverlays();//在地图上清除掉所有的覆盖物。
map.addOverlay(marker);
marker.setAnimation(BMAP_ANIMATION_BOUNCE);//给marker设置动画
console.log("maker的位置"+marker.getPosition().lng+" "+marker.getPosition().lat);
},500);//此暂停放噶目前不得已而位置,带我日后掌握回调函数再战
}
之后我们在页面上写一个按钮,把这个函数绑定给这个按钮,手动刷新就就完成了。
<p id="manualDiv" class="manualDiv">
<%--手动刷新就显示这个p--%>
<button id="getCurrentPosition" name="refreshChoice"> <!--别把class写成calss了ヽ(●-`Д´-)ノ-->
<option selected="selected" id="manual" value="手动刷新" >手动刷新</option> <!--设置手动刷新为默认选项,但是在火狐上好像有bug-->
<option id="auto" value="自动刷新" >自动刷新</option>
</select>
然后需要用到jQuery中的监听器来监听下拉菜单状态的改变,以便采取不同的刷新方法。
<script>
var timer;
//利用jq监测下拉菜单的状态
$(document).ready(function(){
$(".refreshChoice").change(function(){
// alert($(this).find("option:checked").attr("id")); 通过此方法能得到用户选择的option的id值,从而判断用户选择了哪个选项。
if ($(this).find("option:checked").attr("id")=="manual"){
$(document).ready(function(){
$("#manualDiv").show();//如果选择了手动,就把面板显示出来
clearInterval(timer);
});
}else if($(this).find("option:checked").attr("id")=="auto"){
$("#manualDiv").hide();//如果选择了自动,就把面板隐藏。
timer = setInterval(changeMarkerPosition,5000);
//每隔5秒刷新一次点的坐标
}
});
});
</script>
注:
- 这里使用了if语句根据下来菜单选项中id的值来判断当前用户选择的是哪一个选项。
- 如果选择了手动,就把刷新按钮显示出来,反之则隐藏。
- 在用户选择了自动刷新之后,利用 timer = setInterval(changeMarkerPosition,5000);让刷新每隔5秒钟自动循环进行。
- 设置全局变量timer,在用户选择手动刷新的时候,将自动刷新的任务关闭。
最终,jsp中的完整代码如下:
<%--
Created by intelliJ IDEA.
User: 13905
Date: 2018/8/2
Time: 17:02
To change this template use File | settings | File Templates.
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Title</title>
<%--导入jQuery库--%>
<script src="../../js/jquery-3.3.1.js">
</script>
<!--导入百度地图js库-->
<style type="text/css">
html{height:100%}
body{height:100%;margin:0px;padding:0px}
#container{height:100%}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=lH6NeYMvgZMhGi8j9gRmTZuEXObQQ1tX">
//v3.0版本的引用方式:src="http://api.map.baidu.com/api?v=3.0&ak=您的密钥"
</script>
</head>
<body>
<%--用ajax从后台contorller拿到数据--%>
<script type="text/javascript">
// 写ajax请求,调用TestController中的方法
function getCurrentPosition() {
var position = [];
console.log("执行了函数");
jQuery.ajax({
type:'GET',
content:'application/json',
url:'/currentMapFuck',
dataType:'json',
success :function (modelMap) {
console.log("成功");
console.log(modelMap.data.lon);
console.log(modelMap.data.lat);
position.push(modelMap.data.lon);
position.push( modelMap.data.lat);
},
error :function () {
alert("error");
console.log("失败")
}
});
return position;
}
</script>
<p>
这是展示实时位置的地图
</p>
<p>
刷新方式:
<select class="refreshChoice" name="refreshChoice"> <!--别把class写成calss了ヽ(●-`Д´-)ノ-->
<option selected="selected" id="manual" value="手动刷新" >手动刷新</option> <!--设置手动刷新为默认选项,但是在火狐上好像有bug-->
<option id="auto" value="自动刷新" >自动刷新</option>
</select>
<p id="manualDiv" class="manualDiv">
<%--手动刷新就显示这个p--%>
<button id="getCurrentPosition" "+myPosition[1]);
marker = new BMap.Marker(point,{icon:carIcon});
//map.centerAndZoom(point, 14);
map.clearOverlays();//在地图上清除掉所有的覆盖物。
map.addOverlay(marker);
marker.setAnimation(BMAP_ANIMATION_BOUNCE);//给marker设置动画
console.log("maker的位置"+marker.getPosition().lng+" "+marker.getPosition().lat);
},500);//此暂停放噶目前不得已而位置,带我日后掌握回调函数再战
}
</script>
</body>
</html>
现在再打开网页,不管是手动刷新还是自动刷新,你的小车位置会随着时间而改变了。
完毕
相关阅读
如何在nuxt项目中使用百度地图 进入百度地图API选择javascriptAPI,按照流程注册账号获取ak,复制ak按照页面提示的,需要引入script标
编写一个js函数,实时显示当前时间,格式:“年-月-日 时:分
第一种: window.onload = function(){ var show = document.getElementById(‘show’); // setInterval(function(){
在angular框架下使用flv.js播放http-flv实时流直播视
目录 说明 总体思路 FFmpeg Nginx flv.js 效果展示 总结 说明 前段时间,我写了一篇在angular框架下使用videojs播放RTMP视频流
From:https://zhuanlan.zhihu.com/p/33112359 js分析 猫_眼_电_影 字体文件 @font-face:https://www.cnblogs.com/my8100/p/js_maoy
天猫直播这个功能不知道大家有没有听说过,其实它和淘宝直播功能是一样的,就是平台不一样,天猫直播是供天猫卖家服务的。下面seo实验