/// <summary> /// Downloads records and yields them as a lazy sequence of features of the specified type. Possibly throws RestException. /// </summary> /// <typeparam name="T">The type the record should be mapped to.</typeparam> /// <param name="layerId">The layer ID of the feature layer or table.</param> /// <param name="whereClause">The where clause. If set to null, returns all features.</param> /// <param name="extraParameters">The query string that describes any additional query parameters (i.e. outSR=4326). Each parameter must be url encoded.</param> /// <param name="keepQuerying">If set to true, repetitively queries the server until all features have been returned.</param> /// <param name="degreeOfParallelism">The maximum number of concurrent requests.</param> /// <returns></returns> public IEnumerable <T> Download <T>(int layerId, string whereClause = null, string extraParameters = null, bool keepQuerying = false, int degreeOfParallelism = 1) where T : Feature { var layer = GetLayer(layerId); var returnGeometry = typeof(T).HasGeometry(); var featureSet = Esri.GetFeatureSet(ServiceArgs, layerId, returnGeometry, layer.hasZ, whereClause, extraParameters, null); foreach (var g in featureSet.features) { yield return(ToFeature <T>(g, layer)); } var objectIds = featureSet.features.Select(g => Convert.ToInt32(g.attributes[layer.GetObjectIdFieldName()])).ToArray(); if (!keepQuerying || objectIds.Length == 0) { yield break; } var remainingObjectIds = Esri.GetOIDSet(ServiceArgs, layerId, whereClause, extraParameters).objectIds.Except(objectIds); foreach (var f in Download <T>(layer, remainingObjectIds, returnGeometry, whereClause, extraParameters, objectIds.Length, degreeOfParallelism)) { yield return(f); } }
private Service(string url, ICredentials credentials, Token token, string gdbVersion) { ServiceArgs = new ServiceArgs(url, credentials, token, gdbVersion); var serviceInfo = Esri.GetServiceInfo(ServiceArgs); Layers = serviceInfo.AllLayers; Domains = serviceInfo.AllDomains; }
private IEnumerable <T> Download <T>(Layer layer, IEnumerable <int> objectIds, bool returnGeometry, string whereClause, string extraParameters, int batchSize, int degreeOfParallelism) where T : Feature { return(objectIds.Partition(batchSize) .AsParallel() .AsOrdered() .WithDegreeOfParallelism(degreeOfParallelism < 1 ? 1 : degreeOfParallelism) .SelectMany(ids => Esri.GetFeatureSet(ServiceArgs, layer.id, returnGeometry, layer.hasZ, whereClause, extraParameters, ids).features .Select(g => ToFeature <T>(g, layer)))); }
/// <summary> /// Inserts the features into a layer and returns the newly created features. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="features"></param> /// <param name="service"></param> /// <param name="layerId"></param> /// <returns></returns> public static InsertResult <T> InsertInto <T>(this T[] features, Service service, int layerId) where T : Feature { try { if (features.Length == 0) { return(new InsertResult <T>(true)); } var layer = service.GetLayer(layerId); var adds = features.Select(f => f.ToGraphic(layer, false)).ToArray(); var editResultInfo = Esri.ApplyEdits(service.ServiceArgs, layer.id, "adds", adds.Serialize()); return(new InsertResult <T>(true, null, () => service.Download <T>(layerId, editResultInfo.addResults.Select(r => r.objectId), null, null, 50, 1).ToArray())); } catch (RestException restException) { return(new InsertResult <T>(false, restException)); } }
/// <summary> /// Updates the features in the underlying layer. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="features"></param> /// <returns></returns> public static UpdateResult Update <T>(this T[] features) where T : Feature { try { if (features.Length == 0) { return(new UpdateResult(true)); } if (features.Any(f => !f.IsDataBound)) { throw new InvalidOperationException("All features must be bound to a data source before they can be updated."); } var args = GetUnique(features, f => f.ServiceArgs, "url and geodatabase version"); var layer = GetUnique(features, f => f.Layer, "layer"); var updates = features.Select(f => f.ToGraphic(layer, true)).Where(o => o != null).ToArray(); if (updates.Length == 0) { return(new UpdateResult(true)); } Esri.ApplyEdits(args, layer.id, "updates", updates.Serialize()); foreach (var f in features) { f.IsDirty = false; } return(new UpdateResult(true)); } catch (RestException restException) { return(new UpdateResult(false, restException)); } }
/// <summary> /// Deletes the features from the underlying layer. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="features"></param> /// <returns></returns> public static DeleteResult Delete <T>(this T[] features) where T : Feature { try { if (features.Length == 0) { return(new DeleteResult(true)); } if (features.Any(f => !f.IsDataBound)) { throw new InvalidOperationException("All features must be bound to a data source before they can be deleted."); } var args = GetUnique(features, f => f.ServiceArgs, "url and geodatabase version"); var layer = GetUnique(features, f => f.Layer, "layer"); var deletes = string.Join(",", features.Select(f => f.OID)); Esri.ApplyEdits(args, layer.id, "deletes", deletes); foreach (var f in features) { f.ServiceArgs = null; f.Layer = null; f.OID = -1; f.IsDirty = false; } return(new DeleteResult(true)); } catch (RestException restException) { return(new DeleteResult(false, restException)); } }
/// <summary> /// Generates a token for the service url. /// </summary> /// <param name="url"></param> /// <param name="userName"></param> /// <param name="password"></param> /// <param name="expiration"></param> /// <returns></returns> public static Token GenerateToken(string url, string userName, string password, int?expiration = null) { var token = Esri.GetTokenInfo(url, userName, password, expiration); return(new Token(token.token, Esri.BaseTime.AddMilliseconds(token.expires))); }