一切就绪!

着手开发前,请先阅读我们的开发者文档

激活 Google Maps JavaScript API

为帮助您起步,我们将引导您在 Google Developers Console 中先完成几项任务:

  1. 创建或选择项目
  2. 激活 Google Maps JavaScript API 及相关服务
  3. 创建相应密钥
继续

Geometry 库

  1. 概览
  2. 球面几何学概念
    1. 距离和面积函数
    2. 导航函数
  3. 几何形状编码
  4. 多边形和折线函数
    1. containsLocation()
    2. isLocationOnEdge()

概览

此文档内的概念仅指 google.maps.geometry 库内提供的功能。此库不会在您加载 Maps Javascript API 时默认加载,而必须通过使用 libraries 引导程序参数显式指定。

如需了解详细信息,请参阅内容库概览

Google Maps JavaScript API Geometry 库提供诸多实用函数用于计算地球表面上的几何数据。此库包含三个命名空间:

  • spherical:其中包含球面几何学实用程序,让您能够根据纬度和经度计算角度、距离和面积
  • encoding:其中包含用于根据编码折线算法对折线路径进行编码和解码的实用程序
  • poly:其中包含用于涉及多边形和折线的计算的实用函数

google.maps.geometry 库不包含任何类;而是包含有关上述命名空间的静态方法。

球面几何学概念

Google Maps JavaScript API 内的图像是二维的“平面”图像。不过,地球是三维的,通常近似于一个扁球面,或者更像一个球面。在 Maps API 内,我们使用球面并在二维平面(例如您的计算机屏幕)上以其表示地球 – Maps API 使用投影

在二维投影中,外观有时可能会欺人眼目。由于地图投影必定会导致部分失真,因此简单的欧几里得几何通常并不适用。例如,球面上两点之间最短的距离不是直线,而是一个大圆(一种测地线),而且构成球面表面上三角形的角度之和超过 180 度。

由于这些差异,球面上(或其投影上)的几何函数必须使用球面几何学计算距离、航向和面积等构造。计算这些球面几何构造的实用程序包含在 Maps API 的google.maps.geometry.spherical 命名空间内。此命名空间提供用于根据球面坐标(纬度和经度)计算标量值的静态方法。

距离和面积函数

两点之间的距离是指两点之间最短路径的长度。最短的路径称为测地线。在一个球面上,所有测地线均是大圆的分段。要计算此距离,请调用 computeDistanceBetween(),并向其传递两个 LatLng 对象。

如果您有多个位置,则可改用 computeLength() 来计算某给定路径的长度。

距离结果以米表示。

要计算一个多边形区域的面积(以平方米为单位),请调用 computeArea(),并向其传递 LatLng 对象数组用于一个定义一个闭环。

在球面上导航时,航向是指某方向与某固定参考点(通常为正北方)的角度。在 Google Maps API 中,航向通常以与正北方的角度来定义,以正北方(0 度)顺时针测量航向。您可以使用 computeHeading() 方法并向其传递两个 fromto LatLng 对象来计算两个位置之间的此航向。

在给定特定航向、起点和行程距离(以米为单位)条件下,您可以使用 computeOffset() 计算终点坐标。

在给定两个 LatLng 对象且值在 0 和 1 之间的条件下,您还可以使用 interpolate() 方法计算这两个对象之间的终点,该方法在两个位置之间执行球面线性内插,值表示沿着起点与终点之间的路径旅行的分数距离。

下例会在您点击地图上的两点时创建两条折线(一条测地线和一条连接两个位置的“直线”),并计算两点之间行程的航向:

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">

var marker1, marker2;
var poly, geodesicPoly;

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: 34, lng: -40.605}
  });

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(
      document.getElementById('info'));

  marker1 = new google.maps.Marker({
    map: map,
    draggable: true,
    position: {lat: 40.714, lng: -74.006}
  });

  marker2 = new google.maps.Marker({
    map: map,
    draggable: true,
    position: {lat: 48.857, lng: 2.352}
  });

  var bounds = new google.maps.LatLngBounds(
      marker1.getPosition(), marker2.getPosition());
  map.fitBounds(bounds);

  google.maps.event.addListener(marker1, 'position_changed', update);
  google.maps.event.addListener(marker2, 'position_changed', update);

  poly = new google.maps.Polyline({
    strokeColor: '#FF0000',
    strokeOpacity: 1.0,
    strokeWeight: 3,
    map: map,
  });

  geodesicPoly = new google.maps.Polyline({
    strokeColor: '#CC0099',
    strokeOpacity: 1.0,
    strokeWeight: 3,
    geodesic: true,
    map: map
  });

  update();
}

