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