[OpenLayers-Dev] #1666 - One Single, Mother Of All Vector Layers
VR26A
vinci.w.cat at gmail.com
Sat Nov 15 23:43:19 EST 2008
Hi All,
This may not be a good news: the demo page is broken because the trailing
comma found in the patched Openlayers.js and the demo html js
problem found in patch:
line 481:
+ : null,
it should be
+ : null
And there are problems on the element.addEventListener (line 588) in IE - IE
doesn't support the DOM Level 2 Event Model, the solution here is using the
OpenLayers.Event.observe (the OpenLayer wrapper of the Prototype.js Event
module)
line 588:
+ container.addEventListener(
it should be
+ OpenLayers.Event.observe(container,
Then theOpenLayers.js should be fixed on the patch. For the demo page, you
need to remove the comma after the last element/property on the array and
the object.
However, after I fixed the js error, another serious problem come: the
object lost its position and width so the top layer is nothing here. Anybody
can help?
*I checked the debugger and seems IE ignore the width, height, top,
left....I wonder why
==================IE Partial Solution====================
Grouping Vector Features
========================
Author: Volker Grabsch
Index: tests/Layer/Vector.html
===================================================================
--- tests/Layer/Vector.html (Revision 8115)
+++ tests/Layer/Vector.html (Arbeitskopie)
@@ -343,43 +343,43 @@
graphicYOffset: -16
});
- var root = renderer.root;
if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.SVG') {
feature.style = customStyle1;
layer.drawFeature(feature);
- t.eq(root.firstChild.getAttributeNS(null, 'width'),
+ var element = renderer.root.firstChild.firstChild;
+ t.eq(element.getAttributeNS(null, 'width'),
(2*customStyle1.pointRadius).toString(),
"given a pointRadius, width equals
2*pointRadius");
- t.eq(root.firstChild.getAttributeNS(null, 'height'),
+ t.eq(element.getAttributeNS(null, 'height'),
(2*customStyle1.pointRadius).toString(),
"given a pointRadius, height equals
2*pointRadius");
feature.style = customStyle2;
layer.drawFeature(feature);
- t.eq(root.firstChild.getAttributeNS(null, 'width'),
- root.firstChild.getAttributeNS(null,
'height'),
+ t.eq(element.getAttributeNS(null, 'width'),
+ element.getAttributeNS(null, 'height'),
"given a graphicWidth, width equals height");
- t.eq(root.firstChild.getAttributeNS(null, 'width'),
+ t.eq(element.getAttributeNS(null, 'width'),
customStyle2.graphicWidth.toString(),
"width is set correctly");
feature.style = customStyle3;
layer.drawFeature(feature);
- t.eq(root.firstChild.getAttributeNS(null, 'height'),
- root.firstChild.getAttributeNS(null, 'width'),
+ t.eq(element.getAttributeNS(null, 'height'),
+ element.getAttributeNS(null, 'width'),
"given a graphicHeight, height equals width");
- t.eq(root.firstChild.getAttributeNS(null, 'height'),
+ t.eq(element.getAttributeNS(null, 'height'),
customStyle3.graphicHeight.toString(),
"height is set correctly");
feature.style = customStyle4;
layer.drawFeature(feature);
- t.eq(root.firstChild.getAttributeNS(null, 'height'),
+ t.eq(element.getAttributeNS(null, 'height'),
customStyle4.graphicHeight.toString(),
"given graphicHeight and graphicWidth, both
are set: height");
- t.eq(root.firstChild.getAttributeNS(null, 'width'),
+ t.eq(element.getAttributeNS(null, 'width'),
customStyle4.graphicWidth.toString(),
"given graphicHeight and graphicWidth, both
are set: width");
feature.style = customStyle5;
layer.drawFeature(feature);
- t.eq(root.firstChild.getAttributeNS(null, 'style'),
+ t.eq(element.getAttributeNS(null, 'style'),
'opacity:
'+customStyle5.graphicOpacity.toString()+((OpenLayers.Util.getBrowserName()
== "opera" || OpenLayers.Util.getBrowserName() == "safari") ? "" : ';'),
"graphicOpacity correctly set");
feature.style = customStyle6;
@@ -393,56 +393,57 @@
// toFixed() returns a string
x = parseFloat(x);
y = parseFloat(y);
- t.eq(root.firstChild.getAttributeNS(null, 'x'),
+ t.eq(element.getAttributeNS(null, 'x'),
(x +
customStyle6.graphicXOffset).toFixed().toString(),
"graphicXOffset correctly set");
- t.eq(root.firstChild.getAttributeNS(null, 'y'),
+ t.eq(element.getAttributeNS(null, 'y'),
(-y +
customStyle6.graphicYOffset).toFixed().toString(),
"graphicYOffset correctly set");
}
if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.VML') {
feature.style = customStyle1;
layer.drawFeature(feature);
- t.eq(root.firstChild.style.width,
+ var element = renderer.root.firstChild.firstChild;
+ t.eq(element.style.width,
(2*customStyle1.pointRadius).toString()+'px',
"given a pointRadius, width equals
2*pointRadius");
- t.eq(root.firstChild.style.height,
+ t.eq(element.style.height,
(2*customStyle1.pointRadius).toString()+'px',
"given a pointRadius, height equals
2*pointRadius");
feature.style = customStyle2;
layer.drawFeature(feature);
- t.eq(root.firstChild.style.width,
- root.firstChild.style.height,
+ t.eq(element.style.width,
+ element.style.height,
"given a graphicWidth, width equals height");
- t.eq(root.firstChild.style.width,
+ t.eq(element.style.width,
customStyle2.graphicWidth.toString()+'px',
"width is set correctly");
feature.style = customStyle3;
layer.drawFeature(feature);
- t.eq(root.firstChild.style.height,
- root.firstChild.style.width,
+ t.eq(element.style.height,
+ element.style.width,
"given a graphicHeight, height equals width");
- t.eq(root.firstChild.style.height,
+ t.eq(element.style.height,
customStyle3.graphicHeight.toString()+'px',
"height is set correctly");
feature.style = customStyle4;
layer.drawFeature(feature);
- t.eq(root.firstChild.style.height,
+ t.eq(element.style.height,
customStyle4.graphicHeight.toString()+'px',
"given graphicHeight and graphicWidth, both
are set: height");
- t.eq(root.firstChild.style.width,
+ t.eq(element.style.width,
customStyle4.graphicWidth.toString()+'px',
"given graphicHeight and graphicWidth, both
are set: width");
feature.style = customStyle5;
layer.renderer.clear();
layer.drawFeature(feature);
- var fill =
root.firstChild.getElementsByTagName("v:fill")[0];
+ var fill = element.getElementsByTagName("v:fill")[0];
var opacity;
if(fill) {
opacity = fill.getAttribute('opacity');
}
if(opacity === undefined) {
- fill = root.firstChild.getElementsByTagName("fill")[0];
+ fill = element.getElementsByTagName("fill")[0];
opacity = fill.getAttribute('opacity');
}
t.eq(opacity,
@@ -452,12 +453,12 @@
layer.drawFeature(feature);
var x = geometryX / renderer.getResolution();
var y = geometryY / renderer.getResolution();
- t.eq(root.firstChild.style.left,
+ t.eq(element.style.left,
(x +
customStyle6.graphicXOffset).toFixed().toString()+'px',
"graphicXOffset correctly set");
- t.eq(root.firstChild.style.top,
- (y -
(customStyle6.graphicYOffset+parseInt(root.firstChild.style.height))).toFixed().toString()+'px',
+ t.eq(element.style.top,
+ (y -
(customStyle6.graphicYOffset+parseInt(element.style.height))).toFixed().toString()+'px',
"graphicYOffset correctly set");
}
Index: tests/Renderer/Elements.html
===================================================================
--- tests/Renderer/Elements.html (Revision 8115)
+++ tests/Renderer/Elements.html (Arbeitskopie)
@@ -22,6 +22,10 @@
return root;
};
+ OpenLayers.Renderer.Elements.prototype.createGroupContainer =
function(group) {
+ return document.createElement("div");
+ };
+
OpenLayers.Renderer.Elements.prototype._createNode =
OpenLayers.Renderer.Elements.prototype.createNode;
@@ -66,7 +70,7 @@
t.ok(r instanceof OpenLayers.Renderer.Elements, "new
OpenLayers.Renderer.Elements returns Elements object" );
t.ok(r.rendererRoot != null, "elements rendererRoot is not null");
t.ok(r.root != null, "elements root is not null");
- t.ok(r.indexer == null, "indexer is null if unused.");
+ t.ok(r.groups["default"] == null, "default group is null");
t.ok(r.root.parentNode == r.rendererRoot, "elements root is
correctly appended to rendererRoot");
t.ok(r.rendererRoot.parentNode == r.container, "elements
rendererRoot is correctly appended to container");
@@ -146,10 +150,11 @@
g_Node = node;
return {node: node, complete: true};
};
+ r._redrawBackgroundNode = r.redrawBackgroundNode;
r.redrawBackgroundNode = function(id, geometry, style, featureId) {
- b_Node = r.nodeFactory();
- b_Node.id = "foo_background";
- r.root.appendChild(b_Node);
+ var complete = r._redrawBackgroundNode(id, geometry, style,
featureId);
+ b_Node = g_Node;
+ return complete;
};
r.getNodeType = function(geometry, style) {
@@ -162,8 +167,8 @@
var style = {'backgroundGraphic': 'foo'};
var featureId = 'dude';
r.drawGeometry(geometry, style, featureId);
- t.ok(g_Node.parentNode == r.root, "node is correctly appended to
root");
- t.ok(b_Node.parentNode == r.root, "redrawBackgroundNode appended
background node");
+ t.ok(g_Node.parentNode == r.root.firstChild, "node is correctly
appended to root");
+ t.ok(b_Node.parentNode == r.root.firstChild, "redrawBackgroundNode
appended background node");
t.eq(g_Node._featureId, 'dude', "_featureId is correct");
t.eq(g_Node._style.backgroundGraphic, "foo", "_style is correct");
t.eq(g_Node._geometryClass, 'bar', "_geometryClass is correct");
@@ -178,8 +183,8 @@
style = {'display':'none'};
r.drawGeometry(geometry, style, featureId);
- t.ok(g_Node.parentNode != r.root, "node is correctly removed");
- t.ok(b_Node.parentNode != r.root, "background node correctly
removed")
+ t.ok(g_Node.parentNode != r.root.firstChild, "node is correctly
removed");
+ t.ok(b_Node.parentNode != r.root.firstChild, "background node
correctly removed")
document.getElementById = _getElement;
@@ -340,6 +345,7 @@
t.plan(15);
var elements = {
+ 'groups': {},
'eraseGeometry': function(geometry) {
gErased.push(geometry);
}
@@ -412,9 +418,13 @@
// (no tests here, just make sure it doesn't bomb)
//valid element.parentNode, element.geometry
- elements.indexer = {
- 'remove': function(elem) {
- gIndexerRemoved = elem;
+ elements.groups = {
+ 'default': {
+ 'indexer': {
+ 'remove': function(elem) {
+ gIndexerRemoved = elem;
+ }
+ }
}
};
@@ -468,7 +478,7 @@
}
function test_Elements_drawAndErase(t) {
- t.plan(20);
+ t.plan(18);
setUp();
@@ -505,40 +515,38 @@
return result;
}
- t.eq(r.root.childNodes.length, 1, "root is correctly filled");
- t.eq(r.indexer.maxZIndex, 10, "indexer.maxZIndex is correctly
filled");
- t.eq(r.indexer.order.length, 1, "indexer.order is correctly
filled");
- t.eq(count(r.indexer.indices), 1, "indexer.indices is correctly
filled");
+ t.eq(r.root.firstChild.childNodes.length, 1, "default group is
correctly filled");
+ t.eq(r.groups["default"].indexer.maxZIndex, 10, "indexer.maxZIndex
is correctly filled");
+ t.eq(r.groups["default"].indexer.order.length, 1, "indexer.order is
correctly filled");
+ t.eq(count(r.groups["default"].indexer.indices), 1,
"indexer.indices is correctly filled");
r.eraseGeometry(geometry);
- t.eq(r.root.childNodes.length, 0, "root is correctly cleared");
- t.eq(r.indexer.maxZIndex, 0, "indexer.maxZIndex is correctly
reset");
- t.eq(r.indexer.order.length, 0, "indexer.order is correctly
reset");
- t.eq(count(r.indexer.indices), 0, "indexer.indices is correctly
reset");
+ t.eq(r.root.firstChild.childNodes.length, 0, "default group is
correctly cleared");
+ t.eq(r.groups["default"].indexer.maxZIndex, 0, "indexer.maxZIndex
is correctly reset");
+ t.eq(r.groups["default"].indexer.order.length, 0, "indexer.order is
correctly reset");
+ t.eq(count(r.groups["default"].indexer.indices), 0,
"indexer.indices is correctly reset");
delete(style.graphicZIndex);
r.drawGeometry(geometry, style, featureId);
- t.eq(r.root.childNodes.length, 1, "root is correctly filled");
- t.eq(r.indexer.maxZIndex, 0, "indexer.maxZIndex is correctly
filled");
- t.eq(r.indexer.order.length, 1, "indexer.order is correctly
filled");
- t.eq(count(r.indexer.indices), 1, "indexer.indices is correctly
filled");
+ t.eq(r.root.firstChild.childNodes.length, 1, "default group is
correctly filled");
+ t.eq(r.groups["default"].indexer.maxZIndex, 0, "indexer.maxZIndex
is correctly filled");
+ t.eq(r.groups["default"].indexer.order.length, 1, "indexer.order is
correctly filled");
+ t.eq(count(r.groups["default"].indexer.indices), 1,
"indexer.indices is correctly filled");
r.clear();
t.eq(r.root.childNodes.length, 0, "root is correctly cleared");
- t.eq(r.indexer.maxZIndex, 0, "indexer.maxZIndex is correctly
reset");
- t.eq(r.indexer.order.length, 0, "indexer.order is correctly
reset");
- t.eq(count(r.indexer.indices), 0, "indexer.indices is correctly
reset");
+ t.eq(r.groups["default"], null, "indexer is correctly removed");
style.graphicZIndex = 12;
r.drawGeometry(geometry, style, featureId);
- t.eq(r.root.childNodes.length, 1, "root is correctly filled");
- t.eq(r.indexer.maxZIndex, 12, "indexer.maxZIndex is correctly
filled");
- t.eq(r.indexer.order.length, 1, "indexer.order is correctly
filled");
- t.eq(count(r.indexer.indices), 1, "indexer.indices is correctly
filled");
+ t.eq(r.root.firstChild.childNodes.length, 1, "default group is
correctly filled");
+ t.eq(r.groups["default"].indexer.maxZIndex, 12, "indexer.maxZIndex
is correctly filled");
+ t.eq(r.groups["default"].indexer.order.length, 1, "indexer.order is
correctly filled");
+ t.eq(count(r.groups["default"].indexer.indices), 1,
"indexer.indices is correctly filled");
tearDown();
}
Index: doc/walkthru.html
===================================================================
--- doc/walkthru.html (Revision 8115)
+++ doc/walkthru.html (Arbeitskopie)
@@ -72,6 +72,7 @@
<li> ../examples/vector-formats.html Serializing to other formats </li>
<li> ../examples/select-feature.html Selecting features </li>
<li> ../examples/select-feature-openpopup.html Attaching popups to
features </li>
+ <li> ../examples/vector-groups.html Grouping features </li>
</ol>
<h2>Editing Tools</h2>
Index: lib/OpenLayers/Renderer.js
===================================================================
--- lib/OpenLayers/Renderer.js (Revision 8115)
+++ lib/OpenLayers/Renderer.js (Arbeitskopie)
@@ -238,5 +238,24 @@
*/
eraseGeometry: function(geometry) {},
+ /**
+ * Method: getGroupContainer
+ * Returns the container of a feature group.
+ * The group is created if it doesn't exist.
+ * virtual function.
+ *
+ * Parameters:
+ * groupName - {String}
+ *
+ * Returns:
+ * {DOMElement}
+ */
+ getGroupContainer: function(group) {
+ // for renderers that don't support feature groups
+ // it's okay to return just the main container,
+ // i.e. everything is put into one big group.
+ return container;
+ },
+
CLASS_NAME: "OpenLayers.Renderer"
-});
\ Kein Zeilenvorschub am Ende der Datei
+});
Index: lib/OpenLayers/Renderer/Elements.js
===================================================================
--- lib/OpenLayers/Renderer/Elements.js (Revision 8115)
+++ lib/OpenLayers/Renderer/Elements.js (Arbeitskopie)
@@ -344,12 +344,21 @@
xmlns: null,
/**
- * Property: Indexer
- * {<OpenLayers.ElementIndexer>} An instance of
OpenLayers.ElementsIndexer
- * created upon initialization if the zIndexing or yOrdering
options
- * passed to this renderer's constructor are set to true.
+ * Property: groups
+ * {Object} A hash that maps each group name to an object containing:
+ * * container - {DOMElement} the group's container DOM element.
+ * * indexer - {<OpenLayers.ElementIndexer>} the group's indexer.
+ * Will be null unless the zIndexing or yOrdering options
+ * passed to this renderer's constructor are set to true.
*/
- indexer: null,
+ groups: null,
+
+ /**
+ * Property: options
+ * {Object} Options for this renderer. See {<OpenLayers.Renderer>} for
+ * supported options.
+ */
+ options: null,
/**
* Constant: BACKGROUND_ID_SUFFIX
@@ -388,9 +397,8 @@
this.rendererRoot.appendChild(this.root);
this.container.appendChild(this.rendererRoot);
- if(options && (options.zIndexing || options.yOrdering)) {
- this.indexer = new
OpenLayers.ElementsIndexer(options.yOrdering);
- }
+ this.options = options || {};
+ this.groups = {};
},
/**
@@ -417,9 +425,7 @@
this.root.removeChild(this.root.firstChild);
}
}
- if (this.indexer) {
- this.indexer.clear();
- }
+ this.groups = {};
},
/**
@@ -510,6 +516,7 @@
// Set the data for the node, then draw it.
node._featureId = featureId;
+ node.setAttribute("feature-id", featureId);
node._geometry = geometry;
node._geometryClass = geometry.CLASS_NAME;
node._style = style;
@@ -521,16 +528,22 @@
node = drawResult.node;
+ // Reveal the geometry's group container and index.
+ // Create them if necessary.
+ var groupName = geometry.groupName || "default";
+ this.getGroupContainer(groupName);
+ var group = this.groups[groupName];
+
// Insert the node into the indexer so it can show us where to
// place it. Note that this operation is O(log(n)). If there's a
// performance problem (when dragging, for instance) this is
// likely where it would be.
- var insert = this.indexer ? this.indexer.insert(node) : null;
+ var insert = group.indexer ? group.indexer.insert(node) : null;
if(insert) {
- this.root.insertBefore(node, insert);
+ group.container.insertBefore(node, insert);
} else {
- this.root.appendChild(node);
+ group.container.appendChild(node);
}
this.postDraw(node);
@@ -800,6 +813,7 @@
this.eraseGeometry(geometry.components[i]);
}
} else {
+ var group = this.groups[geometry.groupName || "default"];
var element = OpenLayers.Util.getElement(geometry.id);
if (element && element.parentNode) {
if (element.geometry) {
@@ -808,8 +822,8 @@
}
element.parentNode.removeChild(element);
- if (this.indexer) {
- this.indexer.remove(element);
+ if (group && group.indexer) {
+ group.indexer.remove(element);
}
if (element._style.backgroundGraphic) {
@@ -892,6 +906,33 @@
return (graphicName != "circle") && !!graphicName;
},
+ /**
+ * Method: getGroupContainer
+ * Returns the container of a feature group.
+ * The group and its indexer are created if necessary.
+ *
+ * Parameters:
+ * groupName - {String}
+ *
+ * Returns:
+ * {DOMElement}
+ */
+ getGroupContainer: function(groupName) {
+ var group = this.groups[groupName];
+ if (!group) {
+ // Create a new DOM element and indexer.
+ group = {
+ container: this.createGroupContainer(groupName),
+ indexer: (this.options.zIndexing || this.options.yOrdering)
+ ? new
OpenLayers.ElementsIndexer(this.options.yOrdering)
+ : null
+ };
+ this.root.appendChild(group.container);
+ this.groups[groupName] = group;
+ }
+ return group.container;
+ },
+
CLASS_NAME: "OpenLayers.Renderer.Elements"
});
Index: lib/OpenLayers/Renderer/VML.js
===================================================================
--- lib/OpenLayers/Renderer/VML.js (Revision 8115)
+++ lib/OpenLayers/Renderer/VML.js (Arbeitskopie)
@@ -588,12 +588,23 @@
* Create the main root element
*
* Returns:
- * {DOMElement} The main root element to which we'll add vectors
+ * {DOMElement} The main root element to which we'll add groups
*/
createRoot: function() {
return this.nodeFactory(this.container.id + "_root", "olv:group");
},
+ /**
+ * Method: createGroupContainer
+ *
+ * Returns:
+ * {DOMElement} A new group element to which we'll add vectors
+ */
+ createGroupContainer: function(group) {
+ var id = this.container.id + "_group_" + group;
+ return this.nodeFactory(id, "olv:group");
+ },
+
/**************************************
* *
* GEOMETRY DRAWING FUNCTIONS *
Index: lib/OpenLayers/Renderer/SVG.js
===================================================================
--- lib/OpenLayers/Renderer/SVG.js (Revision 8115)
+++ lib/OpenLayers/Renderer/SVG.js (Arbeitskopie)
@@ -414,13 +414,24 @@
* Method: createRoot
*
* Returns:
- * {DOMElement} The main root element to which we'll add vectors
+ * {DOMElement} The main root element to which we'll add groups
*/
createRoot: function() {
return this.nodeFactory(this.container.id + "_root", "g");
},
/**
+ * Method: createGroupContainer
+ *
+ * Returns:
+ * {DOMElement} A new group element to which we'll add vectors
+ */
+ createGroupContainer: function(group) {
+ var id = this.container.id + "_group_" + group;
+ return this.nodeFactory(id, "g");
+ },
+
+ /**
* Method: createDefs
*
* Returns:
Index: lib/OpenLayers/Layer/Vector.js
===================================================================
--- lib/OpenLayers/Layer/Vector.js (Revision 8115)
+++ lib/OpenLayers/Layer/Vector.js (Arbeitskopie)
@@ -742,5 +742,58 @@
return maxExtent;
},
+ /**
+ * Method: toggleGroup
+ * Toggle the visibility of a feature group.
+ *
+ * Parameters:
+ * groupName - {String}
+ */
+ toggleGroup: function(groupName) {
+ var container = this.renderer.getGroupContainer(groupName);
+ if (container.style.visibility == "hidden") {
+ container.style.visibility = "visible";
+ } else {
+ container.style.visibility = "hidden";
+ }
+ },
+
+ /**
+ * Method: addGroupEventListener
+ * Registration an event listener for a feature group.
+ *
+ * Parameters:
+ * groupName - {String}
+ * type - {String}
+ * listener - {EventListener}
+ * useCapture - {Boolean}
+ */
+ addGroupEventListener: function(groupName, type, listener, useCapture)
{
+ var container = this.renderer.getGroupContainer(groupName);
+ var layer = this;
+ OpenLayers.Event.observe(container,
+ type,
+ function(evt) {
+ evt.feature = layer.getFeatureById(evt.target._featureId);
+ evt.groupName = groupName;
+ listener(evt);
+ },
+ useCapture);
+ },
+
+ /**
+ * Method: raiseGroupToTop
+ * Raise a feature group to the top.
+ *
+ * Parameters:
+ * groupName - {String}
+ */
+ raiseGroupToTop: function(groupName) {
+ var container = this.renderer.getGroupContainer(groupName);
+ var containerParent = container.parentNode;
+ containerParent.removeChild(container);
+ containerParent.appendChild(container);
+ },
+
CLASS_NAME: "OpenLayers.Layer.Vector"
});
Index: examples/vector-groups.html
===================================================================
--- examples/vector-groups.html (Revision 0)
+++ examples/vector-groups.html (Revision 0)
@@ -0,0 +1,227 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <link rel="stylesheet" href="../theme/default/style.css"
type="text/css" />
+ <link rel="stylesheet" href="style.css" type="text/css" />
+ <script src="../lib/OpenLayers.js" type="text/javascript"></script>
+ <script type="text/javascript">
+
+ var vectorLayer;
+
+ function clear_text(evt)
+ {
+ document.getElementById('status_text').textContent =
+ "";
+ }
+
+ function show_mouseover_text(evt)
+ {
+ document.getElementById('status_text').textContent =
+ "The mouse is over" +
+ " feature '" + evt.feature.id + "'" +
+ " of group '" + evt.groupName + "'.";
+ }
+
+ function show_click_text(evt)
+ {
+ document.getElementById('status_text').textContent =
+ "You're clicking on" +
+ " feature '" + evt.feature.id + "'" +
+ " of group '" + evt.groupName + "'.";
+ }
+
+ function init()
+ {
+ // map
+ var map = new OpenLayers.Map('map');
+
+ // styles
+ var style_blue = OpenLayers.Util.extend({
+ strokeColor: 'blue',
+ fillColor: 'blue',
+ fillOpacity: 0.2,
+ strokeWidth: 1
+ });
+ var style_green = OpenLayers.Util.extend({
+ strokeColor: 'green',
+ fillColor: 'green',
+ fillOpacity: 0.2,
+ strokeWidth: 1
+ });
+
+ // background layer
+ var backgroundLayer = new OpenLayers.Layer.WMS(
+ "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'});
+ map.addLayer(backgroundLayer);
+
+ // zoom map
+ map.zoomToMaxExtent();
+
+ // features for vector layer
+ var feature1 = new OpenLayers.Feature.Vector(new
OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(15, 22),
+ new OpenLayers.Geometry.Point(15, 6),
+ new OpenLayers.Geometry.Point(22, 10),
+ new OpenLayers.Geometry.Point(22, 15),
+ new OpenLayers.Geometry.Point(24, 15),
+ new OpenLayers.Geometry.Point(23, 19),
+ new OpenLayers.Geometry.Point(16, 23),
+ new OpenLayers.Geometry.Point(15, 22)
+ ])
+ ]));
+ var feature2 = new OpenLayers.Feature.Vector(new
OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(15, 22),
+ new OpenLayers.Geometry.Point(15, 6),
+ new OpenLayers.Geometry.Point( 3, 11),
+ new OpenLayers.Geometry.Point( 4, 19),
+ new OpenLayers.Geometry.Point(15, 22)
+ ])
+ ]));
+ var feature3 = new OpenLayers.Feature.Vector(new
OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point( 74, 39),
+ new OpenLayers.Geometry.Point( 91, 27),
+ new OpenLayers.Geometry.Point(119, 47),
+ new OpenLayers.Geometry.Point(104, 51),
+ new OpenLayers.Geometry.Point( 87, 49),
+ new OpenLayers.Geometry.Point( 74, 39)
+ ])
+ ]));
+ var feature4 = new OpenLayers.Feature.Vector(new
OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(104, 51),
+ new OpenLayers.Geometry.Point( 87, 49),
+ new OpenLayers.Geometry.Point( 74, 39),
+ new OpenLayers.Geometry.Point( 75, 61),
+ new OpenLayers.Geometry.Point(104, 51)
+ ])
+ ]));
+ var feature5 = new OpenLayers.Feature.Vector(new
OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point( 78, 45),
+ new OpenLayers.Geometry.Point(105, 45),
+ new OpenLayers.Geometry.Point(105, 65),
+ new OpenLayers.Geometry.Point( 78, 65),
+ new OpenLayers.Geometry.Point( 78, 45)
+ ])
+ ]));
+ var feature6 = new OpenLayers.Feature.Vector(new
OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(-3, 29),
+ new OpenLayers.Geometry.Point(-3, 16),
+ new OpenLayers.Geometry.Point(31, 16),
+ new OpenLayers.Geometry.Point(31, 29),
+ new OpenLayers.Geometry.Point(-3, 29)
+ ])
+ ]));
+ var feature7 = new OpenLayers.Feature.Vector(new
OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(-116, 55),
+ new OpenLayers.Geometry.Point(-116, 39),
+ new OpenLayers.Geometry.Point(-98 , 39),
+ new OpenLayers.Geometry.Point(-98 , 55),
+ new OpenLayers.Geometry.Point(-116, 55)
+ ])
+ ]));
+ var feature8 = new OpenLayers.Feature.Vector(new
OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(19, 47),
+ new OpenLayers.Geometry.Point(63, 47),
+ new OpenLayers.Geometry.Point(40, 65),
+ new OpenLayers.Geometry.Point(19, 47)
+ ])
+ ]));
+ var feature9 = new OpenLayers.Feature.Vector(new
OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(-40, 78),
+ new OpenLayers.Geometry.Point(-47, 70),
+ new OpenLayers.Geometry.Point(-33, 70),
+ new OpenLayers.Geometry.Point(-40, 78)
+ ])
+ ]));
+
+ // assign styles
+ feature5.style = style_blue;
+ feature6.style = style_blue;
+ feature7.style = style_blue;
+ feature8.style = style_green;
+ feature9.style = style_green;
+
+ // assign groups
+ feature1.geometry.groupName = 'default'; // not necessary
+ feature2.geometry.groupName = 'default'; // not necessary
+ feature3.geometry.groupName = 'default'; // not necessary
+ feature4.geometry.groupName = 'default'; // not necessary
+ feature5.geometry.groupName = 'blue';
+ feature6.geometry.groupName = 'blue';
+ feature7.geometry.groupName = 'blue';
+ feature8.geometry.groupName = 'green';
+ feature9.geometry.groupName = 'green';
+
+ // vector layer
+ vectorLayer = new OpenLayers.Layer.Vector();
+ vectorLayer.toggleGroup('green'); // disable group 'green' by
default
+ vectorLayer.addFeatures([
+ feature1, feature2, feature3, feature4,
+ feature5, feature6, feature7,
+ feature8, feature9
+ ]);
+ map.addLayer(vectorLayer);
+
+ // events on the vector layer
+ var groupNames = ['default', 'blue', 'green'];
+ for (i in groupNames) {
+ var groupName = groupNames[i];
+ vectorLayer.addGroupEventListener(groupName, 'mouseover',
show_mouseover_text, false);
+ vectorLayer.addGroupEventListener(groupName, 'mouseout',
clear_text, false);
+ vectorLayer.addGroupEventListener(groupName, 'mousedown',
show_click_text, false);
+ vectorLayer.addGroupEventListener(groupName, 'mouseup',
show_mouseover_text, false);
+ }
+ }
+ </script>
+ </head>
+ <body onload="init()">
+ <h1 id="title">Grouping Vector Features</h1>
+ <div id="tags">
+ </div>
+ <p id="shortdesc">
+ Shows how to group vector features into sub layers.
+ </p>
+ <div style="text-align: right">
+ <div id="map" class="smallmap"></div>
+ </div>
+ <div style="font-weight: bold; margin: 10pt 0pt 10pt 0pt">
+ <div style="margin-top: 5pt">
+ Toggle group:
+ <button
onclick="vectorLayer.toggleGroup('default')">default</button>
+ <button onclick="vectorLayer.toggleGroup('blue')">blue</button>
+ <button
onclick="vectorLayer.toggleGroup('green')">green</button>
+ </div>
+ <div style="margin-top: 5pt">
+ Raise to top:
+ <button
onclick="vectorLayer.raiseGroupToTop('default')">default</button>
+ <button
onclick="vectorLayer.raiseGroupToTop('blue')">blue</button>
+ <button
onclick="vectorLayer.raiseGroupToTop('green')">green</button>
+ </div>
+ <div style="margin-top: 5pt">
+
+
+ </div>
+ </div>
+ <div id="docs">
+ <p>This example shows the usage of the optional
+ "groupName" property of "features.geometry".
+ The feature data will be inserted into the appropriate
group.</p>
+ <p>Please inspect the vector layer DOM structure (eg. firebug).
+ Move the mouse over some features and click
+ to see the groups in action.</p>
+ <p>A group can be shown and hidden as a whole,
+ even before features are added.
+ Thus, you can disable a group by default,
+ which is here demonstrated with the "green" group.</p>
+ </div>
+ </body>
+</html>
Matthias Pohl wrote:
>
> This is the first attempt to implement the "One Single, Mother Of All
> Vector Layers" approach as described in issue #1666. See a working
> example and details on the project page http://ol.m-click.ws
>
> - the patch URL is http://ol.m-click.ws/grouping-vector-features.patch
> - the patch is tested with version 2.7 and trunk
> - it works fine in our application (no performance issues)
> - no BC breaks
> - of course needs testing (VML)
> - a new "sublayer" switch has to be added to the OL layerswitch control
>
> Please review and comment.
>
> Regards, matt
> _______________________________________________
> Dev mailing list
> Dev at openlayers.org
> http://openlayers.org/mailman/listinfo/dev
>
>
--
View this message in context: http://n2.nabble.com/-1666---One-Single%2C-Mother-Of-All-Vector-Layers-tp1340452p1504998.html
Sent from the OpenLayers Dev mailing list archive at Nabble.com.
More information about the Dev
mailing list