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); } }
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>"); // } // } }