Các phương pháp di chuyển KmlLayer

Giới thiệu

Mục đích của hướng dẫn này là trình bày những trường hợp sử dụng phổ biến nhất của KmlLayer và cung cấp các đường dẫn di chuyển tương ứng đến các cách triển khai thay thế. Thông tin này dành cho những nhà phát triển cần chuyển đổi từ việc sử dụng KmlLayer do lớp này đã được lên lịch ngừng hoạt động. Phiên bản cuối cùng hỗ trợ KmlLayer là 3.65 và sẽ ngừng hoạt động vào tháng 5 năm 2027.

Đường dẫn di chuyển sẽ phụ thuộc vào cách bạn đang sử dụng KmlLayer:

Tệp KML để tạo kiểu cho thông tin về ranh giới/đường viền/khu vực quan tâm

Đối với những nhà phát triển sử dụng KmlLayer để hiển thị hoặc định kiểu cho ranh giới hành chính (chẳng hạn như làm nổi bật một quốc gia, tiểu bang hoặc địa phương cụ thể), Google Maps Platform đề xuất di chuyển sang Định kiểu dựa trên dữ liệu (DDS) cho ranh giới.

Đề xuất di chuyển: Định kiểu dựa trên dữ liệu cho ranh giới

Định kiểu dựa trên dữ liệu cho ranh giới cung cấp quyền truy cập trực tiếp vào các đa giác ranh giới hành chính của Google, cho phép bạn áp dụng kiểu tuỳ chỉnh (màu nền và đường viền) cho các khu vực này mà không cần lưu trữ hoặc quản lý các tệp KML bên ngoài.

FeatureType có sẵn

Các khu vực hành chính được phân loại theo chức năng và sắp xếp theo cấp độ. Sau đây là các loại đối tượng được hỗ trợ để tạo kiểu:

  • COUNTRY: Thực thể chính trị quốc gia.
  • ADMINISTRATIVE_AREA_LEVEL_1: Một thực thể dân sự cấp một dưới cấp quốc gia (ví dụ: các tiểu bang ở Hoa Kỳ).
  • ADMINISTRATIVE_AREA_LEVEL_2: Một thực thể dân sự cấp hai dưới cấp quốc gia (ví dụ: các hạt ở Hoa Kỳ).
  • LOCALITY: Một thành phố hoặc thị trấn hợp nhất.
  • POSTAL_CODE: Mã bưu chính dùng cho thư.
  • SCHOOL_DISTRICT: Học khu thống nhất, tiểu học hoặc trung học.

Xem phạm vi ranh giới cho những khu vực có các loại đối tượng này.

Cách làm nổi bật một khu vực

Để tạo kiểu cho một khu vực cụ thể, bạn phải nhắm đến khu vực đó theo Mã địa điểm.

Hạn chế thao tác xoay và di chuyển đến một khu vực

Để ngăn người dùng di chuyển ra ngoài hộp giới hạn của vùng được đánh dấu, bạn có thể sử dụng lựa chọn restriction trong MapOptions.

Đối tượng restriction xác định một latLngBounds giới hạn khu vực có thể xem của bản đồ. Hãy xem tài liệu để biết thêm thông tin chi tiết về cách hoạt động của chế độ hạn chế.

// Restrict panning to a specific bounding box
restriction: {
  latLngBounds: {
    north: 47.8,
    south: 45.8,
    east: 10.5,
    west: 5.9,
  },
  strictBounds: true,
},

Tóm tắt quá trình triển khai di chuyển

Sau đây là một ví dụ hoàn chỉnh về cách sử dụng tính năng Định kiểu dựa trên dữ liệu cho các ranh giới và một quy tắc hạn chế theo khu vực để tập trung bản đồ vào một khu vực cụ thể.

const myTargetRegion = "ChIJYW1Zb-9kjEcRFXvLDxG1Vlw"; // Place ID for Switzerland

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 46.8, lng: 8.2 },
    zoom: 9,
    mapId: "YOUR_MAP_ID", // Required for DDS
    // Restrict panning to a specific bounding box
    restriction: {
    // Bounding box for Switzerland
      latLngBounds: {
        north: 47.8,
        south: 45.8,
        east: 10.5,
        west: 5.9,
      },
      strictBounds: true,
    },
  });

  // Access the Country layer and style a specific region by Place ID
  const countryLayer = map.getFeatureLayer("COUNTRY");
  countryLayer.style = (options) => {
    if (options.feature.placeId === myTargetRegion) {
      return {
        fillColor: "#FF0000",
        fillOpacity: 0.5,
        strokeColor: "#FF0000",
        strokeWeight: 2,
      };
    } else {
    // Style everything else whited out, to make the area of interest pop out more.
      return {
        fillColor: '#ffffff',
        fillOpacity: 0.8,
      };
    }
  };
}

Tệp KML có dữ liệu vectơ (Điểm/Đường nhiều đoạn/Ranh giới/Đa giác)

Đề xuất di chuyển: Định kiểu dựa trên dữ liệu cho tập dữ liệu

Google đề xuất đường dẫn bên dưới để hiển thị dữ liệu địa lý có sẵn công khai trong khi có quyền kiểm soát nhiều hơn đối với kiểu dáng và hiệu suất.

