offline-editor-js/test/secure_tiles_basic_test.html
2015-09-29 18:12:58 -06:00

429 lines
18 KiB
HTML

<!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>