コード例 #1
0
        /// <summary>
        /// clusters retrieved pins geographically 
        /// </summary>
        /// <param name="pins"></param>
        /// <param name="zoomLevel"></param>
        /// <param name="clusterWidth"></param>
        /// <param name="clusterHeight"></param>
        /// <returns></returns>
        public List<ClusteredPin> cluster(List<ClusteredPin> pins, int zoomLevel, int clusterWidth, int clusterHeight)
        {
            //sort pins - must be ordered correctly.
            PinXYComparer pinComparer = new PinXYComparer();
            pins.Sort(pinComparer);

            List<ClusteredPin> clusteredPins = new List<ClusteredPin>();

            for (int index = 0; index < pins.Count; index++)
            {

                    if ((!pins[index].IsClustered)) //skip already clusted pins
                    {
                        ClusteredPin currentClusterPin = new ClusteredPin();
                        //create our cluster object and add the first pin
                        currentClusterPin.AddPin(pins[index]);
                        pins[index].IsClustered = true;

                        //look backwards in the list for any points within the range that are not already grouped, as the points are in order we exit as soon as it exceeds the range.
                        addPinsWithinRange(pins, index, -1, currentClusterPin, zoomLevel, clusterWidth, clusterHeight);

                        //look forwards in the list for any points within the range, again we short out.
                        addPinsWithinRange(pins, index, 1, currentClusterPin, zoomLevel, clusterWidth, clusterHeight);

                        clusteredPins.Add(currentClusterPin);
                    }

            }
            return clusteredPins;
        }
コード例 #2
0
ファイル: ClusteredPin.cs プロジェクト: Fooway/HydroClient
        /// <summary>Combine clustered pins to thin out map
        /// </summary>
        public void CombineClusteredPins(ClusteredPin newPin)
        {
            //This is needed to prevent alert to be considered for clustering
            //if (newPin.AssessmentHeaderData["Sector"].ToLower() == "alert") return;
            ClusterArea.IncludeInBounds(newPin.ClusterArea);

            if ((Count == 0))
            {
                // AssessmentHeaderData = newPin.AssessmentHeaderData;
                pinType = newPin.PinType;
                // themeParameter = newPin.ThemeParameter;
            }
            else
            {
                //AssessmentHeaderData.Clear();
                // AssessmentHeaderData["icontype"] = newPin.AssessmentHeaderData["icontype"];
                pinType = "clusterpoint";
                // themeParameter = newPin.ThemeParameter;
            }

            assessmentids.AddRange(newPin.assessmentids);
            Count = Count + newPin.Count;

            //Merge the two dictionaries into one dictionary
            //Source: http://stackoverflow.com/questions/10559367/combine-multiple-dictionaries-into-a-single-dictionary
            ServiceCodeToTitle = ServiceCodeToTitle.Concat(newPin.ServiceCodeToTitle).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.First().Value);
        }
コード例 #3
0
        /// <summary>
        /// clusters retrieved pins geographically
        /// </summary>
        /// <param name="pins"></param>
        /// <param name="zoomLevel"></param>
        /// <param name="clusterWidth"></param>
        /// <param name="clusterHeight"></param>
        /// <returns></returns>
        public List <ClusteredPin> cluster(List <ClusteredPin> pins, int zoomLevel, int clusterWidth, int clusterHeight)
        {
            //sort pins - must be ordered correctly.
            PinXYComparer pinComparer = new PinXYComparer();

            pins.Sort(pinComparer);

            List <ClusteredPin> clusteredPins = new List <ClusteredPin>();

            for (int index = 0; index < pins.Count; index++)
            {
                if ((!pins[index].IsClustered))     //skip already clusted pins
                {
                    ClusteredPin currentClusterPin = new ClusteredPin();
                    //create our cluster object and add the first pin
                    currentClusterPin.AddPin(pins[index]);
                    pins[index].IsClustered = true;

                    //look backwards in the list for any points within the range that are not already grouped, as the points are in order we exit as soon as it exceeds the range.
                    addPinsWithinRange(pins, index, -1, currentClusterPin, zoomLevel, clusterWidth, clusterHeight);

                    //look forwards in the list for any points within the range, again we short out.
                    addPinsWithinRange(pins, index, 1, currentClusterPin, zoomLevel, clusterWidth, clusterHeight);

                    clusteredPins.Add(currentClusterPin);
                }
            }
            return(clusteredPins);
        }