Tính năng Định kiểu dựa trên dữ liệu cho tập dữ liệu cho phép bạn tải dữ liệu không gian địa lý của riêng mình lên (KML, GeoJSON hoặc CSV), áp dụng kiểu tuỳ chỉnh dựa trên các thuộc tính dữ liệu và hiển thị các đối tượng trên bản đồ vectơ.

1. Thiết lập và tải lên

Không giống như KmlLayer (tìm nạp một URL trong thời gian chạy), DDS yêu cầu bạn lưu trữ dữ liệu dưới dạng một tập dữ liệu trong Google Cloud Console.

  • Tạo mã bản đồ: Sử dụng mã bản đồ được định cấu hình cho loại Bản đồ vectơ.
  • Tải tập dữ liệu lên: Tải tệp KML lên Google Cloud Console để tạo một Mã tập dữ liệu duy nhất. Hãy đọc tài liệu đầy đủ về cách quản lý Tập dữ liệu trên Maps để biết thêm thông tin chi tiết.
  • Hiển thị Tập dữ liệu: Sau khi tạo một Mã nhận dạng tập dữ liệu, bạn cần liên kết Tập dữ liệu đó với một Kiểu bản đồ và một Mã bản đồ. Sau đó, bạn sẽ dùng Dataset ID (Mã nhận dạng tập dữ liệu) để thực sự hiển thị dữ liệu trên bản đồ. Hãy đọc tài liệu đầy đủ về cách Thêm một tập dữ liệu vào bản đồ để biết mọi thông tin chi tiết.
  • Lưu ý các yêu cầu đối với KML cho Tập dữ liệu, nếu bạn quyết định nhập dữ liệu ở định dạng KML.

2. Đặt khung nhìn thành dữ liệu

KmlLayer tự động di chuyển và thu phóng đến vị trí dữ liệu theo mặc định. Với DDS cho tập dữ liệu, hành vi này không tự động và phải được triển khai theo cách thủ công.

  • Hạn chế được mã hoá cứng: Nếu vùng dữ liệu là tĩnh, hãy sử dụng lựa chọn restriction trong MapOptions để khoá khung hiển thị ở các ranh giới cụ thể.
  • Thu phóng linh động: Để đặt khung hiển thị một cách linh động, bạn có thể sử dụng map.fitBounds() với hộp giới hạn của tập dữ liệu.

3. Tạo kiểu từ Thuộc tính đối tượng

Tệp KML thường chứa thông tin về kiểu (chẳng hạn như màu sắc) mà DDS không tự động áp dụng. Bạn phải tạo một hàm kiểu phía máy khách đọc các thuộc tính từ các đối tượng trong tập dữ liệu để áp dụng màu sắc và độ mờ. Hãy tham khảo tài liệu dành cho nhà phát triển về cách tạo kiểu cho dữ liệu để biết đầy đủ thông tin chi tiết.

Ví dụ: Hàm tạo kiểu bằng cách sử dụng thuộc tính

Ví dụ sau đây minh hoạ cách tạo một hàm kiểu đọc trực tiếp các thuộc tính background_coloropacity từ tập dữ liệu đã tải lên:

/**
 * Migration example: Styling features from dataset attributes.
 */
function styleDDSLayer(map, datasetId) {
  const datasetLayer = map.getDatasetFeatureLayer(datasetId);

  // Set the style function
  datasetLayer.style = (params) => {
    // Access attributes defined in your KML/Dataset
    const featureAttributes = params.feature.datasetAttributes;

    // Read style values from attributes, with fallback defaults
    const fillColor = featureAttributes['background_color'] || '#4285F4';
    const fillOpacity = parseFloat(featureAttributes['opacity']) || 0.5;
    const strokeColor = featureAttributes['border_color'] || '#34A853';

    return {
      fillColor: fillColor,
      fillOpacity: fillOpacity,
      strokeColor: strokeColor,
      strokeWeight: 2,
    };
  };
}

Để biết thêm thông tin chi tiết về cách triển khai các hoạt động tương tác và định kiểu, hãy tham khảo phần Tổng quan về việc định kiểu dựa trên dữ liệu cho tập dữ liệuDatasets API cho dữ liệu động.

Đề xuất di chuyển: Kết xuất phía máy khách bằng GeoJSON

Đối với những nhà phát triển di chuyển từ KmlLayer sang tính năng kết xuất phía máy khách bằng GeoJSON, Google Maps Platform đề xuất một lộ trình di chuyển liên quan đến việc chuyển đổi định dạng dữ liệu và sử dụng Lớp dữ liệu để kết xuất và tạo kiểu cho các đối tượng trực tiếp trong trình duyệt.

Việc kết xuất phía máy khách bằng cách sử dụng Lớp dữ liệu mang đến một cách thức rất linh hoạt để hiển thị dữ liệu địa lý. Không giống như KmlLayer (được hiển thị trên các máy chủ của Google), Lớp dữ liệu cho phép bạn tương tác với các tính năng dưới dạng các đối tượng JavaScript tiêu chuẩn. Tuy nhiên, xin lưu ý rằng đối với các tập dữ liệu lớn, bạn có thể muốn xử lý và hiển thị dữ liệu phía máy chủ, chẳng hạn như với tính năng Định kiểu dựa trên dữ liệu cho tập dữ liệu.

1. Chuyển đổi KML sang GeoJSON

