事实上,地球上任意两个坐标点在地平线上的距离并不是直线,而是球面的弧线。

下面介绍如何利用正矢公式计算已知经纬度数据的两个坐标点之间的距离。半正矢公式也成为Haversine公式,它最早时航海学中的重要公式,其原理是将地球看作圆形,利用公式来计算圆形表面上任意两个点之间的弧线距离。

  Haversine公式中与本项目有关的公式为:

相关符号解释如下:

d : 两点之间的弧线总距离

r : 球体的半径

Q1,Q2: 第一个和第二个坐标点的纬度(需要将角度转换为弧度表示)

y1,y2 : 第一个和第二个坐标点的经度(需要将角度转换为弧度表示)

看个例子:

HTML5运动数据记录页面的设计与实现:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>跑步记录功能的设计与实现</title>
<style>
div {
text-align: left;
margin: auto;
padding: 10px;
}
.center {
text-align: center
}
</style>
</head>
<body>
<h3>跑步记录功能的设计与实现</h3>
<hr />
<div>
<h4>您的当前状态</h4>
<ul>
<li>
开始时间:<span id="start_time"></span>
</li>
<li>
完成时间:<span id="end_time"></span>
</li>
<li>
总距离:<span id="distance">0</span>km
</li>
</ul> <h4>详细信息</h4>
<ul>
<li>
经度:<span id="long"></span>°
</li>
<li>
纬度:<span id="lat"></span>°
</li>
<li>
位置精确度:<span id="acc"></span>
</li>
<li>
海拔高度:<span id="alt">0</span>m
</li>
<li>
速度:<span id="speed">0</span>m/s
</li>
</ul>
<div class="center">
<button id="btn" onclick="toggleBtn()">
开始记录
</button>
</div>
</div>
<script>
//前一次获取的经度
var oldLong;
//前一次获取纬度
var oldLat;
//最新获取的经度
var currentLong;
//最新获取的纬度
var currentLat; //获取地理位置
function getLocation() {
if (navigator.geolocation) {
var watchID = navigator.geolocation.watchPosition(showPosition, showError, options);
} else {
alert("对不起,您的浏览器不支持HTML5地理定位API");
}
} //回调函数,用于接收获取的经纬度以及描述信息
function showPosition(position) {
//更新经纬度数据
if (currentLong != null && currentLat != null) {
oldLong = currentLong;
oldLat = currentLat;
}
currentLong = position.coords.longitude;
currentLat = position.coords.latitude; alert(currentLong + "," + currentLat); //更新经度
var long = document.getElementById("long");
long.innerHTML = currentLong;
//更新纬度
var lat = document.getElementById("lat");
lat.innerHTML = currentLat;
//更新位置精确度
var acc = document.getElementById("acc");
acc.innerHTML = position.coords.accuracy;
//更新海拔高度
var alt = document.getElementById("alt");
alt.innerHTML = position.coords.altitude;
//更新速度
var speed = document.getElementById("speed");
speed = position.coords.speed; //更新运动距离
if (oldLat != null && oldLong != null) {
//计算本次运行的距离
var d = getDistance(currentLat, currentLong, oldLat, oldLong);
//获取页面上目前的总距离
var lastDistance = document.getElementById("distance").innerHTML;
alert(d);
//将总距离加上本次运动的距离,再更新到页面上
document.getElementById("distance").innerHTML = parseFloat(lastDistance) + d;
}
} //回调函数,用于接收获取失败时的错误代码
function showError(error) {
switch(error.code) {
case error.PERMISSION_DENIED:
alert("用户拒绝了地理定位的请求。");
break;
case error.POSITION_UNAVAILABLE:
alert("位置信息不可用。");
break;
case error.TIMEOUT:
alert("请求超时。");
break;
case error.UNKNOWN_ERROR:
alert("未知错误发生。");
break;
}
} //定位参数设置
var options = {
enableHighAccuracy : true,
timeout : 2000,
maximunAge : 2000
}; //当前运动状态,true为正在运动,false为没有运动
var isRunning = false;
//显示运动开始时间的<span>对象
var start_time = document.getElementById("start_time");
//显示运动结束时间的<span>对象
var end_time = document.getElementById("end_time"); function toggleBtn() {
var btn = document.getElementById("btn");
//开始运动
if (!isRunning) {
//获取当前时间对象
var now = new Date();
//更新开始时间信息
start_time.innerHTML = now.toLocaleString();
//清空结束时间信息
end_time.innerHTML = "";
//更新运动状态为true,表示正在运动
isRunning = true;
//更新按钮上的文字内容
btn.innerHTML = "完成记录";
//运动总距离清零
document.getElementById("distance").innerHTML = "0";
//开始定位
getLocation();
}
//结束运动
else {
//更新运动状态为false,表示结束运动
isRunning = false;
//更新按钮上的文字内容
btn.innerHTML = "开始记录";
//获取当前时间对象
var now = new Date();
//更新结束时间信息
end_time.innerHTML = now.toLocaleString();
}
} //角度转换为弧度
function toRadians(degree) {
return degree * Math.PI / 180;
} //计算两个坐标点之间的距离
function getDistance(lat1, long1, lat2, long2) {
// 地球的半径(单位:公里)
var R = 6371;
//角度转换为弧度
var deltaLat = toRadians(lat2 - lat1);
var deltaLong = toRadians(long2 - long1);
lat1 = toRadians(lat1);
lat2 = toRadians(lat2);
//计算过程
var h = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLong / 2) * Math.sin(deltaLong / 2);
//求距离
var d = 2 * R * Math.asin(Math.sqrt(h));
return d;
}
</script>
</body>
</html>

