Skip to content
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

RasterizingTileLayer handles DataChanged now with: Clear Cache After SourceLayer changes #2106

Merged

Conversation

inforithmics
Copy link
Contributor

Refresh cache after Datachanges in Source Layer

@inforithmics inforithmics changed the title Clear Cache After SourceLayer changes RasterizingTileLayer handles DataChanged now with: Clear Cache After SourceLayer changes Jul 8, 2023
@inforithmics
Copy link
Contributor Author

Things done:

  1. Automatic Refreshing of RasterizingTileLayer on DataChanges.
  2. Reduced Flickering when Cache was cleared (TilingRenderFetchStrategy)
  3. MPoint and MRect implement IEquatable now.

Copy link
Member

@pauldendulk pauldendulk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the improvements!

I think there is still a threading problem with the ObservableCollection not being thread save, even with the ToArray. This, may improve it but some of our users will still run into it.

Some general remarks about the ObservableCollection

I've had a lot of trouble with the ObservableCollection in the past. If you change a lot of items at the same time they will all trigger notifications while for most scenarios one notification would suffice, causing performance problems. Also these problems are often hard to track because of the distributed nature of the notification. I prefer a more centralized control for a map component.

A more general argument against the ObservableCollection. It is a pattern that was introduced for lists in users interfaces which are usually small in number and don't change a lot. In Mapsui two map drags can replace all items in the map. This makes it less suitable for the ObservableCollection. Since it is a lot of data changing fast it should take its design patters from game engines.

@@ -35,7 +46,7 @@ public class ObservableMemoryLayer<T> : MemoryLayer
{
_observableCollection.CollectionChanged += DataSource_CollectionChanged;
_shadowCollection.Clear();
foreach (var it in _observableCollection)
foreach (var it in _observableCollection.ToArray()) // collection has been changed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a 'collection has been changed' can happen while iterating over the items, it can also happen within the ToArray method, because to create the array you need to iterate over the items. Perhaps it is less likely if the ToArray takes less time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we need a ThreadSafeObservableCollection. or ConcurrentObservableCollection

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to have a better understanding of the use case for the ObservableCollection.


namespace Mapsui;

public class MPoint
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the IEquatable makes sense.

public class RasterizingTileLayer : TileLayer, ISourceLayer, IAsyncDataFetcher
{
private MRect? _currentExtent;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You found a 'little excessive' 😁 tile fetching problem, which could be explained because the extent and resolutions were changed in two steps (immediately following each other) but on another thread a tiles fetch was triggered after the extent was set but before the resolution was set. In order to avoid that I introduces MSection (I could not think of a better name yet). It is immutable and extent and resolution will always be an atomic thing.

{
ClearCache();
DataHasChanged();
if (_currentExtent != null && _currentResolution != null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, here the extent and resolution are used which are set in the GetFeatures request. There is no better solution in the current architecture, but it feels a bit like a workaround.

@pauldendulk pauldendulk merged commit ea67124 into Mapsui:master Sep 25, 2023
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants