markerclusterer

Topics: Feature Requests
Oct 26, 2011 at 1:21 PM

Сan someone help create markerclusterer?

http://jqeedu.tuxfamily.org/tools/files/markerclusterer/examples/simple_example.html

Oct 26, 2011 at 1:57 PM
Edited Oct 29, 2011 at 6:33 AM

http://vremenno.net/files/uploads/map.yandex.clusterer.js.zip this java script  clastering marker for yandex map

and Google claster http://gmaps-utility-library-dev.googlecode.com/svn/tags/markerclusterer/1.0/src/

Nov 3, 2011 at 12:02 PM
Edited Nov 4, 2011 at 5:56 AM

Here is my code clustering, I'm  beginner, so someone should correct the code.

http://s017.radikal.ru/i414/1111/e0/2c95ba941983.jpg

http://s017.radikal.ru/i425/1111/dc/61df58b0b098.bmp

http://s44.radikal.ru/i103/1111/15/84ce92140003.bmp

 

   public class MarkerClusterer
    {
        List<Cluster> clusters_ = new List<Cluster>();
        List<GMapMarker> clusters;
        Map map_;
        int maxZoom_ = 0;

        int gridSize_ = 60;
        //var sizes = [53, 56, 66, 78, 90];
        //var styles_ = [];
        List<GMapMarker> leftMarkers_ = new List<GMapMarker>();
        //var mcfn_ = null;
        public GMapOverlay Overlay { get; set; }


        public MarkerClusterer(Map MainMap, ObservableCollectionThreadSafe<GMapMarker> opt_markers, GMapOverlay overlay)
        {
            maxZoom_ = MainMap.MaxZoom;
            map_ = MainMap;
            Overlay = overlay;
            if (opt_markers != null)
            {
                addMarkers(opt_markers);
            }
            MainMap.OnMapZoomChanged += new MapZoomChanged(OnMapZoomChanged);
        }
        void OnMapZoomChanged()
        {
            resetViewport();
        }
        /**
        * When we add a marker, the marker may not in the viewport of map, then we don't deal with it, instead
        * we add the marker into a array called leftMarkers_. When we reset MarkerClusterer we should add the
        * leftMarkers_ into MarkerClusterer.
        */
        void addLeftMarkers_()
        {
            if (leftMarkers_.Count == 0)
            {
                return;
            }
            List<GMapMarker> leftMarkers = new List<GMapMarker>();

            for (int i = 0; i < leftMarkers_.Count; i++)
            {
                //me_.addMarker(leftMarkers_[i], true, null, null, true);
                addMarker(leftMarkers_[i], true, false, true);//null, null, true);
            }
            leftMarkers_ = leftMarkers;
        }

        /**
 * Remove all markers from MarkerClusterer.
 */
        void clearMarkers()
        {
            for (int i = 0; i < clusters_.Count; i++)
            {
                if (clusters_[i] != null)
                {
                    clusters_[i].clearMarkers();
                }
            }
            clusters_.Clear();// = null; 
            leftMarkers_.Clear();// = null;


            //++ GEvent.removeListener(mcfn_);
        }

        /**
          * Check a marker, whether it is in current map viewport.
          * @private
          * @return {Boolean} if it is in current map viewport
          */
        bool isMarkerInViewport_(GMapMarker marker)
        {
            //return map_.getBounds().containsLatLng(marker.getLatLng());
            return map_.CurrentViewArea.Contains(marker.Position);
        }

        /**
 * When reset MarkerClusterer, there will be some markers get out of its cluster.
 * These markers should be add to new clusters.
 * @param {Array of GMarker} markers Markers to add.
 */
        public void reAddMarkers_(List<GMapMarker> markers)
        {
            int len = markers.Count;
            var clusters = new Cluster(this);// var clusters = [];
            for (int i = len - 1; i >= 0; i--)
            {
                //me_.addMarker(markers[i].marker, true, markers[i].isAdded, clusters, true);
                addMarker(markers[i], true, markers[i].isAdded, false);
            }
            addLeftMarkers_();
        }
        /**
  * Add a marker.
  * @private
  * @param {GMarker} marker Marker you want to add
  * @param {Boolean} opt_isNodraw Whether redraw the cluster contained the marker
  * @param {Boolean} opt_isAdded Whether the marker is added to map. Never use it.
  * @param {Array of Cluster} opt_clusters Provide a list of clusters, the marker
  *     cluster will only check these cluster where the marker should join.
  */
        //++void addMarker  (marker, opt_isNodraw, opt_isAdded, opt_clusters, opt_isNoCheck)

       public void addMarker(GMapMarker marker, bool opt_isNodraw, bool opt_isAdded, bool opt_isNoCheck)
        {
            // bool opt_isNoCheck = false;
            if (opt_isNoCheck != true)
            {
                if (!isMarkerInViewport_(marker))
                {
                    leftMarkers_.Add(marker);
                    return;
                }
            }

            bool isAdded = opt_isAdded;//opt_isAdded;
            List<Cluster> clusters;// = opt_clusters;

            GPoint pos = map_.FromLatLngToLocal(marker.Position);

            //if (typeof isAdded !== "boolean") {
            //isAdded = false;
            //}
            //if (typeof clusters !== "object" || clusters === null) {
            clusters = clusters_;
            // }

            int length = clusters.Count;

            Cluster cluster = null;
            for (var i = length - 1; i >= 0; i--)
            {
                cluster = clusters[i];
                PointLatLng p = cluster.getCenter();
                if (p == PointLatLng.Zero)
                {
                    continue;
                }
                GPoint center = map_.FromLatLngToLocal(p);

                // Found a cluster which contains the marker.
                if (pos.X >= center.X - gridSize_ && pos.X <= center.X + gridSize_ &&
                    pos.Y >= center.Y - gridSize_ && pos.Y <= center.Y + gridSize_)
                {
                    cluster.addMarker(marker);
                    if (!opt_isNodraw)
                    {
                        cluster.redraw_(false);
                    }
                    return;
                }
            }

            // No cluster contain the marker, create a new cluster.
            cluster = new Cluster(this);
            cluster.addMarker(marker);

            if (!opt_isNodraw)
            {
                cluster.redraw_(false);
            }

            // Add this cluster both in clusters provided and clusters_
            clusters.Add(cluster);
            if (clusters != clusters_)
            {
                clusters_.Add(cluster);
            }
        }
        /**
 * Remove a marker.
 *
 * @param {GMarker} marker The marker you want to remove.
 */

        void removeMarker(GMapMarker marker)
        {
            for (int i = 0; i < clusters_.Count; i++)
            {
                //if (clusters_[i].remove(marker))
                //{
                //    clusters_[i].redraw_(false);
                //    return;
                //}

            }
        }

        /**
         * Redraw all clusters in viewport.
         */
        void redraw_()
        {
            var clusters = this.getClustersInViewport();
            for (var i = 0; i < clusters.Count; ++i)
            {
                clusters[i].redraw_(true);
            }
        }

        /**
        * Get all clusters in viewport.
        * @return {Array of Cluster}
        */
        List<Cluster> getClustersInViewport()
        {
            List<Cluster> clusters = new List<Cluster>();
            //  RectLatLng curBounds = map_.CurrentViewArea;

            for (var i = 0; i < clusters_.Count; i++)
            {

                //if (clusters_[i].isInBounds(curBounds))
                if (clusters_[i].isInBounds())
                {
                    clusters.Add(clusters_[i]);
                }
            }
            return clusters;
        }

        /**
    * Collect all markers of clusters in viewport and regroup them.
    */
        void resetViewport()
        {
            var clusters = getClustersInViewport();

            List<GMapMarker> tmpMarkers = new List<GMapMarker>();
            int removed = 0;

            for (var i = 0; i < clusters.Count; ++i)
            {
                Cluster cluster = clusters[i];
                double oldZoom = cluster.getCurrentZoom();
                if (oldZoom == null)
                {
                    continue;
                }
                double curZoom = map_.Zoom;
                if (curZoom != oldZoom)
                {

                    // If the cluster zoom level changed then destroy the cluster
                    // and collect its markers.

                    List<GMapMarker> mks = cluster.getMarkers();
                    for (int j = 0; j < mks.Count; j++)
                    {
                        GMapMarker newMarker = new GMapMarkerGoogleGreen(mks[j].Position);
                        newMarker.isAdded = false;

                        //{
                        //  'isAdded': false,
                        //  'marker': mks[j].marker
                        //};
                        tmpMarkers.Add(newMarker);
                    }

                    cluster.clearMarkers();

                    removed++;
                    for (int j = 0; j < clusters_.Count; j++)
                    {
                        if (cluster == clusters_[j])
                        {
                            //clusters_.splice(j, 1);
                            clusters_.RemoveAt(j);
                        }
                    }
                }
            }
            //Add the markers collected into marker cluster to reset
            reAddMarkers_(tmpMarkers);
            redraw_();
        }


        /**
         * Add a set of markers.
         *
         * @param {Array of GMarker} markers The markers you want to add.
         */
        void addMarkers(ObservableCollectionThreadSafe<GMapMarker> markers)
        {
            //for (var i = 0; i < markers.length; ++i) {
            //  this.addMarker(markers[i], true);
            //}
            foreach (var item in markers)
            {
                addMarker(item, true, false, false);
            }
            this.redraw_();
        }

        public Map getMap_()
        {
            return map_;
        }

        public int getGridSize_()
        {
            return gridSize_;
        }
        public int getMaxZoom()
        {
            return maxZoom_;
        }
    }
