MapGL.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import React from "react";
  2. import ReactMapGL from "react-map-gl";
  3. import {
  4. Marker,
  5. NavigationControl,
  6. FullscreenControl,
  7. ScaleControl,
  8. GeolocateControl,
  9. // Layer,
  10. // Source,
  11. } from "react-map-gl";
  12. import "./css/maps.css";
  13. import mapboxToken from './config/mapboxToken.js';
  14. import {calcDistance} from './helpers/distance';
  15. import {longitude, latitude, mapWidth, mapHeight, markerIcon} from "./config/variables";
  16. import {Button} from "reactstrap";
  17. export default class MapGL extends React.Component{
  18. state = {
  19. viewport: {
  20. width: mapWidth,
  21. height: mapHeight,
  22. latitude: latitude,
  23. longitude: longitude,
  24. zoom: 15,
  25. bearing: 0,
  26. pitch: 0
  27. },
  28. path: [[longitude, latitude]],
  29. distance: 0,
  30. };
  31. addMarker = event => {
  32. const lng = event.lngLat[0]
  33. const lat = event.lngLat[1]
  34. console.log("Clicked at", lng, "/", lat);
  35. this.getRoute(lng, lat);
  36. this.getDistance()
  37. }
  38. updateMarker = (idx, event) => {
  39. const lng = event.lngLat[0]
  40. const lat = event.lngLat[1]
  41. console.log(lng, lat, idx)
  42. let pathCopy = this.state.path.slice();
  43. pathCopy[idx] = [lng, lat]
  44. this.setState({path: pathCopy})
  45. this.getDistance()
  46. }
  47. getDistance = () => {
  48. let dst = calcDistance(this.state.path)
  49. this.setState({distance: dst})
  50. }
  51. clearPath = () => {
  52. this.setState({path: [], distance: 0})
  53. }
  54. getRoute = (lng, lat) => {
  55. let pathCopy = this.state.path.slice();
  56. var end = [lng, lat];
  57. if (this.state.path.length < 1){
  58. pathCopy.push(end)
  59. this.setState({path: pathCopy})
  60. } else {
  61. var start = this.state.path[this.state.path.length-1];
  62. var baseUrl = "https://api.mapbox.com/directions/v5/mapbox/"
  63. var url = baseUrl + "driving/" + start[0] + "," + start[1] + ";" + end[0] + "," + end[1] + "?alternatives=true&geometries=geojson&steps=true&access_token=" + mapboxToken;
  64. var req = new XMLHttpRequest();
  65. req.open('GET', url, true);
  66. req.onload = (self) => {
  67. var json = JSON.parse(req.response);
  68. var data = json.routes[0];
  69. var route = data.geometry.coordinates;
  70. route.map((pos) => pathCopy.push(pos))
  71. pathCopy.push(end)
  72. this.setState({path: pathCopy})
  73. };
  74. req.send();
  75. }
  76. }
  77. // geojson = {
  78. // type: 'FeatureCollection',
  79. // features: [{
  80. // type: 'Feature',
  81. // geometry: {
  82. // type: 'LineString',
  83. // coordinates: this.state.path
  84. // }
  85. // }]
  86. // }
  87. render() {
  88. return (
  89. <div>
  90. <div className="map">
  91. <ReactMapGL
  92. {...this.state.viewport}
  93. onViewportChange={(viewport) => this.setState({viewport})}
  94. mapboxApiAccessToken={mapboxToken}
  95. mapStyle="mapbox://styles/mapbox/streets-v11"
  96. onClick={this.addMarker}
  97. >
  98. {/*
  99. <Source id="my-data" type="geojson" data={this.geojson}>
  100. <Layer
  101. source="my-data"
  102. id="point"
  103. type="line"
  104. paint={{
  105. "line-color": "#888",
  106. "line-width": 8
  107. }}
  108. layout= {{
  109. "line-join": "round",
  110. "line-cap": "round"
  111. }}
  112. />
  113. </Source>
  114. */}
  115. {this.state.path.map((pos, idx) =>
  116. <Marker
  117. longitude={pos[0]}
  118. latitude={pos[1]}
  119. captureClick={false}
  120. draggable={true}
  121. offsetTop={-20}
  122. offsetLeft={-8}
  123. key={idx}
  124. onDragEnd={(e) => this.updateMarker(idx, e)}
  125. >
  126. <svg height={20} viewBox="0 0 24 24" style={{fill: "#343a40", stroke: "none"}}>
  127. <path d={markerIcon} />
  128. </svg>
  129. </Marker>
  130. )}
  131. <div className="controllers">
  132. <GeolocateControl />
  133. <FullscreenControl />
  134. <NavigationControl />
  135. <ScaleControl />
  136. <small> {'\u00A9'} Mapbox {'\u00A9'} OpenStreetMap </small>
  137. </div>
  138. </ReactMapGL>
  139. </div>
  140. <div className="mapInfo">
  141. <Button onClick={this.clearPath}>Clear path</Button>
  142. <Button onClick={this.getDistance}>Calculate Distance</Button>
  143. <p>
  144. Distanz: {Math.round(this.state.distance*100)/100} km
  145. </p>
  146. </div>
  147. </div>
  148. );
  149. }
  150. }