Find all layers of a type recursively in ArcMap

This code snippit will allow you to return all layers of a type you specify from an mxd.  Very handy code:

public List<ILayer> LoopThroughLayersOfSpecificUID(IMap map, String layerCLSID, bool searchRecursive)
{
/// The different layer GUID's and Interface's are:
/// "{AD88322D-533D-4E36-A5C9-1B109AF7A346}" = IACFeatureLayer
/// "{74E45211-DFE6-11D3-9FF7-00C04F6BC6A5}" = IACLayer
/// "{495C0E2C-D51D-4ED4-9FC1-FA04AB93568D}" = IACImageLayer
/// "{65BD02AC-1CAD-462A-A524-3F17E9D85432}" = IACAcetateLayer
/// "{4AEDC069-B599-424B-A374-49602ABAD308}" = IAnnotationLayer
/// "{DBCA59AC-6771-4408-8F48-C7D53389440C}" = IAnnotationSublayer
/// "{E299ADBC-A5C3-11D2-9B10-00C04FA33299}" = ICadLayer
/// "{7F1AB670-5CA9-44D1-B42D-12AA868FC757}" = ICadastralFabricLayer
/// "{BA119BC4-939A-11D2-A2F4-080009B6F22B}" = ICompositeLayer
/// "{9646BB82-9512-11D2-A2F6-080009B6F22B}" = ICompositeGraphicsLayer
/// "{0C22A4C7-DAFD-11D2-9F46-00C04F6BC78E}" = ICoverageAnnotationLayer
/// "{6CA416B1-E160-11D2-9F4E-00C04F6BC78E}" = IDataLayer
/// "{0737082E-958E-11D4-80ED-00C04F601565}" = IDimensionLayer
/// "{48E56B3F-EC3A-11D2-9F5C-00C04F6BC6A5}" = IFDOGraphicsLayer
/// "{40A9E885-5533-11D0-98BE-00805F7CED21}" = IFeatureLayer
/// "{605BC37A-15E9-40A0-90FB-DE4CC376838C}" = IGdbRasterCatalogLayer
/// "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}" = IGeoFeatureLayer
/// "{34B2EF81-F4AC-11D1-A245-080009B6F22B}" = IGraphicsLayer
/// "{EDAD6644-1810-11D1-86AE-0000F8751720}" = IGroupLayer
/// "{D090AA89-C2F1-11D3-9FEF-00C04F6BC6A5}" = IIMSSubLayer
/// "{DC8505FF-D521-11D3-9FF4-00C04F6BC6A5}" = IIMAMapLayer
/// "{34C20002-4D3C-11D0-92D8-00805F7C28B0}" = ILayer
/// "{E9B56157-7EB7-4DB3-9958-AFBF3B5E1470}" = IMapServerLayer
/// "{B059B902-5C7A-4287-982E-EF0BC77C6AAB}" = IMapServerSublayer
/// "{82870538-E09E-42C0-9228-CBCB244B91BA}" = INetworkLayer
/// "{D02371C7-35F7-11D2-B1F2-00C04F8EDEFF}" = IRasterLayer
/// "{AF9930F0-F61E-11D3-8D6C-00C04F5B87B2}" = IRasterCatalogLayer
/// "{FCEFF094-8E6A-4972-9BB4-429C71B07289}" = ITemporaryLayer
/// "{5A0F220D-614F-4C72-AFF2-7EA0BE2C8513}" = ITerrainLayer
/// "{FE308F36-BDCA-11D1-A523-0000F8774F0F}" = ITinLayer
/// "{FB6337E3-610A-4BC2-9142-760D954C22EB}" = ITopologyLayer
/// "{005F592A-327B-44A4-AEEB-409D2F866F47}" = IWMSLayer
/// "{D43D9A73-FF6C-4A19-B36A-D7ECBE61962A}" = IWMSGroupLayer
/// "{8C19B114-1168-41A3-9E14-FC30CA5A4E9D}" = IWMSMapLayer

List<ILayer> layers = new List<ILayer>();

if (map == null || layerCLSID == null)
{
return layers;
}

ESRI.ArcGIS.esriSystem.IUID uid = new ESRI.ArcGIS.esriSystem.UIDClass();
uid.Value = layerCLSID; // Example: "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}" = IGeoFeatureLayer
try
{
IEnumLayer enumLayer = map.get_Layers(((ESRI.ArcGIS.esriSystem.UID)(uid)), searchRecursive); // Explicit Cast
enumLayer.Reset();
ILayer layer = enumLayer.Next();

while (!(layer == null))
{
layers.Add(layer);
layer = enumLayer.Next();
}
}
catch (System.Exception ex)
{
MessageBox.Show("No layers of type: " + uid.Value.ToString() + " " + ex.Message);
}
return layers;
}

 

