Adding elevation chart
This commit is contained in:
@@ -5,19 +5,12 @@ class Converter extends PhpObject {
|
||||
const GPX_EXT = '.gpx';
|
||||
const GEO_EXT = '.geojson';
|
||||
|
||||
/**
|
||||
* Project to convert
|
||||
* @var Project
|
||||
*/
|
||||
private $oProject;
|
||||
|
||||
public function __construct(&$oProject) {
|
||||
public function __construct() {
|
||||
parent::__construct(__CLASS__, Settings::DEBUG);
|
||||
$this->oProject = &$oProject;
|
||||
}
|
||||
|
||||
public function convertToGeoJson() {
|
||||
$sFileName = pathinfo($this->oProject->getGeoFile(), PATHINFO_FILENAME);
|
||||
public function convertToGeoJson($sGeoFile) {
|
||||
$sFileName = pathinfo($sGeoFile, PATHINFO_FILENAME);
|
||||
$sGpxFileName = $sFileName.self::GPX_EXT;
|
||||
$sGeoJsonFileName = $sFileName.self::GEO_EXT;
|
||||
|
||||
@@ -70,7 +63,7 @@ class Gpx extends Geo {
|
||||
$asTrack['points'][] = array(
|
||||
'lon' => (float) $asPoint['lon'],
|
||||
'lat' => (float) $asPoint['lat'],
|
||||
//'ele' => (int) $asPoint->ele
|
||||
'ele' => (int) $asPoint->ele
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -96,7 +89,7 @@ class GeoJson extends Geo {
|
||||
}
|
||||
|
||||
private function getGeoJson() {
|
||||
$asTracks = array();
|
||||
$asTracks = array('features'=>array());
|
||||
foreach($this->asTracks as $asTrackProps) {
|
||||
|
||||
switch($asTrackProps['color']) {
|
||||
@@ -114,15 +107,15 @@ class GeoJson extends Geo {
|
||||
'description' => $asTrackProps['desc']
|
||||
),
|
||||
'geometry' => array(
|
||||
'type' => 'MultiLineString',
|
||||
'type' => 'LineString',
|
||||
'coordinates' => array()
|
||||
)
|
||||
);
|
||||
|
||||
foreach($asTrackProps['points'] as $asPoint) {
|
||||
$asTrack['geometry']['coordinates'][0][] = array_values($asPoint);
|
||||
$asTrack['geometry']['coordinates'][] = array_values($asPoint);
|
||||
}
|
||||
$asTracks[] = $asTrack;
|
||||
$asTracks['features'][] = $asTrack;
|
||||
}
|
||||
|
||||
return $asTracks;
|
||||
|
||||
@@ -100,7 +100,13 @@ class Project extends PhpObject {
|
||||
case 1: $asProject['mode'] = self::MODE_BLOG; break;
|
||||
case 2: $asProject['mode'] = self::MODE_HISTO; break;
|
||||
}
|
||||
$asProject['geofile'] = Spot::addTimestampToFilePath(self::GEO_FOLDER.$asProject['geofile']);
|
||||
|
||||
$sGeoFile = self::GEO_FOLDER.$asProject['geofile'];
|
||||
if(!file_exists($sGeoFile)) {
|
||||
(new Converter())->convertToGeoJson($asProject['geofile']);
|
||||
}
|
||||
|
||||
$asProject['geofile'] = Spot::addTimestampToFilePath($sGeoFile);
|
||||
$asProject['codename'] = $sCodeName;
|
||||
$asProject['timezone_desc'] = Spot::getTimeZoneDesc($asProject['timezone']);
|
||||
}
|
||||
|
||||
13
inc/spot.php
13
inc/spot.php
@@ -48,7 +48,8 @@ class Spot extends Main
|
||||
$asClasses = array(
|
||||
array('name'=>'project', 'project'=>true),
|
||||
array('name'=>'picture', 'project'=>true),
|
||||
array('name'=>'cacher', 'project'=>true)
|
||||
array('name'=>'cacher', 'project'=>true),
|
||||
array('name'=>'converter', 'project'=>true)
|
||||
);
|
||||
parent::__construct($oClassManagement, $sProcessPage, $asClasses);
|
||||
|
||||
@@ -140,6 +141,7 @@ class Spot extends Main
|
||||
'index',
|
||||
array(
|
||||
'filepath_css' => self::addTimestampToFilePath('style/spot.css'),
|
||||
'filepath_js_d3' => self::addTimestampToFilePath('script/d3.min.js'),
|
||||
'filepath_js_leaflet' => self::addTimestampToFilePath('script/leaflet.min.js'),
|
||||
'filepath_js_jquery' => self::addTimestampToFilePath('script/jquery.min.js'),
|
||||
'filepath_js_jquery_mods' => self::addTimestampToFilePath('script/jquery.mods.js'),
|
||||
@@ -436,6 +438,10 @@ class Spot extends Main
|
||||
$sToken = Settings::IGN_FR_KEY;
|
||||
$sReferer = 'https://www.visugpx.com/yfJDwfuTlf';
|
||||
break;
|
||||
case 'opentopomap':
|
||||
$sPattern = 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png';
|
||||
$asDomains = array('a', 'b', 'c');
|
||||
break;
|
||||
case 'static':
|
||||
$sPattern = 'https://api.mapbox.com/v4/mapbox.satellite/url-https%3A%2F%2Fspot.lutran.fr%2Fimages%2Ffootprint_mapbox.png({x},{y})/{x},{y},{z}/400x300.png?access_token={token}';
|
||||
$sToken = Settings::MAPBOX_KEY;
|
||||
@@ -455,9 +461,8 @@ class Spot extends Main
|
||||
}
|
||||
|
||||
public function convertGpxToGeoJson() {
|
||||
$this->oClassManagement->incClass('converter', true);
|
||||
$oConverter = new Converter($this->oProject);
|
||||
return $oConverter->convertToGeoJson();
|
||||
$oConverter = new Converter();
|
||||
return $oConverter->convertToGeoJson($this->oProject->getGeoFile());
|
||||
}
|
||||
|
||||
public static function DecToDMS($dValue, $sType='lat') {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<link type="image/x-icon" href="images/favicon.ico" rel="shortcut icon" />
|
||||
<link type="image/png" href="images/favicon.png" rel="icon" sizes="32x32" />
|
||||
<link type="text/css" href="[#]filepath_css[#]" rel="stylesheet" media="all" />
|
||||
<script type="text/javascript" src="[#]filepath_js_d3[#]"></script>
|
||||
<script type="text/javascript" src="[#]filepath_js_leaflet[#]"></script>
|
||||
<script type="text/javascript" src="[#]filepath_js_jquery[#]"></script>
|
||||
<script type="text/javascript" src="[#]filepath_js_jquery_mods[#]"></script>
|
||||
|
||||
@@ -137,8 +137,7 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
|
||||
//Tile layers
|
||||
var oMapBoxSat = L.tileLayer(self.tmp('tile_api'), {id: 'mapbox.satellite', minZoom: 0, maxZoom: 19}),
|
||||
oOpenTopoMap = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {id: 'OpenTopoMap', minZoom: 2, maxZoom: 19}),
|
||||
//oMapBoxStreet = L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token='+self.vars('mapbox_key'), {id: 'mapbox.streets'}),
|
||||
oOpenTopoMap = L.tileLayer(self.tmp('tile_api'), {id: 'opentopomap', minZoom: 2, maxZoom: 19}),
|
||||
oIgnSpain = L.tileLayer(self.tmp('tile_api'), {id: 'ign.es', minZoom: 1, maxZoom: 20}),
|
||||
oIgnFrance = L.tileLayer(self.tmp('tile_api'), {id: 'ign.fr', minZoom: 0, maxZoom: 18, tileSize: 256}),
|
||||
oLinz = L.tileLayer(self.tmp('tile_api'), {id: 'linz', maxZoom: 17, continuousWorld: true, attribution: 'Sourced from LINZ. CC BY 4.0'});
|
||||
@@ -151,12 +150,71 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
});
|
||||
self.tmp('map', oMap);
|
||||
|
||||
//Controls: Legend
|
||||
var oLegend = L.control({position: 'bottomleft'});
|
||||
oLegend.onAdd = function(oMap) {return $('#legend').clone()[0];};
|
||||
oLegend.addTo(oMap);
|
||||
|
||||
//Controls: Projects
|
||||
var oProjects = L.control({position: 'bottomleft'});
|
||||
oProjects.onAdd = function(oMap) {
|
||||
|
||||
var $Labels = $('<div>', {'class': 'leaflet-control-layers-base'});
|
||||
$.each(self.vars('projects'), function(sCodeName, asProject){
|
||||
var asRadioAttrs = {'type': 'radio', 'class': 'leaflet-control-layers-selector', 'name':'project', 'value': sCodeName};
|
||||
if(asProject.id == self.vars(['project', 'id'])) asRadioAttrs.checked = 'checked';
|
||||
var $Radio =$('<input>', asRadioAttrs).change(function(){
|
||||
self.setHash(self.vars('page'), [$(this).val()]);
|
||||
});
|
||||
|
||||
var $Label = $('<label>').append($('<div>')
|
||||
.append($Radio)
|
||||
.append($('<span>').text(' '+asProject.name))
|
||||
);
|
||||
$Labels.append($Label);
|
||||
});
|
||||
|
||||
return $('<div>', {'class':'leaflet-control-layers leaflet-control leaflet-control-layers-expanded'}).append($('<section>').append($Labels))[0];
|
||||
};
|
||||
oProjects.addTo(oMap);
|
||||
|
||||
//Controls: Scale
|
||||
oScale = L.control.scale({imperial: false, 'position':'bottomright'}).addTo(oMap);
|
||||
|
||||
//Controls: Elevation
|
||||
var oElev = L.control.elevation({
|
||||
collapsed: true,
|
||||
position: "bottomright",
|
||||
width: $('#messages').width() - $('#feed').outerWidth(true) - $('.leaflet-bottom.leaflet-left').outerWidth(true) + 4,
|
||||
height: 125,
|
||||
hoverNumber: {
|
||||
decimalsX: 0, //distance (km)
|
||||
decimalsY: 0 //elevation (m)
|
||||
},
|
||||
theme: 'spot-theme',
|
||||
onExpand: function(){$('.leaflet-control-scale').hide();},
|
||||
onCollapse: function(){$('.leaflet-control-scale').show();}
|
||||
}).addTo(oMap);
|
||||
|
||||
//Controls: Tiles
|
||||
L.control.layers(
|
||||
{
|
||||
'Satellite': oMapBoxSat,
|
||||
'Open Topo Map': oOpenTopoMap,
|
||||
'IGN (France)': oIgnFrance,
|
||||
'IGN (Espagne)': oIgnSpain,
|
||||
'LINZ (Nouvelle-Zélande)': oLinz
|
||||
},
|
||||
null,
|
||||
{position: 'topleft'}
|
||||
).addTo(oMap);
|
||||
|
||||
//Tracks, colors & popup
|
||||
var oTracks = L.geoJson(aoTracks, {
|
||||
style: function(oTrack) {
|
||||
return self.tmp(['track-type-styles', oTrack.properties.type]);
|
||||
},
|
||||
onEachFeature: function (feature, oLayer) {
|
||||
onEachFeature: function(feature, oLayer) {
|
||||
var asProperties = feature.properties;
|
||||
var $Tooltip = $('<div>', {'class':'track_tooltip'});
|
||||
$('<p>', {'class':'name'}).addIcon('fa-track-'+asProperties.type, true).append(asProperties.name).appendTo($Tooltip);
|
||||
@@ -171,6 +229,8 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
.on('mouseout', function(e) {
|
||||
e.target.closePopup();
|
||||
});
|
||||
|
||||
if(asProperties.type != 'hitchhiking') (oElev.addData.bind(oElev))(feature, oLayer);
|
||||
}
|
||||
}).addTo(oMap);
|
||||
|
||||
@@ -186,19 +246,6 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
}
|
||||
else oMap.fitBounds(oTracks.getBounds(), {paddingTopLeft: L.point(5, 42), paddingBottomRight: L.point(self.tmp('feed_width')+5, 5)});
|
||||
|
||||
//Controls
|
||||
L.control.layers(
|
||||
{
|
||||
'Satellite': oMapBoxSat,
|
||||
'Open Topo Map': oOpenTopoMap,
|
||||
'IGN (France)': oIgnFrance,
|
||||
'IGN (Espagne)': oIgnSpain,
|
||||
'LINZ (Nouvelle-Zélande)': oLinz
|
||||
},
|
||||
null,
|
||||
{position: 'topleft'}
|
||||
).addTo(oMap);
|
||||
|
||||
//Building messages
|
||||
$.each(aoMessages, function(iKey, oMsg){
|
||||
|
||||
@@ -213,19 +260,6 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
})
|
||||
}).addTo(oMap);
|
||||
|
||||
//Marker events
|
||||
/*oMarker.on({
|
||||
mouseover: function(){
|
||||
this.openPopup();
|
||||
},
|
||||
mouseout: function(){
|
||||
|
||||
},
|
||||
click: function(oPoint){
|
||||
self.tmp('map').setOffsetView(self.tmp('map_offset'), oPoint.latlng, 15);
|
||||
}
|
||||
});*/
|
||||
|
||||
//Tooltip
|
||||
$Tooltip = $('<div>', {'class':'info-window'})
|
||||
.append($('<h1>')
|
||||
@@ -258,37 +292,6 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
|
||||
oSpot.tmp(['markers', oMsg.id_message], oMarker);
|
||||
});
|
||||
|
||||
//Legend
|
||||
var oLegend = L.control({position: 'bottomleft'});
|
||||
oLegend.onAdd = function(oMap) {return $('#legend').clone()[0];};
|
||||
oLegend.addTo(oMap);
|
||||
|
||||
//Projects
|
||||
var oProjects = L.control({position: 'bottomleft'});
|
||||
oProjects.onAdd = function(oMap) {
|
||||
|
||||
var $Labels = $('<div>', {'class': 'leaflet-control-layers-base'});
|
||||
$.each(self.vars('projects'), function(sCodeName, asProject){
|
||||
var asRadioAttrs = {'type': 'radio', 'class': 'leaflet-control-layers-selector', 'name':'project', 'value': sCodeName};
|
||||
if(asProject.id == self.vars(['project', 'id'])) asRadioAttrs.checked = 'checked';
|
||||
var $Radio =$('<input>', asRadioAttrs).change(function(){
|
||||
self.setHash(self.vars('page'), [$(this).val()]);
|
||||
});
|
||||
|
||||
var $Label = $('<label>').append($('<div>')
|
||||
.append($Radio)
|
||||
.append($('<span>').text(' '+asProject.name))
|
||||
);
|
||||
$Labels.append($Label);
|
||||
});
|
||||
|
||||
return $('<div>', {'class':'leaflet-control-layers leaflet-control leaflet-control-layers-expanded'}).append($('<section>').append($Labels))[0];
|
||||
};
|
||||
oProjects.addTo(oMap);
|
||||
|
||||
//Scale
|
||||
L.control.scale({imperial: false, 'position':'bottomright'}).addTo(oMap);
|
||||
}
|
||||
|
||||
function getBoundsZoomLevel(bounds, mapDim) {
|
||||
|
||||
2
script/d3.min.js
vendored
Normal file
2
script/d3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
793
script/leaflet.min.js
vendored
793
script/leaflet.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -28,6 +28,19 @@
|
||||
@include animate(fadeIn 0.8s infinite alternate);
|
||||
}
|
||||
|
||||
@mixin rounded($radius) {
|
||||
-webkit-border-radius: $radius;
|
||||
-moz-border-radius: $radius;
|
||||
-ms-border-radius: $radius;
|
||||
-o-border-radius: $radius;
|
||||
border-radius: $radius;
|
||||
}
|
||||
|
||||
@mixin drop-shadow($opacity) {
|
||||
filter: drop-shadow( -1px 1px 1px rgba(0, 0, 0, $opacity));
|
||||
-webkit-filter: drop-shadow( -1px 1px 1px rgba(0, 0, 0, $opacity));
|
||||
}
|
||||
|
||||
/* Fonts */
|
||||
|
||||
@import url('https://fonts.googleapis.com/css?family=Ubuntu:400,700&subset=latin-ext');
|
||||
|
||||
@@ -20,6 +20,16 @@ $fa-css-prefix: fa;
|
||||
}
|
||||
}
|
||||
|
||||
.control-icon {
|
||||
font-size: 28px;
|
||||
text-align: center;
|
||||
line-height: 44px;
|
||||
text-decoration: none;
|
||||
color: #999;
|
||||
background: none;
|
||||
@extend .fa;
|
||||
}
|
||||
|
||||
.#{$fa-css-prefix}-post:before { content: fa-content($fa-var-comment); }
|
||||
.#{$fa-css-prefix}-poster:before { content: fa-content($fa-var-comment-edit); }
|
||||
.#{$fa-css-prefix}-message:before { content: fa-content($fa-var-compass); }
|
||||
@@ -33,3 +43,5 @@ $fa-css-prefix: fa;
|
||||
.#{$fa-css-prefix}-track-main:before { content: fa-content($fa-var-hiking); }
|
||||
.#{$fa-css-prefix}-track-hitchhiking:before { content: fa-content($fa-var-car-side); }
|
||||
.#{$fa-css-prefix}-layers:before { content: fa-content($fa-var-layer-group); }
|
||||
.#{$fa-css-prefix}-elevation:before { content: fa-content($fa-var-chart-area); }
|
||||
|
||||
|
||||
86
style/_leaflet_elevation.scss
Normal file
86
style/_leaflet_elevation.scss
Normal file
@@ -0,0 +1,86 @@
|
||||
$theme : "spot-theme";
|
||||
$base-color : #CCC;
|
||||
$highlight-color : #FFF;
|
||||
$background : rgba($base-color, 0.2);
|
||||
$drag-color : rgba($highlight-color, 0.2);
|
||||
$axis-color : darken($base-color,20%);
|
||||
$stroke-color : darken($base-color,40%);
|
||||
$stroke-width-mouse-focus : 1;
|
||||
$stroke-width-height-focus: 2;
|
||||
$stroke-width-axis : 2;
|
||||
|
||||
.#{$theme}.leaflet-control.elevation {
|
||||
|
||||
.background {
|
||||
//background-color: $background;
|
||||
//@include rounded(3px);
|
||||
margin: 6px 0 -12px;
|
||||
}
|
||||
|
||||
.axis path,
|
||||
.axis line {
|
||||
fill: none;
|
||||
stroke: $axis-color;
|
||||
stroke-width: $stroke-width-axis;
|
||||
}
|
||||
|
||||
//.mouse-focus-label-y,
|
||||
.mouse-focus-label-x {
|
||||
text-anchor: middle;
|
||||
}
|
||||
.mouse-drag{
|
||||
fill: $drag-color;
|
||||
}
|
||||
|
||||
.elevation-toggle {
|
||||
cursor: pointer;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
color: #CCC;
|
||||
text-shadow: 0px 1px 1px rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
.area {
|
||||
fill: $base-color;
|
||||
@include drop-shadow(0.6);
|
||||
}
|
||||
|
||||
.mouse-focus-line {
|
||||
pointer-events: none;
|
||||
stroke-width: $stroke-width-mouse-focus;
|
||||
stroke: $stroke-color;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$theme}.leaflet-control.elevation-collapsed {
|
||||
.background {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.elevation-toggle {
|
||||
@extend .control-icon;
|
||||
@extend .fa-elevation;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$theme}.height-focus{
|
||||
stroke: $base-color;
|
||||
fill: $base-color;
|
||||
@include drop-shadow(0.6);
|
||||
}
|
||||
|
||||
.#{$theme}.height-focus.line{
|
||||
pointer-events: none;
|
||||
stroke-width: $stroke-width-height-focus;
|
||||
@include drop-shadow(0.6);
|
||||
}
|
||||
|
||||
.#{$theme}.height-focus-label{
|
||||
text-anchor: middle;
|
||||
fill: $base-color;
|
||||
@include drop-shadow(0.6);
|
||||
}
|
||||
|
||||
.#{$theme}.height-focus.circle-lower {
|
||||
|
||||
}
|
||||
@@ -68,15 +68,9 @@
|
||||
|
||||
/* Replace Layers image with font awesome icon */
|
||||
.leaflet-control-layers-toggle {
|
||||
font-size: 28px;
|
||||
text-align: center;
|
||||
line-height: 44px;
|
||||
text-decoration: none;
|
||||
color: #999;
|
||||
text-shadow: 0px 1px 1px rgba(0,0,0,0.8);
|
||||
background: none;
|
||||
@extend .fa;
|
||||
@extend .control-icon;
|
||||
@extend .fa-layers;
|
||||
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -6,6 +6,7 @@
|
||||
|
||||
/* Site Global CSS */
|
||||
@import 'common';
|
||||
@import 'leaflet_elevation';
|
||||
|
||||
/* Pages Specific CSS (masks) */
|
||||
@import 'mask_project';
|
||||
|
||||
Reference in New Issue
Block a user