Kết hợp và trực quan hoá nhiều nguồn dữ liệu

Tổng quan

Hướng dẫn này chỉ cho bạn cách hiển thị dữ liệu từ nhiều nguồn trên bản đồ Google. Ví dụ: bản đồ choropleth bên dưới sử dụng hai nguồn khác nhau để đánh dấu nhiều tiểu bang của Hoa Kỳ và hiển thị dữ liệu theo từng tiểu bang.

Bản đồ sử dụng dữ liệu từ tệp GeoJSON để hiển thị các đa giác xác định ranh giới của các tiểu bang tại Hoa Kỳ. API này cũng có thể trình bày dữ liệu trên bản đồ tương ứng với từng tiểu bang, lấy từ một truy vấn được mô phỏng đến API Censusus của Hoa Kỳ.

Chọn một danh mục dữ liệu từ trình đơn thả xuống điều khiển để cập nhật đa giác trên bản đồ. Bạn cũng có thể di chuột qua một đa giác trạng thái để xem thông tin cụ thể của tiểu bang trong một tuỳ chọn kiểm soát hộp dữ liệu trên bản đồ.

Mẫu dưới đây cho thấy toàn bộ mã bạn cần để tạo bản đồ này.

TypeScript

const mapStyle: google.maps.MapTypeStyle[] = [
  {
    stylers: [{ visibility: "off" }],
  },
  {
    featureType: "landscape",
    elementType: "geometry",
    stylers: [{ visibility: "on" }, { color: "#fcfcfc" }],
  },
  {
    featureType: "water",
    elementType: "geometry",
    stylers: [{ visibility: "on" }, { color: "#bfd4ff" }],
  },
];
let map: google.maps.Map;

let censusMin = Number.MAX_VALUE,
  censusMax = -Number.MAX_VALUE;

function initMap(): void {
  // load the map
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    center: { lat: 40, lng: -100 },
    zoom: 4,
    styles: mapStyle,
  });

  // set up the style rules and events for google.maps.Data
  map.data.setStyle(styleFeature);
  map.data.addListener("mouseover", mouseInToRegion);
  map.data.addListener("mouseout", mouseOutOfRegion);

  // wire up the button
  const selectBox = document.getElementById(
    "census-variable"
  ) as HTMLSelectElement;

  google.maps.event.addDomListener(selectBox, "change", () => {
    clearCensusData();
    loadCensusData(selectBox.options[selectBox.selectedIndex].value);
  });

  // state polygons only need to be loaded once, do them now
  loadMapShapes();
}

/** Loads the state boundary polygons from a GeoJSON source. */
function loadMapShapes() {
  // load US state outline polygons from a GeoJson file
  map.data.loadGeoJson(
    "https://storage.googleapis.com/mapsdevsite/json/states.js",
    { idPropertyName: "STATE" }
  );

  // wait for the request to complete by listening for the first feature to be
  // added
  google.maps.event.addListenerOnce(map.data, "addfeature", () => {
    google.maps.event.trigger(
      document.getElementById("census-variable") as HTMLElement,
      "change"
    );
  });
}

/**
 * Loads the census data from a simulated API call to the US Census API.
 *
 * @param {string} variable
 */
function loadCensusData(variable: string) {
  // load the requested variable from the census API (using local copies)
  const xhr = new XMLHttpRequest();

  xhr.open("GET", variable + ".json");

  xhr.onload = function () {
    const censusData = JSON.parse(xhr.responseText) as any;

    censusData.shift(); // the first row contains column names
    censusData.forEach((row: string) => {
      const censusVariable = parseFloat(row[0]);
      const stateId = row[1];

      // keep track of min and max values
      if (censusVariable < censusMin) {
        censusMin = censusVariable;
      }

      if (censusVariable > censusMax) {
        censusMax = censusVariable;
      }

      const state = map.data.getFeatureById(stateId);

      // update the existing row with the new data
      if (state) {
        state.setProperty("census_variable", censusVariable);
      }
    });

    // update and display the legend
    (document.getElementById("census-min") as HTMLElement).textContent =
      censusMin.toLocaleString();
    (document.getElementById("census-max") as HTMLElement).textContent =
      censusMax.toLocaleString();
  };

  xhr.send();
}

