diff --git a/apps/openstmap/ChangeLog b/apps/openstmap/ChangeLog index 32f9f21ad..8ac33f909 100644 --- a/apps/openstmap/ChangeLog +++ b/apps/openstmap/ChangeLog @@ -38,4 +38,6 @@ 0.30: Minor code improvements 0.31: Reset draw colours before rendering (to allow black and white maps) 0.32: Move to non-deprecated track drawing using the recorder library - Add option to hide widgets \ No newline at end of file + Add option to hide widgets +0.33: Map zoom by tapping is now only when tapping at each corner (helps with accidental zooming) + When GPS location is offscreen, draw a blue circle showing the direction to scroll \ No newline at end of file diff --git a/apps/openstmap/README.md b/apps/openstmap/README.md index d492bae05..bf243c391 100644 --- a/apps/openstmap/README.md +++ b/apps/openstmap/README.md @@ -6,7 +6,7 @@ allows you to use the maps in your Bangle.js applications. ## Uploader -Once you've installed OpenStreepMap on your Bangle, find it +Once you've installed OpenStreetMap on your Bangle, find it in the App Loader and click the Disk icon next to it. A window will pop up showing what maps you have loaded. @@ -34,13 +34,16 @@ and marks the path that you've been travelling (if enabled), and displays waypoints in the watch (if dependencies exist). * Drag on the screen to move the map -* Click bottom left to zoom in, bottom right to zoom out +* Click at the bottom left corner to zoom in, bottom right to zoom out (or you can choose from the menu) * Press the button to bring up a menu, where you can zoom, go to GPS location, put the map back in its default location, or choose whether to draw the currently recording GPS track (from the `Recorder` app). -**Note:** If enabled, drawing the currently recorded GPS track can take a second -or two (which happens after you've finished scrolling the screen with your finger). +The map displays: + +* Your current GPS location and angle (in blue) or a circle at the edge of the screen if your location is offscreen +* Your currently recorded/recording track in red (if the `Recorder` app is installed) +* Any waypoints as red markers (if the `Waypoint` app is installed) ## Library diff --git a/apps/openstmap/app.js b/apps/openstmap/app.js index 0d6f92555..00babc9fa 100644 --- a/apps/openstmap/app.js +++ b/apps/openstmap/app.js @@ -2,20 +2,21 @@ var m = require("openstmap"); var R; var fix = {}; var mapVisible = false; -var hasScrolled = false; var settings = require("Storage").readJSON("openstmap.json",1)||{}; var HASWIDGETS = !settings.noWidgets; var plotTrack; let checkMapPos = false; // Do we need to check the if the coordinates we have are valid -var startDrag = 0; +var startDrag = 0; //< to detect a short tap when zooming var hasRecorder = require("Storage").read("recorder")!=undefined; // do we have the recorder library? +var hasWaypoints = require("Storage").read("waypoints")!=undefined; // do we have the recorder library? +var labelFont = g.getFonts().includes("17")?"17":"6x8:2"; +var imgLoc, ovLoc, ovSize = 34; /*Math.ceil(Math.sqrt(imgLoc[0]*imgLoc[0]+imgLoc[1]*imgLoc[1]))*/ if (Bangle.setLCDOverlay) { // Icon for current location+direction: https://icons8.com/icon/11932/gps 24x24, 1 Bit + transparency + inverted - var imgLoc = require("heatshrink").decompress(atob("jEYwINLAQk8AQl+AQn/AQcB/+AAQUD//AAQUH//gAQUP//wAQUf//4j8AvA9IA==")); + imgLoc = require("heatshrink").decompress(atob("jEYwINLAQk8AQl+AQn/AQcB/+AAQUD//AAQUH//gAQUP//wAQUf//4j8AvA9IA==")); // overlay buffer for current location, a bit bigger then image so we can rotate - const ovSize = Math.ceil(Math.sqrt(imgLoc[0]*imgLoc[0]+imgLoc[1]*imgLoc[1])); - var ovLoc = Graphics.createArrayBuffer(ovSize,ovSize,imgLoc[2] & 0x7f,{msb:true}); + ovLoc = Graphics.createArrayBuffer(ovSize,ovSize,imgLoc[2] & 0x7f,{msb:true}); } if (settings.lat !== undefined && settings.lon !== undefined && settings.scale !== undefined) { @@ -66,6 +67,7 @@ function redraw() { // Draw the POIs function drawPOI() { + if (!hasWaypoints) return; let waypoints; try { waypoints = require("waypoints").load(); @@ -73,16 +75,15 @@ function drawPOI() { // Waypoints module not available. return; } - g.setFont("Vector", 18); + if (!waypoints) return; + g; + var img = atob("DRXCAP//APgfAAAAAFVAAVVVAVVVUFUBVFUAFVVABVVQAVRVAVQVVVUBVVUAVVVABVVAAVVQABVQAAVUAABUAACVgACJiACISIAIiIAAiIAA"); + g.setFont(labelFont).setFontAlign(-1,0); waypoints.forEach((wp, idx) => { if (wp.lat === undefined || wp.lon === undefined) return; var p = m.latLonToXY(wp.lat, wp.lon); - var sz = 2; - g.setColor(0,0,0); - g.fillRect(p.x-sz, p.y-sz, p.x+sz, p.y+sz); - g.setColor(0,0,0); - g.drawString(wp.name, p.x, p.y); - //print(wp.name); + g.setColor("#fff").drawImage(img, p.x-6, p.y-18); + g.setColor(0).drawString(wp.name, p.x+8, p.y); }); } @@ -119,17 +120,31 @@ function drawLocation() { // TODO: if this is getting off the screen, we could adjust the map over? Also show marker to show what direction we're offscreen ovLoc.clear(); + if (isInside(R, p, ovLoc.getWidth(), ovLoc.getHeight())) { // avoid drawing over widget area const angle = settings.dirSrc === 1 ? fix.course : Bangle.getCompass().heading; if (!isNaN(angle)) { ovLoc.drawImage(imgLoc, ovLoc.getWidth()/2, ovLoc.getHeight()/2, {rotate: angle*Math.PI/180}); } + } else { // if off-screen, draw a blue dot on the edge + var mx = (R.x+R.x2)/2, my = (R.y+R.y2)/2; + var dy = p.y - mx, dx = p.x - my; + if (Math.abs(dx)>Math.abs(dy)) { + dy = mx * dy / Math.abs(dx); + dx = mx * Math.sign(dx); + } else { + dx = my * dx / Math.abs(dy); + dy = my * Math.sign(dy); + } + p.x = mx+dx; + p.y = my+dy; + ovLoc.fillCircle(ovSize/2,ovSize/2,16); } - Bangle.setLCDOverlay({width:ovLoc.getWidth(), height:ovLoc.getHeight(), + Bangle.setLCDOverlay({width:ovSize, height:ovSize, bpp:ovLoc.getBPP(), transparent:0, palette:new Uint16Array([0, g.toColor("#00F")]), buffer:ovLoc.buffer - }, p.x-ovLoc.getWidth()/2, p.y-ovLoc.getHeight()/2); + }, p.x-ovSize/2, p.y-ovSize/2); this.hasOverlay = true; } @@ -252,25 +267,27 @@ function showMap() { if (e.b) { if (!startDrag) startDrag = getTime(); - g.setClipRect(R.x,R.y,R.x2,R.y2); - g.scroll(e.dx,e.dy); - m.scroll(e.dx,e.dy); - g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); - hasScrolled = true; + if (e.dx || e.dy) { + g.setClipRect(R.x,R.y,R.x2,R.y2); + g.scroll(e.dx,e.dy); + m.scroll(e.dx,e.dy); + g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); + } drawLocation(); - } else if (hasScrolled) { + } else if (startDrag) { const delta = getTime() - startDrag; startDrag = 0; - hasScrolled = false; - if (delta < 0.2) { - if (e.y > g.getHeight() / 2) { - if (e.x < g.getWidth() / 2) { + if (delta < 0.2) { // short tap? + if (e.y > g.getHeight() - 32) { // at bottom egde? + if (e.x < 32) { // zoom in/out m.scale /= 2; - } else { + g.reset().clearRect(R); + } + if (e.x > g.getHeight() - 32) { m.scale *= 2; + g.reset().clearRect(R); } } - g.reset().clearRect(R); } redraw(); } diff --git a/apps/openstmap/metadata.json b/apps/openstmap/metadata.json index 876a977b1..707d8f37f 100644 --- a/apps/openstmap/metadata.json +++ b/apps/openstmap/metadata.json @@ -2,7 +2,7 @@ "id": "openstmap", "name": "OpenStreetMap", "shortName": "OpenStMap", - "version": "0.32", + "version": "0.33", "description": "Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are. Once installed this also adds map functionality to `GPS Recorder` and `Recorder` apps", "readme": "README.md", "icon": "app.png",