Пример #1
0
        private static NeighborhoodType[] GetNeighborhoodTypes()
        {
            var types = new NeighborhoodType[256];

            for (uint mask = 0; mask < 256; ++mask)
            {
                var TL = (mask & 1) != 0;
                var TC = (mask & 2) != 0;
                var TR = (mask & 4) != 0;
                var CL = (mask & 8) != 0;
                var CR = (mask & 16) != 0;
                var BL = (mask & 32) != 0;
                var BC = (mask & 64) != 0;
                var BR = (mask & 128) != 0;

                var count = MathEx.CountBits(mask);

                var diagonal   = !TC && !CL && TL || !CL && !BC && BL || !BC && !CR && BR || !CR && !TC && TR;
                var horizontal = !TC && !BC && (TR || CR || BR) && (TL || CL || BL);
                var vertical   = !CL && !CR && (TL || TC || TR) && (BL || BC || BR);
                var end        = count == 1;

                if (end)
                {
                    types[mask] = NeighborhoodType.Ending;
                }
                else if (!diagonal && !horizontal && !vertical)
                {
                    types[mask] = NeighborhoodType.Removable;
                }
            }

            return(types);
        }
Пример #2
0
        static NeighborhoodType[] NeighborhoodTypes()
        {
            var types = new NeighborhoodType[256];

            for (uint mask = 0; mask < 256; ++mask)
            {
                bool TL         = (mask & 1) != 0;
                bool TC         = (mask & 2) != 0;
                bool TR         = (mask & 4) != 0;
                bool CL         = (mask & 8) != 0;
                bool CR         = (mask & 16) != 0;
                bool BL         = (mask & 32) != 0;
                bool BC         = (mask & 64) != 0;
                bool BR         = (mask & 128) != 0;
                uint count      = Integers.PopulationCount(mask);
                bool diagonal   = !TC && !CL && TL || !CL && !BC && BL || !BC && !CR && BR || !CR && !TC && TR;
                bool horizontal = !TC && !BC && (TR || CR || BR) && (TL || CL || BL);
                bool vertical   = !CL && !CR && (TL || TC || TR) && (BL || BC || BR);
                bool end        = (count == 1);
                if (end)
                {
                    types[mask] = NeighborhoodType.Ending;
                }
                else if (!diagonal && !horizontal && !vertical)
                {
                    types[mask] = NeighborhoodType.Removable;
                }
            }
            return(types);
        }
Пример #3
0
        static NeighborhoodType[] GetNeighborhoodTypes()
        {
            var types = new NeighborhoodType[256];
            for (uint mask = 0; mask < 256; ++mask)
            {
                bool TL = (mask & 1) != 0;
                bool TC = (mask & 2) != 0;
                bool TR = (mask & 4) != 0;
                bool CL = (mask & 8) != 0;
                bool CR = (mask & 16) != 0;
                bool BL = (mask & 32) != 0;
                bool BC = (mask & 64) != 0;
                bool BR = (mask & 128) != 0;

                int count = MathEx.CountBits(mask);

                bool diagonal = !TC && !CL && TL || !CL && !BC && BL || !BC && !CR && BR || !CR && !TC && TR;
                bool horizontal = !TC && !BC && (TR || CR || BR) && (TL || CL || BL);
                bool vertical = !CL && !CR && (TL || TC || TR) && (BL || BC || BR);
                bool end = (count == 1);

                if (end)
                    types[mask] = NeighborhoodType.Ending;
                else if (!diagonal && !horizontal && !vertical)
                    types[mask] = NeighborhoodType.Removable;
            }
            return types;
        }
Пример #4
0
        /// <summary>
        /// Is called by SimPe (through the Wrapper) when the Panel is going to be displayed, so
        /// you should updatet the Data displayed by the Panel with the Attributes stored in the
        /// passed Wrapper.
        /// </summary>
        /// <param name="wrapper">The Attributes of this Wrapper have to be displayed</param>
        public void UpdateGUI(IFileWrapper wrapper)
        {
            Idno wrp = (Idno)wrapper;

            form.wrapper = null;
            form.Tag     = true;

            try
            {
                form.cbtype.SelectedIndex = 0;
                for (int i = 0; i < form.cbtype.Items.Count; i++)
                {
                    NeighborhoodType lt = (NeighborhoodType)form.cbtype.Items[i];
                    if (lt == wrp.Type)
                    {
                        form.cbtype.SelectedIndex = i;
                        break;
                    }
                }
                form.tbtype.Text = "0x" + Helper.HexString((byte)wrp.Type);

                form.tbversion.Text = "0x" + Helper.HexString((uint)wrp.Version);
                form.lbVer.Text     = wrp.Version.ToString().Replace("_", " ");

                form.tbid.Text      = wrp.Uid.ToString();
                form.tbname.Text    = wrp.OwnerName;
                form.tbsubname.Text = wrp.SubName;

                form.wrapper = wrp;
            }
            finally
            {
                form.Tag = null;
            }
        }
