From 1c8c7cc2e72b7c9fd35fb9d19e60068f3ad54b9a Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Sun, 22 Dec 2019 21:07:45 -0700 Subject: [PATCH] Add mapbox-gl-js map client --- www/assets/css/app.css | 7 ++ www/assets/js/location.js | 8 +-- www/assets/js/map.js | 36 +++++++++- www/assets/js/map_leaflet.js | 10 +++ www/assets/js/map_mapbox.js | 132 +++++++++++++++++++++++++++++++++++ www/assets/js/settings.js | 10 +++ www/index.html | 3 + www/routes.js | 8 +++ www/settings.js | 4 ++ 9 files changed, 210 insertions(+), 8 deletions(-) create mode 100644 www/assets/js/map_mapbox.js diff --git a/www/assets/css/app.css b/www/assets/css/app.css index 7779dbb..45a2807 100644 --- a/www/assets/css/app.css +++ b/www/assets/css/app.css @@ -17,4 +17,11 @@ Framework7 and FontAwesome both have a .fab class font-family: var(--f7-font-family); font-size: var(--f7-font-size); line-height: var(--f7-line-height); +} + +#mapbox .package-marker { + width: 25px; + height: 25px; + background-image: url(../images/box.png); + background-size: contain; } \ No newline at end of file diff --git a/www/assets/js/location.js b/www/assets/js/location.js index 96f72df..9d3ce5c 100644 --- a/www/assets/js/location.js +++ b/www/assets/js/location.js @@ -45,15 +45,11 @@ if ("geolocation" in navigator) { localStorage.setItem("user_latitude", userPosition.coords.latitude); localStorage.setItem("user_longitude", userPosition.coords.longitude); if (mapLocationControlStarted) { - //setMapLocation(position.coords.latitude, position.coords.longitude); // Don't refresh at an interval less than ten seconds var currentTimestamp = Math.floor(Date.now() / 1000); if (lastGpsUpdateTimestamp < (currentTimestamp - 10)) { updateDistances(position.coords.latitude, position.coords.longitude); - if (map != null) { - //map.updatePackageLayer(packages); - } - + var alertinterval = localStorage.getItem("alertinterval"); if (alertinterval == null) { alertinterval = 30; @@ -89,7 +85,7 @@ if ("geolocation" in navigator) { } } else { if (map != null) { - map.locateControl.start(); + map.startLocateControl(); mapLocationControlStarted = true; } } diff --git a/www/assets/js/map.js b/www/assets/js/map.js index f9cd491..1d2bfe1 100644 --- a/www/assets/js/map.js +++ b/www/assets/js/map.js @@ -6,8 +6,24 @@ var map = null; +var maptype = "mapbox"; + function createMap() { - map = leafletMap(); + if (localStorage.getItem("maptype") == null) { + localStorage.setItem("maptype", "mapbox"); + } + maptype = localStorage.getItem("maptype"); + if (maptype == "mapbox") { + if (mapboxgl.supported()) { + map = mapboxMap(); + } else { + console.log("Warning: mapbox-gl not supported, falling back to Leaflet"); + maptype = "leaflet"; + map = leafletMap(); + } + } else { + map = leafletMap(); + } map.updatePackageLayer(packages); } @@ -20,16 +36,32 @@ function reloadMap() { if (map != null && typeof map != 'undefined') { var mapcenter = map.getCenter(); var mapzoom = map.getZoom(); + if (map.maptype == "mapbox") { + var mapbearing = map.getBearing(); + var mappitch = map.getPitch(); + } + map.off(); map.remove(); map = null; createMap(); - map.setView(mapcenter, mapzoom); + + if (map.maptype == "mapbox") { + map.jumpTo({ + center: mapcenter, + zoom: mapzoom, + bearing: mapbearing, + pitch: mappitch + }); + } else { + map.setView(mapcenter, mapzoom); + } } else { createMap(); } } catch (ex) { // oh well ¯\(°_o)/¯ + console.log(ex); } } diff --git a/www/assets/js/map_leaflet.js b/www/assets/js/map_leaflet.js index 1899a6a..2629ca5 100644 --- a/www/assets/js/map_leaflet.js +++ b/www/assets/js/map_leaflet.js @@ -13,6 +13,8 @@ function leafletMap() { center: L.latLng(46.5966, -112.0180), attributionControl: false }); + + map.maptype = "leaflet"; if (localStorage.getItem("mapsource") == null) { localStorage.setItem("mapsource", "liberty"); @@ -43,6 +45,14 @@ function leafletMap() { map.setView({lat: userPosition.coords.latitude, lng: userPosition.coords.longitude}, 2); + map.startLocateControl = function () { + map.locateControl.start(); + } + + map.stopLocateControl = function () { + + } + map.setMapHeading = function (heading) { } diff --git a/www/assets/js/map_mapbox.js b/www/assets/js/map_mapbox.js new file mode 100644 index 0000000..5f7ad7c --- /dev/null +++ b/www/assets/js/map_mapbox.js @@ -0,0 +1,132 @@ +/* + * 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/. + */ + +// If true, we'll do a fancy zoom/pan in +// Otherwise we'll just jump to the correct location +var firstload = true; + +function mapboxMap() { + + if (localStorage.getItem("mapsource") == null) { + localStorage.setItem("mapsource", "liberty"); + } + + $("#mapbox").css("background-color", SETTINGS.maptileurls[localStorage.getItem("mapsource")].bgcolor); + + mapboxgl.accessToken = ''; + var map = new mapboxgl.Map({ + container: 'mapbox', + style: SETTINGS.maptileurls[localStorage.getItem("mapsource")].json, + attributionControl: false, + dragPan: true, + pitch: 0, + zoom: 2, + maxZoom: 19 + }); + + map.maptype = "mapbox"; + + map.addControl(new mapboxgl.NavigationControl()); + + map.addControl( + new mapboxgl.GeolocateControl({ + positionOptions: { + enableHighAccuracy: true, + timeout: 10 * 1000 + }, + fitBoundsOptions: { + maxZoom: 16 + }, + trackUserLocation: true + }) + ); + + map.startLocateControl = function () { + // stub + } + + map.stopLocateControl = function () { + // stub + } + + map.mapEasing = function (t) { + return t * (2 - t); + } + + map.setMapHeading = function (heading) { + if (typeof heading == 'number') { + map.easeTo({ + bearing: heading, + easing: map.mapEasing + }); + } + } + + map.setMapLocation = function (latitude, longitude) { + map.easeTo({ + center: [ + longitude, + latitude + ] + }); + } + + map.updatePackageLayer = function (data) { + var oldmarkers = document.getElementsByClassName("package-marker"); + if (oldmarkers.length > 0) { + markerparent = oldmarkers[0].parentNode; + while (oldmarkers.length > 0) { + markerparent.removeChild(oldmarkers[0]); + } + } + + for (var i = 0; i < data.length; i++) { + // JavaScript variable scope and anonymous functions are dumb + // This is necessary, otherwise all the on(click)s will fire for the last iteration + // of the loop, or something like that + (function (datai) { + var iconName = getMapIconForItems(datai.items); + console.log(iconName); + + var el = document.createElement("div"); + el.className = "package-marker"; + + el.style = "background-image: url(assets/images/" + iconName + ".png);"; + + el.addEventListener('click', function () { + openPackageInfoSheet(datai.id); + }); + + new mapboxgl.Marker(el) + .setLngLat([datai.coords[1], datai.coords[0]]) + .addTo(map); + })(data[i]); + } + } + + map.animateMapIn = function (latitude, longitude, zoom, heading) { + if (typeof zoom == 'undefined') { + zoom = 16; + } + if (typeof heading == 'undefined') { + heading = 0; + } + map.flyTo({ + center: [ + longitude, + latitude + ], + speed: 1, + zoom: zoom, + heading: heading, + pitch: 0 + }); + } + + map.animateMapIn(userPosition.coords.latitude, userPosition.coords.longitude, 12); + + return map; +} \ No newline at end of file diff --git a/www/assets/js/settings.js b/www/assets/js/settings.js index 1bc94f6..b588064 100644 --- a/www/assets/js/settings.js +++ b/www/assets/js/settings.js @@ -73,6 +73,16 @@ $('.item-link[data-setting=mapsource] select').on("change", function () { reloadMap(); }); +$('.item-content[data-setting=maptype] .toggle input').on("change", function () { + var checked = $(this).prop('checked'); + console.log(checked); + localStorage.setItem("maptype", checked ? "leaflet" : "mapbox"); + + maptype = checked ? "leaflet" : "mapbox"; + + reloadMap(); +}); + $('.item-link[data-setting=alertsound] select').on("change", function () { localStorage.setItem("alertsound", $('.item-link[data-setting=alertsound] select').val()); // Reload sound effect stuff to apply new sound diff --git a/www/index.html b/www/index.html index 4b07c63..b379f10 100644 --- a/www/index.html +++ b/www/index.html @@ -12,6 +12,7 @@ + @@ -36,6 +37,7 @@ + @@ -50,6 +52,7 @@ + diff --git a/www/routes.js b/www/routes.js index 4c3c12f..47b2375 100644 --- a/www/routes.js +++ b/www/routes.js @@ -268,6 +268,14 @@ var routes = [ options: mapstyles, text: "Choose which map style to use." }, + { + setting: "maptype", + title: "Map viewer", + text: "Use alternate/lightweight map viewer", + toggle: true, + checked: localStorage.getItem("maptype") == "leaflet", + onclick: "" + }, { setting: "versions", title: "PackageHelper app v" + app_version, diff --git a/www/settings.js b/www/settings.js index 245ac33..ee2ebe7 100644 --- a/www/settings.js +++ b/www/settings.js @@ -8,21 +8,25 @@ var SETTINGS = { maptileurls: { liberty: { url: "https://maps.netsyms.net/styles/osm-liberty/{z}/{x}/{y}.png", + json: "https://maps.netsyms.net/styles/osm-liberty/style.json", name: "Liberty", bgcolor: "#EFEFEF" }, terrain: { url: "https://maps.netsyms.net/styles/klokantech-terrain/{z}/{x}/{y}.png", + json: "https://maps.netsyms.net/styles/klokantech-terrain/style.json", name: "Terrain", bgcolor: "#EDF5F3" }, fiord: { url: "https://maps.netsyms.net/styles/fiord-color/{z}/{x}/{y}.png", + json: "https://maps.netsyms.net/styles/fiord-color/style.json", name: "Dark Fiord", bgcolor: "#45516E" }, oledblack: { url: "https://maps.netsyms.net/styles/oled-black/{z}/{x}/{y}.png", + json: "https://maps.netsyms.net/styles/oled-black/style.json", name: "OLED Black", bgcolor: "#000000" }