function update() {
  var path = [marker1.getPosition(), marker2.getPosition()];
  poly.setPath(path);
  geodesicPoly.setPath(path);
  var heading = google.maps.geometry.spherical.computeHeading(path[0], path[1]);
  document.getElementById('heading').value = heading;
  document.getElementById('origin').value = path[0].toString();
  document.getElementById('destination').value = path[1].toString();
}
<div id="map"></div>
<div id="floating-panel">
  Origin: <input type="text" readonly id="origin">
  Destination: <input type="text" readonly id="destination"><br>
  Heading: <input type="text" readonly id="heading"> degrees
</div>
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */
#map {
  height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: 'Roboto','sans-serif';
  line-height: 30px;
  padding-left: 10px;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=geometry&callback=initMap"
    async defer></script>
// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">

var marker1, marker2;
var poly, geodesicPoly;

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: 34, lng: -40.605}
  });

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(
      document.getElementById('info'));

  marker1 = new google.maps.Marker({
    map: map,
    draggable: true,
    position: {lat: 40.714, lng: -74.006}
  });

  marker2 = new google.maps.Marker({
    map: map,
    draggable: true,
    position: {lat: 48.857, lng: 2.352}
  });

  var bounds = new google.maps.LatLngBounds(
      marker1.getPosition(), marker2.getPosition());
  map.fitBounds(bounds);

  google.maps.event.addListener(marker1, 'position_changed', update);
  google.maps.event.addListener(marker2, 'position_changed', update);

  poly = new google.maps.Polyline({
    strokeColor: '#FF0000',
    strokeOpacity: 1.0,
    strokeWeight: 3,
    map: map,
  });

  geodesicPoly = new google.maps.Polyline({
    strokeColor: '#CC0099',
    strokeOpacity: 1.0,
    strokeWeight: 3,
    geodesic: true,
    map: map
  });

  update();
}

function update() {
  var path = [marker1.getPosition(), marker2.getPosition()];
  poly.setPath(path);
  geodesicPoly.setPath(path);
  var heading = google.maps.geometry.spherical.computeHeading(path[0], path[1]);
  document.getElementById('heading').value = heading;
  document.getElementById('origin').value = path[0].toString();
  document.getElementById('destination').value = path[1].toString();
}

查看示例 (geometry-headings.html)

编码方法

Google Maps JavaScript API 中的路径通常以 LatLng 对象的 Array 形式指定。不过,传送此类数组通常是一项庞大的工作。您可以改为使用 Google 的折线编码算法来压缩某给定路径,以后您可以通过解码来解压缩该路径。

geometry 库包含一个 encoding 命名空间,其中容纳用于对折线进行编码和解码的实用程序。

静态方法 encodePath() 对给定路径进行编码。您可以传递一个 LatLng 数组或一个 MVCArray(由 Polyline.getPath() 返回)。

要对已编码路径进行解码,只需调用 decodePath() 并向该方法传递编码字符串。

下例显示的是密西西比州牛津市的地图。在地图上点击可将相应的点添加到折线上。构建折线时,底部会显示其编码。

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 14,
    center: {lat: 34.366, lng: -89.519}
  });
  var poly = new google.maps.Polyline({
    strokeColor: '#000000',
    strokeOpacity: 1,
    strokeWeight: 3,
    map: map
  });

  // Add a listener for the click event
  google.maps.event.addListener(map, 'click', function(event) {
    addLatLngToPoly(event.latLng, poly);
  });
}

/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * Updates the encoding text area with the path's encoded values.
 */
function addLatLngToPoly(latLng, poly) {
  var path = poly.getPath();
  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear
  path.push(latLng);

  // Update the text field to display the polyline encodings
  var encodeString = google.maps.geometry.encoding.encodePath(path);
  if (encodeString) {
    document.getElementById('encoded-polyline').value = encodeString;
  }
}
<div id="map"></div>
<div id="right-panel">
  <div>Encoding:</div>
  <textarea id="encoded-polyline"></textarea>
