2012-04-19 11 views
2

こんにちは、みんな、Google Maps API V3を使用して、デフォルトの開始点から所定の距離にある線を描画しようとしています。たとえば、私のデフォルトの出発点がサンフランシスコで、ユーザーが距離を入力したとすると、私はその入力距離に基づいて米国を横切って東に向かって直線を描きたいと思っています。私はベアリングと呼ばれるこの事に出くわしましたが、それを正しく使う方法がわかりません。ここでは、私が作業しているコードです:指定された距離の線を描く - Google Maps

function initializeMap(){ 

var mapOptions = { 
center: new google.maps.LatLng(36.033036, -93.8655744), 
zoom: 4, 
mapTypeId: google.maps.MapTypeId.ROADMAP 
}; 

var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions); 

var R = 6378137; 
var dis = parseInt(document.form['input']['val'].value); 
var bearing = 80; 
var lat2 = Math.asin( Math.sin(37.470625)*Math.cos(dis/R)+Math.cos(37.470625)*Math.sin(dis/R)*Math.cos(bearing)); 
var lon2 = -122.266823 + Math.atan2(Math.sin(bearing)*Math.sin(dis/R)*Math.cos(37.470625),Math.cos(dis/R)-Math.sin(37.470625)*Math.sin(-122.266823)); 


var impactP = new google.maps.Polyline({ 
    path: new google.maps.LatLng(lat2,lon2), 
       strokeColor: "#FF0000", 
    strokeOpacity: 1.0, 
      strokeWeight: 2 
     }); 
impactP.setMap(map); 
} 

誰かが私を助けてください。私は本当にこれを働かせたい。

+0

https://raw.githubusercontent.com/chrisveness/geodesy/master/latlon-spherical.jsからrhumbDestinationPointを貼り付けました。私が理解していない数学であるGoogle Mapsの部分を手伝うことができます。 37.470625と-122.266823を変数に置き換えることをお勧めします。それらはあなたの目的地を潜んでいますか?私はあなたのコードをいくつか変更して、マップセンターからこの計算lat2、lon2に線を描画しました。 http://jsfiddle.net/X25dZ/ –

+0

基本的に私は、ユーザーが離れて入力できるようにしたい。私はこの距離のGoogleマップに線を描画したいが、私のデフォルトの出発点の東にしか描画したくない。だから本質的に私はサンフランシスコに出発点を欲しいので、私はアメリカの向こうに描かれる線を持っています。難しいのは、明示的に終点を持っていないということです。私はデフォルトの開始点と行の距離しか持っていません。だから、例えば最後に私の地図はこのようになります:http://jsfiddle.net/X25dZ/1/ – cclerville

答えて

0

私はhttp://jsfiddle.net/khwLd/を足場Googleマップに置くが、私の数学は、あなたが行が南にオフに向きを変える見ることができます:(オフになっている。「ベアリングと距離を与え、端末座標を見つける」をグーグルで私のpython関数を与えました私は、変換され、チェックが、まだ期待される結果を与えていない

Calculating coordinates given a bearing and a distance

あなたがする必要がどのように最初にすべての数学を修正している:。

getDestination(origin_lat, origin_lng, bearing, distance)のリターンgoogle.maps.LatLng(destination_lat, destination_lng)

は申し訳ありませんが、私はすべてここで説明されて完全に動作するソリューション:(

+0

これは私を大いに助けました。ありがとう! – cclerville

2

数学を生産することができませんでした:http://www.movable-type.co.uk/scripts/latlong.html#destPoint

var lat2 = Math.asin(Math.sin(lat1)*Math.cos(d/R) + 
       Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng)); 
var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1), 
        Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2)); 

注意lat1,lon1こと(あなたの出発点)とlat2,lon2(終点)はラジアン度ではありません。 dは移動距離、Rは地球の半径です。これらは、両方が同じユニットである限り、任意のユニットにすることができます。

ラジアンで作業すると問題のコードがうまくいくようです。

北半球で90度のベアリングを始めると、南向きになります(最終ベアリングは90度以上になります)。球状のジオメトリは素晴らしいことです!

