POST
|
Hi,
So I've dug a bit deeper over the last day and know a bit more about what is going on. And why the EditOperation.Create is not working correctly for dimension features. As the documentation states, a dimension feature consists of 4 points (the begin, end points, the dimension line point and the text point). These points are stored as x,y fields in the feature class. The polygon shape of the dimension is the bounding rectangle of these points and it should be calculated when the feature is created or modified. In the case of the creation; we supply the points as a mutlipoint geometry, however the calculation to generate the bounding polygon from this point information and the other attributes is not being performed and the shape value of the created feature is null (which is why it is not displayed). As you've seen if you make any modifications to the point coordinate attributes or other attributes, the dimension becomes visible - because it's polygon shape has been generated.
So basically we need to look into a way to force this shape generation to occur on a creation as the software is not working as it should.
Having said all of that, lets deal with the original question you had first - how to move a dimension feature.
Assuming we're dealing with a well-defined dimension feature (ie one that is displaying correctly); you should be able to use EditOperation.Move function. For example
// assuming on the MCT
// get a dim layer
DimensionLayer dimLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<DimensionLayer>().FirstOrDefault();
var selection = dimLayer.GetSelection();
var oids = selection.GetObjectIDs();
var oid = oids.FirstOrDefault();
var op = new EditOperation();
op.Name = "Move dimension";
op.Move(dimLayer, oid, 10, 0); // move it in the x direction only
var success = op.Execute();
Alternatively you can modify the BeginX, BeginY, EndX, EndY, DimX, DimY and TextX and TextY fields individually if you'd rather using the EditOperation.Modify method and an Inspector class. Here's an example snippet of this
// assuming on the MCT
// get a dim layer
DimensionLayer dimLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<DimensionLayer>().FirstOrDefault();
var selection = dimLayer.GetSelection();
var oids = selection.GetObjectIDs();
var oid = oids.FirstOrDefault();
var insp = new ArcGIS.Desktop.Editing.Attributes.Inspector();
insp.Load(dimLayer, oid);
// get all the coordinates
Double.TryParse(insp["BeginX"].ToString(), out double BeginX);
Double.TryParse(insp["BeginY"].ToString(), out double BeginY);
Double.TryParse(insp["EndX"].ToString(), out double EndX);
Double.TryParse(insp["EndY"].ToString(), out double EndY);
Double.TryParse(insp["DimX"].ToString(), out double DimX);
Double.TryParse(insp["DimY"].ToString(), out double DimY);
Double.TryParse(insp["TextX"].ToString(), out double TextX);
Double.TryParse(insp["TextY"].ToString(), out double TextY);
// modify the x positions
BeginX += 10;
EndX += 10;
DimX += 10;
// assign the new values to the fields
insp["BeginX"] = BeginX;
insp["EndX"] = EndX;
insp["DimX"] = DimX;
// do the edit
var op = new EditOperation();
op.Name = "Modify dimension";
op.Modify(insp);
var success = op.Execute();
You can use any of the other EditOperation.Modify overloads as appropriate. The key is that you need to modify the x,y fields of the points and not the shape field itself. Despite supplying a mtulipoint to the EditOperation.Create to generate a dimension feature we cannot use a multipoint within an EditOperation.Modify to modify the geometry.
I've verified that both of these scenarios work correctly at 3.4. Can you try and see if they work for you at 2.9.
As for the creation, you were on the correct path with regards to the DimensionFeature. and the SetDimensionShape method. This is the call we have to make to force the shape generation to occur as the workaround for this bug. The way to use this method within an EditOperaiton is to hook into the RowCreated event. Here's a button that is based on your code snippet with the row event and the SetDimensionShape method.
protected override void OnClick()
{
var CurrentMap = MapView.Active.Map;
DimensionLayer dimLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<DimensionLayer>().FirstOrDefault();
QueuedTask.Run(() =>
{
var sr = dimLayer.GetSpatialReference();
// use layer selection to get an oid
var selection = dimLayer.GetSelection();
var oids = selection.GetObjectIDs();
var oid = oids.FirstOrDefault();
// load inspector with the feature
var insp = new ArcGIS.Desktop.Editing.Attributes.Inspector();
insp.Load(dimLayer, oid);
// get the x,y coords of the the dimension points
Double.TryParse(insp["BeginX"].ToString(), out double BeginX);
Double.TryParse(insp["BeginY"].ToString(), out double BeginY);
Double.TryParse(insp["EndX"].ToString(), out double EndX);
Double.TryParse(insp["EndY"].ToString(), out double EndY);
Double.TryParse(insp["DimX"].ToString(), out double DimX);
Double.TryParse(insp["DimY"].ToString(), out double DimY);
Double.TryParse(insp["TextX"].ToString(), out double TextX);
Double.TryParse(insp["TextY"].ToString(), out double TextY);
// create a new multipoint for updated dimension points
var DimPoints = new List<MapPoint>()
{ MapPointBuilderEx.CreateMapPoint(BeginX + 10, BeginY, 0, sr),
MapPointBuilderEx.CreateMapPoint(EndX + 10, EndY, 0, sr),
MapPointBuilderEx.CreateMapPoint(DimX + 10, DimY, 0, sr) };
var UpdatedGeom = MultipointBuilderEx.CreateMultipoint(DimPoints, AttributeFlags.AllAttributes);
// attributes
var Attributes = new Dictionary<string, object>() { { "StyleID", 0 },
{ "DimType", 0 },
{ "BeginX", DimPoints[0].X }, { "BeginY", DimPoints[0].Y },
{ "EndX", DimPoints[1].X }, { "EndY", DimPoints[1].Y },
{ "DimX", DimPoints[2].X }, { "DimY", DimPoints[2].Y } };
// subscribe to the RowCreatedEvent
// do this as close as possible to the EditOperation to
// minimize the time that we are monitoring the creates
var table = dimLayer.GetTable();
SubscriptionToken token = ArcGIS.Desktop.Editing.Events.RowCreatedEvent.Subscribe(OnRowCreated, table);
// wrap in a try/catch/finally to ensure that we can unsubscribe
// if there is a failure
bool success = false;
var Op = new EditOperation(); Op.Name = "Test";
try
{
Op.Create(dimLayer, UpdatedGeom, Attributes);
success = Op.Execute();
}
catch (Exception ex)
{
}
finally
{
// unsubscribe
if (token != null)
ArcGIS.Desktop.Editing.Events.RowCreatedEvent.Unsubscribe(token);
}
if (!success)
{
throw new Exception(Op.ErrorMessage);
}
});
}
private void OnRowCreated(ArcGIS.Desktop.Editing.Events.RowChangedEventArgs args)
{
var row = args.Row;
if (row is ArcGIS.Core.Data.Mapping.DimensionFeature df)
{
try
{
// force the dimension polygon shape generation
// a simple get and then set will accomplish this
var shape = df.GetDimensionShape();
df.SetDimensionShape(shape);
}
catch (Exception ex)
{
}
}
}
Again, this works on 3.4; can you verify that it will work for you on 2.9.
I've entered an issue into our backlog to fix the dimension creation. In the meantime, I'll get this workaround documented on the Editing Dimensions concept page. Thanks for drawing our attention to this; unfortunately we don't have too many dimension feature SDK users.
Let me know if you have any additional questions or run into any problems with the snippets I've posted.
Narelle
... View more
Wednesday
|
0
|
0
|
43
|
POST
|
Hi Billy,
I am looking at this right now and can confirm that custom dimension construction tools aren't working in the current release. I am trying to find you a work around. In the mean time can you tell me what version of the software you are using.
But from your first sentence it seems like you are also interested in how to move an existing dimension feature. Are you using the EditOperation.Modify operation and modifing the individual x,y coordinates of the BeginX, BeginY, EndX, EndY, DimX, DimY and TextX and TextY fields.?
Thanks
Narelle
... View more
Tuesday
|
0
|
2
|
64
|
POST
|
Kerry,
Sorry for the confusion. I would have to qualify my above statement with regards to determining when a button / command has finished executing; is that it depends on the command.
In the example in the documentation, the command "esri_mapping_createBookmark" displays a modal dialog and performs some action on the ok button.
The command in your example "esri_editing_DivideCommand" activates the divide tool and displays a UI in a dockpane. This is not a modal dialog as tools very often require some interaction with the map. The divide command at this point has finished executing. It is the divide tool and the dockpane UI that actually controls the divide operation. The only way to know when the user has finished interacting with the UI and executed the divide edit is to use the edit events. .
Hope this helps clarify things a bit.
Narelle
... View more
Tuesday
|
0
|
1
|
23
|
POST
|
Hello,
There is no way to determine when a button has finished executing like you're attempting to do. However when it comes to edit operations, you can determine when an edit has occurred by using the edit events. See this documentation. https://github.com/Esri/arcgis-pro-sdk/wiki/ProConcepts-Editing#edit-events
In your case you would need to subscribe to the row Events to determine when the Divide operation has completed and add your custom attribute updates within that event.
Narelle
... View more
Sunday
|
0
|
3
|
44
|
POST
|
Hello,
Here is a sample of the expression that can be used to map field values between two features or rows with the EditOperation.TransferAttributes function.
return { "ADDRESS" : $sourceFeature['ADDRESS'], "IMAGE" : $sourceFeature['IMAGE'], "PRECINCT" : $sourceFeature['PRECINCT'], "WEBSITE" : $sourceFeature['WEBSITE'], "ZIP" : $sourceFeature['ZIP'] }
Here's an example of a simple button that will transfer attributes from a source feature (oid 1) in the Police Stations layer to a destination feature (oid 2) in the same layer
protected override void OnClick()
{
var layer = MapView.Active.Map.GetLayersAsFlattenedList().FirstOrDefault(l => l.Name == "Police Stations");
if (layer == null)
return;
string expression = "return {\r\n " +
"\"ADDRESS\" : $sourceFeature['ADDRESS'],\r\n " +
"\"IMAGE\" : $sourceFeature['IMAGE'],\r\n + " +
"\"PRECINCT\" : $sourceFeature['PRECINCT'],\r\n " +
"\"WEBSITE\" : $sourceFeature['WEBSITE'],\r\n " +
"\"ZIP\" : $sourceFeature['ZIP']\r\n " +
"}";
QueuedTask.Run(() =>
{
var op = new EditOperation();
op.Name = "Transfer atts";
op.TransferAttributes(layer, 1, layer, 2, expression);
var success = op.Execute();
});
}
I'll make sure the documentation for the function is updated. Let me know if you have any additional questions.
Narelle
... View more
Sunday
|
0
|
0
|
31
|
POST
|
Hi Joe,
I think the property you're looking for is part of the CIM definition of the template object. Each EditingTemplate / EditingRowTemplate has a definition which is a CIMRowTemplate. CIMRowTemplate inherits from CIMBasicRowTemplate. There is a RequiredFields property on the CIMBasicRowTemplate object (https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/topic74601.html). This is different from the property used for setting default values (which is CIMBasicRowTemplate.DefaultValues).
Narelle
... View more
a month ago
|
0
|
1
|
124
|
POST
|
Hi Dominic,
Unfortunately we do not have the Smooth function available in the Geometry or Editing APIs as you've pointed out. I've added an issue to have it added to the Geometry API on the GeometryEngine object for the next release. This will be the 3.5 release as we are in the final stages of 3.4 right now which is due to be released shortly.
Narelle
... View more
09-29-2024
06:22 PM
|
0
|
1
|
318
|
POST
|
Hello, An issue has been created and assigned to the development team. It s currently in the near-term queue, but I do not have any other timeline information on this.
... View more
08-27-2024
04:04 PM
|
0
|
0
|
156
|
POST
|
Hello, Thank you for reporting this. Internally we also recently identified this same issue with the RowHandle object and how it is used within the EditOperation object. The Create and Delete operations with regards to relationships is one of these scenarios where some gaps in functionality exist. As you mention if the RowHandle is defined using a MapMember and objectID pair then the EditOperation Delete relationship method will work correctly. Unfortunately it will not work if the rowHandle is defined using a Row (or with a Table/FeatureClass and objectID pair). These bugs have been fixed and will be available in the 3.4 release of the software. Sorry for any inconvenience. Narelle
... View more
08-08-2024
09:44 PM
|
1
|
0
|
147
|
POST
|
Hello, Thanks for bring this bug to our attention. This will be fixed for the Pro 3.4 release.
... View more
07-18-2024
04:46 PM
|
1
|
0
|
186
|
POST
|
Hi Grzegorz, This bug was found and logged too late to be resolved in the 3.3 release. It is currently targeted to be fixed for ArcGIS Pro 3.4. Narelle
... View more
07-02-2024
10:24 PM
|
0
|
0
|
284
|
POST
|
Sometimes there is other data that is in the geopackage file (for example raster data) that is not returned by the Database.GetTableNames method. In this instance you could use the the ItemFactory and Item classes to obtain the content. Here's an example snippet. var otherUris = new List<Uri>();
var tableUris = new List<Uri>();
var item = ItemFactory.Instance.Create(gpkgPath, ItemFactory.ItemType.PathItem);
var children = item.GetItems();
foreach (var child in children)
{
var childPath = child.Path;
if (child.TypeID == "sqlite_table")
tableUris.Add(new Uri(childPath));
else
otherUris.Add(new Uri(childPath));
}
// now use LayerFactory and StandloneTableFactory to
// create layers / tables
... View more
06-26-2024
06:11 PM
|
0
|
0
|
355
|
POST
|
Re the Delete GP Tool no longer removing map layers with deleted data source. There was a change at 3.3 with the behavior of data sources being deleted and renamed. The default behavior is now NOT to remove layers when this occurs I believe this change was made for performance reasons. However, you can alter this default behavior to revert back to the previous behavior. There is a new setting in the backstage options under the Map And Scene tab. See the Layer Data Sources expander where you can set the value for both deleting and renaming of data sources independently. Narelle
... View more
06-04-2024
07:18 PM
|
1
|
1
|
927
|
POST
|
Hello, Thanks for finding and highlighting this problem with the missing data on the Geometry tab with plug in datasources. I am able to duplicate the same behavior. Unfortunately there is no work-around to be able to display the coordinate data. I have logged an issue for this to be fixed in the next software release. regards Narelle
... View more
05-27-2024
09:22 PM
|
4
|
2
|
491
|
POST
|
You cannot add controls to the mapControl itself. but you can add other controls to the window that is hosting the mapControl. In your example (the MapControl sample); this means you can add a button to the OverviewWindow xaml file. If you are not familiar with WPF you may need to do some research about the various WPF controls that can help you control the layout. Here's an article that gives some introduction to the Grid control - https://wpf-tutorial.com/panels/grid/. and how you can use column, rows and alignments to position child elements . Narelle
... View more
05-07-2024
06:26 PM
|
0
|
0
|
404
|
Title | Kudos | Posted |
---|---|---|
1 | 08-08-2024 09:44 PM | |
1 | 07-18-2024 04:46 PM | |
1 | 06-04-2024 07:18 PM | |
4 | 05-27-2024 09:22 PM | |
1 | 02-12-2019 08:59 AM |
Online Status |
Offline
|
Date Last Visited |
7 hours ago
|