Bước đầu tiên là chuyển đổi tệp KML thành GeoJSON. Bạn có thể thực hiện việc này bằng một số công cụ nguồn mở phổ biến:

  • ogr2ogr: Một phần của bộ GDAL, tiện ích dòng lệnh mạnh mẽ này có thể chuyển đổi giữa nhiều định dạng vectơ.
ogr2ogr -f GeoJSON output.json input.kml
  • togeojson: Một công cụ nhỏ, được kiểm tra kỹ lưỡng và được thiết kế riêng để chuyển đổi KML và GPX sang GeoJSON.
togeojson input.kml > output.json

2. Đặt khung nhìn thành dữ liệu

Mặc dù KmlLayer tự động di chuyển và thu phóng đến vị trí dữ liệu, nhưng Lớp dữ liệu thì không. Để đặt khung hiển thị cho phù hợp với dữ liệu GeoJSON, bạn phải tính toán hộp giới hạn theo cách thủ công và gọi map.fitBounds().

3. Tạo kiểu từ Thuộc tính đối tượng

Trong Lớp dữ liệu, bạn có thể xác định một hàm style đọc các thuộc tính (đặc tính) trực tiếp từ mỗi đối tượng GeoJSON để xác định giao diện của đối tượng đó.

Ví dụ: Hàm tạo kiểu và điều chỉnh khung hiển thị

Ví dụ sau đây minh hoạ cách tải dữ liệu GeoJSON, tính toán ranh giới của dữ liệu đó để đặt khung hiển thị và tạo kiểu cho các đối tượng dựa trên thuộc tính của chúng:

/**
 * Migration example: Loading GeoJSON, fitting viewport, and styling from attributes.
 */
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -28, lng: 137 },
  });

  // Load the GeoJSON data
  map.data.loadGeoJson('path/to/your/data.json', null, (features) => {
    // Adjust viewport to show all loaded features
    const bounds = new google.maps.LatLngBounds();
    features.forEach((feature) => {
      feature.getGeometry().forEachLatLng((latlng) => {
        bounds.extend(latlng);
      });
    });
    map.fitBounds(bounds);
  });

  // Set the style function to read from GeoJSON properties
  map.data.setStyle((feature) => {
    // Access attributes defined in your GeoJSON properties
    const fillColor = feature.getProperty('background_color') || '#4285F4';
    const opacity = parseFloat(feature.getProperty('opacity')) || 0.5;
    const strokeColor = feature.getProperty('border_color') || '#34A853';

    return {
      fillColor: fillColor,
      fillOpacity: opacity,
      strokeColor: strokeColor,
      strokeWeight: 2,
      visible: true
    };
  });
}

Để biết thêm thông tin về cách sử dụng Lớp dữ liệu, hãy xem tài liệu Nhập GeoJSON vào Maps.

Lộ trình di chuyển: Kết xuất phía máy khách bằng các thư viện của bên thứ ba

Đối với những nhà phát triển đang tìm kiếm các lựa chọn thay thế khác cho KmlLayer, có một số thư viện do cộng đồng duy trì để hiển thị dữ liệu KML trên API JavaScript của Nền tảng Google Maps.

1. deck.gl

deck.gl là một khung hình ảnh hoá hiệu suất cao dựa trên WebGL. Bạn có thể sử dụng công cụ này như một giải pháp thay thế gần như hoàn hảo cho việc kết xuất KML thông qua GoogleMapsOverlayGeoJsonLayer.

  • Yêu cầu về Canvas: Để sử dụng deck.gl một cách hiệu quả, bạn phải chuyển đổi bản đồ để sử dụng loại bản đồ vectơ (kết xuất thành phần canvas) với các chức năng kết xuất WebGL.
  • Hỗ trợ KML: Phân tích cú pháp hình học được xử lý bằng @loaders.gl/kml, chuyển đổi KML thành GeoJSON. Xin lưu ý rằng một số tính năng KML như kiểu phức tạp, biểu tượng và NetworkLink có thể yêu cầu bạn triển khai thêm theo cách thủ công.
  • Tài liệu: Tài liệu về deck.gl | Trình tải KML loaders.gl.
  • Ví dụ:
    • Mẫu deckgl-kml-updated trên kho lưu trữ Google Maps GitHub minh hoạ cách dùng deck.gl để hiển thị dữ liệu KML được cập nhật theo thời gian thực.
    • Mẫu deckgl-kml minh hoạ cách sử dụng deck.gl để kết xuất dữ liệu KML.

2. geoxml3

geoxml3 là một trình xử lý KML được thiết kế riêng cho API JavaScript phiên bản 3 của Google Maps. Thư viện này phân tích cú pháp KML cục bộ trong trình duyệt và hiển thị dữ liệu dưới dạng các đối tượng API Google Maps tiêu chuẩn như Điểm đánh dấu, Đường nhiều đoạn và Đa giác.

  • Hỗ trợ bản đồ tiêu chuẩn: Không giống như các giải pháp dựa trên WebGL, geoxml3 hoạt động trên các bản đồ API JS v3 tiêu chuẩn của Google Maps mà không yêu cầu chế độ kết xuất cụ thể.
  • Điều cần chú ý:
    • Hỗ trợ hạn chế đối với KMZ: Thư viện này không hỗ trợ đầy đủ các tệp KMZ một cách tự nhiên; việc giải nén các tệp lưu trữ KMZ thường yêu cầu tích hợp với các tập lệnh bổ sung của bên thứ ba, chẳng hạn như ZipFile.complete.js.
    • Các phần tử không được hỗ trợ: Các tính năng như hình học 3D, nhãn phức tạp và một số phần tử KML mới hơn không được hỗ trợ.
  • Tài liệu: Kho lưu trữ geoxml3 trên GitHub.

