mirror of
https://github.com/Esri/offline-editor-js.git
synced 2025-12-15 15:20:05 +00:00
secure tiles basic test app
This commit is contained in:
parent
117012bcb7
commit
b9c1382a7e
429
test/secure_tiles_basic_test.html
Normal file
429
test/secure_tiles_basic_test.html
Normal file
@ -0,0 +1,429 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
|
||||
|
||||
<!--
|
||||
|
||||
This sample demonstrates using an application manifest to store tiles locally.
|
||||
|
||||
The use cases for using this sample are to ensure you can reload and restart you application
|
||||
one it is offline.
|
||||
|
||||
It is strongly recommended that you use your own optimized build of the ArcGIS API for JavaScript
|
||||
using the Web Optimizer: http://jso.arcgis.com/. You can reference the CDN or host it on your
|
||||
own web server.
|
||||
|
||||
Use the included Grunt task to help generate the manifest file. There is manual
|
||||
work involved in determining which files need to go into the manifest. The included manifest
|
||||
file should work with this sample to give you an idea of what goes into the manifest.
|
||||
|
||||
A few things to know about manifest files:
|
||||
- You cannot load an online url that has a redirect.
|
||||
- If there is an error encountered, the manifest file will stop loading
|
||||
- The /utils/appCacheManager.js library will auto detect if the manifest changed and
|
||||
ask if you want to reload the application.
|
||||
|
||||
-->
|
||||
|
||||
<title>Cache Tiles</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="//js.arcgis.com/3.14/dijit/themes/tundra/tundra.css">
|
||||
<link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css">
|
||||
<link rel="stylesheet" type="text/css" href="http://esri.github.io/bootstrap-map-js/src/css/bootstrapmap.css">
|
||||
|
||||
<script>
|
||||
// DO NOT DELETE!
|
||||
// Listen for application cache update events
|
||||
// We want to place this as early in the application life-cycle as possible!
|
||||
window.addEventListener('load', function(evt) {
|
||||
|
||||
window.applicationCache.addEventListener('updateready', function(evt) {
|
||||
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
|
||||
// Browser downloaded a new app cache.
|
||||
if (confirm('A new version of this cache is available.')) {
|
||||
window.location.reload();
|
||||
console.log("App cache reloaded");
|
||||
}
|
||||
} else {
|
||||
// Manifest didn't changed. Nothing new to server.
|
||||
console.log("App cache no change");
|
||||
}
|
||||
}, false);
|
||||
|
||||
}, false);
|
||||
|
||||
// Reserved for debugging on Safari desktop and mobile
|
||||
// Uncomment when doing any debugging on Safari 8 (or previous versions that support App Cache).
|
||||
// To delete the application cache file on Safari refer to the following url then close/restart browser:
|
||||
// http://stackoverflow.com/questions/5615266/how-do-you-clear-the-offline-cache-for-web-apps-in-safari
|
||||
|
||||
// function logEvent(event) {
|
||||
// console.log("Checking for Application Cache Event: " + event.type);
|
||||
// }
|
||||
//
|
||||
// window.applicationCache.addEventListener('checking',logEvent,false);
|
||||
// window.applicationCache.addEventListener('noupdate',logEvent,false);
|
||||
// window.applicationCache.addEventListener('downloading',logEvent,false);
|
||||
// window.applicationCache.addEventListener('cached',logEvent,false);
|
||||
// window.applicationCache.addEventListener('updateready',logEvent,false);
|
||||
// window.applicationCache.addEventListener('obsolete',logEvent,false);
|
||||
//
|
||||
// // If you need to catch AppCache errors as early as possible to troubleshoot errors.
|
||||
// // You should delete this for production use.
|
||||
// window.applicationCache.addEventListener("error",function(err){
|
||||
// console.log("ApplicationCache listener: " + err.toString() + ", " + JSON.stringify(err));
|
||||
// if (confirm('There was a problem setting this app up for offline. Reload?')) {
|
||||
// window.location.reload();
|
||||
// console.log("App cache reloaded");
|
||||
// }
|
||||
// },false);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#mapDiv {
|
||||
min-height: 500px;
|
||||
max-height: 1000px;
|
||||
}
|
||||
body {
|
||||
background-color: #FFF;
|
||||
overflow: hidden;
|
||||
font-family: "Trebuchet MS";
|
||||
}
|
||||
#tile-info{
|
||||
background-color: #000000;
|
||||
color: white;
|
||||
padding: 8px;
|
||||
position: relative; float: right;
|
||||
}
|
||||
.floatRight { float: right;}
|
||||
.container { padding: 20px;}
|
||||
.span-dbsize {color: blue; padding-left: 1em;}
|
||||
</style>
|
||||
<!--<script>-->
|
||||
<!--var locationPath = location.pathname.replace(/\/[^/]+$/, "");-->
|
||||
<!--var dojoConfig = {-->
|
||||
<!--paths: {-->
|
||||
<!--vendor: locationPath + "/../vendor",-->
|
||||
<!--utils: locationPath + "/../utils"-->
|
||||
<!--}-->
|
||||
<!--}-->
|
||||
<!--</script>-->
|
||||
<!-- This is a custom build of the ArcGIS API for JavaScript using the new Web Optimizer Tool -->
|
||||
<!--<script src="../samples/jsolib/dojo.js" data-dojo-config="async: true"></script>-->
|
||||
<script src="http://js.arcgis.com/3.14/"></script>
|
||||
<!-- Use this tag below if you are hosting your ArcGIS API for JavaScript files locally -->
|
||||
<!--<script src="libs/dojo/dojo/dojo.js" data-dojo-config="async: true"></script>-->
|
||||
<script src="../vendor/IndexedDBShim/dist/IndexedDBShim.min.js"></script>
|
||||
<script src="../vendor/offline/offline.min.js"></script>
|
||||
<script>
|
||||
Offline.options = {
|
||||
checks: {
|
||||
image: {
|
||||
url: function() {
|
||||
return 'http://esri.github.io/offline-editor-js/tiny-image.png?_=' + (Math.floor(Math.random() * 1000000000));
|
||||
}
|
||||
},
|
||||
active: 'image'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="tundra">
|
||||
|
||||
<!-- Our buttons and online/offline indicator -->
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-10">
|
||||
<div class="form form-group btn-group" data-toggle="buttons">
|
||||
<button class="btn btn-success" id="btn-get-tiles">1. Download Tiles</button>
|
||||
<button class="btn btn-success" disabled id="btn-online-offline">2. Go Offline</button>
|
||||
<button class="btn btn-success" disabled id="btn-pan-left">3. Pan left</button>
|
||||
</div>
|
||||
<span class="span-dbsize">Database Size (MBs) <span id="span-dbsize-value" class="badge">0</span></span>
|
||||
</div>
|
||||
<div class="col-xs-2">
|
||||
<!-- this indicates whether app is offline (down) or online (up) -->
|
||||
<button id="btn-state" class="btn btn-success btn-large floatRight">
|
||||
<span id="state-span" class="glyphicon glyphicon-link"> Up</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div id="mapDiv"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
require([
|
||||
"esri/map",
|
||||
"dojo/on",
|
||||
"esri/IdentityManager",
|
||||
"//esri.github.io/bootstrap-map-js/src/js/bootstrapmap.js",
|
||||
"../dist/offline-tiles-advanced-src.js",
|
||||
"dojo/domReady!"],
|
||||
function(Map,on,esriId,BootstrapMap) {
|
||||
|
||||
var map;
|
||||
var tileLayer = null;
|
||||
|
||||
var zoom = 18;
|
||||
var globalState = {};
|
||||
var _wantToCancel;
|
||||
var _isOnline = true;
|
||||
var minZoomAdjust = -1, maxZoomAdjust = 1;
|
||||
|
||||
var tiles;
|
||||
var EXTENT_BUFFER = 0; //buffers the map extent in meters
|
||||
var dbsize = document.getElementById("span-dbsize-value");
|
||||
|
||||
var btnGetTiles = document.getElementById("btn-get-tiles");
|
||||
var btnOnlineOffline = document.getElementById("btn-online-offline");
|
||||
var imgOfflineIndicator = document.getElementById("state-span");
|
||||
var btnState = document.getElementById("btn-state");
|
||||
var btnPanLeft = document.getElementById("btn-pan-left");
|
||||
|
||||
Offline.check();
|
||||
Offline.on('up down', updateState );
|
||||
|
||||
/**
|
||||
* There have been a few bugs in the offline detection library (offline.min.js)
|
||||
* This is a utility check to 100% validate if the application is online or
|
||||
* offline prior to launching any map functionality.
|
||||
*/
|
||||
verifyOnline(function(result){ console.log("VERIFY ONLINE " + result)
|
||||
result == true ? _isOnline = true : _isOnline = false;
|
||||
startMap();
|
||||
|
||||
});
|
||||
|
||||
function startMap(){
|
||||
//Make sure map shows up after a browser refresh
|
||||
Offline.state === 'up' ? zoom = 18 : zoom = 17;
|
||||
|
||||
map = BootstrapMap.create("mapDiv", {
|
||||
center: [-104.9622,39.6783], // long, lat
|
||||
zoom: 19,
|
||||
sliderStyle: "small"
|
||||
});
|
||||
|
||||
//
|
||||
//tileLayer = O.esri.Tiles.OfflineTileEnablerLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",function(evt){
|
||||
tileLayer = O.esri.Tiles.OfflineTileEnablerLayer("http://tiles.arcgis.com/tiles/M8KJPUwAXP8jhtnM/arcgis/rest/services/DenverUniv/MapServer",function(evt){
|
||||
console.log("Offline tile lib is enabled. Application state is: " + Offline.state);
|
||||
},_isOnline);
|
||||
|
||||
tileLayer.showBlankTiles = true; // if you don't want to see blank tile indicator images
|
||||
tileLayer.offline.proxyPath = null;
|
||||
|
||||
map.on("load",function(evt){
|
||||
init();
|
||||
|
||||
Offline.check();
|
||||
|
||||
//using null sets this for CORS
|
||||
tileLayer.offline.proxyPath = null;
|
||||
|
||||
on(btnOnlineOffline,"click",goOnlineOffline);
|
||||
on(btnGetTiles,"click",downloadTiles);
|
||||
on(btnPanLeft,"click",panLeft);
|
||||
|
||||
updateOfflineUsage();
|
||||
|
||||
console.log("level: " + tileLayer.getLevel());
|
||||
})
|
||||
|
||||
map.addLayer(tileLayer);
|
||||
}
|
||||
|
||||
function init(){
|
||||
map.on("extent-change",function(evt){
|
||||
updateOfflineUsage();
|
||||
console.log("Zoom level = " + tileLayer.getLevel());
|
||||
|
||||
tileLayer.estimateTileSize(function(size) {
|
||||
console.log("SIZE: " + size);
|
||||
var estimation = tileLayer.getLevelEstimation(map.extent,17,size);
|
||||
console.log("LEVEL: " + estimation);
|
||||
});
|
||||
});
|
||||
|
||||
map.reposition();
|
||||
map.resize();
|
||||
}
|
||||
|
||||
function updateOfflineUsage()
|
||||
{
|
||||
tileLayer.offline.store.usedSpace(function(result,err){
|
||||
if(result != null){
|
||||
var mb = (result.sizeBytes >>> 20 ) + '.' + ( result.sizeBytes & (2*0x3FF ) );
|
||||
dbsize.innerHTML = mb;
|
||||
}
|
||||
else{
|
||||
dbsize.innerHTML = "??";
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function updateState(){
|
||||
if(Offline.state === 'up'){
|
||||
updateOfflineUsage();
|
||||
toggleStateUp(true);
|
||||
if(typeof tileLayer != "undefined") tileLayer.goOnline();
|
||||
}
|
||||
else{
|
||||
toggleStateUp(false);
|
||||
if(typeof tileLayer != "undefined") tileLayer.goOffline();
|
||||
}
|
||||
}
|
||||
|
||||
function toggleStateUp(state){
|
||||
if(state){
|
||||
btnOnlineOffline.innerHTML = "2. Go Offline";
|
||||
tileLayer.goOnline();
|
||||
imgOfflineIndicator.className = "glyphicon glyphicon-link";
|
||||
imgOfflineIndicator.innerHTML = " Up";
|
||||
btnState.className = "btn btn-success btn-large floatRight";
|
||||
}
|
||||
else{
|
||||
btnOnlineOffline.innerHTML = "2. Go Online";
|
||||
tileLayer.goOffline();
|
||||
imgOfflineIndicator.className = "glyphicon glyphicon-thumbs-down";
|
||||
imgOfflineIndicator.innerHTML = " Down";
|
||||
btnState.className = "btn btn-danger btn-large floatRight";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces offlineTileEnabler to go online or offline.
|
||||
* If it is offline it will try to find a tile in the local database.
|
||||
*/
|
||||
function goOnlineOffline(){
|
||||
|
||||
btnPanLeft.disabled = false;
|
||||
|
||||
if(btnOnlineOffline.innerHTML == "2. Go Offline"){
|
||||
toggleStateUp(false);
|
||||
console.log("Map is offline");
|
||||
}
|
||||
else{
|
||||
toggleStateUp(true);
|
||||
console.log("Map is online");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually starts the process to download and store tiles
|
||||
* in the local database
|
||||
*/
|
||||
function downloadTiles(){
|
||||
tileLayer.deleteAllTiles(function(success,err){
|
||||
if(success == false){
|
||||
alert("There was a problem deleting the tile cache");
|
||||
}
|
||||
else{
|
||||
console.log("success deleting tile cache");
|
||||
var self = this.data;
|
||||
|
||||
if( globalState.downloadState == 'downloading')
|
||||
{
|
||||
console.log("cancel!");
|
||||
_wantToCancel = true;
|
||||
btnGetTiles.innerHTML = "cancelling..";
|
||||
}
|
||||
else
|
||||
{
|
||||
var zoom = tileLayer.getMinMaxLOD(minZoomAdjust,maxZoomAdjust);
|
||||
|
||||
var extent = tileLayer.getExtentBuffer(EXTENT_BUFFER,map.extent);
|
||||
_wantToCancel = false;
|
||||
tileLayer.prepareForOffline(zoom.min, zoom.max, extent, reportProgress.bind(this));
|
||||
globalState.downloadState = 'downloading';
|
||||
}
|
||||
}
|
||||
}.bind(this))
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the process while downloading tiles.
|
||||
*/
|
||||
function reportProgress(progress)
|
||||
{
|
||||
console.log("downloading tiles...");
|
||||
if(progress.hasOwnProperty("countNow")){
|
||||
var percent = Math.floor(progress.countNow / progress.countMax * 100);
|
||||
btnGetTiles.innerHTML = 'Saving to phone ' + percent + "% - Tap to Cancel";
|
||||
}
|
||||
|
||||
if( progress.finishedDownloading )
|
||||
{
|
||||
btnGetTiles.innerHTML = "Saving to phone 100% - Tap to Cancel";
|
||||
updateOfflineUsage();
|
||||
|
||||
if( progress.cancelRequested )
|
||||
{
|
||||
globalState.downloadState = 'cancelled';
|
||||
alert("Tile download was cancelled");
|
||||
}
|
||||
else
|
||||
{
|
||||
globalState.downloadState = 'downloaded';
|
||||
btnOnlineOffline.disabled = false;
|
||||
alert("Tile download complete");
|
||||
}
|
||||
|
||||
btnGetTiles.innerHTML = '1. Download Tiles';
|
||||
}
|
||||
return _wantToCancel; //determines if a cancel request has been issued
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts an http request to verify if app is online or offline.
|
||||
* Use this in conjunction with the offline checker library: offline.min.js
|
||||
* @param callback
|
||||
*/
|
||||
function verifyOnline(callback){
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("GET", "images/blue-pin.png?" + (Math.floor(Math.random() * 1000000000)), true);
|
||||
req.onload = function()
|
||||
{
|
||||
if( req.status === 200 && req.responseText !== "")
|
||||
{
|
||||
callback(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("verifyOffline failed");
|
||||
callback(false);
|
||||
}
|
||||
};
|
||||
req.onerror = function(e)
|
||||
{
|
||||
console.log("verifyOffline failed: " + e);
|
||||
callback(false);
|
||||
};
|
||||
req.send(null);
|
||||
}
|
||||
|
||||
function panLeft(){
|
||||
map.panLeft();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
</script>
|
||||
|
||||
<!-- Bootstrap core JavaScript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
|
||||
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user