/** Removes census data from each shape on the map and resets the UI. */
function clearCensusData() {
  censusMin = Number.MAX_VALUE;
  censusMax = -Number.MAX_VALUE;
  map.data.forEach((row) => {
    row.setProperty("census_variable", undefined);
  });
  (document.getElementById("data-box") as HTMLElement).style.display = "none";
  (document.getElementById("data-caret") as HTMLElement).style.display = "none";
}

/**
 * Applies a gradient style based on the 'census_variable' column.
 * This is the callback passed to data.setStyle() and is called for each row in
 * the data set.  Check out the docs for Data.StylingFunction.
 *
 * @param {google.maps.Data.Feature} feature
 */
function styleFeature(feature: google.maps.Data.Feature) {
  const low = [5, 69, 54]; // color of smallest datum
  const high = [151, 83, 34]; // color of largest datum

  let censusVariable = feature.getProperty("census_variable") as number;

  // delta represents where the value sits between the min and max
  const delta =
    (censusVariable - censusMin) /
    (censusMax - censusMin);

  const color: number[] = [];

  for (let i = 0; i < 3; i++) {
    // calculate an integer color based on the delta
    color.push((high[i] - low[i]) * delta + low[i]);
  }

  // determine whether to show this shape or not
  let showRow = true;

  if (
    censusVariable == null ||
    isNaN(censusVariable)
  ) {
    showRow = false;
  }

  let outlineWeight = 0.5,
    zIndex = 1;

  if (feature.getProperty("state") === "hover") {
    outlineWeight = zIndex = 2;
  }

  return {
    strokeWeight: outlineWeight,
    strokeColor: "#fff",
    zIndex: zIndex,
    fillColor: "hsl(" + color[0] + "," + color[1] + "%," + color[2] + "%)",
    fillOpacity: 0.75,
    visible: showRow,
  };
}

/**
 * Responds to the mouse-in event on a map shape (state).
 *
 * @param {?google.maps.MapMouseEvent} e
 */
function mouseInToRegion(e: any) {
  // set the hover state so the setStyle function can change the border
  e.feature.setProperty("state", "hover");

  const percent =
    ((e.feature.getProperty("census_variable") - censusMin) /
      (censusMax - censusMin)) *
    100;

  // update the label
  (document.getElementById("data-label") as HTMLElement).textContent =
    e.feature.getProperty("NAME");
  (document.getElementById("data-value") as HTMLElement).textContent = e.feature
    .getProperty("census_variable")
    .toLocaleString();
  (document.getElementById("data-box") as HTMLElement).style.display = "block";
  (document.getElementById("data-caret") as HTMLElement).style.display =
    "block";
  (document.getElementById("data-caret") as HTMLElement).style.paddingLeft =
    percent + "%";
}

/**
 * Responds to the mouse-out event on a map shape (state).
 *
 */
function mouseOutOfRegion(e: any) {
  // reset the hover state, returning the border to normal
  e.feature.setProperty("state", "normal");
}

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

JavaScript

const mapStyle = [
  {
    stylers: [{ visibility: "off" }],
  },
  {
    featureType: "landscape",
    elementType: "geometry",
    stylers: [{ visibility: "on" }, { color: "#fcfcfc" }],
  },
  {
    featureType: "water",
    elementType: "geometry",
    stylers: [{ visibility: "on" }, { color: "#bfd4ff" }],
  },
];
let map;
let censusMin = Number.MAX_VALUE,
  censusMax = -Number.MAX_VALUE;

