google map测距的实现和分析

不断有传闻google map在今年的7月1号之后在大陆停止运营,具体原因是因为天朝的牌照问题,这个就不多讲了,可以发现现在搜房网的地图,和安居客等的地图纷纷都撤下 google map,而重新选择了mapabc或baidu,当然网易房产地图也不例外,现在也在使用mapabc作为网易房产地图的开发,预计将在6月底前上线,到 时再跟大家分享一下mapabc的一些开发实践。

还是说回google map的开发,自从上次建了个qq群就有不少人在问测距怎么实现,当然很多人想的是拿来主义的,当时是拿http://xf.house.163.com /gz/map/000B.html的例子出来,但确实页面上进行了封装也写得比较乱,所以还是比较难以抽离,先给个简单实现的例子:

<!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>
  <a href="#this" onclick="getDistance();">开始测距</a>
</body>
</html>

例子给完了,其中测距的计算是抄了google的示例,想简单拿来应用的到这里就可以结束了,还有点兴趣的可以看看下面的简单分析:
说到测距无非就是线的计算,根据google map api,测距的线性实现我们采用Polyline类,Polyline是折线是地图上的连接线段的线性叠加层,扩展自MVCObject。
测距是由线组成,然后根据一组线的长短计算出线的启动和终点线的距离,根据这个思路,我们定义出
var polyline;
var polylinesArray = [];
其中polyline是当前画出来这条线,polylinesArray是一个数组,当每话出一条线就将这条线push到polylinesArray这个数组中去。
另外一条线其实是由两个点,始点和终点所组成,所以我们也定义一个
var lenArray = []; 
lenArray是一个数组,用来记录鼠标点过的每一个点的信息
也就是说整个测距是由每一条线所组成,而一条线是由2个点组成。

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

当我们点击了开始测距时,就需要启动一个事件的监听,对整个map的click事件监听
    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,在地图上展现,并将polyline压入到polylinesArray数组中去。
    polyline.setMap(map);
    polylinesArray.push(polyline);
到这里,线和点的展现已经完成了,接下来是需要将这些点线转换成我们需要的距离值。

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>,也就是实际存储了一条线的坐标值,在这里取出这些坐标的数组,并且进行循环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示例的,是将我们的坐标值转换成我们需要计算的距离值,这里就不分析,有兴趣可以玩玩,没兴趣就直接抄过去吧。

结果出来了,这个就是我们需要的测距的距离,当然你也可以用其他方式进行展现

alert((polyline.getLength()/1000).toFixed(3) + "km");

只要阅读google api和自己思路清楚,一个测距的demo很快就完成了,稍加装饰基本就可以应用于生产上

房产地图google map的初步应用点滴.4)(转)的更多相关文章

  1. 房产地图google map的初步应用点滴.3)(转)

    房产地图google map的初步应用点滴.1)房产地图google map的初步应用点滴.2)房产地图google map的初步应用点滴.3) 房产地图google map的初步应用点滴.4) go ...

  2. 房产地图google map的初步应用点滴.2)(转)

    房产地图google map的初步应用点滴.1)房产地图google map的初步应用点滴.2)房产地图google map的初步应用点滴.3) 房产地图google map的初步应用点滴.4) 本来 ...

  3. 房产地图google map的初步应用点滴.1)(转)

    房产地图google map的初步应用点滴.1)房产地图google map的初步应用点滴.2)房产地图google map的初步应用点滴.3) 房产地图google map的初步应用点滴.4) 以前 ...

  4. 谷歌地图实现车辆轨迹移动播放(google map api)

    开发技术:jquery,js baidu map api,json,ajax QQ1310651206 谷歌地图(google map api)实现车辆轨迹移动播放(google map api)

  5. Android Google Map API使用的八个步骤

    本系列教程将分为两部分,第一部分是指导用户使用Mapview控件进行编程,其中包括了如何获得Google Map API,如何使用该API进行简单的开发,如何获得用户当前所在的位置.第二部分则包括如何 ...

  6. Android中Google地图路径导航,使用mapfragment地图上画出线路(google map api v2)详解

    在这篇里我们只聊怎么在android中google map api v2地图上画出路径导航,用mapfragment而不是mapview,至于怎么去申请key,manifest.xml中加入的权限,系 ...

  7. Google Map API v2 (三)----- 地图上添加标记(Marker),标记info窗口,即指定经纬度获取地址字符串

    接上篇 http://www.cnblogs.com/inkheart0124/p/3536322.html 1,在地图上打个标记 private MarkerOptions mMarkOption; ...

  8. Google Map API v2 步步为营(一) ----- 初见地图

    官方文档:https://developers.google.com/maps/documentation/android/start?hl=zh-CN 先谷歌后百度.使用google的api基本上按 ...

  9. arcgis api for silverlight使用google map等多个在线地图

    原文 http://blog.csdn.net/leesmn/article/details/6820245 无可否认,google map实在是很漂亮.可惜对于使用arcgis api for si ...

