Skip to content

Commit

Permalink
Merge pull request #35 from developmentseed/feature/trace-as-gpx
Browse files Browse the repository at this point in the history
Download trace as GPX
  • Loading branch information
vgeorge authored Nov 22, 2019
2 parents 25275d7 + ea1615a commit f9db9e9
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 30 deletions.
36 changes: 36 additions & 0 deletions app/_apidoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,39 @@
* }
* }
*/

/**
* @apiDefine Success200GPX
*
* @apiSuccess {String} file Trace in GPX format.
* @apiSuccessExample {String} Success response:
* HTTP/1.1 200 Success
* <gpx xmlns="http://www.topografix.com/GPX/1/1"
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" creator="togpx">
* <metadata/>
* <trk>
* <name>_EQOlQXjjY</name>
* <desc>id=_EQOlQXjjY ownerId=709 ownerDisplayName=vitor description=This is a TraceJSON file. length=534.717</desc>
* <trkseg>
* <trkpt lat="-23.5927391909129" lon="-46.6599869728088">
* <time>2019-07-24T23:34:20.021Z</time>
* </trkpt>
* <trkpt lat="-23.5919329603572" lon="-46.6597080230712">
* <time>2019-07-24T23:34:21.801Z</time>
* </trkpt>
* <trkpt lat="-23.590930081288" lon="-46.6589999198913">
* <time>2019-07-24T23:34:22.345Z</time>
* </trkpt>
* <trkpt lat="-23.590320484382" lon="-46.6580557823181">
* <time>2019-07-24T23:34:23.968Z</time>
* </trkpt>
* <trkpt lat="-23.5900648461272" lon="-46.6571545600891">
* <time>2019-07-24T23:34:24.112Z</time>
* </trkpt>
* <trkpt lat="-23.58951423896" lon="-46.6564464569091">
* <time>2019-07-24T23:34:25.883Z</time>
* </trkpt>
* </trkseg>
* </trk>
* </gpx>
*/
99 changes: 70 additions & 29 deletions app/routes/traces/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,88 @@ import Joi from '@hapi/joi';
import { getTraceJson } from '../../models/traces';
import logger from '../../services/logger';
import config from 'config';
import togpx from 'togpx';

const idLength = config.get('idLength');

/**
* @apiGroup Traces
*
* @api {get} /traces/:id 4. GET /traces/:id
* @apiDescription Get trace, must be owner or admin.
*
* @apiParam {string} id Trace id.
*
* @apiUse Success200TraceJSON
* @apiUse Error4xx
*/
const validate = {
params: Joi.object({
id: Joi.string().length(idLength)
})
};

export default [
/**
* @apiGroup Traces
*
* @api {get} /traces/:id 4. GET /traces/:id
* @apiDescription Get trace as GeoJSON. Must be trace's owner or admin.
*
* @apiParam {string} id Trace id.
*
* @apiUse AuthorizationHeader
* @apiUse Success200TraceJSON
* @apiUse Error4xx
*/
{
path: '/traces/{id}',
method: ['GET'],
options: {
auth: 'jwt',
validate: {
params: Joi.object({
id: Joi.string().length(idLength)
})
}
validate
},
handler: async function (request, h) {
try {
const { id } = request.params;
handler: handler('json')
},
/**
* @apiGroup Traces
*
* @api {get} /traces/:id.gpx 5. GET /traces/:id.gpx
* @apiDescription Get trace in GPX format. No authorization is required.
*
* @apiParam {string} id Trace id.
*
* @apiUse Success200GPX
* @apiUse Error4xx
*/
{
path: '/traces/{id}.gpx',
method: ['GET'],
options: {
validate
},
handler: handler('gpx')
}
];

function handler (type) {
return async (request, h) => {
try {
const { id } = request.params;

const trace = await getTraceJson(id);
const trace = await getTraceJson(id);

if (!trace) {
return Boom.notFound(`Trace ${id} not found`);
}

if (!trace) {
return Boom.notFound(`Trace ${id} not found`);
}
if (type === 'gpx') {
// Generate GPX file
const gpx = togpx(trace, {
featureCoordTimes: f =>
f.properties.timestamps.map(t => new Date(t).toISOString())
});

return trace;
} catch (error) {
logger.error(error);
return Boom.badImplementation('Unexpected error.');
// Return as text/plain
const response = h.response(gpx);
response.type('text/plain');
return response;
}

// Return as TraceJSON
return trace;
} catch (error) {
logger.error(error);
return Boom.badImplementation('Unexpected error.');
}
}
];
};
}
2 changes: 1 addition & 1 deletion app/routes/traces/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import logger from '../../services/logger';
/**
* @apiGroup Traces
*
* @api {get} /traces 5. GET /traces
* @api {get} /traces 6. GET /traces
* @apiDescription Get a list of photos.
*
* @apiUse AuthorizationHeader
Expand Down
66 changes: 66 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"pg": "^7.12.1",
"qs": "^6.9.0",
"sharp": "^0.23.2",
"togpx": "^0.5.4",
"uuid": "^3.3.3",
"winston": "^3.2.1",
"xml-js": "^1.6.11"
Expand Down

0 comments on commit f9db9e9

Please sign in to comment.