コード例 #1
0
        /// <summary>
        /// Calculate the visual magintude from a viewpoint.
        /// </summary>
        /// <param name="viewpoint">Viewpoint</param>
        /// <param name="losMap">LOS map</param>
        private void CalculateVisualMagnitude(SpatialUtils.ViewpointProps viewpoint, GeoMap losMap)
        {
            double visualMagnitude;

            spatialUtils.Viewpoint = viewpoint;
            viewpoint.Elevation    = elevationMap[viewpoint.Y, viewpoint.X] + viewpoint.ElevationOffset;

            losMap[viewpoint.Y, viewpoint.X] = GeoMap.UndefinedValue; //initialize LOS of the viewpoint

            //find out the maximum distance to the edge of map
            int maxDistance = GetMaximumDistance(viewpoint);

            for (int i = 1 + omittedRings; i < maxDistance; i++)
            {
                GeoMap.Ring ring = elevationMap.GetRing(viewpoint.Y, viewpoint.X, i);
                foreach (int[] item in ring)
                {
                    if (spatialUtils.IsCellVisible(losMap, item[0], item[1]))
                    {
                        visualMagnitude = spatialUtils.GetVisualMagnitude(item[0], item[1]);
                        if (visualMagnitude > 0)
                        {
                            sumator.AddResult(new Sumator.VisualMagnitudeResult()
                            {
                                Y = item[0],
                                X = item[1],
                                VisualMagnitude = visualMagnitude,
                                Weight          = viewpoint.Weight
                            });
                        }
                    }
                }
            }
        }
コード例 #2
0
 /// <summary>
 /// Contructor to initialize the worker.
 /// </summary>
 /// <param name="workQueue">Work queue share amon workers.</param>
 /// <param name="elevationMap">Elevation map</param>
 /// <param name="sumator">Sumator instance</param>
 /// <param name="parent">Work manager</param>
 public VisualMagnitudeWorker(ref ConcurrentQueue <SpatialUtils.ViewpointProps> workQueue, ref GeoMap elevationMap, ref Sumator sumator, WorkManager parent)
 {
     spatialUtils      = new SpatialUtils(ref elevationMap);
     this.workQueue    = workQueue;
     this.elevationMap = elevationMap;
     this.sumator      = sumator;
     this.parent       = parent;
 }
コード例 #3
0
        /// <summary>
        /// Start processing the work queue.
        /// </summary>
        public void Start()
        {
            GeoMap losMap = new GeoMap(elevationMap.GetLength(0), elevationMap.GetLength(1));

            while (workQueue.TryDequeue(out SpatialUtils.ViewpointProps viewpoint))
            {
                System.Diagnostics.Debug.WriteLine(workQueue.Count + " left");
                CalculateVisualMagnitude(viewpoint, losMap);
            }
            System.Diagnostics.Debug.WriteLine("ThreadDone");
            parent.ThreadFinished();
        }
コード例 #4
0
        /// <summary>
        /// Create a mock map for testing purposes.
        /// </summary>
        /// <param name="dimensionY">Y length</param>
        /// <param name="dimensionX">X length</param>
        /// <returns>Mocked GeoMap</returns>
        public static GeoMap CreateMock(int dimensionY, int dimensionX)
        {
            GeoMap map = new GeoMap(dimensionY, dimensionX);
            Random rnd = new Random();

            for (int y = 0; y < dimensionY; y++)
            {
                for (int x = 0; x < dimensionX; x++)
                {
                    map[y, x] = y;
                }
            }
            return(map);
        }
コード例 #5
0
 /// <summary>
 /// Start calculationg the visual magnitude.
 /// </summary>
 /// <param name="elevationMap">Elevation map</param>
 public void StartWorking(ref GeoMap elevationMap)
 {
     sumator = new Sumator(elevationMap.GetLength(0), elevationMap.GetLength(1));
     sumator.Start();
     startingQueueSize = workQueue.Count;
     runningThreads    = threadCount;
     for (int i = 0; i < threadCount; i++)
     {
         VisualMagnitudeWorker worker = new VisualMagnitudeWorker(ref workQueue, ref elevationMap, ref sumator, this);
         Thread thread = new Thread(worker.Start);
         threads[i] = thread;
         thread.Start();
     }
 }
