summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xlib/Travelynx.pm7
-rwxr-xr-xlib/Travelynx/Controller/Traveling.pm26
-rw-r--r--share/locales/en_GB.po15
-rw-r--r--templates/journey.html.ep79
-rw-r--r--templates/polyline.gpx.ep20
5 files changed, 112 insertions, 35 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm
index 607b153..586f1a0 100755
--- a/lib/Travelynx.pm
+++ b/lib/Travelynx.pm
@@ -69,6 +69,8 @@ sub startup {
$self->types->type( csv => 'text/csv; charset=utf-8' );
$self->types->type( json => 'application/json; charset=utf-8' );
+ $self->types->type( gpx => 'application/gpx+xml; charset=utf-8' );
+ $self->types->type( xml => 'text/xml; charset=utf-8' );
$self->plugin('Config');
@@ -3174,6 +3176,11 @@ sub startup {
$authed_r->get( '/journey/:id' => [ format => [ 'html', 'json' ] ] )
->to( 'traveling#journey_details', format => undef )
->name('journey');
+ $authed_r->get( '/polyline/:id' => [ format => [ 'gpx', 'json' ] ] )->to(
+ 'traveling#journey_details',
+ format => undef,
+ polyline_export => 1
+ )->name('polyline_download');
$authed_r->get('/s/*station')->to('traveling#station');
$authed_r->get('/confirm_mail/:token')->to('account#confirm_mail');
$authed_r->post('/account/privacy')->to('account#privacy');
diff --git a/lib/Travelynx/Controller/Traveling.pm b/lib/Travelynx/Controller/Traveling.pm
index e23301e..084b45e 100755
--- a/lib/Travelynx/Controller/Traveling.pm
+++ b/lib/Travelynx/Controller/Traveling.pm
@@ -2149,6 +2149,32 @@ sub journey_details {
);
if ($journey) {
+
+ if ( $self->stash('polyline_export') ) {
+ delete $self->stash->{layout};
+ my $xml = $self->render_to_string(
+ template => 'polyline',
+ name => sprintf( '%s %s: %s → %s',
+ $journey->{type}, $journey->{no},
+ $journey->{from_name}, $journey->{to_name} ),
+ polyline => $journey->{polyline}
+ );
+ $self->respond_to(
+ gpx => {
+ text => $xml,
+ format => 'gpx'
+ },
+ json => {
+ json => [
+ map {
+ $_->[2] ? [ $_->[0], $_->[1], int( $_->[2] ) ] : $_
+ } @{ $journey->{polyline} }
+ ]
+ },
+ );
+ return;
+ }
+
my $map_data = $self->journeys_to_map_data(
journeys => [$journey],
include_manual => 1,
diff --git a/share/locales/en_GB.po b/share/locales/en_GB.po
index 6121045..48fb05a 100644
--- a/share/locales/en_GB.po
+++ b/share/locales/en_GB.po
@@ -270,6 +270,21 @@ msgstr "Export"
msgid "journey.edit"
msgstr "Edit"
+msgid "journey.map-data"
+msgstr "Map Data"
+
+msgid "journey.map.download"
+msgstr "Download"
+
+msgid "journey.map.upload"
+msgstr "Upload"
+
+msgid "journey.map.info"
+msgstr "JSON format: [[lon, lat, station ID], ...], with lon/lat in WGS84 coordinates. GPX files are compatible with BRouter. Uploads may cover either the entire route or just the route segment that belongs to this checkin; station IDs are optional when uploading map data."
+
+msgid "journey.danger"
+msgstr "Danger Zone"
+
msgid "journey.delete"
msgstr "Delete"
diff --git a/templates/journey.html.ep b/templates/journey.html.ep
index f9c78ec..b7b4223 100644
--- a/templates/journey.html.ep
+++ b/templates/journey.html.ep
@@ -317,11 +317,24 @@
</div>
</div>
% if (not stash('readonly')) {
- % if (stash('with_share')) {
- <div class="row">
- <div class="col s12 m6 l6">
- </div>
- <div class="col s12 m6 l6 center-align">
+ <div class="row">
+ <div class="col s12 m6 l4 center-align">
+ <a class="btn waves-effect waves-light" href="<%= url_for('journey', id => $journey->{id}, format => 'json' ) %>">
+ <i class="material-icons left" aria-hidden="true">file_download</i>
+ %= L('journey.export')
+ </a>
+ </div>
+ <div class="col s12 m6 l4 center-align">
+ %= form_for '/journey/edit' => (method => 'POST') => begin
+ %= hidden_field 'journey_id' => param('journey_id')
+ <button class="btn waves-effect waves-light" type="submit" name="action" value="edit">
+ <i class="material-icons left" aria-hidden="true">edit</i>
+ %= L('journey.edit')
+ </button>
+ %= end
+ </div>
+ <div class="col s12 m6 l4 center-align">
+ % if (stash('with_share')) {
<a class="btn waves-effect waves-light action-share"
% if (stash('journey_visibility') eq 'public') {
data-url="<%= url_for('public_journey', name => current_user()->{name}, id => $journey->{id} )->to_abs->scheme('https'); %>"
@@ -334,50 +347,46 @@
<i class="material-icons left" aria-hidden="true">share</i>
%= L('journey.share')
</a>
- </div>
+ % }
</div>
- % }
+ </div>
+ <h2><%= L('journey.map-data') %></h2>
<div class="row">
- <div class="col s12 m6 l6">
+ <div class="col s12 m6 l6 center-align">
+ <a class="btn waves-effect waves-light" href="<%= url_for('polyline_download', id => $journey->{id}, format => 'json' ) %>">
+ <i class="material-icons left" aria-label="<%= L('journey.map.download') %>">file_download</i>
+ JSON
+ </a>
</div>
<div class="col s12 m6 l6 center-align">
- <a class="btn waves-effect waves-light" href="<%= url_for('journey', id => $journey->{id}, format => 'json' ) %>">
- <i class="material-icons left" aria-hidden="true">file_download</i>
- %= L('journey.export')
+ <a class="btn waves-effect waves-light" href="<%= url_for('polyline_download', id => $journey->{id}, format => 'gpx' ) %>">
+ <i class="material-icons left" aria-label="<%= L('journey.map.download') %>">file_download</i>
+ GPX
</a>
</div>
</div>
- <div class="row hide-on-small-only">
+ <div class="row">
<div class="col s12 m6 l6 center-align">
- <a class="waves-effect waves-light red btn action-delete"
- data-id="<%= $journey->{id} %>"
- data-checkin="<%= $journey->{checkin}->epoch %>"
- data-checkout="<%= $journey->{checkout}->epoch %>">
- <i class="material-icons left">delete_forever</i>
- %= L('journey.delete')
+ <a class="btn disabled waves-effect waves-light" href="<%= url_for('journey', id => $journey->{id}, format => 'json' ) %>">
+ <i class="material-icons left" aria-label="<%= L('journey.map.upload') %>">file_upload</i>
+ JSON
</a>
</div>
<div class="col s12 m6 l6 center-align">
- %= form_for '/journey/edit' => (method => 'POST') => begin
- %= hidden_field 'journey_id' => param('journey_id')
- <button class="btn waves-effect waves-light" type="submit" name="action" value="edit">
- <i class="material-icons left" aria-hidden="true">edit</i>
- %= L('journey.edit')
- </button>
- %= end
+ <a class="btn disabled waves-effect waves-light" href="<%= url_for('journey', id => $journey->{id}, format => 'json' ) %>">
+ <i class="material-icons left" aria-label="<%= L('journey.map.upload') %>">file_upload</i>
+ GPX
+ </a>
</div>
</div>
- <div class="row hide-on-med-and-up">
- <div class="col s12 m6 l6 center-align">
- %= form_for '/journey/edit' => (method => 'POST') => begin
- %= hidden_field 'journey_id' => param('journey_id')
- <button class="btn waves-effect waves-light" type="submit" name="action" value="edit">
- <i class="material-icons left" aria-hidden="true">edit</i>
- %= L('journey.edit')
- </button>
- %= end
+ <div class="row">
+ <div class="col s12">
+ %= L('journey.map.info')
</div>
- <div class="col s12 m6 l6 center-align" style="margin-top: 1em;">
+ </div>
+ <h2><%= L('journey.danger') %></h2>
+ <div class="row">
+ <div class="col s12 m12 l12 center-align" style="margin-top: 1em;">
<a class="waves-effect waves-light red btn action-delete"
data-id="<%= $journey->{id} %>"
data-checkin="<%= $journey->{checkin}->epoch %>"
diff --git a/templates/polyline.gpx.ep b/templates/polyline.gpx.ep
new file mode 100644
index 0000000..a243926
--- /dev/null
+++ b/templates/polyline.gpx.ep
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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="travelynx <%= $version %>">
+ <trk>
+ <name><%= $name %></name>
+ <trkseg>
+ % for my $entry (@{$polyline // []}) {
+ <trkpt lon="<%= $entry->[0] %>" lat="<%= $entry->[1] %>">
+ % if ($entry->[2]) {
+ <name><%= $entry->[2] %></name>
+ % }
+ </trkpt>
+ % }
+ </trkseg>
+ </trk>
+</gpx>