Tệp KML có các phần tử tương tác

Đề xuất di chuyển: Định kiểu dựa trên dữ liệu cho tập dữ liệu

Đối với những nhà phát triển di chuyển từ KmlLayer sang Định kiểu dựa trên dữ liệu (DDS) cho tập dữ liệu, hướng dẫn này giải thích cách chuyển đổi từ các hoạt động tương tác KML tự động sang các hoạt động tương tác tuỳ chỉnh, hiệu suất cao như nhấp chuột và di chuột.

Thiết lập ban đầu

Trước khi triển khai các hoạt động tương tác, hãy đảm bảo bạn đã làm theo các bước thiết lập trong hướng dẫn Di chuyển KML: Dữ liệu vectơ:

  • Mã bản đồ: Định cấu hình mã bản đồ cho loại Bản đồ vectơ.
  • Tải lên: Tải dữ liệu KML lên Google Cloud Console để nhận Mã nhận dạng tập dữ liệu.
  • Quyền truy cập vào lớp: Sử dụng map.getDatasetFeatureLayer(datasetId) để truy cập vào lớp tương tác.

1. Xử lý sự kiện tương tác

Trong KmlLayer, các lượt nhấp vào đối tượng được API xử lý tự động để hiển thị một cửa sổ thông tin. Với DDS cho tập dữ liệu, bạn phải đăng ký trình nghe cho các sự kiện chuột trên lớp tập dữ liệu theo cách thủ công.

  • click: Kích hoạt khi người dùng nhấp vào một tính năng.
  • mousemove: Kích hoạt khi con trỏ di chuyển qua một đối tượng, hữu ích cho hiệu ứng di chuột.

2. Tạo kiểu linh động (Hiệu ứng di chuột)

Vì các kiểu DDS được áp dụng trên toàn cục cho lớp, bạn nên duy trì một biến trạng thái để theo dõi tính năng nào đang được tương tác và áp dụng lại kiểu.

let currentFeatureId = null;

function initInteraction(map, datasetId) {
  const datasetLayer = map.getDatasetFeatureLayer(datasetId);

  // Apply the style function
  datasetLayer.style = (params) => {
    const isHovered = params.feature.datasetAttributes['id'] === currentFeatureId;
    return {
      strokeColor: 'green',
      strokeWeight: isHovered ? 4.0 : 2.0, // Bold border on hover
      fillColor: 'green',
      fillOpacity: isHovered ? 0.5 : 0.3,
    };
  };

  // Add interaction listeners
  datasetLayer.addListener('mousemove', (event) => {
    if (event.features.length > 0) {
      currentFeatureId = event.features[0].datasetAttributes['id'];
      datasetLayer.style = datasetLayer.style; // Re-apply style to reflect changes
    }
  });

  // Clear hover state when the mouse leaves the features
  map.addListener('mousemove', () => {
    if (currentFeatureId !== null) {
      currentFeatureId = null;
      datasetLayer.style = datasetLayer.style;
    }
  });
}

3. Hiển thị HTML từ Thuộc tính description

Trong KML, thẻ <description> thường chứa HTML cho cửa sổ thông tin mặc định. Khi dữ liệu này được nhập dưới dạng một tập dữ liệu, description sẽ trở thành một thuộc tính đối tượng. Để hiển thị, hãy truyền trực tiếp chuỗi đến một google.maps.InfoWindow tiêu chuẩn.

const infoWindow = new google.maps.InfoWindow();

datasetLayer.addListener('click', (event) => {
  if (event.features.length > 0) {
    const feature = event.features[0];
    // Access the HTML description attribute
    const htmlContent = feature.datasetAttributes['description'];

    infoWindow.setContent(htmlContent);
    infoWindow.setPosition(event.latLng);
    infoWindow.open(map);
  }
});

4. InfoWindow tuỳ chỉnh bằng ExtendedData

Nếu KML của bạn sử dụng <ExtendedData> để lưu trữ các cặp tên/giá trị tuỳ chỉnh, thì các cặp này sẽ được liên kết với datasetAttributes. Bạn có thể lặp lại các thuộc tính này để tạo một màn hình HTML tuỳ chỉnh.

function createCustomContent(feature) {
  const attributes = feature.datasetAttributes;
  const container = document.createElement("div");
  container.style.padding = "10px";
  container.innerHTML = "<h3>Feature Details</h3><dl></dl>";

  const dl = container.querySelector("dl");

  // Iterate through all data attributes imported from KML ExtendedData
  for (const key in attributes) {
    const dt = document.createElement("dt");
    dt.style.fontWeight = "bold";
    dt.textContent = key;

    const dd = document.createElement("dd");
    dd.textContent = attributes[key];

    dl.appendChild(dt);
    dl.appendChild(dd);
  }
  return container;
}

