/// <summary> /// Ogr to DotSpatial at feature fields level /// </summary> /// <param name="featureDefn">Ogr FeatureDefn</param> /// <returns>DataTable of FeatureSet</returns> public static DataTable Ogr2DSDataTable(OSGeo.OGR.FeatureDefn featureDefn) { DataTable dataTable = new DataTable(); for (int i = 0; i < featureDefn.GetFieldCount(); i++) { OSGeo.OGR.FieldDefn fieldDefn = featureDefn.GetFieldDefn(i); DataColumn dataColumn = Ogr2DSField(fieldDefn); dataTable.Columns.Add(dataColumn); } return(dataTable); }
/// <summary> /// DotSpatial to Ogr at layer level /// </summary> /// <param name="featureSet">DotSpatial IFeatureSet</param> /// <returns>Ogr Layer</returns> public static OSGeo.OGR.Layer DS2OrgLayer(DotSpatial.Data.IFeatureSet featureSet) { using (OSGeo.OGR.Driver driver = OSGeo.OGR.Ogr.GetDriverByName("Memory")) { OSGeo.OGR.DataSource dataSource = driver.CreateDataSource(featureSet.Name, null); OSGeo.OGR.Layer layer = dataSource.CreateLayer("Result", DS2OgrProjection(featureSet.Projection), DS2OgrGeometryType(featureSet.FeatureType), new string[] { }); OSGeo.OGR.FeatureDefn featureDefn = DS2OgrDataTable(featureSet.DataTable); for (int k = 0; k < featureDefn.GetFieldCount(); k++) { layer.CreateField(featureDefn.GetFieldDefn(k), 0); } for (int i = 0; i < featureSet.NumRows(); i++) { DotSpatial.Data.IFeature feature = featureSet.GetFeature(i); OSGeo.OGR.Feature ogrFeature = new OSGeo.OGR.Feature(featureDefn); ogrFeature.SetGeometry(DS2OgrGeometry(feature.Geometry, featureSet)); for (int j = 0; j < feature.DataRow.ItemArray.Length; j++) { #region Set Value to Feature object value = feature.DataRow.ItemArray.GetValue(j); if (value is int) { ogrFeature.SetField(j, (int)value); } else if (value is double) { ogrFeature.SetField(j, (double)value); } else if (value is string) { ogrFeature.SetField(j, (string)value); } else if (value is DateTime) { DateTime dateTime = (DateTime)value; ogrFeature.SetField(j, dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, (float)dateTime.Second, 0); } #endregion } layer.CreateFeature(ogrFeature); } dataSource.FlushCache(); return(layer); } }
public static OSGeo.OGR.Layer DS2OrgLayer(DotSpatial.Data.IFeatureSet featureSet, OSGeo.OGR.Layer layer) { using (OSGeo.OGR.FeatureDefn featureDefn = DS2OgrDataTable(featureSet.DataTable)) { for (int k = 0; k < featureDefn.GetFieldCount(); k++) { layer.CreateField(featureDefn.GetFieldDefn(k), 0); } for (int i = 0; i < featureSet.NumRows(); i++) { DotSpatial.Data.IFeature feature = featureSet.GetFeature(i); using (OSGeo.OGR.Feature ogrFeature = new OSGeo.OGR.Feature(featureDefn)) { ogrFeature.SetGeometry(DS2OgrGeometry(feature.Geometry, featureSet)); for (int j = 0; j < feature.DataRow.ItemArray.Length; j++) { #region Set Value to Feature object value = feature.DataRow.ItemArray.GetValue(j); if (value is int) { ogrFeature.SetField(j, (int)value); } else if (value is double) { ogrFeature.SetField(j, (double)value); } else if (value is string) { ogrFeature.SetField(j, (string)value); } else if (value is DateTime) { DateTime dateTime = (DateTime)value; ogrFeature.SetField(j, dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, (float)dateTime.Second, 0); } #endregion } layer.CreateFeature(ogrFeature); } } } return(layer); }
/// <summary> /// Reads the field types from the OgrFeatureDefinition -> OgrFieldDefinition /// </summary> /// <param name="fdt">FeatureDatatTable</param> /// <param name="oLayer">OgrLayer</param> private static void ReadColumnDefinition(FeatureDataTable fdt, OgrLayer oLayer) { using (OgrFeatureDefn ogrFeatureDefn = oLayer.GetLayerDefn()) { int iField; for (iField = 0; iField < ogrFeatureDefn.GetFieldCount(); iField++) { using (OgrFieldDefn ogrFldDef = ogrFeatureDefn.GetFieldDefn(iField)) { OgrFieldType type = ogrFldDef.GetFieldType(); switch (type) { case OgrFieldType.OFTInteger: fdt.Columns.Add(ogrFldDef.GetName(), typeof(Int32)); break; case OgrFieldType.OFTReal: fdt.Columns.Add(ogrFldDef.GetName(), typeof(Double)); break; case OgrFieldType.OFTString: fdt.Columns.Add(ogrFldDef.GetName(), typeof(String)); break; case OgrFieldType.OFTWideString: fdt.Columns.Add(ogrFldDef.GetName(), typeof(String)); break; case OgrFieldType.OFTDate: case OgrFieldType.OFTTime: case OgrFieldType.OFTDateTime: fdt.Columns.Add(ogrFldDef.GetName(), typeof(DateTime)); break; default: { //fdt.Columns.Add(_OgrFldDef.GetName(), System.Type.GetType("System.String")); Debug.WriteLine("Not supported type: " + type + " [" + ogrFldDef.GetName() + "]"); break; } } } } } }
public static void map_fields(OSGeo.OGR.Layer ogr_layer, out System.Collections.Hashtable outFieldMap, out ESRI.ArcGIS.Geodatabase.IFields outFields, out ESRI.ArcGIS.Geodatabase.esriDatasetType outDatasetType, out ESRI.ArcGIS.Geometry.esriGeometryType outGeometryType, out int outShapeIndex, out int outOIDFieldIndex, out ISpatialReference outSpatialReference) { outSpatialReference = null; outFields = null; outDatasetType = ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTTable; // start assuming it is a table outGeometryType = esriGeometryType.esriGeometryNull; //don't know what it is outOIDFieldIndex = -1; outShapeIndex = -1; outFieldMap = new System.Collections.Hashtable(); System.Collections.ArrayList fieldArray = new System.Collections.ArrayList(); OSGeo.OGR.FeatureDefn featDef = ogr_layer.GetLayerDefn(); int fieldsInserted = 0; // OIDs and Geometries can be pseudo fields in GDAL and are thus *may* not included in the OGR FieldDef // To account for that add those first (if they exist) and keep a mapping of fields using // fieldsInserted ////////////////////////////// // // handle oid field pseudo column // ESRI.ArcGIS.Geodatabase.IFieldEdit2 oidFieldEdit = new ESRI.ArcGIS.Geodatabase.FieldClass(); if (ogr_layer.GetFIDColumn().Length > 0) { oidFieldEdit.Name_2 = ogr_layer.GetFIDColumn(); oidFieldEdit.AliasName_2 = ogr_layer.GetFIDColumn(); } else { oidFieldEdit.Name_2 = "FID"; oidFieldEdit.AliasName_2 = "FID"; } oidFieldEdit.Type_2 = ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeOID; fieldArray.Add(oidFieldEdit); outOIDFieldIndex = fieldsInserted; fieldsInserted++; ////////////////////////////////////// // // handle (optional) geometry field pseudo column // if (!(ogr_layer.GetGeomType() == OSGeo.OGR.wkbGeometryType.wkbNone || ogr_layer.GetGeomType() == OSGeo.OGR.wkbGeometryType.wkbUnknown)) { ESRI.ArcGIS.Geodatabase.IFieldEdit2 geomFieldEdit = new ESRI.ArcGIS.Geodatabase.FieldClass(); if (ogr_layer.GetGeometryColumn().Length > 0) { geomFieldEdit.Name_2 = ogr_layer.GetGeometryColumn(); geomFieldEdit.AliasName_2 = ogr_layer.GetGeometryColumn(); } else { geomFieldEdit.Name_2 = "Shape"; geomFieldEdit.AliasName_2 = "Shape"; } geomFieldEdit.Type_2 = ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeGeometry; // add geometry def ESRI.ArcGIS.Geometry.esriGeometryType gdbType; bool hasZ; ogr_geo_type_to_esri_geo_type(ogr_layer.GetGeomType(), out gdbType, out hasZ); ESRI.ArcGIS.Geodatabase.IGeometryDefEdit geomDef = new ESRI.ArcGIS.Geodatabase.GeometryDefClass(); geomDef.GeometryType_2 = gdbType; geomDef.HasM_2 = false; //no M support on OGR geomDef.HasZ_2 = hasZ; geomDef.SpatialReference_2 = outSpatialReference = ogr_utils.get_spatialReference(ogr_layer.GetSpatialRef()); geomFieldEdit.GeometryDef_2 = geomDef; fieldArray.Add(geomFieldEdit); outDatasetType = ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTFeatureClass; // upgrade to featureclass outGeometryType = gdbType; outShapeIndex = fieldsInserted; fieldsInserted++; } int fieldCount = featDef.GetFieldCount(); for (int i = 0; i < fieldCount; i++) { // map OGR field to ArcObjects OSGeo.OGR.FieldDefn fieldDef = featDef.GetFieldDefn(i); ESRI.ArcGIS.Geodatabase.IFieldEdit2 fieldEdit = new ESRI.ArcGIS.Geodatabase.FieldClass(); fieldEdit.Name_2 = fieldDef.GetName(); fieldEdit.AliasName_2 = fieldDef.GetName(); // map type OSGeo.OGR.FieldType ogrFieldType = fieldDef.GetFieldType(); ESRI.ArcGIS.Geodatabase.esriFieldType mappedType; switch (ogrFieldType) { case OSGeo.OGR.FieldType.OFTInteger: mappedType = ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeInteger; break; case OSGeo.OGR.FieldType.OFTReal: mappedType = ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeDouble; break; case OSGeo.OGR.FieldType.OFTString: mappedType = ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeString; break; case OSGeo.OGR.FieldType.OFTBinary: mappedType = ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeBlob; break; case OSGeo.OGR.FieldType.OFTDateTime: mappedType = ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeDate; break; default: mappedType = ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeString; break; } fieldEdit.Type_2 = mappedType; outFieldMap.Add(fieldsInserted, i); fieldArray.Add(fieldEdit); fieldsInserted++; } // Add all the fields from the array to an ESRI fields class object. The reason that we do that // here is that we need to know the count in advance ESRI.ArcGIS.Geodatabase.IFieldsEdit fields = new ESRI.ArcGIS.Geodatabase.FieldsClass(); fields.FieldCount_2 = fieldArray.Count; for (int i = 0; i < fieldArray.Count; i++) { fields.set_Field(i, fieldArray[i] as ESRI.ArcGIS.Geodatabase.IField); } outFields = fields; }
public FeatureClass(Dataset dataset, OSGeo.OGR.Layer layer) { _dataset = dataset; _ogrLayer = layer; OSGeo.OGR.FeatureDefn defn = layer.GetLayerDefn(); _name = defn.GetName(); if (dataset.ConnectionString.ToLower().EndsWith(".dxf")) { try { System.IO.FileInfo fi = new System.IO.FileInfo(dataset.ConnectionString); _name = fi.Name; } catch { } } _fields = new Fields(); for (int i = 0; i < defn.GetFieldCount(); i++) { OSGeo.OGR.FieldDefn fdefn = defn.GetFieldDefn(i); Field field = new Field(fdefn.GetName()); switch (fdefn.GetFieldTypeName(fdefn.GetFieldType()).ToLower()) { case "integer": if (_idFieldName == String.Empty) { _idFieldName = field.name; } field.type = FieldType.integer; break; case "real": field.type = FieldType.Double; break; case "string": field.type = FieldType.String; field.size = fdefn.GetWidth(); break; } _fields.Add(field); } _countFeatures = layer.GetFeatureCount(1); OSGeo.OGR.Envelope env = new OSGeo.OGR.Envelope(); layer.GetExtent(env, 1); _envelope = new Envelope(env.MinX, env.MinY, env.MaxX, env.MaxY); switch (defn.GetGeomType()) { case OSGeo.OGR.wkbGeometryType.wkbPoint: _geomType = geometryType.Point; break; case OSGeo.OGR.wkbGeometryType.wkbLineString: case OSGeo.OGR.wkbGeometryType.wkbMultiLineString: _geomType = geometryType.Polyline; break; case OSGeo.OGR.wkbGeometryType.wkbPolygon: case OSGeo.OGR.wkbGeometryType.wkbMultiPolygon: _geomType = geometryType.Polygon; break; } }
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) { ///Gather GHA inputs List <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>("Boundary", boundary); string shpFileLoc = ""; DA.GetData <string>("Vector Data Location", ref shpFileLoc); bool cropIt = true; DA.GetData <Boolean>("Crop file", ref cropIt); string userSRStext = "WGS84"; DA.GetData <string>(2, ref userSRStext); ///GDAL setup ///Some preliminary testing has been done to read SHP, GeoJSON, OSM, KML, MVT, GML and GDB ///It can be spotty with KML, MVT and GML and doesn't throw informative errors. Likely has to do with getting a valid CRS and ///TODO: resolve errors with reading KML, MVT, GML. RESTful.GdalConfiguration.ConfigureOgr(); OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver drv = OSGeo.OGR.Ogr.GetDriverByName("ESRI Shapefile"); OSGeo.OGR.DataSource ds = OSGeo.OGR.Ogr.Open(shpFileLoc, 0); if (ds == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The vector datasource was unreadable by this component. It may not a valid file type for this component or otherwise null/empty."); return; } List <OSGeo.OGR.Layer> layerset = new List <OSGeo.OGR.Layer>(); List <int> fc = new List <int>(); for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++) { OSGeo.OGR.Layer layer = ds.GetLayerByIndex(iLayer); if (layer == null) { Console.WriteLine("Couldn't fetch advertised layer " + iLayer); System.Environment.Exit(-1); } else { layerset.Add(layer); } } ///Declare trees GH_Structure <GH_String> layname = new GH_Structure <GH_String>(); GH_Structure <GH_Integer> fcs = new GH_Structure <GH_Integer>(); GH_Structure <GH_Rectangle> recs = new GH_Structure <GH_Rectangle>(); GH_Structure <GH_String> sRefs = new GH_Structure <GH_String>(); GH_Structure <GH_String> fnames = new GH_Structure <GH_String>(); GH_Structure <GH_String> fset = new GH_Structure <GH_String>(); GH_Structure <GH_Point> gset = new GH_Structure <GH_Point>(); GH_Structure <GH_Point> gsetUser = new GH_Structure <GH_Point>(); GH_Structure <GH_Rectangle> recsUser = new GH_Structure <GH_Rectangle>(); ///Loop through each layer. Layers usually occur in Geodatabase GDB format. SHP usually has only one layer. for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++) { OSGeo.OGR.Layer layer = ds.GetLayerByIndex(iLayer); if (layer == null) { Console.WriteLine("Couldn't fetch advertised layer " + iLayer); System.Environment.Exit(-1); } long count = layer.GetFeatureCount(1); int featureCount = System.Convert.ToInt32(count); fcs.Append(new GH_Integer(featureCount), new GH_Path(iLayer)); layname.Append(new GH_String(layer.GetName()), new GH_Path(iLayer)); ///Get the spatial reference of the input vector file and set to WGS84 if not known OSGeo.OSR.SpatialReference sourceSRS = new SpatialReference(Osr.SRS_WKT_WGS84); string sRef = ""; if (layer.GetSpatialRef() == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is missing. CRS set automatically set to WGS84. Mapbox to 3857"); //sr.ImportFromXML(shpFileLoc); //sr.ImportFromEPSG(3857); //sr.SetWellKnownGeogCS("EPSG:3857"); sourceSRS.SetFromUserInput("WGS84"); ///this seems to work where SetWellKnownGeogCS doesn't string pretty = ""; sourceSRS.ExportToPrettyWkt(out pretty, 0); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, pretty); //sr.SetWellKnownGeogCS("WGS84"); //sr.SetWellKnownGeogCS("EPSG:3857"); sRef = "Coordinate Reference System (CRS) is missing. CRS set automatically set to WGS84."; } else { if (layer.GetSpatialRef().Validate() != 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is unknown or unsupported. CRS set automatically set to WGS84."); sourceSRS.SetWellKnownGeogCS("WGS84"); sRef = "Coordinate Reference System (CRS) is unknown or unsupported. SRS set automatically set to WGS84."; } else { sourceSRS = layer.GetSpatialRef(); sourceSRS.ExportToWkt(out sRef); try { int sourceSRSInt = Int16.Parse(sourceSRS.GetAuthorityCode(null)); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Source Coordinate Reference System (CRS) from layer " + layer.GetName() + " is EPSG:" + sourceSRSInt + "."); } catch { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Failed to get Source Coordinate Reference System (CRS) from layer " + layer.GetName() + "."); } } } sRefs.Append(new GH_String(sRef), new GH_Path(iLayer)); ///Set transform from input spatial reference to Rhino spatial reference ///TODO: look into adding a step for transforming to CRS set in SetCRS OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); rhinoSRS.SetWellKnownGeogCS("WGS84"); ///TODO: verify the userSRS is valid ///TODO: use this as override of global SetSRS OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference(""); userSRS.SetFromUserInput(userSRStext); ///This transform moves and scales the points required in going from userSRS to XYZ and vice versa Transform userSRSToModel = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRS = Heron.Convert.GetModelToUserSRSTransform(userSRS); OSGeo.OSR.CoordinateTransformation coordTransformSourceToRhino = new OSGeo.OSR.CoordinateTransformation(sourceSRS, rhinoSRS); OSGeo.OSR.CoordinateTransformation coordTransformRhinoToUser = new OSGeo.OSR.CoordinateTransformation(rhinoSRS, userSRS); OSGeo.OSR.CoordinateTransformation coordTransformSourceToUser = new OSGeo.OSR.CoordinateTransformation(sourceSRS, userSRS); OSGeo.OSR.CoordinateTransformation revTransformUserToRhino = new OSGeo.OSR.CoordinateTransformation(userSRS, rhinoSRS); OSGeo.OSR.CoordinateTransformation revTransformRhinoToSource = new OSGeo.OSR.CoordinateTransformation(rhinoSRS, sourceSRS); OSGeo.OSR.CoordinateTransformation revTransformUserToSource = new OSGeo.OSR.CoordinateTransformation(userSRS, sourceSRS); ///Get OGR envelope of the data in the layer in the sourceSRS OSGeo.OGR.Envelope ext = new OSGeo.OGR.Envelope(); layer.GetExtent(ext, 1); Point3d extMinSource = new Point3d(); Point3d extMaxSource = new Point3d(); extMinSource.X = ext.MinX; extMinSource.Y = ext.MinY; extMaxSource.X = ext.MaxX; extMaxSource.Y = ext.MaxY; ///Get bounding box of data in layer for coordinate transformation in Rhino SRS double[] extMinPT = new double[3] { extMinSource.X, extMinSource.Y, extMinSource.Z }; double[] extMaxPT = new double[3] { extMaxSource.X, extMaxSource.Y, extMaxSource.Z }; ///Transform corners of extents from Source to Rhino SRS coordTransformSourceToRhino.TransformPoint(extMinPT); coordTransformSourceToRhino.TransformPoint(extMaxPT); ///Get extents in Rhino SRS Point3d extPTmin = new Point3d(extMinPT[0], extMinPT[1], extMinPT[2]); Point3d extPTmax = new Point3d(extMaxPT[0], extMaxPT[1], extMaxPT[2]); Rectangle3d rec = new Rectangle3d(Plane.WorldXY, Heron.Convert.WGSToXYZ(extPTmin), Heron.Convert.WGSToXYZ(extPTmax)); recs.Append(new GH_Rectangle(rec), new GH_Path(iLayer)); if (boundary.Count == 0 && cropIt == true) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Define a boundary or set cropIt to False"); } else if (boundary.Count == 0 && cropIt == false) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Clipping boundary has not been defined. File extents will be used instead"); boundary.Add(rec.ToNurbsCurve()); } ///Get bounding box of data in layer for coordinate transformation in User SRS ///TODO: currently the extents are showing odd results that don't seem to be shifting properly double[] extMinPTUser = new double[3] { extMinSource.X, extMinSource.Y, extMinSource.Z }; double[] extMaxPTUser = new double[3] { extMaxSource.X, extMaxSource.Y, extMaxSource.Z }; ///Transform corners of extents from Source to userSRS coordTransformSourceToUser.TransformPoint(extMinPTUser); coordTransformSourceToUser.TransformPoint(extMaxPTUser); ///Get extents in userSRS Point3d extPTminUser = new Point3d(extMinPTUser[0], extMinPTUser[1], extMinPTUser[2]); Point3d extPTmaxUser = new Point3d(extMaxPTUser[0], extMaxPTUser[1], extMaxPTUser[2]); Rectangle3d recUser = new Rectangle3d(Plane.WorldXY, Heron.Convert.UserSRSToXYZ(extPTminUser, userSRSToModel), Heron.Convert.UserSRSToXYZ(extPTmaxUser, userSRSToModel)); recsUser.Append(new GH_Rectangle(recUser), new GH_Path(iLayer)); ///Loop through input boundaries for (int i = 0; i < boundary.Count; i++) { OSGeo.OGR.FeatureDefn def = layer.GetLayerDefn(); ///Get the field names List <string> fieldnames = new List <string>(); for (int iAttr = 0; iAttr < def.GetFieldCount(); iAttr++) { OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iAttr); fnames.Append(new GH_String(fdef.GetNameRef()), new GH_Path(i, iLayer)); } ///Check if boundary is contained in extent if (!rec.IsValid || ((rec.Height == 0) && (rec.Width == 0))) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more vector datasource bounds are not valid."); OSGeo.OGR.Feature feat; int m = 0; while ((feat = layer.GetNextFeature()) != null) { ///Loop through field values for (int iField = 0; iField < feat.GetFieldCount(); iField++) { OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField); fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m)); fdef.Dispose(); } m++; feat.Dispose(); } } else if (boundary[i] == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Clipping boundary " + i + " not set."); } else if (!boundary[i].IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Clipping boundary " + i + " is not valid."); } else if (rec.IsValid && Curve.PlanarClosedCurveRelationship(rec.ToNurbsCurve(), boundary[i], Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) == RegionContainment.Disjoint) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more boundaries may be outside the bounds of the vector datasource."); } else { ///Create bounding box for clipping geometry Point3d min = Heron.Convert.XYZToWGS(boundary[i].GetBoundingBox(true).Min); Point3d max = Heron.Convert.XYZToWGS(boundary[i].GetBoundingBox(true).Max); double[] minpT = new double[3]; double[] maxpT = new double[3]; minpT[0] = min.X; minpT[1] = min.Y; minpT[2] = min.Z; maxpT[0] = max.X; maxpT[1] = max.Y; maxpT[2] = max.Z; revTransformRhinoToSource.TransformPoint(minpT); revTransformRhinoToSource.TransformPoint(maxpT); ///TODO: allow boundary to be converted to userSRS //revTransformUserToRhino.TransformPoint(minpT); //revTransformUserToRhino.TransformPoint(maxpT); ///Convert to OGR geometry ///TODO: add conversion from GH geometry to OGR to Convert class OSGeo.OGR.Geometry ebbox = OSGeo.OGR.Geometry.CreateFromWkt("POLYGON((" + minpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + minpT[1] + "))"); ///Clip Shapefile ///http://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html ///TODO: allow for polyline/curve as clipper, not just bounding box OSGeo.OGR.Layer clipped_layer = layer; if (cropIt) { clipped_layer.SetSpatialFilter(ebbox); } ///Loop through geometry OSGeo.OGR.Feature feat; def = clipped_layer.GetLayerDefn(); int m = 0; while ((feat = clipped_layer.GetNextFeature()) != null) { OSGeo.OGR.Geometry geom = feat.GetGeometryRef(); OSGeo.OGR.Geometry sub_geom; OSGeo.OGR.Geometry geomUser = feat.GetGeometryRef().Clone();// geom.Clone(); OSGeo.OGR.Geometry sub_geomUser; ///reproject geometry to WGS84 ///TODO: look into using the SetCRS global variable here geom.Transform(coordTransformSourceToRhino); geomUser.Transform(coordTransformSourceToUser); if (feat.GetGeometryRef() != null) { ///Start get points if open polylines and points for (int gpc = 0; gpc < geom.GetPointCount(); gpc++) { ///Loop through geometry points for Rhino SRS double[] pT = new double[3]; pT[0] = geom.GetX(gpc); pT[1] = geom.GetY(gpc); pT[2] = geom.GetZ(gpc); if (Double.IsNaN(geom.GetZ(gpc))) { pT[2] = 0; } Point3d pt3D = new Point3d(); pt3D.X = pT[0]; pt3D.Y = pT[1]; pt3D.Z = pT[2]; gset.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3D)), new GH_Path(i, iLayer, m)); ///Loop through geometry points for User SRS double[] pTUser = new double[3]; pTUser[0] = geomUser.GetX(gpc); pTUser[1] = geomUser.GetY(gpc); pTUser[2] = geomUser.GetZ(gpc); if (Double.IsNaN(geomUser.GetZ(gpc))) { pTUser[2] = 0; } Point3d pt3DUser = new Point3d(); pt3DUser.X = pTUser[0]; pt3DUser.Y = pTUser[1]; pt3DUser.Z = pTUser[2]; if ((userSRS.IsProjected() == 0) && (userSRS.IsLocal() == 0)) { gsetUser.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3DUser)), new GH_Path(i, iLayer, m)); } else { gsetUser.Append(new GH_Point(userSRSToModel * 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 < geom.GetGeometryCount(); gi++) { sub_geom = geom.GetGeometryRef(gi); OSGeo.OGR.Geometry subsub_geom; //List<Point3d> geom_list = new List<Point3d>(); sub_geomUser = geomUser.GetGeometryRef(gi); OSGeo.OGR.Geometry subsub_geomUser; if (sub_geom.GetGeometryCount() > 0) { for (int n = 0; n < sub_geom.GetGeometryCount(); n++) { subsub_geom = sub_geom.GetGeometryRef(n); subsub_geomUser = sub_geomUser.GetGeometryRef(n); for (int ptnum = 0; ptnum < subsub_geom.GetPointCount(); ptnum++) { ///Loop through geometry points double[] pT = new double[3]; pT[0] = subsub_geom.GetX(ptnum); pT[1] = subsub_geom.GetY(ptnum); pT[2] = subsub_geom.GetZ(ptnum); Point3d pt3D = new Point3d(); pt3D.X = pT[0]; pt3D.Y = pT[1]; pt3D.Z = pT[2]; gset.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3D)), new GH_Path(i, iLayer, m, gi, n)); double[] pTUser = new double[3]; pTUser[0] = subsub_geomUser.GetX(ptnum); pTUser[1] = subsub_geomUser.GetY(ptnum); pTUser[2] = subsub_geomUser.GetZ(ptnum); Point3d pt3DUser = new Point3d(); pt3DUser.X = pTUser[0]; pt3DUser.Y = pTUser[1]; pt3DUser.Z = pTUser[2]; if ((userSRS.IsProjected() == 0) && (userSRS.IsLocal() == 0)) { gsetUser.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3DUser)), new GH_Path(i, iLayer, m, gi, n)); } else { gsetUser.Append(new GH_Point(userSRSToModel * pt3DUser), new GH_Path(i, iLayer, m, gi, n)); } ///End loop through geometry points } subsub_geom.Dispose(); subsub_geomUser.Dispose(); } } else { for (int ptnum = 0; ptnum < sub_geom.GetPointCount(); ptnum++) { ///Loop through geometry points double[] pT = new double[3]; pT[0] = sub_geom.GetX(ptnum); pT[1] = sub_geom.GetY(ptnum); pT[2] = sub_geom.GetZ(ptnum); Point3d pt3D = new Point3d(); pt3D.X = pT[0]; pt3D.Y = pT[1]; pt3D.Z = pT[2]; gset.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3D)), new GH_Path(i, iLayer, m, gi)); double[] pTUser = new double[3]; pTUser[0] = sub_geomUser.GetX(ptnum); pTUser[1] = sub_geomUser.GetY(ptnum); pTUser[2] = sub_geomUser.GetZ(ptnum); Point3d pt3DUser = new Point3d(); pt3DUser.X = pTUser[0]; pt3DUser.Y = pTUser[1]; pt3DUser.Z = pTUser[2]; if ((userSRS.IsProjected() == 0) && (userSRS.IsLocal() == 0)) { gsetUser.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3DUser)), new GH_Path(i, iLayer, m, gi)); } else { gsetUser.Append(new GH_Point(userSRSToModel * pt3DUser), new GH_Path(i, iLayer, m, gi)); } ///End loop through geometry points } } sub_geom.Dispose(); 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 } //m++; } m++; geom.Dispose(); geomUser.Dispose(); feat.Dispose(); } ///end while loop through features } } //end loop through boundaries layer.Dispose(); }///end loop through layers ds.Dispose(); DA.SetDataTree(0, layname); DA.SetDataTree(1, fcs); DA.SetDataTree(2, recs); DA.SetDataTree(3, sRefs); DA.SetDataTree(4, fnames); DA.SetDataTree(5, fset); DA.SetDataTree(6, gset); DA.SetDataTree(7, gsetUser); DA.SetDataTree(8, recsUser); }