[OpenLayers-Commits] r10944 - in sandbox/august/trunk:
lib/OpenLayers/Protocol
lib/OpenLayers/Protocol/AgsFeatureAccess playground
playground/ags tests/Format
commits-20090109 at openlayers.org
commits-20090109 at openlayers.org
Fri Dec 3 01:58:49 EST 2010
Author: augusttown
Date: 2010-12-02 22:58:49 -0800 (Thu, 02 Dec 2010)
New Revision: 10944
Added:
sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess.js
sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess/
sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess/v2.js
sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess/v2_0.js
sandbox/august/trunk/playground/ags/
sandbox/august/trunk/playground/ags/agsfeatureaccess.html
sandbox/august/trunk/playground/ags/agsfeatureaccess.js
sandbox/august/trunk/tests/Format/AgsJsAdapter_Renderer.html
sandbox/august/trunk/tests/Format/AgsJsAdapter_Renderer.js
Log:
Add and update ArcGIS Server Feature Service (Feature Access) support.
Added: sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess/v2.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess/v2.js (rev 0)
+++ sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess/v2.js 2010-12-03 06:58:49 UTC (rev 10944)
@@ -0,0 +1,486 @@
+/**
+ * @requires OpenLayers/Protocol/AgsFeatureAccess.js
+ * @requires OpenLayers/Format/AgsJsAdapter.js
+ */
+
+/**
+ * Class: OpenLayers.Protocol.AgsFeatureAccess.v2
+ * Abstract class for for v2.0 or above protocol.
+ *
+ * Inherits from:
+ * - <OpenLayers.Protocol>
+ */
+OpenLayers.Protocol.AgsFeatureAccess.v2 = OpenLayers.Class(OpenLayers.Protocol, {
+
+ /**
+ * Property: version
+ * {String} AgsFeatureAccess ArcGIS JavaScript API version number.
+ */
+ version: null,
+
+ /**
+ * Property: srsName
+ * {String} Name of spatial reference system. Default is "EPSG:4326".
+ */
+ srsName: "EPSG:4326",
+
+ /**
+ * Property: format
+ * {Object} the format used to parse information from features service
+ */
+ format: null,
+
+ /**
+ * Property: formatOptions
+ * {Object} Optional options for the format. If a format is not provided,
+ * this property can be used to extend the default format options.
+ */
+ formatOptions: null,
+
+ /**
+ * Property: agsFeatureLayer
+ *
+ *
+ */
+ agsFeatureLayer: null,
+
+ /**
+ *
+ */
+ isAgsFeatureLayerLoaded: false,
+
+ /**
+ * Property: query
+ * {Object} query option used to generate esri.tasks.Query
+ */
+ _query: null,
+
+ /**
+ * Property: defaultQuery
+ * {Object} default query option used to generate esri.tasks.Query
+ */
+ defaultQuery: {
+ outFields: [ "*" ], // meaning all fields? didn't find it in JS API doc though
+ returnGeometry: true,
+ where: "",
+ outSpatialReference: this.srsName
+ // TODO: more default query option
+ },
+
+ /**
+ * Property: style
+ * {OpenLayers.Style}
+ *
+ * Style converted from ArcGIS Server Feature Service layer's renderer
+ */
+ style: null,
+
+ /**
+ *
+ */
+ templates: null,
+
+ /**
+ *
+ */
+ currentFeatureTemplate: null,
+
+ /**
+ *
+ */
+ layer: null,
+
+ // TODO: feature template for inserting new features
+
+ /**
+ * Constructor: OpenLayers.Protocol.AgsFeatureAccess.v2
+ * A class for AgsFeatureAccess protocol.
+ *
+ * Parameters:
+ * options - {Object} Optional object whose properties will be set on the
+ * instance.
+ *
+ * Valid options properties:
+ * url - {String} URL of ArcGIS Server Feature Service resource (required).
+ *
+ */
+ initialize: function(options) {
+ OpenLayers.Protocol.prototype.initialize.apply(this, [options]);
+ if(!this.format) {
+ // initialize parser/encoder format if not provided
+ this.format = new OpenLayers.Format.AgsJsAdapter();
+ }
+ if(this.url!=null && this.url!="") {
+ // create an esri.layers.FeatureLayer to access features and do editing
+ this.agsFeatureLayer = new esri.layers.FeatureLayer(
+ this.url,
+ {} // many options are only applicable when using feature layer in JS API
+ );
+ // creating feature layer is asynchronous, "onLoad" event fires when properties are loaded
+ dojo.connect(
+ this.agsFeatureLayer,
+ "onLoad",
+ this,
+ function(layer){
+ OpenLayers.Console.debug("...feature layer loaded successfully...");
+ this.isAgsFeatureLayerLoaded = true;
+ // parse ArcGIS JS API renderer and create OpenLayers.Style out of it.
+ var agsRendererType = layer.renderer.declaredClass; // is 'declaredClass' a standard way to tell a class type or is it just esri thing
+ // agsRendererType can only be one of the following three: esri.renderer.SimpleRenderer, esri.renderer.ClassBreaksRenderer, or esri.renderer.UniqueValueRenderer
+ var agsRendererParserType = agsRendererType.split(".")[2];
+ this.style = this.format.parseAgsRenderer[agsRendererParserType].apply(this.format, [layer.renderer]);
+ OpenLayers.Console.debug("...feature layer renderer parsed successfully...");
+ // TODO: feature layer metadata has both 'templates' and 'types', so which should be used for template based editing?
+ // I think 'templates', but by default it is empty, shall I instead use 'types'?
+ // e.g. http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0?f=json
+ // "templates" is null, but "types" has all templates, why???
+ this.templates = this.format.parseAgsFeatureTypes.apply(this.format, [layer.types]);
+ OpenLayers.Console.debug("...feature layer feature types parsed successfully...");
+
+ this.currentFeatureTemplate = this.templates[0]; //use the first template as default; user can change it through setCurrentFeatureTemplate()
+ // this is for template based feature editing
+ // DrawFeature trigger this event right before a feature is inserted
+ // if manually insert feature then you have to call this.applyCurrentFeatureTemplate(feature) yourself before adding feature to layer
+ if(this.currentFeatureTemplate) {
+ var applyTemplateFunc = function(obj) { // obj is usually an event {feature:feature}
+ var feature = obj.feature || obj;
+ this.applyCurrentFeatureTemplate(feature);
+ };
+ this.layer.events.on({
+ 'sketchcomplete': applyTemplateFunc,
+ scope: this
+ });
+ }
+ }
+ );
+ } else {
+ OpenLayers.Console.error("...fail to initialize OpenLayers.Protocol.AgsFeatureAccess.v2...invalid or null url...");
+ throw "...fail to initialize OpenLayers.Protocol.AgsFeatureAccess.v2...invalid or null url...";
+ }
+ if(options.query) {
+ this._query = OpenLayers.Util.extend(
+ this.defaultQuery,
+ options.query
+ );
+ }
+ // anything else to do?
+ },
+
+ /**
+ * APIMethod: destroy
+ * Clean up the protocol.
+ */
+ destroy: function() {
+ if(this.options && !this.options.format) {
+ this.format.destroy();
+ }
+ this.format = null;
+ OpenLayers.Protocol.prototype.destroy.apply(this);
+ },
+
+ /**
+ * Method: read
+ * Rely on FeatureLayer of ArcGIS JS API for reading new features.
+ */
+ read: function(options) {
+ OpenLayers.Protocol.prototype.read.apply(this, arguments);
+ options = OpenLayers.Util.extend({}, options);
+ OpenLayers.Util.applyDefaults(options, this.options || {});
+
+ /*
+ * usually a strategy like BBOX or Fixed call read() with following options
+ * filter - {OpenLayers.Filter}
+ * callback - {function}
+ * scope - {object}
+ */
+ if(options.filter instanceof OpenLayers.Filter.Spatial) {
+ // set 'geometry' and 'spatialRelationship' in this.query
+ if(options.filter.type == OpenLayers.Filter.Spatial.BBOX) { // BBOX filter
+ var bbox = options.filter.value;
+ this._query.geometry = bbox;
+ this._query.spatialRelationship = 'INTERSECTS';
+ } else { // other spatial filters
+ // TODO: to be implemented
+ }
+ } else if(options.filter instanceof OpenLayers.Filter.FeatureId) {
+ // simple case: set 'where' in this.query
+ // TODO: to be implemented
+ } else if(options.filter instanceof OpenLayers.Filter.Comparison) {
+ // simple case: set 'where' in this.query
+ // TODO: to be implemented
+ } else {
+ // TODO: compound filter case
+ // TODO: need a format to convert filter object to a where clause
+ }
+
+ // a spatial query can be translated to a geometry plus a spatial relationship in esri.tasks.Query
+ var agsQuery = this.format.encodeAgsQuery.apply(this.format, [this._query]);
+ // important!!!
+ options['parser'] = this.format; // include this.format so it can be called within the single callback with other scope
+ options['layer'] = this.layer; // include this.layer so you can set style on layer
+ if(this.style && this.style instanceof OpenLayers.Style) {
+ options['style'] = this.style;
+ }
+ // call queryFeatures on this.agsFeatureLayer
+ if(this.isAgsFeatureLayerLoaded == true) {
+ this.agsFeatureLayer.queryFeatures(
+ agsQuery,
+ OpenLayers.Util.AgsUtil.createSingleCallback(
+ [this.handleRead],
+ options,
+ options.scope
+ ),
+ this.handleError
+ );
+ } else {
+ OpenLayers.Console.warn("...features not loaded...");
+ OpenLayers.Console.warn("...this.agsFeatureLayer feature layer is not loaded yet...try query feature later...");
+ }
+ },
+
+ /**
+ * Method: handleRead
+ * Deal with response from the read request.
+ *
+ * Parameters:
+ * response - {<esri.tasks.FeatureSet>} the response featureSet passed back by esri.layers.FeatureLayer.
+ * options - {Object} The user options passed to the read call.
+ */
+ handleRead: function(response, options) {
+ if(options.callback) {
+ // parseFeatures from response {<esri.tasks.FeatureSet>}
+ // call options.callback with OpenLayers features as input
+ var olFeatures = options.parser.parseAgsResults['featureSet'].apply(options.parser, [response]);
+ // for each feature create the plain style hash object based this.style (OpenLayers.Style generated out of feature layer renderer)
+ if(options['style']) {
+ if(options['layer']) {
+ options['layer'].styleMap = new OpenLayers.StyleMap(
+ {
+ // TODO: document here how missing 'select' and 'temporary' ends up with a surprisingly good effect on picture marker symbol
+ 'default': options['style'],
+ //'select': new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"]), // TODO: create 'select' style based on default style
+ //'temporary': new OpenLayers.Style(OpenLayers.Feature.Vector.style["temporary"]), // TODO: create 'temporary' style based on default style
+ //'delete': new OpenLayers.Style(OpenLayers.Feature.Vector.style["delete"]), // TODO: create 'delete' style based on default style
+ },
+ {}
+ );
+ } else {
+ for(var i=0; i<olFeatures.length; i++) {
+ //olFeatures[i].style = options['style'].createSymbolizer(olFeatures[i]);
+ }
+ }
+ }
+ options.callback.call(options.scope, {features: olFeatures});
+ }
+ },
+
+ /**
+ * Method: commit
+ * Given a list of feature, assemble a batch request for update, create,
+ * and delete transactions. Rely on ArcGIS JS API to commit the changes back to server
+ * under the hood calling applyEdits(adds?, updates?, deletes?, callback?, errback?) of esri.layers.FeatureLayer
+ *
+ * Parameters:
+ * features - {Array(<OpenLayers.Feature.Vector>}
+ *
+ * Returns:
+ * dojo.Deferred as ArcGIS JS API does
+ */
+ commit: function(features, options) {
+ var deferred = null;
+ options = OpenLayers.Util.extend({}, options);
+ OpenLayers.Util.applyDefaults(options, this.options);
+ //OpenLayers.Console.debug("...commit local changes to server...");
+ var featuresToEdit = [];
+ var featuresToAdd = [];
+ var featuresToUpdate = [];
+ var featuresToDelete = [];
+
+ for(var i=0; i<features.length; i++) {
+ if(features[i].state == OpenLayers.State.INSERT) {
+ featuresToAdd.push(features[i]);
+ featuresToEdit.push(features[i]);
+ } else if(features[i].state == OpenLayers.State.UPDATE) {
+ //OpenLayers.Console.debug("...feature id: + " + features[i].id + "...");
+ //OpenLayers.Console.debug("...feature status: + " + features[i].state + "...");
+ if((features[i].attributes.objectid!=null && features[i].attributes.objectid!="")
+ || (features[i].attributes.OBJECTID!=null && features[i].attributes.OBJECTID!="")
+ || (features[i].fid!=null && features[i].fid!="")) {
+ // for ArcGIS Server Feature Service, you can only edit features with valid objectid
+ if(features[i].fid &&(!features[i].attributes.objectid&&!features[i].attributes.OBJECTID)) {
+ features[i].attributes.objectid = features[i].fid;
+ features[i].attributes.OBJECTID = features[i].fid;
+ }
+ featuresToUpdate.push(features[i]);
+ featuresToEdit.push(features[i]);
+ } else {
+ OpenLayers.Console.debug("...skip commiting changes of feature: + " + features[i].id + "...no valid objectid found...");
+ }
+ } else if(features[i].state == OpenLayers.State.DELETE) {
+ //OpenLayers.Console.debug("...feature id: + " + features[i].id + "...");
+ //OpenLayers.Console.debug("...feature status: + " + features[i].state + "...");
+ if((features[i].attributes.objectid!=null && features[i].attributes.objectid!="")
+ || (features[i].attributes.OBJECTID!=null && features[i].attributes.OBJECTID!="")
+ || (features[i].fid!=null && features[i].fid!="")) {
+ // for ArcGIS Server Feature Service, you can only edit features with valid objectid
+ if(features[i].fid &&(!features[i].attributes.objectid&&!features[i].attributes.OBJECTID)) {
+ features[i].attributes.objectid = features[i].fid;
+ features[i].attributes.OBJECTID = features[i].fid;
+ }
+ featuresToDelete.push(features[i]);
+ featuresToEdit.push(features[i]);
+ } else {
+ OpenLayers.Console.debug("...skip commiting changes of feature: + " + features[i].id + "...no valid objectid found...");
+ }
+ } else {
+ // do nothing
+ }
+ }
+ options['featuresToEdit'] = featuresToEdit;
+
+ var singleCallback = null;
+
+ // need a variant of OpenLayers.Util.AgsUtil.createSingleCallback here
+ // because callback of this.agsFeatureLayer.applyEdits takes three input parameters
+ if(window.dojo !== undefined) {
+ singleCallback = dojo.hitch(
+ this,//options.scope,
+ function(addResults, updateResults, deleteResults) {
+ this.handleCommit.apply(options.scope, [addResults, updateResults, deleteResults, options]);
+ }
+ );
+ } else {
+ singleCallback = OpenLayers.Function.bind(
+ function(addResults, updateResults, deleteResults) {
+ this.handleCommit.apply(options.scope, [addResults, updateResults, deleteResults, options]);
+ },
+ this//options.scope
+ );
+ }
+
+ var agsFeaturesToAdd = this.format.encodeAgsGraphics.apply(this.format, [featuresToAdd, (this.srsName||this.layer.map.projection)]);
+ var agsFeaturesToUpdate = this.format.encodeAgsGraphics.apply(this.format, [featuresToUpdate, (this.srsName||this.layer.map.projection)]);
+ var agsFeaturesToDelete = this.format.encodeAgsGraphics.apply(this.format, [featuresToDelete, (this.srsName||this.layer.map.projection)]);
+ // call applyEdits on this.agsFeatureLayer
+ if(this.isAgsFeatureLayerLoaded == true) {
+ deferred = this.agsFeatureLayer.applyEdits(
+ agsFeaturesToAdd,
+ agsFeaturesToUpdate,
+ agsFeaturesToDelete,
+ singleCallback, // create single callback for succeeded commit
+ this.handleError // TODO: create single callback for failed commit
+ );
+ } else {
+ OpenLayers.Console.warn("...features not loaded...");
+ OpenLayers.Console.warn("...this.agsFeatureLayer feature layer is not loaded yet...try commit changes later...");
+ }
+ return deferred;
+ },
+
+ /**
+ * Method: handleCommit
+ * Called when the commit request returns.
+ *
+ * Parameters:
+ * options - {Object} The user options passed to the commit call.
+ */
+ // only handle succeeded commits
+ handleCommit: function(addResults, updateResults, deleteResults, options) {
+ //OpenLayers.Console.debug("...OpenLayers.Protocol.AgsFeatureAccess.v2.handleCommit is called...");
+ if(options.callback) {
+ var insertIds = [];
+ for(var i=0; i<addResults.length; i++) {
+ if(addResults[i].success == true) {
+ insertIds.push(addResults[i].objectId);
+ OpenLayers.Console.debug("...Collect objectId for inserted features...");
+ }
+ }
+ // a fake OpenLayers.Protocol.Response has to be created
+ // pass it to OpenLayers.Strategy.Save because onCommit() is expecting a response object with
+ // 'code', 'reqFeatures' and 'insertIds' etc.
+ var response = new OpenLayers.Protocol.Response({
+ requestType: "commit",
+ code: OpenLayers.Protocol.Response.SUCCESS,
+ reqFeatures: options['featuresToEdit'],
+ insertIds: insertIds
+ });
+ options.callback.call(
+ options.scope,
+ response
+ );
+ }
+ },
+
+ /**
+ * Method: handleError
+ * Deal with error response from the read request.
+ *
+ * Parameters:
+ * error - {object} the error response from esri.layers.FeatureLayer.
+ *
+ */
+ // only handle failed commits
+ handleError: function(error) {
+ OpenLayers.Console.error(error);
+ },
+
+ /**
+ * Method: setLayer
+ * Point protocol to its parent vector layer
+ *
+ * Parameters:
+ * layer - {OpenLayers.Layer.Vector}
+ */
+ setLayer: function(layer) {
+ this.layer = layer;
+ },
+
+ /**
+ * Method: getFeatureTemplateByRule
+ *
+ */
+ getFeatureTemplateByRule: function(rule) {
+ for(var i=0; i<this.templates.length; i++) {
+ /*
+ * TODO: it is a temporary solution to match rule.name to one of the templates's name
+ */
+ if(rule.name == this.templates[i].templates[0].name) {
+ OpenLayers.Console.debug("...match a rule with a template...");
+ OpenLayers.Console.debug("...rule name: " + rule.name + "...");
+ OpenLayers.Console.debug("...template name: " + this.templates[i].templates[0].name + "...");
+ return this.templates[i];
+ }
+ }
+ },
+
+ /**
+ * Method: setCurrentFeatureTemplate
+ *
+ * Parameters:
+ * olFeatureTemplate - {} object
+ */
+ setCurrentFeatureTemplate: function(olFeatureTemplate) {
+ if(olFeatureTemplate) {
+ this.currentFeatureTemplate = olFeatureTemplate;
+ } else {
+ OpenLayers.Console.warn("...setCurrentFeatureTemplate...invalid feature template...skip setting...");
+ }
+ },
+
+ /**
+ * Method: applyCurrentFeatureTemplate
+ * cast the input feature into another one using the current feature template
+ */
+ applyCurrentFeatureTemplate: function(olFeature) {
+ if(olFeature) {
+ // A feature template has both default values of attributes and a symbolizer too
+ // only apply the attributes part of template to the feature
+ // do not apply the symbolizer because symbolizer should be created out of layer's styleMap
+ // TODO: to be corrected
+ OpenLayers.Util.extend(olFeature.attributes, this.currentFeatureTemplate.templates[0].prototype.attributes);
+ OpenLayers.Console.debug("...current feature template applied...");
+ }
+ },
+
+ CLASS_NAME: "OpenLayers.Protocol.AgsFeatureAccess.v2"
+});
\ No newline at end of file
Added: sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess/v2_0.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess/v2_0.js (rev 0)
+++ sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess/v2_0.js 2010-12-03 06:58:49 UTC (rev 10944)
@@ -0,0 +1,31 @@
+/**
+ * @requires OpenLayers/Protocol/AgsFeatureAccess/v2.js
+ */
+
+/**
+ * Class: OpenLayers.Protocol.AgsFeatureAccess.v2_0
+ * A AgsFeatureAccess v2.0 protocol for vector layers. Create a new instance with the
+ * <OpenLayers.Protocol.AgsFeatureAccess.v2_0> constructor.
+ *
+ * Inherits from:
+ * - <OpenLayers.Protocol.AgsFeatureAccess.v2>
+ */
+OpenLayers.Protocol.AgsFeatureAccess.v2_0 = OpenLayers.Class(OpenLayers.Protocol.AgsFeatureAccess.v2, {
+
+ /**
+ * Property: version
+ * {String} ArcGIS JS API FeatureLayer version number.
+ */
+ version: "2.0",
+
+ /**
+ * Constructor: OpenLayers.Protocol.AgsFeatureAccess.v2_0
+ * A class for giving layers AgsFeatureAccess v2.0 protocol.
+ *
+ * Parameters:
+ * options - {Object} Optional object whose properties will be set on the
+ * instance.
+ */
+
+ CLASS_NAME: "OpenLayers.Protocol.AgsFeatureAccess.v2_0"
+});
\ No newline at end of file
Added: sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess.js (rev 0)
+++ sandbox/august/trunk/lib/OpenLayers/Protocol/AgsFeatureAccess.js 2010-12-03 06:58:49 UTC (rev 10944)
@@ -0,0 +1,28 @@
+/**
+ * @requires OpenLayers/Protocol.js
+ */
+
+/**
+ * Function: OpenLayers.Protocol.AgsFeatureAccess
+ * Used to create a protocol to access ArcGIS Server Feature Service through ArcGIS JavaScript API. Default version is 2.0.
+ *
+ * Returns:
+ * {<OpenLayers.Protocol>} An AgsFeatureAccess protocol of the given version.
+ */
+OpenLayers.Protocol.AgsFeatureAccess = function(options) {
+ options = OpenLayers.Util.applyDefaults(
+ options, OpenLayers.Protocol.AgsFeatureAccess.DEFAULTS
+ );
+ var cls = OpenLayers.Protocol.AgsFeatureAccess["v"+options.version.replace(/\./g, "_")];
+ if(!cls) {
+ throw "Unsupported AgsFeatureAccess version: " + options.version;
+ }
+ return new cls(options);
+};
+
+/**
+ * Constant: OpenLayers.Protocol.WFSTWithLock.DEFAULTS
+ */
+OpenLayers.Protocol.AgsFeatureAccess.DEFAULTS = {
+ "version": "2.0"
+};
Added: sandbox/august/trunk/playground/ags/agsfeatureaccess.html
===================================================================
--- sandbox/august/trunk/playground/ags/agsfeatureaccess.html (rev 0)
+++ sandbox/august/trunk/playground/ags/agsfeatureaccess.html 2010-12-03 06:58:49 UTC (rev 10944)
@@ -0,0 +1,30 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>openlayers vector behavior - wfs</title>
+ <!-- reference ArcGIS JS API -->
+ <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.0/js/dojo/dijit/themes/tundra/tundra.css">
+ <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.0"></script>
+
+ <link rel="stylesheet" href="../../theme/default/style.css" type="text/css"/>
+ <script src="../../lib/Firebug/firebug.js"></script>
+ <script src="../../lib/OpenLayers.js"></script>
+ <script src="agsfeatureaccess.js"></script>
+ <script type="text/javascript">
+ dojo.require("esri.layers.FeatureLayer");
+ dojo.require("esri.dijit.editing.TemplatePicker-all");
+ esriConfig.defaults.io.proxyUrl = "../../util/ags-proxy.jsp";
+ esriConfig.defaults.io.alwaysUseProxy = false;
+ dojo.addOnLoad(init);
+ </script>
+ <!--
+ <link rel="stylesheet" href="../../../patched+/theme/default/style.css" type="text/css"/>
+ <script src="../../../patched+/Firebug/firebug.js"></script>
+ <script src="../../../patched+/OpenLayers.js"></script>
+ <script src="agsfeatureaccess.js"></script>
+ -->
+ </head>
+ <body>
+ <div id="map" style="width: 1024px; height: 512px; margin-top: 5px; margin-left: 5px; background-color: #ffffff"></div>
+ <input id="commit_btn" type="button" value="commit" onclick="commit();"/>
+ </body>
+</html>
Added: sandbox/august/trunk/playground/ags/agsfeatureaccess.js
===================================================================
--- sandbox/august/trunk/playground/ags/agsfeatureaccess.js (rev 0)
+++ sandbox/august/trunk/playground/ags/agsfeatureaccess.js 2010-12-03 06:58:49 UTC (rev 10944)
@@ -0,0 +1,197 @@
+var map;
+var select_control, modify_control, insert_control, delete_control;
+var bbox_strategy, save_strategy;
+var agsFeatureAccessLayer;
+
+function init() {
+
+
+ // set OpenLayers proxy
+ //OpenLayers.ProxyHost= "/openlayers-trunk/ApacheProxyServlet?url=";
+
+ OpenLayers.ProxyHost= function(url) {
+ return "/openlayers-trunk/ApacheProxyServlet?url=" + url;
+ };
+
+ var options = {
+ //panMethod: null, // set 'panMethod' to null to disable animated panning
+ controls: [
+ new OpenLayers.Control.LayerSwitcher(),
+ new OpenLayers.Control.PanZoomBar(),
+ new OpenLayers.Control.Navigation(),
+ new OpenLayers.Control.MousePosition()
+ ],
+ projection: "EPSG:900913",
+ units: "m",
+ maxResolution: 156543.0339,
+ numZoomLevels: 20, // default allowed zoom levels is 16 so change it to 20
+ maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
+ };
+
+ map = new OpenLayers.Map('map', options);
+
+ var base_layer = new OpenLayers.Layer.AgsTiled(
+ "World Topo Map",
+ "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/",
+ //"World Imagery Map",
+ //"http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/",
+ {
+ tileSize: new OpenLayers.Size(256,256),
+ tileFormat:'jpg',
+ tileOrigin: new OpenLayers.LonLat(-20037508.342789, 20037508.342789),
+ tileFullExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
+ isBaseLayer: true,
+ singleTile: false
+ }
+ );
+
+ map.addLayer(base_layer);
+ // add feature service from ArcGIS Server
+ // San Francisco
+ //var lon = -122.391667;
+ //var lat = 37.760628;
+ //var zoom = 16;
+ // Kuwait
+ var lon = 48.01436;
+ var lat = 29.11857;
+ var zoom = 12;
+
+ bbox_strategy = new OpenLayers.Strategy.BBOX();
+ // add "Save" strategy to commit edits to feature layer
+ save_strategy = new OpenLayers.Strategy.Save({
+ auto:false
+ });
+
+ agsFeatureAccessLayer = new OpenLayers.Layer.Vector(
+ "arcgis server feature service",
+ {
+ strategies: [
+ bbox_strategy,
+ save_strategy
+ ],
+ protocol: new OpenLayers.Protocol.AgsFeatureAccess({
+ //url: "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/MapServer/0",
+ url: "http://sazabi:8399/arcgis/rest/services/playground/ihs_featureservice_mercator_auxiliary/FeatureServer/0", // point layer
+ //url: "http://sazabi:8399/arcgis/rest/services/playground/ihs_featureservice_mercator_auxiliary/FeatureServer/2", // polygon layer
+ query: {
+ outFields: []
+ },
+ srsName: map.projection
+ })
+ }
+ );
+ agsFeatureAccessLayer.protocol.setLayer(agsFeatureAccessLayer);
+ agsFeatureAccessLayer.setVisibility(false);
+ map.addLayer(agsFeatureAccessLayer);
+
+ map.setCenter(
+ new OpenLayers.LonLat(lon,lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()),
+ zoom
+ );
+
+ // create, add and activate the SelectFeature control
+ /*
+ select_control = new OpenLayers.Control.SelectFeature(
+ agsFeatureAccessLayer,
+ {
+ clickout: false,
+ toggle: true,
+ multiple: true
+ }
+ );
+ map.addControl(select_control);
+ select_control.activate();
+ */
+ save_strategy.activate();
+
+ agsFeatureAccessLayer.events.on({
+ //"beforefeaturemodified": report,
+ //"featuremodified": monitoring,
+ //"afterfeaturemodified": monitoring
+ //"vertexmodified": report,
+ //"sketchmodified": report,
+ //"sketchstarted": report,
+ //"sketchcomplete": report
+ });
+
+ // to modify features create, add and activate a ModifyFeature control
+
+ modify_control = new OpenLayers.Control.ModifyFeature(
+ agsFeatureAccessLayer,
+ {
+ mode: OpenLayers.Control.ModifyFeature.RESHAPE | OpenLayers.Control.ModifyFeature.ROTATE,
+ clickout: true, //
+ toggle: false //
+ }
+ );
+
+ map.addControl(modify_control);
+ modify_control.activate();
+
+
+ // to delete features temporarily create, add and activate a ModifyFeatureWithLock control
+ // TODO: create a new delete feature control
+ // extend ModifyFeature control to create a DeleteFeature control on the fly
+ //OpenLayers.Control.ModifyFeature.DELETE = 16;
+ /*
+ OpenLayers.Control.DeleteFeature = OpenLayers.Class(OpenLayers.Control.ModifyFeature, {
+ deleteFeatureCodes: [81], // press 'q' key to delete feature on map
+ //
+ selectFeature: function(feature) {
+ this.feature = feature;
+ },
+ //
+ handleKeypress: function(evt) {
+ var code = evt.keyCode;
+ //if(this.mode == OpenLayers.Control.ModifyFeature.DELETE) {
+ if(this.feature &&
+ OpenLayers.Util.indexOf(this.deleteFeatureCodes, code) != -1) {
+ // delete feature at client and change state to "DELETE"
+ this.feature.state = OpenLayers.State.DELETE;
+ this.layer.eraseFeatures([this.feature]);
+ // remove feature from this.layer.selectedFeatures to avoid feature being drawn again
+ if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, this.feature) != -1) {
+ OpenLayers.Util.removeItem(this.layer.selectedFeatures, this.feature);
+ }
+ console.log("...delete feature at client side...");
+ this.layer.events.triggerEvent("featuremodified",
+ {feature: this.feature});
+ }
+ //}
+ },
+ CLASS_NAME: "OpenLayers.Control.DeleteFeature"
+ });
+ delete_control = new OpenLayers.Control.DeleteFeature(
+ agsFeatureAccessLayer,
+ {
+ //mode: OpenLayers.Control.ModifyFeature.DELETE,
+ clickout: true, //
+ toggle: false //
+ }
+ );
+ map.addControl(delete_control);
+ delete_control.activate();
+ */
+ // create, add and activate the DrawFeature control
+ /*
+ insert_control = new OpenLayers.Control.DrawFeature(
+ agsFeatureAccessLayer,
+ OpenLayers.Handler.Point,
+ {
+ //handlerOptions: {}
+ }
+ );
+ map.addControl(insert_control);
+ insert_control.activate();
+ */
+}
+
+function commit() {
+ save_strategy.save(null);
+}
+
+function monitoring(evt) {
+ OpenLayers.Console.debug(evt.type);
+ OpenLayers.Console.debug(evt.feature.id);
+ //OpenLayers.Console.debug(evt.feature.status);
+}
\ No newline at end of file
Added: sandbox/august/trunk/tests/Format/AgsJsAdapter_Renderer.html
===================================================================
--- sandbox/august/trunk/tests/Format/AgsJsAdapter_Renderer.html (rev 0)
+++ sandbox/august/trunk/tests/Format/AgsJsAdapter_Renderer.html 2010-12-03 06:58:49 UTC (rev 10944)
@@ -0,0 +1,36 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!--
+ <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.0/js/dojo/dijit/themes/tundra/tundra.css">
+ <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1"></script>
+ <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.1/js/dojo/dijit/themes/tundra/tundra.css">
+ <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.1"></script>
+ <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.4/js/dojo/dijit/themes/tundra/tundra.css">
+ <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.4"></script>
+ <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.6/js/dojo/dijit/themes/tundra/tundra.css">
+ <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.6"></script>
+ -->
+ <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.0/js/dojo/dijit/themes/tundra/tundra.css">
+ <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.0"></script>
+ <!--
+ Manually reference FeatureLayer.xd.js and iframe.xd.js which are required for support FeatureLayer in AGS JS API
+ You must explicitly reference those two js files here because JS API loads them dynamically when dojo.addOnLoad() is called, which
+ doesn't work quite friendly with TestAnotherWay
+ -->
+ <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/2.0/js/esri/layers/FeatureLayer.xd.js"></script>
+ <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/2.0/js/dojo/dojo/io/iframe.xd.js"></script>
+
+ <script type="text/javascript" src="../../lib/OpenLayers.js"></script>
+ <script type="text/javascript" src="AgsJsAdapter_Renderer.js"></script>
+ <!--
+ <script type="text/javascript">
+ dojo.require("esri.map");
+ dojo.require("esri.layers.FeatureLayer");
+ </script>
+ -->
+ </head>
+ <body>
+ <div id="map" style="width:400px;height:250px;"/>
+ </body>
+</html>
Added: sandbox/august/trunk/tests/Format/AgsJsAdapter_Renderer.js
===================================================================
--- sandbox/august/trunk/tests/Format/AgsJsAdapter_Renderer.js (rev 0)
+++ sandbox/august/trunk/tests/Format/AgsJsAdapter_Renderer.js 2010-12-03 06:58:49 UTC (rev 10944)
@@ -0,0 +1,514 @@
+var adapter = null;
+var _error = -99;
+
+function setUp() {
+ adapter = new OpenLayers.Format.AgsJsAdapter();
+}
+
+function tearDown() {
+ adapter = null;
+}
+
+//simple renderer example: http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Earthquakes/EarthquakesFromLastSevenDays/MapServer/0
+function test_Format_AgsJsAdapter_parseAgsRenderer_SimpleRenderer(t) {
+ //setUp();
+ t.plan(7);
+
+ var featureLayer = new esri.layers.FeatureLayer(
+ "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Earthquakes/EarthquakesFromLastSevenDays/MapServer/0",
+ {mode: esri.layers.FeatureLayer.MODE_SELECTION}
+ );
+ window.setTimeout(
+ function() {
+ var adapter_spec = new OpenLayers.Format.AgsJsAdapter();
+ var agsSimpleRenderer = featureLayer.renderer;
+ agsSimpleRenderer.label = "agsSimpleRenderer.label";
+ agsSimpleRenderer.description = "agsSimpleRenderer.description";
+ var olStyle = adapter_spec.parseAgsRenderer['SimpleRenderer'].apply(adapter_spec,[agsSimpleRenderer]);
+
+ t.ok((olStyle instanceof OpenLayers.Style), "...parseAgsRenderer.SimpleRenderer returns instance of OpenLayers.Style...");
+ t.eq(olStyle.name, "SimpleRendererStyle", "...parses olStyle name...");
+ t.eq(olStyle.title, "SimpleRenderer Style", "...parses olStyle title...");
+ t.eq(olStyle.description, "An OpenLayers Style converted from an esri SimpleRenderer", "...parses olStyle description...");
+
+ t.eq(olStyle.rules.length, 1, "...parses SimpleRender as an one rule style...");
+ t.ok((olStyle.rules[0] instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((olStyle.rules[0].symbolizer instanceof OpenLayers.Symbolizer), "...olStyle.rule.symbolizer is an instance of OpenLayers.Symbolizer.*...");
+ },
+ 1000
+ );
+ t.wait_result(3);
+ //tearDown();
+}
+
+function test_Format_AgsJsAdapter_parseAgsRenderer_ClassBreaksRenderer(t) {
+ setUp();
+ t.plan(40);
+
+ var defaultSymbol = new esri.symbol.SimpleFillSymbol();
+ var agsClassBreaksRenderer = new esri.renderer.ClassBreaksRenderer(defaultSymbol, "POP07_SQMI");
+
+ agsClassBreaksRenderer.addBreak({
+ minValue: 0,
+ maxValue: 9,
+ symbol: new esri.symbol.SimpleMarkerSymbol(),
+ label: "break0_label",
+ description: "break0_description"
+ });
+
+ agsClassBreaksRenderer.addBreak({
+ minValue: 10,
+ maxValue: 19,
+ symbol: new esri.symbol.SimpleFillSymbol(),
+ label: "break1_label",
+ description: "break1_description"
+ });
+
+ agsClassBreaksRenderer.addBreak({
+ minValue: 20,
+ maxValue: 29,
+ symbol: new esri.symbol.SimpleLineSymbol(),
+ label: "break2_label",
+ description: "break2_description"
+ });
+
+ var olStyle = adapter.parseAgsRenderer['ClassBreaksRenderer'].apply(adapter,[agsClassBreaksRenderer]);
+ t.ok((olStyle instanceof OpenLayers.Style), "...parseAgsRenderer.ClassBreaksRenderer returns instance of OpenLayers.Style...");
+ t.eq(olStyle.name, "ClassBreaksRendererStyle", "...parses olStyle name...");
+ t.eq(olStyle.title, "ClassBreaksRenderer Style", "...parses olStyle title...");
+ t.eq(olStyle.description, "An OpenLayers Style converted from an esri ClassBreaksRenderer", "...parses olStyle description...");
+
+ var olRule0 = olStyle.rules[0];
+ t.ok((olRule0 instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((olRule0.symbolizer instanceof OpenLayers.Symbolizer.Point), "...olStyle.rule is an instance of OpenLayers.Symbolizer.*...");
+ t.eq(olRule0.name, "break0_label", "...parse info.label and set to rule.name...");
+ t.eq(olRule0.title, "break0_label", "...parse info.label and set to rule.title...");
+ t.eq(olRule0.description, "break0_description", "...parse info.label and set to rule.description...");
+ t.ok((olRule0.filter instanceof OpenLayers.Filter.Comparison), "...olStyle.rule.filter is an instance of OpenLayers.Filter.Comparison...");
+ t.eq(olRule0.filter.type, OpenLayers.Filter.Comparison.BETWEEN, "...olStyle.rule.filter.type is OpenLayers.Filter.Comparison.BETWEEN...");
+ t.eq(olRule0.filter.property, "POP07_SQMI", "...parse attributeField and set to olStyle.rule.filter.property...");
+ t.eq(olRule0.filter.lowerBoundary, 0, "...parse minValue and set to olStyle.rule.filter.lowerBoundary...");
+ t.eq(olRule0.filter.upperBoundary, 9, "...parse maxValue and set to olStyle.rule.filter.upperBoundary...");
+
+ var olRule1 = olStyle.rules[1];
+ t.ok((olRule1 instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((olRule1.symbolizer instanceof OpenLayers.Symbolizer.Polygon), "...olStyle.rule is an instance of OpenLayers.Symbolizer.*...");
+ t.eq(olRule1.name, "break1_label", "...parse info.label and set to rule.name...");
+ t.eq(olRule1.title, "break1_label", "...parse info.label and set to rule.title...");
+ t.eq(olRule1.description, "break1_description", "...parse info.label and set to rule.description...");
+ t.ok((olRule1.filter instanceof OpenLayers.Filter.Comparison), "...olStyle.rule.filter is an instance of OpenLayers.Filter.Comparison...");
+ t.eq(olRule1.filter.type, OpenLayers.Filter.Comparison.BETWEEN, "...olStyle.rule.filter.type is OpenLayers.Filter.Comparison.BETWEEN...");
+ t.eq(olRule1.filter.property, "POP07_SQMI", "...parse attributeField and set to olStyle.rule.filter.property...");
+ t.eq(olRule1.filter.lowerBoundary, 10, "...parse minValue and set to olStyle.rule.filter.lowerBoundary...");
+ t.eq(olRule1.filter.upperBoundary, 19, "...parse maxValue and set to olStyle.rule.filter.upperBoundary...");
+
+ var olRule2 = olStyle.rules[2];
+ t.ok((olRule2 instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((olRule2.symbolizer instanceof OpenLayers.Symbolizer.Line), "...olStyle.rule is an instance of OpenLayers.Symbolizer.*...");
+ t.eq(olRule2.name, "break2_label", "...parse info.label and set to rule.name...");
+ t.eq(olRule2.title, "break2_label", "...parse info.label and set to rule.title...");
+ t.eq(olRule2.description, "break2_description", "...parse info.label and set to rule.description...");
+ t.ok((olRule2.filter instanceof OpenLayers.Filter.Comparison), "...olStyle.rule.filter is an instance of OpenLayers.Filter.Comparison...");
+ t.eq(olRule2.filter.type, OpenLayers.Filter.Comparison.BETWEEN, "...olStyle.rule.filter.type is OpenLayers.Filter.Comparison.BETWEEN...");
+ t.eq(olRule2.filter.property, "POP07_SQMI", "...parse attributeField and set to olStyle.rule.filter.property...");
+ t.eq(olRule2.filter.lowerBoundary, 20, "...parse minValue and set to olStyle.rule.filter.lowerBoundary...");
+ t.eq(olRule2.filter.upperBoundary, 29, "...parse maxValue and set to olStyle.rule.filter.upperBoundary...");
+
+ var defaultOLRule = olStyle.rules[3];
+ t.ok((defaultOLRule instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((defaultOLRule.symbolizer instanceof OpenLayers.Symbolizer.Polygon), "...olStyle.rule is an instance of OpenLayers.Symbolizer.*...");
+ t.eq(defaultOLRule.name, "defaultRuleName", "...parse info.label and set to rule.name...");
+ t.eq(defaultOLRule.title, "default rule title", "...parse info.label and set to rule.title...");
+ t.eq(defaultOLRule.description, "default rule description", "...parse info.label and set to rule.description...");
+ t.eq(defaultOLRule.elseFilter, true, "...olStyle.rule.filter.type is OpenLayers.Filter.Comparison.BETWEEN...");
+
+ tearDown();
+}
+
+// unique value renderer example: http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Hydrography/Watershed173811/FeatureServer//1
+/**
+ *
+ * @param t
+ * @return
+ */
+function test_Format_AgsJsAdapter_parseAgsRenderer_UniqueValueRenderer(t) {
+ setUp();
+ t.plan(37);
+
+ var defaultSymbol = new esri.symbol.SimpleFillSymbol();
+ var agsUniqueValueRenderer = new esri.renderer.UniqueValueRenderer(defaultSymbol, "POP07_SQMI");
+
+ agsUniqueValueRenderer.addValue({
+ value: 0,
+ symbol: new esri.symbol.SimpleMarkerSymbol(),
+ label: "value0_label",
+ description: "value0_description"
+ });
+
+ agsUniqueValueRenderer.addValue({
+ value: 1,
+ symbol: new esri.symbol.SimpleLineSymbol(),
+ label: "value1_label",
+ description: "value1_description"
+ });
+
+ agsUniqueValueRenderer.addValue({
+ value: 2,
+ symbol: new esri.symbol.SimpleFillSymbol(),
+ label: "value2_label",
+ description: "value2_description"
+ });
+
+ var olStyle = adapter.parseAgsRenderer['UniqueValueRenderer'].apply(adapter,[agsUniqueValueRenderer]);
+ t.ok((olStyle instanceof OpenLayers.Style), "...parseAgsRenderer.UniqueValueRenderer returns instance of OpenLayers.Style...");
+ t.eq(olStyle.name, "UniqueValueRendererStyle", "...parses olStyle name...");
+ t.eq(olStyle.title, "UniqueValueRenderer Style", "...parses olStyle title...");
+ t.eq(olStyle.description, "An OpenLayers Style converted from an esri UniqueValueRenderer", "...parses olStyle description...");
+
+ var olRule0 = olStyle.rules[0];
+ t.ok((olRule0 instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((olRule0.symbolizer instanceof OpenLayers.Symbolizer.Point), "...olStyle.rule is an instance of OpenLayers.Symbolizer.*...");
+ t.eq(olRule0.name, "value0_label", "...parse info.label and set to rule.name...");
+ t.eq(olRule0.title, "value0_label", "...parse info.label and set to rule.title...");
+ t.eq(olRule0.description, "value0_description", "...parse info.label and set to rule.description...");
+ t.ok((olRule0.filter instanceof OpenLayers.Filter.Comparison), "...olStyle.rule.filter is an instance of OpenLayers.Filter.Comparison...");
+ t.eq(olRule0.filter.type, OpenLayers.Filter.Comparison.EQUAL_TO, "...olStyle.rule.filter.type is OpenLayers.Filter.Comparison.EQUAL_TO...");
+ t.eq(olRule0.filter.property, "POP07_SQMI", "...parse attributeField and set to olStyle.rule.filter.property...");
+ t.eq(olRule0.filter.value, 0, "...parse value and set to olStyle.rule.filter.value...");
+
+ var olRule1 = olStyle.rules[1];
+ t.ok((olRule1 instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((olRule1.symbolizer instanceof OpenLayers.Symbolizer.Line), "...olStyle.rule is an instance of OpenLayers.Symbolizer.*...");
+ t.eq(olRule1.name, "value1_label", "...parse info.label and set to rule.name...");
+ t.eq(olRule1.title, "value1_label", "...parse info.label and set to rule.title...");
+ t.eq(olRule1.description, "value1_description", "...parse info.label and set to rule.description...");
+ t.ok((olRule1.filter instanceof OpenLayers.Filter.Comparison), "...olStyle.rule.filter is an instance of OpenLayers.Filter.Comparison...");
+ t.eq(olRule1.filter.type, OpenLayers.Filter.Comparison.EQUAL_TO, "...olStyle.rule.filter.type is OpenLayers.Filter.Comparison.EQUAL_TO...");
+ t.eq(olRule1.filter.property, "POP07_SQMI", "...parse attributeField and set to olStyle.rule.filter.property...");
+ t.eq(olRule1.filter.value, 1, "...parse value and set to olStyle.rule.filter.value...");
+
+ var olRule2 = olStyle.rules[2];
+ t.ok((olRule2 instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((olRule2.symbolizer instanceof OpenLayers.Symbolizer.Polygon), "...olStyle.rule is an instance of OpenLayers.Symbolizer.*...");
+ t.eq(olRule2.name, "value2_label", "...parse info.label and set to rule.name...");
+ t.eq(olRule2.title, "value2_label", "...parse info.label and set to rule.title...");
+ t.eq(olRule2.description, "value2_description", "...parse info.label and set to rule.description...");
+ t.ok((olRule2.filter instanceof OpenLayers.Filter.Comparison), "...olStyle.rule.filter is an instance of OpenLayers.Filter.Comparison...");
+ t.eq(olRule2.filter.type, OpenLayers.Filter.Comparison.EQUAL_TO, "...olStyle.rule.filter.type is OpenLayers.Filter.Comparison.BETWEEN...");
+ t.eq(olRule2.filter.property, "POP07_SQMI", "...parse attributeField and set to olStyle.rule.filter.property...");
+ t.eq(olRule2.filter.value, 2, "...parse minValue and set to olStyle.rule.filter.value...");
+
+ var defaultOLRule = olStyle.rules[3];
+ t.ok((defaultOLRule instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((defaultOLRule.symbolizer instanceof OpenLayers.Symbolizer.Polygon), "...olStyle.rule is an instance of OpenLayers.Symbolizer.*...");
+ t.eq(defaultOLRule.name, "defaultRuleName", "...parse info.label and set to rule.name...");
+ t.eq(defaultOLRule.title, "default rule title", "...parse info.label and set to rule.title...");
+ t.eq(defaultOLRule.description, "default rule description", "...parse info.label and set to rule.description...");
+ t.eq(defaultOLRule.elseFilter, true, "...olStyle.rule.filter.type is OpenLayers.Filter.Comparison.BETWEEN...");
+
+ /*
+ // this example feature layer has a uniquevValueRenderer that has 7 different symbols for those 7 unique values
+ var featureLayer = new esri.layers.FeatureLayer(
+ "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/MapServer/0",
+ {mode: esri.layers.FeatureLayer.MODE_SELECTION}
+ );
+ window.setTimeout(
+ function() {
+ var adapter_spec = new OpenLayers.Format.AgsJsAdapter();
+ var agsUniqueValueRenderer = featureLayer.renderer;
+ agsUniqueValueRenderer.label = "agsUniqueValueRenderer.label";
+ agsUniqueValueRenderer.description = "agsUniqueValueRenderer.description";
+ var olStyle = adapter_spec.parseAgsRenderer['UniqueValueRenderer'].apply(adapter_spec, [agsUniqueValueRenderer]);
+
+ t.ok((olStyle instanceof OpenLayers.Style), "...parseAgsRenderer.UniqueValueRenderer returns instance of OpenLayers.Style...");
+ t.eq(olStyle.name, "UniqueValueRendererStyle", "...parses olStyle name...");
+ t.eq(olStyle.title, "UniqueValueRenderer Style", "...parses olStyle title...");
+ t.eq(olStyle.description, "An OpenLayers Style converted from an esri UniqueValueRenderer", "...parses olStyle description...");
+
+ t.eq(olStyle.rules.length, 7, "...parses UniqueValueRenderer as a multi-rule style...");
+
+ for(var i=0; i<olStyle.rules.length; i++) {
+ t.ok((olStyle.rules[i] instanceof OpenLayers.Rule), "...olStyle.rule is an instance of OpenLayers.Rule...");
+ t.ok((olStyle.rules[i].symbolizer instanceof OpenLayers.Symbolizer.Point), "...olStyle.rule is an instance of OpenLayers.Symbolizer.*...");
+ // TODO: test if filter is parsed correctly
+ }
+ },
+ 1000
+ );
+ t.wait_result(3);
+ */
+
+ tearDown();
+}
+
+/**
+ *
+ * @param t
+ * @return
+ */
+function test_Format_AgsJsAdapter_parseAgsSymbol_SimpleMarkerSymbol(t) {
+ //
+ setUp();
+ t.plan(10);
+ var agsSimpleMarkerSymbol = new esri.symbol.SimpleMarkerSymbol(
+ "STYLE_CIRCLE",
+ 8,
+ new esri.symbol.SimpleLineSymbol(
+ "STYLE_DASHDOT",
+ null, // set null for default color (0,0,0,1)
+ 2
+ ),
+ null // set null for default color (0,0,0,1)
+ );
+ //
+ //var adapter = new OpenLayers.Format.AgsJsAdapter();
+ var olSymbolizer = adapter.parseAgsSymbol['SimpleMarkerSymbol'].apply(adapter, [agsSimpleMarkerSymbol]);
+ t.ok((olSymbolizer instanceof OpenLayers.Symbolizer.Point), "...parseAgsSymbol.SimpleMarkerSymbol returns instance of OpenLayers.Symbolizer.Point...");
+ t.eq(olSymbolizer.pointRadius, 8, "...parse symbol 'size' and set to pointRadius...");
+ t.eq(olSymbolizer.fillColor, "#000000", "...parse 'color' and set to fillColor...");
+ t.eq(olSymbolizer.fillOpacity, 1, "...parse'color' and set to fillOpacity...");
+
+ t.eq(olSymbolizer.strokeDashstyle, "dashdot", "...parse 'strokeDashstyle' and set to strokeDashstyle...");
+ t.eq(olSymbolizer.strokeWidth, 2, "...parse 'strokeWidth' and set to strokeWidth...");
+ t.eq(olSymbolizer.strokeColor, "#000000", "...parse 'strokeColor' and set to strokeColor...");
+ t.eq(olSymbolizer.strokeOpacity, 1, "...parse 'strokeOpacity' and set to strokeOpacity...");
+
+ t.eq(olSymbolizer.graphicName, "circle", "...parse 'style' and set to graphicName...");
+
+ try {
+ var olSymbolizer2 = adapter.parseAgsSymbol['SimpleMarkerSymbol'].apply(adapter, [{'name':"name", 'value':"value"}]);
+ } catch(e) {
+ t.ok(true, "...throws exception if input is invalid esri.symbol.SimpleMarkerSymbol...");
+ }
+ tearDown();
+}
+
+/**
+ *
+ * @param t
+ * @return
+ */
+function test_Format_AgsJsAdapter_parseAgsSymbol_PictureMarkerSymbol(t) {
+ t.plan(9);
+ // this example feature layer has a uniquevValueRenderer that has 7 different symbols for those 7 unique values
+ var featureLayer = new esri.layers.FeatureLayer(
+ "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/MapServer/0",
+ {mode: esri.layers.FeatureLayer.MODE_SELECTION}
+ );
+ window.setTimeout(
+ function() {
+ var adapter_spec = new OpenLayers.Format.AgsJsAdapter();
+ var agsPictureMarkerSymbol = featureLayer.renderer.infos[0].symbol;
+ // hard code some attributes of agsPictureMarkerSymbol
+ agsPictureMarkerSymbol.size = 10;
+ agsPictureMarkerSymbol.width = 32;
+ agsPictureMarkerSymbol.height = 16;
+ agsPictureMarkerSymbol.xoffset = -1;
+ agsPictureMarkerSymbol.yoffset = -5;
+ agsPictureMarkerSymbol.angle = 30;
+
+ var olSymbolizer = adapter_spec.parseAgsSymbol['PictureMarkerSymbol'].apply(adapter_spec, [agsPictureMarkerSymbol]);
+ t.ok((olSymbolizer instanceof OpenLayers.Symbolizer.Point), "...parseAgsSymbol.PictureMarkerSymbol returns instance of OpenLayers.Symbolizer.Point...");
+ t.eq(olSymbolizer.pointRadius, 10, "...parse symbol 'size' and set to pointRadius...");
+ t.eq(olSymbolizer.externalGraphic, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IB2cksfwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAsVJREFUSInt001IVFEUwPH/a2bewwyCCZEZMI2gBoRKSdtEROBKooyiDwqt8QNpYQmjYuIHDZGOVDM5RJAwUvRBizYFLmrXoo+F0iKklROkSOQmyrnqvNNinLHRmdcY5Kqzuvfde8/vnnN5dtYp7P+hlbFnp0uq9isCw7PaP4Oqq1zy/PY0KGDRKYGR7NhfQ2mIgoGGWSq3O+VEd2bsT5AYGChU2uHqKpcUbJpG80CkB2qrwFQGx/b+4EmnU05eW41ZQTIz85XCwoKMlWgeSK6fO2AkKpuHmt3w+LJLTt2cTsMsK6qpOYJhGCilAPA1OmWgdaldgGmaicESElf5yDwcLYVHTS45fXcZywqJCObDLchCPqZyiqNxKrW2EHKjBiBUv5Xz3nqYv59CRBlIDDpG9bR8lhVtOPON+B03xED1uzHaE5hs3oX5+QO+F4rGJgfPXsPh3cuIJ6ATjUZzap0kB7bmKeLX3cg8zHWVkOefRK8dZa6rBACHXef4oCJ2z5kVsaxI9boxehMV6B1TxDrdSAzUAx/G2QB5/knqvlxAz0u0yArJCpU6DUwFP1tK2BicBMD8rsMCLLx6inE2AMC2bdsJBm9Qd96LJ/AyK5IVevbmI83XrjISiWiENCkuLiYajS5viKTnKyoqskSyQWKacUYikdQHb0MT3V2dABogExOf8Hh2pOYOXYfEu66tolAo+PtUc9hsAtDX55eeni7iS/9PX59fABw2m1Ux2aFweIhweCh5SwA6OtoA6O6+kkRS+212x9ohEcm0Ly3Gx8fT5m2+Vm4Fw1xquZg7lEuUlZXB8nsIgK4blmdWQjI2Nk55
eVoiAIaHR8TrreXgwUMrc2iA6Lo9ieb2Hy3GM7fO663VABkIDFJZUb4Kq/fWZTyXEervDyAST95yVbx9995yPWeovd1nmWBfZcWagYzQv4x1g34BI70ZygdCoCgAAAAASUVORK5CYII=", "...parse symbol 'url' for Linux/Unix...");
+ t.eq(olSymbolizer.graphicWidth, 32, "...parse symbol 'width' and set to 'graphicWidth'...");
+ t.eq(olSymbolizer.graphicHeight, 16, "...parse symbol 'height' and set to 'graphicheight'...");
+
+ t.eq(olSymbolizer.graphicXOffset, -1, "...parse symbol 'graphicXOffset' and set to 'graphicXOffset'...");
+ t.eq(olSymbolizer.graphicYOffset, -5, "...parse symbol 'graphicYOffset' and set to 'graphicYOffset'...");
+
+ t.eq(olSymbolizer.rotation, 30, "...parse symbol 'angle' and set to 'rotation'...");
+
+ try {
+ var olSymbolizer2 = adapter.parseAgsSymbol['PictureMarkerSymbol'].apply(adapter, [{'name':"name", 'value':"value"}]);
+ } catch(e) {
+ t.ok(true, "...throws exception if input is invalid esri.symbol.PictureMarkerSymbol...");
+ }
+ },
+ 1000
+ );
+ t.wait_result(3);
+}
+
+/**
+ *
+ * @param t
+ * @return
+ */
+function test_Format_AaJsAdapter_parseAgsSymbol_SimpleLineSymbol(t) {
+ setUp();
+ t.plan(6);
+ var agsSimpleLineSymbol = new esri.symbol.SimpleLineSymbol(
+ "STYLE_DASH",
+ null, // set null for default color (0,0,0,1)
+ 2
+ );
+ //var adapter = new OpenLayers.Format.AgsJsAdapter();
+ var olSymbolizer = adapter.parseAgsSymbol['SimpleLineSymbol'].apply(adapter, [agsSimpleLineSymbol]);
+
+ t.ok((olSymbolizer instanceof OpenLayers.Symbolizer.Line), "...parseAgsSymbol.SimpleLineSymbol returns instance of OpenLayers.Symbolizer.Line...");
+ t.eq(olSymbolizer.strokeDashstyle, "dash", "...parse 'strokeDashstyle' and set to strokeDashstyle...");
+ t.eq(olSymbolizer.strokeWidth, 2, "...parse 'strokeWidth' and set to strokeWidth...");
+ t.eq(olSymbolizer.strokeColor, "#000000", "...parse 'strokeColor' and set to strokeColor...");
+ t.eq(olSymbolizer.strokeOpacity, 1, "...parse 'strokeOpacity' and set to strokeColor...");
+
+ try {
+ var olSymbolizer2 = adapter.parseAgsSymbol['SimpleLineSymbol'].apply(adapter, [{'name':"name", 'value':"value"}]);
+ } catch(e) {
+ t.ok(true, "...throws exception if input is invalid esri.symbol.SimpleLineSymbol...");
+ }
+ tearDown();
+}
+
+/**
+ *
+ * @param t
+ * @return
+ */
+function test_Format_AaJsAdapter_parseAgsSymbol_CartographicLineSymbol(t) {
+ setUp();
+ t.plan(1);
+ // TODO: add real test cases when CartographicLineSymbol is supported in OpenLayers
+ try {
+ var olSymbolizer2 = adapter.parseAgsSymbol['CartographicLineSymbol'].apply(adapter, [{'name':"name", 'value':"value"}]);
+ } catch(e) {
+ t.ok(true, "...throws exception if input is invalid esri.symbol.CartographicLineSymbol...");
+ }
+ tearDown();
+}
+
+/**
+ *
+ * @param t
+ * @return
+ */
+function test_Format_AGSJSAdapter_parseAgsSymbol_SimpleFillSymbol(t) {
+ setUp();
+ t.plan(8);
+ var agsSimpleFillSymbol = new esri.symbol.SimpleFillSymbol(
+ "STYLE_SOLID",
+ new esri.symbol.SimpleLineSymbol(
+ "STYLE_DASHDOT",
+ null, // set null for default color (0,0,0,1)
+ 2
+ ),
+ new dojo.Color([255,255,255]) // set null for default color (0,0,0,1)
+ );
+ //var adapter = new OpenLayers.Format.AgsJsAdapter();
+ var olSymbolizer = adapter.parseAgsSymbol['SimpleFillSymbol'].apply(adapter, [agsSimpleFillSymbol]);
+ t.ok((olSymbolizer instanceof OpenLayers.Symbolizer.Polygon), "...parseAgsSymbol.SimpleFillSymbol returns instance of OpenLayers.Symbolizer.Polygon...");
+ t.eq(olSymbolizer.fillColor, "#ffffff", "...parse 'color' and set to fillColor...");
+ t.eq(olSymbolizer.fillOpacity, 1, "...parse'color' and set to fillOpacity...");
+
+ t.eq(olSymbolizer.strokeDashstyle, "dashdot", "...parse 'strokeDashstyle' and set to strokeDashstyle...");
+ t.eq(olSymbolizer.strokeWidth, 2, "...parse 'strokeWidth' and set to strokeWidth...");
+ t.eq(olSymbolizer.strokeColor, "#000000", "...parse 'strokeColor' and set to strokeColor...");
+ t.eq(olSymbolizer.strokeOpacity, 1, "...parse 'strokeOpacity' and set to strokeOpacity...");
+
+ try {
+ var olSymbolizer2 = adapter.parseAgsSymbol['SimpleFillSymbol'].apply(adapter, [{'name':"name", 'value':"value"}]);
+ } catch(e) {
+ t.ok(true, "...throws exception if input is invalid esri.symbol.SimpleFillSymbol...");
+ }
+ tearDown();
+}
+
+/**
+ *
+ * @param t
+ * @return
+ */
+function test_Format_AaJsAdapter_parseAgsSymbol_PictureFillSymbol(t) {
+ setUp();
+ t.plan(1);
+ // TODO: add real test cases when PictureFillSymbol is supported in OpenLayers
+ try {
+ var olSymbolizer2 = adapter.parseAgsSymbol['PictureFillSymbol'].apply(adapter, [{'name':"name", 'value':"value"}]);
+ } catch(e) {
+ t.ok(true, "...throws exception if input is invalid esri.symbol.PictureFillSymbol...");
+ }
+ tearDown();
+}
+
+/**
+ *
+ * @param t
+ * @return
+ */
+function test_Format_AaJsAdapter_parseAgsSymbol_TextSymbol(t) {
+ setUp();
+ t.plan(8);
+
+ var agsTextSymbol = new esri.symbol.TextSymbol("agsTextSymbol");
+ agsTextSymbol.setColor(new dojo.Color([128,0,0]));
+ agsTextSymbol.setAlign(esri.symbol.Font.ALIGN_START);
+ agsTextSymbol.setAngle(45);
+ var agsFont = new esri.symbol.Font();
+ agsFont.setSize("12pt");
+ agsFont.setFamily("Serif");
+ agsFont.setStyle("STYLE_ITALIC");
+ agsFont.setWeight(esri.symbol.Font.WEIGHT_BOLD);
+ agsTextSymbol.setFont(agsFont);
+ //var adapter = new OpenLayers.Format.AgsJsAdapter();
+ var olSymbolizer = adapter.parseAgsSymbol['TextSymbol'].apply(adapter, [agsTextSymbol]);
+ t.ok((olSymbolizer instanceof OpenLayers.Symbolizer.Text), "...parseAgsSymbol.TextSymbol returns instance of OpenLayers.Symbolizer.Text...");
+
+ t.eq(olSymbolizer.label, "agsTextSymbol", "...parse 'text' and set to label...");
+ t.eq(olSymbolizer.fontFamily, "Serif", "...parse 'font.family' and set to fontFamily...");
+ t.eq(olSymbolizer.fontSize, "12pt", "...parse 'font.size' and set to fontSize...");
+ t.eq(olSymbolizer.fontWeight, "bold", "...parse 'font.weight' and set to fontWeight...");
+ t.eq(olSymbolizer.fontStyle, "STYLE_ITALIC", "...parse 'font.style' and set to fontStyle...");
+ t.eq(olSymbolizer.color, "#800000", "...parse 'color' and set to color...");
+
+ try {
+ var olSymbolizer2 = adapter.parseAgsSymbol['TextSymbol'].apply(adapter, [{'name':"name", 'value':"value"}]);
+ } catch(e) {
+ t.ok(true, "...throws exception if input is invalid esri.symbol.TextSymbol...");
+ }
+ tearDown();
+}
+
+/**
+ * @param t
+ * @return
+ */
+function test_Format_AaJsAdapter_parseAgsFeatureTemplate(t) {
+ setUp();
+ t.plan(3);
+
+ var findTask = new esri.tasks.FindTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/");
+ findParams = new esri.tasks.FindParameters();
+ findParams.layerIds = [0];
+ findParams.searchFields = ["CITY_NAME"];
+ findParams.returnGeometry = true;
+
+ findParams.searchText = "Los Angeles";
+ findTask.execute(
+ findParams,
+ function(findResults) {
+ var adapter = new OpenLayers.Format.AgsJsAdapter({});
+ var agsGraphic = findResults[0].feature;
+ var agsFeatureTemplate = {
+ name: "template_name",
+ description: "template_description",
+ prototype: agsGraphic
+ };
+ var olFeatureTemplate = adapter.parseAgsFeatureTemplate.apply(adapter, [agsFeatureTemplate]);
+ t.eq(olFeatureTemplate.name, "template_name", "...feature template name is parsed and set to name...");
+ t.eq(olFeatureTemplate.description, "template_description", "...feature template description is parsed and set to description...");
+ t.ok(olFeatureTemplate.prototype instanceof OpenLayers.Feature.Vector, "...feature template prototype is an instance of OpenLayers.Feature.Vector...")
+ }
+ );
+ t.wait_result(3);
+
+ tearDown();
+}
+
+// TODO: add test for parseAgsFeatureType
+// TODO: add test for parseAgsFeatureTypes
+// TODO: add test for parseNoGeometryAgsGraphic
+// TODO: add test for parseNoGeometryAgsGraphics
+
+
+
+
More information about the Commits
mailing list