Download - Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Transcript
Page 1: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Extending ArcGIS Pro with .NET and

Python: Interactive Analytics

Carlos A. Osorio-Murillo

Mark Janikas

Page 2: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Introduction

• ArcGIS Pro is highly customizable. From an application perspective, .NET can be used to

construct buttons, ribbons and tool specific user interfaces. Through the use of Python and

Geoprocessing, your desired functionality can run both in demand and interactively with

the .NET extension you created. This session introduces the key concepts necessary to

get started with extending your ArcGIS Pro Application and provides a clear case study of

interactive analytics to show you the power of the strategies outlined.

Page 3: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Objectives.Net & Python

• Integrate .Net and Python for improving workflows

• Powering a Density-Based Clustering method (OPTICS) through an Add-in

• Quick demo how to create an Add-in Visual Studio

Page 4: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Unsupervised learning methods

Density-Based

Clustering

DBSCAN OPTICS HDBSCAN

Find representavives groups

Which criteria depends of user

Partition

(Kmean)

Spatially constrain

(SKATER)

Page 5: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Density-based Clustering

Three clustering algorithms

Fast

Automatic Detection

Interactive

Page 6: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

OPTICS Process

• Produce a special order of the database with a density-base clustering structure

• God for both automatic and interactive cluster analysis, including finding intrinsic

clustering structure

• Can be represented graphically (Plot)

arcpy.DensityBasedClustering_stats()

Page 7: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

OPTICS Processarcpy.DensityBasedClustering_stats()

(Generate Reachability information)

Cluster detection

Map clustering

(Applying color

exclusion schema)

Page 8: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Python Tool for Detecting cluster

def execute(self, parameters, messages):import SSCluster as SSCimport SSDataObject as SSDOimport numpy as NUM

#### Get Parameters ####inputFC = parameters[0].valueAsText minPoints = int(parameters[1].valueAsText)tolerance = int(parameters[2].valueAsText)threshold = int(parameters[3].valueAsText)

#### Allow overwrite Output ###ARCPY.env.overwriteOutput = True

#### Load Data ####ssdo = SSDO.SSDataObject(inputFC)ssdo.obtainData(fields = ["REACHORDER","REACHDIST"])

#### Sort Reachability Order ###ord = ssdo.fields["REACHORDER"].data

#### Get Reachability Distances ####reachValues = ssdo.fields["REACHDIST"].data

#### Sorting by Index ####data = NUM.zeros((len(reachValues), 2), dtype= float)data[:, 0] = reachValues data[:, 1] = ordodata = data[data[:,1].argsort()]

Page 9: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

OPTICS as an

extension of DBSCAN

Distance Threshold

Not enough minimum number

of points to be considered

Clusters

#### Function to get DBSCAN Clusters ####def getDBSCAN(distances, threshold, minPoints, orderValues):

clusterArr = NUM.ones(len(distances), dtype = int)*-1indices = distances <= thresholdini = end = 0clusterIndex = 1c = 1for i in NUM.arange(len(indices)-1):

if indices[i] and indices[i] == indices[i+1]:if c == 1:

ini = ic += 1end = i + 1

else:if (end-ini) >= minPoints-1:

clusterArr[ini:end+1] = clusterIndexclusterIndex += 1ini = end = 0c = 1

return clusterArr[orderValues]

Page 10: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

OPTICS Tolerance

Merged clusters

Cluster shape

import SSCluster as SSC#### Initialize Detect Zone Class ####zones = SSC.DetectZones()

#### Get Cluster By Tolerance ###idClusters, idColor = zones.getClusters(reachValues,

orderValues,minPoints, tolerance)

Arcgis Pro Python Module

Page 11: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Interactive Clustering detection

through Add-in

and Python

Page 12: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Addin

DemoDetecting clusters

https://github.com/Esri/ExampleDotNetAndPythonForAnalytics

Page 13: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Add-in Creation using Visual Studio

Resources

https://github.com/Esri/arcgis-pro-sdk/wiki/ProGuide-

Build-Your-First-Add-in

Page 14: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Add-in Creation using Visual Studio

Page 15: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Creating an Add-in Demo

Page 16: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Design Control WPFComboBox

Slider

TextBox

<UserControl x:Class="InteractiveAnalytics.Dockpane1View"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:ui="clr-namespace:InteractiveAnalytics"xmlns:extensions="clr-namespace:ArcGIS.Desktop.Extensions;assembly=ArcGIS.Desktop.Extensions"mc:Ignorable="d"d:DesignHeight="400" d:DesignWidth="300"d:DataContext="{Binding Path=ui.Dockpane1ViewModel}">

…..

Dockpanel

Page 17: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Add-in Events

Add-In UI App

GetLayersInMap()

GeoprocessingToolbox/Tool

UpdateClusters()

Python

Update Dataset

Update Simbology()

Async method

Time line

Page 18: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

GetLayersInMap()

internal async void GetLayersInMap(){

if (MapView.Active == null)return;

var currentMap = MapView.Active.Map;var layers = currentMap.GetLayersAsFlattenedList();List<FeatureLayer> featureLayers = new List<FeatureLayer>();foreach (Layer lyr in layers){

if (lyr is FeatureLayer){FeatureLayer flyr = lyr as FeatureLayer;bool check = true;check = (flyr.ShapeType == esriGeometryType.esriGeometryPoint);if (check){

/// Layer should contain Reachability distance fieldint hasClusteredOpticLayer = await QueuedTask.Run<int>(() =>{return flyr.GetTable().GetDefinition().FindField("REACHDIST");

});

if (hasClusteredOpticLayer >= 0)featureLayers.Add(flyr);

}}

}_layers = featureLayers;NotifyPropertyChanged(() => Layers);

}

Obtain Point Layers with

a specific field

await QueuedTask.Run<int>(() =>{

return flyr.GetTable().GetDefinition().FindField("REACHDIST");});

check = (flyr.ShapeType == esriGeometryType.esriGeometryPoint);

Page 19: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

UpdateClusters()

internal async void UpdateCluster(bool isTolerance){

if (MapView.Active == null)return;

// Get Layer Namestring inputFC = SelectedLayer.Name;int minPoints = 2;bool parsed = Int32.TryParse(MinPoints, out minPoints);// Set PYT path string tool_path ="C:\\PATH\\UpdateCluster.pyt\\UpdateClusterTool";IReadOnlyList<string> args= null;if (isTolerance){

/// Arguments for executing process using Toleranceargs = Geoprocessing.MakeValueArray(inputFC, minPoints, ValueSlider, -1);

}else{

/// Arguments for executing process using Thresholdargs = Geoprocessing.MakeValueArray(inputFC, minPoints, -1, ValueThreshold);

}

Task<IGPResult> task;/// Execute the Tool in the python toolboxtask = Geoprocessing.ExecuteToolAsync(tool_path, args, flags: GPExecuteToolFlags.AddToHistory);

task = Geoprocessing.ExecuteToolAsync(tool_path, args, flags: GPExecuteToolFlags.AddToHistory);

string tool_path ="C:\\PATH\\UpdateCluster.pyt\\UpdateClusterTool";

Page 20: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Update Simbology

await QueuedTask.Run( () =>{/// Search for a specific Symbol/// Other styles Arcgis/Resouces/Styles/Styles.stylx SQLite DBSymbolStyleItem symbolStyleItem = (SymbolStyleItem)style.LookupItem(StyleItemType.PointSymbol, "Circle 1_Shapes_3");pointSymbol = (CIMPointSymbol)symbolStyleItem.Symbol;

/// Cluster Ids based in Color Schemaint[] ids = new int[] { -1, 1, 2, 3, 4, 5, 6, 7, 8 };

/// Set Colorsstring[] colors = new string[]{ "156,156,156", "166,206,227", "31,120,180", "178,223,138",

"51,160,44", "251,154,153", "227,26,28", "253,191,111","255,127,0" };

/// Color FieldString[] fields = new string[] { "COLOR_ID" };

/// Make a reference of the point symbolCIMSymbolReference symbolPointTemplate = pointSymbol.MakeSymbolReference();

/// Get definition of type symbology unique valuesUniqueValueRendererDefinition uniqueValueRendererDef = new UniqueValueRendererDefinition(fields, symbolPointTemplate, null, symbolPointTemplate, false);

/// Get Current renderer of the Selected Layer CIMUniqueValueRenderer renderer = (CIMUniqueValueRenderer)SelectedLayer.CreateRenderer(uniqueValueRendererDef);CIMUniqueValueClass[] newClasses = new CIMUniqueValueClass[colors.Count()];

/// Get Point Symbol as string for creating other point colors string point = pointSymbol.ToXml();

/// Create Each Color for (int i = 0; i < ids.Length; i++){CIMPointSymbol npoint = CIMPointSymbol.FromXml(point);if (ids[i] == -1){npoint.SetSize(4);

}else{npoint.SetSize(6);

}CIMSymbolReference symbolPointTemplatei = npoint.MakeSymbolReference();newClasses[i] = new CIMUniqueValueClass();newClasses[i].Values = new CIMUniqueValue[1];newClasses[i].Values[0] = new CIMUniqueValue();newClasses[i].Values[0].FieldValues = new string[1];newClasses[i].Values[0].FieldValues[0] = ids[i].ToString();newClasses[i].Label = ids[i].ToString();newClasses[i].Symbol = symbolPointTemplatei;var color = colors[i].Split(',');double r = Convert.ToDouble(color[0]);double g = Convert.ToDouble(color[1]);double b = Convert.ToDouble(color[2]);newClasses[i].Symbol.Symbol.SetColor(CIMColor.CreateRGBColor(r, g, b));

}/// Add Colors into the rendererrenderer.Groups[0].Classes = newClasses;

/// Apply new renderer in the layerSelectedLayer.SetRenderer(renderer);

//SelectedLayer.RecalculateRenderer();});

UniqueValueRendererDefinition uniqueValueRendererDef = new UniqueValueRendererDefinition(fields, symbolPointTemplate, null, symbolPointTemplate, false);

CIMUniqueValueRenderer renderer = (CIMUniqueValueRenderer)SelectedLayer.CreateRenderer(uniqueValueRendererDef);

SymbolStyleItem symbolStyleItem = (SymbolStyleItem)style.LookupItem(StyleItemType.PointSymbol, "Circle 1_Shapes_3");

renderer.Groups[0].Classes = newClasses;SelectedLayer.SetRenderer(renderer);

Page 21: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Conclusions

- Add-in can improve Geoprocessing Tools (Density-Based Clustering)

- Easy way to join Python Scripts and .Net through an Add-in

- ArcGIS Pro SDK Extension in Visual Studio great tool to initial Add-in

Page 22: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,

Thank you

https://github.com/Esri/ExampleDotNetAndPythonForAnalytics

Page 23: Extending ArcGIS Pro with .NET and Python: Interactive ...€¦ · Extending ArcGIS Pro with .NET and Python: Interactive Analytics, 2018 Esri Developer Summit Palm Springs -- Presentation,