Leaflet JS - нарисуйте прямоугольник и отфильтруйте круговые маркеры в прямоугольнике и обновите HTML-таблицу только с этими маркерами.

У меня есть карта-буклет, на которой есть круговые маркеры, нанесенные по долготе и широте с использованием массива маркеров, поступающего из AJAX REQUEST. Все работает нормально. Я пытаюсь поработать над рисованием прямоугольника вокруг набора маркеров, уже находящихся на карте, это должно отфильтровать маркеры круга на карте листовки и таблице HTML на странице.

Ниже показано, как я добавляю маркер круга на карту:

var cMarkers = [];
for (var i = 0; i < markers.length; ++i) {

    var marker =  L.circleMarker([markers[i].lat, markers[i].lng], { radius: 2, color: getColor(markers[i].type) })
        .bindPopup('<a href="' + markers[i].url + '" target="_blank">' + markers[i].number+ '</a>')
        .addTo(map);
    cMarkers.push(marker);
}

Ниже приведен код, в котором я должен нарисовать прямоугольник вокруг набора маркеров, но в настоящее время он ничего не делает, кроме тех случаев, когда я нахожу курсор на прямоугольник, он предупреждает меня о длине и широте прямоугольника. Прямоугольник остается на карте и не фильтрует и не делает ничего, кроме рисования прямоугольника.

 // Initialise the FeatureGroup to store editable layers
var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);

var drawPluginOptions = {
    position: 'topright',
    draw: {
        // disable toolbar item by setting it to false
        polyline: false,
        circle: false, // Turns off this drawing tool
        polygon: false,
        rectangle: true,
        marker: false,
    },
    edit: {
        featureGroup: editableLayers, //REQUIRED!!
        remove: true
    }
};

// Initialise the draw control and pass it the FeatureGroup of editable layers
var drawControl = new L.Control.Draw(drawPluginOptions);
map.addControl(drawControl);

var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);

map.on('draw:created', function (e) {
    var type = e.layerType,
        layer = e.layer;

    if (type === 'rectangle') {
        layer.on('mouseover', function () {
            alert(layer.getLatLngs());
        });
    }

    editableLayers.addLayer(layer);
});

Фрагмент jquery, который я использую для создания таблицы HTML, основан на массиве маркеров:

var html = '<table id="tabledt">';
html += '<thead>';
html += '<tr>';
var flag = 0;
$.each(markers[0], function (index, value) {
    html += '<th>' + index + '</th>';
});
html += '</tr>';
html += '</thead>';
html += '<tbody>';
$.each(markers, function (index, value) {
    html += '<tr data-id="' + index + '">';
    $.each(value, function (index2, value2) {
        html += '<td>' + value2 + '</td>';
    });
    html += '</tr>';
});
html += '</tbody>';
html += '</table>';
$('#dvTable').html(html);

$('#tabledt th:nth-child(1),#tabledt td:nth-child(1)').remove();

В настоящее время страница загружается со всеми маркерами на карте, а в таблице есть данные. Затем я хочу нарисовать прямоугольник и этот фильтр для этих маркеров и обновить таблицу html. Как я могу получить только маркеры в нарисованном прямоугольнике и отфильтровать их на карте листовок и в таблице html на странице?


person roa765    schedule 05.11.2020    source источник


Ответы (2)


С помощью этой функции вы можете получить метки CircleMarkers, которые находятся под рамками прямоугольника:

map.on('draw:created', function (event) {
    var layer = event.layer;
    
    if(layer && layer instanceof L.Rectangle){
        getCircleMarkers(layer.getBounds());
    }
    
    editableLayers.addLayer(layer);
});

function getCircleMarkers(bounds){
    var layers = [];
    editableLayers.eachLayer((layer)=>{
    if(layer && layer instanceof L.CircleMarkers && !(layer instanceof L.Circle)){ //only circleMarkers, exclude Circles
        if(bounds.contains(layer.getLatLng())){
        layers.push(layer)
      }
    }
  });
  return layers;
}

В этом примере вы должны использовать круги: https://jsfiddle.net/falkedesign/qpL90vh6/

person Falke Design    schedule 05.11.2020
comment
Взглянем на пример JS Fiddle. Я нарисовал прямоугольник и круг (пробовал оба) над маркером, и консоль вернулась в виде пустого массива []. Не можете увидеть, как работает скрипка, если я не делаю что-то неправильно? - person roa765; 05.11.2020
comment
Да, вам нужно рисовать круги вместо круговых маркеров, а затем вы можете получить слои (круги) с прямоугольником - person Falke Design; 05.11.2020
comment
В моем коде круговые маркеры уже нанесены на карту. Затем я хочу нарисовать прямоугольники над маркерами круга. Извините, я не совсем понимаю, зачем рисовать круги? Вышеупомянутая функция использует L.circlemarker, поэтому не может ли он найти круговой маркер уже на карте? - person RA19; 05.11.2020
comment
Uncaught TypeError: правая часть instanceof не является объектом. У меня не работает функция. Я получаю указанную выше ошибку. - person roa765; 06.11.2020
comment
@ roa765 Я не могу воспроизвести это, но, может быть, это помогает при первой проверке, действителен ли слой тоже if(layer && layer instanceof L.Rectangle) - person Falke Design; 06.11.2020
comment
leaflet.js: 5 Uncaught TypeError: Невозможно прочитать свойство addEventParent of undefined Это когда я пытаюсь нарисовать прямоугольник, я получаю следующую ошибку - person roa765; 06.11.2020

Приведенный ниже код сработал, чтобы распечатать мне список объектов в прямоугольнике. Просто нужно выяснить, как отфильтровать их на карте:

     new L.Control.Draw({
            draw: {
                marker: false,
                polygon: false,
                polyline: false,
                rectangle: true,
                circle: false
            },
            edit: false
        }).addTo(map);
    
        L.Rectangle.include({
            contains: function (markers) {
                var markersContained = markers.filter(marker => { return this.getBounds().contains(marker.getLatLng()) === true; })
        
                return markersContained;
            }
        });

   map.on(L.Draw.Event.CREATED, function (geometry) {
        // Set an array containing all the markers
        var markers = jsonToArray(layerGroup._layers);
        var result = geometry.layer.contains(markers);
        console.log('result => ', result);
    });
person roa765    schedule 06.11.2020