Changing Data source of map to hosted feature service doesn't change ItemID

2524
7
Jump to solution
03-04-2021 05:43 PM
ChrisSeabrooke1
New Contributor III

I've created an Add-In to ArcGIS Pro to facilitate importing and publishing a web map. I have a map package that I'm importing. I need to change the data source in the map to a hosted feature service in ArcGIS Online. In the Add-In code, I have this method:

private static void ResetFeatureServiceDataConnection(Layer dataConnectionLayer, string newConnectionString)

{

    CIMStandardDataConnection dataConnection = dataConnectionLayer.GetDataConnection() as CIMStandardDataConnection;

    dataConnection.WorkspaceConnectionString = newConnectionString;

    dataConnectionLayer.SetDataConnection(dataConnection);    

}

The parameters to this method are a map layer and the URL for the hosted feature service. This method changes the data source in the layer, but it doesn't change the ItemID.The ItemID is referencing the original data source (from the map package I imported). When I publish the map, the datasource is based on the ItemID, not the Url that I've set in the code.

I've tried changing the data source from the Layer Properties in ArcGIS Pro. When I click the Set Data Source button and select the layer in my hosted feature service, the URL changes, but not the ItemID. 

Is there a way to change the Item ID to match the ItemID of the hosted feature service?

 

0 Kudos
1 Solution

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

It turns out that the ItemID is stored in the layer's underlying Cartographic Information Model (CIM).  More specifically the ItemID value is stored in the SourceURI property of the CIMFeatureLayer class.  The  SourceURI property is only populated when the layer is first added to a map, but the property is not updated when the data connection is changed.  To update the SourceURI you can use the following pattern (from within QueuedTask.Run):

var dcLyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
QueuedTask.Run(() =>
{
  if (!(dcLyr.GetDataConnection() is CIMStandardDataConnection dc))
  {
    MessageBox.Show("Layer doesn't have CIMStandardDataConnection");
    return;
  }
  // make changes to the data connection
  dcLyr.SetDataConnection(dc);
  // update SourceURI
  var lyrDef = dcLyr.GetDefinition();
  lyrDef.SourceURI = string.Empty;
  dcLyr.SetDefinition(lyrDef);
});

 In the snippet above the SourceURI is cleared, but it can also be replaced with the ItemID matching the new data connection.

View solution in original post

0 Kudos
7 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I have a web map with two feature layers.   The first layer in my Map references the first feature layer of my web map.   Below is the code for a button's 'OnClick' method, that changes the data connection for this first layer from a feature service ID of '0' to '1' and vice versa.  Not sure if this is what you need:

 

protected override void OnClick()
{
  try
  {
    var dcLyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
    if (dcLyr == null)
    {
      MessageBox.Show("No Layer found");
      return;
    }
    QueuedTask.Run(() =>
    {
      CIMStandardDataConnection dc = dcLyr.GetDataConnection() as CIMStandardDataConnection;
      if (dc == null)
      {
        MessageBox.Show("Layer doesn't have CIMStandardDataConnection");
        return;
      }
      if (dc.Dataset == "0") 
        dc.Dataset = "1";
      else
        dc.Dataset = "0";
      dcLyr.SetDataConnection(dc);
    });
    }
    catch (Exception ex)
    {
      MessageBox.Show(ex.Message);
    }
}

 

 

0 Kudos
ChrisSeabrooke1
New Contributor III

Thanks for the reply but  I'm trying to change the ItemID for every layer in the map to the correct hosted feature service. I can change the URL, but I need to change the ItemID to the hosted feature service. The datasource is based on the ItemID, not the URL.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

To change the URL to the hosted feature service you have to change the Url, to change the ID you have to change the Dataset property as shown in the sample below.  When you say you have to change the 'ItemID' to the hosted feature service do you mean the ID?  As shown here:

Wolf_0-1615403733293.png

If so then, my sample applies to your question. in the sample I change this (note that the ID is shown under the Name line item):

After.png

To this:

Before.png

In this sample snippet the datasource for the layer is changed from FeatureSerive to MapService and vice versa, and in addition the ID is also changed from '0' to '2' and vice versa.

protected override void OnClick()
{
	try
	{
		var dcLyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
		if (dcLyr == null)
		{
			MessageBox.Show("No Layer found");
			return;
		}
		QueuedTask.Run(() =>
		{
			if (!(dcLyr.GetDataConnection() is CIMStandardDataConnection dc))
			{
				MessageBox.Show("Layer doesn't have CIMStandardDataConnection");
				return;
			}
			if (dc.WorkspaceConnectionString.Contains(@"/FeatureServer"))
				dc.WorkspaceConnectionString = dc.WorkspaceConnectionString.Replace(@"/FeatureServer", @"/MapServer");
			else
				dc.WorkspaceConnectionString = dc.WorkspaceConnectionString.Replace(@"/MapServer", @"/FeatureServer");
			if (dc.Dataset == "0")
				dc.Dataset = "2";
			else
				dc.Dataset = "0";
			dcLyr.SetDataConnection(dc);
		});
	}
	catch (Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
}

 

0 Kudos
ChrisSeabrooke1
New Contributor III

I am not trying to change the ID of the layer. I am trying to change the itemId -- which is the reference to the hosted feature service. I've changed the data source as you've indicated above, but that does not change the itemId. Using ArcGIS Online Assistant, I can see the ItemID is "330dbdc986f34ebd884b42171ff165ae". This is not the ID for the feature service 'SeabrookeFieldSeeker' as you can see from the second image.  This is causing the map layers to reference a hosted feature service that is not the one in the URL. 

ChrisSeabrooke1_0-1615404369463.png

ChrisSeabrooke1_1-1615404519954.png

 

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

My bad, I guess I overlooked the 'ArcGIS Online' part.  The actual 'Feature Service' is hosted on ArcGIS Server referenced the the "url" attribute of the "operationallayer" json from your previous reply.  I only looked at the ArcGIS Server datassource, not a Portal (ArcGIS Online) connection.  I will try a Portal datasource now and let you know what i find.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

It turns out that the ItemID is stored in the layer's underlying Cartographic Information Model (CIM).  More specifically the ItemID value is stored in the SourceURI property of the CIMFeatureLayer class.  The  SourceURI property is only populated when the layer is first added to a map, but the property is not updated when the data connection is changed.  To update the SourceURI you can use the following pattern (from within QueuedTask.Run):

var dcLyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
QueuedTask.Run(() =>
{
  if (!(dcLyr.GetDataConnection() is CIMStandardDataConnection dc))
  {
    MessageBox.Show("Layer doesn't have CIMStandardDataConnection");
    return;
  }
  // make changes to the data connection
  dcLyr.SetDataConnection(dc);
  // update SourceURI
  var lyrDef = dcLyr.GetDefinition();
  lyrDef.SourceURI = string.Empty;
  dcLyr.SetDefinition(lyrDef);
});

 In the snippet above the SourceURI is cleared, but it can also be replaced with the ItemID matching the new data connection.

0 Kudos
ChrisSeabrooke1
New Contributor III

Wolf, thank you. That was exactly what I needed. 

0 Kudos