function initMap() {
  // load the map
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40, lng: -100 },
    zoom: 4,
    styles: mapStyle,
  });
  // set up the style rules and events for google.maps.Data
  map.data.setStyle(styleFeature);
  map.data.addListener("mouseover", mouseInToRegion);
  map.data.addListener("mouseout", mouseOutOfRegion);

  // wire up the button
  const selectBox = document.getElementById("census-variable");

  google.maps.event.addDomListener(selectBox, "change", () => {
    clearCensusData();
    loadCensusData(selectBox.options[selectBox.selectedIndex].value);
  });
  // state polygons only need to be loaded once, do them now
  loadMapShapes();
}

/** Loads the state boundary polygons from a GeoJSON source. */
function loadMapShapes() {
  // load US state outline polygons from a GeoJson file
  map.data.loadGeoJson(
    "https://storage.googleapis.com/mapsdevsite/json/states.js",
    { idPropertyName: "STATE" },
  );
  // wait for the request to complete by listening for the first feature to be
  // added
  google.maps.event.addListenerOnce(map.data, "addfeature", () => {
    google.maps.event.trigger(
      document.getElementById("census-variable"),
      "change",
    );
  });
}

/**
 * Loads the census data from a simulated API call to the US Census API.
 *
 * @param {string} variable
 */
function loadCensusData(variable) {
  // load the requested variable from the census API (using local copies)
  const xhr = new XMLHttpRequest();

  xhr.open("GET", variable + ".json");
  xhr.onload = function () {
    const censusData = JSON.parse(xhr.responseText);

    censusData.shift(); // the first row contains column names
    censusData.forEach((row) => {
      const censusVariable = parseFloat(row[0]);
      const stateId = row[1];

      // keep track of min and max values
      if (censusVariable < censusMin) {
        censusMin = censusVariable;
      }

      if (censusVariable > censusMax) {
        censusMax = censusVariable;
      }

      const state = map.data.getFeatureById(stateId);

      // update the existing row with the new data
      if (state) {
        state.setProperty("census_variable", censusVariable);
      }
    });
    // update and display the legend
    document.getElementById("census-min").textContent =
      censusMin.toLocaleString();
    document.getElementById("census-max").textContent =
      censusMax.toLocaleString();
  };

  xhr.send();
}

/** Removes census data from each shape on the map and resets the UI. */
function clearCensusData() {
  censusMin = Number.MAX_VALUE;
  censusMax = -Number.MAX_VALUE;
  map.data.forEach((row) => {
    row.setProperty("census_variable", undefined);
  });
  document.getElementById("data-box").style.display = "none";
  document.getElementById("data-caret").style.display = "none";
}

/**
 * Applies a gradient style based on the 'census_variable' column.
 * This is the callback passed to data.setStyle() and is called for each row in
 * the data set.  Check out the docs for Data.StylingFunction.
 *
 * @param {google.maps.Data.Feature} feature
 */
function styleFeature(feature) {
  const low = [5, 69, 54]; // color of smallest datum
  const high = [151, 83, 34]; // color of largest datum
  let censusVariable = feature.getProperty("census_variable");
  // delta represents where the value sits between the min and max
  const delta = (censusVariable - censusMin) / (censusMax - censusMin);
  const color = [];

  for (let i = 0; i < 3; i++) {
    // calculate an integer color based on the delta
    color.push((high[i] - low[i]) * delta + low[i]);
  }

  // determine whether to show this shape or not
  let showRow = true;

  if (censusVariable == null || isNaN(censusVariable)) {
    showRow = false;
  }

  let outlineWeight = 0.5,
    zIndex = 1;

  if (feature.getProperty("state") === "hover") {
    outlineWeight = zIndex = 2;
  }
  return {
    strokeWeight: outlineWeight,
    strokeColor: "#fff",
    zIndex: zIndex,
    fillColor: "hsl(" + color[0] + "," + color[1] + "%," + color[2] + "%)",
    fillOpacity: 0.75,
    visible: showRow,
  };
}

/**
 * Responds to the mouse-in event on a map shape (state).
 *
 * @param {?google.maps.MapMouseEvent} e
 */
