private JsonLayer Layer(IServiceMap map, int layerId) { var datasetElement = map.MapElements.Where(e => e.ID == layerId).FirstOrDefault(); if (datasetElement == null) { throw new Exception("Unknown layer: " + layerId); } var tocElement = map.TOC.GetTOCElement(datasetElement as ILayer); JsonField[] fields = new JsonField[0]; if (datasetElement.Class is ITableClass) { fields = ((ITableClass)datasetElement.Class).Fields.ToEnumerable().Select(f => { return(new JsonField() { Name = f.name, Alias = f.aliasname, Type = JsonField.ToType(f.type).ToString() }); }).ToArray(); } JsonExtent extent = null; if (datasetElement.Class is IFeatureClass && ((IFeatureClass)datasetElement.Class).Envelope != null) { extent = new JsonExtent() { // DoTo: SpatialReference Xmin = ((IFeatureClass)datasetElement.Class).Envelope.minx, Ymin = ((IFeatureClass)datasetElement.Class).Envelope.miny, Xmax = ((IFeatureClass)datasetElement.Class).Envelope.maxx, Ymax = ((IFeatureClass)datasetElement.Class).Envelope.maxy }; } string type = "Feature Layer"; if (datasetElement.Class is IRasterClass) { type = "Raster Layer"; } return(new JsonLayer() { CurrentVersion = Version, Id = datasetElement.ID, Name = tocElement != null ? tocElement.Name : datasetElement.Title, DefaultVisibility = tocElement != null ? tocElement.LayerVisible : true, MaxScale = tocElement != null && tocElement.Layers.Count() > 0 ? Math.Max(tocElement.Layers[0].MinimumScale > 1 ? tocElement.Layers[0].MinimumScale : 0, 0) : 0, MinScale = tocElement != null && tocElement.Layers.Count() > 0 ? Math.Max(tocElement.Layers[0].MaximumScale > 1 ? tocElement.Layers[0].MaximumScale : 0, 0) : 0, Fields = fields, Extent = extent, Type = type, GeometryType = datasetElement.Class is IFeatureClass?JsonLayer.ToGeometryType(((IFeatureClass)datasetElement.Class).GeometryType).ToString() : EsriGeometryType.esriGeometryNull.ToString() }); }
private void Query(IServiceRequestContext context, bool isFeatureServer = false) { try { var query = JsonConvert.DeserializeObject <JsonQueryLayer>(context.ServiceRequest.Request); List <JsonFeature> jsonFeatures = new List <JsonFeature>(); List <JsonFeatureResponse.Field> jsonFields = new List <JsonFeatureResponse.Field>(); string objectIdFieldName = String.Empty; EsriGeometryType esriGeometryType = EsriGeometryType.esriGeometryAny; JsonSpatialReference featureSref = null; using (var serviceMap = context.CreateServiceMapInstance()) { string filterQuery; var tableClasses = FindTableClass(serviceMap, query.LayerId.ToString(), out filterQuery); if (isFeatureServer == true && tableClasses.Count > 1) { throw new Exception("FeatureService can't be used with aggregated feature classes"); } foreach (var tableClass in tableClasses) { objectIdFieldName = tableClass.IDFieldName; if (tableClass is IFeatureClass) { esriGeometryType = JsonLayer.ToGeometryType(((IFeatureClass)tableClass).GeometryType); } QueryFilter filter; if (!String.IsNullOrWhiteSpace(query.Geometry)) { filter = new SpatialFilter(); var jsonGeometry = JsonConvert.DeserializeObject <Rest.Json.Features.Geometry.JsonGeometry>(query.Geometry); ((SpatialFilter)filter).Geometry = jsonGeometry.ToGeometry(); ((SpatialFilter)filter).FilterSpatialReference = SRef(query.InSRef); } else { filter = new QueryFilter(); } if (query.ReturnCountOnly == true) { filter.SubFields = !String.IsNullOrWhiteSpace(tableClass.IDFieldName) ? tableClass.IDFieldName : "*"; } else { filter.SubFields = query.OutFields; } filter.WhereClause = query.Where; if (!String.IsNullOrWhiteSpace(query.OutSRef)) { filter.FeatureSpatialReference = SRef(query.OutSRef); } else if (tableClass is IFeatureClass) { filter.FeatureSpatialReference = ((IFeatureClass)tableClass).SpatialReference; } if (filter.FeatureSpatialReference != null) { try { featureSref = new JsonSpatialReference() { Wkid = int.Parse(filter.FeatureSpatialReference.Name.Split(':')[1]) }; } catch { } } if (filterQuery != String.Empty) { filter.WhereClause = (filter.WhereClause != String.Empty) ? "(" + filter.WhereClause + ") AND " + filterQuery : filterQuery; } #region Feature Spatial Reference if (query.OutSRef != null) { filter.FeatureSpatialReference = SRef(query.OutSRef); } #endregion var cursor = tableClass.Search(filter); bool firstFeature = true; if (cursor is IFeatureCursor) { IFeature feature; IFeatureCursor featureCursor = (IFeatureCursor)cursor; while ((feature = featureCursor.NextFeature) != null) { var jsonFeature = new JsonFeature(); var attributesDict = (IDictionary <string, object>)jsonFeature.Attributes; if (feature.Fields != null) { foreach (var field in feature.Fields) { object val = field.Value; if (val is DateTime) { val = Convert.ToInt64(((DateTime)val - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds); } attributesDict[field.Name] = val; if (firstFeature) { var tableField = tableClass.FindField(field.Name); if (tableField != null) { jsonFields.Add(new JsonFeatureResponse.Field() { Name = tableField.name, Alias = tableField.aliasname, Length = tableField.size, Type = JsonField.ToType(tableField.type).ToString() }); } } } } jsonFeature.Geometry = feature.Shape?.ToJsonGeometry(); jsonFeatures.Add(jsonFeature); firstFeature = false; } } } } context.ServiceRequest.Succeeded = true; if (isFeatureServer) { context.ServiceRequest.Response = JsonConvert.SerializeObject(new JsonFeatureServiceQueryResponse() { ObjectIdFieldName = objectIdFieldName, GeometryType = esriGeometryType.ToString(), SpatialReference = featureSref, Fields = jsonFields.ToArray(), Features = jsonFeatures.ToArray() }); } else if (query.ReturnCountOnly == true) { context.ServiceRequest.Response = JsonConvert.SerializeObject(new JsonFeatureCountResponse() { Count = jsonFeatures.Count() }); } else { context.ServiceRequest.Response = JsonConvert.SerializeObject(new JsonFeatureResponse() { GeometryType = esriGeometryType.ToString(), SpatialReference = featureSref, Fields = jsonFields.ToArray(), Features = jsonFeatures.ToArray() }); } } catch (Exception ex) { context.ServiceRequest.Succeeded = false; context.ServiceRequest.Response = JsonConvert.SerializeObject(new JsonError() { error = new JsonError.Error() { code = -1, message = ex.Message } }); } }