简体   繁体   English

Openlayers 3中的多边形选择选项

[英]Polygon selection option in Openlayers 3

I am currently working on a polygon selection tool in Openlayers 3 and am developing on the code posted here . 我目前正在Openlayers 3中使用多边形选择工具,并且正在开发此处发布的代码。

The above example displays the searchable layer (in this case a WFS) from when the application loads, but as my WFS layer contains 80,000+ features that I need to search against, I am trying to adapt this so that the WFS layer is only displayed once the user completes their search polygon to reduce the loading time, and features only within the bounding box of the drawn polygon are shown. 上面的示例显示了应用程序加载时的可搜索层(在本例中为WFS),但是由于我的WFS层包含我需要搜索的80,000多个功能,因此我试图对其进行调整,以便仅显示WFS层一旦用户完成搜索多边形以减少加载时间,便仅显示绘制多边形边界框内的要素。

The JSTS library is then used to do a spatial intersect between the user's drawn polygon and the WFS features added to the map. 然后,使用JSTS库在用户绘制的多边形与添加到地图的WFS要素之间进行空间相交。

The below code works ok as it correctly displays the WFS features in the drawn polygon extent, but it isn't returning the feature's attribute(s) in the console. 下面的代码可以正常运行,因为它可以在绘制的多边形范围内正确显示WFS要素,但不会在控制台中返回该要素的属性。

I am trying to work out if this is because the layer fully isn't loaded before we try to return the feature's attributes? 我正在尝试确定是否因为在尝试返回要素的属性之前未完全加载图层? Do we need to include something to wait until the layer is loaded before carrying out the forEachFeatureInExtent method? 在执行forEachFeatureInExtent方法之前,我们是否需要包含一些内容以等待加载该图层?

var myDrawSource = new ol.source.Vector({wrapX: false});

var myDrawVector = new ol.layer.Vector({
  source: myDrawSource,
  style: new ol.style.Style({
    fill: new ol.style.Fill({
      color: 'rgba(255, 255, 255, 0.5)'
    }),
    stroke: new ol.style.Stroke({
      color: '#ffcc33',
      width: 2
    }),
    image: new ol.style.Circle({
      radius: 7,
      fill: new ol.style.Fill({
        color: '#ffcc33'
      })
    })
  })
});

var mySelectionsSource = new ol.source.Vector({wrapX: false});

var mySelectionsVector = new ol.layer.Vector({
  source: mySelectionsSource,
  style: new ol.style.Style({
    fill: new ol.style.Fill({
      color: 'rgba(255, 0, 0, 0.5)'
    }),
    stroke: new ol.style.Stroke({
      color: 'rgba(255, 0, 0, 1)',
      width: 2
    }),
    image: new ol.style.Circle({
      radius: 7,
      fill: new ol.style.Fill({
        color: '#ffcc33'
      })
    })
  })
});

var map = new ol.Map({
  layers: [raster,myDrawVector,mySelectionsVector],
  target: 'map',
  view: new ol.View({
    projection: bng,
        resolutions: resolutions,
        center: [501776, 167214],
        zoom: 5
  })
});

var  draw = new ol.interaction.Draw({
      source: myDrawSource,
      type: "Polygon",
    });

map.addInteraction(draw);

draw.on('drawend',function(e){
myDrawSource.clear();
mySelectionsSource.clear();
var waterAreasVecSource = new ol.source.Vector({
        format: new ol.format.GeoJSON(),
        url: function() {
          var featuresExtent = e.feature.getGeometry().getExtent();
          return '../../geoserver/wfs?service=WFS&' +
              'version=1.1.0&request=GetFeature&typename=waterfeature&' +
              'outputFormat=application/json&srsname=EPSG:27700&' +
              'bbox=' + featuresExtent.join(',') + ',EPSG:27700';
        },
        strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
          maxZoom: 13
        }))
      });

var waterAreasVector = new ol.layer.Vector({
    source: waterAreasVecSource
});

map.addLayer(waterAreasVector);
var extent = e.feature.getGeometry().getExtent();
var geomA = e.feature.getGeometry();
waterAreasVecSource.forEachFeatureInExtent(extent,function(aa){
console.log("forEachFeatureInExtent",aa.get('name'));
if (polyIntersectsPoly(geomA,aa.getGeometry()) === true){
mySelectionsSource.addFeature(aa);
}
});
});


