Example #1
0
        public static void Reduce(FileMetadata metadata, Stream input, Stream output, int desiredPoints)
        {
            // s = scaler to solve for
            // d = desired points
            // (x / s) * (y / s) == d
            // so...
            // s = (sqrt(x) * sqrt(y))/sqrt(d)

            float scaler = (float)((Math.Sqrt(metadata.Height) * Math.Sqrt(metadata.Width)) / Math.Sqrt(desiredPoints));

            int newHeight = (int)Math.Floor(metadata.Height / scaler);
            int newWidth = (int)Math.Floor(metadata.Width / scaler);

            float[,] originalMatrix = new float[metadata.Width, metadata.Height];
            float[,] newMatrix = new float[newWidth, newHeight];

            using (BinaryReader reader = new BinaryReader(input))
            {
                for (int y = 0; y < metadata.Height; y++)
                {
                    for (int x = 0; x < metadata.Width; x++)
                    {
                        switch (metadata.BitsPerSample)
                        {
                            case 32:
                                originalMatrix[x, y] = reader.ReadSingle();
                                break;
                            case 16:
                                originalMatrix[x, y] = reader.ReadUInt16();
                                break;
                        }
                    }
                }
            }

            float noDataValue = float.Parse(metadata.NoDataValue);

            using (BinaryWriter writer = new BinaryWriter(output))
            {
                for (int y = 0; y < newHeight; y++)
                {
                    for (int x = 0; x < newWidth; x++)
                    {
                        float value = originalMatrix[(int)(x * scaler), (int)(y * scaler)];

                        if (value != noDataValue)
                            value /= scaler;

                        writer.Write(value);
                    }
                }
            }

            metadata.Width = newWidth;
            metadata.Height = newHeight;
            metadata.PixelScaleX *= scaler;
            metadata.PixelScaleY *= scaler;
        }
        public static void Reduce(FileMetadata metadata, float[,] input, Stream output, int desiredPoints)
        {
            // s = scaler to solve for
            // d = desired points
            // (x / s) * (y / s) == d
            // so...
            // s = (sqrt(x) * sqrt(y))/sqrt(d)

            float scaler = (float)((Math.Sqrt(metadata.Height) * Math.Sqrt(metadata.Width)) / Math.Sqrt(desiredPoints));

            int newHeight = (int)Math.Floor(metadata.Height / scaler);
            int newWidth = (int)Math.Floor(metadata.Width / scaler);

            float[,] newMatrix = new float[newWidth, newHeight];

            float noDataValue = float.Parse(metadata.NoDataValue);

            using (BinaryWriter writer = new BinaryWriter(output))
            {
                for (int y = 0; y < newHeight; y++)
                {
                    for (int x = 0; x < newWidth; x++)
                    {
                        float value = input[(int)(x * scaler), (int)(y * scaler)];

                        //if (value != noDataValue)
                        //    value /= scaler;

                        writer.Write(value);
                    }
                }
            }

            metadata.Width = newWidth;
            metadata.Height = newHeight;
            metadata.PixelScaleX *= scaler;
            metadata.PixelScaleY *= scaler;
        }
Example #3
0
        private void WriteBinary(string inputFilename, Stream output, string bitmapFilename, FileMetadata metadata)
        {
            float min = float.MaxValue;
            float max = float.MinValue;
            float range;

            float[,] data = new float[metadata.Width, metadata.Height];

            for (int i = 0; i < metadata.Height; i++)
            {
                byte[] buffer = new byte[metadata.Width * metadata.BitsPerSample / 8];
                _tiff.ReadScanline(buffer, i);
                for (int p = 0; p < metadata.Width; p++)
                {
                    var heightValue = BitConverter.ToSingle(buffer, p * metadata.BitsPerSample / 8);
                    data[p, i] = heightValue;
                    if (heightValue != -10000)
                    {
                        min = Math.Min(min, heightValue);
                        max = Math.Max(max, heightValue);
                    }
                }
                output.Write(buffer, 0, metadata.Width * metadata.BitsPerSample / 8);
            }

            // compute range of heights so we can normalize the values for the grayscale bmp
            range = max - min;

            if (!string.IsNullOrEmpty(bitmapFilename))
            {
                DiagnosticUtils.OutputDebugBitmap(data, min, max, bitmapFilename, -10000);
            }
        }
Example #4
0
        private float[,] WriteBinary(string inputFilename, string bitmapFilename, FileMetadata metadata)
        {
            float min = float.MaxValue;
            float max = float.MinValue;
            float range;

            int width, height, increment;

            if (metadata.Width > 0x1fff || metadata.Height > 0x1fff)
            {
                width = metadata.Width / 2;
                height = metadata.Height / 2;
                increment = 2;
            }
            else
            {
                width = metadata.Width;
                height = metadata.Height;
                increment = 1;
            }

            float[,] data = new float[width, height];

            for (int i = 0; i <= metadata.Height - increment; i += increment)
            {
                byte[] buffer = new byte[metadata.Width * metadata.BitsPerSample / 8];
                _tiff.ReadScanline(buffer, i);
                for (int p = 0; p <= metadata.Width - increment; p += increment)
                {
                    var heightValue = BitConverter.ToSingle(buffer, p * metadata.BitsPerSample / 8);
                    data[p/increment, i/increment] = heightValue;
                    if (heightValue != -10000)
                    {
                        min = Math.Min(min, heightValue);
                        max = Math.Max(max, heightValue);
                    }
                }
                //output.Write(buffer, 0, metadata.Width * metadata.BitsPerSample / 8);
            }

            // compute range of heights so we can normalize the values for the grayscale bmp
            range = max - min;

            if (!string.IsNullOrEmpty(bitmapFilename))
            {
                DiagnosticUtils.OutputDebugBitmap(data, min, max, bitmapFilename, -10000);
            }

            metadata.Width /= increment;
            metadata.Height /= increment;
            metadata.PixelScaleX *= increment;
            metadata.PixelScaleY *= increment;

            return data;
        }
Example #5
0
        private FileMetadata ParseMetadata(string filename)
        {
            FileMetadata metadata = new FileMetadata();
            _tiff = Tiff.Open(filename, "r");

            metadata.Height = _tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
            metadata.Width = _tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();

            FieldValue[] modelPixelScaleTag = _tiff.GetField((TiffTag)33550);
            FieldValue[] modelTiepointTag = _tiff.GetField((TiffTag)33922);

            byte[] modelPixelScale = modelPixelScaleTag[1].GetBytes();
            metadata.PixelScaleX = BitConverter.ToDouble(modelPixelScale, 0);
            metadata.PixelScaleY = BitConverter.ToDouble(modelPixelScale, 8);

            // Ignores first set of model points (3 bytes) and assumes they are 0's...
            byte[] modelTransformation = modelTiepointTag[1].GetBytes();
            metadata.OriginLongitude = BitConverter.ToDouble(modelTransformation, 24);
            metadata.OriginLatitude = BitConverter.ToDouble(modelTransformation, 32);

            // Grab some raster metadata
            metadata.BitsPerSample = _tiff.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();

            // Add other information about the data
            metadata.SampleFormat = "Single";
            // TODO: Read this from tiff metadata or determine after parsing
            metadata.NoDataValue = "-10000";

            metadata.WorldUnits = "meter";

            return metadata;
        }
