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
+15 -1
View File
@@ -221,7 +221,7 @@ OpenLayers.Ajax.Request.prototype = OpenLayers.Class.inherit( OpenLayers.Ajax.Ba
['X-Requested-With', 'XMLHttpRequest',
'X-Prototype-Version', 'OpenLayers'];
if (this.options.method == 'post') {
if (this.options.method == 'post' && !this.options.postBody) {
requestHeaders.push('Content-type',
'application/x-www-form-urlencoded');
@@ -306,3 +306,17 @@ OpenLayers.Ajax.getElementsByTagNameNS = function(parentnode, nsuri, nsprefix,
parentnode.getElementsByTagNameNS(nsuri, tagname)
: parentnode.getElementsByTagName(nsprefix + ':' + tagname);
}
/**
* Wrapper function around XMLSerializer, which doesn't exist/work in
* IE/Safari. We need to come up with a way to serialize in those browser:
* for now, these browsers will just fail.
* #535, #536
*
* @param {XMLNode} xmldom xml dom to serialize
*/
OpenLayers.Ajax.serializeXMLToString = function(xmldom) {
var serializer = new XMLSerializer();
data = serializer.serializeToString(xmldom);
return data;
}
+39 -4
View File
@@ -388,7 +388,7 @@ OpenLayers.Bounds.prototype = {
* (ex.<i>"left-bottom=(5,42) right-top=(10,45)"</i>)
* @type String
*/
toString:function(){
toString:function() {
return ( "left-bottom=(" + this.left + "," + this.bottom + ")"
+ " right-top=(" + this.right + "," + this.top + ")" );
},
@@ -464,10 +464,45 @@ OpenLayers.Bounds.prototype = {
* but shifted by the passed-in x and y values
* @type OpenLayers.Bounds
*/
add:function(x, y){
add:function(x, y) {
return new OpenLayers.Bounds(this.left + x, this.bottom + y,
this.right + x, this.top + y);
},
/**
* Extend the bounds to include the point, lonlat, or bounds specified.
*
* This function assumes that left<right and bottom<top.
*
* @param {OpenLayers.Bounds|OpenLayers.LonLat|OpenLayers.Geometry.Point} object
*/
extend:function(object) {
var bounds = null;
if (object) {
switch(object.CLASS_NAME) {
case "OpenLayers.Geometry.Point":
case "OpenLayers.LonLat":
bounds = new OpenLayers.Bounds(object.lon, object.lat,
object.lon, object.lat);
break;
case "OpenLayers.Bounds":
bounds = object;
break;
}
if (bounds) {
this.left = (bounds.left < this.left) ? bounds.left
: this.left;
this.bottom = (bounds.bottom < this.bottom) ? bounds.bottom
: this.bottom;
this.right = (bounds.right > this.right) ? bounds.right
: this.right;
this.top = (bounds.top > this.top) ? bounds.top
: this.top;
}
}
},
/**
* @param {OpenLayers.LonLat} ll
@@ -781,7 +816,7 @@ OpenLayers.Element = {
* @returns Whether or not this string starts with the string passed in.
* @type Boolean
*/
String.prototype.startsWith = function(sStart){
String.prototype.startsWith = function(sStart) {
return (this.substr(0,sStart.length) == sStart);
};
@@ -791,7 +826,7 @@ String.prototype.startsWith = function(sStart){
* @returns Whether or not this string contains with the string passed in.
* @type Boolean
*/
String.prototype.contains = function(str){
String.prototype.contains = function(str) {
return (this.indexOf(str) != -1);
};
+61 -6
View File
@@ -2,11 +2,15 @@
* See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
* for the full text of the license. */
/**
* @class
*/
OpenLayers.Control = OpenLayers.Class.create();
OpenLayers.Control.TYPE_BUTTON = 1;
OpenLayers.Control.TYPE_TOGGLE = 2;
OpenLayers.Control.TYPE_TOOL = 3;
OpenLayers.Control.prototype = {
/** @type String */
@@ -19,11 +23,27 @@ OpenLayers.Control.prototype = {
/** @type DOMElement */
div: null,
/** @type OpenLayers.Pixel */
position: null,
/**
* Controls can have a 'type'. The type determines the type of interactions
* which are possible with them when they are placed into a toolbar.
* @type OpenLayers.Control.TYPES
*/
type: null,
/** @type OpenLayers.Pixel */
mouseDragStart: null,
/** This property is used for CSS related to the drawing of the Control.
* @type string
*/
displayClass: "",
/**
* @type boolean
*/
active: null,
/**
* @type OpenLayers.Handler
*/
handler: null,
/**
* @constructor
@@ -31,6 +51,10 @@ OpenLayers.Control.prototype = {
* @param {Object} options
*/
initialize: function (options) {
// We do this before the extend so that instances can override
// className in options.
this.displayClass = this.CLASS_NAME.replace("OpenLayers.", "ol").replace(".","");
OpenLayers.Util.extend(this, options);
this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
@@ -52,6 +76,9 @@ OpenLayers.Control.prototype = {
*/
setMap: function(map) {
this.map = map;
if (this.handler) {
this.handler.setMap(map);
}
},
/**
@@ -64,7 +91,7 @@ OpenLayers.Control.prototype = {
if (this.div == null) {
this.div = OpenLayers.Util.createDiv();
this.div.id = this.id;
this.div.className = 'olControl';
this.div.className = this.displayClass;
}
if (px != null) {
this.position = px.clone();
@@ -83,6 +110,34 @@ OpenLayers.Control.prototype = {
}
},
/**
* @type boolean
*/
activate: function () {
if (this.active) {
return false;
}
if (this.handler) {
this.handler.activate();
}
this.active = true;
return true;
},
/**
* @type boolean
*/
deactivate: function () {
if (this.active) {
if (this.handler) {
this.handler.deactivate();
}
this.active = false;
return true;
}
return false;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control"
};
+59
View File
@@ -0,0 +1,59 @@
/* 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/Control.js
* @requires OpenLayers/Handler/Drag.js
*/
OpenLayers.Control.DragPan = OpenLayers.Class.create();
OpenLayers.Control.DragPan.prototype =
OpenLayers.Class.inherit( OpenLayers.Control, {
/** @type OpenLayers.Control.TYPES */
type: OpenLayers.Control.TYPE_TOOL,
/**
*
*/
draw: function() {
this.handler = new OpenLayers.Handler.Drag( this,
{"move": this.panMap, "up": this.panMapDone } );
},
/**
* @param {OpenLayers.Pixel} xy Pixel of the up position
*/
panMap: function (xy) {
var deltaX = this.handler.start.x - xy.x;
var deltaY = this.handler.start.y - xy.y;
var size = this.map.getSize();
var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX,
size.h / 2 + deltaY);
var newCenter = this.map.getLonLatFromViewPortPx( newXY );
this.map.setCenter(newCenter, null, true);
// this assumes xy won't be changed inside Handler.Drag
// a safe bet for now, and saves us the extra call to clone().
this.handler.start = xy;
},
/**
* @param {OpenLayers.Pixel} xy Pixel of the up position
*/
panMapDone: function (xy) {
var deltaX = this.handler.start.x - xy.x;
var deltaY = this.handler.start.y - xy.y;
var size = this.map.getSize();
var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX,
size.h / 2 + deltaY);
var newCenter = this.map.getLonLatFromViewPortPx( newXY );
this.map.setCenter(newCenter, null, false);
// this assumes xy won't be changed inside Handler.Drag
// a safe bet for now, and saves us the extra call to clone().
this.handler.start = xy;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control.DragPan"
});
+63
View File
@@ -0,0 +1,63 @@
/* 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. */
/**
* Draws features on a vector layer when active.
*
* @class
* @requires OpenLayers/Control.js
* @requires OpenLayers/Feature/Vector.js
*/
OpenLayers.Control.DrawFeature = OpenLayers.Class.create();
OpenLayers.Control.DrawFeature.prototype =
OpenLayers.Class.inherit(OpenLayers.Control, {
/**
* @type OpenLayers.Layer.Vector
*/
layer: null,
/**
* @type {Object} The functions that are sent to the handler for callback
*/
callbacks: {},
/**
* @type {Function} Called after each feature is added
*/
featureAdded: function() {},
/**
* Used to set non-default properties on the control's handler
*
* @type Object
*/
handlerOptions: null,
/**
* @param {OpenLayers.Layer.Vector} layer
* @param {OpenLayers.Handler} handler
* @param {Object} options
*/
initialize: function(layer, handler, options) {
OpenLayers.Control.prototype.initialize.apply(this, [options]);
this.callbacks = OpenLayers.Util.extend({done: this.drawFeature},
this.callbacks);
this.layer = layer;
this.handler = new handler(this, this.callbacks, this.handlerOptions);
},
/**
*
*/
drawFeature: function(geometry) {
var feature = new OpenLayers.Feature.Vector(geometry);
this.layer.addFeatures([feature]);
this.featureAdded(feature);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control.DrawFeature"
});
+48
View File
@@ -0,0 +1,48 @@
/* 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/Control/Panel.js
* @requires OpenLayers/Control/Navigation.js
* @requires OpenLayers/Control/DrawFeature.js
*/
OpenLayers.Control.EditingToolbar = OpenLayers.Class.create();
OpenLayers.Control.EditingToolbar.prototype =
OpenLayers.Class.inherit( OpenLayers.Control.Panel, {
/**
* Create an editing toolbar for a given layer.
* @param OpenLayers.Layer.Vector layer
* @param Object options
*/
initialize: function(layer, options) {
OpenLayers.Control.Panel.prototype.initialize.apply(this, [options]);
this.addControls(
[ new OpenLayers.Control.Navigation() ]
);
var controls = [
new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}),
new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}),
new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'})
];
for (var i = 0; i < controls.length; i++) {
controls[i].featureAdded = function(feature) { feature.state = OpenLayers.State.INSERT; }
}
this.addControls(controls);
},
/**
* calls the default draw, and then activates mouse defaults.
*/
draw: function() {
var div = OpenLayers.Control.Panel.prototype.draw.apply(this, arguments);
this.activateControl(this.controls[0]);
return div;
},
CLASS_NAME: "OpenLayers.Control.EditingToolbar"
});
+8 -13
View File
@@ -7,6 +7,7 @@
* @class
*
* @requires OpenLayers/Control.js
* @requires OpenLayers/Handler/Keyboard.js
*/
OpenLayers.Control.KeyboardDefaults = OpenLayers.Class.create();
OpenLayers.Control.KeyboardDefaults.prototype =
@@ -26,16 +27,16 @@ OpenLayers.Control.KeyboardDefaults.prototype =
*
*/
draw: function() {
OpenLayers.Event.observe(document,
'keypress',
this.defaultKeyDown.bindAsEventListener(this));
this.handler = new OpenLayers.Handler.Keyboard( this, {
"keypress": this.defaultKeyPress });
this.activate();
},
/**
* @param {Event} evt
* @param {Integer} code
*/
defaultKeyDown: function (evt) {
switch(evt.keyCode) {
defaultKeyPress: function (code) {
switch(code) {
case OpenLayers.Event.KEY_LEFT:
this.map.pan(-50, 0);
break;
@@ -49,17 +50,11 @@ OpenLayers.Control.KeyboardDefaults.prototype =
this.map.pan(0, 50);
break;
case 33: // Page Up
this.map.zoomIn();
break;
case 34: // Page Down
this.map.zoomOut();
break;
}
switch(evt.charCode) {
case 43: // +
this.map.zoomIn();
break;
case 45: // -
case 34: // Page Down
this.map.zoomOut();
break;
}
+1
View File
@@ -6,6 +6,7 @@
* @class
*
* @requires OpenLayers/Control.js
* @requires OpenLayers/Control.js
*/
OpenLayers.Control.LayerSwitcher = OpenLayers.Class.create();
OpenLayers.Control.LayerSwitcher.prototype =
+4 -1
View File
@@ -2,7 +2,6 @@
* See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
* for the full text of the license. */
/**
* @class
*
@@ -12,6 +11,10 @@ OpenLayers.Control.MouseDefaults = OpenLayers.Class.create();
OpenLayers.Control.MouseDefaults.prototype =
OpenLayers.Class.inherit( OpenLayers.Control, {
/** WARNING WARNING WARNING!!!
This class is DEPRECATED in 2.4 and will be removed by 3.0.
If you need this functionality, use Control.Navigation instead!!! */
/** @type Boolean */
performedDrag: false,
+1 -1
View File
@@ -51,7 +51,7 @@ OpenLayers.Control.MousePosition.prototype =
if (!this.element) {
this.div.left = "";
this.div.top = "";
this.div.className = "olControlMousePosition";
this.div.className = this.displayClass;
this.element = this.div;
}
+4
View File
@@ -15,6 +15,10 @@ OpenLayers.Control.MouseToolbar.Y = 300;
OpenLayers.Control.MouseToolbar.prototype =
OpenLayers.Class.inherit( OpenLayers.Control.MouseDefaults, {
/** WARNING WARNING WARNING!!!
This class is DEPRECATED in 2.4 and will be removed by 3.0.
If you need this functionality, use Control.NavToolbar instead!!! */
mode: null,
buttons: null,
+37
View File
@@ -0,0 +1,37 @@
/* 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/Control/Panel.js
* @requires OpenLayers/Control/Navigation.js
* @requires OpenLayers/Control/ZoomBox.js
*/
OpenLayers.Control.NavToolbar = OpenLayers.Class.create();
OpenLayers.Control.NavToolbar.prototype =
OpenLayers.Class.inherit( OpenLayers.Control.Panel, {
/**
* Add our two mousedefaults controls.
*/
initialize: function(options) {
OpenLayers.Control.Panel.prototype.initialize.apply(this, arguments);
this.addControls([
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.ZoomBox()
]);
},
/**
* calls the default draw, and then activates mouse defaults.
*/
draw: function() {
var div = OpenLayers.Control.Panel.prototype.draw.apply(this, arguments);
this.activateControl(this.controls[0]);
return div;
},
CLASS_NAME: "OpenLayers.Control.NavToolbar"
});
+80
View File
@@ -0,0 +1,80 @@
/* 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/Control/ZoomBox.js
* @requires OpenLayers/Control/DragPan.js
* @requires OpenLayers/Handler/MouseWheel.js
*/
OpenLayers.Control.Navigation = OpenLayers.Class.create();
OpenLayers.Control.Navigation.prototype =
OpenLayers.Class.inherit( OpenLayers.Control, {
/** @type OpenLayers.Control.ZoomBox */
dragPan: null,
/** @type OpenLayers.Control.ZoomBox */
zoomBox: null,
/** @type OpenLayers.Handler.MouseWheel */
wheelHandler: null,
activate: function() {
this.dragPan.activate();
this.wheelHandler.activate();
this.zoomBox.activate();
return OpenLayers.Control.prototype.activate.apply(this,arguments);
},
deactivate: function() {
this.zoomBox.deactivate();
this.dragPan.deactivate();
this.wheelHandler.deactivate();
return OpenLayers.Control.prototype.deactivate.apply(this,arguments);
},
draw: function() {
this.map.events.register( "dblclick", this, this.defaultDblClick );
this.dragPan = new OpenLayers.Control.DragPan({map: this.map});
this.zoomBox = new OpenLayers.Control.ZoomBox(
{map: this.map, keyMask: OpenLayers.Handler.MOD_SHIFT});
this.dragPan.draw();
this.zoomBox.draw();
this.wheelHandler = new OpenLayers.Handler.MouseWheel(
this, {"up" : this.wheelUp,
"down": this.wheelDown} );
this.activate();
},
/**
* @param {Event} evt
*/
defaultDblClick: function (evt) {
var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );
this.map.setCenter(newCenter, this.map.zoom + 1);
OpenLayers.Event.stop(evt);
return false;
},
/** User spun scroll wheel up
*
*/
wheelUp: function(evt) {
this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),
this.map.getZoom() + 1);
},
/** User spun scroll wheel down
*
*/
wheelDown: function(evt) {
this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),
this.map.getZoom() - 1);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control.Navigation"
});
+9 -7
View File
@@ -10,6 +10,8 @@
* @class
*
* @requires OpenLayers/Control.js
* @requires OpenLayers/BaseTypes.js
* @requires OpenLayers/Events.js
*/
OpenLayers.Control.OverviewMap = OpenLayers.Class.create();
@@ -31,7 +33,7 @@ OpenLayers.Control.OverviewMap.prototype =
/**
* The overvew map size in pixels. Note that this is the size of the map
* itself - the element that contains the map (class name
* itself - the element that contains the map (default class name
* olControlOverviewMapElement) may have padding or other style attributes
* added via CSS.
* @type OpenLayers.Size
@@ -93,7 +95,7 @@ OpenLayers.Control.OverviewMap.prototype =
// create overview map DOM elements
this.element = document.createElement('div');
this.element.className = 'olControlOverviewMapElement';
this.element.className = this.displayClass + 'Element';
this.element.style.display = 'none';
this.mapDiv = document.createElement('div');
@@ -110,7 +112,7 @@ OpenLayers.Control.OverviewMap.prototype =
this.extentRectangle.style.backgroundImage = 'url(' +
OpenLayers.Util.getImagesLocation() +
'/blank.png)';
this.extentRectangle.className = 'olControlOverviewMapExtentRectangle';
this.extentRectangle.className = this.displayClass+'ExtentRectangle';
this.mapDiv.appendChild(this.extentRectangle);
this.element.appendChild(this.mapDiv);
@@ -148,18 +150,18 @@ OpenLayers.Control.OverviewMap.prototype =
// Optionally add min/max buttons if the control will go in the
// map viewport.
if(!this.outsideViewport) {
this.div.className = 'olControlOverviewMapContainer';
this.div.className = this.displayClass + 'Container';
var imgLocation = OpenLayers.Util.getImagesLocation();
// maximize button div
var img = imgLocation + 'layer-switcher-maximize.png';
this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv(
'olControlOverviewMapMaximizeButton',
this.displayClass + 'MaximizeButton',
null,
new OpenLayers.Size(18,18),
img,
'absolute');
this.maximizeDiv.style.display = 'none';
this.maximizeDiv.className = 'olControlOverviewMapMaximizeButton';
this.maximizeDiv.className = this.displayClass + 'MaximizeButton';
OpenLayers.Event.observe(this.maximizeDiv,
'click',
this.maximizeControl.bindAsEventListener(this));
@@ -179,7 +181,7 @@ OpenLayers.Control.OverviewMap.prototype =
img,
'absolute');
this.minimizeDiv.style.display = 'none';
this.minimizeDiv.className = 'olControlOverviewMapMinimizeButton';
this.minimizeDiv.className = this.displayClass + 'MinimizeButton';
OpenLayers.Event.observe(this.minimizeDiv,
'click',
this.minimizeControl.bindAsEventListener(this));
+132
View File
@@ -0,0 +1,132 @@
/* 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/Control.js
*/
OpenLayers.Control.Panel = OpenLayers.Class.create();
OpenLayers.Control.Panel.prototype =
OpenLayers.Class.inherit( OpenLayers.Control, {
/**
* @type Array(OpenLayers.Control)
*/
controls: null,
/**
* The control which is activated when the control is activated (turned
* on), which also happens at instantiation.
* @type OpenLayers.Control
*/
defaultControl: null,
/**
* @constructor
*
* @param {DOMElement} element
* @param {String} base
*/
initialize: function(element) {
OpenLayers.Control.prototype.initialize.apply(this, arguments);
this.controls = [];
},
activate: function() {
OpenLayers.Control.prototype.activate.apply(this, arguments);
for(var i = 0; i < this.controls.length; i++) {
if (this.controls[i] == this.defaultControl) {
this.controls[i].activate();
}
}
this.redraw();
},
deactivate: function() {
OpenLayers.Control.prototype.deactivate.apply(this, arguments);
for(var i = 0; i < this.controls.length; i++) {
this.controls[i].deactivate();
}
this.redraw();
},
/**
* @type DOMElement
*/
draw: function() {
OpenLayers.Control.prototype.draw.apply(this, arguments);
for (var i = 0; i < this.controls.length; i++) {
this.map.addControl(this.controls[i]);
this.controls[i].deactivate();
}
this.activate();
return this.div;
},
/**
* @private
*/
redraw: function() {
this.div.innerHTML = "";
if (this.active) {
for (var i = 0; i < this.controls.length; i++) {
var element = document.createElement("div");
var textNode = document.createTextNode(" ");
if (this.controls[i].active) {
element.className = this.controls[i].displayClass + "ItemActive";
} else {
element.className = this.controls[i].displayClass + "ItemInactive";
}
var onClick = function (ctrl, evt) {
OpenLayers.Event.stop(evt ? evt : window.event);
this.activateControl(ctrl);
};
var control = this.controls[i];
element.onclick = onClick.bind(this, control);
element.onmousedown = OpenLayers.Event.stop.bindAsEventListener();
element.onmouseup = OpenLayers.Event.stop.bindAsEventListener();
this.div.appendChild(element);
}
}
},
activateControl: function (control) {
if (!this.active) { return false; }
if (control.type == OpenLayers.Control.TYPE_BUTTON) {
control.trigger();
return;
}
for (var i = 0; i < this.controls.length; i++) {
if (this.controls[i] == control) {
control.activate();
} else {
this.controls[i].deactivate();
}
}
this.redraw();
},
/**
* To build a toolbar, you add a set of controls to it. addControls
* lets you add a single control or a list of controls to the
* Control Panel.
* @param OpenLayers.Control
*/
addControls: function(controls) {
if (!(controls instanceof Array)) {
controls = [controls];
}
this.controls = this.controls.concat(controls);
if (this.map) { // map.addControl() has already been called on the panel
for (var i = 0; i < controls.length; i++) {
map.addControl(controls[i]);
controls[i].deactivate();
}
this.redraw();
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control.Panel"
});
+1 -1
View File
@@ -59,7 +59,7 @@ OpenLayers.Control.Permalink.prototype =
OpenLayers.Control.prototype.draw.apply(this, arguments);
if (!this.element) {
this.div.className = 'olControlPermalink';
this.div.className = this.displayClass;
this.element = document.createElement("a");
this.element.style.fontSize="smaller";
this.element.innerHTML = "Permalink";
+1 -1
View File
@@ -32,7 +32,7 @@ OpenLayers.Control.Scale.prototype =
OpenLayers.Control.prototype.draw.apply(this, arguments);
if (!this.element) {
this.element = document.createElement("div");
this.div.className = "olControlScale";
this.div.className = this.displayClass;
this.element.style.fontSize="smaller";
this.div.appendChild(this.element);
}
+106
View File
@@ -0,0 +1,106 @@
/* 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. */
/**
* Draws features on a vector layer when active.
*
* @class
* @requires OpenLayers/Control.js
* @requires OpenLayers/Feature/Vector.js
*/
OpenLayers.Control.SelectFeature = OpenLayers.Class.create();
OpenLayers.Control.SelectFeature.prototype =
OpenLayers.Class.inherit(OpenLayers.Control, {
/**
* @type {OpenLayers.Layer.Vector}
*/
layer: null,
/**
* @type {OpenLayers.Handler.Select}
*/
handler: null,
/**
* @type {Object} The functions that are sent to the handler for callback
*/
callbacks: {},
/**
* @type {Object} Hash of styles
*/
selectStyle: OpenLayers.Feature.Vector.style['select'],
/**
* @type {Object} Hash of styles
* @private
*/
originalStyle: null,
/**
* @type {Boolean} Allow selection of multiple geometries
*/
multiple: false,
/**
* @param {OpenLayers.Layer.Vector} layer
* @param {OpenLayers.Handler} handler
* @param {Object} options
*/
initialize: function(layer, options) {
OpenLayers.Control.prototype.initialize.apply(this, [options]);
this.callbacks = OpenLayers.Util.extend({down: this.downFeature},
this.callbacks);
this.layer = layer;
this.handler = new OpenLayers.Handler.Select(this, layer, this.callbacks);
},
/**
*
*/
downFeature: function(geometry) {
// Store feature style for restoration later
if(geometry.feature.originalStyle == null) {
geometry.feature.originalStyle = geometry.feature.style;
}
if (this.multiple) {
if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, geometry.feature) > -1) {
this.layer.renderer.drawGeometry(geometry, geometry.feature.originalStyle);
OpenLayers.Util.removeItem(this.layer.selectedFeatures, geometry.feature);
} else {
this.layer.selectedFeatures.push(geometry.feature);
this.layer.renderer.drawGeometry(geometry, this.selectStyle);
}
} else {
if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, geometry.feature) > -1) {
this.layer.renderer.drawGeometry(geometry, geometry.feature.originalStyle);
OpenLayers.Util.removeItem(this.layer.selectedFeatures, geometry.feature);
} else {
if (this.layer.selectedFeatures) {
for (var i = 0; i < this.layer.selectedFeatures.length; i++) {
this.layer.renderer.drawGeometry(this.layer.selectedFeatures[i].geometry, this.layer.selectedFeatures[i].originalStyle);
}
OpenLayers.Util.clearArray(this.layer.selectedFeatures);
}
this.layer.selectedFeatures.push(geometry.feature);
this.layer.renderer.drawGeometry(geometry, this.selectStyle);
}
}
},
/** Set the map property for the control.
*
* @param {OpenLayers.Map} map
*/
setMap: function(map) {
this.handler.setMap(map);
OpenLayers.Control.prototype.setMap.apply(this, arguments);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control.SelectFeature"
});
+42
View File
@@ -0,0 +1,42 @@
/* 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/Control.js
* @requires OpenLayers/Handler/Box.js
*/
OpenLayers.Control.ZoomBox = OpenLayers.Class.create();
OpenLayers.Control.ZoomBox.prototype =
OpenLayers.Class.inherit( OpenLayers.Control, {
/** @type OpenLayers.Control.TYPE_* */
type: OpenLayers.Control.TYPE_TOOL,
/**
*
*/
draw: function() {
this.handler = new OpenLayers.Handler.Box( this,
{done: this.zoomBox}, {keyMask: this.keyMask} );
},
zoomBox: function (position) {
if (position instanceof OpenLayers.Bounds) {
var minXY = this.map.getLonLatFromPixel(
new OpenLayers.Pixel(position.left, position.bottom));
var maxXY = this.map.getLonLatFromPixel(
new OpenLayers.Pixel(position.right, position.top));
var bounds = new OpenLayers.Bounds(minXY.lon, minXY.lat,
maxXY.lon, maxXY.lat);
this.map.zoomToExtent(bounds);
} else { // it's a pixel
this.map.setCenter(this.map.getLonLatFromPixel(position),
this.map.getZoom() + 1);
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control.ZoomBox"
});
+24
View File
@@ -0,0 +1,24 @@
/* 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
*
* Imlements a very simple button control.
* @requires OpenLayers/Control.js
*/
OpenLayers.Control.ZoomToMaxExtent = OpenLayers.Class.create();
OpenLayers.Control.ZoomToMaxExtent.prototype =
OpenLayers.Class.inherit( OpenLayers.Control, {
/** @type OpenLayers.Control.TYPE_* */
type: OpenLayers.Control.TYPE_BUTTON,
trigger: function() {
if (this.map) {
this.map.zoomToMaxExtent();
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control.ZoomToMaxExtent"
});
+15
View File
@@ -227,6 +227,21 @@ OpenLayers.Events.prototype = {
}
}
},
// TODO: get rid of this in 3.0
// Decide whether listeners should be called in the order they were
// registered or in reverse order.
registerPriority: function (type, obj, func) {
if (func != null) {
if (obj == null) {
obj = this.object;
}
var listeners = this.listeners[type];
if (listeners != null) {
listeners.unshift( {obj: obj, func: func} );
}
}
},
/**
* @param {String} type
+2
View File
@@ -7,6 +7,7 @@
* @class
*
* @requires OpenLayers/Util.js
* @requires OpenLayers/Marker.js
*/
OpenLayers.Feature = OpenLayers.Class.create();
OpenLayers.Feature.prototype= {
@@ -151,5 +152,6 @@ OpenLayers.Feature.prototype= {
this.popup.destroy()
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Feature"
};
+298
View File
@@ -0,0 +1,298 @@
/* 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. */
// TRASH THIS
OpenLayers.State = {
/** states */
UNKNOWN: 'Unknown',
INSERT: 'Insert',
UPDATE: 'Update',
DELETE: 'Delete'
}
/**
* @class
*
* @requires OpenLayers/Feature.js
* @requires OpenLayers/Util.js
*/
OpenLayers.Feature.Vector = OpenLayers.Class.create();
OpenLayers.Feature.Vector.prototype =
OpenLayers.Class.inherit( OpenLayers.Feature, {
/** @type String */
fid: null,
/** @type OpenLayers.Geometry */
geometry:null,
/** @type array */
attributes: {},
/** @type strinng */
state: null,
/** @type Object */
style: null,
/**
* Create a vector feature.
* @constructor
*
* @param {OpenLayers.Geometry} geometry
* @param {Object} data
*/
initialize: function(geometry, data, style) {
OpenLayers.Feature.prototype.initialize.apply(this, [null, null, data]);
this.lonlat = null;
this.setGeometry(geometry);
this.state = null;
if (data) {
OpenLayers.Util.extend(this.attributes, data);
}
this.style = style ? style : OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
},
/**
* @returns An exact clone of this OpenLayers.Feature
* @type OpenLayers.Feature
*/
clone: function (obj) {
if (obj == null) {
obj = new OpenLayers.Feature(null, this.geometry.clone(), this.data);
}
// catch any randomly tagged-on properties
OpenLayers.Util.applyDefaults(obj, this);
return obj;
},
/**
*
*/
destroy: function() {
this.geometry = null;
OpenLayers.Feature.prototype.destroy.apply(this, arguments);
},
/**
* HACK - we need to rewrite this for non-point geometry
* @returns null - we need to rewrite this for non-point geometry
* @type Boolean
*/
onScreen:function() {
return null;
},
/**
*
* HACK - we need to decide if all vector features should be able to
* create markers
*
* @returns null
*
* @type OpenLayers.Marker
*/
createMarker: function() {
return null;
},
/**
* HACK - we need to decide if all vector features should be able to
* delete markers
*
* If user overrides the createMarker() function, s/he should be able
* to also specify an alternative function for destroying it
*/
destroyMarker: function() {
// pass
},
/**
* HACK - we need to decide if all vector features should be able to
* create popups
*
* @returns null
*/
createPopup: function() {
return null;
},
/**
* Set a feature id to the feature
*
* @param {String} feature id to set
*/
setFid: function(fid) {
this.fid = fid;
},
/**
* Set a geometry to the feature
*
* @param {OpenLayers.Geometry} geometry to set
* @param {Boolean} recurse Recursively set feature (for components)
*/
setGeometry: function(geometry, recurse) {
if(geometry) {
this.geometry = geometry;
this.geometry.feature = this;
if (recurse != false) {
this._setGeometryFeatureReference(this.geometry, this);
}
}
},
/**
* Sets recursively the reference to the feature in the geometry
*
* @param {OpenLayers.Geometry}
* @param {OpenLayers.Feature}
*/
_setGeometryFeatureReference: function(geometry, feature) {
geometry.feature = feature;
if (geometry.components) {
for (var i = 0; i < geometry.components.length; i++) {
this._setGeometryFeatureReference(geometry.components[i], feature);
}
}
},
/**
* Adds attributes an attributes object to the feature.
* (should not be in geometry but in feature class)
*
* @param {Attributes} attributes
*/
setAttributes: function(attributes) {
this.attributes=attributes;
},
/**
* @param {OpenLayers.LonLat} lonlat
* @param {float} toleranceLon Optional tolerance in Geometric Coords
* @param {float} toleranceLat Optional tolerance in Geographic Coords
*
* @returns Whether or not the feature is at the specified location
* @type Boolean
*/
atPoint: function(lonlat, toleranceLon, toleranceLat) {
var atPoint = false;
if(this.geometry) {
atPoint = this.geometry.atPoint(lonlat, toleranceLon,
toleranceLat);
}
return atPoint;
},
/**
*
* HACK - we need to decide if all vector features should be able to
* delete popups
*/
destroyPopup: function() {
// pass
},
/**
* Sets the new state
* @param {String} state
*/
toState: function(state) {
if (state == OpenLayers.State.UPDATE) {
switch (this.state) {
case OpenLayers.State.UNKNOWN:
case OpenLayers.State.DELETE:
this.state = state;
break;
case OpenLayers.State.UPDATE:
case OpenLayers.State.INSERT:
break;
}
} else if (state == OpenLayers.State.INSERT) {
switch (this.state) {
case OpenLayers.State.UNKNOWN:
break;
default:
this.state = state;
break;
}
} else if (state == OpenLayers.State.DELETE) {
switch (this.state) {
case OpenLayers.State.INSERT:
// the feature should be destroyed
break;
case OpenLayers.State.DELETE:
break;
case OpenLayers.State.UNKNOWN:
case OpenLayers.State.UPDATE:
this.state = state;
break;
}
} else if (state == OpenLayers.State.UNKNOWN) {
this.state = state;
}
},
destroy: function() {
},
CLASS_NAME: "OpenLayers.Feature.Vector"
});
// styles for feature rendering
OpenLayers.Feature.Vector.style = {
'default': {
fillColor: "#ee9900",
fillOpacity: 0.4,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "#ee9900",
strokeOpacity: 1,
strokeWidth: 1,
hoverStrokeColor: "red",
hoverStrokeOpacity: 1,
hoverStrokeWidth: 0.2,
pointRadius: 6,
hoverPointRadius: 1,
hoverPointUnit: "%",
pointerEvents: "visiblePainted"
},
'select': {
fillColor: "blue",
fillOpacity: 0.4,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "blue",
strokeOpacity: 1,
strokeWidth: 2,
hoverStrokeColor: "red",
hoverStrokeOpacity: 1,
hoverStrokeWidth: 0.2,
pointRadius: 6,
hoverPointRadius: 1,
hoverPointUnit: "%",
pointerEvents: "visiblePainted"
},
'temporary': {
fillColor: "yellow",
fillOpacity: 0.2,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "yellow",
strokeOpacity: 1,
strokeWidth: 4,
hoverStrokeColor: "red",
hoverStrokeOpacity: 1,
hoverStrokeWidth: 0.2,
pointRadius: 6,
hoverPointRadius: 1,
hoverPointUnit: "%",
pointerEvents: "visiblePainted"
}
};
+33
View File
@@ -0,0 +1,33 @@
/* 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. */
/**
* Base class for format reading/writing.
* @requires OpenLayers/Util.js
*/
OpenLayers.Format = OpenLayers.Class.create();
OpenLayers.Format.prototype = {
initialize: function(options) {
OpenLayers.Util.extend(this, options);
},
/**
* Read data from a string, and return a list of features.
*
* @param {string} data data to read/parse.
*/
read: function(data) {
alert("Read not implemented.");
},
/**
* Accept Feature Collection, and return a string.
*
* @param {Array} List of features to serialize into a string.
*/
write: function(features) {
alert("Write not implemented.");
}
};
+433
View File
@@ -0,0 +1,433 @@
/* 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. */
/**
* Read/WRite GML.
* @requires OpenLayers/Format.js
* @requires OpenLayers/Feature/Vector.js
* @requires OpenLayers/Ajax.js
* @requires OpenLayers/Geometry.js
*/
OpenLayers.Format.GML = OpenLayers.Class.create();
OpenLayers.Format.GML.prototype =
OpenLayers.Class.inherit( OpenLayers.Format, {
featureNS: "http://mapserver.gis.umn.edu/mapserver",
featureName: "featureMember",
layerName: "features",
geometryName: "geometry",
collectionName: "FeatureCollection",
gmlns: "http://www.opengis.net/gml",
/**
* Extract attributes from GML. Most of the time,
* this is a significant time usage, due to the need
* to recursively descend the XML to search for attributes.
*
* @type Boolean */
extractAttributes: true,
/**
* Read data from a string, and return a list of features.
*
* @param {string|XMLNode} data data to read/parse.
*/
read: function(data) {
if (typeof data == "string") {
data = OpenLayers.parseXMLString(data);
}
var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data, this.gmlns, "gml", this.featureName);
if (featureNodes.length == 0) { return []; }
// Determine dimension of the FeatureCollection. Ie, dim=2 means (x,y) coords
// dim=3 means (x,y,z) coords
// GML3 can have 2 or 3 dimensions. GML2 only 2.
var dim;
var coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(featureNodes[0], this.gmlns, "gml", "posList");
if (coordNodes.length == 0) {
coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(featureNodes[0], this.gmlns, "gml", "pos");
}
if (coordNodes.length > 0) {
dim = coordNodes[0].getAttribute("srsDimension");
}
this.dim = (dim == "3" || dim == 3) ? 3 : 2;
var features = [];
// Process all the featureMembers
for (var i = 0; i < featureNodes.length; i++) {
var feature = this.parseFeature(featureNodes[i]);
if (feature) {
features.push(feature);
}
}
return features;
},
/**
* This function is the core of the GML parsing code in OpenLayers.
* It creates the geometries that are then attached to the returned
* feature, and calls parseAttributes() to get attribute data out.
* @param DOMElement xmlNode
*/
parseFeature: function(xmlNode) {
var geom;
var p; // [points,bounds]
var feature = new OpenLayers.Feature.Vector();
if (xmlNode.firstChild.attributes && xmlNode.firstChild.attributes['fid']) {
feature.fid = xmlNode.firstChild.attributes['fid'].nodeValue;
}
// match MultiPolygon
if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "MultiPolygon").length != 0) {
var multipolygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "MultiPolygon")[0];
geom = new OpenLayers.Geometry.MultiPolygon();
var polygons = OpenLayers.Ajax.getElementsByTagNameNS(multipolygon,
this.gmlns, "gml", "Polygon");
for (var i = 0; i < polygons.length; i++) {
polygon = this.parsePolygonNode(polygons[i],geom);
geom.addComponents(polygon);
}
}
// match MultiLineString
else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "MultiLineString").length != 0) {
var multilinestring = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "MultiLineString")[0];
geom = new OpenLayers.Geometry.MultiLineString();
var lineStrings = OpenLayers.Ajax.getElementsByTagNameNS(multilinestring, this.gmlns, "gml", "LineString");
for (var i = 0; i < lineStrings.length; i++) {
p = this.parseCoords(lineStrings[i]);
if(p.points){
var lineString = new OpenLayers.Geometry.LineString(p.points);
geom.addComponents(lineString);
// TBD Bounds only set for one of multiple geometries
}
}
}
// match MultiPoint
else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "MultiPoint").length != 0) {
var multiPoint = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "MultiPoint")[0];
geom = new OpenLayers.Geometry.MultiPoint();
var points = OpenLayers.Ajax.getElementsByTagNameNS(multiPoint, this.gmlns, "gml", "Point");
for (var i = 0; i < points.length; i++) {
p = this.parseCoords(points[i]);
geom.addComponents(p.points[0]);
// TBD Bounds only set for one of multiple geometries
}
}
// match Polygon
else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "Polygon").length != 0) {
var polygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "Polygon")[0];
geom = this.parsePolygonNode(polygon);
}
// match LineString
else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "LineString").length != 0) {
var lineString = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "LineString")[0];
p = this.parseCoords(lineString);
if (p.points) {
geom = new OpenLayers.Geometry.LineString(p.points);
// TBD Bounds only set for one of multiple geometries
}
}
// match Point
else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "Point").length != 0) {
var point = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.gmlns, "gml", "Point")[0];
p = this.parseCoords(point);
if (p.points) {
geom = p.points[0];
// TBD Bounds only set for one of multiple geometries
}
}
feature.setGeometry(geom, false);
if (this.extractAttributes) {
feature.attributes = this.parseAttributes(xmlNode);
}
return feature;
},
/**
* recursive function parse the attributes of a GML node.
* Searches for any child nodes which aren't geometries,
* and gets their value.
* @param DOMElement xmlNode
*/
parseAttributes: function(xmlNode) {
var nodes = xmlNode.childNodes;
var attributes = {};
for(var i = 0; i < nodes.length; i++) {
var name = nodes[i].nodeName;
var value = OpenLayers.Util.getXmlNodeValue(nodes[i]);
// Ignore Geometry attributes
// match ".//gml:pos|.//gml:posList|.//gml:coordinates"
if((name.search(":pos")!=-1)
||(name.search(":posList")!=-1)
||(name.search(":coordinates")!=-1)){
continue;
}
// Check for a leaf node
if((nodes[i].childNodes.length == 1 && nodes[i].childNodes[0].nodeName == "#text")
|| (nodes[i].childNodes.length == 0 && nodes[i].nodeName!="#text")) {
attributes[name] = value;
}
OpenLayers.Util.extend(attributes, this.parseAttributes(nodes[i]))
}
return attributes;
},
/**
*
* @param {XMLNode} xmlNode
*
* @return {OpenLayers.Geometry.Polygon} polygon geometry
*/
parsePolygonNode: function(polygonNode) {
var linearRings = OpenLayers.Ajax.getElementsByTagNameNS(polygonNode,
this.gmlns, "gml", "LinearRing");
var rings = [];
var p;
var polyBounds;
for (var i = 0; i < linearRings.length; i++) {
p = this.parseCoords(linearRings[i]);
ring1 = new OpenLayers.Geometry.LinearRing(p.points);
rings.push(ring1);
}
var poly = new OpenLayers.Geometry.Polygon(rings);
return poly;
},
/**
* Extract Geographic coordinates from an XML node.
* @private
* @param {XMLNode} xmlNode
*
* @return an array of OpenLayers.Geometry.Point points.
* @type Array
*/
parseCoords: function(xmlNode) {
var x, y, left, bottom, right, top, bounds;
var p = []; // return value = [points,bounds]
if (xmlNode) {
p.points = [];
// match ".//gml:pos|.//gml:posList|.//gml:coordinates"
// Note: GML2 coordinates are of the form:x y,x y,x y
// GML2 can also be of the form <coord><x>1</x><y>2</y></coord>
// GML3 posList is of the form:x y x y. OR x y z x y z.
// GML3 Line or Polygon
var coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "posList");
// GML3 Point
if (coordNodes.length == 0) {
coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "pos");
}
// GML2
if (coordNodes.length == 0) {
coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "coordinates");
}
// TBD: Need to handle an array of coordNodes not just coordNodes[0]
var coordString = OpenLayers.Util.getXmlNodeValue(coordNodes[0]);
// Extract an array of Numbers from CoordString
var nums = (coordString) ? coordString.split(/[, \n\t]+/) : [];
// Remove elements caused by leading and trailing white space
while (nums[0] == "")
nums.shift();
while (nums[nums.length-1] == "")
nums.pop();
for(i = 0; i < nums.length; i = i + this.dim) {
x = parseFloat(nums[i]);
y = parseFloat(nums[i+1]);
p.points.push(new OpenLayers.Geometry.Point(x, y));
}
}
return p;
},
/**
* Accept Feature Collection, and return a string.
*
* @param {Array} List of features to serialize into a string.
*/
write: function(features) {
var featureCollection = document.createElementNS("http://www.opengis.net/wfs", "wfs:" + this.collectionName);
for (var i=0; i < features.length; i++) {
featureCollection.appendChild(this.createFeatureXML(features[i]));
}
return featureCollection;
},
/**
* Accept an OpenLayers.Feature.Vector, and build a geometry for it.
*
* @param OpenLayers.Feature.Vector feature
* @returns DOMElement
*/
createFeatureXML: function(feature) {
var geometryNode = this.buildGeometryNode(feature.geometry);
var geomContainer = document.createElementNS(this.featureNS, "feature:"+this.geometryName);
geomContainer.appendChild(geometryNode);
var featureNode = document.createElementNS(this.gmlns, "gml:" + this.featureName);
var featureContainer = document.createElementNS(this.featureNS, "feature:"+this.layerName);
featureContainer.appendChild(geomContainer);
for(var attr in feature.attributes) {
var attrText = document.createTextNode(feature.attributes[attr]);
var nodename = attr;
if (attr.search(":") != -1) {
nodename = attr.split(":")[1];
}
var attrContainer = document.createElementNS(this.featureNS, "feature:"+nodename);
attrContainer.appendChild(attrText);
featureContainer.appendChild(attrContainer);
}
featureNode.appendChild(featureContainer);
return featureNode;
},
/**
* builds a GML file with a given geometry
*
* @param {OpenLayers.Geometry} geometry
*/
buildGeometryNode: function(geometry) {
// TBD test if geoserver can be given a Multi-geometry for a simple-geometry data store
// ie if multipolygon can be sent for a polygon feature type
var gml = "";
// match MultiPolygon or Polygon
if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
|| geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
gml = document.createElementNS(this.gmlns, 'gml:MultiPolygon');
// TBD retrieve the srs from layer
// srsName is non-standard, so not including it until it's right.
//gml.setAttribute("srsName", "http://www.opengis.net/gml/srs/epsg.xml#4326");
var polygonMember = document.createElementNS(this.gmlns, 'gml:polygonMember');
var polygon = document.createElementNS(this.gmlns, 'gml:Polygon');
var outerRing = document.createElementNS(this.gmlns, 'gml:outerBoundaryIs');
var linearRing = document.createElementNS(this.gmlns, 'gml:LinearRing');
// TBD manage polygons with holes
linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));
outerRing.appendChild(linearRing);
polygon.appendChild(outerRing);
polygonMember.appendChild(polygon);
gml.appendChild(polygonMember);
}
// match MultiLineString or LineString
else if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString"
|| geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
gml = document.createElementNS(this.gmlns, 'gml:MultiLineString');
// TBD retrieve the srs from layer
// srsName is non-standard, so not including it until it's right.
//gml.setAttribute("srsName", "http://www.opengis.net/gml/srs/epsg.xml#4326");
var lineStringMember = document.createElementNS(this.gmlns, 'gml:lineStringMember');
var lineString = document.createElementNS(this.gmlns, 'gml:LineString');
lineString.appendChild(this.buildCoordinatesNode(geometry));
lineStringMember.appendChild(lineString);
gml.appendChild(lineStringMember);
}
// match MultiPoint or Point
else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {
// TBD retrieve the srs from layer
// srsName is non-standard, so not including it until it's right.
//gml.setAttribute("srsName", "http://www.opengis.net/gml/srs/epsg.xml#4326");
gml = document.createElementNS(this.gmlns, 'gml:MultiPoint');
var parts = "";
if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {
parts = geometry.components;
} else {
parts = [geometry];
}
for (var i = 0; i < parts.length; i++) {
var pointMember = document.createElementNS(this.gmlns, 'gml:pointMember');
var point = document.createElementNS(this.gmlns, 'gml:Point');
point.appendChild(this.buildCoordinatesNode(parts[i]));
pointMember.appendChild(point);
gml.appendChild(pointMember);
}
}
return gml;
},
/**
* builds the coordinates XmlNode
* <gml:coordinates decimal="." cs="," ts=" ">...</gml:coordinates>
*
* @param {OpenLayers.Geometry} geometry
* @return {XmlNode} created xmlNode
*/
buildCoordinatesNode: function(geometry) {
var coordinatesNode = document.createElementNS(this.gmlns, "gml:coordinates");
coordinatesNode.setAttribute("decimal", ".");
coordinatesNode.setAttribute("cs", ",");
coordinatesNode.setAttribute("ts", " ");
var points = null;
if (geometry.components) {
points = geometry.components;
}
var path = "";
if (points) {
for (var i = 0; i < points.length; i++) {
path += points[i].x + "," + points[i].y + " ";
}
} else {
path += geometry.x + "," + geometry.y + " ";
}
var txtNode = document.createTextNode(path);
coordinatesNode.appendChild(txtNode);
return coordinatesNode;
}
});
+107
View File
@@ -0,0 +1,107 @@
/* 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. */
/**
* Write-only GeoRSS.
* @requires OpenLayers/Format.js
*/
OpenLayers.Format.GeoRSS = OpenLayers.Class.create();
OpenLayers.Format.GeoRSS.prototype =
OpenLayers.Class.inherit( OpenLayers.Format, {
rssns: "http://backend.userland.com/rss2",
featureNS: "http://mapserver.gis.umn.edu/mapserver",
georssns: "http://www.georss.org/georss",
/**
* Accept Feature Collection, and return a string.
*
* @param {Array} List of features to serialize into a string.
*/
write: function(features) {
var featureCollection = document.createElementNS(this.rssns, "rss");
for (var i=0; i < features.length; i++) {
featureCollection.appendChild(this.createFeatureXML(features[i]));
}
return featureCollection;
},
/**
* Accept an OpenLayers.Feature.Vector, and build a geometry for it.
*
* @param OpenLayers.Feature.Vector feature
* @returns DOMElement
*/
createFeatureXML: function(feature) {
var geometryNode = this.buildGeometryNode(feature.geometry);
var featureNode = document.createElementNS(this.rssns, "item");
var titleNode = document.createElementNS(this.rssns, "title");
titleNode.appendChild(document.createTextNode(feature.attributes.title ? feature.attributes.title : ""));
var descNode = document.createElementNS(this.rssns, "description");
descNode.appendChild(document.createTextNode(feature.attributes.description ? feature.attributes.description : ""));
featureNode.appendChild(titleNode);
featureNode.appendChild(descNode);
for(var attr in feature.attributes) {
var attrText = document.createTextNode(feature.attributes[attr]);
var nodename = attr;
if (attr.search(":") != -1) {
nodename = attr.split(":")[1];
}
var attrContainer = document.createElementNS(this.featureNS, "feature:"+nodename);
attrContainer.appendChild(attrText);
featureNode.appendChild(attrContainer);
}
featureNode.appendChild(geometryNode);
return featureNode;
},
/**
* builds a GeoRSS node with a given geometry
*
* @param {OpenLayers.Geometry} geometry
*/
buildGeometryNode: function(geometry) {
var gml = "";
// match MultiPolygon or Polygon
if (geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
gml = document.createElementNS(this.georssns, 'georss:polygon');
gml.appendChild(this.buildCoordinatesNode(geometry.components[0]));
}
// match MultiLineString or LineString
else if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
gml = document.createElementNS(this.georssns, 'georss:line');
gml.appendChild(this.buildCoordinatesNode(geometry));
}
// match MultiPoint or Point
else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
gml = document.createElementNS(this.georssns, 'georss:point');
gml.appendChild(this.buildCoordinatesNode(geometry));
} else {
alert("Couldn't parse " + geometry.CLASS_NAME);
}
return gml;
},
buildCoordinatesNode: function(geometry) {
var points = null;
if (geometry.components) {
points = geometry.components;
}
var path = "";
if (points) {
for (var i = 0; i < points.length; i++) {
path += points[i].lat + " " + points[i].lon + " ";
}
} else {
path += geometry.lat + " " + geometry.lon + " ";
}
return document.createTextNode(path);
}
});
+169
View File
@@ -0,0 +1,169 @@
/* 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. */
/**
* Read only KML.
* @requires OpenLayers/Format.js
* @requires OpenLayers/Feature/Vector.js
* @requires OpenLayers/Ajax.js
*/
OpenLayers.Format.KML = OpenLayers.Class.create();
OpenLayers.Format.KML.prototype =
OpenLayers.Class.inherit( OpenLayers.Format, {
featureNS: "http://mapserver.gis.umn.edu/mapserver",
collectionName: "FeatureCollection",
kmlns: "http://earth.google.com/kml/2.0",
/**
* Read data from a string, and return a list of features.
*
* @param {string|XMLNode} data data to read/parse.
*/
read: function(data) {
if (typeof data == "string") {
data = OpenLayers.parseXMLString(data);
}
var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data, this.kmlns, "", "Placemark");
var features = [];
// Process all the featureMembers
for (var i = 0; i < featureNodes.length; i++) {
var feature = this.parseFeature(featureNodes[i]);
if (feature) {
features.push(feature);
}
}
return features;
},
/**
* This function is the core of the KML parsing code in OpenLayers.
* It creates the geometries that are then attached to the returned
* feature, and calls parseAttributes() to get attribute data out.
* @param DOMElement xmlNode
*/
parseFeature: function(xmlNode) {
var geom;
var p; // [points,bounds]
var feature = new OpenLayers.Feature.Vector();
// match Point
if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.kmlns, "", "Point").length != 0) {
var point = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.kmlns, "", "Point")[0];
p = this.parseCoords(point);
if (p.points) {
geom = p.points[0];
// TBD Bounds only set for one of multiple geometries
geom.extendBounds(p.bounds);
}
// match LineString
} else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.kmlns, "", "LineString").length != 0) {
var linestring = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
this.kmlns, "", "LineString")[0];
p = this.parseCoords(linestring);
if (p.points) {
geom = new OpenLayers.Geometry.LineString(p.points);
// TBD Bounds only set for one of multiple geometries
geom.extendBounds(p.bounds);
}
}
feature.setGeometry(geom);
feature.attributes = this.parseAttributes(xmlNode);
return feature;
},
/**
* recursive function parse the attributes of a KML node.
* Searches for any child nodes which aren't geometries,
* and gets their value.
* @param DOMElement xmlNode
*/
parseAttributes: function(xmlNode) {
var nodes = xmlNode.childNodes;
var attributes = {};
for(var i = 0; i < nodes.length; i++) {
var name = nodes[i].nodeName;
var value = OpenLayers.Util.getXmlNodeValue(nodes[i]);
// Ignore Geometry attributes
// match ".//gml:pos|.//gml:posList|.//gml:coordinates"
if((name.search(":pos")!=-1)
||(name.search(":posList")!=-1)
||(name.search(":coordinates")!=-1)){
continue;
}
// Check for a leaf node
if((nodes[i].childNodes.length == 1 && nodes[i].childNodes[0].nodeName == "#text")
|| (nodes[i].childNodes.length == 0 && nodes[i].nodeName!="#text")) {
attributes[name] = value;
}
OpenLayers.Util.extend(attributes, this.parseAttributes(nodes[i]))
}
return attributes;
},
/**
* Extract Geographic coordinates from an XML node.
* @private
* @param {XMLNode} xmlNode
*
* @return an array of OpenLayers.Geometry.Point points.
* @type Array
*/
parseCoords: function(xmlNode) {
var p = [];
p.points = [];
// TBD: Need to handle an array of coordNodes not just coordNodes[0]
var coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.kmlns, "", "coordinates")[0];
var coordString = OpenLayers.Util.getXmlNodeValue(coordNodes);
var firstCoord = coordString.split(" ");
while (firstCoord[0] == "")
firstCoord.shift();
var dim = firstCoord[0].split(",").length;
// Extract an array of Numbers from CoordString
var nums = (coordString) ? coordString.split(/[, \n\t]+/) : [];
// Remove elements caused by leading and trailing white space
while (nums[0] == "")
nums.shift();
while (nums[nums.length-1] == "")
nums.pop();
for(i = 0; i < nums.length; i = i + dim) {
x = parseFloat(nums[i]);
y = parseFloat(nums[i+1]);
p.points.push(new OpenLayers.Geometry.Point(x, y));
if (!p.bounds) {
p.bounds = new OpenLayers.Bounds(x, y, x, y);
} else {
p.bounds.extend(x, y);
}
}
return p;
},
CLASS_NAME: "OpenLayers.Format.KML"
});
+156
View File
@@ -0,0 +1,156 @@
/* 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. */
/**
* Read/WRite WFS.
* @requires OpenLayers/Format/GML.js
*/
OpenLayers.Format.WFS = OpenLayers.Class.create();
OpenLayers.Format.WFS.prototype =
OpenLayers.Class.inherit( OpenLayers.Format.GML, {
layer: null,
wfsns: "http://www.opengis.net/wfs",
/*
* Create a WFS-T formatter. This requires a layer: that layer should
* have two properties: geometry_column and typename. The parser
* for this format is subclassed entirely from GML: There is a writer
* only, which uses most of the code from the GML layer, and wraps
* it in transactional elements.
* @param {Object} options
* @param OpenLayers.Layer layer
*/
initialize: function(options, layer) {
OpenLayers.Format.GML.prototype.initialize.apply(this, arguments);
this.layer = layer;
if (this.layer.featureNS) {
this.featureNS = this.layer.featureNS;
}
if (this.layer.options.geometry_column) {
this.geometryName = this.layer.options.geometry_column;
}
if (this.layer.options.typename) {
this.featureName = this.layer.options.typename;
}
},
/**
* write
* Takes a feature list, and generates a WFS-T Transaction
*
* @param Array
*/
write: function(features) {
var transaction = document.createElementNS('http://www.opengis.net/wfs', 'wfs:Transaction');
for (var i=0; i < features.length; i++) {
switch (features[i].state) {
case OpenLayers.State.INSERT:
transaction.appendChild(this.insert(features[i]));
break;
case OpenLayers.State.UPDATE:
transaction.appendChild(this.update(features[i]));
break;
case OpenLayers.State.DELETE:
transaction.appendChild(this.remove(features[i]));
break;
}
}
return transaction;
},
createFeatureXML: function(feature) {
var geometryNode = this.buildGeometryNode(feature.geometry);
var geomContainer = document.createElementNS(this.featureNS, "feature:" + this.geometryName);
geomContainer.appendChild(geometryNode);
var featureContainer = document.createElementNS(this.featureNS, "feature:" + this.featureName);
featureContainer.appendChild(geomContainer);
for(var attr in feature.attributes) {
var attrText = document.createTextNode(feature.attributes[attr]);
var nodename = attr;
if (attr.search(":") != -1) {
nodename = attr.split(":")[1];
}
var attrContainer = document.createElementNS(this.featureNS, "feature:" + nodename);
attrContainer.appendChild(attrText);
featureContainer.appendChild(attrContainer);
}
return featureContainer;
},
/**
* insert
* Takes a feature, and generates a WFS-T Transaction "Insert"
*
* @param OpenLayers.Feature.Vector
*/
insert: function(feature) {
var insertNode = document.createElementNS(this.wfsns, 'wfs:Insert');
insertNode.appendChild(this.createFeatureXML(feature));
return insertNode;
},
/**
* update
* Takes a feature, and generates a WFS-T Transaction "Update"
*
* @param OpenLayers.Feature.Vector
*/
update: function(feature) {
if (!feature.fid) { alert("Can't update a feature for which there is no FID."); }
var updateNode = document.createElementNS(this.wfsns, 'wfs:Update');
updateNode.setAttribute("typeName", this.layerName);
var propertyNode = document.createElementNS(this.wfsns, 'wfs:Property');
var nameNode = document.createElementNS('http://www.opengis.net/wfs', 'wfs:Name');
var txtNode = document.createTextNode(this.geometryName);
nameNode.appendChild(txtNode);
propertyNode.appendChild(nameNode);
var valueNode = document.createElementNS('http://www.opengis.net/wfs', 'wfs:Value');
valueNode.appendChild(this.buildGeometryNode(feature.geometry));
propertyNode.appendChild(valueNode);
updateNode.appendChild(propertyNode);
var filterNode = document.createElementNS('http://www.opengis.net/ogc', 'ogc:Filter');
var filterIdNode = document.createElementNS('http://www.opengis.net/ogc', 'ogc:FeatureId');
filterIdNode.setAttribute("fid", feature.fid);
filterNode.appendChild(filterIdNode);
updateNode.appendChild(filterNode);
return updateNode;
},
/**
* delete
* Takes a feature, and generates a WFS-T Transaction "Delete"
*
* @param OpenLayers.Feature.Vector
*/
remove: function(feature) {
if (!feature.attributes.fid) {
alert("Can't update a feature for which there is no FID.");
return false;
}
var deleteNode = document.createElementNS(this.featureNS, 'wfs:Delete');
deleteNode.setAttribute("typeName", this.layerName);
var filterNode = document.createElementNS('http://www.opengis.net/ogc', 'ogc:Filter');
var filterIdNode = document.createElementNS('http://www.opengis.net/ogc', 'ogc:FeatureId');
filterIdNode.setAttribute("fid", feature.attributes.fid);
filterNode.appendChild(filterIdNode);
deleteNode.appendChild(filterNode);
return deleteNode;
},
destroy: function() {
this.layer = null;
}
});
+165
View File
@@ -0,0 +1,165 @@
/* 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
*/
OpenLayers.Geometry = OpenLayers.Class.create();
OpenLayers.Geometry.prototype = {
/** @type String */
id: null,
/** This is set when a Geometry is added as Component of another Geometry
*
* @type OpenLayers.Geometry */
parent: null,
/** @type OpenLayers.Bounds */
bounds: null,
/**
* Cross reference back to the feature that owns this geometry so
* that that the feature can be identified after the geometry has been
* selected by a mouse click.
*
* @type OpenLayers.Feature */
feature: null,
/** @type OpenLayers.Events */
events:null,
/**
* @constructor
*/
initialize: function() {
this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME+ "_");
},
/**
*
*/
destroy: function() {
this.id = null;
this.bounds = null;
this.feature = null;
if (this.events) {
this.events.destroy();
}
this.events = null;
},
/**
* Set the bounds for this Geometry.
*
* @param {OpenLayers.Bounds} object
*/
setBounds: function(bounds) {
if (bounds) {
this.bounds = bounds.clone();
}
},
/**
* Nullify this components bounds and that of its parent as well.
*/
clearBounds: function() {
this.bounds = null;
if (this.parent) {
this.parent.clearBounds();
}
},
/**
* Extend the existing bounds to include the new bounds.
* If geometry's bounds is not yet set, then set a new Bounds.
*
* @param {OpenLayers.Bounds} newBounds
*/
extendBounds: function(newBounds){
var bounds = this.getBounds();
if (!bounds) {
this.setBounds(newBounds);
} else {
this.bounds.extend(newBounds);
}
},
/**
* Get the bounds for this Geometry. If bounds is not set, it
* is calculated again, this makes queries faster.
*
* @type OpenLayers.Bounds
*/
getBounds: function() {
if (this.bounds == null) {
this.calculateBounds();
}
return this.bounds;
},
/** Recalculate the bounds for the geometry.
*
*/
calculateBounds: function() {
//
// This should be overridden by subclasses.
//
},
/**
* Note: This is only an approximation based on the bounds of the
* geometry.
*
* @param {OpenLayers.LonLat} lonlat
* @param {float} toleranceLon Optional tolerance in Geometric Coords
* @param {float} toleranceLat Optional tolerance in Geographic Coords
*
* @returns Whether or not the geometry is at the specified location
* @type Boolean
*/
atPoint: function(lonlat, toleranceLon, toleranceLat) {
var atPoint = false;
var bounds = this.getBounds();
if ((bounds != null) && (lonlat != null)) {
var dX = (toleranceLon != null) ? toleranceLon : 0;
var dY = (toleranceLat != null) ? toleranceLat : 0;
var toleranceBounds =
new OpenLayers.Bounds(this.bounds.left - dX,
this.bounds.bottom - dY,
this.bounds.right + dX,
this.bounds.top + dY);
atPoint = toleranceBounds.containsLonLat(lonlat);
}
return atPoint;
},
/**
* @returns The length of the geometry
* @type float
*/
getLength: function() {
//to be overridden by geometries that actually have a length
//
return 0.0;
},
/**
* @returns The area of the geometry
* @type float
*/
getArea: function() {
//to be overridden by geometries that actually have an area
//
return 0.0;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry"
};
+201
View File
@@ -0,0 +1,201 @@
/* 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
*
* A Collection is exactly what it sounds like: A collection of different
* Geometries. These are stored in the local parameter "components" (which
* can be passed as a parameter to the constructor).
*
* As new geometries are added to the collection, they are NOT cloned.
* When removing geometries, they need to be specified by reference (ie you
* have to pass in the *exact* geometry to be removed).
*
* The getArea() and getLength() functions here merely iterate through
* the components, summing their respective areas and lengths.
*
* @requires OpenLayers/Geometry.js
*/
OpenLayers.Geometry.Collection = OpenLayers.Class.create();
OpenLayers.Geometry.Collection.prototype =
OpenLayers.Class.inherit( OpenLayers.Geometry, {
/** @type Array(OpenLayers.Geometry) */
components: null,
/**
* @constructor
*
* @param {Array(OpenLayers.Geometry)} components
*/
initialize: function (components) {
OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
this.components = new Array();
if (components != null) {
this.addComponents(components);
}
},
/**
*
*/
destroy: function () {
this.components.length = 0;
this.components = null;
},
/**
* @returns An exact clone of this collection
* @type OpenLayers.Geometry.Collection
*/
clone: function (obj) {
if (obj == null) {
obj = eval("new " + this.CLASS_NAME + "()");
}
for (var i = 0; i < this.components.length; i++) {
obj.addComponent(this.components[i].clone());
}
// catch any randomly tagged-on properties
OpenLayers.Util.applyDefaults(obj, this);
return obj;
},
/**
* @returns the components of the geometry
* @type Array(OpenLayers.Geometry)
*/
getComponents: function(){
return this.components;
},
/**
* @returns the components of the geometry
* @type Array(OpenLayers.Geometry)
*/
getComponentsString: function(){
var strings = [];
for(var i = 0; i < this.components.length; i++) {
strings.push(this.components[i].toShortString());
}
return strings.join(",");
},
/** Recalculate the bounds by iterating through the components and
* calling calling extendBounds() on each item
*
*/
calculateBounds: function() {
this.bounds = null;
if ( !this.components || (this.components.length > 0)) {
this.setBounds(this.components[0].getBounds());
for (var i = 1; i < this.components.length; i++) {
this.extendBounds(this.components[i].getBounds());
}
}
},
/**
* @param {Array(OpenLayers.Geometry)} components
*
*/
addComponents: function(components){
if(!(components instanceof Array)) {
components = [components];
}
for(var i=0; i < components.length; i++) {
this.addComponent(components[i]);
}
},
/** Add a new component (geometry) to the collection.
*
* The bounds cache is reset.
*
* @param {OpenLayers.Geometry} component
* @param {int} index Index into the array to insert the component
*/
addComponent: function(component, index) {
if (component) {
if (index) {
var components1 = this.components.slice(0, index);
var components2 = this.components.slice(index,
this.components.length);
components1.push(component);
this.components = components1.concat(components2);
} else {
this.components.push(component);
}
component.parent = this;
this.clearBounds();
}
},
/**
* @param {Array(OpenLayers.Geometry)} components
*/
removeComponents: function(components) {
if(!(components instanceof Array)) {
components = [components];
}
for (var i = 0; i < components.length; i++) {
this.removeComponent(components[i]);
}
},
/**
* @param {OpenLayers.Geometry} component
*/
removeComponent: function(component) {
OpenLayers.Util.removeItem(this.components, component);
// clearBounds() so that it gets recalculated on the next call
// to this.getBounds();
this.clearBounds();
},
/**
* @returns The length of the geometry
* @type float
*/
getLength: function() {
var length = 0.0;
for (var i = 0; i < this.components.length; i++) {
length += this.components[i].getLength();
}
return length;
},
/** Note how this function is overridden in Polygon
*
* @returns the area of the collection by summing its parts
* @type float
*/
getArea: function() {
var area = 0.0;
for (var i = 0; i < this.components.length; i++) {
area += this.components[i].getArea();
}
return area;
},
/**
* Moves a collection in place
* @param {Float} x
* @param {Float} y
*/
move: function(x, y) {
for(var i = 0; i < this.components.length; i++) {
this.components[i].move(x, y);
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.Collection"
});
+58
View File
@@ -0,0 +1,58 @@
/* 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
*
* A Curve is a MultiPoint, whose points are assumed to be connected. To
* this end, we provide a "getLength()" function, which iterates through
* the points, summing the distances between them.
*
* @requires OpenLayers/Geometry/MultiPoint.js
*/
OpenLayers.Geometry.Curve = OpenLayers.Class.create();
OpenLayers.Geometry.Curve.prototype =
OpenLayers.Class.inherit(OpenLayers.Geometry.MultiPoint, {
/**
* @constructor
*
* @param {Array(OpenLayers.Geometry.Point)} points
*/
initialize: function(points) {
OpenLayers.Geometry.MultiPoint.prototype.initialize.apply(this,
arguments);
},
/**
* @returns An exact clone of this OpenLayers.Feature
* @type OpenLayers.Feature
*/
clone: function (obj) {
if (obj == null) {
obj = new OpenLayers.Geometry.Curve();
}
obj = OpenLayers.Geometry.Collection.prototype.clone.apply(this,
[obj]);
return obj;
},
/**
* @returns The length of the curve
* @type float
*/
getLength: function() {
var length = 0.0;
if ( this.components && (this.components.length > 1)) {
for(var i=1; i < this.components.length; i++) {
length += this.components[i-1].distanceTo(this.components[i]);
}
}
return length;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.Curve"
});
+65
View File
@@ -0,0 +1,65 @@
/* 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
*
* A LineString is a Curve which, once two points have been added to it, can
* never be less than two points long.
*
* @requires OpenLayers/Geometry/Curve.js
*/
OpenLayers.Geometry.LineString = OpenLayers.Class.create();
OpenLayers.Geometry.LineString.prototype =
OpenLayers.Class.inherit(OpenLayers.Geometry.Curve, {
/**
* @constructor
*
* @param {Array(OpenLayers.Geometry.Point)} points
*/
initialize: function(points) {
OpenLayers.Geometry.Curve.prototype.initialize.apply(this,
arguments);
},
/**
* @returns The coordinates components as a string
* @type String
*/
toString: function() {
return this.components.toString();
},
/**
* @returns An exact clone of this OpenLayers.Feature
* @type OpenLayers.Feature
*/
clone: function (obj) {
if (obj == null) {
obj = new OpenLayers.Geometry.LineString();
}
for (var i = 0; i < this.components.length; i++) {
obj.addComponent(this.components[i].clone());
}
return obj;
},
/** Only allows removal of a point if there are three or more points in
* the linestring. (otherwise the result would be just a single point)
*
* @param {OpenLayers.Geometry.Point} point
*/
removeComponent: function(point) {
if ( this.components && (this.components.length > 2)) {
OpenLayers.Geometry.Curve.prototype.removeComponent.apply(this,
arguments);
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.LineString"
});
+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. */
/**
* @class
*
* A Linear Ring is a special LineString which is closed. It closes itself
* automatically on every addPoint/removePoint by adding a copy of the first
* point as the last point.
*
* Also, as it is the first in the line family to close itself, a getArea()
* function is defined to calculate the enclosed area of the linearRing
*
* @requires OpenLayers/Geometry/LineString.js
*/
OpenLayers.Geometry.LinearRing = OpenLayers.Class.create();
OpenLayers.Geometry.LinearRing.prototype =
OpenLayers.Class.inherit(OpenLayers.Geometry.LineString, {
/**
* @constructor
*
* @param {Array(OpenLayers.Geometry.Point)} points
*/
initialize: function(points) {
OpenLayers.Geometry.LineString.prototype.initialize.apply(this,
arguments);
},
/**
* @returns An exact clone of this OpenLayers.Geometry.LinearRing
* @type OpenLayers.Geometry.LinearRing
*/
clone: function (obj) {
if (obj == null) {
obj = new OpenLayers.Geometry.LinearRing();
}
for (var i = 0; i < this.components.length; i++) {
obj.addComponent(this.components[i].clone());
}
return obj;
},
/**
* Adds a point to geometry components
*
* @param {OpenLayers.Geometry.Point} point
* @param {int} index Index into the array to insert the component
*/
addComponent: function(point, index) {
//remove last point
var lastPoint = this.components[this.components.length-1];
OpenLayers.Geometry.Curve.prototype.removeComponent.apply(this,
[lastPoint]);
//add our point
OpenLayers.Geometry.LineString.prototype.addComponent.apply(this,
arguments);
//append copy of first point
var firstPoint = this.components[0];
OpenLayers.Geometry.Curve.prototype.addComponent.apply(this,
[firstPoint.clone()]);
},
/**
* Removes a point from geometry components
*
* @param {OpenLayers.Geometry.Point} point
*/
removeComponent: function(point) {
if (this.components.length > 4) {
//remove last point
var lastPoint = this.components[this.components.length-1];
OpenLayers.Geometry.Curve.prototype.removeComponent.apply(this,
[lastPoint]);
//remove our point
OpenLayers.Geometry.LineString.prototype.removeComponent.apply(this,
arguments);
//append copy of first point
var firstPoint = this.components[0];
OpenLayers.Geometry.Curve.prototype.addComponent.apply(this,
[firstPoint.clone()]);
}
},
/** Note: The area is positive if the ring is oriented CW, otherwise
* it will be negative.
*
* @returns The signed area for a ring.
* @type float
*/
getArea: function() {
var area = 0.0;
if ( this.components && (this.components.length > 2)) {
var sum = 0.0;
for (var i = 0; i < this.components.length - 1; i++) {
var b = this.components[i];
var c = this.components[i+1];
sum += (b.x + c.x) * (c.y - b.y);
}
area = - sum / 2.0;
}
return area;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.LinearRing"
});
@@ -0,0 +1,42 @@
/* 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
*
* A MultiLineString is a collection of LineStrings
*
* @requires OpenLayers/Geometry/Collection.js
*/
OpenLayers.Geometry.MultiLineString = OpenLayers.Class.create();
OpenLayers.Geometry.MultiLineString.prototype =
OpenLayers.Class.inherit(OpenLayers.Geometry.Collection, {
/**
* @constructor
*
* @param {Array(OpenLayers.Geometry.LineString)} components
*/
initialize: function(components) {
OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
arguments);
},
/**
* adds a component to the MultiPoint, checking type
*
* @param {OpenLayers.Geometry.LineString} component lineString to add
* @param {int} index Index into the array to insert the component
*/
addComponent: function(component, index) {
if (!(component instanceof OpenLayers.Geometry.LineString)) {
throw "component should be an OpenLayers.Geometry.LineString";
}
OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
arguments);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.MultiLineString"
});
+60
View File
@@ -0,0 +1,60 @@
/* 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
*
* MultiPoint is a collection of Points.
*
* @requires OpenLayers/Geometry/Collection.js
*/
OpenLayers.Geometry.MultiPoint = OpenLayers.Class.create();
OpenLayers.Geometry.MultiPoint.prototype =
OpenLayers.Class.inherit(OpenLayers.Geometry.Collection, {
/**
* @constructor
*
* @param {Array(OpenLayers.Geometry.Point)} components
*/
initialize: function(components) {
OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
arguments);
},
/**
* adds component to the MultiPoint, checking type
*
* @param {OpenLayers.Geometry.Point} component point to add
* @param {int} index Index into the array to insert the component
*/
addComponent: function(component, index) {
if (!(component instanceof OpenLayers.Geometry.Point)) {
throw "component should be an OpenLayers.Geometry.Point";
}
OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
arguments);
},
/**
* Wrapper for addComponent()
*
* @param {OpenLayers.Geometry.Point} point
* @param {int} index
*/
addPoint: function(point, index) {
this.addComponent(point, index);
},
/**
* Wrapper for removeComponent()
*
* @param {OpenLayers.Geometry.Point} point
*/
removePoint: function(point){
this.removeComponent(point);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.MultiPoint"
});
+45
View File
@@ -0,0 +1,45 @@
/* 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
*
* MultiPolygon is a collection of Polygons.
*
* @requires OpenLayers/Geometry/Collection.js
*/
OpenLayers.Geometry.MultiPolygon = OpenLayers.Class.create();
OpenLayers.Geometry.MultiPolygon.prototype =
OpenLayers.Class.inherit(OpenLayers.Geometry.Collection, {
/**
* @constructor
*
* @param {Array(OpenLayers.Geometry.Polygon)} components
*/
initialize: function(components) {
OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
arguments);
},
/**
* adds component to the MultiPolygon, checking type
*
* @param {OpenLayers.Geometry.Polygon} component Polygon to add
* @param {int} index Index into the array to insert the component
*/
addComponent: function(component, index) {
if (!(component instanceof OpenLayers.Geometry.Polygon)) {
var throwStr = "component should be an " +
"OpenLayers.Geometry.Polygon but is an " +
component.CLASS_NAME;
throw throwStr;
}
OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
arguments);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.MultiPolygon"
});
+135
View File
@@ -0,0 +1,135 @@
/* 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
*
* The Point class is a subclass of Geometry and also a subclass of the
* non-vector OpenLayers.LonLat class. The basic functionality that this adds
* is the ability to switch between lon/lat and x/y at will, as well some
* convenience functions to create a Bounds from a point and measure the
* distance between two points.
*
* getX() and setX() should be used to access the x or lon variables.
*
* @requires OpenLayers/BaseTypes.js
* @requires OpenLayers/Geometry.js
*/
OpenLayers.Geometry.Point = OpenLayers.Class.create();
OpenLayers.Geometry.Point.prototype =
OpenLayers.Class.inherit(OpenLayers.LonLat, OpenLayers.Geometry, {
/** @type float */
x: null,
/** @type float */
y: null,
/**
* @constructor
*
* @param {float} x
* @param {float} y
*/
initialize: function(x, y) {
OpenLayers.LonLat.prototype.initialize.apply(this, arguments);
OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
this.x = this.lon;
this.y = this.lat;
},
/**
* @returns An exact clone of this OpenLayers.Geometry.Point
* @type OpenLayers.Geometry.Point
*/
clone: function(obj) {
if (obj == null) {
obj = new OpenLayers.Geometry.Point(this.x, this.y);
}
// catch any randomly tagged-on properties
OpenLayers.Util.applyDefaults(obj, this);
return obj;
},
/**
* Sets the x coordinate
*
* @param {float} x
*/
setX: function(x) {
this.lon = x;
this.x = x;
},
/**
* Sets the y coordinate
*
* @param {float} y
*/
setY: function(y) {
this.lat = y;
this.y = y;
},
/**
* @type float
*/
getX: function() {
return this.lon;
},
/**
* @type float
*/
getY: function() {
return this.lat;
},
/** Create a new Bounds based on the lon/lat
*
*/
calculateBounds: function () {
this.bounds = new OpenLayers.Bounds(this.lon, this.lat,
this.lon, this.lat);
},
/**
* @param {OpenLayers.Geometry.Point} point
*/
distanceTo: function(point) {
var distance = 0.0;
if ( (this.x != null) && (this.y != null) &&
(point != null) && (point.x != null) && (point.y != null) ) {
var dx2 = Math.pow(this.x - point.x, 2);
var dy2 = Math.pow(this.y - point.y, 2);
distance = Math.sqrt( dx2 + dy2 );
}
return distance;
},
/**
* @returns the coordinates as a string
* @type String
*/
toString: function() {
return this.toShortString();
},
/**
* Moves a point in place
* @param {Float} x
* @param {Float} y
*/
move: function(x, y) {
this.setX(this.x + x);
this.setY(this.y + y);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.Point"
});
+66
View File
@@ -0,0 +1,66 @@
/* 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
*
* Polygon is a collection of Geometry.LinearRings.
*
* The first ring (this.component[0])is the outer bounds of the polygon and
* all subsequent rings (this.component[1-n]) are internal holes.
*
* @requires OpenLayers/Geometry/Collection.js
*/
OpenLayers.Geometry.Polygon = OpenLayers.Class.create();
OpenLayers.Geometry.Polygon.prototype =
OpenLayers.Class.inherit(OpenLayers.Geometry.Collection, {
/**
* @constructor
*
* @param {Array(OpenLayers.Geometry.LinearRing)}
*/
initialize: function(components) {
OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
arguments);
},
/**
* adds a component to the Polygon, checking type
*
* @param {OpenLayers.Geometry.LinearRing} point to add
* @param {int} index Index into the array to insert the component
*/
addComponent: function(component, index) {
if (!(component instanceof OpenLayers.Geometry.LinearRing)) {
var throwStr = "component should be an " +
"OpenLayers.Geometry.LinearRing but is a " +
component.CLASS_NAME;
throw throwStr;
}
OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
arguments);
},
/** Calculated by subtracting the areas of the internal holes from the
* area of the outer hole.
*
* @returns The area of the geometry
* @type float
*/
getArea: function() {
var area = 0.0;
if ( this.components && (this.components.length > 0)) {
area += Math.abs(this.components[0].getArea());
for (var i = 1; i < this.components.length; i++) {
area -= Math.abs(this.components[i].getArea());
}
}
return area;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.Polygon"
});
+76
View File
@@ -0,0 +1,76 @@
/* 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
*
* A Rectangle is a simple geometry. It is specified by a a point (x and y)
* and dimensions (width and height), all of which are directly accessible as
* properties.
*
* @requires OpenLayers/Geometry.js
*/
OpenLayers.Geometry.Rectangle = OpenLayers.Class.create();
OpenLayers.Geometry.Rectangle.prototype =
OpenLayers.Class.inherit(OpenLayers.Geometry, {
/** @type float */
x: null,
/** @type float */
y: null,
/** @type float */
width: null,
/** @type float */
height: null,
/**
* @constructor
*
* @param {array} points
*/
initialize: function(x, y, width, height) {
OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
this.x = x;
this.y = y;
this.width = width;
this.height = height;
},
/**
*
*/
calculateBounds: function() {
this.bounds = new OpenLayers.Bounds(this.x, this.y,
this.x + this.width,
this.y + this.height);
},
/**
* @returns The length of the geometry
* @type float
*/
getLength: function() {
var length = (2 * this.width) + (2 * this.height);
return length;
},
/**
* @returns The area of the geometry
* @type float
*/
getArea: function() {
var area = this.width * this.height;
return area;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.Rectangle"
});
+25
View File
@@ -0,0 +1,25 @@
/* 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/Geometry.js
*/
OpenLayers.Geometry.Surface = OpenLayers.Class.create();
OpenLayers.Geometry.Surface.prototype =
OpenLayers.Class.inherit(OpenLayers.Geometry, {
/**
* @constructor
*
*/
initialize: function() {
OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.Surface"
});
+165
View File
@@ -0,0 +1,165 @@
/* 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. */
/**
* Base class to construct a higher-level handler for event sequences.
* Handlers are created by controls, which ultimately have the responsibility
* of making changes to the map.
*
* @class
*/
OpenLayers.Handler = OpenLayers.Class.create();
OpenLayers.Handler.MOD_NONE = 0;
OpenLayers.Handler.MOD_SHIFT = 1;
OpenLayers.Handler.MOD_CTRL = 2;
OpenLayers.Handler.MOD_ALT = 4;
OpenLayers.Handler.prototype = {
/**
* @type String
* @private
*/
id: null,
/**
* The control that initialized this handler.
* @type OpenLayers.Control
* @private
*/
control: null,
/**
* @type OpenLayers.Map
* @private
*/
map: null,
/**
* @type integer
*/
// keyMask: OpenLayers.Handler.MOD_NONE,
keyMask: null,
/**
* @type Boolean
* @private
*/
active: false,
/**
* @constructor
*
* @param {OpenLayers.Control} control
* @param {Object} callbacks A hash of callback functions
* @param {Object} options
*/
initialize: function(control, callbacks, options) {
OpenLayers.Util.extend(this, options);
this.control = control;
this.callbacks = callbacks;
if (control.map) {
this.setMap(control.map);
}
OpenLayers.Util.extend(this, options);
this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
},
setMap: function (map) {
this.map = map;
},
checkModifiers: function (evt) {
if(this.keyMask == null) {
return true;
}
/* calculate the keyboard modifier mask for this event */
var keyModifiers =
(evt.shiftKey ? OpenLayers.Handler.MOD_SHIFT : 0) |
(evt.ctrlKey ? OpenLayers.Handler.MOD_CTRL : 0) |
(evt.altKey ? OpenLayers.Handler.MOD_ALT : 0);
/* if it differs from the handler object's key mask,
bail out of the event handler */
return (keyModifiers == this.keyMask);
},
/**
* Turn on the handler. Returns false if the handler was already active.
*
* @type {Boolean}
*/
activate: function() {
if(this.active) {
return false;
}
// register for event handlers defined on this class.
var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
for (var i = 0; i < events.length; i++) {
if (this[events[i]]) {
this.register(events[i], this[events[i]]);
}
}
this.active = true;
return true;
},
/**
* Turn off the handler. Returns false if the handler was already inactive.
*
* @type {Boolean}
*/
deactivate: function() {
if(!this.active) {
return false;
}
// unregister event handlers defined on this class.
var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
for (var i = 0; i < events.length; i++) {
if (this[events[i]]) {
this.unregister(events[i], this[events[i]]);
}
}
this.active = false;
return true;
},
/**
* trigger the control's named callback with the given arguments
*/
callback: function (name, args) {
if (this.callbacks[name]) {
this.callbacks[name].apply(this.control, args);
}
},
/**
* register an event on the map
*/
register: function (name, method) {
// TODO: deal with registerPriority in 3.0
this.map.events.registerPriority(name, this, method);
},
/**
* unregister an event from the map
*/
unregister: function (name, method) {
this.map.events.unregister(name, this, method);
},
/**
*
*/
destroy: function () {
// eliminate circular references
this.control = this.map = null;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Handler"
};
+126
View File
@@ -0,0 +1,126 @@
/* 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. */
/**
* Handler for dragging a rectangle across the map. Box is displayed
* on mouse down, moves on mouse move, and is finished on mouse up.
*
* @class
* @requires OpenLayers/Handler.js
*/
OpenLayers.Handler.Box = OpenLayers.Class.create();
OpenLayers.Handler.Box.prototype = OpenLayers.Class.inherit( OpenLayers.Handler, {
/**
* @type OpenLayers.Handler.Drag
*/
dragHandler: null,
/**
* @constructor
*
* @param {OpenLayers.Control} control
* @param {Object} callbacks An object containing a single function to be
* called when the drag operation is finished.
* The callback should expect to recieve a single
* argument, the point geometry.
* @param {Object} options
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
var callbacks = {
"down": this.startBox,
"move": this.moveBox,
"out": this.removeBox,
"up": this.endBox
};
this.dragHandler = new OpenLayers.Handler.Drag(
this, callbacks, {keyMask: this.keyMask});
},
setMap: function (map) {
OpenLayers.Handler.prototype.setMap.apply(this, arguments);
if (this.dragHandler) {
this.dragHandler.setMap(map);
}
},
/**
* @param {Event} evt
*/
startBox: function (xy) {
this.zoomBox = OpenLayers.Util.createDiv('zoomBox',
this.dragHandler.start,
null,
null,
"absolute",
"2px solid red");
this.zoomBox.style.backgroundColor = "white";
this.zoomBox.style.filter = "alpha(opacity=50)"; // IE
this.zoomBox.style.opacity = "0.50";
this.zoomBox.style.fontSize = "1px";
this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1;
this.map.viewPortDiv.appendChild(this.zoomBox);
// TBD: use CSS classes instead
this.map.div.style.cursor = "crosshair";
},
/**
*/
moveBox: function (xy) {
var deltaX = Math.abs(this.dragHandler.start.x - xy.x);
var deltaY = Math.abs(this.dragHandler.start.y - xy.y);
this.zoomBox.style.width = Math.max(1, deltaX) + "px";
this.zoomBox.style.height = Math.max(1, deltaY) + "px";
if (xy.x < this.dragHandler.start.x) {
this.zoomBox.style.left = xy.x+"px";
}
if (xy.y < this.dragHandler.start.y) {
this.zoomBox.style.top = xy.y+"px";
}
},
/**
*/
endBox: function(end) {
var result;
if (Math.abs(this.dragHandler.start.x - end.x) > 5 ||
Math.abs(this.dragHandler.start.y - end.y) > 5) {
var start = this.dragHandler.start;
var top = Math.min(start.y, end.y);
var bottom = Math.max(start.y, end.y);
var left = Math.min(start.x, end.x);
var right = Math.max(start.x, end.x);
result = new OpenLayers.Bounds(left, bottom, right, top);
} else {
result = this.dragHandler.start.clone(); // i.e. OL.Pixel
}
this.removeBox();
// TBD: use CSS classes instead
this.map.div.style.cursor = "default";
this.callback("done", [result]);
},
/**
* Remove the zoombox from the screen and nullify our reference to it.
*/
removeBox: function() {
this.map.viewPortDiv.removeChild(this.zoomBox);
this.zoomBox = null;
},
activate: function () {
OpenLayers.Handler.prototype.activate.apply(this, arguments);
this.dragHandler.activate();
},
deactivate: function () {
OpenLayers.Handler.prototype.deactivate.apply(this, arguments);
this.dragHandler.deactivate();
},
CLASS_NAME: "OpenLayers.Handler.Box"
});
+110
View File
@@ -0,0 +1,110 @@
/* 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. */
/**
* Handler for dragging a rectangle across the map. Drag is displayed
* on mouse down, moves on mouse move, and is finished on mouse up.
*
* @class
* @requires OpenLayers/Handler.js
* @requires OpenLayers/Events.js
*/
OpenLayers.Handler.Drag = OpenLayers.Class.create();
OpenLayers.Handler.Drag.prototype = OpenLayers.Class.inherit( OpenLayers.Handler, {
/**
* When a mousedown event is received, we want to record it, but not set
* 'dragging' until the mouse moves after starting.
*
* @type boolean
**/
started: false,
/** @type boolean **/
dragging: null,
/** @type OpenLayers.Pixel **/
start: null,
/**
* @constructor
*
* @param {OpenLayers.Control} control
* @param {Object} callbacks An object containing a single function to be
* called when the drag operation is finished.
* The callback should expect to recieve a single
* argument, the point geometry.
* @param {Object} options
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
},
mousedown: function (evt) {
if (this.checkModifiers(evt) && OpenLayers.Event.isLeftClick(evt)) {
this.started = true;
this.dragging = null;
this.start = evt.xy.clone();
// TBD replace with CSS classes
this.map.div.style.cursor = "move";
this.callback("down", [evt.xy]);
OpenLayers.Event.stop(evt);
return false;
}
},
mousemove: function (evt) {
if (this.started) {
this.dragging = true;
this.callback("move", [evt.xy]);
}
},
mouseup: function (evt) {
if (this.started) {
this.started = false;
// TBD replace with CSS classes
this.map.div.style.cursor = "default";
this.callback("up", [evt.xy]);
}
},
mouseout: function (evt) {
if (this.started && OpenLayers.Util.mouseLeft(evt, this.map.div)) {
this.started = false;
this.dragging = null;
// TBD replace with CSS classes
this.map.div.style.cursor = "default";
this.callback("out", []);
}
},
/**
* @param {Event} evt
*
* @type Boolean
*/
click: function (evt) {
// throw away the first left click event that happens after a mouse up
if (OpenLayers.Event.isLeftClick(evt) && this.dragging != null) {
this.dragging = null;
return false;
}
this.started = false;
},
activate: function (evt) {
OpenLayers.Handler.prototype.activate.apply(this, arguments);
document.onselectstart = function() { return false; };
this.dragging = null;
},
deactivate: function (evt) {
OpenLayers.Handler.prototype.deactivate.apply(this, arguments);
document.onselectstart = null;
this.dragging = null;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Handler.Drag"
});
+59
View File
@@ -0,0 +1,59 @@
/* 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. */
/**
* Handler for dragging a rectangle across the map. Keyboard is displayed
* on mouse down, moves on mouse move, and is finished on mouse up.
*
* @class
* @requires OpenLayers/Handler.js
* @requires OpenLayers/Events.js
*/
OpenLayers.Handler.Keyboard = OpenLayers.Class.create();
OpenLayers.Handler.Keyboard.prototype = OpenLayers.Class.inherit( OpenLayers.Handler, {
/* http://www.quirksmode.org/js/keys.html explains key x-browser
key handling quirks in pretty nice detail */
/* supported named callbacks are: keyup, keydown, keypress */
/** constant */
KEY_EVENTS: ["keydown", "keypress", "keyup"],
/** @type Function
* @private
*/
eventListener: null,
initialize: function () {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
// cache the bound event listener method so it can be unobserved later
this.eventListener = this.handleKeyEvent.bindAsEventListener(this);
},
activate: function() {
OpenLayers.Handler.prototype.activate.apply(this, arguments);
for (var i = 0; i < this.KEY_EVENTS.length; i++) {
OpenLayers.Event.observe(
window, this.KEY_EVENTS[i], this.eventListener);
}
},
deactivate: function() {
OpenLayers.Handler.prototype.activate.apply(this, arguments);
for (var i = 0; i < this.KEY_EVENTS.length; i++) {
OpenLayers.Event.stopObserving(
document, this.KEY_EVENTS[i], this.eventListener);
}
},
handleKeyEvent: function (evt) {
if (this.checkModifiers(evt)) {
this.callback(evt.type, [evt.charCode || evt.keyCode]);
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Handler.Keyboard"
});
+105
View File
@@ -0,0 +1,105 @@
/* 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. */
/**
* Handler for wheel up/down events.
*
* @class
* @requires OpenLayers/Handler.js
*/
OpenLayers.Handler.MouseWheel = OpenLayers.Class.create();
OpenLayers.Handler.MouseWheel.prototype = OpenLayers.Class.inherit( OpenLayers.Handler, {
/** @type function **/
wheelListener: null,
/**
* @constructor
*
* @param {OpenLayers.Control} control
* @param {Object} callbacks An object containing a single function to be
* called when the drag operation is finished.
* The callback should expect to recieve a single
* argument, the point geometry.
* @param {Object} options
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
this.wheelListener = this.onWheelEvent.bindAsEventListener(this);
},
/**
* Mouse ScrollWheel code thanks to http://adomas.org/javascript-mouse-wheel/
*/
/** Catch the wheel event and handle it xbrowserly
*
* @param {Event} e
*/
onWheelEvent: function(e){
// first check keyboard modifiers
if (!this.checkModifiers(e)) return;
// first determine whether or not the wheeling was inside the map
var inMap = false;
var elem = OpenLayers.Event.element(e);
while(elem != null) {
if (this.map && elem == this.map.div) {
inMap = true;
break;
}
elem = elem.parentNode;
}
if (inMap) {
var delta = 0;
if (!e) {
e = window.event;
}
if (e.wheelDelta) {
delta = e.wheelDelta/120;
if (window.opera) {
delta = -delta;
}
} else if (e.detail) {
delta = -e.detail / 3;
}
if (delta) {
// add the mouse position to the event because mozilla has a bug
// with clientX and clientY (see https://bugzilla.mozilla.org/show_bug.cgi?id=352179)
// getLonLatFromViewPortPx(e) returns wrong values
// TODO FIXME FIXME this might not be the right way to port the 2.3 behavior
e.xy = this.map.events.getMousePosition(e);
if (delta < 0) {
this.callback("down", [e, delta]);
} else {
this.callback("up", [e, delta]);
}
}
//only wheel the map, not the window
OpenLayers.Event.stop(e);
}
},
activate: function (evt) {
OpenLayers.Handler.prototype.activate.apply(this, arguments);
//register mousewheel events specifically on the window and document
var wheelListener = this.wheelListener;
OpenLayers.Event.observe(window, "DOMMouseScroll", wheelListener);
OpenLayers.Event.observe(window, "mousewheel", wheelListener);
OpenLayers.Event.observe(document, "mousewheel", wheelListener);
},
deactivate: function (evt) {
OpenLayers.Handler.prototype.deactivate.apply(this, arguments);
// unregister mousewheel events specifically on the window and document
var wheelListener = this.wheelListener;
OpenLayers.Event.stopObserving(window, "DOMMouseScroll", wheelListener);
OpenLayers.Event.stopObserving(window, "mousewheel", wheelListener);
OpenLayers.Event.stopObserving(document, "mousewheel", wheelListener);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Handler.MouseWheel"
});
+216
View File
@@ -0,0 +1,216 @@
/* 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. */
/**
* Handler to draw a path on the map. Path is displayed on mouse down,
* moves on mouse move, and is finished on mouse up.
*
* @class
* @requires OpenLayers/Handler/Point.js
* @requires OpenLayers/Geometry/Point.js
* @requires OpenLayers/Geometry/LineString.js
*/
OpenLayers.Handler.Path = OpenLayers.Class.create();
OpenLayers.Handler.Path.prototype =
OpenLayers.Class.inherit(OpenLayers.Handler.Point, {
/**
* @type OpenLayers.Geometry.LineString
* @private
*/
line: null,
/**
* In freehand mode, the handler starts the path on mouse down, adds a point
* for every mouse move, and finishes the path on mouse up. Outside of
* freehand mode, a point is added to the path on every mouse click and
* double-click finishes the path.
*
* @type Boolean
*/
freehand: false,
/**
* If set, freehandToggle is checked on mouse events and will set the
* freehand mode to the opposite of this.freehand. To disallow toggling
* between freehand and non-freehand mode, set freehandToggle to null.
* Acceptable toggle values are 'shiftKey', 'ctrlKey', and 'altKey'.
*
* @type String
*/
freehandToggle: 'shiftKey',
/**
* @constructor
*
* @param {OpenLayers.Control} control
* @param {Array} callbacks An object with a 'done' property whos value is
* a function to be called when the path drawing is
* finished. The callback should expect to recieve a
* single argument, the line string geometry.
* If the callbacks object contains a 'point'
* property, this function will be sent each point
* as they are added. If the callbacks object contains
* a 'cancel' property, this function will be called when
* the handler is deactivated while drawing. The cancel
* should expect to receive a geometry.
* @param {Object} options
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.Point.prototype.initialize.apply(this, arguments);
},
/**
* Add temporary geometries
*/
createGeometry: function() {
this.line = new OpenLayers.Geometry.LineString();
this.point = new OpenLayers.Geometry.Point();
},
/**
* Destroy temporary geometries
*/
destroyGeometry: function() {
this.line.destroy();
this.point.destroy();
},
/**
* Add point to geometry
*/
addPoint: function() {
this.line.addComponent(this.point.clone());
},
/**
* Determine whether to behanve in freehand mode or not.
*
* @type Boolean
*/
freehandMode: function(evt) {
return (this.freehandToggle && evt[this.freehandToggle]) ?
!this.freehand : this.freehand;
},
/**
* Modify the existing geometry given the new point
*
*/
modifyGeometry: function() {
var index = this.line.components.length - 1;
this.line.components[index].setX(this.point.x);
this.line.components[index].setY(this.point.y);
},
/**
* Render geometries on the temporary layer.
*/
drawGeometry: function() {
this.layer.renderer.drawGeometry(this.line, this.style);
this.layer.renderer.drawGeometry(this.point, this.style);
},
/**
* Return a clone of the relevant geometry.
*
* @type OpenLayers.Geometry.LineString
*/
geometryClone: function() {
return this.line.clone();
},
/**
* Handle mouse down. Add a new point to the geometry and render it.
* Return determines whether to propagate the event on the map.
*
* @param {Event} evt
* @type Boolean
*/
mousedown: function(evt) {
// ignore double-clicks
if (this.lastDown && this.lastDown.equals(evt.xy)) {
return false;
}
if(this.lastDown == null) {
this.createGeometry();
}
this.mouseDown = true;
this.lastDown = evt.xy;
var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
this.point.setX(lonlat.lon);
this.point.setY(lonlat.lat);
if((this.lastUp == null) || !this.lastUp.equals(evt.xy)) {
this.addPoint();
}
this.drawGeometry();
this.drawing = true;
return false;
},
/**
* Handle mouse move. Adjust the geometry and redraw.
* Return determines whether to propagate the event on the map.
*
* @param {Event} evt
* @type Boolean
*/
mousemove: function (evt) {
if(this.drawing) {
var lonlat = this.map.getLonLatFromPixel(evt.xy);
this.point.setX(lonlat.lon);
this.point.setY(lonlat.lat);
if(this.mouseDown && this.freehandMode(evt)) {
this.addPoint();
} else {
this.modifyGeometry();
}
this.drawGeometry();
}
return true;
},
/**
* Handle mouse up. Send the latest point in the geometry to the control.
* Return determines whether to propagate the event on the map.
*
* @param {Event} evt
* @type Boolean
*/
mouseup: function (evt) {
this.mouseDown = false;
if(this.drawing) {
if(this.freehandMode(evt)) {
this.finalize();
} else {
if(this.lastUp == null) {
this.addPoint();
}
this.lastUp = evt.xy;
this.callback("point", [this.point]);
}
return false;
}
return true;
},
/**
* Handle double-clicks. Finish the geometry and send it back
* to the control.
*
* @param {Event} evt
*/
dblclick: function(evt) {
if(!this.freehandMode(evt)) {
var index = this.line.components.length - 1;
this.line.removeComponent(this.line.components[index]);
this.finalize(this.line);
}
return false;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Handler.Path"
});
+232
View File
@@ -0,0 +1,232 @@
/* 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. */
/**
* Handler to draw a point on the map. Point is displayed on mouse down,
* moves on mouse move, and is finished on mouse up.
*
* @class
* @requires OpenLayers/Handler.js
* @requires OpenLayers/Geometry/Point.js
*/
OpenLayers.Handler.Point = OpenLayers.Class.create();
OpenLayers.Handler.Point.prototype =
OpenLayers.Class.inherit(OpenLayers.Handler, {
/**
* @type OpenLayers.Geometry.Point
* @private
*/
point: null,
/**
* @type OpenLayers.Layer.Vector
* @private
*/
layer: null,
/**
* @type Boolean
* @private
*/
drawing: false,
/**
* @type Boolean
* @private
*/
mouseDown: false,
/**
* @type OpenLayers.Pixel
* @private
*/
lastDown: null,
/**
* @type OpenLayers.Pixel
* @private
*/
lastUp: null,
/**
* @constructor
*
* @param {OpenLayers.Control} control
* @param {Array} callbacks An object with a 'done' property whos value is
* a function to be called when the point drawing
* is finished. The callback should expect to
* recieve a single argument, the point geometry.
* If the callbacks object contains a 'cancel' property,
* this function will be called when the handler is deactivated
* while drawing. The cancel should expect to receive a geometry.
* @param {Object} options
*/
initialize: function(control, callbacks, options) {
// TBD: deal with style
this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
},
/**
* turn on the handler
*/
activate: function() {
if(!OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
return false;
}
// create temporary vector layer for rendering geometry sketch
// TBD: this could be moved to initialize/destroy - setting visibility here
var options = {displayInLayerSwitcher: false};
this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);
this.map.addLayer(this.layer);
return true;
},
/**
* Add temporary geometries
*/
createGeometry: function() {
this.point = new OpenLayers.Geometry.Point();
},
/**
* turn off the handler
*/
deactivate: function() {
if(!OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
return false;
}
// call the cancel callback if mid-drawing
if(this.drawing) {
this.cancel();
}
this.map.removeLayer(this.layer, false);
this.layer.destroy();
return true;
},
/**
* Destroy the temporary geometries
*/
destroyGeometry: function() {
this.point.destroy();
},
/**
* Finish the geometry and call the "done" callback.
*/
finalize: function() {
this.layer.renderer.clear();
this.callback("done", [this.geometryClone()]);
this.destroyGeometry();
this.drawing = false;
this.mouseDown = false;
this.lastDown = null;
this.lastUp = null;
},
/**
* Finish the geometry and call the "cancel" callback.
*/
cancel: function() {
this.layer.renderer.clear();
this.callback("cancel", [this.geometryClone()]);
this.destroyGeometry();
this.drawing = false;
this.mouseDown = false;
this.lastDown = null;
this.lastUp = null;
},
/**
* Handle double clicks.
*/
dblclick: function(evt) {
OpenLayers.Event.stop(evt);
return false;
},
/**
* Render geometries on the temporary layer.
*/
drawGeometry: function() {
this.layer.renderer.drawGeometry(this.point, this.style);
},
/**
* Return a clone of the relevant geometry.
*
* @type OpenLayers.Geometry.Point
*/
geometryClone: function() {
return this.point.clone();
},
/**
* Handle mouse down. Add a new point to the geometry and render it.
* Return determines whether to propagate the event on the map.
*
* @param {Event} evt
* @type Boolean
*/
mousedown: function(evt) {
// check keyboard modifiers
if(!this.checkModifiers(evt)) {
return true;
}
// ignore double-clicks
if(this.lastDown && this.lastDown.equals(evt.xy)) {
return true;
}
if(this.lastDown == null) {
this.createGeometry();
}
this.lastDown = evt.xy;
this.drawing = true;
var lonlat = this.map.getLonLatFromPixel(evt.xy);
this.point.setX(lonlat.lon);
this.point.setY(lonlat.lat);
this.drawGeometry();
return false;
},
/**
* Handle mouse move. Adjust the geometry and redraw.
* Return determines whether to propagate the event on the map.
*
* @param {Event} evt
* @type Boolean
*/
mousemove: function (evt) {
if(this.drawing) {
var lonlat = this.map.getLonLatFromPixel(evt.xy);
this.point.setX(lonlat.lon);
this.point.setY(lonlat.lat);
this.drawGeometry();
}
return true;
},
/**
* Handle mouse up. Send the latest point in the geometry to the control.
* Return determines whether to propagate the event on the map.
*
* @param {Event} evt
* @type Boolean
*/
mouseup: function (evt) {
if(this.drawing) {
this.finalize(this.point);
return false;
} else {
return true;
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Handler.Point"
});
+91
View File
@@ -0,0 +1,91 @@
/* 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. */
/**
* Handler to draw a path on the map. Polygon is displayed on mouse down,
* moves on mouse move, and is finished on mouse up.
*
* @class
* @requires OpenLayers/Handler/Path.js
* @requires OpenLayers/Geometry/Polygon.js
*/
OpenLayers.Handler.Polygon = OpenLayers.Class.create();
OpenLayers.Handler.Polygon.prototype =
OpenLayers.Class.inherit(OpenLayers.Handler.Path, {
/**
* @type OpenLayers.Geometry.Polygon
* @private
*/
polygon: null,
/**
* @constructor
*
* @param {OpenLayers.Control} control
* @param {Array} callbacks An object with a 'done' property whos value is
* a function to be called when the path drawing is
* finished. The callback should expect to recieve a
* single argument, the polygon geometry.
* If the callbacks object contains a 'point'
* property, this function will be sent each point
* as they are added. If the callbacks object contains
* a 'cancel' property, this function will be called when
* the handler is deactivated while drawing. The cancel
* should expect to receive a geometry.
* @param {Object} options
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.Path.prototype.initialize.apply(this, arguments);
},
/**
* Add temporary geometries
*/
createGeometry: function() {
this.polygon = new OpenLayers.Geometry.Polygon();
this.line = new OpenLayers.Geometry.LinearRing();
this.polygon.addComponent(this.line);
this.point = new OpenLayers.Geometry.Point();
},
/**
* Destroy temporary geometries
*/
destroyGeometry: function() {
this.polygon.destroy();
this.point.destroy();
},
/**
* Modify the existing geometry given the new point
*
*/
modifyGeometry: function() {
var index = this.line.components.length - 2;
this.line.components[index].setX(this.point.x);
this.line.components[index].setY(this.point.y);
},
/**
* Render geometries on the temporary layer.
*/
drawGeometry: function() {
this.layer.renderer.drawGeometry(this.polygon, this.style);
this.layer.renderer.drawGeometry(this.point, this.style);
},
/**
* Return a clone of the relevant geometry.
*
* @type OpenLayers.Geometry.Polygon
*/
geometryClone: function() {
return this.polygon.clone();
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Handler.Polygon"
});
+122
View File
@@ -0,0 +1,122 @@
/* 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. */
/**
* Handler to draw a path on the map. Polygon is displayed on mouse down,
* moves on mouse move, and is finished on mouse up.
*
* @class
* @requires OpenLayers/Handler.js
*/
OpenLayers.Handler.Select = OpenLayers.Class.create();
OpenLayers.Handler.Select.prototype =
OpenLayers.Class.inherit(OpenLayers.Handler, {
/**
* @type {Int}
*/
layerIndex: null,
/**
* @constructor
*
* @param {OpenLayers.Control} control
* @param {Array} layers List of OpenLayers.Layer.Vector
* @param {Array} callbacks An object with a 'over' property whos value is
* a function to be called when the mouse is over
* a feature. The callback should expect to recieve
* a single argument, the geometry.
* @param {Object} options
*/
initialize: function(control, layer, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, [control, callbacks, options]);
this.layer = layer;
},
/**
* Handle mouse down. Call the "up" callback if down on a feature.
*
* @param {Event} evt
*/
mousedown: function(evt) {
return this.select('down', evt);
},
/**
* Handle mouse moves. Call the "over" callback if over a feature.
*
* @param {Event} evt
*/
mousemove: function(evt) {
this.select('move', evt);
return true;
},
/**
* Handle mouse moves. Call the "down" callback if up on a feature.
*
* @param {Event} evt
*/
mouseup: function(evt) {
return this.select('up', evt);
},
/**
* Capture double-clicks.
*
*/
dblclick: function(evt) {
return false;
},
/**
* Trigger the appropriate callback if a feature is under the mouse.
*
* @param {String} type Callback key
*/
select: function(type, evt) {
var geometry = this.layer.renderer.getGeometryFromEvent(evt);
if(geometry) {
if (geometry.parent) {
geometry = geometry.parent;
}
this.callback(type, [geometry]);
return false; // stop event propagation
}
return true;
},
/**
* Turn on the handler. Returns false if the handler was already active.
*
* @type {Boolean}
*/
activate: function() {
if(OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
this.layerIndex = this.layer.div.style.zIndex;
this.layer.div.style.zIndex = this.map.Z_INDEX_BASE['Popup'] - 1;
return true;
} else {
return false;
}
},
/**
* Turn onf the handler. Returns false if the handler was already active.
*
* @type {Boolean}
*/
deactivate: function() {
if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
this.layer.div.style.zIndex = this.layerIndex;
return true;
} else {
return false;
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Handler.Select"
});
+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"
});
+2 -1
View File
@@ -185,7 +185,7 @@ OpenLayers.Map.prototype = {
if (this.controls == null) {
if (OpenLayers.Control != null) { // running full or lite?
this.controls = [ new OpenLayers.Control.MouseDefaults(),
this.controls = [ new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoom(),
new OpenLayers.Control.ArgParser()
];
@@ -1226,5 +1226,6 @@ OpenLayers.Map.prototype = {
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Map"
};
+2
View File
@@ -5,6 +5,8 @@
/**
* @class
* @requires OpenLayers/Events.js
* @requires OpenLayers/Icon.js
*/
OpenLayers.Marker = OpenLayers.Class.create();
OpenLayers.Marker.prototype = {
+1
View File
@@ -349,5 +349,6 @@ OpenLayers.Popup.prototype = {
this.mousedown = false;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Popup"
};
+151
View File
@@ -0,0 +1,151 @@
/* 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 Renderer is the base class for all renderers.
*
* This is based on a merger code written by Paul Spencer and Bertil Chapuis.
* It is largely composed of virtual functions that are to be implemented
* in technology-specific subclasses, but there is some generic code too.
*
* The functions that *are* implemented here merely deal with the maintenance
* of the size and extent variables, as well as the cached 'resolution'
* value.
*
* A note to the user that all subclasses should use getResolution() instead
* of directly accessing this.resolution in order to correctly use the
* cacheing system.
*
*/
OpenLayers.Renderer = OpenLayers.Class.create();
OpenLayers.Renderer.prototype =
{
/** @type DOMElement */
container: null,
/** @type OpenLayers.Bounds */
extent: null,
/** @type OpenLayers.Size */
size: null,
/** cache of current map resolution
* @type float */
resolution: null,
/** Reference to the map -- this is set in Vector's setMap()
* @type OpenLayers.Map */
map: null,
/**
* @constructor
*
* @param {String} containerID
*/
initialize: function(containerID) {
this.container = $(containerID);
},
/**
*
*/
destroy: function() {
this.container = null;
this.extent = null;
this.size = null;
this.resolution = null;
this.map = null;
},
/**
* This should be overridden by specific subclasses
*
* @returns Whether or not the browser supports the VML renderer
* @type Boolean
*/
supported: function() {
return false;
},
/**
* Set the visible part of the layer.
*
* Resolution has probably changed, so we nullify the resolution
* cache (this.resolution) -- this way it will be re-computed when
* next it is needed.
*
* @param {OpenLayers.Bounds} extent
*/
setExtent: function(extent) {
this.extent = extent.clone();
this.resolution = null;
},
/**
* Sets the size of the drawing surface.
*
* Resolution has probably changed, so we nullify the resolution
* cache (this.resolution) -- this way it will be re-computed when
* next it is needed.
*
* @param {OpenLayers.Size} size
*/
setSize: function(size) {
this.size = size.clone();
this.resolution = null;
},
/** Uses cached copy of resolution if available to minimize computing
*
* @returns The current map's resolution
* @type float
*/
getResolution: function() {
this.resolution = this.resolution || this.map.getResolution();
return this.resolution;
},
/**
* virtual function
*
* Draw a geometry on the specified layer.
*
* @param geometry {OpenLayers.Geometry}
* @param style {Object}
*/
drawGeometry: function(geometry, style) {},
/**
* virtual function
*
* Clear all vectors from the renderer
*
*/
clear: function() {},
/**
* virtual function
*
* Returns a geometry from an event that happened on a layer.
* How this happens is specific to the renderer.
*
* @param evt {OpenLayers.Event}
*
* @returns A geometry from an event that happened on a layer
* @type OpenLayers.Geometry
*/
getGeometryFromEvent: function(evt) {},
/**
* virtual function
*
* Remove a geometry from the renderer (by id)
*
* @param geometry {OpenLayers.Geometry}
*/
eraseGeometry: function(geometry) {},
/** @final @type String */
CLASS_NAME: "OpenLayers.Renderer"
};
+269
View File
@@ -0,0 +1,269 @@
/* 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
*
* This is another virtual class in that it should never be instantiated by
* itself as a Renderer. It exists because there is *tons* of shared
* functionality between different vector libraries which use nodes/elements
* as a base for rendering vectors.
*
* The highlevel bits of code that are implemented here are the adding and
* removing of geometries, which is essentially the same for any
* element-based renderer. The details of creating each node and drawing the
* paths are of course different, but the machinery is the same.
*
* @requires OpenLayers/Renderer.js
*/
OpenLayers.Renderer.Elements = OpenLayers.Class.create();
OpenLayers.Renderer.Elements.prototype =
OpenLayers.Class.inherit(OpenLayers.Renderer, {
/** @type DOMElement */
rendererRoot: null,
/** @type DOMElement */
root: null,
/** @type String */
xmlns: null,
/**
* @constructor
*
* @param {String} containerID
*/
initialize: function(containerID) {
OpenLayers.Renderer.prototype.initialize.apply(this, arguments);
this.rendererRoot = this.createRenderRoot();
this.root = this.createRoot();
this.rendererRoot.appendChild(this.root);
this.container.appendChild(this.rendererRoot);
},
/**
*
*/
destroy: function() {
this.clear();
this.rendererRoot = null;
this.root = null;
this.xmlns = null;
OpenLayers.Renderer.prototype.destroy.apply(this, arguments);
},
/**
* Remove all the elements from the root
*
*/
clear: function() {
if (this.root) {
while (this.root.childNodes.length > 0) {
this.root.removeChild(this.root.firstChild);
}
}
},
/**
* Cycle through the rendered nodes and reproject them (this should be
* called when the extent or size has changed);
*
* @param {OpenLayers.Bounds} extent
*/
reproject: function(extent) {
for (var i = 0; i < this.root.childNodes.length; i++) {
var node = this.root.childNodes[i];
//reproject node
// for the moment, this only really happens so as to reset
// the heaviness of the line relative to the resolution and
// the size of the circle for the Point object
this.reprojectNode(node);
}
},
/** This function is in charge of asking the specific renderer which type
* of node to create for the given geometry. All geometries in an
* Elements-based renderer consist of one node and some attributes. We
* have the nodeFactory() function which creates a node for us, but it
* takes a 'type' as input, and that is precisely what this function
* tells us.
*
* @param geometry {OpenLayers.Geometry}
*
* @returns The corresponding node type for the specified geometry
* @type String
*/
getNodeType: function(geometry) { },
/**
* Draw the geometry on the specified layer, creating new nodes,
* setting paths, setting style.
*
* @param {OpenLayers.Geometry} geometry
* @param {Object} style
*/
drawGeometry: function(geometry, style) {
if ((geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") ||
(geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString") ||
(geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon")) {
for (var i = 0; i < geometry.components.length; i++) {
this.drawGeometry(geometry.components[i], style);
}
return;
};
//first we create the basic node and add it to the root
var nodeType = this.getNodeType(geometry);
var node = this.nodeFactory(geometry.id, nodeType, geometry);
node.geometry = geometry;
node.olStyle = style;
this.root.appendChild(node);
//now actually draw the node, and style it
this.drawGeometryNode(node);
},
/**
* Given a node, draw a geometry on the specified layer.
*
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
* @param {Object} style
*/
drawGeometryNode: function(node, geometry, style) {
geometry = geometry || node.geometry;
style = style || node.olStyle;
var options = {
'isFilled': true,
'isStroked': true
};
switch (geometry.CLASS_NAME) {
case "OpenLayers.Geometry.Point":
this.drawPoint(node, geometry);
break;
case "OpenLayers.Geometry.Curve":
options.isFilled = false;
this.drawCurve(node, geometry);
break;
case "OpenLayers.Geometry.LineString":
options.isFilled = false;
this.drawLineString(node, geometry);
break;
case "OpenLayers.Geometry.LinearRing":
this.drawLinearRing(node, geometry);
break;
case "OpenLayers.Geometry.Polygon":
this.drawPolygon(node, geometry);
break;
case "OpenLayers.Geometry.Surface":
this.drawSurface(node, geometry);
break;
case "OpenLayers.Geometry.Rectangle":
this.drawRectangle(node, geometry);
break;
default:
break;
}
node.olStyle = style;
node.olOptions = options;
//set style
this.setStyle(node);
},
/**
* virtual functions for drawing different Geometries.
* These should all be implemented by subclasses.
*
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawPoint: function(node, geometry) {},
drawLineString: function(node, geometry) {},
drawLinearRing: function(node, geometry) {},
drawPolygon: function(node, geometry) {},
drawRectangle: function(node, geometry) {},
drawCircle: function(node, geometry) {},
drawCurve: function(node, geometry) {},
drawSurface: function(node, geometry) {},
/**
* @param evt {Object} an OpenLayers.Event object
*
* @returns A geometry from an event that happened on a layer
* @type OpenLayers.Geometry
*/
getGeometryFromEvent: function(evt) {
var node = evt.target || evt.srcElement;
var geometry = node.geometry ? node.geometry : null
return geometry;
},
/** Erase a geometry from the renderer. In the case of a multi-geometry,
* we cycle through and recurse on ourselves. Otherwise, we look for a
* node with the geometry.id, destroy its geometry, and remove it from
* the DOM.
*
* @param {OpenLayers.Geometry} geometry
*/
eraseGeometry: function(geometry) {
if ((geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") ||
(geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString") ||
(geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon")) {
for (var i = 0; i < geometry.components.length; i++) {
this.eraseGeometry(geometry.components[i]);
}
} else {
var element = $(geometry.id);
if (element && element.parentNode) {
if (element.geometry) {
element.geometry.destroy();
element.geometry = null;
}
element.parentNode.removeChild(element);
}
}
},
/**
* @private
*
* Create new node of the specified type, with the (optional) specified id.
*
* If node already exists with same ID and type, we remove it and then
* call ourselves again to recreate it.
*
* @param {String} id
* @param {String} type Kind of node to draw
* @param {OpenLayers.Geometry} geometry
*
* @returns A new node of the given type and id
* @type DOMElement
*/
nodeFactory: function(id, type, geometry) {
var node = $(id);
if (node) {
if (!this.nodeTypeCompare(node, type)) {
node.parentNode.removeChild(node);
node = this.nodeFactory(id, type, geometry);
}
} else {
node = this.createNode(type, id);
}
return node;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Renderer.Elements"
});
+327
View File
@@ -0,0 +1,327 @@
/* 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/Renderer/Elements.js
*/
OpenLayers.Renderer.SVG = OpenLayers.Class.create();
OpenLayers.Renderer.SVG.prototype =
OpenLayers.Class.inherit(OpenLayers.Renderer.Elements, {
/** @type String */
xmlns: "http://www.w3.org/2000/svg",
/**
* @constructor
*
* @param {String} containerID
*/
initialize: function(containerID) {
if (!this.supported()) {
return;
}
OpenLayers.Renderer.Elements.prototype.initialize.apply(this,
arguments);
},
/**
*
*/
destroy: function() {
OpenLayers.Renderer.Elements.prototype.destroy.apply(this, arguments);
},
/**
* @returns Whether or not the browser supports the VML renderer
* @type Boolean
*/
supported: function() {
var svgFeature = "http://www.w3.org/TR/SVG11/feature#SVG";
var supported = document.implementation.hasFeature(svgFeature, "1.1");
return supported;
},
/**
* @param {OpenLayers.Bounds} extent
*/
setExtent: function(extent) {
OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
arguments);
var extentString = extent.left + " " + -extent.top + " " +
extent.getWidth() + " " + extent.getHeight();
this.rendererRoot.setAttributeNS(null, "viewBox", extentString);
},
/**
* function
*
* sets the size of the drawing surface
*
* @param size {OpenLayers.Size} the size of the drawing surface
*/
setSize: function(size) {
OpenLayers.Renderer.prototype.setSize.apply(this, arguments);
this.rendererRoot.setAttributeNS(null, "width", this.size.w);
this.rendererRoot.setAttributeNS(null, "height", this.size.h);
},
/**
* @param geometry {OpenLayers.Geometry}
*
* @returns The corresponding node type for the specified geometry
* @type String
*/
getNodeType: function(geometry) {
var nodeType = null;
switch (geometry.CLASS_NAME) {
case "OpenLayers.Geometry.Point":
nodeType = "circle";
break;
case "OpenLayers.Geometry.Rectangle":
nodeType = "rect";
break;
case "OpenLayers.Geometry.LineString":
nodeType = "polyline";
break;
case "OpenLayers.Geometry.LinearRing":
nodeType = "polygon";
break;
case "OpenLayers.Geometry.Polygon":
case "OpenLayers.Geometry.Curve":
case "OpenLayers.Geometry.Surface":
nodeType = "path";
break;
default:
break;
}
return nodeType;
},
/**
* @param {DOMElement} node
*/
reprojectNode: function(node) {
//just reset style (stroke width and point radius), since coord
// system has not changed
this.setStyle(node);
},
/**
* Use to set all the style attributes to a SVG node.
*
* Note: takes care to adjust stroke width and point radius
* to be resolution-relative
*
* @param node {SVGDomElement} an SVG element to decorate
* @param {Object} style
* @param {Object} options
* @option isFilled {boolean}
* @option isStroked {boolean}
*/
setStyle: function(node, style, options) {
style = style || node.olStyle;
options = options || node.olOptions;
if (node.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
var newRadius = style.pointRadius * this.getResolution();
node.setAttributeNS(null, "r", newRadius);
}
if (options.isFilled) {
node.setAttributeNS(null, "fill", style.fillColor);
node.setAttributeNS(null, "fill-opacity", style.fillOpacity);
} else {
node.setAttributeNS(null, "fill", "none");
}
if (options.isStroked) {
node.setAttributeNS(null, "stroke", style.strokeColor);
node.setAttributeNS(null, "stroke-opacity", style.strokeOpacity);
var newStrokeWidth = style.strokeWidth * this.getResolution();
node.setAttributeNS(null, "stroke-width", newStrokeWidth);
} else {
node.setAttributeNS(null, "stroke", "none");
}
if (style.pointerEvents) {
node.setAttributeNS(null, "pointer-events", style.pointerEvents);
}
},
/**
* @private
*
* @param {String} type Kind of node to draw
* @param {String} id Id for node
*
* @returns A new node of the given type and id
* @type DOMElement
*/
createNode: function(type, id) {
var node = document.createElementNS(this.xmlns, type);
if (id) {
node.setAttributeNS(null, "id", id);
}
return node;
},
/**
* @private
*
* @param {String} type Kind of node to draw
* @param {String} id Id for node
*
* @returns Whether or not the specified node is of the specified type
* @type Boolean
*/
nodeTypeCompare: function(node, type) {
return (type == node.nodeName);
},
/**
* @returns The specific render engine's root element
* @type DOMElement
*/
createRenderRoot: function() {
var id = this.container.id + "_svgRoot";
var rendererRoot = this.nodeFactory(id, "svg");
return rendererRoot;
},
/**
* @returns The main root element to which we'll add vectors
* @type DOMElement
*/
createRoot: function() {
var id = this.container.id + "_root";
var root = this.nodeFactory(id, "g");
// flip the SVG display Y axis upside down so it
// matches the display Y axis of the map
root.setAttributeNS(null, "transform", "scale(1, -1)");
return root;
},
/**************************************
* *
* GEOMETRY DRAWING FUNCTIONS *
* *
**************************************/
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawPoint: function(node, geometry) {
this.drawCircle(node, geometry, 1);
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
* @param {float} radius
*/
drawCircle: function(node, geometry, radius) {
node.setAttributeNS(null, "cx", geometry.x);
node.setAttributeNS(null, "cy", geometry.y);
node.setAttributeNS(null, "r", radius);
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawLineString: function(node, geometry) {
node.setAttributeNS(null, "points", geometry.getComponentsString());
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawLinearRing: function(node, geometry) {
node.setAttributeNS(null, "points", geometry.getComponentsString());
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawPolygon: function(node, geometry) {
var d = "";
for (var j = 0; j < geometry.components.length; j++) {
var linearRing = geometry.components[j];
d += " M";
for (var i = 0; i < linearRing.components.length; i++) {
d += " " + linearRing.components[i].toShortString();
}
}
d += " z";
node.setAttributeNS(null, "d", d);
node.setAttributeNS(null, "fill-rule", "evenodd");
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawRectangle: function(node, geometry) {
node.setAttributeNS(null, "x", geometry.x);
node.setAttributeNS(null, "y", geometry.y);
node.setAttributeNS(null, "width", geometry.width);
node.setAttributeNS(null, "height", geometry.height);
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawCurve: function(node, geometry) {
var d = null;
for (var i = 0; i < geometry.components.length; i++) {
if ((i%3) == 0 && (i/3) == 0) {
d = "M " + geometry.components[i].toShortString();
} else if ((i%3) == 1) {
d += " C " + geometry.components[i].toShortString();
} else {
d += " " + geometry.components[i].toShortString();
}
}
node.setAttributeNS(null, "d", d);
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawSurface: function(node, geometry) {
// create the svg path string representation
var d = null;
for (var i = 0; i < geometry.components.length; i++) {
if ((i%3) == 0 && (i/3) == 0) {
d = "M " + geometry.components[i].toShortString();
} else if ((i%3) == 1) {
d += " C " + geometry.components[i].toShortString();
} else {
d += " " + geometry.components[i].toShortString();
}
}
d += " Z";
node.setAttributeNS(null, "d", d);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Renderer.SVG"
});
+444
View File
@@ -0,0 +1,444 @@
/* 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
*
* Note that for all calculations in this class, we use toFixed() to round a
* float value to an integer. This is done because it seems that VML doesn't
* support float values.
*
* @requires OpenLayers/Renderer/Elements.js
*/
OpenLayers.Renderer.VML = OpenLayers.Class.create();
OpenLayers.Renderer.VML.prototype =
OpenLayers.Class.inherit(OpenLayers.Renderer.Elements, {
/** @type String */
xmlns: "urn:schemas-microsoft-com:vml",
/**
* @constructor
*
* @param {String} containerID
*/
initialize: function(containerID) {
if (!this.supported()) {
return;
}
document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
var style = document.createStyleSheet();
style.addRule('v\\:*', "behavior: url(#default#VML);");
OpenLayers.Renderer.Elements.prototype.initialize.apply(this,
arguments);
},
/**
*
*/
destroy: function() {
OpenLayers.Renderer.Elements.prototype.destroy.apply(this, arguments);
},
/**
* @returns Whether or not the browser supports the VML renderer
* @type Boolean
*/
supported: function() {
var supported = document.namespaces;
return supported;
},
/**
* @param {OpenLayers.Bounds} extent
*/
setExtent: function(extent) {
OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
arguments);
var resolution = this.getResolution();
var org = extent.left/resolution + " " +
extent.top/resolution;
this.root.setAttribute("coordorigin", org);
var size = extent.getWidth()/resolution + " " +
-extent.getHeight()/resolution;
this.root.setAttribute("coordsize", size);
},
/**
* Set the size of the drawing surface
*
* @param size {OpenLayers.Size} the size of the drawing surface
*/
setSize: function(size) {
OpenLayers.Renderer.prototype.setSize.apply(this, arguments);
this.rendererRoot.style.width = this.size.w;
this.rendererRoot.style.height = this.size.h;
this.root.style.width = this.size.w;
this.root.style.height = this.size.h
},
/**
* @param geometry {OpenLayers.Geometry}
*
* @returns The corresponding node type for the specified geometry
* @type String
*/
getNodeType: function(geometry) {
var nodeType = null;
switch (geometry.CLASS_NAME) {
case "OpenLayers.Geometry.Point":
nodeType = "v:oval";
break;
case "OpenLayers.Geometry.Rectangle":
nodeType = "v:rect";
break;
case "OpenLayers.Geometry.LineString":
case "OpenLayers.Geometry.LinearRing":
case "OpenLayers.Geometry.Polygon":
case "OpenLayers.Geometry.Curve":
case "OpenLayers.Geometry.Surface":
nodeType = "v:shape";
break;
default:
break;
}
return nodeType;
},
/**
* @param {DOMElement} node
*/
reprojectNode: function(node) {
//we have to reprojectNode the entire node since the coordinates
// system has changed
this.drawGeometryNode(node);
},
/**
* Use to set all the style attributes to a VML node.
*
* @param {DOMElement} node
* @param {Object} style
* @param {Object} options
* @option isFilled {boolean}
* @option isStroked {boolean}
*/
setStyle: function(node, style, options) {
style = style || node.olStyle;
options = options || node.olOptions;
if (node.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
this.drawCircle(node, node.geometry, style.pointRadius);
}
//fill
var fillColor = (options.isFilled) ? style.fillColor : "none";
node.setAttribute("fillcolor", fillColor);
var fills = node.getElementsByTagName("fill");
var fill = (fills.length == 0) ? null : fills[0];
if (!options.isFilled) {
if (fill) {
node.removeChild(fill);
}
} else {
if (!fill) {
fill = this.createNode('v:fill', node.id + "_fill");
node.appendChild(fill);
}
fill.setAttribute("opacity", style.fillOpacity);
}
//stroke
var strokeColor = (options.isStroked) ? style.strokeColor : "none";
node.setAttribute("strokecolor", strokeColor);
node.setAttribute("strokeweight", style.strokeWidth);
var strokes = node.getElementsByTagName("stroke");
var stroke = (strokes.length == 0) ? null : strokes[0];
if (!options.isStroked) {
if (stroke) {
node.removeChild(stroke);
}
} else {
if (!stroke) {
stroke = this.createNode('v:stroke', node.id + "_stroke");
node.appendChild(stroke);
}
stroke.setAttribute("opacity", style.strokeOpacity);
}
},
/** Get the geometry's bounds, convert it to our vml coordinate system,
* then set the node's position, size, and local coordinate system.
*
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
setNodeDimension: function(node, geometry) {
var bbox = geometry.getBounds();
var resolution = this.getResolution();
var scaledBox =
new OpenLayers.Bounds((bbox.left/resolution).toFixed(),
(bbox.bottom/resolution).toFixed(),
(bbox.right/resolution).toFixed(),
(bbox.top/resolution).toFixed());
// Set the internal coordinate system to draw the path
node.style.left = scaledBox.left;
node.style.top = scaledBox.top;
node.style.width = scaledBox.getWidth();
node.style.height = scaledBox.getHeight();
node.coordorigin = scaledBox.left + " " + scaledBox.top;
node.coordsize = scaledBox.getWidth()+ " " + scaledBox.getHeight();
},
/**
* @private
*
* @param {String} type Kind of node to draw
* @param {String} id Id for node
*
* @returns A new node of the given type and id
* @type DOMElement
*/
createNode: function(type, id) {
var node = document.createElement(type);
if (id) {
node.setAttribute('id', id);
}
return node;
},
/**
* @private
*
* @param {String} type Kind of node to draw
* @param {String} id Id for node
*
* @returns Whether or not the specified node is of the specified type
* @type Boolean
*/
nodeTypeCompare: function(node, type) {
//split type
var subType = type;
var splitIndex = subType.indexOf(":");
if (splitIndex != -1) {
subType = subType.substr(splitIndex+1);
}
//split nodeName
var nodeName = node.nodeName;
splitIndex = nodeName.indexOf(":");
if (splitIndex != -1) {
nodeName = nodeName.substr(splitIndex+1);
}
return (subType == nodeName);
},
/**
* @returns The specific render engine's root element
* @type DOMElement
*/
createRenderRoot: function() {
var id = this.container.id + "_vmlRoot";
var rendererRoot = this.nodeFactory(id, "div");
return rendererRoot;
},
/**
* @returns The main root element to which we'll add vectors
* @type DOMElement
*/
createRoot: function() {
var id = this.container.id + "_root";
var root = this.nodeFactory(id, "v:group");
return root;
},
/**************************************
* *
* GEOMETRY DRAWING FUNCTIONS *
* *
**************************************/
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawPoint: function(node, geometry) {
this.drawCircle(node, node.geometry, 1);
},
/** Size and Center a circle given geometry (x,y center) and radius
*
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
* @param {float} radius
*/
drawCircle: function(node, geometry, radius) {
var resolution = this.getResolution();
node.style.left = (geometry.x /resolution).toFixed() - radius;
node.style.top = (geometry.y /resolution).toFixed() - radius;
var diameter = radius * 2;
node.style.width = diameter;
node.style.height = diameter;
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawLineString: function(node, geometry) {
this.drawLine(node, geometry, false);
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawLinearRing: function(node, geometry) {
this.drawLine(node, geometry, true);
},
/**
* @param {DOMElement} node
* @param {OpenLayers.Geometry} geometry
* @param {Boolean} closeLine Close the line? (make it a ring?)
*/
drawLine: function(node, geometry, closeLine) {
this.setNodeDimension(node, geometry);
var resolution = this.getResolution();
var path = "m";
for (var i = 0; i < geometry.components.length; i++) {
var x = (geometry.components[i].getX()/resolution);
var y = (geometry.components[i].getY()/resolution);
path += " " + x.toFixed() + "," + y.toFixed() + " l ";
}
if (closeLine) {
path += " x";
}
path += " e";
node.path = path;
},
/**
* @parm {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawPolygon: function(node, geometry) {
this.setNodeDimension(node, geometry);
var resolution = this.getResolution();
var path = "";
for (var j = 0; j < geometry.components.length; j++) {
var linearRing = geometry.components[j];
path += "m";
for (var i = 0; i < linearRing.components.length; i++) {
var x = linearRing.components[i].getX() / resolution;
var y = linearRing.components[i].getY() / resolution;
path += " " + x.toFixed() + "," + y.toFixed();
if (i==0) {
path += " l";
}
}
path += " x ";
}
path += "e";
node.path = path;
},
/**
* @parm {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawRectangle: function(node, geometry) {
var resolution = this.getResolution();
node.style.left = geometry.x/resolution;
node.style.top = geometry.y/resolution;
node.style.width = geometry.width/resolution;
node.style.height = geometry.height/resolution;
},
/**
* @parm {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawCurve: function(node, geometry) {
this.setNodeDimension(node, geometry);
var resolution = this.getResolution();
var path = "";
for (var i = 0; i < geometry.components.length; i++) {
var x = geometry.components[i].getX() / resolution;
var y = geometry.components[i].getY() / resolution;
if ((i%3)==0 && (i/3)==0) {
path += "m"
} else if ((i%3)==1) {
path += " c"
}
path += " " + x + "," + y;
}
path += " x e";
node.path = path;
},
/**
* @parm {DOMElement} node
* @param {OpenLayers.Geometry} geometry
*/
drawSurface: function(node, geometry) {
this.setNodeDimension(node, geometry);
var resolution = this.getResolution();
var path = "";
for (var i = 0; i < geometry.components.length; i++) {
var x = geometry.components[i].getX() / resolution;
var y = geometry.components[i].getY() / resolution;
if ((i%3)==0 && (i/3)==0) {
path += "m";
} else if ((i%3)==1) {
path += " c";
}
path += " " + x + "," + y;
}
path += " x e";
node.path = path;
},
CLASS_NAME: "OpenLayers.Renderer.VML"
});
+16 -25
View File
@@ -16,7 +16,7 @@ OpenLayers.Tile.WFS.prototype =
features: null,
/** @type Array(String) */
urls: null,
url: null,
/**
* @constructor
@@ -27,11 +27,11 @@ OpenLayers.Tile.WFS.prototype =
* @param {Array} urls
* @param {OpenLayers.Size} size
*/
initialize: function(layer, position, bounds, urls, size) {
initialize: function(layer, position, bounds, url, size) {
var newArguments = arguments;
newArguments = [layer, position, bounds, null, size];
OpenLayers.Tile.prototype.initialize.apply(this, newArguments);
this.urls = urls;
this.url = url;
this.features = new Array();
},
@@ -42,7 +42,7 @@ OpenLayers.Tile.WFS.prototype =
OpenLayers.Tile.prototype.destroy.apply(this, arguments);
this.destroyAllFeatures();
this.features = null;
this.urls = null;
this.url = null;
},
/** Clear the tile of any bounds/position-related data so that it can
@@ -57,12 +57,9 @@ OpenLayers.Tile.WFS.prototype =
*
*/
draw:function() {
if (!OpenLayers.Tile.prototype.draw.apply(this, arguments)) {
return false;
if (OpenLayers.Tile.prototype.draw.apply(this, arguments)) {
this.loadFeaturesForRegion(this.requestSuccess);
}
this.loadFeaturesForRegion(this.requestSuccess);
this.drawn = true;
return true;
},
/** get the full request string from the ds and the tile params
@@ -74,21 +71,12 @@ OpenLayers.Tile.WFS.prototype =
* @param {function} failure
*/
loadFeaturesForRegion:function(success, failure) {
if (this.urls != null) {
for(var i=0; i < this.urls.length; i++) {
var params = { BBOX:this.bounds.toBBOX() };
var url = this.urls[i] + "&" +
OpenLayers.Util.getParameterString(params);
OpenLayers.loadURL(url, null, this, success, failure);
}
}
OpenLayers.loadURL(this.url, null, this, success);
},
/** Return from AJAX request
*
* @param {XMLHttpRequest} request
* @param {} request
*/
requestSuccess:function(request) {
var doc = request.responseXML;
@@ -96,9 +84,13 @@ OpenLayers.Tile.WFS.prototype =
if (!doc || request.fileType!="XML") {
doc = OpenLayers.parseXMLString(request.responseText);
}
var resultFeatures = OpenLayers.Ajax.getElementsByTagNameNS(doc, "http://www.opengis.net/gml","gml", "featureMember");
this.addResults(resultFeatures);
if (this.layer.vectorMode) {
var gml = new OpenLayers.Format.GML({extractAttributes: this.layer.options.extractAttributes});
this.layer.addFeatures(gml.read(doc));
} else {
var resultFeatures = OpenLayers.Ajax.getElementsByTagNameNS(doc, "http://www.opengis.net/gml","gml", "featureMember");
this.addResults(resultFeatures);
}
},
/**
@@ -112,6 +104,7 @@ OpenLayers.Tile.WFS.prototype =
}
},
/** Iterate through and call destroy() on each feature, removing it from
* the local array
*
@@ -128,5 +121,3 @@ OpenLayers.Tile.WFS.prototype =
CLASS_NAME: "OpenLayers.Tile.WFS"
}
);