2017-02-22 10 views
0

Я имею дело с картой, на которой векторные слои поступают из разных файлов geojson. Каждый файл содержит серию полигонов (type = multipolygon).Как изменить стиль в векторном слое geojson с multipolygons

Каждый полигон характеризуется рядом параметров, таких как «виды». По умолчанию слои устанавливаются невидимыми и имеют определенный стиль (заливка и обводка).

Я создал выбор для того, чтобы поиск по видам

  <form> 
      <select class="species"> 
       <option value="">Choose</option> 
       <option value="Balaenopteraphysalus">Balaenoptera physalus</option> 
       <option value="Physetercatodon">Physeter catodon</option> 
       <option value="Delphinusdelphis">Delphinus delphis</option> 
       <option value="Tursiopstruncatus">Tursiops truncatus</option> 
       <option value="Stenellacoeruleoalba">Stenella coeruleoalba</option> 
       <option value="Grampusgriseus">Grampus griseus</option> 
       <option value="Globicephalamelaena">Globicephala melaena</option> 
       <option value="Ziphiuscavirostris">Ziphius cavirostris</option> 
       <option value="Monachusmonachus">Monachus monachus</option> 
      </select> 
     </form> 
     <button id="clearSpecies">Clear</button> 

Я тогда написал JQuery, который позволяет загружать слои только если выбранные виды присутствует в файле

$(document).ready(function() { 
      $("select.species").change(function() { 

       var selectedSpecies = $(".species option:selected").val(); 

       if (selectedSpecies) { 
        //geojson request 
        $.getJSON('http://localhost:8888/maps/prova/immas_test_separated_js_immas_file/resources/test_imma_2.geojson', function (data) { 
           $.each(data.features, function (key, val) { 
            $.each(val.properties, function(i,j){ //i = proprietà l = valore proprietà 
             if(i == 'Species') { 
             //replace spaces to have one single word 
             j = j.replace(/\s+/g, ''); 
              species = j.split(","); 

              species.forEach(function(animal) { 
              if(animal == selectedSpecies) { 
               //test passed 
               prova1.setVisible(true); 

    //add something to change style (hide the multipolygon not which are not satisfying the condition and show those who satisfy the condition 
              } 
              });         

             } 
            });//loop ends 
           });//loop ends 
        }); 
       //ends geojson request 
       } 
      }); 

      //clears layers 
      $("#clearSpecies").click(function(){ 
       prova1.setVisible(false); 
      }); 
}); 

Everything работает отлично. Однако, поскольку я на самом деле разбираюсь с разными полигонами в одном слое, мне нужен еще один шаг. После установки слоя как видимого в петле выше (prova1.setVisible(true); ), мне нужно изменить стиль не на весь слой, а на отдельные полигоны в соответствии с условием if: те, в которых параметр «вид» не содержит выбранную опцию значение должно изменять заливку и ход до ни одного (прозрачного), в то время как полигоны, для которых вид параметра содержит выбранное значение параметра, должны быть заполнены цветом.

Рассмотрим, что параметр "вид" в файле GeoJSON содержит более одного имени (напр "Вид":. «Monachus Monachus, Balaenoptera physalus, Physeter macrocephalus, Ziphius cavirostris, Globicephala Мелас, Grampus пзеиз, Tursiops truncatus, Stenella coeruleoalba, Delphinus delphis ")

Любое предложение? Благодаря!

=========== UPDATE ===========

Я последовал @pavlos предложение изучил пример сообщил here. Однако я не прошел.

Вот код, который я использовал для стилей и создать function styleFunction(feature, resolution)

//SET STYLES 

//set colours 
var colourSpecies = [64,196,64,1]; 
var colourCriteria = [90,160,64,1]; 

//set levelnames related to colours 
var selectedLevels = { 
    'species': colourSpecies, 
    'criteria': colourCriteria 
} 

//default style 
var defaultStyle = 
    new ol.style.Style({ 
     fill: new ol.style.Fill({ 
     color: [0,0,0,1] 
    }), 
    stroke: new ol.style.Stroke({ 
    color: [0,0,0,1], 
    width: 1 
    }) 
}); 

//custom styleFunction 
var styleCache = {}; 
function styleFunction(feature, resolution) { 
    var level = feature.get('selectedLevel'); 
    if (!level || !selectedLevels[level]) { 
     return [defaultStyle]; 
    } 
    if (!styleCache[level]) { 
     styleCache[level] = 
    new ol.style.Style({ 
     fill: new ol.style.Fill({ 
     color: selectedLevels[level] 
     }), 
     stroke: defaultStyle.stroke 
     }); 
    } 
    return [styleCache[level]]; 
} 

я поэтому пытался переписать JQuery/JavaScript для обработки изменения стиля, когда поиск пользователей для вида. При этом я не использовал функцию forEachFeature, так как мне никогда не удавалось получить какие-либо результаты, но я зациклился внутри объектов через jQuery. Различные циклы обусловлены тем, что параметр «species» содержит строку с разными именами (род + вид), в противном случае я мог бы преодолеть проблему, скопировав именно пример, приведенный в ссылке выше. Как уже говорилось ранее, я хотел бы выделить в разных стилях те полигоны, которые содержат в строке вид, найденный с помощью select (лучше было бы закрепить их и скрыть все остальные, не содержащие искомые виды).

$(document).ready(function() { 

    $("select.species").change(function() { 
     var selectedSpecies = $(".species option:selected").val(); 

      if (selectedSpecies && selectedSpecies !='') { 
       //geojson request 
       $.getJSON('http://localhost:8888/maps/prova/immas_test_separated_js_immas_file/resources/test_imma_2.geojson', function (data) { 
        {$.each(data.features, function (key, val) { 
         console.log(val.properties); 
         $.each(val.properties, function(i,j){ //i = proprietà l = valore proprietà 
          console.log(i); 
          if(i == 'Species') { 
          j = j.replace(/\s+/g, ''); //eliminates spaces between genus and species 
           var species = j.split(","); 
           console.log(species); 
           var species_array_length = species.length; 
           console.log(species_array_length); 

           var counter; 
           for (counter = 0; counter < species_array_length; counter++){ 
            if (selectedSpecies === species[counter]){ 
             var animal = species[counter]; 
              console.log('Found' + animal); 
              var feature = val.properties; 
              console.log(feature); 
              feature.set('selectedLevel', 'species'); 
            } 
            }//termina ciclo for 
          } 
         });//termina loop 
        });//temrina loop} 
       }); 
       //ends geojson request 
       prova1.setVisible(true); 
      } 
    }); 

    //clears layers 
    $("#clearSpecies").click(function(){ 
     prova1.setVisible(false); 
    }); 

}); 

Однако это не работает: отображается сообщение об ошибке с feature.set('selectedLevel', 'species'); и снова все слои загружаются со стилем по умолчанию. Я очень волнуюсь, потому что это простой пример. В конце я должен иметь дело с 18 файлами geojson и двумя выборами (по видам и по «критерийкоде», что является еще одним параметром внутри моего файла geojson).

добавить здесь ссылку на files использования (включая дэ формате GeoJSON, используемый в качестве теста)

+1

Вы должны назначить функцию стиля на вашем векторном слое. Функция принимает функцию и разрешение. поэтому вы сможете разобрать свою функцию в индивидуальном порядке и, таким образом, индивидуально подобрать ее. Вот пример -> http://openlayers.org/en/latest/examples/vector-layer.html?q=style – pavlos

+0

спасибо @pavlos, я собираюсь попробовать. Я новичок в ol3 и надеюсь сделать это! В случае, если я стану сомневаться здесь –

+0

Привет @pavlos, как и ожидалось, я немного застрял. Я обновил свой пост с кодом, который я написал до сих пор. Если у вас есть время, чтобы взглянуть на это, это будет большой помощью! –

ответ

0

Это ==== UPDATE === на вопрос размещен выше.

благодаря некоторым предложениям, предоставленным @pavlos, я преуспел в решении вышеперечисленных проблем.

Полное решение с тестовыми файлами доступно на этом fiddle.

УСТАНОВЛЕНИЕ СТИЛИ к слою

//SET STYLES 
//default style 
var defaultStyle = 
    new ol.style.Style({ 
     fill: new ol.style.Fill({ 
     color: [0,0,0,1] 
    }), 
    stroke: new ol.style.Stroke({ 
    color: [0,0,0,1], 
    width: 1 
    }) 
}); 
var selectStyle = new ol.style.Style({ 
     fill: new ol.style.Fill({ 
     color: [64,196,64,1] 
    }), 
    stroke: new ol.style.Stroke({ 
    color: [64,196,64,1], 
    width: 1 
    }) 
}); 
var transparentStyle = new ol.style.Style({ 
     fill: new ol.style.Fill({ 
     color: [255,255,255, 0] 
    }), 
    stroke: new ol.style.Stroke({ 
    color: [255,255,255, 0], 
    width: 1 
    }) 
}); 


//Gets the layer sources 

var ocean_map = 
    new ol.layer.Tile({ 
     source: new ol.source.XYZ({ 
     url: 'https://services.arcgisonline.com/ArcGIS/rest/services/' + 
      'Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', 

     }), 
     visible: true, 
     }); 

var source = 
    new ol.source.Vector({ 
    format: new ol.format.GeoJSON({ 
    }), 
     dataProjection: 'EPSG:3857', 
    url: 'test.geojson', 
    attributions: [ 
     new ol.Attribution({ 
     html: 'Mediteranean region' 
     }) 
    ] 
    }); 

var prova1 = 

new ol.layer.Vector({ 
    source: source, 
    style: defaultStyle, 
    name: 'Mediteranean region', 
    visible: false, 
}); 

распоряжающихся СТИЛИ

//when clicking the select 
document.getElementById("species_select").addEventListener('click', function() { 
    resetSelectElement(mySelect); 
//first step it loads the vector layer and sets the style to transparent 
    prova1.setStyle(transparentStyle); 
    prova1.setVisible(true); 
//second step when the select changes (i.e. I make a choice) 
    $("#species_select").change(function() { 
//it starts the function to change styles according to the selection made 
     var selectedSpecies = $("#species_select option:selected").text(); 
     console.log('selectedSpecies',selectedSpecies); 
      source.forEachFeature(function(feat){ 
       console.log(feat); 
       console.log(feat.get('Species')) 
       console.log(feat.get('Species').indexOf(selectedSpecies)); 
    //if substring(selected text) exist within fetaure property('Speices) 
    //should return any value other than -1 
       if (feat.get('Species').indexOf(selectedSpecies)!=-1) { 
    //so set the style on each feature 
       feat.setStyle(selectStyle); 

       } else { 
    //and if doesnt exist switch back to the deafult style 
       feat.setStyle(transparentStyle); 
       } 
      }) 

    }); 
}); 
//clears layers 
$("#clearSpecies").click(function(){ 
    prova1.setVisible(false); 
    prova1.setStyle(defaultStyle); 
});