Пример #5
0
        /// <summary>
        /// Once the Parameter have been configured the Execute command can be called, it returns true if succesful
        /// </summary>
        public override bool Execute(ICancelProgressHandler cancelProgressHandler)
        {
            IFeatureSet input = _inputParam[0].Value as IFeatureSet;

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

            input.FillAttributes();
            ListParam lp = _inputParam[1] as ListParam;

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

            string           zField       = lp.ValueList[lp.Value];
            double           cellSize     = (double)_inputParam[2].Value;
            double           power        = (double)_inputParam[3].Value;
            NeighborhoodType neighborType = _inputParam[4].Value as string == TextStrings.FixedDistance
                                                ? NeighborhoodType.FixedDistance
                                                : NeighborhoodType.FixedCount;
            int     pointCount = (int)_inputParam[5].Value;
            double  distance   = (double)_inputParam[6].Value;
            IRaster output     = _outputParam[0].Value as IRaster;

            return(Execute(
                       input, zField, cellSize, power, neighborType, pointCount, distance, output, cancelProgressHandler));
        }
Пример #6
0
        private static string LoadLabel(SimPe.Packages.File pk, out NeighborhoodType type)
        {
            string name = SimPe.Localization.GetString("Unknown");

            type = NeighborhoodType.Unknown;
            try
            {
                SimPe.Interfaces.Files.IPackedFileDescriptor pfd = pk.FindFile(0x43545353, 0, 0xffffffff, 1);
                if (pfd != null)
                {
                    SimPe.PackedFiles.Wrapper.Str str = new SimPe.PackedFiles.Wrapper.Str();
                    str.ProcessData(pfd, pk);
                    name = str.LanguageItems(new SimPe.PackedFiles.Wrapper.StrLanguage((byte)Data.MetaData.Languages.English))[0].Title;
                }

                pfd = pk.FindFile(0xAC8A7A2E, 0, 0xffffffff, 1);
                if (pfd != null)
                {
                    SimPe.Plugin.Idno idno = new Idno();
                    idno.ProcessData(pfd, pk);
                    type = idno.Type;
                }
                //pk.Reader.Close();
            }
            finally
            {
                //pk.Reader.Close();
            }
            return(name);
        }
Пример #7
0
        /// <summary>
        /// Constructor
        /// </summary>
        public Idno() : base()
        {
            if (SimPe.PathProvider.Global.EPInstalled >= 1)
            {
                this.version = (uint)NeighborhoodVersion.Sims2_University;
            }
            else
            {
                this.version = (uint)NeighborhoodVersion.Sims2;
            }

            this.type = NeighborhoodType.Normal;
            over      = new byte[0];

            uid     = 0;
            name    = "Nxxx";
            subname = "";
        }
Пример #8
0
        private void SelectType(object sender, System.EventArgs e)
        {
            if (cbtype.SelectedIndex < 0)
            {
                return;
            }

            NeighborhoodType nt = (NeighborhoodType)cbtype.Items[cbtype.SelectedIndex];

            if (nt != NeighborhoodType.Unknown)
            {
                this.tbtype.Text = "0x" + Helper.HexString((uint)nt);
            }

            tbsubname.Enabled = (nt == NeighborhoodType.University);

            if (this.Tag != null)
            {
                return;
            }
            wrapper.Type    = nt;
            wrapper.Changed = true;
        }
Пример #9
0
        /// <summary>
        /// Unserializes a BinaryStream into the Attributes of this Instance
        /// </summary>
        /// <param name="reader">The Stream that contains the FileData</param>
        protected override void Unserialize(System.IO.BinaryReader reader)
        {
            version = reader.ReadUInt32();
            int ct = reader.ReadInt32();

            name = Helper.ToString(reader.ReadBytes(ct));
            uid  = reader.ReadUInt32();

            if (version >= (int)NeighborhoodVersion.Sims2_University)
            {
                type = (NeighborhoodType)reader.ReadUInt32();
                if ((int)type >= (int)NeighborhoodType.University)
                {
                    ct      = reader.ReadInt32();
                    subname = Helper.ToString(reader.ReadBytes(ct));
                }
            }
            else
            {
                type = NeighborhoodType.Normal;
            }
            over = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position));
        }
