|
POST
|
LAS is represented in Pro with PointCloudSceneLayer There is additional information here: https://github.com/esri/arcgis-pro-sdk/wiki/ProConcepts-Scene-Layers
... View more
09-06-2022
07:37 AM
|
0
|
1
|
1207
|
|
POST
|
David, I dont know a lot about importing an mxd but that doesnt sound right. Symbology/Layer properties should be editable AFAIK. I did a quick scan of the online help and there was no mention of "Read Only". eg https://pro.arcgis.com/en/pro-app/latest/help/projects/add-maps-to-a-project.htm https://pro.arcgis.com/en/pro-app/latest/help/projects/drawing-behavior-in-arcgis-pro.htm I'd also suggest posting in the ArcGIS Pro forum in addition: https://community.esri.com/t5/arcgis-pro-questions/bd-p/arcgis-pro-questions
... View more
09-02-2022
08:17 AM
|
0
|
0
|
985
|
|
POST
|
Richard, this is definitely a bug. We'll try to get this addressed for 3.1. The workaround would be to delete and re-add which I realize is not optimal.
... View more
08-22-2022
12:36 PM
|
0
|
0
|
1742
|
|
POST
|
Abel, Looking at the tool help regarding input parameters, as written, this does looks correct to me also //gp
List<string> vals= new List<string>();
vals.Add(SelectedProximityLayer.URI);
vals.Add(...);
...
await Geoprocessing.ExecuteToolAsync("SelectLayerByLocation_management",
parameters) Here is my stab at this (which does work for me): Given these inputs (using Crimes and Fire stations point data sets from the community samples data): I have this code - as Gintatuatas mentioned I just pass the param values straight to MakeValueArray: internal class TestGP : Button
{
protected async override void OnClick()
{
var sel_tool_name = "SelectLayerByLocation_management";
var input_layer = MapView.Active.Map.GetLayersAsFlattenedList()
.OfType<FeatureLayer>().FirstOrDefault(l => l.Name == "Crimes");
if (input_layer == null) return;
var sel_layer = MapView.Active.Map.GetLayersAsFlattenedList()
.OfType<FeatureLayer>().FirstOrDefault(l => l.Name == "Fire_Stations");
if (sel_layer == null) return;
var parameters =
Geoprocessing.MakeValueArray(
input_layer, "WITHIN_A_DISTANCE_GEODESIC", sel_layer, "1000 Feet",
"NEW_SELECTION", "NOT_INVERT");
await Geoprocessing.ExecuteToolAsync(sel_tool_name, parameters);
//test params by showing the tool dialog
//await Geoprocessing.OpenToolDialogAsync(sel_tool_name, parameters);
} (these are my parameters returned from Geoprocessing.MakeValueArray:)
... View more
08-22-2022
12:33 PM
|
0
|
1
|
3823
|
|
POST
|
you may find this helpful on how to add dependencies to your addin: https://github.com/esri/arcgis-pro-sdk/wiki/ProGuide-content-and-image-resources#3rd-party-assemblies
... View more
08-22-2022
11:43 AM
|
1
|
1
|
4013
|
|
POST
|
When faced with what syntax to use when running GP tools via ExecuteToolAsync I typically follow the same approach which u may find useful: 1. Open the GP Tool Dialog. 2. Manually configure the GP Tool Dialog with the desired options (may be some trial and error here) 3. Run the tool 4. Click on "View Details", then "Parameters" to view the parameters the tool used based on my dialog options. 5. Transfer the options from the "View Details" parameters to the addin code. Typically, ";" (semi-colons) in the output params indicates an input list. Again, u may have a bit of fiddling here to get this right. However, every parameter that is shown on the View Details with an assigned value should have a corresponding parameter variable in your addin code. For Calculate Geometry Attributes, this looks like: 1. Open the dialog and configure: 2. Run the tool, "View Details"...shows these parameter values based on my selections: 3. Transfer the parameters to the addin code: internal class RunCalcGeomAttribs : Button {
protected override async void OnClick() {
var inputLayer =
MapView.Active.Map.GetLayersAsFlattenedList()
.OfType<FeatureLayer>().First(l => l.Name == "Portland_PD_Precincts");
var toolName = "management.CalculateGeometryAttributes";
var geom_attribs = new List<string>() {
"AREA AREA_GEODESIC", "LENGTH PERIMETER_LENGTH_GEODESIC", "VERTICES POINT_COUNT"
};
var length_unit = "FEET_US";
var area_unit = "SQUARE_FEET_US";
var calcParams = Geoprocessing.MakeValueArray(
new object[] { inputLayer, geom_attribs, length_unit, area_unit });
IGPResult result = await Geoprocessing.ExecuteToolAsync(
toolName, calcParams, null, CancelableProgressor.None,
GPExecuteToolFlags.InheritGPOptions);
var str = "No errors";
if (result.IsFailed) {
str = string.Join(',', result.ErrorMessages?.Select(
m => m.Text).ToList() ?? new List<string>());
}
System.Diagnostics.Debug.WriteLine(str);
}
} Notice that the format of the params in my code are different than yours based on what the View Details dialog provided. 4. This gives the final output: You can always double-check if your params are correct by calling Geoprocessing.OpenToolDialog or OpenToolDialogAsync - it should give the same tool dialog view "pre-configured" with the same options. If OpenToolDialog doesn't open the tool dialog correctly then chances are that GP.ExecuteToolAsync won't work correctly either. ...
var calcParams = Geoprocessing.MakeValueArray(
new object[] { inputLayer, geom_attribs, length_unit, area_unit });
//use OpenToolDialog to check param format is correct
Geoprocessing.OpenToolDialogAsync(toolName, calcParams);
... View more
08-16-2022
03:34 PM
|
2
|
1
|
2540
|
|
POST
|
Hi Dave, Internally, "Do" or "DoAync" is called on the OperationManager to execute the given operation - in this case the removing of a layer. Within the context of the Do or DoAsync, the operation is executed - i.e. removal of the layer(s) which, in turn, fires all relevant events - to include "Removing" and "Removed" events - _then_ , assuming completion was successful, the operation is added to the undo stack to allow it to be undone. Do now returns and/or DoAsync completes. An unsuccessful operation, conversely, would not be added (to be undone). The best u can do, as u r trying to catch the operation "as it/when it" is added to the stack is to try a slight delay. So, something like: //elsewhere - register for layers removed
ArcGIS.Desktop.Mapping.Events.LayersRemovedEvent.Subscribe((args) => {
DelayedListUndoOperations("LayersRemovedEvent",
args.Layers.Select(x => $"Remove layer: {x.Name}").ToList(),
1000);
});
//delay before reading operations
private async void DelayedListUndoOperations(string when,
List<string> opNames, int milliseconds) {
//non-blocking wait
await Task.Delay(milliseconds);
ListUndoOperations($"delayed {milliseconds}, {when}", opNames);
}
private void ListUndoOperations(string when, List<string> opNames) {
var opManager = MapView.Active?.Map?.OperationManager;
var ops =
opManager?.FindUndoOperations(o => !string.IsNullOrEmpty(o.Name)) ??
new List<Operation>();
System.Diagnostics.Debug.WriteLine(when);
if (ops.Count() == 0) {
System.Diagnostics.Debug.WriteLine("No Undo operations");
}
foreach (var op in ops) {
var match = opNames.Contains(op.Name) ? " (match)" : "";
System.Diagnostics.Debug.WriteLine($"{op.Name}{match}");
}
}
There is still an edge case however, where, depending on the delay, the user still has the opportunity - albeit brief - to execute the undo.
... View more
08-10-2022
02:44 PM
|
1
|
1
|
3667
|
|
POST
|
Hi Stephen, use IDisplayTable.GetFieldDescriptions() and not the field descriptions off the CIM and u will be good to go (see Wolf's code above). The CIM is optimized to only store field descriptions if they have been (previously) modified, otherwise they are null. This is also true for feature layers (not just standalone tables). Whereas, field descriptions will always be provisioned from the IDisplayTable - and never null - regardless of whether they have been modified or not. It could be that your CIM code worked previously because the table field descriptions had been modified at some point after it was added to a map.
... View more
08-10-2022
09:26 AM
|
0
|
1
|
3198
|
|
POST
|
you have a threading issue. Usually an InvalidOperation exception is thrown when u create something on the _background_ thread that needs to be created on the UI thread (the reverse of most cases w the Pro SDK which do require u to use the QTR). However it's not possible to tell from just this snippet. Make sure that the complete sequence occurs on the UI thread in this case.
... View more
08-02-2022
09:10 AM
|
1
|
0
|
2412
|
|
POST
|
you want a "MapViewOverlayControl". It is, essentially, a wrapper around a "standard" WPF User Control that u can add to the MapView control overlay. This overlay is used by Pro for user control content (as opposed to graphics elements content) - such as the Time slider, Edit sketch toolbar, Navigation tool "compass/navigator", and so on that sits "on top of" the map view. To use it, create a user control - in this case it sounds like it will be something like a WPF canvas that contains your cross-hair image, centered. Wrap the user control with a MapViewOverlayControl and then add _that_ to the map view control overlay with mapView.AddOverlayerControl(....) : MapViewOverlayControl You should also look at the scribble control sample - it uses the map view overlay to hold a scribble control allowing users to "scribble" or "annotate" markup directly on top of the mapview (via a MapViewOverlayControl wrapping the scribble control). https://github.com/Esri/arcgis-pro-sdk-community-samples/tree/master/Map-Exploration/ScribbleControl_ArcGISPro Your code to add the overlay control will look something like this: var crossHairControl = new CrossHairControl(); //your user control
//do any required configuration upfront
crossHairControl.Foo = ....;
crossHairControl.Bar = ....;
//Create a MapViewOverlayControl.
var mapViewOverlayControl = new MapViewOverlayControl(
crossHairControl, true, true,
true, OverlayControlRelativePosition.Center, .5, .8);
//Add to the active map view
MapView.Active.AddOverlayControl(mapViewOverlayControl);
... View more
07-29-2022
02:54 PM
|
1
|
0
|
2429
|
|
POST
|
"Dockpane" is a type, not a Dockpane instance which is what u are after. cast the returned value from FrameworkApplication.DockPaneManager.Find("dockpane_id") to your dockpane view model class. For instance: _vm = FrameworkApplication.DockPaneManager.Find(
"ProAppModule1_Dockpane1") as Dockpane1ViewModel; This is, essentially, the same thing the auto-generated code for the Dockpane item template is doing when it consrtucts its "default" Show method (to activate the dockpane in the first place). /// <summary>
/// Show the DockPane.
/// </summary>
internal static void Show()
{
DockPane pane = FrameworkApplication.DockPaneManager.Find(_dockPaneID);
if (pane == null)
return;
pane.Activate();
}
... View more
07-28-2022
06:06 PM
|
0
|
0
|
1875
|
|
POST
|
What you want is something like this: // This is your view model or .xaml.cs if your Window is acting as its own
// DataContext
private ImageSource _imgSource = null;
public ImageSource IconImageSource {
get {
if (_imgSource == null) {
var url = "";
//check current theme
if (FrameworkApplication.ApplicationTheme ==
ApplicationTheme.Default) {
//light theme icon
//note: full path looks something like this:
//@"pack://application:,,,/MyCustomApp;component/MyImages/WindowIcon.png";
url = "/MyImages/WindowIcon.png";
}
else {
//dark theme icon
url = "/MyImages/WindowIconDark.png";
}
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.UriSource = new Uri(url, UriKind.RelativeOrAbsolute);
bmp.EndInit();
_imgSource = bmp;
}
return _imgSource;
}
}
//In your .xaml
<Image Source={Binding IconImageSource} .... /> In your addin, add two images - one for your "light" and one for your "dark". Make sure to set the BuildAction to "Resource". You may have to fiddle with the pack Uri. In my example, there would be two images in the addin stored in a folder called "MyImages". Notice I am _binding_ the image source to a property as opposed to setting it to a DynamicResource.
... View more
07-28-2022
02:47 PM
|
0
|
0
|
4243
|
|
POST
|
First thing I notice is that the toolname is "SummarizeAttributes" rather than "Summarize" as u have it so that needs to be changed. Second thing I noticed was that using the toolname "geoanalytics.SummarizeAttributes" I actually got a _server_ flavor of the tool and not the _desktop_ flavor (not that I knew there were two as I am not personally familiar with the Geoanalytics toolbox). I wonder if you have a similar issue and are invoking the Geoanalytics server tool and not the desktop tool? Well, eventually, I ended up with a toolname of "gapro.SummarizeAttributes" which seemed to do the trick and invoke the desktop toolbox. You can try my code below. (I am using the "Interacting with Maps.gdb\Crimes" dataset from the pro community sample data fyi). internal class GPTestButton : Button {
protected async override void OnClick()
{
var sum_tool_name = "gapro.SummarizeAttributes";
//var sum_tool_name = "geoanalytics.SummarizeAttributes";
var extent = MapView.Active.Extent;
var summarizeLayer = MapView.Active.Map.GetLayersAsFlattenedList()
.OfType<FeatureLayer>().FirstOrDefault(l => l.Name == "Crimes");
if (summarizeLayer == null) return;
var gdb = Project.Current.DefaultGeodatabasePath;
//output table
var out_table = System.IO.Path.Combine(gdb, "crimes_summary");
var fields = new List<string>() { "Major_Offense_Type", "Police_Precinct" };
var summary_fields = new List<string>() { "Major_Offense_Type COUNT" };
var sum_params = await QueuedTask.Run(() =>
{
return Geoprocessing.MakeValueArray(
new object[] { summarizeLayer, out_table, fields, summary_fields });
});
await Geoprocessing.ExecuteToolAsync(sum_tool_name, sum_params,
null, CancelableProgressor.None,
GPExecuteToolFlags.InheritGPOptions);
//Or open the dialog
//Geoprocessing.OpenToolDialog(sum_tool_name, sum_params);
}
} Gives: This is the tool dialog invoked via Geoprocessing.OpenToolDialog Note: To resolve the toolname I had to look in the GP tool cache to see what it (GP) was looking for. You can find that here: C:\Users\your_username\AppData\Local\ESRI\Local Caches. Despite their rather intimidating appearance they are just text files. Just drag and drop one of them into notepad. I searched for "SummarizeAttributes" and came up with two hits: "geoanalytics.SummarizeAttributes" and "gapro.SummarizeAttributes". As I had already tried "geoanalytics.SummarizeAttributes", I went with the other one.
... View more
07-21-2022
02:58 PM
|
1
|
1
|
3548
|
|
POST
|
You most likely want FeatureLayer Select(...). https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/topic11392.html Something like: var sqf = new SpatialQueryFilter() {
FilterGeometry = clickedPoint,
SpatialRelationship = SpatialRelationship.Intersects,//change as needed
WhereClause = "Optional SQL whereclause here",
SubFields = "*"
};
var selection = featLayer.Select(sqf);
... View more
07-21-2022
08:49 AM
|
0
|
1
|
2231
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 05-19-2026 10:29 AM | |
| 1 | 04-29-2026 02:06 PM | |
| 1 | 01-08-2026 02:03 PM | |
| 1 | 01-08-2026 02:15 PM | |
| 3 | 12-17-2025 11:33 AM |
| Online Status |
Offline
|
| Date Last Visited |
05-31-2026
09:30 AM
|