| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- /* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
- * full list of contributors). Published under the Clear BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
- * full text of the license. */
- /**
- * @requires OpenLayers/Tile/WFS.js
- * @requires OpenLayers/Layer/Vector.js
- * @requires OpenLayers/Layer/Markers.js
- * @requires OpenLayers/Console.js
- * @requires OpenLayers/Lang.js
- */
- /**
- * Class: OpenLayers.Layer.WFS
- * *Deprecated*. To be removed in 3.0. Instead use OpenLayers.Layer.Vector
- * with a Protocol.WFS and one or more Strategies.
- *
- * Inherits from:
- * - <OpenLayers.Layer.Vector>
- * - <OpenLayers.Layer.Markers>
- */
- OpenLayers.Layer.WFS = OpenLayers.Class(
- OpenLayers.Layer.Vector, OpenLayers.Layer.Markers, {
- /**
- * APIProperty: isBaseLayer
- * {Boolean} WFS layer is not a base layer by default.
- */
- isBaseLayer: false,
-
- /**
- * Property: tile
- * {<OpenLayers.Tile.WFS>}
- */
- tile: null,
-
- /**
- * APIProperty: ratio
- * {Float} The ratio property determines the size of the serverside query
- * relative to the map viewport size. By default, we load an area twice
- * as big as the map, to allow for panning without immediately reload.
- * Setting this to 1 will cause the area of the WFS request to match
- * the map area exactly. It is recommended to set this to some number
- * at least slightly larger than 1, otherwise accidental clicks can
- * cause a data reload, by moving the map only 1 pixel.
- */
- ratio: 2,
- /**
- * Property: DEFAULT_PARAMS
- * {Object} Hashtable of default key/value parameters
- */
- DEFAULT_PARAMS: { service: "WFS",
- version: "1.0.0",
- request: "GetFeature"
- },
-
- /**
- * APIProperty: featureClass
- * {<OpenLayers.Feature>} If featureClass is defined, an old-style markers
- * based WFS layer is created instead of a new-style vector layer. If
- * sent, this should be a subclass of OpenLayers.Feature
- */
- featureClass: null,
-
- /**
- * APIProperty: format
- * {<OpenLayers.Format>} The format you want the data to be parsed with.
- * Must be passed in the constructor. Should be a class, not an instance.
- * This option can only be used if no featureClass is passed / vectorMode
- * is false: if a featureClass is passed, then this parameter is ignored.
- */
- format: null,
- /**
- * Property: formatObject
- * {<OpenLayers.Format>} Internally created/managed format object, used by
- * the Tile to parse data.
- */
- formatObject: null,
- /**
- * APIProperty: formatOptions
- * {Object} Hash of options which should be passed to the format when it is
- * created. Must be passed in the constructor.
- */
- formatOptions: null,
- /**
- * Property: vectorMode
- * {Boolean} Should be calculated automatically. Determines whether the
- * layer is in vector mode or marker mode.
- */
- vectorMode: true,
-
- /**
- * APIProperty: encodeBBOX
- * {Boolean} Should the BBOX commas be encoded? The WMS spec says 'no',
- * but some services want it that way. Default false.
- */
- encodeBBOX: false,
-
- /**
- * APIProperty: extractAttributes
- * {Boolean} Should the WFS layer parse attributes from the retrieved
- * GML? Defaults to false. If enabled, parsing is slower, but
- * attributes are available in the attributes property of
- * layer features.
- */
- extractAttributes: false,
- /**
- * Constructor: OpenLayers.Layer.WFS
- *
- * Parameters:
- * name - {String}
- * url - {String}
- * params - {Object}
- * options - {Object} Hashtable of extra options to tag onto the layer
- */
- initialize: function(name, url, params, options) {
- if (options == undefined) { options = {}; }
-
- if (options.featureClass ||
- !OpenLayers.Layer.Vector ||
- !OpenLayers.Feature.Vector) {
- this.vectorMode = false;
- }
- // Uppercase params
- params = OpenLayers.Util.upperCaseObject(params);
-
- // Turn off error reporting, browsers like Safari may work
- // depending on the setup, and we don't want an unneccesary alert.
- OpenLayers.Util.extend(options, {'reportError': false});
- var newArguments = [];
- newArguments.push(name, options);
- OpenLayers.Layer.Vector.prototype.initialize.apply(this, newArguments);
- if (!this.renderer || !this.vectorMode) {
- this.vectorMode = false;
- if (!options.featureClass) {
- options.featureClass = OpenLayers.Feature.WFS;
- }
- OpenLayers.Layer.Markers.prototype.initialize.apply(this,
- newArguments);
- }
-
- if (this.params && this.params.typename && !this.options.typename) {
- this.options.typename = this.params.typename;
- }
-
- if (!this.options.geometry_column) {
- this.options.geometry_column = "the_geom";
- }
-
- this.params = OpenLayers.Util.applyDefaults(
- params,
- OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)
- );
- this.url = url;
- },
-
- /**
- * APIMethod: destroy
- */
- destroy: function() {
- if (this.vectorMode) {
- OpenLayers.Layer.Vector.prototype.destroy.apply(this, arguments);
- } else {
- OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);
- }
- if (this.tile) {
- this.tile.destroy();
- }
- this.tile = null;
- this.ratio = null;
- this.featureClass = null;
- this.format = null;
- if (this.formatObject && this.formatObject.destroy) {
- this.formatObject.destroy();
- }
- this.formatObject = null;
-
- this.formatOptions = null;
- this.vectorMode = null;
- this.encodeBBOX = null;
- this.extractAttributes = null;
- },
-
- /**
- * Method: setMap
- *
- * Parameters:
- * map - {<OpenLayers.Map>}
- */
- setMap: function(map) {
- if (this.vectorMode) {
- OpenLayers.Layer.Vector.prototype.setMap.apply(this, arguments);
-
- var options = {
- 'extractAttributes': this.extractAttributes
- };
-
- OpenLayers.Util.extend(options, this.formatOptions);
- if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
- options.externalProjection = this.projection;
- options.internalProjection = this.map.getProjectionObject();
- }
-
- this.formatObject = this.format ? new this.format(options) : new OpenLayers.Format.GML(options);
- } else {
- OpenLayers.Layer.Markers.prototype.setMap.apply(this, arguments);
- }
- },
-
- /**
- * Method: moveTo
- *
- * Parameters:
- * bounds - {<OpenLayers.Bounds>}
- * zoomChanged - {Boolean}
- * dragging - {Boolean}
- */
- moveTo:function(bounds, zoomChanged, dragging) {
- if (this.vectorMode) {
- OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);
- } else {
- OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);
- }
- // don't load wfs features while dragging, wait for drag end
- if (dragging) {
- // TBD try to hide the vector layer while dragging
- // this.setVisibility(false);
- // this will probably help for panning performances
- return false;
- }
-
- if ( zoomChanged ) {
- if (this.vectorMode) {
- this.renderer.clear();
- }
- }
-
- //DEPRECATED - REMOVE IN 3.0
- // don't load data if current zoom level doesn't match
- if (this.options.minZoomLevel) {
- OpenLayers.Console.warn(OpenLayers.i18n('minZoomLevelError'));
-
- if (this.map.getZoom() < this.options.minZoomLevel) {
- return null;
- }
- }
-
- if (bounds == null) {
- bounds = this.map.getExtent();
- }
- var firstRendering = (this.tile == null);
- //does the new bounds to which we need to move fall outside of the
- // current tile's bounds?
- var outOfBounds = (!firstRendering &&
- !this.tile.bounds.containsBounds(bounds));
- if (zoomChanged || firstRendering || (!dragging && outOfBounds)) {
- //determine new tile bounds
- var center = bounds.getCenterLonLat();
- var tileWidth = bounds.getWidth() * this.ratio;
- var tileHeight = bounds.getHeight() * this.ratio;
- var tileBounds =
- new OpenLayers.Bounds(center.lon - (tileWidth / 2),
- center.lat - (tileHeight / 2),
- center.lon + (tileWidth / 2),
- center.lat + (tileHeight / 2));
- //determine new tile size
- var tileSize = this.map.getSize();
- tileSize.w = tileSize.w * this.ratio;
- tileSize.h = tileSize.h * this.ratio;
- //determine new position (upper left corner of new bounds)
- var ul = new OpenLayers.LonLat(tileBounds.left, tileBounds.top);
- var pos = this.map.getLayerPxFromLonLat(ul);
- //formulate request url string
- var url = this.getFullRequestString();
-
- var params = null;
- // Cant combine "filter" and "BBOX". This is a cheap hack to help
- // people out who can't migrate to the WFS protocol immediately.
- var filter = this.params.filter || this.params.FILTER;
- if (filter) {
- params = {FILTER: filter};
- }
- else {
- params = {BBOX: this.encodeBBOX ? tileBounds.toBBOX()
- : tileBounds.toArray()};
- }
-
- if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
- var projectedBounds = tileBounds.clone();
- projectedBounds.transform(this.map.getProjectionObject(),
- this.projection);
- if (!filter){
- params.BBOX = this.encodeBBOX ? projectedBounds.toBBOX()
- : projectedBounds.toArray();
- }
- }
- url += "&" + OpenLayers.Util.getParameterString(params);
- if (!this.tile) {
- this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds,
- url, tileSize);
- this.addTileMonitoringHooks(this.tile);
- this.tile.draw();
- } else {
- if (this.vectorMode) {
- this.destroyFeatures();
- this.renderer.clear();
- } else {
- this.clearMarkers();
- }
- this.removeTileMonitoringHooks(this.tile);
- this.tile.destroy();
-
- this.tile = null;
- this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds,
- url, tileSize);
- this.addTileMonitoringHooks(this.tile);
- this.tile.draw();
- }
- }
- },
- /**
- * Method: addTileMonitoringHooks
- * This function takes a tile as input and adds the appropriate hooks to
- * the tile so that the layer can keep track of the loading tile
- * (making sure to check that the tile is always the layer's current
- * tile before taking any action).
- *
- * Parameters:
- * tile - {<OpenLayers.Tile>}
- */
- addTileMonitoringHooks: function(tile) {
- tile.onLoadStart = function() {
- //if this is the the layer's current tile, then trigger
- // a 'loadstart'
- if (this == this.layer.tile) {
- this.layer.events.triggerEvent("loadstart");
- }
- };
- tile.events.register("loadstart", tile, tile.onLoadStart);
-
- tile.onLoadEnd = function() {
- //if this is the the layer's current tile, then trigger
- // a 'tileloaded' and 'loadend'
- if (this == this.layer.tile) {
- this.layer.events.triggerEvent("tileloaded");
- this.layer.events.triggerEvent("loadend");
- }
- };
- tile.events.register("loadend", tile, tile.onLoadEnd);
- tile.events.register("unload", tile, tile.onLoadEnd);
- },
-
- /**
- * Method: removeTileMonitoringHooks
- * This function takes a tile as input and removes the tile hooks
- * that were added in addTileMonitoringHooks()
- *
- * Parameters:
- * tile - {<OpenLayers.Tile>}
- */
- removeTileMonitoringHooks: function(tile) {
- tile.unload();
- tile.events.un({
- "loadstart": tile.onLoadStart,
- "loadend": tile.onLoadEnd,
- "unload": tile.onLoadEnd,
- scope: tile
- });
- },
- /**
- * Method: onMapResize
- * Call the onMapResize method of the appropriate parent class.
- */
- onMapResize: function() {
- if(this.vectorMode) {
- OpenLayers.Layer.Vector.prototype.onMapResize.apply(this,
- arguments);
- } else {
- OpenLayers.Layer.Markers.prototype.onMapResize.apply(this,
- arguments);
- }
- },
-
- /**
- * Method: display
- * Call the display method of the appropriate parent class.
- */
- display: function() {
- if(this.vectorMode) {
- OpenLayers.Layer.Vector.prototype.display.apply(this,
- arguments);
- } else {
- OpenLayers.Layer.Markers.prototype.display.apply(this,
- arguments);
- }
- },
-
- /**
- * APIMethod: mergeNewParams
- * Modify parameters for the layer and redraw.
- *
- * Parameters:
- * newParams - {Object}
- */
- mergeNewParams:function(newParams) {
- var upperParams = OpenLayers.Util.upperCaseObject(newParams);
- var newArguments = [upperParams];
- return OpenLayers.Layer.HTTPRequest.prototype.mergeNewParams.apply(this,
- newArguments);
- },
- /**
- * APIMethod: clone
- *
- * Parameters:
- * obj - {Object}
- *
- * Returns:
- * {<OpenLayers.Layer.WFS>} An exact clone of this OpenLayers.Layer.WFS
- */
- clone: function (obj) {
-
- if (obj == null) {
- obj = new OpenLayers.Layer.WFS(this.name,
- this.url,
- this.params,
- this.getOptions());
- }
- //get all additions from superclasses
- if (this.vectorMode) {
- obj = OpenLayers.Layer.Vector.prototype.clone.apply(this, [obj]);
- } else {
- obj = OpenLayers.Layer.Markers.prototype.clone.apply(this, [obj]);
- }
- // copy/set any non-init, non-simple values here
- return obj;
- },
- /**
- * APIMethod: getFullRequestString
- * combine the layer's url with its params and these newParams.
- *
- * Add the SRS parameter from 'projection' -- this is probably
- * more eloquently done via a setProjection() method, but this
- * works for now and always.
- *
- * Parameters:
- * newParams - {Object}
- * altUrl - {String} Use this as the url instead of the layer's url
- */
- getFullRequestString:function(newParams, altUrl) {
- var projectionCode = this.projection.getCode() || this.map.getProjection();
- this.params.SRS = (projectionCode == "none") ? null : projectionCode;
- return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(
- this, arguments);
- },
-
- /**
- * APIMethod: commit
- * Write out the data to a WFS server.
- */
- commit: function() {
- if (!this.writer) {
- var options = {};
- if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
- options.externalProjection = this.projection;
- options.internalProjection = this.map.getProjectionObject();
- }
-
- this.writer = new OpenLayers.Format.WFS(options,this);
- }
- var data = this.writer.write(this.features);
- OpenLayers.Request.POST({
- url: this.url,
- data: data,
- success: this.commitSuccess,
- failure: this.commitFailure,
- scope: this
- });
- },
- /**
- * Method: commitSuccess
- * Called when the Ajax request returns a response
- *
- * Parameters:
- * response - {XmlNode} from server
- */
- commitSuccess: function(request) {
- var response = request.responseText;
- if (response.indexOf('SUCCESS') != -1) {
- this.commitReport(OpenLayers.i18n("commitSuccess", {'response':response}));
-
- for(var i = 0; i < this.features.length; i++) {
- this.features[i].state = null;
- }
- // TBD redraw the layer or reset the state of features
- // foreach features: set state to null
- } else if (response.indexOf('FAILED') != -1 ||
- response.indexOf('Exception') != -1) {
- this.commitReport(OpenLayers.i18n("commitFailed", {'response':response}));
- }
- },
-
- /**
- * Method: commitFailure
- * Called when the Ajax request fails
- *
- * Parameters:
- * response - {XmlNode} from server
- */
- commitFailure: function(request) {},
-
- /**
- * APIMethod: commitReport
- * Called with a 'success' message if the commit succeeded, otherwise
- * a failure message, and the full request text as a second parameter.
- * Override this function to provide custom transaction reporting.
- *
- * string - {String} reporting string
- * response - {String} full XML response
- */
- commitReport: function(string, response) {
- OpenLayers.Console.userError(string);
- },
-
- /**
- * APIMethod: refresh
- * Refreshes all the features of the layer
- */
- refresh: function() {
- if (this.tile) {
- if (this.vectorMode) {
- this.renderer.clear();
- this.features.length = 0;
- } else {
- this.clearMarkers();
- this.markers.length = 0;
- }
- this.tile.draw();
- }
- },
-
- /**
- * APIMethod: getDataExtent
- * Calculates the max extent which includes all of the layer data.
- *
- * Returns:
- * {<OpenLayers.Bounds>}
- */
- getDataExtent: function () {
- var extent;
- //get all additions from superclasses
- if (this.vectorMode) {
- extent = OpenLayers.Layer.Vector.prototype.getDataExtent.apply(this);
- } else {
- extent = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(this);
- }
- return extent;
- },
-
- /**
- * APIMethod: setOpacity
- * Call the setOpacity method of the appropriate parent class to set the
- * opacity.
- *
- * Parameter:
- * opacity - {Float}
- */
- setOpacity: function (opacity) {
- if (this.vectorMode) {
- OpenLayers.Layer.Vector.prototype.setOpacity.apply(this, [opacity]);
- } else {
- OpenLayers.Layer.Markers.prototype.setOpacity.apply(this, [opacity]);
- }
- },
- CLASS_NAME: "OpenLayers.Layer.WFS"
- });
|