public DefaultTerrainElevationSource(Dataset databaseDataset, double lat, double lon, uint size, uint lod, float unitScale)
            {
                if (databaseDataset == null)
                {
                    throw new ArgumentNullException("databaseDataset");
                }

                // IDisposable referenced
                _DatabaseDataset = databaseDataset;
                _DatabaseDataset.IncRef();

                // Determine current position
                double[] datasetTransform = new double[6], datasetInvTransform = new double[6];
                _DatabaseDataset.GetGeoTransform(datasetTransform);
                Gdal.InvGeoTransform(datasetTransform, datasetInvTransform);

                double xCurrentPosition, yCurrentPosition;

                Gdal.ApplyGeoTransform(datasetInvTransform, lon, lat, out xCurrentPosition, out yCurrentPosition);

                // Let the higher levels to be pixel aligned
                int x = (int)Math.Floor(xCurrentPosition), y = (int)Math.Floor(yCurrentPosition);

                _CurrentTexPosition = _OriginPosition = new Vertex2d(x, y);

                Latitude  = lat;
                Longitude = lon;
                Lod       = lod;
                UnitScale = unitScale;

                _TerrainElevation = new Image(PixelLayout.GRAY16S, size, size);
                _TerrainElevation.IncRef();
            }
Example #2
0
            /// <summary>
            /// Extract all information required from the specified dataset.
            /// </summary>
            /// <param name="dataset">
            /// The <see cref="Dataset"/> from which the information must be extracted.
            /// </param>
            protected void ExtractGeoInformation(Dataset dataset, Rectangle area)
            {
                if (dataset == null)
                {
                    throw new ArgumentNullException("dataset");
                }

                // Geographic area
                // Geographic area
                double[] geoTransform = new double[6];
                double[] lat          = new double[2], lon = new double[2];

                dataset.GetGeoTransform(geoTransform);
                Gdal.ApplyGeoTransform(geoTransform, area.Left, area.Bottom, out lon[0], out lat[0]);
                Gdal.ApplyGeoTransform(geoTransform, area.Right, area.Top, out lon[1], out lat[1]);

                Latitude  = (lat[0] + lat[1]) / 2.0;
                Longitude = (lon[0] + lon[1]) / 2.0;
                Width     = Math.Abs(lat[0] - lat[1]);
                Height    = Math.Abs(lon[0] - lon[1]);

                // Textel precision
                double w1 = Vincenty.GetDistance(new Vertex2d(lon[0], lat[0]), new Vertex2d(lon[1], lat[0]));
                double w2 = Vincenty.GetDistance(new Vertex2d(lon[0], lat[1]), new Vertex2d(lon[1], lat[1]));
                double h1 = Vincenty.GetDistance(new Vertex2d(lon[0], lat[0]), new Vertex2d(lon[0], lat[1]));
                double h2 = Vincenty.GetDistance(new Vertex2d(lon[1], lat[0]), new Vertex2d(lon[1], lat[1]));

                double wp = ((w1 + w2) / 2.0) / (double)area.Width;
                double hp = ((h1 + h2) / 2.0) / (double)area.Height;

                _TextelPrecision = (wp + hp) / 2.0;
            }
