POST
|
Adding my voice here. AGP on .net framework has now become a hinderance in our development
... View more
03-13-2022
03:35 AM
|
0
|
3
|
826
|
POST
|
Thanks all - i have achieved a fair performance improvement using a combination of memory geodatabase + DDL API + insert cursor.
... View more
12-21-2021
05:40 AM
|
0
|
0
|
215
|
POST
|
// Works :
protected async Task MemDB_Geoprocessing()
{
string gdbPath = "memory";
//string gdbPath = CoreModule.CurrentProject.DefaultGeodatabasePath;
string featureclassName = "testFC";
string featureclassType = "POINT";
int spatialRefID = 20351; //Z51
var activeMap = MapView.Active.Map;
// 1) Create the Feature class table - use GP tools
var sr = SpatialReferenceBuilder.CreateSpatialReference(spatialRefID);
List<object> geoProcessingArgs = new List<object> { gdbPath, featureclassName, featureclassType, "", "DISABLED", "DISABLED", sr };
GPExecuteToolFlags flags = GPExecuteToolFlags.None | GPExecuteToolFlags.AddOutputsToMap;
IGPResult result = null;
var t = Task.Run(async () =>
{
result = await Geoprocessing.ExecuteToolAsync("CreateFeatureclass_management", Geoprocessing.MakeValueArray(geoProcessingArgs.ToArray()), null, null, null, flags);
});
await (t);
// 2) Set up attribute structure
int numFields = 64 / 2; // 64 fields, 1 each of type text, numeric
var fields = new Dictionary<string, string>();
for (int fldCnt = 0; fldCnt < numFields; fldCnt++)
{
fields.Add($"Field{fldCnt}", $"Text # 255 myDefaultValue");
fields.Add($"Field{fldCnt}_num", $"DOUBLE # # #");
}
AddFields(gdbPath + @"\" + featureclassName, fields);
// 3) Add some test point features to the Feature layer
var pointFeatureLayer = activeMap.FindLayers(featureclassName)[0] as FeatureLayer;
var featureAttribs = new Dictionary<string, object>();
Random rnd = new Random();
var createOp = new EditOperation() { Name = "Generate points", SelectNewFeatures = false };
long pointCnt = 0;
for (pointCnt = 0; pointCnt < 50*1000; pointCnt++) // for each new point feature
{
featureAttribs.Clear();
// geometry - random-ish coords
Coordinate2D newCoordinate = new Coordinate2D(320000 + rnd.Next(-1000, 1000), 7140000 + rnd.Next(-1000, 1000));
featureAttribs.Add("Shape", MapPointBuilder.CreateMapPoint(newCoordinate));
// attribute values
for (int fldCnt = 0; fldCnt < numFields; fldCnt++)
{
featureAttribs.Add($"Field{fldCnt}", $"SomeText{fldCnt}");
featureAttribs.Add($"Field{fldCnt}_num", fldCnt);
}
createOp.Create(pointFeatureLayer, featureAttribs); // queue feature creation
}
// commit features
Task<bool> tRes = createOp.ExecuteAsync(); // execute the batch edit operation
await (tRes);
if (!tRes.Result) throw new Exception(createOp.ErrorMessage);
Task tse = Task.Run(async () => { await Project.Current.SaveEditsAsync(); });
await(tse);
Task tz = Task.Run(async () => {
await MapView.Active.ZoomToAsync(pointFeatureLayer, false);
});
await(tz);
}
private void AddFields(string tableNamePath, Dictionary<string, string> fields)
{
string fieldNames = "";
List<object> geoProcessingArgs = null;
foreach (KeyValuePair<string, string> item in fields)
{
fieldNames = String.Format("{0}{1} {2}; ", fieldNames, item.Key, item.Value);
}
geoProcessingArgs = new List<object>{tableNamePath,fieldNames};
var t = Task.Run(async () =>
{
var result = Geoprocessing.ExecuteToolAsync("management.AddFields", Geoprocessing.MakeValueArray(geoProcessingArgs.ToArray()));
});
t.Wait();
}
... View more
12-10-2021
05:25 AM
|
0
|
1
|
1481
|
POST
|
I have got this working today actually. Using memory gdb has approximately doubled the performance, which is certainly an improvement. I'll post my working test harness code for reference, but would love to know if you can see how to improve significantly ? For example the geoprocessing call to create the empty featureclass seems to be taking longer than QGIS takes to create and display a 100k points layer - surely I am doing something wrong here? Also - I would be interested to see what the best practice equivalent would look like in the DDL API ? Thanks
... View more
12-10-2021
05:23 AM
|
0
|
3
|
1481
|
POST
|
Thanks Rich - are you aware of any c# examples ? i am struggling to get geoprocessing to work with memory geodb.
... View more
12-08-2021
08:17 PM
|
0
|
0
|
1492
|
POST
|
I'm getting ArcGis Pro (2.8.0) crashing during an EditOperation.ExecuteAsync() call from a .net add-in I dont see it with smaller files, but do with 250k newly created rows, each with approx 100 attributes. I saw an out-of-memory notification briefly I believe as AGP dissappeared. We do not see this issue on a 16gb test machine, but do see it on a 8gb dev machine Is this a known issue? any work arounds ?
... View more
12-08-2021
12:56 AM
|
0
|
0
|
279
|
POST
|
Thanks for those suggestions - shapefiles i think have some limitations, will look at in-mem database : It is not clear to me from documentation whether i can use existing geoprocessing-style code with an in-mem geodB, or whether i need to move all code over to the DDL API ?
... View more
12-07-2021
11:57 PM
|
0
|
0
|
1502
|
POST
|
Q1: Is there a faster mechanism to create a point layer in ArcGis Pro from a custom formatted data file in a .net add-in? Currently : I am loading data point programmatically from a custom file format, firstly into a data structure, I create a FeatureLayer in CurrentProject.DefaultGeodatabasePath [which seems to add to current map automatically] I then iterate the points data, creating with MapPointBuilder.CreateMapPoint() and adding with an EditOperation, and then commit using createOperation.ExecuteAsync() Then apply a renderer All good, BUT the commit operation is very slow : eg 10k points takes 20-30 secs, 100k points takes 3-5 minutes Q2 : Often this is an ephemeral/temp display layer - do i still need to create in the geoDB, or can i create in some faster, memory-only, map-only mechanism ? For reference on the same machine , our stats package would load and display 100k points on a map in 6-7 secs, QGIS plugin using the same mechanism would load & display 10k points in under 2 secs and the 100k points file in 10-11 secs Abbreviated Code : FeatureLayer pointFeatureLayer = [... create empty Feature layer using : Geoprocessing.ExecuteToolAsync("CreateFeatureclass_management",...]
AddFields(); // using Geoprocessing.ExecuteToolAsync("management.AddFields",.....
// add points & attributes :
var createOperation = new EditOperation();
createOperation.SelectNewFeatures = false;
[foreach source point record ]
{
featureAttribs = [..get point attribute values..]
// create the geometry & add the attribute values
MapPoint newMapPoint = null;
Coordinate3D newCoordinate = new Coordinate3D(x, y, z);
newMapPoint = MapPointBuilder.CreateMapPoint(newCoordinate, sref);
// add the geometry as an attribute
featureAttribs.Add("Shape", newMapPoint);
// queue feature creation
createOperation.Create(pointFeatureLayer, featureAttribs);
}
// then commit :
Task<bool> res = createOperation.ExecuteAsync();
[ create and apply CIMUniqueValueRenderer ]
... View more
11-30-2021
09:50 PM
|
0
|
11
|
1799
|
POST
|
Thanks Thomas , I have looked through the articles you referred to and checked out CIMViewer. Actually I cannot see how to achieve the desired state in the retail UI. For example, using your USA_Major_Cities dataset as an example of what i need to display, how would i set up symbology such as : 1) control symbol shape by the "Place Class" field [e.g. squares for cities, triangles for villages etc] plus 2) Control the symbol size by the "Avg Fam Sz" field plus 3) Control the symbol colour by a continuous range using the "Med Age M" field Note i want the fields to be independently controlled - there is no benefit to the user in symbolising the permutations of symbol shape/size/colour etc and in any case the permutations would run to hundreds/thousands; Alternatively is it possible to implement my own renderer ? thanks, Jack
... View more
03-29-2017
02:29 AM
|
0
|
1
|
1506
|
POST
|
I have a requirement for an addin that imports and displays points that have already been externally symbolised; i.e. the imported point data has attributes _Symbol, _Size, _Colour that can be translated to esri equivalents. I have been able to implement a CIMUniqueValueRenderer that will translate the _Symbol attribute value to appropriate symbol and that's working. Is it possible for the renderer to use separate attributes (_Size, _Colour) to set size and colour ? or perhaps is there some other technique to achieve this? I'd appreciate any pointers/example code.
... View more
03-23-2017
07:33 PM
|
0
|
8
|
3454
|
Online Status |
Offline
|
Date Last Visited |
03-14-2022
08:26 AM
|