程序编辑SHP文件并应用更改到数据源

简介:


在上一篇Blog中峻祁连介绍了在Map 3D中通过程序删除图层及数据源的方法,并且卖了个关子,这个方法还有另外一个妙用,今天就简单介绍一下。对数据源的编辑估计是Map 3D开发中最常见的功能了,包括对添加、删除和修改要素。这里以删除要素为例介绍。下面的代码实现了使用Map 3D API来删除地图上选中的要素。

 

    [CommandMethod("DeleteSelectedFeatures", CommandFlags.UsePickSet
          | CommandFlags.Modal | CommandFlags.Redraw)]
    public void DeleteSelectedFeatures()
    {
      Editor ed = Autodesk.AutoCAD.ApplicationServices
          .Application.DocumentManager.MdiActiveDocument.Editor;
      MgFeatureService _featureService = AcMapServiceFactory
        .GetService(MgServiceType.FeatureService) as MgFeatureService;
      PromptSelectionResult res = ed.SelectImplied();

      if (PromptStatus.OK == res.Status)
      {
        // Convert the SelectionSet to MgSelectionBase 
        // using AcMapFeatureEntityService. 

        Debug.Assert(res.Value != null);
        ObjectId entityID = res.Value[0].ObjectId;
        int entitytype = AcMapFeatureEntityService.GetEntityType(entityID);
        if (entitytype == EntityType.BulkEntity)
        {
          MgSelectionBase curSelection = AcMapFeatureEntityService
                                    .GetSelection(res.Value);

          foreach (MgLayerBase layer in curSelection.GetLayers())
          {
            string filter = curSelection
                  .GenerateFilter(layer, layer.FeatureClassName);

            if (filter != "")
            {
              MgFeatureCommandCollection featCommands =
                new MgFeatureCommandCollection();

              string strclassName = layer.FeatureClassName;
              MgDeleteFeatures delFeat =
                new MgDeleteFeatures(strclassName, filter);
              featCommands.Add(delFeat);
              try
              {
                AcMapLayer aclayer = layer as AcMapLayer;
                MgPropertyCollection pProps = aclayer
                  .UpdateFeatures(featCommands);

                // save and update the layer, commit the changes,
// 注意这里,必须要通过下面的代码来checkin来应用对数据源的更改
MgFeatureQueryOptions opt = new MgFeatureQueryOptions(); // build the filter string, this is required for // data source such as Sql Server/Oracle... String commitFilter = ""; if (aclayer.IsCached() && EditMode.EditSet == aclayer.EditMode) { commitFilter = ClassSystemProperties.FeatureStatus + " = " + ClassSystemProperties.FeatureStatusDeleted; } opt.SetFilter(commitFilter); //This is a must aclayer.SaveFeatureChanges(opt); aclayer.ForceRefresh(); } catch (Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage(ex.Message); } } } //remove the highlight AcMapFeatureEntityService.UnhighlightFeatures(curSelection); } } }

 

下面是执行时的截图,首先用鼠标选中一些要素,然后执行自定义命令DeleteSelectedFeatures

image

执行结束后,选用的要素被成功删除。

image

 

这个例子中我使用的FDO Provider for SHP连接到SHP文件。下面是上面自定义命令执行之前,注意一下shp相关文件的日期。

image

下面是DeleteSelectedFeatures执行完毕后,注意到Shp文件的相关变化,其中*.dbf文件是日期发在了变化,但*.shp文件并没有变化。即上面的代码并没有对*.shp进行更改。

image

也许有人会说,这是个Map 3D的bug,他们的证据就是这时在ArcGIS中打开shp文件,发现刚才在Map 3D中删除的要素还是ArcGIS中显示,好像并没有被删除。其实不然。根据DBF规范,DBF保存属性信息和删除标志,SHP文件也采用了这个DBF规范。shp文件中被删除的geometry只在DBF中做删除标记。Map 3D的确对DBF文件做了更改,即按照规范添加了删除标志。但不知道为什么ArcGIS并没有遵守DBF规范,而忽略了该删除标志,所以在ArcGIS查看时中你会认为该要素没有删除。下面是DBF规范相关点的摘录:

http://www.dbf2002.com/dbf-file-format.html

Note   The data in dbf file starts at the position indicated in bytes 8 to 9 of the header record. Data records begin with a delete flag byte. If this byte is an ASCII space (0x20), the record is not deleted. If the first byte is an asterisk (0x2A), the record is deleted. The data from the fields named in the field subrecords follows the delete flag.

 

  尽管不是Map 3D的错,但ArcGIS作为业内占统治地位的GIS软件,我们也得迁就一下,有什么办法在Map 3D中更改的结果也能让ArcGIS显示出来呢? 答案就是不但要按照DBF规范添加删除标记,同时还要压缩shp文件。目前在Map 3D中还没有这样的API来压缩shp文件来反应要素变化,不过可以用下面的workaround,就是关闭到shp文件的连接(必要时再按照BuildMap中的例子再创建连接)。当FDO连接关闭时,Map 3D会压缩shp文件,从而让ArcGIS也能检验到变化。压缩shp文件这个过程比较耗时,这也是Map 3D只是在关闭连接时才做这一步的原因。如果你要求你在Map 3D中的更改能更快的体现在ArcGIS中,就需要手动来关闭连接让Map 3D强制压缩shp。

关闭连接的代码我们已经上一篇博客Map 3D中通过程序删除图层及数据源中介绍过了。这里还是把代码贴一下:

    [CommandMethod("CloseConnection")]
    public void CloseConnectionForLayer()
    {
      RemoveLayer("Layer1");
    }

    public void RemoveLayer(string layerName)
    {
      Document doc = Application.DocumentManager.MdiActiveDocument;
      Editor ed = doc.Editor;
      Database db = doc.Database;

      AcMapMap map = AcMapMap.GetCurrentMap();

      // remove the layer
      var layers = map.GetLayers();
      if (!layers.Contains(layerName))
      {
        ed.WriteMessage("\nLayer does not exist: " + layerName);
        return;
      }

      MgLayerBase layer = layers.GetItem(layerName);
      layers.Remove(layer);

      // remove the layer resource
      MgResourceIdentifier identifier = layer.LayerDefinition;
      MgResourceService resourceService
        = AcMapServiceFactory.GetService(MgServiceType.ResourceService)
        as MgResourceService;

      if (resourceService.ResourceExists(identifier))
        resourceService.DeleteResource(identifier);

      // remove the feature source
      identifier = new MgResourceIdentifier(layer.FeatureSourceId);
      if (resourceService.ResourceExists(identifier))
        resourceService.DeleteResource(identifier);


    }
 

上面的代码会从地图中删除图层,并且关闭下图中的DataConnection。

image

执行完毕,你会发现shp文件的日期已经反正了变化,这是在arcGIS中查看就可以看到修改后的效果了。

image

 

好了,希望对你有帮助。

 

还有更详细的信息请同时看看这个http://adndevblog.typepad.com/infrastructure/2012/08/remove-the-discrepancy-between-arcviewarcgis-and-map-3d-when-deleting-features.html

作者: 峻祁连
邮箱:junqilian@163.com 
出处: http://junqilian.cnblogs.com 
转载请保留此信息。

本文转自峻祁连. Moving to Cloud/Mobile博客园博客,原文链接:http://www.cnblogs.com/junqilian/archive/2012/08/06/2625172.html ,如需转载请自行联系原作者
相关文章
|
7月前
动态将用户指定的内表的内容通过 Excel 导出
动态将用户指定的内表的内容通过 Excel 导出
38 0
|
5月前
|
安全
复制粘贴Excel文件后,显示“安全警告 宏已被禁用”,复制后得到的文件看不到内容
问题 系统:Win10 Excel版本:2016 我将一个原本正常的Excel文件复制到另一个文件夹后,打开就提示安全警告 宏已被禁用(复制操作时电脑莫名会变卡),而且原来文件里的数据也看不到了。 复制前的原文件:
32 0
|
8月前
|
区块链
如何修改 pdf 文件默认的显示图标
如何修改 pdf 文件默认的显示图标
167 0
|
8月前
|
XML 存储 数据格式
基于大量文件的名称特征自动新建多个文件夹并自动复制对应文件:Python
本文介绍基于Python,对一个文件夹下大量栅格影像,基于其各自文件名,分别创建指定名称的新文件夹,并将对应影像文件复制到不同的新文件夹下的方法。
112 3
基于大量文件的名称特征自动新建多个文件夹并自动复制对应文件:Python
|
图形学
PDF文件打开后显示的名称不正确该怎么办?
本文介绍打开PDF文件时,PDF阅读器所显示的文件名称与文件实际名称不一致的解决办法~
378 1
PDF文件打开后显示的名称不正确该怎么办?
|
10月前
|
Windows
ArcGIS:如何连接文件夹、修改元数据样式、建立个人地理数据库、复制移动文件?
ArcGIS:如何连接文件夹、修改元数据样式、建立个人地理数据库、复制移动文件?
284 0