React-leaflet + leaflet.elevation 用法

问题描述 投票:0回答:2

我发帖是为了看看是否有人可以给我一些关于这个“问题/问题”的线索。 我正在使用react-leaflet和leaflet-elevation,这是一个“插件”,可以创建海拔图并添加一些额外的东西

从下图中可以看到,L.control.elevation 正在被解释(我是这样导入的: import "leaflet.elevation/dist/Leaflet.Elevation-0.0.2.min.js";

Console.log of the function.

但是编译我得到这个:

Error message from the console.

谢谢。

编辑:添加更多信息

所以就代码而言:

地图组件(更新)

import React from "react";
import { MapContainer, TileLayer, Marker, Popup, useMap } from "react-leaflet";
import L from "leaflet";
import 'leaflet.elevation/dist/Leaflet.Elevation-0.0.2.min.js'
import "./Map.css";

const Map = () => {

  function InitProfile() {
    var elevation_options = {
      // Default chart colors: theme lime-theme, magenta-theme, ...
      theme: "lightblue-theme",
      // Chart container outside/inside map container
      detached: true,
      // if (detached), the elevation chart container
      elevationDiv: "#elevation-div",
      // if (!detached) autohide chart profile on chart mouseleave
      autohide: false,
      // if (!detached) initial state of chart profile control
      collapsed: false,
      // if (!detached) control position on one of map corners
      position: "topright",
      // Toggle close icon visibility
      closeBtn: true,
      // Autoupdate map center on chart mouseover.
      followMarker: true,
      // Autoupdate map bounds on chart update.
      autofitBounds: true,
      // Chart distance/elevation units.
      imperial: false,
      // [Lat, Long] vs [Long, Lat] points. (leaflet default: [Lat, Long])
      reverseCoords: false,
      // Acceleration chart profile: true || "summary" || "disabled" || false
      acceleration: false,
      // Slope chart profile: true || "summary" || "disabled" || false
      slope: false,
      // Speed chart profile: true || "summary" || "disabled" || false
      speed: false,
      // Altitude chart profile: true || "summary" || "disabled" || false
      altitude: true,
      // Display time info: true || "summary" || false
      time: true,
      // Display distance info: true || "summary" || false
      distance: true,
      // Summary track info style: "inline" || "multiline" || false
      summary: "multiline",
      // Download link: "link" || false || "modal"
      downloadLink: "link",
      // Toggle chart ruler filter
      ruler: true,
      // Toggle chart legend filter
      legend: true,
      // Toggle "leaflet-almostover" integration
      almostOver: true,
      // Toggle "leaflet-distance-markers" integration
      distanceMarkers: false,
      // Toggle "leaflet-hotline" integration
      hotline: true,
      // Display track datetimes: true || false
      timestamps: false,
      // Display track waypoints: true || "markers" || "dots" || false
      waypoints: true,
      // Toggle custom waypoint icons: true || { associative array of <sym> tags } || false
      wptIcons: {
        "": L.divIcon({
          className: "elevation-waypoint-marker",
          html: '<i class="elevation-waypoint-icon"></i>',
          iconSize: [30, 30],
          iconAnchor: [8, 30],
        }),
      },
      // Toggle waypoint labels: true || "markers" || "dots" || false
      wptLabels: true,
      // Render chart profiles as Canvas or SVG Paths
      preferCanvas: true,
    };

    // Instantiate map (leaflet-ui).
    var map = useMap();

    // Instantiate elevation control.
    var controlElevation = L.control.elevation(elevation_options).addTo(map);

    // Load track from url (allowed data types: "*.geojson", "*.gpx", "*.tcx")
    // controlElevation.load(
    //   "https://raruto.github.io/leaflet-elevation/examples/via-emilia.gpx"
    // );
  }

  return (
    <MapContainer
      id="map"
      center={[51.505, -0.09]}
      zoom={13}
      scrollWheelZoom={false}
    >
      <InitProfile />
      <TileLayer
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      <Marker position={[51.505, -0.09]}>
        <Popup>
          A pretty CSS3 popup. <br /> Easily customizable.
        </Popup>
      </Marker>
    </MapContainer>
  );
};

export default Map;

地图.css

#map {
  height: 75vh;
}

应用程序.js

import './App.css';
import Map from "./components/Map"