随机推荐

  1. 如何利用启明星Portal门户系统的Page模块构建文档库

    利用启明星门户系统的Page模块构架可以搭建企业内部的文档管理系统. (一)应用背景 企业内部通常都会使用共享网盘的方式来存放不同部门之间的文档,例如管理员在服务器上对人事部门增加人事部文档文件夹. ...

  2. Mysql 查询注意和运行shell命令

    Mysql 查询注意 1. 在mysql查询的时候须要注意在表的前面加上数据库的前缀,不然就是默认是当前的数据库(当多个库查询的时候,可能会出现反复的查同样的表多次) 2. \! ls –al ,my ...

  3. 用SBT编译Spark的WordCount程序

    问题导读: 1.什么是sbt? 2.sbt项目环境如何建立? 3.如何使用sbt编译打包scala? sbt介绍 sbt是一个代码编译工具,是scala界的mvn,可以编译scala,java等,需要 ...

  4. C语言项目:学生成绩管理系统

    C语言项目:学生成绩管理系统    1.数据结构:学生信息:学号.姓名.年龄.性别.3课成绩    2.功能:   (1)增加学生记录    (2)  删除学生记录    (3)  查找学生信息(学号 ...

  5. Objective-C:NSDectionary字典的常见操作

    NSDectionary字典:它是一个存储键值的容器,每一个键key都对应着一个值value,可以通过键key一次性找到目标值value,这是一个比较好的存储器,相比于数组而言,它明显提高了查询效率. ...

  6. OTL翻译(9) --常量的SQL语句

    常量的SQL语句 一个没有绑定变量的SQL语句.SQL语句块或是存储过程就被称为常量的SQL语句.OTL通过一个静态的函数来执行这样的SQL语句. 例如: // static otl_cursor:: ...

  7. [置顶] think in java interview-高级开发人员面试宝典(一)

    “生死六重门” 无论你是在职,非在职,高级工程师,工程师,架构师,如果你正在面试阶段,请看完此文! 相信这篇文章对你的职业生涯和阶值观会造成重大的改变! 如果你是一名PM或者是管理者正在物色合适的开发 ...

  8. 【华为OJ平台练习题】求最大公共子串的个数和元素

    1.原题是求出最大公共子串的个数就可以 原理:利用二维矩阵排列的方式.将俩字符串进行比較 #include <iostream> #include <vector> using ...

  9. [转] ssh穿透??未验证。。。

    一. SSH ProxyCommand 实践 http://www.cnblogs.com/shanpow/p/4264867.html 二. SSH穿越跳板机:一条命令跨越跳板机直接登陆远程计算机 ...

  10. System.Net.Http.Formatting的nuget版本冲突问题

      已经添加了nuget Microsoft.AspNet.WebApi.Client 调用System.Net.Http.HttpClient.PostAsJsonAsync的时候报如下的错误: C ...