/**
* check whether the supplied polygons have any spatial interaction
* @{ol.geometry.Polygon} polygeomA 
* @{ol.geometry.Polygon} polygeomB 
* @returns {Boolean} true||false
*/
function polyIntersectsPoly(polygeomA, polygeomB) {
 var geomA = new jsts.io.GeoJSONReader().read(new ol.format.GeoJSON().writeFeatureObject(
        new ol.Feature({
            geometry: polygeomA
       })
   )
   ).geometry;
var geomB = new jsts.io.GeoJSONReader().read(new ol.format.GeoJSON().writeFeatureObject(
        new ol.Feature({
            geometry: polygeomB
        })
    )
    ).geometry;
return geomA.intersects(geomB);
};

There are several mistakes within the provided fiddle. 提供的小提琴有几个错误。 Adding one more layer each time drawend event is fired is defenanlty wrong. 每次触发drawend事件时drawend添加一层都是错误的。 Instead add a vactor layer on start up and then add / remove features on it. 而是在启动时添加一个vactor层,然后在其上添加/删除功能。 here is a working code. 这是一个工作代码。 and fiddle Check the console to see the logging of feature attributes. 拨弄检查控制台查看要素属性的记录。

var raster = new ol.layer.Tile({
  source: new ol.source.OSM({})
});

var myDrawSource = new ol.source.Vector({wrapX: false});

var myDrawVector = new ol.layer.Vector({
  source: myDrawSource,
  style: new ol.style.Style({
    fill: new ol.style.Fill({
      color: 'rgba(255, 255, 255, 0.5)'
    }),
    stroke: new ol.style.Stroke({
      color: '#ffcc33',
      width: 2
    }),
    image: new ol.style.Circle({
      radius: 7,
      fill: new ol.style.Fill({
        color: '#ffcc33'
      })
    })
  })
});

var mySelectionsSource = new ol.source.Vector({wrapX: false});

var mySelectionsVector = new ol.layer.Vector({
  source: mySelectionsSource,
  style: new ol.style.Style({
    fill: new ol.style.Fill({
      color: 'rgba(255, 0, 0, 0.5)'
    }),
    stroke: new ol.style.Stroke({
      color: 'rgba(255, 0, 0, 1)',
      width: 2
    }),
    image: new ol.style.Circle({
      radius: 7,
      fill: new ol.style.Fill({
        color: '#ffcc33'
      })
    })
  })
});

var map = new ol.Map({
  layers: [raster, myDrawVector,mySelectionsVector],
  target: 'map',
  view: new ol.View({
    center: [-8908887.277395891, 5381918.072437216],
    maxZoom: 19,
    zoom: 12
  })
});


var  draw = new ol.interaction.Draw({
      source: myDrawSource,
      type: "Polygon",
    });

map.addInteraction(draw);

//just clear featutes and add back those falling within drawn polygon
//you need an ajax request and new ol.format.WFS to parse the feats 
draw.on('drawend',function(e){
var extent = e.feature.getGeometry().getExtent();
var geomA = e.feature.getGeometry();

myDrawSource.clear();
mySelectionsSource.clear();
$.ajax('http://demo.opengeo.org/geoserver/wfs', {
            type: 'GET',
            data: {
                service: 'WFS',
                version: '1.1.0',
                request: 'GetFeature',
                typename: 'water_areas',
                srsname: 'EPSG:3857',
                bbox: extent.join(',') + ',EPSG:3857'
            }
        }).done(function(resp){
        var formatWFS = new ol.format.WFS();
        var featuresInExtent = formatWFS.readFeatures(resp);
        var featuresOnDrawPoly = new Array();
        for (var i=0;i<featuresInExtent.length;i++){       
        var geomB = featuresInExtent[i].getGeometry();
          if (polyIntersectsPoly(geomA,geomB)===true){
          featuresOnDrawPoly.push(featuresInExtent[i])
          }
        }
        mySelectionsSource.addFeatures(featuresOnDrawPoly);
        //here you may iterate and get the attributes of those falling within the draw polygon
        for (var z=0;z<featuresOnDrawPoly.length;z++){
        console.log("feature landuse is ======", featuresOnDrawPoly[z].get('landuse'));
        }
        }).fail(function () {
        alert("fail loading layer!!!")
        });

})





/**
* check whether the supplied polygons have any spatial interaction
* @{ol.geometry.Polygon} polygeomA 
* @{ol.geometry.Polygon} polygeomB 
* @returns {Boolean} true||false
*/
function polyIntersectsPoly(polygeomA, polygeomB) {
 var geomA = new jsts.io.GeoJSONReader().read(new ol.format.GeoJSON().writeFeatureObject(
        new ol.Feature({
            geometry: polygeomA
       })
   )
   ).geometry;
var geomB = new jsts.io.GeoJSONReader().read(new ol.format.GeoJSON().writeFeatureObject(
        new ol.Feature({
            geometry: polygeomB
        })
    )
    ).geometry;
return geomA.intersects(geomB);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM