簡體   English   中英

Mapbox 示例作為 React 組件

[英]Mapbox example as a React component

我正在嘗試在我的React應用程序中使用Mapbox中的這個小提琴代碼 官方代碼在這里

到目前為止,這是我的代碼,我收到此錯誤TypeError: Cannot set property 'accessToken' of undefined我是 React 的新手,因此很難轉換此 js 代碼。 感謝您提供任何資源/代碼鏈接以供參考。 以及如何使 mapbox 作為反應組件工作。

import React, { useEffect } from "react";
// import * as d3 from 'd33';
import './StreamGraph.css';
// import 'https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.js';
// import 'https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.css';
// import 'https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js';
// import 'https://code.jquery.com/jquery-3.5.1.js';
// import 'https://api.mapbox.com/mapbox.js/plugins/arc.js/v0.1.0/arc.js';
// import 'https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v1.0.0/leaflet.markercluster.js';
// import 'https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v1.0.0/MarkerCluster.css';
// import 'https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v1.0.0/MarkerCluster.Default.css';

// import mapbox from 'mapbox';
import 'mapbox';
import 'leaflet';
import arc from 'arc';
import largeAirports from '../data/large_airports_only.csv';
import 'mapbox/lib/mapbox.js';
import 'jquery/dist/jquery.min.js';
import 'jquery/src/ajax.js';
import 'ajax/lib/ajax.js';
import 'arc/arc.js';
import 'jquery/src/jquery.js';
import 'mapbox/dist/mapbox-sdk.min.js';
import L from 'leaflet';
import 'leaflet.markercluster/dist/leaflet.markercluster.js';
import 'leaflet.markercluster/dist/MarkerCluster.css';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css';
// import * from 'jquery';


// setting up via node
// var MapboxClient = require('mapbox');
// var client = new MapboxClient('pk.eyJ1Ijoic2FueWFzaW4iLCJhIjoiY2tnbzA2aW9mMGI4cTJybnFvOTVzYm84aCJ9.voOP8PnCpZrEsilFflPswg');