Пример #10
0
        /// <summary>
        /// Executes the Area tool with programatic input
        /// Ping delete static for external testing
        /// </summary>
        /// <param name="input">The input raster</param>
        /// <param name="output">The output polygon feature set</param>
        /// <param name="zField">The field name containing the values to interpolate</param>
        /// <param name="cellSize">The double geographic size of the raster cells to create</param>
        /// <param name="power">The double power representing the inverse</param>
        /// <param name="neighborType">Fixed distance of fixed number of neighbors</param>
        /// <param name="pointCount">The number of neighbors to include if the neighborhood type
        /// is Fixed</param>
        /// <param name="distance">Points further from the raster cell than this distance are not included 
        /// in the calculation if the neighborhood type is Fixed Distance.</param>
        /// <param name="output">The output raster where values are stored.  The filename is used, but the number
        /// of rows and columns will be computed from the cellSize and input featureset</param>
        /// <param name="cancelProgressHandler">A progress handler for receiving progress messages</param>
        /// <returns>A boolean, true if the IDW process worked correctly</returns>
        public bool Execute(IFeatureSet input, string zField, double cellSize, double power, NeighborhoodType neighborType, int pointCount, double distance, IRaster output, ICancelProgressHandler cancelProgressHandler)
        {
           
            //Validates the input and output data
            if (input == null || output == null)
                return false;

            //If the cellSize is 0 we calculate a cellsize based on the input extents
            if (cellSize == 0)
                cellSize = input.Envelope.Width / 255;

            //Defines the dimesions and position of the raster
            int numColumns = Convert.ToInt32(Math.Round(input.Envelope.Width / cellSize));
            int numRows = Convert.ToInt32(Math.Round(input.Envelope.Height / cellSize));
          
            output = Raster.Create(output.Filename, "",numColumns, numRows, 1, typeof(double), new[] {""} );

            output.CellHeight = cellSize;
            output.CellWidth = cellSize;
            output.Xllcenter = input.Envelope.Minimum.X + (cellSize/2);
            output.Yllcenter = input.Envelope.Minimum.Y + (cellSize/2);

            //Used to calculate progress
            int lastUpdate=0;

            //Populates the KD tree
            MapWindow.Analysis.Topology.KDTree.KDTree kd = new MapWindow.Analysis.Topology.KDTree.KDTree(2);
            List<int> randomList = new List<int>();
            for (int i = 0; i < input.Features.Count; i++)
            {
                randomList.Add(i);
            }

            Random rnd = new Random();
            List<int> completed = new List<int>();
            while (randomList.Count > 0)
            {
                int index = rnd.Next(0,randomList.Count -1);
                Coordinate coord = input.Features[randomList[index]].Coordinates[0];
                while (kd.Search(coord.ToArray()) != null)
                    coord.X = coord.X * 1.000000000000001D;                    
                kd.Insert(coord.ToArray(), input.Features[randomList[index]]);
                completed.Add(randomList[index]);
                randomList.RemoveAt(index);
            }

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            //Makes sure we don't try to search for more points then exist
            if (kd.Count < pointCount)
                pointCount = kd.Count;

            if (neighborType == NeighborhoodType.FixedCount)
            {
                //we add all the old features to output
                for (int x = 0; x < numColumns; x++)
                {
                    for (int y = 0; y < numRows; y++)
                    {                     
                        //Gets the pointCount number of cells closest to the current cell
                        Coordinate cellCenter = output.CellToProj(y, x);
                        Double[] pixelCoord = new double[2];
                        pixelCoord[0] = output.CellToProj(y, x).X;
                        pixelCoord[1] = output.CellToProj(y, x).Y;
                        sw.Start();
                        object[] result = kd.Nearest(pixelCoord, pointCount);
                        sw.Stop();

                        //Sets up the IDW numerator and denominator
                        double top = 0;
                        double bottom = 0;
                        foreach (object feat in result)
                        {
                              IFeature featurePt = feat as Feature;
                              if (featurePt == null) continue;
                              double distanceToCell = cellCenter.Distance(featurePt.Coordinates[0]);
                              if (distanceToCell <= distance || distance == 0)
                              {
                                  //If we can't convert the value to a double throw it out
                                  try
                                  {
                                      Convert.ToDouble(featurePt.DataRow[zField]);
                                  }
                                  catch
                                  {
                                      continue;
                                  }

                                  if (power == 2)
                                  {
                                      top += (1 / (distanceToCell * distanceToCell)) * Convert.ToDouble(featurePt.DataRow[zField]);
                                      bottom += (1 / (distanceToCell* distanceToCell));
                                  }
                                  else
                                  {
                                      top += (1 / Math.Pow(distanceToCell, power)) * Convert.ToDouble(featurePt.DataRow[zField]);
                                      bottom += (1 / Math.Pow(distanceToCell, power));
                                  }
                              }
                        }

                        output.Value[y, x] = top / bottom;
                    }

                    //Checks if we need to update the status bar
                    if (Convert.ToInt32(Convert.ToDouble(x*numRows ) / Convert.ToDouble(numColumns * numRows) * 100) > lastUpdate)
                    {
                        lastUpdate = Convert.ToInt32(Convert.ToDouble(x * numRows) / Convert.ToDouble(numColumns * numRows) * 100);
                        cancelProgressHandler.Progress("", lastUpdate, "Cell: " + (x * numRows) + " of " + (numColumns * numRows));
                        if (cancelProgressHandler.Cancel)
                        return false;
                    }
                }
                System.Diagnostics.Debug.WriteLine(sw.ElapsedMilliseconds);
            }

            output.Save();
            return true;
        }
