Mapbox.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import React from "react";
  2. import ReactMapboxGl, {
  3. Layer,
  4. Feature,
  5. ZoomControl,
  6. ScaleControl,
  7. RotationControl,
  8. Source,
  9. Marker,
  10. } from "react-mapbox-gl";
  11. import mapboxToken from "./../config/mapboxToken.js";
  12. import {calcDistance} from "./../helpers/distance";
  13. import {longitude, latitude, mapWidth, mapHeight, markerIcon} from "./../config/variables";
  14. import {Button} from "reactstrap";
  15. import {getRoute, mapStyles} from "./../helpers/mapboxHelper";
  16. import PathButtons from "./../PathButtons";
  17. import {GeoJSONLayer} from "react-mapbox-gl";
  18. const Map = ReactMapboxGl({ accessToken: mapboxToken });
  19. export default class Mapbox extends React.Component{
  20. constructor(props){
  21. super(props);
  22. this.state = {
  23. latitude: latitude,
  24. longitude: longitude,
  25. zoom: [14],
  26. path: [[longitude, latitude], [longitude+0.003, latitude]],
  27. distance: 0,
  28. center: [longitude, latitude]
  29. }
  30. this.getRoute = getRoute.bind(this)
  31. }
  32. updateState = (key, value) => {
  33. this.setState({[key]: value})
  34. this.getDistance()
  35. }
  36. addMarker = (event, click) => {
  37. const lng = click.lngLat.lng
  38. const lat = click.lngLat.lat
  39. this.getRoute(lng, lat);
  40. // let pathCopy = this.state.path.slice();
  41. // pathCopy.push([lng, lat]);
  42. // this.setState({path: pathCopy})
  43. this.getDistance()
  44. }
  45. updateMarker = (idx, event) => {
  46. const lng = event.lngLat.lng
  47. const lat = event.lngLat.lat
  48. let pathCopy = this.state.path.slice();
  49. pathCopy[idx] = [lng, lat]
  50. this.setState({path: pathCopy})
  51. this.getDistance()
  52. }
  53. getDistance = () => {
  54. let dst = calcDistance(this.state.path)
  55. this.setState({distance: dst})
  56. }
  57. clearPath = () => {
  58. this.setState({path: [], distance: 0})
  59. }
  60. render() {
  61. let testMarkers = this.props.markers
  62. let testMarkerType = this.props.markerType
  63. let markers = <></>
  64. if (testMarkers){
  65. if (testMarkerType === "feature"){
  66. markers = (
  67. <Layer type="symbol" id="marker" layout={{"icon-image": "marker-15"}}>
  68. {testMarkers.map((pos, idx) =>
  69. <Feature
  70. coordinates={pos}
  71. key={idx}
  72. />
  73. )}
  74. </Layer>
  75. )
  76. } else {
  77. markers = testMarkers.map((pos, idx) =>
  78. <Marker
  79. coordinates={pos}
  80. key={idx}
  81. anchor="bottom"
  82. >
  83. <svg height={15} viewBox="0 0 24 24" style={{fill: "#343a40"}}>
  84. <path d={markerIcon} />
  85. </svg>
  86. </Marker>
  87. )}
  88. } else {
  89. markers = this.state.path.map((pos, idx) =>
  90. <Feature
  91. coordinates={pos}
  92. key={idx}
  93. draggable={true}
  94. onDragEnd={(e) => this.updateMarker(idx, e)}
  95. />
  96. )
  97. }
  98. return (
  99. <div>
  100. <div className="map">
  101. <Map
  102. style={mapStyles.bright}
  103. containerStyle={{
  104. height: mapHeight,
  105. width: mapWidth
  106. }}
  107. center={this.state.center}
  108. zoom={this.state.zoom}
  109. onClick={(e, c) => this.addMarker(e, c)}
  110. >
  111. {/*<Layer type="line" layout={{'line-join': 'round', 'line-cap': 'round'}}
  112. paint={{"line-color": "#888", "line-width": 3}}
  113. source="routeSource"
  114. id="routeSource"
  115. type="line"
  116. data={{type: "LineString", coordinates: this.state.path}}
  117. >
  118. <Feature
  119. source="routeSource"
  120. id="route"
  121. type="line"
  122. data={{type: "line", coordinates: this.state.path}}
  123. paint={{"line-color": "#888", "line-width": 3}}
  124. layout= {{"line-join": "round", "line-cap": "round"}}
  125. />
  126. </Layer>*/}
  127. <Source
  128. id="routeSource"
  129. type="geojson"
  130. data={{type: "LineString", coordinates: this.state.path}}
  131. >
  132. <Layer
  133. source="routeSource"
  134. id="route"
  135. type="line"
  136. paint={{"line-color": "#888", "line-width": 3}}
  137. layout= {{"line-join": "round", "line-cap": "round"}}
  138. />
  139. </Source>
  140. {markers}
  141. <ZoomControl position={"top-right"}/>
  142. <ScaleControl position={"bottom-right"}/>
  143. <RotationControl position={"top-right"}/>
  144. </Map>
  145. </div>
  146. <div className="mapInfo">
  147. <Button onClick={this.clearPath}>Clear path</Button>
  148. <Button onClick={this.getDistance}>Calculate Distance</Button>
  149. <p>
  150. Distanz: {Math.round(this.state.distance*100)/100} km
  151. </p>
  152. <PathButtons updateState={this.updateState} path={this.state.path} switchLatLng={true}/>
  153. </div>
  154. </div>
  155. );
  156. }
  157. }