コード例 #4
0
ファイル: ClusteredPin.cs プロジェクト: Fooway/HydroClient
        /// <summary>
        /// Adds a pin to the cluster
        /// </summary>
        /// <param name="newPin">the pin to add</param>
        public void AddPin(ClusteredPin newPin)
        {
            //This is needed to prevent alert to be sonsidered for clustering
            //if (newPin.AssessmentHeaderData["Sector"].ToLower() == "alert") return;
            if (Loc == null)
            {
                Loc = newPin.Loc;
            }
            ClusterArea.IncludeInBounds(newPin.ClusterArea);

            if ((Count == 0))
            {
                // AssessmentHeaderData = newPin.AssessmentHeaderData;
                pinType = newPin.PinType;
                //themeParameter = newPin.ThemeParameter;
            }
            else
            {
                //AssessmentHeaderData.Clear();
                // AssessmentHeaderData["icontype"] = newPin.AssessmentHeaderData["icontype"];
                pinType = "clusterpoint";
                //themeParameter = newPin.ThemeParameter;
            }

            assessmentids.Add(newPin.assessmentids[0]);
            Count = Count + 1;

            //Merge the two dictionaries into one dictionary
            //Source: http://stackoverflow.com/questions/10559367/combine-multiple-dictionaries-into-a-single-dictionary
            //ServiceCodeToTitle = ServiceCodeToTitle.Concat(newPin.ServiceCodeToTitle).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.First().Value);

            //Update counts dictionary...
            foreach (var key in newPin.ServiceCodeToTitle.Keys)
            {
                servCodeCounts[key] = (servCodeCounts.ContainsKey(key)) ? servCodeCounts[key] + 1 : 1;
            }

            //Update service code dictionary...
            //	Expected format for strings:  <service title> (<service count>)
            foreach (var key in servCodeCounts.Keys)
            {
                string titlePlusCount = ServiceCodeToTitle.ContainsKey(key) ? ServiceCodeToTitle[key] : newPin.ServiceCodeToTitle[key];

                int last = titlePlusCount.LastIndexOf(')');
                if (-1 != last)
                {
                    titlePlusCount = titlePlusCount.Substring(0, last);
                }

                last = titlePlusCount.LastIndexOf(" (");
                if (-1 != last)
                {
                    titlePlusCount = titlePlusCount.Substring(0, last);
                }

                ServiceCodeToTitle[key] = titlePlusCount + " (" + servCodeCounts[key].ToString() + ")";
            }
        }
コード例 #5
0
        /// <summary>
        /// clusteres visually
        /// </summary>
        /// <param name="clusteredpins"></param>
        /// <param name="zoomLevel"></param>
        /// <param name="minClusterDistance"></param>
        /// <returns></returns>
        private List <ClusteredPin> reduceClusterDensity(List <ClusteredPin> clusteredpins, int zoomLevel, int minClusterDistance)
        {
            PinXYComparer pinComparer = new PinXYComparer();

            clusteredpins.Sort(pinComparer);
            List <ClusteredPin> pins = new List <ClusteredPin>();

            //reset flag
            //Only cluster already clusteredpoints and do not cluster Alerts
            for (int j = 0; j < clusteredpins.Count; j++)
            {
                if (clusteredpins[j].PinType == "clusterpoint")
                {
                    clusteredpins[j].IsClustered = false;
                }
                else
                {
                    clusteredpins[j].IsClustered = true;
                    pins.Add(clusteredpins[j]);
                }
            }
            for (int i = 0; i < clusteredpins.Count; i++)
            {
                if ((!clusteredpins[i].IsClustered)) //skip already clusted pins
                {
                    ClusteredPin currentClusterPin = new ClusteredPin();
                    //create our cluster object and add the first pin
                    currentClusterPin.AddPin(clusteredpins[i]);


                    //look backwards in the list for any points within the range that are not already grouped, as the points are in order we exit as soon as it exceeds the range.
                    addClusteredPinsWithinRange(clusteredpins, i, -1, clusteredpins[i], zoomLevel, minClusterDistance);

                    //look forwards in the list for any points within the range, again we short out.
                    addClusteredPinsWithinRange(clusteredpins, i, 1, clusteredpins[i], zoomLevel, minClusterDistance);

                    clusteredpins[i].IsClustered = true;

                    pins.Add(clusteredpins[i]);
                }
            }
            return(pins);
        }
