在 React 中使用 leaflet.offline ?

2023-11-23

我正在开发一个 React 应用程序,并且正在尝试实现一个支持离线下载地图图块的 Leaflet 地图。为此我想到使用 leaflet.offline (https://github.com/allartk/leaflet.offline),但我不确定如何在 React 中使用这个库?

如何将 leaflet.offline 与 React 结合使用,或者是否有任何特定于 React 的库支持使用 Leaflet 离线下载地图图块?

谢谢你的帮助!


编辑:好的,所以旧的解决方案工作得很好,但它需要直接从Leaflet Offline包下载文件,并修改它们,这并不理想。我现在已经成功地将 Leaflet Offline 包与 npm 和 React 一起使用。我建议首先阅读下面发布的旧解决方案,因为新解决方案是在此基础上构建的。这就是我所做的:

更新的新解决方案:

1 - 离线安装 Leaflet:npm install leaflet.offline@next

2 - 使用以下命令将 Leaflet Offline 包导入到您的 React 组件中:

import L from "leaflet"; // Remember that this must also be imported
import "leaflet.offline";

3 - 现在看看旧解决方案中的步骤 6。我们现在分别使用 L.tileLayer.offline 和 L.control.savetiles,而不是使用“generateOfflineTilelayer”和“generateControlSavetiles”。如果您像我一样使用 TypeScript,请在​​代码行上方添加 ts-ignore 作为注释,以防止由 TypeScript 引起的任何错误。因此,第 6 步中的 useEffect 代码现在如下所示:

useEffect(() => {
  if(map){

    // @ts-ignore
    const tileLayerOffline = L.tileLayer.offline(
      "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
      {
        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
        minZoom: 13,
      }
    );

    tileLayerOffline.addTo(map);

    // @ts-ignore
    const controlSaveTiles = L.control.savetiles(
      tileLayerOffline, 
      {
        zoomlevels: [13, 14, 15, 16], // optional zoomlevels to save, default current zoomlevel
      }
    );

    controlSaveTiles.addTo(map!);
  }
}, [map]);

4 - 地图现在应该按预期工作。在尝试导入 leaflet.offline 时,我确实遇到了缺少声明文件的问题。对我来说,这个问题奇怪地只存在于我的一个组件中,而不存在于其他组件中。如果您遇到同样的问题,您可以尝试按照 IDE 的建议创建一个声明文件,或者您可以尝试在 import 语句的正上方添加“// @ts-ignore”。希望这对某人有帮助:)


旧解决方案:

好吧,所以我从来没有在网上找到任何人可以解决这个问题,但经过一些尝试和错误后,我已经解决了这个问题。我之所以希望能够在Leaflet中下载地图以供离线使用,是因为我正在使用Ionic、Capacitor和React制作一个手机应用程序。可能值得一提的是我也在使用打字稿。

为了其他人的利益,我将在下面发布有关如何实现此工作的指南。希望这能防止其他人经历我所经历的同样的挫折:D

所以我在使用 Leaflet.offline 插件时遇到的问题是 Leaflet.tileLayer.offline 或 Leaflet.control.saveTiles 无法被识别(可能是由于使用了 React)。以下是我为使离线地图正常工作而采取的步骤:

1 - 我最初是通过 npm 包使用 leaflet.offline 。我们想要更改插件,以便我们不再依赖插件对 Leaflet.tileLayer.offline 或 Leaflet.control.saveTiles 的使用。我们想要的是创建一些返回这两个提到的类的实例的方法,然后我们可以将这些方法导入到我们的 React 组件中。最简单的方法是不通过 npm 使用插件,而是直接下载插件的文件。因此,您应该做的第一件事是下载在插件的 GitHub 页面上找到的 leaflet.offline/src 文件夹内容的副本(https://github.com/allartk/leaflet.offline/tree/master/src)。您应该下载的文件是 ControlSaveTiles.js、TileLayerOffline.js 和 TileManager.js。

2 - 现在在您的 React 项目中创建一个文件夹。我将我的名称命名为 LeafletMapOfflinePlugin,但您可以将其命名为任何您想要的名称。然后将您下载的文件移动到该文件夹​​中。

3 - 打开 TileLayerOffline.js 文件,并将以下代码粘贴到文件底部。这将导出一个可用于创建 TileLayerOffline 类的新实例的函数,以便我们不再依赖 L.tileLayer.offline:

// Export a function that generates an offfline tilelayer-object, 
// as the above expansion of L.tileLayer.offline doesn't work
export function generateOfflineTilelayer(url, options) {
  return new TileLayerOffline(url, options)
}

4 - 打开 ControlSaveTiles.js 文件,并将以下代码粘贴到文件底部。这将导出一个可用于创建 ControlSaveTiles 类的新实例的函数,以便我们不再依赖 L.control.saveTiles:

// Export a function that generates a savetiles-object,
// as the above expansion of L.control.savetiles doesn't work
export function generateControlSavetiles(baseLayer, options) {
  return new ControlSaveTiles(baseLayer, options);
}

5 - 现在可以使用以下导入将它们导入到任何 React 组件中:

import { generateOfflineTilelayer } from "<path-to-TileLayerOffline.js>";
import { generateControlSavetiles } from "<path-to-ControlSaveTiles.js>";

6 - 下面是如何在 React 组件(使用 TypeScript)中使用它的简单示例。这里我们使用useState存储MapContainer对象,并在useEffect中使用它来手动设置tileLayer和控件:

import L, { Map } from "leaflet";
import { MapContainer } from "react-leaflet";
import { generateOfflineTilelayer } from "<path-to-TileLayerOffline.js>";
import { generateControlSavetiles } from "<path-to-ControlSaveTiles.js>";
import React, { useState } from "react";


const LeafletMap: React.FC<LeafletMapProps> = () => {
  const [map, setMap] = useState<Map | undefined>();
  
  useEffect(() => {
    if(map){
      const tileLayerOffline = generateOfflineTilelayer(
        "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        {
          attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
          minZoom: 13,
        }
      );

      tileLayerOffline.addTo(map);

      const controlSaveTiles = generateControlSavetiles(
        tileLayerOffline, 
        {
          zoomlevels: [13, 14, 15, 16], // optional zoomlevels to save, default current zoomlevel
        }
      );

      controlSaveTiles.addTo(map!);
    }
  }, [map]);
  
  return(
    <MapContainer
      style={{ width: "100vw", height: "20vh" }}
      center={[63.446827, 10.421906]}
      zoom={13}
      scrollWheelZoom={false}
      whenCreated={setMap}
    >
    </MapContainer>
  )
}

7 - 您现在应该有一个带有控制元素的简单 Leaflet-map,当“+”(不要与用于缩放的“+”混淆。“+”是 leaflet.offline 的控制元素的默认值时,并且可以通过查看 leaflet.offline 的文档进行更改)单击后,它会下载并保存地图上当前可见区域的地图图块。如果需要,您可以转到网络浏览器的网络选项卡来检查这些图块的下载。单击“-”(再次强调,不要与缩放按钮混淆)时,所有下载的图块都会被删除。请参见下图,了解使用 leaflet.offline 的 ControlSaveTiles 时地图的外观;用于保存图块的控制元素位于用于缩放的控制元素下方:

Leaflet offline map example

好了,差不多就这样结束了。希望这对某人有帮助:D 还有与传单地图相关的提示;如果您在仅显示地图的一小部分时遇到问题,请尝试使用map.invalidateSize()(如果您的地图容器存储为“地图”)。这将重置并更新传单地图已知的设备宽度,这有望使地图正确渲染:D

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 React 中使用 leaflet.offline ? 的相关文章

随机推荐

  • 向上导航(操作栏的后箭头)不适用于片段

    我将抽屉布局作为我的活动的基本布局 并且我正在替换此抽屉布局内框架上的两个片段 第一个片段不会添加到片段的返回堆栈中 我在我的活动中显示汉堡包图标 我也希望在我的第一个片段中显示抽屉菜单 在第二个片段中 我禁用了汉堡包图标mActionBa
  • 是否可以使用输入值属性作为 CSS 选择器?

    是否可以使用 CSS 选择器来定位具有特定值的输入 示例 如何根据以下内容定位以下输入value United States
  • 使用 py2exe 捆绑 GTK 资源

    我正在使用 Python 2 6 和 PyGTK 2 22 6一体化安装程序在 Windows XP 上 尝试构建一个单文件可执行文件 通过py2exe 对于我的应用程序 我的问题是 当我将我的应用程序作为脚本运行时 即未内置到 exe文件
  • 当 C 预处理器宏定义两次时会发生什么?

    我定义了一个宏两次 如下所示 define a 2 define a 3 我认为任何发生a代码中将替换为2 什么时候 define a 3遇到了就没有了a代码中的 s 可以替换为3 所以2将优先 但是当我执行它的时候a被替换为3 为什么 如
  • 当我使用 XmlSerializer 反序列化时,为什么我的 DbNull 不是单例?

    我一直认为 DbNull value 是一个单例 因此你可以这样做 VB NET If someObject Is DbNull Value Then End if C If someObject DbNull Value 但最近 我使用
  • Azure 数据工厂和 SharePoint

    我有一些 Excel 文件存储在 SharePoint Online 中 我想要将 SharePoint 文件夹中存储的文件复制到 Azure Blob 存储 为了实现这一目标 我使用 Azure 门户在 Azure 数据工厂中创建一个新管
  • 写入RenderTarget后,如何高效克隆输出?

    XNA菜鸟在这里 每天都在学习 我刚刚弄清楚如何使用 RenderTarget2D 将多个纹理合成为一个 然而 虽然我可以将 RenderTarget2D 用作 Texture2D 来满足大多数用途 但有一个关键的区别 当调整后缓冲区大小时
  • Java GUI:文档对象模型

    HTML 有一个文档对象模型 Javascript 可以对其进行操作 移动 当我在 Swing 中创建 GUI 时 模型似乎非常不同 我不知道模型的名称 因为我正在创建布局管理器 并将对象粘贴在其中 我的问题 有没有办法以类似 DOM 的方
  • Safari 不发送“If-Modified-Since”和“If-None-Match”标头

    我正在使用 PHP 生成动态内容 我发送以下 HTTP 标头 HTTP 1 1 304 Not Modified Date Sun 09 Dec 2012 17 24 41 GMT Server Apache Connection keep
  • 规范表示是什么意思及其对网站的潜在漏洞

    我在谷歌上搜索了规范表示的含义 发现了一些非常神秘的文档 任何人都可以快速解释规范表示以及网站中针对规范表示攻击的一些典型漏洞是什么 规范化是获取输入 例如文件名或字符串 并将其转换为标准表示形式的过程 例如 如果您的 Web 应用程序仅允
  • Html.BeginForm 使用 FormMethod.GET 丢失了 RouteValues

    我注意到了什么Html BeginForm 提供的方法编码路线值 into actionFORM 标签的属性 这与 POST 方法配合得很好 但如果方法是 GET 则操作 URL 中的所有参数都会被浏览器删除 在 IE8 和 Firefox
  • 茉莉花期望(resultCode).toBe(200或409)

    对于某些测试场景 我需要针对多个值进行测试 这些值都可以 我想做的是如下 expect resultCode toBeIn 200 409 该规范应该在以下情况下通过 resultCode或者是200 or 409 那可能吗 ADDED感谢
  • 如何从 SQLite 文件恢复 Firefox 书签文件?

    我成功地从 Windows XP 下安装的 Firefox 中恢复了两个文件 第一个是 urlclassifier3 sqlite 第二个是 urlclassifier pset 据我了解 这些文件包含在用户配置文件下安装 Firefox
  • 我应该返回 List 还是 ArrayList?

    我发现自己同意返回一个接口而不是一个具体的类 原因很简单 我想要松耦合 但还会有其他影响或权衡吗 最好返回适合您的界面的最通用类型 如果有什么原因的话ArrayList本质上适合您返回的数据 那么您应该使用它 通常List很好 但你也可以考
  • Firebase 屏幕名称显示未设置

    我创建了一个项目Google Firebase Analytics我可以在控制台中记录屏幕名称 但对于一个屏幕screen view未记录 显示为not set在屏幕视图列表中 我使用了默认函数来记录屏幕视图事件 即 setCurrentS
  • 使用 python 在 2D 列表中搜索以查找 x,y 位置

    我有二维列表 我需要搜索元素的索引 由于我是编程新手 因此我使用了以下函数 def in list c for i in xrange 0 no classes if c in classes i return i return 1 这里的
  • 如何使用 NSNumberFormatter 在 UITextField 中打印货币

    我是这里的N00b 我这样打印我的货币 IBAction buttonPressed1 id sender double currency Amount1 text doubleValue Amount2 text doubleValue
  • KeyCloak 将用户管理限制到某些组,同时启用“管理用户”

    使用 KeyCloak 管理控制台 我尝试制定以下用例 我们有X组和Y组 角色 Group X Admin 可以执行以下操作 可以创建没有组的用户 可以将没有组的用户分配到组 X 可以编辑和管理X组中的用户 无法查看 编辑 管理 Y 组中的
  • AuthenticationCredentialsNotFoundException:在安全上下文中找不到身份验证对象

    当我尝试将 JSON 有效负载从 Chrome 浏览器的 POSTMAN 插件发送到作为 REST URL 公开的控制器时 出现以下错误 http localhost 8080 services account create SEVERE
  • 在 React 中使用 leaflet.offline ?

    我正在开发一个 React 应用程序 并且正在尝试实现一个支持离线下载地图图块的 Leaflet 地图 为此我想到使用 leaflet offline https github com allartk leaflet offline 但我不