datasetLayer.addListener('click', (event) => {
  if (event.features.length > 0) {
    const content = createCustomContent(event.features[0]);
    infoWindow.setContent(content);
    infoWindow.setPosition(event.latLng);
    infoWindow.open(map);
  }
});

Để biết thêm các kỹ thuật trực quan hoá nâng cao, hãy xem tài liệu dành cho nhà phát triển về cách tạo kiểu cho các đối tượng dữ liệu.

Đề xuất di chuyển: Kết xuất phía máy khách bằng GeoJSON

Đối với những nhà phát triển di chuyển từ KmlLayer sang tính năng kết xuất phía máy khách bằng GeoJSON và Lớp dữ liệu, hướng dẫn này giải thích cách chuyển đổi từ các hoạt động tương tác KML tự động sang các hoạt động tương tác tuỳ chỉnh, dựa trên sự kiện và tạo kiểu linh hoạt.

Thiết lập ban đầu

Trước khi triển khai các lượt tương tác, bạn phải chuyển đổi dữ liệu KML sang GeoJSON và tải dữ liệu đó vào Lớp dữ liệu. Hãy tham khảo hướng dẫn Đề xuất di chuyển: Kết xuất phía máy khách bằng GeoJSON để biết thông tin chi tiết về cách sử dụng các công cụ như ogr2ogr hoặc togeojson và khởi tạo bản đồ bằng map.data.loadGeoJson().

1. Tương tác tự động so với tương tác thủ công

Điểm khác biệt chính giữa các lớp này là cách chúng xử lý hoạt động đầu vào của người dùng:

  • KmlLayer: Tự động xử lý các lượt nhấp vào đối tượng và hiển thị một InfoWindow chứa dữ liệu KML.
  • Lớp dữ liệu: Không tự động hiển thị các đối tượng InfoWindow. Bạn phải thêm trình nghe sự kiện theo cách thủ công để ghi lại các lượt tương tác của người dùng và viết mã để hiển thị dữ liệu.

2. Xử lý sự kiện tương tác

Để làm cho các đối tượng GeoJSON có tính tương tác, hãy sử dụng phương thức addListener() trên đối tượng map.data. Các sự kiện thường gặp bao gồm:

  • click: Dùng để kích hoạt cửa sổ thông tin hoặc logic lựa chọn.
  • mouseover / mouseout: Dùng cho hiệu ứng di chuột và làm nổi bật.

3. Hiển thị nội dung mô tả HTML trong một InfoWindow

Khi KML được chuyển đổi thành GeoJSON, thẻ <description> (thường chứa HTML) thường được liên kết với một thuộc tính có tên là description. Bạn có thể dùng feature.getProperty('description') để truy xuất chuỗi này và hiển thị chuỗi đó bên trong một google.maps.InfoWindow tiêu chuẩn.

const infoWindow = new google.maps.InfoWindow();

// Handle clicks to show the HTML description
map.data.addListener('click', (event) => {
  // Access the 'description' property from the GeoJSON feature
  const htmlContent = event.feature.getProperty('description');

  if (htmlContent) {
    infoWindow.setContent(htmlContent);
    infoWindow.setPosition(event.latLng);
    infoWindow.open(map);
  }
});

4. Custom InfoWindows và ExtendedData

Nếu KML ban đầu của bạn sử dụng <ExtendedData>, thì các cặp tên-giá trị này sẽ được chuyển đổi thành các thuộc tính GeoJSON. Vì Lớp dữ liệu không có giao diện người dùng mặc định cho các lớp này, nên bạn phải triển khai một InfoWindow tuỳ chỉnh để lặp lại và hiển thị chúng.

Bạn có thể truy cập vào các thuộc tính này bằng event.feature.getProperty('attribute_name') và tạo một chuỗi HTML tuỳ chỉnh hoặc phần tử DOM để truyền đến phương thức infoWindow.setContent().

5. Tạo kiểu linh hoạt (Hiệu ứng di chuột)

Lớp Dữ liệu cho phép bạn cập nhật các kiểu đối tượng theo phương thức lập trình để phản hồi các sự kiện. Sử dụng overrideStyle() để tạm thời thay đổi giao diện của một thành phần (ví dụ: khi di chuột) và revertStyle() để quay lại kiểu chung.

// Set a base style for all features
map.data.setStyle({
  fillColor: 'blue',
  strokeWeight: 1
});

// Highlight feature on mouseover
map.data.addListener('mouseover', (event) => {
  map.data.revertStyle(); // Clear previous highlights
  map.data.overrideStyle(event.feature, {strokeWeight: 8});
});

// Revert style on mouseout
map.data.addListener('mouseout', (event) => {
  map.data.revertStyle();
});

Để biết thông tin chi tiết hơn về cách triển khai, hãy xem tài liệu về Lớp dữ liệu: Xử lý sự kiệnLớp dữ liệu: Định kiểu động.

Lộ trình di chuyển: Kết xuất phía máy khách bằng các thư viện của bên thứ ba

Đối với những nhà phát triển di chuyển từ KmlLayer sang các giải pháp của bên thứ ba, hướng dẫn này tập trung vào việc xử lý dữ liệu tương tác, chẳng hạn như lượt nhấp chuột và các sự kiện động bằng cách sử dụng deck.glgeoxml3.

Thiết lập ban đầu

