Closed christopherdude closed 4 months ago
You are right. It should be same for polygon Do you have small demo how create polygon?
The current BGM wrapper over the JS polygon object is not designed to facilitate fully deleting the object in a way that allows the browser to dispose of the JS object until the map object itself is disposed and deletes all objects attached to it (not sure if an unattached polygon is deleted in that case).
So if you're showing a single polygon at a time it's best to merely hide it from the map and then if you want to show another polygon you reuse the object by redefining all the points and adding it back to the map.
If you have a Map.Polygon
named object userPolygon
in C#, removing the polygon from the map is just:
// disconnect the JS polygon from the map so that the map stops rendering it.
await userPolygon.SetMap(null);
Then to define/redefine the polygon you have something like this:
using GoogleMapsComponents.Maps;
private GoogleMap? bgmMap;
private Polygon? userPolygon = null;
// Creates or reuses the userPolygon. Ignores MapPolygonOptions parameter when polygon object already exists.
public async Task SetUserPolygon(MapPolygonOptions mapPolygon, IEnumerable<IEnumerable<LatLngLiteral>> paths)
{
PolygonOptions googlePolygonOptions;
if (mapPolygon != null)
{
googlePolygonOptions = mapPolygon.ToGooglePolygonOptions();
}
else
{
googlePolygonOptions = new PolygonOptions();
}
googlePolygonOptions.Map = bgmMap.InteropObject;
googlePolygonOptions.Paths = paths;
if (userPolygon == null)
{
userPolygon = await Polygon.CreateAsync(JS, googlePolygonOptions);
}
else
{
await userPolygon.SetPaths(paths);
}
}
I think actually deleting the JS polygon object and then disposing of the C# reference would involve something like this (untested code):
// remove from the map first
await userPolygon.SetMap(null);
// (untested):
// manually invoke the remove function which under the hood eventually calls `delete mapObjects[guid];` in JS.
// Currently it looks like only `EventListeners` will call this on themselves from their
// Dispose(), but there's a TODO comment implying that other managed resources should maybe also do this when disposed.
// It's probably not implemented because there are perf concerns if we would be for example
// calling "remove" for hundreds of map markers at once.
await userPolygon.InvokeAsync("remove") ;
// Dispose the C# JSInterop handle object
await userPolygon.Dispose();
// Optionally set the C# interop object to null so that other code knows it can/should create a new one if needed.
userPolygon = null;
@christopherdude Does this help for you? https://github.com/rungwiroon/BlazorGoogleMaps/blob/master/ServerSideDemo/Pages/MapPolyline.razor#L353
@TheAtomicOption i did quick google to investigate how to dispose map object and it related. I am not sure if reusing map object should be library responsibility. It could make other issues. Maybe having as option to reuse could be one way. Also Polygon and polyline dont have "remove" method. Only event listeners have it. Despite all i think it is issue with memory consumption and release on google maps and parts could be solve from our side.
Note that the above method does not delete the marker. It removes the marker from the map. If instead you wish to delete the marker, you should remove it from the map, and then set the marker itself to null. https://developers.google.com/maps/documentation/javascript/markers#remove https://issuetracker.google.com/issues/35821412#comment32
Closing this one. Discussion related memory could continue on this one https://github.com/rungwiroon/BlazorGoogleMaps/issues/270
Is there a way within this interop to delete a polygon after being created? I can't seem to find any implementation of that?