Skip to content

Commit

Permalink
- checking in for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
temi committed Feb 1, 2024
1 parent 2e3273d commit 0387aba
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 30 deletions.
4 changes: 2 additions & 2 deletions grails-app/assets/javascripts/MapUtilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,11 @@ Biocollect.MapUtilities = {
break;
case 'maptilersatellite':
option = {
url: url || 'https://api.maptiler.com/maps/hybrid/{z}/{x}/{y}.jpg?key=O11Deo7fBLatChkUYGIH',
url: url || 'https://api.maptiler.com/maps/hybrid/256/{z}/{x}/{y}.jpg?key=O11Deo7fBLatChkUYGIH',
options: {
attribution: '<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>',
maxZoom: 21,
maxNativeZoom: 13
maxNativeZoom: 21
}
};
layer = L.tileLayer(option.url, option.options);
Expand Down
109 changes: 91 additions & 18 deletions grails-app/assets/javascripts/pwa-index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
async function downloadMapTiles(bounds, tileUrl, minZoom, maxZoom, callback) {
minZoom = minZoom || 0; // Minimum zoom level
maxZoom = maxZoom || 20; // Maximum zoom level
const MAX_PARALLEL_REQUESTS = 10;

var deferred = $.Deferred();
var deferred = $.Deferred(), requestArray = [];
// Check if the browser supports the Cache API
if ('caches' in window) {
// Function to fetch and cache the vector basemap tiles for a bounding box at different zoom levels
Expand Down Expand Up @@ -30,14 +31,19 @@ async function downloadMapTiles(bounds, tileUrl, minZoom, maxZoom, callback) {
if (!cachedResponse) {
console.log(`Tile at zoom ${zoom}, x ${x}, y ${y} not found in cache. Fetching and caching...`);

// Fetch the tile from the server
const response = await fetch(requestUrl);

// Clone the response, as it can only be consumed once
const responseClone = response.clone();
// run x number of queries in parallel
if (requestArray.length <= MAX_PARALLEL_REQUESTS) {
requestArray.push(fetch(requestUrl).then(function (response) {
// Clone the response, as it can only be consumed once
const responseClone = response.clone();

// Cache the response
await cache.put(requestUrl, responseClone);
// Cache the response
cache.put(requestUrl, responseClone);
}));
} else {
await Promise.all(requestArray);
requestArray = [];
}

console.log(`Tile at zoom ${zoom}, x ${x}, y ${y} cached.`);
} else {
Expand All @@ -52,6 +58,9 @@ async function downloadMapTiles(bounds, tileUrl, minZoom, maxZoom, callback) {
}
}

if (requestArray.length > 0) {
await Promise.all(requestArray);
}
console.log('Vector basemap tiles cached for the bounding box.');
deferred.resolve();
} catch (error) {
Expand Down Expand Up @@ -184,18 +193,25 @@ function OfflineViewModel(config) {
minZoom = config.minZoom || 0,
maxZoom = config.maxZoom || 20,
mapId = config.mapId,
overlayLayersMapControlConfig = Biocollect.MapUtilities.getOverlayConfig(),
mapOptions = {
autoZIndex: false,
zoomToObject: true,
preserveZIndex: true,
addLayersControlHeading: false,
drawControl: false,
showReset: false,
draggableMarkers: false,
useMyLocation: true,
maxAutoZoom: maxZoom,
maxZoom: maxZoom,
minZoom: minZoom,
allowSearchLocationByAddress: true,
allowSearchRegionByAddress: true,
trackWindowHeight: false,
baseLayer: L.tileLayer(config.baseMapUrl, config.baseMapOptions)
baseLayer: L.tileLayer(config.baseMapUrl, config.baseMapOptions),
wmsFeatureUrl: overlayLayersMapControlConfig.wmsFeatureUrl,
wmsLayerUrl: overlayLayersMapControlConfig.wmsLayerUrl
},
alaMap = new ALA.Map(mapId, mapOptions),
mapImpl = alaMap.getMapImpl(),
Expand Down Expand Up @@ -390,33 +406,90 @@ function OfflineViewModel(config) {
return area;
}

/**
* Downloads base map tiles and wms layer of a site for offline use.
* It is done for all sites of a project activity.
* @returns {Promise<void>}
*/
async function startDownloadingSites() {
var sites = pa.sites || [], zoom = 15;
const TIMEOUT = 3000, // 3 seconds
MAP_LOAD_TIMEOUT = 2000, // 2 seconds
MAX_ZOOM=20,
MIN_ZOOM= 10;
var sites = pa.sites || [], zoom = 15, mapZoomedInIndicator, tileLoadedPromise, cancelTimer,
callback = function () {
cancelTimer && clearTimeout(cancelTimer);
cancelTimer = null;
// resolve it in the next event loop
if(mapZoomedInIndicator && mapZoomedInIndicator.state() == 'pending') {
// setTimeout(function () {
mapZoomedInIndicator && mapZoomedInIndicator.resolve();
// }, 0);
}
};
self.currentStage(self.stages.sites);
self.sitesStatus(self.statuses.doing);
alaMap.registerListener('dataload', callback);

try {
self.numberOfSiteTilesDownloaded(0);
self.totalSiteTilesDownload(sites.length);
for (var i = 0; i < sites.length; i++) {
var site = sites[i],
zoomIntoMap = true,
geoJson = Biocollect.MapUtilities.featureToValidGeoJson(site.extent.geometry),
layer = L.geoJson(geoJson),
bounds = layer.getBounds();

alaMap.addLayer(layer);
alaMap.fitBounds();
zoom = mapImpl.getZoom();
alaMap.removeLayer(layer);
await downloadMapTiles(bounds, config.baseMapUrl, zoom, zoom);
geoJsonLayer = alaMap.setGeoJSON(geoJson, {
wmsFeatureUrl: overlayLayersMapControlConfig.wmsFeatureUrl,
wmsLayerUrl: overlayLayersMapControlConfig.wmsLayerUrl,
maxZoom: MAX_ZOOM
});

geoJsonLayer.on('tileload', function () {
if(tileLoadedPromise && tileLoadedPromise.state() == 'pending') {
tileLoadedPromise.resolve();
}
});
// so that layer zooms beyond default max zoom of 18
geoJsonLayer.options.maxZoom = MAX_ZOOM;
mapZoomedInIndicator = $.Deferred();
// cancel waiting for map to load feature data
cancelTimer = setTimeout(function (){
zoomIntoMap = false;
mapZoomedInIndicator && mapZoomedInIndicator.resolve();
}, TIMEOUT);

// no need to wait if promise is resolved.
if (mapZoomedInIndicator && mapZoomedInIndicator.state() == 'pending') {
// wait for map layer to load feature data from spatial server for pid.
await mapZoomedInIndicator.promise();
}

if (zoomIntoMap) {
// zoom into to map to get tiles and feature from spatial server
for (zoom = MIN_ZOOM; zoom <= MAX_ZOOM; zoom++) {
tileLoadedPromise = $.Deferred();
mapImpl.setZoom(zoom, {animate: false});
timer(MAP_LOAD_TIMEOUT, tileLoadedPromise);
await tileLoadedPromise.promise();
}
}

alaMap.clearLayers();
self.numberOfSiteTilesDownloaded(self.numberOfSiteTilesDownloaded() + 1);
}

alaMap.removeListener('dataload', callback);
completedSitesDownload();
} catch (e) {
console.error(e);
errorSitesDownload();
}
}

function timer(ms, deferred) {
return setTimeout(deferred.resolve, ms);
}

function completedSitesDownload() {
updateSitesProgressBar(self.totalCount(), self.totalCount());
self.sitesStatus(self.statuses.done);
Expand Down
11 changes: 10 additions & 1 deletion grails-app/assets/javascripts/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ self.addEventListener('fetch', e => {
return res;
}
else if (isFetchingBaseMap(e.request.url)) {
return fetch(pwaConfig.noCacheTileFile);
return caches.match(pwaConfig.noCacheTileFile).then(res => {
if (res) {
return res;
}
});
}
});
}
Expand Down Expand Up @@ -97,6 +101,11 @@ function isFetchingBaseMap (url) {

async function precache() {
const cache = await caches.open(pwaConfig.cacheName);

for(var i = 0; i < pwaConfig.filesToPreCache.length; i++) {
await cache.delete(pwaConfig.filesToPreCache[i]);
}

return cache.addAll(pwaConfig.filesToPreCache);
}
console.debug("SW Script: end reading");
7 changes: 5 additions & 2 deletions grails-app/conf/application.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,9 @@ if (!app.file.script.path) {
script.read.extensions.list = ['js','min.js','png', 'json', 'jpg', 'jpeg']

// yml interpreter doesn't evaluate expression in deep nested objects such as baseLayers below
if (pwa.mapConfig.baseLayers?.size() > 1) {
pwa.mapConfig.baseLayers[0].url = pwa.baseMapUrl
pwaMapConfig = { def config ->
Map pwa = config.getProperty('pwa', Map)
Map mapConfig = pwa.mapConfig
mapConfig.baseLayers.getAt(0).url = pwa.baseMapUrl + pwa.apiKey
mapConfig
}
7 changes: 4 additions & 3 deletions grails-app/conf/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -315,22 +315,23 @@ pwa:
cache:
ignore: ["/image/upload", "/ws/attachment/upload"]
maxAreaInKm: 25
tileSize: 512
tileSize: 256
apiKey: ""
cacheVersion: "v3"
oldCacheToDelete: "v2"
serviceWorkerConfig:
pathsToIgnoreCache: [ "/image/upload", "/ws/attachment/upload", "/ajax/keepSessionAlive", "/noop", '/pwa/sw.js', '/pwa/config.js', "/ws/species/speciesDownload" ]
cachePathForRequestsStartingWith: [ "/pwa/bioActivity/edit/", "/pwa/createOrEditFragment/", "/pwa/bioActivity/index/", "/pwa/indexFragment/", "/pwa/offlineList" ]
filesToPreCache: ["webjars/leaflet/0.7.7/dist/images/layers.png", "webjars/leaflet/0.7.7/dist/images/layers-2x.png", "webjars/leaflet/0.7.7/dist/images/marker-icon.png", "webjars/leaflet/0.7.7/dist/images/marker-icon-2x.png", "webjars/leaflet/0.7.7/dist/images/marker-shadow.png", "map-not-cached.png", "font-awesome/5.15.4/svgs/regular/image.svg"]
baseMapPrefixUrl: "https://api.maptiler.com/maps/hybrid"
baseMapPrefixUrl: "https://api.maptiler.com/maps/hybrid/256"
noCacheTileFile: "map-not-cached.png"
baseMapUrl: "${pwa.serviceWorkerConfig.baseMapPrefixUrl}/{z}/{x}/{y}.jpg?key=${pwa.apiKey}"
baseMapUrl: "${pwa.serviceWorkerConfig.baseMapPrefixUrl}/{z}/{x}/{y}.jpg?key="
mapConfig:
baseLayers:
- code: 'maptilersatellite'
displayText: 'Satellite'
isSelected: true
attribution: '<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>'
overlays: [ ]

---
Expand Down
10 changes: 8 additions & 2 deletions grails-app/views/bioActivity/pwa.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@
<asset:script type="text/javascript">
var params = getParams(), initialized = false;
var fcConfig = {
intersectService: "${createLink(controller: 'proxy', action: 'intersect')}",
featuresService: "${createLink(controller: 'proxy', action: 'features')}",
featureService: "${createLink(controller: 'proxy', action: 'feature')}",
spatialWms: "${grailsApplication.config.spatial.geoserverUrl}",
layersStyle: "${createLink(controller: 'regions', action: 'layersStyle')}",
createActivityUrl: "/pwa/bioActivity/edit/" + params.projectActivityId + "?cache=true",
indexActivityUrl: "/pwa/bioActivity/index/" + params.projectActivityId+ "?cache=true",
baseMapUrl: "${grailsApplication.config.getProperty("pwa.baseMapUrl")}",
baseMapUrl: "${grailsApplication.config.getProperty("pwa.baseMapUrl")}${grailsApplication.config.getProperty("pwa.apiKey")}",
baseMapAttribution: "${grailsApplication.config.getProperty("pwa.mapConfig.baseLayers", List)?.getAt(0)?.attribution?.encodeAsJavaScript()}",
fetchSpeciesUrl: "${createLink(controller: 'search', action: 'searchSpecies')}",
metadataURL: "/ws/projectActivity/activity",
siteUrl: '${createLink(controller: 'site', action: 'index' )}',
Expand Down Expand Up @@ -78,7 +84,7 @@
totalUrl: fcConfig.totalUrl,
downloadSpeciesUrl: fcConfig.downloadSpeciesUrl,
baseMapOptions: {
attribution: '<a target="_blank" rel="noopener noreferrer" href="https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9">Tiles from Esri</a> &mdash; Sources: Esri, DigitalGlobe, Earthstar Geographics, CNES/Airbus DS, GeoEye, USDA FSA, USGS, Aerogrid, IGN, IGP, and the GIS User Community',
attribution: fcConfig.baseMapAttribution,
maxZoom: 20
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
getOutputSpeciesIdUrl : "${createLink(controller: 'output', action: 'getOutputSpeciesIdentifier')}",
getGuidForOutputSpeciesUrl : "${createLink(controller: 'record', action: 'getGuidForOutputSpeciesIdentifier')}",
imageLeafletViewer: '${createLink(controller: 'resource', action: 'imageviewer', absolute: true)}',
mapLayersConfig: ${ grailsApplication.config.getProperty('pwa.mapConfig', Map) as JSON },
mapLayersConfig: ${ grailsApplication.config.getProperty('pwaMapConfig', Closure)(grailsApplication.config) as JSON },
excelOutputTemplateUrl: "${createLink(controller: 'proxy', action:'excelOutputTemplate')}",
uploadImagesUrl: "${createLink(controller: 'image', action: 'upload')}",
originUrl: "${grailsApplication.config.getProperty('server.serverURL')}",
Expand Down
2 changes: 1 addition & 1 deletion grails-app/views/bioActivity/pwaBioActivityIndex.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
speciesProfileUrl: "${createLink(controller: 'proxy', action: 'speciesProfile')}",
noImageUrl: '${asset.assetPath(src: "font-awesome/5.15.4/svgs/regular/image.svg")}',
speciesImageUrl:"${createLink(controller:'species', action:'speciesImage')}",
mapLayersConfig: ${ grailsApplication.config.getProperty('pwa.mapConfig', Map) as JSON },
mapLayersConfig: ${ grailsApplication.config.getProperty('pwaMapConfig', Closure)(grailsApplication.config) as JSON },
excelOutputTemplateUrl: "${createLink(controller: 'proxy', action:'excelOutputTemplate')}",
pwaAppUrl: "${grailsApplication.config.getProperty('pwa.appUrl')}",
bulkUpload: false,
Expand Down

0 comments on commit 0387aba

Please sign in to comment.