How to: Implement a Custom Clusterer

  • 10 minutes to read

To implement a custom clusterer, design a class implementing the IClusterer interface and its IClusterer.Clusterize and IClusterer.SetOwner abstract methods, and IClusterer.Items and IClusterer.IsBusyproperties.

In this example, the CURE clustering method is implemented. Note that it has a high algorithmic complexity.

NOTE
  • The owner adapter's IMapDataAdapter.OnClustered method should be called to notify the Adapter that clustering is finished.
  • When creating a cluster representative collection, send an owner as the constructor argument.
using DevExpress.XtraMap;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
using System.Xml.Linq;

namespace CustomClustererSample {
    public partial class Form1 : Form {
        VectorItemsLayer VectorLayer { get { return (VectorItemsLayer)map.Layers["VectorLayer"]; } }
        ListSourceDataAdapter DataAdapter { get { return (ListSourceDataAdapter)VectorLayer.Data; } }

        public Form1() {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            VectorLayer.DataLoaded += (obj, args) => { map.ZoomToFitLayerItems(); };

            DataAdapter.DataSource = LoadData();
            DataAdapter.Clusterer = new CureClusterer();
        }

        List<Tree> LoadData() {
            List<Tree> trees = new List<Tree>();
            XDocument doc = XDocument.Load("Data\\treesCl.xml");
            foreach (XElement xTree in doc.Element("RowSet").Elements("Row"))
                trees.Add(new Tree {
                    Latitude = Convert.ToDouble(xTree.Element("lat").Value, CultureInfo.InvariantCulture),
                    Longitude = Convert.ToDouble(xTree.Element("lon").Value, CultureInfo.InvariantCulture),
                    LocationName = xTree.Element("location").Value
                });
            return trees;
        }
    }
}