jueves, 19 de julio de 2018

Ejecutar consultas a un Feature Layer de Arcgis Online desde C#


En la documentación de ArcGIS Runtime SDK for .NET (versión de SDK 100.3.0), se encuentran ejemplos sobre autenticación y sobre consultas a un Feature Layer público, sin embargo, no encontré un ejemplo sobre una consulta a un Feature Layer privado (requiere autenticación), lo que me tomó algunas horas realizar.

Comparto el ejemplo realizado (app de consola):

Program.cs
  1. using System;
  2. using Esri.ArcGISRuntime.Data;
  3. using System.Collections.Generic;
  4. namespace arcgisAuthTest
  5. {
  6.     class Program
  7.     {
  8.        
  9.         static void Main(string[] args)
  10.         {
  11.             string serviceUrl = "https://services6.arcgis.com/FFF6MrlVn5PAw2F8/arcgis/rest/services/service_bf963161c24047259028034xxxxxx/FeatureServer/0";
  12.             // Would be better to read them from a secure source
  13.             string username = "usr";
  14.             string password = "pa$$";
  15.             FeatureLayerQuery flq = new FeatureLayerQuery(serviceUrl, username, password);
  16.             var i = 0;
  17.             string query = "upper(placa_motocicleta) LIKE '%342FFF%'";
  18.             List<string> outFields = new List<string>() {
  19.                 "*"
  20.             };
  21.             var listado = flq.QueryFeature(query, outFields);
  22.             foreach (Feature f in listado)
  23.             {
  24.                 Console.WriteLine(string.Format(Environment.NewLine "Feature {0}", i++));
  25.                 for (int j = 0; j < f.FeatureTable.Fields.Count; j++)
  26.                 {
  27.                     string fieldName = f.FeatureTable.Fields[j].Name;
  28.                     Console.WriteLine(string.Format("f[{0}] = '{1}'", fieldName, f.Attributes[fieldName]));
  29.                 }
  30.             }
  31.             Console.ReadKey();
  32.         }
  33.     }
  34. }
FeatureLayerQuery.cs
  1. using Esri.ArcGISRuntime.Data;
  2. using Esri.ArcGISRuntime.Security;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Threading.Tasks;
  6. namespace arcgisAuthTest
  7. {
  8.     /// <summary>
  9.     /// Ejecución de queries sobre un Feature Layer de Arcgis Online.
  10.     /// Incluye autenticación por medio de usuario y contraseña.
  11.     /// Author: Cristian de León R.
  12.     /// </summary>
  13.     public class FeatureLayerQuery
  14.     {
  15.         private string _password;
  16.         private Credential _credential;
  17.         public string ServiceUrl { get; private set; }
  18.         public string Usuario { get; private set; }
  19.         public ServiceFeatureTable SrvFeatureTable { get; private set; }
  20.         public FeatureLayerQuery(string serviceUrl, string usuario, string password)
  21.         {
  22.             Usuario = usuario;
  23.             _password = password;
  24.             ServiceUrl = serviceUrl;
  25.             _credential = CreateKnownCredentials(new CredentialRequestInfo()
  26.             {
  27.                 AuthenticationType = AuthenticationType.Token,
  28.                 ServiceUri = new Uri(ServiceUrl)
  29.             }).GetAwaiter().GetResult();
  30.         }
  31.         /// <summary>
  32.         /// Ejecutar una consulta contra un Feature Layer de Arcgis Online.
  33.         /// </summary>
  34.         /// <param name="whereClause">Ej.: "upper(placa_motocicleta) LIKE '%" + (NumPlaca.Trim().ToUpper()) + "%'"</param>
  35.         /// <param name="outFields">listado de campos a retornar o * para devolver todos</param>
  36.         /// <param name="maxFeatures">Número máximo de features devuelto</param>
  37.         /// <returns></returns>
  38.         public List<Feature> QueryFeature(string whereClause, List<string> outFields, int maxFeatures = 0)
  39.         {
  40.             Uri serviceUri = new Uri(ServiceUrl);
  41.             SrvFeatureTable = new ServiceFeatureTable(serviceUri);
  42.             SrvFeatureTable.Credential = _credential;
  43.             // Create a query parameters that will be used to Query the feature table
  44.             var queryParams = new QueryParameters()
  45.             {
  46.                 WhereClause = whereClause,
  47.                 MaxFeatures = maxFeatures
  48.             };
  49.             // Query the feature table
  50.             FeatureQueryResult queryResult = SrvFeatureTable.PopulateFromServiceAsync(queryParams, true, outFields).GetAwaiter().GetResult();
  51.             List<Feature> features = new List<Feature>();
  52.             foreach (Feature r in queryResult)
  53.             {
  54.                 features.Add(r);
  55.                 //Console.WriteLine(r.Attributes["placa_motocicleta"]);
  56.             }
  57.             return features;
  58.         }
  59.         /// <summary>
  60.         /// Challenge method that checks for service access with known (hard coded) credentials
  61.         /// </summary>
  62.         /// <param name="info"></param>
  63.         /// <returns></returns>
  64.         private async Task<Credential> CreateKnownCredentials(CredentialRequestInfo info)
  65.         {
  66.             Credential knownCredential = null;
  67.             if (info.ServiceUri.AbsoluteUri.ToLower().Contains("arcgis.com"))
  68.             {
  69.                 knownCredential = await AuthenticationManager.Current.GenerateCredentialAsync(
  70.                     info.ServiceUri,
  71.                     Usuario,
  72.                     _password,
  73.                     info.GenerateTokenOptions);
  74.             }
  75.             return knownCredential;
  76.         }
  77.     }
  78. }

Arcgis API Reference