Mapbox.js 4.9 KB

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