Openlayers 3 中的多边形选择选项
Polygon selection option in Openlayers 3
我目前正在 Openlayers 3 中开发多边形选择工具,并且正在开发发布的代码 。
上面的示例显示了应用程序加载时的可搜索层(在本例中为 WFS),但由于我的 WFS 层包含 80,000 多个我需要搜索的功能,我正在尝试对其进行调整,以便WFS 图层仅在用户完成搜索多边形后显示以减少加载时间,并且仅显示所绘制多边形边界框内的要素。
然后使用 JSTS 库在用户绘制的多边形和添加到地图的 WFS 要素之间进行空间相交。
下面的代码工作正常,因为它在绘制的多边形范围内正确显示了 WFS 要素,但它没有return在控制台中输入要素的属性。
我想知道这是否是因为在我们尝试 return 要素的属性之前图层未完全加载?在执行 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);
};
所提供的 fiddle 中有几处错误。
每次触发 drawend
事件时再添加一层在防御上是错误的。
而是在启动时添加一个 vactor 层,然后在其上添加/删除功能。
这是一个工作代码。和 fiddle
检查控制台以查看功能属性的日志记录。
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);
};
我目前正在 Openlayers 3 中开发多边形选择工具,并且正在开发发布的代码
上面的示例显示了应用程序加载时的可搜索层(在本例中为 WFS),但由于我的 WFS 层包含 80,000 多个我需要搜索的功能,我正在尝试对其进行调整,以便WFS 图层仅在用户完成搜索多边形后显示以减少加载时间,并且仅显示所绘制多边形边界框内的要素。
然后使用 JSTS 库在用户绘制的多边形和添加到地图的 WFS 要素之间进行空间相交。
下面的代码工作正常,因为它在绘制的多边形范围内正确显示了 WFS 要素,但它没有return在控制台中输入要素的属性。
我想知道这是否是因为在我们尝试 return 要素的属性之前图层未完全加载?在执行 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);
};
所提供的 fiddle 中有几处错误。
每次触发 drawend
事件时再添加一层在防御上是错误的。
而是在启动时添加一个 vactor 层,然后在其上添加/删除功能。
这是一个工作代码。和 fiddle
检查控制台以查看功能属性的日志记录。
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);
};