//**********************************************

    class Cluster
    {
        PointLatLng center_;
        List<GMapMarker> markers_ = new List<GMapMarker>();

        MarkerClusterer markerClusterer_;
        Map map_;
        GMapMarkerGoogleGreen clusterMarker_ = null;
        //var clusterMarker_ = null;

        double zoom_;

        public Cluster(MarkerClusterer markerClusterer)
        {
            markerClusterer_ = markerClusterer;
            map_ = markerClusterer.getMap_();
            zoom_ = map_.Zoom;
        }

        public List<GMapMarker> getMarkers()
        {
            return markers_;
        }


        /**
   * If this cluster intersects certain bounds.
   *
   * @param {GLatLngBounds} bounds A bounds to test
   * @return {Boolean} Is this cluster intersects the bounds
   */
        public bool isInBounds()
        {

            if (center_ == null)
            {
                return false;
            }

            //if (!bounds) 
            //{
            RectLatLng bounds = map_.CurrentViewArea;
            //}

            GPoint sw = map_.FromLatLngToLocal(new PointLatLng(bounds.Bottom, bounds.Left));//= map_.FromLatLngToLocal(bounds.getSouthWest());

            GPoint ne = map_.FromLatLngToLocal(new PointLatLng(bounds.Top, bounds.Right));//= map_.FromLatLngToLocal(bounds.getNorthEast());

            GPoint centerxy = map_.FromLatLngToLocal(center_);

            bool inViewport = true;
            double gridSize = markerClusterer_.getGridSize_();

            if (zoom_ != map_.Zoom)
            {
                double dl = map_.Zoom - zoom_;
                gridSize = Math.Pow(2, dl) * gridSize;
            }

            if (ne.X != sw.X && (centerxy.X + gridSize < sw.X || centerxy.X - gridSize > ne.X))
            {
                inViewport = false;
            }

            if (inViewport && (centerxy.Y + gridSize < ne.Y || centerxy.Y - gridSize > sw.Y))
            {
                inViewport = false;
            }
            return inViewport;
        }



        /**
 * Add a marker.
 *
 * @param {Object} marker An object of marker you want to add:
 *   {Boolean} isAdded If the marker is added on map.
 *   {GMarker} marker The marker you want to add.
 */
        public void addMarker(GMapMarker marker)
        {
            if (center_ == PointLatLng.Zero)
            {
                /*var pos = marker['marker'].getLatLng();
                 pos = map.fromLatLngToContainerPixel(pos);
                 pos.x = parseInt(pos.x - pos.x % (GRIDWIDTH * 2) + GRIDWIDTH);
                 pos.y = parseInt(pos.y - pos.y % (GRIDWIDTH * 2) + GRIDWIDTH);
                 center = map.fromContainerPixelToLatLng(pos);*/
                center_ = marker.Position;
            }
            markers_.Add(marker);
        }


        /**
         * Remove a marker from cluster.
         *
         * @param {GMarker} marker The marker you want to remove.
         * @return {Boolean} Whether find the marker to be removed.
         */
        bool removeMarker(GMapMarker marker)
        {
            for (var i = 0; i < markers_.Count; ++i) 
            {
              if (marker == markers_[i]) 
              {
                if (markers_[i].isAdded)
                {

                 // map_.removeOverlay(markers_[i]);
                  markerClusterer_.Overlay.Markers.Remove(markers_[i]);
                }
                markers_.RemoveAt(i);
                return true;
              }
            }
            return false;
        }

        /**
         * Get current zoom level of this cluster.
         * Note: the cluster zoom level and map zoom level not always the same.
         *
         * @return {Number}
         */
        public double getCurrentZoom()
        {
            return zoom_;
        }


        /**
           * Redraw a cluster.
           * @private
           * @param {Boolean} isForce If redraw by force, no matter if the cluster is
           *     in viewport.
           */
        public void redraw_(bool isForce)
        {
            if (!isForce && !isInBounds())
            {
                return;
            }

            // Set cluster zoom level.
            zoom_ = map_.Zoom;
            int i = 0;
            int mz = markerClusterer_.getMaxZoom();

            if (mz == null) {
              mz = map_.MaxZoom;//.getCurrentMapType().getMaximumResolution();
            }

            if (zoom_ >= mz || getTotalMarkers() == 1) 
            {
     
                for (i = 0; i < markers_.Count; i++)
                {

                    if (markers_[i].isAdded)
                    {
                        if (!markers_[i].IsVisible)
                        {
                            markers_[i].IsVisible = true;
                        }
                    }
                    else
                    {
                       // map_.addOverlay(markers_[i].marker);
                        markers_[i].isAdded = true;
                        markerClusterer_.Overlay.Markers.Add(markers_[i]);
                       
                    }
                }
                //if (clusterMarker_ != null)
                //{
                //    clusterMarker_.hide();
                //}
            }
            else
            {
            
                for (i = 0; i < markers_.Count; ++i)
                {
                    //if (markers_[i].isAdded && (!markers_[i].marker.isHidden()))
                    if (markers_[i].isAdded && (markers_[i].IsVisible))
                    {
                        markers_[i].IsVisible = false;
                    }
                }
                if (clusterMarker_ == null)
                {
                    //clusterMarker_ = new ClusterMarker_(center_, getTotalMarkers(), markerClusterer_.getStyles_(), markerClusterer_.getGridSize_());
                    //map_.addOverlay(clusterMarker_);
                    clusterMarker_ = new GMapMarkerGoogleGreen(center_);
                    clusterMarker_.ToolTipText = markers_.Count.ToString();
                    clusterMarker_.ToolTipMode = MarkerTooltipMode.Always;
                    clusterMarker_.isAdded = true;
                    markerClusterer_.Overlay.Markers.Add(clusterMarker_);

                }
                else
                {
                    if (!clusterMarker_.IsVisible)
                    {
                       // clusterMarker_.show();
                        clusterMarker_.IsVisible = true;
                    }
                    //clusterMarker_.redraw(true);
                }
            }
        }

        /**
         * Remove all the markers from this cluster.
         */
        public void clearMarkers()
        {
            if (clusterMarker_ != null)
            {
               // map_.removeOverlay(clusterMarker_);
                markerClusterer_.Overlay.Markers.Remove(clusterMarker_);
            }

            for (int i = 0; i < markers_.Count; ++i)
            {
                if (markers_[i].isAdded)
                {
                   // map_.removeOverlay(markers_[i].marker);
                    markerClusterer_.Overlay.Markers.Remove(markers_[i]);

                }
            }

            markers_.Clear();// = [];
        }

        public PointLatLng getCenter()
        {
            return center_;
        }

        int getTotalMarkers()
        {
            return markers_.Count;
        }

    }
