Files
openlayers/lib/OpenLayers/Feature/Vector.js
ahocevar 9588f25ce5 Stroke style of features can now be specified. Both SVG's
stroke-dasharray and VML's dashstyle properties are allowed in the new 
strokeDashstyle symbolizer property. For VML, which does not support 
custom dash styles, one of the 5 matching pre-defined dash styles will 
be guessed. The patch also adds support for the stroke-dasharray 
property in SLD. r=crschmidt (closes #1126)


git-svn-id: http://svn.openlayers.org/trunk/openlayers@7673 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
2008-08-01 21:56:17 +00:00

392 lines
11 KiB
JavaScript

/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
// TRASH THIS
OpenLayers.State = {
/** states */
UNKNOWN: 'Unknown',
INSERT: 'Insert',
UPDATE: 'Update',
DELETE: 'Delete'
};
/**
* @requires OpenLayers/Feature.js
* @requires OpenLayers/Util.js
*/
/**
* Class: OpenLayers.Feature.Vector
* Vector features use the OpenLayers.Geometry classes as geometry description.
* They have an 'attributes' property, which is the data object, and a 'style'
* property, the default values of which are defined in the
* <OpenLayers.Feature.Vector.style> objects.
*
* Inherits from:
* - <OpenLayers.Feature>
*/
OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {
/**
* Property: fid
* {String}
*/
fid: null,
/**
* APIProperty: geometry
* {<OpenLayers.Geometry>}
*/
geometry: null,
/**
* APIProperty: attributes
* {Object} This object holds arbitrary properties that describe the
* feature.
*/
attributes: null,
/**
* Property: state
* {String}
*/
state: null,
/**
* APIProperty: style
* {Object}
*/
style: null,
/**
* Property: renderIntent
* {String} rendering intent currently being used
*/
renderIntent: "default",
/**
* Constructor: OpenLayers.Feature.Vector
* Create a vector feature.
*
* Parameters:
* geometry - {<OpenLayers.Geometry>} The geometry that this feature
* represents.
* attributes - {Object} An optional object that will be mapped to the
* <attributes> property.
* style - {Object} An optional style object.
*/
initialize: function(geometry, attributes, style) {
OpenLayers.Feature.prototype.initialize.apply(this,
[null, null, attributes]);
this.lonlat = null;
this.geometry = geometry ? geometry : null;
this.state = null;
this.attributes = {};
if (attributes) {
this.attributes = OpenLayers.Util.extend(this.attributes,
attributes);
}
this.style = style ? style : null;
},
/**
* Method: destroy
* nullify references to prevent circular references and memory leaks
*/
destroy: function() {
if (this.layer) {
this.layer.removeFeatures(this);
this.layer = null;
}
this.geometry = null;
OpenLayers.Feature.prototype.destroy.apply(this, arguments);
},
/**
* Method: clone
* Create a clone of this vector feature. Does not set any non-standard
* properties.
*
* Returns:
* {<OpenLayers.Feature.Vector>} An exact clone of this vector feature.
*/
clone: function () {
return new OpenLayers.Feature.Vector(
this.geometry ? this.geometry.clone() : null,
this.attributes,
this.style);
},
/**
* Method: onScreen
* Determine whether the feature is within the map viewport. This method
* tests for an intersection between the geometry and the viewport
* bounds. If a more effecient but less precise geometry bounds
* intersection is desired, call the method with the boundsOnly
* parameter true.
*
* Parameters:
* boundsOnly - {Boolean} Only test whether a feature's bounds intersects
* the viewport bounds. Default is false. If false, the feature's
* geometry must intersect the viewport for onScreen to return true.
*
* Returns:
* {Boolean} The feature is currently visible on screen (optionally
* based on its bounds if boundsOnly is true).
*/
onScreen:function(boundsOnly) {
var onScreen = false;
if(this.layer && this.layer.map) {
var screenBounds = this.layer.map.getExtent();
if(boundsOnly) {
var featureBounds = this.geometry.getBounds();
onScreen = screenBounds.intersectsBounds(featureBounds);
} else {
var screenPoly = screenBounds.toGeometry();
onScreen = screenPoly.intersects(this.geometry);
}
}
return onScreen;
},
/**
* Method: createMarker
* HACK - we need to decide if all vector features should be able to
* create markers
*
* Returns:
* {<OpenLayers.Marker>} For now just returns null
*/
createMarker: function() {
return null;
},
/**
* Method: destroyMarker
* 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
},
/**
* Method: createPopup
* HACK - we need to decide if all vector features should be able to
* create popups
*
* Returns:
* {<OpenLayers.Popup>} For now just returns null
*/
createPopup: function() {
return null;
},
/**
* Method: atPoint
* Determins whether the feature intersects with the specified location.
*
* Parameters:
* lonlat - {<OpenLayers.LonLat>}
* toleranceLon - {float} Optional tolerance in Geometric Coords
* toleranceLat - {float} Optional tolerance in Geographic Coords
*
* Returns:
* {Boolean} Whether or not the feature is at the specified location
*/
atPoint: function(lonlat, toleranceLon, toleranceLat) {
var atPoint = false;
if(this.geometry) {
atPoint = this.geometry.atPoint(lonlat, toleranceLon,
toleranceLat);
}
return atPoint;
},
/**
* Method: destroyPopup
* HACK - we need to decide if all vector features should be able to
* delete popups
*/
destroyPopup: function() {
// pass
},
/**
* Method: move
* Moves the feature and redraws it at its new location
*
* Parameters:
* state - {OpenLayers.LonLat or OpenLayers.Pixel} the
* location to which to move the feature.
*/
move: function(location) {
if(!this.layer || !this.geometry.move){
//do nothing if no layer or immoveable geometry
return;
}
var pixel;
if (location.CLASS_NAME == "OpenLayers.LonLat") {
pixel = this.layer.getViewPortPxFromLonLat(location);
} else {
pixel = location;
}
var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());
var res = this.layer.map.getResolution();
this.geometry.move(res * (pixel.x - lastPixel.x),
res * (lastPixel.y - pixel.y));
this.layer.drawFeature(this);
return lastPixel;
},
/**
* Method: toState
* Sets the new state
*
* Parameters:
* state - {String}
*/
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;
}
},
CLASS_NAME: "OpenLayers.Feature.Vector"
});
/**
* Constant: OpenLayers.Feature.Vector.style
* OpenLayers features can have a number of style attributes. The 'default'
* style will typically be used if no other style is specified.
*
* Default style properties:
*
* - fillColor: "#ee9900",
* - fillOpacity: 0.4,
* - hoverFillColor: "white",
* - hoverFillOpacity: 0.8,
* - strokeColor: "#ee9900",
* - strokeOpacity: 1,
* - strokeWidth: 1,
* - strokeLinecap: "round", [butt | round | square]
* - strokeDashstyle: "solid", [dot | dash | dashdot | longdash | longdashdot | solid]
* - hoverStrokeColor: "red",
* - hoverStrokeOpacity: 1,
* - hoverStrokeWidth: 0.2,
* - pointRadius: 6,
* - hoverPointRadius: 1,
* - hoverPointUnit: "%",
* - pointerEvents: "visiblePainted"
* - cursor: ""
*
* Other style properties that have no default values:
*
* - externalGraphic,
* - graphicWidth,
* - graphicHeight,
* - graphicOpacity,
* - graphicXOffset,
* - graphicYOffset,
* - graphicName,
* - display
*/
OpenLayers.Feature.Vector.style = {
'default': {
fillColor: "#ee9900",
fillOpacity: 0.4,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "#ee9900",
strokeOpacity: 1,
strokeWidth: 1,
strokeLinecap: "round",
strokeDashstyle: "solid",
hoverStrokeColor: "red",
hoverStrokeOpacity: 1,
hoverStrokeWidth: 0.2,
pointRadius: 6,
hoverPointRadius: 1,
hoverPointUnit: "%",
pointerEvents: "visiblePainted",
cursor: "inherit"
},
'select': {
fillColor: "blue",
fillOpacity: 0.4,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "blue",
strokeOpacity: 1,
strokeWidth: 2,
strokeLinecap: "round",
strokeDashstyle: "solid",
hoverStrokeColor: "red",
hoverStrokeOpacity: 1,
hoverStrokeWidth: 0.2,
pointRadius: 6,
hoverPointRadius: 1,
hoverPointUnit: "%",
pointerEvents: "visiblePainted",
cursor: "pointer"
},
'temporary': {
fillColor: "yellow",
fillOpacity: 0.2,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "yellow",
strokeOpacity: 1,
strokeLinecap: "round",
strokeWidth: 4,
strokeDashstyle: "solid",
hoverStrokeColor: "red",
hoverStrokeOpacity: 1,
hoverStrokeWidth: 0.2,
pointRadius: 6,
hoverPointRadius: 1,
hoverPointUnit: "%",
pointerEvents: "visiblePainted",
cursor: "inherit"
}
};