Search code examples
azure-maps

Azure Maps clear map without affecting style


I have multiple rendering options exposed through a UI in my Azure maps application. When a user changes one of these options, then the whole map is re-rendered. This functionality uses map.clear() internally. However, after calling this method, the style of the map dissapears, which results in a white background. I did not find this effect in the official documentation.

I looked at the map.getStyle() properties after map.clear() and it seems that the style is still the same (starting with style: 'road' will still be style: 'road' after the clear), but it isn't visible until the user selects a new style from the controls. Changing the map style options after the clear to the map style options before the clear (map.setStyle(oldStyleOptions, false)) generates errors so that's also not possible. Any thoughts about this?


Solution

  • map.clear() removes everything and in most cases, not what you will want.

    If you simply want to remove all data on the map, but keep the rendering layers there, ready for new data later, use the data sources clear function. For example:

    var source = new atlas.source.DataSource();
    map.sources.add(source);
    
    //Connect source to rendering layers...
    //Add some data at some point....
    
    //Later, decide to remove data from the map.
    source.clear();
    

    A key concept of Azure Maps is that is separates data from rendering layers. It's a bit different from older map SDKs, but it provides a lot more potential for performance and styling.

    Update - 10/10/2023

    Here is a function that will remove only content added by users of the map SDK, and not the basemap layers/sources.

    function removeUserContent(map) {
        //Remove popups.
        map.popups.clear();
        
        //Remove markers.
        map.markers.remove();
        
        //Get user layers. (workaround using undocumented method to get the layers created by the user). The response contains information about layers and what layer they are added before.
        var userLayerInfo = map.layers._getUserLayers();
        
        //Get the sources used by user layers that don't belong to the basemap.
        //Get user layer objects.
        var userSources = [];   
        var userLayers = [];
        
        userLayerInfo.forEach(l => {
            var sourceId = l.layer.options.source.id;
            if(sourceId !== 'bing-mvt' && userSources.indexOf(sourceId) === -1) {
                userSources.push(sourceId);
            }
            userLayers.push(l.layer);
        });
            
        //Remove user layers.
        map.layers.remove(userLayers);
        
        //Remove user sources.
        map.sources.remove(userSources);
        
        //Optional. Remove all user added images.
        map.imageSprite.clear();
    }
    

    Simply pass your map object into this function and it will do the rest.