[英]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 組件:
通過 index.html 上的 cdns 包括 mapbox css 和 js
<link href="https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.css" rel="stylesheet" />
arc.js 通過 index.html 上的 cdn 使路徑彎曲
<script src="https://api.mapbox.com/mapbox.js/plugins/arc.js/v0.1.0/arc.js"></script>
通常你可以通過這個腳本直接導入航班變量<script src='/mapbox.js/assets/data/flights.js'></script>
但它似乎不起作用所以將 json 放在一個常量中(你可以如果使用上述腳本對您有用,請再試一次)
現在您擁有了創建自定義 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.