Merge pull request #41 from jabadia/jabadia

jabadia - included save and load tiles to/from csv files
This commit is contained in:
Andy 2014-01-14 08:20:32 -08:00
commit f9df767f48
8 changed files with 307 additions and 327 deletions

View File

@ -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
}
});

View File

@ -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?

View File

@ -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();

View File

@ -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);
}
});
}
}
}
});

View File

@ -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">&times;</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>

View File

@ -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;
}

View File

@ -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">&times;</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">&times;</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">

View File

@ -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()