scott_f想要一个 C# 实现,将来可能有人也需要它,所以我将它作为答案发布。我很懒,不想使用嵌套列表和不同的数据结构重写整个事情,Rhino/Grasshopper
因为这个实现是插件GH_Structure, IGH_GeometricGoo, IGH_Goo
的一部分(是Rhino/Grasshopper
API 的一部分)。但基本上IGH_Goo
在这种情况下是指一个几何类bools
,IGH_GeometricGoo
它可以包含Polyline
和Point3d
类,并且GH_Structure
是一个多维数据结构(列表列表),它通过.Append()
方法“添加”项目,其中第一个参数是要添加的数据第二个是“路径”,因此.Append( item, new GH_Path( 0, 3 ) )
将添加item
到第 4 个索引处的第一个列表列表中。这可能是个好主意wkbFlatten
,以便它在 wkbType 的维度不同时起作用,但我将把它留给读者,因为我的实现不需要它。请注意,layer
是作为参数传递的,因此如果您需要文件中的所有数据,则应遍历所有层。
class WKBToRhinoGeoUtilities
{
private string input;
private int layerNumber;
private int EPSGCode;
private int InEPSGCode;
private OSGeo.OGR.Driver driver;
OSGeo.OGR.DataSource dataSource;
private GH_Path path;
private double[] pointList = { 0, 0, 0 };
private long numberOfFeatures;
private int layerCount;
private OSGeo.OGR.Layer layer;
private OSGeo.OGR.wkbGeometryType wkbGeoType;
private int currentProjection;
private OSGeo.OSR.CoordinateTransformation transform;
private OSGeo.OGR.Feature feature;
private OSGeo.OGR.Geometry geo, ring;
public string debug = "Working!";
public WKBToRhinoGeoUtilities( string input, int layerNumber, int EPSGCode,
int InEPSGCode, OSGeo.OGR.DataSource dataSource )
{
this.input = input;
this.layerNumber = layerNumber;
this.EPSGCode = EPSGCode;
this.InEPSGCode = InEPSGCode;
this.dataSource = dataSource;
}
public string Setup()
{
GetDataSourceAttributes();
IdentifyEPSG();
return debug;
}
public GH_Structure<IGH_GeometricGoo> Run( ref GH_Structure<IGH_Goo> cullPattern )
{
switch( wkbGeoType )
{
case OSGeo.OGR.wkbGeometryType.wkbUnknown:
return WKBUnknown( ref cullPattern );
case OSGeo.OGR.wkbGeometryType.wkbPolygon:
return WKBPolygon( ref cullPattern );
case OSGeo.OGR.wkbGeometryType.wkbLineString:
return WKBLineString( ref cullPattern );
case OSGeo.OGR.wkbGeometryType.wkbPoint:
return WKBPoint( ref cullPattern );
case OSGeo.OGR.wkbGeometryType.wkbPoint25D:
return WKBPoint( ref cullPattern );
case OSGeo.OGR.wkbGeometryType.wkbMultiPolygon:
return WKBMultiPolygon( ref cullPattern );
case OSGeo.OGR.wkbGeometryType.wkbMultiLineString:
return WKBMultiLineString( ref cullPattern );
case OSGeo.OGR.wkbGeometryType.wkbGeometryCollection:
return WKBGeometryCollection( ref cullPattern );
default:
return null;
}
}
private void GetDataSourceAttributes()
{
if( dataSource != null )
{
layerCount = dataSource.GetLayerCount();
layer = dataSource.GetLayerByIndex( layerNumber % layerCount );
wkbGeoType = layer.GetGeomType();
numberOfFeatures = unchecked( ( int ) layer.GetFeatureCount( 0 ) );
}
else
{
debug = "Data Source is null!";
}
}
private void IdentifyEPSG()
{
// Source projections, try to get it automatically otherwise resort to user input.
OSGeo.OSR.SpatialReference source = null;
int identifyEPSG = 0;
try
{
source = layer.GetSpatialRef();
identifyEPSG = source.AutoIdentifyEPSG();
}
catch
{
debug = "The file's EPSG code couldn't be found automatically, it will default to EPSG:3857, make sure you input the correct one!";
source = new OSGeo.OSR.SpatialReference( "" );
identifyEPSG = source.ImportFromEPSG( InEPSGCode );
}
currentProjection = Convert.ToInt32( source.GetAttrValue( "AUTHORITY", 1 ) );
// Reprojections.
OSGeo.OSR.SpatialReference target = new OSGeo.OSR.SpatialReference( "" );
if( currentProjection != EPSGCode )
{
target.ImportFromEPSG( EPSGCode );
transform = new OSGeo.OSR.CoordinateTransformation( source, target );
}
}
private GH_Structure<IGH_GeometricGoo> WKBUnknown( ref GH_Structure<IGH_Goo> cullPattern )
{
GH_Structure<IGH_GeometricGoo> geoOutput = new GH_Structure<IGH_GeometricGoo>();
cullPattern = new GH_Structure<IGH_Goo>();
double[] pointList = { 0, 0, 0 };
int counter = 0;
do
{
path = new GH_Path( counter );
feature = layer.GetNextFeature();
bool pattern = false;
if( feature != null )
{
OSGeo.OGR.Geometry geo = feature.GetGeometryRef();
if( geo != null )
{
if( currentProjection != EPSGCode )
{
geo.Transform( transform );
}
pattern = true;
int pointCount = geo.GetPointCount();
IGH_GeometricGoo geoGoo = null;
Point3d[] tempPointArray = new Point3d[pointCount];
for( int i = 0; i < pointCount; ++i )
{
geo.GetPoint( i, pointList );
tempPointArray[i] = new Point3d( pointList[0], pointList[1], pointList[2] );
}
if( tempPointArray.Length > 2 )
{
Polyline tempPoly = new Polyline( tempPointArray );
geoGoo = GH_Convert.ToGeometricGoo( tempPoly );
geoOutput.Append( geoGoo, path );
}
else if( tempPointArray.Length > 0 )
{
geoGoo = GH_Convert.ToGeometricGoo( tempPointArray[0] );
geoOutput.Append( geoGoo, path );
}
}
}
IGH_Goo patternGoo = GH_Convert.ToGoo( pattern );
cullPattern.Append( patternGoo, path );
counter++;
} while( feature != null );
return geoOutput;
}
private GH_Structure<IGH_GeometricGoo> WKBPolygon( ref GH_Structure<IGH_Goo> cullPattern )
{
GH_Structure<IGH_GeometricGoo> geoOutput = new GH_Structure<IGH_GeometricGoo>();
cullPattern = new GH_Structure<IGH_Goo>();
if ( numberOfFeatures != -1 )
{
for( int i = 0; i < numberOfFeatures; ++i )
{
path = new GH_Path(i);
feature = layer.GetFeature(i);
bool pattern = false;
if( feature != null )
{
geo = feature.GetGeometryRef();
if( geo != null )
{
IGH_GeometricGoo geoGoo = WKBPolygonSingle( geo, ref pattern );
geoOutput.Append( geoGoo, path );
}
}
IGH_Goo gooPattern = GH_Convert.ToGoo( pattern );
cullPattern.Append( gooPattern, path );
}
}
else
{
feature = layer.GetNextFeature();
int counter = 0;
while( feature != null )
{
path = new GH_Path( counter );
geo = feature.GetGeometryRef();
bool pattern = false;
if( geo != null )
{
IGH_GeometricGoo geoGoo = WKBPolygonSingle( geo, ref pattern );
geoOutput.Append( geoGoo, path );
}
IGH_Goo gooPattern = GH_Convert.ToGoo( pattern );
cullPattern.Append( gooPattern, path );
feature = layer.GetNextFeature();
counter++;
}
}
return geoOutput;
}
private GH_Structure<IGH_GeometricGoo> WKBLineString( ref GH_Structure<IGH_Goo> cullPattern )
{
GH_Structure<IGH_GeometricGoo> geoOutput = new GH_Structure<IGH_GeometricGoo>();
cullPattern = new GH_Structure<IGH_Goo>();
if ( numberOfFeatures != -1 )
{
for( int i = 0; i < numberOfFeatures; ++i )
{
path = new GH_Path(i);
feature = layer.GetFeature(i);
bool pattern = false;
if( feature != null )
{
geo = feature.GetGeometryRef();
if( geo != null )
{
IGH_GeometricGoo geoGoo = WKBLineStringSingle( geo, ref pattern );
geoOutput.Append( geoGoo, path );
}
}
IGH_Goo gooPattern = GH_Convert.ToGoo( pattern );
cullPattern.Append( gooPattern, path );
}
}
else
{
int counter = 0;
feature = layer.GetNextFeature();
while( feature != null )
{
path = new GH_Path( counter );
geo = feature.GetGeometryRef();
bool pattern = false;
if( geo != null )
{
IGH_GeometricGoo geoGoo = WKBLineStringSingle( geo, ref pattern );
geoOutput.Append( geoGoo, path );
}
IGH_Goo gooPattern = GH_Convert.ToGoo( pattern );
cullPattern.Append( gooPattern, path );
feature = layer.GetNextFeature();
counter++;
}
}
return geoOutput;
}
private GH_Structure<IGH_GeometricGoo> WKBPoint( ref GH_Structure<IGH_Goo> cullPattern )
{
GH_Structure<IGH_GeometricGoo> geoOutput = new GH_Structure<IGH_GeometricGoo>();
cullPattern = new GH_Structure<IGH_Goo>();
if ( numberOfFeatures != -1 )
{
for( int i = 0; i < numberOfFeatures; ++i )
{
path = new GH_Path(i);
feature = layer.GetFeature(i);
bool tempPattern = feature != null ? true : false;
IGH_Goo gooPattern = GH_Convert.ToGoo( tempPattern );
cullPattern.Append( gooPattern, path );
if( feature != null )
{
geo = feature.GetGeometryRef();
IGH_GeometricGoo geoGoo = WKBPointSingle( geo );
geoOutput.Append( geoGoo, path );
}
}
}
else
{
int counter = 0;
feature = layer.GetNextFeature();
while( feature != null )
{
path = new GH_Path( counter );
bool tempPattern = feature != null ? true : false;
IGH_Goo gooPattern = GH_Convert.ToGoo( tempPattern );
cullPattern.Append( gooPattern, path );
geo = feature.GetGeometryRef();
IGH_GeometricGoo geoGoo = WKBPointSingle( geo );
geoOutput.Append( geoGoo, path );
feature = layer.GetNextFeature();
counter++;
}
}
return geoOutput;
}
private GH_Structure<IGH_GeometricGoo> WKBMultiPolygon( ref GH_Structure<IGH_Goo> cullPattern )
{
GH_Structure<IGH_GeometricGoo> geoOutput = new GH_Structure<IGH_GeometricGoo>();
cullPattern = new GH_Structure<IGH_Goo>();
if ( numberOfFeatures != -1 )
{
for( int i = 0; i < numberOfFeatures; ++i )
{
path = new GH_Path(i);
feature = layer.GetFeature(i);
bool pattern = false;
if( feature != null )
{
geo = feature.GetGeometryRef();
for( int j = 0; j < geo.GetGeometryCount(); ++j )
{
OSGeo.OGR.Geometry inGeo = geo.GetGeometryRef(j);
IGH_GeometricGoo geoGoo = WKBPolygonSingle( inGeo, ref pattern );
geoOutput.Append( geoGoo, path );
}
}
IGH_Goo gooPattern = GH_Convert.ToGoo( pattern );
cullPattern.Append( gooPattern, path );
}
}
else
{
int counter = 0;
feature = layer.GetNextFeature();
while( feature != null )
{
bool pattern = false;
path = new GH_Path( counter );
geo = feature.GetGeometryRef();
for( int j = 0; j < geo.GetGeometryCount(); ++j )
{
OSGeo.OGR.Geometry inGeo = geo.GetGeometryRef(j);
if( inGeo != null )
{
IGH_GeometricGoo geoGoo = WKBPolygonSingle( inGeo, ref pattern );
geoOutput.Append( geoGoo, path );
}
}
IGH_Goo gooPattern = GH_Convert.ToGoo( pattern );
cullPattern.Append( gooPattern, path );
counter++;
feature = layer.GetNextFeature();
}
}
return geoOutput;
}
private GH_Structure<IGH_GeometricGoo> WKBMultiLineString( ref GH_Structure<IGH_Goo> cullPattern )
{
GH_Structure<IGH_GeometricGoo> geoOutput = new GH_Structure<IGH_GeometricGoo>();
cullPattern = new GH_Structure<IGH_Goo>();
if ( numberOfFeatures != -1 )
{
for( int i = 0; i < numberOfFeatures; ++i )
{
path = new GH_Path(i);
feature = layer.GetFeature(i);
bool pattern = false;
if( feature != null )
{
geo = feature.GetGeometryRef();
if( geo != null )
{
for( int j = 0; j < geo.GetGeometryCount(); ++j )
{
ring = geo.GetGeometryRef(j);
IGH_GeometricGoo geoGoo = WKBLineStringSingle( ring, ref pattern );
geoOutput.Append( geoGoo, path );
}
}
}
IGH_Goo gooPattern = GH_Convert.ToGoo( pattern );
cullPattern.Append( gooPattern, path );
}
}
else
{
feature = layer.GetNextFeature();
int counter = 0;
while( feature != null )
{
path = new GH_Path( counter );
geo = feature.GetGeometryRef();
bool pattern = false;
if( geo != null )
{
for( int j = 0; j < geo.GetGeometryCount(); ++j )
{
ring = geo.GetGeometryRef(j);
IGH_GeometricGoo geoGoo = WKBLineStringSingle( ring, ref pattern );
geoOutput.Append( geoGoo, path );
}
}
IGH_Goo gooPattern = GH_Convert.ToGoo( pattern );
cullPattern.Append( gooPattern, path );
feature = layer.GetNextFeature();
counter++;
}
}
return geoOutput;
}
private GH_Structure<IGH_GeometricGoo> WKBGeometryCollection( ref GH_Structure<IGH_Goo> cullPattern )
{
GH_Structure<IGH_GeometricGoo> geoOutput = new GH_Structure<IGH_GeometricGoo>();
cullPattern = new GH_Structure<IGH_Goo>();
GH_Structure<IGH_Goo> cullPatternTemp = new GH_Structure<IGH_Goo>();
if ( numberOfFeatures != -1 )
{
for( int i = 0; i < numberOfFeatures; ++i )
{
path = new GH_Path(i);
feature = layer.GetFeature(i);
if( feature != null )
{
geo = feature.GetGeometryRef();
if( geo != null )
{
bool tempPattern = feature != null ? true : false;
IGH_GeometricGoo geoGoo = null;
if( geo != null )
{
for( int j = 0; j < geo.GetGeometryCount(); ++j )
{
path = new GH_Path( j, i );
ring = geo.GetGeometryRef(i);
OSGeo.OGR.wkbGeometryType geoType = ring.GetGeometryType();
switch( geoType )
{
case OSGeo.OGR.wkbGeometryType.wkbPoint:
geoGoo = WKBPointSingle( ring );
break;
case OSGeo.OGR.wkbGeometryType.wkbPoint25D:
geoGoo = WKBPointSingle( ring );
break;
case OSGeo.OGR.wkbGeometryType.wkbPolygon:
geoGoo = WKBPolygonSingle( ring, ref tempPattern );
break;
case OSGeo.OGR.wkbGeometryType.wkbLineString:
geoGoo = WKBLineStringSingle( ring, ref tempPattern );
break;
}
geoOutput.Append( geoGoo, path );
IGH_Goo gooPattern = GH_Convert.ToGoo( tempPattern );
cullPattern.Append( gooPattern, path );
}
}
}
}
}
}
else
{
int counter = 0;
feature = layer.GetNextFeature();
while( feature != null )
{
geo = feature.GetGeometryRef();
bool tempPattern = feature != null ? true : false;
IGH_GeometricGoo geoGoo = null;
if( geo != null )
{
for( int i = 0; i < geo.GetGeometryCount(); ++i )
{
path = new GH_Path( counter, i );
ring = geo.GetGeometryRef(i);
OSGeo.OGR.wkbGeometryType geoType = ring.GetGeometryType();
switch( geoType )
{
case OSGeo.OGR.wkbGeometryType.wkbPoint:
geoGoo = WKBPointSingle( ring );
break;
case OSGeo.OGR.wkbGeometryType.wkbPoint25D:
geoGoo = WKBPointSingle( ring );
break;
case OSGeo.OGR.wkbGeometryType.wkbPolygon:
geoGoo = WKBPolygonSingle( ring, ref tempPattern );
break;
case OSGeo.OGR.wkbGeometryType.wkbLineString:
geoGoo = WKBLineStringSingle( ring, ref tempPattern );
break;
}
geoOutput.Append( geoGoo, path );
IGH_Goo gooPattern = GH_Convert.ToGoo( tempPattern );
cullPattern.Append( gooPattern, path );
}
}
feature = layer.GetNextFeature();
counter++;
}
}
return geoOutput;
}
private IGH_GeometricGoo WKBPointSingle( OSGeo.OGR.Geometry geo )
{
IGH_GeometricGoo geoGoo = null;
if( currentProjection != EPSGCode )
{
geo.Transform( transform );
}
geo.GetPoint( 0, pointList );
Point3d tempPoint = new Point3d( pointList[0], pointList[1], pointList[2] );
geoGoo = GH_Convert.ToGeometricGoo( tempPoint );
return geoGoo;
}
private IGH_GeometricGoo WKBPolygonSingle( OSGeo.OGR.Geometry geo, ref bool pattern )
{
IGH_GeometricGoo geoGoo = null;
ring = geo.GetGeometryRef( 0 );
if( currentProjection != EPSGCode )
{
ring.Transform( transform );
}
int pointCount = ring.GetPointCount();
Point3d[] tempPointArray = new Point3d[pointCount];
for (int j = 0; j < pointCount; ++j)
{
ring.GetPoint( j, pointList );
tempPointArray[j] = new Point3d( pointList[0], pointList[1], pointList[2] );
}
if( tempPointArray.Length > 1 )
{
Polyline polyOut = new Polyline( tempPointArray );
geoGoo = GH_Convert.ToGeometricGoo( polyOut );
pattern = true;
}
return geoGoo;
}
private IGH_GeometricGoo WKBLineStringSingle( OSGeo.OGR.Geometry geo, ref bool pattern )
{
IGH_GeometricGoo geoGoo = null;
if( currentProjection != EPSGCode )
{
geo.Transform( transform );
}
int pointCount = geo.GetPointCount();
Point3d[] tempPointArray = new Point3d[pointCount];
for( int j = 0; j < pointCount; ++j )
{
geo.GetPoint( j, pointList );
tempPointArray[j] = new Point3d( pointList[0], pointList[1], pointList[2] );
}
if( tempPointArray.Length > 1 )
{
Polyline polyOut = new Polyline( tempPointArray );
geoGoo = GH_Convert.ToGeometricGoo( polyOut );
pattern = true;
}
IGH_Goo gooPattern = GH_Convert.ToGoo( pattern );
return geoGoo;
}
}
你会打电话给它(确保你打电话给
GdalConfiguration.ConfigureOgr();
GdalConfiguration.ConfigureGdal();
):
OSGeo.OGR.Driver driver = Utilities.GetExtractorDriver( input, ref debug );
OSGeo.OGR.DataSource dataSource = driver.Open( input, 0 );
WKBToRhinoGeoUtilities wkbToRhino = new WKBToRhinoGeoUtilities( input, layerNumber, EPSGCode, InEPSGCode, dataSource );
debug = wkbToRhino.Setup();
AddRuntimeMessage( GH_RuntimeMessageLevel.Blank, debug );
if( debug != "Driver is null!" || debug != "Data Source is null!" || debug != "File does not exist!" )
{
GH_Structure<IGH_Goo> cullPattern = new GH_Structure<IGH_Goo>();
GH_Structure<IGH_GeometricGoo> geoOutput = wkbToRhino.Run( ref cullPattern );
DA.SetDataTree( 0, geoOutput );
DA.SetDataTree( 1, cullPattern );
}
我有一个Utilities
带有这个静态方法的类:
public static OSGeo.OGR.Driver GetExtractorDriver( string inputString, ref string debug )
{
if( File.Exists( inputString ) )
{
debug = "File exists!";
string isRunning = RunGDAL.output;
OSGeo.OGR.Driver driver = null;
string[] fileTypeArray = inputString.Split( '.' );
string fileType = fileTypeArray[fileTypeArray.Length - 1];
if( fileType == "shp" )
{
driver = OSGeo.OGR.Ogr.GetDriverByName( "ESRI Shapefile" );
}
else if( fileType == "json" || fileType == "geojson" )
{
driver = OSGeo.OGR.Ogr.GetDriverByName( "GeoJSON" );
}
else if( fileType == "topojson" )
{
driver = OSGeo.OGR.Ogr.GetDriverByName( "TopoJSON" );
}
else if( fileType == "gpkg" )
{
driver = OSGeo.OGR.Ogr.GetDriverByName( "GPKG" );
}
else if( fileType == "dxf" )
{
driver = OSGeo.OGR.Ogr.GetDriverByName( "DXF" );
}
else if( fileType == "kml" )
{
driver = OSGeo.OGR.Ogr.GetDriverByName( "KML" );
}
else if( fileType == "osm" )
{
driver = OSGeo.OGR.Ogr.GetDriverByName( "OSM" );
}
return driver;
}
else
{
debug = "File does not exist!";
return null;
}
}