/************************************ 对比并筛选 ***************************************************/ /// <summary> /// 通过ID数组提取出所有要素,创建动作 /// </summary> /// <param name="dzLine"></param> /// <param name="pdLing"></param> /// <param name="savePath"></param> public static void selectFeat(string dzx, string pdx, string savePath) { Stopwatch ssww = new Stopwatch(); ssww.Start(); //获得数组 int[] a = getMinIdGroupM(dzx, pdx); Console.WriteLine("ID to Feater..."); OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource dzDS = dr.Open(dzx, 0); OSGeo.OGR.Layer dzLayer = dzDS.GetLayerByIndex(0); if (System.IO.File.Exists(savePath)) { System.IO.File.Delete(savePath); } OSGeo.OGR.DataSource ds = dr.CreateDataSource(savePath, null); OSGeo.OGR.Layer fileLayer = ds.CreateLayer("", null, OSGeo.OGR.wkbGeometryType.wkbPolygon, null); //get featuer by ID for (int i = 0; i < a.Length; i++) { fileLayer.CreateFeature(dzLayer.GetFeature(a[i])); dzLayer.GetFeature(a[i]).Dispose(); } dzLayer.Dispose(); dzDS.Dispose(); fileLayer.Dispose(); ds.Dispose(); _2_坡度线.OutLine.CutImg.cleanPdxM(savePath); ssww.Stop(); Console.WriteLine("提取轮廓线完成!用时:{0}", ssww.Elapsed.ToString()); }
/****************************** Delete Feature Update ********************************************/ public static void deleteFeatUpdate(this OSGeo.OGR.DataSource myDS) { string a = "REPACK " + myDS.GetLayerByIndex(0).GetName(); myDS.ExecuteSQL(a, null, ""); myDS.Dispose(); }
/// <summary> /// 通过是否相交和面积差,获得最小面积差相交要素的ID数组--------多线OK /// </summary> /// <param name="dzx"></param> /// <param name="pdx"></param> /// <returns></returns> private static int[] getMinIdGroupM(string dzx, string pdx) { Console.WriteLine("起用多线程提取轮廓线ID...."); OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource pdDS = dr.Open(pdx, 0); OSGeo.OGR.Layer pdLayer = pdDS.GetLayerByIndex(0); int pdCount = pdLayer.GetFeatureCount(0); for (int pdi = 0; pdi < pdCount; pdi++) { OSGeo.OGR.Feature pdFeat = pdLayer.GetFeature(pdi); select(pdFeat, dzx); } while (tickTime < pdCount) { Console.WriteLine("第{0}个完成,共{1}个", tickTime, pdCount); Thread.Sleep(2000); } pdLayer.Dispose(); pdDS.Dispose(); Console.WriteLine("多线程提取ID完成....."); return(minIdG.ToArray()); }
public IArray get_DatasetNames(esriDatasetType DatasetType) { if (m_connString == null) { return(null); } if (DatasetType == esriDatasetType.esriDTAny || DatasetType == esriDatasetType.esriDTFeatureClass) { IArray datasets = new ArrayClass(); int count = m_datasource.GetLayerCount(); for (int i = 0; i < count; i++) { OSGeo.OGR.Layer layer = m_datasource.GetLayerByIndex(i); OGRDataset dataset = new OGRDataset(layer); datasets.Add(dataset); } return(datasets); } return(null); }
async static void subAdd(Feature poiFeat, string dzx, Layer newLayer) { await Task.Run(() => { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource dzxDS = dr.Open(dzx, 0); OSGeo.OGR.Layer dzxLayer = dzxDS.GetLayerByIndex(0); int dzxCount = dzxLayer.GetFeatureCount(0); OSGeo.OGR.Geometry poiGeom = poiFeat.GetGeometryRef(); for (int i = 0; i < dzxLayer.GetFeatureCount(0); i++) { OSGeo.OGR.Feature dzxFeat = dzxLayer.GetFeature(i); OSGeo.OGR.Geometry dzxGeom = dzxFeat.GetGeometryRef(); if (poiGeom.Within(dzxGeom)) { newLayer.CreateFeature(dzxFeat); } dzxGeom.Dispose(); dzxFeat.Dispose(); } poiFeat.Dispose(); dzxDS.Dispose(); tickTime++; }); }
/// <summary> /// 整合坡度多边形(Polygon),并清除重叠部份 /// </summary> /// <param name="subPdx"></param> /// <returns></returns> public static string zhengHePdx(List <string> subPdx) { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); string res = StaticTools.tempFilePath("shp", "整合"); OSGeo.OGR.DataSource newDS = dr.CreateDataSource(res, null); //////////////待关闭1 has Layer newLayer = newDS.CreateLayer("podu", null, OSGeo.OGR.wkbGeometryType.wkbPolygon, null); //////////////待关闭2 for (int i = 0; i < subPdx.Count; i++) { OSGeo.OGR.DataSource ds = dr.Open(subPdx[i], 0);//////////////待关闭3 has Layer layer = ds.GetLayerByIndex(0); for (int j = 0; j < layer.GetFeatureCount(0); j++) { OSGeo.OGR.Feature subFeat = layer.GetFeature(j); OSGeo.OGR.Geometry subGeom = subFeat.GetGeometryRef(); double thisArea = subGeom.GetArea(); // 清理过小Featuer if (thisArea > 200) { newLayer.CreateFeature(layer.GetFeature(j)); } } ds.Dispose(); Console.WriteLine("完成整合{0}/{1}", i + 1, subPdx.Count); } newDS.Dispose(); cleanPdx(res); return(res); }
/// <summary> /// 清理重复的Featuer----------多线程----与单线程效率差别很小,不推荐 /// </summary> /// <param name="filePath"></param> public static void cleanPdxM(string filePath) { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource ds = dr.Open(filePath, 1); OSGeo.OGR.Layer layer = ds.GetLayerByIndex(0); int featCount = layer.GetFeatureCount(0); var sw = new System.Diagnostics.Stopwatch(); sw.Start(); for (int i = 0; i < featCount - 1; i++) { getDoubFeat(filePath, i, featCount); } while (tickTime != featCount - 1) { Thread.Sleep(2000); Console.WriteLine(tickTime.ToString() + " /" + featCount.ToString() + "/ deletePoint " + ids.Count().ToString()); } sw.Stop(); Console.WriteLine("多线程清理重复Featuer用时:" + sw.Elapsed.ToString()); for (int i = 0; i < ids.Count; i++) { layer.DeleteFeature(ids[i]); } string a = "REPACK " + layer.GetName(); ds.ExecuteSQL(a, null, ""); ds.Dispose(); }
async static void getDoubFeat(string filePath, int s, int ss) { await Task.Run(() => { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource ds = dr.Open(filePath, 0); OSGeo.OGR.Layer layer = ds.GetLayerByIndex(0); OSGeo.OGR.Feature oriFeat = layer.GetFeature(s); for (int i = s + 1; i < ss; i++) { OSGeo.OGR.Feature nextFeat = layer.GetFeature(i); if (StaticTools.isSame(oriFeat, nextFeat, 1)) { ids.Add(s); break; } nextFeat.Dispose(); } oriFeat.Dispose(); layer.Dispose(); ds.Dispose(); tickTime++; } ); }
public static void selectDZXFromPointM(string point, string dzx, string savePath) { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource poiDS = dr.Open(point, 0); OSGeo.OGR.Layer poiLayer = poiDS.GetLayerByIndex(0); if (File.Exists(savePath)) { File.Delete(savePath); } OSGeo.OGR.DataSource newDS = dr.CreateDataSource(savePath, null); OSGeo.OGR.Layer newLayer = newDS.CreateLayer("", null, OSGeo.OGR.wkbGeometryType.wkbPolygon, null); tickTime = 0; int poiCount = poiLayer.GetFeatureCount(0); for (int i = 0; i < poiCount; i++) { subAdd(poiLayer.GetFeature(i), dzx, newLayer); } while (tickTime < poiCount) { Thread.Sleep(2222); Console.WriteLine("getFeatureByPoint:{0}/{1}", tickTime, poiCount); } Console.WriteLine("【本次提取到{0}个要素】", newLayer.GetFeatureCount(0)); newDS.Dispose(); poiDS.Dispose(); }
/// <summary> /// 整合坡度线(Line) /// </summary> /// <param name="subPdx"></param> /// <returns></returns> public static string zhengHePdLine(List <string> subPdx) { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); string newPath = StaticTools.tempFilePath("shp", "整合线"); OSGeo.OGR.DataSource newDs = dr.CreateDataSource(newPath, null);///////////////// OSGeo.OGR.Layer newLayer = newDs.CreateLayer("Lines", dr.Open(subPdx[0], 0).GetLayerByIndex(0).GetSpatialRef(), dr.Open(subPdx[0], 0).GetLayerByIndex(0).GetGeomType(), null); for (int i = 0; i < subPdx.Count; i++) { OSGeo.OGR.DataSource dsLine = dr.Open(subPdx[i], 0);/////////////////////// OSGeo.OGR.Layer lineLayer = dsLine.GetLayerByIndex(0); for (int j = 0; j < lineLayer.GetFeatureCount(0); j++) { newLayer.CreateFeature(lineLayer.GetFeature(j)); } dsLine.Dispose(); } newDs.Dispose(); return(newPath); }
/// <summary> /// Loads a Ogr datasource with the specified layer /// </summary> /// <param name="Filename">datasource</param> /// <param name="LayerNum">number of layer</param> public Ogr(string Filename, int LayerNum) { this.Filename = Filename; OSGeo.OGR.Ogr.RegisterAll(); _OgrDataSource = OSGeo.OGR.Ogr.Open(this.Filename, 0); _OgrLayer = _OgrDataSource.GetLayerByIndex(LayerNum); }
/// <summary> /// Loads a Ogr datasource with the specified layer /// </summary> /// <param name="Filename">datasource</param> /// <param name="LayerNum">number of layer</param> public Ogr(string Filename, int LayerNum) { this.Filename = Filename; OSGeo.OGR.Ogr.RegisterAll(); _OgrDataSource = OSGeo.OGR.Ogr.Open(this.Filename, 0); _OgrLayer = _OgrDataSource.GetLayerByIndex(LayerNum); }
/************************************* 点角式 *****************************************/ /// <summary> /// 清理等后生成新的文件 /// /// </summary> public static void claenPoint(string filePath, string savefile, double jiaodu, int cishu) { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); //进来的Layer OSGeo.OGR.DataSource oriDs = dr.Open(filePath, 0); OSGeo.OGR.Layer oriLayer = oriDs.GetLayerByIndex(0); //出去的Layer if (System.IO.File.Exists(savefile)) { savefile.deleteFiles(); } OSGeo.OGR.DataSource targDs = dr.CreateDataSource(savefile, null); OSGeo.OGR.Layer targLayer = targDs.CreateLayer("targ", null, OSGeo.OGR.wkbGeometryType.wkbPolygon, null); int featCount = oriLayer.GetFeatureCount(0); for (int i = 0; i < featCount; i++) { ///进来的Featuer OSGeo.OGR.Feature oriFeat = oriLayer.GetFeature(i); ///把一个Featuer转为点数组 OSGeo.OGR.Geometry oriGeom = oriFeat.GetGeometryRef(); OSGeo.OGR.Geometry subGeom = oriGeom.GetGeometryRef(0); int pointCount = subGeom.GetPointCount(); Point[] aFeat = new Point[pointCount]; for (int c = 0; c < pointCount; c++) { aFeat[c].X = subGeom.GetX(c); aFeat[c].Y = subGeom.GetY(c); aFeat[c].Z = subGeom.GetZ(c); } ///调选点方法,得到一个新的Featuer Geometry newGeom = null; if (aFeat.Length > cishu * 3) { newGeom = JID(aFeat, jiaodu, cishu); } else { oriFeat.Dispose(); continue; } if (newGeom != null) { Feature temp = new Feature(new FeatureDefn("")); temp.SetGeometry(newGeom); targLayer.CreateFeature(temp); temp.Dispose(); } oriFeat.Dispose(); Console.WriteLine("已完成{0}/{1}", i, featCount); } oriDs.Dispose(); targDs.Dispose(); }
/// <summary> /// Loads a OgrFeatureProvider datasource with the specified layer /// </summary> /// <param name="path">datasource</param> /// <param name="layerNumber">number of layer</param> public OgrFeatureProvider(string path, int layerNumber) : this() { this.path = path; ogrDataSource = Ogr.Open(path, 0); ogrLayer = ogrDataSource.GetLayerByIndex(layerNumber); this.layerName = ogrLayer.GetName(); Name = LayerName; _IsOpen = true; }
static void CreateIndexes(DataSource OGRDataSource, string MSSQLConnectionString) { // Create coordinate transformation SpatialReference sourceSRS = new SpatialReference(""); sourceSRS.ImportFromEPSG(4326); SpatialReference targetSRS = new SpatialReference(""); targetSRS.ImportFromEPSG(900913); CoordinateTransformation transform = new CoordinateTransformation(sourceSRS, targetSRS); for (int iLayer = 0; iLayer < OGRDataSource.GetLayerCount(); iLayer++) { Layer OGRLayer = OGRDataSource.GetLayerByIndex(iLayer); string layerName = OGRLayer.GetName(); // Get extent in EPSG:900913 Envelope extent = new Envelope(); OGRLayer.GetExtent(extent,0); double[] ll = new double[] { extent.MinX, extent.MinY }; double[] ur = new double[] { extent.MaxX, extent.MaxY }; transform.TransformPoint(ll); transform.TransformPoint(ur); using (SqlConnection con = new SqlConnection(MSSQLConnectionString)) { con.Open(); try { // Create primary key/clustered index string pkSQL = string.Format("ALTER TABLE [{0}] ADD CONSTRAINT [PK_{0}] PRIMARY KEY CLUSTERED([id] ASC) WITH (SORT_IN_TEMPDB = ON);", layerName); using (SqlCommand pkCmd = new SqlCommand(pkSQL, con)) { log(TraceLevel.Info, string.Format("Creating clustured index pk_{0} on table {0}...", layerName)); pkCmd.CommandTimeout = 0; pkCmd.ExecuteNonQuery(); } // Create spatial index OGRLayer.GetExtent(extent, 0); string sidxSQL = string.Format("CREATE SPATIAL INDEX sidx_{0}_ogr_geometry ON [{0}](ogr_geometry) WITH (BOUNDING_BOX = ( {1}, {2}, {3}, {4} ), SORT_IN_TEMPDB = ON );", layerName, ll[0], ll[1], ur[0], ur[1]); using (SqlCommand sidxCmd = new SqlCommand(sidxSQL, con)) { log(TraceLevel.Info, string.Format("Creating spatial index sidx_{0}_ogr_geometry on table {0}...", layerName)); sidxCmd.CommandTimeout = 0; sidxCmd.ExecuteNonQuery(); } } catch (Exception e) { log(TraceLevel.Error, e.Message); Environment.Exit(1); } } } }
public static IList <Layer> GetDatasetLayers(OSGeo.OGR.DataSource dataset) { IList <Layer> layers = new List <Layer>(); var layerCount = dataset.GetLayerCount(); for (int i = 0; i < layerCount; i++) { layers.Add(dataset.GetLayerByIndex(i)); } return(layers); }
/// <summary> /// 子线程提取轮廓线ID /// </summary> /// <param name="pdFeat"></param> /// <param name="dzx"></param> async static void select(Feature pdFeat, string dzx) { await Task.Run(() => { double afterCha = -1; int yesID = -1; OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource dzDS = dr.Open(dzx, 0); OSGeo.OGR.Layer dzxLayer = dzDS.GetLayerByIndex(0); OSGeo.OGR.Geometry pdGeom = pdFeat.GetGeometryRef(); int dzCount = dzxLayer.GetFeatureCount(0); for (int dzi = 0; dzi < dzCount; dzi++) { OSGeo.OGR.Feature dzFeat = dzxLayer.GetFeature(dzi); OSGeo.OGR.Geometry dzGeom = dzFeat.GetGeometryRef(); if (pdGeom.Intersect(dzGeom)) { double cha = Math.Abs(dzGeom.GetArea() - pdGeom.GetArea()); if (afterCha == -1) { afterCha = cha; yesID = dzi; } else if (cha < afterCha) { afterCha = cha; yesID = dzi; } } dzGeom.Dispose(); dzFeat.Dispose(); } if (yesID != -1) { minIdG.Add(yesID); } dzDS.Dispose(); dzxLayer.Dispose(); pdGeom.Dispose(); pdFeat.Dispose(); tickTime++; }); }
public static void selectFromPoint(string point, string slopPoly) { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource poiDS = dr.Open(point, 0); OSGeo.OGR.DataSource slopDS = dr.Open(slopPoly, 1); OSGeo.OGR.Layer poiLayer = poiDS.GetLayerByIndex(0); OSGeo.OGR.Layer slopLayer = slopDS.GetLayerByIndex(0); List <int> staIds = new List <int>(); int poiCount = WorkFlow.pointIds.Count; int slopCount = slopLayer.GetFeatureCount(0); for (int i = 0; i < poiCount; i++) { OSGeo.OGR.Feature poiFeat = poiLayer.GetFeature(WorkFlow.pointIds[i]); OSGeo.OGR.Geometry poiGeom = poiFeat.GetGeometryRef(); for (int t = 0; t < slopCount; t++) { OSGeo.OGR.Feature slopFeat = slopLayer.GetFeature(t); OSGeo.OGR.Geometry slopGeom = slopFeat.GetGeometryRef(); if (poiGeom.Within(slopGeom)) { staIds.Add(t); WorkFlow.pointIds[i] = -1; } slopFeat.Dispose(); } poiFeat.Dispose(); } Console.WriteLine("【本次提取到{0}个要素】", staIds.Count); while (WorkFlow.pointIds.IndexOf(-1) > -1) { WorkFlow.pointIds.Remove(-1); } for (int i = 0; i < slopCount; i++) { if (staIds.IndexOf(i) == -1) { slopLayer.DeleteFeature(i); } } slopDS.deleteFeatUpdate(); slopDS.Dispose(); poiDS.Dispose(); }
public OgrDataReader(string sDataSource) { //wkbReader = new DotSpatial.Data.WKBReader(); _ogrDataSource = Ogr.Open(sDataSource, 0); _ogrLayer = _ogrDataSource.GetLayerByIndex(0); _iFeatureCount = _ogrLayer.GetFeatureCount(1); _ogrFeatureDefinition = _ogrLayer.GetLayerDefn(); _iFieldCount = _ogrFeatureDefinition.GetFieldCount(); BuildSchemaTable(); _currentFeature = null; bClosed = false; }
/// <summary> /// 清理原文件 /// </summary> /// <param name="filePath"></param> public static void claenPoint(string filePath, double jiaodu, int cishu) { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource oriDs = dr.Open(filePath, 1); OSGeo.OGR.Layer oriLayer = oriDs.GetLayerByIndex(0); int featCount = oriLayer.GetFeatureCount(0); for (int i = 0; i < featCount; i++) { OSGeo.OGR.Feature oriFeat = oriLayer.GetFeature(i); OSGeo.OGR.Geometry oriGeom = oriFeat.GetGeometryRef(); OSGeo.OGR.Geometry subGeom = oriGeom.GetGeometryRef(0); int pointCount = subGeom.GetPointCount(); Point[] aFeat = new Point[pointCount]; for (int c = 0; c < pointCount; c++) { aFeat[c].X = subGeom.GetX(c); aFeat[c].Y = subGeom.GetY(c); aFeat[c].Z = subGeom.GetZ(c); } OSGeo.OGR.Geometry newGeom = null; if (aFeat.Length > cishu * 3) { newGeom = JID(aFeat, jiaodu, cishu); } else { oriFeat.Dispose(); continue; } if (newGeom != null) { oriFeat.SetGeometry(newGeom); oriLayer.SetFeature(oriFeat); } Console.WriteLine("cleanPoint已完成{0}/{1}", i, featCount); oriFeat.Dispose(); } oriDs.Dispose(); }
public static string addPdx(string point, string inDSM, int lev) { //读取点ID OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource pointDs = dr.Open(point, 0); OSGeo.OGR.Layer pointLayer = pointDs.GetLayerByIndex(0); int pointCount = pointLayer.GetFeatureCount(0); for (int i = 0; i < pointCount; i++) { pointIds.Add(i); } //提升分辨率,计算坡度图 List <string> subSlop = new List <string>(); string upDataDSM = StaticTools.tempFilePath("img", "UpDataDSM"); CutImg.ImgReProject(inDSM, upDataDSM, 2); string addSolpeMap = StaticTools.tempFilePath("img", "addSolpeMap"); SlopeDem.Instance.Sloping(upDataDSM, addSolpeMap); //循环坡度下限值 for (int i = 0; i < lev; i++) { //没点了就退出 if (pointIds.Count == 0) { Console.WriteLine("所有目标都已找到匹配元素!"); break; } Console.WriteLine("【开始第{0}次循环,还有{1}个点待提取!】", i, pointIds.Count); string _outShpPath = StaticTools.tempFilePath("shp", "SlopAdd" + i.ToString() + "Times"); GetOutlines.Instance.MyGetOutlines(upDataDSM, addSolpeMap, _outShpPath, 80 - i * 5); 补充要素.AddFeatuer.selectFromPoint(point, _outShpPath); subSlop.Add(_outShpPath); } Console.WriteLine("还有{0}个目标没有找到对应要素!", pointIds.Count.ToString()); return(OutLine.CutImg.zhengHePdx(subSlop, 10)); }
public static void selectDZXFromPoint(string point, string dzx, string savePath) { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource poiDS = dr.Open(point, 0); OSGeo.OGR.DataSource dzxDS = dr.Open(dzx, 0); if (File.Exists(savePath)) { File.Delete(savePath); } OSGeo.OGR.DataSource newDS = dr.CreateDataSource(savePath, null); OSGeo.OGR.Layer poiLayer = poiDS.GetLayerByIndex(0); OSGeo.OGR.Layer dzxLayer = dzxDS.GetLayerByIndex(0); OSGeo.OGR.Layer newLayer = newDS.CreateLayer("", dzxLayer.GetSpatialRef(), dzxLayer.GetGeomType(), null); int poiCount = poiLayer.GetFeatureCount(0); int dzxCount = dzxLayer.GetFeatureCount(0); for (int i = 0; i < poiCount; i++) { OSGeo.OGR.Feature poiFeat = poiLayer.GetFeature(i); OSGeo.OGR.Geometry poiGeom = poiFeat.GetGeometryRef(); for (int t = 0; t < dzxCount; t++) { OSGeo.OGR.Feature dzxFeat = dzxLayer.GetFeature(t); OSGeo.OGR.Geometry dzxGeom = dzxFeat.GetGeometryRef(); if (poiGeom.Within(dzxGeom)) { newLayer.CreateFeature(dzxFeat); } dzxFeat.Dispose(); Console.WriteLine("getFeatureByPoint:{0}/{1}", i, poiCount); } poiFeat.Dispose(); } Console.WriteLine("【本次提取到{0}个要素】", newLayer.GetFeatureCount(0)); newDS.Dispose(); dzxDS.Dispose(); poiDS.Dispose(); }
//从文件中读取数据 private static FeatureSource GetFeaturesource(SHPGeoDataBase thisdb, String path) { OSGeo.OGR.DataSource ds = GetOGRDataSource(thisdb, path); //init schema OSGeo.OGR.Layer layer = ds.GetLayerByIndex(0); OSGeo.OGR.FeatureDefn fd = layer.GetLayerDefn(); Int32 sIndex = path.LastIndexOf("\\"); string sname = path.Substring(sIndex + 1, path.Length - sIndex - 1 - 4); int fieldcount = fd.GetFieldCount(); Dictionary <String, FieldDefn> tmpField = new Dictionary <string, FieldDefn>(); for (int i = 0; i < fieldcount; ++i) { OSGeo.OGR.FieldDefn field = fd.GetFieldDefn(i); tmpField.Add(field.GetName(), field); } GisSmartTools.RS.ReferenceSystem rfs; OSGeo.OSR.SpatialReference osrrf = layer.GetSpatialRef(); if (osrrf.IsProjected() != 0) { rfs = new GisSmartTools.RS.SRS(osrrf); } else { rfs = new GisSmartTools.RS.GRS(osrrf); } Schema rs = new Schema(sname, layer.GetGeomType(), rfs, tmpField); //get featurecollection FeatureCollection fc = GetFeatureCollection(layer, rs); //close file //ds.Dispose(); return(new FeatureSource(rs, fc)); }
static IEnumerable<DataTable> ReadData(DataSource OGRDataSource, DataSet OSMDataSet, int SQLBatchSize) { int featureCount = 0; // Create coordinate transformation SpatialReference sourceSRS = new SpatialReference(""); sourceSRS.ImportFromEPSG(4326); SpatialReference targetSRS = new SpatialReference(""); targetSRS.ImportFromEPSG(900913); CoordinateTransformation transform = new CoordinateTransformation(sourceSRS, targetSRS); // Use interleaved reading - http://www.gdal.org/drv_osm.html bool bHasLayersNonEmpty = false; do { bHasLayersNonEmpty = false; for (int iLayer = 0; iLayer < OGRDataSource.GetLayerCount(); iLayer++) { Layer OGRLayer = OGRDataSource.GetLayerByIndex(iLayer); log(TraceLevel.Verbose, string.Format("Processing {0}...", OGRLayer.GetName())); FeatureDefn OGRFeatDef = OGRLayer.GetLayerDefn(); DataTable buffer = OSMDataSet.Tables[OGRLayer.GetName()]; Feature feat; while ((feat = OGRLayer.GetNextFeature()) != null) { bHasLayersNonEmpty = true; // Commit buffer larger than batch size if (buffer.Rows.Count >= SQLBatchSize) { yield return buffer.Copy(); buffer.Rows.Clear(); } // Fill buffer row DataRow row = buffer.NewRow(); for (int iField = 0; iField < OGRFeatDef.GetFieldCount(); iField++) { if (feat.IsFieldSet(iField)) { // Add one to skip id IDENTITY column row[iField + 1] = feat.GetFieldAsString(iField); } } // Get OGR geometry object Geometry geom = feat.GetGeometryRef(); // Project from EPSG:4326 to EPSG:900913 geom.Transform(transform); // Serialize to WKB byte[] geomBuffer = new byte[geom.WkbSize()]; geom.ExportToWkb(geomBuffer); // Set ogr_geometry buffer column from WKB try { SqlGeometry sqlGeom = SqlGeometry.STGeomFromWKB(new SqlBytes(geomBuffer), 900913).MakeValid(); row["ogr_geometry"] = sqlGeom; row["ogr_geometry_area"] = sqlGeom.STArea().Value; // Add row to buffer buffer.Rows.Add(row); } catch (Exception e) { log(TraceLevel.Warning, string.Format("Cannot process osm_id: {0} ({1})", feat.GetFID(), e.Message)); } // Update progress featureCount++; } // Commit buffer before moving on to another layer if (buffer.Rows.Count != 0) { yield return buffer.Copy(); buffer.Rows.Clear(); } } } while (bHasLayersNonEmpty); }
static void DropTables(DataSource OGRDataSource, string MSSQLConnectionString) { for (int iLayer = 0; iLayer < OGRDataSource.GetLayerCount(); iLayer++) { Layer OGRLayer = OGRDataSource.GetLayerByIndex(iLayer); string layerName = OGRLayer.GetName(); using (SqlConnection con = new SqlConnection(MSSQLConnectionString)) { con.Open(); try { // Check if table exists bool tableExists; using (SqlCommand checkCmd = new SqlCommand(string.Format("SELECT OBJECT_ID('{0}');", layerName), con)) { tableExists = (!(checkCmd.ExecuteScalar() is DBNull)); } if (tableExists) { using (SqlCommand dropCmd = new SqlCommand(string.Format("DROP TABLE [{0}];", layerName), con)) { log(TraceLevel.Info, string.Format("Dropping table {0}...", layerName)); dropCmd.ExecuteNonQuery(); } } } catch (Exception e) { log(TraceLevel.Error, e.Message); Environment.Exit(1); } } } }
public static bool CovertRegion2Line(string path, string savePath) { try { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); if (dr == null) { Console.WriteLine("启动驱动失败!\n"); } OSGeo.OGR.DataSource ds = dr.Open(path, 0); int layerCount = ds.GetLayerCount(); OSGeo.OGR.Layer layer = ds.GetLayerByIndex(0); FeatureDefn fdf = layer.GetLayerDefn(); int fieldCount = fdf.GetFieldCount(); // 创建数据源 DataSource oDS = dr.CreateDataSource(savePath, null); if (oDS == null) { Console.WriteLine("创建矢量文件【%s】失败!\n", savePath); return(false); } OSGeo.OSR.SpatialReference srs = layer.GetSpatialRef(); // 创建图层,创建一个多边形图层,这里没有指定空间参考,如果需要的话,需要在这里进行指定 Layer oLayer = oDS.CreateLayer("line", srs, OSGeo.OGR.wkbGeometryType.wkbMultiLineString, null); if (oLayer == null) { Console.WriteLine("图层创建失败!\n"); return(false); } for (int i = 0; i < fieldCount; i++) { FieldDefn fieldDefn = fdf.GetFieldDefn(i); oLayer.CreateField(fieldDefn, 1); } FeatureDefn oDefn = oLayer.GetLayerDefn(); OSGeo.OGR.Feature feat; while ((feat = layer.GetNextFeature()) != null) { Feature oFeatureMulty = new Feature(oDefn); OSGeo.OGR.Geometry geometry = feat.GetGeometryRef(); for (int i = 0; i < fieldCount; i++) { string value = feat.GetFieldAsString(i); oFeatureMulty.SetField(i, value); } OSGeo.OGR.wkbGeometryType goetype = geometry.GetGeometryType(); if (goetype == OSGeo.OGR.wkbGeometryType.wkbPolygon) { Geometry tempGeo = new Geometry(wkbGeometryType.wkbMultiLineString); int count = geometry.GetGeometryCount(); for (int j = 0; j < count; j++) { Geometry line = new Geometry(wkbGeometryType.wkbLinearRing); Geometry geo = geometry.GetGeometryRef(j); for (int i = 0; i < geo.GetPointCount(); i++) { double x = geo.GetX(i); double y = geo.GetY(i); line.AddPoint(x, y, 0); } tempGeo.AddGeometryDirectly(line); } oFeatureMulty.SetGeometry(tempGeo); } oLayer.SetFeature(oFeatureMulty); } oLayer.Dispose(); layer.Dispose(); oDS.Dispose(); ds.Dispose(); dr.Dispose(); } catch { } return(false); }
/// <summary> /// 转换并纠偏,只使用与火星坐标纠偏 /// </summary> /// <param name="dataTable">数据表,如果是点表中含X,Y字段,如果是线和面,表中含有PATH字段</param> /// <param name="filePath">存储路径</param> /// <param name="geoType">数据类型,暂时支持简单的点线面</param> //public static void saveShpFile(DataTable dataTable,string filePath,wkbGeometryType geoType) //{ // saveShpFile(dataTable, filePath, geoType, ProjectConvert.GCJ_WGS); //} /// <summary> /// 导出shp数据到表格 /// </summary> /// <param name="path">文件路径</param> /// <returns>DataTable</returns> public static DataTable GetData(string path) { try { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); if (dr == null) { Console.WriteLine("启动驱动失败!\n"); } OSGeo.OGR.DataSource ds = dr.Open(path, 0); int layerCount = ds.GetLayerCount(); OSGeo.OGR.Layer layer = ds.GetLayerByIndex(0); DataTable dataTable = new DataTable(); FeatureDefn fdf = layer.GetLayerDefn(); int fieldCount = fdf.GetFieldCount(); for (int i = 0; i < fieldCount; i++) { dataTable.Columns.Add(fdf.GetFieldDefn(i).GetName(), Type.GetType("System.String")); } if (fdf.GetGeomType() == OSGeo.OGR.wkbGeometryType.wkbPoint) { if (!dataTable.Columns.Contains("X")) { dataTable.Columns.Add("X", Type.GetType("System.String")); } if (!dataTable.Columns.Contains("Y")) { dataTable.Columns.Add("Y", Type.GetType("System.String")); } } else if (fdf.GetGeomType() == OSGeo.OGR.wkbGeometryType.wkbPolygon || fdf.GetGeomType() == OSGeo.OGR.wkbGeometryType.wkbLineString) { if (!dataTable.Columns.Contains("PATH")) { dataTable.Columns.Add("PATH", Type.GetType("System.String")); } } OSGeo.OGR.Feature feat; while ((feat = layer.GetNextFeature()) != null) { DataRow row = dataTable.NewRow(); OSGeo.OGR.Geometry geometry = feat.GetGeometryRef(); for (int i = 0; i < fieldCount; i++) { string value = feat.GetFieldAsString(i); row[i] = value.Replace(",", ""); } OSGeo.OGR.wkbGeometryType goetype = geometry.GetGeometryType(); if (goetype == OSGeo.OGR.wkbGeometryType.wkbPoint) { double x = geometry.GetX(0); double y = geometry.GetY(0); row["X"] = x.ToString(); row["Y"] = y.ToString(); } else if (goetype == OSGeo.OGR.wkbGeometryType.wkbLineString) { string points = ""; for (int i = 0; i < geometry.GetPointCount(); i++) { double x = geometry.GetX(i); double y = geometry.GetY(i); points += x.ToString() + "|" + y.ToString() + ";"; } if (points != "") { points.Substring(0, points.Length - 1); } row["PATH"] = points; } else if (goetype == OSGeo.OGR.wkbGeometryType.wkbPolygon) { int count = geometry.GetGeometryCount(); string points = ""; for (int j = 0; j < count; j++) { Geometry geo = geometry.GetGeometryRef(j); for (int i = 0; i < geo.GetPointCount(); i++) { double x = geo.GetX(i); double y = geo.GetY(i); points += x.ToString() + "|" + y.ToString() + ";"; } if (points != "") { points.Substring(0, points.Length - 1); } points += "|"; } if (points != "") { points.Substring(0, points.Length - 1); } row["PATH"] = points; } } layer.Dispose(); ds.Dispose(); dr.Dispose(); return(dataTable); } catch { return(null); } }
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_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>(); GH_Structure <GH_String> gtype = new GH_Structure <GH_String>(); GH_Structure <IGH_GeometricGoo> gGoo = new GH_Structure <IGH_GeometricGoo>(); ///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); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Layer #" + iLayer + " " + layer.GetName() + " has " + featureCount + " features"); ///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, "Spatial Reference System (SRS) is missing. SRS set automatically set to WGS84."); Driver driver = ds.GetDriver(); if (driver.GetName() == "MVT") { sourceSRS.SetFromUserInput("EPSG:3857"); } else { sourceSRS.SetFromUserInput("WGS84"); } ///this seems to work where SetWellKnownGeogCS doesn't string pretty = ""; sourceSRS.ExportToPrettyWkt(out pretty, 0); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, pretty); sRef = "Spatial Reference System (SRS) is missing. SRS set automatically set to WGS84."; } else { if (layer.GetSpatialRef().Validate() != 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Spatial Reference System (SRS) is unknown or unsupported. SRS set automatically set to WGS84."); sourceSRS.SetWellKnownGeogCS("WGS84"); sRef = "Spatial Reference System (SRS) 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, "The source Spatial Reference System (SRS) from layer " + layer.GetName() + " is EPSG:" + sourceSRSInt + "."); } catch { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Failed to get an EPSG Spatial Reference System (SRS) 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); ///These transforms move and scale in order to go from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); Transform sourceToModelSRSTransform = Heron.Convert.GetUserSRSToModelTransform(sourceSRS); Transform modelToSourceSRSTransform = Heron.Convert.GetModelToUserSRSTransform(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); OSGeo.OGR.Geometry extMinSourceOgr = new OSGeo.OGR.Geometry(wkbGeometryType.wkbPoint); extMinSourceOgr.AddPoint(ext.MinX, ext.MinY, 0.0); extMinSourceOgr.AssignSpatialReference(sourceSRS); OSGeo.OGR.Geometry extMaxSourceOgr = new OSGeo.OGR.Geometry(wkbGeometryType.wkbPoint); extMaxSourceOgr.AddPoint(ext.MaxX, ext.MaxY, 0.0); extMaxSourceOgr.AssignSpatialReference(sourceSRS); ///Get extents in Rhino SRS Point3d extPTmin = Heron.Convert.OgrPointToPoint3d(extMinSourceOgr, sourceToModelSRSTransform); Point3d extPTmax = Heron.Convert.OgrPointToPoint3d(extMaxSourceOgr, sourceToModelSRSTransform); Rectangle3d rec = new Rectangle3d(Plane.WorldXY, extPTmin, extPTmax); recs.Append(new GH_Rectangle(rec), new GH_Path(iLayer)); ///Get extents in userSRS ///Can give odd results if crosses 180 longitude extMinSourceOgr.TransformTo(userSRS); extMaxSourceOgr.TransformTo(userSRS); Point3d extPTminUser = Heron.Convert.OgrPointToPoint3d(extMinSourceOgr, userSRSToModelTransform); Point3d extPTmaxUser = Heron.Convert.OgrPointToPoint3d(extMaxSourceOgr, userSRSToModelTransform); Rectangle3d recUser = new Rectangle3d(Plane.WorldXY, extPTminUser, extPTmaxUser); recsUser.Append(new GH_Rectangle(recUser), 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()); } ///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))) { ///Get field data if even if no geometry is present in the layer 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 clipping boundaries may be outside the bounds of the vector datasource."); } else { ///Create bounding box for clipping geometry Point3d min = boundary[i].GetBoundingBox(true).Min; Point3d max = boundary[i].GetBoundingBox(true).Max; min.Transform(modelToSourceSRSTransform); max.Transform(modelToSourceSRSTransform); 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; 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] + "))"); ///Create bounding box for clipping geometry ///Not working on MVT type files //boundary[i].Transform(modelToSourceSRSTransform); //OSGeo.OGR.Geometry ebbox = Heron.Convert.CurveToOgrPolygon(boundary[i]); ///Clip Shapefile ///http://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html 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(); OSGeo.OGR.Geometry sub_geomUser; ///reproject geometry to WGS84 and userSRS ///TODO: look into using the SetCRS global variable here if (geom.GetSpatialReference() == null) { geom.AssignSpatialReference(sourceSRS); } if (geomUser.GetSpatialReference() == null) { geomUser.AssignSpatialReference(sourceSRS); } geom.TransformTo(rhinoSRS); geomUser.TransformTo(userSRS); gtype.Append(new GH_String(geom.GetGeometryName()), new GH_Path(i, iLayer, m)); if (feat.GetGeometryRef() != null) { ///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 ///Start get points if open polylines and points for (int gpc = 0; gpc < geom.GetPointCount(); gpc++) { ///Loop through geometry points for Rhino SRS double[] ogrPt = new double[3]; geom.GetPoint(gpc, ogrPt); Point3d pt3D = new Point3d(ogrPt[0], ogrPt[1], ogrPt[2]); pt3D.Transform(Heron.Convert.WGSToXYZTransform()); gset.Append(new GH_Point(pt3D), new GH_Path(i, iLayer, m)); ///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); gsetUser.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 < geom.GetGeometryCount(); gi++) { sub_geom = geom.GetGeometryRef(gi); OSGeo.OGR.Geometry subsub_geom; 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[] ogrPt = new double[3]; subsub_geom.GetPoint(ptnum, ogrPt); Point3d pt3D = new Point3d(ogrPt[0], ogrPt[1], ogrPt[2]); pt3D.Transform(Heron.Convert.WGSToXYZTransform()); gset.Append(new GH_Point(pt3D), new GH_Path(i, iLayer, m, gi, n)); ///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); gsetUser.Append(new GH_Point(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[] ogrPt = new double[3]; sub_geom.GetPoint(ptnum, ogrPt); Point3d pt3D = new Point3d(ogrPt[0], ogrPt[1], ogrPt[2]); pt3D.Transform(Heron.Convert.WGSToXYZTransform()); gset.Append(new GH_Point(pt3D), new GH_Path(i, iLayer, m, gi)); ///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); gsetUser.Append(new GH_Point(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 clipped layer else statement } ///end loop through boundaries layer.Dispose(); }///end loop through layers ds.Dispose(); DA.SetDataTree(0, recs); DA.SetDataTree(1, sRefs); DA.SetDataTree(2, fnames); DA.SetDataTree(3, fset); DA.SetDataTree(4, gset); DA.SetDataTree(5, gsetUser); DA.SetDataTree(6, recsUser); DA.SetDataTree(7, gGoo); DA.SetDataTree(8, gtype); }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>(0, boundary); string shpFileLoc = ""; DA.GetData <string>("Shapefile Location", ref shpFileLoc); ////int SRef = 3857; GdalConfiguration.ConfigureOgr(); GdalConfiguration.ConfigureGdal(); OSGeo.OGR.Driver drv = OSGeo.OGR.Ogr.GetDriverByName("ESRI Shapefile"); OSGeo.OGR.DataSource ds = OSGeo.OGR.Ogr.Open(shpFileLoc, 0); 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("FAILURE: Couldn't fetch advertised layer " + iLayer); System.Environment.Exit(-1); } long count = layer.GetFeatureCount(1); int featureCount = System.Convert.ToInt32(count); fc.Add(featureCount); layerset.Add(layer); } //Get OGR envelope of Shapefile OSGeo.OGR.Envelope ext = new OSGeo.OGR.Envelope(); layerset[0].GetExtent(ext, 1); Point3d extMin = new Point3d(); Point3d extMax = new Point3d(); extMin.X = ext.MinX; extMin.Y = ext.MinY; extMax.X = ext.MaxX; extMax.Y = ext.MaxY; OSGeo.OSR.SpatialReference sr = layerset[0].GetSpatialRef(); OSGeo.OSR.SpatialReference dst = new OSGeo.OSR.SpatialReference(""); dst.SetWellKnownGeogCS("WGS84"); //Get the spatial refernce of the input Shapefile string sRef; sr.ExportToWkt(out sRef); OSGeo.OSR.CoordinateTransformation coordTransform = new OSGeo.OSR.CoordinateTransformation(sr, dst); OSGeo.OSR.CoordinateTransformation revTransform = new OSGeo.OSR.CoordinateTransformation(dst, sr); //Get bounding box of data in Shapefile double[] extMinPT = new double[3] { extMin.X, extMin.Y, extMin.Z }; double[] extMaxPT = new double[3] { extMax.X, extMax.Y, extMax.Z }; coordTransform.TransformPoint(extMinPT); coordTransform.TransformPoint(extMaxPT); 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.ToXYZ(extPTmin), Heron.Convert.ToXYZ(extPTmax)); //Declare trees GH_Structure <GH_String> fset = new GH_Structure <GH_String>(); GH_Structure <GH_Point> gset = new GH_Structure <GH_Point>(); GH_Structure <GH_String> layname = new GH_Structure <GH_String>(); OSGeo.OGR.FeatureDefn def = layerset[0].GetLayerDefn(); //Loop through input boundaries for (int i = 0; i < boundary.Count; i++) { if (rec.BoundingBox.Contains(boundary[i].GetBoundingBox(true).Min) && (rec.BoundingBox.Contains(boundary[i].GetBoundingBox(true).Max))) { //Create bounding box for clipping geometry Point3d min = Heron.Convert.ToWGS(boundary[i].GetBoundingBox(true).Min); Point3d max = Heron.Convert.ToWGS(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; revTransform.TransformPoint(minpT); revTransform.TransformPoint(maxpT); OSGeo.OGR.Geometry bbox = OSGeo.OGR.Geometry.CreateFromWkt("POLYGON((" + min.X + " " + min.Y + ", " + min.X + " " + max.Y + ", " + max.X + " " + max.Y + ", " + max.X + " " + min.Y + ", " + min.X + " " + min.Y + "))"); 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 OSGeo.OGR.Layer clipped_layer = layerset[0]; clipped_layer.SetSpatialFilter(ebbox); //Loop through geometry OSGeo.OGR.Feature feat; def = clipped_layer.GetLayerDefn(); int m = 0; while ((feat = layerset[0].GetNextFeature()) != null) { if (feat.GetGeometryRef() != null) { //Get geometry points and field values OSGeo.OGR.Geometry geom = feat.GetGeometryRef(); OSGeo.OGR.Geometry sub_geom; //Start get points if open polylines and points for (int gpc = 0; gpc < geom.GetPointCount(); gpc++) { //Loop through geometry points 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; } coordTransform.TransformPoint(pT); Point3d pt3D = new Point3d(); pt3D.X = pT[0]; pt3D.Y = pT[1]; pt3D.Z = pT[2]; gset.Append(new GH_Point(Heron.Convert.ToXYZ(pt3D)), new GH_Path(i, m)); //End loop through geometry points // Get Feature Values if (fset.PathExists(new GH_Path(i, m))) { fset.get_Branch(new GH_Path(i, 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, m)); } else { fset.Append(new GH_String("null"), new GH_Path(i, 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); List <Point3d> geom_list = new List <Point3d>(); 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); coordTransform.TransformPoint(pT); Point3d pt3D = new Point3d(); pt3D.X = pT[0]; pt3D.Y = pT[1]; pt3D.Z = pT[2]; gset.Append(new GH_Point(Heron.Convert.ToXYZ(pt3D)), new GH_Path(i, m, gi)); //End loop through geometry points // Get Feature Values if (fset.PathExists(new GH_Path(i, m))) { fset.get_Branch(new GH_Path(i, 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, m)); } else { fset.Append(new GH_String("null"), new GH_Path(i, m)); } } //End Get Feature Values } //End getting points from closed polylines } m++; } feat.Dispose(); } } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more boundaries may be outside the bounds of the Shapefile dataset."); //return; } } //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); fieldnames.Add(fdef.GetNameRef()); } DA.SetData(0, def.GetName()); DA.SetDataList(1, fc); DA.SetData(2, rec); DA.SetData(3, sRef); DA.SetDataList(4, fieldnames); DA.SetDataTree(5, fset); DA.SetDataTree(6, gset); }
public override void DoWork(Action <string, double> ReportProgress, Action Done) { // Checking for cancellation if (CancellationToken.IsCancellationRequested) { return; } ///Make sure there's an API key string mbToken = ApiKey; if (mbToken == "") { string hmbToken = System.Environment.GetEnvironmentVariable("HERONMAPBOXTOKEN"); if (hmbToken != null) { mbToken = hmbToken; RuntimeMessages.Add((GH_RuntimeMessageLevel.Remark, "Using Mapbox token stored in Environment Variable HERONMAPBOXTOKEN.")); } else { RuntimeMessages.Add((GH_RuntimeMessageLevel.Error, "No Mapbox token is specified. Please get a valid token from mapbox.com")); return; } } ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); OSGeo.OGR.Ogr.RegisterAll(); ///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); userSRS.SetFromUserInput("WGS84"); ///Mapbox uses EPSG:3857 OSGeo.OSR.SpatialReference sourceSRS = new SpatialReference(""); sourceSRS.SetFromUserInput("EPSG:3857"); ///These transforms move and scale in order to go from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); Transform sourceToModelSRSTransform = Heron.Convert.GetUserSRSToModelTransform(sourceSRS); Transform modelToSourceSRSTransform = Heron.Convert.GetModelToUserSRSTransform(sourceSRS); double lat = Heron.Convert.XYZToWGS(Location).Y; double lon = Heron.Convert.XYZToWGS(Location).X; ///Setup contour style and unit type string contourType = String.Empty; double?contourNum = Contour; if (contourNum < 0.0) { contourNum = 0.0; } double unitConversion = Rhino.RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, Rhino.UnitSystem.Meters); if (MapboxIsochroneSpeckle.MinutesOrMeters == "Distance") { contourType = "contours_meters="; contourNum = contourNum * unitConversion; } else { contourType = "contours_minutes="; if (contourNum > 60) { contourNum = 60; RuntimeMessages.Add((GH_RuntimeMessageLevel.Warning, "Maximum minute contour is 60. Contour value reduced to 60.")); } } ///Make sure Denoise is between 0..1 double?denoiseNum = Denoise; if (denoiseNum < 0.0) { denoiseNum = 0.0; } if (denoiseNum > 1.0) { denoiseNum = 1.0; } ///Make sure Generalize is > 0 double?generalizeNum = Generalize * unitConversion; if (generalizeNum < 0.0) { generalizeNum = 0.0; } ///Construct URL query string string url = @"https://api.mapbox.com/isochrone/v1/mapbox/"; if (!String.IsNullOrEmpty(MapboxIsochroneSpeckle.Profile)) { url = url + MapboxIsochroneSpeckle.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 (contourNum != null) { url = url + contourNum; } url = url + "&polygons=true"; if (denoiseNum != null) { url = url + "&denoise=" + denoiseNum; } if (generalizeNum != null) { url = url + "&generalize=" + generalizeNum; } if (mbToken != "") { url = url + "&access_token=" + mbToken; } Url = url; if (CancellationToken.IsCancellationRequested) { return; } if (Run) { List <IGH_GeometricGoo> gGoo = new List <IGH_GeometricGoo>(); OSGeo.OGR.DataSource dataSource = OSGeo.OGR.Ogr.Open(url, 0); if (dataSource == null) { RuntimeMessages.Add((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) { 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) { gGoo.AddRange(Heron.Convert.OgrGeomToGHGoo(geomUser, userSRSToModelTransform)); } } Isochrones = gGoo; } Done(); }
static DataSet CreateTables(DataSource OGRDataSource, string MSSQLConnectionString) { // Create OSM ADO.NET DataSet DataSet OSMDataSet = new DataSet(); // Create SQL Tables for (int iLayer = 0; iLayer < OGRDataSource.GetLayerCount(); iLayer++) { Layer OGRLayer = OGRDataSource.GetLayerByIndex(iLayer); string layerName = OGRLayer.GetName(); // Construct CREATE TABLE statement StringBuilder SQLCreateCmd = new StringBuilder(); SQLCreateCmd.Append(string.Format("CREATE TABLE [{0}] (", layerName)); SQLCreateCmd.Append("[id] [INT] IDENTITY(1,1), "); FeatureDefn OGRLayerDef = OGRLayer.GetLayerDefn(); for (int iField = 0; iField < OGRLayerDef.GetFieldCount(); iField++) { FieldDefn OGRFieldDef = OGRLayerDef.GetFieldDefn(iField); SQLCreateCmd.Append(string.Format("[{0}] " + "[VARCHAR](MAX), ", OGRFieldDef.GetName())); } SQLCreateCmd.Append("[ogr_geometry] [GEOMETRY],"); SQLCreateCmd.Append("[ogr_geometry_area] [FLOAT]);"); //geometry_columns metadata string SQLGeometryColumnsCmd = string.Format(@"IF OBJECT_ID('dbo.geometry_columns') IS NOT NULL INSERT INTO [dbo].[geometry_columns] ([f_table_catalog],[f_table_schema],[f_table_name],[f_geometry_column],[coord_dimension],[srid],[geometry_type]) VALUES (DB_NAME(),SCHEMA_NAME(),'{0}','ogr_geometry',2,900913,'{1}')", layerName, OGRLayer.GetGeomType().ToString().Replace("wkb","") ); // Construct SQL statement used to get table schema // We use this to set a DataTable object schema after we create the SQL table string SQLSchemaCmd = string.Format("SET FMTONLY ON; SELECT * FROM [{0}]; SET FMTONLY OFF;", layerName); // Execute SQL DataTable table = new DataTable(); using (SqlConnection con = new SqlConnection(MSSQLConnectionString)) { con.Open(); try { // Create SQL table using (SqlCommand cmd = new SqlCommand(SQLCreateCmd.ToString(), con)) { log(TraceLevel.Info, string.Format("Creating table {0}...", layerName)); cmd.ExecuteNonQuery(); } // Set DataTable object schema using (SqlDataAdapter da = new SqlDataAdapter(SQLSchemaCmd, con)) { da.FillSchema(table, SchemaType.Source); // Hack to set ogr_geometry datatable column to correct SQLGeometry type // http://msdn.microsoft.com/en-us/library/ms143179(v=sql.110).aspx#Y2686 // http://connect.microsoft.com/SQLServer/feedback/details/685654/invalidcastexception-retrieving-sqlgeography-column-in-ado-net-data-reader table.Columns["ogr_geometry"].DataType = typeof(SqlGeometry); // Add DataTable to OSM DataSet OSMDataSet.Tables.Add(table); } } catch (Exception e) { log(TraceLevel.Error, e.Message); Environment.Exit(1); } //insert geoemtry_columns record try { using (SqlCommand cmd = new SqlCommand(SQLGeometryColumnsCmd, con)) { log(TraceLevel.Info, string.Format("Update geometry_columns metadata for {0}...", layerName)); cmd.ExecuteNonQuery(); } } catch (Exception e) { log(TraceLevel.Warning, e.Message); } } } return OSMDataSet; }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>(0, boundary); string shpFileLoc = ""; DA.GetData <string>("Vector Data Location", ref shpFileLoc); ///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>(); ///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 OGR envelope of the data in the layer OSGeo.OGR.Envelope ext = new OSGeo.OGR.Envelope(); layer.GetExtent(ext, 1); Point3d extMin = new Point3d(); Point3d extMax = new Point3d(); extMin.X = ext.MinX; extMin.Y = ext.MinY; extMax.X = ext.MaxX; extMax.Y = ext.MaxY; ///Get the spatial reference of the input vector file and set to WGS84 if not known OSGeo.OSR.SpatialReference sr = 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."); sr.ImportFromXML(shpFileLoc); string pretty = ""; sr.ExportToPrettyWkt(out pretty, 0); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, pretty); sr.SetWellKnownGeogCS("WGS84"); sRef = "Coordinate Reference System (CRS) is missing. CRS set automatically set to WGS84."; //sr.ImportFromEPSG(2263); } else { if (layer.GetSpatialRef().Validate() != 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is unknown or unsupported. CRS set automatically set to WGS84."); sr.SetWellKnownGeogCS("WGS84"); sRef = "Coordinate Reference System (CRS) is unknown or unsupported. SRS set automatically set to WGS84."; } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) set from layer" + iLayer + "."); sr = layer.GetSpatialRef(); sr.ExportToWkt(out sRef); } } 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 dst = new OSGeo.OSR.SpatialReference(""); dst.SetWellKnownGeogCS("WGS84"); OSGeo.OSR.CoordinateTransformation coordTransform = new OSGeo.OSR.CoordinateTransformation(sr, dst); OSGeo.OSR.CoordinateTransformation revTransform = new OSGeo.OSR.CoordinateTransformation(dst, sr); ///Get bounding box of data in layer double[] extMinPT = new double[3] { extMin.X, extMin.Y, extMin.Z }; double[] extMaxPT = new double[3] { extMax.X, extMax.Y, extMax.Z }; coordTransform.TransformPoint(extMinPT); coordTransform.TransformPoint(extMaxPT); 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.ToXYZ(extPTmin), Heron.Convert.ToXYZ(extPTmax)); recs.Append(new GH_Rectangle(rec), 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.ToWGS(boundary[i].GetBoundingBox(true).Min); Point3d max = Heron.Convert.ToWGS(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; revTransform.TransformPoint(minpT); revTransform.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; 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; ///reproject geometry to WGS84 ///TODO: look into using the SetCRS global variable here geom.Transform(coordTransform); if (feat.GetGeometryRef() != null) { ///Start get points if open polylines and points for (int gpc = 0; gpc < geom.GetPointCount(); gpc++) { ///Loop through geometry points 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; } //coordTransform.TransformPoint(pT); Point3d pt3D = new Point3d(); pt3D.X = pT[0]; pt3D.Y = pT[1]; pt3D.Z = pT[2]; gset.Append(new GH_Point(Heron.Convert.ToXYZ(pt3D)), 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>(); ///trouble getting all points. this is a troubleshoot ///gset.Append(new GH_Point(new Point3d(0, 0, sub_geom.GetGeometryCount())), new GH_Path(i, iLayer, m, gi)); if (sub_geom.GetGeometryCount() > 0) { for (int n = 0; n < sub_geom.GetGeometryCount(); n++) { subsub_geom = sub_geom.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.ToXYZ(pt3D)), new GH_Path(i, iLayer, m, gi, n)); ///End loop through geometry points } subsub_geom.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.ToXYZ(pt3D)), new GH_Path(i, iLayer, m, gi)); ///End loop through geometry points } } sub_geom.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++; 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); }
/// <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) { Curve boundary = null; DA.GetData <Curve>(0, ref boundary); int zoom = -1; DA.GetData <int>(1, ref zoom); string filePath = string.Empty; DA.GetData <string>(2, ref filePath); if (!filePath.EndsWith(@"\")) { filePath = filePath + @"\"; } string prefix = string.Empty; DA.GetData <string>(3, ref prefix); if (prefix == "") { prefix = mbSource; } string URL = mbURL; string mbToken = string.Empty; DA.GetData <string>(4, ref mbToken); 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; } } bool run = false; DA.GetData <bool>("Run", ref run); ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); OSGeo.OGR.Ogr.RegisterAll(); RESTful.GdalConfiguration.ConfigureGdal(); GH_Curve imgFrame; GH_String tCount; GH_Structure <GH_String> fnames = new GH_Structure <GH_String>(); GH_Structure <GH_String> fvalues = new GH_Structure <GH_String>(); GH_Structure <IGH_GeometricGoo> gGoo = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <GH_String> gtype = new GH_Structure <GH_String>(); GH_Structure <IGH_GeometricGoo> gGooBuildings = new GH_Structure <IGH_GeometricGoo>(); int tileTotalCount = 0; int tileDownloadedCount = 0; ///Get image frame for given boundary if (!boundary.GetBoundingBox(true).IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Boundary is not valid."); return; } BoundingBox boundaryBox = boundary.GetBoundingBox(true); //create cache folder for vector tiles string cacheLoc = filePath + @"HeronCache\"; List <string> cachefilePaths = new List <string>(); if (!Directory.Exists(cacheLoc)) { Directory.CreateDirectory(cacheLoc); } //tile bounding box array List <Point3d> boxPtList = new List <Point3d>(); //get the tile coordinates for all tiles within boundary var ranges = Convert.GetTileRange(boundaryBox, zoom); var x_range = ranges.XRange; var y_range = ranges.YRange; if (x_range.Length > 100 || y_range.Length > 100) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "This tile range is too big (more than 100 tiles in the x or y direction). Check your units."); return; } ///cycle through tiles to get bounding box List <Polyline> tileExtents = new List <Polyline>(); List <double> tileHeight = new List <double>(); List <double> tileWidth = new List <double>(); for (int y = (int)y_range.Min; y <= y_range.Max; y++) { for (int x = (int)x_range.Min; x <= x_range.Max; x++) { //add bounding box of tile to list for translation Polyline tileExtent = Heron.Convert.GetTileAsPolygon(zoom, y, x); tileExtents.Add(tileExtent); tileWidth.Add(tileExtent[0].DistanceTo(tileExtent[1])); tileHeight.Add(tileExtent[1].DistanceTo(tileExtent[2])); boxPtList.AddRange(tileExtent.ToList()); cachefilePaths.Add(cacheLoc + mbSource.Replace(" ", "") + zoom + "-" + x + "-" + y + ".mvt"); tileTotalCount = tileTotalCount + 1; } } tCount = new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"); ///bounding box of tile boundaries BoundingBox bboxPts = new BoundingBox(boxPtList); ///convert bounding box to polyline List <Point3d> imageCorners = bboxPts.GetCorners().ToList(); imageCorners.Add(imageCorners[0]); imgFrame = new GH_Curve(new Rhino.Geometry.Polyline(imageCorners).ToNurbsCurve()); ///tile range as string for (de)serialization of TileCacheMeta string tileRangeString = "Tile range for zoom " + zoom.ToString() + ": " + x_range[0].ToString() + "-" + y_range[0].ToString() + " to " + x_range[1].ToString() + "-" + y_range[1].ToString(); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, tileRangeString); ///Query Mapbox URL ///download all tiles within boundary ///API to query string mbURLauth = mbURL + mbToken; if (run == true) { for (int y = (int)y_range.Min; y <= (int)y_range.Max; y++) { for (int x = (int)x_range.Min; x <= (int)x_range.Max; x++) { //create tileCache name string tileCache = mbSource.Replace(" ", "") + zoom + "-" + x + "-" + y + ".mvt"; string tileCacheLoc = cacheLoc + tileCache; //check cache folder to see if tile image exists locally if (File.Exists(tileCacheLoc)) { } else { string urlAuth = Heron.Convert.GetZoomURL(x, y, zoom, mbURLauth); System.Net.WebClient client = new System.Net.WebClient(); client.DownloadFile(urlAuth, tileCacheLoc); client.Dispose(); ///https://gdal.org/development/rfc/rfc59.1_utilities_as_a_library.html ///http://osgeo-org.1560.x6.nabble.com/gdal-dev-How-to-convert-shapefile-to-geojson-using-c-bindings-td5390953.html#a5391028 ///ogr2ogr is slow //OSGeo.GDAL.Dataset httpDS = OSGeo.GDAL.Gdal.OpenEx("MVT:"+urlAuth,4,null,null,null); //var transOptions = new OSGeo.GDAL.GDALVectorTranslateOptions(new[] { "-s_srs","EPSG:3857", "-t_srs", "EPSG:4326","-skipfailures" }); //var transDS = OSGeo.GDAL.Gdal.wrapper_GDALVectorTranslateDestName(mvtLoc + zoom + "-" + x + "-" + y , httpDS, transOptions, null, null); //httpDS.Dispose(); //transDS.Dispose(); tileDownloadedCount = tileDownloadedCount + 1; } } } } //add to tile count total tCount = new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, tCount.ToString()); ///Build a VRT file ///https://stackoverflow.com/questions/55386597/gdal-c-sharp-wrapper-for-vrt-doesnt-write-a-vrt-file //string vrtFile = cacheLoc + "mapboxvector.vrt"; //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, vrtFile); //var vrtOptions = new OSGeo.GDAL.GDALBuildVRTOptions(new[] { "-overwrite" }); //var vrtDataset = OSGeo.GDAL.Gdal.wrapper_GDALBuildVRT_names(vrtFile, cachefilePaths.ToArray(), vrtOptions, null, null); //vrtDataset.Dispose(); ///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); userSRS.SetFromUserInput("WGS84"); OSGeo.OSR.SpatialReference sourceSRS = new SpatialReference(""); sourceSRS.SetFromUserInput("EPSG:3857"); ///These transforms move and scale in order to go from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); Transform sourceToModelSRSTransform = Heron.Convert.GetUserSRSToModelTransform(sourceSRS); Transform modelToSourceSRSTransform = Heron.Convert.GetModelToUserSRSTransform(sourceSRS); //OSGeo.GDAL.Driver gdalOGR = OSGeo.GDAL.Gdal.GetDriverByName("VRT"); //var ds = OSGeo.GDAL.Gdal.OpenEx(vrtFile, 4, ["VRT","MVT"], null, null); int t = 0; foreach (string mvtTile in cachefilePaths)// cachefilePaths) { OSGeo.OGR.Driver drv = OSGeo.OGR.Ogr.GetDriverByName("MVT"); OSGeo.OGR.DataSource ds = OSGeo.OGR.Ogr.Open("MVT:" + mvtTile, 0); string[] mvtOptions = new[] { "CLIP", "NO" }; //OSGeo.OGR.DataSource ds = drv.Open(mvtTile, 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; } ///Morph raw mapbox tile points to geolocated tile Vector3d moveDir = tileExtents[t].ElementAt(0) - new Point3d(0, 0, 0); Transform move = Transform.Translation(moveDir); Transform scale = Transform.Scale(Plane.WorldXY, tileWidth[t] / 4096, tileHeight[t] / 4096, 1); Transform scaleMove = Transform.Multiply(move, scale); for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++) { OSGeo.OGR.Layer layer = ds.GetLayerByIndex(iLayer); long count = layer.GetFeatureCount(1); int featureCount = System.Convert.ToInt32(count); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Layer #" + iLayer + " " + layer.GetName() + " has " + featureCount + " features"); //if (layer.GetName() == "admin" || layer.GetName() == "building") //{ 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(iLayer, t)); } ///Loop through geometry OSGeo.OGR.Feature feat; int m = 0; ///error "Self-intersection at or near point..." when zoom gets below 12 for water ///this is an issue with the way mvt simplifies geometries at lower zoom levels and is a known problem ///TODO: look into how to fix invalid geom and return to the typical while loop iterating method //while ((feat = layer.GetNextFeature()) != null) while (true) { try { feat = layer.GetNextFeature(); } catch { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Some features had invalid geometry and were skipped."); continue; } if (feat == null) { break; } OSGeo.OGR.Geometry geom = feat.GetGeometryRef(); ///reproject geometry to WGS84 and userSRS ///TODO: look into using the SetCRS global variable here gtype.Append(new GH_String(geom.GetGeometryName()), new GH_Path(iLayer, t, m)); Transform tr = scaleMove; // new Transform(1); if (feat.GetGeometryRef() != null) { ///Convert GDAL geometries to IGH_GeometricGoo foreach (IGH_GeometricGoo gMorphed in Heron.Convert.OgrGeomToGHGoo(geom, tr)) { //gMorphed.Morph(morph); gGoo.Append(gMorphed, new GH_Path(iLayer, t, m)); } if (layer.GetName() == "building") { if (feat.GetFieldAsString(def.GetFieldIndex("extrude")) == "true") { double unitsConversion = Rhino.RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, Rhino.UnitSystem.Meters); double height = System.Convert.ToDouble(feat.GetFieldAsString(def.GetFieldIndex("height"))) / unitsConversion; double min_height = System.Convert.ToDouble(feat.GetFieldAsString(def.GetFieldIndex("min_height"))) / unitsConversion; bool underground = System.Convert.ToBoolean(feat.GetFieldAsString(def.GetFieldIndex("underground"))); if (geom.GetGeometryType() == wkbGeometryType.wkbPolygon) { Extrusion bldg = Heron.Convert.OgrPolygonToExtrusion(geom, tr, height, min_height, underground); IGH_GeometricGoo bldgGoo = GH_Convert.ToGeometricGoo(bldg); gGooBuildings.Append(bldgGoo, new GH_Path(iLayer, t, m)); } if (geom.GetGeometryType() == wkbGeometryType.wkbMultiPolygon) { List <Extrusion> bldgs = Heron.Convert.OgrMultiPolyToExtrusions(geom, tr, height, min_height, underground); foreach (Extrusion bldg in bldgs) { IGH_GeometricGoo bldgGoo = GH_Convert.ToGeometricGoo(bldg); gGooBuildings.Append(bldgGoo, new GH_Path(iLayer, t, m)); } } } } /// Get Feature Values if (fvalues.PathExists(new GH_Path(iLayer, t, m))) { //fvalues.get_Branch(new GH_Path(iLayer, t, m)).Clear(); } for (int iField = 0; iField < feat.GetFieldCount(); iField++) { OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField); if (feat.IsFieldSet(iField)) { fvalues.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(iLayer, t, m)); } else { fvalues.Append(new GH_String("null"), new GH_Path(iLayer, t, m)); } } } m++; geom.Dispose(); feat.Dispose(); }///end while loop through features //}///end layer by name layer.Dispose(); }///end loop through layers ds.Dispose(); t++; }///end loop through mvt tiles //write out new tile range metadata for serialization TileCacheMeta = tileRangeString; DA.SetData(0, imgFrame); DA.SetDataTree(1, fnames); DA.SetDataTree(2, fvalues); DA.SetDataTree(3, gGoo); DA.SetDataList(4, "copyright Mapbox"); DA.SetDataTree(5, gtype); DA.SetDataTree(6, gGooBuildings); DA.SetDataList(7, tileExtents); }