private async Task CalculatePointClusters(List <System.Windows.Point> pixels) #endif { int maxX = (int)Math.Ceiling(_map.ActualWidth + ClusterRadius); int maxY = (int)Math.Ceiling(_map.ActualHeight + ClusterRadius); clusters = await Task.Run <ClusteredPoint[]>(() => { var clusteredData = new List <ClusteredPoint>(); if (_items != null && _items.Count > 0) { double tileZoomRatio = 256 * Math.Pow(2, _currentZoomLevel); #if WINDOWS_APP || WINDOWS_PHONE_APP Windows.Foundation.Point pixel; #elif WPF || WINDOWS_PHONE System.Windows.Point pixel; #endif //Itirate through the data for (int i = 0; i < _items.Count; i++) { var entity = _items[i]; pixel = pixels[i]; if (pixel.X < -ClusterRadius) { pixel.X += tileZoomRatio; } else if (pixel.X > maxX + ClusterRadius) { pixel.X -= tileZoomRatio; } //Check to see if the pin is within the bounds of the viewable map if (pixel != null && pixel.X <= maxX && pixel.Y <= maxY && pixel.X >= -ClusterRadius && pixel.Y >= -ClusterRadius) { var cluster = (from c in clusteredData where (pixel.Y >= c.Top && pixel.Y <= c.Bottom && ((c.Left <= c.Right && pixel.X >= c.Left && pixel.X <= c.Right) || (c.Left >= c.Right && (pixel.X >= c.Left || pixel.X <= c.Right)))) select c).FirstOrDefault(); //If entity is not in a cluster then it does not fit an existing cluster if (cluster == null)//!IsInCluster) { cluster = new ClusteredPoint() { Location = _allLocations[i], Left = pixel.X - ClusterRadius, Right = pixel.X + ClusterRadius, Top = pixel.Y - ClusterRadius, Bottom = pixel.Y + ClusterRadius, Zoom = _currentZoomLevel, ItemIndices = new List <int>() { i } }; if (cluster.Left < 0) { cluster.Left += tileZoomRatio; } if (cluster.Right > tileZoomRatio) { cluster.Right -= tileZoomRatio; } clusteredData.Add(cluster); } else { cluster.ItemIndices.Add(i); } } } } return(clusteredData.ToArray()); }); }
private async Task CalculateGridClusters(List <System.Windows.Point> pixels, System.Windows.Point centerPixel) #endif { int gridSize = ClusterRadius * 2; int numXCells = (int)Math.Ceiling(_map.ActualWidth / gridSize); int numYCells = (int)Math.Ceiling(_map.ActualHeight / gridSize); int maxX = (int)Math.Ceiling(_map.ActualWidth + ClusterRadius); int maxY = (int)Math.Ceiling(_map.ActualHeight + ClusterRadius); //grid should be relative to 0,0 (lat,lon), not top-left corner of map, so that panning //doesn't cause items to move to different clusters and therefore cluster markers move //if placement is GridCenter var gridBaseX = centerPixel.X % gridSize; var gridBaseY = centerPixel.Y % gridSize; clusters = await Task.Run <ClusteredPoint[]>(() => { int numCells = numXCells *numYCells; ClusteredPoint[] clusteredData = new ClusteredPoint[numCells]; #if WINDOWS_APP || WINDOWS_PHONE_APP Windows.Foundation.Point pixel; #elif WPF || WINDOWS_PHONE System.Windows.Point pixel; #endif int k, j, key; //Itirate through the data for (int i = 0; i < _items.Count; i++) { var entity = _items[i]; pixel = pixels[i]; //Check to see if the pin is within the bounds of the viewable map if (pixel != null && pixel.X <= maxX && pixel.Y <= maxY && pixel.X >= -ClusterRadius && pixel.Y >= -ClusterRadius) { //calculate the grid position on the map of where the location is located k = (int)Math.Floor((pixel.X - gridBaseX) / gridSize); j = (int)Math.Floor((pixel.Y - gridBaseY) / gridSize); //calculates the grid location in the array key = k + j *numXCells; if (key >= 0 && key < numCells) { if (clusteredData[key] == null) { clusteredData[key] = new ClusteredPoint() { Location = _allLocations[i], ItemIndices = new List <int>() { i }, Zoom = _currentZoomLevel, Left = k *gridSize, Top = j *gridSize, Bottom = (j + 1) * gridSize, Right = (k + 1) * gridSize }; } else { clusteredData[key].ItemIndices.Add(i); } } } } return(clusteredData); }); }