/// <summary> /// Convert Vector3 World Space location to Position taking account of zoom, scale and mapscale /// </summary> /// <param name="position">Vector3 World Space coordinates</param> /// <returns>Position</returns> static public IPosition ToPosition(this Vector3 position, ICRSObject crs = null) { Geometry geom = position.ToGeometry(); SpatialReference sr = new SpatialReference(null); if (crs == null) { sr.SetWellKnownGeogCS("EPSG:4326"); } else { switch (crs.Type) { case CRSType.Name: string name = (crs as NamedCRS).Properties["name"] as string; sr.SetProjCS(name); break; case CRSType.Link: string url = (crs as LinkedCRS).Properties["href"] as string; sr.ImportFromUrl(url); break; case CRSType.Unspecified: sr.SetWellKnownGeogCS("EPSG:4326"); break; } } geom.TransformTo(sr); double[] argout = new double[3]; geom.GetPoint(0, argout); return(new Position(argout[0], argout[1], argout[2])); }
static public Geometry ToGeometry(this LineString line) { Geometry geom = new Geometry(wkbGeometryType.wkbLineString); SpatialReference sr = new SpatialReference(null); ICRSObject crs = line.CRS; if (crs == null) { crs = new NamedCRS("EPSG:4326"); } switch (crs.Type) { case CRSType.Name: string name = (crs as NamedCRS).Properties["name"] as string; if (name.Contains("urn")) { sr.ImportFromUrl(name); } else if (name.Contains("EPSG")) { string[] args = name.Split(':'); sr.ImportFromEPSG(int.Parse(args[1])); } else { sr.SetWellKnownGeogCS(name); } break; case CRSType.Link: string url = (crs as LinkedCRS).Properties["href"] as string; sr.ImportFromUrl(url); break; case CRSType.Unspecified: sr.SetWellKnownGeogCS("EPSG:4326"); break; } geom.AssignSpatialReference(sr); Position[] vertexes = line.Points(); foreach (Position vertex in vertexes) { Nullable <double> alt = vertex.Altitude; geom.AddPoint(vertex.Latitude, vertex.Longitude, alt ?? 0.0); } return(geom); }
public static void CoordTransformToWgs84(this OSGeo.OSR.SpatialReference srcSR, params double[][] inouts) { using (OSGeo.OSR.SpatialReference destSR = new OSGeo.OSR.SpatialReference("")) { destSR.SetWellKnownGeogCS("EPSG:4326"); CoordTransform(srcSR, destSR, inouts); } }
public static void CoordTransformToWgs84(this OSGeo.OSR.SpatialReference srcSR, ref double x, ref double y) { using (OSGeo.OSR.SpatialReference destSR = new OSGeo.OSR.SpatialReference("")) { destSR.SetWellKnownGeogCS("EPSG:4326"); double[] inout = { x, y }; CoordTransform(srcSR, destSR, inout); x = inout[0]; y = inout[1]; } }
public void CreateShp(string layerName, List <Geometry> GeomList) { string strDriverName = "ESRI Shapefile"; using (Driver oDriver = Ogr.GetDriverByName(strDriverName)) { //用此Driver创建Shape文件 OSGeo.OGR.DataSource poDS; poDS = oDriver.CreateDataSource(_outputFileName, null); if (poDS == null) { MessageBox.Show("DataSource Creation Error"); } using (DataSource oDS = oDriver.CreateDataSource(_outputFileName, null)) { //步骤2、创建空间坐标系 OSGeo.OSR.SpatialReference oSRS = new OSGeo.OSR.SpatialReference(""); oSRS.SetWellKnownGeogCS("WGS84"); //步骤3、创建图层,并添加坐标系,创建一个多边形图层(wkbGeometryType.wkbUnknown,存放任意几何特征) Layer oLayer = oDS.CreateLayer(layerName, oSRS, wkbGeometryType.wkbUnknown, null); // 步骤4、下面创建属性表 FieldDefn oFieldPlotArea = new FieldDefn("Name", FieldType.OFTString); // 先创建一个叫PlotArea的属性 oFieldPlotArea.SetWidth(100); // 步骤5、将创建的属性表添加到图层中 oLayer.CreateField(oFieldPlotArea, 1); foreach (var geom in GeomList) { //步骤6、定义一个特征要素oFeature(特征要素包含两个方面1.属性特征2.几何特征) FeatureDefn oDefn = oLayer.GetLayerDefn(); Feature oFeature = new Feature(oDefn); //建立了一个特征要素并将指向图层oLayer的属性表 oFeature.SetField(0, -1); //步骤7、设置属性特征的值 oFeature.SetGeometry(geom); //步骤8、设置几何特征 oLayer.CreateFeature(oFeature); //步骤9、将特征要素添加到图层中 } } } MessageBox.Show("成功导出文件到" + _outputFileName); }
public static LayerType AddToCapabilities(Capabilities capabilities, string name, string projectionStr, double xMin, double yMin, double xMax, double yMax) { LayerType layerType = null; if (capabilities == null || capabilities == null) { return(layerType); } if (capabilities.Contents == null) { capabilities.Contents = new ContentsType(); } DatasetDescriptionSummaryBaseType[] datasets = capabilities.Contents.DatasetDescriptionSummary; if (datasets?.Any(x => x.Identifier.Value == name) == true) { return(layerType); } int layerCount = datasets == null ? 1 : datasets.Length + 1; capabilities.Contents.DatasetDescriptionSummary = new DatasetDescriptionSummaryBaseType[layerCount]; datasets?.CopyTo(capabilities.Contents.DatasetDescriptionSummary, 0); datasets = capabilities.Contents.DatasetDescriptionSummary; #region 获取layerType layerType = GetLayerType(name); string projectName = null; double semimajor; BoundingBoxType[] boundingBoxs = GetBoundingBoxTypes(xMin, yMin, xMax, yMax); WGS84BoundingBoxType[] WGS84BoundingBoxes = null; using (OSGeo.OSR.SpatialReference srcSR = new OSGeo.OSR.SpatialReference(projectionStr)) { semimajor = srcSR.GetSemiMajor(); projectName = srcSR.GetAttrValue("PROJCS", 0); using (OSGeo.OSR.SpatialReference destSR = new OSGeo.OSR.SpatialReference("")) { destSR.SetWellKnownGeogCS("EPSG:4326"); if (srcSR.IsSame(destSR) != 1) { double[] leftBottom = { xMin, yMin }; double[] topRight = { xMax, yMax }; srcSR.CoordTransform(destSR, leftBottom, topRight); xMin = leftBottom[0]; yMin = leftBottom[1]; xMax = topRight[0]; yMax = topRight[1]; } WGS84BoundingBoxes = GetWGS84BoundingBoxTypes(xMin, yMin, xMax, yMax); } } TileMatrixSetLink[] tileMatrixSetLinks = GetTileMatrixSetLinks(projectName); layerType.BoundingBox = boundingBoxs; layerType.WGS84BoundingBox = WGS84BoundingBoxes; layerType.TileMatrixSetLink = tileMatrixSetLinks; #endregion datasets[datasets.Length - 1] = layerType; #region 设置tileMatrixSet TileMatrixSet[] tileMatrixSets = capabilities.Contents.TileMatrixSet; if (tileMatrixSets?.Any(x => x.Identifier.Value == projectName) != true) { int tileMatrixSetCount = tileMatrixSets == null ? 1 : tileMatrixSets.Length + 1; capabilities.Contents.TileMatrixSet = new TileMatrixSet[tileMatrixSetCount]; tileMatrixSets?.CopyTo(capabilities.Contents.TileMatrixSet, 0); tileMatrixSets = capabilities.Contents.TileMatrixSet; int minLevel = 0; int maxLevel = 20; TileMatrix[] tileMatrices = GetTileMatrices(semimajor, xMin, yMin, xMax, yMax, minLevel, maxLevel);; TileMatrixSet tileMatrixSet = new TileMatrixSet() { Identifier = new CodeType() { Value = projectName }, SupportedCRS = "urn:ogc:def:crs:OGC:1.3:CRS84",//TODO 待修改 TileMatrix = tileMatrices }; tileMatrixSets[tileMatrixSets.Length - 1] = tileMatrixSet; } #endregion return(layerType); }
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) { GH_Structure <IGH_GeometricGoo> gGoo = new GH_Structure <IGH_GeometricGoo>(); DA.GetDataTree <IGH_GeometricGoo>("Feature Geometry", out gGoo); GH_Structure <GH_Number> bufferInt = new GH_Structure <GH_Number>(); DA.GetDataTree <GH_Number>("Buffer Distance", out bufferInt); GH_Structure <IGH_GeometricGoo> gGooBuffered = new GH_Structure <IGH_GeometricGoo>(); ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); ///Use WGS84 spatial reference OSGeo.OSR.SpatialReference dst = new OSGeo.OSR.SpatialReference(""); dst.SetWellKnownGeogCS("WGS84"); Transform transform = new Transform(1); // Heron.Convert.XYZToWGSTransform(); Transform revTransform = new Transform(1); //Heron.Convert.WGSToXYZTransform(); ///Create virtual datasource to be converted later ///Using geojson as a flexiblle base file type which can be converted later with ogr2ogr OSGeo.OGR.Driver drv = Ogr.GetDriverByName("GeoJSON"); DataSource ds = drv.CreateDataSource("/vsimem/out.geojson", null); ///Use OGR catch-all for geometry types var gtype = wkbGeometryType.wkbGeometryCollection; ///Create layer OSGeo.OGR.Layer layer = ds.CreateLayer("temp", dst, gtype, null); FeatureDefn def = layer.GetLayerDefn(); var branchPaths = gGoo.Paths; for (int a = 0; a < gGoo.Branches.Count; a++) { ///create feature OSGeo.OGR.Feature feature = new OSGeo.OGR.Feature(def); ///Get geometry type(s) in branch var geomList = gGoo.Branches[a]; string geomType = string.Empty; List <string> geomTypeList = geomList.Select(o => o.TypeName).ToList(); ///Test if geometry in the branch is of the same type. ///If there is more than one element of a type, tag as multi, if there is more than one type, tag as mixed if (geomTypeList.Count == 1) { geomType = geomTypeList.First(); } else if (geomTypeList.Count > 1 && geomTypeList.All(gt => gt == geomTypeList.First())) { geomType = "Multi" + geomTypeList.First(); } else { geomType = "Mixed"; } //var buffList = bufferInt.Branches[a]; var buffList = new List <GH_Number>(); //var path = new GH_Path(a); var path = branchPaths[a]; if (path.Valid) { buffList = (List <GH_Number>)bufferInt.get_Branch(path); } else { buffList = bufferInt.Branches[0]; } int buffIndex = 0; double buffDist = 0; GH_Convert.ToDouble(buffList[buffIndex], out buffDist, GH_Conversion.Primary); ///For testing //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, geomType); ///Add geomtery to feature ///Create containers for translating from GH Goo Point3d pt = new Point3d(); List <Point3d> pts = new List <Point3d>(); Curve crv = null; List <Curve> crvs = new List <Curve>(); Mesh mesh = new Mesh(); Mesh multiMesh = new Mesh(); int quadsecs = 10; switch (geomType) { case "Point": geomList.First().CastTo <Point3d>(out pt); var bufferPt = Heron.Convert.Point3dToOgrPoint(pt, transform).Buffer(buffDist, quadsecs); gGooBuffered.AppendRange(Heron.Convert.OgrGeomToGHGoo(bufferPt, revTransform), new GH_Path(a)); break; case "MultiPoint": foreach (var point in geomList) { point.CastTo <Point3d>(out pt); pts.Add(pt); } var bufferPts = Heron.Convert.Point3dsToOgrMultiPoint(pts, transform).Buffer(buffDist, quadsecs); gGooBuffered.AppendRange(Heron.Convert.OgrGeomToGHGoo(bufferPts, revTransform), new GH_Path(a)); break; case "Curve": geomList.First().CastTo <Curve>(out crv); var bufferCrv = Heron.Convert.CurveToOgrLinestring(crv, transform).Buffer(buffDist, quadsecs); gGooBuffered.AppendRange(Heron.Convert.OgrGeomToGHGoo(bufferCrv, revTransform), new GH_Path(a)); break; case "MultiCurve": bool allClosed = true; foreach (var curve in geomList) { curve.CastTo <Curve>(out crv); if (!crv.IsClosed) { allClosed = false; } crvs.Add(crv); } if (allClosed) { var bufferCrvs = Heron.Convert.CurvesToOgrPolygon(crvs, transform).Buffer(buffDist, quadsecs); gGooBuffered.AppendRange(Heron.Convert.OgrGeomToGHGoo(bufferCrvs, revTransform), new GH_Path(a)); } else { var bufferCrvs = Heron.Convert.CurvesToOgrMultiLinestring(crvs, transform).Buffer(buffDist, quadsecs); gGooBuffered.AppendRange(Heron.Convert.OgrGeomToGHGoo(bufferCrvs, revTransform), new GH_Path(a)); } break; case "Mesh": geomList.First().CastTo <Mesh>(out mesh); mesh.Ngons.AddPlanarNgons(DocumentTolerance()); var bufferPoly = Ogr.ForceToMultiPolygon(Heron.Convert.MeshToMultiPolygon(mesh, transform)).Buffer(buffDist, quadsecs); gGooBuffered.AppendRange(Heron.Convert.OgrGeomToGHGoo(bufferPoly, revTransform), new GH_Path(a)); break; case "MultiMesh": foreach (var m in geomList) { Mesh meshPart = new Mesh(); m.CastTo <Mesh>(out meshPart); meshPart.Ngons.AddPlanarNgons(DocumentTolerance()); multiMesh.Append(meshPart); } var bufferPolys = Ogr.ForceToMultiPolygon(Heron.Convert.MeshToMultiPolygon(multiMesh, transform)).Buffer(buffDist, quadsecs); gGooBuffered.AppendRange(Heron.Convert.OgrGeomToGHGoo(bufferPolys, revTransform), new GH_Path(a)); break; case "Mixed": OSGeo.OGR.Geometry geoCollection = new OSGeo.OGR.Geometry(wkbGeometryType.wkbGeometryCollection); for (int gInt = 0; gInt < geomList.Count; gInt++) { string geomTypeMixed = geomTypeList[gInt]; switch (geomTypeMixed) { case "Point": geomList[gInt].CastTo <Point3d>(out pt); geoCollection.AddGeometry(Heron.Convert.Point3dToOgrPoint(pt, transform)); break; case "Curve": geomList[gInt].CastTo <Curve>(out crv); geoCollection.AddGeometry(Heron.Convert.CurveToOgrLinestring(crv, transform)); break; case "Mesh": geomList[gInt].CastTo <Mesh>(out mesh); geoCollection.AddGeometry(Ogr.ForceToMultiPolygon(Heron.Convert.MeshToMultiPolygon(mesh, transform))); break; default: AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Not able to export " + geomType + " geometry at branch " + gGoo.get_Path(a).ToString() + ". Geometry must be a Point, Curve or Mesh."); break; } } var bufferCol = geoCollection.Buffer(buffDist, quadsecs); gGooBuffered.AppendRange(Heron.Convert.OgrGeomToGHGoo(bufferCol, revTransform), new GH_Path(a)); break; default: AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Not able to export " + geomType + " geometry at branch " + gGoo.get_Path(a).ToString() + ". Geometry must be a Point, Curve or Mesh."); break; } } def.Dispose(); layer.Dispose(); ds.Dispose(); DA.SetDataTree(0, gGooBuffered); }
public static LayerType AddToCapabilities(Capabilities capabilities, string name, string projectionStr, double xMin, double yMin, double xMax, double yMax, int minLevel, int maxLevel) { LayerType layerType = null; if (capabilities == null || capabilities == null || minLevel < 0 || minLevel > maxLevel) { return(layerType); } if (capabilities.Contents == null) { capabilities.Contents = new ContentsType(); } DatasetDescriptionSummaryBaseType[] datasets = capabilities.Contents.DatasetDescriptionSummary; if (datasets?.Any(x => x.Identifier.Value == name) == true) { return(layerType); } int layerCount = datasets == null ? 1 : datasets.Length + 1; capabilities.Contents.DatasetDescriptionSummary = new DatasetDescriptionSummaryBaseType[layerCount]; datasets?.CopyTo(capabilities.Contents.DatasetDescriptionSummary, 0); datasets = capabilities.Contents.DatasetDescriptionSummary; #region 获取layerType layerType = CreateLayerType(name); string projcs = null; string geogcs = null; double semimajor; BoundingBoxType[] boundingBoxs = CreateBoundingBoxTypes(xMin, yMin, xMax, yMax); WGS84BoundingBoxType[] WGS84BoundingBoxes = null; using (OSGeo.OSR.SpatialReference srcSR = new OSGeo.OSR.SpatialReference(projectionStr)) { semimajor = srcSR.GetSemiMajor(); projcs = srcSR.GetAttrValue("PROJCS", 0); if (string.IsNullOrEmpty(projcs)) { geogcs = srcSR.GetAttrValue("GEOGCS", 0); } using (OSGeo.OSR.SpatialReference destSR = new OSGeo.OSR.SpatialReference("")) { destSR.SetWellKnownGeogCS("EPSG:4326"); double WGS84XMin = xMin; double WGS84YMin = yMin; double WGS84XMax = xMax; double WGS84YMax = yMax; if (srcSR.IsSame(destSR) != 1) { double[] leftBottom = { xMin, yMin }; double[] topRight = { xMax, yMax }; srcSR.CoordTransform(destSR, leftBottom, topRight); WGS84XMin = leftBottom[0]; WGS84YMin = leftBottom[1]; WGS84XMax = topRight[0]; WGS84YMax = topRight[1]; } WGS84BoundingBoxes = CreateWGS84BoundingBoxTypes(WGS84XMin, WGS84YMin, WGS84XMax, WGS84YMax); } } string tileMatrixSetName = !string.IsNullOrEmpty(projcs) ? projcs : geogcs; TileMatrixSetLink[] tileMatrixSetLinks = CreateTileMatrixSetLinks(tileMatrixSetName); layerType.BoundingBox = boundingBoxs; layerType.WGS84BoundingBox = WGS84BoundingBoxes; layerType.TileMatrixSetLink = tileMatrixSetLinks; #endregion datasets[datasets.Length - 1] = layerType; #region 设置tileMatrixSet TileMatrixSet[] tileMatrixSets = capabilities.Contents.TileMatrixSet; if (tileMatrixSets?.Any(x => x.Identifier.Value == tileMatrixSetName) != true) { int tileMatrixSetCount = tileMatrixSets == null ? 1 : tileMatrixSets.Length + 1; capabilities.Contents.TileMatrixSet = new TileMatrixSet[tileMatrixSetCount]; tileMatrixSets?.CopyTo(capabilities.Contents.TileMatrixSet, 0); tileMatrixSets = capabilities.Contents.TileMatrixSet; bool isDegree = projcs == null; TileMatrix[] tileMatrices = CreateTileMatrices(semimajor, isDegree, xMin, yMin, xMax, yMax, minLevel, maxLevel); int?wkid = null; if (!string.IsNullOrEmpty(projcs)) { wkid = SpatialReferenceHelper.GetWellKnownWkidFromProjecs(projcs); } else if (!string.IsNullOrEmpty(geogcs)) { wkid = SpatialReferenceHelper.GetWellKnownWkidFromGeogcs(geogcs); } if (wkid.HasValue) { TileMatrixSet tileMatrixSet = new TileMatrixSet() { Identifier = new CodeType() { Value = tileMatrixSetName }, SupportedCRS = $"urn:ogc:def:crs:EPSG::{wkid.Value}",//TODO 待修改 根据名称获取EPSG,网上下载arcgis的 TileMatrix = tileMatrices }; tileMatrixSets[tileMatrixSets.Length - 1] = tileMatrixSet; } } #endregion return(layerType); }
/// <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); }