В листовке 1.6.0 я делаю список местоположений (маркеры и полилинии), сгруппированные по странам, и мне нужно выполнить фильтрацию по странам, нажимая на кнопку страны. Я использую layerGroup, и мне удалось показать маркеры и полилинии с помощью метода типа:
drawGroupedAdLocationsMarkers() {
let polylinePoints = [] // I get all info about all Polylines
let loop_index = 0
this.groupedAdLocations.forEach(nextGroupedAdLocations => { // draw all groupedAdLocations
this.groupedCountriesList[this.groupedCountriesList.length] = {
key: nextGroupedAdLocations.country,
label: this.countriesList[nextGroupedAdLocations.country],
}
let markersList = []
let polylinesList = []
nextGroupedAdLocations.adLocations.forEach(nextAddLocation => { // draw all nextAddLocation
let priorPoint = null // eslint-disable-line
let priorMarker = null // eslint-disable-line
if (loop_index > 0) {
priorPoint = this.groupedAdLocations[loop_index - 1]
priorMarker= nextMarker
}
polylinePoints[polylinePoints.length] = [nextAddLocation.lat, nextAddLocation.lng]
let nextMarker= this.showLocationMarker(nextAddLocation)
markersList[markersList.length] = nextMarker
polylinesList[polylinesList.length] = this.showLocationDirections(polylinePoints, nextGroupedAdLocations.country)
loop_index++
}) // nextGroupedAdLocations.adLocations.forEach(nextAddLocation => { // draw all nextAddLocation
polylinesList.map((nextPolyline) => {
markersList.push(nextPolyline);
});
let newMarkersLayerGroup = this.leaflet.layerGroup(markersList).addTo(this.locationsMap);
this.layerGroupsMarkersArray[this.layerGroupsMarkersArray.length] = {
country: nextGroupedAdLocations.country,
layersObj: newMarkersLayerGroup
}
}) // this.groupedAdLocations.forEach(nextGroupedAdLocations => { // draw all groupedAdLocations
let radius = 10;
let polyline = new this.leaflet.Polyline(polylinePoints, {
color: 'green',
opacity: 1,
weight: 2,
customData: {
type:'polyline'
// point_id: point.id,
// prior_point_id: priorPoint ? priorPoint.id : null,
},
offset: radius
});
polyline.on('click', function (event) {
event.stopPropagation();
window.event.cancelBubble = true;
// showModal(event)
// alert('Polyline clicked!');
});
// Add polyline to featuregroup
polyline.addTo(this.locationsMap);
}, // drawGroupedAdLocationsMarkers() {
и методов для создания маркеров / полилиний:
showLocationMarker(nextAddLocation) {
let icon_size = 32
if (nextAddLocation.featured) {
icon_size = 48
}
var markerIcon = this.leaflet.icon({
iconUrl: (!nextAddLocation.featured ? '/images/location.png' : '/images/location_featured.png'),
iconSize: [icon_size, icon_size], // size of the icon
// shadowSize: [50, 64], // size of the shadow
iconAnchor: [icon_size, icon_size], // point of the icon which will correspond to marker's location
// shadowAnchor: [4, 62], // the same for the shadow
popupAnchor: [0, 0] // point from which the popup should open relative to the iconAnchor
});
let nextMarker = this.leaflet.marker(
[nextAddLocation.lat, nextAddLocation.lng],
{
icon: markerIcon,
customData:{add_location_id: nextAddLocation.id,type:'marker'}
})
.addTo(this.locationsMap)
.bindPopup(nextAddLocation.content)
.on('mouseover', this.locationMarkerOnMouseOver)
.on('click', this.locationMarkerOnClick)
.on('popupopen', this.locationMarkerOnPopupOpen)
// circleMarker
if (nextAddLocation.featured) {
nextMarker.bindTooltip("Featured Location").openTooltip();
}
let self = this
this.locationsMap.on('zoomend', function (/*e*/) {
self.current_zoom = self.locationsMap.getZoom()
});
if (nextAddLocation.opened) {
nextMarker.openPopup()
}
return nextMarker
}, // showLocationMarker(nextAddLocation) {
showLocationDirections(polylinePoints, country) {
let radius = 10;
let polyline = new this.leaflet.Polyline(polylinePoints, {
color: 'green',
opacity: 1,
weight: 2,
customData: {
type:'polyline'
// point_id: point.id,
// prior_point_id: priorPoint ? priorPoint.id : null,
},
offset: radius
});
// Add click listener
polyline.on('click', function (event) {
event.stopPropagation();
window.event.cancelBubble = true;
});
// Add polyline to featuregroup
polyline.addTo(this.locationsMap);
let decorator = this.leaflet.polylineDecorator(polyline, { // eslint-disable-line
patterns: [
// defines a pattern of 10px-wide dashes, repeated every 20px on the line
{
offset: 0,
repeat: 50,
symbol: this.leaflet.Symbol.arrowHead({
pixelSize: 10,
polygon: false,
pathOptions: {stroke: true}
})
}
]
}).addTo(this.locationsMap)
this.locationsMap.fitBounds(polyline.getBounds());
return polyline;
}, // showLocationDirections(polylinePoints) {
в результате я вижу карту с маркерами / полилиниями: https://prnt.sc/t1751f
при нажатии на метод для фильтров маркеры скрываются / отображаются, но полилинии всегда видны с помощью метода:
filterByGroupedCountry(country_key, country_label) {
let self = this
this.layerGroupsMarkersArray.forEach(nextLayerMarkerGroup => { // draw all layerGroupsMarkersArray
if (nextLayerMarkerGroup.country === country_key) {
let layersObj = nextLayerMarkerGroup.layersObj
if (self.locationsMap.hasLayer(layersObj)) {
self.locationsMap.removeLayer(layersObj);
} else {
self.locationsMap.addLayer(layersObj);
}
return
}
}) // this.layerGroupsMarkersArray.forEach(nextLayerMarkerGroup => { // draw all layerGroupsMarkersArray
Это неправильный способ pu sh чтобы маркеры размещали все полилинии, как я писал выше:
...
polylinesList.map((nextPolyline) => {
markersList.push(nextPolyline);
});
let newMarkersLayerGroup = this.leaflet.layerGroup(markersList).addTo(this.locationsMap);
...
Какой путь правильный?
БЛОК №2:
Я переделал , и он работает нормально, если у меня есть только 1 группа данных. Но это работает неправильно, если у меня больше 1 группы. Скажем, если у меня есть 2 группы стран с набором местоположений для любых стран на открытой странице (после запуска drawGroupedAdLocationsMarkers), я вижу маркеры с полилиниями, показанными нормально. Когда я нажимаю, чтобы скрыть 1-ю группу страны (метод filterByGroupedCountry), скрываются только маркеры, но полилинии и декораторы все еще видны. Когда я нажимаю, чтобы скрыть вторую (последнюю) группу стран, все маркеры полилинии и декораторы скрываются. Я полагаю, что это был неправильный способ создания LayerGroup с одним массивом
let newMarkersLayerGroup = this.leaflet.layerGroup(markersList);
, если я добавил в markersList все полилинии и декораторы, но какой способ является допустимым?
drawGroupedAdLocationsMarkers() {
let polylinePoints = [] // I get all info about all Polylines
let loop_index = 0
this.groupedCountriesList= []
this.groupedAdLocations.forEach(nextGroupedAdLocations => { // draw all groupedAdLocations
this.groupedCountriesList[this.groupedCountriesList.length] = { // keep list of countries for filtering countries list
key: nextGroupedAdLocations.country,
label: this.countriesList[nextGroupedAdLocations.country],
}
let markersList = []
let polylinesList = []
let decoratorsList = [] // init markers, polylines, decorators Lists withing one country group
nextGroupedAdLocations.adLocations.forEach(nextAdLocation => { // draw all adLocations inside of one country group
let priorPoint = null // eslint-disable-line
let priorMarker = null // eslint-disable-line
if (loop_index > 0) {
priorPoint = this.groupedAdLocations[loop_index - 1]
priorMarker= nextMarker
}
polylinePoints[polylinePoints.length] = [nextAdLocation.lat, nextAdLocation.lng]
// add new marker and add it to markersList
let nextMarker= this.showLocationMarker(nextAdLocation, nextGroupedAdLocations.country)
markersList[markersList.length] = nextMarker
let radius = 10; // Add new polyline based on point of nextAdLocation
let polyline = new this.leaflet.Polyline(polylinePoints, {
color: 'green',
opacity: 1,
weight: 2,
customData: {
add_location_id: nextAdLocation.id,
type:'polyline',
country:nextGroupedAdLocations.country
},
offset: radius
});
polyline.on('click', function (event) {
event.stopPropagation();
window.event.cancelBubble = true;
});
// polyline.addTo(this.locationsMap);
// add new decorator for polyline created above
let decorator = this.leaflet.polylineDecorator(polyline, { // eslint-disable-line
patterns: [
// defines a pattern of 10px-wide dashes, repeated every 20px on the line
{
offset: 0,
repeat: 50,
symbol: this.leaflet.Symbol.arrowHead({
pixelSize: 10,
polygon: false,
pathOptions: {stroke: true},
customData: {
add_location_id: nextAdLocation.id,
type:'polyline',
country:nextGroupedAdLocations.country
},
})
}
]
})
// decorator.addTo(this.locationsMap)
this.locationsMap.fitBounds(polyline.getBounds());
// add created polyline to polylinesList
polylinesList[polylinesList.length] = polyline
// add created decorator to decoratorsList
decoratorsList[decoratorsList.length] = decorator
loop_index++
}) // nextGroupedAdLocations.adLocations.forEach(nextAdLocation => { // draw all adLocations inside of one country group
polylinesList.map((nextPolyline) => {
markersList.push(nextPolyline);
});
decoratorsList.map((nextDecorator) => {
markersList.push(nextDecorator);
});
// create layer Group with polylinesList, markersList and decoratorsList
let newMarkersLayerGroup = this.leaflet.layerGroup(markersList);
this.locationsMap.addLayer(newMarkersLayerGroup);
this.layerGroupsMarkersArray[this.layerGroupsMarkersArray.length] = {
country: nextGroupedAdLocations.country,
layersObj: newMarkersLayerGroup
}
}) // this.groupedAdLocations.forEach(nextGroupedAdLocations => { // draw all groupedAdLocations
}, // drawGroupedAdLocationsMarkers() {
showLocationMarker(nextAdLocation, country) {
let icon_size = 32
if (nextAdLocation.featured) {
icon_size = 48
}
var markerIcon = this.leaflet.icon({
iconUrl: (!nextAdLocation.featured ? '/images/location.png' : '/images/location_featured.png'),
iconSize: [icon_size, icon_size], // size of the icon
// shadowSize: [50, 64], // size of the shadow
iconAnchor: [icon_size, icon_size], // point of the icon which will correspond to marker's location
// shadowAnchor: [4, 62], // the same for the shadow
popupAnchor: [0, 0] // point from which the popup should open relative to the iconAnchor
});
let nextMarker = this.leaflet.marker(
[nextAdLocation.lat, nextAdLocation.lng],
{
icon: markerIcon,
customData:{
add_location_id: nextAdLocation.id,
type:'marker',
country:country
}
})
.addTo(this.locationsMap)
.bindPopup(nextAdLocation.content)
.on('mouseover', this.locationMarkerOnMouseOver)
.on('click', this.locationMarkerOnClick)
.on('popupopen', this.locationMarkerOnPopupOpen)
if (nextAdLocation.featured) {
nextMarker.bindTooltip("Featured Location").openTooltip();
}
let self = this
this.locationsMap.on('zoomend', function (/*e*/) {
self.current_zoom = self.locationsMap.getZoom()
});
if (nextAdLocation.opened) {
nextMarker.openPopup()
}
return nextMarker
}, // showLocationMarker(nextAdLocation) {
filterByGroupedCountry(country_key, country_label) {
let self = this
this.layerGroupsMarkersArray.forEach(nextLayerMarkerGroup => { // draw all layerGroupsMarkersArray
if (nextLayerMarkerGroup.country === country_key) {
console.log('FOUND country_key::')
console.log(country_key)
let layersObj = nextLayerMarkerGroup.layersObj
console.log(0)
if (self.locationsMap.hasLayer(layersObj)) {
console.log(-1)
self.locationsMap.removeLayer(layersObj);
} else {
console.log(-2)
self.locationsMap.addLayer(layersObj);
}
return
}
}) // this.layerGroupsMarkersArray.forEach(nextLayerMarkerGroup => { // draw all layerGroupsMarkersArray
}
БЛОК №3: Я сделал онлайн-демонстрацию. Откройте http://ads.my-demo-apps.tk/login Учетные данные уже введены. Просто нажмите «Войти». После этого перенаправьте на http://ads.my-demo-apps.tk/test2. Вы должны увидеть карту с некоторыми точками / полилиниями и списком 4 стран ниже. Попробуйте щелкнуть страны по одной. Вы увидите, как относительные маркеры скрыты (или отображаются снова, если снова щелкнуть ссылку стран): https://prnt.sc/t8dsxb Но полилинии не скрыты, как я ожидал
Щелкните все страны - затем все скрыты. Я дал описание кода в БЛОКЕ №2:
Спасибо!