HTML5运动数据记录页面的设计与实现:

HTML5地理定位(已知经纬度,计算两个坐标点之间的距离)的更多相关文章

  1. java通过经纬度计算两个点的之间的距离的算法

    通过两个点的经纬度计算距离 从google maps的脚本里扒了段代码,没准啥时会用上.大家一块看看是怎么算的. private const double EARTH_RADIUS = 6378.13 ...

  2. 计算两个latitude-longitude点之间的距离? (Haversine公式)

    问题描述 如何计算纬度和经度指定的两点之间的距离?为了澄清,我想要距离公里;这些点使用WGS84系统,我想了解可用方法的相对准确性.最佳解决方案 这个link可能对您有帮助,因为它详细说明了使用Hav ...

  3. mysql实现经纬度计算两个坐标之间的距离sql语句

    select *,(2 * 6378.137* ASIN(SQRT(POW(SIN(PI()*(111.86141967773438-latitude)/360),2)+COS(PI()*33.070 ...

  4. mysql实现经纬度计算两个坐标之间的距离

    DELIMITER $$CREATE DEFINER = CURRENT_USER FUNCTION `getDistance`(`lon1` float,`lat1` float,`lon2` fl ...

  5. 【机器学习实战】计算两个矩阵的成对距离(pair-wise distances)

    矩阵中每一行是一个样本,计算两个矩阵样本之间的距离,即成对距离(pair-wise distances),可以采用 sklearn 或 scipy 中的函数,方便计算. sklearn: sklear ...

  6. PHP计算两个已知经纬度之间的距离

    /** *求两个已知经纬度之间的距离,单位为千米 *@param lng1,lng2 经度 *@param lat1,lat2 纬度 *@return float 距离,单位千米 **/ privat ...

  7. 基于浏览器的HTML5地理定位

    基于浏览器的HTML5地理定位 地理位置(Geolocation)是 HTML5 的重要特性之一,提供了确定用户位置的功能,借助这个特性能够开发基于位置信息的应用.今天这篇文章向大家介绍一下 HTML ...

  8. php计算两个坐标(经度,纬度)之间距离的方法

    本文实例讲述了php计算两个坐标(经度,纬度)之间距离的方法.分享给大家供大家参考.具体如下: 这里使用php计算两个坐标(经度,纬度)之间的距离,返回结果为米或者千米 function distan ...

  9. Java计算两个字符串日期之间的天数差

    Java计算两个字符串日期之间的天数差 调用方法: public static void main(String[] args) throws ParseException { String a = ...

随机推荐

  1. Mabitis中的#与$符号区别及用法介绍

    这篇文章主要介绍了Mabitis中的 #{}与   ${} 符号区别,需要的朋友可以参考下 一.介绍 mybatis 中使用 Mapper.xml里面的配置进行 sql 查询,经常需要动态传递参数,例 ...

  2. vue中什么是模块 什么是组件?

    模块: 封装好的应用程序,它只是js文件的封装. 组件: 一个完整的单位个体,可以有js可以有css和html. 作者:晋飞翔手机号(微信同步):17812718961希望本篇文章 能给正在学习 前端 ...

  3. [POI2000] 公共串 - 后缀数组,二分

    [POI2000] 公共串 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. Solution 预处理出后缀数组和高度数组,二分答案 \(k\) ,对于每一个连续的 ...

  4. 题解 P4289 【[HAOI2008]移动玩具】

    题目地址:https://www.luogu.com.cn/problem/P4289 题解原地址:https://createsj.blog.luogu.org/solution-p4289 让我们 ...

  5. C#画图超出屏幕的部分无法显示的解决方法

    C#画图超出屏幕的部分无法显示,通过AutoScrollMinSize属性及相关方法解决问题. 可以实现 到 的转变. 代码如下: using System.Drawing; using System ...

  6. c++面向对象 之 内联函数 this 静态成员

    1,内联函数 如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方.用inline指定,内联函数通常短小精悍没有while和for循环,能够帮助提升程序执行的速度 ...

  7. Docker+JMeter单机版+Nginx

    基于JMeter5.1.1+Nginx1.12.2JMeter发起压测  Nginx作为文件服务器 一.目录结构: Dockerfile文件: FROM ubuntu:18.04# 基础镜像 MAIN ...

  8. vue引用fastClick后,ios输入框聚焦不灵敏问题

    fastClick.prototype.focus = function (targetElement) {       targetElement.focus() }

  9. UI组件的学习

    今天继续学习UI的组件知识,包括文本框,编辑框,普通按钮,图片按钮,单选按钮以及复选框组件,今天所学的组件的方法及属性与之前的组件大部分相同. 1. 文本框组件 TextView 文本框组件就是最常见 ...

  10. C++-HDU1394-Minimum Inversion Number[数据结构][树状数组]

    给出0~n-1的一个排列,可以整体移动,求逆序对最小值 把数字num[i]的加入,等价于树状数组的第n-num[i]位加1 因为num[i]是第 (n-1)-num[i]+1=n-num[i]大的数字 ...