Trước khi triển khai các lượt tương tác, hãy đảm bảo bạn đã làm theo các bước thiết lập trong hướng dẫn Lộ trình di chuyển: Kết xuất phía máy khách bằng các thư viện của bên thứ ba. Nội dung như vậy bao gồm:

  • deck.gl: Chuyển đổi bản đồ để sử dụng Loại bản đồ vectơ (yêu cầu về canvas).
  • geoxml3: Phân phát các tập lệnh thư viện từ máy chủ của riêng bạn và quản lý Cơ chế chia sẻ tài nguyên trên nhiều nguồn gốc (CORS).

1. Dữ liệu tương tác với deck.gl

deck.gl hỗ trợ KML dưới dạng định dạng đầu vào trực tiếp và tự động xử lý các hoạt động tương tác với đối tượng như lượt nhấp dựa trên dữ liệu được cung cấp trong tệp KML.

  • Xử lý KMLLoader: Khi sử dụng mô-đun @loaders.gl/kml, hình học và các thuộc tính sẽ được phân tích cú pháp thành một định dạng mà deck.gl dùng để kích hoạt các sự kiện tương tác một cách tự nhiên.
  • Số lượt nhấp vào đối tượng: Khi một đối tượng được nhấp vào, deck.gl có thể ghi lại sự kiện và hiển thị siêu dữ liệu được liên kết (chẳng hạn như <name> hoặc <description>).
  • Ví dụ: Mẫu deckgl-kml-updated minh hoạ việc kết xuất KML theo thời gian thực, trong đó khi di chuột lên các điểm đánh dấu động đất, thông tin chi tiết về sự kiện sẽ xuất hiện.

2. Dữ liệu tương tác với geoxml3

geoxml3 phân tích cú pháp KML cục bộ trong trình duyệt, trích xuất thông tin về kiểu và tạo các đối tượng API Google Maps tiêu chuẩn vẫn giữ được tính tương tác.

  • Trích xuất kiểu gốc: Thư viện này lấy các phần tử <Style><StyleMap> từ KML để áp dụng cho các điểm đánh dấu, đường nhiều đoạn và đa giác được tạo.
  • Trình xử lý lượt nhấp: Theo mặc định, geoxml3 cung cấp trình xử lý lượt nhấp cho các đối tượng này. Bạn cũng có thể xác định các hàm gọi lại tuỳ chỉnh (createMarker, createOverlay) trong quá trình khởi tạo trình phân tích cú pháp để triển khai logic lựa chọn hoặc nội dung cập nhật thanh bên của riêng bạn.
  • Ví dụ: Ví dụ này minh hoạ cách sử dụng geoxml3 để hiển thị KML, với các chế độ tuỳ chỉnh như điểm đánh dấu hình tròn có tương tác, chẳng hạn như nhấp vào điểm đánh dấu để hiển thị thông tin về trận động đất.
  • Mẫu sử dụng:
var myParser = new geoXML3.parser({
  map: map,
  processStyles: true, // Automatically handle KML styles
  afterParse: function(doc) {
    // Code to run after the KML is fully parsed
  }
});
myParser.parse('interactive_data.kml');

Tệp KML có hình ảnh

Đối với những nhà phát triển sử dụng KmlLayer để hiển thị hình ảnh (chẳng hạn như bản đồ có dữ liệu từ vệ tinh, hình thái thời tiết hoặc bản thiết kế cũ), hướng dẫn này trình bày các đường dẫn di chuyển đến GroundOverlays hoặc trình phân tích cú pháp của bên thứ ba.

Đề xuất di chuyển: GroundOverlay của Maps JavaScript API

Bạn nên sử dụng lớp google.maps.GroundOverlay để di chuyển hình ảnh. Điều này cho phép bạn đặt hình ảnh lên bản đồ tại các toạ độ địa lý cụ thể ngay trong mã của mình.

1. Triển khai

Thay vì dựa vào tệp KML để xác định ranh giới, bạn chỉ định URL của hình ảnh và một đối tượng LatLngBounds đại diện cho hình chữ nhật trên bản đồ.

  • Tài liệu: Hướng dẫn về lớp phủ trên mặt đất.
  • Chuẩn bị hình ảnh: Nếu hình ảnh của bạn được tham chiếu địa lý nhưng không có phép chiếu chính xác (EPSG:4326), bạn có thể sử dụng công cụ nguồn mở gdalwarp để biến dạng hình ảnh nhằm sử dụng với Maps JS API.
gdalwarp -t_srs EPSG:4326 image.jp2 image.jpg

Đường dẫn di chuyển: Sử dụng thư viện của bên thứ ba

Nếu quy trình làm việc yêu cầu bạn giữ dữ liệu ở định dạng KML, thì bạn có thể sử dụng các thư viện bên thứ ba như geoxml3 hoặc deck.gl để hiển thị lớp phủ hình ảnh.

Tuyên bố từ chối trách nhiệm: Các giải pháp của bên thứ ba này không được Google hỗ trợ. Tuy nhiên, các API này đã được kiểm thử và sẽ hoạt động trong hầu hết các trường hợp sử dụng.

1. geoxml3

geoxml3 là một lựa chọn phù hợp để phân tích cú pháp các phần tử GroundOverlay đơn giản cục bộ trong trình duyệt và chuyển đổi chúng thành các đối tượng API Google Maps.