コード例 #6
0
ファイル: ClusteredPin.cs プロジェクト: CUAHSI/HydroClient
        /// <summary>Combine clustered pins to thin out map
        /// </summary>
        public void CombineClusteredPins(ClusteredPin newPin)
        {
            //This is needed to prevent alert to be considered for clustering
            //if (newPin.AssessmentHeaderData["Sector"].ToLower() == "alert") return;
            ClusterArea.IncludeInBounds(newPin.ClusterArea);

            if ((Count == 0))
            {
               // AssessmentHeaderData = newPin.AssessmentHeaderData;
                pinType = newPin.PinType;
               // themeParameter = newPin.ThemeParameter;
            }
            else
            {
                //AssessmentHeaderData.Clear();
               // AssessmentHeaderData["icontype"] = newPin.AssessmentHeaderData["icontype"];
                pinType = "clusterpoint";
               // themeParameter = newPin.ThemeParameter;
            }

            assessmentids.AddRange(newPin.assessmentids);
            Count = Count + newPin.Count;

            //Merge the two dictionaries into one dictionary
            //Source: http://stackoverflow.com/questions/10559367/combine-multiple-dictionaries-into-a-single-dictionary
            ServiceCodeToTitle = ServiceCodeToTitle.Concat(newPin.ServiceCodeToTitle).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.First().Value);
        }
コード例 #7
0
ファイル: ClusteredPin.cs プロジェクト: CUAHSI/HydroClient
        /// <summary>
        /// Adds a pin to the cluster
        /// </summary>
        /// <param name="newPin">the pin to add</param>
        public void AddPin(ClusteredPin newPin)
        {
            //This is needed to prevent alert to be sonsidered for clustering
            //if (newPin.AssessmentHeaderData["Sector"].ToLower() == "alert") return;
            if (Loc == null)
            {
                Loc = newPin.Loc;
            }
            ClusterArea.IncludeInBounds(newPin.ClusterArea);

            if ((Count == 0))
            {
               // AssessmentHeaderData = newPin.AssessmentHeaderData;
                pinType = newPin.PinType;
                //themeParameter = newPin.ThemeParameter;
            }
            else
            {
                //AssessmentHeaderData.Clear();
               // AssessmentHeaderData["icontype"] = newPin.AssessmentHeaderData["icontype"];
                pinType = "clusterpoint";
                //themeParameter = newPin.ThemeParameter;
            }

            assessmentids.Add(newPin.assessmentids[0]);
            Count = Count + 1;

            //Merge the two dictionaries into one dictionary
            //Source: http://stackoverflow.com/questions/10559367/combine-multiple-dictionaries-into-a-single-dictionary
            //ServiceCodeToTitle = ServiceCodeToTitle.Concat(newPin.ServiceCodeToTitle).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.First().Value);

            //Update counts dictionary...
            foreach( var key in newPin.ServiceCodeToTitle.Keys)
            {
                servCodeCounts[key] = (servCodeCounts.ContainsKey(key)) ? servCodeCounts[key] + 1 : 1;
            }

            //Update service code dictionary...
            //	Expected format for strings:  <service title> (<service count>)
            foreach( var key in servCodeCounts.Keys)
            {
                string titlePlusCount = ServiceCodeToTitle.ContainsKey(key) ? ServiceCodeToTitle[key] : newPin.ServiceCodeToTitle[key];

                int last = titlePlusCount.LastIndexOf(')');
                if (-1 != last)
                {
                    titlePlusCount = titlePlusCount.Substring(0, last);
                }

                last = titlePlusCount.LastIndexOf(" (");
                if (-1 != last)
                {
                    titlePlusCount = titlePlusCount.Substring(0, last);
                }

                ServiceCodeToTitle[key] = titlePlusCount + " (" + servCodeCounts[key].ToString() + ")";
            }
        }