コード例 #6
0
        /// <summary>
        /// Convert the DEM raster to internal elevation map.
        /// </summary>
        /// <param name="raster">DEM raster</param>
        /// <returns>Elevation map</returns>
        private GeoMap CreateElevationMap(Raster raster)
        {
            PixelBlock currentPixelBlock = raster.CreatePixelBlock(raster.GetWidth(), raster.GetHeight());

            raster.Read(0, 0, currentPixelBlock);

            Array pixels = currentPixelBlock.GetPixelData(0, false);

            GeoMap elevationMap             = new GeoMap(raster.GetHeight(), raster.GetWidth());
            Tuple <double, double> cellSize = raster.GetMeanCellSize();

            /*if (Math.Abs(cellSize.Item1-cellSize.Item2) < cellSize.Item1*0.05) {
             *  MessageBox.Show("Cells are not squares. Using X size of cells.", "Rectuangular cells", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
             * }*/
            elevationMap.CellSize = cellSize.Item1;
            elevationMap.ImportData(pixels);
            return(elevationMap);
        }
コード例 #7
0
        /// <summary>
        /// Determine if the cell is visible from the viewpoint. All cells in LOS cell-viewpoint have to be previously calculated and present in LOS map.
        /// </summary>
        /// <param name="losMap">Map which contains LOS values of the cells</param>
        /// <param name="cellY">Y coordinate of the cell</param>
        /// <param name="cellX">X coordinate of the cell</param>
        /// <returns></returns>
        public bool IsCellVisible(GeoMap losMap, int cellY, int cellX)
        {
            Orientation cellOrientation = GetCellOrientation(cellY, cellX);

            GetNeighborCells(cellY, cellX, cellOrientation, out int adjacentY, out int adjacentX, out int offsetY, out int offsetX);

            double adjacentWeight = InterpolateWeight(cellY, cellX, cellOrientation);

            double viewingLos = GetViewingSlope(cellY, cellX);
            double cellLos    = losMap[adjacentY, adjacentX] * adjacentWeight + losMap[offsetY, offsetX] * (1 - adjacentWeight);

            if (viewingLos > cellLos)
            {
                losMap[cellY, cellX] = cellLos;
                return(false);
            }
            else
            {
                losMap[cellY, cellX] = viewingLos;
                return(true);
            }
        }
コード例 #8
0
 /// <summary>
 /// Constructor. Initialize the class with an elevation map.
 /// </summary>
 /// <param name="elevationMap">Elevtion map</param>
 public SpatialUtils(ref GeoMap elevationMap)
 {
     cellResolution = elevationMap.CellSize;
     ElevationMap   = elevationMap;
 }
