日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GPS/轨迹追踪、轨迹回放、围栏控制

發布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GPS/轨迹追踪、轨迹回放、围栏控制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

折騰一個多月終于弄完了這個項目,起初都未曾接觸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>&nbsp;名稱:&nbsp;&nbsp;</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>描述:&nbsp;</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>&nbsp;</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) + "&nbsp;節點坐標:"+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>&nbsp;名稱:&nbsp;&nbsp;</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>描述:&nbsp;</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>&nbsp;</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」創作共享協議,轉載請在文章明顯位置注明作者及出處。

總結

以上是生活随笔為你收集整理的GPS/轨迹追踪、轨迹回放、围栏控制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。