Activities: display gpx on map

This commit is contained in:
Sam
2018-05-03 21:42:54 +02:00
parent 4d2f2e1afb
commit a88a9a328c
10 changed files with 198 additions and 18 deletions

View File

@ -2,6 +2,10 @@ import mpwoApi from '../mwpoApi/activities'
import { history } from '../index'
import { setError } from './index'
export const setGpx = gpxContent => ({
type: 'SET_GPX',
gpxContent,
})
export function addActivity(form) {
return function(dispatch) {
@ -17,3 +21,18 @@ export function addActivity(form) {
.catch(error => dispatch(setError(`activities: ${error}`)))
}
}
export function getActivityGpx(activityId) {
return function(dispatch) {
return mpwoApi
.getActivityGpx(activityId)
.then(ret => {
if (ret.status === 'success') {
dispatch(setGpx(ret.data.gpx))
} else {
dispatch(setError(`activities: ${ret.message}`))
}
})
.catch(error => dispatch(setError(`activities: ${error}`)))
}
}

View File

@ -73,7 +73,7 @@ class ActivityDisplay extends React.Component {
Map
</div>
<div className="card-body">
<ActivityMap />
<ActivityMap activity={activity} />
</div>
</div>
</div>

View File

@ -1,30 +1,57 @@
import React from 'react'
import { Map, TileLayer } from 'react-leaflet'
import { GeoJSON, Map, TileLayer } from 'react-leaflet'
import { connect } from 'react-redux'
import { thunderforestApiKey } from '../../utils'
import { getActivityGpx } from '../../actions/activities'
import { getGeoJson, thunderforestApiKey } from '../../utils'
export default class ActivityMap extends React.Component {
class ActivityMap extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
lat: 51.505,
lng: -0.09,
zoom: 13,
zoom: 13,
}
}
componentDidMount() {
this.props.loadActivityGpx(this.props.activity.id)
}
render() {
const position = [this.state.lat, this.state.lng]
const { gpxContent } = this.props
const { jsonData, bounds } = getGeoJson(gpxContent)
return (
<Map center={position} zoom={this.state.zoom}>
<TileLayer
// eslint-disable-next-line max-len
attribution='&copy; <a href="http://www.thunderforest.com/">Thunderforest</a>, &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
url="https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png"
apikey={thunderforestApiKey}
/>
</Map>
<div>
{jsonData && (
<Map
zoom={this.state.zoom}
bounds={bounds}
boundsOptions={{ padding: [50, 50] }}
>
<TileLayer
// eslint-disable-next-line max-len
attribution='&copy; <a href="http://www.thunderforest.com/">Thunderforest</a>, &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
// eslint-disable-next-line max-len
url={`https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=${thunderforestApiKey}`}
/>
<GeoJSON data={jsonData} />
</Map>
)}
</div>
)
}
}
export default connect(
state => ({
gpxContent: state.gpx
}),
dispatch => ({
loadActivityGpx: activityId => {
dispatch(getActivityGpx(activityId))
},
})
)(ActivityMap)

View File

@ -15,4 +15,16 @@ export default class MpwoApi {
.catch(error => error)
}
static getActivityGpx(activityId) {
const request = new Request(`${apiUrl}activities/${activityId}/gpx`, {
method: 'GET',
headers: new Headers({
Authorization: `Bearer ${window.localStorage.getItem('authToken')}`,
}),
})
return fetch(request)
.then(response => response.json())
.catch(error => error)
}
}

View File

@ -66,6 +66,15 @@ const formProfile = (state = initial.formProfile, action) => {
}
}
const gpx = (state = initial.gpx, action) => {
switch (action.type) {
case 'SET_GPX':
return action.gpxContent
default:
return state
}
}
const message = (state = initial.message, action) => {
switch (action.type) {
case 'AUTH_ERROR':
@ -144,6 +153,7 @@ const reducers = combineReducers({
activities,
formData,
formProfile,
gpx,
message,
messages,
router: routerReducer,

View File

@ -41,6 +41,8 @@ export default {
activities: {
...emptyData,
},
// check if storing gpx content is OK
gpx: null,
sports: {
...emptyData,
}

View File

@ -1,3 +1,6 @@
import togeojson from '@mapbox/togeojson'
import bbox from 'geojson-bbox'
export const apiUrl = `${process.env.REACT_APP_API_URL}/api/`
export const thunderforestApiKey = `${
process.env.REACT_APP_THUNDERFOREST_API_KEY
@ -13,3 +16,18 @@ export function generateIds(arr) {
return obj
})
}
export function getGeoJson(gpxContent) {
let jsonData, bboxCorners
let bounds = [[0, 0], [0, 0]]
if (gpxContent) {
const gpx = new DOMParser().parseFromString(gpxContent, 'text/xml')
jsonData = togeojson.gpx(gpx)
bboxCorners = bbox(jsonData)
bounds = [
[bboxCorners[1], bboxCorners[0]],
[bboxCorners[3], bboxCorners[2]]
]
}
return { jsonData, bounds }
}