|
POST
|
So I tried two scenarios. I could not reproduce your issues. I am using a File GDB, all local data. Projection is WebMercator. Scenario1: I created a point layer that included the end points of an underlying line feature class as well as mid points. There are a total of 9 points (I had 3 lines originally). I used the Buffer GP Tool to buffer the points and add the result to the map. I changed the symbol using a SimpleRenderer. There is a noticeable pause on the first GP call. Say 4 or 5 seconds. Subsequent calls take about 1 second. No flickering. Scenario2: I extracted all the Geometries from the point layer. I made a MultiPoint. I buffered the Multipoint using GeometryEngine.Buffer. I added the output polygon (from the buffer) to the Graphic Overlay. This was almost instantaneous. You could improve the performance by caching the geometry and not querying the layer each time (if the point layer was not changing in your session). //This is Scenario 1 using the GP internal class ButtonScenario1 : Button { internal static int _count = 1; protected async override void OnClick() { var pointsLayer = MapView.Active.Map.GetLayersAsFlattenedList().First( l => l.Name == "Points_For_Lines"); var layerName = $@"Points_Buffer{_count++}"; var valueArray = Geoprocessing.MakeValueArray(pointsLayer, $@"E:\Scratch\TestBuffer\TestBuffer.gdb\{layerName}", "50 meters"); await Geoprocessing.ExecuteToolAsync("analysis.Buffer", valueArray); var buffer_layer = MapView.Active.Map.GetLayersAsFlattenedList().First( l => l.Name == layerName) as FeatureLayer; //set the renderer to something different than the default await QueuedTask.Run(() => { var outline = SymbolFactory.ConstructStroke(ColorFactory.BlueRGB, 2.0, SimpleLineStyle.Solid); var circleSymbol = SymbolFactory.ConstructPolygonSymbol(ColorFactory.GreyRGB, SimpleFillStyle.Solid, outline); var srdef = buffer_layer.GetRenderer() as CIMSimpleRenderer; srdef.Symbol = circleSymbol.MakeSymbolReference(); buffer_layer.SetRenderer(srdef); }); } } //This is Scenario 2 using the Overlay internal class ButtonScenario2 : Button { private IDisposable _graphic = null; private CIMPolygonSymbol _polySymbol = null; private Geometry _bufferResult = null; protected async override void OnClick() { if (_graphic != null) { _graphic.Dispose();//Clear out the old overlay _graphic = null; } if (_polySymbol == null) { _polySymbol = await CreatePolygonSymbolAsync(); } //we will use a Geometry in this example var pointsLayer = MapView.Active.Map.GetLayersAsFlattenedList().First( l => l.Name == "Points_For_Lines") as FeatureLayer; await QueuedTask.Run(() => { var mpBuilder = new MultipointBuilder(pointsLayer.GetSpatialReference()); var cursor = pointsLayer.GetFeatureClass().Search(); while (cursor.MoveNext()) { mpBuilder.Add(((Feature) cursor.Current).GetShape() as MapPoint); } //Can be cached safely if the Geometry is not changing var mp = mpBuilder.ToGeometry(); var buff = GeometryEngine.Buffer(mp, 50.0); _graphic = MapView.Active.AddOverlay(buff, _polySymbol.MakeSymbolReference()); }); } internal static Task<CIMPolygonSymbol> CreatePolygonSymbolAsync() { return QueuedTask.Run(() => { var outline = SymbolFactory.ConstructStroke(ColorFactory.BlueRGB, 2.0, SimpleLineStyle.Solid); return SymbolFactory.ConstructPolygonSymbol(ColorFactory.GreyRGB, SimpleFillStyle.Solid, outline); }); } }
... View more
08-01-2016
05:57 PM
|
2
|
0
|
3476
|
|
POST
|
Right, no I get what you are trying to do, the distinction I was trying to make in my original comment was that View Models created as Pro Framework elements -eg a View Model that is subclassed from ArcGIS.Desktop.Framework.Contracts.DockPane - (another example I gave was an embedded control but there are others) are created and managed by Pro - their lifecycle, datacontext, the whole smash. There are no substitutes (eg GalaSoft) for what Pro does via its Framework and no dependency injection for those classes. Now, if you had custom content, say a User Control and an associated proprietary View Model, that you wanted to re-use on "X" Dockpanes (eg - in the UserControl hosted on a Pro Dockpane you had a content provider to which you were binding your custom control) then this would be a relationship that you would manage as you wish within the limitations of Add-ins, etc.. I guess that was what I was trying to say. Of course, as you state, you can not create the "parent" "Pro" Dockpane and its user control (to which your custom User Control was bound) in a Unit Test scenario, or otherwise.
... View more
07-28-2016
05:53 PM
|
0
|
0
|
2648
|
|
POST
|
Dockpane is the correct way to go. The best you can do on the docking is dock to the application window (left, right, top, bottom) - it does not support docking to a Pane (map, layout, etc) as you mention. Conceptually, Pro has an Active pane (the one with focus). The TOC (amongst other things) keys off this and changes its contents to match whichever pane is active. Therefore, when you try to use a Pane (and not a ~dock~ pane), even though you get the docking behavior you want, activating your Pane de-activates the previously active pane (eg a map) and the TOC, seeing that ~your~ pane is not a mapview, it empties. There are special cases in Pro where the context needs to be maintained even though a MapView does not have focus. For example, if you open a layer attribute table the TOC remains unchanged and the MapView.Active property is still valid. In this case, the table pane instance (hosting the attribute table) is providing the proper context to the TOC (for the mapview that contains the layer whose attributes are being shown) to keep the TOC populated. However, the code to do that is all internal and is not exposed in the API. Currently there are no plans to support this.
... View more
07-28-2016
03:57 PM
|
0
|
5
|
3764
|
|
POST
|
Can you provide more information please: How many points in the collections and what is the size of the buffer? I will try and reproduce. I am assuming that there are no exceptions? That the code executes without failing (GP succeeds, Renderer definition is good, renderer is set with no errors)? Also: it is not possible to change the buffer symbol.
... View more
07-28-2016
03:44 PM
|
0
|
2
|
3476
|
|
POST
|
I am not sure I understand the reference to MVVM Light and ViewModelLocator??......however, the closest thing to that construct would be the DockpaneManager class and FrameworkApplication.DockPaneManager.Find("the id of the dockpane"). The returned DockPane is your ViewModel instance and it is a singleton. This pattern is also repeated in other aspects of Pro. For example, an Embedded Control if you are using such in a Map Tool, can be accessed via a MapTool's OverlayEmbeddableControl property: which also returns your ViewModel - again, a singleton. These are view models created by Framework from the definitions added to your Config.daml. You cannot create them. If you are referring to a ~custom~ view model - one that you are making rather than one defined in your Config.daml - then you are responsible for instantiating and passing that guy around. To make a property, method, instance, etc globally available within your Add-in you must add such a method or property to your Module class (to which all objects in your Add-in have access)
... View more
07-28-2016
03:38 PM
|
0
|
2
|
2648
|
|
POST
|
I can reproduce the tool behavior. Looks like a bug. Ideally, the developer could choose how he/she wants their tool to behave - either complete the sketch on MouseUp or require a second click. In part, this behavior is being inherited from the base class which is more geared for editing (rather than selection) where individual clicks (eg for digitizing) are required. Unfortunately you are getting a bit of both - one click the first time, two clicks subsequently. We will look at this for 1.4. I will speak with the developers about the possibility of a "popup window closed" event.
... View more
07-12-2016
02:58 PM
|
1
|
0
|
5548
|
|
POST
|
Hi Luke, yes, metadata is still planned for 1.4 however it will be off the layer and not the feature class.
... View more
07-06-2016
11:00 AM
|
0
|
9
|
3530
|
|
POST
|
I think you are missing the "SetDefinition" call on the layerdef. There is a snippet that shows what you want to do here: Change the layer selection color EDIT: sorry - looks like that snippet hasn't posted yet. This is it: var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(); ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => { // get the CIM definition of the layer var layerDef = featureLayer.GetDefinition() as ArcGIS.Core.CIM.CIMBasicFeatureLayer; // disable the default symbol layerDef.UseSelectionSymbol = false; // assign a new color layerDef.SelectionColor = ColorFactory.RedRGB; // apply the definition to the layer featureLayer.SetDefinition(layerDef); if (!featureLayer.IsVisible) featureLayer.SetVisibility(true); //Do a selection MapView.Active.SelectFeatures(MapView.Active.Extent); });
... View more
06-08-2016
04:09 PM
|
0
|
0
|
2552
|
|
POST
|
Oh, you need this guy too in your Module: /// <summary>Create a linesymbol with circle markers on the ends</summary> internal static Task<CIMLineSymbol> CreateLineSymbolAsync() { return QueuedTask.Run(() => { var lineStroke = SymbolFactory.ConstructStroke(ColorFactory.RedRGB, 4.0); var marker = SymbolFactory.ConstructMarker(ColorFactory.RedRGB, 12, SimpleMarkerStyle.Circle); marker.MarkerPlacement = new CIMMarkerPlacementOnVertices() { AngleToLine = true, PlaceOnEndPoints = true, Offset = 0 }; return new CIMLineSymbol() { SymbolLayers = new CIMSymbolLayer[2] { marker, lineStroke } }; }); }
... View more
04-29-2016
08:58 AM
|
0
|
0
|
2057
|
|
POST
|
In Pro, you need to use something called the "Overlay". If you look at the MapView class you will see methods to manipulate the overlay. MapTools have an extension method called "AddOverlayAsync" so that you can add a sketch to the overlay as a convenience rather than getting the MapView.Active. Here is some code - I copy-pasted it out of a sample we will be providing (amongst others) to show how to work with the Overlay. The easiest way to use it is to run the MapTool template in the SDK, delete out the entire contents of the code behind generated by the maptool template, copy this code into the code behind file. Change the class name back to the default (probably MapTool1 or something like that. Please let me know if you have questions. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ArcGIS.Core.CIM; using ArcGIS.Core.Geometry; using ArcGIS.Desktop.Framework.Threading.Tasks; using ArcGIS.Desktop.Mapping; namespace OverlayExamples { /// <summary> /// Show how to add a graphic to the overlay in either 2D or 3D. /// </summary> /// <remarks>Sketch a geometry. When the sketch is completed it is added to the /// overlay. When you begin sketching again or deactivate the tool the previous /// sketch is deleted</remarks> class AddOverlayTool : MapTool { private IDisposable _graphic = null; private CIMLineSymbol _lineSymbol = null; public AddOverlayTool() { IsSketchTool = true; SketchType = SketchGeometryType.Line; //Sketch a line geometry SketchOutputMode = SketchOutputMode.Map; } protected override Task OnToolDeactivateAsync(bool hasMapViewChanged) { if (_graphic != null) _graphic.Dispose();//Clear out the old overlay _graphic = null; return base.OnToolDeactivateAsync(hasMapViewChanged); } /// <summary> /// Occurs when the tool is activated. /// </summary> /// <param name="hasMapViewChanged">A value indicating if the active <see cref="T:ArcGIS.Desktop.Mapping.MapView"/> has changed.</param> /// <returns> /// A Task that represents a tool activation event. /// </returns> protected async override Task OnToolActivateAsync(bool hasMapViewChanged) { if (_lineSymbol == null) { _lineSymbol = await Module1.CreateLineSymbolAsync(); } this.SketchSymbol = _lineSymbol.MakeSymbolReference(); } protected override void OnToolMouseDown(MapViewMouseButtonEventArgs e) { if (_graphic != null) { _graphic.Dispose();//Clear out the old overlay _graphic = null; } base.OnToolMouseDown(e); } protected async override Task<bool> OnSketchCompleteAsync(Geometry geometry) { _graphic = await this.AddOverlayAsync(geometry, _lineSymbol.MakeSymbolReference()); return true; } } }
... View more
04-29-2016
08:57 AM
|
2
|
1
|
2057
|
|
POST
|
Hi Joseph, this is not supported in the API currently. It is planned for v1.4
... View more
04-29-2016
08:46 AM
|
0
|
1
|
3257
|
|
POST
|
Hi Luke, We have to edit the unique value renderer itself, once it has been made. I have provided some code below. Note: I encourage you to look at the samples for the CIM at https://github.com/esri/arcgis-pro-sdk-community-samples/tree/master/Map-Authoring/CIMExamples. I based the code snippet below on the source code in 'CreateCIMRendererFromScratch.cs'. It uses the U.S. States dataset available with the samples. internal class SetLabelsOnUniqueValueRenderer : Button { protected async override void OnClick() { var usStatesLayer = MapView.Active.Map.GetLayersAsFlattenedList().FirstOrDefault((fl) => fl.Name == "States") as FeatureLayer; if (usStatesLayer == null) { MessageBox.Show("Please add the 'States' layer to the TOC - with a 'STATE_NAME' field containing state names.", "Cannot find US States"); return; } //make a unique value renderer await CreateUniqueValueRendererOnStatesAsync(usStatesLayer); SetLabelsOnStatesRendererAsync(usStatesLayer); } private Task CreateUniqueValueRendererOnStatesAsync(FeatureLayer fl) { return QueuedTask.Run(() => { var uvrDef = new UniqueValueRendererDefinition() { ValueFields = new string[] {"STATE_ABBR"}, SymbolTemplate = SymbolFactory.DefaultPolygonSymbol.MakeSymbolReference(), //Simple ramp ColorRamp = new CIMLinearContinuousColorRamp() { FromColor = CIMColor.CreateRGBColor(0, 255, 0, 60),//Green, partially transparent ToColor = CIMColor.CreateRGBColor(255, 0, 0, 60),//Red, partially transparent ColorSpace = new CIMICCColorSpace() { URL = "Default RGB" } } }; fl.SetRenderer(fl.CreateRenderer(uvrDef)); }); } private Task SetLabelsOnStatesRendererAsync(FeatureLayer fl) { return QueuedTask.Run(() => { var renderer = fl.GetRenderer() as CIMUniqueValueRenderer; //A UniqueValue renderer has one or more CIMUniqueValueGroups. In this example //there is only one CIMUniqueValueGroup (otherwise use a 'foreach(var group in ....)' var group = renderer.Groups[0]; //Each group has one or more CIMUniqueValueClasses - in this case we have one class per //STATE_ABBR value. Note: The default value and label are on the renderer itself //(renderer.DefaultLabel, renderer.DefaultSymbol) and are NOT in a class. foreach (var valClass in group.Classes) { //Each CIMUniqueValueClass has a Label (what you are after 😉 and an array of CIMUniqueValues //As our values are unique, we have one CIMUniqueValue per class. //Get its field value (read from STATE_ABBR) and change the label to be the state name if (valClass.Values[0].FieldValues[0] == "AK") valClass.Label = "Alaska"; else if (valClass.Values[0].FieldValues[0] == "AL") valClass.Label = "Alabama"; else if (valClass.Values[0].FieldValues[0] == "AR") valClass.Label = "Arkansas"; else if (valClass.Values[0].FieldValues[0] == "AZ") valClass.Label = "Arizona"; //etc,etc } fl.SetRenderer(renderer); }); } }
... View more
04-07-2016
10:52 AM
|
0
|
1
|
1481
|
|
POST
|
Ted, try this (from http://converter.telerik.com/) Protected Overrides Sub OnToolMouseDown(e As MapViewMouseButtonEventArgs) If e.ChangedButton = MouseButton.Left Then e.Handled = True End If 'Let Framework know we want to handle MouseDown asynchronously End Sub Private _lastClickedMapPoint As MapPoint = Nothing Protected Overrides Function HandleKeyDownAsync(k As MapViewKeyEventArgs) As Task _lastClickedMapPoint = Await QueuedTask.Run(Function() ActiveMapView.ClientToMap(k.ClientPoint)) 'TODO - do something with _lastClickedMapPoint End Function Oh - I think also you are looking for the starting point - In Visual Studio, add a new project of type Module (within ArcGIS folder). In the project, right-click Add New Item, again in the ArcGIS folder pick MapTool or SketchTool.. There is more info here: https://github.com/esri/arcgis-pro-sdk/wiki/ProGuide-Build-Your-First-Add-in
... View more
03-25-2016
09:23 AM
|
1
|
0
|
3408
|
|
POST
|
The easiest way would be to create the layer using LayerFactory and then apply the symbology to the layer (you just created) using Geoprocessing.ExecuteToolAsync() and the layer file. Something like: var gpresult = await Geoprocessing.ExecuteToolAsync("ApplySymbologyFromLayer_management", new string[] {theNewLayerName,@"C:\Location\my_layer_file.lyr"}); Here are some links that might help: Apply Symbology From Layer Performing Geoprocessing Create and Add a Layer to the Active Map
... View more
03-03-2016
03:54 PM
|
0
|
1
|
1989
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 12 hours ago | |
| 1 | 3 weeks ago | |
| 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 |
13 hours ago
|