function App() {
  return (
    <>
      <Map />
    </>
  );
}

export default App;

错误:(现在不相关,缺少 leaflet.elevation 的导入)

Uncaught TypeError: leaflet__WEBPACK_IMPORTED_MODULE_1___default(...).control.elevation is not a function
    at InitProfile (Map.jsx:111:1)
    at renderWithHooks (react-dom.development.js:16175:1)
    at mountIndeterminateComponent (react-dom.development.js:20913:1)
    at beginWork (react-dom.development.js:22416:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4161:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4210:1)
    at invokeGuardedCallback (react-dom.development.js:4274:1)
    at beginWork$1 (react-dom.development.js:27405:1)
    at performUnitOfWork (react-dom.development.js:26513:1)
    at workLoopSync (react-dom.development.js:26422:1)

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <!-- leaflet -->
    <style>
      html,
      body,
      #map,
      #elevation-div {
        height: 100%;
        width: 100%;
        padding: 0;
        margin: 0;
      }
      #map {
        height: 75%;
      }
      #elevation-div {
        height: 25%;
        font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
      }
    </style>
    <link
      rel="stylesheet"
      href="https://unpkg.com/[email protected]/dist/leaflet.css"
      integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
      crossorigin=""
    />
    <link
      rel="stylesheet"
      href="https://unpkg.com/@raruto/leaflet-elevation@latest/dist/leaflet-elevation.css"
    />
    <!-- Make sure you put this AFTER Leaflet's CSS -->
    <script
      src="https://unpkg.com/[email protected]/dist/leaflet.js"
      integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
      crossorigin=""
    ></script>
    <script src="https://unpkg.com/leaflet-ui@latest/dist/leaflet-ui.js"></script>
    <script src="https://unpkg.com/@raruto/leaflet-elevation@latest/dist/leaflet-elevation.js"></script>
    <!-- end leaflet -->
    <!-- D3js -->
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <!-- End D3js -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

我还必须“npm i”d3 和 leaflet.elevation。

目前的问题是 L.control.elevation 对象的“.load()”函数没有被识别

Uncaught TypeError: controlElevation.load is not a function
    at InitProfile (Map.jsx:88:1)
    at renderWithHooks (react-dom.development.js:16175:1)
    at mountIndeterminateComponent (react-dom.development.js:20913:1)
    at beginWork (react-dom.development.js:22416:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4161:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4210:1)
    at invokeGuardedCallback (react-dom.development.js:4274:1)
    at beginWork$1 (react-dom.development.js:27405:1)
    at performUnitOfWork (react-dom.development.js:26513:1)
    at workLoopSync (react-dom.development.js:26422:1)

还有这个:

App running, but with two instances of the leaflet.elevation.

reactjs leaflet react-leaflet
2个回答
0
投票

关于海拔图的第二个实例,您应该注释掉index.js文件中的

React.StrictMode
标签,只保留
App
标签。 从这里复制答案:为什么我的 React 组件渲染了两次?


0
投票

这个话题有点晚了,但这个解决方案应该有效:

import { useEffect } from "react";
import { MapContainer, TileLayer, useMap } from "react-leaflet";
import L from "leaflet";
import "leaflet.elevation/dist/Leaflet.Elevation-0.0.2.min.js"; // [email protected]
import "./Map.css";

import myGeoJson from "./myGeoJson.json";

function InitProfile() {
  // Instantiate map (leaflet-ui).
  var map = useMap();
  // Instantiate elevation control.
  var elevation_options = {};

  var controlElevation = L.control.elevation(elevation_options).addTo(map);

  useEffect(() => {
    L.geoJson(myGeoJson, {
      onEachFeature: controlElevation.addData.bind(controlElevation),
    }).addTo(map);

    return () => {
      controlElevation.remove();
    };
  }, [map, controlElevation]);
}

export default function Map() {
  return (
    <MapContainer id="map" center={[-44.968683, 168.957614]} zoom={13} scrollWheelZoom={false}>
      <InitProfile />
      <TileLayer
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
    </MapContainer>
  );
}

清理 controlElevation 应避免图形的多个实例。 index.html 中唯一需要的脚本是 D3js,无需在其中包含 Leaflet,因为它已经加载到组件中。

© www.soinside.com 2019 - 2024. All rights reserved.