当用户尝试根据开放图层 6 中的属性进行修改时,如何使特定多边形不被修改?

问题描述

当我呈现我的 geojson 时。我希望用户不能修改具有属性区域键名称 - Serviceable 的多边形。特征数组中的其他对象用户可以在地图上修改 具有区域键值的特征对象可服务。请在这里帮助我。

html 文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <Meta charset="UTF-8">
    <title>Draw Features</title>
    <!-- Pointer events polyfill for old browsers,see https://caniuse.com/#feat=pointer -->
    <script src="https://unpkg.com/elm-pep"></script>
    <!-- The line below is only needed for old environments like internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL,TextDecoder,Number.isInteger"></script>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.bundle.min.js"></script>
   <style>
      .map {
        width: 100%;
        height:400px;
      }
      .ol-popup {
        position: absolute;
        background-color: white;
        Box-shadow: 0 1px 4px rgba(0,0.2);
        padding: 15px;
        border-radius: 10px;
        border: 1px solid #cccccc;
        bottom: 12px;
        left: -50px;
        min-width: 280px;
      }
      .ol-popup:after,.ol-popup:before {
        top: 100%;
        border: solid transparent;
        content: " ";
        height: 0;
        width: 0;
        position: absolute;
        pointer-events: none;
      }
      .ol-popup:after {
        border-top-color: white;
        border-width: 10px;
        left: 48px;
        margin-left: -10px;
      }
      .ol-popup:before {
        border-top-color: #cccccc;
        border-width: 11px;
        left: 48px;
        margin-left: -11px;
      }
      .ol-popup-closer {
        text-decoration: none;
        position: absolute;
        top: 2px;
        right: 8px;
      }
      .ol-popup-closer:after {
        content: "✖";
      }
      .hideForm{
          display: none;
      }
      .hideHover{
          display: none;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
    <form class="form-inline">
        <label for="type">Select type to create: &nbsp;</label>
        <select class="form-control mr-2 mb-2 mt-2" id="type">
            <option value="">Please Select</option>
          <option value="Point">Point</option>
          <option value="Linestring">Linestring</option>
          <option value="polygon"> Create polygon</option>
          <option value="Circle">Circle</option>
          <option value="None">None</option>
        </select>
        <!-- <input class="form-control mr-2 mb-2 mt-2" type="button" value="undo" id="undo"> -->
      </form>
    <div id="popup" class="ol-popup hideForm"  >
        
      <a href="#" id="popup-closer" class="ol-popup-closer"></a>
      <div id="popup-content" >
        <form class="form-inline">
            <label for="type">Please Select: &nbsp;</label>
            <select class="form-control mr-2 mb-2 mt-2" id="selectType">
                <option value="">Please Select</option>
              <option value="Serviceable">Serviceable Area</option>
              <option value="cluster">Cluster</option>
              <option value="Society"> Society</option>
            </select>
            <input class="form-control mr-2 mb-2 mt-2" type="button" onclick="submitData($event)" value="submit" id="submitForm">
          </form>
      </div>

    </div>
    <div id="hoverPopup" class="ol-popup hideHover"  >
        <a href="#" id="popup-closer-hover" class="ol-popup-closer"></a>
        <div id="popup-content-hover">
        </div>
  
      </div>

<button  id="download">Download</button>
   
    <script src="main.js"></script>
  </body>
</html>


这是我的 js 文件。我是打开层的新手。 在将数据传递给修改对象或任何其他可以帮助这里的方法之前,有什么方法可以过滤数据

 import 'ol/ol.css';
import Circle from 'ol/geom/Circle';
import Feature from 'ol/Feature';
import GeoJSON from 'ol/format/GeoJSON';
import Map from 'ol/Map';
import View from 'ol/View';
import Point from 'ol/geom/Point';
import {Circle as CircleStyle,Fill,stroke,Style,Icon} from 'ol/style';
import {OSM,Vector as VectorSource} from 'ol/source';
import {Tile as TileLayer,Vector as VectorLayer} from 'ol/layer';
import {Draw,Modify,Select,Snap} from 'ol/interaction';
import {fromLonLat} from 'ol/proj';
import Overlay from 'ol/Overlay';

const iconFeature = new Feature({
    geometry: new Point([0,0]),name: 'Null Island',population: 4000,rainfall: 500,});
  
  const iconStyle = new Style({
    image: new Icon({
      anchor: [0.5,46],anchorXUnits: 'fraction',anchorYUnits: 'pixels',src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',}),});
  
  iconFeature.setStyle(iconStyle);
let showHover = true;
  const styles = {
  'polygon': new Style({
    stroke: new stroke({
      color: 'blue',width: 3,fill: new Fill({
      color: 'rgba(0,255,0.1)',})
  }),'Serviceable': new Style({
    stroke: new stroke({
      color: 'grey','cluster': new Style({
    stroke: new stroke({
      color: 'green','society': new Style({
    stroke: new stroke({
      color: 'yellow',})
      
  }),geometry: function(feature) {
    let geometry = feature.getGeometry();
    let geometryType = geometry.getType();
    return (
        geometryType == 'polygon' ? geometry.getInteriorPoint() :
        geometryType == 'Multipolygon' ? geometry.getInteriorPoints() :
        geometry
    );
  },image: new Icon({
    anchor: [0.5,anchorXUnits: "fraction",anchorYUnits: "pixels",};

const styleFunction = function (feature) { 
   
  const featureStyle =feature.values_.region?feature.values_.region:feature.getGeometry().getType();
  return styles[featureStyle];
};

const geojsonObject = {
    'type': 'FeatureCollection','crs': {
      'type': 'name','properties': {
        'name': 'epsg:3857',},'features': [
      {
          'type': 'Feature','properties':{
              'region':'Serviceable','name':'serviceable 1'
          },'geometry': {
            'type': 'polygon','coordinates': [
              [
                fromLonLat([ 77.15760062500001,30.890967638580772]),fromLonLat([ 77.2941240625,29.57600861486909]),fromLonLat([ 76.95873343750002,28.428848818170273]),fromLonLat([ 75.9202178125,28.434726060930952]),fromLonLat([ 75.5131084375,28.909133164756486]),fromLonLat([ 74.70792777343749,29.39857793541408]),fromLonLat([ 74.78873587890624,29.871326311523653]),fromLonLat([ 75.48477835937497,29.65680741133687]),fromLonLat([ 76.15957328125,29.79063051517841]),],{
          'type': 'Feature','properties':{
              'region':'cluster','name':'jhajjar'
          },'coordinates': [
              [
                fromLonLat([ 76.68930838867189,28.636901895884023]),fromLonLat([ 76.69674247070313,28.57745043657983]),fromLonLat([ 76.5677959375,28.5792192324589]),fromLonLat([ 76.58323355957032,28.637598392669847]),fromLonLat([ 76.68930838867189,'name':'cluster 3'
          },'coordinates': [
              [
                fromLonLat([ 75.92163871093751,29.542932708619503]),fromLonLat([ 76.2352342919922,29.539852918027435]),fromLonLat([ 76.38952811523438,29.244818184007894]),fromLonLat([ 76.03893607421875,28.974670297760245]),fromLonLat([ 75.5955058984375,29.235604663759762]),fromLonLat([ 75.92163871093751,'properties':{
              'region':'society','name':'vatika city'
          },'coordinates': [
              [
                fromLonLat([ 75.91751883789064,29.38271030601346]),fromLonLat([ 75.96332267089845,29.399966998733607]),fromLonLat([ 76.01049979492188,29.35020995663461]),fromLonLat([ 75.8823808984375,29.30093429893928]),fromLonLat([ 75.84544486328124,29.35896121182201]),fromLonLat([ 75.91751883789064,'name':'orchid petals'
          },'coordinates': [
              [
                fromLonLat([ 76.1626512841797,29.33662949113684]),fromLonLat([ 76.20845511718751,29.353893995208363]),fromLonLat([ 76.1979540185547,29.305311991234767]),fromLonLat([ 76.19205802246094,29.279375332655874]),fromLonLat([ 76.12696952148437,29.324843490064747]),fromLonLat([ 76.1626512841797,29.33662949113684])            ],'name':'Vatika City'
          },'coordinates': [
              [
                fromLonLat([ 77.14661429687501,28.326682984225194]),fromLonLat([ 77.1348223046875,28.190829441589432]),fromLonLat([ 76.9578105859375,28.19502541100354]),fromLonLat([ 77.0000273828125,28.34067794211981]),fromLonLat([ 77.14661429687501,}
      
    ],};

const vectorSource = new VectorSource({
  features: new GeoJSON().readFeatures(geojsonObject),});
function vectorSourceData(feature){
console.log(feature,'feature data');
}
//vectorSource.addFeature(new Feature(new Circle([5e6,7e6],1e6)));
console.log(vectorSource,'source data');

const vectorLayer = new VectorLayer({
  source: vectorSource,style: styleFunction,});

const container = document.getElementById('popup');
const content = document.getElementById('popup-content');
const closer = document.getElementById('popup-closer');
const hoverCloser = document.getElementById('popup-closer-hover');

const overlay = new Overlay({
   element: container,autopan: true,autopanAnimation: {
     duration: 250,});

//  var overlay = new ol.Overlay({
//     element: document.getElementById('info'),//     positioning: 'bottom-left'
//   });
//   overlay.setMap(map);
 
const gurgaonLatLong = [77.019135,28.481216];
const gurgaonLatitudeLongnitude = fromLonLat(gurgaonLatLong);
const map = new Map({
  layers: [
    new TileLayer({
      source: new OSM(),vectorLayer,target: 'map',overlays: [overlay],view: new View({
    center: gurgaonLatitudeLongnitude,zoom: 6,});
**This line makes the features modify**
const modify = new Modify({source: vectorSource});

map.addInteraction(modify);

let draw,snap; // global so we can remove them later
const typeSelect = document.getElementById('type');

function addInteractions() {
    console.log(typeSelect.value,'value called ');

    if(typeSelect.value === ''){
        showHover= true;
    
    } else if (typeSelect !== 'None') {
  draw = new Draw({
    source: vectorSource,type: typeSelect.value,});
  map.addInteraction(draw);
  snap = new Snap({source: vectorSource});
  map.addInteraction(snap);
  showHover= false;
}

}

/**
 * Handle change event.
 */
typeSelect.onchange = function () {
  //  popUpData.style.display = 'none';
    container.style.display = 'none';
  map.removeInteraction(draw);
  map.removeInteraction(snap);
  addInteractions();
};
var coord;
var featureData;
map.on('click',function (evt) {
    coord=evt
     const coordinate = evt.coordinate;
    featureData = map.forEachFeatureAtPixel(evt.pixel,function(feature,layer) {
    if(layer){
        popUpData.style.display = 'none';
        container.style.display = 'block';
        overlay.setPosition(coordinate);
    }
 return feature
  });
  });
  const popUpData = document.getElementById('hoverPopup');
  const popUpDataContent = document.getElementById('popup-content-hover');

  map.on('pointermove',function (evt) {
if(showHover) {
    featureData = map.forEachFeatureAtPixel(evt.pixel,layer) {
        console.log(layer,'layered data fetcehd');
    if(layer){

        popUpData.style.display = 'block';
        const overlay = new Overlay({
            element: popUpData,autopanAnimation: {
              duration: 250,});
          popUpDataContent.innerHTML = `${evt.coordinate}`

        overlay.setPosition(evt.coordinate);     
     map.addOverlay(overlay);
    } else{
        popUpData.style.display = 'none';
    } 
 return feature
  });
} 
  });

addInteractions();

const formSelect = document.getElementById('submitForm');

formSelect.onclick  = function(ev){
  const selectValue =  document.getElementById('selectType').value;

     var coordinate = coord.coordinate;
  //   var hdms = ol.coordinate.toStringHDMS (ol.proj.transform (coordinate,'epsg: 31700','epsg: 3857'));

if(selectValue) {
      var selected_polygon_style = 
        new Style({
            stroke: new stroke({
              color: selectValue === 'Serviceable'?'grey':selectValue === 'cluster'?'green':'yellow',fill: new Fill({
              color: 'rgba(0,// image: new Icon({
            //     color:'#8959AB',//     crossOrigin:'anonymous',//      src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',//      imgSize:[20,20]
            //    }),})
     // add more styling key / value pairs as your need
    
     featureData.setStyle(selected_polygon_style);
     vectorSource.addFeatures(featureData);
     selectValue.value='';
     showHover=true;
     closeWindow();
        }
}

/**
   * Handle change event.
   */

//   document.getElementById('undo').addEventListener('click',function () {
//     draw.removeLastPoint();
//   });

/**
 * Popup
 **/
 closer.onclick =  closeWindow;

  function closeWindow() {
    overlay.setPosition(undefined);
    closer.blur();
    return false;
  };

  hoverCloser.onclick = function(){
    popUpData.style.display = 'none';
    overlay.setPosition(undefined);
    hoverCloser.blur();
    return false;
  }
 

解决方法

您可以使用特征集合而不是源来进行修改交互。将允许修改的特征添加到集合中:

const features = new Collection();
vectorSource.forEachFeature(function(feature) {
  if (feature.get('name') != 'Serviceable') {
    features.push(feature);
  }
});
const modify = new Modify({features: features});
,

我得到了答案。通过过滤处理。

const modifiedSource = new VectorSource();

modifiedSource.clear();

const modified = vectorSource.getFeatures().filter(feature =>feature.get('region') != 'Serviceable')

modifiedSource.addFeatures(modified);

const modify = new Modify({source: modifiedSource});