Merge pull request #348 from andygup/gh-pages

Update gh-pages
This commit is contained in:
Andy 2015-05-29 16:04:57 -06:00
commit 8fd3674c41
15 changed files with 138 additions and 42 deletions

View File

@ -1,12 +1,21 @@
# offline-editor-js - Changelog
## Version 2.9.1 - May 28, 2015
No breaking changes.
**Enhancements**
* Initializes internal featureCollectionObject when a layer is extended.
* Added property `OfflineFeaturesManager.ENABLE_FEATURECOLLECTION`. Default value is `false`. When enabled this will
allow the library to automatically create a snapshot of the feature layer.
## Version 2.9 - May 27, 2015
No breaking changes.
**Enhancements**
* Closes #341 - Improved use of keys and indexes in editsStore.js. Minor tweaks at this time.
* Closes #342 - Automates featureCollection management. New method `offlineFeaturesManager.getFeatureCollections()`.
* Closes #327 - Improved use of keys and indexes in editsStore.js. Minor tweaks at this time.
* Closes #342 - Automates featureCollection management. New method `OfflineFeaturesManager.getFeatureCollections()`.
## Version 2.8.2 - May 19, 2015

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/*! offline-editor-js - v2.9.0 - 2015-05-27
/*! offline-editor-js - v2.9.1 - 2015-05-29
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
/*jshint -W030 */
@ -35,6 +35,9 @@ define([
attachmentsStore: null, // indexedDB for storing attachments
proxyPath: null, // by default we use CORS and therefore proxyPath is null
ENABLE_FEATURECOLLECTION: false, // Set this to true for full offline use if you want to use the
// getFeatureCollections() pattern of reconstituting a feature layer.
// Database properties
DB_NAME: "features_store", // Sets the database name.
DB_OBJECTSTORE_NAME: "features",// Represents an object store that allows access to a set of data in the IndexedDB database
@ -1134,7 +1137,13 @@ define([
// We are currently only passing in a single deferred.
all(extendPromises).then(function (r) {
if(r.length === 0){
// DB already initialized
if(r.length === 0 && url){
// Initialize the internal featureLayerCollectionObject
if(this.ENABLE_FEATURECOLLECTION) {
layer._pushFeatureCollections();
}
callback(true, null);
}
else if(r[0].success && !url){
@ -1146,15 +1155,27 @@ define([
if(success) {
this._featureLayers[message.__featureLayerURL] = layer;
layer.url = message.__featureLayerURL;
// Initialize the internal featureLayerCollectionObject
if(this.ENABLE_FEATURECOLLECTION) {
layer._pushFeatureCollections();
}
callback(true, null);
}
else {
console.error("getFeatureLayerJSON() failed.");
// NOTE: We have to have a valid feature layer URL in order to initialize the featureLayerCollectionObject
console.error("getFeatureLayerJSON() failed and unable to create featureLayerCollectionObject.");
callback(false, message);
}
}.bind(this));
}
else if(r[0].success){
// Initialize the internal featureLayerCollectionObject
if(this.ENABLE_FEATURECOLLECTION) {
layer._pushFeatureCollections();
}
callback(true, null);
}
}.bind(this));

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/*! offline-editor-js - v2.9.0 - 2015-05-27
/*! offline-editor-js - v2.9.1 - 2015-05-29
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
define([

View File

@ -1,4 +1,4 @@
/*! offline-editor-js - v2.9.0 - 2015-05-27
/*! offline-editor-js - v2.9.1 - 2015-05-29
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
define(["dojo/query","dojo/request","esri/geometry/Polygon","dojo/_base/declare"],function(a,b,c,d){"use strict";return d("O.esri.Tiles.OfflineTilesEnabler",[],{getBasemapLayer:function(a){var b=a.layerIds[0];return a.getLayer(b)},extend:function(c,d,e){c._tilesCore=new O.esri.Tiles.TilesCore,c._lastTileUrl="",c._imageType="",c._minZoom=null,c._maxZoom=null,c._getTileUrl=c.getTileUrl;var f=!0;return"undefined"!=typeof e&&(f=e),c.offline={online:f,store:new O.esri.Tiles.TilesStore,proxyPath:null},c.offline.store.isSupported()?(c.offline.store.init(function(b){b&&(c.resampling=!1,c.getTileUrl=function(b,d,e){var f=this._getTileUrl(b,d,e);if(this.offline.online)return""==c._imageType&&(c._imageType=this.tileInfo.format.toLowerCase()),c._lastTileUrl=f,f;f=f.split("?")[0];var g="void:/"+b+"/"+d+"/"+e,h=null;return c._tilesCore._getTiles(h,this._imageType,f,g,this.offline.store,a),g},d&&d(!0))}.bind(this)),c.getLevelEstimation=function(a,b,c){var d=new O.esri.Tiles.TilingScheme(this),e=d.getAllCellIdsInExtent(a,b),f={level:b,tileCount:e.length,sizeBytes:e.length*c};return f},c.prepareForOffline=function(a,b,d,e){c._tilesCore._createCellsForOffline(this,a,b,d,function(a){this._doNextTile(0,a,e)}.bind(this))},c.goOffline=function(){this.offline.online=!1},c.goOnline=function(){this.offline.online=!0,this.refresh()},c.isOnline=function(){return this.offline.online},c.deleteAllTiles=function(a){var b=this.offline.store;b.deleteAll(a)},c.getOfflineUsage=function(a){var b=this.offline.store;b.usedSpace(a)},c.getTilePolygons=function(a){c._tilesCore._getTilePolygons(this.offline.store,c.url,this,a)},c.saveToFile=function(a,b){c._tilesCore._saveToFile(a,this.offline.store,b)},c.loadFromFile=function(a,b){c._tilesCore._loadFromFile(a,this.offline.store,b)},c.getMaxZoom=function(a){null==this._maxZoom&&(this._maxZoom=c.tileInfo.lods[c.tileInfo.lods.length-1].level),a(this._maxZoom)},c.getMinZoom=function(a){null==this._minZoom&&(this._minZoom=c.tileInfo.lods[0].level),a(this._minZoom)},c.getMinMaxLOD=function(a,b){var d={},e=c.getMap(),f=e.getLevel()+a,g=e.getLevel()+b;return null!=this._maxZoom&&null!=this._minZoom?(d.max=Math.min(this._maxZoom,g),d.min=Math.max(this._minZoom,f)):(c.getMinZoom(function(a){d.min=Math.max(a,f)}),c.getMaxZoom(function(a){d.max=Math.min(a,g)})),d},c.estimateTileSize=function(a){c._tilesCore._estimateTileSize(b,this._lastTileUrl,this.offline.proxyPath,a)},c.getExtentBuffer=function(a,b){return b.xmin-=a,b.ymin-=a,b.xmax+=a,b.ymax+=a,b},c.getTileUrlsByExtent=function(a,b){var d=new O.esri.Tiles.TilingScheme(c),e=d.getAllCellIdsInExtent(a,b),f=[];return e.forEach(function(a){f.push(c.url+"/"+b+"/"+a[1]+"/"+a[0])}.bind(this)),f},void(c._doNextTile=function(a,b,d){var e=b[a],f=this._getTileUrl(e.level,e.row,e.col);c._tilesCore._storeTile(f,this.offline.proxyPath,this.offline.store,function(c,f){c||(f={cell:e,msg:f});var g=d({countNow:a,countMax:b.length,cell:e,error:f,finishedDownloading:!1});g||a===b.length-1?d({finishedDownloading:!0,cancelRequested:g}):this._doNextTile(a+1,b,d)}.bind(this))})):d(!1,"indexedDB not supported")}})}),"undefined"!=typeof O?O.esri.Tiles={}:(O={},O.esri={Tiles:{}}),O.esri.Tiles.Base64Utils={},O.esri.Tiles.Base64Utils.outputTypes={Base64:0,Hex:1,String:2,Raw:3},O.esri.Tiles.Base64Utils.addWords=function(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c},O.esri.Tiles.Base64Utils.stringToWord=function(a){for(var b=8,c=(1<<b)-1,d=[],e=0,f=a.length*b;f>e;e+=b)d[e>>5]|=(a.charCodeAt(e/b)&c)<<e%32;return d},O.esri.Tiles.Base64Utils.wordToString=function(a){for(var b=8,c=(1<<b)-1,d=[],e=0,f=32*a.length;f>e;e+=b)d.push(String.fromCharCode(a[e>>5]>>>e%32&c));return d.join("")},O.esri.Tiles.Base64Utils.wordToHex=function(a){for(var b="0123456789abcdef",c=[],d=0,e=4*a.length;e>d;d++)c.push(b.charAt(a[d>>2]>>d%4*8+4&15)+b.charAt(a[d>>2]>>d%4*8&15));return c.join("")},O.esri.Tiles.Base64Utils.wordToBase64=function(a){for(var b="=",c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",d=[],e=0,f=4*a.length;f>e;e+=3)for(var g=(a[e>>2]>>8*(e%4)&255)<<16|(a[e+1>>2]>>8*((e+1)%4)&255)<<8|a[e+2>>2]>>8*((e+2)%4)&255,h=0;4>h;h++)d.push(8*e+6*h>32*a.length?b:c.charAt(g>>6*(3-h)&63));return d.join("")},/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */

View File

@ -1,4 +1,4 @@
/*! offline-editor-js - v2.9.0 - 2015-05-27
/*! offline-editor-js - v2.9.1 - 2015-05-29
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
define([

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/*! offline-editor-js - v2.9.0 - 2015-05-27
/*! offline-editor-js - v2.9.1 - 2015-05-29
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
/**

View File

@ -77,44 +77,51 @@ NOTE: You can also monitor standard ArcGIS API for JavaScript layer events using
**Step 4** After the `layers-add-result` event fires extend the feature layer using the `extend()` method.
Optionally, if you are building a fully offline app then you will also need to set the `dataStore` property in the constructor if you want full control of what is stored. You can also access an automatically created data store via the `getFeatureCollections()` method. If you use the `getFeatureCollections()` pattern you can simply ignore the `dataStore` property in the constructor. Here is an example of the Object returned in the `getFeatureCollections()` callback:
Optionally, if you are building a fully offline app then you will also need to set the `dataStore` property in the constructor if you want full control of what is stored. Alternatively, you can access an automatically created data store via the `getFeatureCollections()` method. If you use the `getFeatureCollections()` pattern you can simply ignore the `dataStore` property in the constructor.
```js
{
id: "feature-collection-object-1001",
featureLayerCollections: [
{
featureLayerUrl: "http://...",
featureLayerCollection: { . . . }
}
]
}
```
The `featureLayerCollection` is equivalent to `featureLayer.toJson()`.
The library's internal `featureLayerCollection` is equivalent to `featureLayer.toJson()`.
Note: the `layer.extend()` callback only indicates that the edits database has been successfully initialized.
Here is an example of initializing the library for partial offline use. Note that the `dataStore` property is not set because it's only needed if you need to restart the browser while offline.
```js
function initEditor(evt)
{
offlineFeaturesManager.extend(layer1,function(success, error){
if(success){
console.log("Layer has been extended for offline use.");
}
});
}
```
For full offline use, the pattern would look like this where we are creating a `dataStore`.
```js
function initEditor(evt)
{
// OPTIONAL - for fully offline use you can store a data object
// var options = {};
// options.graphics = JSON.stringify(layer1.toJson());
// options.zoom = map.getZoom();
var dataStore = {};
dataStore.featureLayerJSON = layer1.toJson();
dataStore.zoom = map.getZoom();
offlineFeaturesManager.extend(layer1,function(success, error){
offlineFeaturesManager.extend(layer1,function(success, error){
if(success){
console.log("layer1 has been extended for offline use.");
console.log("Layer has been extended for offline use.");
}
}/*, dataStore */);
}, dataStore);
}
```
When working with fully offline browser restarts you should wait until the layer has been successfully extended before forcing the library to go back online. The workflow for this coding pattern is you start out online > offline > browser restart > then back online.
When working with fully offline browser restarts you should wait until the layer has been successfully extended before forcing the library to go back online. When you force the library to `goOnline()` it will attempt to sync any edits that occurred while offline.
The workflow for this coding pattern is you start out online > offline > browser restart > then back online.
```js
@ -161,7 +168,7 @@ You can then retrieve this data after an offline restart by using the following
offlineFeaturesManager.getFeatureLayerJSONDataStore(function(success, dataStore){
if(success){
myFeatureLayer = new
FeatureLayer(JSON.parse(dataStore.featureLayerCollection),{
FeatureLayer(dataStore.featureLayerJSON,{
mode: FeatureLayer.MODE_SNAPSHOT,
outFields: ["GlobalID","BSID","ROUTES","STOPNAME"]
});
@ -177,7 +184,26 @@ You can then retrieve this data after an offline restart by using the following
```
If you don't want to deal with creating and managing your own data store when working with offline browser restarts, then here's the pattern for using the built-in `featureLayerCollections`. This pattern is ideal if you are using Esri's pre-built widgets such as `AttributeInspector` and you don't have access to the necessary events for creating and updating the `dataStore`.
If you don't want to deal with creating and managing your own data store when working with offline browser restarts, then here's the pattern for using the built-in `featureLayerCollections`. This pattern is ideal if you are using Esri's pre-built widgets such as `AttributeInspector` and you don't have access to the necessary events for creating and updating the `dataStore`.
Once you set `ENABLED_FEATURECOLLECTION` to `true` the library will automatically update its internal snapshot of the feature layer every time an ADD, UPDATE or DELETE is executed while offline.
```js
// Tell the library to automatically create and store a snapshot of the
// of the feature layer.
offlineFeaturesManager.ENABLE_FEATURECOLLECTION = true
offlineFeaturesManager.extend(layer1,function(success, error){
if(success){
console.log("layer1 has been extended for offline use.");
}
});
```
Now you can use this pattern to reconstitute the layer after an offline browser restart:
```js
@ -199,6 +225,22 @@ If you don't want to deal with creating and managing your own data store when wo
```
Here is an example of the Object returned in the `getFeatureCollections()` callback:
```js
{
id: "feature-collection-object-1001",
featureLayerCollections: [
{
featureLayerUrl: "http://...",
featureLayerCollection: { . . . }
}
]
}
```
**Step 5** Once a layer has been extended the offline library will enable it with new methods. Here are a few examples that include code snippets of how to take advantage of some of the library's methods. You can also use a combination of methods from `editsStore` and `offlineFeaturesManager`.
####offlineFeaturesManager.proxyPath

View File

@ -20,6 +20,7 @@ Property | Value | Description
`ATTACHMENTS_DB_OBJECTSTORE_NAME` | "attachments" | (Added @ v2.7) Sets the attachments database object store name.
`proxyPath` | null | Default is `null`. If you are using a Feature Service that is not CORS-enabled then you will need to set this path.
`attachmentsStore` | null | Default is `null`. If you are using attachments, this property gives you access to the associated database.
`ENABLE_FEATURECOLLECTION` | `false` | Enabling this property will allow the library to create a snapshot of the feature layer and make it available via `getFeatureCollections()`. When you extend a layer and you want to use a custom `dataStore` then leave this property set to `false` so that you don't end up with two copies of the feature layer in the database.
###ENUMs
The manager can be in one of these three states (see `getOnlineStatus()` method):

View File

@ -32,6 +32,9 @@ define([
attachmentsStore: null, // indexedDB for storing attachments
proxyPath: null, // by default we use CORS and therefore proxyPath is null
ENABLE_FEATURECOLLECTION: false, // Set this to true for full offline use if you want to use the
// getFeatureCollections() pattern of reconstituting a feature layer.
// Database properties
DB_NAME: "features_store", // Sets the database name.
DB_OBJECTSTORE_NAME: "features",// Represents an object store that allows access to a set of data in the IndexedDB database
@ -1131,7 +1134,13 @@ define([
// We are currently only passing in a single deferred.
all(extendPromises).then(function (r) {
if(r.length === 0){
// DB already initialized
if(r.length === 0 && url){
// Initialize the internal featureLayerCollectionObject
if(this.ENABLE_FEATURECOLLECTION) {
layer._pushFeatureCollections();
}
callback(true, null);
}
else if(r[0].success && !url){
@ -1143,15 +1152,27 @@ define([
if(success) {
this._featureLayers[message.__featureLayerURL] = layer;
layer.url = message.__featureLayerURL;
// Initialize the internal featureLayerCollectionObject
if(this.ENABLE_FEATURECOLLECTION) {
layer._pushFeatureCollections();
}
callback(true, null);
}
else {
console.error("getFeatureLayerJSON() failed.");
// NOTE: We have to have a valid feature layer URL in order to initialize the featureLayerCollectionObject
console.error("getFeatureLayerJSON() failed and unable to create featureLayerCollectionObject.");
callback(false, message);
}
}.bind(this));
}
else if(r[0].success){
// Initialize the internal featureLayerCollectionObject
if(this.ENABLE_FEATURECOLLECTION) {
layer._pushFeatureCollections();
}
callback(true, null);
}
}.bind(this));

View File

@ -1,6 +1,6 @@
{
"name": "offline-editor-js",
"version": "2.9.0",
"version": "2.9.1",
"description": "Lightweight set of libraries for working offline with map tiles and ArcGIS feature services",
"author": "Andy Gup <agup@esri.com> (http://blog.andygup.net)",
"license": "Apache 2",

View File

@ -9,7 +9,7 @@
"appHomePage": "appcache-features.html",
"optimizedApiURL": "../samples/jsolib",
"arcGISBaseURL": "http://js.arcgis.com/3.11",
"version": "2.9.0",
"version": "2.9.1",
"private": true,
"description": "manifest generator project",
"repository": {

View File

@ -103,6 +103,8 @@
options.graphics = JSON.stringify(layer.toJson());
options.zoom = g_map.getZoom();
// WE will use both the featureLayerCollection and dataStore objects for testing purposes
g_offlineFeaturesManager.ENABLE_FEATURECOLLECTION = true;
g_offlineFeaturesManager.extend(layer,function(result){
if(result == false) console.error("WARNING: Unable to initialize database");
},options);