</div>
#right-panel {
  font-family: 'Roboto','sans-serif';
  line-height: 30px;
  padding-left: 10px;
}

#right-panel select, #right-panel input {
  font-size: 15px;
}

#right-panel select {
  width: 100%;
}

#right-panel i {
  font-size: 12px;
}
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#map {
  height: 100%;
  width: 50%;
  float: left;
}
#right-panel {
  width: 46%;
  float: left;
}
#encoded-polyline {
  height: 100px;
  width: 100%;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=geometry&callback=initMap"
    async defer></script>
// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 14,
    center: {lat: 34.366, lng: -89.519}
  });
  var poly = new google.maps.Polyline({
    strokeColor: '#000000',
    strokeOpacity: 1,
    strokeWeight: 3,
    map: map
  });

  // Add a listener for the click event
  google.maps.event.addListener(map, 'click', function(event) {
    addLatLngToPoly(event.latLng, poly);
  });
}

/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * Updates the encoding text area with the path's encoded values.
 */
function addLatLngToPoly(latLng, poly) {
  var path = poly.getPath();
  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear
  path.push(latLng);

  // Update the text field to display the polyline encodings
  var encodeString = google.maps.geometry.encoding.encodePath(path);
  if (encodeString) {
    document.getElementById('encoded-polyline').value = encodeString;
  }
}

查看示例 (geometry-encodings.html)

多边形和折线函数

Geometry 库的 poly 命名空间包含实用函数,可用于判断给定点是在多边形或折线内部还是附近。

containsLocation()

containsLocation(point:LatLng, polygon:Polygon)

要查明给定点是否在多边形内部,请将该点和多边形传递给 google.maps.geometry.poly.containsLocation()。如果该点在多边形内或在其边缘上,则函数会返回 true。

如果用户的点击落入在给定三角形内部,以下代码会向浏览器控制台写入“true”;否则会写入“false”。

function initialize() {
  var mapOptions = {
    zoom: 5,
    center: new google.maps.LatLng(24.886, -70.269),
    mapTypeId: 'terrain'
  };

  var map = new google.maps.Map(document.getElementById('map'),
      mapOptions);

  var bermudaTriangle = new google.maps.Polygon({
    paths: [
      new google.maps.LatLng(25.774, -80.190),
      new google.maps.LatLng(18.466, -66.118),
      new google.maps.LatLng(32.321, -64.757)
    ]
  });

  google.maps.event.addListener(map, 'click', function(event) {
    console.log(google.maps.geometry.poly.containsLocation(event.latLng, bermudaTriangle));
  });
}

google.maps.event.addDomListener(window, 'load', initialize);

如果点击落入百慕大三角内部,此代码的另一版本会在地图上绘制一个红色圆圈;否则绘制一个绿色圆圈。

查看示例 (poly-containsLocation)

isLocationOnEdge()

isLocationOnEdge(point:LatLng, poly:Polygon|Polyline, tolerance?:number)

要判断点是落入折线上还是其附近,还是落入多边形边缘上或其附近,请将该点、折线/多边形并可选择将公差值(度数)传递给 google.maps.geometry.poly.isLocationOnEdge()。如果该点与线或边缘上的最近点之间的距离在指定公差范围内,则函数会返回 true。默认公差值为 10-9 度。

function initialize() {
  var myPosition = new google.maps.LatLng(46.0, -125.9);

  var mapOptions = {
    zoom: 5,
    center: myPosition,
    mapTypeId: 'terrain'
  };

  var map = new google.maps.Map(document.getElementById('map'),
      mapOptions);

  var cascadiaFault = new google.maps.Polyline({
    path: [
      new google.maps.LatLng(49.95, -128.1),
      new google.maps.LatLng(46.26, -126.3),
      new google.maps.LatLng(40.3, -125.4)
    ]
  });

  cascadiaFault.setMap(map);

  if (google.maps.geometry.poly.isLocationOnEdge(myPosition, cascadiaFault, 10e-1)) {
    alert("Relocate!");
  }
}

google.maps.event.addDomListener(window, 'load', initialize);

发送以下问题的反馈:

此网页
Google Maps JavaScript API
Google Maps JavaScript API
需要帮助?请访问我们的支持页面