Example #3
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Curve> boundary = new List <Curve>();

            DA.GetDataList <Curve>(0, boundary);

            string IMG_file = "";

            DA.GetData <string>("IMG Location", ref IMG_file);

            /*
             * //Does not work with HGT files
             *
             * byte[] imageBuffer;
             *
             * using (FileStream fs = new FileStream(IMG_file, FileMode.Open, FileAccess.Read))
             * {
             *    using (BinaryReader br = new BinaryReader(fs))
             *    {
             *        long numBytes = new FileInfo(IMG_file).Length;
             *        imageBuffer = br.ReadBytes((int)numBytes);
             *        br.Close();
             *        fs.Close();
             *    }
             * }
             */

            RESTful.GdalConfiguration.ConfigureGdal();
            OSGeo.GDAL.Gdal.AllRegister();

            //string memFilename = "/vsimem/inmemfile";
            //Gdal.FileFromMemBuffer(memFilename, imageBuffer);

            Dataset ds = Gdal.Open(IMG_file, Access.GA_ReadOnly);

            OSGeo.GDAL.Driver drv = ds.GetDriver();


            if (ds == null)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The vector datasource was unreadable by this component. It may not a valid file type for this component or otherwise null/empty.");
                return;
            }


            ///Get the spatial reference of the input raster file and set to WGS84 if not known
            ///Set up transform from source to WGS84
            OSGeo.OSR.SpatialReference sr = new SpatialReference(Osr.SRS_WKT_WGS84);
            if (ds.GetProjection() == null)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is missing.  CRS set automatically set to WGS84.");
            }

            else
            {
                sr = new SpatialReference(ds.GetProjection());
                if (sr.Validate() != 0)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is unknown or unsupported.  CRS set automatically set to WGS84.");
                    sr.SetWellKnownGeogCS("WGS84");
                }

                else
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Data source SRS: EPSG:" + sr.GetAttrValue("AUTHORITY", 1));
                }
            }

            //OSGeo.OSR.SpatialReference sr = new SpatialReference(ds.GetProjection());
            OSGeo.OSR.SpatialReference dst = new OSGeo.OSR.SpatialReference("");
            dst.SetWellKnownGeogCS("WGS84");
            OSGeo.OSR.CoordinateTransformation coordTransform = new OSGeo.OSR.CoordinateTransformation(sr, dst);
            OSGeo.OSR.CoordinateTransformation revTransform   = new OSGeo.OSR.CoordinateTransformation(dst, sr);

            double[] adfGeoTransform = new double[6];
            double[] invTransform    = new double[6];
            ds.GetGeoTransform(adfGeoTransform);
            Gdal.InvGeoTransform(adfGeoTransform, invTransform);
            Band band = ds.GetRasterBand(1);

            int width  = ds.RasterXSize;
            int height = ds.RasterYSize;

            //Dataset bounding box
            double oX = adfGeoTransform[0] + adfGeoTransform[1] * 0 + adfGeoTransform[2] * 0;
            double oY = adfGeoTransform[3] + adfGeoTransform[4] * 0 + adfGeoTransform[5] * 0;
            double eX = adfGeoTransform[0] + adfGeoTransform[1] * width + adfGeoTransform[2] * height;
            double eY = adfGeoTransform[3] + adfGeoTransform[4] * width + adfGeoTransform[5] * height;

            ///Transform to WGS84
            double[] extMinPT = new double[3] {
                oX, eY, 0
            };
            double[] extMaxPT = new double[3] {
                eX, oY, 0
            };
            coordTransform.TransformPoint(extMinPT);
            coordTransform.TransformPoint(extMaxPT);
            Point3d dsMin = new Point3d(extMinPT[0], extMinPT[1], extMinPT[2]);
            Point3d dsMax = new Point3d(extMaxPT[0], extMaxPT[1], extMaxPT[2]);

            //Point3d dsMin = new Point3d(oX, eY, 0);
            //Point3d dsMax = new Point3d(eX, oY, 0);
            Rectangle3d dsbox = new Rectangle3d(Plane.WorldXY, Heron.Convert.WGSToXYZ(dsMin), Heron.Convert.WGSToXYZ(dsMax));

            //Declare trees
            GH_Structure <GH_Point>   pointcloud = new GH_Structure <GH_Point>();
            GH_Structure <GH_Integer> rCount     = new GH_Structure <GH_Integer>();
            GH_Structure <GH_Integer> cCount     = new GH_Structure <GH_Integer>();
            GH_Structure <GH_Mesh>    tMesh      = new GH_Structure <GH_Mesh>();

            for (int i = 0; i < boundary.Count; i++)
            {
                if (dsbox.BoundingBox.Contains(boundary[i].GetBoundingBox(true).Min) && (dsbox.BoundingBox.Contains(boundary[i].GetBoundingBox(true).Max)))
                {
                    Point3d min = Heron.Convert.XYZToWGS(boundary[i].GetBoundingBox(true).Corner(true, false, true));
                    Point3d max = Heron.Convert.XYZToWGS(boundary[i].GetBoundingBox(true).Corner(false, true, true));

                    ///Transform to source SRS
                    double[] minR = new double[3] {
                        min.X, min.Y, min.Z
                    };
                    double[] maxR = new double[3] {
                        max.X, max.Y, max.Z
                    };
                    revTransform.TransformPoint(minR);
                    revTransform.TransformPoint(maxR);

                    GH_Path path = new GH_Path(i);

                    // http://gis.stackexchange.com/questions/46893/how-do-i-get-the-pixel-value-of-a-gdal-raster-under-an-ogr-point-without-numpy

                    double ur, uc, lr, lc;

                    Gdal.ApplyGeoTransform(invTransform, minR[0], minR[1], out uc, out ur);
                    Gdal.ApplyGeoTransform(invTransform, maxR[0], maxR[1], out lc, out lr);
                    //Gdal.ApplyGeoTransform(invTransform, min.X, min.Y, out uc, out ur);
                    //Gdal.ApplyGeoTransform(invTransform, max.X, max.Y, out lc, out lr);

                    int Urow = System.Convert.ToInt32(ur);
                    int Ucol = System.Convert.ToInt32(uc);
                    int Lrow = System.Convert.ToInt32(lr) + 1;
                    int Lcol = System.Convert.ToInt32(lc) + 1;
                    rCount.Append(new GH_Integer(Lrow - Urow), path);
                    cCount.Append(new GH_Integer(Lcol - Ucol), path);
                    Mesh           mesh  = new Mesh();
                    List <Point3d> verts = new List <Point3d>();
                    //var vertsParallel = new System.Collections.Concurrent.ConcurrentDictionary<double[][], Point3d>(Environment.ProcessorCount, ((Urow - 1) * (Lrow - 1)));

                    double[] bits = new double[width * height];
                    band.ReadRaster(0, 0, width, height, bits, width, height, 0, 0);

                    for (int col = Ucol; col < Lcol; col++)
                    {
                        for (int row = Urow; row < Lrow; row++)
                        {
                            // equivalent to bits[col][row] if bits is 2-dimension array
                            double pixel = bits[col + row * width];
                            if (pixel < -10000)
                            {
                                pixel = 0;
                            }

                            double gcol = adfGeoTransform[0] + adfGeoTransform[1] * col + adfGeoTransform[2] * row;
                            double grow = adfGeoTransform[3] + adfGeoTransform[4] * col + adfGeoTransform[5] * row;

                            ///convert to WGS84
                            double[] wgsPT = new double[3] {
                                gcol, grow, pixel
                            };
                            coordTransform.TransformPoint(wgsPT);
                            Point3d pt = new Point3d(wgsPT[0], wgsPT[1], wgsPT[2]);

                            //Point3d pt = new Point3d(gcol, grow, pixel);
                            verts.Add(Heron.Convert.WGSToXYZ(pt));
                        }

                        /*Parallel.For(Urow, Lrow - 1, rowP =>
                         *  {
                         *      // equivalent to bits[col][row] if bits is 2-dimension array
                         *      double pixel = bits[col + rowP * width];
                         *      if (pixel < -10000)
                         *      {
                         *          pixel = 0;
                         *      }
                         *
                         *      double gcol = adfGeoTransform[0] + adfGeoTransform[1] * col + adfGeoTransform[2] * rowP;
                         *      double grow = adfGeoTransform[3] + adfGeoTransform[4] * col + adfGeoTransform[5] * rowP;
                         *
                         *      Point3d pt = new Point3d(gcol, grow, pixel);
                         *      vertsParallel[] = Heron.Convert.ToXYZ(pt);
                         *  });
                         * */
                    }

                    //Create meshes
                    //non Parallel
                    mesh.Vertices.AddVertices(verts);
                    //Parallel
                    //mesh.Vertices.AddVertices(vertsParallel.Values);

                    for (int u = 1; u < cCount[path][0].Value; u++)
                    {
                        for (int v = 1; v < rCount[path][0].Value; v++)
                        {
                            mesh.Faces.AddFace(v - 1 + (u - 1) * (Lrow - Urow), v - 1 + u * (Lrow - Urow), v - 1 + u * (Lrow - Urow) + 1, v - 1 + (u - 1) * (Lrow - Urow) + 1);
                            //(k - 1 + (j - 1) * num2, k - 1 + j * num2, k - 1 + j * num2 + 1, k - 1 + (j - 1) * num2 + 1)
                        }
                    }
                    //mesh.Flip(true, true, true);
                    tMesh.Append(new GH_Mesh(mesh), path);
                }

                else
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more boundaries may be outside the bounds of the topo dataset.");
                    //return;
                }
            }
            DA.SetDataTree(0, tMesh);
            DA.SetData(1, dsbox);
        }
            public DefaultTerrainElevationFactory(string databaseRoot, double lat, double lon, uint maxLod)
            {
                if (databaseRoot == null)
                {
                    throw new ArgumentNullException("databaseRoot");
                }

                // Open the dataset.
                try {
                    _DatabaseDataset = Gdal.OpenShared(databaseRoot, Access.GA_ReadOnly);

                    if (_DatabaseDataset.RasterCount != 1)
                    {
                        throw new NotSupportedException();
                    }

                    DatabaseRoot = databaseRoot;

                    using (Band band = _DatabaseDataset.GetRasterBand(1)) {
                        switch (band.GetColorInterpretation())
                        {
                        case ColorInterp.GCI_Undefined:
                            switch (_DatabaseDataset.GetDriver().ShortName)
                            {
                            case "SRTMHGT":
                            case "VRT":
                                break;

                            default:
                                throw new NotSupportedException("unknown GDAL driver");
                            }
                            break;

                        default:
                            throw new NotSupportedException("unknown color interpretation");
                        }
                    }

                    // Determine current position
                    double[] datasetTransform = new double[6], datasetInvTransform = new double[6];
                    _DatabaseDataset.GetGeoTransform(datasetTransform);
                    Gdal.InvGeoTransform(datasetTransform, datasetInvTransform);

                    double xCurrentPosition, yCurrentPosition;
                    Gdal.ApplyGeoTransform(datasetInvTransform, lon, lat, out xCurrentPosition, out yCurrentPosition);

                    // Let the higher levels to be pixel aligned
                    int x = (int)Math.Floor(xCurrentPosition), y = (int)Math.Floor(yCurrentPosition);
                    int maxLodStride = (int)Math.Pow(2.0, maxLod);

                    x -= x % maxLodStride;
                    y -= y % maxLodStride;

                    x = Math.Max(x, 0);
                    y = Math.Max(y, 0);

                    Gdal.ApplyGeoTransform(datasetTransform, x, y, out lon, out lat);

                    Latitude  = lat;
                    Longitude = lon;
                } catch {
                    // Ensure GDAL object disposition
                    if (_DatabaseDataset != null)
                    {
                        _DatabaseDataset.Dispose();
                    }
                    // Exception
                    throw;
                }
            }