开发者社区> 史迪奇2号> 正文

程序编辑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,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
树莓派:文本编辑器与文件
作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载。   GNU nano是Unix系统下一款常用的文本编辑器,以简单易用著称。与之相比,功能更强大的Vi和Emacs编辑器,学习曲线比nano陡峭很多。
1325 0
TFS分布式文件系统应用
TFS是淘宝开源的一套高性能文件存储系统,在阿里广泛应用,除了自建文件系统,在应用上云的大趋势下,还可以使用阿里云的对象存储OSS服务。
6792 0
《C++语言基础》实践项目——文本文件及应用
返回:贺老师课程教学链接 本周项目中用到的数据文件,请在这里下载:点击打开链接【项目1 - 小玩文件】(1)下面程序的功能是统计文本文件abc.txt中的字符个数,请填空将程序补充完整。 #include <iostream> #include <cstdlib> #include _____________ // (1) using namespace std; i
1365 0
【精通Linux系列】Linux中的系统文件概述与编辑器详解
【精通Linux系列】Linux中的系统文件概述与编辑器详解
36 0
vim下如何去掉windows编辑的文件中的^M
可以去掉^M, 例如: 在终端下敲命令: dos2unix a.c 直接转换成unix格式,这样就可以去掉^M    •$dos2unix filename •vim filename :%s/^M$//g ^M = Ctrl+v+m   著作权归作者所有。
885 0
纯前端JSON文件编辑器[0]
准备工作 参考资料: FileReader(用来获取上传文件的数据) (用来设置下载文件的名称) Blob(用来存储数据的一个容器) createObjectURL(用来将一个Blog对象转换为Base64格式资源的API) 前言:     因前段时间给老板做了个在线编辑lua文件的小工具,期间用到了上述几个新的API,感觉挺有意思,所以决定做一个在线编辑JSON文件的例子show出来,并重新捋一遍思路。
977 0
858
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载