/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); ///Working with data trees allows us to only call the osr coordinate transformation once, which seems to be expensive GH_Structure <GH_Point> sourcePoints = new GH_Structure <GH_Point>(); DA.GetDataTree(0, out sourcePoints); GH_Structure <GH_Point> destPoints = new GH_Structure <GH_Point>(); string sourceString = string.Empty; DA.GetData(1, ref sourceString); OSGeo.OSR.SpatialReference sourceSRS = new OSGeo.OSR.SpatialReference(""); sourceSRS.SetFromUserInput(sourceString); if (sourceSRS.Validate() == 1) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid Source SRS."); return; } string destString = string.Empty; DA.GetData(2, ref destString); OSGeo.OSR.SpatialReference destSRS = new OSGeo.OSR.SpatialReference(""); destSRS.SetFromUserInput(destString); if (destSRS.Validate() == 1) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid Destination SRS."); return; } OSGeo.OSR.CoordinateTransformation trans = new OSGeo.OSR.CoordinateTransformation(sourceSRS, destSRS); foreach (var path in sourcePoints.Paths) { List <GH_Point> branchPts = (List <GH_Point>)sourcePoints.get_Branch(path); foreach (var sp in branchPts) { OSGeo.OGR.Geometry destOgrPoint = new OSGeo.OGR.Geometry(wkbGeometryType.wkbPoint); destOgrPoint.AddPoint(sp.Value.X, sp.Value.Y, sp.Value.Z); destOgrPoint.AssignSpatialReference(sourceSRS); destOgrPoint.Transform(trans); Point3d destPoint = new Point3d(destOgrPoint.GetX(0), destOgrPoint.GetY(0), destOgrPoint.GetZ(0)); destPoints.Append(new GH_Point(destPoint), path); destOgrPoint.Dispose(); } } DA.SetDataTree(0, destPoints); }
public static string EsriToProj4(string esriProjectionPath) { OSGeo.OSR.SpatialReference oSRS = new SpatialReference(""); if (oSRS.SetFromUserInput(esriProjectionPath) != Ogr.OGRERR_NONE) { throw new ApplicationException(string.Format("Error occured translating {0}", esriProjectionPath)); } string proj4OutputString; if (oSRS.ExportToProj4(out proj4OutputString) == Ogr.OGRERR_NONE) { return(proj4OutputString); } else { throw new ApplicationException("Export to proj4 failed"); } /* * if (nArgc != 2) * { * printf("Usage: wkt2proj4 [srtext def or srtext file]\n"); * exit(1); * } * * if (oSRS.SetFromUserInput(papszArgv[1]) != OGRERR_NONE) * { * CPLError(CE_Failure, CPLE_AppDefined, * "Error occured translating %s.\n", papszArgv[1]); * } * * oSRS.morphFromESRI(); * * char* pszProj4 = NULL; * * if (oSRS.exportToProj4(&pszProj4) == OGRERR_NONE) * { * printf("%s\n", pszProj4); * } * else * { * fprintf(stderr, "exportToProj4() failed.\n"); * } * */ }
public static string EsriToProj4(string esriProjectionPath) { OSGeo.OSR.SpatialReference oSRS= new SpatialReference(""); if (oSRS.SetFromUserInput(esriProjectionPath)!=Ogr.OGRERR_NONE) { throw new ApplicationException(string.Format("Error occured translating {0}",esriProjectionPath)); } string proj4OutputString; if( oSRS.ExportToProj4(out proj4OutputString)==Ogr.OGRERR_NONE) { return proj4OutputString; } else { throw new ApplicationException("Export to proj4 failed"); } /* if (nArgc != 2) { printf("Usage: wkt2proj4 [srtext def or srtext file]\n"); exit(1); } if (oSRS.SetFromUserInput(papszArgv[1]) != OGRERR_NONE) { CPLError(CE_Failure, CPLE_AppDefined, "Error occured translating %s.\n", papszArgv[1]); } oSRS.morphFromESRI(); char* pszProj4 = NULL; if (oSRS.exportToProj4(&pszProj4) == OGRERR_NONE) { printf("%s\n", pszProj4); } else { fprintf(stderr, "exportToProj4() failed.\n"); } */ }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>(0, boundary); string URL = string.Empty; DA.GetData <string>("REST URL", ref URL); if (!URL.EndsWith("/")) { URL = URL + "/"; } string userSRStext = string.Empty; DA.GetData <string>("User Spatial Reference System", ref userSRStext); bool run = false; DA.GetData <bool>("run", ref run); ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); ///TODO: implement SetCRS here. ///Option to set CRS here to user-defined. Needs a SetCRS global variable. OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference(""); userSRS.SetFromUserInput(userSRStext); int userSRSInt = Int16.Parse(userSRS.GetAuthorityCode(null)); ///Set transform from input spatial reference to Rhino spatial reference OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); rhinoSRS.SetWellKnownGeogCS("WGS84"); ///This transform moves and scales the points required in going from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); GH_Structure <GH_String> mapquery = new GH_Structure <GH_String>(); GH_Structure <GH_Point> gsetUser = new GH_Structure <GH_Point>(); GH_Structure <IGH_GeometricGoo> gGoo = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <GH_String> fset = new GH_Structure <GH_String>(); GH_Structure <GH_String> fieldnames = new GH_Structure <GH_String>(); for (int i = 0; i < boundary.Count; i++) { GH_Path cpath = new GH_Path(i); BoundingBox bbox = boundary[i].GetBoundingBox(false); bbox.Transform(modelToUserSRSTransform); string restquery = URL + "query?where=&text=&objectIds=&time=&geometry=" + bbox.Min.X + "%2C" + bbox.Min.Y + "%2C" + bbox.Max.X + "%2C" + bbox.Max.Y + "&geometryType=esriGeometryEnvelope&inSR=" + userSRSInt + "&spatialRel=esriSpatialRelIntersects" + "&relationParam=&outFields=*" + "&returnGeometry=true" + "&maxAllowableOffset=" + "&geometryPrecision=" + "&outSR=" + userSRSInt + "&returnIdsOnly=false" + "&returnCountOnly=false" + "&orderByFields=" + "&groupByFieldsForStatistics=&outStatistics=" + "&returnZ=true" + "&returnM=false" + "&gdbVersion=" + "&returnDistinctValues=false" + "&f=json"; mapquery.Append(new GH_String(restquery), cpath); if (run) { //string result = Heron.Convert.HttpToJson(restquery); OSGeo.OGR.DataSource dataSource = OSGeo.OGR.Ogr.Open("ESRIJSON:" + restquery, 0); if (dataSource == 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."); } ///Loop through each layer. Likely not any layers in a REST service for (int iLayer = 0; iLayer < dataSource.GetLayerCount(); iLayer++) { OSGeo.OGR.Layer ogrLayer = dataSource.GetLayerByIndex(iLayer); if (ogrLayer == null) { Console.WriteLine($"Couldn't fetch advertised layer {iLayer}"); System.Environment.Exit(-1); } long count = ogrLayer.GetFeatureCount(1); int featureCount = System.Convert.ToInt32(count); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Layer #{iLayer} {ogrLayer.GetName()} has {featureCount} features"); OSGeo.OGR.FeatureDefn def = ogrLayer.GetLayerDefn(); ///Get the field names for (int iAttr = 0; iAttr < def.GetFieldCount(); iAttr++) { ///TODO: Look into GetAlternativeNameRef() for field aliases (more readable) available in GDAL 3.2 OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iAttr); fieldnames.Append(new GH_String(fdef.GetNameRef()), new GH_Path(i, iLayer)); } ///Loop through geometry OSGeo.OGR.Feature feat; def = ogrLayer.GetLayerDefn(); int m = 0; while ((feat = ogrLayer.GetNextFeature()) != null) { OSGeo.OGR.Geometry geomUser = feat.GetGeometryRef().Clone(); OSGeo.OGR.Geometry sub_geomUser; ///reproject geometry to WGS84 and userSRS ///TODO: look into using the SetCRS global variable here if (geomUser.GetSpatialReference() == null) { geomUser.AssignSpatialReference(userSRS); } geomUser.TransformTo(userSRS); if (feat.GetGeometryRef() != null) { if (!pointsOnly) { ///Convert GDAL geometries to IGH_GeometricGoo gGoo.AppendRange(Heron.Convert.OgrGeomToGHGoo(geomUser, userSRSToModelTransform), new GH_Path(i, iLayer, m)); /// Get Feature Values if (fset.PathExists(new GH_Path(i, iLayer, m))) { fset.get_Branch(new GH_Path(i, iLayer, m)).Clear(); } for (int iField = 0; iField < feat.GetFieldCount(); iField++) { OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField); if (feat.IsFieldSet(iField)) { fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m)); } else { fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m)); } } ///End get Feature Values } else { ///Start get points if open polylines and points for (int gpc = 0; gpc < geomUser.GetPointCount(); gpc++) { ///Loop through geometry points for User SRS double[] ogrPtUser = new double[3]; geomUser.GetPoint(gpc, ogrPtUser); Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]); pt3DUser.Transform(userSRSToModelTransform); gGoo.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m)); ///End loop through geometry points /// Get Feature Values if (fset.PathExists(new GH_Path(i, iLayer, m))) { fset.get_Branch(new GH_Path(i, iLayer, m)).Clear(); } for (int iField = 0; iField < feat.GetFieldCount(); iField++) { OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField); if (feat.IsFieldSet(iField)) { fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m)); } else { fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m)); } } ///End Get Feature Values } ///End getting points if open polylines or points ///Start getting points if closed polylines and multipolygons for (int gi = 0; gi < geomUser.GetGeometryCount(); gi++) { sub_geomUser = geomUser.GetGeometryRef(gi); OSGeo.OGR.Geometry subsub_geomUser; if (sub_geomUser.GetGeometryCount() > 0) { for (int n = 0; n < sub_geomUser.GetGeometryCount(); n++) { subsub_geomUser = sub_geomUser.GetGeometryRef(n); for (int ptnum = 0; ptnum < subsub_geomUser.GetPointCount(); ptnum++) { ///Loop through geometry points for User SRS double[] ogrPtUser = new double[3]; subsub_geomUser.GetPoint(ptnum, ogrPtUser); Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]); pt3DUser.Transform(userSRSToModelTransform); gGoo.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m, gi, n)); ///End loop through geometry points } subsub_geomUser.Dispose(); } } else { for (int ptnum = 0; ptnum < sub_geomUser.GetPointCount(); ptnum++) { ///Loop through geometry points for User SRS double[] ogrPtUser = new double[3]; sub_geomUser.GetPoint(ptnum, ogrPtUser); Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]); pt3DUser.Transform(userSRSToModelTransform); gGoo.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m, gi)); ///End loop through geometry points } } sub_geomUser.Dispose(); /// Get Feature Values if (fset.PathExists(new GH_Path(i, iLayer, m))) { fset.get_Branch(new GH_Path(i, iLayer, m)).Clear(); } for (int iField = 0; iField < feat.GetFieldCount(); iField++) { OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField); if (feat.IsFieldSet(iField)) { fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m)); } else { fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m)); } } ///End Get Feature Values } ///End closed polygons and multipolygons } ///End points only } m++; geomUser.Dispose(); feat.Dispose(); }///end while loop through features } dataSource.Dispose(); } } ///Not the most elegant way of setting outputs only on run if (run) { DA.SetDataList(0, fieldnames.get_Branch(0)); DA.SetDataTree(1, fset); DA.SetDataTree(2, gGoo); } DA.SetDataTree(3, mapquery); }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>("Boundary", boundary); int Res = -1; DA.GetData <int>("Resolution", ref Res); string folderPath = string.Empty; DA.GetData <string>("Target Folder", ref folderPath); if (!folderPath.EndsWith(@"\")) { folderPath = folderPath + @"\"; } string prefix = string.Empty; DA.GetData <string>("Prefix", ref prefix); string URL = string.Empty; DA.GetData <string>("REST URL", ref URL); if (URL.EndsWith(@"/")) { URL = URL + "export?"; } bool run = false; DA.GetData <bool>("run", ref run); string userSRStext = string.Empty; DA.GetData <string>("User Spatial Reference System", ref userSRStext); string imageType = string.Empty; DA.GetData <string>("Image Type", ref imageType); ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); ///TODO: implement SetCRS here. ///Option to set CRS here to user-defined. Needs a SetCRS global variable. //string userSRStext = "EPSG:4326"; OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference(""); userSRS.SetFromUserInput(userSRStext); int userSRSInt = Int16.Parse(userSRS.GetAuthorityCode(null)); ///Set transform from input spatial reference to Rhino spatial reference OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); rhinoSRS.SetWellKnownGeogCS("WGS84"); ///This transform moves and scales the points required in going from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); GH_Structure <GH_String> mapList = new GH_Structure <GH_String>(); GH_Structure <GH_String> mapquery = new GH_Structure <GH_String>(); GH_Structure <GH_Rectangle> imgFrame = new GH_Structure <GH_Rectangle>(); FileInfo file = new FileInfo(folderPath); file.Directory.Create(); string size = string.Empty; if (Res != 0) { size = "&size=" + Res + "%2C" + Res; } for (int i = 0; i < boundary.Count; i++) { GH_Path path = new GH_Path(i); ///Get image frame for given boundary BoundingBox imageBox = boundary[i].GetBoundingBox(false); imageBox.Transform(modelToUserSRSTransform); ///Make sure to have a rect for output Rectangle3d rect = BBoxToRect(imageBox); ///Query the REST service string restquery = URL + ///legacy method for creating bounding box string "bbox=" + imageBox.Min.X + "%2C" + imageBox.Min.Y + "%2C" + imageBox.Max.X + "%2C" + imageBox.Max.Y + "&bboxSR=" + userSRSInt + size + //"&layers=&layerdefs=" + "&imageSR=" + userSRSInt + //"&transparent=false&dpi=&time=&layerTimeOptions=" + "&format=" + imageType; // + //"&f=json"; string restqueryJSON = restquery + "&f=json"; string restqueryImage = restquery + "&f=image"; mapquery.Append(new GH_String(restqueryImage), path); string result = string.Empty; ///Get extent of image from arcgis rest service as JSON result = Heron.Convert.HttpToJson(restqueryJSON); JObject jObj = JsonConvert.DeserializeObject <JObject>(result); if (!jObj.ContainsKey("href")) { restqueryJSON = restqueryJSON.Replace("export?", "exportImage?"); restqueryImage = restqueryImage.Replace("export?", "exportImage?"); mapquery.RemovePath(path); mapquery.Append(new GH_String(restqueryImage), path); result = Heron.Convert.HttpToJson(restqueryJSON); jObj = JsonConvert.DeserializeObject <JObject>(result); } if (run) { Point3d extMin = new Point3d((double)jObj["extent"]["xmin"], (double)jObj["extent"]["ymin"], 0); Point3d extMax = new Point3d((double)jObj["extent"]["xmax"], (double)jObj["extent"]["ymax"], 0); rect = new Rectangle3d(Plane.WorldXY, extMin, extMax); rect.Transform(userSRSToModelTransform); ///Download image from source ///Catch if JSON query throws an error string imageQueryJSON = jObj["href"].ToString(); using (WebClient webC = new WebClient()) { try { if (!String.IsNullOrEmpty(imageQueryJSON)) { webC.DownloadFile(imageQueryJSON, folderPath + prefix + "_" + i + "." + imageType); webC.Dispose(); } else { webC.DownloadFile(restqueryImage, folderPath + prefix + "_" + i + "." + imageType); webC.Dispose(); } } catch (WebException e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, e.Message); webC.DownloadFile(restqueryImage, folderPath + prefix + "_" + i + "." + imageType); webC.Dispose(); } } } var bitmapPath = folderPath + prefix + "_" + i + "." + imageType; mapList.Append(new GH_String(bitmapPath), path); imgFrame.Append(new GH_Rectangle(rect), path); AddPreviewItem(bitmapPath, rect); } DA.SetDataTree(0, mapList); DA.SetDataTree(1, imgFrame); DA.SetDataTree(2, mapquery); }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>(0, boundary); string URL = string.Empty; DA.GetData <string>("REST URL", ref URL); string userSRStext = string.Empty; DA.GetData <string>("User Spatial Reference System", ref userSRStext); bool run = false; DA.GetData <bool>("run", ref run); ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); ///TODO: implement SetCRS here. ///Option to set CRS here to user-defined. Needs a SetCRS global variable. int SRef = 3857; OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference(""); userSRS.SetFromUserInput(userSRStext); int userSRSInt = Int16.Parse(userSRS.GetAuthorityCode(null)); ///Set transform from input spatial reference to Rhino spatial reference OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); rhinoSRS.SetWellKnownGeogCS("WGS84"); ///This transform moves and scales the points required in going from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); GH_Structure <GH_String> mapquery = new GH_Structure <GH_String>(); GH_Structure <GH_ObjectWrapper> jT = new GH_Structure <GH_ObjectWrapper>(); List <JObject> j = new List <JObject>(); GH_Structure <GH_Point> restpoints = new GH_Structure <GH_Point>(); GH_Structure <GH_String> attpoints = new GH_Structure <GH_String>(); GH_Structure <GH_String> fieldnames = new GH_Structure <GH_String>(); for (int i = 0; i < boundary.Count; i++) { GH_Path cpath = new GH_Path(i); BoundingBox bbox = boundary[i].GetBoundingBox(false); bbox.Transform(modelToUserSRSTransform); string restquery = URL + "query?where=&text=&objectIds=&time=&geometry=" + bbox.Min.X + "%2C" + bbox.Min.Y + "%2C" + bbox.Max.X + "%2C" + bbox.Max.Y + "&geometryType=esriGeometryEnvelope&inSR=" + userSRSInt + "&spatialRel=+esriSpatialRelIntersects" + "&relationParam=&outFields=*" + "&returnGeometry=true" + "&maxAllowableOffset=" + "&geometryPrecision=" + "&outSR=" + userSRSInt + "&returnIdsOnly=false" + "&returnCountOnly=false" + "&orderByFields=" + "&groupByFieldsForStatistics=&outStatistics=" + "&returnZ=true" + "&returnM=false" + "&gdbVersion=" + "&returnDistinctValues=false" + "&f=json"; mapquery.Append(new GH_String(restquery), cpath); if (run) { string result = Heron.Convert.HttpToJson(restquery); jT.Append(new GH_ObjectWrapper(JsonConvert.DeserializeObject <JObject>(result)), cpath); j.Add(JsonConvert.DeserializeObject <JObject>(result)); JArray e = (JArray)j[i]["features"]; for (int m = 0; m < e.Count; m++) { JObject aa = (JObject)j[i]["features"][m]["attributes"]; GH_Path path = new GH_Path(i, m); ///Need to be able to escape this if no "geometry" property //if (j[i].Property("features.[" + m + "].geometry") != null) if (j[i]["features"][m]["geometry"] != null) { ///Choose type of geometry to read JsonReader jreader = j[i]["features"][m]["geometry"].CreateReader(); int jrc = 0; string gt = null; while ((jreader.Read()) && (jrc < 1)) { if (jreader.Value != null) { //gtype.Add(jreader.Value, path); gt = jreader.Value.ToString(); jrc++; } } JArray c = (JArray)j[i]["features"][m]["geometry"][gt][0]; for (int k = 0; k < c.Count; k++) { double xx = (double)j[i]["features"][m]["geometry"][gt][0][k][0]; double yy = (double)j[i]["features"][m]["geometry"][gt][0][k][1]; Point3d xyz = new Point3d(xx, yy, 0); restpoints.Append(new GH_Point(userSRSToModelTransform * xyz), path); } } foreach (JProperty attribute in j[i]["features"][m]["attributes"]) { attpoints.Append(new GH_String(attribute.Value.ToString()), path); } } //Get the field names foreach (JObject fn in j[i]["fields"]) { fieldnames.Append(new GH_String(fn["alias"].Value <string>()), cpath); } } } ///Not the most elegant way of setting outputs only on run if (run) { DA.SetDataList(0, fieldnames.get_Branch(0)); DA.SetDataTree(1, attpoints); DA.SetDataTree(2, restpoints); } DA.SetDataTree(3, mapquery); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { ///Setup location Point3d location = new Point3d(); DA.GetData(0, ref location); double lat = Heron.Convert.XYZToWGS(location).Y; double lon = Heron.Convert.XYZToWGS(location).X; ///Setup contour style and unit type List <double> contourNums = new List <double>(); DA.GetDataList <double>(1, contourNums); string contourType = String.Empty; double unitConversion = Rhino.RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, Rhino.UnitSystem.Meters); contourNums.Sort(); for (int i = 0; i < contourNums.Count; i++) { double contourNum = contourNums[i]; if (contourNum < 0.0) { contourNum = 0.0; AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Minimum countour must be greater than 0."); } if (MinutesOrMeters == "Distance") { contourType = "contours_meters="; contourNum = Math.Round(contourNum * unitConversion, 0); if (contourNum < 1) { contourNum = 1; AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Minimum distance contour must be greater than the Rhino unit equivalent of 1 meter."); } if (contourNum > 100000) { contourNum = 100000; AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Maximum distance contour must be less than the Rhino unit equivalent of 1,000km."); } } else { contourType = "contours_minutes="; if (contourNum > 60) { contourNum = 60; AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Maximum minute contour is 60. Contour value reduced to 60."); } } contourNums[i] = contourNum; } ///Setup denoise and make sure Denoise is between 0..1 double?denoiseNum = null; DA.GetData(2, ref denoiseNum); if (denoiseNum < 0.0) { denoiseNum = 0.0; AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Denoise must be greater than 0."); } if (denoiseNum > 1.0) { denoiseNum = 1.0; AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Denoise must be less than 1.0"); } ///Setup generalize and make sure it's greater than 0 double?generalize = null; DA.GetData(3, ref generalize); double?generalizeNum = generalize * unitConversion; if (generalizeNum < 0.0) { generalizeNum = 0.0; AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Generalize must be greater than 0"); } ///Setup Mapbox token string apiKey = string.Empty; DA.GetData(4, ref apiKey); string mbToken = apiKey; if (mbToken == "") { string hmbToken = System.Environment.GetEnvironmentVariable("HERONMAPBOXTOKEN"); if (hmbToken != null) { mbToken = hmbToken; AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Using Mapbox token stored in Environment Variable HERONMAPBOXTOKEN."); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No Mapbox token is specified. Please get a valid token from mapbox.com"); return; } } ///Setup run bool run = false; DA.GetData(5, ref run); ///Outputs List <IGH_GeometricGoo> isochrones = new List <IGH_GeometricGoo>(); List <string> urls = new List <string>(); ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); OSGeo.OGR.Ogr.RegisterAll(); ///Set transform from input spatial reference to Rhino spatial reference OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); rhinoSRS.SetWellKnownGeogCS("WGS84"); ///TODO: use this as override of global SetSRS OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference(""); //userSRS.SetFromUserInput(userSRStext); userSRS.SetFromUserInput("WGS84"); ///These transforms move and scale in order to go from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); ///Construct URL query string int increment = 0; while (increment < contourNums.Count) { string contourString = contourNums[increment].ToString(); if (increment + 1 < contourNums.Count) { contourString = contourString + "%2C" + contourNums[increment + 1]; } if (increment + 2 < contourNums.Count) { contourString = contourString + "%2C" + contourNums[increment + 2]; } if (increment + 3 < contourNums.Count) { contourString = contourString + "%2C" + contourNums[increment + 3]; } string url = @"https://api.mapbox.com/isochrone/v1/mapbox/"; if (!String.IsNullOrEmpty(Profile)) { url = url + Profile.ToLower() + "/"; } if (lon > -180.0 && lon <= 180.0) { url = url + lon + "%2C"; } if (lat > -90.0 && lat <= 90.0) { url = url + lat + "?"; } if (!String.IsNullOrEmpty(contourType)) { url = url + contourType.ToLower(); } if (contourString != null) { url = url + contourString; } if (polygons == "Meshes") { url = url + "&polygons=true"; } else { url = url + "&polygons=false"; } if (denoiseNum != null) { url = url + "&denoise=" + denoiseNum; } if (generalizeNum != null) { url = url + "&generalize=" + generalizeNum; } if (mbToken != "") { url = url + "&access_token=" + mbToken; } urls.Add(url); increment = increment + 4; } if (run) { foreach (string u in urls) { List <IGH_GeometricGoo> gGoo = new List <IGH_GeometricGoo>(); OSGeo.OGR.DataSource dataSource = OSGeo.OGR.Ogr.Open(u, 0); if (dataSource == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mapbox returned an invalid response."); return; } ///Only interested in geometry, not fields or values OSGeo.OGR.Layer ogrLayer = dataSource.GetLayerByIndex(0); OSGeo.OGR.Feature feat; while ((feat = ogrLayer.GetNextFeature()) != null) { if (feat.GetGeometryRef() == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Isochrone may be too small or otherwise degenerate."); continue; } OSGeo.OGR.Geometry geomUser = feat.GetGeometryRef().Clone(); ///reproject geometry to WGS84 and userSRS ///TODO: look into using the SetCRS global variable here if (geomUser.GetSpatialReference() == null) { geomUser.AssignSpatialReference(userSRS); } geomUser.TransformTo(userSRS); if (feat.GetGeometryRef() != null) { isochrones.AddRange(Heron.Convert.OgrGeomToGHGoo(geomUser, userSRSToModelTransform)); } } ///Garbage cleanup ogrLayer.Dispose(); dataSource.Dispose(); } } List <string> mbAtts = new List <string> { "© Mapbox, © OpenStreetMap", "https://www.mapbox.com/about/maps/", "http://www.openstreetmap.org/copyright" }; DA.SetDataList(0, isochrones); DA.SetDataList(1, urls); DA.SetDataList(2, mbAtts); }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>("Boundary", boundary); int Res = -1; DA.GetData <int>("Resolution", ref Res); string fileloc = ""; DA.GetData <string>("File Location", ref fileloc); if (!fileloc.EndsWith(@"\")) { fileloc = fileloc + @"\"; } string prefix = ""; DA.GetData <string>("Prefix", ref prefix); string URL = ""; DA.GetData <string>("REST URL", ref URL); bool run = false; DA.GetData <bool>("run", ref run); string userSRStext = ""; DA.GetData <string>("User Spatial Reference System", ref userSRStext); ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); ///TODO: implement SetCRS here. ///Option to set CRS here to user-defined. Needs a SetCRS global variable. //string userSRStext = "EPSG:4326"; OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference(""); userSRS.SetFromUserInput(userSRStext); int userSRSInt = Int16.Parse(userSRS.GetAuthorityCode(null)); ///Set transform from input spatial reference to Rhino spatial reference OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); rhinoSRS.SetWellKnownGeogCS("WGS84"); ///This transform moves and scales the points required in going from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); OSGeo.OSR.CoordinateTransformation coordTransformRhinoToUser = new OSGeo.OSR.CoordinateTransformation(rhinoSRS, userSRS); OSGeo.OSR.CoordinateTransformation coordTransformUserToRhino = new OSGeo.OSR.CoordinateTransformation(userSRS, rhinoSRS); GH_Structure <GH_String> mapList = new GH_Structure <GH_String>(); GH_Structure <GH_String> mapquery = new GH_Structure <GH_String>(); GH_Structure <GH_Rectangle> imgFrame = new GH_Structure <GH_Rectangle>(); FileInfo file = new FileInfo(fileloc); file.Directory.Create(); string size = ""; if (Res != 0) { size = "&size=" + Res + "%2C" + Res; } for (int i = 0; i < boundary.Count; i++) { GH_Path path = new GH_Path(i); //Get image frame for given boundary BoundingBox imageBox = boundary[i].GetBoundingBox(false); Point3d min = Heron.Convert.XYZToWGS(imageBox.Min); Point3d max = Heron.Convert.XYZToWGS(imageBox.Max); Rectangle3d rect = BBoxToRect(imageBox); ///ogr method OSGeo.OGR.Geometry minOgr = Heron.Convert.Point3dToOgrPoint(min); minOgr.Transform(coordTransformRhinoToUser); OSGeo.OGR.Geometry maxOgr = Heron.Convert.Point3dToOgrPoint(max); maxOgr.Transform(coordTransformRhinoToUser); //Query the REST service string restquery = URL + ///legacy method for creating bounding box string //"bbox=" + Heron.Convert.ConvertLat(min.X, 3857) + "%2C" + Heron.Convert.ConvertLon(min.Y, 3857) + "%2C" + Heron.Convert.ConvertLat(max.X, 3857) + "%2C" + Heron.Convert.ConvertLon(max.Y, 3857) + ///ogr method for creating bounding box string "bbox=" + minOgr.GetX(0) + "%2C" + minOgr.GetY(0) + "%2C" + maxOgr.GetX(0) + "%2C" + maxOgr.GetY(0) + "&bboxSR=" + userSRSInt + size + //"&layers=&layerdefs=" + "&imageSR=" + userSRSInt + //"&transparent=false&dpi=&time=&layerTimeOptions=" + "&format=jpg&f=json"; mapquery.Append(new GH_String(restquery), path); string result = ""; if (run) { ///get extent of image from arcgis rest service as JSON result = Heron.Convert.HttpToJson(restquery); JObject jObj = JsonConvert.DeserializeObject <JObject>(result); Point3d extMin = new Point3d((double)jObj["extent"]["xmin"], (double)jObj["extent"]["ymin"], 0); Point3d extMax = new Point3d((double)jObj["extent"]["xmax"], (double)jObj["extent"]["ymax"], 0); ///convert and transform extents to points OSGeo.OGR.Geometry extOgrMin = new OSGeo.OGR.Geometry(wkbGeometryType.wkbPointZM); extOgrMin.AddPoint((double)jObj["extent"]["xmin"], (double)jObj["extent"]["ymin"], 0.0); extOgrMin.Transform(coordTransformUserToRhino); Point3d ogrPtMin = Heron.Convert.OgrPointToPoint3d(extOgrMin); OSGeo.OGR.Geometry extOgrMax = new OSGeo.OGR.Geometry(wkbGeometryType.wkbPointZM); extOgrMax.AddPoint((double)jObj["extent"]["xmax"], (double)jObj["extent"]["ymax"], 0.0); extOgrMax.Transform(coordTransformUserToRhino); Point3d ogrPtMax = Heron.Convert.OgrPointToPoint3d(extOgrMax); ///if SRS is geographic (ie WGS84) use Rhino's internal projection ///this is still buggy as it doesn't work with other geographic systems like NAD27 if ((userSRS.IsProjected() == 0) && (userSRS.IsLocal() == 0)) { rect = new Rectangle3d(Plane.WorldXY, Heron.Convert.WGSToXYZ(extMin), Heron.Convert.WGSToXYZ(extMax)); } else { //rect = new Rectangle3d(Plane.WorldXY, Heron.Convert.UserSRSToXYZ(extMin, userSRSToModel), Heron.Convert.UserSRSToXYZ(extMax, userSRSToModel)); rect = new Rectangle3d(Plane.WorldXY, userSRSToModelTransform * extMin, userSRSToModelTransform * extMax); } ///download image from source string imageQuery = jObj["href"].ToString(); System.Net.WebClient webClient = new System.Net.WebClient(); webClient.DownloadFile(imageQuery, fileloc + prefix + "_" + i + ".jpg"); webClient.Dispose(); } var bitmapPath = fileloc + prefix + "_" + i + ".jpg"; mapList.Append(new GH_String(bitmapPath), path); imgFrame.Append(new GH_Rectangle(rect), path); AddPreviewItem(bitmapPath, rect); } DA.SetDataTree(0, mapList); DA.SetDataTree(1, imgFrame); DA.SetDataTree(2, mapquery); }