X-Git-Url: https://git-public.kairo.at/?p=lantea.git;a=blobdiff_plain;f=js%2Fmap.js;h=cb659f9d2f6f81967557b57fca08fd39017d3de2;hp=3c12015f01d31f1161abd191c682fc8290473ee1;hb=4b12da3a7069591d3ec6aceb4a949c97bc7549f2;hpb=55c4a0b7df4ca84d3d2fb6c6e294b0b75751b6ed diff --git a/js/map.js b/js/map.js index 3c12015..cb659f9 100644 --- a/js/map.js +++ b/js/map.js @@ -1,41 +1,9 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Lantea mapping/tracking web app. - * - * The Initial Developer of the Original Code is - * Robert Kaiser . - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Robert Kaiser - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -var gCanvas, gContext; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var gCanvas, gContext, gGeolocation; +var gDebug = false; var gTileSize = 256; var gMaxZoom = 18; // The minimum is 0. @@ -74,23 +42,73 @@ var gLastMouseX = 0; var gLastMouseY = 0; var gZoomFactor; -// Used as an associative array. They keys have to be strings, ours will be "xindex,yindex,zindex" e.g. "13,245,12". +// Used as an associative array. +// The keys have to be strings, ours will be "xindex,yindex,zindex" e.g. "13,245,12". var gTiles = {}; var gLoadingTile; +var gMapPrefsLoaded = false; + var gDragging = false; -var gZoomTouchID; +var gDragTouchID; var gGeoWatchID; var gTrack = []; var gLastTrackPoint; +var gCenterPosition = true; function initMap() { + gGeolocation = navigator.geolocation; gCanvas = document.getElementById("map"); gContext = gCanvas.getContext("2d"); if (!gActiveMap) gActiveMap = "osm_mapnik"; + //gDebug = true; + if (gDebug) { + gGeolocation = geofake; + var hiddenList = document.getElementsByClassName("debugHide"); + // last to first - list of elements with that class is changing! + for (var i = hiddenList.length - 1; i >= 0; i--) { + hiddenList[i].classList.remove("debugHide"); + } + } + + var loopCnt = 0; + var getPersistentPrefs = function() { + if (mainDB) { + gPrefs.get("position", function(aValue) { + if (aValue) { + gPos = aValue; + drawMap(); + } + }); + gPrefs.get("center_map", function(aValue) { + if (aValue === undefined) + document.getElementById("centerCheckbox").checked = true; + else + document.getElementById("centerCheckbox").checked = aValue; + setCentering(document.getElementById("centerCheckbox")); + }); + gPrefs.get("tracking_enabled", function(aValue) { + if (aValue === undefined) + document.getElementById("trackCheckbox").checked = true; + else + document.getElementById("trackCheckbox").checked = aValue; + setTracking(document.getElementById("trackCheckbox")); + }); + gMapPrefsLoaded = true; + } + else + setTimeout(getPersistentPrefs, 100); + loopCnt++; + if (loopCnt > 20) { + gMapPrefsLoaded = true; + return; + } + }; + getPersistentPrefs(); + gCanvas.addEventListener("mouseup", mapEvHandler, false); gCanvas.addEventListener("mousemove", mapEvHandler, false); gCanvas.addEventListener("mousedown", mapEvHandler, false); @@ -232,14 +250,19 @@ function drawMap() { var xMax = gPos.x + wid / 2; var yMax = gPos.y + ht / 2; - // Go through all the tiles we want. If any of them aren't loaded or being loaded, do so. + if (gMapPrefsLoaded && mainDB) + gPrefs.set("position", gPos); + + // Go through all the tiles we want. + // If any of them aren't loaded or being loaded, do so. for (var x = Math.floor(xMin / size); x < Math.ceil(xMax / size); x++) { for (var y = Math.floor(yMin / size); y < Math.ceil(yMax / size); y++) { var xoff = (x * size - xMin) / gZoomFactor; var yoff = (y * size - yMin) / gZoomFactor; var tileKey = encodeIndex(x, y, gPos.z); if (gTiles[tileKey] && gTiles[tileKey].complete) { - // Round here is **CRUICIAL** otherwise the images are filtered and the performance sucks (more than expected). + // Round here is **CRUCIAL** otherwise the images are filtered + // and the performance sucks (more than expected). gContext.drawImage(gTiles[tileKey], Math.round(xoff), Math.round(yoff)); } else { @@ -297,21 +320,21 @@ var mapEvHandler = { return; // Bail out if the started touch can't be found. - if (touchEvent && zoomstart && - !aEvent.changedTouches.identifiedTouch(gZoomTouchID)) + if (touchEvent && gDragging && + !aEvent.changedTouches.identifiedTouch(gDragTouchID)) return; } var coordObj = touchEvent ? - aEvent.changedTouches.identifiedTouch(gZoomTouchID) : + aEvent.changedTouches.identifiedTouch(gDragTouchID) : aEvent; switch (aEvent.type) { case "mousedown": case "touchstart": if (touchEvent) { - zoomTouchID = aEvent.changedTouches.item(0).identifier; - coordObj = aEvent.changedTouches.identifiedTouch(gZoomTouchID); + gDragTouchID = aEvent.changedTouches.item(0).identifier; + coordObj = aEvent.changedTouches.identifiedTouch(gDragTouchID); } var x = coordObj.clientX - gCanvas.offsetLeft; var y = coordObj.clientY - gCanvas.offsetTop; @@ -387,14 +410,26 @@ var mapEvHandler = { } }; -geofake = { +var geofake = { tracking: false, + lastPos: {x: undefined, y: undefined}, watchPosition: function(aSuccessCallback, aErrorCallback, aPrefObject) { this.tracking = true; var watchCall = function() { + // calc new position in lat/lon degrees + // 90° on Earth surface are ~10,000 km at the equator, + // so try moving at most 10m at a time + if (geofake.lastPos.x) + geofake.lastPos.x += (Math.random() - .5) * 90 / 1000000 + else + geofake.lastPos.x = 48.208174 + if (geofake.lastPos.y) + geofake.lastPos.y += (Math.random() - .5) * 90 / 1000000 + else + geofake.lastPos.y = 16.373819 aSuccessCallback({timestamp: Date.now(), - coords: {latitude: 48.208174, // + Math.random() - .5, - longitude: 16.373819, // + Math.random() - .5, + coords: {latitude: geofake.lastPos.x, + longitude: geofake.lastPos.y, accuracy: 20}}); if (geofake.tracking) setTimeout(watchCall, 1000); @@ -407,14 +442,59 @@ geofake = { } } +function setCentering(aCheckbox) { + if (gMapPrefsLoaded && mainDB) + gPrefs.set("center_map", aCheckbox.checked); + gCenterPosition = aCheckbox.checked; +} + +function setTracking(aCheckbox) { + if (gMapPrefsLoaded && mainDB) + gPrefs.set("tracking_enabled", aCheckbox.checked); + if (aCheckbox.checked) + startTracking(); + else + endTracking(); +} + function startTracking() { + var loopCnt = 0; + var getStoredTrack = function() { + if (mainDB) + gTrackStore.getList(function(aTPoints) { + if (gDebug) + document.getElementById("debug").textContent = aTPoints.length + " points loaded."; + if (aTPoints.length) { + gTrack = aTPoints; + } + }); + else + setTimeout(getStoredTrack, 100); + loopCnt++; + if (loopCnt > 20) + return; + }; + getStoredTrack(); if (navigator.geolocation) { - //gGeoWatchID = geofake.watchPosition( - gGeoWatchID = navigator.geolocation.watchPosition( + gGeoWatchID = gGeolocation.watchPosition( function(position) { // Coords spec: https://developer.mozilla.org/en/XPCOM_Interface_Reference/NsIDOMGeoPositionCoords - gTrack.push({time: position.timestamp, coords: position.coords}); + var tPoint = {time: position.timestamp, + coords: position.coords, + beginSegment: !gLastTrackPoint}; + gTrack.push(tPoint); + gTrackStore.push(tPoint); drawTrackPoint(position.coords.latitude, position.coords.longitude); + if (gCenterPosition) { + var posCoord = gps2xy(position.coords.latitude, + position.coords.longitude); + if (Math.abs(gPos.x - posCoord.x) > gCanvas.width * gZoomFactor / 4 || + Math.abs(gPos.y - posCoord.y) > gCanvas.height * gZoomFactor / 4) { + gPos.x = posCoord.x; + gPos.y = posCoord.y; + drawMap(); + } + } }, function(error) { // Ignore erros for the moment, but this is good for debugging. @@ -428,6 +508,12 @@ function startTracking() { function endTracking() { if (gGeoWatchID) { - navigator.geolocation.clearWatch(gGeoWatchID); + gGeolocation.clearWatch(gGeoWatchID); } } + +function clearTrack() { + gTrack = []; + gTrackStore.clear(); + drawMap(); +}