折腾一个多月终于弄完了这个项目,起初都未曾接触GPS/轨迹追踪、轨迹回放、圈划围栏...等一些在百度地图或者Googel地图操作的一些业务,后端的业务相对来说简单点
cas单点登录,mongdb灵活的数据存储方式,ActiveMQ消息推送、Redis存储...
这篇的主要篇幅主要来讲述下项目中的一些地图上棘手的问题
接口测试数据:
1.GPS数据接收接口对于日期格式的转化
作为码农都知道Web接口传输的数据都是以Json的数据形式传输,日期格式不同是我们头疼的事情,当然要是我们自己给App端,云平台端...都喜欢直接点java.util.Date类型直接抛给对
方,当然作为接收方很反感这种以毫秒的形式
①org.springframework.web.bind.annotation.ResponseBody 这是我们用SpringMvc常用的一种转JSON的形式,常用业务中完全可以搞定
②com.alibaba.fastjson.annotation.JSONField 阿里巴巴的转JSON形式,起初对它并不有所偏好,后来写接口写多了,就慢慢喜欢上了
@ResponseBody 直接将我们所需要的数据格式封装起来直接转JSON返回
如:
1 import java.io.Serializable;2 3 @SuppressWarnings("rawtypes")4 public class APIContent implements Serializable{5 /**6 * 7 */8 private static final long serialVersionUID = 2127409162712908650L;9 10 public APIContent(){}11 12 private Page page;13 14 private boolean ok=true;15 16 /**17 * 返回的数据包18 */19 private Object data;20 21 /**22 * 错误码,请查globs23 */24 private int code = ApiGlobals.SUCCESS;25 /**26 * 消息处理27 */28 private String msg;29 30 31 /**32 * 返回数据成功,设置数据。33 * @param data34 */35 public APIContent(Object data){36 this.data=data;37 }38 39 /**40 * 返回数据成功,设置数据。41 * @param data42 */43 public APIContent(Page page, Object data){44 this.page = page;45 this.data=data;46 }47 public APIContent(int code){48 this.code=code;49 }50 public Object getData() {51 return data;52 }53 54 public void setData(Object data) {55 this.data = data;56 }57 58 public int getCode() {59 return code;60 }61 62 public void setApiCode(int code){63 switch(code){64 case ApiCode.opt.DATA_REPEAT:65 setMsg("data is repeat! ");66 break;67 case ApiCode.opt.NOT_LOGIN:68 setMsg("please login first! ");69 break;70 case ApiCode.bug.INVAILD_PARAMS:71 setMsg("invaild params! ");72 break;73 case ApiCode.bug.NO_RESOURCE:74 setMsg("not exists resource! ");75 break;76 case ApiCode.bug.OPERATION:77 setMsg("operation falied! ");78 break;79 case ApiCode.bug.UNDEFINE_FUN:80 setMsg("unimplements function or version! ");81 break; 82 case ApiCode.fatal.ERR_SERVER:83 setMsg("server error! ");84 break; 85 case ApiCode.Login.INVAILD_PWD:86 setMsg("password is invalid! ");87 case ApiCode.Login.NOT_REGISTER:88 setMsg("not register user! ");89 break; 90 case ApiCode.BindDevice.DEVICE_HAS_BIND:91 setMsg("device has binded! ");92 break; 93 case ApiCode.BindDevice.INVAILD_PWD:94 setMsg("device password is invalid! ");95 break; 96 case ApiCode.BindDevice.NO_DEVICE:97 setMsg("device is not exists! ");98 break; 99 }
100 this.code=code;
101 }
102
103 public boolean isOk() {
104 return ok;
105 }
106 public void setOk(boolean ok) {
107 this.ok = ok;
108 }
109 public void setCode(int code) {
110
111 this.code = code;
112 }
113
114 public Page getPage() {
115 return page;
116 }
117 public void setPage(Page page) {
118 this.page = page;
119 }
120 public String getMsg() {
121 return msg;
122 }
123 public void setMsg(String msg) {
124 this.msg = msg;
125 }
126
127 }
将数据封装到date中然后标识状态码,提示信息返回
@JSONField 的处理有所不同的是,对于日期的处理以及返回形式都可改变
如:我们对日期格式的转化
@JSONField(name = "type")
private String mcTypeName; // 设备类型
@JSONField(name = "expireTime", format = "yyyy-MM-dd HH:mm:ss")
private Date expireTime; //过期时间
@JSONField(name = "createTime", format = "yyyy-MM-dd HH:mm:ss")
private Date createTime; //接入时间
返回数据处理 :自定义形式..仅作参考
View Code
View Code
1 /*2 * public void returnJson2(HttpServletResponse response, Object object, String... includes) { returnJson2(response, getJson(object, includes)); }3 * 4 * public void returnJson2(HttpServletResponse response, Object object, String[] includes, String[] excludes) { returnJson2(response, getJson(object, includes, excludes)); }5 * 6 * public void returnJson2(HttpServletResponse response, String json) { returnJson(response, (HttpServletRequest) null, json); }7 */8 public void returnJson(HttpServletResponse response, HttpServletRequest request, String json) {9 try {
10 String contentType = "application/json; charset=UTF-8";
11 if (request != null) {
12 String accept = request.getHeader("accept");
13 if (accept != null && !accept.contains("json")) {
14 contentType = "text/html; charset=UTF-8";
15 }
16 }
17 response.setContentType(contentType);
18 response.getWriter().write(json);
19 response.getWriter().flush();
20 } catch (IOException e) {
21 if (logger.isErrorEnabled()) {
22 logger.error("returnJson is error!", e);
23 }
24 }
25 }
2.分段轨迹/轨迹追踪
(注:每次选取不同轨迹的时候先清除原先画的轨迹)
百度地图
谷歌地图
代码实现:
①值得注意的是GPS经纬度转化为百度经纬度和谷歌经纬度是不一样的
这里我做的算法处理
获取百度经纬度:通过GPS/(lat,lng)得到百度地图经纬度
获取谷歌地图经纬度:通过GPS/(lat,lng)得到百度地图经纬度,在将百度经纬度转化为谷歌地图经纬度
源码:(获取上诉接口数据...然后在做坐标处理)
Point.java
View Code
经纬度转化算法
1 public class CoordinateConversion {2 private static final double x_pi = 3.14159265358979324 * 3000.0 / 180.0;3 4 private static final double pi = 3.14159265358979324; //元周率5 private static final double a = 6378245.0; //卫星椭球坐标投影到平面地图坐标系的投影因子。6 private static final double ee = 0.00669342162296594323; //ee: 椭球的偏心率。7 8 /**9 * gg_lat 纬度 10 * gg_lon 经度 11 * GCJ-02转换BD-09 Google地图经纬度转百度地图经纬度12 * */13 public static Point google_bd_encrypt(double gg_lat, double gg_lon) {14 Point point = new Point();15 double x = gg_lon, y = gg_lat;16 double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);17 double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);18 double bd_lon = z * Math.cos(theta) + 0.0065;19 double bd_lat = z * Math.sin(theta) + 0.006;20 point.setLat(bd_lat);21 point.setLng(bd_lon);22 return point;23 }24 25 /**26 * wgLat 纬度 27 * wgLon 经度 28 * BD-09转换GCJ-02 百度转google29 * */30 public static Point bd_google_encrypt(double bd_lat, double bd_lon) {31 Point point = new Point();32 double x = bd_lon - 0.0065, y = bd_lat - 0.006;33 double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);34 double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);35 double gg_lon = z * Math.cos(theta);36 double gg_lat = z * Math.sin(theta);37 point.setLat(gg_lat);38 point.setLng(gg_lon);39 return point;40 }41 42 43 /**44 * wgLat 纬度 45 * wgLon 经度 46 * BD-09转换GCJ-02 百度转47 * */48 public static Point bd_google_baidu_encrypt(double bd_lat, double bd_lon) {49 Point point = new Point();50 point=wgs_gcj_encrypts(bd_lat,bd_lon);51 point=google_bd_encrypt(point.getLat(),point.getLng());52 return point;53 }54 55 56 /**57 * wgLat 纬度58 * wgLon 经度59 * WGS-84 到 GCJ-02 的转换(即 GPS 加偏)60 * */61 public static Point wgs_gcj_encrypts(double wgLat, double wgLon) {62 Point point = new Point();63 if (outOfChina(wgLat, wgLon)) {64 point.setLat(wgLat);65 point.setLng(wgLon);66 return point;67 }68 double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);69 double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);70 double radLat = wgLat / 180.0 * pi;71 double magic = Math.sin(radLat);72 magic = 1 - ee * magic * magic;73 double sqrtMagic = Math.sqrt(magic);74 dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);75 dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);76 double lat = wgLat + dLat;77 double lon = wgLon + dLon;78 point.setLat(lat);79 point.setLng(lon);80 return point;81 }82 83 public static void transform(double wgLat, double wgLon, double[] latlng) {84 if (outOfChina(wgLat, wgLon)) {85 latlng[0] = wgLat;86 latlng[1] = wgLon;87 return;88 }89 double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);90 double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);91 double radLat = wgLat / 180.0 * pi;92 double magic = Math.sin(radLat);93 magic = 1 - ee * magic * magic;94 double sqrtMagic = Math.sqrt(magic);95 dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);96 dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);97 latlng[0] = wgLat + dLat;98 latlng[1] = wgLon + dLon;99 }
100
101 private static boolean outOfChina(double lat, double lon) {
102 if (lon < 72.004 || lon > 137.8347)
103 return true;
104 if (lat < 0.8293 || lat > 55.8271)
105 return true;
106 return false;
107 }
108
109 private static double transformLat(double x, double y) {
110 double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
111 + 0.2 * Math.sqrt(Math.abs(x));
112 ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
113 ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
114 ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
115 return ret;
116 }
117
118 private static double transformLon(double x, double y) {
119 double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
120 * Math.sqrt(Math.abs(x));
121 ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
122 ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
123 ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
124 * pi)) * 2.0 / 3.0;
125 return ret;
126 }
127 }
初始化原型地图通用模块
1 <script type="text/javascript">2 var allMap;//公共的默认加载百度google地图3 var allMapType=$("#selectMap").val();4 if(allMapType=='googleMap'){5 initGoogleMap();6 7 }else{8 initBaiDuMap();//默认自动加载百度地图9 10 }11 12 //普通13 $("#selectMap").change(function(){14 var mapType=$(this).children('option:selected').val();//这就是selected的值 15 if(mapType=='googleMap'){16 initGoogleMap();17 18 }else{19 initBaiDuMap();20 21 }22 allMapType=mapType;23 });24 25 /***26 电子围栏切换27 $("#selectGeozoneMap").change(function(){28 var mapType=$(this).children('option:selected').val();//这就是selected的值 29 if(mapType=='googleMap'){30 initGoogleMap();//初始化google地图31 intoGoogleTools();//初始化google地图绘制工具32 }else{33 initBaiDuMap();//初始化百度地图34 intoBaiDuMapTools();//初始化百度地图绘制工具35 }36 });37 **/38 39 function initBaiDuMaps(){40 var myCity = new BMap.LocalCity();41 myCity.get(myCenterAndZoom); 42 function myCenterAndZoom(result){43 var cityName = result.name;44 //initBaiDuMaps(cityName);45 }46 }47 function initBaiDuMap(){48 // 百度地图API功能49 allMap= new BMap.Map("allmap"); // 创建Map实例 divID必须为allmap50 allMap.centerAndZoom(new BMap.Point(116.404, 39.915), 11); // 初始化地图,设置中心点坐标和地图级别51 allMap.addControl(new BMap.MapTypeControl()); //添加地图类型控件52 allMap.addControl(new BMap.NavigationControl());//设置导航条 (左上角,添加默认缩放平移控件)53 allMap.enableScrollWheelZoom(true); //开启鼠标滚轮缩放54 allMap.clearOverlays();55 }56 57 58 function initGoogleMap(){59 //Google地图API功能60 //纬度&经度61 var myCenter=new google.maps.LatLng(39.915,116.404);62 var mapProp = {63 center:myCenter,64 zoom:10,65 mapTypeId:google.maps.MapTypeId.ROADMAP66 };67 allMap = new google.maps.Map(document.getElementById("allmap"),mapProp);68 }69 70 71 //地图自动高度72 function mapAutoHeight(){73 $("#allmap").height($(window).height() - $(".header").outerHeight() - $(".breadcrumb-func").outerHeight() - $(".footer").outerHeight());74 }75 mapAutoHeight(); 76 $(window).resize(function(){77 mapAutoHeight();78 });79 80 //状态81 var icon_end = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/end.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};82 var icon_start = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/start.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};83 var icon_gray_automobile = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/gray_automobile.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};84 var icon_gray_bus = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/gray_bus.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};85 var icon_gray_truck = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/gray_truck.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};86 var icon_green_automobile = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/green_automobile.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};87 var icon_green_bus = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/green_bus.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};88 var icon_green_truck = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/green_truck.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};89 var icon_red_automobile = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/red_automobile.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};90 var icon_red_bus = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/red_bus.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};91 var icon_red_truck = {icon:new BMap.Icon(_ctx+"/resource/images/36x43/red_truck.png" ,new BMap.Size(36,44)),offset:new BMap.Size(0,-22),imageOffset:new BMap.Size(0,-22)};92 //0,离线; 1,在线静止; 2,在线运动.93 var vechleIconMap=94 {95 '0_bus' :icon_gray_bus ,96 '1_bus' :icon_red_bus ,97 '2_bus' :icon_green_bus ,98 '0_automobile' :icon_gray_automobile ,99 '1_automobile' :icon_red_automobile ,
100 '2_automobile' :icon_green_automobile ,
101 '0_truck' :icon_gray_truck ,
102 '1_truck' :icon_red_truck ,
103 '2_truck' :icon_green_truck
104 };
105
106 var gicon_end = {url:_ctx+"/resource/images/36x43/end.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
107 var gicon_start = {url:_ctx+"/resource/images/36x43/start.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
108 var gicon_gray_automobile = {url:_ctx+"/resource/images/36x43/gray_automobile.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
109 var gicon_gray_bus = {url:_ctx+"/resource/images/36x43/gray_bus.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
110 var gicon_gray_truck = {url:_ctx+"/resource/images/36x43/gray_truck.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
111 var gicon_green_automobile = {url:_ctx+"/resource/images/36x43/green_automobile.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
112 var gicon_green_bus = {url:_ctx+"/resource/images/36x43/green_bus.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
113 var gicon_green_truck = {url:_ctx+"/resource/images/36x43/green_truck.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
114 var gicon_red_automobile = {url:_ctx+"/resource/images/36x43/red_automobile.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
115 var gicon_red_bus = {url:_ctx+"/resource/images/36x43/red_bus.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
116 var gicon_red_truck = {url:_ctx+"/resource/images/36x43/red_truck.png" ,size:new google.maps.Size(36,44),origin:new google.maps.Point(0,0),anchor:new google.maps.Point(18,44)};
117
118 //0,离线; 1,在线静止; 2,在线运动.
119 var gvechleIconMap=
120 {
121 '0_bus' :gicon_gray_bus ,
122 '1_bus' :gicon_red_bus ,
123 '2_bus' :gicon_green_bus ,
124 '0_automobile' :gicon_gray_automobile ,
125 '1_automobile' :gicon_red_automobile ,
126 '2_automobile' :gicon_green_automobile ,
127 '0_truck' :gicon_gray_truck ,
128 '1_truck' :gicon_red_truck ,
129 '2_truck' :gicon_green_truck
130 };
131
132 </script>
轨迹分段Map.js
1 //获取所有点的坐标2 3 var label; //信息标签4 var centerPoint;5 var selfAll;6 7 var startIcon=_ctx+"/resource/images/36x43//start.png";//8 var startMaker;//起点9 var startLable;10 var startPoint;11 12 var endIcon=_ctx+"/resource/images/36x43/end.png";//13 var endLable;//终点14 var endMaker;15 var endPoint;16 17 var points=[];18 //Googel19 var map;20 21 //选择加载22 $("#selectMap").change(function(){23 var mapType=$(this).children('option:selected').val();//这就是selected的值 24 if(mapType=='googleMap'){25 initGoogleMap();26 }else{27 initBaiDuMap();28 }29 allMapType=mapType;30 getPointAtMap();31 });32 33 34 //选择路段信息35 function getPointAtMap(startTime,endTime,imei){36 points.splice(0, points.length); //清除记录37 $.ajax({38 type:"post",39 url:_ctx+"/drivingrecord/getPonitAtMap",40 async: false,41 cache: false,42 data:{"startTime":startTime,"endTime":endTime,"imei":imei,"selectMap":allMapType}, 43 dataType: 'json',44 success:function(returnData){45 if(returnData.code==0){46 if(allMapType == 'googleMap'){47 $.each(returnData.data,function(n,value){48 points.push(new google.maps.LatLng(value.lat, value.lng));49 });50 initgoogel();51 }else{52 allMap.clearOverlays();53 $.each(returnData.data,function(n,value){54 points.push(new BMap.Point(value.lng, value.lat));55 });56 initbaidu();57 }58 }else{59 layer.msg("该时间段无行驶记录");60 allMap.clearOverlays();61 initbaidu();62 }63 }64 });65 }66 67 function initbaidu() {68 //初始化地图,选取第一个点为起始点69 allMap.centerAndZoom(points[0], 15);70 71 centerPoint = new BMap.Point((points[0].lng + points[points.length - 1].lng) / 2, (points[0].lat + points[points.length - 1].lat) / 2);72 allMap.panTo(centerPoint);73 //连接所有点74 allMap.addOverlay(new BMap.Polyline(points, {strokeColor: "#00cc00", strokeWeight: 5, strokeOpacity: 1}));75 76 //显示起点77 startLable = new BMap.Label("", {offset: new BMap.Size(-35,-35)});78 //car = new BMap.Marker(points[0], {icon: new BMap.Icon(iconImg, new BMap.Size(48, 48), {imageOffset: new BMap.Size(0, 0)})});79 startPoint=points[0];80 startMaker = new BMap.Marker(startPoint, {icon: new BMap.Icon(startIcon, new BMap.Size(48,48)),offset: new BMap.Size(2,-20),imageOffset: new BMap.Size(0,-20)});81 //startMaker.setLabel(startLable);82 allMap.addOverlay(startMaker);83 //显示终点84 endLable = new BMap.Label("", {offset: new BMap.Size(-35,-35)});85 //car = new BMap.Marker(points[0], {icon: new BMap.Icon(iconImg, new BMap.Size(48, 48), {imageOffset: new BMap.Size(0, 0)})});86 endPoint=points[points.length-1];87 endMaker = new BMap.Marker(endPoint, {icon: new BMap.Icon(endIcon, new BMap.Size(48,48)),offset: new BMap.Size(2,-20),imageOffset: new BMap.Size(0,-20)});88 //endMaker.setLabel(endLable);89 allMap.addOverlay(endMaker);90 }91 92 //初始化谷歌地图93 function initgoogel(){94 var indexCenter=points.length/2;95 indexCenter=indexCenter>>0;96 97 var mapOptions = {98 zoom: 14, //缩放级别99 center: points[indexCenter],
100 panControl: true,
101 zoomControl: true,
102 mapTypeControl: true,
103 scaleControl: true,
104 overviewMapControl: true,
105 mapTypeId: google.maps.MapTypeId.ROADMAP
106 };
107 map = new google.maps.Map(document.getElementById('allmap'),mapOptions);
108 var lineSymbol = {
109 //travelMode: google.maps.DirectionsTravelMode.DRIVING,
110 path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
111 scale: 2,
112 strokeColor: '#0000',
113 strokeOpacity: 1.0, // 透明度
114 strokeWeight: 2, // 宽度
115 strokeOpacity : 0.8,
116 fillColor : "#0000",
117 fillOpacity : 0.4
118 };
119 line = new google.maps.Polyline({
120 path: points,
121 icons: [{
122 icon: lineSymbol,
123 offset: '1%'
124 }],
125 strokeColor: '#418f02',
126 //travelMode: google.maps.DirectionsTravelMode.DRIVING,
127 map: map
128 });
129 linePath=line.getPath();
130 new google.maps.Marker(
131 {
132 position: points[0],
133 icon:startIcon,
134 map: map
135 }
136
137 );
138 new google.maps.Marker(
139 {
140 position: points[points.length - 1],
141 icon:endIcon,
142 map: map
143 }
144 );
145
146 }
注:
① 我们都知道纬度的范围是南北纬0-90°,经度的范围是东西经0-180°
百度地图:对应点经纬度先填纬度,后天经度(开始没有仔细看百度API被坑了许久)
points.push(new BMap.Point(value.lng, value.lat));
谷歌地图:经纬度正常
points.push(new google.maps.LatLng(value.lat, value.lng));
②对起始位置,终点位置的修饰以及轨迹的修饰
其实原理都相通,我们描画地图上的坐标,都是通过逐个坐标点来控制,确定起始,终点坐标,自定义类型
如:
百度地图~
//初始化地图,选取第一个点为起始点
allMap.centerAndZoom(points[0], 15);
//连接所有点
allMap.addOverlay(new BMap.Polyline(points, {strokeColor: "#00cc00", strokeWeight: 5, strokeOpacity: 1}));
//显示起点
startLable = new BMap.Label("", {offset: new BMap.Size(-35,-35)});
//car = new BMap.Marker(points[0], {icon: new BMap.Icon(iconImg, new BMap.Size(48, 48), {imageOffset: new BMap.Size(0, 0)})});
startPoint=points[0];
startMaker = new BMap.Marker(startPoint, {icon: new BMap.Icon(startIcon, new BMap.Size(48,48)),offset: new BMap.Size(2,-20),imageOffset: new BMap.Size(0,-20)});
//显示终点
endLable = new BMap.Label("", {offset: new BMap.Size(-35,-35)});
//car = new BMap.Marker(points[0], {icon: new BMap.Icon(iconImg, new BMap.Size(48, 48), {imageOffset: new BMap.Size(0, 0)})});
endPoint=points[points.length-1];
endMaker = new BMap.Marker(endPoint, {icon: new BMap.Icon(endIcon, new BMap.Size(48,48)),offset: new BMap.Size(2,-20),imageOffset: new BMap.Size(0,-20)});
//endMaker.setLabel(endLable);
allMap.addOverlay(endMaker);
(当然这里值得一提的中点位置,不是终点是中点,当时围栏显示轨迹中心位置所取的一个点,每种地图都要设置一个中心点)
即取起始位置和终点位置的中点就OK了~有点逻辑头脑的都可以接收
开始做百度地图的时候有点棘手,毕竟先前没有接触过,后来做谷歌地图的时候,就灵活点了~
起点,终点 (确定坐标位置就OK了,我们是把所有坐标放到数组上的,当前后面的操作就SO easy啦)
new google.maps.Marker({position: points[0],icon:startIcon,map: map });
new google.maps.Marker({position: points[points.length - 1],icon:endIcon,map: map });
③百度经纬度,谷歌经纬度转当前地理位置
百度地图:
谷歌地图:
转存失败重新上传取消
View Code
围栏设置与控制
百度:
谷歌:
百度 JS
1 //0:电子围栏,1:地标2 var flag = $("#flag").val();3 $(document).ready(function(){4 var allMapType=$("#selectGeozoneMap").val();5 if(allMapType=='googleMap'){6 $("#map-pin").hide();7 initGoogleMap();8 intoGoogleTools();//初始化google地图绘制工具9 }else{10 $("#map-pin").show();11 initBaiDuMap();//默认自动加载百度地图12 intoBaiDuMapTools();13 searchAddrTip();14 }15 16 });17 18 $("#selectGeozoneMap").change(function(){19 var mapType=$(this).children('option:selected').val();//这就是selected的值 20 if(mapType=='googleMap'){21 $("#map-pin").hide();22 initGoogleMap();//初始化google地图23 intoGoogleTools();//初始化google地图绘制工具24 }else{25 $("#map-pin").show();26 initBaiDuMap();//初始化百度地图27 intoBaiDuMapTools();//初始化百度地图绘制工具28 }29 });30 31 //多边形清除32 function initToDrawing(){33 //drawingManagerBaidu.setDrawingMode(BMAP_DRAWING_POLYGON);//默认进入地图开启画多边形34 clearAll();35 intoBaiDuMapTools();36 }37 38 39 /**40 * 百度绘制工具加载41 * */42 43 var baiduoverlays = [];44 function intoBaiDuMapTools(){45 allMap.removeEventListener("click", initToDrawing);46 //实例化鼠标绘制工具47 var drawingManagerBaidu = new BMapLib.DrawingManager(allMap, {48 isOpen: false, //是否开启绘制模式49 enableDrawingTool: true, //是否显示工具栏50 drawingToolOptions: {51 anchor: BMAP_ANCHOR_TOP_RIGHT, //位置52 //drawingModes: [BMAP_DRAWING_POLYGON,BMAP_DRAWING_CIRCLE],53 drawingModes: [BMAP_DRAWING_POLYGON],54 offset: new BMap.Size(150, 5), //偏离值55 scale: 0.8 //工具栏缩放比例56 },57 polygonOptions: {58 strokeColor : "#0000FF",59 strokeOpacity : 0.8,60 strokeWeight : 2,61 fillColor : "#FF0000",62 fillOpacity : 0.4,63 editable:false, //是否可以编辑64 draggable:false //是否可拖动 65 } //多边形的样式66 });67 drawingManagerBaidu.setDrawingMode(BMAP_DRAWING_POLYGON);//默认进入地图开启画多边形68 //添加鼠标绘制工具监听事件,用于获取绘制结果69 drawingManagerBaidu.addEventListener('overlaycomplete', overlaycomplete);70 var htmlcontent = '';71 var opts = '';72 var strName="围栏";73 if(flag != 0){74 strName="地标";75 }76 77 htmlcontent += '<div class="p-tb10">';78 htmlcontent += '<div>';79 htmlcontent += '<table>';80 htmlcontent += '<tr>';81 htmlcontent += '<td class="ta-r"><label><font color="#ff0000">*</font> 名称: </label></td>';82 htmlcontent += '<td><input type="text" id="geoname" name="geoname" size="20" placeholder="请输入'+strName+'标题" class="form-control" style="width:160px;" /></td>';83 htmlcontent += '</tr>';84 htmlcontent += '<tr>';85 htmlcontent += '<td class="ta-r p-t7"><label>描述: </label></td>';86 htmlcontent += '<td class="p-t7"><input type="text" id="description" name="description" placeholder="请输入'+strName+'描述信息" class="form-control" size="50" style="width:160px;" /></td>';87 htmlcontent += '</tr>';88 htmlcontent += '<tr>';89 htmlcontent += '<td> </td>';90 htmlcontent += '<td class="p-t7"><input type="submit" value="提交" class="btn btn-primary btn-block" onclick="saveGoogleGeozoneInfo();" /></td>';91 htmlcontent += '</tr>';92 htmlcontent += '</table>';93 htmlcontent += '</div>';94 htmlcontent += '</div>';95 opts = {96 width : 200, // 信息窗口宽度97 height: 156, // 信息窗口高度98 title : "创建"+strName , // 信息窗口标题99 enableMessage:false,//设置允许信息窗发送短息
100 message:htmlcontent
101 };
102
103
104 var infoWindow = new BMap.InfoWindow(htmlcontent,opts); // 创建信息窗口对象
105
106 //回调获得覆盖物信息
107 function overlaycomplete(e){
108 drawingManagerBaidu.setDrawingMode(BMAP_DRAWING_POLYGON);//默认进入地图开启画多边形
109 baiduoverlays.push(e.overlay);
110 try{
111 var array= e.overlay.getPath();
112 showLonLat(array);
113 }catch(e){
114 }
115 //添加单击事件
116 allMap.addEventListener("click",initToDrawing);
117 }
118 //获取所画围栏点经纬度
119 function showLonLat(arr){
120 var info="";
121 for(var i=0; i<arr.length;i++){
122 //纬度&经度
123 info+="|("+arr[i].lat+","+arr[i].lng+")";
124 }
125 var coors=info.substring(1);
126 var str="多边形节点数:" + (arr.length) + " 节点坐标:"+info;
127 //document.getElementById('mapinfo').innerHTML = "手动绘制多边形节点数:" + arr.length + "<br>节点坐标:"+info;
128 console.log("overlaycomplete:"+str);
129 var falgs=false;
130 var len=arr.length;
131 len=Number(len);
132 if(len>=3){
133 falgs=true;
134 }else{
135 intoBaiDuMapTools();
136 if(flag == 0){
137 layer.msg('围栏为封闭的多边形!');
138 }else{
139 layer.msg('地标为封闭的多边形!');
140 }
141 }
142 if(falgs){
143 $("#maptype").val("baidu");
144 $("#coors").val(coors);
145 var point = new BMap.Point(arr[0].lng,arr[0].lat);
146 allMap.openInfoWindow(infoWindow,point); //开启信息窗口
147 }
148 }
149 }
150
151 //清除围栏
152 function clearAll() {
153 for(var i = 0; i < baiduoverlays.length; i++){
154 allMap.removeOverlay(baiduoverlays[i]);
155 allMap.clearOverlays();
156 }
157 baiduoverlays.length = 0;
158 }
谷歌:
1 //0:电子围栏,1:地标2 var flag = $("#flag").val();3 /**4 * Google绘制工具加载5 * */6 function intoGoogleTools(){7 //图形绘制工具控加载此AIP链接后面加上&libraries=drawing8 var drawingManager = new google.maps.drawing.DrawingManager({9 drawingMode: google.maps.drawing.OverlayType.POLYGON,10 drawingControl: true,11 drawingControlOptions: {12 position: google.maps.ControlPosition.TOP_CENTER,13 drawingModes: [14 //google.maps.drawing.OverlayType.MARKER,15 //google.maps.drawing.OverlayType.CIRCLE,16 google.maps.drawing.OverlayType.POLYGON, //仅使用多边形绘制工具17 //google.maps.drawing.OverlayType.POLYLINE,18 // google.maps.drawing.OverlayType.RECTANGLE19 ]20 },21 circleOptions: {22 strokeColor : "#0000FF",23 strokeOpacity : 0.8,24 strokeWeight : 2,25 fillColor : "#FF0000",26 fillOpacity : 0.4,27 editable:false, //是否可以编辑28 draggable:false //是否可拖动29 },30 polygonOptions: {//设置画线样式31 strokeColor: "#0000FF", 32 strokeOpacity: 0.8, 33 strokeWeight: 3, 34 fillColor: "#FF0000", 35 fillOpacity: 0.35, 36 editable: false 37 } 38 });39 drawingManager.setMap(allMap);40 41 //注册 多边形 绘制完成事件 42 var geozonePolygon = null;43 google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) { 44 drawingManager.setDrawingMode(null); //切换为选择模式45 geozonePolygon=polygon;46 showLonLat(polygon);47 });48 var htmlcontent = '';49 var strName="围栏";50 if(flag != 0){51 strName="地标";52 }53 54 htmlcontent += '<div class="p-t10 p-b5">';55 htmlcontent += '<div>';56 htmlcontent += '<table>';57 htmlcontent += '<tr>';58 htmlcontent += '<td class="ta-r"><label><font color="#ff0000">*</font> 名称: </label></td>';59 htmlcontent += '<td><input type="text" id="geoname" name="geoname" size="20" placeholder="请输入'+strName+'标题" class="form-control" style="width:160px;" /></td>';60 htmlcontent += '</tr>';61 htmlcontent += '<tr>';62 htmlcontent += '<td class="ta-r p-t7"><label>描述: </label></td>';63 htmlcontent += '<td class="p-t7"><input type="text" id="description" name="description" placeholder="请输入'+strName+'描述信息" class="form-control" size="50" style="width:160px;" /></td>';64 htmlcontent += '</tr>';65 htmlcontent += '<tr>';66 htmlcontent += '<td> </td>';67 htmlcontent += '<td class="p-t7"><input type="submit" value="提交" class="btn btn-primary btn-block" onclick="saveGoogleGeozoneInfo();" /></td>';68 htmlcontent += '</tr>';69 htmlcontent += '</table>';70 htmlcontent += '</div>';71 htmlcontent += '</div>';72 73 var infowindow = new google.maps.InfoWindow({74 content: htmlcontent,75 zIndex: 100076 });77 //循环显示 经纬度 78 function showLonLat(polygon){79 var array= polygon.getPath().getArray();80 var paths = polygon.getPath();81 var geozone=""; 82 for(var i=0; i<array.length;i++){ 83 geozone+="|"+array[i];84 };85 geozone=geozone.substring(1);86 //document.getElementById('mapinfo').innerHTML = "手动绘制多边形节点数:" + arr.length + "<br>节点坐标:"+info;87 var falg=false;88 var len=array.length;89 len=Number(len);90 if(len>=3){91 falg=true;92 }else{93 infowindow.setMap(null);94 geozonePolygon.setMap(null);95 drawingManager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);96 if(flag == 0){97 layer.msg('围栏为封闭的多边形!');98 }else{99 layer.msg('地标为封闭的多边形!');
100 }
101 }
102 if(falg){
103 $("#maptype").val("google");
104 $("#coors").val(geozone);
105 infowindow.setPosition(paths.getAt(0));
106 infowindow.open(allMap);
107 }
108 }
109
110 //信息框弹出关闭
111 google.maps.event.addListener(infowindow,'closeclick', function() {
112 geozonePolygon.setMap(null);
113 drawingManager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);
114 });
115
116 //点击地图页面
117 google.maps.event.addListener(allMap, 'click', function(event) {
118 infowindow.setMap(null);
119 geozonePolygon.setMap(null);
120 drawingManager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);
121 });
122 }
123
124
125
126
127 //弹框后输入围栏信息保存
128 function saveGoogleGeozoneInfo(){
129 var mapType=$("#maptype").val();
130 var coors=$("#coors").val();
131 var geoname=$("#geoname").val();
132 var description=$("#description").val();
133 ajaxMapFencingSave(mapType,coors,geoname,description);
134 }
135
136 //围栏保存到后台 flag:0为电子围栏
137 var postSaveUrl=_ctx+"/geozone/editGeozone";
138 function ajaxMapFencingSave(mapType,coors,geoname,description){
139 if(geoname!=''){
140 $.ajax({
141 type:'POST',
142 url:postSaveUrl,
143 data:{"geom":coors,
144 "mapType":mapType,
145 "type":"polygon",
146 "geoname":geoname,
147 "description":description,
148 "flag":flag},
149 dataType:'json',
150 success: function(rest){
151 if(rest.ok){
152 if(flag == 0){
153 layer.msg('围栏设置成功!');
154 window.location.href=_ctx+"/geozone/giveanalarm?id="+rest.data.id+"&geonames="+rest.data.geoname;
155 }else{
156 layer.msg('地标设置成功!');
157 window.location.href=_ctx+"/geozone/landMarkList";
158 }
159 //$("#id").val(rest.data.id);
160 //$("#geonames").val(rest.data.geoname);
161 //$("#giveanalarmForm").submit();
162 }else{
163 if(flag == 0){
164 layer.msg('围栏设置失败!');
165 }else{
166 layer.msg('地标设置失败!');
167 }
168 }
169 }
170 });
171 }else{
172 document.getElementById('geoname').focus();
173 if(flag == 0){
174 layer.msg('围栏名称必须填写!');
175 }else{
176 layer.msg('地标名称必须填写!');
177 }
178 }
179 }
180
181
182 /**
183 * 地址查询
184 * 自动提示功能
185 * @param inputId
186 */
187 function initSeachBaidu(inputId){
188 //建立一个自动完成的对象
189 var autoComplete= new BMap.Autocomplete({"input" : inputId ,"location" :allMap});
190 //鼠标点击下拉列表后的事件
191 //查询输入 TODO 是否去掉查询按钮
192 // autoComplete.addEventListener("onconfirm", function(e) {
193 // var _value = e.item.value;
194 // var searchValue = _value.province + _value.city + _value.district + _value.street + _value.business;
195 // });
196 }
197
198
199 function searchAddrTip(){
200 var allMapType=$("#selectGeozoneMap").val();
201 if(allMapType=='baiduMap'){
202 baiduInit();
203 }else{
204 //googleSeach(inputId);
205 }
206 }
207 /**
208 * 地址查询
209 * 自动提示功能
210 * @param inputId
211 */
212 function baiduInit(){
213 // 百度地图API功能
214 function G(id) {
215 return document.getElementById(id);
216 }
217
218 var ac = new BMap.Autocomplete( //建立一个自动完成的对象
219 {"input" : "mapSearchText"
220 ,"location" : allMap
221 });
222
223 ac.addEventListener("onhighlight", function(e) { //鼠标放在下拉列表上的事件
224 var str = "";
225 var _value = e.fromitem.value;
226 var value = "";
227 if (e.fromitem.index > -1) {
228 value = _value.province + _value.city + _value.district + _value.street + _value.business;
229 }
230 str = "FromItem<br />index = " + e.fromitem.index + "<br />value = " + value;
231
232 value = "";
233 if (e.toitem.index > -1) {
234 _value = e.toitem.value;
235 value = _value.province + _value.city + _value.district + _value.street + _value.business;
236 }
237 str += "<br />ToItem<br />index = " + e.toitem.index + "<br />value = " + value;
238 G("searchResultPanel").innerHTML = str;
239 });
240
241 var myValue;
242 ac.addEventListener("onconfirm", function(e) { //鼠标点击下拉列表后的事件
243 var _value = e.item.value;
244 myValue = _value.province + _value.city + _value.district + _value.street + _value.business;
245 G("searchResultPanel").innerHTML ="onconfirm<br />index = " + e.item.index + "<br />myValue = " + myValue;
246 setPlace();
247 });
248
249 function setPlace(){
250 allMap.clearOverlays(); //清除地图上所有覆盖物
251 function myFun(){
252 var pp = local.getResults().getPoi(0).point; //获取第一个智能搜索的结果
253 allMap.centerAndZoom(pp, 18);
254 allMap.addOverlay(new BMap.Marker(pp)); //添加标注
255 }
256 var local = new BMap.LocalSearch(allMap, { //智能搜索
257 onSearchComplete: myFun
258 });
259 local.search(myValue);
260 }
261 }
262
263 /**
264 * Google搜索
265 * */
266 function googleSeach(inputId){
267 var options = {
268 bounds: defaultBounds,
269 types: ['establishment']
270 };
271 autocomplete = new google.maps.places.Autocomplete(inputId, options);
272 }
围栏显示:
1 var geozId=$("#geozId").val();2 echoGeozone();3 var data;4 5 //围栏回显6 $("#selectGeozoneMap").change(function(){7 var mapType=$(this).children('option:selected').val();//这就是selected的值 8 if(mapType=='googleMap'){9 initGoogleMap();10 echoGeozoneGoogleMapData(data);//google回显11 }else{12 initBaiDuMap();13 echoGeozoneBaiduMapData(data);//百度回显14 }15 });16 function echoGeozone(){17 $.ajax({18 type:'POST',19 url:_ctx+"/geozone/getgeozone",20 data:{"geozId":geozId},21 dataType:'json',22 success: function(ret){23 if(ret.ok){24 data=ret.data;25 //initBaiDuMap();26 echoGeozoneBaiduMapData(data);27 }28 }29 });30 }31 32 //百度地图回显33 function echoGeozoneBaiduMapData(data){34 var typeMap=data.mapType;35 var datas=null;36 if(typeMap=='google'){37 datas=data.backGeom;38 }else{39 datas=data.geom;40 }41 var coords=datas.point;42 43 var centerAndZoomPointLat;44 var centerAndZoomPointLng;45 var BmapPointArray=[];46 for(var i=0;i<coords.length;i++){47 var lat=coords[i].lat;48 var lng=coords[i].lng;49 centerAndZoomPointLat=coords[0].lat;50 centerAndZoomPointLng=coords[0].lng;51 var BmapPoint=new BMap.Point(lng,lat);52 BmapPointArray.push(BmapPoint);53 }54 //回显多边形55 var polygon = new BMap.Polygon(BmapPointArray,{56 strokeColor : "#0000FF",57 strokeOpacity : 0.8,58 strokeWeight : 2,59 fillColor : "#FF0000",60 fillOpacity : 0.4,61 editable:false, //是否可以编辑62 draggable:false //是否可拖动 63 }); //创建多边形64 allMap.centerAndZoom(new BMap.Point(centerAndZoomPointLng,centerAndZoomPointLat),11); //设置中心点坐标和地图级别65 allMap.addOverlay(polygon); //增加多边形66 }67 //google 地图回显示68 function echoGeozoneGoogleMapData(data){69 var typeMap=data.mapType;70 var datas=null;71 if(typeMap=='baidu'){72 datas=data.backGeom;73 }else{74 datas=data.geom;75 }76 var coords=datas.point;77 78 var centerAndZoomPointLat;79 var centerAndZoomPointLng;80 var GmapPointArray=[];81 for(var i=0;i<coords.length;i++){82 var lat=coords[i].lat;83 var lng=coords[i].lng;84 centerAndZoomPointLat=coords[0].lat;85 centerAndZoomPointLng=coords[0].lng;86 var pointArray= new google.maps.LatLng(lat,lng);87 GmapPointArray.push(pointArray);88 }89 var centerPoint= new google.maps.LatLng(centerAndZoomPointLat,centerAndZoomPointLng);90 91 var myLatlng = new google.maps.LatLng(centerAndZoomPointLat,centerAndZoomPointLng);92 var mapOptions = {93 zoom: 13,94 center: centerPoint,95 mapTypeId: google.maps.MapTypeId.ROADMAP96 };97 //var maps = new google.maps.Map(document.getElementById("allmap"), mapOptions);98 var polygonGoogle = new google.maps.Polygon({99 path : GmapPointArray,
100 strokeColor : "#0000FF",
101 strokeOpacity : 0.8,
102 strokeWeight : 2,
103 fillColor : "#FF0000",
104 fillOpacity : 0.4,
105 editable:false, //是否可以编辑
106 draggable:false //是否可拖动
107 });
108 polygonGoogle.setMap(allMap);
109 }
先这样了.........了解详细讨论
https://gitee.com/ibyte/M-Pass
作者: iByte丶Li
出处:https://www.cnblogs.com/visec479/p/4599551.html
版权:本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。