4

名前と写真、そしてもちろん経度と緯度を含む、さまざまな場所の配列があります。これらをそのまま地図に載せるとごちゃごちゃしてしまいます。だから私はClustersを使用しようとします。

機能の作成から始めます。

 for(var i = 0; i < points.length; i++){
     features[i] = new ol.Feature({
     population: 4000,
     name : points[i].name,
     geometry: new ol.geom.Point(
     ol.proj.transform([
     points[i].long,
     points[i].lat],
     'EPSG:4326', oProjection))
     });
 }

次に、特徴を含むベクトルをクラスターに入力します。

var vSource = new ol.source.Vector({ features: features});

var vFeatures = vSource.getFeatures();

var clusterSource = new ol.source.Cluster({
                   distance: 20,
                   source: vSource});

次に、いくつかのアイコンを使用してクラスターのスタイルを設定します

var clusters = new ol.layer.Vector({
          source: clusterSource,
          style : new ol.style.Style({
                image: new ol.style.Icon(({
                src: 'image/image.png'})),
          text: new ol.style.Text({
                font: '18px Helvetica, Arial Bold, sans-serif',
                text: size.toString(),
                fill: new ol.style.Fill({
                color: '#fff'
                })
})
 map.add(clusters)

後で、フィーチャーから「名前」を取得する必要がある onclick メソッドがありますが、印刷できるのはジオメトリだけです。オブジェクトの名前がクラスターから消えるようなものです。たとえば、 a を実行するとclusterSource.getFeatures()、空のベクトル が返されます[]

function addOverlays(points){
    for(var i = 0; i<points.length;i++){
        var element = document.getElementById(points[i].id);
        var popup = new ol.Overlay({
            element: element,
            positioning: 'bottom-center',
            stopEvent: false
        });
        map.addOverlay(popup);
        // display popup on click
    }

    // display popup on click
    map.on('click', function(evt) {
        var feature = map.forEachFeatureAtPixel(evt.pixel,
            function(feature, layer) {
                console.log("feature on click: ",feature);
                return feature;
            });
        if (feature) {
            var geometry = feature.getGeometry();
            var coord = geometry.getCoordinates();
            popup.setPosition(coord);
            console.log(feature.get('name'));
            $(element).popover({
                'placement': 'bottom',
                'html': true,
                'content': feature.get('name') //THIS IS THE TROUBLE
            });
            $(element).popover('show');
        } else {
            $(element).popover('destroy');
        }
    });
}

addOverlay メソッドは機能の名前を取得できません。非常に奇妙な「未定義」を返します。ヘルプ?何か助けてください。クラスターに追加されると、機能が存在しなくなるようなものです。

4

4 に答える 4

9

したがって、クラスタリングを使用すると、OL3 はその下にあるすべてのクラスタ化された機能をラップする新しい機能を作成します。クラスター化された機能を見ると、values 属性の下に次のように表示されます。

values_: Object
  features: Array[19]
  geometry: ol.geom.Point

これがgetFeatures()機能しない理由です。クラスタ フィーチャを使用する場合、作成時にこれら 2 つの値しかありません。

function isCluster(feature) {
  if (!feature || !feature.get('features')) { 
        return false; 
  }
  return feature.get('features').length > 1;
}

map.on('click', function(evt) {
  var feature = map.forEachFeatureAtPixel(evt.pixel, 
                  function(feature) { return feature; });
  if (isCluster(feature)) {
    // is a cluster, so loop through all the underlying features
    var features = feature.get('features');
    for(var i = 0; i < features.length; i++) {
      // here you'll have access to your normal attributes:
      console.log(features[i].get('name'));
    }
  } else {
    // not a cluster
    console.log(feature.get('name'));
  }
});
于 2014-11-13T22:50:51.350 に答える
3

まだコメントを追加できません (十分な評判がありません) が、クラスター化された機能とクラスター化されていない機能にポップアップが表示されるなどのソリューションを追加したいと考えています。@Timh の例のように。

ただし、ズーム レベルが低くなり、クラスタリングが「解消」されるとundefined、クラスタ内にあった (そして技術的にはまだ) フィーチャをクリックすると、ポップアップが表示されます。

だから、あなたは同じことをすることができます

if (typeof feature.get('features') === 'undefined') {
  // feature.get('whatever');
} else {
  var cfeatures = feature.get('features');
  for(var i = 0; i < cfeatures.length; i++) {
    //like in  the example of timh
  }
}

たとえば、クラスター化された、クラスター化されていない、および現時点で (視覚的に) クラスター化されていない機能からポップアップを取得します。

編集ポップアップの例

于 2015-07-11T21:40:34.513 に答える