コード例 #8
0
        /// <summary>
        /// clusteres visually 
        /// </summary>
        /// <param name="clusteredpins"></param>
        /// <param name="zoomLevel"></param>
        /// <param name="minClusterDistance"></param>
        /// <returns></returns>
        private List<ClusteredPin> reduceClusterDensity(List<ClusteredPin> clusteredpins, int zoomLevel, int minClusterDistance)
        {
            PinXYComparer pinComparer = new PinXYComparer();
            clusteredpins.Sort(pinComparer);
            List<ClusteredPin> pins = new List<ClusteredPin>();
            //reset flag
            //Only cluster already clusteredpoints and do not cluster Alerts
            for (int j = 0; j < clusteredpins.Count; j++)
            {
                if (clusteredpins[j].PinType == "clusterpoint")
                {
                    clusteredpins[j].IsClustered = false;
                }
                else
                {
                    clusteredpins[j].IsClustered = true;
                    pins.Add(clusteredpins[j]);
                }
            }
            for (int i = 0; i < clusteredpins.Count; i++)
            {

                if ((!clusteredpins[i].IsClustered)) //skip already clusted pins
                {
                    ClusteredPin currentClusterPin = new ClusteredPin();
                    //create our cluster object and add the first pin
                    currentClusterPin.AddPin(clusteredpins[i]);

                    //look backwards in the list for any points within the range that are not already grouped, as the points are in order we exit as soon as it exceeds the range.
                    addClusteredPinsWithinRange(clusteredpins, i, -1, clusteredpins[i], zoomLevel, minClusterDistance);

                    //look forwards in the list for any points within the range, again we short out.
                    addClusteredPinsWithinRange(clusteredpins, i, 1, clusteredpins[i], zoomLevel, minClusterDistance);

                    clusteredpins[i].IsClustered = true;

                    pins.Add(clusteredpins[i]);
                }

            }
            return pins;
        }
コード例 #9
0
        /// <summary>
        /// Adds pins to nearby cluster for theme
        /// </summary>
        /// <param name="pins"></param>
        /// <param name="index"></param>
        /// <param name="direction"></param>
        /// <param name="currentClusterPin"></param>
        /// <param name="zoomLevel"></param>
        /// <param name="themeParameter"></param>
        private void addPinsWithinRange(List<ClusteredPin> pins, int index, int direction, ClusteredPin currentClusterPin, int zoomLevel, string themeParameter)
        {
            bool finished = false;
            int searchindex;
            searchindex = index + direction;
            while (!finished)
            {
                if (searchindex >= pins.Count || searchindex < 0)
                {
                    finished = true;
                }
                else
                {
                    if (!pins[searchindex].IsClustered)
                    {
                       // if (pins[searchindex].ThemeParameter == themeParameter)//only cluster if parameter are the same
                        //{
                            if (Math.Abs(pins[searchindex].GetPixelX(zoomLevel) - pins[index].GetPixelX(zoomLevel)) < CLUSTERWIDTH) //within the same x range
                            {
                                if (Math.Abs(pins[searchindex].GetPixelY(zoomLevel) - pins[index].GetPixelY(zoomLevel)) < CLUSTERHEIGHT) //within the same y range = cluster needed
                                {
                                    //add to cluster
                                    currentClusterPin.AddPin(pins[searchindex]);

                                    //stop any further clustering
                                    pins[searchindex].IsClustered = true;
                                }
                            }
                            else
                            {
                                finished = true;
                            }
                        //}
                    };
                    searchindex += direction;
                }
            }
        }
コード例 #10
0
        /// <summary>
        /// Adds pins to nearby cluster
        /// </summary>
        /// <param name="pins"></param>
        /// <param name="index"></param>
        /// <param name="direction"></param>
        /// <param name="currentClusterPin"></param>
        /// <param name="zoomLevel"></param>
        /// <param name="clusterWidth"></param>
        /// <param name="clusterHeight"></param>
        private void addPinsWithinRange(List<ClusteredPin> pins, int index, int direction, ClusteredPin currentClusterPin, int zoomLevel, int clusterWidth, int clusterHeight)
        {
            bool finished = false;
            int searchindex;
            searchindex = index + direction;
            while (!finished)
            {
                if (searchindex >= pins.Count || searchindex < 0)
                {
                    finished = true;
                }
                else
                {
                    if (!pins[searchindex].IsClustered)
                    {
                        if (Math.Abs(pins[searchindex].GetPixelX(zoomLevel) - pins[index].GetPixelX(zoomLevel)) < clusterWidth) //within the same x range
                        {
                            if (Math.Abs(pins[searchindex].GetPixelY(zoomLevel) - pins[index].GetPixelY(zoomLevel)) < clusterHeight) //within the same y range = cluster needed
                            {
                                //add to cluster
                                currentClusterPin.AddPin(pins[searchindex]);

                                //stop any further clustering
                                pins[searchindex].IsClustered = true;
                            }
                        }
                        else
                        {
                            finished = true;
                        }
                    };
                    searchindex += direction;
                }
            }
        }
