Leaflet 地址自动完成与 Geoapify(MapLibre 示例配套)

发布: (2025年12月25日 GMT+8 13:58)
9 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的正文内容,我将把它翻译成简体中文并保持原有的格式、Markdown 语法以及技术术语不变。

Leaflet 版地址自动完成示例

如果您已经看过 MapLibre GL 教程,这个示例遵循相同的用户体验模式:用户可以搜索地址,并在带有标记的交互式地图上看到它。

使用的 API

🧭 目录

第一步:设置 Leaflet 地图

首先加载 Leaflet 并使用 Geoapify 栅格瓦片初始化地图。

引入 Leaflet

从 CDN 添加 CSS 和 JavaScript:

创建地图容器

为容器设置样式

html, body, #map {
  width: 100%;
  height: 100%;
  margin: 0;
}

初始化地图

const myAPIKey = "YOUR_API_KEY";

const map = L.map("map", { zoomControl: false }).setView(
  [38.908838755401035, -77.02346458179596], // Washington DC
  12
);

// Retina displays require different tile quality
const isRetina = L.Browser.retina;

const baseUrl   = "https://maps.geoapify.com/v1/tile/osm-bright/{z}/{x}/{y}.png?apiKey={apiKey}";
const retinaUrl = "https://maps.geoapify.com/v1/tile/osm-bright/{z}/{x}/{y}@2x.png?apiKey={apiKey}";

L.tileLayer(isRetina ? retinaUrl : baseUrl, {
  attribution: 'Powered by [Geoapify](https://www.geoapify.com/) | © OpenMapTiles © OpenStreetMap contributors',
  apiKey: myAPIKey,
  maxZoom: 20
}).addTo(map);

// Add zoom control to bottom‑right
L.control.zoom({ position: "bottomright" }).addTo(map);

注意: Leaflet 使用栅格(PNG)瓦片,而 MapLibre 使用矢量瓦片。Geoapify 同时提供这两种格式。@2x 瓦片用于视网膜显示屏。

🔑 API 密钥: 前往 注册以获取免费 API 密钥。

以华盛顿特区为中心并带有缩放控件的 Leaflet 地图
已使用 Geoapify 栅格瓦片初始化的 Leaflet 地图。

第2步:添加地址自动完成字段

自动完成的设置与 MapLibre 示例完全相同。

引入 Geocoder Autocomplete 库

创建自动完成容器


  
.autocomplete-panel {
  position: absolute;
  top: 10px;
  left: 10px;
  width: 400px;
  z-index: 1002;
}

初始化自动完成小部件

const autocompleteInput = new autocomplete.GeocoderAutocomplete(
  document.getElementById("autocomplete"),
  myAPIKey,
  { /* options */ }
);

无论使用哪种地图库,GeocoderAutocomplete 小部件的工作方式都是相同的。

地址自动完成下拉列表在 Leaflet 地图上显示建议
当用户输入时,自动完成下拉列表会出现。

第 3 步:将选择同步到 Leaflet 地图

当用户选择地址时,平移地图并放置标记。

创建自定义标记图标

使用 Geoapify Map Marker Icon API 生成自定义图钉:

const markerIcon = L.icon({
  iconUrl: `https://api.geoapify.com/v1/icon/?type=awesome&color=%232ea2ff&size=large&scaleFactor=2&apiKey=${myAPIKey}`,
  iconSize: [38, 56],
  iconAnchor: [19, 51],
  popupAnchor: [0, -60]
});

iconAnchor 定义图标的哪个点对应标记的坐标。

在选择时添加标记

let marker; // will hold the current marker

autocompleteInput.on("select", (place) => {
  const { lat, lon } = place.properties;

  // Pan the map to the selected location
  map.setView([lat, lon], 15);

  // Remove previous marker, if any
  if (marker) {
    map.removeLayer(marker);
  }

  // Add new marker
  marker = L.marker([lat, lon], { icon: markerIcon }).addTo(map);
});

现在地图会自动居中到所选地址,并显示自定义标记。

第 4 步:探索演示

将完整的 HTML/JS 代码复制到文件(例如 leaflet-autocomplete.html),并在浏览器中打开。
您应该会看到:

  1. 一个全屏的 Leaflet 地图。
  2. 左上角的自动完成输入框。
  3. 实时地址建议。
  4. 选中地址后自动平移并显示自定义标记。

