private byte[] FindNearFeatures(int layerID, IPoint location, double distance) { if (layerID < 0) { throw new ArgumentOutOfRangeException("layerID"); } if (distance <= 0.0) { throw new ArgumentOutOfRangeException("distance"); } IGeometry queryGeometry = ((ITopologicalOperator)location).Buffer(distance); ISpatialFilter filter = new SpatialFilterClass(); filter.Geometry = queryGeometry; filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; IQueryResultOptions resultOptions = new QueryResultOptionsClass(); resultOptions.Format = esriQueryResultFormat.esriQueryResultJsonAsMime; AutoTimer timer = new AutoTimer(); //starts the timer IMapTableDescription tableDesc = GetTableDesc(layerID); this.serverLog.LogMessage(ServerLogger.msgType.infoDetailed, "FindNearFeatures", -1, timer.Elapsed, "Finding table description elapsed this much."); IQueryResult result = this.ms.QueryData(this.ms.DefaultMapName, tableDesc, filter, resultOptions); return(result.MimeData); }
private IRecordSet FindNearFeatures(int layerID, IPoint location, double distance) { IMapServer3 mapServer = serverObjectHelper.ServerObject as IMapServer3; if (mapServer == null) { throw new Exception("Unable to access the map server."); } IGeometry queryGeometry = ((ITopologicalOperator)location).Buffer(distance); ISpatialFilter filter = new SpatialFilterClass(); filter.Geometry = queryGeometry; filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; IQueryResultOptions resultOptions = new QueryResultOptionsClass(); resultOptions.Format = esriQueryResultFormat.esriQueryResultRecordSetAsObject; IMapTableDescription tableDesc = GetTableDesc(mapServer, layerID); IQueryResult result = mapServer.QueryData(mapServer.DefaultMapName, tableDesc, filter, resultOptions); return((RecordSet)result.Object); }
/// <summary> /// Queries the specified layer id. /// </summary> /// <param name="layerId">The layer id.</param> /// <param name="spatialFilter">The spatial filter.</param> /// <param name="attributeFilter">The attribute filter.</param> /// <param name="transformationId">The transformation id.</param> /// <returns></returns> public RecordSet Query(int layerId, IGeometry spatialFilter, string attributeFilter, string geometryFieldName, ExportOutputSpatialReference outputSr) { ISpatialFilter filter = new SpatialFilterClass(); RecordSet recordSet = null; IQueryResultOptions resultOptions; IMapTableDescription tableDesc; IQueryResult result; try { //set the filter properties filter.Geometry = spatialFilter; //todo //the geometry field name comes in via the request, but could we look at layerinfo from the map server? //the type of spatial reference systen should be passed in: i.e. geographic or projected //already implemented method: GetFeatureClassShapeFieldName which does this //create desired output spatial reference if (outputSr != null) { Type t = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment"); System.Object obj = Activator.CreateInstance(t); ISpatialReferenceFactory srFact = obj as ISpatialReferenceFactory; ISpatialReference sr; if (outputSr.CoordinateSystemType == "projected") { sr = srFact.CreateProjectedCoordinateSystem((int)outputSr.Wkid); } else sr = srFact.CreateGeographicCoordinateSystem((int)outputSr.Wkid); filter.GeometryField = geometryFieldName; filter.set_OutputSpatialReference(geometryFieldName, sr); } filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; if (!String.IsNullOrEmpty(attributeFilter)) filter.WhereClause = attributeFilter; //set the result options resultOptions = new QueryResultOptionsClass(); resultOptions.Format = esriQueryResultFormat.esriQueryResultRecordSetAsObject; //apply transformation if required if (outputSr != null) { if (outputSr.TransformationId != null) { Type factoryType = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment"); ISpatialReferenceFactory3 srFactory = (ISpatialReferenceFactory3)Activator.CreateInstance(factoryType); IGeoTransformation gt; gt = srFactory.CreateGeoTransformation((int)outputSr.TransformationId) as IGeoTransformation; resultOptions.GeoTransformation = gt; } } tableDesc = GetTableDesc(_server, layerId); result = _server.QueryData(_server.DefaultMapName, tableDesc, filter, resultOptions); //IlayerDescription3 lyrDesc = GetLayerDesc(_server, layerId); //result = _server.QueryFeatureData2(_server.DefaultMapName, lyrDesc, filter, resultOptions); recordSet = result.Object as RecordSet; return recordSet; } catch (Exception ex) { throw ex; } finally { filter = null; resultOptions = null; tableDesc = null; result = null; } }
private IRecordSet FindNearFeatures(int layerID, IPoint location, double distance) { IMapServer3 mapServer = serverObjectHelper.ServerObject as IMapServer3; if (mapServer == null) throw new Exception("Unable to access the map server."); IGeometry queryGeometry = ((ITopologicalOperator)location).Buffer(distance); ISpatialFilter filter = new SpatialFilterClass(); filter.Geometry = queryGeometry; filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; IQueryResultOptions resultOptions = new QueryResultOptionsClass(); resultOptions.Format = esriQueryResultFormat.esriQueryResultRecordSetAsObject; IMapTableDescription tableDesc = GetTableDesc(mapServer, layerID); IQueryResult result = mapServer.QueryData(mapServer.DefaultMapName, tableDesc, filter, resultOptions); return (RecordSet)result.Object; }
/// <summary> /// Creates and Serves vector tiles /// </summary> /// <param name="boundVariables"></param> /// <param name="operationInput"></param> /// <param name="outputFormat"></param> /// <param name="requestProperties"></param> /// <param name="responseProperties"></param> /// <returns></returns> private byte[] VectorTileHandler(NameValueCollection boundVariables, JsonObject operationInput, string outputFormat, string requestProperties, out string responseProperties) { //responseProperties = null; responseProperties = null; //"Content-Type:application/json"; ESRI.ArcGIS.SOESupport.AutoTimer timer = new AutoTimer(); const string methodName = "VectorTileHandler"; try { long? layerIndex; long? zoom; long? row; long? col; string jsonFormatParam; TileFormat jsonFormat = TileFormat.EsriJson; // Defaulting to EsriJson if (!operationInput.TryGetAsLong("l", out layerIndex)) throw new ArgumentNullException("layer"); if (!operationInput.TryGetAsLong("z", out zoom)) throw new ArgumentNullException("zoom"); if (!operationInput.TryGetAsLong("y", out row)) throw new ArgumentNullException("row"); if (!operationInput.TryGetAsLong("x", out col)) throw new ArgumentNullException("col"); if (operationInput.TryGetString("jf", out jsonFormatParam)) { if (!string.IsNullOrEmpty(jsonFormatParam)) { jsonFormatParam = jsonFormatParam.ToLower().Trim(); Enum.GetNames(typeof(TileFormat)).ToList().ForEach(n => { if (n.ToLower() == jsonFormatParam) { jsonFormat = (TileFormat)Enum.Parse(typeof(TileFormat), jsonFormatParam, true); } }); } } //System.Diagnostics.Debug.WriteLine(string.Format("l:{0}, r:{1}, c:{2}", zoom, row, col)); // Check to see if the tile exists on disk... // <cache-root>\<layerId>\<zoom>\<row>\<col>.esrijson; //i.e. to be consistent with Esri tile caching structure string tilePath = string.Format(@"{0}\{1}\{2}\{3}\{4}.{5}", _vectorCacheRootDirectory, layerIndex, zoom.Value, row.Value, col.Value, jsonFormat.ToString().ToLower()); if (File.Exists(tilePath)) { // Fetch tile contents from disk _dtsLogger.LogInfo(soe_name, methodName, "Time: " + timer.Elapsed.ToString()); logger.LogMessage(ServerLogger.msgType.infoSimple, methodName, -1, "Time: " + timer.Elapsed.ToString()); return this.ReadTileFile(tilePath); } else { // Write new files to disk IMapServer3 mapServer = serverObjectHelper.ServerObject as IMapServer3; if (mapServer == null) { throw new InvalidOperationException("Unable to access the map server."); } // Get the bbox. Returns an envelope in WGS84 (4326). IEnvelope env102100 = TileUtil.GetEnvelopeFromZoomRowCol((int)zoom.Value, (int)row.Value, (int)col.Value); //_dtsLogger.LogInfo(soe_name, methodName, this.GeometryToXml(env4326)); // Convert envelope to polygon b/c QueryData does not support spatialfilter geometry using envelope IPolygon polygon102100 = this.CreatePolygonFromEnvelope(env102100); // Use QueryData and generalize result geometries based on zoom level IQueryResultOptions resultOptions = new QueryResultOptionsClass(); // i.e; IRecordSet to support BOTH json and geojson resultOptions.Format = esriQueryResultFormat.esriQueryResultRecordSetAsObject; IMapTableDescription tableDescription = this.GetTableDescription(mapServer, (int)layerIndex, (int)zoom); // Create spatial filter ISpatialFilter spatialFilter = new SpatialFilterClass(); spatialFilter.Geometry = polygon102100; spatialFilter.GeometryField = "Shape"; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; //TODO: Subfields should be configurable spatialFilter.SubFields = "*"; // Execute query IQueryResult result = mapServer.QueryData(mapServer.DefaultMapName, tableDescription, spatialFilter, resultOptions); byte[] json = null; // TODO: Support writing tiles for no data // Need a way to do this for GeoJson; parse Esri JSON recordset into GeoJson if (result == null || !this.RecordsetHasFeatures(result.Object as IRecordSet)) { // Write "no data" tile if (jsonFormat == TileFormat.EsriJson) { resultOptions.Format = esriQueryResultFormat.esriQueryResultJsonAsMime; result = mapServer.QueryData(mapServer.DefaultMapName, tableDescription, spatialFilter, resultOptions); json = result.MimeData; } else { json = StrToByteArray(NO_DATA_GEOJSON); } } else { //We have features... IRecordSet features = result.Object as IRecordSet; // Get geometry type for query layer esriGeometryType geometryType = this.GetLayerGeometryType(mapServer.GetServerInfo(mapServer.DefaultMapName).MapLayerInfos, (int)layerIndex); switch (geometryType) { case esriGeometryType.esriGeometryPoint: // Do nothing... already intersected json = ESRI.ArcGIS.SOESupport.Conversion.ToJson(features); break; case esriGeometryType.esriGeometryPolyline: // Polylines must be clipped to envelope IFeatureCursor cursor = null; this.ClipFeaturesToTile(ref cursor, ref features, env102100); json = ESRI.ArcGIS.SOESupport.Conversion.ToJson(features); this.ReleaseComObject(cursor); break; case esriGeometryType.esriGeometryMultipoint: case esriGeometryType.esriGeometryPolygon: // Get IDs of features whose centroid is contained by tile envelope List<int> ids = this.GetIdsOfContainedFeatureCentroids(features, polygon102100); if (ids.Count == 0) { // Write no data tile if (jsonFormat == TileFormat.EsriJson) { // Query to get empty featureset and serialize to disk resultOptions.Format = esriQueryResultFormat.esriQueryResultJsonAsMime; IQueryFilter queryFilter = new QueryFilterClass(); queryFilter.SubFields = "*"; queryFilter.WhereClause = "1=2"; result = mapServer.QueryData(mapServer.DefaultMapName, tableDescription, queryFilter, resultOptions); json = result.MimeData; } else { json = StrToByteArray(NO_DATA_GEOJSON); } } else { // Execute new query for IDs IQueryFilter queryFilter = new QueryFilterClass(); queryFilter.SubFields = "*"; // TODO: Account for sql query syntax based on datasource // FGDB/Shapefile then "OBJECTID"; quotes required // PGDB then [OBJECTID]; brackets required // SDE then OBJECTID; nothing but the fieldname queryFilter.WhereClause = string.Format("\"OBJECTID\" IN({0})", ids.ToDelimitedString<int>(",")); // FGDB result = mapServer.QueryData(mapServer.DefaultMapName, tableDescription, queryFilter, resultOptions); features = result.Object as IRecordSet; // Do some checking here... var featureCount = this.GetRecordsetFeatureCount(features); if (featureCount != ids.Count) { System.Diagnostics.Debug.WriteLine(string.Format("Query Problem: ID search results IS NOT EQUAL to contained IDs count - [{0}:{1}]", featureCount, ids.Count)); System.Diagnostics.Debug.WriteLine("Query: " + queryFilter.WhereClause); } json = ESRI.ArcGIS.SOESupport.Conversion.ToJson(features); } break; default: throw new NotSupportedException(string.Format("Geometry type {0} is not supported by {1}", geometryType.ToString(), soe_name)); } } //store the json to disk this.WriteTileFile(json, tilePath, (int)layerIndex, (int)zoom, (int)row); _dtsLogger.LogInfo(soe_name, methodName,"Time: " + timer.Elapsed.ToString()); logger.LogMessage(ServerLogger.msgType.infoSimple,methodName,-1,"Time: " + timer.Elapsed.ToString()); return json; } } catch (Exception ex) { // Log the error _dtsLogger.LogError(soe_name, methodName, "n/a", ex); logger.LogMessage(ServerLogger.msgType.error, methodName, 9999, ex.StackTrace); return StrToByteArray("{}"); } }
private byte[] FindNearFeatures(int layerID, IPoint location, double distance) { if (layerID < 0) throw new ArgumentOutOfRangeException("layerID"); if (distance <= 0.0) throw new ArgumentOutOfRangeException("distance"); IGeometry queryGeometry = ((ITopologicalOperator)location).Buffer(distance); ISpatialFilter filter = new SpatialFilterClass(); filter.Geometry = queryGeometry; filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; IQueryResultOptions resultOptions = new QueryResultOptionsClass(); resultOptions.Format = esriQueryResultFormat.esriQueryResultJsonAsMime; AutoTimer timer = new AutoTimer(); //starts the timer IMapTableDescription tableDesc = GetTableDesc(layerID); this.serverLog.LogMessage(ServerLogger.msgType.infoDetailed, "FindNearFeatures", -1, timer.Elapsed, "Finding table description elapsed this much."); IQueryResult result = this.ms.QueryData(this.ms.DefaultMapName, tableDesc, filter, resultOptions); return result.MimeData; }
private Byte[] GetUserSiteFeatures(String userID) { SqlCommand cmd = new SqlCommand("_IWC_GetUserSites", sqlConn); cmd.CommandType = CommandType.StoredProcedure; SqlParameter param = cmd.Parameters.AddWithValue("@userID", userID); SqlDataReader reader = cmd.ExecuteReader(); String siteCodes = null; if (reader.HasRows) { while (reader.Read()) { siteCodes = siteCodes + "'" + reader.GetString(0) + "',"; } siteCodes = siteCodes.Substring(0, siteCodes.Length - 1); } reader.Close(); IMapServer3 mapServer = serverObjectHelper.ServerObject as IMapServer3; if (mapServer == null) throw new Exception("Unable to access the map server."); IQueryFilter filter = new QueryFilterClass(); filter.WhereClause = "WI_Sitecode IN (" + siteCodes + ")"; IQueryResultOptions resultOptions = new QueryResultOptionsClass(); resultOptions.Format = esriQueryResultFormat.esriQueryResultJsonAsMime; AutoTimer timer = new AutoTimer(); //starts the timer IMapTableDescription tableDesc = GetTableDesc(mapServer, 0); logger.LogMessage(ServerLogger.msgType.infoDetailed, "GetUserSiteFeatures", -1, timer.Elapsed, "Finding table description elapsed this much."); IQueryResult result = mapServer.QueryData(mapServer.DefaultMapName, tableDesc, filter, resultOptions); return result.MimeData; }
/// <summary> /// Creates and Serves vector tiles /// </summary> /// <param name="boundVariables"></param> /// <param name="operationInput"></param> /// <param name="outputFormat"></param> /// <param name="requestProperties"></param> /// <param name="responseProperties"></param> /// <returns></returns> private byte[] VectorTileHandler(NameValueCollection boundVariables, JsonObject operationInput, string outputFormat, string requestProperties, out string responseProperties) { //responseProperties = null; responseProperties = null; //"Content-Type:application/json"; ESRI.ArcGIS.SOESupport.AutoTimer timer = new AutoTimer(); const string methodName = "VectorTileHandler"; try { long? layerIndex; long? zoom; long? row; long? col; string jsonFormatParam; TileFormat jsonFormat = TileFormat.EsriJson; // Defaulting to EsriJson if (!operationInput.TryGetAsLong("l", out layerIndex)) { throw new ArgumentNullException("layer"); } if (!operationInput.TryGetAsLong("z", out zoom)) { throw new ArgumentNullException("zoom"); } if (!operationInput.TryGetAsLong("y", out row)) { throw new ArgumentNullException("row"); } if (!operationInput.TryGetAsLong("x", out col)) { throw new ArgumentNullException("col"); } if (operationInput.TryGetString("jf", out jsonFormatParam)) { if (!string.IsNullOrEmpty(jsonFormatParam)) { jsonFormatParam = jsonFormatParam.ToLower().Trim(); Enum.GetNames(typeof(TileFormat)).ToList().ForEach(n => { if (n.ToLower() == jsonFormatParam) { jsonFormat = (TileFormat)Enum.Parse(typeof(TileFormat), jsonFormatParam, true); } }); } } //System.Diagnostics.Debug.WriteLine(string.Format("l:{0}, r:{1}, c:{2}", zoom, row, col)); // Check to see if the tile exists on disk... // <cache-root>\<layerId>\<zoom>\<row>\<col>.esrijson; //i.e. to be consistent with Esri tile caching structure string tilePath = string.Format(@"{0}\{1}\{2}\{3}\{4}.{5}", _vectorCacheRootDirectory, layerIndex, zoom.Value, row.Value, col.Value, jsonFormat.ToString().ToLower()); if (File.Exists(tilePath)) { // Fetch tile contents from disk _dtsLogger.LogInfo(soe_name, methodName, "Time: " + timer.Elapsed.ToString()); logger.LogMessage(ServerLogger.msgType.infoSimple, methodName, -1, "Time: " + timer.Elapsed.ToString()); return(this.ReadTileFile(tilePath)); } else { // Write new files to disk IMapServer3 mapServer = serverObjectHelper.ServerObject as IMapServer3; if (mapServer == null) { throw new InvalidOperationException("Unable to access the map server."); } // Get the bbox. Returns an envelope in WGS84 (4326). IEnvelope env102100 = TileUtil.GetEnvelopeFromZoomRowCol((int)zoom.Value, (int)row.Value, (int)col.Value); //_dtsLogger.LogInfo(soe_name, methodName, this.GeometryToXml(env4326)); // Convert envelope to polygon b/c QueryData does not support spatialfilter geometry using envelope IPolygon polygon102100 = this.CreatePolygonFromEnvelope(env102100); // Use QueryData and generalize result geometries based on zoom level IQueryResultOptions resultOptions = new QueryResultOptionsClass(); // i.e; IRecordSet to support BOTH json and geojson resultOptions.Format = esriQueryResultFormat.esriQueryResultRecordSetAsObject; IMapTableDescription tableDescription = this.GetTableDescription(mapServer, (int)layerIndex, (int)zoom); // Create spatial filter ISpatialFilter spatialFilter = new SpatialFilterClass(); spatialFilter.Geometry = polygon102100; spatialFilter.GeometryField = "Shape"; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; //TODO: Subfields should be configurable spatialFilter.SubFields = "*"; // Execute query IQueryResult result = mapServer.QueryData(mapServer.DefaultMapName, tableDescription, spatialFilter, resultOptions); byte[] json = null; // TODO: Support writing tiles for no data // Need a way to do this for GeoJson; parse Esri JSON recordset into GeoJson if (result == null || !this.RecordsetHasFeatures(result.Object as IRecordSet)) { // Write "no data" tile if (jsonFormat == TileFormat.EsriJson) { resultOptions.Format = esriQueryResultFormat.esriQueryResultJsonAsMime; result = mapServer.QueryData(mapServer.DefaultMapName, tableDescription, spatialFilter, resultOptions); json = result.MimeData; } else { json = StrToByteArray(NO_DATA_GEOJSON); } } else { //We have features... IRecordSet features = result.Object as IRecordSet; // Get geometry type for query layer esriGeometryType geometryType = this.GetLayerGeometryType(mapServer.GetServerInfo(mapServer.DefaultMapName).MapLayerInfos, (int)layerIndex); switch (geometryType) { case esriGeometryType.esriGeometryPoint: // Do nothing... already intersected json = ESRI.ArcGIS.SOESupport.Conversion.ToJson(features); break; case esriGeometryType.esriGeometryPolyline: // Polylines must be clipped to envelope IFeatureCursor cursor = null; this.ClipFeaturesToTile(ref cursor, ref features, env102100); json = ESRI.ArcGIS.SOESupport.Conversion.ToJson(features); this.ReleaseComObject(cursor); break; case esriGeometryType.esriGeometryMultipoint: case esriGeometryType.esriGeometryPolygon: // Get IDs of features whose centroid is contained by tile envelope List <int> ids = this.GetIdsOfContainedFeatureCentroids(features, polygon102100); if (ids.Count == 0) { // Write no data tile if (jsonFormat == TileFormat.EsriJson) { // Query to get empty featureset and serialize to disk resultOptions.Format = esriQueryResultFormat.esriQueryResultJsonAsMime; IQueryFilter queryFilter = new QueryFilterClass(); queryFilter.SubFields = "*"; queryFilter.WhereClause = "1=2"; result = mapServer.QueryData(mapServer.DefaultMapName, tableDescription, queryFilter, resultOptions); json = result.MimeData; } else { json = StrToByteArray(NO_DATA_GEOJSON); } } else { // Execute new query for IDs IQueryFilter queryFilter = new QueryFilterClass(); queryFilter.SubFields = "*"; // TODO: Account for sql query syntax based on datasource // FGDB/Shapefile then "OBJECTID"; quotes required // PGDB then [OBJECTID]; brackets required // SDE then OBJECTID; nothing but the fieldname queryFilter.WhereClause = string.Format("\"OBJECTID\" IN({0})", ids.ToDelimitedString <int>(",")); // FGDB result = mapServer.QueryData(mapServer.DefaultMapName, tableDescription, queryFilter, resultOptions); features = result.Object as IRecordSet; // Do some checking here... var featureCount = this.GetRecordsetFeatureCount(features); if (featureCount != ids.Count) { System.Diagnostics.Debug.WriteLine(string.Format("Query Problem: ID search results IS NOT EQUAL to contained IDs count - [{0}:{1}]", featureCount, ids.Count)); System.Diagnostics.Debug.WriteLine("Query: " + queryFilter.WhereClause); } json = ESRI.ArcGIS.SOESupport.Conversion.ToJson(features); } break; default: throw new NotSupportedException(string.Format("Geometry type {0} is not supported by {1}", geometryType.ToString(), soe_name)); } } //store the json to disk this.WriteTileFile(json, tilePath, (int)layerIndex, (int)zoom, (int)row); _dtsLogger.LogInfo(soe_name, methodName, "Time: " + timer.Elapsed.ToString()); logger.LogMessage(ServerLogger.msgType.infoSimple, methodName, -1, "Time: " + timer.Elapsed.ToString()); return(json); } } catch (Exception ex) { // Log the error _dtsLogger.LogError(soe_name, methodName, "n/a", ex); logger.LogMessage(ServerLogger.msgType.error, methodName, 9999, ex.StackTrace); return(StrToByteArray("{}")); } }