3

I've been asked to write code that creates a .lyr file pointing to a non-existent shapefile. I expected to be able to do this utilizing IDataLayer2, however I get COMException FDO_E_TABLE_NOT_FOUND when I call dLayer.DataSourceName = (IName)fcn in the c# below.

Update: As suggested by Vince, here's the use case. We have an end-user with limited experience in ArcGIS who's offered to test an app we're developing. We'd like the user to verify our app works with their ArcSDE instance. At this point the app uses pre-configured lyr files that we haven't set up yet. So instead of trying to explain to the user how to set up the lyr files, I've been asked to provide the user lyr files, that point their ArcSDE instance. I'm working off-site, with no access to their network. I'm assuming that if I can't do this with a shapefile, then I can't do it with an ArcSDE featureclass either, so I've posted code that keeps it simple.

public static void Test()
{
    string folder = @"C:\projects\";

    string shpfile1 = Path.Combine(folder, "mypolygons.shp"); // exists
    string lyrfile1 = Path.Combine(folder, "testsave1.lyr");

    string shpfile2 = Path.Combine(folder, "junk.shp"); // doesn't exist
    string lyrfile2 = Path.Combine(folder, "testsave2.lyr");
    TestSaveLyr(shpfile1, lyrfile1); // works
    TestSaveLyr(shpfile2, lyrfile2); // fails
}

public static void TestSaveLyr(string shpFilepath, string lyrFilepath)
{
    // make a simple featurelayer for a shp file and save it
    FileInfo fi = new FileInfo(shpFilepath);
    var wsn = new WorkspaceNameClass() as IWorkspaceName;
    wsn.PathName = fi.DirectoryName;
    wsn.WorkspaceFactoryProgID = "esriDataSourcesFile.ShapefileWorkspaceFactory";

    var fcn = new FeatureClassNameClass() as IDatasetName2;
    fcn.WorkspaceName = wsn;
    fcn.Name = fi.Name.ToLower().Replace(".shp", "");

    if (File.Exists(shpFilepath))
        Debug.Print("exists: " + fi.Name);

    var dLayer = new FeatureLayerClass() as IDataLayer2;
    ((IFeatureLayer)dLayer).DataSourceType = "Shapefile Feature Class";
    dLayer.DataSourceName = (IName)fcn; // COMException here FDO_E_TABLE_NOT_FOUND -2147220655
    ((ILayer)dLayer).Name = fcn.Name;
    Util.Save((ILayer)dLayer, lyrFilepath, true);
}
2
  • 1
    You want to make a layer file point to a non- existant source? Of what possible use would that be? What business case? I certainly wouldn't permit that if I were coding the layer object. Step one is to validate the parameters. Sisyphus had it easy compared to your task.
    – Vince
    Commented Jan 21, 2017 at 6:12
  • @Vince It looks like such an approach might work with ArcGIS pro by editing the lyrx, but unfortunately lyr layers are not easily edited. Please see updated question, Thanks! Commented Jan 30, 2017 at 20:47

1 Answer 1

1

I think you have to use a template to give ArcMap the geometry type, this belongs to the minimum input for creating a lyr-file. After creating you can delete it. For shape it is so:

if (File.Exists(shpFilepath))
  System.Diagnostics.Debug.Print("exists: " + fi.Name);
else
{
  IFields fields = new FieldsClass();
  IFieldsEdit fieldsEdit = (IFieldsEdit)fields;
  fieldsEdit.FieldCount_2 = 2;

  IField oidField = new FieldClass();
  IFieldEdit oidFieldEdit = (IFieldEdit)oidField;
  oidFieldEdit.Name_2 = "ObjectID";
  oidFieldEdit.AliasName_2 = "FID";
  oidFieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;

  fieldsEdit.set_Field(0, oidField);

  IField shpField = new FieldClass();
  IFieldEdit shpFieldEdit = (IFieldEdit)shpField;
  shpFieldEdit.Name_2 = "Shape";
  shpFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;

  IGeometryDef geomDef = null;
  IGeometryDefEdit geomDefEdit = null;
  geomDef = new GeometryDefClass();
  geomDefEdit = (IGeometryDefEdit)geomDef;
  geomDefEdit.GeometryType_2 = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint; // or Line or Polygon


  shpFieldEdit.GeometryDef_2 = geomDef;
  fieldsEdit.set_Field(1, shpField);

  UID theCLSID = new UIDClass();
  UID theEXTCLSID = new UIDClass();

  IWorkspace ws = fcn.WorkspaceName.WorkspaceFactory.OpenFromFile(wsn.PathName, 0);
  ITable table = ((IFeatureWorkspace)ws).CreateTable(fcn.Name, fields, theCLSID, theEXTCLSID, "");
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.