Jelajahi Sumber

mapbox: add and drag markers, calc distance

Bernadette Elena Hammerle 4 tahun lalu
induk
melakukan
48ed9675cc
1 mengubah file dengan 72 tambahan dan 25 penghapusan
  1. 72 25
      src/Mapbox.js

+ 72 - 25
src/Mapbox.js

@@ -5,10 +5,11 @@ import ReactMapboxGl, {
     ZoomControl, 
     ScaleControl, 
     RotationControl, 
-    Marker 
+    Marker
 } from 'react-mapbox-gl';
 import mapboxToken from './config/mapboxToken.js';
-import {longitude, latitude, testPath, mapWidth, mapHeight, markerIcon} from "./config/variables";
+import {calcDistance} from './helpers/distance';
+import {longitude, latitude, mapWidth, mapHeight, markerIcon} from "./config/variables";
 
 const Map = ReactMapboxGl({ accessToken: mapboxToken });
 
@@ -17,39 +18,85 @@ export default class Mapbox extends React.Component{
     latitude: latitude,
     longitude: longitude,
     zoom: [15],
-    path: testPath,
+    path: [[longitude, latitude]],
     distance: 0
     }
 
+  addMarker = (event, click) => {
+    const lng = click.lngLat.lng
+    const lat = click.lngLat.lat
+    console.log("Clicked at", lat, "/", lng)
+    let pathCopy = this.state.path.slice();
+    pathCopy.push([lng, lat]);
+    this.setState({path: pathCopy})
+    this.getDistance()
+  }
+
+  updateMarker = (idx, event) => {
+    const lng = event.lngLat.lng
+    const lat = event.lngLat.lat
+    console.log(lat, lng, idx)
+    let pathCopy = this.state.path.slice();
+    pathCopy[idx] = [lng, lat]
+    this.setState({path: pathCopy})
+    this.getDistance()
+  }
+
+  getDistance = () => {
+    let dst = calcDistance(this.state.path)
+    this.setState({distance: dst})
+  }
+
+  clearPath = () => {
+    this.setState({path: [], distance: 0})
+  }
+
   render() {
     const position = [this.state.longitude, this.state.latitude]
     return (
-      <Map
-        style="mapbox://styles/mapbox/streets-v9"
-        containerStyle={{
+      <div>
+        <Map
+          style="mapbox://styles/mapbox/bright-v9"
+          containerStyle={{
             height: mapHeight,
             width: mapWidth
-        }}
-        center={position}
-        zoom={this.state.zoom}
-      >
-          <Layer type="symbol" id="marker" layout={{ 'icon-image': 'marker-15' }}>
-            <Feature coordinates={position} />
-          </Layer>
+          }}
+          center={position}
+          zoom={this.state.zoom}
+          onClick={(e, c) => this.addMarker(e, c)}
+        >
 
-          <Marker
-            coordinates={position}
-            anchor="bottom"
-          >
-            <svg height={20} viewBox="0 0 24 24" style={{fill: "#343a40", stroke: "none"}}>
-              <path d={markerIcon} />
-            </svg>
-          </Marker>
-
-          <ZoomControl position={"bottom-right"}/>
+          <Layer type="symbol" id="marker" layout={{"icon-image": "marker-15" }}>
+            {this.state.path.map((pos, idx) =>
+              <Feature
+                coordinates={pos}
+                key={idx} draggable={true}
+                onDragEnd={(e) => this.updateMarker(idx, e)}
+              />
+//              <Marker
+//                coordinates={pos}
+//                anchor="bottom"
+//                key={idx}
+//              >
+//                <svg height={20} viewBox="0 0 24 24" style={{fill: "#343a40"}}>
+//                  <path d={markerIcon} />
+//                </svg>
+//              </Marker>
+            )}
+          </Layer>
+          <ZoomControl position={"top-right"}/>
           <ScaleControl position={"bottom-right"}/>
-          <RotationControl position={"bottom-right"}/>
-      </Map>
+          <RotationControl position={"top-right"}/>
+        </Map>
+
+        <div>
+          <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>
+        </div>
+      </div>
     );
   }
 }