于吉吉的技術博客

          建造高性能門戶網

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            65 隨筆 :: 6 文章 :: 149 評論 :: 0 Trackbacks
          房產地圖google map的初步應用點滴.1)
          房產地圖google map的初步應用點滴.2)
          房產地圖google map的初步應用點滴.3)
          房產地圖google map的初步應用點滴.4)

          google map測距的實現(xiàn)和分析

          不斷有傳聞google map在今年的7月1號之后在大陸停止運營,具體原因是因為天朝的牌照問題,這個就不多講了,可以發(fā)現(xiàn)現(xiàn)在搜房網的地圖,和安居客等的地圖紛紛都撤下 google map,而重新選擇了mapabc或baidu,當然網易房產地圖也不例外,現(xiàn)在也在使用mapabc作為網易房產地圖的開發(fā),預計將在6月底前上線,到 時再跟大家分享一下mapabc的一些開發(fā)實踐。

          還是說回google map的開發(fā),自從上次建了個qq群就有不少人在問測距怎么實現(xiàn),當然很多人想的是拿來主義的,當時是拿http://xf.house.163.com /gz/map/000B.html的例子出來,但確實頁面上進行了封裝也寫得比較亂,所以還是比較難以抽離,先給個簡單實現(xiàn)的例子:

          <!DOCTYPE html>
          <html>
          <head>
          <meta http-equiv="content-type" content="text/html; charset=GBK"/>
          <title>163網易房產</title>
          <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
          <script type="text/javascript">
            
          var map;
            
          function initialize() {
              
          var myLatlng = new google.maps.LatLng(23.116193,113.374525);
              
          var myOptions = {
                zoom: 
          15,
                center: myLatlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP
              }
              map 
          = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
            }
          var polyline;
          var polylinesArray = [];
          //距離標記數組
          var lenArray = []; 
          var rule = null
           
          //距離
          function getDistance(){
              
          //啟動整個地圖的click偵聽
              rule = google.maps.event.addListener(map,"click",function(event){
                  addMarker(event.latLng);
              });
          }
          //添加新標記
          function addMarker(location){
              
          //標記選項
              var myOptions = {
                  position : location,
                  draggable :
          false,
                  map : map,
              };
              marker 
          = new google.maps.Marker(myOptions);
              
          //將標記壓入數組
              lenArray.push(marker);
              
          //計算距離 
              drawOverlay();
          }
          //畫出路徑覆蓋層
              function drawOverlay(){
              
          //路線數組
              var flightPlanCoordinates = [];
              
          //將坐標壓入路線數組
              if (lenArray) {
                  
          for (i in lenArray) {
                      flightPlanCoordinates.push(lenArray[i].getPosition());
                  }
              }
              
          //路徑選項
              var polylineOptions = {
                  path : flightPlanCoordinates,
                  map : map,
                  strokeColor : 
          "#FF0000",
                  strokeOpacity : 
          1.0,
                  strokeWeight : 
          2
              };
              polyline 
          = new google.maps.Polyline(polylineOptions);
              
          //清除原有折線路徑
              if (polylinesArray) {
                  
          for (i in polylinesArray) {
                      polylinesArray[i].setMap(
          null);
                  }
                  polylinesArray 
          = [];
              }
              polyline.setMap(map);
              polylinesArray.push(polyline);
              alert((polyline.getLength()
          /1000).toFixed(3+ "km");
          }
          google.maps.LatLng.prototype.distanceFrom 
          = function(latlng) {
              
          var lat = [this.lat(), latlng.lat()]
              
          var lng = [this.lng(), latlng.lng()] 
              
          var R = 6378137;
              
          var dLat = (lat[1- lat[0]) * Math.PI / 180;
              
          var dLng = (lng[1- lng[0]) * Math.PI / 180;
              
          var a = Math.sin(dLat / 2* Math.sin(dLat / 2+ Math.cos(lat[0* Math.PI / 180* Math.cos(lat[1* Math.PI / 180* Math.sin(dLng / 2* Math.sin(dLng / 2);
              
          var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
              
          var d = R * c;
              
          return Math.round(d);

          google.maps.Marker.prototype.distanceFrom 
          = function(marker) {
              
          return this.getPosition().distanceFrom(marker.getPosition());
          }
          google.maps.Polyline.prototype.getLength 
          = function() {
              
          var d = 0;
              
          var path = this.getPath();
              
          var latlng;
              
          for (var i = 0; i < path.getLength() - 1; i++) {
                  latlng 
          = [path.getAt(i), path.getAt(i + 1)];
                  d 
          += latlng[0].distanceFrom(latlng[1]);
              }
              
          return d;
          }
          </script>
          </head>
          <body onload="initialize()">
            
          <div id="map_canvas" style="width: 500px; height: 400px"></div>
            
          <href="#this" onclick="getDistance();">開始測距</a>
          </body>
          </html>



          例子給完了,其中測距的計算是抄了google的示例,想簡單拿來應用的到這里就可以結束了,還有點興趣的可以看看下面的簡單分析:

          說到測距無非就是線的計算,根據google map api,測距的線性實現(xiàn)我們采用Polyline類,Polyline是折線是地圖上的連接線段的線性疊加層,擴展自MVCObject。

          測距是由線組成,然后根據一組線的長短計算出線的啟動和終點線的距離,根據這個思路,我們定義出
          var polyline;
          var polylinesArray = [];
          其中polyline是當前畫出來這條線,polylinesArray是一個數組,當每話出一條線就將這條線push到polylinesArray這個數組中去。

          另外一條線其實是由兩個點,始點和終點所組成,所以我們也定義一個
          var lenArray = [];
          lenArray是一個數組,用來記錄鼠標點過的每一個點的信息
          也就是說整個測距是由每一條線所組成,而一條線是由2個點組成。

          思路理清楚了,接著一步一步看

          當我們點擊了開始測距時,就需要啟動一個事件的監(jiān)聽,對整個map的click事件監(jiān)聽
              rule = google.maps.event.addListener(map,"click",function(event){
                  addMarker(event.latLng);
              });
          當我們在地圖上進行點擊時,就會新增一個maker點,并且將這個maker壓入lenArray數組,以便于后面的計算
          function addMarker(location){
          ...
          marker = new google.maps.Marker(myOptions);
          ...
          lenArray.push(marker);
          drawOverlay();
          接著會調用drawOverlay();使用polyline來畫線
              var flightPlanCoordinates = [];
              //將坐標壓入路線數組
              if (lenArray) {
                  for (i in lenArray) {
                      flightPlanCoordinates.push(lenArray[i].getPosition());
                  }
              }
              var polylineOptions = {
                  path : flightPlanCoordinates,
                  map : map,
                  strokeColor : "#FF0000",
                  strokeOpacity : 1.0,
                  strokeWeight : 2
              };
              polyline = new google.maps.Polyline(polylineOptions);

          其中polylineOptions的path參數是折線坐標的有序序列??梢允褂靡粋€簡單的 LatLng 數組或者 LatLng 的 MVCArray 指定此路徑。請注意,如果您傳

          遞簡單的數組,則它會轉換為 MVCArray。在 MVCArray 中插入或刪除 LatLng 將自動更新地圖上的折線。
          flightPlanCoordinates數組用于存儲在上面我們定義的lenArray數組的坐標值,每點擊一次就壓入一對坐標值。
          strokeColor和strokeOpacity,strokeWeight是一些樣式的參數,如指定線條的寬度等等。
          最后我們將定義的polyline進行setMap,在地圖上展現(xiàn),并將polyline壓入到polylinesArray數組中去。
              polyline.setMap(map);
              polylinesArray.push(polyline);
          到這里,線和點的展現(xiàn)已經完成了,接下來是需要將這些點線轉換成我們需要的距離值。

          google.maps.Polyline.prototype.getLength = function() {
              var d = 0;
              var path = this.getPath();
              var latlng;
              for (var i = 0; i < path.getLength() - 1; i++) {
                  latlng = [path.getAt(i), path.getAt(i + 1)];
                  d += latlng[0].distanceFrom(latlng[1]);
              }
              return d;
          }

          這里需要講明的是this.getPath();它的說明是檢索第一條路徑。并且返回值是一組MVCArray.<LatLng>,也就是實際存儲了一條線的坐標值,在這里取出這些坐標的數組,并且進行循環(huán)distanceFrom計算

          google.maps.LatLng.prototype.distanceFrom = function(latlng) {
              var lat = [this.lat(), latlng.lat()]
              var lng = [this.lng(), latlng.lng()]
              var R = 6378137;
              var dLat = (lat[1] - lat[0]) * Math.PI / 180;
              var dLng = (lng[1] - lng[0]) * Math.PI / 180;
              var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat[0] * Math.PI / 180) * Math.cos(lat[1] * Math.PI / 180) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
              var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
              var d = R * c;
              return Math.round(d);
          }
          這段計算實際上是抄自google map示例的,是將我們的坐標值轉換成我們需要計算的距離值,這里就不分析,有興趣可以玩玩,沒興趣就直接抄過去吧。

          結果出來了,這個就是我們需要的測距的距離,當然你也可以用其他方式進行展現(xiàn)

          alert((polyline.getLength()/1000).toFixed(3) + "km");
          只要閱讀google api和自己思路清楚,一個測距的demo很快就完成了,稍加裝飾基本就可以應用于生產上

          如果你也在進行google map的開發(fā),歡迎賜教和討論,建了個qq群:11029590
          posted on 2011-06-02 14:01 陳于喆 閱讀(3970) 評論(1)  編輯  收藏 所屬分類: web開發(fā) 、Google Map開發(fā)

          評論

          # re: 房產地圖google map的初步應用點滴.4) 2011-10-06 23:04 張生馬
          池州網站建設 九華山網站建設 青陽網站建設QQ:615863218
          專注于網站建設服務!

          行業(yè)網站建設 企業(yè)網站建設 企業(yè)網站維護二次開放

            回復  更多評論
            

          主站蜘蛛池模板: 上林县| 澄江县| 于都县| 仁化县| 五峰| 托克逊县| 宁化县| 佛山市| 栖霞市| 武乡县| 宁河县| 泸水县| 玉山县| 安泽县| 定边县| 汶上县| 山西省| 叙永县| 达拉特旗| 田林县| 尼勒克县| 遂平县| 钟山县| 西安市| 民乐县| 颍上县| 焦作市| 台前县| 靖边县| 黄大仙区| 徐水县| 铜陵市| 富阳市| 永福县| 德阳市| 平度市| 达拉特旗| 墨竹工卡县| 海盐县| 镇原县| 曲松县|