function mouseInToRegion(e) {
  // set the hover state so the setStyle function can change the border
  e.feature.setProperty("state", "hover");

  const percent =
    ((e.feature.getProperty("census_variable") - censusMin) /
      (censusMax - censusMin)) *
    100;

  // update the label
  document.getElementById("data-label").textContent =
    e.feature.getProperty("NAME");
  document.getElementById("data-value").textContent = e.feature
    .getProperty("census_variable")
    .toLocaleString();
  document.getElementById("data-box").style.display = "block";
  document.getElementById("data-caret").style.display = "block";
  document.getElementById("data-caret").style.paddingLeft = percent + "%";
}

/**
 * Responds to the mouse-out event on a map shape (state).
 *
 */
function mouseOutOfRegion(e) {
  // reset the hover state, returning the border to normal
  e.feature.setProperty("state", "normal");
}

window.initMap = initMap;

CSS

html,
body,
#map {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.nicebox {
  position: absolute;
  text-align: center;
  font-family: "Roboto", "Arial", sans-serif;
  font-size: 13px;
  z-index: 5;
  box-shadow: 0 4px 6px -4px #333;
  padding: 5px 10px;
  background: rgb(255, 255, 255);
  background: linear-gradient(to bottom, rgb(255, 255, 255) 0%, rgb(245, 245, 245) 100%);
  border: rgb(229, 229, 229) 1px solid;
}

#controls {
  top: 10px;
  left: 110px;
  width: 360px;
  height: 45px;
}

#data-box {
  top: 10px;
  left: 500px;
  height: 45px;
  line-height: 45px;
  display: none;
}

#census-variable {
  width: 360px;
  height: 20px;
}

#legend {
  display: flex;
  display: -webkit-box;
  padding-top: 7px;
}

.color-key {
  background: linear-gradient(to right, hsl(5, 69%, 54%) 0%, hsl(29, 71%, 51%) 17%, hsl(54, 74%, 47%) 33%, hsl(78, 76%, 44%) 50%, hsl(102, 78%, 41%) 67%, hsl(127, 81%, 37%) 83%, hsl(151, 83%, 34%) 100%);
  flex: 1;
  -webkit-box-flex: 1;
  margin: 0 5px;
  text-align: left;
  font-size: 1em;
  line-height: 1em;
}

#data-value {
  font-size: 2em;
  font-weight: bold;
}

#data-label {
  font-size: 2em;
  font-weight: normal;
  padding-right: 10px;
}

#data-label:after {
  content: ":";
}

#data-caret {
  margin-left: -5px;
  display: none;
  font-size: 14px;
  width: 14px;
}

HTML

<html>
  <head>
    <title>Mashups with google.maps.Data</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="controls" class="nicebox">
      <div>
        <select id="census-variable">
          <option
            value="https://storage.googleapis.com/mapsdevsite/json/DP02_0066PE"
          >
            Percent of population over 25 that completed high school
          </option>
          <option
            value="https://storage.googleapis.com/mapsdevsite/json/DP05_0017E"
          >
            Median age
          </option>
          <option
            value="https://storage.googleapis.com/mapsdevsite/json/DP05_0001E"
          >
            Total population
          </option>
          <option
            value="https://storage.googleapis.com/mapsdevsite/json/DP02_0016E"
          >
            Average family size
          </option>
          <option
            value="https://storage.googleapis.com/mapsdevsite/json/DP03_0088E"
          >
            Per-capita income
          </option>
        </select>
      </div>
      <div id="legend">
        <div id="census-min">min</div>
        <div class="color-key"><span id="data-caret">&#x25c6;</span></div>
        <div id="census-max">max</div>
      </div>
    </div>
    <div id="data-box" class="nicebox">
      <label id="data-label" for="data-value"></label>
      <span id="data-value"></span>
    </div>
    <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>

Thử dùng mẫu

Bắt đầu

