mirror of
https://github.com/Esri/offline-editor-js.git
synced 2025-12-15 15:20:05 +00:00
Merge pull request #41 from jabadia/jabadia
jabadia - included save and load tiles to/from csv files
This commit is contained in:
commit
f9df767f48
@ -13,6 +13,8 @@
|
||||
|
||||
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
|
||||
|
||||
define([],function()
|
||||
{
|
||||
var saveAs = saveAs
|
||||
|| (typeof navigator !== 'undefined' && navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
|
||||
|| (function(view) {
|
||||
@ -229,4 +231,8 @@ var saveAs = saveAs
|
||||
// while `this` is nsIContentFrameMessageManager
|
||||
// with an attribute `content` that corresponds to the window
|
||||
|
||||
if (typeof module !== 'undefined') module.exports = saveAs;
|
||||
//if (typeof module !== 'undefined') module.exports = saveAs;
|
||||
return {
|
||||
saveAs: saveAs
|
||||
}
|
||||
});
|
||||
|
||||
@ -20,7 +20,16 @@
|
||||
- [x] keep on downloading tiles even if one of them fails
|
||||
- [x] add message telling that something failed while initing the indexedDB
|
||||
- [x] update README.md
|
||||
- [x] save/load to/from csv file
|
||||
+ http://www.html5rocks.com/es/tutorials/file/dndfiles/
|
||||
|
||||
- [x] better UI for selecting file to load
|
||||
+ drag & drop (NO)
|
||||
+ test in iPad (save / load) - 'save' seems to work, but no file is stored anywhere, 'load' opens the picture gallery selection :-(
|
||||
|
||||
- [ ] include FileSaver.js and Blob.js as submodules? https://github.com/eligrey/Blob.js and https://github.com/eligrey/FileSaver.js
|
||||
|
||||
- [ ] search for CDN included files and bring them to local
|
||||
- [ ] better tile estimation and limits
|
||||
|
||||
- [ ] allow naming caches?
|
||||
|
||||
@ -161,8 +161,7 @@ define(["tiles/phoneGapConnector"],function(phonegap)
|
||||
* @param callback callbakck(url, img, err)
|
||||
*/
|
||||
this.getAllTiles = function(callback){
|
||||
if(this._db.hasOwnProperty("name"))
|
||||
{
|
||||
if(this._db != null){
|
||||
var transaction = this._db.transaction(["tilepath"])
|
||||
.objectStore("tilepath")
|
||||
.openCursor();
|
||||
|
||||
@ -5,8 +5,9 @@ define([
|
||||
"esri/geometry",
|
||||
"tiles/base64utils",
|
||||
"tiles/dbStore",
|
||||
"tiles/tilingScheme"
|
||||
], function(query, geometry,Base64Utils,DbStore,TilingScheme)
|
||||
"tiles/tilingScheme",
|
||||
"tiles/FileSaver"
|
||||
], function(query, geometry,Base64Utils,DbStore,TilingScheme,FileSaver)
|
||||
{
|
||||
return {
|
||||
/*
|
||||
@ -88,13 +89,6 @@ define([
|
||||
return tileid;
|
||||
};
|
||||
|
||||
layer.estimateTileSize = function()
|
||||
{
|
||||
var tileInfo = this.tileInfo;
|
||||
|
||||
return 14000; // TODO - come up with a more precise estimation method
|
||||
};
|
||||
|
||||
layer.getLevelEstimation = function(extent, level)
|
||||
{
|
||||
var tilingScheme = new TilingScheme(this,geometry);
|
||||
@ -110,7 +104,7 @@ define([
|
||||
return levelEstimation;
|
||||
};
|
||||
|
||||
layer.prepareForOffline = function(minLevel, maxLevel, extent, reportProgress, finishedDownloading)
|
||||
layer.prepareForOffline = function(minLevel, maxLevel, extent, reportProgress)
|
||||
{
|
||||
/* create list of tiles to store */
|
||||
var tilingScheme = new TilingScheme(this,geometry);
|
||||
@ -133,32 +127,9 @@ define([
|
||||
}
|
||||
|
||||
/* launch tile download */
|
||||
this.downloadTile(0, cells, reportProgress, finishedDownloading);
|
||||
this.doNextTile(0, cells, reportProgress);
|
||||
};
|
||||
|
||||
layer.downloadTile = function(i,cells, reportProgress, finishedDownloading)
|
||||
{
|
||||
var cell = cells[i];
|
||||
var cancelRequested = reportProgress({countNow:i, countMax:cells.length});
|
||||
|
||||
this.storeTile(cell.level,cell.row,cell.col, function(success, error)
|
||||
{
|
||||
if(!success)
|
||||
{
|
||||
console.log("error storing tile", cell, error);
|
||||
reportProgress({countNow:i, countMax:cells.length, error: { cell:cell, msg:error}});
|
||||
}
|
||||
|
||||
if( cancelRequested )
|
||||
finishedDownloading(true);
|
||||
else if( i==cells.length-1 )
|
||||
finishedDownloading(false);
|
||||
else
|
||||
this.downloadTile(i+1, cells, reportProgress, finishedDownloading);
|
||||
|
||||
}.bind(this))
|
||||
}
|
||||
|
||||
layer.goOffline = function()
|
||||
{
|
||||
this.offline.online = false;
|
||||
@ -170,6 +141,154 @@ define([
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
layer.deleteAllTiles = function(callback)
|
||||
{
|
||||
var store = this.offline.store;
|
||||
store.deleteAll(callback);
|
||||
}
|
||||
|
||||
layer.getOfflineUsage = function(callback)
|
||||
{
|
||||
var store = this.offline.store;
|
||||
store.size(callback);
|
||||
};
|
||||
|
||||
layer.getTilePolygons = function(callback)
|
||||
{
|
||||
var store = this.offline.store;
|
||||
var tilingScheme = new TilingScheme(this,geometry);
|
||||
store.getAllTiles(function(url,img,err)
|
||||
{
|
||||
if(url)
|
||||
{
|
||||
var components = url.split("/");
|
||||
var level = parseInt(components[ components.length - 3]);
|
||||
var col = parseInt(components[ components.length - 2]);
|
||||
var row = parseInt(components[ components.length - 1]);
|
||||
var cellId = [row,col];
|
||||
var polygon = tilingScheme.getCellPolygonFromCellId(cellId, level);
|
||||
//if( level == 15)
|
||||
callback(polygon);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(null,err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
layer.saveToFile = function(fileName, callback)
|
||||
{
|
||||
var store = this.offline.store;
|
||||
var csv = [];
|
||||
|
||||
csv.push("url,img");
|
||||
store.getAllTiles(function(url,img,evt)
|
||||
{
|
||||
if(evt=="end")
|
||||
{
|
||||
var blob = new Blob([ csv.join("\r\n") ], {type:"text/plain;charset=utf-8"});
|
||||
var saver = FileSaver.saveAs(blob, fileName);
|
||||
|
||||
if( saver.readyState == saver.DONE )
|
||||
{
|
||||
if( saver.error )
|
||||
return callback(false,"Error saving file " + fileName);
|
||||
else
|
||||
return callback(true, "Saved " + (csv.length-1) + " tiles (" + Math.floor(blob.size / 1024 / 1024 * 100) / 100 + " Mb) into " + fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
saver.onerror = function(evt) {
|
||||
callback(false,"Error saving file " + fileName);
|
||||
}
|
||||
saver.onwriteend = function(evt)
|
||||
{
|
||||
callback(true, "Saved " + (csv.length-1) + " tiles (" + Math.floor(blob.size / 1024 / 1024 * 100) / 100 + " Mb) into " + fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
csv.push(url+","+img);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
layer.loadFromFile = function(file, callback)
|
||||
{
|
||||
var store = this.offline.store;
|
||||
|
||||
if (window.File && window.FileReader && window.FileList && window.Blob)
|
||||
{
|
||||
// Great success! All the File APIs are supported.
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(evt)
|
||||
{
|
||||
var csvContent = evt.target.result;
|
||||
var tiles = csvContent.split("\r\n");
|
||||
var tileCount = 0;
|
||||
|
||||
if(tiles[0] != "url,img")
|
||||
return callback(false, "File " + file.name + " doesn't contain tiles that can be loaded");
|
||||
|
||||
for(var i=1; i<tiles.length; i++)
|
||||
{
|
||||
var pair = tiles[i].split(',');
|
||||
var tile = {
|
||||
url: pair[0],
|
||||
img: pair[1]
|
||||
}
|
||||
store.add(tile,function(success)
|
||||
{
|
||||
if( success )
|
||||
tileCount += 1;
|
||||
|
||||
if( tileCount == tiles.length-1)
|
||||
callback(true, tileCount + " tiles loaded from " + file.name);
|
||||
});
|
||||
}
|
||||
}
|
||||
reader.readAsText(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(false, 'The File APIs are not fully supported in this browser.');
|
||||
}
|
||||
}
|
||||
|
||||
/* internal methods */
|
||||
|
||||
layer.estimateTileSize = function()
|
||||
{
|
||||
var tileInfo = this.tileInfo;
|
||||
|
||||
return 14000; // TODO - come up with a more precise estimation method
|
||||
};
|
||||
|
||||
layer.doNextTile = function(i,cells, reportProgress)
|
||||
{
|
||||
var cell = cells[i];
|
||||
var error;
|
||||
|
||||
this.storeTile(cell.level,cell.row,cell.col, function(success, error)
|
||||
{
|
||||
if(!success)
|
||||
{
|
||||
console.log("error storing tile", cell, error);
|
||||
error = { cell:cell, msg:error};
|
||||
}
|
||||
|
||||
var cancelRequested = reportProgress({countNow:i, countMax:cells.length, error: error, finishedDownloading:false});
|
||||
|
||||
if( cancelRequested || i==cells.length-1 )
|
||||
reportProgress({ finishedDownloading: true, cancelRequested: cancelRequested})
|
||||
else
|
||||
this.doNextTile(i+1, cells, reportProgress);
|
||||
|
||||
}.bind(this))
|
||||
}
|
||||
|
||||
layer.storeTile = function(level,row,col,callback)
|
||||
{
|
||||
var store = this.offline.store;
|
||||
@ -208,42 +327,6 @@ define([
|
||||
}
|
||||
req.send(null);
|
||||
};
|
||||
|
||||
layer.deleteAllTiles = function(callback)
|
||||
{
|
||||
var store = this.offline.store;
|
||||
store.deleteAll(callback);
|
||||
}
|
||||
|
||||
layer.getOfflineUsage = function(callback)
|
||||
{
|
||||
var store = this.offline.store;
|
||||
store.size(callback);
|
||||
};
|
||||
|
||||
layer.getTilePolygons = function(callback)
|
||||
{
|
||||
var store = this.offline.store;
|
||||
var tilingScheme = new TilingScheme(this,geometry);
|
||||
store.getAllTiles(function(url,img,err)
|
||||
{
|
||||
if(url)
|
||||
{
|
||||
var components = url.split("/");
|
||||
var level = parseInt(components[ components.length - 3]);
|
||||
var col = parseInt(components[ components.length - 2]);
|
||||
var row = parseInt(components[ components.length - 1]);
|
||||
var cellId = [row,col];
|
||||
var polygon = tilingScheme.getCellPolygonFromCellId(cellId, level);
|
||||
//if( level == 15)
|
||||
callback(polygon);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(null,err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,203 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<link rel="shortcut icon" href="../vendor/bootstrap-map-js/bootstrap_v3/docs-assets/ico/favicon.png">
|
||||
|
||||
<link rel="stylesheet" href="//js.arcgis.com/3.7/js/esri/css/esri.css">
|
||||
|
||||
<link rel="stylesheet" href="../vendor/bootstrap-map-js/bootstrap_v3/dist/css/bootstrap.css" >
|
||||
<link rel="stylesheet" href="../vendor/bootstrap-map-js/src/css/bootstrapmap.css">
|
||||
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" >
|
||||
<link rel="stylesheet" href="./tiles/offlineProbe.css" >
|
||||
<link rel="stylesheet" href="./tiles/tiles-indexed-db.css" >
|
||||
|
||||
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../vendor/bootstrap-map-js/bootstrap_v3/docs-assets/js/html5shiv.js"></script>
|
||||
<script src="../vendor/bootstrap-map-js/bootstrap_v3/docs-assets/js/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<title>Offline</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="http://github.com/Esri/offline-editor-js"><i class="fa fa-html5"></i> JS Offline Mapping</s>
|
||||
<a class="navbar-brand" href="http://developers.arcgis.com"><i class="fa fa-globe"></i> esri</a>
|
||||
</div>
|
||||
<!--
|
||||
<div class="collapse navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#">Home</a></li>
|
||||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
--><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12" id="error-div">
|
||||
<div class="alert alert-danger">
|
||||
<a class="close" data-dismiss="alert">×</a>
|
||||
<i class="fa fa-info-circle"></i><strong></strong> <span id="error-msg">Change a few things up and try submitting again..</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<h3>Map: <span id="mapTitle">[none]</span></h3>
|
||||
<p id="mapDescription">[none]</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<form role="form">
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="minLevel">Min Zoom Level</label>
|
||||
<input type="number" id="minLevel" name"minLevel" class="form-control" value=1 min=0 max=19>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="currentLevel">Current Zoom Level</label>
|
||||
<input type="number" id="currentLevel" name"currentLevel" class="form-control" value=19 min=0 max=19>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="maxLevel">Max Zoom Level</label>
|
||||
<input type="number" id="maxLevel" name"maxLevel" class="form-control" value=19 min=0 max=19>
|
||||
</div>
|
||||
</form>
|
||||
<table id="tile-count-table" class="table table-striped table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Level</th>
|
||||
<th>Tile Count</th>
|
||||
<th>Size Mb (aprox.)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tile-count-table-body">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<!-- Bootstrap-map-js -->
|
||||
<div id="mapDiv"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div id="ready-to-download-ui">
|
||||
<div class="col-xs-12">
|
||||
<button id="prepare-for-offline-btn" type="button" class="btn btn-primary"><i class="glyphicon glyphicon-cloud-download"></i> Prepare for Offline</button>
|
||||
<button id="delete-all-tiles-btn" type="button" class="btn btn-danger"><i class="glyphicon glyphicon-floppy-remove"></i> Delete All Tiles</button>
|
||||
<button id="go-offline-btn" type="button" class="btn btn-default"><i class="fa fa-chain-broken"></i> Go Offline</button>
|
||||
<button id="go-online-btn" type="button" class="btn btn-default" disabled="disabled"><i class="fa fa-link"></i> Go Online</button>
|
||||
<button id="update-offline-usage" type="button" class="btn btn-default"><i class="fa fa-refresh"></i> Usage: <span id="offline-usage">[click to update]</span></button>
|
||||
<button id="show-stored-tiles" type="button" class="btn btn-default"><i class="fa fa-th"></i> <span id="show-stored-tiles-caption">Show Stored Tiles</span></button>
|
||||
<button id="save-file" type="button" onclick="saveFile()" class="btn btn-default"><i class="glyphicon glyphicon-folder-open"></i> <span id="save-file-caption"> Save to File</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="downloading-ui">
|
||||
<div class="col-xs-1">
|
||||
<button id="cancel-btn" type="button" class="btn btn-warning"><i class="glyphicon glyphicon-remove"></i> Cancel</button>
|
||||
</div>
|
||||
<div id="download-progress" class="col-xs-10">
|
||||
<div class="progress progress-striped active">
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" style="width:0%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="remaining-time" class="col-xs-1">__:__</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-4">
|
||||
<div class="well lead step-1"><i class="fa fa-arrows"></i> 1. Navigate to your area of interest</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-4">
|
||||
<div class="well lead step-2"><i class="glyphicon glyphicon-cloud-download"></i> 2. Click 'Prepare for Offline' button</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-4">
|
||||
<div class="well lead step-3"><i class="fa fa-chain-broken"></i> 3. Go Offline and enjoy!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div><!-- /.container -->
|
||||
|
||||
<script>
|
||||
var locationPath = location.pathname.replace(/\/[^/]+$/, "");
|
||||
var dojoConfig = {
|
||||
paths: {
|
||||
tiles: locationPath + "/../lib/tiles",
|
||||
vendor: locationPath + "/../vendor"
|
||||
}
|
||||
}
|
||||
window.proxyPath = "../lib/proxy.php";
|
||||
</script>
|
||||
|
||||
<script src="//js.arcgis.com/3.7compact"></script>
|
||||
<script src="../vendor/offline/offline.min.js"></script>
|
||||
<script src="../vendor/IndexedDBShim/dist/IndexedDBShim.min.js"></script>
|
||||
<script src="./tiles/offlineProbe.js"></script>
|
||||
<script src="./tiles/tiles-indexed-db.js"></script>
|
||||
<!-- really should use AMD loading -->
|
||||
<script src="../lib/tiles/FileSaver.js"></script>
|
||||
<script src="../lib/tiles/Blob.js"></script>
|
||||
<!-- -->
|
||||
<script>
|
||||
function saveFile(){
|
||||
require(["tiles/dbStore"],function(DBStore)
|
||||
{
|
||||
console.log('test')
|
||||
var db = new DBStore();
|
||||
db.init(function(result,val){
|
||||
console.log(result + ", " + val)
|
||||
|
||||
var csv = "url,img,\r\n";
|
||||
|
||||
if(result == true){
|
||||
db.getAllTiles(function(url,img,evt){
|
||||
// console.log(url + ", " + img);
|
||||
csv+= url + "," +img+"\r\n";
|
||||
|
||||
if(evt == "end"){
|
||||
console.log(csv)
|
||||
var blob = new Blob([csv], {type: "text/plain;charset=utf-8"});
|
||||
saveAs(blob, "tiles.csv");
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Bootstrap core JavaScript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<!--
|
||||
<script src="../vendor/bootstrap-map-js/bootstrap_v3/docs-assets/js/jquery.js"></script>
|
||||
<script src="../vendor/bootstrap-map-js/bootstrap_v3/dist/js/bootstrap.min.js"></script>
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@ -27,7 +27,40 @@ body > .container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#ready-to-download-ui, #downloading-ui {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#ready-to-download-ui .btn
|
||||
{
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#error-div {
|
||||
margin-top: 10px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.alert {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
#load-file {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#load-file input[type=file] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
font-size: 999px;
|
||||
text-align: right;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
background: red;
|
||||
cursor: inherit;
|
||||
display: block;
|
||||
}
|
||||
@ -51,14 +51,6 @@
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12" id="error-div">
|
||||
<div class="alert alert-danger">
|
||||
<a class="close" data-dismiss="alert">×</a>
|
||||
<i class="fa fa-info-circle"></i><strong></strong> <span id="error-msg">Change a few things up and try submitting again..</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
</div>
|
||||
@ -108,9 +100,11 @@
|
||||
<button id="prepare-for-offline-btn" type="button" class="btn btn-primary"><i class="glyphicon glyphicon-cloud-download"></i> Prepare for Offline</button>
|
||||
<button id="delete-all-tiles-btn" type="button" class="btn btn-danger"><i class="glyphicon glyphicon-floppy-remove"></i> Delete All Tiles</button>
|
||||
<button id="go-offline-btn" type="button" class="btn btn-default"><i class="fa fa-chain-broken"></i> Go Offline</button>
|
||||
<button id="go-online-btn" type="button" class="btn btn-default" disabled="disabled"><i class="fa fa-link"></i> Go Online</button>
|
||||
<button id="go-online-btn" type="button" class="btn btn-default" disabled="disabled" style="display:none;"><i class="fa fa-link"></i> Go Online</button>
|
||||
<button id="update-offline-usage" type="button" class="btn btn-default"><i class="fa fa-refresh"></i> Usage: <span id="offline-usage">[click to update]</span></button>
|
||||
<button id="show-stored-tiles" type="button" class="btn btn-default"><i class="fa fa-th"></i> <span id="show-stored-tiles-caption">Show Stored Tiles</span></button>
|
||||
<button id="save-file" type="button" class="btn btn-default"><i class="fa fa-download"></i> Save to File</button>
|
||||
<span id="load-file" type="button" class="btn btn-default"><i class="fa fa-upload"></i> Load from File <input type="file" id="file-select" name="file-select"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="downloading-ui">
|
||||
@ -126,6 +120,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12" id="error-div">
|
||||
<div class="alert alert-danger">
|
||||
<a class="close" data-dismiss="alert">×</a>
|
||||
<i class="fa fa-info-circle"></i><strong></strong> <span id="error-msg">Change a few things up and try submitting again..</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
|
||||
@ -129,6 +129,9 @@ require(["esri/map",
|
||||
on(dojo.byId('go-online-btn'),'click', goOnline);
|
||||
on(dojo.byId('update-offline-usage'),'click', updateOfflineUsage);
|
||||
on(dojo.byId('show-stored-tiles'),'click', toggleShowStoredTiles);
|
||||
on(dojo.byId('save-file'),'click', saveToFile);
|
||||
on(dojo.byId('file-select'),'change', loadFromFile);
|
||||
dojo.byId('go-online-btn').style.display = "none";
|
||||
esri.show(dojo.byId('ready-to-download-ui'));
|
||||
esri.hide(dojo.byId('downloading-ui'));
|
||||
updateOfflineUsage();
|
||||
@ -140,6 +143,7 @@ require(["esri/map",
|
||||
dojo.byId('delete-all-tiles-btn').disabled = true;
|
||||
dojo.byId('go-offline-btn').disabled = true;
|
||||
dojo.byId('go-online-btn').disabled = true;
|
||||
esri.hide(dojo.byId('go-online-btn'));
|
||||
dojo.byId('update-offline-usage').disabled = true;
|
||||
dojo.byId('show-stored-tiles').disabled = true;
|
||||
esri.hide(dojo.byId('downloading-ui'));
|
||||
@ -216,6 +220,8 @@ require(["esri/map",
|
||||
{
|
||||
dojo.byId('go-offline-btn').disabled = true;
|
||||
dojo.byId('go-online-btn').disabled = undefined;
|
||||
dojo.byId('go-offline-btn').style.display = "none";
|
||||
dojo.byId('go-online-btn').style.display = "";
|
||||
|
||||
basemapLayer.goOffline();
|
||||
}
|
||||
@ -224,6 +230,8 @@ require(["esri/map",
|
||||
{
|
||||
dojo.byId('go-offline-btn').disabled = undefined;
|
||||
dojo.byId('go-online-btn').disabled = true;
|
||||
dojo.byId('go-offline-btn').style.display = "";
|
||||
dojo.byId('go-online-btn').style.display = "none";
|
||||
|
||||
basemapLayer.goOnline();
|
||||
}
|
||||
@ -239,7 +247,11 @@ require(["esri/map",
|
||||
else
|
||||
showAlert("alert-danger", "Can't delete tiles: " + err);
|
||||
|
||||
setTimeout(updateOfflineUsage,0); // request execution in the next turn of the event loop
|
||||
setTimeout(function()
|
||||
{
|
||||
updateOfflineUsage();
|
||||
showStoredTiles(showTiles);
|
||||
},0); // request execution in the next turn of the event loop
|
||||
});
|
||||
}
|
||||
|
||||
@ -260,7 +272,7 @@ require(["esri/map",
|
||||
/* launch offline preparation process */
|
||||
var minLevel = parseInt(dojo.byId('minLevel').value);
|
||||
var maxLevel = parseInt(dojo.byId('maxLevel').value);
|
||||
basemapLayer.prepareForOffline(minLevel, maxLevel, map.extent, reportProgress, finishedDownloading);
|
||||
basemapLayer.prepareForOffline(minLevel, maxLevel, map.extent, reportProgress);
|
||||
}
|
||||
|
||||
function cancel()
|
||||
@ -270,50 +282,56 @@ require(["esri/map",
|
||||
|
||||
function reportProgress(progress)
|
||||
{
|
||||
var pbar = query('#download-progress [role=progressbar]')[0];
|
||||
var percent = progress.countMax? (progress.countNow / progress.countMax * 100) : 0;
|
||||
pbar.style.width = percent+"%";
|
||||
|
||||
if( progress.error )
|
||||
if( progress.finishedDownloading )
|
||||
{
|
||||
query('#download-progress [role=progressbar]')
|
||||
.removeClass('progress-bar-success')
|
||||
.addClass('progress-bar-warning');
|
||||
if( progress.cancelRequested )
|
||||
showAlert('alert-warning', 'Cancelled');
|
||||
else if (errorList.length == 0)
|
||||
showAlert('alert-success', 'All tiles downloaded and stored');
|
||||
else
|
||||
showAlert('alert-warning', "Finished downloading tiles, " + errorList.length + " tiles couldn't be downloaded");
|
||||
|
||||
errorList.push(progress.error.msg);
|
||||
|
||||
showAlert('alert-warning', progress.error.msg);
|
||||
setTimeout(function()
|
||||
{
|
||||
esri.show(dojo.byId('ready-to-download-ui'));
|
||||
esri.hide(dojo.byId('downloading-ui'));
|
||||
updateOfflineUsage();
|
||||
showStoredTiles(showTiles);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
if( progress.countNow > 5 )
|
||||
{
|
||||
var currentTime = new Date();
|
||||
var elapsedTime = currentTime - startTime;
|
||||
var remainingTime = (elapsedTime / progress.countNow) * (progress.countMax - progress.countNow);
|
||||
var sec = 1 + Math.floor(remainingTime / 1000);
|
||||
var min = Math.floor(sec / 60);
|
||||
sec -= (min * 60);
|
||||
dojo.byId('remaining-time').innerHTML = ((min<10)? "0" + min : min) + ":" + ((sec<10)? "0" + sec : sec);
|
||||
}
|
||||
return cancelRequested;
|
||||
}
|
||||
|
||||
function finishedDownloading(cancelled)
|
||||
{
|
||||
if( cancelled )
|
||||
showAlert('alert-warning', 'Cancelled');
|
||||
else if (errorList.length == 0)
|
||||
showAlert('alert-success', 'All tiles downloaded and stored');
|
||||
else
|
||||
showAlert('alert-warning', "Finished downloading tiles, " + errorList.length + " tiles couldn't be downloaded");
|
||||
{
|
||||
// progress bar
|
||||
var pbar = query('#download-progress [role=progressbar]')[0];
|
||||
var percent = progress.countMax? (progress.countNow / progress.countMax * 100) : 0;
|
||||
pbar.style.width = percent+"%";
|
||||
|
||||
setTimeout(function()
|
||||
{
|
||||
esri.show(dojo.byId('ready-to-download-ui'));
|
||||
esri.hide(dojo.byId('downloading-ui'));
|
||||
updateOfflineUsage();
|
||||
showStoredTiles(showTiles);
|
||||
}, 1000);
|
||||
// any errors?
|
||||
if( progress.error )
|
||||
{
|
||||
query('#download-progress [role=progressbar]')
|
||||
.removeClass('progress-bar-success')
|
||||
.addClass('progress-bar-warning');
|
||||
|
||||
errorList.push(progress.error.msg);
|
||||
|
||||
showAlert('alert-warning', progress.error.msg);
|
||||
}
|
||||
|
||||
// remaining time
|
||||
if( progress.countNow > 5 )
|
||||
{
|
||||
var currentTime = new Date();
|
||||
var elapsedTime = currentTime - startTime;
|
||||
var remainingTime = (elapsedTime / progress.countNow) * (progress.countMax - progress.countNow);
|
||||
var sec = 1 + Math.floor(remainingTime / 1000);
|
||||
var min = Math.floor(sec / 60);
|
||||
sec -= (min * 60);
|
||||
dojo.byId('remaining-time').innerHTML = ((min<10)? "0" + min : min) + ":" + ((sec<10)? "0" + sec : sec);
|
||||
}
|
||||
|
||||
return cancelRequested;
|
||||
}
|
||||
}
|
||||
|
||||
function toggleShowStoredTiles()
|
||||
@ -344,6 +362,39 @@ require(["esri/map",
|
||||
}
|
||||
}
|
||||
|
||||
function saveToFile()
|
||||
{
|
||||
basemapLayer.saveToFile("tiles.csv", function(success,msg)
|
||||
{
|
||||
if(success)
|
||||
showAlert('alert-success',msg);
|
||||
else
|
||||
showAlert('alert-danger',msg);
|
||||
});
|
||||
}
|
||||
|
||||
function loadFromFile()
|
||||
{
|
||||
var selectedFile = dojo.byId('file-select').files[0];
|
||||
|
||||
if( !selectedFile )
|
||||
{
|
||||
showAlert('alert-warning',"Please, select one file");
|
||||
return;
|
||||
}
|
||||
|
||||
basemapLayer.loadFromFile(selectedFile, function(success,msg)
|
||||
{
|
||||
if(success)
|
||||
showAlert('alert-success',msg);
|
||||
else
|
||||
showAlert('alert-danger',msg);
|
||||
|
||||
updateOfflineUsage();
|
||||
showStoredTiles(showTiles);
|
||||
});
|
||||
}
|
||||
|
||||
function showAlert(type, msg)
|
||||
{
|
||||
var icon = "";
|
||||
@ -366,7 +417,6 @@ require(["esri/map",
|
||||
.removeClass('fa-info-circle')
|
||||
.addClass(icon);
|
||||
esri.show(dojo.byId('error-div'));
|
||||
window.scrollTo(0,0);
|
||||
}
|
||||
|
||||
function hideAlert()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user