无法获取要素坐标,因此我可以获得其最接近的功能

时间:2015-10-20 14:11:17

标签: openlayers-3

我在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); 
                        })

这是否意味着这是我唯一的选择?为什么我无法设置矢量图层,获取功能,设置我的地图和访问功能?在真实场景中,在完成所有加载之后,用户选择随机特征并获得更接近的特征。不可能知道身份证。在阅读时播放功能是不切实际的,也没有意义。有什么想法吗?

谢谢

2 个答案:

答案 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")) ;
 });

<强> 修改

我道歉。原来有一个错误。在这种情况下

enter image description here

如果我点击多边形,我会得到最近特征的名称,但如果我点击这些点,我会得到该点的名称,所以如果我点击&#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'));

但仍然是同一个错误。有小费吗?感谢