Ví dụ về cách sử dụng:

const geoXmlParser = new geoXML3.parser({
    map: map,
    afterParse: function(doc) {
        console.log("Parsing complete. Number of documents: " + doc.length);
        const bounds = doc[0].gbounds;
        if (bounds && !bounds.isEmpty()) {
           map.fitBounds(bounds);
        }
    },
    createOverlay: function(groundOverlayData) {
        // Extract bounds and URL from parsed KML data
        const imageUrl = groundOverlayData.icon.href;
        const imageBounds = {
            north: parseFloat(groundOverlayData.latLonBox.north),
            south: parseFloat(groundOverlayData.latLonBox.south),
            east: parseFloat(groundOverlayData.latLonBox.east),
            west: parseFloat(groundOverlayData.latLonBox.west)
        };

        // Create the Google Maps GroundOverlay
        const nativeOverlay = new google.maps.GroundOverlay(imageUrl, imageBounds);
        nativeOverlay.setMap(map);
    }
});
geoXmlParser.parse('your_file.kml');

2. deck.gl

Mặc dù GeoJsonLayer tiêu chuẩn của deck.gl xử lý dữ liệu vectơ, nhưng nó cũng có thể hỗ trợ GroundOverlays thông qua một quy trình triển khai thủ công bằng cách sử dụng BitmapLayer.

Phương pháp này liên quan đến việc tận dụng KMLLoader để phân tích cú pháp tệp, sau đó xác định rõ ràng một BitmapLayer bằng URL hình ảnh và toạ độ được trích xuất từ dữ liệu KML.

  • Yêu cầu: Để sử dụng deck.gl, bạn phải dùng loại Bản đồ vectơ.
  • Tài liệu: Lớp bitmap deck.gl

Trường hợp nâng cao: Kim tự tháp ô sử dụng gdal2tiles

Đối với các tệp KML phức tạp chứa các kim tự tháp ô hình ảnh, việc di chuyển sẽ khó khăn hơn và yêu cầu bạn phải trích xuất dữ liệu hình ảnh.

  • Công cụ: gdal2tiles có thể trích xuất dữ liệu từ một kim tự tháp KMZ và tạo mã API Maps JavaScript tiêu chuẩn để hiển thị các ô. Xin lưu ý rằng bạn có thể phải sửa đổi kết quả cuối cùng theo cách thủ công để kết hợp vào bản đồ hiện có.
gdal2tiles -z 10- -n -u https://yourhost.com/tiles/ -w google input.kmz

Việc xử lý tệp KML bằng đường liên kết mạng đòi hỏi phải chuyển từ việc tìm nạp tự động KmlLayer phía đám mây sang các chiến lược quản lý dữ liệu rõ ràng hơn.

Giải pháp được hỗ trợ: Định kiểu dựa trên dữ liệu (DDS) cho tập dữ liệu

Vì các tập dữ liệu của Google Maps Platform không phân tích cú pháp các phần tử <NetworkLink> một cách tự nhiên, nên bạn phải chọn một chiến lược di chuyển dựa trên cấu trúc dữ liệu của mình:

  • Chiến lược A: Tập dữ liệu riêng biệt (Phù hợp nhất cho các lớp do người dùng kiểm soát) Tải từng tệp KML từng là một đường liên kết mạng lên dưới dạng tập dữ liệu riêng trong Google Cloud Console. Sau đó, bạn có thể dùng JavaScript để tải và hiển thị các lớp này một cách linh động khi cần bằng cách gọi map.getDatasetFeatureLayer(datasetId) và điều chỉnh chế độ hiển thị hoặc kiểu của lớp.
  • Chiến lược B: Tệp KML được đơn giản hoá (Phù hợp nhất cho màn hình hiệu suất cao) Kết hợp tất cả các đối tượng từ nhiều tệp được liên kết với mạng thành một tệp KML toàn diện duy nhất trước khi tải tệp đó lên dưới dạng một tập dữ liệu. Sau đó, bạn có thể sử dụng kiểu động dựa trên các thuộc tính của đối tượng để lọc và hiển thị các nhóm nhỏ dữ liệu cụ thể ngay lập tức.

Cập nhật dữ liệu động: Để mô phỏng hành vi "tự động làm mới" của các đường liên kết mạng, hãy sử dụng Datasets API để tải lên theo cách lập trình một phiên bản mới của tập dữ liệu bất cứ khi nào dữ liệu nguồn thay đổi.

Giải pháp nguồn mở: deck.gl và geoxml3

Cả deck.glgeoxml3 đều không hỗ trợ mạnh mẽ việc phân tích cú pháp và tự động tìm nạp các phần tử <NetworkLink> KML.

deck.gl

deck.gl sử dụng KMLLoader (được xây dựng trên togeojson), không hỗ trợ NetworkLinks một cách rõ ràng.

  • Tại sao đây không phải là một giải pháp tốt: Trình phân tích cú pháp được thiết kế để trở thành một trình chuyển đổi đồng bộ, "không phức tạp", tránh đưa ra các yêu cầu mạng riêng để đảm bảo độ tin cậy và tính đơn giản. Nếu ứng dụng của bạn dựa vào các tệp KML trỏ đến nhiều URL khác, thì deck.gl sẽ không tự động phân giải các URL đó.

