Trực quan hoá dữ liệu: Lập bản đồ động đất

Tổng quan

Hướng dẫn này trình bày cách trực quan hoá dữ liệu trên Google Maps. Ví dụ: các bản đồ trong hướng dẫn này trực quan hoá dữ liệu về vị trí và cường độ của các trận động đất. Tìm hiểu các kỹ thuật sử dụng nguồn dữ liệu của riêng bạn và tạo nên những câu chuyện ấn tượng trên Google Maps như những câu chuyện dưới đây.

2 khung đầu tiên thấy ở trên (từ trái sang phải) hiển thị bản đồ với điểm đánh dấu cơ bảnvòng tròn định kích thước. Khung cuối cùng hiển thị một bản đồ nhiệt.

Nhập dữ liệu của bạn

Hướng dẫn này sử dụng dữ liệu động đất theo thời gian thực của Cơ quan Khảo sát Địa chất Hoa Kỳ (USGS). Trang web của USGS cung cấp dữ liệu của họ ở một số định dạng mà bạn có thể sao chép vào miền của mình để ứng dụng truy cập cục bộ. Hướng dẫn này sẽ yêu cầu JSONP trực tiếp từ các máy chủ USGS bằng cách thêm thẻ script vào phần đầu của tài liệu.

// Create a script tag and set the USGS URL as the source.
        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);

Đặt điểm đánh dấu cơ bản

Lúc này, sau khi đã kéo dữ liệu về vị trí động đất từ nguồn cấp dữ liệu USGS vào ứng dụng, bạn có thể hiển thị dữ liệu này trên bản đồ. Phần này cho bạn biết cách tạo bản đồ sử dụng dữ liệu đã nhập để đặt một điểm đánh dấu cơ bản tại tâm chấn của mỗi vị trí động đất.

Phần dưới đây hiển thị toàn bộ mã bạn cần để tạo bản đồ trong hướng dẫn này.

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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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 callback 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>

Thử mẫu

Sử dụng hình dạng và bản đồ nhiệt để tuỳ chỉnh bản đồ

Phần này trình bày cho bạn các cách khác để tuỳ chỉnh tập dữ liệu đa dạng thức trên bản đồ. Hãy xem xét bản đồ đã tạo trong phần trước của hướng dẫn này, trong đó cho thấy các điểm đánh dấu trên mọi vị trí động đất. Bạn có thể tuỳ chỉnh các điểm đánh dấu để trực quan hoá dữ liệu bổ sung, chẳng hạn như các vị trí có nhiều trận động đất nhất và cường độ hoặc độ sâu của các địa điểm đó.

Dưới đây là một số cách tuỳ chỉnh điểm đánh dấu cơ bản:

  • Sử dụng kích thước hình tròn:
    Bạn có thể vẽ hình tròn (hoặc bất kỳ hình dạng nào khác) có kích thước tương ứng với cường độ của trận động đất bằng cách dùng ký hiệu. Bằng cách này, các trận động đất mạnh được biểu thị dưới dạng những vòng tròn lớn nhất trên bản đồ.

  • Sử dụng bản đồ nhiệt:
    Lớp bản đồ nhiệt trong thư viện trực quan hoá cung cấp một cách đơn giản nhưng hiệu quả để hiển thị dữ liệu phân bố động đất. Bản đồ nhiệt sử dụng màu sắc để thể hiện mật độ của các điểm, giúp bạn dễ dàng chọn các khu vực có hoạt động cao. Bản đồ nhiệt cũng có thể sử dụng WeightedLocations để chẳng hạn như các trận động đất lớn hơn sẽ hiển thị nổi bật hơn trong bản đồ nhiệt.

Kích thước hình tròn

Bản đồ bên dưới hiển thị các điểm đánh dấu được tuỳ chỉnh sử dụng các vòng tròn. Kích thước vòng tròn tăng theo cường độ của trận động đất tại vị trí cụ thể đó.

Phần dưới đây hiển thị toàn bộ mã bạn cần để tạo bản đồ bằng các điểm đánh dấu vòng tròn tuỳ chỉnh.

TypeScript

let map: google.maps.Map;

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    zoom: 2,
    center: { lat: -33.865427, lng: 151.196123 },
    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);

  map.data.setStyle((feature) => {
    const magnitude = feature.getProperty("mag");
    return {
      icon: getCircle(magnitude),
    };
  });
}

function getCircle(magnitude: number) {
  return {
    path: google.maps.SymbolPath.CIRCLE,
    fillColor: "red",
    fillOpacity: 0.2,
    scale: Math.pow(2, magnitude) / 2,
    strokeColor: "white",
    strokeWeight: 0.5,
  };
}

function eqfeed_callback(results: any) {
  map.data.addGeoJson(results);
}

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: { lat: -33.865427, lng: 151.196123 },
    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);
  map.data.setStyle((feature) => {
    const magnitude = feature.getProperty("mag");
    return {
      icon: getCircle(magnitude),
    };
  });
}

function getCircle(magnitude) {
  return {
    path: google.maps.SymbolPath.CIRCLE,
    fillColor: "red",
    fillOpacity: 0.2,
    scale: Math.pow(2, magnitude) / 2,
    strokeColor: "white",
    strokeWeight: 0.5,
  };
}

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

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 Circles</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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 callback 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>

Thử mẫu

Bản đồ nhiệt

Bản đồ nhiệt giúp người xem dễ dàng hiểu được tình trạng phân bố của các trận động đất, theo báo cáo của USGS. Thay vì đặt một điểm đánh dấu trên từng tâm chấn, bản đồ nhiệt sử dụng màu sắc và hình dạng để thể hiện việc phân phối dữ liệu. Trong ví dụ này, màu đỏ biểu thị các khu vực hoạt động mạnh liên quan đến động đất.

Phần bên dưới hiển thị toàn bộ mã bạn cần để tạo bản đồ này.

TypeScript

let map: google.maps.Map;

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    zoom: 2,
    center: { lat: -33.865427, lng: 151.196123 },
    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);
}

function eqfeed_callback(results: any) {
  const heatmapData: google.maps.LatLng[] = [];

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

    heatmapData.push(latLng);
  }

  const heatmap = new google.maps.visualization.HeatmapLayer({
    data: heatmapData,
    dissipating: false,
    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: { lat: -33.865427, lng: 151.196123 },
    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);
}

function eqfeed_callback(results) {
  const heatmapData = [];

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

    heatmapData.push(latLng);
  }

  const heatmap = new google.maps.visualization.HeatmapLayer({
    data: heatmapData,
    dissipating: false,
    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 Heatmap</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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 callback 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&libraries=visualization&v=weekly"
      defer
    ></script>
  </body>
</html>

Thử mẫu

Thông tin khác

Đọc thêm về các chủ đề sau: