private void ButtMultiAnalyzeDiffClick(object sender, RoutedEventArgs e) { try { var layerNames = new List<string>(); var allFieldNames = new List<string>(); foreach (string s in this.lbChangeLayers.SelectedItems) { if (!layerNames.Contains(s)) { layerNames.Add(s); } } if (this.lbChangeLayers.SelectedItems.Count < 2) { MessageBox.Show("Please select at least two layers"); return; } var colsMappingForMsgBox = new Dictionary<string, string>(); var uniqueFieldNames = new Dictionary<string, string>(); var multiResult = new PivotTable(); var analyzer = new PivotTableAnalyzer(this.UpdatePBar, this.SetPBarProperties); for (var i = 0; i < layerNames.Count; i++) { for (var x = i + 1; x < layerNames.Count; x++) { var layerA = layerNames[i]; var layerB = layerNames[x]; colsMappingForMsgBox.Add("L" + i + "_" + x + "L", layerA + " --> " + layerB); if (layerA == null || layerB == null) { MessageBox.Show("no layers available"); } var layers = this.GetFeatureLayersFromToc(this.GetActiveViewFromArcMap(ArcMap.Application)); // getSelectedFeatureFromLayerByName(layers, "somename"); var flayerA = this.GetLayerByName(layers, layerA); var flayerB = this.GetLayerByName(layers, layerB); this.pbarChangeDet.Value = 0; this.UpdateStatusLabel("Preparing " + layerA); Application.DoEvents(); var ignoreCols = new List<string> { "OBJECTID", "SHAPE", "SHAPE_Length", "SHAPE_Area" }; var ptA = this.FeatureLayerToPivotTable(flayerA, "GeoHash", ignoreCols); this.UpdateStatusLabel("Preparing " + layerB); Application.DoEvents(); var ptB = this.FeatureLayerToPivotTable(flayerB, "GeoHash", ignoreCols); this.UpdateStatusLabel("Calculating change"); Application.DoEvents(); var res = analyzer.DetectChange(ptA, ptB, "L" + i + "_" + x + "L", false); foreach (var entry in res) { if (!entry.Data.ContainsKey("layerAIndex")) { entry.Data.Add("layerAIndex", i); } if (!entry.Data.ContainsKey("layerBIndex")) { entry.Data.Add("layerBIndex", i); } entry.Label = "L" + i + "_" + x + "L"; foreach (var name in entry.Data.Keys) { if (!allFieldNames.Contains(name)) { allFieldNames.Add(name); } if (!uniqueFieldNames.ContainsKey(name)) { uniqueFieldNames.Add(name, name); } } break; } multiResult.AddRange(res); } } var flat = analyzer.flattenAndSimplify(multiResult, "percent_change"); uniqueFieldNames = new Dictionary<string, string>(); foreach (var pte in flat) { var vals = new List<double>(); foreach (var field in pte.Data.Keys) { vals.Add(pte.Data[field]); } pte.Data.Add("stdev_", analyzer.stdev(vals)); pte.Data.Add("avg_", analyzer.avg(vals)); pte.Data.Add("min_", analyzer.min(vals)); pte.Data.Add("max_", analyzer.max(vals)); foreach (var field in pte.Data.Keys) { if (!uniqueFieldNames.ContainsKey(field)) { uniqueFieldNames.Add(field, field); } } } var ws = Jarvis.OpenWorkspace(Settings.Default.geoDatabase); var fcName = "multi_change_" + DateTime.Now.Millisecond; // uniqueFieldNames.Add("context_str", "context_str"); var featureClass = Jarvis.CreateStandaloneFeatureClass(ws, fcName, uniqueFieldNames, false, 0); var insertCur = featureClass.Insert(true); this.UpdateStatusLabel("Loading Output Feature Class"); Application.DoEvents(); this.InsertPivoTableRowsToFeatureClass(featureClass, flat, uniqueFieldNames); this.AddLayerToArcMap(fcName); this.pbarChangeDet.Value = 0; this.lblPbarStatus.Content = "Done"; var message = "FYI:\n"; foreach (var colName in colsMappingForMsgBox.Keys) { message += "Column " + colName + " represents change for " + colsMappingForMsgBox[colName] + "\n"; } message += "\n*This is required because of field length limitations"; MessageBox.Show(message); Application.DoEvents(); // now I need to create a feature class and feature layer from this object } catch (Exception ex) { MessageBox.Show("An error occured calculating change" + ex.Message); } }