Search code examples
mapboxmapbox-gl-jsmapbox-gl

How to set multiple markers on same coordinates with mapbox?


I use mapbox GL to referenced video games company based in Africa. All these company are placed on a map : https://africangamingnetworks.com/

When I have multiple markers with same coordinate for example two companies in Yaounde in Cameroon, mapbox shows just the first one, because they have the same latitude and longitude.

How could I do to show all markers with same coordinates ?

Thanks in advance.

<%@ include file="/init.jsp"%>
<div class="shadow row">
    <div class=" col-12 rounded-sm " id='map'
        style='height: 800px;'></div>

</div>


<script>
    mapboxgl.accessToken = 'pk.eyJ1Ijoia29zdGVkIiMWQzbXA3M2ZxYmd5MnkifQ.faOl-gGzibR9yMpZ-i7FTQ';
    var map = new mapboxgl.Map({
        container : 'map',
        style : 'mapbox://styles/mapbox/streets-v11',
        zoom : 2
    // starting zoom
    });

    // Add zoom and rotation controls to the map.
    map.addControl(new mapboxgl.NavigationControl());

    var studioListComplete = [];

    <c:forEach var="studio" items="${studioList}">

    studioListComplete
            .push({
                "type" : "Feature",
                "properties" : {
                    "description" : "<strong>${studio.studioName} (${studio.country})</strong> <br/><br/>" + 
                                    "${studio.studioDescription}<br/><br/>"+
                                    "<strong>City : </strong>${studio.city}<br/>"+
                                    "<strong>Number of employees : </strong>${studio.numberOfEmployees}<br/>"+
                                    "<strong>Phone : </strong>${studio.phoneNumber}<br/><br/>"+

                                    "<a href=\"${studio.webSiteUrl}\" target=\"_blank\">Please visit our website</a>",
                    "icon": "rocket"
                },
                "geometry" : {
                    "type" : "Point",
                    "coordinates" : [ "${studio.longitude}",
                            "${studio.latitude}" ]
                }
            });
    //var marker = new mapboxgl.Marker()
    //.setLngLat(["${studio.longitude}", "${studio.latitude}"])
    //.addTo(map);
    </c:forEach>

    console.log(studioListComplete);

    map.on('load', function() {
        // Add a layer showing the places.
        map.addLayer({
            "id" : "places",
            "type" : "symbol",
            "source" : {
                "type" : "geojson",
                "data" : {
                    "type" : "FeatureCollection",
                    "features" : studioListComplete
                }
            },
            "layout" : {
                "icon-image" : "{icon}-15",
                'icon-size': 1,
                "icon-allow-overlap" : true
            }
        });

        // When a click event occurs on a feature in the places layer, open a popup at the
        // location of the feature, with description HTML from its properties.
        map.on('click', 'places', function(e) {
            var coordinates = e.features[0].geometry.coordinates.slice();
            var description = e.features[0].properties.description;

            // Ensure that if the map is zoomed out such that multiple
            // copies of the feature are visible, the popup appears
            // over the copy being pointed to.
            while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
                coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
            }

            new mapboxgl.Popup().setLngLat(coordinates).setHTML(description)
                    .addTo(map);
        });

        // Change the cursor to a pointer when the mouse is over the places layer.
        map.on('mouseenter', 'places', function() {
            map.getCanvas().style.cursor = 'pointer';
        });

        // Change it back to a pointer when it leaves.
        map.on('mouseleave', 'places', function() {
            map.getCanvas().style.cursor = '';
        });
    });
</script>

<style>
    //Style is here

</style>

Solution

  • If you'd like two discrete markers to display for points with the same coordinates, the best thing to do is to slightly modify the latitude and longitude of one of the points so that it is not directly on top of the other one.

    Alternatively, if it is not an option to modify the coordinate data, you could explore clustering your data so that it is visually clear that multiple companies are located within the same cluster. This example shows how to create and style clusters using a default circle layer, and this example shows how the visual clusters can be highly customized.