简体   繁体   English

距离地图中心太远时,地图框标记会消失

[英]Mapbox markers disappearing when too far away from map center

I have a Mapbox map with markers (I also use MarkerCluster). 我有一个带有标记的Mapbox地图(我也使用MarkerCluster)。 I get these HTML markers in JavaScript to determine their position (from viewport, not their coordinates), so I can add some indicators of markers that are not in viewport. 我在JavaScript中获得了这些HTML标记,以确定它们的位置(从视口而不是从坐标),因此我可以添加一些不在视口中的标记的指示符。 But I realized that when I'm too far away from a marker (when zooming or dragging the map for example), the markers just doesn't appear in the HTML! 但是我意识到,当我离标记太远时(例如,缩放或拖动地图时),标记就不会出现在HTML中! It seems it's the normal behaviour because I can see the same thing happening in the official examples. 看来这是正常现象,因为我可以在官方示例中看到相同的情况。

So, here's the question: is there any way to prevent this behaviour and always have the markers in the HTML? 因此,这是一个问题:有什么方法可以防止这种行为,并且在HTML中始终具有标记?

Here is the JavaScript: (I use mapbox.js and leaflet.markercluster) 这是JavaScript :(我使用mapbox.js和leaflet.markercluster)

var places = {
    "type": "FeatureCollection",
    "features": [{
        "type": "Feature",
        "properties": {
            "description": ">Test 1"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-1.6313898, 47.2005156]
        }
    }, {
        "type": "Feature",
        "properties": {
            "description": "Test 2"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [2.3279346, 48.8960698]
        }
    }, {
        "type": "Feature",
        "properties": {
            "description": "Test 3"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [2.7391394, 48.7238554]
        }
    }, {
        "type": "Feature",
        "properties": {
            "description": "Test 4"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [55.4933757, -20.9034031]
        }
    }]
};

L.mapbox.accessToken = 'pk.eyJ1Ijoic3RlcmVvc3VwZXIiLCJhIjoiY2lyM2JnMDIwMDAxM2k0bWNndmUzeTFhbSJ9.UZ-XuPASxGVtYFSqdVyppg';

var map = L.mapbox.map('map', null, {minZoom: 3, maxZoom: 16, center: [46, 8], zoom: 5, scrollWheelZoom: false, maxBounds: [[-100.0,-100.0],[100.0,100.0]]});
L.mapbox.styleLayer('mapbox://styles/stereosuper/cir3bgtaz001wjcnntu6n2axw').addTo(map);

var markers = L.mapbox.featureLayer(places);
var icon = L.divIcon({ iconSize: [30, 30], popupAnchor: [0, -20] });
markers.eachLayer(function(l){ l.setIcon(icon); });

var clusterPlaces = new L.MarkerClusterGroup({
    iconCreateFunction: function(cluster){
        return new L.DivIcon({ iconSize: [30, 30], html: '<div class="marker-cluster"><span>'+cluster.getChildCount()+'</span></div>' });
    }
});
clusterPlaces.addLayer(markers).addTo(map);

