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:
+15
-1
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* @class
|
||||
*
|
||||
* @requires OpenLayers/Control.js
|
||||
* @requires OpenLayers/Control.js
|
||||
*/
|
||||
OpenLayers.Control.LayerSwitcher = OpenLayers.Class.create();
|
||||
OpenLayers.Control.LayerSwitcher.prototype =
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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));
|
||||
|
||||
@@ -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"
|
||||
});
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
};
|
||||
@@ -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.");
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
@@ -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"
|
||||
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
@@ -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"
|
||||
};
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
};
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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(
|
||||
|
||||
@@ -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"
|
||||
});
|
||||
@@ -7,6 +7,7 @@
|
||||
* @class
|
||||
*
|
||||
* @requires OpenLayers/Layer/Markers.js
|
||||
* @requires OpenLayers/Ajax.js
|
||||
*/
|
||||
OpenLayers.Layer.GeoRSS = OpenLayers.Class.create();
|
||||
OpenLayers.Layer.GeoRSS.prototype =
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
@@ -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"
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @requires OpenLayers/Events.js
|
||||
* @requires OpenLayers/Icon.js
|
||||
*/
|
||||
OpenLayers.Marker = OpenLayers.Class.create();
|
||||
OpenLayers.Marker.prototype = {
|
||||
|
||||
@@ -349,5 +349,6 @@ OpenLayers.Popup.prototype = {
|
||||
this.mousedown = false;
|
||||
},
|
||||
|
||||
/** @final @type String */
|
||||
CLASS_NAME: "OpenLayers.Popup"
|
||||
};
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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"
|
||||
});
|
||||
@@ -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
@@ -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"
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user