一定のベアリングラインが必要な場合は、マップ上で90度線が直線で水平になるようにするには、Rhumb線:http://www.movable-type.co.uk/scripts/latlong.html#rhumblinesが必要です。これははるかに複雑ですが、このページでも距離とベアリングからエンドポイントを計算し、必要な数学とJavascriptについて説明しています。

/** Converts numeric degrees to radians */ 
if (typeof(Number.prototype.toRad) === "undefined") { 
    Number.prototype.toRad = function() { 
    return this * Math.PI/180; 
    } 
} 

/** Converts radians to numeric (signed) degrees */ 
if (typeof(Number.prototype.toDeg) === "undefined") { 
    Number.prototype.toDeg = function() { 
    return this * 180/Math.PI; 
    } 
} 

したがって(78).toRad()1.3613568ある:


同じページが再び度からラジアンに変換し、数字にメソッドを追加することを示唆しています。

0

あなたがここにもhttp://www.movable-type.co.uk/scripts/latlong.html

rhumbDestinationPointを参照してください、クリスVenessにより、ライブラリhttps://github.com/chrisveness/geodesyからメソッドrhumbDestinationPointを使用することができますがLatLonオブジェクトに適用し、六十進法でベアリングメートルに及び2番目の引数として最初の引数として距離をとるれますすなわち0は北、90は東、180は南、270は西です。

私はちょうど私はあなたがやろうとしている正確に何についてのより多くの情報が必要(OP http://jsfiddle.net/X25dZ/1/から適応)以下のスニペット

function initializeMap() { 
 
    mapCenter = new google.maps.LatLng(36.033036, -93.8655744); 
 
    defaultStart = new google.maps.LatLng(37.470625, -122.266823); 
 
    var mapOptions = { 
 
    center: mapCenter, 
 
    zoom: 2, 
 
    mapTypeId: google.maps.MapTypeId.ROADMAP 
 
    }; 
 

 
    var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions); 
 

 
    var distance_in_meter = 600000; 
 
    var bearing = 90; 
 

 
    var start = new LatLon(defaultStart.lat(), defaultStart.lng()); 
 
    var destination = start.rhumbDestinationPoint(distance_in_meter, bearing); 
 

 
    var impactP = new google.maps.Polyline({ 
 
    map: map, 
 
    path: [defaultStart, 
 
     new google.maps.LatLng(destination.lat, destination.lon) 
 
    ], 
 
    strokeColor: "#FF0000", 
 
    strokeOpacity: 1.0, 
 
    strokeWeight: 2 
 
    }); 
 
} 
 

 
google.maps.event.addDomListener(window, 'load', initializeMap);
html { 
 
    height: 100% 
 
} 
 
body { 
 
    height: 100%; 
 
    margin: 0; 
 
    padding: 0 
 
} 
 
#map-canvas { 
 
    height: 100% 
 
} 
 
#menu { 
 
    position: absolute; 
 
    top: 0px; 
 
    left: 0px; 
 
    padding: 0px; 
 
    font-family: Arial, sans-serif; 
 
}
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> 
 

 

 
<script type="text/javascript"> 
 
// Taken from https://raw.githubusercontent.com/chrisveness/geodesy/master/latlon-spherical.js \t 
 
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
 
/* Latitude/longitude spherical geodesy tools       (c) Chris Veness 2002-2016 */ 
 
/*                     MIT Licence */ 
 
/* www.movable-type.co.uk/scripts/latlong.html             */ 
 
/* www.movable-type.co.uk/scripts/geodesy/docs/module-latlon-spherical.html      */ 
 
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
 
'use strict'; 
 
if (typeof module!='undefined' && module.exports) var Dms = require('./dms'); // ≡ import Dms from 'dms.js' 
 
/** 
 
* Library of geodesy functions for operations on a spherical earth model. 
 
* 
 
* @module latlon-spherical 
 
* @requires dms 
 
*/ 
 
/** 
 
* Creates a LatLon point on the earth's surface at the specified latitude/longitude. 
 
* 
 
* @constructor 
 
* @param {number} lat - Latitude in degrees. 
 
* @param {number} lon - Longitude in degrees. 
 
* 
 
* @example 
 
*  var p1 = new LatLon(52.205, 0.119); 
 
*/ 
 
