问题描述
当我呈现我的 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: </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: </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});