|
POST
|
Duncan, do u want all 3 bits (viewer, preview, anno) or just the CIM Viewer itself? Edit: And Debug or Release build?
... View more
07-01-2022
07:07 AM
|
0
|
1
|
2675
|
|
POST
|
there are a couple of ways I can think of to do the sort. One is to use the Geodatabase API and the SortDescription and TableSortDescription classes. Another way is to use LINQ OrderBy. LINQ also has a SortedList and various other collections optimized for sorting u could look at. The advantage of using the GDB would be if your dataset is large. LINQ is probably quicker if your dataset is small. GDB sorting is further described here. In this example I am using a feature class called "Crimes" containing some made up crime data where each incident has an X and Y coordinate stored in the attribute table which i will use to replicate your scenario. internal class SortFieldValues : Button {
protected async override void OnClick() {
var crimes = MapView.Active.Map.FindLayers("Crimes").First()
as FeatureLayer;
await QueuedTask.Run(() => {
var field_name = "X_Coordinate";
var field_name2 = "Y_Coordinate";
var asc_sort_list_x = new List<double>();
var asc_sort_list_y = new List<double>();
//Do the sort using GDB
using (var fc = crimes.GetFeatureClass()) {
using (var fc_def = fc.GetDefinition()) {
var x_field = fc_def.GetFields().First(f => f.Name == field_name);
var y_field = fc_def.GetFields().First(f => f.Name == field_name2);
//create a sort description for each field
var xSortDesc = new SortDescription(x_field);
var ySortDesc = new SortDescription(y_field);
//Sort order
xSortDesc.SortOrder = SortOrder.Ascending;
ySortDesc.SortOrder = SortOrder.Ascending;
//table sort
var TableSort_by_X = new TableSortDescription(
new List<SortDescription>() { xSortDesc });
var TableSort_by_Y = new TableSortDescription(
new List<SortDescription>() { ySortDesc });
//do the sorts
//x first
using (var rc = fc.Sort(TableSort_by_X)) {
while(rc.MoveNext()) {
if (rc.Current[x_field.Name] == null ||
rc.Current[x_field.Name] is DBNull)
continue;//TODO handle nulls as needed...
asc_sort_list_x.Add((double)rc.Current[x_field.Name]);
}
}
//now Y
using (var rc = fc.Sort(TableSort_by_Y)) {
while (rc.MoveNext()) {
if (rc.Current[y_field.Name] == null ||
rc.Current[y_field.Name] is DBNull)
continue;//TODO handle nulls...
asc_sort_list_y.Add((double)rc.Current[y_field.Name]);
}
}
//first 100
for(int i = 0; i < 100; i++) {
System.Diagnostics.Debug.WriteLine(
$"X: {asc_sort_list_x[i]} Y:{asc_sort_list_y[i]}");
}
asc_sort_list_x.Clear();
asc_sort_list_y.Clear();
//Do the sort using LINQ
using (var rc = fc.Search()) {
while (rc.MoveNext()) {
if (rc.Current[x_field.Name] == null ||
rc.Current[x_field.Name] is DBNull)
continue;//TODO handle nulls...
if (rc.Current[y_field.Name] == null ||
rc.Current[y_field.Name] is DBNull)
continue;//TODO handle nulls...
asc_sort_list_x.Add((double)rc.Current[x_field.Name]);
asc_sort_list_y.Add((double)rc.Current[y_field.Name]);
}
}
var result_w_linq_x = asc_sort_list_x.OrderBy(x => x).ToList();
var result_w_linq_y = asc_sort_list_y.OrderBy(y => y).ToList();
//first 100
for (int i = 0; i < 100; i++)
{
System.Diagnostics.Debug.WriteLine(
$"X: {result_w_linq_x[i]} Y:{result_w_linq_y[i]}");
}
}
}
});
}
}
... View more
06-30-2022
01:08 PM
|
0
|
0
|
5113
|
|
POST
|
Having a path separator in your toolname does not seem correct- "\Archive Imagery\ArchiveImagerySearch"? Here is a Pro SDK sample: https://github.com/Esri/arcgis-pro-sdk-community-samples/tree/master/Geoprocessing/DeepThought It contains a python toolbox: "DeepThought.tbx". It has a tool "answer.py" with a toolname "Answer" and so: internal class ShowGPDialogButton : Button {
protected override void OnClick()
{
var tool_path =
@"E:\Data\SDK\Migration\DeepThought-ProAddin\Toolboxes\toolboxes\DeepThought.tbx";
var tool_name = System.IO.Path.Combine(tool_path, "Answer");
//map just so happens to be of Portland
var wkid = MapView.Active.Map.SpatialReference.Wkid;
var env_array = Geoprocessing.MakeEnvironmentArray(outputCoordinateSystem: $"{wkid}");
Geoprocessing.OpenToolDialog(tool_name, null, env_array);
}
} results in:
... View more
06-24-2022
12:37 PM
|
0
|
0
|
7781
|
|
POST
|
For System toolbox tools, either specifying the full path to the Toolbox or using the convention "ToolboxName.ToolName" are equivalent. so, for example, these are both equivalent: var path = @"C:\<ArcGIS Pro Install Path>\Resources\ArcToolBox\Toolboxes\Analysis Tools.tbx"; var long_tool_name = System.IO.Path.Combine(path, "Buffer"); var short_tool_name = "analysis.Buffer"; With a custom tool, as it is _not_ a System toolbox tool, then u will always default to the fully qualified path to the toolbox - i.e. what I show as "long_tool_name" above (only the path to the toolbox will be whatever is the relevant full path to your custom toolbox in question). Geoprocessing.OpenToolDialog(...) can then be invoked with the relevant toolbox name and parameters - the parameters will be used to prepopulate the corresponding fields on the tool dialog. One last point, it is always best to call Geoprocessing.OpenToolDialog(...) on the UI thread and _not_ on the QueuedTask. If the Geoprocessing Dockpane has not been opened at least once before during the current session then Geoprocessing.OpenToolDialog(...) must create the dockpane before showing the tool page (hosted in the GP dockpane). If Geoprocessing.OpenToolDialog(...) is called on the QueuedTask then creation of the GP dockpane fails (if the GP dialog has not been created for the session) and nothing will be shown. internal class ShowGPDialogButton : Button {
protected async override void OnClick()
{
var map = MapView.Active.Map;
var extent = MapView.Active.Extent;
var path = @"C:\ArcGIS\Resources\ArcToolBox\Toolboxes\Analysis Tools.tbx";
//these are equivalent for a System tool
var long_tool_name = System.IO.Path.Combine(path, "Buffer");
var short_tool_name = "analysis.Buffer";
var tool_name = long_tool_name;//or can use short_tool_name for System tools
var val_array = await QueuedTask.Run(() => {
//make a geometry for the buffer
var center_pt = MapPointBuilderEx.CreateMapPoint(
MapView.Active.Camera.X,
MapView.Active.Camera.Y,
MapView.Active.Camera.SpatialReference);
var geom = new List<object>() { center_pt };
//set up some params for Buffer
return Geoprocessing.MakeValueArray(new object[] { geom, null, @"1000 Meters" });
});
//Show the tool page - call OpenToolDialog on the UI
Geoprocessing.OpenToolDialog(tool_name, val_array, null, false);
}
}
... View more
06-23-2022
03:44 PM
|
2
|
1
|
7800
|
|
POST
|
the UI probably needs a chance to redraw between the PanTo and the Export. Try splitting it across two QueuedTask invocations and await the first. You shouldnt need the redraw. So... await QueuedTask,Run(()=> ....PanTo() ...); //the UI will refresh here var layout = LayoutView.Active.Layout; QueuedTask.Run(() => layout.Export() ....); This is, essentially the same as calling mapView.PanToAsync() with an _await_ which should have the same effect....so: await mapView.PanToAsync(....); var layout = LayoutView.Active.Layout; QueuedTask.Run(() => layout.Export() ....);
... View more
06-23-2022
01:25 PM
|
0
|
0
|
1070
|
|
POST
|
Note: Salvador, the file Gintautas is referring to is the Config.daml and not the user control .xaml (which contains the WPF definition)
... View more
06-23-2022
01:06 PM
|
1
|
0
|
4007
|
|
POST
|
This will get a lot easier at 3.0 (which will be released on Thurs). Display constraints, at 3.0 can be set using a "GetAutoCamera()/SetAutoCamera(autoCamera)" method pair. Display constraints will be explained here: https://github.com/esri/arcgis-pro-sdk/wiki/ProConcepts-Layouts#map-frame-display-constraints This link will be broken until Thursday because it has not been released yet. In the interim, u can use this code. Be advised that not all map frames can be rotated, especially if the map frame is linked or is a map series frame. Generally speaking, if the current display constraint is any of these then it should be fine. I did add a some defensive code to check for the most obvious conditions (such as 3D). internal class RotateTheMap : Button {
private static double _angle = 0;
protected override void OnClick() {
if (LayoutView.Active == null)
return;
var layout = LayoutView.Active.Layout;
var mapFrame = layout.Elements.OfType<MapFrame>().FirstOrDefault();
if (mapFrame == null)
return;
QueuedTask.Run(() => {
var def = mapFrame.GetDefinition() as CIMMapFrame;
if (def.View.ViewingMode != MapViewingMode.Map)
return; //2D only
_angle -= 15;//Counter-clockwise
if (_angle < -345) _angle = 0;
var autoCamera = def.AutoCamera;
if (autoCamera == null)
{
//unusual
def.AutoCamera = new CIMAutoCamera()
{
Camera = new CIMViewCamera(),
AutoCameraType = AutoCameraType.Extent
};
}
else if (autoCamera.Source != AutoCameraSource.None &&
autoCamera.Source != AutoCameraSource.Fixed)
{
return;
}
def.View.Camera.Heading = _angle;
mapFrame.SetDefinition(def);
});
}
}
... View more
06-21-2022
09:23 AM
|
0
|
0
|
2432
|
|
POST
|
Cast the pane to ITablePane. From ITablePane get its MapMember. The MapMember will either be a layer or a standalone table. https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/index.html#topic18696.html If you are wanting to get the currently selected (standalone) table from the contents view instead you can use MapView.Active.GetSelectedStandaloneTables() https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/index.html#topic11959.html
... View more
06-20-2022
03:03 PM
|
1
|
0
|
1923
|
|
POST
|
Yes, I see your confusion - presumably this sentence? "You can open many panes at the same time, and they can be grouped, tiled (horizontally or vertically), or floated.".... We will change it to "You can open many panes at the same time, and they can be grouped, tiled (horizontally or vertically), or floated - but only interactively" for the next release.
... View more
05-24-2022
08:44 AM
|
0
|
1
|
3696
|
|
POST
|
there are a number of different ways to can open panes - map panes in your case - var mapItem = Project.Current.GetItems<MapProjectItem>().First();
//ok to call on the UI
mapItem.OpenMapPaneAsync(MapViewingMode.Map);
QueuedTask.Run(()=> {
//GetMap needs the QTR but OpenViewAsync does not
mapItem.GetMap().OpenViewAsync();
//assuming u have a map - ok to call on the UI
FrameworkApplication.Panes.CreateMapPaneAsync(map); However u cannot control their placement. However, if you open a view for a map that was previously opened (in the project in the session) then the pane will go back to the configuration it was last in
... View more
05-24-2022
08:24 AM
|
0
|
1
|
3700
|
|
POST
|
ArcGIS.Desktop.Mapping.Events.MapMemberPropertiesChangedEvent event hints Any + DataSource. MapMemberPropertiesChangedEventArgs.MapMembers had the changed layer entered twice. Presumably once for each hint.
... View more
05-20-2022
03:39 PM
|
1
|
0
|
800
|
|
POST
|
Save works at the edit session level. This is the same as was the case in Arcmap. The difference with Pro is that, under the covers, u can have multiple edit sessions active across multiple workspaces/datastores. In Arcmap there could only be one.
... View more
05-19-2022
11:42 AM
|
0
|
1
|
1201
|
|
POST
|
There are multiple symbols it seems that control the borders - for the rows, the header, columns, etc. However, the "outer" border is this one: var frame_def = tableFrame.GetDefinition() as CIMTableFrame;
var dashed_line = SymbolFactory.Instance.ConstructLineSymbol(
ColorFactory.Instance.CreateColor(System.Windows.Media.Colors.CadetBlue),
1, SimpleLineStyle.Dash);
//change the outer border symbol
frame_def.GraphicFrame.BorderSymbol.Symbol = dashed_line;
tableFrame.SetDefinition(frame_def);
... View more
04-25-2022
08:30 PM
|
1
|
1
|
1654
|
|
POST
|
internal class Button1 : Button {
protected override void OnClick() {
var layout = LayoutView.Active.Layout;
if (layout == null)
return;
QueuedTask.Run(() => {
var tableFrame = layout.GetElements().OfType<TableFrame>().FirstOrDefault();
if (tableFrame != null) {
//change the text symbol
//the property panel conflates the symbols for each field
var frame_def = tableFrame.GetDefinition() as CIMTableFrame;
var fields = frame_def.Fields?.ToList() ?? new List<CIMTableFrameField>();
var green = ColorFactory.Instance.CreateColor(
System.Windows.Media.Colors.ForestGreen);
var size = 11;
var fontName = "Bernard MT Condensed";
var textSymbol = SymbolFactory.Instance.ConstructTextSymbol(green, size, fontName);
foreach (var frameField in fields) {
//to mimic the property sheet, change heading and field symbols
frameField.HeadingTextSymbol.Symbol = textSymbol;
frameField.TextSymbol.Symbol = textSymbol;
}
//these are defaults for new fields - optional - but, based on
//some experimentation, they need to match if u want the property
//sheet to show the changed symbology.
frame_def.DefaultTableFrameField.HeadingTextSymbol.Symbol = textSymbol;
frame_def.DefaultTableFrameField.TextSymbol.Symbol = textSymbol;
//commit the changes
tableFrame.SetDefinition(frame_def);
}
});
}
} Take a look at https://www.youtube.com/watch?v=MP90p-jkA5Q&t=14s on Youtube for on some guidance on how to figure these kind of things out. The session content is here: UnderstandingTheCIM.zip
... View more
04-22-2022
09:47 AM
|
1
|
0
|
1680
|
| 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
|