-
Notifications
You must be signed in to change notification settings - Fork 336
LayerGroup content synchronization #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LayerGroup content synchronization #88
Conversation
Since this is handled in the raster synchronizer, will that also work for vector layers? To me it seems it would be more logical if there was a group synchronizer, which would handle all layer types. Because groups can have vector and raster layers. |
@petrsloup, with a hierarchy of layer groups aren't we receive a change event both on the child and on the father? @ahocevar, we would loose the flexibility to synchronize only one type of layers. |
@gberaudo This is true, but only when the layergroup2 is visible: https://github.com/openlayers/ol3/blob/1c7f2ad5ccdc5961f212408c97c7fba8118cd86c/src/ol/layer/layergroup.js#L80. Since we don't synchronize the display properties (including @ahocevar I don't think the "group synchronizer" is necessary at the moment (and it would require large refactoring) -- I can add the same 3 lines of code to the vectorsynchronizer so the vector layers will stay synchronized as well. It could make sense to implemented some "group synchronizer" as part of the advanced layergroup synchronization (together with the synchronization of the display properties). |
@petrsloup, interesting finding. When layergroup2 is visible and gets changed, the change event will be But, since the event will be dispatched to the parent layer, it |
@petrsloup If vector layers can be kept in sync by adding the same 3 lines of code for vector layers, then I'm fine with it for now. Would you be working on this, or is it something for @gberaudo? |
Looks good to me. Further improvements can be made later - I think this is good to merge. |
@ahocevar, we cannot merge this PR knowing the above issue. We must find a real solution. |
What about something like this: var changing = false;
olLayer.on('change', function(e) {
if (!changing) {
changing = true;
this.synchronize();
}
if (e.target === /* need reference to map */ map.getLayerGroup()) {
changing = false;
}
}, this); |
Why not simply listen on |
@ahocevar This would not work, because the event "propagation" can stop at any time and not reach the root.
@gberaudo 'add' and 'remove' are events of the underlying |
I just realized the solution drafted above won't work, because we actually need to determine the visibility of the parent group (if the group is hidden, it does not fire the event any more) which is not possible. Alternatively, we could listen @gberaudo @ahocevar What do you think -- is this solution acceptable? Any other ideas? |
@petrsloup, I strongly prefer your second solution. |
… are added/removed
…rSynchronizer and VectorSynchronizer
@ahocevar how deep hierarchy of LayerGroups is the client using? |
…event propagation issues)
Since the code duplicity introduced by this PR was getting larger and larger I moved the code shared between raster and vector synchronizer to the new This PR now implements the synchronization based on 'add', 'remove' and 'change:layers' events. |
As a side-effect, I believe this PR now also fixes the issue described in #38 (comment). |
this.map = map; | ||
|
||
/** | ||
* @type {?ol.View} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ?
is not necessary.
The convention in ol3 is to declare nullable object types without ?
. It is closure default for objects.
} | ||
|
||
this.destroyAll(); | ||
this.synchronize(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the synchronize
method has not been called yet by the app developer, we should prevent calling synchronize()
. See https://github.com/boundlessgeo/ol3-cesium/pull/88/files#r18266082.
}); | ||
|
||
return; | ||
} else if (!(olLayer instanceof ol.layer.Layer)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about declaring the type of sources handled by the olcs.AbstractSynchronizer
and use it here:
@template F,T
and !(olLayer instanceof F)
Since the class is about the conversion of an Ol3 type into a Cesium type, it feels more natural to have both from
and to
types declared. Using F = ol.layer.Layer
as the same effect as current code.
The introduction of an abstract base class would be a great addition, leading to more robust and readable code. Please see my comments. |
Thank you for the comments, but most of them are proposing various improvements of the current synchronization mechanism -- this is not the point of this PR. From my point of view, it makes sense to fix the code-style related comment (already done) and unlistening of the 'add' and 'remove' events when layergroup collection changes. Other comments are out of scope of this PR. |
goog.asserts.assert(!goog.isNull(view)); | ||
synchronizeLayer(el, view); | ||
}); | ||
source.on('updatefeature', function(e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updatefeature
has been renamed to changefeature
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks
…r used or when collection is replaced
I added the required changes related to the LayerGroup synchronization. |
@gberaudo Do you have any other comments regarding the LayerGroup synchronization or can this be merged? Synchronization improvements can be done later in a separate PR. |
One more bug detected by C2C team (mentioned during the Hangout as "never removed listeners") - to be reported here and after it is fixed this can be merged. |
}, this); | ||
listenAddRemove(); | ||
|
||
listenKeyArray.push(olLayer.on('change:layers', function(e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a layer group is removed from the layer tree (using map.removeLayer(aLayerGroup)
) what code is going to deregister the change:layers
listener from that layer group and the add
and remove
listeners from that layer group's collection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a layer group is removed, it should fire remove
event on some collection. This will result in this.synchronize();
call. The synchronizer keeps track of added event listeners and every time the synchronize
is called, it detects which layer groups are no longer used and removes the listeners. (L153)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been tested on our side - the event listeners are removed. Considered to be fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a layer group is removed, it should fire remove event on some collection. This will result in this.synchronize(); call. The synchronizer keeps track of added event listeners and every time the synchronize is called, it detects which layer groups are no longer used and removes the listeners. (L153)
What does look strange to me is that this.map.unByKey
is used to deregister listeners that were registered on the collection or on the layer group. I don't get it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gberaudo reminded me that this.map.unByKey
is actually just a wrapper to a static function. But it would have been clearer to use ol.Observable.prototype.unByKey
rather than this.map.unByKey
in the ol3cesium source code. And I hope we'll have ol.Observable.unByKey
in the future: openlayers/openlayers#2794.
LayerGroup content synchronization
This PR ensures that changes inside LayerGroups (add/remove layer) are synchronized.
Closes #27.
Closes #38.