private void Configure() { _elevationFactor = 1 / 3640000f; _isElevation = true; _extrusion = 1; _shadedRelief = new ShadedRelief(); _noDataColor = Color.Transparent; Scheme = new ColorScheme(); if (_raster != null) { _scheme.ApplyScheme(ColorSchemeType.FallLeaves, _raster); } }
private void Configure() { _shadedRelief = new ShadedRelief(); _noDataColor = Color.Transparent; Scheme = new ColorScheme(); if (_raster != null) { var colors = _raster.CategoryColors(); if (colors != null && colors.Length > 0) { // Use colors that are built into the raster, e.g. GeoTIFF with palette _isElevation = false; // use all colors instead of unique colors because unique colors are not always set/correct int lastColor = colors[0].ToArgb(); // changed by jany_ 2015-06-02 int firstNr = 0; // group succeeding values with the same color to the same category for (int i = 1; i < colors.Length; i++) { int hash = colors[i].ToArgb(); if (hash != lastColor) { // the current color differs from the one before so we add a category for the color before AddCategory(firstNr, i - 1, colors[firstNr]); firstNr = i; lastColor = hash; } if (i == colors.Length - 1) // this is the last color, so we add the last category { AddCategory(firstNr, i, colors[firstNr]); } } } else { // Assume grid is elevation _elevationFactor = 1 / 3640000f; _isElevation = true; _extrusion = 1; _scheme.ApplyScheme(ColorSchemeType.FallLeaves, _raster); } } }
/// <summary> /// Create Hillshade of values ranging from 0 to 1, or -1 for no-data regions. /// This should be a little faster since we are accessing the Data field directly instead of working /// through a value parameter. /// </summary> /// <param name="raster">The raster to create the hillshade from.</param> /// <param name="shadedRelief">An implementation of IShadedRelief describing how the hillshade should be created.</param> /// <param name="progressHandler">An implementation of IProgressHandler for progress messages</param> public static float[][] CreateHillShade(this IRaster raster, IShadedRelief shadedRelief, IProgressHandler progressHandler = null) { if (progressHandler == null) { progressHandler = raster.ProgressHandler; } var pm = new ProgressMeter(progressHandler, SymbologyMessageStrings.DesktopRasterExt_CreatingShadedRelief, raster.NumRows); Func <int, int, double> getValue; if (raster.DataType == typeof(int)) { var r = raster.ToRaster <int>(); getValue = (row, col) => r.Data[row][col]; } else if (raster.DataType == typeof(float)) { var r = raster.ToRaster <float>(); getValue = (row, col) => r.Data[row][col]; } else if (raster.DataType == typeof(short)) { var r = raster.ToRaster <short>(); getValue = (row, col) => r.Data[row][col]; } else if (raster.DataType == typeof(byte)) { var r = raster.ToRaster <byte>(); getValue = (row, col) => r.Data[row][col]; } else if (raster.DataType == typeof(double)) { var r = raster.ToRaster <double>(); getValue = (row, col) => r.Data[row][col]; } else { getValue = (row, col) => raster.Value[row, col]; } return(CreateHillShadeT(raster, getValue, shadedRelief, pm)); }
private void Configure() { _shadedRelief = new ShadedRelief(); _noDataColor = Color.Transparent; Scheme = new ColorScheme(); if (_raster != null) { var Colors = _raster.CategoryColors(); if (Colors != null && Colors.Length > 0) { // Use colors that are built into the raster, e.g. GeoTIFF with palette var Names = _raster.CategoryNames(); bool overMaxCount = false; var UniqueValues = _raster.GetUniqueValues(Colors.Length, out overMaxCount); _isElevation = false; for (int i = 0; i < Colors.Length; i++) { //Only add colors to the legend if they appear in the layer //NLCD CategoryColors include 256 colors, but only 16 are valid if (UniqueValues.Contains(Convert.ToDouble(i))) { // It seems buggy that using value i - 1 below works ICategory newCat = new ColorCategory(i - 1, Colors[i]); if (Names != null && Names.Length > i) { newCat.LegendText = Names[i]; } else { newCat.LegendText = i.ToString(); } Scheme.AddCategory(newCat); } } } else // Assume grid is elevation { _elevationFactor = 1 / 3640000f; _isElevation = true; _extrusion = 1; _scheme.ApplyScheme(ColorSchemeType.FallLeaves, _raster); } } }
private void Configure() { _shadedRelief = new ShadedRelief(); _noDataColor = Color.Transparent; Scheme = new ColorScheme(); if (_raster != null) { var Colors = _raster.CategoryColors(); if (Colors != null && Colors.Length > 0) { // Use colors that are built into the raster, e.g. GeoTIFF with palette _isElevation = false; //use all colors instead of unique colors because unique colors are not allways set/correct int lastColor = Colors[0].ToArgb(); //changed by jany_ 2015-06-02 int firstNr = 0; //group succeding values with the same color to the same category for (int i = 1; i < Colors.Length; i++) { int hash = Colors[i].ToArgb(); if (hash != lastColor || i == Colors.Length - 1) { ICategory newCat = new ColorCategory(firstNr, i - 1, Colors[firstNr], Colors[firstNr]); newCat.Range.MaxIsInclusive = true; newCat.Range.MinIsInclusive = true; newCat.LegendText = firstNr.ToString(); Scheme.AddCategory(newCat); firstNr = i; lastColor = hash; } } } else // Assume grid is elevation { _elevationFactor = 1 / 3640000f; _isElevation = true; _extrusion = 1; _scheme.ApplyScheme(ColorSchemeType.FallLeaves, _raster); } } }
private void Configure() { _shadedRelief = new ShadedRelief(); _noDataColor = Color.Transparent; Scheme = new ColorScheme(); if (_raster != null) { var Colors = _raster.CategoryColors(); if (Colors != null && Colors.Length > 0) { // Use colors that are built into the raster, e.g. GeoTIFF with palette var names = _raster.CategoryNames(); bool overMaxCount; var uniqueValues = _raster.GetUniqueValues(Colors.Length, out overMaxCount); _isElevation = false; for (int i = 0; i < Colors.Length; i++) { //Only add colors to the legend if they appear in the layer //NLCD CategoryColors include 256 colors, but only 16 are valid if (uniqueValues.Contains(Convert.ToDouble(i))) { // It seems buggy that using value i - 1 below works ICategory newCat = new ColorCategory(i - 1, Colors[i]); if (names != null && names.Length > i) newCat.LegendText = names[i]; else newCat.LegendText = i.ToString(); Scheme.AddCategory(newCat); } } } else // Assume grid is elevation { _elevationFactor = 1 / 3640000f; _isElevation = true; _extrusion = 1; _scheme.ApplyScheme(ColorSchemeType.FallLeaves, _raster); } } }
/// <summary> /// Create Hillshade of values ranging from 0 to 1, or -1 for no-data regions. /// This should be a little faster since we are accessing the Data field directly instead of working /// through a value parameter. /// </summary> /// <typeparam name="T">Type of the raster.</typeparam> /// <param name="raster">The raster to create the hillshade from.</param> /// <param name="shadedRelief">An implementation of IShadedRelief describing how the hillshade should be created.</param> /// <param name="progressMeter">An implementation of IProgressHandler for progress messages</param> /// <returns>The resulting hill shade array.</returns> public static float[][] CreateHillShadeT <T>(this Raster <T> raster, IShadedRelief shadedRelief, ProgressMeter progressMeter) where T : IEquatable <T>, IComparable <T> { return(CreateHillShadeT(raster, (row, col) => raster.Data[row][col], shadedRelief, progressMeter)); }
private static float[][] CreateHillShadeT <T>(this IRaster raster, Func <int, int, T> getValue, IShadedRelief shadedRelief, ProgressMeter progressMeter) where T : IEquatable <T>, IComparable <T> { if (!raster.IsInRam) { return(null); } int numCols = raster.NumColumns; int numRows = raster.NumRows; var noData = Convert.ToSingle(raster.NoDataValue); float extrusion = shadedRelief.Extrusion; float elevationFactor = shadedRelief.ElevationFactor; float lightIntensity = shadedRelief.LightIntensity; float ambientIntensity = shadedRelief.AmbientIntensity; FloatVector3 lightDirection = shadedRelief.GetLightDirection(); float[] aff = new float[6]; // affine coefficients converted to float format for (int i = 0; i < 6; i++) { aff[i] = Convert.ToSingle(raster.Bounds.AffineCoefficients[i]); } float[][] hillshade = new float[numRows][]; if (progressMeter != null) { progressMeter.BaseMessage = "Creating Shaded Relief"; } for (int row = 0; row < numRows; row++) { hillshade[row] = new float[numCols]; for (int col = 0; col < numCols; col++) { // 3D position vectors of three points to create a triangle. FloatVector3 v1 = new FloatVector3(0f, 0f, 0f); FloatVector3 v2 = new FloatVector3(0f, 0f, 0f); FloatVector3 v3 = new FloatVector3(0f, 0f, 0f); float val = Convert.ToSingle(getValue(row, col)); // Cannot compute polygon ... make the best guess) if (col >= numCols - 1 || row <= 0) { if (col >= numCols - 1 && row <= 0) { v1.Z = val; v2.Z = val; v3.Z = val; } else if (col >= numCols - 1) { v1.Z = Convert.ToSingle(getValue(row, col - 1)); // 3 - 2 v2.Z = Convert.ToSingle(getValue(row - 1, col)); // | / v3.Z = Convert.ToSingle(getValue(row - 1, col - 1)); // 1 * } else if (row <= 0) { v1.Z = Convert.ToSingle(getValue(row + 1, col)); // 3* 2 v2.Z = Convert.ToSingle(getValue(row, col + 1)); // | / v3.Z = val; // 1 } } else { v1.Z = val; // 3 - 2 v2.Z = Convert.ToSingle(getValue(row - 1, col + 1)); // | / v3.Z = Convert.ToSingle(getValue(row - 1, col)); // 1* } // Test for no-data values and don't calculate hillshade in that case if (v1.Z == noData || v2.Z == noData || v3.Z == noData) { hillshade[row][col] = -1; // should never be negative otherwise. continue; } // Apply the Conversion Factor to put elevation into the same range as lat/lon v1.Z = v1.Z * elevationFactor * extrusion; v2.Z = v2.Z * elevationFactor * extrusion; v3.Z = v3.Z * elevationFactor * extrusion; // Complete the vectors using the latitude/longitude coordinates v1.X = aff[0] + (aff[1] * col) + (aff[2] * row); v1.Y = aff[3] + (aff[4] * col) + (aff[5] * row); v2.X = aff[0] + (aff[1] * (col + 1)) + (aff[2] * (row + 1)); v2.Y = aff[3] + (aff[4] * (col + 1)) + (aff[5] * (row + 1)); v3.X = aff[0] + (aff[1] * col) + (aff[2] * (row + 1)); v3.Y = aff[3] + (aff[4] * col) + (aff[5] * (row + 1)); // We need two direction vectors in order to obtain a cross product FloatVector3 dir2 = FloatVector3.Subtract(v2, v1); // points from 1 to 2 FloatVector3 dir3 = FloatVector3.Subtract(v3, v1); // points from 1 to 3 FloatVector3 cross = FloatVector3.CrossProduct(dir3, dir2); // right hand rule - cross direction should point into page... reflecting more if light direction is in the same direction // Normalizing this vector ensures that this vector is a pure direction and won't affect the intensity cross.Normalize(); // Hillshade now has an "intensity" modifier that should be applied to the R, G and B values of the color found at each pixel. hillshade[row][col] = (FloatVector3.Dot(cross, lightDirection) * lightIntensity) + ambientIntensity; } progressMeter?.Next(); } // Setting this indicates that a hillshade has been created more recently than characteristics have been changed. shadedRelief.HasChanged = false; return(hillshade); }
private void Configure() { _elevationFactor = 1 / 3640000f; _isElevation = true; _extrusion = 1; _shadedRelief = new ShadedRelief(); _noDataColor = Color.Transparent; Scheme = new ColorScheme(); if (_raster != null) _scheme.ApplyScheme(ColorSchemeType.FallLeaves, _raster); }
/// <summary> /// Create Hillshade of values ranging from 0 to 1, or -1 for no-data regions. /// This should be a little faster since we are accessing the Data field directly instead of working /// through a value parameter. /// </summary> /// <param name="raster">The raster to create the hillshade from.</param> /// <param name="shadedRelief">An implementation of IShadedRelief describing how the hillshade should be created.</param> /// <param name="progressHandler">An implementation of IProgressHandler for progress messages</param> public static float[][] CreateHillShade(this IRaster raster, IShadedRelief shadedRelief, IProgressHandler progressHandler) { int numCols = raster.NumColumns; int numRows = raster.NumRows; double noData = raster.NoDataValue; float extrusion = shadedRelief.Extrusion; float elevationFactor = shadedRelief.ElevationFactor; float lightIntensity = shadedRelief.LightIntensity; float ambientIntensity = shadedRelief.AmbientIntensity; FloatVector3 lightDirection = shadedRelief.GetLightDirection(); float[] aff = new float[6]; // affine coefficients converted to float format for (int i = 0; i < 6; i++) { aff[i] = Convert.ToSingle(raster.Bounds.AffineCoefficients[i]); } float[][] hillshade = new float[numRows][]; ProgressMeter pm = new ProgressMeter(progressHandler, MessageStrings.CreatingShadedRelief, numRows); for (int row = 0; row < numRows; row++) { hillshade[row] = new float[numCols]; for (int col = 0; col < numCols; col++) { // 3D position vectors of three points to create a triangle. FloatVector3 v1 = new FloatVector3(0f, 0f, 0f); FloatVector3 v2 = new FloatVector3(0f, 0f, 0f); FloatVector3 v3 = new FloatVector3(0f, 0f, 0f); double val = raster.Value[row, col]; // Cannot compute polygon ... make the best guess if (col >= numCols - 1 || row <= 0) { if (col >= numCols - 1 && row <= 0) { v1.Z = (float)val; v2.Z = (float)val; v3.Z = (float)val; } else if (col >= numCols - 1) { v1.Z = (float)raster.Value[row, col - 1]; // 3 - 2 v2.Z = (float)raster.Value[row - 1, col]; // | / v3.Z = (float)raster.Value[row - 1, col - 1]; // 1 * } else if (row <= 0) { v1.Z = (float)raster.Value[row + 1, col]; // 3* 2 v2.Z = (float)raster.Value[row, col + 1]; // | / v3.Z = (float)val; // 1 } } else { v1.Z = (float)val; // 3 - 2 v2.Z = (float)raster.Value[row - 1, col + 1]; // | / v3.Z = (float)raster.Value[row - 1, col]; // 1* } // Test for no-data values and don't calculate hillshade in that case if (v1.Z == noData || v2.Z == noData || v3.Z == noData) { hillshade[row][col] = -1; // should never be negative otherwise. continue; } // Apply the Conversion Factor to put elevation into the same range as lat/lon v1.Z = v1.Z * elevationFactor * extrusion; v2.Z = v2.Z * elevationFactor * extrusion; v3.Z = v3.Z * elevationFactor * extrusion; // Complete the vectors using the latitude/longitude coordinates v1.X = aff[0] + aff[1] * col + aff[2] * row; v1.Y = aff[3] + aff[4] * col + aff[5] * row; v2.X = aff[0] + aff[1] * (col + 1) + aff[2] * (row + 1); v2.Y = aff[3] + aff[4] * (col + 1) + aff[5] * (row + 1); v3.X = aff[0] + aff[1] * col + aff[2] * (row + 1); v3.Y = aff[3] + aff[4] * col + aff[5] * (row + 1); // We need two direction vectors in order to obtain a cross product FloatVector3 dir2 = FloatVector3.Subtract(v2, v1); // points from 1 to 2 FloatVector3 dir3 = FloatVector3.Subtract(v3, v1); // points from 1 to 3 FloatVector3 cross = FloatVector3.CrossProduct(dir3, dir2); // right hand rule - cross direction should point into page... reflecting more if light direction is in the same direction // Normalizing this vector ensures that this vector is a pure direction and won't affect the intensity cross.Normalize(); // Hillshade now has an "intensity" modifier that should be applied to the R, G and B values of the color found at each pixel. hillshade[row][col] = FloatVector3.Dot(cross, lightDirection) * lightIntensity + ambientIntensity; } pm.CurrentValue = row; } pm.Reset(); // Setting this indicates that a hillshade has been created more recently than characteristics have been changed. shadedRelief.HasChanged = false; return hillshade; }
/// <summary> /// Create Hillshade of values ranging from 0 to 1, or -1 for no-data regions. /// This uses the progress handler defined on this raster. /// </summary> /// <param name="raster">The raster to create hillshade information for</param> /// <param name="shadedRelief">An implementation of IShadedRelief describing how the hillshade should be created.</param> public static float[][] CreateHillShade(this IRaster raster, IShadedRelief shadedRelief) { return CreateHillShade(raster, shadedRelief, raster.ProgressHandler); }