function Mapbox(props) {

    useEffect(() => {

        console.log(largeAirports);

        // feb map for now
        var pairs = [[[47.539123535, -122.30667114299999], [47.539238364, -122.30649508]], [[38.690728656, -121.60168457], [47.54095459, -122.311683655]], [[49.297393799, -123.105046199], [48.41784668, -123.388718825]], [[25.065261065, 121.22915591799999], [22.31350708, 113.906000311]], [[34.422586732, 135.237007141], [25.067138672, 121.23148600299999]], [[49.18676861300001, -123.16721866], [49.17910766600001, -123.14927321200001]], [[22.298858643000003, 113.90620006200001], [25.073966333, 121.21734043299999]]]


        // declaring for the purpose of checking mapbox in react
        var ident_lat = {"KLAX": 47.539123535}
        var ident_lon = {"KLAX": -122.30252}
        var origin_lat = {"KLAX": -122.30252}
        var origin_lon = {"KLAX": -122.30252}
        var dest_lat = {"KLAX": -122.30252}
        var dest_lon = {"KLAX": -122.30252}


        var container = L.DomUtil.get('map');
        if(container != null){
            container._leaflet_id = null;
        }

        L.mapbox.accessToken = 'pk.eyJ1Ijoic2FueWFzaW4iLCJhIjoiY2tnbzA2aW9mMGI4cTJybnFvOTVzYm84aCJ9.voOP8PnCpZrEsilFflPswg';

        // Animation is non-geographical - lines interpolate in the same amount of time regardless of trip length.

        // Show the whole world in this first view.
        var map = L.mapbox.map('map')
            .setView([20, 0], 2)
            .addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/satellite-v9'));

        var credits = L.control.attribution({
        prefix: ''
        }).addTo(map);



        // Disable drag and zoom handlers.
        // Making this effect work with zooming and panning
        // would require a different technique with different
        // tradeoffs.
        map.dragging.disable();
        map.touchZoom.disable();
        map.doubleClickZoom.disable();
        map.scrollWheelZoom.disable();
        if (map.tap) map.tap.disable();

        // Transform the short [lat,lng] format in our
        // data into the {x, y} expected by arc.js.
        function obj(ll) { return { y: ll[0], x: ll[1] }; }

        // var select_id = document.getElementById('select');
        // var get_value = select_id.value;
        // var get_ident = name_ident.get(get_value)
        // console.log("get_ident: ", get_ident);
        var counter = 0;

        var get_ident = undefined;

        if (get_ident != undefined){
            // adding marker - airport
            var marker = L.marker(new L.LatLng(ident_lat.get(get_ident), ident_lon.get(get_ident)), {
                icon: L.mapbox.marker.icon({'marker-symbol':'airport', 'marker-color': '4587f4'})
                });
                map.addLayer(marker);
        }

    
    for (var i = 0; i < pairs.length; i++) {
        if (ident_lat.has(get_ident)){
            // airport is selected
            origin_lat = pairs[i][0][0].toString()
            origin_lon = pairs[i][0][1].toString()
            dest_lat = pairs[i][1][0].toString()
            dest_lon = pairs[i][1][1].toString()

            if (JSON.stringify([ident_lat.get(get_ident), ident_lon.get(get_ident)]) == JSON.stringify([origin_lat.slice(0,4), origin_lon.slice(0,4)]) || JSON.stringify([ident_lat.get(get_ident), ident_lon.get(get_ident)]) == JSON.stringify([dest_lat.slice(0,4), dest_lon.slice(0,4)])){
                counter = counter + 1;
                // filter it out
                var generator = new arc.GreatCircle(
                obj(pairs[i][0]),
                obj(pairs[i][1]));
                var line = generator.Arc(100, { offset: 100 });
                var newLine = L.polyline(line.geometries[0].coords.map(function(c) {
                return c.reverse();
                }), {
                    color: '#fff',
                    weight: 1,
                    opacity: 0.5
                })
                .addTo(map);
                var totalLength = newLine._path.getTotalLength();
                newLine._path.classList.add('path-start');
                newLine._path.style.strokeDashoffset = totalLength;
                newLine._path.style.strokeDasharray = totalLength;
                setTimeout((function(path) {
                    return function() {
                        path.style.strokeDashoffset = 2; // no animation == 0
                    };
                })(newLine._path), i * 2); // no animation == 0
            }
            console.log("counter: ", counter);
        }
        else if (get_ident == undefined) {
            console.log("else block");
            // Transform each pair into a circle using the Arc.js plugin
            var generator = new arc.GreatCircle(
                    obj(pairs[i][0]),
                    obj(pairs[i][1]));
            var line = generator.Arc(100, { offset: 100 });
            // Leaflet expects [lat,lng] arrays, but a lot of
            // software does the opposite, including arc.js, so flip here.
            var newLine = L.polyline(line.geometries[0].coords.map(function(c) {
                return c.reverse();
            }), {
                color: '#fff',
                weight: 1,
                opacity: 0.5
            })
            .addTo(map);
            var totalLength = newLine._path.getTotalLength();
            newLine._path.classList.add('path-start');
            // This pair of CSS properties hides the line initially
            // See http://css-tricks.com/svg-line-animation-works/ for details on this trick.
            newLine._path.style.strokeDashoffset = totalLength;
            newLine._path.style.strokeDasharray = totalLength;
            // Offset the timeout here: setTimeout makes a function run after a certain number of milliseconds
            setTimeout((function(path) {
                return function() {
                    // setting the strokeDashoffset to 0 triggers animation
                    path.style.strokeDashoffset = 2;
                };
            })(newLine._path), i * 2);
        }
    }


    });


    return (
        <div className="mapbox_container">
            <div id = "map" className="dark"></div>
        </div>
    )
}   

export default Mapbox;

我不熟悉傳單,但是,使用 mapbox-gl,您可以將地圖設置如下

import React from "react";
import "./styles.css";
import * as mapboxgl from "mapbox-gl";

mapboxgl.accessToken = "your-token-here";

export default function App() {
  React.useEffect(() => {
    const map = new mapboxgl.Map({
      container: "map",
      style: "mapbox://styles/mapbox/light-v9",
      zoom: 12,
      center: [-122.447303, 37.753574]
    });
  }, []);

  return (
    <>
      <div id="map" style={{ height: "100vh" }}></div>
    </>
  );
}

