const axios = require('axios');
const moment = require('moment');
const express = require('express');
const config = require('./config');
const db = require('./db');
let router = express.Router();
module.exports = router;
router.get('/associations/:association.gpx', (req, res) => {
res.cacheControl = {
noCache: true
};
res.set('Content-Type', 'application/gpx+xml');
res.set('Content-Disposition', 'attachment; filename="' + req.params.association + '.gpx"');
gpxForQuery('^' + req.params.association + '/', `SOTA Association ${req.params.association}`, req.query, (err, gpx) => {
if (err) {
console.error(err);
res.status(500).end();
return;
}
res.send(gpx).end();
});
});
router.get('/associations/:association.kml', (req, res) => {
res.cacheControl = {
noCache: true
};
res.set('Content-Type', 'application/vnd.google-earth.kml+xml');
res.set('Content-Disposition', 'attachment; filename="' + req.params.association + '.kml"');
kmlForAssociation(req.params.association, req.query, (err, kml) => {
if (err) {
console.error(err);
res.status(500).end();
return;
}
if (!kml) {
res.status(404).end();
return;
}
res.send(kml).end();
});
});
router.get('/associations/:association.geojson', (req, res) => {
res.cacheControl = {
noCache: true
};
res.set('Content-Type', 'application/geo+json');
res.set('Content-Disposition', 'attachment; filename="' + req.params.association + '.geojson"');
geoJsonForQuery('^' + req.params.association + '/', req.query, (err, geoJson) => {
if (err) {
console.error(err);
res.status(500).end();
return;
}
res.json(geoJson).end();
});
});
router.get('/regions/:association/:region.gpx', (req, res) => {
res.cacheControl = {
noCache: true
};
res.set('Content-Type', 'application/gpx+xml');
res.set('Content-Disposition', 'attachment; filename="' + req.params.association + '_' + req.params.region + '.gpx"');
gpxForQuery('^' + req.params.association + '/' + req.params.region + '-', `SOTA Region ${req.params.association + '/' + req.params.region}`, req.query, (err, gpx) => {
if (err) {
console.error(err);
res.status(500).end();
return;
}
res.send(gpx).end();
});
});
router.get('/regions/:association/:region.kml', (req, res) => {
res.cacheControl = {
noCache: true
};
res.set('Content-Type', 'application/vnd.google-earth.kml+xml');
res.set('Content-Disposition', 'attachment; filename="' + req.params.association + '_' + req.params.region + '.kml"');
kmlForRegion(req.params.association, req.params.region, req.query, (err, kml) => {
if (err) {
console.error(err);
res.status(500).end();
return;
}
if (!kml) {
res.status(404).end();
return;
}
res.send(kml).end();
});
});
router.get('/regions/:association/:region.geojson', (req, res) => {
res.cacheControl = {
noCache: true
};
res.set('Content-Type', 'application/geo+json');
res.set('Content-Disposition', 'attachment; filename="' + req.params.association + '_' + req.params.region + '.geojson"');
geoJsonForQuery('^' + req.params.association + '/' + req.params.region + '-', req.query, (err, geoJson) => {
if (err) {
console.error(err);
res.status(500).end();
return;
}
res.json(geoJson).end();
});
});
function gpxForQuery(query, name, options, callback) {
let filter = {code: {$regex: query}};
if (!options.inactive) {
filter.validFrom = {$lte: new Date()};
filter.validTo = {$gte: new Date()};
}
db.getDb().collection('summits').find(filter).sort({code: 1}).toArray((err, summits) => {
if (err) {
callback(err);
return;
}
let minlat, minlon, maxlat, maxlon;
summits.forEach(summit => {
if (!minlat || summit.coordinates.latitude < minlat) {
minlat = summit.coordinates.latitude;
}
if (!minlon || summit.coordinates.longitude < minlon) {
minlon = summit.coordinates.longitude;
}
if (!maxlat || summit.coordinates.latitude > maxlat) {
maxlat = summit.coordinates.latitude;
}
if (!maxlon || summit.coordinates.longitude > maxlon) {
maxlon = summit.coordinates.longitude;
}
});
let now = moment.utc();
let gpx = `
${name}
SOTLAS
SOTLAS
`;
summits.forEach(summit => {
gpx += `
${summit.altitude}
SOTA${('0' + summit.points).substr(-2)}
Summit
`;
});
gpx += "";
callback(null, gpx);
});
}
function kmlForAssociation(associationCode, options, callback) {
db.getDb().collection('associations').findOne({code: associationCode}, (err, association) => {
if (err) {
callback(err);
return;
}
if (!association) {
callback(null, null);
return;
}
let filter = {code: {$regex: "^" + association.code + "/"}};
if (!options.inactive) {
filter.validFrom = {$lte: new Date()};
filter.validTo = {$gte: new Date()};
}
db.getDb().collection('summits').find(filter).sort({code: 1}).toArray((err, summits) => {
let now = moment.utc();
let kmlName = 'SOTA Association ' + association.code + ' - ' + association.name;
let kml = `
${now.toISOString()}
`;
association.regions.forEach(region => {
kml += `
`;
summits.filter(summit => {return summit.code.startsWith(association.code + '/' + region.code)}).forEach(summit => {
kml += kmlForSummit(summit, options);
});
kml += `
`;
});
kml += `
`;
callback(null, kml);
});
});
}
function kmlForRegion(associationCode, regionCode, options, callback) {
db.getDb().collection('associations').findOne({code: associationCode}, (err, association) => {
if (err) {
callback(err);
return;
}
if (!association) {
callback(null, null);
return;
}
let filter = {code: {$regex: "^" + association.code + "/" + regionCode + '-'}};
if (!options.inactive) {
filter.validFrom = {$lte: new Date()};
filter.validTo = {$gte: new Date()};
}
db.getDb().collection('summits').find(filter).sort({code: 1}).toArray((err, summits) => {
let now = moment.utc();
let kmlName = 'SOTA Region ' + associationCode + '/' + regionCode;
let kml = `
${now.toISOString()}
`;
association.regions.forEach(region => {
if (regionCode && region.code !== regionCode) {
return;
}
kml += ` SOTA Region
`;
summits.filter(summit => {return summit.code.startsWith(association.code + '/' + region.code)}).forEach(summit => {
kml += kmlForSummit(summit, options);
});
});
kml += `
`;
callback(null, kml);
});
});
}
function geoJsonForQuery(query, options, callback) {
let filter = {code: {$regex: query}};
if (!options.inactive) {
filter.validFrom = {$lte: new Date()};
filter.validTo = {$gte: new Date()};
}
db.getDb().collection('summits').find(filter).sort({code: 1}).toArray((err, summits) => {
if (err) {
callback(err);
return;
}
let features = summits.map(summit => {
return {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [summit.coordinates.longitude, summit.coordinates.latitude]
},
id: summit.code,
properties: {
code: summit.code,
name: summit.name,
title: summitName(summit, options)
}
}
})
let geojson = {
type: 'FeatureCollection',
features
}
callback(null, geojson);
});
}
function summitName(summit, options) {
let name = summit.code;
let nameopts = [];
if (options.nameopts) {
nameopts = options.nameopts.split(',')
}
if (nameopts.includes('name')) {
name += ' - ' + summit.name;
}
if (nameopts.includes('altitude')) {
name += ', ' + summit.altitude + 'm';
}
if (nameopts.includes('points')) {
name += ', ' + summit.points + 'pt';
}
return name;
}
function kmlForSummit(summit, options) {
return `
${summit.coordinates.longitude},${summit.coordinates.latitude},${summit.altitude}
`;
}