In the previous Blog, junqilian introduced the method of deleting layers and data sources through programs in Map 3D, and sold a token. This method also has another clever use. I will briefly introduce it today. Editing data sources is estimated to be the most common feature in Map 3D development, including adding, deleting, and modifying elements. Here we will take the deletion element as an example. The following code deletes the elements selected on a Map using the 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,
// Note that the following code must be used to checkin the changes to the data source 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 );}}}
The following is the execution time. First, select some elements with the mouse, and then execute the custom command DeleteSelectedFeatures.
After the execution, the selected elements are deleted successfully.
In this example, I use FDO Provider for SHP to connect to the SHP file. The following figure shows the date of shp-related files before executing the preceding custom command.
The following figure shows the changes in the Shp file after DeleteSelectedFeatures is executed. The *. dbf file contains a change in date, but the *. shp file does not. That is, the above Code does not change *. shp.
Some people may say that this is a Map 3D bug. Their evidence is that the shp file is opened in ArcGIS and the elements deleted in Map 3D are displayed in ArcGIS, it seems that it has not been deleted. Actually not. According to the DBF specification, DBF saves the attribute information and deletes the flag. The SHP file also adopts this DBF specification. The deleted geometry in the shp file only marks the deletion in DBF. Map 3D indeed changed the DBF file, that is, added the delete flag according to the specification. However, you do not know why ArcGIS does not comply with the DBF specification and ignore the deletion mark. Therefore, when you view ArcGIS, you will think that this element has not been deleted. The following is an excerpt from the DBF specifications:
Http://www.dbf2002.com/dbf-file-format.html
NoteThe 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.
Although it is not the fault of Map 3D, as the dominant GIS software in the industry, we also have to accommodate ArcGIS, is there any way for ArcGIS to display the changed results in Map 3D? The answer is not only to add the delete mark according to the DBF specification, but also to compress the shp file. Currently, there is no such API in Map 3D to compress the shp file to reflect element changes, but the following workaround can be used, close the connection to the shp file (if necessary, create a connection based on the example in BuildMap ). When the FDO connection is closed, Map 3D compresses the shp file so that ArcGIS can detect the changes. The process of compressing the shp file is time-consuming. This is why Map 3D only performs this step when closing the connection. If you want your changes in Map 3D to be reflected in ArcGIS more quickly, you need to manually close the connection so that Map 3D can forcibly compress shp.
The code for closing the connection has been introduced in Map 3D in the previous blog to delete layers and data sources through programs. Paste the code here:
[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); }
The above code deletes the layer from the map and closes the DataConnection.
After the execution is complete, you will find that the shp file date has changed anyway. You can view the modified date in arcGIS.
Well, I hope it will help you.
Please take a look at this http://adndevblog.typepad.com/infrastructure/2012/08/remove-the-discrepancy-between-arcviewarcgis-and-map-3d-when-deleting-features.html For more details