Bạn có thể phát triển phiên bản riêng của bản đồ choropleth này bằng cách sử dụng đoạn mã trong hướng dẫn này. Để bắt đầu thực hiện việc này, hãy tạo một tệp mới trong trình chỉnh sửa văn bản và lưu tệp đó dưới dạng index.html.

Đọc các phần sau đây để nắm được mã mà bạn có thể thêm vào tệp này.

Tạo bản đồ cơ bản

Phần này giải thích mã thiết lập bản đồ cơ bản. Cách này có thể tương tự như cách bạn tạo bản đồ khi bắt đầu sử dụng API JavaScript của Maps.

Sao chép mã bên dưới vào tệp index.html. Mã này tải API JavaScript của Maps và làm cho bản đồ ở chế độ toàn màn hình.

<!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8">
      <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
      <title>Mashups with google.maps.Data</title>
      <style>
        #map {
          height: 100%;
        }
        /* Optional: Makes the sample page fill the window. */
        html, body {
          height: 100%;
          margin: 0;
          padding: 0;
        }
      </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      function initMap() {

        // load the map
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: 40, lng: -100},
          zoom: 4,
          styles: mapStyle
        });

        var mapStyle = [{
          'featureType': 'all',
          'elementType': 'all',
          'stylers': [{'visibility': 'off'}]
        }, {
          'featureType': 'landscape',
          'elementType': 'geometry',
          'stylers': [{'visibility': 'on'}, {'color': '#fcfcfc'}]
        }, {
          'featureType': 'water',
          'elementType': 'labels',
          'stylers': [{'visibility': 'off'}]
        }, {
          'featureType': 'water',
          'elementType': 'geometry',
          'stylers': [{'visibility': 'on'}, {'hue': '#5f94ff'}, {'lightness': 60}]
        }];
      }

    </script>
    <script defer
        src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
    </script>
  </body>
</html>

Mã trong thẻ tập lệnh đầu tiên là điểm bắt đầu chạy chương trình bằng cách tạo một hàm có tên là initMap để khởi động đối tượng bản đồ.

Trình tạo kiểu trong mã ở trên tắt chế độ hiển thị của tất cả featureTypes trên bản đồ như đường, địa điểm yêu thích, phong cảnh, khu vực hành chính và tất cả elementTypes của chúng. Để biết danh sách tất cả giá trị có sẵn cho featureTypeelementType, hãy xem tài liệu tham khảo về kiểu JSON.

Nhấp vào YOUR_API_KEY trong mã mẫu hoặc làm theo hướng dẫn để lấy khoá API. Thay thế YOUR_API_KEY bằng khoá API của ứng dụng. Sau khi API được tải hoàn tất, tham số gọi lại trong thẻ tập lệnh bên dưới sẽ thực thi hàm initMap() trong tệp HTML.

<script> defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
</script>

Tạo và định kiểu điều khiển bản đồ

Đoạn mã dưới đây tạo các chế độ kiểm soát sau đây trên bản đồ:

  • Một chế độ điều khiển có trình đơn thả xuống có 5 lựa chọn về dữ liệu.
  • Chú giải bản đồ.
  • Hộp dữ liệu hiển thị dữ liệu theo từng tiểu bang xuất hiện khi bạn di chuột qua một đa giác.
<div id="controls" class="nicebox">
  <div>
  <select id="census-variable">
    <option value="https://storage.googleapis.com/mapsdevsite/json/DP02_0066PE">Percent of population over 25 that completed high
    school</option>
    <option value="https://storage.googleapis.com/mapsdevsite/json/DP05_0017E">Median age</option>
    <option value="https://storage.googleapis.com/mapsdevsite/json/DP05_0001E">Total population</option>
    <option value="https://storage.googleapis.com/mapsdevsite/json/DP02_0016E">Average family size</option>
    <option value="https://storage.googleapis.com/mapsdevsite/json/DP03_0088E">Per-capita income</option>
  </select>
  </div>
  <div id="legend">
    <div id="census-min">min</div>
    <div class="color-key"><span id="data-caret">◆</span></div>
    <div id="census-max">max</div>
  </div>