function LatLon(lat, lon) { 
 
// allow instantiation without 'new' 
 
if (!(this instanceof LatLon)) return new LatLon(lat, lon); 
 
this.lat = Number(lat); 
 
this.lon = Number(lon); 
 
} 
 

 
/** 
 
* Returns the destination point having travelled along a rhumb line from ‘this’ point the given 
 
* distance on the given bearing. 
 
* 
 
* @param {number} distance - Distance travelled, in same units as earth radius (default: metres). 
 
* @param {number} bearing - Bearing in degrees from north. 
 
* @param {number} [radius=6371e3] - (Mean) radius of earth (defaults to radius in metres). 
 
* @returns {LatLon} Destination point. 
 
* 
 
* @example 
 
*  var p1 = new LatLon(51.127, 1.338); 
 
*  var p2 = p1.rhumbDestinationPoint(40300, 116.7); // 50.9642°N, 001.8530°E 
 
*/ 
 
LatLon.prototype.rhumbDestinationPoint = function(distance, bearing, radius) { 
 
radius = (radius === undefined) ? 6371e3 : Number(radius); 
 
var δ = Number(distance)/radius; // angular distance in radians 
 
var φ1 = this.lat.toRadians(), λ1 = this.lon.toRadians(); 
 
var θ = Number(bearing).toRadians(); 
 
var Δφ = δ * Math.cos(θ); 
 
var φ2 = φ1 + Δφ; 
 
// check for some daft bugger going past the pole, normalise latitude if so 
 
if (Math.abs(φ2) > Math.PI/2) φ2 = φ2>0 ? Math.PI-φ2 : -Math.PI-φ2; 
 
var Δψ = Math.log(Math.tan(φ2/2+Math.PI/4)/Math.tan(φ1/2+Math.PI/4)); 
 
var q = Math.abs(Δψ) > 10e-12 ? Δφ/Δψ : Math.cos(φ1); // E-W course becomes ill-conditioned with 0/0 
 
var Δλ = δ*Math.sin(θ)/q; 
 
var λ2 = λ1 + Δλ; 
 
return new LatLon(φ2.toDegrees(), (λ2.toDegrees()+540) % 360 - 180); // normalise to −180..+180° 
 
}; 
 

 

 
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
 
/** 
 
* Checks if another point is equal to ‘this’ point. 
 
* 
 
* @param {LatLon} point - Point to be compared against this point. 
 
* @returns {bool} True if points are identical. 
 
* 
 
* @example 
 
* var p1 = new LatLon(52.205, 0.119); 
 
* var p2 = new LatLon(52.205, 0.119); 
 
* var equal = p1.equals(p2); // true 
 
*/ 
 
LatLon.prototype.equals = function(point) { 
 
if (!(point instanceof LatLon)) throw new TypeError('point is not LatLon object'); 
 
if (this.lat != point.lat) return false; 
 
if (this.lon != point.lon) return false; 
 
return true; 
 
}; 
 
/** 
 
* Returns a string representation of ‘this’ point, formatted as degrees, degrees+minutes, or 
 
* degrees+minutes+seconds. 
 
* 
 
* @param {string} [format=dms] - Format point as 'd', 'dm', 'dms'. 
 
* @param {number} [dp=0|2|4] - Number of decimal places to use - default 0 for dms, 2 for dm, 4 for d. 
 
* @returns {string} Comma-separated latitude/longitude. 
 
*/ 
 
LatLon.prototype.toString = function(format, dp) { 
 
return Dms.toLat(this.lat, format, dp) + ', ' + Dms.toLon(this.lon, format, dp); 
 
}; 
 
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
 
/** Extend Number object with method to convert numeric degrees to radians */ 
 
if (Number.prototype.toRadians === undefined) { 
 
Number.prototype.toRadians = function() { return this * Math.PI/180; }; 
 
} 
 
/** Extend Number object with method to convert radians to numeric (signed) degrees */ 
 
if (Number.prototype.toDegrees === undefined) { 
 
Number.prototype.toDegrees = function() { return this * 180/Math.PI; }; 
 
} 
 
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
 
if (typeof module != 'undefined' && module.exports) module.exports = LatLon; // ≡ export default LatLon </script> 
 

 

 
<div id="map-canvas"></div>

関連する問題