要知道坐标点是否在两个其他坐标之间。
我正在制作一个谷歌地图应用程序,我需要知道某个点是否在两个LatLng点之间(开始和结束)。
我正在寻找以下功能:
var currentCoord = {lat: 51.8732, lng: -118.6346};
var startCoord = {lat: 61.3434, lng: -118.0046};
var endCoord = {lat: 50.5468, lng: -118.5435};
function isBetween(startCoord, endCoord, currentCoord){
//calculations here
return "true if currentCoord is between startCoord and endCoord, or false otherwise";
}
为实现这一目标,我读了几个问题和主题:
if
陈述。无论我尝试什么,我都无法让它发挥作用,但我的失败实验确实有一个很小的例子:
"use strict";
/*global google*/
function initialize() {
let mapOptions = {
zoom: 3,
center: new google.maps.LatLng(0, -180),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
let map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
let flightPlanCoordinates = [
new google.maps.LatLng(37.772323, -122.214897),
new google.maps.LatLng(21.291982, -157.821856),
new google.maps.LatLng(-18.142599, 178.431),
new google.maps.LatLng(-27.46758, 153.027892)
];
let flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(map);
google.maps.event.addListener(flightPath, 'mouseover', function(event) {
console.log("Marker is over the polyline");
});
let marker = new google.maps.Marker({
position: new google.maps.LatLng(37.772323, -122.214897),
draggable: true,
map: map,
title: 'Drag me!'
});
marker.addListener('drag', function(event) {
let startPoint = {
lat: 37.772323,
lng: -122.214897
};
let endPoint = {
lat: 21.291982,
lng: -157.821856
};
let currentPoint = {
lat: marker.getPosition().lat(),
lng: marker.getPosition().lng()
};
if (checkCoordinate(startPoint, endPoint, currentPoint))
console.log("in line !");
});
}
google.maps.event.addDomListener(window, 'load', initialize);
function checkCoordinate(start, end, point) {
var slope = (end.lng - start.lng) / (end.lat - start.lat);
var newSlope = (end.lng - point.lng) / (end.lat - point.lat);
return (point.lat > start.lat && point.lat < end.lat && point.lng > start.lng && point.lng < end.lng && slope == newSlope);
}
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Simple Polylines</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<script src="script.js" type="text/javascript"></script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
答案 0 :(得分:2)
一种选择是使用google.maps.geometry.poly.isLocationOnEdge方法。
代码段
var map;
function initialize() {
var mapOptions = {
zoom: 2,
center: new google.maps.LatLng(0, -180),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var flightPlanCoordinates = [
new google.maps.LatLng(37.772323, -122.214897),
new google.maps.LatLng(21.291982, -157.821856),
new google.maps.LatLng(-18.142599, 178.431),
new google.maps.LatLng(-27.46758, 153.027892)
];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: false,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(map);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(37.772323, -122.214897),
draggable: true,
map: map,
title: 'Drag me!'
});
marker.addListener('dragend', function(event) {
var startPoint = {
lat: 37.772323,
lng: -122.214897
};
var startMarker = new google.maps.Marker({
position: startPoint,
map: map
});
var endPoint = {
lat: 21.291982,
lng: -157.821856
};
var endMarker = new google.maps.Marker({
position: endPoint,
map: map
});
var currentPoint = {
lat: marker.getPosition().lat(),
lng: marker.getPosition().lng()
};
if (checkCoordinate(startPoint, endPoint, marker.getPosition()))
console.log("in line !");
});
}
google.maps.event.addDomListener(window, 'load', initialize);
function checkCoordinate(start, end, point) {
return google.maps.geometry.poly.isLocationOnEdge(point, new google.maps.Polyline({
map: map,
path: [start, end]
}), 10e-1);
}
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Simple Polylines</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<script src="script.js" type="text/javascript"></script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
答案 1 :(得分:0)
通过计算一个点是否属于一条线,我已经找到了解决方案。
在研究了许多数学原理之后,我决定计算两点之间矩阵的行列式,并检查(具有一定的精度)我的给定点是否在点A和B之间。
/**
* @const
* @type {Number}
* @description The precision to calculate if a given point is between two other points. Low precisions get precise results but are less forgiving against errors.
*/
const PRECISION = 1;
/**
* @function isBetween
* @description Determines if a point P = (p.x, p.y) lies on the line connecting points S = (S.x, S.y) and E = (E.x, E.y) by calculating the determinant of the matrix. A point is considered to belong to the line if the precision of the calculation is small enough (tests for errors and loss of precision).
* @param {Point} start The start point
* @param {Point} end The end point
* @param {Point} point The point we which to test.
* @returns <code>true</code> if the given point belongs to the line, <code>false</code> otherwise.
* @see {@link http://stackoverflow.com/a/907491/1337392|Distance Matrix Calculation}
*/
function isBetween(start, end, point) {
return Math.abs((end.lat - start.lat) * (point.lng - start.lng) - (end.lng - start.lng) * (point.lat - start.lat)) < PRECISION;
}
然而,这个解决方案有一个值得一提的陷阱。该解决方案的问题在于它没有考虑地球的曲率。它只适用于直线。
所以,如果你要检查你镇上的距离,这根本不可能是重要的。但是如果你正在检查穿越太平洋的航班,你应该使用另一种数学方法。
由于这个原因,并且由于折线已经考虑了地球的曲率,我决定使用geocodezip的答案。
PS:我不得不说这很有趣。几个小时前,我回答了一个老问题,我也感谢geocodezip给出的深刻见解,现在他在这里,回答我的问题。有时,我确实相信世界是一个小地方。谢谢你!
答案 2 :(得分:0)
使用上述http://www.movable-type.co.uk/scripts/latlong.html页面中的方位部分,您只需检查
即可bearing(from currentCoord to startCoord) =
bearing(from currentCoord to endCoord) +/- 180 (with some tolerance)
这个等式表示所有三个点都位于同一个大圆弧上
(我假设你的“在两个其他坐标之间”具有相同的含义)