Merge vector-2.4 branch back to trunk.

svn merge sandbox/vector-2.4/@2307 sandbox/vector-2.4/@HEAD trunk/openlayers/


git-svn-id: http://svn.openlayers.org/trunk/openlayers@2803 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
crschmidt
2007-03-16 13:23:56 +00:00
parent 8b9d974dc2
commit 3ca974acec
159 changed files with 10193 additions and 343 deletions
+9 -6
View File
@@ -13,17 +13,20 @@ OpenLayers.Layer.Boxes = OpenLayers.Class.create();
OpenLayers.Layer.Boxes.prototype =
OpenLayers.Class.inherit( OpenLayers.Layer.Markers, {
/**
* @constructor
*/
initialize: function () {
OpenLayers.Layer.Markers.prototype.initialize.apply(this, arguments);
},
/** Calculate the pixel location for the marker, create it, and
* add it to the layer's div
*
* @private
*
* @param {OpenLayers.Marker.Box} marker
*/
* add it to the layer's div
*
* @private
*
* @param {OpenLayers.Marker.Box} marker
*/
drawMarker: function(marker) {
var bounds = marker.bounds;
var topleft = this.map.getLayerPxFromLonLat(
+113
View File
@@ -0,0 +1,113 @@
/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
* See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
* for the full text of the license. */
/**
* Create a vector layer by parsing a GML file. The GML file is
* passed in as a parameter.
* @class
*
* @requires OpenLayers/Layer/Vector.js
* @requires OpenLayers/Ajax.js
*/
OpenLayers.Layer.GML = OpenLayers.Class.create();
OpenLayers.Layer.GML.prototype =
OpenLayers.Class.inherit( OpenLayers.Layer.Vector, {
/**
* Flag for whether the GML data has been loaded yet.
* @type Boolean
*/
loaded: false,
format: null,
/**
* @constructor
*
* @param {String} name
* @param {String} url URL of a GML file.
* @param {Object} options Hashtable of extra options to tag onto the layer.
* Options renderer {Object}: Typically SvgRenderer or VmlRenderer.
*/
initialize: function(name, url, options) {
var newArguments = new Array()
newArguments.push(name, options);
OpenLayers.Layer.Vector.prototype.initialize.apply(this, newArguments);
this.url = url;
},
/**
* Set the visibility flag for the layer and hide/show&redraw accordingly.
* Fire event unless otherwise specified
* GML will be loaded if the layer is being made visible for the first
* time.
*
* @param {Boolean} visible Whether or not to display the layer
* (if in range)
* @param {Boolean} noEvent
*/
setVisibility: function(visibility, noEvent) {
OpenLayers.Layer.Vector.prototype.setVisibility.apply(this, arguments);
if(this.visibility && !this.loaded){
// Load the GML
this.loadGML();
}
},
/**
* If layer is visible and GML has not been loaded, load GML, then load GML
* and call OpenLayers.Layer.Vector.moveTo() to redraw at the new location.
* @param {Object} bounds
* @param {Object} zoomChanged
* @param {Object} minor
*/
moveTo:function(bounds, zoomChanged, minor) {
OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);
// Wait until initialisation is complete before loading GML
// otherwise we can get a race condition where the root HTML DOM is
// loaded after the GML is paited.
// See http://trac.openlayers.org/ticket/404
if(this.visibility && !this.loaded){
this.loadGML();
}
},
loadGML: function() {
if (!this.loaded) {
var results = OpenLayers.loadURL(this.url, null, this, this.requestSuccess, this.requestFailure);
this.loaded = true;
}
},
/**
* Process GML after it has been loaded.
* Called by initialise() and loadUrl() after the GML has been loaded.
* @private
* @param {String} request
*/
requestSuccess:function(request) {
var doc = request.responseXML;
if (!doc || request.fileType!="XML") {
doc = request.responseText;
}
var gml = this.format ? new this.format() : new OpenLayers.Format.GML();
this.addFeatures(gml.read(doc));
},
/**
* Process a failed loading of GML.
* Called by initialise() and loadUrl() if there was a problem loading GML.
* @private
* @param {String} request
*/
requestFailure: function(request) {
alert("Error in loading GML file "+this.url);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Layer.GML"
});
+1
View File
@@ -7,6 +7,7 @@
* @class
*
* @requires OpenLayers/Layer/Markers.js
* @requires OpenLayers/Ajax.js
*/
OpenLayers.Layer.GeoRSS = OpenLayers.Class.create();
OpenLayers.Layer.GeoRSS.prototype =
+1
View File
@@ -4,6 +4,7 @@
// @requires OpenLayers/Layer/Grid.js
/**
* @class
* @requires OpenLayers/Layer/Grid.js
*/
OpenLayers.Layer.MapServer = OpenLayers.Class.create();
OpenLayers.Layer.MapServer.prototype =
+321
View File
@@ -0,0 +1,321 @@
/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
* See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
* for the full text of the license. */
/**
* @class
*
* @requires OpenLayers/Layer.js
* @requires OpenLayers/Renderer.js
*/
OpenLayers.Layer.Vector = OpenLayers.Class.create();
OpenLayers.Layer.Vector.prototype =
OpenLayers.Class.inherit(OpenLayers.Layer, {
/** @type Boolean */
isBaseLayer: false,
/** @type Boolean */
isFixed: false,
/** @type Boolean */
isVector: true,
/** @type {Array(OpenLayer.Feature.Vector)} */
features: null,
/** @type {Array(OpenLayers.Feature.Vector)} */
selectedFeatures: [],
/** @type {Boolean} */
editing: false,
/** @type {Boolean} */
editable: false,
/** @type {Boolean} */
reportError: true,
/**
* List of supported Renderer classes. Add to this list to
* add support for additional renderers. This list is ordered:
* the first renderer which returns true for the 'supported()'
* method will be used, if not defined in the 'renderer' option.
*
* @type {Array(String)}
*/
renderers: ['SVG', 'VML'],
/** @type OpenLayers.Renderer */
renderer: null,
/**
* geometryType allows you to limit the types of geometries this
* layer supports. This should be set to something like
* "OpenLayers.Geometry.Point" to limit types.
*
* @type string
*/
geometryType: null,
/** Whether the Vector Layer features have been drawn yet.
*
* @type boolean
*/
drawn: false,
/**
* @constructor
*
* @param {String} name
* @param {Object} options Hashtable of extra options to tag onto the layer.
* Options renderer {Object}: Typically SVGRenderer or VMLRenderer.
*/
initialize: function(name, options) {
OpenLayers.Layer.prototype.initialize.apply(this, arguments);
// allow user-set renderer, otherwise assign one
if (!this.renderer || !this.renderer.supported()) {
this.assignRenderer();
}
// if no valid renderer found, display error
if (!this.renderer || !this.renderer.supported()) {
this.renderer = null;
this.displayError();
}
this.features = new Array();
this.selectedFeatures = new Array();
},
/**
*
*/
destroy: function() {
OpenLayers.Layer.prototype.destroy.apply(this, arguments);
// HACK HACK -- I believe we should be iterating and
// calling feature[i].destroy() here.
this.features = null;
this.selectedFeatures = null;
this.editing = null;
this.editable = null;
if (this.renderer) {
this.renderer.destroy();
}
this.renderer = null;
this.geometryType = null;
this.drawn = null;
},
/** Iterates through the available renderer implementations and selects
* and assigns the first one whose "supported()" function returns true.
*
* @private
*
*/
assignRenderer: function() {
for (var i = 0; i < this.renderers.length; i++) {
var rendererClass = OpenLayers.Renderer[this.renderers[i]];
if (rendererClass && rendererClass.prototype.supported()) {
this.renderer = new rendererClass(this.div);
break;
}
}
},
/**
* Let the user know their browser isn't supported.
*
* @private
*
*/
displayError: function() {
if (this.reportError) {
var message = "Your browser does not support vector rendering. " +
"Currently supported renderers are:\n";
message += this.renderers.join("\n");
alert(message);
}
},
/** The layer has been added to the map.
*
* If there is no renderer set, the layer can't be used. Remove it.
* Otherwise, give the renderer a reference to the map and set its size.
*
* @param {OpenLayers.Map} map
*/
setMap: function(map) {
OpenLayers.Layer.prototype.setMap.apply(this, arguments);
if (!this.renderer) {
this.map.removeLayer(this);
} else {
this.renderer.map = this.map;
this.renderer.setSize(this.map.getSize());
}
},
/** Notify the renderer of the change in size.
*
*/
onMapResize: function() {
OpenLayers.Layer.prototype.onMapResize.apply(this, arguments);
this.renderer.setSize(this.map.getSize());
},
/** Reset the vector layer's div so that it once again is lined up with
* the map. Notify the renderer of the change of extent, and in the
* case of a change of zoom level (resolution), have the
* renderer reproject.
*
* If the layer has not yet been drawn, cycle through the layer's
* features and draw each one.
*
* @param {OpenLayers.Bounds} bounds
* @param {Boolean} zoomChanged
* @param {Boolean} dragging
*/
moveTo: function(bounds, zoomChanged, dragging) {
OpenLayers.Layer.prototype.moveTo.apply(this, arguments);
if (!dragging) {
this.div.style.left = - parseInt(this.map.layerContainerDiv.style.left) + "px";
this.div.style.top = - parseInt(this.map.layerContainerDiv.style.top) + "px";
var extent = this.map.getExtent();
this.renderer.setExtent(extent);
}
if (zoomChanged) {
this.renderer.reproject();
}
if (!this.drawn) {
this.drawn = true;
for(var i = 0; i < this.features.length; i++) {
var feature = this.features[i];
this.renderer.drawGeometry(feature.geometry, feature.style);
}
}
},
/**
* @param {Array(OpenLayers.Feature.Vector} features
*/
addFeatures: function(features) {
if (!(features instanceof Array)) {
features = [features];
}
for (var i = 0; i < features.length; i++) {
var feature = features[i];
if (this.geometryType &&
!(feature.geometry instanceof this.geometryType)) {
var throwStr = "addFeatures : component should be an " +
this.geometryType.prototype.CLASS_NAME;
throw throwStr;
}
this.features.push(feature);
//give feature reference to its layer
feature.layer = this;
if (this.drawn) {
this.renderer.drawGeometry(feature.geometry, feature.style);
}
this.onFeatureInsert(feature);
}
},
/**
* @param {Array(OpenLayers.Feature.Vector} features
*/
removeFeatures: function(features) {
if (!(features instanceof Array)) {
features = [features];
}
for (var i = 0; i < features.length; i++) {
var feature = features[i];
this.features = OpenLayers.Util.removeItem(this.features, feature);
this.renderer.eraseGeometry(feature.geometry);
}
},
/**
* @param {String} fid
* @param {Object} style
*/
redrawFeature: function(fid, style) {
for (var i = 0; i < this.features.length; i++) {
var feature = this.features[i];
if (feature.fid == fid) {
this.renderer.drawGeometry(feature.geometry, style);
}
}
},
/**
* Start editing the layer
*
* @returns Whether or not the layer is editable
* @type Boolean
*/
unlock: function() {
if(this.editable) {
this.editing = true;
}
return this.editable;
},
/**
* Stop editing the layer
*
* @return Whether or not the layer *was* editing
* HACK HACK This return value seems wierd to me.
* @type Boolean
*/
lock: function() {
if(this.editing) {
this.editing = false;
}
return this.editing;
},
/**
* Unselect the selected features
* i.e. clears the featureSelection array
* change the style back
clearSelection: function() {
var vectorLayer = this.map.vectorLayer;
for (var i = 0; i < this.map.featureSelection.length; i++) {
var featureSelection = this.map.featureSelection[i];
vectorLayer.renderer.drawGeometry(featureSelection.geometry,
vectorLayer.style);
}
this.map.featureSelection = [];
},
*/
/**
* method called when a feature is inserted.
* Does nothing by default. Override this if you
* need to do something on feature updates.
*
* @param {OpenLayers.Feature.Vector} feature
*/
onFeatureInsert: function(feature) {
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Layer.Vector"
});
+227 -115
View File
@@ -6,42 +6,45 @@
/**
* @class
*
* @requires OpenLayers/Layer/Grid.js
* @requires OpenLayers/Layer/Vector.js
* @requires OpenLayers/Layer/Markers.js
*/
OpenLayers.Layer.WFS = OpenLayers.Class.create();
OpenLayers.Layer.WFS.prototype =
OpenLayers.Class.inherit( OpenLayers.Layer.Grid,
OpenLayers.Layer.Markers, {
OpenLayers.Class.inherit( OpenLayers.Layer.Vector, OpenLayers.Layer.Markers, {
/** WFS layer is never a base layer.
*
* @type Boolean
*/
isBaseLayer: false,
buffer: 1,
/** Allow the user to specify special classes for features and tiles.
*
* This allows for easy-definition of behaviour. The defaults are
* set here, but to override it, the property should be set via
* the "options" parameter.
*/
/** @type Object */
featureClass: OpenLayers.Feature.WFS,
/** @type Object */
tileClass: OpenLayers.Tile.WFS,
/** the ratio of image/tile size to map size (this is the untiled buffer)
* @type int */
ratio: 2,
/** Hashtable of default key/value parameters
* @final @type Object */
DEFAULT_PARAMS: { service: "WFS",
version: "1.0.0",
request: "GetFeature",
typename: "docpoint"
request: "GetFeature"
},
/**
* 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
*
* @type OpenLayers.Feature
*/
featureClass: null,
/**
* Should be calculated automatically.
*
* @type Boolean
*/
vectorMode: true,
/**
* @constructor
@@ -52,21 +55,40 @@ OpenLayers.Layer.WFS.prototype =
* @param {Object} options Hashtable of extra options to tag onto the layer
*/
initialize: function(name, url, params, options) {
var newArguments = new Array();
//uppercase params
params = OpenLayers.Util.upperCaseObject(params);
newArguments.push(name, url, params, options);
OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
var newArguments = new Array();
//uppercase params
if (options == undefined) { options = {}; }
if (options.featureClass || !OpenLayers.Layer.Vector || !OpenLayers.Feature.Vector) {
this.vectorMode = false;
}
// 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=new Array()
newArguments.push(name, options);
OpenLayers.Layer.Markers.prototype.initialize.apply(this, newArguments);
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 = params;
OpenLayers.Util.applyDefaults(
this.params,
OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)
);
this.url = url;
},
@@ -74,16 +96,22 @@ OpenLayers.Layer.WFS.prototype =
*
*/
destroy: function() {
OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);
OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);
if (this.vectorMode) {
OpenLayers.Layer.Vector.prototype.destroy.apply(this, arguments);
} else {
OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);
}
},
/**
* @param {OpenLayers.Map} map
*/
setMap: function(map) {
OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);
OpenLayers.Layer.Markers.prototype.setMap.apply(this, arguments);
if (this.vectorMode) {
OpenLayers.Layer.Vector.prototype.setMap.apply(this, arguments);
} else {
OpenLayers.Layer.Markers.prototype.setMap.apply(this, arguments);
}
},
/**
@@ -92,8 +120,86 @@ OpenLayers.Layer.WFS.prototype =
* @param {Boolean} dragging
*/
moveTo:function(bounds, zoomChanged, dragging) {
OpenLayers.Layer.Grid.prototype.moveTo.apply(this, arguments);
OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);
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();
}
}
// don't load data if current zoom level doesn't match
if (this.options.minZoomLevel && 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 = { BBOX:tileBounds.toBBOX() };
url += "&" + OpenLayers.Util.getParameterString(params);
if (!this.tile) {
this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds,
url, tileSize);
this.tile.draw();
} else {
if (this.vectorMode) {
this.renderer.clear();
} else {
this.clearMarkers();
}
this.tile.destroy();
this.tile = null;
this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds,
url, tileSize);
this.tile.draw();
}
}
},
/**
@@ -112,58 +218,15 @@ OpenLayers.Layer.WFS.prototype =
}
//get all additions from superclasses
obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
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;
},
/**
* addTile creates a tile, initializes it (via 'draw' in this case), and
* adds it to the layer div.
*
* @param {OpenLayers.Bounds} bounds
*
* @returns The added OpenLayers.Tile.WFS
* @type OpenLayers.Tile.WFS
*/
addTile:function(bounds, position) {
var urls = new Array();
//add standard URL
urls.push( this.getFullRequestString() );
if (this.urls != null) {
// if there are more urls, add them.
for(var i=0; i < this.urls.length; i++) {
urls.push( this.getFullRequestString(null, this.urls[i]) );
}
}
return new this.tileClass(this, position, bounds,
urls, this.tileSize);
},
/**
* Catch changeParams and uppercase the new params to be merged in
* before calling changeParams on the super class.
*
* Once params have been changed, we will need to re-init our tiles
*
* @param {Object} newParams Hashtable of new params to use
*/
mergeNewParams:function(newParams) {
var upperParams = OpenLayers.Util.upperCaseObject(newParams);
var newArguments = [upperParams];
OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this, newArguments);
if (this.grid != null) {
this._initTiles();
}
},
/** combine the layer's url with its params and these newParams.
@@ -183,43 +246,92 @@ OpenLayers.Layer.WFS.prototype =
return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(
this, arguments);
},
/**
* @param {String} featureID
*
* @returns The Feature, found within one of the layer's tiles' features
* array, with a matching id.
* If none found or if null passed-in, returns null
* @type OpenLayers.Feature
*/
getFeature: function(featureID) {
var foundFeature = null;
if (featureID != null) {
if (this.grid) {
for(var iRow = 0; iRow < this.grid.length; iRow++) {
var row = this.grid[iRow];
for(var iCol = 0; iCol < row.length; iCol++) {
var tile = row[iCol];
for(var i=0; i < tile.features.length; i++) {
var feature = tile.features[i];
if (feature.id == featureID) {
foundFeature = feature;
}
}
}
}
}
commit: function() {
if (!this.writer) {
this.writer = new OpenLayers.Format.WFS({},this);
}
return foundFeature;
var data = this.writer.write(this.features);
var url = this.url;
if (OpenLayers.ProxyHost && this.url.startsWith("http")) {
url = OpenLayers.ProxyHost + escape(this.url);
}
var success = this.commitSuccess.bind(this);
var failure = this.commitFailure.bind(this)
//
OpenLayers.Ajax.serializeXMLToString(data);
// from prototype.js
new OpenLayers.Ajax.Request(url,
{ method: 'post',
postBody: data,
onComplete: success,
onFailure: failure
}
);
},
/**
* Called when the Ajax request returns a response
*
* @param {XmlNode} response from server
*/
commitSuccess: function(request) {
var response = request.responseText;
if (response.indexOf('SUCCESS') != -1) {
this.report('WFS Transaction: SUCCESS', response);
for(var i = 0; i < this.features.length; i++) {
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.report('WFS Transaction: FAILED', response);
}
},
/**
* Called when the Ajax request fails
*
* @param {XmlNode} response from server
*/
commitFailure: function(request) {},
/**
* Called with a 'success' message if the commit succeeded, otherwise
* a failure message, and the full text as a second parameter.
*
* @param {String} string reporting string
* @param {String} response full XML response
*/
commitReport: function(string, response) {
alert(string);
},
/**
* Refreshes all the features of the layer
*/
refresh: function() {
if (this.tile) {
if (this.vectorMode) {
this.renderer.clear();
OpenLayers.Util.clearArray(this.features);
} else {
this.clearMarkers();
OpenLayers.Util.clearArray(this.markers);
}
this.tile.draw();
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Layer.WFS"
});