Пример #11
0
        public static uint ClassifyTile(Grid <float> inputBuffer, uint[,] outputBuffer, float maxHeightDiffBetweenPixels, uint currentClassIndexSpanningTiles, uint minClusterSize, float noDataVal, NeighborhoodType neighborhoodType)
        {
            int width  = inputBuffer.SizeX;
            int height = inputBuffer.SizeY;

            UInt32 currentClassIndex = 2;

            Dictionary <uint, SortedList <uint, bool> > substitutions = new Dictionary <uint, SortedList <uint, bool> >();
            Dictionary <uint, uint> classPixelCounts = new Dictionary <uint, uint>();

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    UInt32 newClassVal = 0;

                    float thisVal = inputBuffer.Data[x, y];

                    // skip nodata values
                    if (thisVal != noDataVal)
                    {
                        System.Drawing.Point[] coords = new System.Drawing.Point[4];
                        int neighborIndex             = 0;

                        if (y > 0)
                        {
                            coords[neighborIndex++] = new System.Drawing.Point(x, y - 1);
                        }

                        if (x > 0)
                        {
                            coords[neighborIndex++] = new System.Drawing.Point(x - 1, y);
                        }

                        if (neighborhoodType == NeighborhoodType.EightNeighbors)
                        {
                            if (y > 0 && x > 0)
                            {
                                coords[neighborIndex++] = new System.Drawing.Point(x - 1, y - 1);
                            }

                            if (y > 0 && x < width - 1)
                            {
                                coords[neighborIndex++] = new System.Drawing.Point(x + 1, y - 1);
                            }
                        }

                        for (int i = 0; i < neighborIndex; i++)
                        {
                            int neighborX = coords[i].X;
                            int neighborY = coords[i].Y;

                            float neighborVal = inputBuffer.Data[neighborX, neighborY];
                            if (neighborVal != noDataVal)
                            {
                                uint neighborClass = outputBuffer[neighborX, neighborY];
                                if (System.Math.Abs(thisVal - neighborVal) <= maxHeightDiffBetweenPixels)
                                {
                                    if (newClassVal == 0)
                                    {
                                        newClassVal = neighborClass;
                                    }
                                    else
                                    {
                                        newClassVal = DetermineNewClassSubstitution(substitutions, newClassVal, neighborClass);
                                    }
                                }
                            }
                        }

                        if (newClassVal == 0)
                        {
                            newClassVal = currentClassIndex;
                            currentClassIndex++;
                        }
                    }
                    outputBuffer[x, y] = newClassVal;
                }
            }

            // perform substitutions
            uint maxPixelCount = 0;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    uint currentClass = outputBuffer[x, y];
                    if (currentClass > 0)
                    {
                        uint newClass = FindSubstitutePixelClass(substitutions, classPixelCounts, ref maxPixelCount, currentClass);
                        outputBuffer[x, y] = newClass;
                    }
                }
            }

            // filter small clusters (trees and edges)
            if (minClusterSize > 0)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        uint currentClass = outputBuffer[x, y];

                        if (currentClass > 0)
                        {
                            uint count = classPixelCounts[currentClass];
                            uint value = 0;

                            value = currentClass;
                            if (count < minClusterSize)
                            {
                                value = 0;
                            }

                            outputBuffer[x, y] = value;
                        }
                    }
                }
            }

            // Update class indices to reduce max index values and remove duplicates across tiles.
            // This is feasible because small clusters have been filtered out (set to zero).
            Dictionary <uint, uint> classMappingUpdate = new Dictionary <uint, uint>();

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    uint currentClass = outputBuffer[x, y];
                    if (currentClass > 0)
                    {
                        if (!classMappingUpdate.ContainsKey(currentClass))
                        {
                            ++currentClassIndexSpanningTiles;
                            classMappingUpdate.Add(currentClass, currentClassIndexSpanningTiles);
                        }
                        outputBuffer[x, y] = classMappingUpdate[currentClass];
                    }
                }
            }

            return(currentClassIndexSpanningTiles);
        }
