Брошюра - Как выбрать объект за пределами карты

Имея два элемента div: представление карты и боковую панель, где каждая строка соответствует имени объекта, как я могу гарантировать, что событие щелчка в строке боковой панели выберет соответствующий объект на карте?

Это выполнимо с всплывающими окнами, но я хочу выбрать функцию, а не создавать маркер или всплывающее окно. Используя Angular и angular-leaflet-directive, у меня есть такое представление:

<div class="preview-wrapper container-fluid">
    <div class="row">
        <div class="col-md-8">
            <leaflet id="map-preview" geojson="geojson" center="nyc"></leaflet>
        </div>
        <div class="col-md-4">
            <div class="toolbox panel panel-default">
                <div class="panel-heading">
                    <div class="panel-title text-center">Toolbox</div>
                </div>
                <div class="panel-body">
                    <div class="row" ng-repeat="segment in trails" ng-click="toolboxTrailSelect(segment)">{{ segment.properties.name }}</div>
                </div>
            </div>
        </div>
    </div>
</div>

Как видите, ng-repeat просто выводит имя функции, определенное в контроллере:

angular.module('dataUpload')
.controller('MapPreviewCtrl', function($scope, $log, $window, leafletData, fileReader) {
    "use strict";


    $scope.toolboxTrailSelect = function(obj) {
        $log.debug(obj);
        var latLng = new L.LatLng(obj.geometry.coordinates[0][0], obj.geometry.coordinates[0][1]);

        leafletData.getMap('map-preview').then(function(map) {
            map.fireEvent('click', {
                latlng : latLng,
                containerPoint : map.latLngToContainerPoint(latLng),
                layerPoint : map.latLngToLayerPoint(latLng)
            });
        });
    };

    leafletData.getMap('map-preview').then(function(map) {
        mapContainer = map;
        var kml = fileReader.getLocalFile();

        if (kml === null)
            $log.error("No file loaded");
        else {
            var data = getData();

            try {
                map.fitBounds(data.latlng);

                angular.extend($scope, {
                    geojson : {
                        data : data.geojson,
                        style : {
                            stroke : true,
                            weight : 5,
                            color : '#000000'
                        },
                        onEachFeature : function(feature, layer) {
                            layer.on('click', function(e) {
                                    $log.debug('Path click event: ' + e);
                                }
                            );
                        }
                    }
                });

            } catch (e) {
                $log.error(e.message);
                $window.alert(e.message);
            }
        }
    });
});

Когда создается экземпляр контроллера, он добавляет геометрию и свойства всех функций в область действия, которая затем повторяется в директиве ng-repeat.

Прямо сейчас для каждой функции определен обработчик кликов, который выводит отладочное сообщение. Каждая строка на боковой панели имеет событие клика, которое обрабатывается toolboxTrailSelect.

Это делается для того, чтобы событие щелчка на боковой панели получало первую пару координат широта/долгота и запускало событие щелчка на основе этой пары координат. Это событие должно обрабатываться событием щелчка объекта карты.

Я получаю отладочное сообщение из события щелчка функции и из события щелчка боковой панели. Но я не получаю сообщение об отладке обработчика щелчка функции, когда происходит щелчок на боковой панели.


person Jason    schedule 18.01.2016    source источник


Ответы (1)


Похоже, я был на правильном пути, но упустил несколько ключевых моментов. Запись ответа здесь на случай, если кто-то еще столкнется с такой же ситуацией.

Во-первых, включите в свой проект object-hash. Поскольку GeoJSON не всегда содержит идентификатор, это позволяет использовать хеш-значение на основе объекта, который вы отображаете.

Поскольку мне нужно сопоставить границы карты с путями, я создаю массив точек LatLng, которые будут использоваться map.fitBounds(). В результате я могу использовать хэш и значение функции в объекте области видимости.

<div class="row" ng-repeat="segment in trails" 
     ng-click="toolboxTrailSelect(segment)">{{ segment.properties.name }}</div>

    $scope.toolboxTrailSelect = function(obj) {
        var hash = objectHash.sha1(obj);
        leafletData.getMap('map-preview').then(function(map) {
            map._layers[hash].fire('click');
        });
    };

Объект карты листовки содержит внутреннее значение _layers, которое представляет собой сопоставление ID с объектами. При повторении набора функций в

           onEachFeature : function(feature, layer) {
               layer._leaflet_id = objectHash.sha1(feature);
               layer.on('click', function(e) {
                   $log.debug('Path click event: ' + e);
               });
           }

Я могу добавить свой собственный идентификатор к значению _leaflet_id, которое затем сохраняется внутри map._layers.

Теперь, поскольку каждая функция представляет собой отдельный слой, все, что мне нужно сделать, это хешировать входящий объект из события щелчка, получить соответствующий слой с карты и запустить для него событие щелчка.

person Jason    schedule 18.01.2016