zoukankan      html  css  js  c++  java
  • 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

     终于解决。

  • 相关阅读:
    latex
    slab着色,可以减少cache conflict miss概率么?
    内存管理 初始化(八) 至kswapd_init
    内存管理 初始化(七)kmem_cache_init_late 初始化slab分配器(下)
    vmwareubuntu18.04网络配置
    高德地图的一些使用心得
    mongodb聚合管道用法
    python学习链接
    python开发者常犯的10个错误(转)
    vim配置python开发环境(转)
  • 原文地址:https://www.cnblogs.com/chenxiao/p/GDAL.html
Copyright © 2011-2022 走看看