KML,SHP TAB互转,GDAL

时间:2021-11-13 08:25:13

最近在接触地图数据转换的东西,从硬件kml的数据转换其他的格式,因为从没做过着东西, 先去了解kml文件格式

http://baike.baidu.com/view/400307.htm?fr=aladdin

原来是谷歌地球的一种数据格式,先大致看了写里面的标签,kml与xml文件差多,

kml数据:

KML,SHP TAB互转,GDAL

longitude:经度  latitude:纬度   altitude:高度 其他的就自己去看了。

现在开始转换,在谷歌上找到一个开源的项目 里面是对地图数据的操作,GDAL

http://www.gdal.org/ogr/ogr_formats.html 参考这里。

kml->SHP

 private string CreateShp(List<Placemark> list)
{ //注册Ogr库
string pszDriverName = DriverType.Shapefile;
OSGeo.OGR.Ogr.RegisterAll(); //为了支持中文路径,请添加下面这句代码
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
// 为了支持shp属性表字段支持中文,请添加下面这句
OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", " "); //调用对Shape文件读写的Driver接口
OSGeo.OGR.Driver poDriver = OSGeo.OGR.Ogr.GetDriverByName(pszDriverName);
if (poDriver == null)
return "打开驱动失败"; //用此Driver创建Shape文件
OSGeo.OGR.DataSource poDS;
poDS = poDriver.CreateDataSource(CreateSavePath(), null);
if (poDS == null)
return "创建数据源失败"; //创建层Layer
OSGeo.OGR.Layer poLayer;
poLayer = poDS.CreateLayer(CurrentDate, null, OSGeo.OGR.wkbGeometryType.wkbPoint, null);
if (poLayer == null)
return "创建地图层失败"; //创建属性
OSGeo.OGR.FieldDefn oField = new OSGeo.OGR.FieldDefn("name", OSGeo.OGR.FieldType.OFTString);
oField.SetWidth();
OSGeo.OGR.FieldDefn oField2 = new OSGeo.OGR.FieldDefn("height", OSGeo.OGR.FieldType.OFTInteger); OSGeo.OGR.FieldDefn ofield3 = new FieldDefn("lat", FieldType.OFTInteger);
OSGeo.OGR.FieldDefn ofield4 = new FieldDefn("lng", FieldType.OFTInteger); poLayer.CreateField(oField, );
poLayer.CreateField(oField2, );
poLayer.CreateField(ofield3, );
poLayer.CreateField(ofield4, ); //创建一个Feature,一个Point
OSGeo.OGR.Feature poFeature = new Feature(poLayer.GetLayerDefn());
OSGeo.OGR.Geometry pt = new Geometry(OSGeo.OGR.wkbGeometryType.wkbPoint); foreach (Placemark item in list)
{
//属性一"名称"赋值
poFeature.SetField(, item.Name);
//属性二"高度"赋值
poFeature.SetField(, item.LookAt.altitude);
poFeature.SetField(, item.LookAt.latitude);
poFeature.SetField(, item.LookAt.longitude); //添加坐标点 x y z
pt.AddPoint(item.LookAt.longitude, item.LookAt.latitude, item.LookAt.altitude); poFeature.SetGeometry(pt);
//将带有坐标及属性的Feature要素点写入Layer中
poLayer.CreateFeature(poFeature); } //关闭文件读写
poFeature.Dispose();
poDS.Dispose(); return "转换成功";
}

SHP->mapinfo tab转换出现问题,当我的经纬度像上图一样小数位数比较多的情况,会自动截断,仔细调试都没找到解决办法,截断都是没规则的,只能继续谷歌了,╮(╯▽╰)╭。

代码如下:

 public string Convert(string driverTypeName, OnAction action)
{
string msg = string.Empty;
DataSource sourceSource;
OSGeo.OGR.Driver shpDriver;
RegisterAll(driverTypeName, out sourceSource, out shpDriver);
DataSource destSource = shpDriver.CreateDataSource(Dest, new string[] {
"AUX=YES",
"STATISTICS=YES"}); //中文
int layerCount = sourceSource.GetLayerCount();
for (int i = ; i < layerCount; i++)
{
Layer layer = sourceSource.GetLayerByIndex(i);
int featureCount = layer.GetFeatureCount();
Layer destLayer = null; //深度拷贝
//Layer destLayer = destSource.CopyLayer(layer, dest, null); #region MyRegion
for (int j = ; j < featureCount; j++)
{
Feature feature = layer.GetFeature(j); if (feature != null)
{
try
{ if (destLayer == null)
{
wkbGeometryType geoType = feature.GetGeometryRef().GetGeometryType();
//创建图层
destLayer = destSource.CreateLayer(
layer.GetName(),
action(layer),
geoType,
new string[] { });
//创建字段
FeatureDefn featureDefn = layer.GetLayerDefn();
for (int k = ; k < featureDefn.GetFieldCount(); k++)
{
destLayer.CreateField(featureDefn.GetFieldDefn(k), );
}
}
//写入要素 Feature cloneFeature = feature.Clone(); // Feature newfeature = ConvetToFeature(feature); destLayer.CreateFeature(cloneFeature); // OnFeatureConvert(featureCount, EventArgs.Empty);
}
catch (Exception ex)
{
msg = "转换失败"+ex.Message;
continue;
}
}
}
#endregion //保存
destLayer.SyncToDisk();
} msg = "转换成功";
sourceSource.Dispose();
destSource.Dispose();
shpDriver.Dispose();
return msg;
}

原来是坐标系的问题,

shp的默认与tab的坐标系不一样。参考文章:http://blog.sina.com.cn/s/blog_6e51df7f0100ui7n.html

坐标系转换参考:http://wiki.woodpecker.org.cn/moin/lilin/ogr-create

终于解决。