OpenLayers API
This commit is contained in:
parent
160773929a
commit
8c9a527fdf
13
README
13
README
@ -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
173
api_gmaps.js
Executable 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
169
api_openlayers.js
Executable 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);
|
||||
}
|
||||
});
|
||||
}
|
17
config.php
17
config.php
@ -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";
|
||||
|
||||
?>
|
||||
|
64
index.php
64
index.php
@ -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 />
|
||||
|
2
lang.php
2
lang.php
@ -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;
|
||||
}
|
||||
?>
|
||||
|
16
main.css
16
main.css
@ -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
200
main.js
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user