Find all layers of a type recursively in ArcMap

Deleting corrupt rasters from ArcSDE

Sometimes data gets corrupted when trying to load data into ArcSDE.  This can be problematic as standard and recommended processes to remove data from ArcSDE cannot be used (i.e. ArcCatalog).

Manual deletion must be undertaken by going to the database directly and deleting all record of the data in the SDE system tables and the actual business table itself.  Yes, this is scary!, but if you do some defensive SQL to create “backups” of the data you are about to delete then you should be OK.  Also check that you have made a backup of your database too for “belt and braces”.

Featured image

In SDE Schema:

SELECT rastercolumn_id FROM raster_columns WHERE table_name = <table name>
SELECT layer_id FROM layers WHERE table_name = <table name>

The results from above will be used in the schema where the faulty raster is stored so make a note of the rastercolumn_id and the layer_id  !!


CREATE TABLE table_registry_bak AS SELECT * FROM table_registry WHERE table_name = <table name>;
DELETE FROM table_registry WHERE table_name = <table name>;

CREATE TABLE layers_bak AS SELECT * FROM layers WHERE table_name = <table name>;
DELETE FROM layers WHERE table_name = <table name>;

CREATE TABLE raster_columns_bak AS SELECT * FROM raster_columns WHERE table_name = <table name>;
DELETE FROM raster_columns WHERE table_name = <table name>;

CREATE TABLE gdb_objectclasses_bak AS SELECT * FROM gdb_objectclasses WHERE NAME = <table name>;
DELETE FROM gdb_objectclasses WHERE NAME = <table name>;

CREATE TABLE geometry_columns_bak AS SELECT * FROM geometry_columns WHERE f_table_name = <table name>;
DELETE FROM geometry_columns WHERE f_table_name = <table name>;

CREATE TABLE column_registry_bak AS SELECT * FROM column_registry WHERE table_name = <table name>;
DELETE FROM column_registry WHERE table_name = <table name>;

In the faulty data schema:

CREATE TABLE DEM_20M_0042_LUTE_ON_SP_HS_bak AS SELECT * FROM <table name>;
DROP TABLE <table name>;

CREATE TABLE sde_aux_<rastercolumn_id>_bak AS SELECT * FROM sde_aux_<rastercolumn_id>;
DROP TABLE sde_aux_<rastercolumn_id>;

CREATE TABLE sde_bnd_<rastercolumn_id>_bak AS SELECT * FROM sde_bnd_<rastercolumn_id>;
DROP TABLE sde_bnd_<rastercolumn_id>;

CREATE TABLE sde_blk_<rastercolumn_id>_bak AS SELECT * FROM sde_blk_<rastercolumn_id>;
DROP TABLE sde_blk_<rastercolumn_id>;

CREATE TABLE sde_ras_<rastercolumn_id>_bak AS SELECT * FROM sde_ras_<rastercolumn_id>;
DROP TABLE sde_ras_<rastercolumn_id>;

CREATE TABLE f4707_bak AS SELECT * FROM f<layer_id> ;
DROP TABLE f<layer_id>;

CREATE TABLE s<layer_id>_bak AS SELECT * FROM s<layer_id>;
DROP TABLE s<layer_id>;

Once you have run these sql commands, check everything is ok in ArcCatalog, then delete all tables with “_bak” to clean everything up.

Deleting corrupt rasters from ArcSDE

Simple Interface Example in C#

The following shows a simple example of how Interfaces can be very useful in C#.  Here SomeOtherClass doesn’t care what’s passed in as long as it conforms to ILog, then it will be able to call the Log function – this is truly polymorphic guys!

 

public interface ILog
{
 void Log(string text);
}
public class FileLog : ILog
{
 public void Log(string text)
 {
  // write text to a file
 }
}
public class DatabaseLog : ILog
{
 public void Log(string text)
 {
  // write text to the database
 }
}
public class SomeOtherClass
{
 private ILog _logger;
 public SomeOtherClass(ILog logger)
 {
  // I don't know if logger is the FileLog or DatabaseLog
  // but I don't need to know either as long as its implementing ILog
  this._logger = logger;
  logger.Log("Hello World!");
  }
}
Simple Interface Example in C#