Summary

  • Leaflet + Geoapify raster tiles → 简单、轻量级的地图。
  • Address Autocomplete API 提供即时建议。
  • Map Marker Icon API 让您可以将标记样式与您的设计匹配。
  • 同一自动完成小部件可在不同的地图库之间使用,轻松在 Leaflet、MapLibre、Mapbox GL 等之间切换。

常见问题

问:栅格瓦片需要付费计划吗?
答:不需要。免费层每月提供大量的栅格瓦片请求额度。

问:我可以更改标记的颜色吗?
答:可以。修改图标 URL 中的 color 参数(十六进制值,例如 %23ff0000 表示红色)。

问:如何将自动完成结果限制在特定国家?
答:在初始化组件时传入 filter 选项,例如 { filter: "countrycode:us" }

问:如果想使用其他地图样式怎么办?
答:将 baseUrl/retinaUrl 替换为其他 Geoapify 样式(例如 osm-darkosm-light)。

随意尝试并将代码适配到自己的项目中吧!

注意: 对于针形图标,它应位于底部尖端附近。

处理 select 事件

let marker;

autocompleteInput.on("select", (location) => {
  // Remove existing marker
  if (marker) {
    marker.remove();
  }

  if (location) {
    // Add marker at the selected location
    marker = L.marker([location.properties.lat, location.properties.lon], {
      icon: markerIcon
    }).addTo(map);

    // Pan to the selected location
    map.panTo([location.properties.lat, location.properties.lon]);
  }
});

注意: Leaflet 使用 [lat, lon],而 MapLibre 使用 [lon, lat]

Leaflet 地图,标记放置在选定的地址位置

选择地址后,地图会平移到该位置并显示标记。

第4步:探索演示

The live CodePen demo shows the complete implementation.

试试以下流程

  • 输入地址 → 从下拉列表中选择 → 地图平移并出现标记
  • 尝试不同主题 → 使用主题选择器切换明暗模式

主题切换器

演示包含一个主题选择器,可同时切换自动完成样式和地图瓦片:

const mapTiles = {
  light: {
    baseUrl: "https://maps.geoapify.com/v1/tile/osm-bright/{z}/{x}/{y}.png?apiKey={apiKey}",
    retinaUrl: "https://maps.geoapify.com/v1/tile/osm-bright/{z}/{x}/{y}@2x.png?apiKey={apiKey}"
  },
  dark: {
    baseUrl: "https://maps.geoapify.com/v1/tile/dark-matter-brown/{z}/{x}/{y}.png?apiKey={apiKey}",
    retinaUrl: "https://maps.geoapify.com/v1/tile/dark-matter-brown/{z}/{x}/{y}@2x.png?apiKey={apiKey}"
  }
};

想要逆向地理编码吗?

对于点击获取地址的功能(点击地图获取地址),请参阅 MapLibre GL tutorial
相同的 Reverse Geocoding API 调用也适用于 Leaflet——只需将 MapLibre 标记代码替换为 Leaflet 的 L.marker()

👉 在交互式演示中尝试一下。

摘要

  • Leaflet 地图 – 支持视网膜显示的栅格瓦片
  • 地址自动完成 – 与 MapLibre 相同的 Geoapify 小部件
  • 自定义标记 – 使用 Marker Icon API

与 MapLibre 的主要区别

  • Leaflet 使用栅格(PNG)瓦片;MapLibre 使用矢量瓦片。
  • 坐标顺序:Leaflet [lat, lon],MapLibre [lon, lat]
  • 标记创建方式:L.marker()maplibregl.Marker()

有用链接

常见问题

问:Leaflet 与 MapLibre 有何区别?
答:Leaflet 使用栅格(PNG)瓦片,体积更轻。MapLibre 使用矢量瓦片,支持 3D,并提供更流畅的缩放。两者都能很好地配合 Geoapify API 使用。

问:如何将自动完成结果限制在特定国家?
答:使用 filter 选项配合 countrycoderect(边界框)或 circle 参数。例如:

filter: { countrycode: ["us", "ca"] }

将结果限制在美国和加拿大。参见 地址自动完成 API 文档

问:我可以在 React 或 Angular 中使用自动完成吗?
答:可以。提供了专用的封装库:

问:在编写代码之前,我如何试验这些 API?
答:使用我们的交互式 Playground:

立即尝试

👉 打开实时演示

geoapify.com 注册并获取免费 API 密钥,开始构建带地址自动完成的 Leaflet 地图。

Back to Blog

相关文章

阅读更多 »