2014-10-29 14 views
1

我使用從谷歌地圖的google.maps.geometry.spherical.computeHeading法計算的JS一個Polygon路徑標題的標題。谷歌地圖計算平分兩個已知標題

我想要做的是計算的標題正是其中每兩個標題之間。

例如,如果第一軌跡的方位是45和第二是135,我想找的標題應當是90或者,如果第一個標題是350,第二個是90,在標題I」找的是40

我知道我在這裏失去了一些基本的幾何形狀(從不擅長在學校數學),但我希望有人能指出我在正確的方向。

此外,如果任何人都更優雅的方法來獲取一個多邊形的兩個路徑之間的航向的人都知道,我很開放的建議。

UPDATE:

我居然找到了一種方法來解決我的問題。這不是很優雅,但它與建議的SO之前的問題中的答案非常相似。

/* 
    * h1 = first heading 
    * h2 = second heading 
    * 
    */ 
    if (h1 < 0) { 
    h1 = 360 - Math.abs(h1); 
    } 

    h2 = (h2 >= 180) ? h2 - 180 : h2 + 180; 

    // get average of both headings (i.e. the middle) 
    bisect = ((h2 + h1)/2); 

    // if bisect is > than the h1, we need the inverse 
    if (bisect > h1) { 
    bisect = bisect -180; 
    } 
+0

什麼是你的代碼是什麼樣子? – geocodezip 2014-10-29 22:33:28

+0

[如何計算谷歌地圖上兩條路徑線之間使用經緯度座標的角度]的可能重複(http://stackoverflow.com/questions/24045510/how-to-calculate-angle-between-two-path-lines -on-google-map-using-lat-long-coord) – 2014-10-29 22:36:41

+1

爲什麼第二個角度50?它不應該是40嗎? – geocodezip 2014-10-29 22:47:24

回答

2

基本答案:

保持所有的數字在-180到+180的範圍,計算的最短距離(將小於180; 180是一個特例,它有兩個答案,無論是垂直於該線的方向)

假設中心標記在兩條線的公共點,angle1marker和angle2marker使從該點線。

var hdg1 = google.maps.geometry.spherical.computeHeading(centerMark.getPosition(), angle1marker.getPosition()); 
var hdg2 = google.maps.geometry.spherical.computeHeading(centerMark.getPosition(), angle2marker.getPosition()); 
if (hdg1 > 180) hdg1 -= 360; 
if (hdg1 <= -180) hdg1 += 360; 
if (hdg2 > 180) hdg2 -= 360; 
if (hdg2 <= -180) hdg2 += 306; 

var deltaHdg = (hdg1 - hdg2); 
if (deltaHdg > 180) deltaHdg -= 360; 
if (deltaHdg <= -180) deltaHdg += 360; 

var bisectHdg = deltaHdg/2 + hdg2; 
var bisectPosn = google.maps.geometry.spherical.computeOffset(centerMark.getPosition(), 1000, bisectHdg); 

代碼片段:

var map; 
 
var infowindow = new google.maps.InfoWindow(); 
 
var bisectLine = null; 
 
var bisectMark = null; 
 
var centerMark = null; 
 
var angle1marker = null; 
 
var angle2marker = null; 
 

 
function initialize() { 
 
    geocoder = new google.maps.Geocoder(); 
 
    var latlng = new google.maps.LatLng(-34.397, 150.644); 
 
    var mapOptions = { 
 
    zoom: 15, 
 
    center: latlng 
 
    } 
 
    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); 
 

 
    centerMark = new google.maps.Marker({ 
 
    map: map, 
 
    position: map.getCenter() 
 
    }); 
 
    angle1marker = new google.maps.Marker({ 
 
    map: map, 
 
    draggable: true, 
 
    position: google.maps.geometry.spherical.computeOffset(map.getCenter(), 1000, 45) 
 
    }); 
 
    google.maps.event.addListener(angle1marker, 'dragend', bisectAngle); 
 

 
    angle2marker = new google.maps.Marker({ 
 
    map: map, 
 
    draggable: true, 
 
    position: google.maps.geometry.spherical.computeOffset(map.getCenter(), 1000, 30) 
 
    }); 
 
    google.maps.event.addListener(angle2marker, 'dragend', bisectAngle); 
 

 
    var poly1 = new google.maps.Polyline({ 
 
    path: [centerMark.getPosition(), angle1marker.getPosition()], 
 
    map: map 
 
    }); 
 
    poly1.binder = new MVCArrayBinder(poly1.getPath()); 
 
    angle1marker.bindTo('position', poly1.binder, '1'); 
 

 
    var poly2 = new google.maps.Polyline({ 
 
    path: [centerMark.getPosition(), angle2marker.getPosition()], 
 
    map: map 
 
    }); 
 
    poly2.binder = new MVCArrayBinder(poly2.getPath()); 
 
    angle2marker.bindTo('position', poly2.binder, '1'); 
 

 
    var bounds = new google.maps.LatLngBounds(); 
 
    bounds.extend(centerMark); 
 
    bounds.extend(angle1marker); 
 
    bounds.extend(angle2marker); 
 

 
    map.fitBounds(bounds); 
 
} 
 
