ThinkGeo.com    |     Documentation    |     Premium Support

GridFeatureSource.GenerateGrid is slow

Hello,



I’ve a helper function to create grid file which uses Thinkgeo GridFeatureSource.GenerateGrid




internal static string CreateGridCellFile(Dictionary
<pointshape,>double> points, double rowCount,</pointshape,>


    double columnCount, double ignoreValue, RectangleShape extend, int id)
{
    var gridPath = Path.Combine(TempFolderHelper.Folder, string.Format(@"{0}.grid", id));
 
    var extent = new RectangleShape(
        new PointShape(extend.UpperLeftPoint.X - extend.Width*.1, extend.UpperLeftPoint.Y + .1*extend.Height),
        new PointShape(extend.LowerRightPoint.X + extend.Width*.1,
            extend.LowerRightPoint.Y - .1*extend.Height));
 
    var cellSize = Math.Min(extent.Width/columnCount, extent.Height/rowCount);
    var gridDefinition = new GridDefinition(extent, cellSize, ignoreValue, points);
    FileStream writer = null;
    try
    {
        writer = new FileStream(gridPath, FileMode.Create);
        GridFeatureSource.GenerateGrid(gridDefinition,
            new InverseDistanceWeightedGridInterpolationModel(5, cellSize*4), writer);
    }
    finally
    {
        if (writer != null) writer.Close();
    }
    return gridPath;}


The problem is when number of rows and columns is large (for instance 500) grid generation takes ages. Just wondering is there any way to make it faster? for example using multi-threading internally or any other way? Because it is that slow that user give up eventually.



Thanks in advanced,

Regards

Shahin 




Hi Shahin, 
  
 In fact we are using multi-threading to calculate grid file. 
  
 When you increase points number or row/column count the speed will more slow. 
  
 I did a quickly test and the result shows the relationships between the sample points number and cost time: 
  
 Change points Number, row = column = 500: 
 60    The time is: 1.2829258 seconds 
 600   The time is: 3.2229654 seconds 
 6000  The time is: 24.5317369 seconds 
 60000 The time is: 245.3421401 seconds 
  
 Change row/column number, points number = 600: 
 100   The time is: 0.1872314 seconds 
 200   The time is: 0.5447509 seconds 
 500   The time is: 3.3636499 seconds 
 1000  The time is: 13.4287454 seconds 
  
 Other test parameter is RectangleShape(-139.2, 90, 120.9, -90), point value between 0 ~ 300. 
  
 I watch the CPU usage, it nearly take 100% for this calculate. 
  
 I wish the test is helpful for your optimize, and we will do some research to see whether we can improve performance in the algorithm.  
  
 Regards, 
  
 Don 
  
  
  
internal static string CreateGridCellFile(Dictionary<PointShape, double> points, double rowCount, double columnCount, double ignoreValue, RectangleShape extend, int id)
        {            
            var gridPath = @"D:\test.grid";

            var extent = new RectangleShape(
                new PointShape(extend.UpperLeftPoint.X - extend.Width * .1, extend.UpperLeftPoint.Y + .1 * extend.Height),
                new PointShape(extend.LowerRightPoint.X + extend.Width * .1,
                    extend.LowerRightPoint.Y - .1 * extend.Height));

            var cellSize = Math.Min(extent.Width / columnCount, extent.Height / rowCount);
            var gridDefinition = new GridDefinition(extent, cellSize, ignoreValue, points);
            FileStream writer = null;
            try
            {
                writer = new FileStream(gridPath, FileMode.Create);
                Stopwatch sw = new Stopwatch();
                sw.Start();
                GridFeatureSource.GenerateGrid(gridDefinition,
                    new InverseDistanceWeightedGridInterpolationModel(5, cellSize * 4), writer);
                sw.Stop();
                Debug.WriteLine("The time is: " + sw.Elapsed.TotalSeconds + " seconds");
            }
            finally
            {
                if (writer != null) writer.Close();
            }
            return gridPath;
        }

        private void GenerateLayers(LayerOverlay overlay, int number)
        {
            for (int i = 0; i < number; i++)
            {
                ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"…\SampleData\Data\Countries02.shp", ShapeFileReadWriteMode.ReadOnly);
                worldLayer.Name = i.ToString();
                worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
                worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

                overlay.Layers.Add(worldLayer);
            }
        }

        internal Dictionary<PointShape, double> CalculateRandomList(int number, RectangleShape extent, double minValue, double maxValue)
        {
            Dictionary<PointShape, double> points = new Dictionary<PointShape, double>();

            Random random = new Random();

            for (int i = 0; i < number; i++)
            {
                double x = extent.LowerLeftPoint.X + random.NextDouble() * (extent.UpperRightPoint.X - extent.LowerLeftPoint.X);
                double y = extent.LowerLeftPoint.Y + random.NextDouble() * (extent.UpperRightPoint.Y - extent.LowerLeftPoint.Y);

                PointShape point = new PointShape(x, y);

                double value = minValue + random.NextDouble() * (maxValue - minValue);

                points.Add(point, value);
            }

            return points;
        }

        private void WpfMap_Loaded(object sender, RoutedEventArgs e)
        {
            RectangleShape extent = new RectangleShape(-139.2, 90, 120.9, -90);

            Dictionary<PointShape, double> points = CalculateRandomList(600, extent, 0, 300);

            CreateGridCellFile(points, 1000, 1000, -9999, extent, 0);
        }