-1

when i render my geojson. i want user should not able to modified the polygon having property region key name- Serviceable. Other objects in the feature array user can modify on the map expect the feature object having region key value Serviciable.Please help me here.

html file

<!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,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>


This is my js file .i am new to open layer. Is there any way through which i can filter the data before passing it to the modify object or any other approach that can help here

 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, 0, 255, 0.1)',
    })
  }),
  'Serviceable': new Style({
    stroke: new Stroke({
      color: 'grey',
      width: 3,
    }),
    fill: new Fill({
      color: 'rgba(0, 0, 255, 0.1)',
    }),
  }),
  'cluster': new Style({
    stroke: new Stroke({
      color: 'green',
      width: 3,
    }),
    fill: new Fill({
      color: 'rgba(0, 0, 255, 0.1)',
    }),
  }),
  'society': new Style({
    stroke: new Stroke({
      color: 'yellow',
      width: 3,
    }),
    fill: new Fill({
      color: 'rgba(0, 0, 255, 0.1)',
    })
      
  }),
  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, 46],
    anchorXUnits: "fraction",
    anchorYUnits: "pixels",
    src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',
  }),
};

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'
          },
          'geometry': {
            'type': 'Polygon',
            'coordinates': [
              [
                fromLonLat([ 76.68930838867189,28.636901895884023]),
                fromLonLat([ 76.69674247070313,28.57745043657983]),
                fromLonLat([ 76.5677959375,28.5792192324589]),
               fromLonLat([ 76.58323355957032,28.637598392669847]),
               fromLonLat([ 76.68930838867189,28.636901895884023]),
              ],
            ],
          },
        },
        {
          'type': 'Feature',
          'properties':{
              'region':'cluster',
              'name':'cluster 3'
          },
          'geometry': {
            'type': 'Polygon',
            '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,29.542932708619503]),
              ],
            ],
          },
        },
        {
          'type': 'Feature',
          'properties':{
              'region':'society',
              'name':'vatika city'
          },
          'geometry': {
            'type': 'Polygon',
            '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,29.38271030601346]),
              ],
            ],
          },
        },
        {
          'type': 'Feature',
          'properties':{
              'region':'society',
              'name':'orchid petals'
          },
          'geometry': {
            'type': 'Polygon',
            '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])            ],
            ],
          },
        },
        {
          'type': 'Feature',
          'properties':{
              'region':'society',
              'name':'Vatika City'
          },
          'geometry': {
            'type': 'Polygon',
            'coordinates': [
              [
                fromLonLat([ 77.14661429687501,28.326682984225194]),
                fromLonLat([ 77.1348223046875,28.190829441589432]),
                fromLonLat([ 76.9578105859375,28.19502541100354]),
               fromLonLat([ 77.0000273828125,28.34067794211981]),
               fromLonLat([ 77.14661429687501,28.326682984225194]),
              ],
            ],
          },
        }
      
    ],
  };

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, function(feature,layer) {
        console.log(layer,'layered data fetcehd');
    if(layer){

        popUpData.style.display = 'block';
        const overlay = new Overlay({
            element: popUpData,
            autoPan: true,
            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',
              width: 3,
            }),
            fill: new Fill({
              color: 'rgba(0, 0, 255, 0.1)',
            }),
            // 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;
  }
 

ankit chauhan
  • 37
  • 1
  • 9

2 Answers2

1

You can use a features collection instead of a source for the Modify interaction. Add features which are allowed to be modified to the collection:

const features = new Collection();
vectorSource.forEachFeature(function(feature) {
  if (feature.get('name') != 'Serviceable') {
    features.push(feature);
  }
});
const modify = new Modify({features: features});
Mike
  • 16,042
  • 2
  • 14
  • 30
0

I got the answer. Handled it through filteration.

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});
geocodezip
  • 158,664
  • 13
  • 220
  • 245
ankit chauhan
  • 37
  • 1
  • 9