KML,SHP TAB互轉,GDAL


  最近在接觸地圖數據轉換的東西,從硬件kml的數據轉換其他的格式,因為從沒做過着東西, 先去了解kml文件格式

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

   原來是谷歌地球的一種數據格式,先大致看了寫里面的標簽,kml與xml文件差多,

     kml數據:

        

        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(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);

            //創建一個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);

                //添加坐標點 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 "轉換成功";
        }
View Code

  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 = 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();
                               //創建圖層
                               destLayer = destSource.CreateLayer(
                                   layer.GetName(),
                                   action(layer),
                                   geoType,
                                   new string[] { });
                               //創建字段
                               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 = "轉換失敗"+ex.Message;
                           continue;
                       }
                   }
               }
               #endregion

               //保存
               destLayer.SyncToDisk();
           }

           msg = "轉換成功";
           sourceSource.Dispose();
           destSource.Dispose();
           shpDriver.Dispose();
           return msg;
       }
View Code

    原來是坐標系的問題,

   shp的默認與tab的坐標系不一樣。參考文章:http://blog.sina.com.cn/s/blog_6e51df7f0100ui7n.html

   坐標系轉換參考:http://wiki.woodpecker.org.cn/moin/lilin/ogr-create

 終於解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM