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

问题描述

我使用Google地图中的

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地图会计算一个标题,它将两个已知标题平分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 13:47