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