OpenLayers API

This commit is contained in:
bfabiszewski 2013-06-21 11:15:09 +02:00
parent 160773929a
commit 8c9a527fdf
8 changed files with 463 additions and 191 deletions

13
README
View File

@ -1,15 +1,15 @@
This is a simple web viewer for GPS tracks uploaded with mobile client.
It is designed to work with Android version of great app TrackMe (http://www.luisespinosa.com/trackme_eng.html),
but it should be easy to adjust it for other clients.
but it should be easy to adjust it for other clients (other database tables).
Interface "look and feel" is based on TrackMe Display (http://forum.xda-developers.com/showthread.php?t=477394).
It currently uses Google Maps API, but work on OpenStreetMap is in progress.
It is possible to switch between Google Maps API and OpenLayers API with OpenStreetMap (any other base layer should be easy to add).
Live demo:
- http://flaa.fabiszewski.net/phptrackme/
Requirements:
- php 5
- mysql
- PHP 5.1.2
- MYSQL 4.1
- browser with javascript enabled, cookies for authentication
Features:
@ -20,12 +20,13 @@ Features:
- multiple users
- user authentication
- Google Maps API v3
- OpenLayers 2.13
- ajax
- server based configuration
Todo
- OpenStreetMap API
- client based configuration
- install script
- user level customization, storing settings in cookies?
- write opensource client?
License

173
api_gmaps.js Executable file
View File

@ -0,0 +1,173 @@
/* phpTrackme
*
* Copyright(C) 2013 Bartek Fabiszewski (www.fabiszewski.net)
*
* This is free software; you can redistribute it and/or modify it under
* the terms of the GNU Library General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// google maps
var map;
var polies = new Array();
var markers = new Array();
var popups = new Array();
var polyOptions;
var mapOptions;
var loadedAPI = 'gmaps';
function init() {
google.maps.visualRefresh = true;
polyOptions = {
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
}
mapOptions = {
center: new google.maps.LatLng(52.23, 21.01),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scaleControl: true
};
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
function displayTrack(xml,update) {
altitudes.length = 0;
var totalMeters = 0;
var totalSeconds = 0;
// init polyline
var poly = new google.maps.Polyline(polyOptions);
poly.setMap(map);
var path = poly.getPath();
var latlngbounds = new google.maps.LatLngBounds( );
var positions = xml.getElementsByTagName('position');
var posLen = positions.length;
for (var i=0; i<posLen; i++) {
var p = parsePosition(positions[i]);
totalMeters += p.distance;
totalSeconds += p.seconds;
p['totalMeters'] = totalMeters;
p['totalSeconds'] = totalSeconds;
p['coordinates'] = new google.maps.LatLng(p.latitude,p.longitude);
// set marker
setMarker(p,i,posLen);
// update polyline
path.push(p.coordinates);
latlngbounds.extend(p.coordinates);
// save altitudes for chart
altitudes[i] = p.altitude;
}
if (update) {
map.fitBounds(latlngbounds);
if (i==1) {
// only one point, zoom out
zListener =
google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
if (this.getZoom()){
this.setZoom(15);
}
});
setTimeout(function(){google.maps.event.removeListener(zListener)}, 2000);
}
}
latestTime = p.dateoccured;
polies.push(poly);
updateSummary(p.dateoccured,totalMeters,totalSeconds);
if (p.tid!=trackid) {
trackid=p.tid;
setTrack(trackid);
}
if (document.getElementById('bottom').style.display=='block') {
// update altitudes chart
chart.clearChart();
displayChart();
}
}
function clearMap(){
if (polies){
for (var i=0; i<polies.length; i++){
polies[i].setMap(null);
}
}
if (markers){
for (var i=0; i<markers.length; i++){
google.maps.event.removeListener(popups[i].listener);
popups[i].setMap(null);
markers[i].setMap(null);
}
}
markers.length = 0;
polies.length = 0;
popups.lentgth = 0;
}
var popup;
function setMarker(p,i,posLen) {
// marker
var marker = new google.maps.Marker( {
map: map,
position: p.coordinates,
title: p.dateoccured
});
if (latest==1) { marker.setIcon('http://maps.google.com/mapfiles/dd-end.png') }
else if (i==0) { marker.setIcon('http://maps.google.com/mapfiles/marker_greenA.png') }
else if (i==posLen-1) { marker.setIcon('http://maps.google.com/mapfiles/markerB.png') }
else { marker.setIcon('http://labs.google.com/ridefinder/images/mm_20_gray.png') }
// popup
var content = '<div id="popup">'+
'<div id="pheader">'+lang_user+': '+p.username.toUpperCase()+'<br />'+lang_track+': '+p.trackname.toUpperCase()+
'</div>'+
'<div id="pbody">'+
'<div id="pleft"><b>'+lang_time+':</b> '+p.dateoccured+'<br />'+
((p.speed != null)?'<b>'+lang_speed+':</b> '+(p.speed.toKmH()*factor_kmh)+' '+unit_kmh+'<br />':'')+
((p.altitude != null)?'<b>'+lang_altitude+':</b> '+(p.altitude*factor_m).toFixed()+' '+unit_m+'<br />':'')+'</div>'+
((latest==0)?
('<div id="pright"><b>'+lang_ttime+':</b> '+p.totalSeconds.toHMS()+'<br />'+
'<b>'+lang_aspeed+':</b> '+((p.totalSeconds>0)?((p.totalMeters/p.totalSeconds).toKmH()*factor_kmh).toFixed():0)+' '+unit_kmh+'<br />'+
'<b>'+lang_tdistance+':</b> '+(p.totalMeters.toKm()*factor_km).toFixed(2)+' '+unit_km+'<br />'+'</div>'):'')+
'<div id="pfooter">'+lang_point+' '+(i+1)+' '+lang_of+' '+(posLen)+'</div>'+
'</div></div>';
popup = new google.maps.InfoWindow();
popup.listener = google.maps.event.addListener(marker, 'click', (function(marker,content) {
return function() {
popup.setContent(content);
popup.open(map, marker);
if (document.getElementById('bottom').style.display=='block') {
chart.setSelection([{row:i,column:null}]);
}
}
})(marker,content));
markers.push(marker);
popups.push(popup);
}
function addChartEvent(chart) {
google.visualization.events.addListener(chart, 'select', function() {
if (popup) {popup.close(); clearTimeout(altTimeout);}
var selection = chart.getSelection()[0];
if (selection) {
var id = selection.row;
var icon = markers[id].getIcon();
markers[id].setIcon('http://maps.google.com/mapfiles/marker_orange.png');
//var contentString = '<div style="width:40px; height:20px;padding:10px">'+Math.round(altitudes[id]*factor_m)+' '+unit_m+'</div>';
//popup = new google.maps.InfoWindow({
// content: contentString
//});
//popup.open(map,markers[id]);
//altTimeout = setTimeout(function() { if (popup) {popup.close();} },2000);
altTimeout = setTimeout(function() { markers[id].setIcon(icon); },2000);
}
});
}

169
api_openlayers.js Executable file
View File

@ -0,0 +1,169 @@
/* phpTrackme
*
* Copyright(C) 2013 Bartek Fabiszewski (www.fabiszewski.net)
*
* This is free software; you can redistribute it and/or modify it under
* the terms of the GNU Library General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// openlayers
var map;
var layerTrack;
var layerMarkers;
var lineStyle = {strokeColor: '#FF0000', strokeOpacity: 1, strokeWidth: 2};
var wgs84;
var mercator;
var loadedAPI = 'openlayers';
function init() {
wgs84 = new OpenLayers.Projection('EPSG:4326'); // from WGS 1984
mercator = new OpenLayers.Projection('EPSG:900913'); // to Mercator
var options = { controls: [
new OpenLayers.Control.ArgParser(), // default
new OpenLayers.Control.Attribution(), // default
new OpenLayers.Control.LayerSwitcher({'ascending':false}),
new OpenLayers.Control.Navigation(), // default
new OpenLayers.Control.PanZoomBar(),// do we need it?
new OpenLayers.Control.ScaleLine()
]
};
map = new OpenLayers.Map('map-canvas', options);
map.addLayer(new OpenLayers.Layer.OSM());
var position = new OpenLayers.LonLat(21.01,52.23).transform(wgs84, mercator);
var zoom = 8;
map.setCenter(position, zoom);
}
function displayTrack(xml,update) {
altitudes.length = 0;
var totalMeters = 0;
var totalSeconds = 0;
// init layer
layerTrack = new OpenLayers.Layer.Vector( 'Track' );
layerMarkers = new OpenLayers.Layer.Markers( 'Markers' );
var points = new Array();
var latlngbounds = new OpenLayers.Bounds();
var positions = xml.getElementsByTagName('position');
var posLen = positions.length;
for (var i=0; i<posLen; i++) {
var p = parsePosition(positions[i]);
totalMeters += p.distance;
totalSeconds += p.seconds;
p['totalMeters'] = totalMeters;
p['totalSeconds'] = totalSeconds;
// set marker
setMarker(p,i,posLen);
// update polyline
var point = new OpenLayers.Geometry.Point(p.longitude, p.latitude).transform(wgs84,mercator);
latlngbounds.extend(point);
points.push(point);
// save altitudes for chart
altitudes[i] = p.altitude;
}
var lineString = new OpenLayers.Geometry.LineString(points);
var lineFeature = new OpenLayers.Feature.Vector(lineString, null, lineStyle);
layerTrack.addFeatures([lineFeature]);
map.addLayer(layerTrack);
map.addLayer(layerMarkers);
if (update) {
map.zoomToExtent(latlngbounds);
if (i==1) {
// only one point, zoom out
map.zoomOut();
}
}
latestTime = p.dateoccured;
//polies.push(poly);
updateSummary(p.dateoccured,totalMeters,totalSeconds);
if (p.tid!=trackid) {
trackid=p.tid;
setTrack(trackid);
}
if (document.getElementById('bottom').style.display=='block') {
// update altitudes chart
chart.clearChart();
displayChart();
}
}
function clearMap(){
if (layerTrack){
layerTrack.removeAllFeatures();
}
if (layerMarkers){
layerMarkers.clearMarkers();
}
}
function setMarker(p,i,posLen) {
// marker
var lonLat = new OpenLayers.LonLat(p.longitude,p.latitude).transform(wgs84,mercator);
var size = new OpenLayers.Size(21, 25);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
if (latest==1) { var icon = new OpenLayers.Icon('http://www.openstreetmap.org/openlayers/img/marker.png',size,offset); }
else if (i==0) { var icon = new OpenLayers.Icon('http://www.openstreetmap.org/openlayers/img/marker-green.png',size,offset); }
else if (i==posLen-1) { var icon = new OpenLayers.Icon('http://www.openstreetmap.org/openlayers/img/marker.png',size,offset); }
else {
size = new OpenLayers.Size(12, 20);
offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var icon = new OpenLayers.Icon('http://labs.google.com/ridefinder/images/mm_20_gray.png',size,offset);
}
var marker = new OpenLayers.Marker(lonLat,icon);
layerMarkers.addMarker(marker);
// popup
var content = '<div id="popup">'+
'<div id="pheader">'+lang_user+': '+p.username.toUpperCase()+'<br />'+lang_track+': '+p.trackname.toUpperCase()+
'</div>'+
'<div id="pbody">'+
'<div id="pleft"><b>'+lang_time+':</b> '+p.dateoccured+'<br />'+
((p.speed != null)?'<b>'+lang_speed+':</b> '+(p.speed.toKmH()*factor_kmh)+' '+unit_kmh+'<br />':'')+
((p.altitude != null)?'<b>'+lang_altitude+':</b> '+(p.altitude*factor_m).toFixed()+' '+unit_m+'<br />':'')+'</div>'+
((latest==0)?
('<div id="pright"><b>'+lang_ttime+':</b> '+p.totalSeconds.toHMS()+'<br />'+
'<b>'+lang_aspeed+':</b> '+((p.totalSeconds>0)?((p.totalMeters/p.totalSeconds).toKmH()*factor_kmh).toFixed():0)+' '+unit_kmh+'<br />'+
'<b>'+lang_tdistance+':</b> '+(p.totalMeters.toKm()*factor_km).toFixed(2)+' '+unit_km+'<br />'+'</div>'):'')+
'<div id="pfooter">'+lang_point+' '+(i+1)+' '+lang_of+' '+(posLen)+'</div>'+
'</div></div>';
marker.events.register("mousedown", marker, (function() {
return function() {
// remove popups
if (map.popups.length>0) {
for (var i = map.popups.length-1; i>=0; i-- ) {
map.removePopup(map.popups[i])
};
}
// show popup
var popup = new OpenLayers.Popup.FramedCloud("id "+(i+1),lonLat,null,content,icon,true);
map.addPopup(popup);
if (document.getElementById('bottom').style.display=='block') {
chart.setSelection([{row:i,column:null}]);
}
}
})());
}
function addChartEvent(chart) {
google.visualization.events.addListener(chart, 'select', function() {
var selection = chart.getSelection()[0];
if (selection) {
var id = selection.row;
var marker = layerMarkers.markers[id];
var url = marker.icon.url;
marker.setUrl('http://www.openstreetmap.org/openlayers/img/marker-gold.png');
altTimeout = setTimeout(function() { marker.setUrl(url); },2000);
}
});
}

View File

@ -17,15 +17,18 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
$version = "1.0";
$version = "2.0";
// map drawing framework
// (gmaps = google maps, osm = openstreetmap (not supported yet))
// (gmaps = google maps, openlayers = openlayers/osm)
$mapapi = "gmaps";
//$mapapi = "openlayers";
// you may add your google maps api key
// this is not obligatory by now
//$gkey =
// db
// MySQL config
$dbhost = ""; // mysql host, eg. localhost
$dbuser = ""; // database user
$dbpass = ""; // database pass
@ -35,17 +38,23 @@ $salt = ""; // fill in random string here, it will increase security of password
// other
// require login/password authentication
// (0 = no, 1 = yes)
$require_authentication = 0;
$require_authentication = 1;
// allow automatic registration of new users
// (0 = no, 1 = yes)
$allow_registration = 0;
// Default interval in seconds for live auto reload
$interval = 10;
// Default language
// (en, pl)
$lang = "en";
//$lang = "pl";
// units
// (metric, imperial)
$units = "metric";
//$units = "imperial";
?>

View File

@ -67,6 +67,17 @@ $track_form .= '
</form>
';
// map api select form
$api_form = '
<u>'.$lang_api.'</u><br />
<form>
<select name="track" onchange="loadMapAPI(this.options[this.selectedIndex].value);">
<option value="gmaps"'.(($mapapi=="gmaps")?' selected':'').'>Google Maps</option>
<option value="openlayers"'.(($mapapi=="openlayers")?' selected':'').'>OpenLayers</option>
</select>
</form>
';
print
'<!DOCTYPE html>
<html>
@ -74,7 +85,7 @@ print
<title>'.$lang_title.'</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<link rel="stylesheet" type="text/css" href="main.css">
<link rel="stylesheet" type="text/css" href="main.css" />
<script>
var interval = '.$interval.';
var userid = '.(($auth)?$auth:-1).';
@ -93,54 +104,20 @@ print
var lang_track = "'.$lang_track.'";
var lang_newinterval = "'.$lang_newinterval.'";
var units = "'.$units.'";
var mapapi = "'.$mapapi.'";
</script>
<script type="text/javascript" src="main.js">
</script>
<script type="text/javascript" src="main.js"></script>
';
if ($mapapi == "gmaps") {
print
' <script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?'.(isset($gkey)?'key='.$gkey.'&':'').'sensor=false">
</script>
<script type="text/javascript">
var map;
var polies = new Array();
var markers = new Array();
var popups = new Array();
google.maps.visualRefresh = true;
var polyOptions = {
strokeColor: \'#FF0000\',
strokeOpacity: 1.0,
strokeWeight: 2
}
var mapOptions = {
center: new google.maps.LatLng(52.23, 21.01),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scaleControl: true
};
function init() {
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
</script>
' <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?'.(isset($gkey)?'key='.$gkey.'&':'').'sensor=false"></script>
<script type="text/javascript" src="api_gmaps.js"></script>
';
}
else {
print
' <script type="text/javascript"
src="http://openlayers.org/api/OpenLayers.js">
</script>
<script>
function init() {
map = new OpenLayers.Map("map-canvas");
map.addLayer(new OpenLayers.Layer.OSM());
var fromProjection = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984
var toProjection = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
var position = new OpenLayers.LonLat(21.01,52.23).transform(fromProjection, toProjection);
var zoom = 8;
map.setCenter(position, zoom);
}
</script>
' <script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript" src="api_openlayers.js"></script>
';
}
print '
@ -163,7 +140,10 @@ print '
</div>
<div id="summary"></div>
<div id="other">
<a href="javascript:void(0);" onclick="toggleChart();">'.$lang_chart.'</a><br />
<a href="javascript:void(0);" onclick="toggleChart();">'.$lang_chart.'</a>
</div>
<div id="api">
'.$api_form.'
</div>
<div id="export">
<u>'.$lang_download.'</u><br />

View File

@ -47,6 +47,7 @@ switch($lang) {
$lang_password = "Password";
$lang_language = "Language";
$lang_newinterval = "Enter new interval value (seconds)";
$lang_api = "Map API";
break;
case "pl":
@ -77,6 +78,7 @@ switch($lang) {
$lang_password = "Hasło";
$lang_language = "Język";
$lang_newinterval = "Podaj częstotliwość odświeżania (w sekundach)";
$lang_api = "Map API";
break;
}
?>

View File

@ -78,7 +78,7 @@ input[type = "checkbox"] {
background-color: #666;
color: lightgray;
}
#user, #trip, #summary, #export, #other {
#user, #trip, #summary, #export, #other, #api {
padding-bottom: 10px;
}
#login {
@ -107,8 +107,12 @@ input[type = "checkbox"] {
color: yellow;
}
#popup {
width:350px;
height:150px;
width:370px;
height:130px;
}
#popup * {
font-family: Roboto, Verdana, sans-serif;
font-size: 12px;
}
#pheader {
font-weight: bolder;
@ -129,6 +133,8 @@ input[type = "checkbox"] {
}
#bottom {
display: none;
position: absolute;
z-index: 10000;
}
#chart {
position: fixed;
@ -139,10 +145,10 @@ input[type = "checkbox"] {
opacity: 0.8;
}
#close {
position: absolute;
position: fixed;
bottom: 175px;
right: 175px;
z-index: 100;
z-index: 10001;
font-family: Verdana, sans-serif;
font-size: 0.8em;
}

200
main.js
View File

@ -16,126 +16,8 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// google maps
function displayTrack(xml,update) {
altitudes.length = 0;
var totalMeters = 0;
var totalSeconds = 0;
// init polyline
var poly = new google.maps.Polyline(polyOptions);
poly.setMap(map);
var path = poly.getPath();
var latlngbounds = new google.maps.LatLngBounds( );
var positions = xml.getElementsByTagName('position');
var posLen = positions.length;
for (var i=0; i<posLen; i++) {
var p = parsePosition(positions[i]);
totalMeters += p.distance;
totalSeconds += p.seconds;
p['totalMeters'] = totalMeters;
p['totalSeconds'] = totalSeconds;
p['coordinates'] = new google.maps.LatLng(p.latitude,p.longitude);
// set marker
setMarker(p,i,posLen);
// update polyline
path.push(p.coordinates);
latlngbounds.extend(p.coordinates);
// save altitudes for chart
altitudes[i] = p.altitude;
}
if (update) {
map.fitBounds(latlngbounds);
if (i==1) {
// only one point, zoom out
zListener =
google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
if (this.getZoom()){
this.setZoom(15);
}
});
setTimeout(function(){google.maps.event.removeListener(zListener)}, 2000);
}
}
latestTime = p.dateoccured;
polies.push(poly);
updateSummary(p.dateoccured,totalMeters,totalSeconds);
if (p.tid!=trackid) {
trackid=p.tid;
setTrack(trackid);
}
if (document.getElementById('bottom').style.display=='block') {
// update altitudes chart
chart.clearChart();
displayChart();
}
}
function clearMap(){
if (polies){
for (var i=0; i<polies.length; i++){
polies[i].setMap(null);
}
}
if (markers){
for (var i=0; i<markers.length; i++){
google.maps.event.removeListener(popups[i].listener);
popups[i].setMap(null);
markers[i].setMap(null);
}
}
markers.length = 0;
polies.length = 0;
popups.lentgth = 0;
}
var popup;
function setMarker(p,i,posLen) {
// marker
var marker = new google.maps.Marker( {
map: map,
position: p.coordinates,
title: p.dateoccured
});
if (latest==1) { marker.setIcon('http://maps.google.com/mapfiles/dd-end.png') }
else if (i==0) { marker.setIcon('http://maps.google.com/mapfiles/marker_greenA.png') }
else if (i==posLen-1) { marker.setIcon('http://maps.google.com/mapfiles/markerB.png') }
else { marker.setIcon('http://labs.google.com/ridefinder/images/mm_20_gray.png') }
// popup
var content = '<div id="popup">'+
'<div id="pheader">'+lang_user+': '+p.username.toUpperCase()+'<br />'+lang_track+': '+p.trackname.toUpperCase()+
'</div>'+
'<div id="pbody">'+
'<div id="pleft"><b>'+lang_time+':</b> '+p.dateoccured+'<br />'+
((p.speed != null)?'<b>'+lang_speed+':</b> '+(p.speed.toKmH()*factor_kmh)+' '+unit_kmh+'<br />':'')+
((p.altitude != null)?'<b>'+lang_altitude+':</b> '+(p.altitude*factor_m).toFixed()+' '+unit_m+'<br />':'')+'</div>'+
((latest==0)?
('<div id="pright"><b>'+lang_ttime+':</b> '+p.totalSeconds.toHMS()+'<br />'+
'<b>'+lang_aspeed+':</b> '+((p.totalSeconds>0)?((p.totalMeters/p.totalSeconds).toKmH()*factor_kmh).toFixed():0)+' '+unit_kmh+'<br />'+
'<b>'+lang_tdistance+':</b> '+(p.totalMeters.toKm()*factor_km).toFixed(2)+' '+unit_km+'<br />'+'</div>'):'')+
'<div id="pfooter">'+lang_point+' '+(i+1)+' '+lang_of+' '+(posLen)+'</div>'+
'</div></div>';
popup = new google.maps.InfoWindow();
popup.listener = google.maps.event.addListener(marker, 'click', (function(marker,content) {
return function() {
popup.setContent(content);
popup.open(map, marker);
if (document.getElementById('bottom').style.display=='block') {
chart.setSelection([{row:i,column:null}]);
}
}
})(marker,content));
markers.push(marker);
popups.push(popup);
}
// openstreetmaps
// TODO
// general stuff
// general stuff
if (units=='imperial') {
factor_kmh = 0.62; //to mph
unit_kmh = 'mph';
@ -177,19 +59,7 @@ function displayChart() {
chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', function() {
if (popup) {popup.close(); clearTimeout(altTimeout);}
var selection = chart.getSelection()[0];
if (selection) {
var id = selection.row;
var contentString = '<div style="width:40px; height:20px;padding:10px">'+Math.round(altitudes[id]*factor_m)+' '+unit_m+'</div>';
popup = new google.maps.InfoWindow({
content: contentString
});
popup.open(map,markers[id]);
altTimeout = setTimeout(function() { if (popup) {popup.close();} },2000);
}
});
addChartEvent(chart);
}
function toggleChart(i) {
@ -408,5 +278,67 @@ function setTime() {
clearInterval(auto);
autoReload();
}
}
}
}
// dynamic change of map api
function loadMapAPI(api) {
document.getElementById("map-canvas").innerHTML = '';
var url = new Array();
if (api=='gmaps') {
url.push('api_gmaps.js');
url.push('https://maps.googleapis.com/maps/api/js?sensor=false&callback=init');
}
else {
url.push('api_openlayers.js');
url.push('http://openlayers.org/api/OpenLayers.js');
}
addScript(url[0]);
waitAndLoad(api,url);
}
var loadTime = 0;
function waitAndLoad(api,url) {
// wait till first script loaded
if (loadTime>5000) { loadTime = 0; alert('Sorry, can\'t load '+api+' API'); return; }
if (loadedAPI!==api) {
setTimeout(function() { loadTime += 50; waitAndLoad(api,url); }, 50);
return;
}
if(!isScriptLoaded(url[1])){
addScript(url[1]);
}
loadTime = 0;
waitAndInit(api);
}
function waitAndInit(api) {
// wait till main api loads
if (loadTime>10000) { loadTime = 0; alert('Sorry, can\'t load '+api+' API'); return; }
try {
init();
}
catch(e) {
setTimeout(function() { loadTime += 50; waitAndInit(api); }, 50);
return;
}
loadTime = 0;
loadTrack(userid,trackid,1);
}
function addScript(url) {
var tag = document.createElement('script');
tag.setAttribute('type','text/javascript');
tag.setAttribute('src', url);
if (typeof tag!='undefined') {
document.getElementsByTagName('head')[0].appendChild(tag);
}
}
function isScriptLoaded(url) {
scripts = document.getElementsByTagName('script');
for (var i = scripts.length; i--;) {
// check if url matches src
if (scripts[i].src != '' && url.indexOf(scripts[i].src) !== -1) return true;
}
return false;
}