コード例 #9
0
        /// <summary>
        /// Asynchrnously start the visual magnitude analysis.
        /// </summary>
        public async void StartAnalysis()
        {
            if (!ValidateInputLayers())
            {
                return;
            }
            outputFolder = CreateOutputDirectory(outputFolderName);
            if (File.Exists(outputFolder + "/" + SettingsManager.Instance.CurrentSettings.OutputFilename))
            {
                System.Windows.MessageBoxResult messageResult = MessageBox.Show("The output file already exists and will be overwritten. Continue?", "File exists!", System.Windows.MessageBoxButton.OKCancel, System.Windows.MessageBoxImage.Warning);
                if (messageResult == System.Windows.MessageBoxResult.OK)
                {
                    GarbageHelper.Instance.AddGarbage(outputFolder + "/" + SettingsManager.Instance.CurrentSettings.OutputFilename);
                    GarbageHelper.Instance.CleanUp();
                }
                else
                {
                    return;
                }
            }

            if (File.Exists(outputFolder + "/" + tmpRasterName))
            {
                GarbageHelper.Instance.AddGarbage(outputFolder + "/" + tmpRasterName);
                GarbageHelper.Instance.CleanUp();
            }

            ///most tasks have to run on MCT thread
            await QueuedTask.Run(async() => {
                outputFolder = CreateOutputDirectory(outputFolderName);
                FileSystemDatastore outputDataStore = CreateNewDatastore();

                //get viewpoints
                Raster raster         = SettingsManager.Instance.SelectedDemLayer.GetRaster();
                Projection projection = new Projection(raster, outputFolder); //make the detection automatic
                try {
                    if (await projection.CalculateViewpoints(SettingsManager.Instance.SelectedViewpointLayer) == false)
                    {
                        MessageBox.Show("Invalid viewpoint layer type.\nOnly points, lines and polylines are supported.", "Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                        return;
                    }
                } catch (Exception) {
                    if (!SettingsManager.Instance.CurrentSettings.OffsetGlobal)
                    {
                        MessageBox.Show("Invalid viewpoint data. Do the viewpoints have OFFSET column specified?", "Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                    }
                    else if (SettingsManager.Instance.CurrentSettings.WeightedViewpoints)
                    {
                        MessageBox.Show("Invalid viewpoint data. Do the viewpoints have WEIGHT column specified?", "Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                    }
                    else
                    {
                        MessageBox.Show("Invalid viewpoint data.", "Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                    }
                    return;
                }

                GeoMap elevationMap = CreateElevationMap(raster);

                //initialize work manager
                WorkManager workManager    = new WorkManager(SettingsManager.Instance.CurrentSettings.WorkerThreads);
                int invalidViewpointsCount = 0;
                foreach (SpatialUtils.ViewpointProps viewpoint in projection)
                {
                    if (viewpoint.Y < 0 || viewpoint.X < 0)
                    {
                        invalidViewpointsCount++;
                    }
                    else
                    {
                        if (SettingsManager.Instance.CurrentSettings.OffsetGlobal)
                        {
                            viewpoint.ElevationOffset = SettingsManager.Instance.CurrentSettings.AltOffset;
                        }
                        workManager.AddWork(viewpoint);
                    }
                }
                if (invalidViewpointsCount > 0)
                {
                    string message = invalidViewpointsCount.ToString()
                                     + (invalidViewpointsCount == 1
                            ? " viewpoint was invalid or failed to process."
                            : " viewpoints were invalid or failed to process.");
                    MessageBox.Show(message, "Ignored viewpoints", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Warning);
                }

                //wait for the calculation of the visual magnitude for all viewpoints to finish
                var watch = System.Diagnostics.Stopwatch.StartNew();
                workManager.StartWorking(ref elevationMap);
                WorkManager.AutoEvent.WaitOne();
                GeoMap result = workManager.GetResult();
                MessageBox.Show("Computation finished\n------------\nTime: " + watch.ElapsedMilliseconds / 1000 + " seconds\nViewpoints: " + projection.GetViewpointsCount(), "Finished", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);

                //save and display the result
                try {
                    WriteToRaster(raster, outputDataStore, result);
                } catch (Exception) {
                    MessageBox.Show("Cannot write data to raster.", "Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                }

                LayerFactory.Instance.CreateLayer(new Uri(Path.Combine(outputFolder, SettingsManager.Instance.CurrentSettings.OutputFilename)),
                                                  MapView.Active.Map);

                //clean up temporary files
                GarbageHelper.Instance.CleanUp();
            });
        }
コード例 #10
0
        /// <summary>
        /// Write results to a rester.
        /// </summary>
        /// <param name="raster">DEM raster</param>
        /// <param name="outputDataStore">Output datastore</param>
        /// <param name="result">Elevation map with resuluts</param>
        private void WriteToRaster(Raster raster, FileSystemDatastore outputDataStore, GeoMap result)
        {
            raster.SetNoDataValue(0);
            raster.SetPixelType(RasterPixelType.DOUBLE);
            RasterDataset resultRasterDataset = raster.SaveAs(tmpRasterName, outputDataStore, rasterFormat);

            GarbageHelper.Instance.AddGarbage(Path.Combine(outputFolder, tmpRasterName));
            Raster resultRaster = resultRasterDataset.CreateRaster(new int[1] {
                0
            });

            resultRaster.Refresh();

            if (!resultRaster.CanEdit())
            {
                MessageBox.Show("Cannot write to raster", "Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                return;
            }
            PixelBlock pixelBlock = resultRaster.CreatePixelBlock(resultRaster.GetWidth(), resultRaster.GetHeight());

            resultRaster.Read(0, 0, pixelBlock);
            pixelBlock.Clear(0);
            Array pixel = new double[resultRaster.GetWidth(), resultRaster.GetHeight()];

            pixelBlock.SetPixelData(0, result.Transpose());

            resultRaster.Write(0, 0, pixelBlock);
            resultRaster.Refresh();
            resultRaster.SaveAs(SettingsManager.Instance.CurrentSettings.OutputFilename, outputDataStore, rasterFormat);
        }
コード例 #11
0
ファイル: Sumator.cs プロジェクト: czechflek/VisualMagnitude
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="dimensionY">Y size of the map</param>
 /// <param name="dimensionX">X size of the map</param>
 public Sumator(int dimensionY, int dimensionX)
 {
     VisualMagnitudeMap = new GeoMap(dimensionY, dimensionX);
     VisualMagnitudeMap.Initialize();
 }