Beispiel #1
0
 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);
         }
     }
 }
Beispiel #2
0
        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);
                }
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
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);
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
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>");
            //                }
            //            }
        }