//***************************************
Using:
public abstract class GMapMarker : ISerializable
{
   public bool isAdded { get; set; }
...}
          ObservableCollectionThreadSafe ClasterMarkers = new ObservableCollectionThreadSafe();

          GMapMarkerGoogleGreen m = new GMapMarkerGoogleGreen(new PointLatLng(54.9268725,23.8724264));
          GMapMarkerGoogleGreen m1 = new GMapMarkerGoogleGreen(new PointLatLng(54.9068728, 23.9024265));
          GMapMarkerGoogleGreen m2 = new GMapMarkerGoogleGreen(new PointLatLng(54.9218149707138, 8945770263672));
          GMapMarkerGoogleGreen m3 = new GMapMarkerGoogleGreen(new PointLatLng(54.9368730, 23.8924267));
          GMapMarkerGoogleGreen m4 = new GMapMarkerGoogleGreen(new PointLatLng(54.9168727, 23.8924268));
          GMapMarkerGoogleGreen m5 = new GMapMarkerGoogleGreen(new PointLatLng(54.9068724, 23.8924260));

          ClasterMarkers.Add(m);
          ClasterMarkers.Add(m1);
          ClasterMarkers.Add(m2);
          ClasterMarkers.Add(m3);
          ClasterMarkers.Add(m4);
          ClasterMarkers.Add(m5);
          markerClusterer = new MarkerClusterer(MainMap, ClasterMarkers, objects);