Google.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import React from "react";
  2. import GoogleMapReact from "google-map-react";
  3. import "./css/maps.css";
  4. import apiKey from './config/googleApiKey.js';
  5. import {calcDistance} from './helpers/distance';
  6. import {longitude, latitude, mapWidth, mapHeight, markerIcon, testPath} from "./config/variables";
  7. import {Button} from "reactstrap";
  8. const svgStyle = {
  9. top: "-20",
  10. left: "-8",
  11. position: "absolute"
  12. };
  13. const Marker = ({ text }) =>
  14. <div>
  15. <svg height={20} viewBox="0 0 24 24" style={svgStyle}>
  16. <path d={markerIcon}/>
  17. </svg>
  18. <p>{text}</p>
  19. </div>;
  20. export default class Google extends React.Component{
  21. state = {
  22. latitude: latitude,
  23. longitude: longitude,
  24. zoom: 15,
  25. distance: 0,
  26. path: testPath,
  27. draggable: true
  28. }
  29. componentDidUpdate(){
  30. this.drawPath()
  31. }
  32. getRoute = (lng, lat) => {
  33. let pathCopy = this.state.path.slice();
  34. var end = [lat, lng];
  35. if (this.state.path.length < 1){
  36. pathCopy.push(end)
  37. this.setState({path: pathCopy})
  38. } else {
  39. var start = this.state.path[this.state.path.length-1];
  40. var proxyurl = "https://cors-anywhere.herokuapp.com/";
  41. var baseUrl = "https://maps.googleapis.com/maps/api/directions/json?origin="
  42. var url = baseUrl + start[0] + "," + start[1] + "&destination=" + end[0] + "," + end[1] + "&key=" + apiKey;
  43. var reqOptions = {
  44. method:'GET',
  45. mode: 'cors',
  46. headers:{
  47. 'Access-Control-Allow-Origin':'*'
  48. },
  49. }
  50. fetch(proxyurl + url, reqOptions)
  51. .then(response => response.json())
  52. .then(data => {
  53. let routes = data.routes
  54. if(routes.length > 0){
  55. let steps = routes[0].legs[0].steps
  56. steps.forEach(step => {
  57. pathCopy.push([step.end_location.lat, step.end_location.lng])
  58. })
  59. } else{
  60. pathCopy.push(end)
  61. }
  62. this.setState({path: pathCopy})
  63. this.getDistance()
  64. })
  65. .catch((error) =>{
  66. console.error(error);
  67. });
  68. }
  69. }
  70. onMarkerInteraction = (childKey, childProps, mouse) => {
  71. this.setState({draggable: false});
  72. }
  73. addMarker = (event) => {
  74. const lng = event.lng
  75. const lat = event.lat
  76. // let pathCopy = this.state.path.slice();
  77. // pathCopy.push([lat, lng])
  78. // this.setState({path: pathCopy})
  79. this.getRoute(lng, lat);
  80. this.getDistance()
  81. }
  82. updateMarker = (childKey, childProps, mouse) => {
  83. const lng = mouse.lng
  84. const lat = mouse.lat
  85. console.log("new position (marker", childKey, "):", lat, lng)
  86. let pathCopy = this.state.path.slice();
  87. pathCopy[childKey] = [lat, lng]
  88. this.setState({path: pathCopy, draggable: true})
  89. this.getDistance()
  90. }
  91. getDistance = () => {
  92. let dst = calcDistance(this.state.path)
  93. this.setState({distance: dst})
  94. }
  95. clearPath = () => {
  96. this.setState({path: [], distance: 0})
  97. }
  98. drawPath = () => {
  99. let path = this.state.path.map(p => {
  100. return {lat: p[0], lng: p[1]}
  101. })
  102. let map = this.state.map
  103. let maps = this.state.maps
  104. new maps.Polyline({
  105. path: path,
  106. geodesic: true,
  107. strokeColor: "#212529",
  108. strokeOpacity: 1.0,
  109. strokeWeight: 4,
  110. map,
  111. });
  112. }
  113. handleApiLoaded = (map, maps) => {
  114. this.setState({map: map, maps: maps})
  115. }
  116. render() {
  117. const position = [this.state.latitude, this.state.longitude]
  118. return (
  119. <div>
  120. <div className="map" style={{height: mapHeight, width: mapWidth}}>
  121. <GoogleMapReact
  122. bootstrapURLKeys={{ key: apiKey }}
  123. defaultCenter={position}
  124. defaultZoom={this.state.zoom}
  125. yesIWantToUseGoogleMapApiInternals
  126. layerTypes={['TrafficLayer', 'TransitLayer']}
  127. onClick={(e, c) => this.addMarker(e, c)}
  128. draggable={this.state.draggable}
  129. onChildMouseDown={this.onMarkerInteraction}
  130. onChildMouseUp={this.updateMarker}
  131. onGoogleApiLoaded={({map, maps}) => this.handleApiLoaded(map, maps)}
  132. >
  133. {this.state.path.map((pos, idx) =>
  134. <Marker
  135. lat={pos[0]}
  136. lng={pos[1]}
  137. text={idx}
  138. key={idx}
  139. draggable={true}
  140. onDragEnd={(e) => this.updateMarker(idx, e)}
  141. />
  142. )}
  143. </GoogleMapReact>
  144. </div>
  145. <div className="mapInfo">
  146. <Button onClick={this.clearPath}>Clear path</Button>
  147. <Button onClick={this.getDistance}>Calculate Distance</Button>
  148. <p>
  149. Distanz: {Math.round(this.state.distance*100)/100} km
  150. </p>
  151. </div>
  152. </div>
  153. );
  154. }
  155. }