google.maps.event.addDomListener(window, 'load', initialize); 
 

 
function bisectAngle() { 
 
    var hdg1 = google.maps.geometry.spherical.computeHeading(centerMark.getPosition(), angle1marker.getPosition()); 
 
    var hdg2 = google.maps.geometry.spherical.computeHeading(centerMark.getPosition(), angle2marker.getPosition()); 
 
    if (hdg1 > 180) hdg1 -= 360; 
 
    if (hdg1 <= -180) hdg1 += 360; 
 
    if (hdg2 > 180) hdg2 -= 360; 
 
    if (hdg2 <= -180) hdg2 += 306; 
 

 
    var deltaHdg = (hdg1 - hdg2); 
 
    if (deltaHdg > 180) deltaHdg -= 360; 
 
    if (deltaHdg <= -180) deltaHdg += 360; 
 
    var bisectHdg = deltaHdg/2 + hdg2; 
 
    document.getElementById('info').innerHTML = "a1=" + hdg1.toFixed(2) + ", a2=" + hdg2.toFixed(2) + ", bA=" + bisectHdg.toFixed(2); 
 
    var bisectPosn = google.maps.geometry.spherical.computeOffset(centerMark.getPosition(), 1000, bisectHdg); 
 
    if (bisectMark && bisectMark.setMap) { 
 
    // bisectMark.setMap(null); 
 
    bisectMark.setPosition(bisectPosn); 
 
    } else { 
 
    bisectMark = new google.maps.Marker({ 
 
     position: bisectPosn, 
 
     map: map 
 
    }); 
 
    } 
 
    if (bisectLine && bisectLine.setMap) { 
 
    // bisectLine.setMap(null); 
 
    bisectLine.setPath([centerMark.getPosition(), bisectPosn]); 
 
    } else { 
 
    bisectLine = new google.maps.Polyline({ 
 
     path: [centerMark.getPosition(), bisectPosn], 
 
     map: map 
 
    }); 
 
    } 
 
} 
 

 
/* 
 
* Use bindTo to allow dynamic drag of markers to refresh poly. 
 
*/ 
 

 
function MVCArrayBinder(mvcArray) { 
 
    this.array_ = mvcArray; 
 
} 
 
MVCArrayBinder.prototype = new google.maps.MVCObject(); 
 
MVCArrayBinder.prototype.get = function(key) { 
 
    if (!isNaN(parseInt(key))) { 
 
    return this.array_.getAt(parseInt(key)); 
 
    } else { 
 
    this.array_.get(key); 
 
    } 
 
} 
 
MVCArrayBinder.prototype.set = function(key, val) { 
 
    if (!isNaN(parseInt(key))) { 
 
    this.array_.setAt(parseInt(key), val); 
 
    } else { 
 
    this.array_.set(key, val); 
 
    } 
 
}
html, 
 
body, 
 
#map-canvas { 
 
    height: 100%; 
 
    width: 100%; 
 
    margin: 0px; 
 
    padding: 0px 
 
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry&ext=.js"></script> 
 
<div id="info"></div> 
 
<div id="map-canvas"></div>

+0

偉人......你太好了...... – 2016-05-30 07:11:17

+0

你的代碼運行良好。但是移動中心標記是不可能的。將其更改爲可拖動時 - 可以移動。但是,只有平分線會正確更新。角線將繼續「記住」地圖中心作爲起點。無法弄清楚爲什麼。 – Guy 2017-06-21 06:51:48

+0

我注意到,添加'centerMark.bindTo('position',poly1.binder,'0');'幫助,更新兩行中的一行。但不可能添加'centerMark.bindTo('position',poly2.binder,'0');'以使兩行更新。 – Guy 2017-06-21 07:58:08