geoxml3

Mặc dù geoxml3 được phát triển để phân tích cú pháp KML cho Maps JS API, nhưng khả năng hỗ trợ các đường liên kết mạng của geoxml3thử nghiệm và không được duy trì.

  • Lý do đây không phải là một giải pháp tốt: Chức năng này chỉ tồn tại trong một nhánh "network_link" cụ thể, đã cũ và chưa được kiểm thử kỹ lưỡng. Bạn không nên sử dụng phương thức này để di chuyển dữ liệu sản xuất, vì phương thức này có thể không xử lý được các cấu trúc liên kết phức tạp hoặc các yêu cầu bảo mật hiện đại như CORS.

Đề xuất tóm tắt

Để di chuyển một cách đáng tin cậy, nhà phát triển nên tránh sử dụng trình phân tích cú pháp của bên thứ ba cho các tệp có đường liên kết mạng và thay vào đó, hãy tạo lại logic tìm nạp dữ liệu bằng Datasets API. Điều này đảm bảo dữ liệu của bạn được quản lý an toàn trong cơ sở hạ tầng của Nền tảng Google Maps thay vì dựa vào các trình phân tích cú pháp phía máy khách không được duy trì.

Sử dụng KML để hiển thị Lớp phủ màn hình

Đối với những nhà phát triển di chuyển từ KmlLayer sang các lựa chọn thay thế hiện đại như Định kiểu dựa trên dữ liệu (DDS), bạn cần lưu ý rằng Lớp phủ màn hình không được hỗ trợ trong Tập dữ liệu. Để đạt được hiệu ứng tương tự khi hiển thị hình ảnh, biểu trưng hoặc chú thích cố định ở trên cùng của bản đồ, bạn phải tạo Chế độ kiểm soát tuỳ chỉnh bằng Maps JavaScript API.

1. Nội dung cần tìm trong tệp KML

Để tạo một Chế độ kiểm soát tuỳ chỉnh tương đương, hãy kiểm tra phần tử <ScreenOverlay> trong tệp KML để tìm các thuộc tính khoá sau:

  • <Icon>&lt;href>: URL của hình ảnh mà bạn muốn hiển thị.
  • <screenXY>: Thuộc tính này xác định vị trí của lớp phủ trên màn hình.
    • x=0, y=1 (phân số) tương ứng với Trên cùng bên trái.
    • x=1, y=1 tương ứng với Trên cùng bên phải.
    • x=0, y=0 tương ứng với Dưới cùng bên trái.
    • x=1, y=0 tương ứng với Dưới cùng bên phải.
  • <size>: Xác định chiều rộng và chiều cao của lớp phủ.
  • <rotation>: Cho biết liệu hình ảnh có cần xoay hay không.

2. Triển khai: Tạo chế độ kiểm soát tuỳ chỉnh

Về cơ bản, Chế độ kiểm soát tuỳ chỉnh là một phần tử HTML tiêu chuẩn (chẳng hạn như <div> hoặc <img>) mà bạn "đẩy" vào một trong các vị trí được xác định trước của bản đồ.

Ánh xạ vị trí KML đến ControlPosition

Maps JavaScript API sử dụng enum ControlPosition để cố định các chế độ kiểm soát. Sử dụng bảng bên dưới để liên kết <screenXY> KML với hằng số JS API thích hợp:

Vị trí KML (screenXY) JS API ControlPosition
Trên cùng bên trái (x:0, y:1) TOP_LEFT (Phiên bản cũ) hoặc BLOCK_START_INLINE_START (Logic)
Trên cùng bên phải (x:1, y:1) TOP_RIGHT hoặc BLOCK_START_INLINE_END
Dưới cùng bên trái (x:0, y:0) BOTTOM_LEFT hoặc BLOCK_END_INLINE_START
Dưới cùng bên phải (x:1, y:0) BOTTOM_RIGHT hoặc BLOCK_END_INLINE_END

3. Ví dụ về quá trình di chuyển: Lớp phủ biểu trưng cố định

Ví dụ sau đây mô phỏng một biểu trưng KML ScreenOverlay được đặt ở vị trí Trên cùng bên phải của bản đồ.

Tạo kiểu CSS

Sử dụng CSS để xác định kích thước và giao diện của "lớp phủ".

#logo-control {
  padding: 10px;
  background-color: rgba(255, 255, 255, 0.8);
  margin: 10px;
  border-radius: 2px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.3);
}

#logo-control img {
  width: 150px; /* Equivalent to KML <size> */
  display: block;
}

Triển khai JavaScript

Thêm phần tử vào mảng map.controls.

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 12,
    center: { lat: 41.85, lng: -87.65 },
  });

  // 1. Create the container for the overlay
  const logoControlDiv = document.createElement("div");
  logoControlDiv.id = "logo-control";

  // 2. Create the image (KML <Icon>)
  const logoImage = document.createElement("img");
  logoImage.src = "https://example.com/logo.png";
  logoImage.alt = "Company Logo";

  logoControlDiv.appendChild(logoImage);

  // 3. Position the control (KML <screenXY>)
  // In this case, we use TOP_RIGHT
  map.controls[google.maps.ControlPosition.TOP_RIGHT].push(logoControlDiv);
}

Thông tin khác