Files
spot/masks/messages.html
2018-10-08 22:12:57 +02:00

392 lines
12 KiB
HTML
Executable File

<div id="messages">
<div id="map">
<div class="loader fa fa-map"></div>
</div>
<div id="legend">
<div class="line te_araroa">Te Araroa</div>
<div class="line routeburn">Routeburn Track</div>
<div class="line hitchhiking">Hors rando</div>
</div>
<div id="feed">
<div id="posts">
<div id="poster"></div>
<div id="posts_list"></div>
<div id="loading"></div>
</div>
</div>
</div>
<script type="text/javascript" src="script/lightbox.min.js"></script>
<script type="text/javascript">
oSpot.pageInit = function(asHash)
{
/* TODO
- keep tooltip open so pictures can be clicked on (use popup?)
- apply 30 % offset to all re-centering
- Track Names
*/
self.tmp('$Map', $('#map'));
//Add Loading
var asLoading = {
type: 'loading',
formatted_time: '',
relative_time: '',
displayed_id: 'Chargement...'
};
getPost(asLoading).appendTo($('#loading'));
self.get('messages', function(oMessages){
//Build Feed
self.tmp('updatable', true);
self.tmp('out-of-data', 'boolean');
updateFeed(true);
self.tmp('simple-bar', new SimpleBar($('#posts')[0]));
self.tmp('simple-bar').getScrollElement().addEventListener('scroll', onFeedScroll);
self.tmp('infowindow', 'boolean');
//Centering map
var agCenter = {lat:0, lng:0};
var iZoom = 0;
if(self.vars('mode')=='blog')
{
//on last message
var oLastMsg = oMessages[oMessages.length-1];
agCenter.lat = oLastMsg.latitude;
agCenter.lng = oLastMsg.longitude;
iZoom = 12;
}
else
{
var iMapRatio = 0.7;
var iConfidenceInterval = 0.05;
var iMinLat, iMaxLat, iMinLng, iMaxLng;
iMinLat = iMinLng = 180;
iMaxLat = iMaxLng = -180;
$.each(oMessages, function(iKey, oMsg){
iMinLat = Math.min(iMinLat, oMsg.latitude);
iMaxLat = Math.max(iMaxLat, oMsg.latitude);
iMinLng = Math.min(iMinLng, oMsg.longitude);
iMaxLng = Math.max(iMaxLng, oMsg.longitude);
});
//Get Marker bounds
var oSouthWest = L.latLng(iMinLat, iMinLng);
var oNorthEast = L.latLng(iMaxLat, iMaxLng);
oMarkerBounds = new L.LatLngBounds(oSouthWest, oNorthEast);
agCenter = oMarkerBounds.getCenter();
//Calculate adequate zoom (map.fitBounds is dezooming too much)
var oMapDim = {
height: self.tmp('$Map').height()*(1 - iConfidenceInterval),
width: self.tmp('$Map').width()*(iMapRatio - iConfidenceInterval)
};
iZoom = getBoundsZoomLevel(oMarkerBounds, oMapDim);
}
//Tile layers
var oMapBoxSat = L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}@2x.png?access_token='+self.vars('mapbox_key'), {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'}),
oLinz = L.tileLayer('http://tiles-{s}.data-cdn.linz.govt.nz/services;key=92193c0af382409a98694d3e4aa8bd46/tiles/v4/layer=50767/EPSG:3857/{z}/{x}/{y}.png', {id: 'Linz', maxZoom: 17, continuousWorld: true, attribution: 'Sourced from LINZ. CC BY 4.0', subdomains:'abcd'});
//oGoogleSatellite = L.tileLayer('https://mt.google.com/vt/lyrs=y&x={x}&y={y}&z={z}', {id: 'GoogleSatellite', minZoom: 1, maxZoom: 22});
//Map
var oMap = L.map(self.tmp('$Map')[0], {
center: agCenter,
zoom: iZoom,
layers: [oMapBoxSat],
attributionControl: false,
zoomControl: false
/*mapTypeId: google.maps.MapTypeId.SATELLITE,
scaleControl: true,
scaleControlOptions: {
position: google.maps.ControlPosition.TOP_LEFT
},
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
position: google.maps.ControlPosition.TOP_LEFT
},
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_TOP
},
fullscreenControl: true,
fullscreenControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM
},
streetViewControl: false*/
});
//Swap tile layers on zoom level
oMap.on('zoomend', function(o) {
//if(self.tmp('map').getZoom()) self.tmp('map')
});
//Controls
L.control.layers({'Satellite': oMapBoxSat, 'LINZ': oLinz}, null, {position: 'topleft'}).addTo(oMap);
//Te Araroa track
$.ajax({
dataType: 'json',
url: 'kml/TeAraroaTrail_simplified.geojson',
mimeType: 'application/json',
success: function(aoTracks) {
//Get track colors
var asColors = {};
$('#legend').find('.line').each(function(iKey, oLegend){
var $Legend = $(oLegend);
asColors[$Legend.attr('class').replace('line', '').trim()] = $Legend.css('border-top-color');
});
//Assign track color
L.geoJson(aoTracks, {
style: function(oTrack) {return {color: asColors[oTrack.properties.type]};}
}).addTo(oMap);
}
});
//Building messages
$.each(oMessages, function(iKey, oMsg){
//Marker
var oMarker = L.marker(L.latLng(oMsg.latitude, oMsg.longitude), {
id: oMsg.id_message,
riseOnHover: true,
icon: L.icon({
iconUrl: (iKey%2==0)?'images/footprint_alt.png':'images/footprint.png',
iconSize: [32, 37],
iconAnchor: [16, 37]
})
}).addTo(oMap);
//Marker events
oMarker.on({
/*mouseover: function(){
},
mouseout: function(){
},*/
click: function(oPoint){
self.tmp('map').setView(oPoint.latlng, 15);
}
});
//Tooltip
$Tooltip = $('<div>', {'class':'info-window'})
.append($('<h1>').append('Message '+oMsg.type+' #'+oMsg.id_message))
.append($('<p>', {'class':'time'}).addIcon('fa-clock-o').append(oMsg.formatted_time+' ('+oMsg.relative_time+')'))
.append($('<p>', {'class':'coordinates'}).addIcon('fa-compass').append('Lat : '+oMsg.latitude+', Lng : '+oMsg.longitude));
//Tooltip pictures
if(oMsg.pics) {
var $Pics = $('<div>', {'class':'pics'});
$.each(oMsg.pics, function(iKey, asPic){
$Pics.append($('<a>', {href: asPic.path, 'data-lightbox': self.consts.title, 'data-title': asPic.formatted_time})
.append($('<img>', {'src': asPic.thumb_path})));
});
$Tooltip
.append($('<p>').addIcon('fa-image').append('Photos'))
.append($Pics);
}
oMarker.bindTooltip($Tooltip[0], {
offset: [-16, -18],
direction: 'left'
});
});
//Recenter map once loaded to be at the center of 70% (iMapRatio) of the page
if(self.vars('mode')!='blog') oMap.panTo(getOffsetCenter(oMap, iMapRatio));
//Legend
var oLegend = L.control({position: 'bottomleft'});
oLegend.onAdd = function() {return L.DomUtil.get('legend');};
oLegend.addTo(oMap);
self.tmp('map', oMap);
});
//Post
if(self.vars('mode')=='histo') $('#poster').hide();
else {
var asPoster = {
type: 'poster',
formatted_time: '',
relative_time: 'Nouveau message'
};
getPost(asPoster).appendTo($('#poster'));
$('#name').defaultVal('Nom...');
$('#post').defaultVal('Ton message...');
$('#submit').click(function(){
if($('#poster').checkForm())
{
self.get(
'add_post',
function()
{
$('#name').val('');
$('#post').val('');
updateFeed(true);
},
{name:$('#name').val(), content:$('#post').val()}
);
}
});
}
};
function getBoundsZoomLevel(bounds, mapDim) {
var WORLD_DIM = { height: 256, width: 256 };
var ZOOM_MAX = 21;
function latRad(lat) {
var sin = Math.sin(lat * Math.PI / 180);
var radX2 = Math.log((1 + sin) / (1 - sin)) / 2;
return Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2;
}
function zoom(mapPx, worldPx, fraction) {
return Math.floor(Math.log(mapPx / worldPx / fraction) / Math.LN2);
}
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
var latFraction = (latRad(ne.lat) - latRad(sw.lat)) / Math.PI;
var lngDiff = ne.lng - sw.lng;
var lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;
var latZoom = zoom(mapDim.height, WORLD_DIM.height, latFraction);
var lngZoom = zoom(mapDim.width, WORLD_DIM.width, lngFraction);
return Math.min(latZoom, lngZoom, ZOOM_MAX);
}
function getOffsetCenter(oMap, iMapRatio) {
var oBounds = oMap.getBounds();
var oCenter = oMap.getCenter();
var iOffsetX = (oBounds.getEast() - oBounds.getWest())*(iMapRatio - 1)/2;
oCenter.lng = oCenter.lng - iOffsetX;
return oCenter;
}
function onFeedScroll(){
var $Box = $(this);
var $BoxContent = $Box.find('.simplebar-content');
if(($Box.scrollTop() + $(window).height()) / $BoxContent.height() >= 0.8) updateFeed();
}
function updateFeed(bFirstChunk)
{
bFirstChunk = bFirstChunk || false;
if(self.tmp('updatable')) {
if(!self.tmp('out-of-data') || bFirstChunk) {
var $Posts = $('#posts_list');
if(bFirstChunk===true) {
$Posts.empty();
self.tmp('news_chunk', 0);
}
self.tmp('updatable', false);
$('#loading').fadeIn('fast');
self.get('feed', function(asData) {
$.each(asData, function(iKey, asPost){
getPost(asPost).appendTo($Posts);
});
//oSimpleBar.recalculate();
self.tmp('news_chunk', self.tmp('news_chunk') + 1);
self.tmp('out-of-data', Object.keys(asData).length != self.vars('chunk_size'));
self.tmp('updatable', true);
$('#loading').fadeOut('fast');
}, {
'chunk': self.tmp('news_chunk')
});
}
}
else if(bFirstChunk) { //Delaying important data load
if(typeof oUpdateTimer != 'undefined') clearTimeout(oUpdateTimer);
oUpdateTimer = setTimeout(function(){updateFeed(true);}, 200);
}
}
function getPost(asPost) {
var $Post = $('<div>', {'class':'post '+asPost.type});
var sRelTime = (self.vars('mode')=='histo')?asPost.formatted_time.substr(0, 10):asPost.relative_time;
var sAbsTime = asPost.formatted_time;
var $Body = {};
switch(asPost.type)
{
case 'message':
$Body = $('<div>')
.append($('<p>').addIcon('fa-compass', true).append('Latitude '+asPost.latitude+', Longitude '+asPost.longitude))
.append($('<p>').addIcon('fa-clock-o', true).append(sAbsTime))
.append(
$('<img>', {'class':'staticmap', title: 'Click pour zoomer', src: getStaticMapUrl(asPost.latitude, asPost.longitude)})
.data('lat', asPost.latitude)
.data('lng', asPost.longitude)
.click(function(){
var $This = $(this);
self.tmp('map').setView(L.latLng(parseFloat($This.data('lat')), parseFloat($This.data('lng'))), 13);
})
);
sClass = 'compass';
break;
case 'picture':
var $Image = $('<img>', {'src': asPost.thumb_path/*, 'style':'transform:rotate('+asPost.rotate+'deg);'*/});
$Body = $('<a>', {href: asPost.path, 'data-lightbox': self.consts.title, 'data-title': sAbsTime}).append($Image);
sClass = 'image';
break;
case 'post':
$Body = $('<div>')
.append($('<p>', {'class':'message'}).text(asPost.content))
.append($('<p>', {'class':'signature'}).text('-- '+asPost.formatted_name));
sClass = 'comment';
break;
case 'poster':
$Body = $('<p>', {'class':'message'})
.append($('<input>', {type:'text', id:'post', name:'post'}))
.append($('<input>', {type:'text', id:'name', name:'name'}))
.append($('<button>', {type:'button', id:'submit', name:'submit'}).addIcon('fa-send'));
sClass = 'comment';
break;
case 'loading':
$Body = $('<p>', {'class':'spinner'}).addIcon('fa-spin fa-spinner');
sClass = 'tasks';
break;
}
$Post
.append($('<div>', {'class':'header'})
.append($('<span>', {'class':'index'}).addIcon('fa-'+sClass))
.append($('<span>', {'class':'time', 'title':sAbsTime}).text(sRelTime)))
.append($('<div>', {'class':'body'}).append($Body));
if(asPost.displayed_id) $Post.find('.index').append(' '+asPost.displayed_id);
//if(asPost.type=='picture' && asPost.rotate!='0') $Body.height($Image.height());
return $Post;
}
function getStaticMapUrl(oCenterLat, oCenterLng){
var asParams = [
'https://api.mapbox.com/v4/mapbox.satellite', //Domain
'url-http%3A%2F%2Fspot.lutran.fr%2Fimages%2Ffootprint.png('+oCenterLng+','+oCenterLat+')', //Marker
oCenterLng+','+oCenterLat+',13', //Center + zoom
'400x300.png?access_token='+self.vars('mapbox_key') //Image size + access token
];
return asParams.join('/');
}
</script>