• 使用OGR创建弧形图形


    很多时候我们需要在矢量文件中记录一些弧形图形,由于目前OGR中没有支持通过圆心半径等方式来保存矢量图形,所以对于这些矢量图形必须要计算出弧线上的点坐标来进行存储,如果自己按照圆弧的算法来创建这些点确实有些麻烦,OGR中提供了一个叫approximateArcAngles的函数来对圆弧点坐标进行计算,使用起来非常方便,下面是该函数的一个简单说明。函数原型为:

    创建一段椭圆弧段。指定一个原点坐标、椭圆的长半轴长度、短半轴长度、旋转角度、起始角度和结束角度来生成一段弧段。参数dfMaxAngleStepSizeDegrees用来指定最大步长,可以使用配置选项OGR_ARC_STEPSIZE来进行设置默认值。

    生成弧段如图1所示,左侧和下侧两条白色线段分别为X轴和Y轴,交点为坐标原点,绿色椭圆的圆心坐标为(dfCenterX,dfCenterY,dfZ),长半轴和短半轴长度分别如图中两条蓝色线段表示,起始角度和结束角度方向射线如图中紫色线段所示,图中红色的弧段即为生成的弧段。


    图1 函数参数说明示意图

    OGRGeometry * OGRGeometryFactory::approximateArcAngles(
    double dfCenterX, 
    double dfCenterY, 
    double dfZ, 
    double dfPrimaryRadius, 
    double dfSecondaryRadius, 
    double dfRotation, 
    double dfStartAngle, 
    double dfEndAngle, 
    double dfMaxAngleStepSizeDegrees )
    参数说明:

    dfCenterX

    椭圆原点X坐标

    dfCenterY

    椭圆原点Y坐标

    dfZ

    椭圆原点Z坐标

    dfPrimaryRadius

    椭圆长半轴长度

    dfSecondaryRadius

    椭圆短半轴长度

    dfRotation

    椭圆顺时针旋转角度

    dfStartAngle

    弧段起始点角度(与X轴顺时针夹角)

    dfEndAngle

    弧段结束点角度(与X轴顺时针夹角)

    dfMaxAngleStepSizeDegrees

    沿着弧段最长步长对应的角度,设置为0按默认值计算

           通过上面的函数参数说明和图形大概应该就比较清楚了,下面使用一段代码来创建几个图形测试一下。测试代码如下:

    void WriteVectorFile1()
    {
    	// 为了支持中文SHP路径,请添加下面这句代码
    	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
    #ifdef CREATSHP 
    	// 为了使属性表字段支持中文,请添加下面这句,创建SHP
    	CPLSetConfigOption("SHAPE_ENCODING", "" );
    	const char* pszVectorFile = "E:\\TestArc.shp";
    	const char *pszDriverName = "ESRI Shapefile";
    #else 
    	// 创建DXF
    	CPLSetConfigOption("GDAL_DATA", "C:\\warmerda\\GDAL110\\data");
    	const char* pszVectorFile = "E:\\TestArc.dxf";
    	const char *pszDriverName = "DXF";
    #endif
    
    	// 注册所有的驱动
    	OGRRegisterAll();
    
    	//创建数据
    	OGRSFDriver *poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName );
    	if( poDriver == NULL )
    	{
    		printf( "%s 驱动不可用!\n", pszDriverName );
    		return;
    	}
    
    	// 创建数据源
    	OGRDataSource *poDS = poDriver->CreateDataSource(pszVectorFile, NULL );
    	if( poDS == NULL )
    	{
    		printf( "创建矢量文件【%s】失败!\n", pszVectorFile );
    		return;
    	}
    
    	// 创建图层,创建一个线图层,这里没有指定空间参考,如果需要的话,需要在这里进行指定
    	OGRLayer *poLayer = poDS->CreateLayer( "TestPolygon", NULL, wkbLineString, NULL );
    	if( poLayer == NULL )
    	{
    		printf( "图层创建失败!\n" );
    		OGRDataSource::DestroyDataSource( poDS );
    		return;
    	}
    
    	// 由于DXF不支持属性表,所以下面几句OGR会提示错误信息
    	// 下面创建属性表
    	// 先创建一个叫FieldID的整型属性
    	OGRFieldDefn oFieldID("FieldID", OFTInteger);
    	poLayer->CreateField(&oFieldID);
    
    	// 再创建一个叫FeatureName的字符型属性,字符长度为
    	OGRFieldDefn oFieldName("FieldName", OFTString);
    	oFieldName.SetWidth(100);
    	poLayer->CreateField(&oFieldName);
    
    	OGRFeatureDefn *poDefn = poLayer->GetLayerDefn();
    
    	// 创建两个坐标轴X和Y
    	OGRFeature *poFeatureXAxis  = OGRFeature::CreateFeature(poDefn);
    	poFeatureXAxis->SetField(0, 0);
    	poFeatureXAxis->SetField(1, "X轴");
    	OGRLineString *pGeoXAxis = (OGRLineString*)OGRGeometryFactory::createGeometry(wkbLineString) ;
    	pGeoXAxis->setPoint(0, -100, 0);
    	pGeoXAxis->setPoint(1,  100, 0);
    	poFeatureXAxis->SetGeometry(pGeoXAxis);
    	poLayer->CreateFeature( poFeatureXAxis );
    	OGRFeature::DestroyFeature( poFeatureXAxis );
    
    	// 创建Y轴
    	OGRFeature *poFeatureYAxis = OGRFeature::CreateFeature(poDefn);
    	poFeatureYAxis->SetField(0, 1);
    	poFeatureYAxis->SetField(1, "Y轴");
    	OGRLineString *pGeoYAxis = (OGRLineString*) OGRGeometryFactory::createGeometry(wkbLineString) ;
    	pGeoYAxis->setPoint(0, 0, -100);
    	pGeoYAxis->setPoint(1, 0, 100);
    	poFeatureYAxis->SetGeometry(pGeoYAxis);
    	poLayer->CreateFeature( poFeatureYAxis );
    	OGRFeature::DestroyFeature( poFeatureYAxis );
    
    	// 创建圆形要素
    	OGRFeature *poFeatureCircle = OGRFeature::CreateFeature(poDefn);
    	poFeatureCircle->SetField(0, 2);
    	poFeatureCircle->SetField(1, "圆形");
    
    	OGRGeometry * pCircleLine = OGRGeometryFactory::approximateArcAngles(50.0,-10.0, 0.0, 10.0, 10.0, 0.0, 0.0, 360.0, 1.0 );
    	poFeatureCircle->SetGeometry(pCircleLine);
    
    	poLayer->CreateFeature( poFeatureCircle );
    	OGRFeature::DestroyFeature( poFeatureCircle );
    
    	// 创建圆形要素
    	OGRFeature *poFeatureEclipse = OGRFeature::CreateFeature(poDefn);
    	poFeatureEclipse->SetField(0, 3);
    	poFeatureEclipse->SetField(1, "椭圆");
    
    	OGRGeometry * pEclipseLine = OGRGeometryFactory::approximateArcAngles(50.0, 50.0, 0.0, 10.0, 20.0, 45.0, 0.0, 360.0, 1.0 );
    	poFeatureEclipse->SetGeometry(pEclipseLine);
    
    	poLayer->CreateFeature( poFeatureEclipse );
    	OGRFeature::DestroyFeature( poFeatureEclipse );
    
    	// 创建半圆形要素
    	OGRFeature *poFeatureArc = OGRFeature::CreateFeature(poDefn);
    	poFeatureArc->SetField(0, 4);
    	poFeatureArc->SetField(1, "半圆形");
    
    	OGRGeometry * pArcLine = OGRGeometryFactory::approximateArcAngles(-50.0,50.0, 0.0, 20.0, 20.0, 0.0, 45.0, 215.0, 1.0 );
    	poFeatureArc->SetGeometry(pArcLine);
    
    	poLayer->CreateFeature( poFeatureArc );
    	OGRFeature::DestroyFeature( poFeatureArc );
    
    	OGRDataSource::DestroyDataSource( poDS );
    	printf( "\n数据集创建完成!\n" );
    }
         上面创建的是一个线状图层,如果要创建面状图形,需要把里面的线状要素构造一个面状的,上面的代码创建的图形如图2和图3所示。相互垂直的是两个坐标轴X和Y,方便几个弧段定位的,其中有个椭圆,椭圆的圆心为(50,50),长短半轴分别为20和10,同时旋转了45度,生成的弧段范围为整个椭圆弧(0~360),采样间隔为1度,意思就是整个弧段由360个点组成。还有个圆,圆心为(50,-10),半径为10,其他的和椭圆一样。最后还有个半圆弧,半圆弧的圆心为(-50,50),圆半径为20,起点为45度,终点为215度,共180度,一个半圆弧。

    图2 创建的Shp图形用ArcMap打开标记属性值

    图3 创建的DXF图形用AutoCAD打开

  • 相关阅读:
    58:二叉树的下一个节点
    57:删除链表中重复的结点
    56:链表中环的入口结点
    55:字符流中第一个不重复的字符
    54:表示数值的字符串
    53:正则表达式匹配
    52:构建成绩数组
    51:数组中重复的数字
    每个努力奋斗过的人,被不公正的际遇砸了满头包的时候,都有那么一瞬间的代入感。出生就是hard模式的人,早已经历了太多的劳其筋骨饿其体肤,再多的人为考验只会摧毁人对美好的向往。
    ClientValidationEnabled
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6313950.html
Copyright © 2020-2023  润新知