KML,SHP TAB互轉(zhuǎn),GDAL
最近在接觸地圖數(shù)據(jù)轉(zhuǎn)換的東西,從硬件kml的數(shù)據(jù)轉(zhuǎn)換其他的格式,因?yàn)閺臎]做過著東西, 先去了解kml文件格式
http://baike.baidu.com/view/400307.htm?fr=aladdin
原來是谷歌地球的一種數(shù)據(jù)格式,先大致看了寫里面的標(biāo)簽,kml與xml文件差多,
kml數(shù)據(jù):

longitude:經(jīng)度 latitude:緯度 altitude:高度 其他的就自己去看了。
現(xiàn)在開始轉(zhuǎn)換,在谷歌上找到一個開源的項(xiàng)目 里面是對地圖數(shù)據(jù)的操作,GDAL
http://www.gdal.org/ogr/ogr_formats.html 參考這里。
kml->SHP
private string CreateShp(List<Placemark> list) { //注冊O(shè)gr庫 string pszDriverName = DriverType.Shapefile; OSGeo.OGR.Ogr.RegisterAll(); //為了支持中文路徑,請?zhí)砑酉旅孢@句代碼 OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // 為了支持shp屬性表字段支持中文,請?zhí)砑酉旅孢@句 OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", " "); //調(diào)用對Shape文件讀寫的Driver接口 OSGeo.OGR.Driver poDriver = OSGeo.OGR.Ogr.GetDriverByName(pszDriverName); if (poDriver == null) return "打開驅(qū)動失敗"; //用此Driver創(chuàng)建Shape文件 OSGeo.OGR.DataSource poDS; poDS = poDriver.CreateDataSource(CreateSavePath(), null); if (poDS == null) return "創(chuàng)建數(shù)據(jù)源失敗"; //創(chuàng)建層Layer OSGeo.OGR.Layer poLayer; poLayer = poDS.CreateLayer(CurrentDate, null, OSGeo.OGR.wkbGeometryType.wkbPoint, null); if (poLayer == null) return "創(chuàng)建地圖層失敗"; //創(chuàng)建屬性 OSGeo.OGR.FieldDefn oField = new OSGeo.OGR.FieldDefn("name", OSGeo.OGR.FieldType.OFTString); oField.SetWidth(16); 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, 1); poLayer.CreateField(oField2, 0); poLayer.CreateField(ofield3, 2); poLayer.CreateField(ofield4, 3); //創(chuàng)建一個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(0, item.Name); //屬性二"高度"賦值 poFeature.SetField(1, item.LookAt.altitude); poFeature.SetField(2, item.LookAt.latitude); poFeature.SetField(3, item.LookAt.longitude); //添加坐標(biāo)點(diǎn) x y z pt.AddPoint(item.LookAt.longitude, item.LookAt.latitude, item.LookAt.altitude); poFeature.SetGeometry(pt); //將帶有坐標(biāo)及屬性的Feature要素點(diǎn)寫入Layer中 poLayer.CreateFeature(poFeature); } //關(guān)閉文件讀寫 poFeature.Dispose(); poDS.Dispose(); return "轉(zhuǎn)換成功"; }
SHP->mapinfo tab轉(zhuǎn)換出現(xiàn)問題,當(dāng)我的經(jīng)緯度像上圖一樣小數(shù)位數(shù)比較多的情況,會自動截斷,仔細(xì)調(diào)試都沒找到解決辦法,截斷都是沒規(guī)則的,只能繼續(xù)谷歌了,╮(╯▽╰)╭。
代碼如下:
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 = 0; i < layerCount; i++) { Layer layer = sourceSource.GetLayerByIndex(i); int featureCount = layer.GetFeatureCount(0); Layer destLayer = null; //深度拷貝 //Layer destLayer = destSource.CopyLayer(layer, dest, null); #region MyRegion for (int j = 0; j < featureCount; j++) { Feature feature = layer.GetFeature(j); if (feature != null) { try { if (destLayer == null) { wkbGeometryType geoType = feature.GetGeometryRef().GetGeometryType(); //創(chuàng)建圖層 destLayer = destSource.CreateLayer( layer.GetName(), action(layer), geoType, new string[] { }); //創(chuàng)建字段 FeatureDefn featureDefn = layer.GetLayerDefn(); for (int k = 0; k < featureDefn.GetFieldCount(); k++) { destLayer.CreateField(featureDefn.GetFieldDefn(k), 0); } } //寫入要素 Feature cloneFeature = feature.Clone(); // Feature newfeature = ConvetToFeature(feature); destLayer.CreateFeature(cloneFeature); // OnFeatureConvert(featureCount, EventArgs.Empty); } catch (Exception ex) { msg = "轉(zhuǎn)換失敗"+ex.Message; continue; } } } #endregion //保存 destLayer.SyncToDisk(); } msg = "轉(zhuǎn)換成功"; sourceSource.Dispose(); destSource.Dispose(); shpDriver.Dispose(); return msg; }
原來是坐標(biāo)系的問題,
shp的默認(rèn)與tab的坐標(biāo)系不一樣。參考文章:http://blog.sina.com.cn/s/blog_6e51df7f0100ui7n.html
坐標(biāo)系轉(zhuǎn)換參考:http://wiki.woodpecker.org.cn/moin/lilin/ogr-create
終于解決。

浙公網(wǎng)安備 33010602011771號