구글 지도 V3에서 두 점 사이의 거리를 계산합니다.
Google 지도 V3에서 두 마커 사이의 거리는 어떻게 계산합니까? (마커 V3와 유사함)distanceFrom
기능합니다.)
감사합니다.
직접 계산하려면 Haversine 공식을 사용할 수 있습니다.
var rad = function(x) {
return x * Math.PI / 180;
};
var getDistance = function(p1, p2) {
var R = 6378137; // Earth’s mean radius in meter
var dLat = rad(p2.lat() - p1.lat());
var dLong = rad(p2.lng() - p1.lng());
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) *
Math.sin(dLong / 2) * Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d; // returns the distance in meter
};
GMap3에는 실제로 방법이 있는 것 같습니다.네임스페이스의 정적 방식입니다.
논거로 삼다LatLng
는 기본 지구 반지름 6378137m를 사용합니다.단, 필요한 경우 기본 반지름은 커스텀 값으로 덮어쓸 수 있습니다.
다음 항목을 포함하십시오.
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&v=3&libraries=geometry"></script>
당신의 머리 부분에.
콜은 다음과 같습니다.
google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB);
GPS 위도/경도 2점 사용 예제
var latitude1 = 39.46;
var longitude1 = -0.36;
var latitude2 = 40.40;
var longitude2 = -3.68;
var distance = google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(latitude1, longitude1), new google.maps.LatLng(latitude2, longitude2));
JavaScript 코드의 선두에 다음과 같이 추가합니다.
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);
}
그런 다음 다음과 같은 기능을 사용합니다.
var loc1 = new GLatLng(52.5773139, 1.3712427);
var loc2 = new GLatLng(52.4788314, 1.7577444);
var dist = loc2.distanceFrom(loc1);
alert(dist/1000);
//p1 and p2 are google.maps.LatLng(x,y) objects
function calcDistance(p1, p2) {
var d = (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
console.log(d);
}
이 포럼의 c# 실장은 다음과 같습니다.
public class DistanceAlgorithm
{
const double PIx = 3.141592653589793;
const double RADIO = 6378.16;
/// <summary>
/// This class cannot be instantiated.
/// </summary>
private DistanceAlgorithm() { }
/// <summary>
/// Convert degrees to Radians
/// </summary>
/// <param name="x">Degrees</param>
/// <returns>The equivalent in radians</returns>
public static double Radians(double x)
{
return x * PIx / 180;
}
/// <summary>
/// Calculate the distance between two places.
/// </summary>
/// <param name="lon1"></param>
/// <param name="lat1"></param>
/// <param name="lon2"></param>
/// <param name="lat2"></param>
/// <returns></returns>
public static double DistanceBetweenPlaces(
double lon1,
double lat1,
double lon2,
double lat2)
{
double dlon = Radians(lon2 - lon1);
double dlat = Radians(lat2 - lat1);
double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos(Radians(lat1)) * Math.Cos(Radians(lat2)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
double angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
return (angle * RADIO) * 0.62137;//distance in miles
}
}
구글에서는 구면 api를 사용하여 할 수 있습니다.google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB);
.
그러나 구면 투영이나 해버신 솔루션의 정밀도가 충분하지 않은 경우(예를 들어 극에 가깝거나 더 먼 거리를 계산하는 경우)에는 다른 라이브러리를 사용해야 합니다.
위키피디아에서 찾은 주제에 대한 대부분의 정보는 여기 있습니다.
주어진 알고리즘의 정밀도가 적절한지 여부를 확인하는 방법은 지구의 최대 반지름과 최소 반지름을 채우고 그 차이가 사용 사례에 문제를 일으킬 수 있는지 확인하는 것입니다.자세한 내용은 이 문서에서 확인할 수 있습니다.
결국 구글 api 또는 haversine은 문제없이 대부분의 목적을 달성할 것이다.
PHP 를 사용하면, 다음의 간단한 함수를 사용해 거리를 계산할 수 있습니다.
// 두 위도와 외각 사이의 거리를 계산합니다. 함수 calculate_distance sublat1, $lon1, $lat2, $lon2, $unit='N'){$theta = $lon1 - $lon2;$dist = sin(sin2radglat1) * sin(sin2radglat2) + cos(scos2radglat1) * cos(scos2radglat2);$dist = acosparent dist);$dist = rad2gcdist);$140 = $dist * 60 * 1.1515;$unit = strtoupper unit); ($단위 == "K")의 경우,반품($180*1.609344)} ($단위 == "N") {반품($180*0.8684); } 기타 {$140를 반환한다.}} // 함수는 여기서 끝납니다.
오프라인 솔루션 - Haversine 알고리즘
Javascript에서
var _eQuatorialEarthRadius = 6378.1370;
var _d2r = (Math.PI / 180.0);
function HaversineInM(lat1, long1, lat2, long2)
{
return (1000.0 * HaversineInKM(lat1, long1, lat2, long2));
}
function HaversineInKM(lat1, long1, lat2, long2)
{
var dlong = (long2 - long1) * _d2r;
var dlat = (lat2 - lat1) * _d2r;
var a = Math.pow(Math.sin(dlat / 2.0), 2.0) + Math.cos(lat1 * _d2r) * Math.cos(lat2 * _d2r) * Math.pow(Math.sin(dlong / 2.0), 2.0);
var c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a));
var d = _eQuatorialEarthRadius * c;
return d;
}
var meLat = -33.922982;
var meLong = 151.083853;
var result1 = HaversineInKM(meLat, meLong, -32.236457779983745, 148.69094705162837);
var result2 = HaversineInKM(meLat, meLong, -33.609020205923713, 150.77061469270831);
C#
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var meLat = -33.922982;
double meLong = 151.083853;
var result1 = HaversineInM(meLat, meLong, -32.236457779983745, 148.69094705162837);
var result2 = HaversineInM(meLat, meLong, -33.609020205923713, 150.77061469270831);
Console.WriteLine(result1);
Console.WriteLine(result2);
}
static double _eQuatorialEarthRadius = 6378.1370D;
static double _d2r = (Math.PI / 180D);
private static int HaversineInM(double lat1, double long1, double lat2, double long2)
{
return (int)(1000D * HaversineInKM(lat1, long1, lat2, long2));
}
private static double HaversineInKM(double lat1, double long1, double lat2, double long2)
{
double dlong = (long2 - long1) * _d2r;
double dlat = (lat2 - lat1) * _d2r;
double a = Math.Pow(Math.Sin(dlat / 2D), 2D) + Math.Cos(lat1 * _d2r) * Math.Cos(lat2 * _d2r) * Math.Pow(Math.Sin(dlong / 2D), 2D);
double c = 2D * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1D - a));
double d = _eQuatorialEarthRadius * c;
return d;
}
}
참고 자료: https://en.wikipedia.org/wiki/Great-circle_distance
어쩔 수 없이...액션 스크립트 방식
//just make sure you pass a number to the function because it would accept you mother in law...
public var rad = function(x:*) {return x*Math.PI/180;}
protected function distHaversine(p1:Object, p2:Object):Number {
var R:int = 6371; // earth's mean radius in km
var dLat:Number = rad(p2.lat() - p1.lat());
var dLong:Number = rad(p2.lng() - p1.lng());
var a:Number = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) * Math.sin(dLong/2) * Math.sin(dLong/2);
var c:Number = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d:Number = R * c;
return d;
}
제 경우 SQL Server에서 계산하는 것이 가장 좋았습니다.현재 위치를 파악한 후 현재 위치에서 일정 거리 내에 있는 모든 우편 번호를 검색하고 싶었기 때문입니다.우편번호와 그들의 lat longs 목록이 들어 있는 DB도 가지고 있었다.건배.
--will return the radius for a given number
create function getRad(@variable float)--function to return rad
returns float
as
begin
declare @retval float
select @retval=(@variable * PI()/180)
--print @retval
return @retval
end
go
--calc distance
--drop function dbo.getDistance
create function getDistance(@cLat float,@cLong float, @tLat float, @tLong float)
returns float
as
begin
declare @emr float
declare @dLat float
declare @dLong float
declare @a float
declare @distance float
declare @c float
set @emr = 6371--earth mean
set @dLat = dbo.getRad(@tLat - @cLat);
set @dLong = dbo.getRad(@tLong - @cLong);
set @a = sin(@dLat/2)*sin(@dLat/2)+cos(dbo.getRad(@cLat))*cos(dbo.getRad(@tLat))*sin(@dLong/2)*sin(@dLong/2);
set @c = 2*atn2(sqrt(@a),sqrt(1-@a))
set @distance = @emr*@c;
set @distance = @distance * 0.621371 -- i needed it in miles
--print @distance
return @distance;
end
go
--get all zipcodes within 2 miles, the hardcoded #'s would be passed in by C#
select *
from cityzips a where dbo.getDistance(29.76,-95.38,a.lat,a.long) <3
order by zipcode
//JAVA
public Double getDistanceBetweenTwoPoints(Double latitude1, Double longitude1, Double latitude2, Double longitude2) {
final int RADIUS_EARTH = 6371;
double dLat = getRad(latitude2 - latitude1);
double dLong = getRad(longitude2 - longitude1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(getRad(latitude1)) * Math.cos(getRad(latitude2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return (RADIUS_EARTH * c) * 1000;
}
private Double getRad(Double x) {
return x * Math.PI / 180;
}
Google Distance Matrix 서비스를 사용하면 매우 간단합니다.
첫 번째 단계는 구글 API 콘솔에서 디스턴스 매트릭스 서비스를 활성화하는 것입니다.위치 집합 간의 거리를 반환합니다.그리고 이 간단한 기능을 적용하세요.
function initMap() {
var bounds = new google.maps.LatLngBounds;
var markersArray = [];
var origin1 = {lat:23.0203, lng: 72.5562};
//var origin2 = 'Ahmedabad, India';
var destinationA = {lat:23.0436503, lng: 72.55008939999993};
//var destinationB = {lat: 23.2156, lng: 72.6369};
var destinationIcon = 'https://chart.googleapis.com/chart?' +
'chst=d_map_pin_letter&chld=D|FF0000|000000';
var originIcon = 'https://chart.googleapis.com/chart?' +
'chst=d_map_pin_letter&chld=O|FFFF00|000000';
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 55.53, lng: 9.4},
zoom: 10
});
var geocoder = new google.maps.Geocoder;
var service = new google.maps.DistanceMatrixService;
service.getDistanceMatrix({
origins: [origin1],
destinations: [destinationA],
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, function(response, status) {
if (status !== 'OK') {
alert('Error was: ' + status);
} else {
var originList = response.originAddresses;
var destinationList = response.destinationAddresses;
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = '';
deleteMarkers(markersArray);
var showGeocodedAddressOnMap = function(asDestination) {
var icon = asDestination ? destinationIcon : originIcon;
return function(results, status) {
if (status === 'OK') {
map.fitBounds(bounds.extend(results[0].geometry.location));
markersArray.push(new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: icon
}));
} else {
alert('Geocode was not successful due to: ' + status);
}
};
};
for (var i = 0; i < originList.length; i++) {
var results = response.rows[i].elements;
geocoder.geocode({'address': originList[i]},
showGeocodedAddressOnMap(false));
for (var j = 0; j < results.length; j++) {
geocoder.geocode({'address': destinationList[j]},
showGeocodedAddressOnMap(true));
//outputDiv.innerHTML += originList[i] + ' to ' + destinationList[j] + ': ' + results[j].distance.text + ' in ' + results[j].duration.text + '<br>';
outputDiv.innerHTML += results[j].distance.text + '<br>';
}
}
}
});
}
여기서 origin1은 사용자의 위치이고 destinationA는 destination 위치입니다.둘 이상의 데이터를 추가할 수 있습니다.
예제를 포함한 Rad Full Documentation
/**
* Calculates the haversine distance between point A, and B.
* @param {number[]} latlngA [lat, lng] point A
* @param {number[]} latlngB [lat, lng] point B
* @param {boolean} isMiles If we are using miles, else km.
*/
function haversineDistance(latlngA, latlngB, isMiles) {
const squared = x => x * x;
const toRad = x => (x * Math.PI) / 180;
const R = 6371; // Earth’s mean radius in km
const dLat = toRad(latlngB[0] - latlngA[0]);
const dLon = toRad(latlngB[1] - latlngA[1]);
const dLatSin = squared(Math.sin(dLat / 2));
const dLonSin = squared(Math.sin(dLon / 2));
const a = dLatSin +
(Math.cos(toRad(latlngA[0])) * Math.cos(toRad(latlngB[0])) * dLonSin);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
let distance = R * c;
if (isMiles) distance /= 1.609344;
return distance;
}
80% 정확하지만 잘못된 파라미터를 삽입하여 입력 사용에 일관성이 없는 버전을 온라인에서 찾았습니다.이 버전은 완전히 수정되었습니다.
Google 지도에서 거리를 계산하기 위해 길찾기 API를 사용할 수 있습니다.그게 가장 쉬운 방법 중 하나일 거예요.Google Server에서 데이터를 가져오려면 Retrofit 또는 Balley를 사용할 수 있습니다.둘 다 장점이 있어요.개조를 사용하여 구현한 다음 코드를 살펴보십시오.
private void build_retrofit_and_get_response(String type) {
String url = "https://maps.googleapis.com/maps/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitMaps service = retrofit.create(RetrofitMaps.class);
Call<Example> call = service.getDistanceDuration("metric", origin.latitude + "," + origin.longitude,dest.latitude + "," + dest.longitude, type);
call.enqueue(new Callback<Example>() {
@Override
public void onResponse(Response<Example> response, Retrofit retrofit) {
try {
//Remove previous line from map
if (line != null) {
line.remove();
}
// This loop will go through all the results and add marker on each location.
for (int i = 0; i < response.body().getRoutes().size(); i++) {
String distance = response.body().getRoutes().get(i).getLegs().get(i).getDistance().getText();
String time = response.body().getRoutes().get(i).getLegs().get(i).getDuration().getText();
ShowDistanceDuration.setText("Distance:" + distance + ", Duration:" + time);
String encodedString = response.body().getRoutes().get(0).getOverviewPolyline().getPoints();
List<LatLng> list = decodePoly(encodedString);
line = mMap.addPolyline(new PolylineOptions()
.addAll(list)
.width(20)
.color(Color.RED)
.geodesic(true)
);
}
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
위는 거리 계산을 위한 함수 build_retrofit_and_get_response의 코드입니다.다음은 해당 Retrofit 인터페이스입니다.
package com.androidtutorialpoint.googlemapsdistancecalculator;
import com.androidtutorialpoint.googlemapsdistancecalculator.POJO.Example;
import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Query;
public interface RetrofitMaps {
/*
* Retrofit get annotation with our URL
* And our method that will return us details of student.
*/
@GET("api/directions/json?key=AIzaSyC22GfkHu9FdgT9SwdCWMwKX1a4aohGifM")
Call<Example> getDistanceDuration(@Query("units") String units, @Query("origin") String origin, @Query("destination") String destination, @Query("mode") String mode);
}
이것이 당신의 질문을 설명해 주길 바랍니다.행운을 빈다 :)
첫째, 전체 경로의 길이와 같은 거리를 말하는 것입니까, 아니면 변위(직선 거리)만 알고 싶은 것입니까?아무도 거리와 변위의 차이를 지적하지 않는군요. 데이터에 주어진 각 에는, 는, JSON/XML 를 사용한 이 있습니다.Spherical
표시
//calculates distance between two points in km's
function calcDistance(p1, p2) {
return (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
}
언급URL : https://stackoverflow.com/questions/1502590/calculate-distance-between-two-points-in-google-maps-v3
'programing' 카테고리의 다른 글
MySql에 대한 Java 길이 (0) | 2023.01.31 |
---|---|
명령줄 경유로 csv를 mysql로 Import (0) | 2023.01.31 |
순서가 매겨지지 않은 두 리스트가 동일한지 확인합니다. (0) | 2023.01.31 |
팬더에서 데이터 프레임의 처음 세 행을 삭제합니다. (0) | 2023.01.31 |
창 크기 조정 시 v-navigation이 런어웨이 루프로 떨어짐 (0) | 2023.01.31 |