Пример #12
0
        /// <summary>
        /// Executes the Area tool with programatic input
        /// Ping delete static for external testing.
        /// </summary>
        /// <param name="input">The input raster.</param>
        /// <param name="zField">The field name containing the values to interpolate.</param>
        /// <param name="cellSize">The double geographic size of the raster cells to create.</param>
        /// <param name="power">The double power representing the inverse.</param>
        /// <param name="neighborType">Fixed distance of fixed number of neighbors.</param>
        /// <param name="pointCount">The number of neighbors to include if the neighborhood type
        /// is Fixed.</param>
        /// <param name="distance">Points further from the raster cell than this distance are not included
        /// in the calculation if the neighborhood type is Fixed Distance.</param>
        /// <param name="output">The output raster where values are stored. The fileName is used, but the number
        /// of rows and columns will be computed from the cellSize and input featureset.</param>
        /// <param name="cancelProgressHandler">A progress handler for receiving progress messages.</param>
        /// <returns>A boolean, true if the IDW process worked correctly.</returns>
        public bool Execute(IFeatureSet input, string zField, double cellSize, double power, NeighborhoodType neighborType, int pointCount, double distance, IRaster output, ICancelProgressHandler cancelProgressHandler)
        {
            // Validates the input and output data
            if (input == null || output == null)
            {
                return(false);
            }

            // If the cellSize is 0 we calculate a cell size based on the input extents
            if (cellSize == 0)
            {
                cellSize = input.Extent.Width / 255;
            }

            // Defines the dimensions and position of the raster
            int numColumns = Convert.ToInt32(Math.Round(input.Extent.Width / cellSize));
            int numRows    = Convert.ToInt32(Math.Round(input.Extent.Height / cellSize));

            output = Raster.CreateRaster(output.Filename, string.Empty, numColumns, numRows, 1, typeof(double), new[] { string.Empty });

            output.CellHeight = cellSize;
            output.CellWidth  = cellSize;
            output.Xllcenter  = input.Extent.MinX + (cellSize / 2);
            output.Yllcenter  = input.Extent.MinY + (cellSize / 2);

            // Used to calculate progress
            int lastUpdate = 0;

            // Populates the KD tree
            var        kd         = new KdTreeEx <IFeature>();
            List <int> randomList = new();

            for (int i = 0; i < input.Features.Count; i++)
            {
                randomList.Add(i);
            }

            Random     rnd       = new();
            List <int> completed = new();

            while (randomList.Count > 0)
            {
                int        index = rnd.Next(0, randomList.Count - 1);
                Coordinate coord = input.Features[randomList[index]].Geometry.Coordinates[0];
                while (kd.Search(coord) != null)
                {
                    coord.X *= 1.000000000000001D;
                }

                kd.Insert(coord, input.Features[randomList[index]]);
                completed.Add(randomList[index]);
                randomList.RemoveAt(index);
            }

            if (neighborType == NeighborhoodType.FixedCount)
            {
                // we add all the old features to output
                for (int x = 0; x < numColumns; x++)
                {
                    for (int y = 0; y < numRows; y++)
                    {
                        // Gets the pointCount number of cells closest to the current cell
                        Coordinate cellCenter = output.CellToProj(y, x);
                        var        coord      = output.CellToProj(y, x);
                        var        result     = kd.NearestNeighbor(coord);
                        var        featurePt  = result?.Data;
                        if (featurePt != null)
                        {
                            // Sets up the IDW numerator and denominator
                            double top    = 0;
                            double bottom = 0;

                            double distanceToCell = cellCenter.Distance(featurePt.Geometry.Coordinates[0]);
                            if (distanceToCell <= distance || distance == 0)
                            {
                                // If we can't convert the value to a double throw it out
                                try
                                {
                                    Convert.ToDouble(featurePt.DataRow[zField]);
                                }
                                catch
                                {
                                    continue;
                                }

                                if (power == 2)
                                {
                                    top    += (1 / (distanceToCell * distanceToCell)) * Convert.ToDouble(featurePt.DataRow[zField]);
                                    bottom += 1 / (distanceToCell * distanceToCell);
                                }
                                else
                                {
                                    top    += (1 / Math.Pow(distanceToCell, power)) * Convert.ToDouble(featurePt.DataRow[zField]);
                                    bottom += 1 / Math.Pow(distanceToCell, power);
                                }
                            }

                            output.Value[y, x] = top / bottom;
                        }
                    }

                    // Checks if we need to update the status bar
                    if (Convert.ToInt32(Convert.ToDouble(x * numRows) / Convert.ToDouble(numColumns * numRows) * 100) > lastUpdate)
                    {
                        lastUpdate = Convert.ToInt32(Convert.ToDouble(x * numRows) / Convert.ToDouble(numColumns * numRows) * 100);
                        cancelProgressHandler.Progress(lastUpdate, "Cell: " + (x * numRows) + " of " + (numColumns * numRows));
                        if (cancelProgressHandler.Cancel)
                        {
                            return(false);
                        }
                    }
                }
            }

            output.Save();
            return(true);
        }
