Я автор последнего вопроса здесь . Он тесно связан с листовкой js и касается объединения маркеров при уменьшении масштаба на уровне страны. Я пытался прочитать мой код, но не смог найти способ решить эту проблему. Или, другими словами, на самом низком уровне масштабирования я бы хотел, чтобы отображался только один кластер, чтобы он отображал счет по всей стране.
Хотя у меня были хорошие ответы на мои предыдущие вопросы, я не могу технически выполнить их ответы, так как им не хватает необходимых сведений для кого-либо на моем уровне кода. Следовательно, почему я сделал дополнительный вопрос, чтобы преследовать дополнительную помощь. Моим идеальным решением будет фрагмент кода, который решает мою проблему, с кратким объяснением того, как работает код.
Прилагается мой код для моей карты. Некоторые дополнительные указания: L.divIcon - это место, где я добавляю синие и красные кружки, показанные в выводе ниже.
(function() {
window.PEW = {
map: '',
mapCenter: [36.19109202182454, -95.99853515625001],
tileUrl: 'https://api.mapbox.com/styles/v1/sourcetop/ck3yaryi60z7z1co7p7ttw4kf/tiles/256/{z}/{x}/{y}@2x?access_token=pk.eyJ1Ijoic291cmNldG9wIiwiYSI6ImNrM3lhYXMyazA2ZmczZ3FsbDM0aThhYnIifQ.eyPqNH3WmEFy8D1aw2vn6w',
mapAttribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
bounds: [],
zoom: 5,
zoomLevel: 'country',
callbackUrl: URL.com
locationCallbackUrl: URL.com
dmaJsonUrl: URL.com
markers: {
profile: {},
conditions: {}
},
dataLevel: 'profile',
locationMarkes: {},
dmaMarkers: [],
dmaPoly: [],
progress: 0,
progressTimer: '',
initMap: function() {
this.mapZoomClass();
this.map = L.map('map', {
center: this.mapCenter,
zoom: 5,
zoomControl: false,
zoomDelta: 2,
trackResize: true,
wheelPxPerZoomLevel: 25,
scrollEnable: true
});
L.control.zoom({
position: 'bottomright'
}).addTo(this.map);
L.tileLayer(this.tileUrl, {
attribution: this.mapAttribution,
minZoom: 2,
maxZoom: 13
}).addTo(this.map);
this.getBounds();
this.getZoomLevel();
this.mapAction();
},
plotMap: function(dataLevel) {
this.progressBarInit();
this.dataLevel = dataLevel;
this.dataLevelFixer();
this.requestDataFromServer();
},
requestDataParams: function() {
return {
bounds: this.bounds,
zoom: this.zoom,
level: this.zoomLevel,
year: PEWFilters.year,
x: Object.keys(window.PEWFilters.x),
y: Object.keys(window.PEWFilterss.y),
z: Object.keys(window.PEWFilters.z),
a: Object.keys(window.PEWFilters.a)
};
},
requestDataFromServer: function() {
$.ajax({
url : this.callbackUrl,
data: this.requestDataParams(),
})
.done(function(response) {
PEW.progressBarReset();
if(PEW.dataLevel == 'conditions') {
PEW.dataLevel = 'profile';
PEW.plotMarkers(response);
PEW.dataLevel = 'conditions';
}
PEW.plotMarkers(response);
})
.fail(function(jqXHR, textStatus) {
console.log('Request failed: ' + textStatus);
});
},
// Plot markers.
plotMarkers: function(response) {
this.clearmarkerLayer();
var color = window.PEWFilters.colors[this.dataLevel];
if(this.zoomLevel != 'state') {
this.initClusterMarker(color, this.dataLevel);
} else {
this.markers[PEW.dataLevel] = L.featureGroup();
}
var markerList = [];
response.forEach(function(data){
var count = PEW.getResultCount(data);
if(data.location != null && count) {
var icon = L.divIcon({
html: PEW.getMarkerHtml(count, color)
});
var marker = L.marker(
new L.LatLng(data.location[1], data.location[0]),
{icon: icon, zIndexOffset: 2000}
);
marker.count = count;
if(PEW.zoomLevel == 'state') {
marker.on('click', function(e) {
PEW.map.setView(e.latlng, 1);
});
PEW.markers[PEW.dataLevel].addLayer(marker);
} else {
markerList.push(marker);
}
}
});
if(this.zoomLevel != 'state') {
this.markers[this.dataLevel].addLayers(markerList);
}
this.map.addLayer(this.markers[this.dataLevel]);
},
// init cluster markers.
initClusterMarker: function(color, type) {
this.markers[type] = L.markerClusterGroup({
chunkedLoading: true,
spiderfyOnMaxZoom: true,
showCoverageOnHover: false,
iconCreateFunction: function(cluster) {
var markers = cluster.getAllChildMarkers();
var markerCount = 0;
markers.forEach(function(m){
markerCount = markerCount + m.count;
});
return new L.DivIcon({
html: petMap.getMarkerHtml(markerCount, color),
className: 'marker-type-cluster-' + (petMapFilters.colors.profile == color ? 'profile' : 'condition')
});
}
});
},
clearmarkerLayer: function() {
if(Object.keys(this.markers.profile).length && this.dataLevel == 'profile') {
this.markers.profile.clearLayers();
}
if(Object.keys(this.markers.conditions).length) {
this.markers.conditions.clearLayers();
}
},
/**********************************************************/
plotLocations: function() {
if(Object.keys(petMapFilters.locationSelected).length) {
for(var i in petMapFilters.locationSelected) {
if(typeof this.locationMarkes[i] == 'undefined') {
this.plotLocation(i);
}
}
}
},
removeLocationMarker: function(id) {
if(typeof this.locationMarkes[id] != 'undefined' && Object.keys(this.locationMarkes[id]).length) {
this.locationMarkes[id].clearLayers();
delete this.locationMarkes[id];
}
},
plotLocation: function(id) {
this.progressBarInit();
$.ajax({
url: this.locationCallbackUrl,
data: {
// bounds: this.bounds,
collection: id
}
})
.done(function(response) {
petMap.progressBarReset();
petMap.plotLocationMarkers(id, response);
})
.fail(function(jqXHR, textStatus) {
console.log('Request failed: ' + textStatus);
});
},
plotLocationMarkers: function(id, response) {
if(typeof this.locationMarkes[id] != 'undefined' && Object.keys(this.locationMarkes[id]).length) {
this.locationMarkes[id].clearLayers();
this.locationMarkes[id] = [];
}
this.initLocationClusterMarker(id);
var markerList = [];
response.forEach(function(data){
if(data.location != null) {
var marker = L.marker(new L.LatLng(data.location.coordinates[1], data.location.coordinates[0]), {icon: petMap.getLocationIcon(id, 'marker'), zIndexOffset: 1000}).bindPopup(petMap.getLocationPopup(data));
markerList.push(marker);
}
});
this.locationMarkes[id].addLayers(markerList);
},
initLocationClusterMarker: function(id) {
this.locationMarkes[id] = L.markerClusterGroup({
chunkedLoading: true,
spiderfyOnMaxZoom: true,
showCoverageOnHover: false,
iconCreateFunction: function(cluster) {
return petMap.getLocationIcon(id, 'cluster', cluster.getAllChildMarkers().length);
}
});
this.map.addLayer(this.locationMarkes[id]);
},
getLocationIcon: function(id, type, count) {
var sizeMap = {
'shop-marker': [16, 19],
'shop-cluster': [35, 40],
'clinic-marker': [18, 17],
'clinic-cluster': [38, 35],
};
var dt = id.split(':');
var icon = dt[0] == 'shop' ? 'shop-' + type + '.svg' : 'hospital-' + type + '.svg';
var anchor = dt[0] == 'shop' ? [-1, -10] : [0, -8];
if(type == 'cluster') {
return new L.DivIcon({
html: '<div class="location-marker location-type-' + dt[0] + '" tabindex="0">' + count + '</div>',
className: 'marker-type-cluster-location'
});
} else {
return L.icon({
iconUrl: 'images/' + icon,
iconSize: sizeMap[dt[0] + '-' + type],
popupAnchor: anchor,
className: 'location-single-marker'
});
}
},
getLocationPopup: function(data) {
var details = [];
if(typeof data.street != 'undefined') { details.push(data.street); }
if(typeof data.city != 'undefined') { details.push(data.city); }
if(typeof data.state != 'undefined') { details.push(data.state); }
if(typeof data.contact != 'undefined') { details.push(data.contact); }
details = details.join('<br/>');
if(details.length) {
details = '<div class="location">' + details + '</div>';
}
return '<div class="hospital-popup"><div class="color-red">' + data.name + '</div>' + details + '</div>';
},
/**********************************************************/
plotDmaData: function(op) {
if(op == 'add') {
if(!Object.keys(this.dmaMarkers).length) {
this.getDmaData();
} else {
this.map.addLayer(this.dmaMarkers);
this.map.addLayer(this.dmaPoly);
}
} else {
if(Object.keys(this.dmaMarkers).length) {
this.map.removeLayer(this.dmaMarkers);
this.map.removeLayer(this.dmaPoly);
}
}
},
getDmaData: function() {
$.getJSON(this.dmaJsonUrl, function(response) {
petMap.plotDmaMarkers(response);
});
},
plotDmaMarkers: function(response) {
this.dmaMarkers = L.featureGroup();
this.dmaPoly = L.geoJson(response, {
style: {
opacity: 0,
fillOpacity: 0
},
onEachFeature: function(feature, layer) {
var latlng = new L.LatLng(feature.properties.latitude, feature.properties.longitude);
var icon = petMap.getDmaMarkerIcon(feature.properties);
var marker = L.marker(latlng, {icon: icon, riseOnHover: true, riseOffset: 3000});
marker.data = feature.properties;
marker.layer = layer;
marker.on('click', function(e) {
petMapDmaPopup.init(e.target.data);
});
marker.on('mouseover', function(e) {
var layer = e.target.layer;
layer.setStyle({
weight: 1,
color: '#8A8D8F',
dashArray: '',
fillOpacity: 0.5
});
if(!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
});
marker.on('mouseout', function(e) {
petMap.dmaPoly.resetStyle(e.target.layer);
});
petMap.dmaMarkers.addLayer(marker);
}
});
this.map.addLayer(this.dmaMarkers);
this.map.addLayer(this.dmaPoly);
},
getDmaMarkerIcon: function(data) {
var cluster_classes = [
'dma-marker-icon',
'leaflet-marker-icon',
'leaflet-zoom-animated',
'leaflet-clickable'
];
return L.divIcon({
html: '<div class="' + cluster_classes.join(' ') + '" tabindex="0">' + data.dma_name + '</div>'
});
},
/**********************************************************/
mapAction: function() {
this.map.on('zoomend dragend',function(e) {
petMap.getBounds();
petMap.getZoomLevel();
petMap.progressBarInit();
petMap.requestDataFromServer();
});
},
resetMap: function() {
this.dataLevel = 'profile';
this.clearmarkerLayer();
if(Object.keys(this.locationMarkes).length) {
for(var id in this.locationMarkes) {
this.locationMarkes[id].clearLayers();
delete this.locationMarkes[id];
}
}
this.map.removeLayer(this.dmaMarkers);
this.map.setView(new L.LatLng(this.mapCenter[0], this.mapCenter[1]), 5);
},
getBounds: function() {
var bounds = this.map.getBounds();
this.bounds = {
tr: {
lat: bounds.getNorthEast().lat,
lng: bounds.getNorthEast().lng
},
bl: {
lat: bounds.getSouthWest().lat,
lng: bounds.getSouthWest().lng
}
};
},
getZoomLevel: function() {
this.zoom = this.map.getZoom();
this.zoomLevel = 'state';
if(this.zoom > 6) {
this.zoomLevel = 'city';
}
if(this.zoom > 8) {
this.zoomLevel = 'zip';
}
// dma data.
if(this.zoom > 6) {
this.plotDmaData('add');
} else {
this.plotDmaData('remove');
}
},
mapZoomClass: function() {
L.Map.mergeOptions({
zoomCss: true
});
L.Map.ZoomCSS = L.Handler.extend({
addHooks: function() {
this._zoomCSS();
this._map.on('zoomend', this._zoomCSS, this);
},
removeHooks: function() {
this._map.off('zoomend', this._zoomCSS, this);
},
_zoomCSS: function(e) {
var map = this._map,
zoom = map.getZoom(),
container = map.getContainer();
container.className = container.className.replace( /\smap-zoom-[0-9]{1,2}/g, '' ) + ' map-zoom-' + zoom;
}
});
L.Map.addInitHook('addHandler', 'zoomCss', L.Map.ZoomCSS);
},
/**********************************************************/
progressBarInit: function() {
clearTimeout(petMap.progressTimer);
$('.progress-bar .progress').css('width', '0%');
$('.progress-bar').removeClass('hide');
this.progressBarProress();
},
progressBarProress: function() {
this.progressTimer = setTimeout(function() {
petMap.progress += 0.5;
$('.progress-bar .progress').css('width', petMap.progress + '%');
if(petMap.progress != 100) {
petMap.progressBarProress();
}
}, 25);
},
progressBarReset: function() {
$('.progress-bar').addClass('hide');
$('.progress-bar .progress').css('width', '0%');
clearTimeout(petMap.progressTimer);
petMap.progress = 0;
},
/**********************************************************/
formatCount: function(count) {
if(count > 1000) {
count = Math.floor(count / 1000) + 'K' + (count % 1000 !== 0 ? '+' : '');
}
return count;
},
getMarkerSize: function(count) {
size = 30;
if(count > 100) {
size = 35;
}
if(count > 500) {
size = 40;
}
if(count > 1000) {
size = 45;
}
if(count > 5000) {
size = 50;
}
if(count > 10000) {
size = 55;
}
if(count > 20000) {
size = 60;
}
if(count > 30000) {
size = 65;
}
if(count > 50000) {
size = 70;
}
if(count > 70000) {
size = 75;
}
if(count > 90000) {
size = 80;
}
if(count > 120000) {
size = 85;
}
if(count > 140000) {
size = 90;
}
if(count > 160000) {
size = 95;
}
if(count > 180000) {
size = 100;
}
if(count > 200000) {
size = 105;
}
if(count > 220000) {
size = 110;
}
if(count > 240000) {
size = 115;
}
if(count > 260000) {
size = 120;
}
if(count > 280000) {
size = 125;
}
if(count > 300000) {
size = 130;
}
if(count > 320000) {
size = 135;
}
if(count > 340000) {
size = 140;
}
if(count > 360000) {
size = 145;
}
if(count > 380000) {
size = 150;
}
if(count > 400000) {
size = 155;
}
if(count > 500000) {
size = 160;
}
if(count > 600000) {
size = 165;
}
if(count > 700000) {
size = 170;
}
if(count > 800000) {
size = 175;
}
return size;
},
getMarkerHtml: function(count, color) {
var size = this.getMarkerSize(count);
var hsize = (size / 2) - 6;
var font = count < 1000 ? Math.ceil(size / 3) : Math.ceil(size / 4);
if(count < 100) {
font = font + 3;
}
var cluster_classes = [
'map-marker',
'marker-bg-' + (petMapFilters.colors.profile === color ? 'profile' : 'condition')
];
if(this.zoomLevel !== 'zip') {
size = size * 1.5;
if(petMapFilters.colors.profile !== color) {
hsize = size / 2;
}
}
var cluster_styles = [
'margin-left: -' + hsize + 'px;',
'margin-top: -' + hsize + 'px;',
'width: ' + size + 'px;',
'height: ' + size + 'px;',
'font-size: ' + font + 'px;'
];
var div_style = [
'line-height: ' + (size - (size * 0.3)) + 'px;'
];
count = this.formatCount(count);
return '<div class="' + cluster_classes.join(' ') + '" tabindex="0" style="' + cluster_styles.join(' ') + '"><div style="' + div_style.join(' ') + '">' + count + '</div></div>';
},
getResultCount: function(data) {
if(this.dataLevel === 'conditions') {
if(typeof data.total_ailments != 'undefined') {
return data.total_ailments;
}
return 0;
}
return data.total;
},
dataLevelFixer: function() {
this.dataLevel = 'profile';
if(Object.keys(petMapFilters.ailments).length) {
this.dataLevel = 'conditions';
}
}
};
})(jQuery);
Изображение моего вывода: