如何使用多面体更改geojson矢量图层的样式

问题描述:

我正在处理的矢量图层来自不同的geojson文件。每个文件都包含一系列多边形(type = multipolygon)。如何使用多面体更改geojson矢量图层的样式

每个多边形的特点是一系列的参数,如“物种”。默认情况下,图层设置为不可见,并具有特定的样式(填充和描边)。

我创建了一个选择,使按品种搜索

  <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); 
      }); 
}); 

一切都在工作正常。但是,因为我实际上处理同一图层中的不同多边形,所以我需要更进一步。 将图层设置为在上面的循环中可视(prova1.setVisible(true); )之后,我需要将样式更改为整个图层,但根据if条件将样式更改为单个多边形:参数“species”不包含所选选项的样式值必须将填充和描边更改为无(透明),而参数物种包含所选选项值的多边形必须填充颜色。

考虑到以GeoJSON文件中的参数“种”包含不止一个名称(如“种”:“Monachus monachus,鲸physalus,Physeter鲷,Ziphius cavirostris,Globicephala MELAS,鲸灰色链霉菌,宽吻海豚,原海豚(Delerus 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在对象内部循环。因为“物种”参数包含一个带有不同名称(属+物种)的字符串,否则我可以通过复制上面链接中给出的示例来克服这个问题。如前所述,我想用不同的样式强调那些包含在字符串中的多边形,这些多边形用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文件和两个选择(按物种和“criteriacode”,这是我的geojson文件中的另一个参数)。

我在这里添加到所使用的files的链接(包括用作测试TEH以GeoJSON)

+1

您需要在矢量图层上指定样式的功能。该功能接受功能和解决方案。所以你将能够独立地分析它的功能,并且单独设计它的样式。这里是一个例子 - > http://openlayers.org/en/latest/examples/vector-layer.html?q=style – pavlos

+0

谢谢@pavlos,我会尝试它。我是ol3的初学者,希望能成功!如果我打算在这里张贴我的怀疑 –

+0

嗨@pavlos,如预期的那样,我有点卡住了。我用我之前写的代码更新了我的帖子。如果你有时间看一看,这将非常有帮助! –

这一个==== 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); 
});