diff --git a/Community.Blazor.MapLibre/MapLibre.razor.cs b/Community.Blazor.MapLibre/MapLibre.razor.cs index dbd2652..320ead8 100644 --- a/Community.Blazor.MapLibre/MapLibre.razor.cs +++ b/Community.Blazor.MapLibre/MapLibre.razor.cs @@ -294,13 +294,13 @@ public async Task AddTerraDrawDeleteListener(Action handler) return new Listener(callback); } - public async Task AddTerraDrawChangeListener(Action handler) + public async Task AddTerraDrawChangeListener(Action handler, int throttleTime) { var callback = new CallbackHandler(_jsModule, "change", handler, typeof(T)); var reference = DotNetObjectReference.Create(callback); _references.TryAdd(Guid.NewGuid(), reference); - await _jsModule.InvokeVoidAsync("onTerraDrawChange", MapId, reference); + await _jsModule.InvokeVoidAsync("onTerraDrawChange", MapId, reference, throttleTime); return new Listener(callback); } diff --git a/Community.Blazor.MapLibre/MapLibre.razor.js b/Community.Blazor.MapLibre/MapLibre.razor.js index 7babb13..694f244 100644 --- a/Community.Blazor.MapLibre/MapLibre.razor.js +++ b/Community.Blazor.MapLibre/MapLibre.razor.js @@ -261,18 +261,42 @@ export function onTerraDrawDelete(container, dotnetReference) { }); } -export function onTerraDrawChange(container, dotnetReference) { +export function onTerraDrawChange(container, dotnetReference, throttleTime = 100) { const draw = drawControls[container]; + const throttledInvoke = throttle(() => { + const features = draw.getSnapshot(); + const featuresAsJson = JSON.stringify(features); + dotnetReference.invokeMethodAsync('Invoke', featuresAsJson); + }, throttleTime); + draw.on('change', (ids, type) => { if (type === 'create' || type === 'update' || type === 'delete') { - const features = draw.getSnapshot(); - const featuresAsJson = JSON.stringify(features); - dotnetReference.invokeMethodAsync('Invoke', featuresAsJson); + throttledInvoke(); } }); } +function throttle(func, intervalInMs) { + let lastFunc; + let lastRan; + + return function(...args) { + if (!lastRan) { + func.apply(this, args); + lastRan = Date.now(); + } else { + clearTimeout(lastFunc); + lastFunc = setTimeout(() => { + if ((Date.now() - lastRan) >= intervalInMs) { + func.apply(this, args); + lastRan = Date.now(); + } + }, intervalInMs - (Date.now() - lastRan)); + } + } +} + /** * Adds a scale control to the given map container. * diff --git a/Community.Blazor.MapLibre/Models/Feature/IFeature.cs b/Community.Blazor.MapLibre/Models/Feature/IFeature.cs index a734305..0be200f 100644 --- a/Community.Blazor.MapLibre/Models/Feature/IFeature.cs +++ b/Community.Blazor.MapLibre/Models/Feature/IFeature.cs @@ -2,6 +2,7 @@ namespace Community.Blazor.MapLibre.Models.Feature; +[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type")] [JsonDerivedType(typeof(FeatureCollection))] [JsonDerivedType(typeof(FeatureFeature))] public interface IFeature diff --git a/Community.Blazor.MapLibre/Models/Feature/IGeometry.cs b/Community.Blazor.MapLibre/Models/Feature/IGeometry.cs index d871bfa..9580878 100644 --- a/Community.Blazor.MapLibre/Models/Feature/IGeometry.cs +++ b/Community.Blazor.MapLibre/Models/Feature/IGeometry.cs @@ -2,7 +2,7 @@ namespace Community.Blazor.MapLibre.Models.Feature; -[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] +[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type")] [JsonDerivedType(typeof(LineGeometry), typeDiscriminator: "LineString")] [JsonDerivedType(typeof(MultiLineGeometry), typeDiscriminator: "MultiLineString")] [JsonDerivedType(typeof(MultiPointGeometry), typeDiscriminator: "MultiPoint")]