OpenLayers 4 - подходит для степени выбранных функций

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

Я пытаюсь реализовать панель автозаполнения / поиска с использованием Materialise Materialize Framework. (Вот пример скрипта простой панели поиска)

  $(document).ready(function(){
    $('input.autocomplete').autocomplete({
      data: {
        "Apple": null,
        "Microsoft": null,
        "Google": 'https://placehold.it/250x250'
      },
    });
  });

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

map.getView().fit(selectedFeature.getSource().getExtent(), animationOptions);

Или я делаю это совершенно неправильно?

$(document).ready(function() {
function sendItem(val) {
    console.log(val);
}

var animationOptions = {
    duration: 2000,
    easing: ol.easing.easeOut
};

$(function() {
    $.ajax({
        type: 'GET',
        url: 'geojson/jls.geojson',
        dataType: 'json',
        success: function(response) {
            var jls_array = response;
            var features = jls_array.features;
            var jls = {};

            for (var i = 0; i < features.length; i++) {
                var geo = features[i].properties;
                jls[geo['JLS_IME']] = null;
            }
            console.log(jls)
            $('input.autocomplete').autocomplete({
                data: jls,
                limit: 5,
                onAutocomplete: function(txt) {
                    sendItem(txt);
                    map.getView().fit(vectorJLS.getSource().getExtent(), animationOptions);
                }
            });
        }
    });
});
});

А вот пример моего объекта геойсон

{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name":"EPSG:3765" } },
"features": [
{ "type": "Feature", "properties": { "JLS_MB": "00116", "JLS_IME": "BEDEKOVČINA", "JLS_ST": "OP", "JLS_SJ": "Bedekovčina", "ZU_RB": "02", "ZU_IME": "Krapinsko-zagorska", "ZU_SJ": "Krapina", "pov": 51.42 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 461117.98, 5108379.85 ], [ 461124.53, 5108368.39 ], [ 461132.37, 5108354.26 ]...

ОБНОВЛЕНИЕ - РЕШЕНИЕ

Таким образом, как заметил приятель Дьюб с логическим и практическим решением, в котором он находит объект и масштабирует выбранный объект в источнике слоя геойсон с помощью простого метода.find().

Я только немного подправил существующий код с добавленной переменной перед вызовом ajax

var source_layer = vectorJLS.getSource(); // collecting layer source

$(function() {
    $.ajax({
        type: 'GET',
        url: 'geojson/jls.geojson',
        dataType: 'json'.....

onAutocomplete: function(txt) {
  var feature = source_layer.getFeatures().find(function(f) { return f.get('JLS_IME') === txt; });
  if (feature) {
    const extent = feature.getGeometry().getExtent()
    map.getView().fit(extent);
  }
};

Вот слой, который я пытаюсь повторить, и выберите, чтобы увеличить объект

2 ответа

Решение

Сам объект не имеет экстента, но его геометрия имеет один:

const extent = feature.getGeometry().getExtent()
map.getView().fit(extent);

Однако до сих пор у вас, похоже, нет объектов-объектов OpenLayers, просто простой объект json, который вы получили в ответе ajax. Давайте преобразуем это:

var source = new ol.source.Vector({
features: (new ol.format.GeoJSON({
  featureProjection: "EPSG:3765" // probably not required in your case
})).readFeatures(featureCollection);

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

onAutocomplete: function(txt) {
  var feature = source.getFeatures().find(function(f) { return f.get('JLS_IME') === txt; });
  if (feature) {
    const extent = feature.getGeometry().getExtent()
    map.getView().fit(extent);
  }
};

Я не уверен, как должно работать ваше картографическое приложение, но я думаю, что вы должны использовать Select-Interaction, если вы хотите обрабатывать выбранные объекты ('ol/ взаимодействия /select'), потому что вы можете использовать все события, запущенные и установить индивидуальный стиль для вашего выбора. Содержимое Select Interaction представляет собой коллекцию ol.Collection, которая содержит выбранные вами функции. Поэтому, помимо вашего Vectorlayer, вы также должны реализовать Select-Interaction:

const selectedItems = new ol.interaction.Select({
        layers: [yourbasicvectorlayer],
        style: new ol.style.Style({...})
    });
//Listen if any new items are pushed into the selection
selectedItems.getFeatures().on('add', function(feature) {
    //for one feature:
    map.getView().fit(feature.getGeometry().getExtent(), AnimationOptions);
    //for multiple features --> so everytime a new is added
    //Create an empty extent like:
    let extent = new ol.extent.createEmpty();
    selectedItems.getFeatures().forEach(feature) {
        //add extent of every feature to the extent
        extent = new ol.extent.extend(extent, feature.getGeometry().getExtent(); 
    }
    map.getView().fit(extent, animationOptions);
})
// Dont forget to add the Select Interaction to the map
map.addInteraction(selectedItems).
//you can fill the selection interaction programmatically
selectedItems.getFeatures().push(yourfeature);

Не проверял код. С Select-Interaction это больше накладных расходов, но лучше структурировано. Вы также можете просто использовать часть в слушателе для подхода с несколькими функциями. Дайте мне знать, если я полностью недопонимаю:-)

Другие вопросы по тегам