</div>
<div id="data-box" class="nicebox">
  <label id="data-label" for="data-value"></label>
  <span id="data-value"></span>
</div>

Sử dụng mã dưới đây trong các thẻ style để tạo kiểu cho các nút điều khiển bản đồ.

<style>
  html, body, #map { height: 100%; margin: 0; padding: 0; overflow: hidden; }
    .nicebox {
      position: absolute;
      text-align: center;
      font-family: "Roboto", "Arial", sans-serif;
      font-size: 13px;
      z-index: 5;
      box-shadow: 0 4px 6px -4px #333;
      padding: 5px 10px;
      background: rgb(255,255,255);
      background: linear-gradient(to bottom,rgba(255,255,255,1) 0%,rgba(245,245,245,1) 100%);
      border: rgb(229, 229, 229) 1px solid;
    }
    #controls {
      top: 10px;
      left: 110px;
      width: 360px;
      height: 45px;
    }
    #data-box {
      top: 10px;
      left: 500px;
      height: 45px;
      line-height: 45px;
      display: none;
    }
    #census-variable {
      width: 360px;
      height: 20px;
    }
    #legend { display: flex; display: -webkit-box; padding-top: 7px }
    .color-key {
      background: linear-gradient(to right,
        hsl(5, 69%, 54%) 0%,
        hsl(29, 71%, 51%) 17%,
        hsl(54, 74%, 47%) 33%,
        hsl(78, 76%, 44%) 50%,
        hsl(102, 78%, 41%) 67%,
        hsl(127, 81%, 37%) 83%,
        hsl(151, 83%, 34%) 100%);
      flex: 1;
      -webkit-box-flex: 1;
      margin: 0 5px;
      text-align: left;
      font-size: 1.0em;
      line-height: 1.0em;
    }
    #data-value { font-size: 2.0em; font-weight: bold }
    #data-label { font-size: 2.0em; font-weight: normal; padding-right: 10px; }
    #data-label:after { content: ':' }
    #data-caret { margin-left: -5px; display: none; font-size: 14px; width: 14px}
</style>

Nhập dữ liệu từ US Census API

Mã bên dưới truy vấn Cục Thống kê Dân số Hoa Kỳ để biết dữ liệu điều tra dân số gần đây nhất của tất cả các tiểu bang ở Hoa Kỳ mà cơ quan này nhận được ở định dạng JSON.

function loadCensusData(variable) {
// load the requested variable from the census API
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://api.census.gov/data/2012/acs5/profile?get=' +
  variable + '&for=state:*&key=YOUR_API_KEY');
        xhr.onload = function() {
          var censusData = JSON.parse(xhr.responseText);
          censusData.shift(); // the first row contains column names
          censusData.forEach(function(row) {
            var censusVariable = parseFloat(row[0]);
            var stateId = row[1];

            // keep track of min and max values
            if (censusVariable < censusMin) {
              censusMin = censusVariable;
            }
            if (censusVariable > censusMax) {
              censusMax = censusVariable;
            }

            // update the existing row with the new data
            map.data
              .getFeatureById(stateId)
              .setProperty('census_variable', censusVariable);
          });

          // update and display the legend
          document.getElementById('census-min').textContent =
              censusMin.toLocaleString();
          document.getElementById('census-max').textContent =
              censusMax.toLocaleString();
        };
        xhr.send();
}

Tạo kiểu dữ liệu

Đoạn mã dưới đây tạo bản đồ choropleth bằng cách áp dụng một độ dốc cho từng đa giác trong tập dữ liệu, dựa trên giá trị dữ liệu điều tra dân số. Bạn có thể tạo kiểu cho dữ liệu bằng đối tượng Data.StyleOptions hoặc hàm trả về đối tượng Data.StyleOptions.