map.on('moveend', function(e){
    var htmlMarkers = $('.leaflet-marker-icon'),
        xCenter = $(window).width()/2, yCenter = $(window).height()/2;

    if($('.map-indicator').length){
        $('.map-indicator').remove();
    }

    htmlMarkers.each(function(i){
        var thisMarker = $(this),
            thisCluster = thisMarker.find('span').length,
            thisMarkerHtml = thisCluster ? thisMarker.find('span').html() : 1;
        var top = thisMarker.offset().top, left = thisMarker.offset().left;
        var indicator = '<button class="map-indicator map-indicator-'+i+'"><span>'+thisMarkerHtml+'</span></button>';
        var newLeft, newTop, angle, distance;
        var mapHtml = $('#map');

        if(top + thisMarker.height() < 0){
            mapHtml.append(indicator)
            if(left > xCenter){
                distance = (left-xCenter) * (yCenter/(yCenter-top));
                angle = Math.atan(distance/yCenter)*180/Math.PI;
                newLeft = xCenter + distance;
                if(newLeft > $(window).width() - 40) newLeft = $(window).width() - 40;
            }else{
                distance = (xCenter-left) * (yCenter/(yCenter-top));
                angle = - Math.atan(distance/yCenter)*180/Math.PI;
                newLeft = xCenter - distance;
                if(newLeft < 40) newLeft = 40;
            }
            $('.map-indicator-'+i).css({'top': '10px', 'left':  newLeft + 'px', 'bottom': 'auto', 'right': 'auto', '-webkit-transform': 'rotate('+angle+'deg)', 'transform': 'rotate('+angle+'deg)'}).addClass('top').removeClass('bottom', 'left', 'right');
        }else if(top > $(window).height()){
            mapHtml.append(indicator)
            if(left > xCenter){
                distance = (left-xCenter) * (yCenter/(yCenter+(top-$(window).height())));
                angle = - Math.atan(distance/yCenter)*180/Math.PI;
                newLeft = xCenter + distance;
                if(newLeft > $(window).width() - 40) newLeft = $(window).width() - 40;
            }else{
                distance = (xCenter-left) * (yCenter/(yCenter+(top-$(window).height())));
                angle = Math.atan(distance/yCenter)*180/Math.PI;
                newLeft = xCenter - distance;
                if(newLeft < 40) newLeft = 40;
            }
            $('.map-indicator-'+i).css({'bottom': '10px', 'left':  newLeft + 'px', 'top': 'auto', 'right': 'auto', '-webkit-transform': 'rotate('+angle+'deg)', 'transform': 'rotate('+angle+'deg)'}).addClass('bottom').removeClass('top', 'left', 'right');
        }else if(left + thisMarker.width() < 0){
            mapHtml.append(indicator)
            if(top < yCenter){
                distance = (yCenter-top) * (xCenter/(xCenter-left));
                angle = Math.atan(distance/xCenter)*180/Math.PI;
                newTop = yCenter - distance;
                if(newTop < 0) newTop = 0;
            }else{
                distance = (top-yCenter) * (xCenter/(xCenter-left));
                angle = - Math.atan(distance/xCenter)*180/Math.PI;
                newTop = yCenter + distance;
                if(newTop > $(window).height()) newTop = $(window).height() - thisMarker.height();
            }
            $('.map-indicator-'+i).css({'top': newTop, 'left': '10px', 'bottom': 'auto', 'right': 'auto', '-webkit-transform': 'rotate('+angle+'deg)', 'transform': 'rotate('+angle+'deg)'}).addClass('left').removeClass('bottom', 'top', 'right');
        }else if(left > $(window).width()){
            mapHtml.append(indicator)
            if(top < yCenter){
                distance = (yCenter-top) * (xCenter/(xCenter+(left-$(window).width())));
                angle = - Math.atan(distance/xCenter)*180/Math.PI;
                newTop = yCenter - distance;
                if(newTop < 0) newTop = 0;
            }else{
                distance = (top-yCenter) * (xCenter/(xCenter+(left-$(window).width())));
                angle = Math.atan(distance/xCenter)*180/Math.PI;
                newTop = yCenter + distance;
                if(newTop > $(window).height()) newTop = $(window).height() - thisMarker.height();
            }
            $('.map-indicator-'+i).css({'top': newTop, 'left': 'auto', 'bottom': 'auto', 'right': '10px', '-webkit-transform': 'rotate('+angle+'deg)', 'transform': 'rotate('+angle+'deg)'}).addClass('right').removeClass('bottom', 'left', 'top');
        }

        $('.map-indicator-'+i).on('click', function(e){
            var coordinates = map.layerPointToLatLng(thisMarker.context._leaflet_pos);
            map.panTo(coordinates);
        });
    });
});

Thanks in advance 提前致谢

You guessed absolutely right, Leaflet.markercluster plugin removes by default markers and clusters which are far away from your view port. 您猜测完全正确,Leaflet.markercluster插件默认会删除远离视口的标记和群集。

You can use removeOutsideVisibleBounds option when you create your Marker Cluster Group to disable this behaviour. 创建标记群集组时,可以使用removeOutsideVisibleBounds选项来禁用此行为。

Note that at high zoom, this may slow down your browser performance, as you will have plenty markers on map, which is one of the things Leaflet.markercluster tries to avoid. 请注意,在高缩放状态下,这可能会减慢您的浏览器性能,因为您将在地图上放置大量标记,这是Leaflet.markercluster试图避免的事情之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM