2014-10-24 6 views
2

У меня есть массив с множеством разных мест, с именами и фотографиями и, конечно, долготой и широтой. Если я наберу их непосредственно на карту, она будет захламлена. Поэтому я стараюсь использовать Clusters.Получение функций из кластеров в OpenLayers?

Начните с создания features:

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) 

I позже есть метод onclick, который должен получить «имя» из Feature, но единственное, что он может распечатать, это геометрия, это похоже на то, что имя объекта исчезает из кластеров. Например, выполнение 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 не может получить имя функции, она возвращает «неопределенный», который очень странно. Помогите? Любая помощь, пожалуйста? Это похоже на то, что функции перестают существовать при добавлении в кластер.

ответ

7

Таким образом, при кластеризации OL3 создает новую функцию, которая обертывает все кластерные функции под ней. Если вы посмотрите на кластерную функции вы видите это под значениями атрибутов:

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

Вот почему getFeatures() не работает, при работе с кассетными особенностями, у них есть только эти два значения, когда они созданы.

+0

очень хорошее решение, но у меня есть некоторые проблемы с ним с некластерными исключительными функциями, но в конечном итоге они попадут. – radhoo

+0

@radhoo Я знаю, что это уже давно, но я наткнулся на ту же проблему, и я решил ее, заменив 'feature.get ('name')' на 'feature.get ('features'). Get ('name')' in остальное. надеюсь, что это поможет –

+0

Код Тима уже исправлен для поддержки как особых функций, так и кластеров. Ваш комментарий верен и соответствует опубликованному коду. – radhoo

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 
    } 
} 

и получать от Popups например, сгруппированных, некластеризованных и от особенностей, которые не кластерные (визуальным способом) на данный момент.

Edit: Example with Popups

0

Я не могу комментировать, так как я не имею репутацию, но это комментарий к решению Timh, который хорош, но имеет недостаток (поэтому radhoo имеет проблемы с отдельными функциями, как описанных в его комментарии).

Функция «isCluster» не должны проверить, если есть один или несколько признаков, так как это все-таки кластер, даже если он содержит только одну особенность

function isCluster(feature) { 
    return !feature || !feature.get('features'); 
} 

Так что лучше обрабатывать все кластеры таким же образом, и необязательно обрабатывать объекты объектов отдельно.