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