123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- import React from "react";
- import GoogleMapReact from "google-map-react";
- import "./../css/maps.css";
- import apiKey from './../config/googleApiKey.js';
- import {calcDistance} from './../helpers/distance';
- import {longitude, latitude, mapWidth, mapHeight, markerIcon, testPath} from "./../config/variables";
- import {Button} from "reactstrap";
- import PathButtons from "./../PathButtons";
- import EvaluationTable from "./../EvaluationTable";
- const svgStyle = {
- top: "-20",
- left: "-8",
- position: "absolute"
- };
- const Marker = ({ text }) =>
- <div>
- <svg height={20} viewBox="0 0 24 24" style={svgStyle}>
- <path d={markerIcon}/>
- </svg>
- <p>{text}</p>
- </div>;
- let pathPolyLines = [];
- export default class Google extends React.Component{
- constructor(props){
- super(props);
- this.state = {
- latitude: latitude,
- longitude: longitude,
- zoom: 15,
- distance: 0,
- path: testPath,
- draggable: true
- }
- }
- componentDidUpdate(){
- this.drawPath()
- }
- updateState = (key, value) => {
- this.setState({[key]: value})
- this.getDistance()
- }
- getRoute = (lng, lat) => {
- let pathCopy = this.state.path.slice();
- var end = [lat, lng];
- if (this.state.path.length < 1){
- pathCopy.push(end)
- this.setState({path: pathCopy})
- } else {
- console.log("requesting the directions..")
- var start = this.state.path[this.state.path.length-1];
- var proxyurl = "https://cors-anywhere.herokuapp.com/";
- var baseUrl = "https://maps.googleapis.com/maps/api/directions/json?mode=walking&origin="
- var url = baseUrl + start[0] + "," + start[1] + "&destination=" + end[0] + "," + end[1] + "&key=" + apiKey;
- var reqOptions = {
- method:'GET',
- mode: 'cors',
- headers:{
- 'Access-Control-Allow-Origin':'*'
- },
- }
- fetch(proxyurl + url, reqOptions)
- .then(response => response.json())
- .then(data => {
- let routes = data.routes
- if(routes.length > 0){
- let steps = routes[0].legs[0].steps
- steps.forEach(step => {
- pathCopy.push([step.end_location.lat, step.end_location.lng])
- })
- } else{
- pathCopy.push(end)
- }
- this.setState({path: pathCopy})
- this.getDistance()
- })
- .catch((error) =>{
- console.error(error);
- });
- }
- }
- onMarkerInteraction = (childKey, childProps, mouse) => {
- this.setState({draggable: false});
- }
- addMarker = (event) => {
- const lng = event.lng
- const lat = event.lat
- let pathCopy = this.state.path.slice();
- pathCopy.push([lat, lng])
- this.setState({path: pathCopy})
- // this.getRoute(lng, lat);
- this.getDistance()
- }
- updateMarker = (childKey, childProps, mouse) => {
- const lng = mouse.lng
- const lat = mouse.lat
- console.log("new position (marker", childKey, "):", lat, lng)
- let pathCopy = this.state.path.slice();
- pathCopy[childKey] = [lat, lng]
- this.setState({path: pathCopy, draggable: true})
- this.getDistance()
- pathPolyLines.forEach(polyline => {
- polyline.setMap(null);
- })
- this.drawPath();
- }
- getDistance = () => {
- let dst = calcDistance(this.state.path)
- this.setState({distance: dst})
- }
- clearPath = () => {
- this.setState({path: [], distance: 0})
- pathPolyLines.forEach(polyline => {
- polyline.setMap(null);
- })
- }
- drawPath = () => {
- if (!this.props.markers){
- let path = this.state.path.map(p => {
- return {lat: p[0], lng: p[1]}
- })
- let map = this.state.map
- let maps = this.state.maps
- pathPolyLines.push(new maps.Polyline({
- path: path,
- geodesic: true,
- strokeColor: "#212529",
- strokeOpacity: 1.0,
- strokeWeight: 4,
- map,
- }));
- }
- }
- handleApiLoaded = (map, maps) => {
- // map.setMapTypeId("satellite");
- this.setState({map: map, maps: maps})
- }
- 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
- lat={pos[0]}
- lng={pos[1]}
- key={idx}
- />
- )
- }else{
- markers = this.state.path.map((pos, idx) =>
- <Marker
- lat={pos[0]}
- lng={pos[1]}
- text={idx}
- key={idx}
- draggable={true}
- onDragEnd={(e) => this.updateMarker(idx, e)}
- />
- )}
- return (
- <div>
- <div className="map" style={{height: mapHeight, width: mapWidth}}>
- <GoogleMapReact
- bootstrapURLKeys={{ key: apiKey }}
- defaultCenter={position}
- defaultZoom={this.state.zoom}
- yesIWantToUseGoogleMapApiInternals
- layerTypes={['TrafficLayer', 'TransitLayer']}
- onClick={(e, c) => this.addMarker(e, c)}
- draggable={this.state.draggable}
- onChildMouseDown={this.onMarkerInteraction}
- onChildMouseUp={this.updateMarker}
- onGoogleApiLoaded={({map, maps}) => this.handleApiLoaded(map, maps)}
- >
- {markers}
- </GoogleMapReact>
- </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>
- <EvaluationTable mapId="google"/>
- </div>
- );
- }
- }
|