Google地图会计算一个标题,它将两个已知标题平分 [英] Google Maps calculate a heading which bisects two known headings

查看:76
本文介绍了Google地图会计算一个标题,它将两个已知标题平分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Google地图中的 google.maps.geometry.spherical.computeHeading 方法来计算 Polygon in JS。



我想要做的是计算两个标题之间精确的标题。



例如,如果第一个路径的标题是45而第二个是135,那么我要查找的标题应该是90.或者如果第一个标题是350,第二个是90,我要找的标题是40。



我知道我在这里缺少一些基本的几何图形(从来不擅长数学),但我会感谢任何人都能指出我正确的方向。



另外,如果有人知道更优雅的方法来获取多边形的两个路径之间的标题,我很乐意提供建议。



更新:

解决我的问题的方法。这不是很优雅,但它与建议的SO以前的问题中的答案非常相似。

  / * 
* h1 =第一个标题
* h2 =第二个标题
*
* /
if(h1 <0){
h1 = 360 - Math.abs(h1) ;
}

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

//得到两个标题(即中间)的平均值
bisect =((h2 + h1)/ 2);

//如果bisect>> (bisect> h1){
bisect = bisect -180;


解决方案

基本答案:



将所有数字保持在-180至+180范围内,计算最短距离(将小于180; 180是特殊情况,它有两个答案,两个方向垂直)假设centerMark位于两条线的共同点,angle1marker和angle2marker就是从这一点开始的线。


$ b


b

  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(中心标记); bounds.extend(angle1marker); bounds.extend(angle2marker); google.maps.event.addDomListener(window,'load',initialize);函数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;如果(hdg2 <= -180)hdg2 + = 306; var deltaHdg =(hdg1  -  hdg2);如果(deltaHdg> 180)deltaHdg = 360;如果(deltaHdg≤-180)deltaHdg + = 360; var bisectHdg = deltaHdg / 2 + hdg2; innerHTML =a1 =+ hdg1.toFixed(2)+,a2 =+ hdg2.toFixed(2)+,bA =+ bisectHdg.toFixed(2); document.getElementById('info')。 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}); }} / * *使用bindTo允许动态拖动标记来刷新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%;宽度:100%; margin:0px; < script src =https://

I am using the google.maps.geometry.spherical.computeHeading method from Google Maps to calculate headings of paths of a Polygon in JS.

What I want to do is calculate the heading which exactly between each two headings.

For example, if the heading of the first path is 45 and the second is 135, the heading I'm looking for should be 90. Or if the first heading is 350 and the second is 90, the heading I'm looking for is 40.

I know I'm missing some basic geometry here (was never good at math in school), but I would appreciate anyone able to point me in the right direction.

Additionally if anyone knows of a more elegant method to get the heading between two paths of a polygon, I am open to suggestions.

UPDATE:

I actually found a way to solve my problem. It's not very elegant but it is very similar to the answer in the suggested SO previous question.

  /*
   * 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;
  }

解决方案

Basic answer:

keep all your numbers in the range -180 to +180, calculate the shortest distance (will be less than 180; 180 is a special case, it has two answers, both directions perpendicular to that line)

assuming centerMark at the common point of the two lines, angle1marker and angle2marker make lines from that point.

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);

code snippet:

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>

这篇关于Google地图会计算一个标题,它将两个已知标题平分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