将 GeoJSON 数据导入 Google 地图

概览

了解如何从本地或远程来源导入 GeoJSON 数据,并在地图上显示这些数据。本教程运用下面这幅地图介绍了将数据导入地图的各种方法。

下文显示了创建本教程中的地图所需的完整代码。

TypeScript

let map: google.maps.Map;

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    zoom: 2,
    center: new google.maps.LatLng(2.8, -187.3),
    mapTypeId: "terrain",
  });

  // Create a <script> tag and set the USGS URL as the source.
  const script = document.createElement("script");

  // This example uses a local copy of the GeoJSON stored at
  // http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp
  script.src =
    "https://developers.google.com/maps/documentation/javascript/examples/json/earthquake_GeoJSONP.js";
  document.getElementsByTagName("head")[0].appendChild(script);
}

// Loop through the results array and place a marker for each
// set of coordinates.
const eqfeed_callback = function (results: any) {
  for (let i = 0; i < results.features.length; i++) {
    const coords = results.features[i].geometry.coordinates;
    const latLng = new google.maps.LatLng(coords[1], coords[0]);

    new google.maps.Marker({
      position: latLng,
      map: map,
    });
  }
};

declare global {
  interface Window {
    initMap: () => void;
    eqfeed_callback: (results: any) => void;
  }
}
window.initMap = initMap;
window.eqfeed_callback = eqfeed_callback;

JavaScript

let map;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 2,
    center: new google.maps.LatLng(2.8, -187.3),
    mapTypeId: "terrain",
  });

  // Create a <script> tag and set the USGS URL as the source.
  const script = document.createElement("script");

  // This example uses a local copy of the GeoJSON stored at
  // http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp
  script.src =
    "https://developers.google.com/maps/documentation/javascript/examples/json/earthquake_GeoJSONP.js";
  document.getElementsByTagName("head")[0].appendChild(script);
}

// Loop through the results array and place a marker for each
// set of coordinates.
const eqfeed_callback = function (results) {
  for (let i = 0; i < results.features.length; i++) {
    const coords = results.features[i].geometry.coordinates;
    const latLng = new google.maps.LatLng(coords[1], coords[0]);

    new google.maps.Marker({
      position: latLng,
      map: map,
    });
  }
};

window.initMap = initMap;
window.eqfeed_callback = eqfeed_callback;

CSS

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

HTML

<html>
  <head>
    <title>Earthquake Markers</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>

正在加载数据

本部分介绍了如何从 Maps JavaScript API 应用所在网域或其他网域加载数据。

从同一网域加载数据

Google 地图数据层提供了一个用于存储任意地理空间数据(包括 GeoJSON 数据)的容器。如果数据所在的文件托管在您的 Maps JavaScript API 应用所在网域上,您可以使用 map.data.loadGeoJson() 方法加载这些数据。文件必须位于您的 Maps JavaScript API 应用所在网域上,但您可以将其托管在不同的子网域中。例如,您可以从 www.example.com 向 files.example.com 发出请求。

map.data.loadGeoJson('data.json');

跨网域加载数据

如果网域配置允许,您还可以从不属于您的网域请求数据。针对这种权限的标准称作跨域资源共享 (CORS)。如果某个网域已允许跨网域请求,其响应标头应包含以下声明:

Access-Control-Allow-Origin: *

使用 Chrome 开发者工具 (DevTools) 查看网域是否已启用 CORS。

从此类网域加载数据与从同一网域加载 JSON 数据是一样的:

map.data.loadGeoJson('http://www.CORS-ENABLED-SITE.com/data.json');

请求 JSONP

目标网域必须支持 JSONP 请求,才能使用此方法。

若要请求 JSONP,请使用 createElement() 将 script 标记添加到文档的标头。

var script = document.createElement('script');
script.src = 'http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp';
document.getElementsByTagName('head')[0].appendChild(script);

该脚本运行时,目标网域会将数据作为参数传递给另一个脚本(通常命名为 callback())。目标网域会定义回调脚本名称,即在浏览器中加载目标网址时页面上出现的第一个名称。

例如,如果在浏览器窗口中加载 http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp,显示的回调名称为 eqfeed_callback。

您必须在代码中定义回调脚本:

function eqfeed_callback(response) {
  map.data.addGeoJson(response);
}

使用 addGeoJson() 方法将解析后的 GeoJSON 数据添加到地图中。

导入 GeoJSON 几何图形对象

map.data.addGeoJson() 方法需要解析后的 GeoJSON Feature 或 FeatureCollection 对象。它不直接接受独立的 GeoJSON 几何对象(Point、MultiPoint、LineString、MultiLineString、Polygon、MultiPolygon 或 GeometryCollection)。

如果您的数据源或 API 响应返回的是没有顶级 "type": "Feature" 封装容器的独立 GeoJSON 几何图形对象,您必须先将其封装在 Feature 对象中,然后才能调用 map.data.addGeoJson()。

例如,如果几何图形(例如 Polygon)是已解析的 JavaScript 对象,请将其封装在 Feature 对象中:

const polygonGeometry = {
  type: "Polygon",
  coordinates: [
    [
      [-78.45, 35.82],
      [-78.41, 35.73],
      [-78.28, 35.66],
      [-78.45, 35.82],
    ],
  ],
};

const geoJsonFeature = {
  type: "Feature",
  geometry: polygonGeometry,
};

map.data.addGeoJson(geoJsonFeature);

如果几何图形以 JSON 格式的字符串返回(例如,天气警报或边界响应返回的 polygon 字段),您还可以添加标头和页脚,以形成有效的 GeoJSON Feature,然后再使用 JSON.parse() 进行解析:

const geojson_header = "{\"type\":\"Feature\", \"geometry\": ";
const geojson_footer = "}";

map.data.addGeoJson(
    JSON.parse(geojson_header + polygon + geojson_footer));

如需详细了解如何在数据层中使用几何图形和多边形,请参阅数据层开发者指南。

设置数据样式

您可以通过向地图对象添加 GeoJSON 数据来更改数据的呈现方式。如需详细了解如何设置数据样式,请参阅开发者指南。

了解详情

  • GeoJSON 是一种广泛使用的开放格式,基于 JSON(JavaScript 对象表示法)对地理数据进行编码。专为 JSON 数据设计的 JavaScript 工具和方法也适用于 GeoJSON。如需了解详情,请参阅开发者指南。
  • JSONP 代表填充式 JSON。在网络浏览器内运行的 JavaScript 程序使用 JSONP 作为通信方法,从位于不同网域的服务器请求数据。