Пример #13
0
        /// <summary>
        /// Executes the Area tool with programatic input
        /// Ping delete static for external testing
        /// </summary>
        /// <param name="input">The input raster</param>
        /// <param name="zField">The field name containing the values to interpolate</param>
        /// <param name="cellSize">The double geographic size of the raster cells to create</param>
        /// <param name="power">The double power representing the inverse</param>
        /// <param name="neighborType">Fixed distance of fixed number of neighbors</param>
        /// <param name="pointCount">The number of neighbors to include if the neighborhood type
        /// is Fixed</param>
        /// <param name="distance">Points further from the raster cell than this distance are not included
        /// in the calculation if the neighborhood type is Fixed Distance.</param>
        /// <param name="output">The output raster where values are stored.  The fileName is used, but the number
        /// of rows and columns will be computed from the cellSize and input featureset</param>
        /// <param name="cancelProgressHandler">A progress handler for receiving progress messages</param>
        /// <returns>A boolean, true if the IDW process worked correctly</returns>
        public bool Execute(IFeatureSet input, string zField, double cellSize, double power, NeighborhoodType neighborType, int pointCount, double distance,
                            IRaster output, ICancelProgressHandler cancelProgressHandler)
        {
            // Validates the input and output data
            if (input == null || output == null)
            {
                return(false);
            }

            // If the cellSize is 0 we calculate a cell size based on the input extents
            if (cellSize == 0)
            {
                cellSize = input.Extent.Width / 255;
            }

            // Defines the dimensions and position of the raster
            int numColumns = Convert.ToInt32(Math.Round(input.Extent.Width / cellSize));
            int numRows    = Convert.ToInt32(Math.Round(input.Extent.Height / cellSize));

            output = Raster.CreateRaster(output.Filename, string.Empty, numColumns, numRows, 1, typeof(double), new[] { string.Empty });

            output.CellHeight = cellSize;
            output.CellWidth  = cellSize;
            output.Xllcenter  = input.Extent.MinX + (cellSize / 2);
            output.Yllcenter  = input.Extent.MinY + (cellSize / 2);

            // Used to calculate progress
            //int lastUpdate = 0;

            //TODO jany_ correct code to work with new KdTree

            //// Populates the KD tree
            //KdTree kd = new KdTree(2);
            //List<int> randomList = new List<int>();
            //for (int i = 0; i < input.Features.Count; i++)
            //{
            //    randomList.Add(i);
            //}

            //Random rnd = new Random();
            //List<int> completed = new List<int>();
            //while (randomList.Count > 0)
            //{
            //    int index = rnd.Next(0, randomList.Count - 1);
            //    Coordinate coord = input.Features[randomList[index]].Geometry.Coordinates[0];
            //    while (kd.Search(coord.ToArray()) != null)
            //    {
            //        coord.X = coord.X * 1.000000000000001D;
            //    }

            //    kd.Insert(coord.ToArray(), input.Features[randomList[index]]);
            //    completed.Add(randomList[index]);
            //    randomList.RemoveAt(index);
            //}

            //// Makes sure we don't try to search for more points then exist
            //if (kd.Count < pointCount)
            //{
            //    pointCount = kd.Count;
            //}

            //if (neighborType == NeighborhoodType.FixedCount)
            //{
            //    // we add all the old features to output
            //    for (int x = 0; x < numColumns; x++)
            //    {
            //        for (int y = 0; y < numRows; y++)
            //        {
            //            // Gets the pointCount number of cells closest to the current cell
            //            Coordinate cellCenter = output.CellToProj(y, x);
            //            Double[] pixelCoord = new double[2];
            //            pixelCoord[0] = output.CellToProj(y, x).X;
            //            pixelCoord[1] = output.CellToProj(y, x).Y;
            //            object[] result = kd.Nearest(pixelCoord, pointCount);

            //            // Sets up the IDW numerator and denominator
            //            double top = 0;
            //            double bottom = 0;
            //            foreach (object feat in result)
            //            {
            //                IFeature featurePt = feat as Feature;
            //                if (featurePt == null)
            //                {
            //                    continue;
            //                }

            //                double distanceToCell = cellCenter.Distance(featurePt.Geometry.Coordinates[0]);
            //                if (distanceToCell <= distance || distance == 0)
            //                {
            //                    // If we can't convert the value to a double throw it out
            //                    try
            //                    {
            //                        Convert.ToDouble(featurePt.DataRow[zField]);
            //                    }
            //                    catch
            //                    {
            //                        continue;
            //                    }

            //                    if (power == 2)
            //                    {
            //                        top += (1 / (distanceToCell * distanceToCell))
            //                               * Convert.ToDouble(featurePt.DataRow[zField]);
            //                        bottom += 1 / (distanceToCell * distanceToCell);
            //                    }
            //                    else
            //                    {
            //                        top += (1 / Math.Pow(distanceToCell, power))
            //                               * Convert.ToDouble(featurePt.DataRow[zField]);
            //                        bottom += 1 / Math.Pow(distanceToCell, power);
            //                    }
            //                }
            //            }

            //            output.Value[y, x] = top / bottom;
            //        }

            //        // Checks if we need to update the status bar
            //        if (Convert.ToInt32(Convert.ToDouble(x * numRows) / Convert.ToDouble(numColumns * numRows) * 100) > lastUpdate)
            //        {
            //            lastUpdate = Convert.ToInt32(Convert.ToDouble(x * numRows) / Convert.ToDouble(numColumns * numRows) * 100);
            //            cancelProgressHandler.Progress(
            //                string.Empty, lastUpdate, "Cell: " + (x * numRows) + " of " + (numColumns * numRows));
            //            if (cancelProgressHandler.Cancel)
            //            {
            //                return false;
            //            }
            //        }
            //    }
            //}

            output.Save();
            return(true);
        }
        public List <Cell> GetNeighborhood(int row, int col, NeighborhoodType type)
        {
            // There
            int MyMod(int x, int mod) => (x >= 0) ? (x % mod) : (x + mod);

            List <Cell> neighborhood = new List <Cell>();


            switch (type)
            {
            case NeighborhoodType.L5:
            {
                neighborhood.Add(GetAt(row, col));

                neighborhood.Add(GetAt(row, MyMod(col - 1, ColCount)));         // Left
                neighborhood.Add(GetAt(MyMod(row - 1, RowCount), col));         // Top
                neighborhood.Add(GetAt(row, MyMod(col + 1, ColCount)));         // Right
                neighborhood.Add(GetAt(MyMod(row + 1, RowCount), col));         // Bottom

                Debug.Assert(neighborhood.Count == 5);
            }
            break;

            case NeighborhoodType.L9:
            {
                neighborhood.Add(GetAt(row, col));

                neighborhood.Add(GetAt(row, MyMod(col - 1, ColCount)));         // Left
                neighborhood.Add(GetAt(row, MyMod(col - 2, ColCount)));         // Left 2
                neighborhood.Add(GetAt(MyMod(row - 1, RowCount), col));         // Top
                neighborhood.Add(GetAt(MyMod(row - 2, RowCount), col));         // Top 2
                neighborhood.Add(GetAt(row, MyMod(col + 1, ColCount)));         // Right
                neighborhood.Add(GetAt(row, MyMod(col + 2, ColCount)));         // Right 2
                neighborhood.Add(GetAt(MyMod(row + 1, RowCount), col));         // Bottom
                neighborhood.Add(GetAt(MyMod(row + 2, RowCount), col));         // Bottom 2

                Debug.Assert(neighborhood.Count == 9);
            }
            break;

            case NeighborhoodType.C9:
            {
                for (int nRow = row - 1; nRow <= row + 1; nRow++)
                {
                    for (int nCol = col - 1; nCol <= col + 1; nCol++)
                    {
                        neighborhood.Add(GetAt(MyMod(nRow, RowCount), MyMod(nCol, ColCount)));
                    }
                }
                Debug.Assert(neighborhood.Count == 9);
            }
            break;

            case NeighborhoodType.C13:
            {
                for (int nRow = row - 1; nRow <= row + 1; nRow++)
                {
                    for (int nCol = col - 1; nCol <= col + 1; nCol++)
                    {
                        neighborhood.Add(GetAt(MyMod(nRow, RowCount), MyMod(nCol, ColCount)));
                    }
                }
                neighborhood.Add(GetAt(row, MyMod(col - 2, ColCount)));         // Left 2
                neighborhood.Add(GetAt(MyMod(row - 2, RowCount), col));         // Top 2
                neighborhood.Add(GetAt(row, MyMod(col + 2, ColCount)));         // Right 2
                neighborhood.Add(GetAt(MyMod(row + 2, RowCount), col));         // Bottom 2

                Debug.Assert(neighborhood.Count == 13);
            }
            break;

            default:
                throw new Exception("INVALID TYPE.");
            }

            return(neighborhood);
        }
