|
POST
|
You can use the vector tile package in Runtime, but it cannot be queried. It is just lines and labels, there is no data behind it (at least that is my understanding)
... View more
07-31-2019
02:55 PM
|
0
|
1
|
1325
|
|
POST
|
So you are saying that one cannot run the Python API on a machine that does not have ArcGIS Pro installed? That is a a very limiting restriction. Logging into Portal should provide the required license.
... View more
07-31-2019
07:38 AM
|
0
|
1
|
4601
|
|
POST
|
Are you sure it's a Within and not a Contains. Personally I always play around with those spatial relationships because they never seem to work like I think they should. Also in general I think using FirstOrDefault and checking for null is a cleaner approach, as opposed to capturing an exception.
... View more
07-26-2019
10:45 AM
|
0
|
0
|
1967
|
|
POST
|
With Layers it is based on order added to the Layers collection, last in is on top. So index zero is on top, I would assume GraphcsOverlay is the same but I have never had a case of overlap with graphics to confirm that. OperationalLayers has an Insert method, so you put layers in a specific order instead of just using Add
... View more
07-26-2019
07:20 AM
|
2
|
0
|
2570
|
|
POST
|
At the bottom under attachments is the IdentifyAction.cs.zip. i. Implement a graphics identify in a identical pattern
... View more
07-25-2019
08:57 PM
|
0
|
0
|
2911
|
|
POST
|
It's a fun exercise in architecture, and took me a few iterations to find something I was completely happy with in the limitations of the MapView needing to display the callout. The MapView is a control so while it is possible to pass this to other parts of the application, it would break some MVVM principle (imo - although I have gone back and forth on this). The approach I have used does require eventing, and so some outside framework is needed. I use Prism, but MVVMLight would work. Because the MapView is a control, it is not against MVVM to have code in the code behind of the View that contains the MapView control. All the methods that actually display the popup are in in the MapView's code behind. The code to identify is implemented as a custom TriggerAction which is attached to the MapView. I have attached the IdentifiyAction code. In Xaml of the MapView <esri:MapView x:Name="MapView" Map="{Binding Map}" GraphicsOverlays="{Binding GraphicsOverlays}"
SketchEditor="{Binding SketchEditor}"
framework:MapViewExtensions.MapViewController="{Binding MapViewController}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GeoViewTapped">
<identify:IndentifyAction Map="{Binding Map}" EventAggregator="{Binding EventAggregator}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</esri:MapView> The EventAggregator is passed into the Action so it can fire off when the identify is completed and send the results. In the code behind of the View that contain MapView the callout is displayed. The Action passed in a custom arguments parameter which can really be defined however is needed private void OnShowCallout(ShowCalloutEventArgs obj)
{
try
{
MapView.ShowCalloutAt(obj.Location, obj.Callout);
}
catch (Exception e)
{
_log.Error(e.Message, e);
}
}
... View more
07-25-2019
12:14 PM
|
0
|
2
|
2911
|
|
POST
|
Also not sure if this is still a concern. The way you generate the delta is with the rest API https://developers.arcgis.com/rest/services-reference/synchronize-replica.htm. You could do through python or in C# with HttpClient. This is some code that does in C#, most of everything is here, excluding some custom objects that define some of the basics which I think can be figured out. //returns the Url of the delta file which is used by the calling method to download
public async Task<string> SyncronizeReplicaAsync(ReplicaDefinition replicaDefinition)
{
try
{
ArcGISHttpClientHandler handler = new ArcGISHttpClientHandler { ArcGISCredential = await _portalManager.Credential(true) };
using ( var client = new HttpClient(handler) )
{
try
{
var featureServiceUrl = new Uri($"{FeatureServiceUrl(replicaDefinition)}?f=json");
var get = await client.GetStringAsync(featureServiceUrl);
}
catch (Exception)
{
_log.Warn($"Could not connect to Url: {FeatureServiceUrl(replicaDefinition)}");
return null;
}
//This gets the replica url wich is featureserviceUrl/replicaId
var requestUri = new Uri($"{FeatureServiceUrl(replicaDefinition)}/synchronizeReplica");
var parameters = new Dictionary<string, string>
{
{"f", "json"},
{"async", "true"},
{"dataFormat", "sqlite"},
{"replicaID", replicaDefinition.ReplicaId.ToLower()},
{"rollbackOnFailure", "false"},
{"syncLayers", await GetSyncLayersAsync(replicaDefinition)},
{"transportType", "esriTransportTypeUrl"}
};
var content = new FormUrlEncodedContent(parameters);
//This sends off the sync request to the server
var response = await client.PostAsync(requestUri, content);
if ( !(response.Content is ByteArrayContent byteArrayContent) ) return null;
var json = await byteArrayContent.ReadAsStringAsync();
var status = JsonConvert.DeserializeObject<StatusResponse>(json);
var resultUrl = await CheckJobAsync(replicaDefinition, status);
return resultUrl;
}
}
catch (Exception e)
{
_log.Error(e.Message, e);
return null;
}
}
// I have some custom objects that mimic responses and use json deserializer to convert to .net objects
private async Task<string> CheckJobAsync(ReplicaDefinition replicaDefinition, StatusResponse status)
{
JobResponse job = null;
ArcGISHttpClientHandler handler = null;
try
{
while ( true )
{
handler = new ArcGISHttpClientHandler {ArcGISCredential = await _portalManager.Credential(false)};
using (var client = new HttpClient(handler))
{
//This is a periodic check of the Job status
var requestUri = new Uri($"{status.StatusUrl}?f=json");
var json = await client.GetStringAsync(requestUri);
job = JsonConvert.DeserializeObject<JobResponse>(json);
// When job is complete the respence incluses the Url of the delta database
if ( job.JobStatus == JobStatus.Completed ) break;
if ( job.JobStatus == JobStatus.Failed )
{
_log.Warn($"Job failed: {replicaDefinition.Name}");
return null;
}
if ( job.JobStatus == JobStatus.Other )
{
_log.Warn($"Job unknown: {replicaDefinition.Name}");
return null;
}
await Task.Delay(TimeSpan.FromSeconds(5));
}
}
}
catch (ArcGISWebException e)
{
if ( handler?.ArcGISCredential is TokenCredential tokenCredential )
{
_log.Error($"{e.Message}: {tokenCredential.ExpirationDate?.LocalDateTime:hh:mm:ss}");
}
else
{
_log.Error(e.Message, e);
}
}
catch (Exception e)
{
_log.Error(e.Message, e);
}
return job?.ResultUrl;
}
// Gets the layer array required by the syncronizeReplica request
private async Task<string> GetSyncLayersAsync(ReplicaDefinition replicaDefinition)
{
try
{
var handler = new ArcGISHttpClientHandler { ArcGISCredential = await _portalManager.Credential(false) };
using ( var client = new HttpClient(handler){Timeout = TimeSpan.FromMinutes(5)} )
{
var requestUri = new Uri($"{FeatureServiceUrl(replicaDefinition)}/replicas/{replicaDefinition.ReplicaId}?f=json");
var response = await client.GetStringAsync(requestUri);
var jObject = JObject.Parse(response);
var syncLayers = JsonConvert.DeserializeObject<IEnumerable<SyncLayer>>(jObject["layerServerGens"].ToString()).ToArray();
foreach (var syncLayer in syncLayers)
{
syncLayer.SyncDirection = "download";
}
//Setting to allow to sync back beyond last sync time
// The serverGen parameter is actually the time stamp that the syncronizeReplica looks back into the past
// by default this is retrieved from the replica definition.
//This is logic to allow us to push that time back in case we need to go further to the past
if (_appSettings.DownloadSyncBack)
{
long time = (DateTimeOffset.UtcNow - TimeSpan.FromDays(_appSettings.DownloadDaysBack)).ToUnixTimeMilliseconds();
foreach (var syncLayer in syncLayers)
{
syncLayer.ServerGen = time;
}
}
var serializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
string json = JsonConvert.SerializeObject(syncLayers, serializerSettings);
return json;
}
}
catch (Exception e)
{
_log.Error(e.Message, e);
return null;
}
}
... View more
07-25-2019
11:43 AM
|
0
|
0
|
2923
|
|
POST
|
You could always download the code from github, update to 100.5, and compile yourself if you have an immediate need.
... View more
07-23-2019
07:39 AM
|
0
|
0
|
2292
|
|
POST
|
The standard workflow today would be to work in Portal or AGOL and create a WebMap that would be used as the source data. The user or admin could pre-package (see preplanned workflow) this data so the package does not have to be generated at the time of download which reduces download time significantly (generating a package takes 5+ minutes depending on size). Although, be aware that a single WebMap can only have 16 preplanned work areas which is both arbitrary and far too small (at least for the world I work in). The other option is to do a custom process on the enterprise side. Yes, it is true that only a offline replica generated from a feature service is editable. But there is no requirement that this be generated on the device itself. You could develop a process to create your own offline packages on the enterprise and then a process to download those packages. If the packages are complex as you describe, this may be the only option. Also while Runtime does a nice job of simplifying this process, replicas can always be created directly from the rest endpoint. This custom approach is the path we are heading down, primarily because of the 16 prepackaged limit which is a good 10x less than the amount we need. Also, it gives us an ability to deliver additional data in the package which is a plus. We use an application run on the server to generate/update the offline packages which are stored on a web server. We have an application exposed as a rest endpoint that services client requests to download the prepackaged offline maps. -Joe
... View more
07-22-2019
07:35 AM
|
0
|
0
|
1175
|
|
POST
|
Without seeing example of how you did things, and only limited knowledge of the Toolkit... The way you describe things you had bound the GraphicsOverlay to the Datagrid and the Graphic within the GraphicsOverlay is also what was being used for symbolization. The updates you made were reflected in the GraphicsOverlay not in the data table itself. But because this is what is driving the symbols you see the behavior you describe. In a way a Graphic is like a really lightweight feature, it has a geometry, attributes and a symbol but no backing data store it just lives in memory You could do a pretty similar thing in Xamarin. There is no FeatureDataGrid from the toolkit, but you could create a ListView that is bound to the GraphicsOverlay.Graphics. Question 1: Yes this is correct, in that the FeatureLayer that is created from the FeatureTable cannot be edited. Question 2: See the above description Question 3: ??? - I think there is a 100.5 version, I just don't think they have a FeatureDataGrid for Xamarin. Some other things. There is no reason a Runtime MapPackage needs to be generated onto the device itself. If you have a workflow to copy an ArcGIS Pro MapPackage to the device, you could write a standalone tool in Runtime to generate the package (it's pretty simple) and then copy those packages to the device. Even if you could edit the sqlite database directly you would not achieve the desired results. Changes to the underlying table would not immediately be reflected in the FeatureLayer because the API is not refreshing if changes are not made through the API. [As a note, the reason for what you see is that there are triggers on the tables which would seem to use custom functions which are part of Runtime so the errors you see occur when you try to update through the sqlite API)
... View more
07-21-2019
07:39 AM
|
0
|
2
|
2292
|
|
POST
|
Have you looked at Collector? If you don't have specific custom needs Collector will let you do what you decribe
... View more
07-21-2019
07:06 AM
|
0
|
0
|
6046
|
|
POST
|
The only way to generate editable offline map package is through the OfflineMapTask. The link gives a pretty detailed example of how it is done. I believe the long term plan is to allow map packages developed in Pro to be editable, but it is not available at this time.
... View more
07-19-2019
02:02 PM
|
0
|
6
|
6046
|
|
POST
|
What about in addition to the Collector team you talk to the Runtime API team. It would seem there is a vested interest in things working across the board in a consistent manner with both ArcGIS Server and AGOL. I don't know how Collector develops their application. As the Feature Service Lead I would have thought you would consider it critical to discuss the definition with the Runtime team and to have it tested by everyone If one assumes that the typeId field and the subtypeId field are going to be the same you could gather this information, however, this is not always a valid assumption. Plus the Runtime API has done the work to have this supported it would be nice not to have to write a bunch of code that is only needed in the case of AGOL cases. Rex Hansen
... View more
07-18-2019
01:08 PM
|
0
|
1
|
2084
|
|
POST
|
I am using the Runtime WPF API. Have just checked in the latest version 100.5 and despite the service definition showing a 'subType' array I see no Subtypes in the object exposed by the API. What type of mobile apps are you developing that you say this is not an issue? I see in the Runtime API for WPF. I have not confirmed this issue in the Xamarin API application at this point.
... View more
07-18-2019
11:05 AM
|
0
|
3
|
2084
|
|
POST
|
Another one of those who is responsible issues so I'll dual post. Was just looking at the changes made to support subtypes in AGOL. While it seems there was a valid attempt made in this regard it would appear to not actually work. My guess is that the issue is that in the ArcGIS Server service definition the json name used is 'subtype' while in AGOL it is 'subType' So at 100.5 and current AGOL you can still not use FeatureSubtypes. The SubtypeField property is correct in both cases
... View more
07-18-2019
10:58 AM
|
0
|
0
|
733
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 05-11-2026 09:07 AM | |
| 1 | 10-23-2025 12:16 PM | |
| 1 | 10-19-2022 01:08 PM | |
| 1 | 09-03-2025 09:25 AM | |
| 1 | 04-16-2025 12:37 PM |
| Online Status |
Offline
|
| Date Last Visited |
a month ago
|