// set up the style rules and events for google.maps.Data
map.data.setStyle(styleFeature);

      function styleFeature(feature) {
        var low = [5, 69, 54];  // color of smallest datum
        var high = [151, 83, 34];   // color of largest datum

        // delta represents where the value sits between the min and max
        var delta = (feature.getProperty('census_variable') - censusMin) /
            (censusMax - censusMin);

        var color = [];
        for (var i = 0; i < 3; i++) {
          // calculate an integer color based on the delta
          color[i] = (high[i] - low[i]) * delta + low[i];
        }

        // determine whether to show this shape or not
        var showRow = true;
        if (feature.getProperty('census_variable') == null ||
            isNaN(feature.getProperty('census_variable'))) {
          showRow = false;
        }

        var outlineWeight = 0.5, zIndex = 1;
        if (feature.getProperty('state') === 'hover') {
          outlineWeight = zIndex = 2;
        }

        return {
          strokeWeight: outlineWeight,
          strokeColor: '#fff',
          zIndex: zIndex,
          fillColor: 'hsl(' + color[0] + ',' + color[1] + '%,' + color[2] + '%)',
          fillOpacity: 0.75,
          visible: showRow
        };
      }

Ngoài việc tô màu đa giác, mã dưới đây còn tạo một phần tử tương tác bằng cách thêm các sự kiện phản hồi hoạt động của chuột. Khi di chuột qua một đa giác, đường viền tiểu bang sẽ được đánh dấu và đồng thời cập nhật tuỳ chọn kiểm soát hộp dữ liệu trên bản đồ.

// set up the style rules and events for google.maps.Data
map.data.addListener('mouseover', mouseInToRegion);
map.data.addListener('mouseout', mouseOutOfRegion);

      /**
       * Responds to the mouse-in event on a map shape (state).
       *
       * @param {?google.maps.MapMouseEvent} e
       */
      function mouseInToRegion(e) {
        // set the hover state so the setStyle function can change the border
        e.feature.setProperty('state', 'hover');

        var percent = (e.feature.getProperty('census_variable') - censusMin) /
            (censusMax - censusMin) * 100;

        // update the label
        document.getElementById('data-label').textContent =
            e.feature.getProperty('NAME');
        document.getElementById('data-value').textContent =
            e.feature.getProperty('census_variable').toLocaleString();
        document.getElementById('data-box').style.display = 'block';
        document.getElementById('data-caret').style.display = 'block';
        document.getElementById('data-caret').style.paddingLeft = percent + '%';
      }

      /**
       * Responds to the mouse-out event on a map shape (state).
       *
       * @param {?google.maps.MapMouseEvent} e
       */
      function mouseOutOfRegion(e) {
        // reset the hover state, returning the border to normal
        e.feature.setProperty('state', 'normal');
      }

Đang tải đa giác ranh giới của tiểu bang

Thêm mã bên dưới sau toàn bộ hàm initMap. Hàm loadMapShapes tải đa giác cho ranh giới của các tiểu bang ở Hoa Kỳ từ tệp GeoJSON bằng cách sử dụng phương thức loadGeoJson.

/** Loads the state boundary polygons from a GeoJSON source. */
function loadMapShapes() {
  // load US state outline polygons from a GeoJSON file
  map.data.loadGeoJson('https://storage.googleapis.com/mapsdevsite/json/states.js', { idPropertyName: 'STATE' });

Thêm dòng bên dưới vào cuối hàm initMap.

  // state polygons only need to be loaded once, do them now
  loadMapShapes();

Khi chọn một nguồn dữ liệu trong trình đơn thả xuống kiểm soát bản đồ, bản đồ sẽ truy vấn US Census Data API cho biến được chỉ định. Để kết nối dữ liệu điều tra dân số với dữ liệu hình dạng, mã này sẽ đặt idPropertyName thành "STATE". Đây là khoá phổ biến trong cả dữ liệu điều tra dân số và trong các thuộc tính của GeoJson.

Thông tin khác

Bản minh hoạ này sử dụng API Dữ liệu của Cục Thống kê Dân số nhưng không được Cục Thống kê Dân số chứng thực hoặc chứng nhận.