Example #6
0
        private static FileMetadata ParseMetadata(string filename, string outputFile, string outputBitmap, int targetPixelWidth)
        {
            FileMetadata metadata = new FileMetadata();

            Obj obj = new Obj();
            obj.LoadObj(filename);

            metadata.BitsPerSample = BITS_PER_SAMPLE;
            metadata.SampleFormat = "Single";

            double pointsPerPixel = obj.Size.XSize / targetPixelWidth;
            metadata.Height = (int)(Math.Ceiling(obj.Size.YSize / pointsPerPixel)) + 1;
            metadata.Width = (int)(Math.Ceiling(obj.Size.XSize / pointsPerPixel)) + 1;
            metadata.PixelScaleX = pointsPerPixel;
            metadata.PixelScaleY = pointsPerPixel;

            float[,] heights = new float[metadata.Height, metadata.Width];
            bool[,] dataPresent = new bool[metadata.Height, metadata.Width];

            metadata.OriginLatitude = obj.Size.XMin;
            metadata.OriginLongitude = obj.Size.YMax;

            metadata.WorldUnits = "meters";

            float minHeight = float.MaxValue;
            float maxHeight = float.MinValue;

            for (int y = 0; y < metadata.Height; y++)
            {
                var row = obj.VertexList.Where(v => (int)(Math.Floor((v.Y - obj.Size.YMin) / pointsPerPixel)) == y);
                var rowCols = row.GroupBy(r => (int)(Math.Floor((r.X - obj.Size.XMin) / pointsPerPixel))).OrderBy(rc => rc.Key);

                int x = 0;
                foreach (var rowcol in rowCols)
                {
                    while (rowcol.Key > x)
                    {
                        heights[y, x] = -1;
                        x++;
                    }

                    heights[y, x] = (float)rowcol.Average(v => v.Z);

                    if (heights[y, x] > maxHeight)
                    {
                        maxHeight = heights[y, x];
                    }
                    if (heights[y, x] < minHeight)
                    {
                        minHeight = heights[y, x];
                    }

                    dataPresent[y, x] = true;
                    x++;

                }
                while (x < metadata.Width)
                {
                    heights[y, x] = -1;
                    x++;
                }
            }

            bool dataMissing = true;
            int maxCount = 8;
            while (dataMissing)
            {
                dataMissing = false;
                bool dataFound = false;
                for (int i = 0; i < dataPresent.GetLength(0); i++)
                {
                    for (int j = 0; j < dataPresent.GetLength(1); j++)
                    {
                        if (!dataPresent[i, j])
                        {
                            var sum = 0.0f;
                            var count = 0;

                            bool firstRow = i == 0;
                            bool lastRow = i == dataPresent.GetLength(0) - 1;
                            bool firstCol = j == 0;
                            bool lastCol = j == dataPresent.GetLength(1) - 1;

                            // up left
                            if (!firstRow && !firstCol && dataPresent[i - 1, j - 1])
                            {
                                sum += heights[i - 1, j - 1];
                                count++;
                            }
                            // up center
                            if (!firstRow && dataPresent[i - 1, j])
                            {
                                sum += heights[i - 1, j];
                                count++;
                            }

                            // up right
                            if (!firstRow && !lastCol && dataPresent[i - 1, j + 1])
                            {
                                sum += heights[i - 1, j + 1];
                                count++;
                            }

                            // center left
                            if (!firstCol && dataPresent[i, j - 1])
                            {
                                sum += heights[i, j - 1];
                                count++;
                            }

                            // center right
                            if (!lastCol && dataPresent[i, j + 1])
                            {
                                sum += heights[i, j + 1];
                                count++;
                            }

                            // down left
                            if (!lastRow && !firstCol && dataPresent[i + 1, j - 1])
                            {
                                sum += heights[i + 1, j - 1];
                                count++;
                            }

                            // down center
                            if (!lastRow && dataPresent[i + 1, j])
                            {
                                sum += heights[i + 1, j];
                                count++;
                            }

                            // down right
                            if (!lastRow && !lastCol && dataPresent[i + 1, j + 1])
                            {
                                sum += heights[i + 1, j + 1];
                                count++;
                            }

                            if (count >= maxCount)
                            {
                                dataPresent[i, j] = true;
                                heights[i, j] = sum / count;
                                dataFound = true;
                            }
                            else
                            {
                                dataMissing = true;
                            }

                        }
                    }
                }
                if (dataMissing && !dataFound)
                {
                    maxCount--;
                }
            }

            if (!string.IsNullOrEmpty(outputBitmap))
            {
                DiagnosticUtils.OutputDebugBitmap(heights, minHeight, maxHeight, outputBitmap);
            }

            if (!string.IsNullOrEmpty(outputFile))
            {
                using (var stream = File.OpenWrite(outputFile))
                {
                    foreach (var height in heights)
                    {
                        byte[] bytesToWrite = BitConverter.GetBytes(height);
                        stream.Write(bytesToWrite, 0, bytesToWrite.Length);
                    }
                }
            }

            return metadata;
        }