[76] | 1 | /* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for |
---|
| 2 | * full list of contributors). Published under the Clear BSD license. |
---|
| 3 | * See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
---|
| 4 | * full text of the license. */ |
---|
| 5 | |
---|
| 6 | // TRASH THIS |
---|
| 7 | OpenLayers.State = { |
---|
| 8 | /** states */ |
---|
| 9 | UNKNOWN: 'Unknown', |
---|
| 10 | INSERT: 'Insert', |
---|
| 11 | UPDATE: 'Update', |
---|
| 12 | DELETE: 'Delete' |
---|
| 13 | }; |
---|
| 14 | |
---|
| 15 | /** |
---|
| 16 | * @requires OpenLayers/Feature.js |
---|
| 17 | * @requires OpenLayers/Util.js |
---|
| 18 | */ |
---|
| 19 | |
---|
| 20 | /** |
---|
| 21 | * Class: OpenLayers.Feature.Vector |
---|
| 22 | * Vector features use the OpenLayers.Geometry classes as geometry description. |
---|
| 23 | * They have an 'attributes' property, which is the data object, and a 'style' |
---|
| 24 | * property, the default values of which are defined in the |
---|
| 25 | * <OpenLayers.Feature.Vector.style> objects. |
---|
| 26 | * |
---|
| 27 | * Inherits from: |
---|
| 28 | * - <OpenLayers.Feature> |
---|
| 29 | */ |
---|
| 30 | OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, { |
---|
| 31 | |
---|
| 32 | /** |
---|
| 33 | * Property: fid |
---|
| 34 | * {String} |
---|
| 35 | */ |
---|
| 36 | fid: null, |
---|
| 37 | |
---|
| 38 | /** |
---|
| 39 | * APIProperty: geometry |
---|
| 40 | * {<OpenLayers.Geometry>} |
---|
| 41 | */ |
---|
| 42 | geometry: null, |
---|
| 43 | |
---|
| 44 | /** |
---|
| 45 | * APIProperty: attributes |
---|
| 46 | * {Object} This object holds arbitrary, serializable properties that |
---|
| 47 | * describe the feature. |
---|
| 48 | */ |
---|
| 49 | attributes: null, |
---|
| 50 | |
---|
| 51 | /** |
---|
| 52 | * Property: bounds |
---|
| 53 | * {<OpenLayers.Bounds>} The box bounding that feature's geometry, that |
---|
| 54 | * property can be set by an <OpenLayers.Format> object when |
---|
| 55 | * deserializing the feature, so in most cases it represents an |
---|
| 56 | * information set by the server. |
---|
| 57 | */ |
---|
| 58 | bounds: null, |
---|
| 59 | |
---|
| 60 | /** |
---|
| 61 | * Property: state |
---|
| 62 | * {String} |
---|
| 63 | */ |
---|
| 64 | state: null, |
---|
| 65 | |
---|
| 66 | /** |
---|
| 67 | * APIProperty: style |
---|
| 68 | * {Object} |
---|
| 69 | */ |
---|
| 70 | style: null, |
---|
| 71 | |
---|
| 72 | /** |
---|
| 73 | * APIProperty: url |
---|
| 74 | * {String} If this property is set it will be taken into account by |
---|
| 75 | * {<OpenLayers.HTTP>} when upadting or deleting the feature. |
---|
| 76 | */ |
---|
| 77 | url: null, |
---|
| 78 | |
---|
| 79 | /** |
---|
| 80 | * Property: renderIntent |
---|
| 81 | * {String} rendering intent currently being used |
---|
| 82 | */ |
---|
| 83 | renderIntent: "default", |
---|
| 84 | |
---|
| 85 | /** |
---|
| 86 | * Constructor: OpenLayers.Feature.Vector |
---|
| 87 | * Create a vector feature. |
---|
| 88 | * |
---|
| 89 | * Parameters: |
---|
| 90 | * geometry - {<OpenLayers.Geometry>} The geometry that this feature |
---|
| 91 | * represents. |
---|
| 92 | * attributes - {Object} An optional object that will be mapped to the |
---|
| 93 | * <attributes> property. |
---|
| 94 | * style - {Object} An optional style object. |
---|
| 95 | */ |
---|
| 96 | initialize: function(geometry, attributes, style) { |
---|
| 97 | OpenLayers.Feature.prototype.initialize.apply(this, |
---|
| 98 | [null, null, attributes]); |
---|
| 99 | this.lonlat = null; |
---|
| 100 | this.geometry = geometry ? geometry : null; |
---|
| 101 | this.state = null; |
---|
| 102 | this.attributes = {}; |
---|
| 103 | if (attributes) { |
---|
| 104 | this.attributes = OpenLayers.Util.extend(this.attributes, |
---|
| 105 | attributes); |
---|
| 106 | } |
---|
| 107 | this.style = style ? style : null; |
---|
| 108 | }, |
---|
| 109 | |
---|
| 110 | /** |
---|
| 111 | * Method: destroy |
---|
| 112 | * nullify references to prevent circular references and memory leaks |
---|
| 113 | */ |
---|
| 114 | destroy: function() { |
---|
| 115 | if (this.layer) { |
---|
| 116 | this.layer.removeFeatures(this); |
---|
| 117 | this.layer = null; |
---|
| 118 | } |
---|
| 119 | |
---|
| 120 | this.geometry = null; |
---|
| 121 | OpenLayers.Feature.prototype.destroy.apply(this, arguments); |
---|
| 122 | }, |
---|
| 123 | |
---|
| 124 | /** |
---|
| 125 | * Method: clone |
---|
| 126 | * Create a clone of this vector feature. Does not set any non-standard |
---|
| 127 | * properties. |
---|
| 128 | * |
---|
| 129 | * Returns: |
---|
| 130 | * {<OpenLayers.Feature.Vector>} An exact clone of this vector feature. |
---|
| 131 | */ |
---|
| 132 | clone: function () { |
---|
| 133 | return new OpenLayers.Feature.Vector( |
---|
| 134 | this.geometry ? this.geometry.clone() : null, |
---|
| 135 | this.attributes, |
---|
| 136 | this.style); |
---|
| 137 | }, |
---|
| 138 | |
---|
| 139 | /** |
---|
| 140 | * Method: onScreen |
---|
| 141 | * Determine whether the feature is within the map viewport. This method |
---|
| 142 | * tests for an intersection between the geometry and the viewport |
---|
| 143 | * bounds. If a more effecient but less precise geometry bounds |
---|
| 144 | * intersection is desired, call the method with the boundsOnly |
---|
| 145 | * parameter true. |
---|
| 146 | * |
---|
| 147 | * Parameters: |
---|
| 148 | * boundsOnly - {Boolean} Only test whether a feature's bounds intersects |
---|
| 149 | * the viewport bounds. Default is false. If false, the feature's |
---|
| 150 | * geometry must intersect the viewport for onScreen to return true. |
---|
| 151 | * |
---|
| 152 | * Returns: |
---|
| 153 | * {Boolean} The feature is currently visible on screen (optionally |
---|
| 154 | * based on its bounds if boundsOnly is true). |
---|
| 155 | */ |
---|
| 156 | onScreen:function(boundsOnly) { |
---|
| 157 | var onScreen = false; |
---|
| 158 | if(this.layer && this.layer.map) { |
---|
| 159 | var screenBounds = this.layer.map.getExtent(); |
---|
| 160 | if(boundsOnly) { |
---|
| 161 | var featureBounds = this.geometry.getBounds(); |
---|
| 162 | onScreen = screenBounds.intersectsBounds(featureBounds); |
---|
| 163 | } else { |
---|
| 164 | var screenPoly = screenBounds.toGeometry(); |
---|
| 165 | onScreen = screenPoly.intersects(this.geometry); |
---|
| 166 | } |
---|
| 167 | } |
---|
| 168 | return onScreen; |
---|
| 169 | }, |
---|
| 170 | |
---|
| 171 | /** |
---|
| 172 | * Method: getVisibility |
---|
| 173 | * Determine whether the feature is displayed or not. It may not displayed |
---|
| 174 | * because: |
---|
| 175 | * - its style display property is set to 'none', |
---|
| 176 | * - it doesn't belong to any layer, |
---|
| 177 | * - the styleMap creates a symbolizer with display property set to 'none' |
---|
| 178 | * for it, |
---|
| 179 | * - the layer which it belongs to is not visible. |
---|
| 180 | * |
---|
| 181 | * Returns: |
---|
| 182 | * {Boolean} The feature is currently displayed. |
---|
| 183 | */ |
---|
| 184 | getVisibility: function() { |
---|
| 185 | return !(this.style && this.style.display == 'none' || |
---|
| 186 | !this.layer || |
---|
| 187 | this.layer && this.layer.styleMap && |
---|
| 188 | this.layer.styleMap.createSymbolizer(this, this.renderIntent).display == 'none' || |
---|
| 189 | this.layer && !this.layer.getVisibility()); |
---|
| 190 | }, |
---|
| 191 | |
---|
| 192 | /** |
---|
| 193 | * Method: createMarker |
---|
| 194 | * HACK - we need to decide if all vector features should be able to |
---|
| 195 | * create markers |
---|
| 196 | * |
---|
| 197 | * Returns: |
---|
| 198 | * {<OpenLayers.Marker>} For now just returns null |
---|
| 199 | */ |
---|
| 200 | createMarker: function() { |
---|
| 201 | return null; |
---|
| 202 | }, |
---|
| 203 | |
---|
| 204 | /** |
---|
| 205 | * Method: destroyMarker |
---|
| 206 | * HACK - we need to decide if all vector features should be able to |
---|
| 207 | * delete markers |
---|
| 208 | * |
---|
| 209 | * If user overrides the createMarker() function, s/he should be able |
---|
| 210 | * to also specify an alternative function for destroying it |
---|
| 211 | */ |
---|
| 212 | destroyMarker: function() { |
---|
| 213 | // pass |
---|
| 214 | }, |
---|
| 215 | |
---|
| 216 | /** |
---|
| 217 | * Method: createPopup |
---|
| 218 | * HACK - we need to decide if all vector features should be able to |
---|
| 219 | * create popups |
---|
| 220 | * |
---|
| 221 | * Returns: |
---|
| 222 | * {<OpenLayers.Popup>} For now just returns null |
---|
| 223 | */ |
---|
| 224 | createPopup: function() { |
---|
| 225 | return null; |
---|
| 226 | }, |
---|
| 227 | |
---|
| 228 | /** |
---|
| 229 | * Method: atPoint |
---|
| 230 | * Determins whether the feature intersects with the specified location. |
---|
| 231 | * |
---|
| 232 | * Parameters: |
---|
| 233 | * lonlat - {<OpenLayers.LonLat>} |
---|
| 234 | * toleranceLon - {float} Optional tolerance in Geometric Coords |
---|
| 235 | * toleranceLat - {float} Optional tolerance in Geographic Coords |
---|
| 236 | * |
---|
| 237 | * Returns: |
---|
| 238 | * {Boolean} Whether or not the feature is at the specified location |
---|
| 239 | */ |
---|
| 240 | atPoint: function(lonlat, toleranceLon, toleranceLat) { |
---|
| 241 | var atPoint = false; |
---|
| 242 | if(this.geometry) { |
---|
| 243 | atPoint = this.geometry.atPoint(lonlat, toleranceLon, |
---|
| 244 | toleranceLat); |
---|
| 245 | } |
---|
| 246 | return atPoint; |
---|
| 247 | }, |
---|
| 248 | |
---|
| 249 | /** |
---|
| 250 | * Method: destroyPopup |
---|
| 251 | * HACK - we need to decide if all vector features should be able to |
---|
| 252 | * delete popups |
---|
| 253 | */ |
---|
| 254 | destroyPopup: function() { |
---|
| 255 | // pass |
---|
| 256 | }, |
---|
| 257 | |
---|
| 258 | /** |
---|
| 259 | * Method: move |
---|
| 260 | * Moves the feature and redraws it at its new location |
---|
| 261 | * |
---|
| 262 | * Parameters: |
---|
| 263 | * state - {OpenLayers.LonLat or OpenLayers.Pixel} the |
---|
| 264 | * location to which to move the feature. |
---|
| 265 | */ |
---|
| 266 | move: function(location) { |
---|
| 267 | |
---|
| 268 | if(!this.layer || !this.geometry.move){ |
---|
| 269 | //do nothing if no layer or immoveable geometry |
---|
| 270 | return; |
---|
| 271 | } |
---|
| 272 | |
---|
| 273 | var pixel; |
---|
| 274 | if (location.CLASS_NAME == "OpenLayers.LonLat") { |
---|
| 275 | pixel = this.layer.getViewPortPxFromLonLat(location); |
---|
| 276 | } else { |
---|
| 277 | pixel = location; |
---|
| 278 | } |
---|
| 279 | |
---|
| 280 | var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat()); |
---|
| 281 | var res = this.layer.map.getResolution(); |
---|
| 282 | this.geometry.move(res * (pixel.x - lastPixel.x), |
---|
| 283 | res * (lastPixel.y - pixel.y)); |
---|
| 284 | this.layer.drawFeature(this); |
---|
| 285 | return lastPixel; |
---|
| 286 | }, |
---|
| 287 | |
---|
| 288 | /** |
---|
| 289 | * Method: toState |
---|
| 290 | * Sets the new state |
---|
| 291 | * |
---|
| 292 | * Parameters: |
---|
| 293 | * state - {String} |
---|
| 294 | */ |
---|
| 295 | toState: function(state) { |
---|
| 296 | if (state == OpenLayers.State.UPDATE) { |
---|
| 297 | switch (this.state) { |
---|
| 298 | case OpenLayers.State.UNKNOWN: |
---|
| 299 | case OpenLayers.State.DELETE: |
---|
| 300 | this.state = state; |
---|
| 301 | break; |
---|
| 302 | case OpenLayers.State.UPDATE: |
---|
| 303 | case OpenLayers.State.INSERT: |
---|
| 304 | break; |
---|
| 305 | } |
---|
| 306 | } else if (state == OpenLayers.State.INSERT) { |
---|
| 307 | switch (this.state) { |
---|
| 308 | case OpenLayers.State.UNKNOWN: |
---|
| 309 | break; |
---|
| 310 | default: |
---|
| 311 | this.state = state; |
---|
| 312 | break; |
---|
| 313 | } |
---|
| 314 | } else if (state == OpenLayers.State.DELETE) { |
---|
| 315 | switch (this.state) { |
---|
| 316 | case OpenLayers.State.INSERT: |
---|
| 317 | // the feature should be destroyed |
---|
| 318 | break; |
---|
| 319 | case OpenLayers.State.DELETE: |
---|
| 320 | break; |
---|
| 321 | case OpenLayers.State.UNKNOWN: |
---|
| 322 | case OpenLayers.State.UPDATE: |
---|
| 323 | this.state = state; |
---|
| 324 | break; |
---|
| 325 | } |
---|
| 326 | } else if (state == OpenLayers.State.UNKNOWN) { |
---|
| 327 | this.state = state; |
---|
| 328 | } |
---|
| 329 | }, |
---|
| 330 | |
---|
| 331 | CLASS_NAME: "OpenLayers.Feature.Vector" |
---|
| 332 | }); |
---|
| 333 | |
---|
| 334 | |
---|
| 335 | /** |
---|
| 336 | * Constant: OpenLayers.Feature.Vector.style |
---|
| 337 | * OpenLayers features can have a number of style attributes. The 'default' |
---|
| 338 | * style will typically be used if no other style is specified. These |
---|
| 339 | * styles correspond for the most part, to the styling properties defined |
---|
| 340 | * by the SVG standard. |
---|
| 341 | * Information on fill properties: http://www.w3.org/TR/SVG/painting.html#FillProperties |
---|
| 342 | * Information on stroke properties: http://www.w3.org/TR/SVG/painting.html#StrokeProperties |
---|
| 343 | * |
---|
| 344 | * Symbolizer properties: |
---|
| 345 | * fill - {Boolean} Set to false if no fill is desired. |
---|
| 346 | * fillColor - {String} Hex fill color. Default is "#ee9900". |
---|
| 347 | * fillOpacity - {Number} Fill opacity (0-1). Default is 0.4 |
---|
| 348 | * stroke - {Boolean} Set to false if no stroke is desired. |
---|
| 349 | * strokeColor - {String} Hex stroke color. Default is "#ee9900". |
---|
| 350 | * strokeOpacity - {Number} Stroke opacity (0-1). Default is 1. |
---|
| 351 | * strokeWidth - {Number} Pixel stroke width. Default is 1. |
---|
| 352 | * strokeLinecap - {String} Stroke cap type. Default is "round". [butt | round | square] |
---|
| 353 | * strokeDashstyle - {String} Stroke dash style. Default is "solid". [dot | dash | dashdot | longdash | longdashdot | solid] |
---|
| 354 | * graphic - {Boolean} Set to false if no graphic is desired. |
---|
| 355 | * pointRadius - {Number} Pixel point radius. Default is 6. |
---|
| 356 | * pointerEvents - {String} Default is "visiblePainted". |
---|
| 357 | * cursor - {String} Default is "". |
---|
| 358 | * externalGraphic - {String} Url to an external graphic that will be used for rendering points. |
---|
| 359 | * graphicWidth - {Number} Pixel width for sizing an external graphic. |
---|
| 360 | * graphicHeight - {Number} Pixel height for sizing an external graphic. |
---|
| 361 | * graphicOpacity - {Number} Opacity (0-1) for an external graphic. |
---|
| 362 | * graphicXOffset - {Number} Pixel offset along the positive x axis for displacing an external graphic. |
---|
| 363 | * graphicYOffset - {Number} Pixel offset along the positive y axis for displacing an external graphic. |
---|
| 364 | * rotation - {Number} For point symbolizers, this is the rotation of a graphic in the clockwise direction about its center point (or any point off center as specified by graphicXOffset and graphicYOffset). |
---|
| 365 | * graphicZIndex - {Number} The integer z-index value to use in rendering. |
---|
| 366 | * graphicName - {String} Named graphic to use when rendering points. Supported values include "circle" (default), |
---|
| 367 | * "square", "star", "x", "cross", "triangle". |
---|
| 368 | * graphicTitle - {String} Tooltip for an external graphic. Only supported in Firefox and Internet Explorer. |
---|
| 369 | * backgroundGraphic - {String} Url to a graphic to be used as the background under an externalGraphic. |
---|
| 370 | * backgroundGraphicZIndex - {Number} The integer z-index value to use in rendering the background graphic. |
---|
| 371 | * backgroundXOffset - {Number} The x offset (in pixels) for the background graphic. |
---|
| 372 | * backgroundYOffset - {Number} The y offset (in pixels) for the background graphic. |
---|
| 373 | * backgroundHeight - {Number} The height of the background graphic. If not provided, the graphicHeight will be used. |
---|
| 374 | * backgroundWidth - {Number} The width of the background width. If not provided, the graphicWidth will be used. |
---|
| 375 | * label - {String} The text for an optional label. For browsers that use the canvas renderer, this requires either |
---|
| 376 | * fillText or mozDrawText to be available. |
---|
| 377 | * labelAlign - {String} Label alignment. This specifies the insertion point relative to the text. It is a string |
---|
| 378 | * composed of two characters. The first character is for the horizontal alignment, the second for the vertical |
---|
| 379 | * alignment. Valid values for horizontal alignment: "l"=left, "c"=center, "r"=right. Valid values for vertical |
---|
| 380 | * alignment: "t"=top, "m"=middle, "b"=bottom. Example values: "lt", "cm", "rb". The canvas renderer does not |
---|
| 381 | * support vertical alignment, it will always use "b". |
---|
| 382 | * labelXOffset - {Number} Pixel offset along the positive x axis for displacing the label. |
---|
| 383 | * labelYOffset - {Number} Pixel offset along the positive y axis for displacing the label. |
---|
| 384 | * labelSelect - {Boolean} If set to true, labels will be selectable using SelectFeature or similar controls. |
---|
| 385 | * Default is false. |
---|
| 386 | * fontColor - {String} The font color for the label, to be provided like CSS. |
---|
| 387 | * fontOpacity - {Number} Opacity (0-1) for the label |
---|
| 388 | * fontFamily - {String} The font family for the label, to be provided like in CSS. |
---|
| 389 | * fontSize - {String} The font size for the label, to be provided like in CSS. |
---|
| 390 | * fontWeight - {String} The font weight for the label, to be provided like in CSS. |
---|
| 391 | * display - {String} Symbolizers will have no effect if display is set to "none". All other values have no effect. |
---|
| 392 | */ |
---|
| 393 | OpenLayers.Feature.Vector.style = { |
---|
| 394 | 'default': { |
---|
| 395 | fillColor: "#ee9900", |
---|
| 396 | fillOpacity: 0.4, |
---|
| 397 | hoverFillColor: "white", |
---|
| 398 | hoverFillOpacity: 0.8, |
---|
| 399 | strokeColor: "#ee9900", |
---|
| 400 | strokeOpacity: 1, |
---|
| 401 | strokeWidth: 1, |
---|
| 402 | strokeLinecap: "round", |
---|
| 403 | strokeDashstyle: "solid", |
---|
| 404 | hoverStrokeColor: "red", |
---|
| 405 | hoverStrokeOpacity: 1, |
---|
| 406 | hoverStrokeWidth: 0.2, |
---|
| 407 | pointRadius: 6, |
---|
| 408 | hoverPointRadius: 1, |
---|
| 409 | hoverPointUnit: "%", |
---|
| 410 | pointerEvents: "visiblePainted", |
---|
| 411 | cursor: "inherit" |
---|
| 412 | }, |
---|
| 413 | 'select': { |
---|
| 414 | fillColor: "blue", |
---|
| 415 | fillOpacity: 0.4, |
---|
| 416 | hoverFillColor: "white", |
---|
| 417 | hoverFillOpacity: 0.8, |
---|
| 418 | strokeColor: "blue", |
---|
| 419 | strokeOpacity: 1, |
---|
| 420 | strokeWidth: 2, |
---|
| 421 | strokeLinecap: "round", |
---|
| 422 | strokeDashstyle: "solid", |
---|
| 423 | hoverStrokeColor: "red", |
---|
| 424 | hoverStrokeOpacity: 1, |
---|
| 425 | hoverStrokeWidth: 0.2, |
---|
| 426 | pointRadius: 6, |
---|
| 427 | hoverPointRadius: 1, |
---|
| 428 | hoverPointUnit: "%", |
---|
| 429 | pointerEvents: "visiblePainted", |
---|
| 430 | cursor: "pointer" |
---|
| 431 | }, |
---|
| 432 | 'temporary': { |
---|
| 433 | fillColor: "#66cccc", |
---|
| 434 | fillOpacity: 0.2, |
---|
| 435 | hoverFillColor: "white", |
---|
| 436 | hoverFillOpacity: 0.8, |
---|
| 437 | strokeColor: "#66cccc", |
---|
| 438 | strokeOpacity: 1, |
---|
| 439 | strokeLinecap: "round", |
---|
| 440 | strokeWidth: 2, |
---|
| 441 | strokeDashstyle: "solid", |
---|
| 442 | hoverStrokeColor: "red", |
---|
| 443 | hoverStrokeOpacity: 1, |
---|
| 444 | hoverStrokeWidth: 0.2, |
---|
| 445 | pointRadius: 6, |
---|
| 446 | hoverPointRadius: 1, |
---|
| 447 | hoverPointUnit: "%", |
---|
| 448 | pointerEvents: "visiblePainted", |
---|
| 449 | cursor: "inherit" |
---|
| 450 | }, |
---|
| 451 | 'delete': { |
---|
| 452 | display: "none" |
---|
| 453 | } |
---|
| 454 | }; |
---|