41
Views
7
Comments
Solved
[OutSystems Maps] Stop google maps from auto centering when there's only a single marker
outsystems-maps
Reactive icon
Forge asset by OutSystems
Application Type
Reactive

Hello,

Using Google Maps in reactive,

I have multiple markers spread across a specific country, the issue I'm having is that we have filters which can change where the markers appear.

I will use the united states as an example:

I start out with the entire united states markers, but then I have a dropdown where I can filter by State,

If I select a state, the map will only have markers on that state, which will cause the map to center on the first loaded marker from that state (I'm guessing it's the first marker or the boundaries of the markers of the state)

Is there any way I can stop this behaviour?

I was thinking that the map property "RespectUserZoom" was to stop this but I guess not.

Attached is a simple OML example, the map starts centered within all the markers, but as soon as you disable marker 2 and 3 it drags into marker 1, which is not what I want, I want to keep the same position.



MapsMarkerCentering.oml
2022-11-12 11-28-30
Gonçalo Martins
Staff
Solution

Hello @Fábio Rodrigues 

I was able to replicate the use case you mentioned, and it's by design.

As a workaround, you can override the API responsible for dealing with this behaviour, which is the method refresh, to adapt to your use case, which is basically adding an equal sign to a condition.

For that, place a JS node in the Map_Initialized event handler with the following: 

OutSystems.Maps.MapAPI.MapManager.GetMapById($parameters.MapId).refresh = 
    function (centerChanged) {
        this._removeMapZoomHandler();
        let position = this.features.center.getCenter();
        const isDefault = 
            position.lat === OSFramework.Maps.Helper.Constants.defaultMapCenter.lat &&
            position.lng === OSFramework.Maps.Helper.Constants.defaultMapCenter.lng;
        if (this.markers.length > 0) {
            const markerProvider = this.markers[0].provider;
            //CHANGED THIS AS A WORKAROUND, HAVING >=1 INSTEAD OF >1
            if (this.markers.length >= 1) {
                if (this.allowRefreshZoom) {
                    if (markerProvider !== undefined) {
                        if (isDefault || this.features.zoom.isAutofit) {
                            position = markerProvider.position.toJSON();
                        }
                    }
                }
                else {
                    position = centerChanged
                        ? this.config.center
                        : this.provider.getCenter().toJSON();
                }
            }
            else if (markerProvider !== undefined) {
                position = markerProvider.position.toJSON();
            }
        }
        this.features.center.refreshCenter(position);
        if (this.allowRefreshZoom) {
            this.features.zoom.refreshZoom();
        }
        this.features.offset.setOffset(this.features.offset.getOffset);
        this.hasMarkerClusterer() && this.features.markerClusterer.repaint();
        this._addMapZoomHandler();
    }

//$parameters.MapId is the identifier of the Map block

No change will be done in the product, so I won't share any task code to follow this up.

Hope it helps!

Cheers,
GM

2024-07-12 05-57-50
Gourav Shrivastava
Champion

Hello Fabio

When you filter the makers ->  country to state the map shows markers in that state only right ,so you need to center your map position to that state not that state's first loaded marker ,so for that you can use the map center feature of that map widget you can make it dynamical like if you select a country it set to country lat and long and if you select state it set to state lat long so your map always set their position where your filters goes .


Thanks 

Regards 

Gourav Shrivastava



2021-09-09 22-42-33
Fábio Rodrigues

Thanks for the reply but that’s not what I’m looking for.

What I need is to set the map to respect the user center, the map should only change it’s center whenever the user clicks a marker or drags the map himself.

2025-07-31 10-32-21
Vikram garasiya

Hi, 

I don't know whether it is feasible or not but I think you can use map events when the user clicks on the marker it will return its lat,lan you can use one local variable for the center and assign marker lat-lan to that center local variable same you can do when user drag map himself. for the click event, I already did the same using the marker click event but not sure about the drag event still you can try I hope it works for you. 

Thanks  - Vikram Garasiya

2021-09-09 22-42-33
Fábio Rodrigues

Hi Vikram,

The problem I'm having is not on clicking on a marker to center, the issue is that the map is autocentering on a solo marker, which I do not want to happen, if the user is centered in X and the only marker is in Y, the map has to keep itself in X, not move to Y, which is what is happening right now.

2025-07-31 10-32-21
Vikram garasiya

I saw your OML, you need to add one default center marker on the map on the center point.

https://personal-ljskqth5.outsystemscloud.com/PreviewInDevices/?IsMobilePreview=True&DeviceName=Smartphone&URL=/MapNeoLive/Home?_ts=638683948148336207

2021-09-09 22-42-33
Fábio Rodrigues

That doesn't make sense since the user can keep changing the center of the map by dragging the map itself.


I'm looking for a behaviour of the map itself, I believe it has nothing to do with the markers.

2022-11-12 11-28-30
Gonçalo Martins
Staff
Solution

Hello @Fábio Rodrigues 

I was able to replicate the use case you mentioned, and it's by design.

As a workaround, you can override the API responsible for dealing with this behaviour, which is the method refresh, to adapt to your use case, which is basically adding an equal sign to a condition.

For that, place a JS node in the Map_Initialized event handler with the following: 

OutSystems.Maps.MapAPI.MapManager.GetMapById($parameters.MapId).refresh = 
    function (centerChanged) {
        this._removeMapZoomHandler();
        let position = this.features.center.getCenter();
        const isDefault = 
            position.lat === OSFramework.Maps.Helper.Constants.defaultMapCenter.lat &&
            position.lng === OSFramework.Maps.Helper.Constants.defaultMapCenter.lng;
        if (this.markers.length > 0) {
            const markerProvider = this.markers[0].provider;
            //CHANGED THIS AS A WORKAROUND, HAVING >=1 INSTEAD OF >1
            if (this.markers.length >= 1) {
                if (this.allowRefreshZoom) {
                    if (markerProvider !== undefined) {
                        if (isDefault || this.features.zoom.isAutofit) {
                            position = markerProvider.position.toJSON();
                        }
                    }
                }
                else {
                    position = centerChanged
                        ? this.config.center
                        : this.provider.getCenter().toJSON();
                }
            }
            else if (markerProvider !== undefined) {
                position = markerProvider.position.toJSON();
            }
        }
        this.features.center.refreshCenter(position);
        if (this.allowRefreshZoom) {
            this.features.zoom.refreshZoom();
        }
        this.features.offset.setOffset(this.features.offset.getOffset);
        this.hasMarkerClusterer() && this.features.markerClusterer.repaint();
        this._addMapZoomHandler();
    }

//$parameters.MapId is the identifier of the Map block

No change will be done in the product, so I won't share any task code to follow this up.

Hope it helps!

Cheers,
GM

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.