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

what's the proper way to replace a map overlay ? #343

Closed
emaayan opened this issue Feb 27, 2024 · 6 comments
Closed

what's the proper way to replace a map overlay ? #343

emaayan opened this issue Feb 27, 2024 · 6 comments
Assignees
Labels
question Information is requested stale waiting-for-response If no response is received after a certain time the issue will be closed

Comments

@emaayan
Copy link

emaayan commented Feb 27, 2024

so far i've only seen methods that either remove or add a map
so assuming i have a tree on the left like so, i'd like to map and it's markers to be replaced.
but all of them are kept beeing added using addTo and i'm assuming they won't be cleared off the compoenent registry
image

@AB-xdev AB-xdev added the question Information is requested label Feb 29, 2024
@AB-xdev AB-xdev self-assigned this Feb 29, 2024
@AB-xdev
Copy link
Member

AB-xdev commented Feb 29, 2024

How I would solve this:

  1. Use Layers and build/display them dynamically if needed
  2. If you want to remove the marker/layer from the map simply call #remove().
  3. If you want to completely get rid of a marker/layer (on the client and server side) to e.g. free up memory: Remove it as mentioned above from the map and then call LComponentManagementRegistry#remove

@emaayan
Copy link
Author

emaayan commented Feb 29, 2024

thanks, but this would require me to hold a class level referne for everytying i add to the map (like markers and layers
i was hoping to get them from the map once, (like for example based on a well known string like so:
map.setLayer("Image",image)

btw is there a way to use an image obtained dynamically (like for example if you get a base64 encoding string from another server), i saw there is some way to register a dynamic resource in vaadin, but it doesn't seem to work with leaflet

@AB-xdev
Copy link
Member

AB-xdev commented Feb 29, 2024

No problem :)

thanks, but this would require me to hold a class level referne for everytying i add to the map

Well you can just hold the Layers and then call remove or add that wouldn't be that much or you build them for each "Floor"/Marker Group dynamically each time.

I created an example similar to your use case in our demo:
https://github.com/xdev-software/vaadin-maps-leaflet-flow/blob/develop/vaadin-maps-leaflet-flow-demo/src/main/java/software/xdev/vaadin/maps/leaflet/flow/demo/MultiLayerWithPyramidDemo.java
check it out, maybe it helps.

i was hoping to get them from the map once, (like for example based on a well known string like so:
map.setLayer("Image",image)

Do you mean from the client side? If yes, don't do that since clientside data can easily manipulated and therefore data integrity is no longer guaranteed. It's also not implemented in the library for exactly this reason :)

btw is there a way to use an image obtained dynamically (like for example if you get a base64 encoding string from another server), i saw there is some way to register a dynamic resource in vaadin, but it doesn't seem to work with leaflet

For what exactly?
For an ImageOverlay it works like this when using no external urls.
Otherwise you need to register that resource dynamically with Vaadin or host it somewhere else (e.g. with Amazon S3).

@AB-xdev AB-xdev added the waiting-for-response If no response is received after a certain time the issue will be closed label Feb 29, 2024
@emaayan
Copy link
Author

emaayan commented Feb 29, 2024

so basically i can do something like this:
and have configure get called each time i click on a line

package org.example;



public class MapView extends VerticalLayout {

    private final LComponentManagementRegistry reg;
    private final LMap map;
    private LLayerGroup lLayerGroup;
    public MapView() {
        this.reg = new LDefaultComponentManagementRegistry(this);

        final MapContainer mapContainer = new MapContainer(
                this.reg,
                new LMapOptions()
                        .withCrs(LCRS.Defined.SIMPLE)
                        .withMinZoom(-3)

        );
        mapContainer.setSizeFull();
        map = mapContainer.getlMap();
        add(mapContainer);
    }


    public void configure(PointXY startPoint, PointXY endPoint, String imageFileURL, Collection<Device> devs,final Collection<Polygon> cells) {
        if (lLayerGroup!=null) {
            lLayerGroup.remove();
        }
        lLayerGroup=new LLayerGroup(reg);
        lLayerGroup.addTo(this.map);

        final LLatLng start = this.xy(startPoint.getX(), startPoint.getY());
        final LLatLng end = this.xy(endPoint.getX(), endPoint.getY());
        final LLatLngBounds bounds = new LLatLngBounds(this.reg, start, end);
        final LImageOverlay overlay = new LImageOverlay(this.reg, imageFileURL, bounds);
        overlay.addTo(lLayerGroup);

        devs.stream().map(device -> {
            final String name = device.getName();
            final LLatLng coord = xy(locationPoint.getX(), locationPoint.getY());
            final LMarker lMarker = createMarker(coord, name)
                    //	.bindTooltip(text,new LTooltipOptions().withPermanent(true).withDirection("center"))
                    ;
            return lMarker;
        }).forEach(lLayer -> lLayer.addTo(lLayerGroup));
        
        cells.stream().map(geometry1 -> {
            final ArrayList<PointXY> allPoints = geometry1.getAllPoints();
            final Collection<LLatLng> list = new ArrayList<>();
            for (PointXY allPoint : allPoints) {
                final LLatLng xy = xy(allPoint.getX(), allPoint.getY());
                final LMarker lMarker = createMarker(xy, String.format("%d %d",allPoint.getX(), allPoint.getY()));
                lMarker.addTo(lLayerGroup);
                list.add(xy);
            }
            final LPolyline lPolyline = new LPolyline(MapView.this.reg, list);
            return lPolyline;
        }).forEach(lPolyline -> lPolyline.addTo(lLayerGroup));
        map.fitBounds(bounds);

    }

    private LMarker createMarker(LLatLng coord, String name) {
        return new LMarker(MapView.this.reg, coord, new LMarkerOptions()
//                                    .withIcon(icon)
                .withTitle(name))
                .bindPopup(name);
    }


    public void clear(){
        this.reg.clearAll();
    }
    private LLatLng xy(final double x, final double y) {
        return new LLatLng(this.reg, y, x);
    }
}

Copy link

github-actions bot commented Mar 8, 2024

This issue will be closed soon because there has been no response.

@github-actions github-actions bot added the stale label Mar 8, 2024
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Mar 11, 2024
@emaayan
Copy link
Author

emaayan commented Apr 30, 2024

can i use clearLayers instead of remove?
https://stackoverflow.com/questions/24318862/removing-all-data-markers-in-leaflet-map-before-calling-another-json
i've been searching around due to some error, (which i fixed), and i've seen similar questions,
there's seem to be remove, removeFrom, clearLayers, reg.remove , reg.freeUpClient, etc.. so i've been trying to get handle on all of them. (like for example do you need to call both remove and removeFrom and reg.remove on the component you want to free)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Information is requested stale waiting-for-response If no response is received after a certain time the issue will be closed
Projects
None yet
Development

No branches or pull requests

2 participants