无法获取要素坐标,因此我可以获得最接近的要素
Cannot get feature coordinates so I can get its closest feature
我在 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
implies that the id must be a number, but in my case is a string (myLayer.709
). On the other hand, a feature的API可以得到一个字符串作为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);
})
这是否意味着这是我唯一的选择?为什么我不能设置我的矢量图层、获取特征、设置我的地图和访问特征?在真实场景中,加载完成后,用户选择一个随机特征并靠近。不可能知道id。在阅读特征的同时玩弄特征是不切实际的,也没有意义。有什么想法吗?
谢谢
应该是:
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'
});
是的,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")) ;
});
编辑
我很抱歉。原来有一个错误。在这种情况下
如果我单击多边形,我会得到最近要素的名称,但是如果我单击这些点,我会得到那个点的名称,所以如果我单击 "testpoint9",我会得到 "testpoint9" 但我应该得到 "8" 或 "u" 或 "e" 或其他东西。所以我想和积分有关。
我把函数的内容改成了
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'));
但还是一样的错误。有小费吗?谢谢
我在 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
implies that the id must be a number, but in my case is a string (myLayer.709
). On the other hand, a feature的API可以得到一个字符串作为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);
})
这是否意味着这是我唯一的选择?为什么我不能设置我的矢量图层、获取特征、设置我的地图和访问特征?在真实场景中,加载完成后,用户选择一个随机特征并靠近。不可能知道id。在阅读特征的同时玩弄特征是不切实际的,也没有意义。有什么想法吗?
谢谢
应该是:
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'
});
是的,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")) ;
});
编辑
我很抱歉。原来有一个错误。在这种情况下
如果我单击多边形,我会得到最近要素的名称,但是如果我单击这些点,我会得到那个点的名称,所以如果我单击 "testpoint9",我会得到 "testpoint9" 但我应该得到 "8" 或 "u" 或 "e" 或其他东西。所以我想和积分有关。
我把函数的内容改成了
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'));
但还是一样的错误。有小费吗?谢谢