如何将 vanilla JS 与 React 组件一起使用(在加载反应 mapbox gl 时缩放到边界)
How to use vanilla JS with React component (zoom to bounds on load react mapbox gl)
我希望在安装组件时能够缩放到边界。
我知道这个 vanilla JS 代码可以实现缩放到边界,但不确定如何将其添加到下面的 React 代码中(我认为需要一个 REF?):
var bounds = new mapboxgl.LngLatBounds();
parkDate.features.forEach(function(feature) {
bounds.extend(feature.geometry.coordinates);
});
map.fitBounds(bounds, {
padding: {top: 20, bottom:20, left: 20, right: 20}
})
分量:
import React, { useState } from "react";
import ReactMapGL, { Marker } from "react-map-gl";
import * as parkDate from "./data.json";
const mapIcon: any = require('../images/mapIcon.png');
export default function App() {
const [viewport, setViewport] = useState({
latitude: 45.4211,
longitude: -75.6903,
width: "100%",
height: "400px",
zoom: 10
});
const [selectedPark, setSelectedPark] = useState(null);
return (
<div>
<ReactMapGL
{...viewport}
mapboxApiAccessToken="pk.eyJ1IjoiYmVubmtpbmd5IiwiYSI6ImNrY2ozMnJ5dzBrZ28ycnA1b2Vqb2I0bXgifQ.ZOaVtzsDQOrAovh9Orh13Q"
mapStyle="mapbox://styles/mapbox/streets-v11"
onViewportChange={viewport => {
setViewport(viewport);
}}
>
{parkDate.features.map(park => (
<Marker
key={park.properties.PARK_ID}
latitude={park.geometry.coordinates[1]}
longitude={park.geometry.coordinates[0]}
>
<button
className="marker-btn"
onClick={e => {
e.preventDefault();
setSelectedPark(park);
}}
>
<img src={mapIcon} alt="Map Pointer Icon" />
</button>
</Marker>
))}
</ReactMapGL>
{selectedPark ? (
<div>
<h2>{selectedPark.properties.NAME}</h2>
<p>{selectedPark.properties.DESCRIPTIO}</p>
<button onClick={e => {
e.preventDefault();
setSelectedPark(null);
}}>X</button>
</div>
) : null}
</div>
);
}
得到这样的效果:
import React, { useState } from "react";
import ReactMapGL, { Marker, WebMercatorViewport } from "react-map-gl";
import * as parkData from "./data.json";
const mapIcon: any = require('../images/mapIcon.png');
const applyToArray = (func, array) => func.apply(Math, array)
const getBoundsForPoints = (points) => {
console.log('Points:', points)
// Calculate corner values of bounds
const pointsLong = points.map(point => point.geometry.coordinates[0])
const pointsLat = points.map(point => point.geometry.coordinates[1])
const cornersLongLat = [
[applyToArray(Math.min, pointsLong), applyToArray(Math.min, pointsLat)],
[applyToArray(Math.max, pointsLong), applyToArray(Math.max, pointsLat)]
]
// Use WebMercatorViewport to get center longitude/latitude and zoom
const viewport = new WebMercatorViewport({ width: 600, height: 600 })
// @ts-ignore
.fitBounds(cornersLongLat, { padding: {top:150, bottom:200, left:100, right:150} })
const { longitude, latitude, zoom } = viewport
return { longitude, latitude, zoom }
}
const myMap = () => {
const bounds = getBoundsForPoints(parkData.features);
const [viewport, setViewport] = useState({
width: "100%",
height: "600px",
...bounds
});
const [selectedPark, setSelectedPark] = useState(null);
return (
<div>
<ReactMapGL
{...viewport}
mapboxApiAccessToken="pk.eyJ1IjoiYmVubmtpbmd5IiwiYSI6ImNrY2ozMnJ5dzBrZ28ycnA1b2Vqb2I0bXgifQ.ZOaVtzsDQOrAovh9Orh13Q"
mapStyle="mapbox://styles/mapbox/streets-v11"
onViewportChange={viewport => {
setViewport(viewport);
}}
>
{parkData.features.map(park => (
<Marker
key={park.properties.PARK_ID}
latitude={park.geometry.coordinates[1]}
longitude={park.geometry.coordinates[0]}
>
<button
className="marker-btn"
onClick={e => {
e.preventDefault();
setSelectedPark(park);
}}
>
<img src={mapIcon} alt="Map Pointer Icon" />
</button>
</Marker>
))}
</ReactMapGL>
{selectedPark ? (
<div>
<h2>{selectedPark.properties.NAME}</h2>
<p>{selectedPark.properties.DESCRIPTIO}</p>
<button onClick={e => {
e.preventDefault();
setSelectedPark(null);
}}>X</button>
</div>
) : null}
</div>
);
}
export default myMap;
我希望在安装组件时能够缩放到边界。
我知道这个 vanilla JS 代码可以实现缩放到边界,但不确定如何将其添加到下面的 React 代码中(我认为需要一个 REF?):
var bounds = new mapboxgl.LngLatBounds();
parkDate.features.forEach(function(feature) {
bounds.extend(feature.geometry.coordinates);
});
map.fitBounds(bounds, {
padding: {top: 20, bottom:20, left: 20, right: 20}
})
分量:
import React, { useState } from "react";
import ReactMapGL, { Marker } from "react-map-gl";
import * as parkDate from "./data.json";
const mapIcon: any = require('../images/mapIcon.png');
export default function App() {
const [viewport, setViewport] = useState({
latitude: 45.4211,
longitude: -75.6903,
width: "100%",
height: "400px",
zoom: 10
});
const [selectedPark, setSelectedPark] = useState(null);
return (
<div>
<ReactMapGL
{...viewport}
mapboxApiAccessToken="pk.eyJ1IjoiYmVubmtpbmd5IiwiYSI6ImNrY2ozMnJ5dzBrZ28ycnA1b2Vqb2I0bXgifQ.ZOaVtzsDQOrAovh9Orh13Q"
mapStyle="mapbox://styles/mapbox/streets-v11"
onViewportChange={viewport => {
setViewport(viewport);
}}
>
{parkDate.features.map(park => (
<Marker
key={park.properties.PARK_ID}
latitude={park.geometry.coordinates[1]}
longitude={park.geometry.coordinates[0]}
>
<button
className="marker-btn"
onClick={e => {
e.preventDefault();
setSelectedPark(park);
}}
>
<img src={mapIcon} alt="Map Pointer Icon" />
</button>
</Marker>
))}
</ReactMapGL>
{selectedPark ? (
<div>
<h2>{selectedPark.properties.NAME}</h2>
<p>{selectedPark.properties.DESCRIPTIO}</p>
<button onClick={e => {
e.preventDefault();
setSelectedPark(null);
}}>X</button>
</div>
) : null}
</div>
);
}
得到这样的效果:
import React, { useState } from "react";
import ReactMapGL, { Marker, WebMercatorViewport } from "react-map-gl";
import * as parkData from "./data.json";
const mapIcon: any = require('../images/mapIcon.png');
const applyToArray = (func, array) => func.apply(Math, array)
const getBoundsForPoints = (points) => {
console.log('Points:', points)
// Calculate corner values of bounds
const pointsLong = points.map(point => point.geometry.coordinates[0])
const pointsLat = points.map(point => point.geometry.coordinates[1])
const cornersLongLat = [
[applyToArray(Math.min, pointsLong), applyToArray(Math.min, pointsLat)],
[applyToArray(Math.max, pointsLong), applyToArray(Math.max, pointsLat)]
]
// Use WebMercatorViewport to get center longitude/latitude and zoom
const viewport = new WebMercatorViewport({ width: 600, height: 600 })
// @ts-ignore
.fitBounds(cornersLongLat, { padding: {top:150, bottom:200, left:100, right:150} })
const { longitude, latitude, zoom } = viewport
return { longitude, latitude, zoom }
}
const myMap = () => {
const bounds = getBoundsForPoints(parkData.features);
const [viewport, setViewport] = useState({
width: "100%",
height: "600px",
...bounds
});
const [selectedPark, setSelectedPark] = useState(null);
return (
<div>
<ReactMapGL
{...viewport}
mapboxApiAccessToken="pk.eyJ1IjoiYmVubmtpbmd5IiwiYSI6ImNrY2ozMnJ5dzBrZ28ycnA1b2Vqb2I0bXgifQ.ZOaVtzsDQOrAovh9Orh13Q"
mapStyle="mapbox://styles/mapbox/streets-v11"
onViewportChange={viewport => {
setViewport(viewport);
}}
>
{parkData.features.map(park => (
<Marker
key={park.properties.PARK_ID}
latitude={park.geometry.coordinates[1]}
longitude={park.geometry.coordinates[0]}
>
<button
className="marker-btn"
onClick={e => {
e.preventDefault();
setSelectedPark(park);
}}
>
<img src={mapIcon} alt="Map Pointer Icon" />
</button>
</Marker>
))}
</ReactMapGL>
{selectedPark ? (
<div>
<h2>{selectedPark.properties.NAME}</h2>
<p>{selectedPark.properties.DESCRIPTIO}</p>
<button onClick={e => {
e.preventDefault();
setSelectedPark(null);
}}>X</button>
</div>
) : null}
</div>
);
}
export default myMap;