mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-06-16 14:28:14 +00:00
113 lines
2.8 KiB
TypeScript
113 lines
2.8 KiB
TypeScript
import React, { Component } from "react";
|
|
|
|
import L, { LatLngTuple, FitBoundsOptions } from "leaflet";
|
|
import "leaflet.awesome-markers";
|
|
import { MarkerProps as LMarkerProps } from "react-leaflet";
|
|
import { MapContainer, Marker as LMarker, TileLayer } from 'react-leaflet';
|
|
|
|
|
|
interface IProps {
|
|
height: number;
|
|
center?: [number, number];
|
|
bounds?: LatLngTuple[];
|
|
boundsOptions?: FitBoundsOptions;
|
|
}
|
|
|
|
interface IState {
|
|
map?: L.Map;
|
|
}
|
|
|
|
|
|
class Map extends Component<IProps, IState> {
|
|
constructor(props: IProps) {
|
|
super(props);
|
|
this.state = {};
|
|
}
|
|
|
|
setMap = (map: L.Map) => {
|
|
this.setState({
|
|
map: map,
|
|
}, () => {
|
|
// This is needed as setMap is called after the map has been created.
|
|
// There is a small amount of time where componentDidUpdate can't update
|
|
// the map with the new center because setMap hasn't been called yet.
|
|
// In such case, the map would never update to the new center.
|
|
if (this.props.center !== undefined) {
|
|
map.panTo(this.props.center);
|
|
}
|
|
|
|
if (this.props.bounds !== undefined) {
|
|
map.fitBounds(this.props.bounds, this.props.boundsOptions);
|
|
}
|
|
});
|
|
}
|
|
|
|
componentDidUpdate(oldProps: IProps) {
|
|
if (this.props === oldProps) {
|
|
return;
|
|
}
|
|
|
|
if (this.state.map) {
|
|
if (this.props.center !== undefined) {
|
|
this.state.map.flyTo(this.props.center);
|
|
}
|
|
|
|
if (this.props.bounds !== undefined) {
|
|
this.state.map.flyToBounds(this.props.bounds, this.props.boundsOptions);
|
|
}
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const style = {
|
|
height: this.props.height,
|
|
};
|
|
|
|
return(
|
|
<MapContainer
|
|
bounds={this.props.bounds}
|
|
boundsOptions={this.props.boundsOptions}
|
|
center={this.props.center}
|
|
zoom={13}
|
|
scrollWheelZoom={false}
|
|
animate={true}
|
|
style={style}
|
|
whenCreated={this.setMap}
|
|
>
|
|
<TileLayer
|
|
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
/>
|
|
{this.props.children}
|
|
</MapContainer>
|
|
);
|
|
}
|
|
}
|
|
|
|
export type MarkerColor = "red" | "darkred" | "orange" | "green" | "darkgreen" | "blue" | "purple" | "darkpurple" | "cadetblue" | undefined;
|
|
|
|
interface MarkerProps extends LMarkerProps {
|
|
position: [number, number];
|
|
faIcon: string;
|
|
color: MarkerColor;
|
|
}
|
|
|
|
export class Marker extends Component<MarkerProps> {
|
|
render() {
|
|
const { faIcon, color, position, ...otherProps } = this.props;
|
|
|
|
const iconMarker = L.AwesomeMarkers.icon({
|
|
icon: faIcon,
|
|
prefix: "fa",
|
|
markerColor: color,
|
|
});
|
|
|
|
|
|
return(
|
|
<LMarker icon={iconMarker} position={position} {...otherProps}>{this.props.children}</LMarker>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default Map;
|