コード例 #11
0
        /// <summary>
        /// Visual clustering.
        /// </summary>
        /// <param name="pins"></param>
        /// <param name="index"></param>
        /// <param name="direction"></param>
        /// <param name="currentClusterPin"></param>
        /// <param name="zoomLevel"></param>
        /// <param name="minClusterDistance"></param>
        private void addClusteredPinsWithinRange(List <ClusteredPin> pins, int index, int direction, ClusteredPin currentClusterPin, int zoomLevel, int minClusterDistance)
        {
            bool finished = false;
            int  searchindex;

            searchindex = index + direction;
            while (!finished)
            {
                if (searchindex >= pins.Count || searchindex < 0)
                {
                    finished = true;
                }
                else
                {
                    if (!pins[searchindex].IsClustered)
                    {
                        if (Math.Abs(pins[searchindex].GetPixelX(zoomLevel) - pins[index].GetPixelX(zoomLevel)) < minClusterDistance)     //within the same x range
                        {
                            if (Math.Abs(pins[searchindex].GetPixelY(zoomLevel) - pins[index].GetPixelY(zoomLevel)) < minClusterDistance) //within the same y range = cluster needed
                            {
                                //add to cluster
                                currentClusterPin.CombineClusteredPins(pins[searchindex]);

                                //stop any further clustering
                                pins[searchindex].IsClustered = true;
                            }
                        }
                        else
                        {
                            finished = true;
                        }
                    }
                    ;
                    searchindex += direction;
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Adds pins to nearby cluster for theme
        /// </summary>
        /// <param name="pins"></param>
        /// <param name="index"></param>
        /// <param name="direction"></param>
        /// <param name="currentClusterPin"></param>
        /// <param name="zoomLevel"></param>
        /// <param name="themeParameter"></param>
        private void addPinsWithinRange(List <ClusteredPin> pins, int index, int direction, ClusteredPin currentClusterPin, int zoomLevel, string themeParameter)
        {
            bool finished = false;
            int  searchindex;

            searchindex = index + direction;
            while (!finished)
            {
                if (searchindex >= pins.Count || searchindex < 0)
                {
                    finished = true;
                }
                else
                {
                    if (!pins[searchindex].IsClustered)
                    {
                        // if (pins[searchindex].ThemeParameter == themeParameter)//only cluster if parameter are the same
                        //{
                        if (Math.Abs(pins[searchindex].GetPixelX(zoomLevel) - pins[index].GetPixelX(zoomLevel)) < CLUSTERWIDTH)      //within the same x range
                        {
                            if (Math.Abs(pins[searchindex].GetPixelY(zoomLevel) - pins[index].GetPixelY(zoomLevel)) < CLUSTERHEIGHT) //within the same y range = cluster needed
                            {
                                //add to cluster
                                currentClusterPin.AddPin(pins[searchindex]);

                                //stop any further clustering
                                pins[searchindex].IsClustered = true;
                            }
                        }
                        else
                        {
                            finished = true;
                        }
                        //}
                    }
                    ;
                    searchindex += direction;
                }
            }
        }
コード例 #13
0
ファイル: HomeController.cs プロジェクト: CUAHSI/HydroClient
		public List<ClusteredPin> transformSeriesDataCartIntoClusteredPin(List<TimeSeriesViewModel> series, clientFilterAndSearchCriteria filterAndSearchCriteria)
		{
			List<ClusteredPin> clusterPins = new List<ClusteredPin>();
			bool bUseFilter = ! (null == filterAndSearchCriteria || filterAndSearchCriteria.isEmpty());

			if (  bUseFilter) {
				//Retrieve COPIES of all time series which match filter criteria...
				series = filterTimeSeries(series, filterAndSearchCriteria);
			}

			for (int i = 0; i < series.Count; i++)
			{

				var cl = new ClusteredPin();

				cl.Loc = new LatLong(series[i].Latitude, series[i].Longitude);

				cl.assessmentids.Add(series[i].SeriesId);
				cl.PinType = "point";

				//Retain the service code, title and highest value count for later reference...
				string key = series[i].ServCode;
				string title = series[i].ServTitle;

				cl.ServiceCodeToTitle[key] = title;
	
				clusterPins.Add(cl);
			}

			return clusterPins;
		}