rungwiroon / BlazorGoogleMaps

Blazor interop for GoogleMap library
MIT License
319 stars 102 forks source link

How to delete polygons #284

Closed christopherdude closed 4 months ago

christopherdude commented 10 months ago

Is there a way within this interop to delete a polygon after being created? I can't seem to find any implementation of that?

valentasm1 commented 10 months ago

https://developers.google.com/maps/documentation/javascript/markers#remove

valentasm1 commented 10 months ago

You are right. It should be same for polygon Do you have small demo how create polygon?

TheAtomicOption commented 4 months ago

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; 
valentasm1 commented 4 months ago

@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