Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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>");
            //                }
            //            }
        }