我在Openlayers 3.9.0中有一个矢量图层。 Geoserver从PostGIS获取数据,我使用ol.source.Vector
抓取图层。
返回数据的GeoJSON格式为
{"type":"FeatureCollection","totalFeatures":422,"features":
[{"type":"Feature","id":"myLayer.709","geometry":{"type":"Point","coordinates":
[2391735.8907621,4695330.8039257005]},"geometry_name":"myLayer_geom","properties"
:{"myLayer_name":"Hello"....next feature
因此我通过其ID获取第一个特征,并尝试根据其坐标找到其最接近的特征。这是我的代码
var bb = (sourceVector.getFeatureById('myLayer.709')).getCoordinates()
var aa = getClosestFeatureToCoordinate(bb);
console.log(aa);
我收到Cannot read property 'getCoordinates' of null
错误。
为什么?我错过了什么?
此外,getFeatureById
的API意味着id必须是数字,但在我的情况下是一个字符串(myLayer.709
)。另一方面,feature可以获取字符串作为ID,并且可以在数据读取期间设置ID。
修改
这是整个代码(图层切换器模块here)
var textent = ol.proj.transformExtent([2297128.5, 4618333, 2459120.25, 4763120], 'EPSG:900913', 'EPSG:3857');
var layer = new ol.layer.Tile({
source: new ol.source.OSM({})});
var bingMapsAerial = new ol.layer.Tile({
source: new ol.source.BingMaps({
key: 'aaaa',
imagerySet:'AerialWithLabels'
})
});
var ait = new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://localhost:8080/geoserver/mymap/wms?',
params: {'LAYERS': 'mymap:polygons, mymap:lines', 'TILED': true, 'VERSION': '1.3.0','FORMAT': 'image/png' ,'CRS': 'EPSG:900913'},
serverType: 'geoserver'
})
})
var sourceVector = new ol.source.Vector({
format: new ol.format.GeoJSON(),
useSpatialIndex : true,
loader: function (extent) {
$.ajax('http://localhost:5550/geoserver/mymap/wfs?service=WFS&version=1.0.0&request=GetFeature&typeName=mymap:mylayer&outputFormat=application/json&BBOX='+extent.join(','),
{type: 'GET'})
.done(
function(response) {
var geojsonFormat = new ol.format.GeoJSON({});
sourceVector.addFeatures(geojsonFormat.readFeatures(response,{dataProjection : projection,featureProjection : projection}));
})
.fail(function () {alert("no");});
},
strategy: ol.loadingstrategy.bbox
});
var fill = new ol.style.Fill({
color: 'rgba(0,0,0,0.2)'
});
var stroke = new ol.style.Stroke({
color: 'rgba(0,0,0,0.4)'
});
var circle = new ol.style.Circle({
radius: 6,
fill: fill,
stroke: stroke
});
layerVector = new ol.layer.Vector({
source: sourceVector,
style: new ol.style.Style({
fill: fill,
stroke: stroke,
image: circle
})
});
layer.set('title','a');
layer.set('type','base');
bingMapsAerial.set('title','b');
bingMapsAerial.set('type','base');
ait.set('title','ait');
ait.set('type','base');
var kbz = new ol.interaction.KeyboardZoom();
var dr = new ol.interaction.DragRotateAndZoom();
var control = new ol.control.FullScreen();
var ext = new ol.control.ZoomToExtent({extent: textent});
var center = ol.proj.transform([21.54967, 38.70250], 'EPSG:4326', 'EPSG:3857');
var view = new ol.View({
center: center,
zoom: 6,
extent : textent,
maxZoom:20
});
var map = new ol.Map({
target: 'map',
layers:[bingMapsAerial, layer, ait, layerVector],
view: view
});
map.getView().fit(textent, map.getSize());
map.addInteraction(kbz);
map.addInteraction(dr);
map.addControl(control);
map.addControl(ext);
var layerSwitcher = new ol.control.LayerSwitcher();
map.addControl(layerSwitcher);
var bb = sourceVector.getFeatureById('mylayer.709').getGeometry().getCoordinates();
var aa = sourceVector.getClosestFeatureToCoordinate(bb);
console.log(aa);
更新
在控制台中,如果我点击map.getLayers()
,我会得到矢量图层和包含所有特征的idIndex_
数组(也是709)。但是在我的代码中如果我var cc = sourceVector.getFeatures(); console.log(cc);
我得到[ ]
,只有两个空括号。这是否意味着在我尝试通过ID获取功能之前没有加载功能?
更新2 如果我删除
var bb=sourceVector.getFeatureById('mylayer.709').getGeometry().getCoordinates();
var aa = sourceVector.getClosestFeatureToCoordinate(bb);
console.log(aa);
并将其放在读取功能的响应函数中,在wfs请求之后,它可以正常工作
.done(
function(response) {
var geojsonFormat = new ol.format.GeoJSON({});
sourceVector.addFeatures(geojsonFormat.readFeatures(response,{dataProjection :projection,featureProjection : projection}));
//-------------add the following
var bb=sourceVector.getFeatureById('mylayer.709').getGeometry().getCoordinates();
var aa = sourceVector.getClosestFeatureToCoordinate(bb);
console.log(aa);
})
这是否意味着这是我唯一的选择?为什么我无法设置矢量图层,获取功能,设置我的地图和访问功能?在真实场景中,在完成所有加载之后,用户选择随机特征并获得更接近的特征。不可能知道身份证。在阅读时播放功能是不切实际的,也没有意义。有什么想法吗?
谢谢
答案 0 :(得分:1)
应该是:
var bb = (sourceVector.getFeatureById('myLayer.709'))
.getGeometry().getCoordinates();
var aa = sourceVector.getClosestFeatureToCoordinate(bb);
console.log(aa);
ol.Feature#id
始终(https://github.com/openlayers/ol3/blob/v3.9.0/src/ol/source/vectorsource.js#L694)被视为字符串。
更新 - http://jsfiddle.net/jonataswalker/fn721xdk/
在阅读json功能时告诉OL3你的data projection:
var features = new ol.format.GeoJSON().readFeatures(geojsonObject, {
dataProjection: 'EPSG:3857',
featureProjection: 'EPSG:3857'
});
答案 1 :(得分:1)
是的,Jonatas Walker是对的,我必须等待Ajax完成加载矢量图层上的所有功能,然后才能使用功能。
所以,要知道Ajax何时完成,我保留了与我的OP相同的代码,但我补充说。
function(response) {
var geojsonFormat = new ol.format.GeoJSON({});
sourceVector.addFeatures(geojsonFormat.readFeatures(response,{dataProjection : projection,featureProjection : projection}));
ww();//<---added this to the existing response function
})
因此,当它全部完成后,所有功能都被加载,现在可以访问它们。我叫一个函数
所以,在添加到地图控件和交互之后,我替换了这个
var bb = sourceVector.getFeatureById('mylayer.709').getGeometry().getCoordinates();
var aa = sourceVector.getClosestFeatureToCoordinate(bb);
console.log(aa);
用这个
function ww(){
var rr = sourceVector.getFeatureById('mylayer.709').getGeometry().getCoordinates();
var hh = sourceVector.getClosestFeatureToCoordinate(rr);
console.log("The name of the closest feature is : "+hh.get("mylayer_name"));
}
但是,mylayer.709
是一个观点。因此,如果地图还有线条和多边形,用户可以点击任何功能而你没有找到固定的功能(你事先不知道id)
只需在ww函数
之后添加它 var select = new ol.interaction.Select();//simple click interaction
map.addInteraction(select);//add it to the map
select.on('select', function(e) {//on every select (=click)
//get the extent of the first selected feature (from the e.selected array)
var aa = e.selected[0].getGeometry().getExtent();
//in case of line or polygon get the center of that extent (=just a point)
var oo = ol.extent.getCenter(aa);
//use that center (=point) to get the name of the closest feature
console.log((sourceVector.getClosestFeatureToCoordinate(oo)).get("mylayer_name")) ;
});
<强> 修改 强>
我道歉。原来有一个错误。在这种情况下
如果我点击多边形,我会得到最近特征的名称,但如果我点击这些点,我会得到该点的名称,所以如果我点击&#34; testpoint9&#34;我得到了&#34; testpoint9&#34;但我应该得到&#34; 8&#34;或&#34; u&#34;或者&#34; e&#34;或者是其他东西。所以我想与积分有关。
我将功能的内容更改为
var closestType = e.selected[0].getGeometry().getType();
var oo;
if (closestType === 'Point'){
oo = e.selected[0].getGeometry().getCoordinates();
}
else{
var aa = e.selected[0].getGeometry().getExtent();
oo = ol.extent.getCenter(aa);
}
console.log("---------------------------------------------------");
console.log("Name of closest : "+sourceVector.getClosestFeatureToCoordinate(oo).get('mylayer_name'));
但仍然是同一个错误。有小费吗?感谢