|
POST
|
Thanks for the additional details. Since this only occurs in an iOS Release build and not in Debug, it seems more likely to be related to Release build configuration (linking, trimming, AOT, or LLVM optimizations) than the MMPK content itself. To help narrow down the cause, could you try the following, starting with the simplest checks? Test with the latest 200.8.2 release instead of 200.8.1 to determine whether the issue has already been addressed in a newer patch. Run a Release build on the simulator and a Debug build on a physical device to determine whether the behavior is tied to the build configuration or device architecture. What type of FeatureLayer.DisplayFilterDefinition is being used: manual or scale-based? What are the values of FeatureLayer.RenderingMode and FeatureLayer.TilingMode? Is FeatureLayer.DefinitionExpression, ServiceFeatureTable.DefinitionExpression, or FeatureLayer.FloorDefinition also set? If so, what values are being applied? For scale-based display filters, verify that the current MapView.MapScale falls within at least one authored display filter range. Compare the layer state between Debug and Release builds and check whether the active display filter changes or becomes null after loading. Inspect the MMPK JSON (.mmap) and confirm the layer's displayFilterInfo is present and contains the expected values for filterMode, filters, id, where, and activeFilterId. It would also be helpful to subscribe to GeoView.LayerViewStateChanged and capture the LayerViewStateChangedEventArgs for the affected layer. Specifically: Does LayerViewState.Error contain an exception? Is Layer.LoadError populated? Does LayerViewState.Status include any of: LayerViewStatus.Error, LayerViewStatus.Warning, LayerViewStatus.OutOfScale, LayerViewStatus.NotVisible If the issue still reproduces, please try the following Release-build configuration changes: Test with linking/trimming reduced or disabled. Test with LLVM disabled (and optionally enable the interpreter). If any of these checks or configuration changes affect the behavior, that would provide a useful workaround and help narrow down the root cause. Thanks.
... View more
3 weeks ago
|
0
|
2
|
173
|
|
POST
|
I think your overall approach is reasonable, but you may be able to simplify it. Rather than special-casing ArcGISFeatureTable, shapefiles, GeoPackages, etc., you can determine the ObjectID field from the table schema, then serialize the ObjectIDs of the selected features: var objectIdField = featureTable.Fields.FirstOrDefault(f => f.FieldType == FieldType.OID);
long objectId = Convert.ToInt64(feature.GetAttributeValue(objectIdField.Name)); To restore the selection, you could persist a mapping of FeatureTable.TableName (assuming it is unique in your application) to a list of selected ObjectIDs obtained from FeatureLayer.GetSelectedFeaturesAsync(). On reload, populate QueryParameters.ObjectIds with the saved IDs, query the matching features, and select them on the layer. This has a couple of advantages: You don't need to know the specific FeatureTable implementation to identify the key field. You can use QueryParameters.ObjectIds directly rather than constructing a potentially large WHERE ... IN (...) clause. Regarding the concern about large selections (100k+ features), any solution will need to persist enough information to identify those selected features. Storing ObjectIDs is about as compact as you can get, but the amount of data you save and restore will still scale with the size of the selection.
... View more
3 weeks ago
|
1
|
0
|
182
|
|
POST
|
There is currently no way from SubtypeSublayer to get to its parent layer. But if you have a feature from an identify or query, this feature has reference to the table, and the table has reference to the layer it comes from. As for the SubtypeSublayer.Id, in the Native SDKs this is meant to match the Subtype.code property. If you are using search.layer | Web Map Specification | Esri Developer, I think there's an optional subLayer property that will match SubtypeSublayer.Id. The "id" on this search is a string so it will not match the sublayer. There is however, a SubtypeSublayer.unsupportedJSON property that is deprecated and will be removed in the next release that contains the "id" string. JSON on the left can be web/mobile map, watch window on the right is from map loaded in Native SDK for .NET.
... View more
09-11-2025
01:30 PM
|
1
|
0
|
1201
|
|
POST
|
The query operations are on the FeatureLayer.featureTable property. ArcGISFeatureTable, you can use the Sublayer's subtype code as additional filter in your where clause or use SubtypeSubtable. Whether you're getting SubtypeFeatureLayer from web map or table that supports subtype, you can try the following code. Notice that for "Service Station" subtype (code: 21) on a Pipeline Device there's only 1 feature of this subtype out of 31411 features. var credential = await AccessTokenCredential.CreateAsync(new Uri("https://sampleserver7.arcgisonline.com/portal/sharing/rest"), "viewer01", "I68VGU^nMurF");
AuthenticationManager.Current.AddCredential(credential);
var geodatabase = new ServiceGeodatabase(new Uri("https://sampleserver7.arcgisonline.com/server/rest/services/UtilityNetwork/NapervilleGasV6/FeatureServer"));
await geodatabase.LoadAsync();
var table = geodatabase.GetTable(0);
var layer = new SubtypeFeatureLayer(table);
await layer.LoadAsync();
var sublayer = layer.SubtypeSublayers.LastOrDefault();
ArgumentNullException.ThrowIfNull(sublayer);
var query = new QueryParameters();
query.WhereClause = $"{table.SubtypeField} = {sublayer.Subtype.Code}";
ArgumentNullException.ThrowIfNull(layer.FeatureTable);
var features = await layer.FeatureTable.QueryFeaturesAsync(query);
var subtypeTable = new SubtypeSubtable(sublayer.Subtype);
table.SubtypeSubtables.Add(subtypeTable);
var subtypeFeatures = await subtypeTable.QueryFeaturesAsync(new QueryParameters() { WhereClause = "1=1" });
var count = await layer.FeatureTable.QueryFeatureCountAsync(new QueryParameters() { WhereClause = "1=1" }); Hm, there is no back-reference to the parent layer from SubtypeSublayer though. Can you describe your workflow, how you have access to the sublayer only but not have access to the layer?
... View more
09-11-2025
11:16 AM
|
0
|
1
|
1240
|
|
POST
|
Just adding to William's suggestion. Should you need to get more information about the GenerateOfflineMapJob and its subjobs, before awaiting for the job's result, you can subscribe and print out messages for the job. It may tell you more where it's failing. job.MessageAdded += (s, e) =>
{
System.Diagnostics.Debug.WriteLine($"{e.Severity}{e.Message}");
}; When you get this value - you can inspect what the current UtilityNetworkSyncMode, SyncModel, ContinueOnError properties as well before changing it. var gdbParameters = paramsOverride.GenerateGeodatabaseParameters[overrideKey];
... View more
06-06-2025
10:14 AM
|
1
|
0
|
1084
|
|
POST
|
Side note if you're on 11.1, there is a config file you can change to see this advanced option UI see step 4 here: Offline Utility Networks in ArcGIS Maps SDKs for Native Apps: Part 2 Offline Utility Networks in ArcGIS Native SDKs: Part 2 Update the config.js file to enable the utility network offline options on your ArcGIS Enterprise Portal. Find the Home App config.js file in your Portal installation directory. This can typically be found at the following location: C:\Program Files\ArcGIS\Portal\framework\webapps\arcgis#home\js\arcgisonline. Using a standard text editor, find the line that reads utilNetworkOfflineOptionsEnabledand change its value from false to true. Restart Portal for ArcGIS Enterprise.
... View more
04-02-2025
07:13 PM
|
0
|
0
|
2536
|
|
POST
|
I'm glad to have met you finally. Thank you for being an MVP! You've helped fellow developers and given us feedback to improve our API. I can't remember all now but the definition expression affecting `GetFeaturesForElementsAsync` is from you. Good to know it's working for you now. Jennifer
... View more
04-02-2025
07:08 PM
|
0
|
0
|
2536
|
|
POST
|
Hi Joe, It is possible for field crew without UN extensions to download edits from server by disabling editing capabilities on the feature service. You can check out the "Trace Offline (read-only)" in this part 4 of the blog series. The utility network sync mode for offline map is determined from this advanced offline setting of the portal item. This cannot be changed for ahead-of-time workflow with preplanned map area since the geodatabase is generated on the server and only downloaded on the client. But if you have 11.3 with the offline patch, there is a known limitation that it remains read-only despite the portal item advanced offline setting indicating "Trace and edit" for preplanned map area. If you are using on-demand workflow where you generate the offline map on the client by specifying an area of interest, you can still change this utility network sync mode using parameters override. This can also be found in our guide doc. var task = await OfflineMapTask.CreateAsync(map);
var parameters = await task.CreateDefaultGenerateOfflineMapParametersAsync(areaOfInterest);
var parametersOverride = await task.CreateGenerateOfflineMapParameterOverridesAsync(parameters);
var overrideKey = new OfflineMapParametersKey(map.UtilityNetworks[0]);
var geodatabaseParameters = parametersOverride.GenerateGeodatabaseParameters[overrideKey];
// simple features
geodatabaseParameters.UtilityNetworkSyncMode = UtilityNetworkSyncMode.None;
var job = task.GenerateOfflineMap(parameters, downloadDirectoryPath, parametersOverride);
var result = await job.GetResultAsync(); But I think if you want the ability to trace, this should be UtilityNetworkSyncMode.SyncSystemAndTopologyTables with a feature service that is read-only, which will allow you download-only sync. I hope this helps. Jennifer
... View more
04-02-2025
02:58 PM
|
0
|
0
|
2561
|
|
POST
|
Hi Pierre, I have not seen sluggish query when zooming in/out but I've seen the expected lock errors when editing the same version simultaneously from different apps. How are you creating the ServiceGeodatabase? If you're opening from a web map, there is a load setting that you can set to persistent if you wish to lock the version for editing. It is transient by default. If you've created from URL, be sure all layers and tables of the map come from the same service geodatabase. Use the service geodatabase to apply the edits (instead of table apply edits). More information about session management here. When starting from web map var map = new Map(new Uri(WebmapItemUrl));
map.LoadSettings = new LoadSettings() { FeatureServiceSessionType = FeatureServiceSessionType.Persistent }; When starting from feature service URL var sgdb = await ServiceGeodatabase.CreateAsync(featureServiceUrl, FeatureServiceSessionType.Persistent); // specify session mode Be sure to call close at the end when done with working on the branch version to release the read/write locks. var parameters = new ServiceVersionParameters()
{
Name = $"VALID_VERSION_{digits}",
Description = versionDescription,
Access = VersionAccess.Private
};
var serviceVersionInfo = await sgdb.CreateVersionAsync(parameters); // create version
await sgdb.SwitchVersionAsync(serviceVersionInfo.Name); // switch
var layer = sgdb.GetTable(serviceLayerId); // all layers/tables
await sgdb.CloseAsync(); // when done Opening the same version in ArcGIS Pro or Map Viewer will attempt to acquire read and write locks as well. On the server, there's purge lock and delete version that will allow you to cleanup versions that should be released and deleted.
... View more
03-17-2025
09:47 AM
|
1
|
0
|
1218
|
|
POST
|
Hi Joe,
The ExportDeltaAsync is based on the last sync time on the geodatabase. I just tested the following code, if there's a syncGeodatabase happened in between, no delta is created. Code snippet against sample server is shared below.
HasEdits only reset after edits are applied/sync'd or undone/rolled back. Edits in a mobile geodatabase can be wrapped in explicit transaction by gdb.Begin/Commit/RollbackTransaction().
If you're uploading client delta a different way, the API will not have information about the last acknowledged update to compare with the edit and gdb tracking fields. Geodatabase.hasLocalEdits(), ArcGISFeatureTable.hasLocalEdits() and ArcGISFeatureTable.getLocalEditsAsync() are all based on this time. There's a GeodatabaseFeatureTable.getHasLocalEditsSince() with DateTimeOffset parameter that you could use but it only returns boolean.
Is there something in the current sync workflow that can be improved to support your custom sync processes?
private const string FeatureServiceUrl = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Sync/SaveTheBaySync/FeatureServer";
private async Task TestExportDeltaAsync(bool syncBeforeExport = false)
{
try
{
var task = await GeodatabaseSyncTask.CreateAsync(new Uri(FeatureServiceUrl));
var areaOfInterest = task.ServiceInfo?.FullExtent;
ArgumentNullException.ThrowIfNull(areaOfInterest);
var parameters = await task.CreateDefaultGenerateGeodatabaseParametersAsync(areaOfInterest);
var pathToGeodatabase = $@"C:\dev\gdb\{Guid.NewGuid()}.geodatabase";
Debug.WriteLine(pathToGeodatabase);
var job = task.GenerateGeodatabase(parameters, pathToGeodatabase);
var gdb = await job.GetResultAsync();
// introduce an edit
areaOfInterest = gdb.GenerateGeodatabaseGeometry?.Extent;
ArgumentNullException.ThrowIfNull(areaOfInterest);
if (gdb.GetGeodatabaseFeatureTable(0) is GeodatabaseFeatureTable table)
{
await table.LoadAsync();
if (table.GeometryType == GeometryType.Point
&& table.FeatureTypes.Count > 0
&& !string.IsNullOrEmpty(table.LayerInfo?.DisplayFieldName))
{
var random = new Random();
var index = random.Next(0, table.FeatureTypes.Count - 1);
var featureType = table.FeatureTypes[index];
double x = areaOfInterest.XMin + random.NextDouble() * areaOfInterest.Width;
double y = areaOfInterest.YMin + random.NextDouble() * areaOfInterest.Height;
var point = new MapPoint(x, y, areaOfInterest.SpatialReference);
var feature = table.CreateFeature(featureType, point);
feature.SetAttributeValue(table.LayerInfo.DisplayFieldName, $"Added on {DateTimeOffset.UtcNow}");
await table.AddFeatureAsync(feature);
}
}
if (syncBeforeExport)
{
var syncParameters = await task.CreateDefaultSyncGeodatabaseParametersAsync(gdb);
var syncJob = task.SyncGeodatabase(syncParameters, gdb);
await syncJob.GetResultAsync();
}
var deltaPath = $@"{gdb.Path.Replace(".geodatabase", "")}-delta.geodatabase";
var hasDeltaExported = await GeodatabaseSyncTask.ExportDeltaAsync(gdb, deltaPath);
Debug.WriteLine($"Exported? {hasDeltaExported}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private async void OnExportDelta(object sender, RoutedEventArgs e)
{
await TestExportDeltaAsync(true);
await TestExportDeltaAsync(false);
}
Thanks.
Jennifer
... View more
09-25-2024
11:21 AM
|
0
|
0
|
755
|
|
POST
|
No problem. The NumberOfFeatures would be a cumulative value of the features retrieved in the table so far. So if you have this table rendered as a layer on a map, a query with view extent would have already run to fetch features. Or if you had previous queries made with different fips value. There is a QueryFeatureCountAsync method if you only want the count for features from a specific query. But if you will be working on the features returned from QueryFeaturesAsync then you can use features.Count() instead where features is the return value of the awaited query task.
... View more
07-24-2024
07:32 AM
|
1
|
0
|
1692
|
|
POST
|
I don't see anything wrong with how you formed the query. String equality looks correct provided the field exists with the correct name and type. If you want query to return just one, you can set MaxFeatures = 1; but if you say this value is unique then you should expect a single feature returned without MaxFeatures. var attributeValue = "270530265081";
var table = BlockGroupGeoPackage.GeoPackageFeatureTables[0];
var tableField = table.GetField("fips");
var query = new QueryParameters()
{
WhereClause = $"{tableField.Name} = '{attributeValue}'",
MaxFeatures = 1
};
I would await the result of query though and may be inspect the features that come back. Output window should have the attribute value for each feature. var features = await table.QueryFeaturesAsync(query);
foreach(var feature in features)
{
// Consider printing other attributes to identify the feature (i.e. OBJECTID)
System.Diagnostics.Debug.WriteLine($"{tableField.Name}: feature.Attribute[tableField.Name]")
}
... View more
07-23-2024
06:26 PM
|
0
|
2
|
1760
|
|
POST
|
I do not see anything wrong with your code that could've led to this error. Just a suggestion (but likely not relevant to the error you're seeing) since you are awaiting the result of syncJob.GetResultAsync() already in a try-catch. There is no need to call syncJob.Start() or handle success/fail in JobChanged. Based on the API name, I think you are using an older version of ArcGIS Maps SDK for .NET. One thing I would like to suggest (if you're able) is try the same request with latest 200.4. The equivalent event for JobChanged is StatusChanged. There is also a MessageAdded that could provide some insight at what stage this error happens (if it still happens). There could be a number of things that could result to this generic server error. Are you able to inspect ArcGISWebException.Details property? According to this doc, one possibility is the replica GUID no longer exists on server. If you have access to the ArcGIS Server Logs, it may give more information on the GP Server error. You can also see if you are hitting these support issues: https://support.esri.com/en-us/knowledge-base/error-code-400-description-unable-to-complete-operation-000020342 https://support.esri.com/en-us/knowledge-base/problem-unable-to-sync-services-in-arcgis-server-000027501 Another case that I've seen in my sync testing, it's possible for sync to fail to acquire the necessary lock to apply delta changes or have synchronization conflicts that need to be resolved.
... View more
06-04-2024
09:17 AM
|
0
|
0
|
996
|
|
POST
|
Thanks for following-up and sharing with us the root of the problem. I am curious to know how the table was created and why ServiceGeodatabase do not see this edit. If you loaded the feature service from a webmap or called ServiceGeodatabase.getTable() to create the ServiceFeatureTable, the ServiceFeatureTable will have a ServiceGeodatabase property. You'd see ServiceGeodatabase.connectedTables include this table. Your feature should have access to the same ServiceGeodatabase. If however, you used a ServiceFeatureTable constructor, then the table will not have a ServiceGeodatabase. You can add a check to ServiceGeodatabase.hasLocalEdits() or ServiceFeatureTable.hasLocalEdits(), before calling the appropriate applyEdits. If this returns false, there are no edits to send to server. It is best to use ServiceGeodatabase, for these reasons: https://developers.arcgis.com/net/edit-features/apply-edits/ if (feature.FeatureTable is ServiceFeatureTable sft && sft.ServiceGeodatabase is ServiceGeodatabase sgdb)
{
if (sgdb.HasLocalEdits())
{
await sgdb.ApplyEditsAsync();
}
}
... View more
04-08-2024
09:13 AM
|
0
|
0
|
2106
|
|
POST
|
Could your ApplyEdits be wrapped in a try-catch? Can you see if exception has message/details? Could the new feature be rejected by server because of geometry (has or lack of m/z-value, spatial reference, outside layer extent) or attributes (any unspecified required fields, data type mismatch, domain errors, or perhaps constraint rule violation)? Few other things you can try: After addFeatureAsyc, check getAddedFeaturesCountAsync to ensure new feature was added. Before applyEdits subscribe to ArcGISHttpClientHandler events: HttpBeginRequest and HttpResponseEnd. You can check request URI on Begin to ensure an /applyEdits request was made. And read content as string on End to ensure an appropriate server response in JSON was received. This should provide objectid or globalid when successful or an error code/message. If the message is the generic unable to complete, you can check server logs for verbose message if you have access to the server.
... View more
04-05-2024
06:37 AM
|
1
|
1
|
2153
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 3 weeks ago | |
| 1 | 09-11-2025 01:30 PM | |
| 1 | 06-06-2025 10:14 AM | |
| 1 | 03-17-2025 09:47 AM | |
| 1 | 07-24-2024 07:32 AM |
| Online Status |
Offline
|
| Date Last Visited |
3 weeks ago
|