123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- import React from "react";
- import {
- Map,
- TileLayer,
- Marker,
- Popup,
- ZoomControl,
- Polyline,
- FeatureGroup
- } from "react-leaflet";
- import {EditControl} from "react-leaflet-draw";
- import L from "leaflet";
- import "./../css/maps.css";
- import {calcDistance} from "./../helpers/distance";
- import {longitude, latitude, mapWidth, mapHeight} from "./../config/variables";
- import {Button} from "reactstrap";
- import PathButtons from "./../PathButtons";
- export default class Leaflet extends React.Component{
- constructor(props){
- super(props);
- this.state = {
- latitude: latitude,
- longitude: longitude,
- zoom: 15,
- path: [],
- distance: 0,
- }
- }
- updateState = (key, value) => {
- this.setState({[key]: value})
- this.getDistance()
- }
- addMarker = event => {
- const { lat, lng } = event.latlng
- let pathCopy = this.state.path.slice();
- pathCopy.push([lat, lng]);
- this.setState({path: pathCopy})
- this.getDistance()
- }
- updateMarker = (idx, event) => {
- let {lat, lng} = event.target.getLatLng();
- let pathCopy = this.state.path.slice();
- pathCopy[idx] = [lat, lng]
- this.setState({path: pathCopy})
- this.getDistance()
- }
- getDistance = () => {
- let dst = calcDistance(this.state.path)
- this.setState({distance: dst})
- }
- clearPath = () => {
- this.setState({path: [], distance: 0})
- }
- _onEdited = (e) => {
- let numEdited = 0;
- e.layers.eachLayer( (layer) => {
- numEdited += 1;
- });
- this._onChange();
- }
- _onCreated = (e) => {
- let type = e.layerType;
- let layer = e.layer;
- // Do whatever else you need to. (save to db; etc)
- this._onChange();
- }
- _onDeleted = (e) => {
- let numDeleted = 0;
- e.layers.eachLayer( (layer) => {
- numDeleted += 1;
- });
- this._onChange();
- }
- _editableFG = null
- _onChange = () => {
- // this._editableFG contains the edited geometry, which can be manipulated through the leaflet API
- const { onChange } = this.props;
- if (!this._editableFG || !onChange) {
- return;
- }
- const geojsonData = this._editableFG.leafletElement.toGeoJSON();
- onChange(geojsonData);
- }
- render() {
- const position = [this.state.latitude, this.state.longitude]
- let testMarkers = this.props.markers
- let markers = <></>
- if (testMarkers){
- markers = this.props.markers.map((pos, idx) =>
- <Marker position={pos} key={idx}></Marker>
- )
- }else{
- markers = this.state.path.map((pos, idx) =>
- <Marker
- position={pos}
- draggable
- key={idx}
- onDragend={(e) => this.updateMarker(idx, e)}
- >
- <Popup>
- {idx}
- </Popup>
- </Marker>
- )
- }
- return (
- <div>
- <div className="map">
- <Map
- center={position}
- zoom={this.state.zoom}
- zoomControl={false}
- style={{width: mapWidth, height: mapHeight}}
- onClick={this.addMarker}
- >
- <TileLayer
- attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
- url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
- />
- <FeatureGroup>
- <EditControl
- position='topright'
- onEdited={this._onEdited}
- onCreated={this._onCreated}
- onDeleted={this._onDeleted}
- draw={{rectangle: false}}
- />
- </FeatureGroup>
- {markers}
- <Polyline color="grey" positions={this.state.path} />
- <ZoomControl position="bottomright" />
- </Map>
- </div>
- <div className="mapInfo">
- <Button onClick={this.clearPath}>Clear path</Button>
- <Button onClick={this.getDistance}>Calculate Distance</Button>
- <p>
- Distanz: {Math.round(this.state.distance*100)/100} km
- </p>
- <PathButtons updateState={this.updateState} path={this.state.path}/>
- </div>
- </div>
- );
- }
- }
|