static private void GetMovingWindow(IRasterDigitalElevationModel dem, double[][] window, int x, int y) { for (int xi = -1; xi <= 1; xi++) { for (int yi = -1; yi <= 1; yi++) { window[xi + 1][yi + 1] = dem.GetElevationForDataPoint(x + xi, y + yi); } } }
public virtual void CopyElevationPointsFrom(IRasterDigitalElevationModel dem) { if (dem == null) { throw new ArgumentNullException("dem"); } if (LatResolution != dem.LatResolution || LonResolution != dem.LonResolution) { throw new ArgumentException("The two DEM's have incompatibile resolutions."); } // cell absolute position int cellLonAbs = dem.LonOffset * dem.LonResolution; int cellLatAbs = dem.LatOffset * dem.LatResolution; // first find the place to copy to and extent // initialize the copying rectangle to the cell's extent int west, south, east, north; west = cellLonAbs; south = cellLatAbs; east = west + dem.LonResolution - 1; north = south + dem.LatResolution - 1; // now intersect it with the destination extent if (LonOffset > west) { west = LonOffset; } if (LatOffset > south) { south = LatOffset; } if (LonOffset + LonLength - 1 < east) { east = LonOffset + LonLength - 1; } if (LatOffset + LatLength - 1 < north) { north = LatOffset + LatLength - 1; } for (int xx = west; xx <= east; xx++) { for (int yy = south; yy <= north; yy++) { double elevation = dem.GetElevationForDataPoint(xx - cellLonAbs, yy - cellLatAbs); SetElevationForDataPoint(xx - LonOffset, yy - LatOffset, elevation); } } }
private Polyline ConstructIsohypseSegment(IRasterDigitalElevationModel dem, IsohypseMovements isohypseMovements) { Polyline polyline = new Polyline(); polyline.IsClosed = isohypseMovements.IsClosed; int x = isohypseMovements.StartingX; int y = isohypseMovements.StartingY; bool checkedOrientation = false; bool shouldBeReversed = false; foreach (IsohypseMovement movement in isohypseMovements.Movements) { int dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0; switch (movement) { case IsohypseMovement.East: x++; dx1 = dx2 = x; dy1 = y; dy2 = y + 1; break; case IsohypseMovement.North: dx1 = x; dx2 = x + 1; dy1 = dy2 = y; y--; break; case IsohypseMovement.South: y++; dx1 = x + 1; dx2 = x; dy1 = dy2 = y; break; case IsohypseMovement.West: dx1 = dx2 = x; dy1 = y + 1; dy2 = y; x--; break; } double elevation1 = dem.GetElevationForDataPoint(dx1, dy1); double elevation2 = dem.GetElevationForDataPoint(dx2, dy2); // check the orientation of the isohypse if (false == checkedOrientation) { // the right-side elevation should be higher if (elevation2 < elevation1) { shouldBeReversed = true; } } double factor = (isohypseMovements.IsohypseElevation - elevation1) / (elevation2 - elevation1); double ix, iy; ix = (factor * (dx2 - dx1) + dx1); iy = (factor * (dy2 - dy1) + dy1); GeoPosition geoPos = dem.GetGeoPosition(ix, iy); Point3 <double> isohypseVertex = new Point3 <double> (geoPos.Longitude, geoPos.Latitude, isohypseMovements.IsohypseElevation); polyline.AddVertex(isohypseVertex); } // now reverse the polyline if needed if (shouldBeReversed) { polyline.Reverse(); } return(polyline); }
public void Isoplete(IRasterDigitalElevationModel dem, double elevationStep, NewIsohypseCallback callback) { DigitalElevationModelStatistics statistics = dem.CalculateStatistics(); double minElevation = Math.Floor(statistics.MinElevation / elevationStep) * elevationStep; double maxElevation = Math.Floor(statistics.MaxElevation / elevationStep) * elevationStep; //if (visualizer != null) //{ // GeoPosition geoPosMin = dem.GetGeoPosition (0, 0, false); // GeoPosition geoPosMax = dem.GetGeoPosition (dem.LonLength, dem.LatLength, false); // visualizer.Initialize (geoPosMin.Longitude, geoPosMin.Latitude, // geoPosMax.Longitude, geoPosMax.Latitude); //} Array2 <byte> flags = new Array2 <byte> (dem.LonLength - 1, dem.LatLength - 1); Array2 <IsohypseMovement> movements = new Array2 <IsohypseMovement> (dem.LonLength - 1, dem.LatLength - 1); int[,] adjacentCells = new int[, ] { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; // foreach elevation step for (double isoElev = minElevation; isoElev <= maxElevation; isoElev += elevationStep) { activityLogger.Log(ActivityLogLevel.Normal, String.Format(System.Globalization.CultureInfo.InvariantCulture, "Analyzing elevation {0}", isoElev)); //if (visualizer != null) //{ // GeoPosition geoPosMin = dem.GetGeoPosition (0, 0, false); // GeoPosition geoPosMax = dem.GetGeoPosition (dem.LongLength, dem.LatLength, false); // visualizer.Initialize (geoPosMin.Longitude, geoPosMin.Latitude, // geoPosMax.Longitude, geoPosMax.Latitude); // for (int x = 0; x < dem.LongLength; x++) // { // for (int y = 0; y < dem.LatLength; y++) // { // int elevation = dem.GetElevation (x, y); // GeoPosition geoPos = dem.GetGeoPosition (x, y); // string color = elevation >= isoElev ? "orange" : "yellow"; // visualizer.DrawPoint (color, geoPos.Longitude, geoPos.Latitude); // visualizer.DrawText ("pink", geoPos.Longitude, geoPos.Latitude, elevation.ToString ()); // } // } //} Isohypse isohypse = new Isohypse(isoElev); flags.Initialize(0); movements.Initialize(0); for (int x = 0; x < dem.LonLength - 1; x++) { for (int y = 0; y < dem.LatLength - 1; y++) { byte cellCharacteristic = 0; for (int i = 0; i < adjacentCells.GetLength(0); i++) { double adjacentCellElev = dem.GetElevationForDataPoint(x + adjacentCells[i, 0], y + adjacentCells[i, 1]); if (adjacentCellElev >= isoElev) { cellCharacteristic++; flags.SetValue((byte)(flags.GetValue(x, y) | (byte)(1 << i)), x, y); } } // skip cells which are definitively not along the isohypse if (cellCharacteristic == 0 || cellCharacteristic == 4) { continue; } if (cellCharacteristic == 2) { int maskedFlags = flags.GetValue(x, y) & 0x9; if (maskedFlags == 0 || maskedFlags == 0x9) { movements.SetValue(IsohypseMovement.North | IsohypseMovement.South, x, y); } else { maskedFlags = flags.GetValue(x, y) & 0x3; if (maskedFlags == 0 || maskedFlags == 0x3) { movements.SetValue(IsohypseMovement.West | IsohypseMovement.East, x, y); } else { movements.SetValue( IsohypseMovement.West | IsohypseMovement.East | IsohypseMovement.North | IsohypseMovement.South, x, y); } } } else { int maskedFlags = flags.GetValue(x, y) & 0x3; if (maskedFlags != 0 && maskedFlags != 0x3) { movements.SetValue(movements.GetValue(x, y) | IsohypseMovement.North, x, y); } maskedFlags = flags.GetValue(x, y) & 0x6; if (maskedFlags != 0 && maskedFlags != 0x6) { movements.SetValue(movements.GetValue(x, y) | IsohypseMovement.East, x, y); } maskedFlags = flags.GetValue(x, y) & 0xc; if (maskedFlags != 0 && maskedFlags != 0xc) { movements.SetValue(movements.GetValue(x, y) | IsohypseMovement.South, x, y); } maskedFlags = flags.GetValue(x, y) & 0x9; if (maskedFlags != 0 && maskedFlags != 0x9) { movements.SetValue(movements.GetValue(x, y) | IsohypseMovement.West, x, y); } } //if (visualizer != null) //{ // if (cellCharacteristic > 0 && cellCharacteristic < 4) // { // GeoPosition geoPos = dem.GetGeoPosition (x + 0.5, y + 0.5); // if (movements.GetValue (x, y) // == (IsohypseMovement.West | IsohypseMovement.East | IsohypseMovement.North | IsohypseMovement.South)) // visualizer.DrawText ("blue", geoPos.Longitude, geoPos.Latitude, // "X"); // //visualizer.DrawText ("blue", geoPos.Longitude, geoPos.Latitude, // // cellCharacteristic == 2 ? "K" : "T"); // //List<Point2> points = new List<Point2> (); // //if ((movements[x, y] & IsohypseMovement.North) != 0) // // points.Add (new Point2 (0.5, 0)); // //if ((movements[x, y] & IsohypseMovement.East) != 0) // // points.Add (new Point2 (1, 0.5)); // //if ((movements[x, y] & IsohypseMovement.South) != 0) // // points.Add (new Point2 (0.5, 1)); // //if ((movements[x, y] & IsohypseMovement.West) != 0) // // points.Add (new Point2 (0, 0.5)); // //List<GeoPosition> geoPoints = new List<GeoPosition> (); // //foreach (Point2 point in points) // // geoPoints.Add (dem.GetGeoPosition (x + point.X, y + point.Y)); // //visualizer.DrawLine ("black", geoPoints[0].Longitude, geoPoints[0].Latitude, // // geoPoints[1].Longitude, geoPoints[1].Latitude); // //if (geoPoints.Count > 2) // // visualizer.DrawLine ("black", geoPoints[2].Longitude, geoPoints[2].Latitude, // // geoPoints[3].Longitude, geoPoints[3].Latitude); // } //} } } for (int x = 0; x < dem.LonLength - 1; x++) { for (int y = 0; y < dem.LatLength - 1; y++) { if (movements.GetValue(x, y) != IsohypseMovement.None) { IsohypseMovements isohypseMovements = ExtractIsohypseMovements(dem, isoElev, movements, flags, x, y); Polyline isohypseSegment = ConstructIsohypseSegment(dem, isohypseMovements); isohypseSegment.RemoveDuplicateVertices(); isohypse.AddSegment(isohypseSegment); activityLogger.Log(ActivityLogLevel.Verbose, String.Format(System.Globalization.CultureInfo.InvariantCulture, "Found segment with {0} vertices", isohypseSegment.VerticesCount)); } } } if (isohypse.Segments.Count > 0) { callback(isohypse); } //isoColl.AddIsohypse (isohypse); } }
static public IList <PointOfInterest> FindPeaks(IRasterDigitalElevationModel dem, int howMany) { IList <PointOfInterest> peaks = new List <PointOfInterest> (); Point2 <int>[] neighbourPoints = { new Point2 <int> (-1, 0), new Point2 <int> (1, 0), new Point2 <int> (0, -1), new Point2 <int> (0, 1) }; for (int x = 1; x < dem.LonLength - 1; x++) { for (int y = 1; y < dem.LatLength - 1; y++) { double elevation = dem.GetElevationForDataPoint(x, y); // first check if it is a peak bool isPeak = true; for (int i = 0; i < neighbourPoints.Length; i++) { if (elevation <= dem.GetElevationForDataPoint((int)(x + neighbourPoints[i].X), (int)(y + neighbourPoints[i].Y))) { isPeak = false; break; } } if (isPeak) { for (int i = 0; i < peaks.Count + 1; i++) { bool addPeak = false; if (i == peaks.Count) { addPeak = true; } else { PointOfInterest peak = peaks[i] as PointOfInterest; if (elevation > peak.Position.Elevation) { addPeak = true; } } if (addPeak) { PointOfInterest newPeak = new PointOfInterest(dem.GetGeoPosition(x, y), String.Format(System.Globalization.CultureInfo.InvariantCulture, "Peak {0}", elevation)); peaks.Insert(i, newPeak); if (peaks.Count > howMany) { peaks.RemoveAt(peaks.Count - 1); } break; } } } } } return(peaks); }
static private double CalculateNeighbours(IRasterDigitalElevationModel dem, MissingElevation me) { double interpolatedElevation = 0; me.MissingNeighbours = 0; if (me.Lng > 0) { double elevation = dem.GetElevationForDataPoint(me.Lng - 1, me.Lat); if (elevation == Int16.MinValue) { me.MissingNeighbours++; } else { interpolatedElevation += elevation; } } else { me.MissingNeighbours++; } if (me.Lng < dem.LonLength - 1) { double elevation = dem.GetElevationForDataPoint(me.Lng + 1, me.Lat); if (elevation == Int16.MinValue) { me.MissingNeighbours++; } else { interpolatedElevation += elevation; } } else { me.MissingNeighbours++; } if (me.Lat > 0) { double elevation = dem.GetElevationForDataPoint(me.Lng, me.Lat - 1); if (elevation == Int16.MinValue) { me.MissingNeighbours++; } else { interpolatedElevation += elevation; } } else { me.MissingNeighbours++; } if (me.Lat < dem.LatLength - 1) { double elevation = dem.GetElevationForDataPoint(me.Lng, me.Lat + 1); if (elevation == Int16.MinValue) { me.MissingNeighbours++; } else { interpolatedElevation += elevation; } } else { me.MissingNeighbours++; } if (me.MissingNeighbours < 4) { interpolatedElevation /= (4 - me.MissingNeighbours); } else { interpolatedElevation = 0; } return(interpolatedElevation); }
public IRasterDigitalElevationModel Process(IRasterDigitalElevationModel input) { // clone data IRasterDigitalElevationModel output = input.Clone() as IRasterDigitalElevationModel; SortedList <MissingElevation, Point2 <double> > missingElevations = new SortedList <MissingElevation, Point2 <double> > (); // find all missing elevations for (int x = 0; x < output.LonLength; x++) { for (int y = 0; y < output.LatLength; y++) { double elevation = output.GetElevationForDataPoint(x, y); if (elevation == double.MinValue) { MissingElevation me = new MissingElevation(); me.Lng = x; me.Lat = y; // now calculate missing neighbours count CalculateNeighbours(output, me); // now add it to the list missingElevations.Add(me, new Point2 <double> (me.Lng, me.Lat)); } } } int startingMissingElevations = missingElevations.Count; // while there are missing elevations while (missingElevations.Count > 0) { // use first missing elevation MissingElevation me = missingElevations.Keys[0]; // based on the neighbouring non-missing data, calculate interpolated elevation double interpolatedElevation = CalculateNeighbours(output, me); // enter this elevation into the output ElevationData output.SetElevationForDataPoint(me.Lng, me.Lat, interpolatedElevation); // remove this elevation from missing elevation list missingElevations.Remove(me); // for each neighbour which is also missing elevation: // decrease the missingNeighbours counter // and reposition the neighbour in the missing elevations list Point2 <double>[] neighbourPoints = { new Point2 <double> (me.Lng - 1, me.Lat), new Point2 <double> (me.Lng + 1, me.Lat),new Point2 <double> (me.Lng, me.Lat - 1), new Point2 <double> (me.Lng, me.Lat + 1) }; for (int i = 0; i < 4; i++) { Point2 <double> p = neighbourPoints[i]; if (missingElevations.ContainsValue(p)) { MissingElevation me2 = missingElevations.Keys[missingElevations.IndexOfValue(p)]; missingElevations.Remove(me2); me2.MissingNeighbours--; missingElevations.Add(me2, p); } } } return(output); }