或者你也可以像這樣使用 react-map-gl

import * as React from "react";
import ReactMapGL from "react-map-gl";

export default () => {
  const [viewport, setViewport] = React.useState({
    width: "100%",
    height: "100%",
    longitude: 139.63270819862225,
    latitude: 35.458058995332536,
    zoom: 13.5,
    mapStyle: "mapbox://styles/mapbox/streets-v11",
    mapboxApiAccessToken:
      "your-token-here"
  });

  return (
    <div style={{ height: "100vh" }}>
      <ReactMapGL {...viewport} onViewportChange={setViewport} />
    </div>
  );
};

您可以通過以下方式將提供的示例轉換為 React 組件:

  1. 通過 index.html 上的 cdns 包括 mapbox css 和 js

     <link href="https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.css" rel="stylesheet" />
  2. arc.js 通過 index.html 上的 cdn 使路徑彎曲

<script src="https://api.mapbox.com/mapbox.js/plugins/arc.js/v0.1.0/arc.js"></script>

  1. 通常你可以通過這個腳本直接導入航班變量<script src='/mapbox.js/assets/data/flights.js'></script>但它似乎不起作用所以將 json 放在一個常量中(你可以如果使用上述腳本對您有用,請再試一次)

  2. 現在您擁有了創建自定義 Mapbox comp 所需的所有庫,就像您在示例中所做的那樣,將演示代碼放在 useEffect 中:

import React, { useEffect } from "react"; 從“./flights.json”導入對;

L.mapbox.accessToken =
  "pk.eyJ1Ijoic2FueWFzaW4iLCJhIjoiY2tnbzA2aW9mMGI4cTJybnFvOTVzYm84aCJ9.voOP8PnCpZrEsilFflPswg";

export default function Mapbox() {
  useEffect(() => {
    // console.log(L.mapbox);

    const map = L.mapbox
      .map("map")
      .setView([20, 0], 2)
      .addLayer(L.mapbox.styleLayer("mapbox://styles/mapbox/satellite-v9"));

    L.control
      .attribution({
        prefix:
          '<a href="http://openflights.org/data.html">Flight data from Open Flights, under the ODbL license</a>'
      })
      .addTo(map);

    // Disable drag and zoom handlers.
    // Making this effect work with zooming and panning
    // would require a different technique with different
    // tradeoffs.
    map.dragging.disable();
    map.touchZoom.disable();
    map.doubleClickZoom.disable();
    map.scrollWheelZoom.disable();
    if (map.tap) map.tap.disable();

    // Transform the short [lat,lng] format in our
    // data into the {x, y} expected by arc.js.
    function obj(ll) {
      return { y: ll[0], x: ll[1] };
    }

    for (var i = 0; i < pairs.length; i++) {
      // Transform each pair of coordinates into a pretty
      // great circle using the Arc.js plugin, as included above.
      var generator = new arc.GreatCircle(obj(pairs[i][0]), obj(pairs[i][1]));
      var line = generator.Arc(100, { offset: 10 });
      // Leaflet expects [lat,lng] arrays, but a lot of
      // software does the opposite, including arc.js, so
      // we flip here.
      var newLine = L.polyline(
        line.geometries[0].coords.map(function (c) {
          return c.reverse();
        }),
        {
          color: "#fff",
          weight: 1,
          opacity: 0.5
        }
      ).addTo(map);
      var totalLength = newLine._path.getTotalLength();
      newLine._path.classList.add("path-start");
      // This pair of CSS properties hides the line initially
      // See http://css-tricks.com/svg-line-animation-works/
      // for details on this trick.
      newLine._path.style.strokeDashoffset = totalLength;
      newLine._path.style.strokeDasharray = totalLength;
      // Offset the timeout here: setTimeout makes a function
      // run after a certain number of milliseconds - in this
      // case we want each flight path to be staggered a bit.
      setTimeout(
        (function (path) {
          return function () {
            // setting the strokeDashoffset to 0 triggers
            // the animation.
            path.style.strokeDashoffset = 0;
          };
        })(newLine._path),
        i * 100
      );
    }
}, []);

return <div id="map" className="light"></div>;
}

演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM