写一个react组件,带开关的mapbox点击测距
时间: 2024-05-02 11:23:04 浏览: 225
好的,我可以帮你回答这个问题。以下是一个示例React组件,它可以在Mapbox地图上使用点击事件测距离,并带有开关:
```
import React, { Component } from 'react';
import mapboxgl from 'mapbox-gl';
mapboxgl.accessToken = 'your_access_token_here';
class Map extends Component {
constructor(props) {
super(props);
this.state = {
map: null,
distance: 0,
isMeasuring: false
};
this.handleMapClick = this.handleMapClick.bind(this);
this.toggleMeasurement = this.toggleMeasurement.bind(this);
}
componentDidMount() {
const map = new mapboxgl.Map({
container: this.mapContainer,
style: 'mapbox://styles/mapbox/streets-v11',
center: [-122.4443, 47.2529],
zoom: 10
});
map.on('click', this.handleMapClick);
this.setState({ map });
}
handleMapClick(event) {
const { isMeasuring, map } = this.state;
if (isMeasuring) {
const { lngLat } = event;
const { lng, lat } = lngLat;
const { lng: prevLng, lat: prevLat } = map.getSource('measure')._data.geometry.coordinates[
map.getSource('measure')._data.geometry.coordinates.length - 1
];
const newDistance = this.calculateDistance([prevLng, prevLat], [lng, lat]);
this.setState({ distance: this.state.distance + newDistance });
const source = map.getSource('measure');
source.setData({
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: [...source._data.geometry.coordinates, [lng, lat]]
}
});
}
}
calculateDistance(point1, point2) {
const lng1 = point1[0];
const lat1 = point1[1];
const lng2 = point2[0];
const lat2 = point2[1];
const R = 6371e3;
const φ1 = lat1 * (Math.PI / 180);
const φ2 = lat2 * (Math.PI / 180);
const Δφ = ((lat2 - lat1) * Math.PI) / 180;
const Δλ = ((lng2 - lng1) * Math.PI) / 180;
const a =
Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
toggleMeasurement() {
const { isMeasuring, map } = this.state;
if (isMeasuring) {
this.setState({ isMeasuring: false });
map.removeSource('measure');
map.removeLayer('measure-line');
} else {
this.setState({ isMeasuring: true, distance: 0 });
map.addSource('measure', {
type: 'geojson',
data: {
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: []
}
}
});
map.addLayer({
id: 'measure-line',
type: 'line',
source: 'measure',
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': '#0000ff',
'line-width': 4
}
});
}
}
render() {
const { distance, isMeasuring } = this.state;
return (
<div>
<div ref={el => (this.mapContainer = el)} className="map-container" />
<div>
<button onClick={this.toggleMeasurement}>{isMeasuring ? 'Stop Measuring' : 'Start Measuring'}</button>
<div>Distance: {distance.toFixed(2)} meters</div>
</div>
</div>
);
}
}
export default Map;
```
请注意,此代码仅为示例,如果您想在实际应用中使用此代码,请根据您的需求进行修改。同时,您需要在Mapbox网站上获取自己的访问令牌并将其添加到`mapboxgl.accessToken`中。
阅读全文