Пример #15
0
        public static uint ClassifyTile(Grid<float> inputBuffer, uint[,] outputBuffer, float maxHeightDiffBetweenPixels, uint currentClassIndexSpanningTiles, uint minClusterSize, float noDataVal, NeighborhoodType neighborhoodType)
        {
            int width = inputBuffer.SizeX;
            int height = inputBuffer.SizeY;

            UInt32 currentClassIndex = 2;

            Dictionary<uint, SortedList<uint, bool>> substitutions = new Dictionary<uint, SortedList<uint, bool>>();
            Dictionary<uint, uint> classPixelCounts = new Dictionary<uint, uint>();

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    UInt32 newClassVal = 0;

                    float thisVal = inputBuffer.Data[x, y];

                    // skip nodata values
                    if (thisVal != noDataVal)
                    {
                        System.Drawing.Point[] coords = new System.Drawing.Point[4];
                        int neighborIndex = 0;

                        if (y > 0)
                            coords[neighborIndex++] = new System.Drawing.Point(x, y - 1);

                        if (x > 0)
                            coords[neighborIndex++] = new System.Drawing.Point(x - 1, y);

                        if (neighborhoodType == NeighborhoodType.EightNeighbors)
                        {
                            if (y > 0 && x > 0)
                                coords[neighborIndex++] = new System.Drawing.Point(x - 1, y - 1);

                            if (y > 0 && x < width - 1)
                                coords[neighborIndex++] = new System.Drawing.Point(x + 1, y - 1);
                        }

                        for (int i = 0; i < neighborIndex; i++)
                        {
                            int neighborX = coords[i].X;
                            int neighborY = coords[i].Y;

                            float neighborVal = inputBuffer.Data[neighborX, neighborY];
                            if (neighborVal != noDataVal)
                            {
                                uint neighborClass = outputBuffer[neighborX, neighborY];
                                if (System.Math.Abs(thisVal - neighborVal) <= maxHeightDiffBetweenPixels)
                                {
                                    if (newClassVal == 0)
                                        newClassVal = neighborClass;
                                    else
                                        newClassVal = DetermineNewClassSubstitution(substitutions, newClassVal, neighborClass);
                                }
                            }
                        }

                        if (newClassVal == 0)
                        {
                            newClassVal = currentClassIndex;
                            currentClassIndex++;
                        }
                    }
                    outputBuffer[x, y] = newClassVal;
                }
            }

            // perform substitutions
            uint maxPixelCount = 0;
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    uint currentClass = outputBuffer[x, y];
                    if (currentClass > 0)
                    {
                        uint newClass = FindSubstitutePixelClass(substitutions, classPixelCounts, ref maxPixelCount, currentClass);
                        outputBuffer[x, y] = newClass;
                    }
                }
            }

            // filter small clusters (trees and edges)
            if (minClusterSize > 0)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        uint currentClass = outputBuffer[x, y];

                        if (currentClass > 0)
                        {
                            uint count = classPixelCounts[currentClass];
                            uint value = 0;

                            value = currentClass;
                            if (count < minClusterSize)
                                value = 0;

                            outputBuffer[x, y] = value;
                        }
                    }
                }
            }

            // Update class indices to reduce max index values and remove duplicates across tiles.
            // This is feasible because small clusters have been filtered out (set to zero).
            Dictionary<uint, uint> classMappingUpdate = new Dictionary<uint, uint>();
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    uint currentClass = outputBuffer[x, y];
                    if (currentClass > 0)
                    {
                        if (!classMappingUpdate.ContainsKey(currentClass))
                        {
                            ++currentClassIndexSpanningTiles;
                            classMappingUpdate.Add(currentClass, currentClassIndexSpanningTiles);
                        }
                        outputBuffer[x, y] = classMappingUpdate[currentClass];
                    }
                }
            }

            return currentClassIndexSpanningTiles;
        }
Пример #16
0
 public NgbhType(string file, string name, NeighborhoodType type)
 {
     this.name = name;
     this.type = type;
     this.file = file;
 }