2015-10-20 24 views
1

我在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可以在数据读取过程中设置。

EDIT

这是整个代码(层切换模块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); 

UPDATE

在控制台中,如果我打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); 
         }) 

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

感谢

回答

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)作为字符串处理。

UPDATE - http://jsfiddle.net/jonataswalker/fn721xdk/

告诉OL3你data projection读你的JSON功能时:

var features = new ol.format.GeoJSON().readFeatures(geojsonObject, { 
    dataProjection: 'EPSG:3857', 
    featureProjection: 'EPSG:3857' 
}); 
+0

一个有用的观察。但是现在我得到'Uncaught TypeError:无法读取属性'getGeometry'的null'错误。似乎我无法正确地获取该功能,但我知道它在那里,我在地图上看到它,并且在我的'wfs'请求中没有出现错误。我看不到问题。有小费吗?谢谢 – slevin

+0

查看更新的答案。 –

+0

以我装载机我有'.done(\t \t \t 功能\t(响应){ VAR geojsonFormat =新ol.format.GeoJSON({}); sourceVector.addFeatures(geojsonFormat.readFeatures(响应,{dataProjection:投影,featureProjection:projection})); })'和'var projection = ol.proj.get('EPSG:3857');'。顺便说一下,我看到控制台中的所有图层,它们都被正确加载。 – slevin

1

是,Jonatas沃克是对的,我必须等待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

如果我点击我得到的最接近的特征的名称命名的多边形,但如果我点击了点,我得到这一点的名字,所以,如果我点击“ 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')); 

,但还是一样的错误。有小费吗?谢谢

+0

很高兴看到你的成功。 –

+0

@JonatasWalker嘿,我刚刚发现一个错误,以为你应该检查出来。 – slevin