Давайте предположим упрощенную версию вашего набора данных, например, Geo JSON FeatureCollection
, содержащую точки для клиник / отделений в больницах, где две (или более) клиники, относящиеся к одной и той же больнице, занимают одну и ту же позицию:
let clinics = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": { "clinic": "cardio", "phone": "11 22 33 44 55" },
"geometry": {
"type": "Point", "coordinates": [5.74, 45.20]
}
},
{
"type": "Feature",
"properties": { "clinic": "trauma", "phone": "66 77 88 99 00" },
"geometry": {
"type": "Point", "coordinates": [5.74, 45.20]
}
},
{
"type": "Feature",
"properties": { "clinic": "neuro", "phone": "77 66 55 44 33" },
"geometry": {
"type": "Point", "coordinates": [6.12, 43.88]
}
}
]
};
Мой подход заключается в том, чтобы вручную l oop через указанный Geo JSON FeatureCollection
, индексировать точечные объекты на основе их координат и объединять их свойства в массив, например:
let clinicsByPosition = {};
for (let clinic of clinics.features) {
// Let the index be the string representation of the coordinates array;
// this is probably inefficient, but will suffice.
// Note there are no sanity checks performed here (e.g. checking geometry type)
let idx = clinic.geometry.coordinates.toString();
// Does clinicsByPosition already have something in that index?
if (clinicsByPosition[idx] === undefined) {
// Create a new feature in that index
// Initialize the properties of that new feature to an array with
// one element, the properties of the clinic, and same geometry
// than the clinic.
clinicsByPosition[idx] = {
type: "Feature",
geometry: clinic.geometry,
properties: [clinic.properties]
}
} else {
// Add the properties of the clinic to the already existing indexed
// feature
clinicsByPosition[idx].properties.push(clinic.properties);
}
}
// Second pass: convert the "clinicsByPosition" data structure
// into a GeoJSON FeatureCollection
let hospitals = {
type:'FeatureCollection',
features: []
}
for (let indexedClinicSet of Object.values(clinicsByPosition)) {
hospitals.features.push(indexedClinicSet)
}
После этого преобразования агрегированный набор данных будет выглядеть следующим образом:
let hospitals = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: { type: "Point", coordinates: [5.74, 45.2] },
properties: [
{ clinic: "cardio", phone: "11 22 33 44 55" },
{ clinic: "trauma", phone: "66 77 88 99 00" },
],
},
{
type: "Feature",
geometry: { type: "Point", coordinates: [6.12, 43.88] },
properties: [{ clinic: "neuro", phone: "77 66 55 44 33" }],
},
],
};
Давайте поместим это в Leaflet с несколькими всплывающими подсказками:
var hospitals = L.geoJson(hospitalsData,{
onEachFeature: function(feat, marker) {
// For this example, let the contents of the popup of a hospital marker
// to be a concatenation of the data for all clinics in that hospital
marker.bindPopup(feat.properties.map(function(clinicData){
return clinicData.clinic + " - tlf " + clinicData.phone
}).join("<br>"))
}
}).addTo(map);
A рабочий пример с что выглядит не так уж и плохо:
Теперь должно быть ясно, что в каждом наборе клиник есть только одна функция по тем же координатам.
Теперь фильтрацию можно выполнять (ИМХО) разумным способом. L oop через маркеры больницы в экземпляре L.GeoJSON
и l oop через свойства каждого связанного объекта, чтобы увидеть, выполняется ли условие видимости для любого его компонентов, например:
function recalculateHospitalVisibility(){
var cardioVisible = document.getElementById('cardio').checked;
var traumaVisible = document.getElementById('trauma').checked;
var neuroVisible = document.getElementById('neuro').checked;
hospitals.eachLayer(function (marker) {
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
if (
marker.feature.properties.some(function (clinic) {
return (
(clinic.clinic === "cardio" && cardioVisible) ||
(clinic.clinic === "trauma" && traumaVisible) ||
(clinic.clinic === "neuro" && neuroVisible)
);
})
) {
marker.addTo(map);
} else {
marker.remove();
}
});
}
Рабочий пример здесь . Даже если код может выглядеть немного запутанным, пример данных упрощен (так что мой немедицинский мозг может работать с ним лучше), использование итераторов и структур данных немного тяжело, и возможна оптимизация, это должно помочь вам на трассе.