1.ogr
使用ogr库创建点状要素的shapefile文件以及将经纬度坐标转为投影坐标。实例如下:
#include "ogrsf_frmts.h"#include "gdal.h"#include "gdal_priv.h"#include "cpl_string.h" #include <string>#include <iostream>#include <strstream>using namespace std;void convertToShp(double longitude, double latitude, char *outshp){ CPLSetConfigOption("SHAPE_ENCODING",""); OGRRegisterAll(); char *pszDriverName = "ESRI Shapefile"; OGRSFDriver *poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName); if (poDriver == NULL) { cout<<pszDriverName<<"驱动不可用!"<<endl; return; } OGRDataSource *poDs = poDriver->CreateDataSource(outshp, NULL); if (poDs == NULL) { cout<<"DataSource Creation Error"<<endl; return; } string outShapName = outshp; string layerName = outShapName.substr(0, outShapName.length()-4); OGRLayer *poLayer = poDs->CreateLayer(layerName.c_str(), NULL, wkbPoint, NULL); if (poLayer == NULL) { cout<<"Layer Creation Failed"<<endl; OGRDataSource::DestroyDataSource(poDs); return; } OGRFieldDefn oFieldId("ID", OFTInteger); oFieldId.SetWidth(5); poLayer->CreateField(&oFieldId); OGRFieldDefn oFieldX("X", OFTString); oFieldX.SetWidth(30); poLayer->CreateField(&oFieldX); OGRFieldDefn oFieldY("Y", OFTString); oFieldY.SetWidth(30); poLayer->CreateField(&oFieldY); OGRFeature *poFeature; poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn()); int i = 0; poFeature->SetField("ID", i); poFeature->SetField("X", longitude); poFeature->SetField("Y", latitude); i++; OGRPoint point; point.setX(longitude); point.setY(latitude); poFeature->SetGeometry(&point); if(poLayer->CreateFeature(poFeature) != OGRERR_NONE ) { printf( "Failed to create feature in shapefile.\n" ); exit( 1 ); } OGRFeature::DestroyFeature(poFeature); OGRDataSource::DestroyDataSource(poDs); }double* transfer(double longitude, double latitude){ OGRSpatialReference oSourceSRS; oSourceSRS.importFromEPSG(4326); OGRSpatialReference oTargetSRS; oTargetSRS.importFromEPSG(2029); OGRCoordinateTransformation *poTransform; poTransform = OGRCreateCoordinateTransformation(&oSourceSRS, &oTargetSRS); if (poTransform == NULL) { cout<<"poTransform is null"<<endl; exit(1); } if (!poTransform->Transform(1, &longitude, &latitude, NULL)) { cout<<"transform failed"<<endl; exit(1); } double *inout = new double[2]; inout[0] = longitude; inout[1] = latitude; return inout;}int main(int argc, char *argv[]){ char *xCoordinate = argv[1]; char *yCoordinate = argv[2]; char *outShp = argv[3]; double x = atof(xCoordinate); double y = atof(yCoordinate); convertToShp(x, y, outShp); cout<<"success! file is saved to "<<outShp<<endl; double *transferedLongLat = transfer(116.246742, 40.022211); cout<<"转换后的投影坐标为:"<<transferedLongLat[0]<<","<<transferedLongLat[1]<<endl; getchar();}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
程序运行结束后即在我们指定的目录下生成点状要素的shp文件。
关于坐标转换,可以参考:http://blog.csdn.net/jingss_3/article/details/8240328
本文介绍如何使用GDAL/OGR 库对shapefile文件进行简单的操作,包括读取、创建、修改等.在GDAL官网上有读写shp文件的介绍,主要是针对点要素的操作例子:点击打开链接
2.读取shp文件
- void ExtracInfo::ReadShapeFile()
- {
- OGRRegisterAll();
-
- OGRDataSource *poDS;
- poDS = OGRSFDriverRegistrar::Open("F:/test.shp", FALSE);
- if (poDS == NULL)
- {
-
-
- }
-
- OGRLayer *poLayer;
- poLayer = poDS->GetLayerByName("test");
- int layercount = poDS->GetLayerCount();
-
-
- OGRFeature *poFeature;
- poLayer->ResetReading();
- while((poFeature = poLayer->GetNextFeature()) != NULL)
- {
-
-
- OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
- int iField;
- int fieldcount = poFDefn->GetFieldCount();
-
- int fieldv1;
- double fieldv2;
- string feildv3;
- for (iField = 0; iField < poFDefn->GetFieldCount(); iField ++)
- {
- OGRFieldDefn * poFieldDefn = poFDefn->GetFieldDefn(iField);
- if (poFieldDefn->GetType() == OFTInteger)
- {
- fieldv1 = poFeature->GetFieldAsInteger(iField);
-
- }
- else if (poFieldDefn->GetType() == OFTReal)
- {
- fieldv2 = poFeature->GetFieldAsDouble(iField);
-
- }
- else if (poFieldDefn->GetType() == OFTString)
- {
- feildv3 = poFeature->GetFieldAsString(iField);
-
- }
-
-
- }
-
-
- OGRGeometry *poGeometry;
- poGeometry = poFeature->GetGeometryRef();
- double x, y;double area;
- if (poGeometry != NULL && wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon)
- {
- OGRPolygon *poPolygon = (OGRPolygon * )poGeometry;
- area = poPolygon->get_Area();
- OGRPoint point;
- OGRLinearRing *pOGRLinearRing = poPolygon->getExteriorRing();
- pOGRLinearRing->getPoint(0,&point);
- x = point.getX();
- y = point.getY();
-
- }
- else
-
-
-
- OGRFeature::DestroyFeature(poFeature);
- }
-
-
- OGRDataSource::DestroyDataSource(poDS);
-
-
- }
3.shp文件添加字段有时需要对已经存在的shp文件进行添加字段操作。代码如下:
- OGRDataSource *poDS;
- poDS = OGRSFDriverRegistrar::Open("F:/test.shp", TRUE);
- if (poDS == NULL)
- {
-
-
- }
- OGRLayer *poLayer;
- poLayer = poDS->GetLayerByName("test");
- int layercount = poDS->GetLayerCount();
-
- OGRFieldDefn poField("NewField", OFTReal);
-
- poField.SetPrecision(8);
- if (poLayer->CreateField(&poField) != OGRERR_NONE)
- {
-
-
- }
- OGRFeature *poFeature;
- poLayer->ResetReading();
-
- int featureNum = 0;
- while((poFeature = poLayer->GetNextFeature()) != NULL)
- {
- OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
- int fieldcount = poFDefn->GetFieldCount();
-
- poFeature->SetField(fieldcount - 1, featureNum);
-
- poLayer->SetFeature(poFeature);
- OGRFeature::DestroyFeature(poFeature);
- featureNum ++;
- }
- OGRDataSource::DestroyDataSource(poDS);
刚开始老是添加不成功,最后发现是open函数里第二个参数,如果默认设置为FALSE,则表示只读;需要把它设置为TRUE才可读写。4.创建shp文件
下面主要说说创建多边形shp文件。创建的方法:使用的WKT格式的字符串来进行创建。也可以使用其他的方式进行创建(参考大神博客:点击打开链接)。但是它是wkt方法的C#、Python代码,c++代码对应的函数没查到。所以用另一种方法创建如下:
- const char *pszDriverName = "ESRI Shapefile";
- OGRSFDriver *poDriver;
-
- OGRRegisterAll();
-
- poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
- if (poDriver == NULL)
- {
-
- }
-
- OGRDataSource *poDS;
- poDS = poDriver->CreateDataSource("F:/zjq/testProject/ogrtest/polygon.shp", NULL);
- if (poDS == NULL)
- {
-
-
- }
-
- OGRLayer *poLayer;
- poLayer = poDS->CreateLayer("polygon1", NULL, wkbPolygon, NULL);
- if (poLayer == NULL)
- {
-
-
- }
-
- OGRFieldDefn poFieldID("ID", OFTInteger);
- poLayer->CreateField(&poFieldID);
-
- OGRFieldDefn poFieldname("Name", OFTString);
- poFieldname.SetWidth(32);
- poLayer->CreateField(&poFieldname);
-
- double x = 0.0, y = 0.0;
- for (int i = 0; i < 10; i++)
- {
- string szname = "a_" + QString::number(i).toStdString();
- OGRFeature *poFeature;
- poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
- poFeature->SetField(0, i);
- poFeature->SetField(1, szname.c_str());
-
- OGRLinearRing ring;
-
- ring.addPoint(0 + 10 * i, 0 + 10 *i);
- ring.addPoint(0 +10 * i, 10 + 10 *i);
- ring.addPoint(10 + 10 *i, 10 + 10 *i);
- ring.addPoint(10 + 10 *i, 0 + 10*i);
-
- ring.closeRings();
-
- OGRPolygon polygon;
- polygon.addRing(&ring);
- poFeature->SetGeometry(&polygon);
-
- if ( poLayer->CreateFeature( poFeature) != OGRERR_NONE)
- {
-
-
- }
- OGRFeature::DestroyFeature(poFeature);
- }
-
- OGRDataSource::DestroyDataSource(poDS);
以上创建代码的结果如下图所示:(QGIS显示)