Przeglądaj źródła

pigeon: move state to app; add markers, calc distance (without path)

Bernadette Elena Hammerle 4 lat temu
rodzic
commit
2cc6092ab3
2 zmienionych plików z 91 dodań i 29 usunięć
  1. 46 1
      src/App.js
  2. 45 28
      src/Pigeon.js

+ 46 - 1
src/App.js

@@ -13,6 +13,45 @@ import Leaflet from './Leaflet';
 import Google from './Google';
 
 export class App extends React.Component{
+    constructor(props) {
+        super(props)
+
+        this.state = {
+            mapConfig: {
+                zoom: 15,
+                path: [],
+                coords: [48.336950, 14.320570],
+                width: 600,
+                height: 400,
+                defaultZoom: 15,
+                distance: 0,
+            }
+        }
+    }
+
+    updateMapState = (key, value) => {
+        let mapConfigCopy = JSON.parse(JSON.stringify(this.state.mapConfig));
+        mapConfigCopy[key] = value;
+        this.setState({mapConfig: mapConfigCopy})
+    }
+
+    calcDistance = () => {
+        let dst = 0;
+        let pathCopy = this.state.mapConfig.path.slice();
+        for(let i=0; i<pathCopy.length-1; i++) {
+            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.updateMapState("distance", dst)
+    }
+
     render(){
         return (
           <div>
@@ -21,7 +60,13 @@ export class App extends React.Component{
                 <Switch>
                   <Route path="/" exact component={Home} />
                   <Route path="/about" exact component={About} />
-                  <Route path="/pigeon-map" exact component={Pigeon} />
+                  <Route exact path="/pigeon-map" render={() =>
+                    <Pigeon
+                        mapConfig={this.state.mapConfig}
+                        updateMapState={this.updateMapState}
+                        calcDistance={this.calcDistance}
+                    />}
+                  />
                   <Route path="/mapbox-gl" exact component={Mapbox} />
                   <Route path="/leaflet" exact component={Leaflet} />
                   <Route path="/google-map" exact component={Google} />

+ 45 - 28
src/Pigeon.js

@@ -4,15 +4,6 @@ import Marker from 'pigeon-marker'
 import Overlay from 'pigeon-overlay'
 
 export default class Pigeon extends React.Component{
-
-  constructor(props) {
-    super(props)
-
-    this.state = {
-      zoom: 15
-    }
-  }
-  
   providers = {
     osm: (x, y, z) => {
       // use 3 urls to download the tiles faster
@@ -25,40 +16,66 @@ export default class Pigeon extends React.Component{
   }
   
   zoomIn = () => {
-    this.setState({
-      zoom: Math.min(this.state.zoom + 1, 22),
-    })
+    let newZoom = Math.min(this.props.mapConfig.zoom + 1, 22)
+    this.props.updateMapState("zoom", newZoom)
   }
   
   zoomOut = () => {
-    this.setState({
-      zoom: Math.max(this.state.zoom - 1, 0),
-    })
+    let newZoom = Math.max(this.props.mapConfig.zoom - 1, 0)
+    this.props.updateMapState("zoom", newZoom)
   }
 
-  render(){
+  removeMarkers = () => {
+    this.props.updateMapState("path", [])
+  }
 
+  addMarker = (event) => {
+    const lat = event.latLng[0]
+    const lng = event.latLng[1]
+    console.log("Clicked at", lat, "/", lng, event)
+    let pathCopy = this.props.mapConfig.path.slice();
+    pathCopy.push([lat, lng]);
+    this.props.updateMapState("path", pathCopy)
+    this.props.calcDistance()
+  }
+
+  render(){
+    const mapConfig = this.props.mapConfig;
     return (
       <div>
         <Map
-          center={[48.336950, 14.320570]}
-          defaultZoom={15}
-          zoom={this.state.zoom}
-          width={600}
-          height={400}
+          center={mapConfig.coords}
+          defaultZoom={mapConfig.defaultZoom}
+          zoom={mapConfig.zoom}
+          width={mapConfig.width}
+          height={mapConfig.height}
           attribution="Pigeon Map"
           attributionPrefix={false}
-          animation={true} 
-          provider={this.providers["osm"]}>
-          {/* animation: for example when switching between different markers */}
-            <Marker anchor={[48.336950, 14.320570]} payload={1} onClick={({ event, anchor, payload }) => {}} />
-        
+          animation={true}
+          provider={this.providers["osm"]}
+          dprs={[1, 2]}
+          onClick={(event) => this.addMarker(event)}
+        >
+           <Marker anchor={[48.336950, 14.320570]} payload={1} onClick={({ event, anchor, payload }) => {}} />
+
+            {mapConfig.path.map((pos, idx) =>
+              <Marker anchor={pos} key={idx}/>
+            )}
+
             <Overlay anchor={[48.337069, 14.319570]} offset={[120, 79]}>
               {/*<img src='pigeon.png' width={240} height={158} alt='pigeon' />*/}
             </Overlay>
         </Map>
-        <button onClick={this.zoomIn}>+</button>
-        <button onClick={this.zoomOut}>-</button>
+
+        <div>
+          <button onClick={this.zoomIn}>+</button>
+          <button onClick={this.zoomOut}>-</button>
+          <button onClick={this.removeMarkers}>Clear path</button>
+          <button onClick={this.props.calcDistance}>Calculate Distance</button>
+          <p>
+            Distanz: {Math.round(mapConfig.distance*100)/100} km
+          </p>
+        </div>
       </div>
     );
   }