Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/OpenLayers/lib/OpenLayers/Renderer/Elements.js @ 76

Revision 76, 31.8 KB checked in by djay, 12 years ago (diff)

Ajout du répertoire web

  • Property svn:executable set to *
Line 
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/**
7 * @requires OpenLayers/Renderer.js
8 */
9
10/**
11 * Class: OpenLayers.ElementsIndexer
12 * This class takes care of figuring out which order elements should be
13 *     placed in the DOM based on given indexing methods.
14 */
15OpenLayers.ElementsIndexer = OpenLayers.Class({
16   
17    /**
18     * Property: maxZIndex
19     * {Integer} This is the largest-most z-index value for a node
20     *     contained within the indexer.
21     */
22    maxZIndex: null,
23   
24    /**
25     * Property: order
26     * {Array<String>} This is an array of node id's stored in the
27     *     order that they should show up on screen. Id's higher up in the
28     *     array (higher array index) represent nodes with higher z-indeces.
29     */
30    order: null, 
31   
32    /**
33     * Property: indices
34     * {Object} This is a hash that maps node ids to their z-index value
35     *     stored in the indexer. This is done to make finding a nodes z-index
36     *     value O(1).
37     */
38    indices: null,
39   
40    /**
41     * Property: compare
42     * {Function} This is the function used to determine placement of
43     *     of a new node within the indexer. If null, this defaults to to
44     *     the Z_ORDER_DRAWING_ORDER comparison method.
45     */
46    compare: null,
47   
48    /**
49     * APIMethod: initialize
50     * Create a new indexer with
51     *
52     * Parameters:
53     * yOrdering - {Boolean} Whether to use y-ordering.
54     */
55    initialize: function(yOrdering) {
56
57        this.compare = yOrdering ? 
58            OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_Y_ORDER :
59            OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_DRAWING_ORDER;
60           
61        this.order = [];
62        this.indices = {};
63        this.maxZIndex = 0;
64    },
65   
66    /**
67     * APIMethod: insert
68     * Insert a new node into the indexer. In order to find the correct
69     *     positioning for the node to be inserted, this method uses a binary
70     *     search. This makes inserting O(log(n)).
71     *
72     * Parameters:
73     * newNode - {DOMElement} The new node to be inserted.
74     *
75     * Returns
76     * {DOMElement} the node before which we should insert our newNode, or
77     *     null if newNode can just be appended.
78     */
79    insert: function(newNode) {
80        // If the node is known to the indexer, remove it so we can
81        // recalculate where it should go.
82        if (this.exists(newNode)) {
83            this.remove(newNode);
84        }
85       
86        var nodeId = newNode.id;
87       
88        this.determineZIndex(newNode);       
89
90        var leftIndex = -1;
91        var rightIndex = this.order.length;
92        var middle;
93
94        while (rightIndex - leftIndex > 1) {
95            middle = parseInt((leftIndex + rightIndex) / 2);
96           
97            var placement = this.compare(this, newNode,
98                OpenLayers.Util.getElement(this.order[middle]));
99           
100            if (placement > 0) {
101                leftIndex = middle;
102            } else {
103                rightIndex = middle;
104            } 
105        }
106       
107        this.order.splice(rightIndex, 0, nodeId);
108        this.indices[nodeId] = this.getZIndex(newNode);
109       
110        // If the new node should be before another in the index
111        // order, return the node before which we have to insert the new one;
112        // else, return null to indicate that the new node can be appended.
113        return this.getNextElement(rightIndex);
114    },
115   
116    /**
117     * APIMethod: remove
118     *
119     * Parameters:
120     * node - {DOMElement} The node to be removed.
121     */
122    remove: function(node) {
123        var nodeId = node.id;
124        var arrayIndex = OpenLayers.Util.indexOf(this.order, nodeId);
125        if (arrayIndex >= 0) {
126            // Remove it from the order array, as well as deleting the node
127            // from the indeces hash.
128            this.order.splice(arrayIndex, 1);
129            delete this.indices[nodeId];
130           
131            // Reset the maxium z-index based on the last item in the
132            // order array.
133            if (this.order.length > 0) {
134                var lastId = this.order[this.order.length - 1];
135                this.maxZIndex = this.indices[lastId];
136            } else {
137                this.maxZIndex = 0;
138            }
139        }
140    },
141   
142    /**
143     * APIMethod: clear
144     */
145    clear: function() {
146        this.order = [];
147        this.indices = {};
148        this.maxZIndex = 0;
149    },
150   
151    /**
152     * APIMethod: exists
153     *
154     * Parameters:
155     * node- {DOMElement} The node to test for existence.
156     *
157     * Returns:
158     * {Boolean} Whether or not the node exists in the indexer?
159     */
160    exists: function(node) {
161        return (this.indices[node.id] != null);
162    },
163
164    /**
165     * APIMethod: getZIndex
166     * Get the z-index value for the current node from the node data itself.
167     *
168     * Parameters:
169     * node - {DOMElement} The node whose z-index to get.
170     *
171     * Returns:
172     * {Integer} The z-index value for the specified node (from the node
173     *     data itself).
174     */
175    getZIndex: function(node) {
176        return node._style.graphicZIndex; 
177    },
178   
179    /**
180     * Method: determineZIndex
181     * Determine the z-index for the current node if there isn't one,
182     *     and set the maximum value if we've found a new maximum.
183     *
184     * Parameters:
185     * node - {DOMElement}
186     */
187    determineZIndex: function(node) {
188        var zIndex = node._style.graphicZIndex;
189       
190        // Everything must have a zIndex. If none is specified,
191        // this means the user *must* (hint: assumption) want this
192        // node to succomb to drawing order. To enforce drawing order
193        // over all indexing methods, we'll create a new z-index that's
194        // greater than any currently in the indexer.
195        if (zIndex == null) {
196            zIndex = this.maxZIndex;
197            node._style.graphicZIndex = zIndex; 
198        } else if (zIndex > this.maxZIndex) {
199            this.maxZIndex = zIndex;
200        }
201    },
202
203    /**
204     * APIMethod: getNextElement
205     * Get the next element in the order stack.
206     *
207     * Parameters:
208     * index - {Integer} The index of the current node in this.order.
209     *
210     * Returns:
211     * {DOMElement} the node following the index passed in, or
212     *     null.
213     */
214    getNextElement: function(index) {
215        var nextIndex = index + 1;
216        if (nextIndex < this.order.length) {
217            var nextElement = OpenLayers.Util.getElement(this.order[nextIndex]);
218            if (nextElement == undefined) {
219                nextElement = this.getNextElement(nextIndex);
220            }
221            return nextElement;
222        } else {
223            return null;
224        } 
225    },
226   
227    CLASS_NAME: "OpenLayers.ElementsIndexer"
228});
229
230/**
231 * Namespace: OpenLayers.ElementsIndexer.IndexingMethods
232 * These are the compare methods for figuring out where a new node should be
233 *     placed within the indexer. These methods are very similar to general
234 *     sorting methods in that they return -1, 0, and 1 to specify the
235 *     direction in which new nodes fall in the ordering.
236 */
237OpenLayers.ElementsIndexer.IndexingMethods = {
238   
239    /**
240     * Method: Z_ORDER
241     * This compare method is used by other comparison methods.
242     *     It can be used individually for ordering, but is not recommended,
243     *     because it doesn't subscribe to drawing order.
244     *
245     * Parameters:
246     * indexer - {<OpenLayers.ElementsIndexer>}
247     * newNode - {DOMElement}
248     * nextNode - {DOMElement}
249     *
250     * Returns:
251     * {Integer}
252     */
253    Z_ORDER: function(indexer, newNode, nextNode) {
254        var newZIndex = indexer.getZIndex(newNode);
255
256        var returnVal = 0;
257        if (nextNode) {
258            var nextZIndex = indexer.getZIndex(nextNode);
259            returnVal = newZIndex - nextZIndex; 
260        }
261       
262        return returnVal;
263    },
264
265    /**
266     * APIMethod: Z_ORDER_DRAWING_ORDER
267     * This method orders nodes by their z-index, but does so in a way
268     *     that, if there are other nodes with the same z-index, the newest
269     *     drawn will be the front most within that z-index. This is the
270     *     default indexing method.
271     *
272     * Parameters:
273     * indexer - {<OpenLayers.ElementsIndexer>}
274     * newNode - {DOMElement}
275     * nextNode - {DOMElement}
276     *
277     * Returns:
278     * {Integer}
279     */
280    Z_ORDER_DRAWING_ORDER: function(indexer, newNode, nextNode) {
281        var returnVal = OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(
282            indexer, 
283            newNode, 
284            nextNode
285        );
286       
287        // Make Z_ORDER subscribe to drawing order by pushing it above
288        // all of the other nodes with the same z-index.
289        if (nextNode && returnVal == 0) {
290            returnVal = 1;
291        }
292       
293        return returnVal;
294    },
295
296    /**
297     * APIMethod: Z_ORDER_Y_ORDER
298     * This one should really be called Z_ORDER_Y_ORDER_DRAWING_ORDER, as it
299     *     best describes which ordering methods have precedence (though, the
300     *     name would be too long). This method orders nodes by their z-index,
301     *     but does so in a way that, if there are other nodes with the same
302     *     z-index, the nodes with the lower y position will be "closer" than
303     *     those with a higher y position. If two nodes have the exact same y
304     *     position, however, then this method will revert to using drawing 
305     *     order to decide placement.
306     *
307     * Parameters:
308     * indexer - {<OpenLayers.ElementsIndexer>}
309     * newNode - {DOMElement}
310     * nextNode - {DOMElement}
311     *
312     * Returns:
313     * {Integer}
314     */
315    Z_ORDER_Y_ORDER: function(indexer, newNode, nextNode) {
316        var returnVal = OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(
317            indexer, 
318            newNode, 
319            nextNode
320        );
321       
322        if (nextNode && returnVal === 0) {           
323            var result = nextNode._boundsBottom - newNode._boundsBottom;
324            returnVal = (result === 0) ? 1 : result;
325        }
326       
327        return returnVal;       
328    }
329};
330
331/**
332 * Class: OpenLayers.Renderer.Elements
333 * This is another virtual class in that it should never be instantiated by
334 *  itself as a Renderer. It exists because there is *tons* of shared
335 *  functionality between different vector libraries which use nodes/elements
336 *  as a base for rendering vectors.
337 *
338 * The highlevel bits of code that are implemented here are the adding and
339 *  removing of geometries, which is essentially the same for any
340 *  element-based renderer. The details of creating each node and drawing the
341 *  paths are of course different, but the machinery is the same.
342 *
343 * Inherits:
344 *  - <OpenLayers.Renderer>
345 */
346OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
347
348    /**
349     * Property: rendererRoot
350     * {DOMElement}
351     */
352    rendererRoot: null,
353   
354    /**
355     * Property: root
356     * {DOMElement}
357     */
358    root: null,
359   
360    /**
361     * Property: vectorRoot
362     * {DOMElement}
363     */
364    vectorRoot: null,
365
366    /**
367     * Property: textRoot
368     * {DOMElement}
369     */
370    textRoot: null,
371
372    /**
373     * Property: xmlns
374     * {String}
375     */   
376    xmlns: null,
377   
378    /**
379     * Property: Indexer
380     * {<OpenLayers.ElementIndexer>} An instance of OpenLayers.ElementsIndexer
381     *     created upon initialization if the zIndexing or yOrdering options
382     *     passed to this renderer's constructor are set to true.
383     */
384    indexer: null, 
385   
386    /**
387     * Constant: BACKGROUND_ID_SUFFIX
388     * {String}
389     */
390    BACKGROUND_ID_SUFFIX: "_background",
391   
392    /**
393     * Constant: BACKGROUND_ID_SUFFIX
394     * {String}
395     */
396    LABEL_ID_SUFFIX: "_label",
397   
398    /**
399     * Constructor: OpenLayers.Renderer.Elements
400     *
401     * Parameters:
402     * containerID - {String}
403     * options - {Object} options for this renderer. Supported options are:
404     *     * yOrdering - {Boolean} Whether to use y-ordering
405     *     * zIndexing - {Boolean} Whether to use z-indexing. Will be ignored
406     *         if yOrdering is set to true.
407     */
408    initialize: function(containerID, options) {
409        OpenLayers.Renderer.prototype.initialize.apply(this, arguments);
410
411        this.rendererRoot = this.createRenderRoot();
412        this.root = this.createRoot("_root");
413        this.vectorRoot = this.createRoot("_vroot");
414        this.textRoot = this.createRoot("_troot");
415       
416        this.root.appendChild(this.vectorRoot);
417        this.root.appendChild(this.textRoot);
418       
419        this.rendererRoot.appendChild(this.root);
420        this.container.appendChild(this.rendererRoot);
421       
422        if(options && (options.zIndexing || options.yOrdering)) {
423            this.indexer = new OpenLayers.ElementsIndexer(options.yOrdering);
424        }
425    },
426   
427    /**
428     * Method: destroy
429     */
430    destroy: function() {
431
432        this.clear(); 
433
434        this.rendererRoot = null;
435        this.root = null;
436        this.xmlns = null;
437
438        OpenLayers.Renderer.prototype.destroy.apply(this, arguments);
439    },
440   
441    /**
442     * Method: clear
443     * Remove all the elements from the root
444     */   
445    clear: function() {
446        var child;
447        var root = this.vectorRoot;
448        if (root) {
449            while (child = root.firstChild) {
450                root.removeChild(child);
451            }
452        }
453        root = this.textRoot;
454        if (root) {
455            while (child = root.firstChild) {
456                root.removeChild(child);
457            }
458        }
459        if (this.indexer) {
460            this.indexer.clear();
461        }
462    },
463
464    /**
465     * Method: getNodeType
466     * This function is in charge of asking the specific renderer which type
467     *     of node to create for the given geometry and style. All geometries
468     *     in an Elements-based renderer consist of one node and some
469     *     attributes. We have the nodeFactory() function which creates a node
470     *     for us, but it takes a 'type' as input, and that is precisely what
471     *     this function tells us. 
472     * 
473     * Parameters:
474     * geometry - {<OpenLayers.Geometry>}
475     * style - {Object}
476     *
477     * Returns:
478     * {String} The corresponding node type for the specified geometry
479     */
480    getNodeType: function(geometry, style) { },
481
482    /**
483     * Method: drawGeometry
484     * Draw the geometry, creating new nodes, setting paths, setting style,
485     *     setting featureId on the node.  This method should only be called
486     *     by the renderer itself.
487     *
488     * Parameters:
489     * geometry - {<OpenLayers.Geometry>}
490     * style - {Object}
491     * featureId - {String}
492     *
493     * Returns:
494     * {Boolean} true if the geometry has been drawn completely; null if
495     *     incomplete; false otherwise
496     */
497    drawGeometry: function(geometry, style, featureId) {
498        var className = geometry.CLASS_NAME;
499        var rendered = true;
500        if ((className == "OpenLayers.Geometry.Collection") ||
501            (className == "OpenLayers.Geometry.MultiPoint") ||
502            (className == "OpenLayers.Geometry.MultiLineString") ||
503            (className == "OpenLayers.Geometry.MultiPolygon")) {
504            for (var i = 0, len=geometry.components.length; i<len; i++) {
505                rendered = this.drawGeometry(
506                    geometry.components[i], style, featureId) && rendered;
507            }
508            return rendered;
509        };
510
511        rendered = false;
512        if (style.display != "none") {
513            if (style.backgroundGraphic) {
514                this.redrawBackgroundNode(geometry.id, geometry, style,
515                    featureId);
516            }
517            rendered = this.redrawNode(geometry.id, geometry, style,
518                featureId);
519        }
520        if (rendered == false) {
521            var node = document.getElementById(geometry.id);
522            if (node) {
523                if (node._style.backgroundGraphic) {
524                    node.parentNode.removeChild(document.getElementById(
525                        geometry.id + this.BACKGROUND_ID_SUFFIX));
526                }
527                node.parentNode.removeChild(node);
528            }
529        }
530        return rendered;
531    },
532   
533    /**
534     * Method: redrawNode
535     *
536     * Parameters:
537     * id - {String}
538     * geometry - {<OpenLayers.Geometry>}
539     * style - {Object}
540     * featureId - {String}
541     *
542     * Returns:
543     * {Boolean} true if the complete geometry could be drawn, null if parts of
544     *     the geometry could not be drawn, false otherwise
545     */
546    redrawNode: function(id, geometry, style, featureId) {
547        style = this.applyDefaultSymbolizer(style);
548        // Get the node if it's already on the map.
549        var node = this.nodeFactory(id, this.getNodeType(geometry, style));
550       
551        // Set the data for the node, then draw it.
552        node._featureId = featureId;
553        node._boundsBottom = geometry.getBounds().bottom;
554        node._geometryClass = geometry.CLASS_NAME;
555        node._style = style;
556
557        var drawResult = this.drawGeometryNode(node, geometry, style);
558        if(drawResult === false) {
559            return false;
560        }
561         
562        node = drawResult.node;
563       
564        // Insert the node into the indexer so it can show us where to
565        // place it. Note that this operation is O(log(n)). If there's a
566        // performance problem (when dragging, for instance) this is
567        // likely where it would be.
568        if (this.indexer) {
569            var insert = this.indexer.insert(node);
570            if (insert) {
571                this.vectorRoot.insertBefore(node, insert);
572            } else {
573                this.vectorRoot.appendChild(node);
574            }
575        } else {
576            // if there's no indexer, simply append the node to root,
577            // but only if the node is a new one
578            if (node.parentNode !== this.vectorRoot){ 
579                this.vectorRoot.appendChild(node);
580            }
581        }
582       
583        this.postDraw(node);
584       
585        return drawResult.complete;
586    },
587   
588    /**
589     * Method: redrawBackgroundNode
590     * Redraws the node using special 'background' style properties. Basically
591     *     just calls redrawNode(), but instead of directly using the
592     *     'externalGraphic', 'graphicXOffset', 'graphicYOffset', and
593     *     'graphicZIndex' properties directly from the specified 'style'
594     *     parameter, we create a new style object and set those properties
595     *     from the corresponding 'background'-prefixed properties from
596     *     specified 'style' parameter.
597     *
598     * Parameters:
599     * id - {String}
600     * geometry - {<OpenLayers.Geometry>}
601     * style - {Object}
602     * featureId - {String}
603     *
604     * Returns:
605     * {Boolean} true if the complete geometry could be drawn, null if parts of
606     *     the geometry could not be drawn, false otherwise
607     */
608    redrawBackgroundNode: function(id, geometry, style, featureId) {
609        var backgroundStyle = OpenLayers.Util.extend({}, style);
610       
611        // Set regular style attributes to apply to the background styles.
612        backgroundStyle.externalGraphic = backgroundStyle.backgroundGraphic;
613        backgroundStyle.graphicXOffset = backgroundStyle.backgroundXOffset;
614        backgroundStyle.graphicYOffset = backgroundStyle.backgroundYOffset;
615        backgroundStyle.graphicZIndex = backgroundStyle.backgroundGraphicZIndex;
616        backgroundStyle.graphicWidth = backgroundStyle.backgroundWidth || backgroundStyle.graphicWidth;
617        backgroundStyle.graphicHeight = backgroundStyle.backgroundHeight || backgroundStyle.graphicHeight;
618       
619        // Erase background styles.
620        backgroundStyle.backgroundGraphic = null;
621        backgroundStyle.backgroundXOffset = null;
622        backgroundStyle.backgroundYOffset = null;
623        backgroundStyle.backgroundGraphicZIndex = null;
624       
625        return this.redrawNode(
626            id + this.BACKGROUND_ID_SUFFIX, 
627            geometry, 
628            backgroundStyle, 
629            null
630        );
631    },
632
633    /**
634     * Method: drawGeometryNode
635     * Given a node, draw a geometry on the specified layer.
636     *     node and geometry are required arguments, style is optional.
637     *     This method is only called by the render itself.
638     *
639     * Parameters:
640     * node - {DOMElement}
641     * geometry - {<OpenLayers.Geometry>}
642     * style - {Object}
643     *
644     * Returns:
645     * {Object} a hash with properties "node" (the drawn node) and "complete"
646     *     (null if parts of the geometry could not be drawn, false if nothing
647     *     could be drawn)
648     */
649    drawGeometryNode: function(node, geometry, style) {
650        style = style || node._style;
651
652        var options = {
653            'isFilled': style.fill === undefined ?
654                true :
655                style.fill,
656            'isStroked': style.stroke === undefined ?
657                !!style.strokeWidth :
658                style.stroke
659        };
660        var drawn;
661        switch (geometry.CLASS_NAME) {
662            case "OpenLayers.Geometry.Point":
663                if(style.graphic === false) {
664                    options.isFilled = false;
665                    options.isStroked = false;
666                }
667                drawn = this.drawPoint(node, geometry);
668                break;
669            case "OpenLayers.Geometry.LineString":
670                options.isFilled = false;
671                drawn = this.drawLineString(node, geometry);
672                break;
673            case "OpenLayers.Geometry.LinearRing":
674                drawn = this.drawLinearRing(node, geometry);
675                break;
676            case "OpenLayers.Geometry.Polygon":
677                drawn = this.drawPolygon(node, geometry);
678                break;
679            case "OpenLayers.Geometry.Surface":
680                drawn = this.drawSurface(node, geometry);
681                break;
682            case "OpenLayers.Geometry.Rectangle":
683                drawn = this.drawRectangle(node, geometry);
684                break;
685            default:
686                break;
687        }
688
689        node._options = options; 
690
691        //set style
692        //TBD simplify this
693        if (drawn != false) {
694            return {
695                node: this.setStyle(node, style, options, geometry),
696                complete: drawn
697            };
698        } else {
699            return false;
700        }
701    },
702   
703    /**
704     * Method: postDraw
705     * Things that have do be done after the geometry node is appended
706     *     to its parent node. To be overridden by subclasses.
707     *
708     * Parameters:
709     * node - {DOMElement}
710     */
711    postDraw: function(node) {},
712   
713    /**
714     * Method: drawPoint
715     * Virtual function for drawing Point Geometry.
716     *     Should be implemented by subclasses.
717     *     This method is only called by the renderer itself.
718     *
719     * Parameters:
720     * node - {DOMElement}
721     * geometry - {<OpenLayers.Geometry>}
722     *
723     * Returns:
724     * {DOMElement} or false if the renderer could not draw the point
725     */ 
726    drawPoint: function(node, geometry) {},
727
728    /**
729     * Method: drawLineString
730     * Virtual function for drawing LineString Geometry.
731     *     Should be implemented by subclasses.
732     *     This method is only called by the renderer itself.
733     *
734     * Parameters:
735     * node - {DOMElement}
736     * geometry - {<OpenLayers.Geometry>}
737     *
738     * Returns:
739     * {DOMElement} or null if the renderer could not draw all components of
740     *     the linestring, or false if nothing could be drawn
741     */ 
742    drawLineString: function(node, geometry) {},
743
744    /**
745     * Method: drawLinearRing
746     * Virtual function for drawing LinearRing Geometry.
747     *     Should be implemented by subclasses.
748     *     This method is only called by the renderer itself.
749     *
750     * Parameters:
751     * node - {DOMElement}
752     * geometry - {<OpenLayers.Geometry>}
753     *
754     * Returns:
755     * {DOMElement} or null if the renderer could not draw all components
756     *     of the linear ring, or false if nothing could be drawn
757     */ 
758    drawLinearRing: function(node, geometry) {},
759
760    /**
761     * Method: drawPolygon
762     * Virtual function for drawing Polygon Geometry.
763     *    Should be implemented by subclasses.
764     *    This method is only called by the renderer itself.
765     *
766     * Parameters:
767     * node - {DOMElement}
768     * geometry - {<OpenLayers.Geometry>}
769     *
770     * Returns:
771     * {DOMElement} or null if the renderer could not draw all components
772     *     of the polygon, or false if nothing could be drawn
773     */ 
774    drawPolygon: function(node, geometry) {},
775
776    /**
777     * Method: drawRectangle
778     * Virtual function for drawing Rectangle Geometry.
779     *     Should be implemented by subclasses.
780     *     This method is only called by the renderer itself.
781     *
782     * Parameters:
783     * node - {DOMElement}
784     * geometry - {<OpenLayers.Geometry>}
785     *
786     * Returns:
787     * {DOMElement} or false if the renderer could not draw the rectangle
788     */ 
789    drawRectangle: function(node, geometry) {},
790
791    /**
792     * Method: drawCircle
793     * Virtual function for drawing Circle Geometry.
794     *     Should be implemented by subclasses.
795     *     This method is only called by the renderer itself.
796     *
797     * Parameters:
798     * node - {DOMElement}
799     * geometry - {<OpenLayers.Geometry>}
800     *
801     * Returns:
802     * {DOMElement} or false if the renderer could not draw the circle
803     */ 
804    drawCircle: function(node, geometry) {},
805
806    /**
807     * Method: drawSurface
808     * Virtual function for drawing Surface Geometry.
809     *     Should be implemented by subclasses.
810     *     This method is only called by the renderer itself.
811     *
812     * Parameters:
813     * node - {DOMElement}
814     * geometry - {<OpenLayers.Geometry>}
815     *
816     * Returns:
817     * {DOMElement} or false if the renderer could not draw the surface
818     */ 
819    drawSurface: function(node, geometry) {},
820
821    /**
822     * Method: removeText
823     * Removes a label
824     *
825     * Parameters:
826     * featureId - {String}
827     */
828    removeText: function(featureId) {
829        var label = document.getElementById(featureId + this.LABEL_ID_SUFFIX);
830        if (label) {
831            this.textRoot.removeChild(label);
832        }
833    },
834
835    /**
836     * Method: getFeatureIdFromEvent
837     *
838     * Parameters:
839     * evt - {Object} An <OpenLayers.Event> object
840     *
841     * Returns:
842     * {<OpenLayers.Geometry>} A geometry from an event that
843     *     happened on a layer.
844     */
845    getFeatureIdFromEvent: function(evt) {
846        var target = evt.target;
847        var useElement = target && target.correspondingUseElement;
848        var node = useElement ? useElement : (target || evt.srcElement);
849        var featureId = node._featureId;
850        return featureId;
851    },
852
853    /**
854     * Method: eraseGeometry
855     * Erase a geometry from the renderer. In the case of a multi-geometry,
856     *     we cycle through and recurse on ourselves. Otherwise, we look for a
857     *     node with the geometry.id, destroy its geometry, and remove it from
858     *     the DOM.
859     *
860     * Parameters:
861     * geometry - {<OpenLayers.Geometry>}
862     * featureId - {String}
863     */
864    eraseGeometry: function(geometry, featureId) {
865        if ((geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") ||
866            (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString") ||
867            (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon") ||
868            (geometry.CLASS_NAME == "OpenLayers.Geometry.Collection")) {
869            for (var i=0, len=geometry.components.length; i<len; i++) {
870                this.eraseGeometry(geometry.components[i], featureId);
871            }
872        } else {   
873            var element = OpenLayers.Util.getElement(geometry.id);
874            if (element && element.parentNode) {
875                if (element.geometry) {
876                    element.geometry.destroy();
877                    element.geometry = null;
878                }
879                element.parentNode.removeChild(element);
880
881                if (this.indexer) {
882                    this.indexer.remove(element);
883                }
884               
885                if (element._style.backgroundGraphic) {
886                    var backgroundId = geometry.id + this.BACKGROUND_ID_SUFFIX;
887                    var bElem = OpenLayers.Util.getElement(backgroundId);
888                    if (bElem && bElem.parentNode) {
889                        // No need to destroy the geometry since the element and the background
890                        // node share the same geometry.
891                        bElem.parentNode.removeChild(bElem);
892                    }
893                }
894            }
895        }
896    },
897
898    /**
899     * Method: nodeFactory
900     * Create new node of the specified type, with the (optional) specified id.
901     *
902     * If node already exists with same ID and a different type, we remove it
903     *     and then call ourselves again to recreate it.
904     *
905     * Parameters:
906     * id - {String}
907     * type - {String} type Kind of node to draw.
908     *
909     * Returns:
910     * {DOMElement} A new node of the given type and id.
911     */
912    nodeFactory: function(id, type) {
913        var node = OpenLayers.Util.getElement(id);
914        if (node) {
915            if (!this.nodeTypeCompare(node, type)) {
916                node.parentNode.removeChild(node);
917                node = this.nodeFactory(id, type);
918            }
919        } else {
920            node = this.createNode(type, id);
921        }
922        return node;
923    },
924   
925    /**
926     * Method: nodeTypeCompare
927     *
928     * Parameters:
929     * node - {DOMElement}
930     * type - {String} Kind of node
931     *
932     * Returns:
933     * {Boolean} Whether or not the specified node is of the specified type
934     *     This function must be overridden by subclasses.
935     */
936    nodeTypeCompare: function(node, type) {},
937   
938    /**
939     * Method: createNode
940     *
941     * Parameters:
942     * type - {String} Kind of node to draw.
943     * id - {String} Id for node.
944     *
945     * Returns:
946     * {DOMElement} A new node of the given type and id.
947     *     This function must be overridden by subclasses.
948     */
949    createNode: function(type, id) {},
950
951    /**
952     * Method: moveRoot
953     * moves this renderer's root to a different renderer.
954     *
955     * Parameters:
956     * renderer - {<OpenLayers.Renderer>} target renderer for the moved root
957     */
958    moveRoot: function(renderer) {
959        var root = this.root;
960        if(renderer.root.parentNode == this.rendererRoot) {
961            root = renderer.root;
962        }
963        root.parentNode.removeChild(root);
964        renderer.rendererRoot.appendChild(root);
965    },
966   
967    /**
968     * Method: getRenderLayerId
969     * Gets the layer that this renderer's output appears on. If moveRoot was
970     * used, this will be different from the id of the layer containing the
971     * features rendered by this renderer.
972     *
973     * Returns:
974     * {String} the id of the output layer.
975     */
976    getRenderLayerId: function() {
977        return this.root.parentNode.parentNode.id;
978    },
979   
980    /**
981     * Method: isComplexSymbol
982     * Determines if a symbol cannot be rendered using drawCircle
983     *
984     * Parameters:
985     * graphicName - {String}
986     *
987     * Returns
988     * {Boolean} true if the symbol is complex, false if not
989     */
990    isComplexSymbol: function(graphicName) {
991        return (graphicName != "circle") && !!graphicName;
992    },
993
994    CLASS_NAME: "OpenLayers.Renderer.Elements"
995});
996
997
998/**
999 * Constant: OpenLayers.Renderer.symbol
1000 * Coordinate arrays for well known (named) symbols.
1001 */
1002OpenLayers.Renderer.symbol = {
1003    "star": [350,75, 379,161, 469,161, 397,215, 423,301, 350,250, 277,301,
1004            303,215, 231,161, 321,161, 350,75],
1005    "cross": [4,0, 6,0, 6,4, 10,4, 10,6, 6,6, 6,10, 4,10, 4,6, 0,6, 0,4, 4,4,
1006            4,0],
1007    "x": [0,0, 25,0, 50,35, 75,0, 100,0, 65,50, 100,100, 75,100, 50,65, 25,100, 0,100, 35,50, 0,0],
1008    "square": [0,0, 0,1, 1,1, 1,0, 0,0],
1009    "triangle": [0,10, 10,10, 5,0, 0,10]
1010};
Note: See TracBrowser for help on using the repository browser.