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); } } }
public IsohypseCollection Isoplete(IRasterDigitalElevationModel dem, double elevationStep) { IsohypseCollection isoColl = new IsohypseCollection(); Isoplete(dem, elevationStep, delegate(Isohypse isohypse) { isoColl.AddIsohypse(isohypse); }); //if (visualizer != null) //{ // string[] segmentColors = new string[] { "red", "violet", "DarkRed" }; // int segmentCount = 0; // foreach (Isohypse isohypse in isoColl.Isohypses.Values) // { // foreach (Polyline segment in isohypse.Segments) // { // segmentCount++; // for (int i = 0; i < segment.Vertices.Count; i++) // { // // if the segment is not closed and we have reached the end, break out // if (false == segment.IsClosed && i == segment.Vertices.Count - 1) // break; // Point3<double> vertexA = segment.Vertices[i]; // Point3<double> vertexB = segment.Vertices[(i + 1) % segment.Vertices.Count]; // visualizer.DrawLine ("brown", vertexA.X, vertexA.Y, // vertexB.X, vertexB.Y); // //visualizer.DrawLine (segmentColors[segmentCount % (segmentColors.Length)], vertexA.X, vertexA.Y, // // vertexB.X, vertexB.Y); // //visualizer.DrawPoint ("black", vertexA.X, vertexA.Y); // } // } // } //} return(isoColl); }
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); } }
private IsohypseMovements ExtractIsohypseMovements( IRasterDigitalElevationModel dem, double isohypseElevation, Array2 <IsohypseMovement> movements, Array2 <byte> flags, int startingX, int startingY) { IsohypseMovements isohypseMovements = new IsohypseMovements(isohypseElevation); isohypseMovements.StartingX = startingX; isohypseMovements.StartingY = startingY; int x = isohypseMovements.StartingX; int y = isohypseMovements.StartingY; int lastX = 0, lastY = 0; IsohypseMovement lastMovement = IsohypseMovement.None; bool foundOneEnd = false; while (true) { // if we reached the end of the grid if (x < 0 || y < 0 || x >= dem.LonLength - 1 || y >= dem.LatLength - 1) { // have we already found one end of the segment? if (false == foundOneEnd) { // we haven't... foundOneEnd = true; // ... so reverse the segment and start moving from the other end int oldStartingX = isohypseMovements.StartingX; int oldStartingY = isohypseMovements.StartingY; isohypseMovements.ReverseIsohypseMovements(x, y); x = oldStartingX; y = oldStartingY; } else { // we have, so we can exit break; } } if (x == isohypseMovements.StartingX && y == isohypseMovements.StartingY && isohypseMovements.Movements.Count > 0) { // we found the starting point, this is a closed polygon isohypseMovements.IsClosed = true; break; } IsohypseMovement currentCellMovement = movements.GetValue(x, y); bool movementFound = false; for (int i = 0; i < 4; i++) { IsohypseMovement movementConsidered = (IsohypseMovement)(1 << i); if (0 != (currentCellMovement & movementConsidered)) { int nextX = x, nextY = y; switch (movementConsidered) { case IsohypseMovement.East: nextX++; break; case IsohypseMovement.North: nextY--; break; case IsohypseMovement.South: nextY++; break; case IsohypseMovement.West: nextX--; break; default: throw new NotImplementedException(); } // find the opposite movement of the last movement IsohypseMovement oppositeMovement = IsohypseMovements.GetOppositeMovement(lastMovement); if (lastMovement != IsohypseMovement.None) { // check that we haven't moved back if (nextX == lastX && nextY == lastY) { continue; } // special case when all movements are possible if ((((int)currentCellMovement) & 0xf) == 0xf) { IsohypseMovement movementCombination = movementConsidered | oppositeMovement; // check that we haven't moved in such a way as to make the polygon cross itself if ((movementCombination & (IsohypseMovement.North | IsohypseMovement.South)) == (IsohypseMovement.North | IsohypseMovement.South)) { continue; } // check that we haven't moved in such a way as to make the polygon cross itself if ((movementCombination & (IsohypseMovement.West | IsohypseMovement.East)) == (IsohypseMovement.West | IsohypseMovement.East)) { continue; } // check that the movement is the right one in regards to cells elevations if (flags.GetValue(x, y) == 5) { if (movementCombination == (IsohypseMovement.South | IsohypseMovement.East) || movementCombination == (IsohypseMovement.North | IsohypseMovement.West)) { continue; } } else if (flags.GetValue(x, y) == 10) { if (movementCombination == (IsohypseMovement.South | IsohypseMovement.West) || movementCombination == (IsohypseMovement.North | IsohypseMovement.East)) { continue; } } else { throw new NotImplementedException(); } } } isohypseMovements.Movements.Add(movementConsidered); // remove the used movement from the array movements.SetValue(movements.GetValue(x, y) & ~movementConsidered, x, y); // remove this opposite movement from the array movements.SetValue(movements.GetValue(x, y) & ~oppositeMovement, x, y); lastX = x; lastY = y; lastMovement = movementConsidered; x = nextX; y = nextY; movementFound = true; break; } } if (movementFound == false) { throw new NotImplementedException(); } } return(isohypseMovements); }
static public Image GenerateShadedReliefImage( IRasterDigitalElevationModel dem, IShadingMethod shadingMethod, ShadingParameters shadingParameters) { Bitmap bitmap = new Bitmap(dem.LonLength, dem.LatLength); double[][] window = new double[3][] { new double[3], new double[3], new double[3] }; double earthRadius = 6360000; double earthCircumference = earthRadius * 2 * Math.PI; double latSpacing = earthCircumference / (360 * dem.LatResolution); shadingMethod.Initialize(shadingParameters); for (int y = 1; y < dem.LatLength - 1; y++) { GeoPosition geoPos = dem.GetGeoPosition(0, y); double lonSpacing = earthCircumference / (360 * dem.LonResolution) * Math.Cos(geoPos.Latitude * Math.PI / 180.0); for (int x = 1; x < dem.LonLength - 1; x++) { GetMovingWindow(dem, window, x, y); double dzdx = ((window[0][0] + 2 * window[0][1] + window[0][2]) - (window[2][0] + 2 * window[2][1] + window[2][2])) / (8 * lonSpacing); if (double.IsNaN(dzdx)) { continue; } double dzdy = ((window[0][0] + 2 * window[1][0] + window[2][0]) - (window[0][2] + 2 * window[1][2] + window[2][2])) / (8 * latSpacing); if (double.IsNaN(dzdy)) { continue; } double riseRun = Math.Sqrt(dzdx * dzdx + dzdy * dzdy); double slope = Math.PI / 2 - Math.Atan(riseRun); double aspect = Math.Atan2(dzdy, dzdx); //double aspect = Math.Atan2 (window[1][0] - window[1][2], // window[0][1] - window[2][1]); if (dzdx != 0 || dzdy != 0) { if (aspect == 0) { aspect = Math.PI * 2; } } else { aspect = 0; } Color color = shadingMethod.CalculateColor(aspect, slope); bitmap.SetPixel(x, bitmap.Height - y, color); } } return(bitmap); }
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); }
public void Execute() { ConsoleActivityLogger activityLogger = new ConsoleActivityLogger(); activityLogger.LogLevel = ActivityLogLevel.Verbose; // Use all available encryption protocols supported in the .NET Framework 4.0. // TLS versions > 1.0 are supported and available via the extensions. // see https://blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support/ // This is a global setting for all HTTP requests. ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12 | SecurityProtocolType.Ssl3; // first make sure that the SRTM directory exists if (!Directory.Exists(srtmDir)) { Directory.CreateDirectory(srtmDir); } string srtmIndexFilename = Path.Combine(srtmDir, "SrtmIndex.dat"); SrtmIndex srtmIndex = null; SrtmIndex.SrtmSource = srtmSource; try { srtmIndex = SrtmIndex.Load(srtmIndexFilename); } catch (Exception) { // in case of exception, regenerate the index generateIndex = true; } if (generateIndex) { srtmIndex = new SrtmIndex(); srtmIndex.ActivityLogger = activityLogger; srtmIndex.Generate(); srtmIndex.Save(srtmIndexFilename); srtmIndex = SrtmIndex.Load(srtmIndexFilename); } Srtm3Storage.SrtmSource = srtmSource; Srtm3Storage storage = new Srtm3Storage(Path.Combine(srtmDir, "SrtmCache"), srtmIndex); storage.ActivityLogger = activityLogger; IIsopletingAlgorithm alg = new Igor4IsopletingAlgorithm(); alg.ActivityLogger = activityLogger; double elevationStepInUnits = elevationStep * elevationUnits; contourMarker.Configure(elevationUnits); // Default: Start with highest possible ID and count down. That should give maximum space // between contour data and real OSM data. IdCounter nodeCounter = new IdCounter(incrementId, firstNodeId); IdCounter wayCounter = new IdCounter(incrementId, firstWayId); OutputSettings settings = new OutputSettings(); settings.ContourMarker = contourMarker; settings.LongitudeCorrection = corrX; settings.LatitudeCorrection = corrY; settings.MaxWayNodes = maxWayNodes; // The following IDs and name do exist in the OSM database. settings.UserName = "******"; settings.UserId = 941874; settings.ChangesetId = 13341398; OutputBase output = null; if (largeAreaMode) { output = new DirectOutput(new FileInfo(outputOsmFile), settings); } else { output = new DatabaseOutput(new FileInfo(outputOsmFile), settings); } output.Begin(); if (osmMergeFile != null) { activityLogger.LogFormat(ActivityLogLevel.Normal, "Importing dataset from {0}", osmMergeFile); output.Merge(osmMergeFile); } if (this.splitWidth != 0 && this.splitHeight != 0) { List <Bounds2> newBounds = new List <Bounds2> (); foreach (Bounds2 bound in this.bounds) { newBounds.AddRange(BoundsSplitter.Split(bound, this.splitWidth, this.splitHeight)); } this.bounds = newBounds; activityLogger.LogFormat(ActivityLogLevel.Normal, "Will process {0} seperate bounds.", bounds.Count); } foreach (Bounds2 bound in this.bounds) { Bounds2 corrBounds = new Bounds2(bound.MinX - corrX, bound.MinY - corrY, bound.MaxX - corrX, bound.MaxY - corrY); activityLogger.LogFormat(ActivityLogLevel.Normal, "Calculating contour data for bound {0}...", corrBounds); IRasterDigitalElevationModel dem = (IRasterDigitalElevationModel)storage.LoadDemForArea(corrBounds); // clear up some memory used in storage object if (this.bounds.Count == 1) { storage = null; GC.Collect(); } DigitalElevationModelStatistics statistics = dem.CalculateStatistics(); activityLogger.Log(ActivityLogLevel.Normal, String.Format(CultureInfo.InvariantCulture, "DEM data points count: {0}", dem.DataPointsCount)); activityLogger.Log(ActivityLogLevel.Normal, String.Format(CultureInfo.InvariantCulture, "DEM minimum elevation: {0}", statistics.MinElevation)); activityLogger.Log(ActivityLogLevel.Normal, String.Format(CultureInfo.InvariantCulture, "DEM maximum elevation: {0}", statistics.MaxElevation)); activityLogger.Log(ActivityLogLevel.Normal, String.Format(CultureInfo.InvariantCulture, "DEM has missing points: {0}", statistics.HasMissingPoints)); try { alg.Isoplete(dem, elevationStepInUnits, delegate(Isohypse isohypse) { output.ProcessIsohypse(isohypse, delegate() { return(GetNextId(nodeCounter, true)); }, delegate() { return(GetNextId(wayCounter, false)); }); }); } catch (OutOfMemoryException) { string msg = "Not enough memory. "; if (this.splitWidth == 0 && this.splitHeight == 0) { msg += "Try to decrease the bounding box or use the splitbounds parameter."; } else { msg += "Try to decrease the splitbounds value."; } activityLogger.Log(ActivityLogLevel.Error, msg); break; } } if (!largeAreaMode) { activityLogger.Log(ActivityLogLevel.Normal, "Saving contour data to file..."); } output.End(); activityLogger.Log(ActivityLogLevel.Normal, "Done."); // TODO: SVG file generator code // using (FileStream stream = File.Open ("test.svg", FileMode.Create, FileAccess.Write)) // { // using (StreamWriter writer = new StreamWriter (stream)) // { // int width = 1000; // int height = 800; // double aspectRatio = (maxLat - minLat) / height; // aspectRatio = Math.Max (aspectRatio, (maxLng - minLng) / width); // writer.WriteLine (String.Format (System.Globalization.CultureInfo.InvariantCulture, // @"<?xml version='1.0' encoding='utf-8' standalone='yes'?> //<!DOCTYPE svg[]> //<svg viewBox='{0} {1} {2} {3}' width='{2}' height='{3}' id='0'>", 0, 0, width, height)); // foreach (Isohypse isohypse in isoCollection.Isohypses.Values) // { // foreach (Polyline polyline in isohypse.Segments) // { // StringBuilder pathString = new StringBuilder (); // for (int i = 0; i < polyline.VerticesCount; i++) // { // Point3 point = polyline.Vertices[i]; // if (i == 0) // { // pathString.AppendFormat ("M "); // } // else if (i == 1) // { // pathString.AppendFormat ("C "); // } // pathString.AppendFormat (System.Globalization.CultureInfo.InvariantCulture, "{0},{1} ", // (point.X - minLng) / aspectRatio, (maxLat - point.Y) / aspectRatio); // if (i > 0) // pathString.AppendFormat (System.Globalization.CultureInfo.InvariantCulture, "{0},{1} ", // (point.X - minLng) / aspectRatio, (maxLat - point.Y) / aspectRatio); // } // writer.WriteLine (@"<path d='{0}' fill='none' stroke='black' stroke-width='0.25px'/>", pathString.ToString ()); // } // } // writer.WriteLine (@"</svg>"); // } // } }