Răsfoiți Sursa

leaflet: draw path with mouse click; calculate distance, drag marker

Bernadette Elena Hammerle 4 ani în urmă
părinte
comite
9d74cb38d7
1 a modificat fișierele cu 77 adăugiri și 2 ștergeri
  1. 77 2
      src/Leaflet.js

+ 77 - 2
src/Leaflet.js

@@ -5,41 +5,116 @@ import {
   Marker,
   Popup,
   ZoomControl,
+  Polyline
 } from "react-leaflet";
 import "./css/maps.css";
 
 const LONGITUDE = 14.320570
 const LATITUDE = 48.336950
 
+
 export default class Leaflet extends React.Component{
   state = {
     latitude: LATITUDE,
     longitude: LONGITUDE,
     zoom: 15,
+    path: [[48.295742, 14.286967], [48.328529, 14.322428]],
+    distance: 0
+    }
+
+  newPathPoint = event => {
+    const { lat, lng } = event.latlng
+    console.log("Clicked at", lat, "/", lng)
+    let pathCopy = this.state.path.slice();
+    pathCopy.push([lat, lng]);
+    this.setState({path: pathCopy})
+    this.calcDistance()
+  }
+
+  updateMarker = (idx, event) => {
+    let {lat, lng} = event.target.getLatLng();
+    console.log(lat, lng, idx)
+    let pathCopy = this.state.path.slice();
+    pathCopy[idx] = [lat, lng]
+    this.setState({path: pathCopy})
+    this.calcDistance()
+  }
+
+  calcDistance = () => {
+    let dst = 0;
+    let pathCopy = this.state.path.slice();
+    for(let i=0; i<pathCopy.length-1; i++) {
+    /*  let currLat = pathCopy[i][0];
+      let currLng = pathCopy[i][1];
+      let nextLat = pathCopy[i+1][0];
+      let nextLng = pathCopy[i+1][1];
+      let dstLat = (currLat - nextLat) ** 2
+      let dstLng = (currLng - nextLng) ** 2
+      dst += Math.sqrt(dstLat + dstLng) * 108*/
+      var radlat1 = Math.PI * pathCopy[i][0]/180;
+      var radlat2 = Math.PI * pathCopy[i+1][0]/180;
+      var theta = pathCopy[i][1]-pathCopy[i+1][1];
+      var radtheta = Math.PI * theta/180;
+      var d = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
+      if (d > 1) {
+        d = 1;
+      }
+      dst += Math.acos(d) * 180/Math.PI * 60 * 1.1515 * 1.609344;
     }
+    this.setState({distance: dst})
+  }
+
+  clearPath = () => {
+    this.setState({path: [], distance: 0})
+  }
   
   render() {
     const position = [this.state.latitude, this.state.longitude]
     return (
+      <div>
         <Map
           center={position}
           zoom={this.state.zoom}
           zoomControl={false}
           style={{width: 600, height: 400}}
+          onClick={this.newPathPoint}
         >
             <TileLayer
               attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
               url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
             />
+            <ZoomControl position="bottomright" />
   
-            <Marker position={position}>
+            <Marker position={position} onClick={this.newPathPoint}>
               <Popup>
                 JKU: Ente
               </Popup>
             </Marker>
-            <ZoomControl position="bottomright" />
 
+            {this.state.path.map((pos, idx) =>
+              <Marker
+                position={pos}
+                draggable
+                key={idx}
+                onDragend={(e) => this.updateMarker(idx, e)}
+              >
+                <Popup>
+                  {idx}
+                </Popup>
+              </Marker>
+            )}
+
+            <Polyline color="grey" positions={this.state.path} />
         </Map>
+
+        <div>
+          <button onClick={this.clearPath}>Clear path</button>
+          <button onClick={this.calcDistance}>Calculate Distance</button>
+          <p>
+            Distanz: {Math.round(this.state.distance*100)/100} km
+          </p>
+          </div>
+      </div>
     );
   }
 }