Пример #1
0
        /// <summary>
        /// From service fills list of layer with M
        /// </summary>
        private void GetRouteLayerInfos()
        {
            IMapServer3    serverObject  = this.GetMapServer();
            IMapLayerInfos mapLayerInfos = serverObject.GetServerInfo(serverObject.DefaultMapName).MapLayerInfos;

            this.routeLayerInfos = new List <RouteLayerInfo>();
            for (int i = 0; i < mapLayerInfos.Count; i++)
            {
                IMapLayerInfo mapLayerInfo = mapLayerInfos.get_Element(i);
                if (mapLayerInfo.IsFeatureLayer)
                {
                    IFields fields = mapLayerInfo.Fields;
                    for (int j = 0; j < fields.FieldCount; j++)
                    {
                        IField field = fields.get_Field(j);
                        if (field.Type == esriFieldType.esriFieldTypeGeometry)
                        {
                            IGeometryDef geometryDef = field.GeometryDef;
                            if (geometryDef.HasM)
                            {
                                this.routeLayerInfos.Add(new RouteLayerInfo(mapLayerInfo));
                            }

                            break;
                        }
                    }
                }
            }
        }
        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);
        }
Пример #3
0
        /// <summary>
        /// Feature Class from id of layer
        /// </summary>
        /// <param name="routelayerID">id route layer</param>
        /// <returns>feature class</returns>
        private IFeatureClass GetRouteFeatureClass(int routelayerID)
        {
            IMapServer3          mapServer  = this.GetMapServer();
            IMapServerDataAccess dataAccess = (IMapServerDataAccess)mapServer;

            return((IFeatureClass)dataAccess.GetDataSource(mapServer.DefaultMapName, routelayerID));
        }
        /// <summary>
        /// Geodataset from id of layer
        /// </summary>
        /// <param name="layerID">unique id layer</param>
        /// <returns>object Geodataset</returns>
        private IGeoDataset GetGeodataset(int layerID)
        {
            IMapServer3          mapServer  = this.GetMapServer();
            IMapServerDataAccess dataAccess = (IMapServerDataAccess)mapServer;

            return((IGeoDataset)dataAccess.GetDataSource(mapServer.DefaultMapName, layerID));
        }
        private CustomLayerInfos GetLayerInfos()
        {
            IMapServer3 mapServer = serverObjectHelper.ServerObject as IMapServer3;

            if (mapServer == null)
            {
                throw new Exception("Unable to access the map server.");
            }

            IMapServerInfo msInfo     = mapServer.GetServerInfo(mapServer.DefaultMapName);
            IMapLayerInfos layerInfos = msInfo.MapLayerInfos;
            int            c          = layerInfos.Count;

            CustomLayerInfos customLayerInfos = new CustomLayerInfos(Constants.SOENamespaceURI);

            for (int i = 0; i < c; i++)
            {
                IMapLayerInfo layerInfo = layerInfos.get_Element(i);

                CustomLayerInfo customLayerInfo = new CustomLayerInfo();
                customLayerInfo.Name   = layerInfo.Name;
                customLayerInfo.ID     = layerInfo.ID;
                customLayerInfo.Extent = layerInfo.Extent;

                customLayerInfos.Add(customLayerInfo);
            }

            return(customLayerInfos);
        }
Пример #6
0
        /// <summary>
        /// Get object MapServer of ServerObject
        /// </summary>
        /// <returns>object MapServer</returns>
        private IMapServer3 GetMapServer()
        {
            IMapServer3 mapServer = this.serverObjectHelper.ServerObject as IMapServer3;

            if (mapServer == null)
            {
                throw new DynamicSegmentationException("Unable to access the map server.");
            }

            return(mapServer);
        }
        /// <summary>
        /// Get object MapServer of ServerObject
        /// </summary>
        /// <returns>object MapServer</returns>
        private IMapServer3 GetMapServer()
        {
            IMapServer3 mapServer = this.serverObjectHelper.ServerObject as IMapServer3;

            if (mapServer == null)
            {
                throw new SpatialAnalystException("Unable to access the map server.");
            }

            return(mapServer);
        }
Пример #8
0
        public void Init(IServerObjectHelper pSOH)
        {
            this.soHelper            = pSOH;
            this.serverLog           = new ServerLogger();
            this.mapServerDataAccess = (IMapServerDataAccess)this.soHelper.ServerObject;
            ms              = (IMapServer3)this.mapServerDataAccess;
            mapServerInfo   = ms.GetServerInfo(ms.DefaultMapName);
            this.layerInfos = mapServerInfo.MapLayerInfos;
            this.mapDesc    = (IMapDescription3)mapServerInfo.DefaultMapDescription;

            serverLog.LogMessage(ServerLogger.msgType.infoStandard, this.soeName + ".init()", 200, "Initialized " + this.soeName + " SOE.");
        }
Пример #9
0
        public void Init(IServerObjectHelper pSOH) 
        {
            this.soHelper = pSOH;
            this.serverLog = new ServerLogger();
            this.mapServerDataAccess = (IMapServerDataAccess) this.soHelper.ServerObject;
            ms = (IMapServer3) this.mapServerDataAccess;
            mapServerInfo = ms.GetServerInfo(ms.DefaultMapName);
            this.layerInfos = mapServerInfo.MapLayerInfos;
            this.mapDesc = (IMapDescription3)mapServerInfo.DefaultMapDescription;

            serverLog.LogMessage(ServerLogger.msgType.infoStandard, this.soeName + ".init()", 200, "Initialized " + this.soeName + " SOE.");
        }
        private bool loadGeometricNetworkFromServer(IServerObjectHelper serverObjectHelper, ServerLogger logger)
        {
            bool result = false;

            if (null != serverObjectHelper)
            {
                try
                {
                    IMapServer3          mapServer  = (IMapServer3)serverObjectHelper.ServerObject;
                    IMapServerDataAccess da         = (IMapServerDataAccess)mapServer;
                    IMapLayerInfos       layerInfos = mapServer.GetServerInfo(mapServer.DefaultMapName).MapLayerInfos;
                    IFeatureDataset      ftrDataset = null;
                    for (int i = 0; i < layerInfos.Count; i++)
                    {
                        IMapLayerInfo lyrInfo = layerInfos.get_Element(i);
                        if (lyrInfo.IsFeatureLayer)
                        {
                            IFeatureClass ftrClass = (IFeatureClass)da.GetDataSource(mapServer.DefaultMapName, lyrInfo.ID);
                            if (null == ftrDataset && ftrClass.FeatureDataset.Name == this.networkName)
                            {
                                ftrDataset = ftrClass.FeatureDataset;
                            }
                            if (esriFeatureType.esriFTSimpleEdge == ftrClass.FeatureType)
                            {
                                this.addEdgeFeatureClass(ftrClass);
                            }
                            else if (esriFeatureType.esriFTSimpleJunction == ftrClass.FeatureType)
                            {
                                this.addJunctionFeatureClass(ftrClass);
                            }
                        }
                    }
                    if (this.edgeCount > 0 && this.junctionCount > 0 && null != ftrDataset)
                    {
                        INetworkCollection networkCollection = ftrDataset as INetworkCollection;
                        if (networkCollection != null && networkCollection.GeometricNetworkCount > 0)
                        {
                            this.geometricNetwork = networkCollection.GeometricNetwork[0];
                            result = true;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (null != logger)
                    {
                        logger.LogMessage(ServerLogger.msgType.error, typeof(NetworkHelper).Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, GLC.AO.AOUtilities.ErrorCode, e.Message);
                    }
                }
            }
            return(result);
        }
        public void Init(IServerObjectHelper pSOH)
        {
            serverObjectHelper = pSOH;

            mapServerDataAccess = (IMapServerDataAccess)pSOH.ServerObject;
            IMapServer3 ms = (IMapServer3)pSOH.ServerObject;

            this.mapServerInfo = ms.GetServerInfo(ms.DefaultMapName);
            this.layerInfos    = mapServerInfo.MapLayerInfos;

            if (layerId < 0)
            {
                layerId = 0;
            }
        }
        private IMapLayerInfo GetLayerInfo(IMapServer3 mapServer, int layerID)
        {
            IMapLayerInfo layerInfo;

            IMapLayerInfos layerInfos = mapServer.GetServerInfo(mapServer.DefaultMapName).MapLayerInfos;
            long           c          = layerInfos.Count;

            for (int i = 0; i < c; i++)
            {
                layerInfo = layerInfos.get_Element(i);
                if (layerInfo.ID == layerID)
                {
                    return(layerInfo);
                }
            }

            throw new ArgumentOutOfRangeException("layerID");
        }
Пример #13
0
        private void ValidateMapServiceSpatialReference()
        {
            // Currently only supporting map services published in 102100
            IMapServer3 mapServer = serverObjectHelper.ServerObject as IMapServer3;

            if (mapServer == null)
            {
                throw new Exception("Unable to access the map server.");
            }

            IMapServerInfo mapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName);

            _spatialReference = mapServerInfo.DefaultMapDescription.SpatialReference;
            var wkid = _spatialReference.FactoryCode;

            if (wkid != 102100 && wkid != 3857 && wkid != 102113)   // All interchangeable, though 102100 should supercede all
            {
                throw new NotSupportedException(string.Format("WKID {0} is not currently supported. Map service must be in Web Mercator Aux. Sphere (WKID: 102100, 102113, or 3857).", wkid));
            }
        }
        private IMapTableDescription GetTableDesc(IMapServer3 mapServer, int layerID)
        {
            ILayerDescriptions layerDescs = mapServer.GetServerInfo(mapServer.DefaultMapName).DefaultMapDescription.LayerDescriptions;
            long c = layerDescs.Count;

            for (int i = 0; i < c; i++)
            {
                ILayerDescription3 layerDesc = (ILayerDescription3)layerDescs.get_Element(i);

                if (layerDesc.ID == layerID)
                {
                    layerDesc.LayerResultOptions = new LayerResultOptionsClass();
                    layerDesc.LayerResultOptions.GeometryResultOptions = new GeometryResultOptionsClass();
                    layerDesc.LayerResultOptions.GeometryResultOptions.DensifyGeometries = true;

                    return((IMapTableDescription)layerDesc);
                }
            }

            throw new ArgumentOutOfRangeException("layerID");
        }
Пример #15
0
        /// <summary>
        /// construct() is called only once, when the SOE is created, after IServerObjectExtension.init() is called. This
        /// method hands back the configuration properties for the SOE as a property set. You should include any expensive
        /// initialization logic for your SOE within your implementation of construct().
        /// </summary>
        /// <param name="props">object propertySet</param>
        public void Construct(IPropertySet props)
        {
            AutoTimer timer = new AutoTimer();

            this.LogInfoSimple(this.soeName + ": il costruttore è stato avviato.", MethodBase.GetCurrentMethod().Name);

            try
            {
                this.configProps = props;
                if (this.configProps.GetProperty("workspaceId") is string)
                {
                    this.workspaceId = this.configProps.GetProperty("workspaceId") as string;
                }

                if (this.configProps.GetProperty("connectionString") is string)
                {
                    this.workspace = Helper.OpenFileGdbWorkspace(this.configProps.GetProperty("connectionString") as string);
                }

                IMapServer3    mapServer     = this.serverObjectHelper.ServerObject as IMapServer3;
                IMapServerInit mapServerInit = mapServer as IMapServerInit;

                string hostnameWebAdaptor = string.Empty;
                if (this.configProps.GetProperty("rootWebAdaptor") is string)
                {
                    hostnameWebAdaptor = this.configProps.GetProperty("rootWebAdaptor") as string;
                }

                this.pathOutputVirtualAGS = Helper.CombineUri(hostnameWebAdaptor, mapServerInit.VirtualOutputDirectory);

                // c'è il replace perchè se il nome del servizio è in una cartella ags il percorso restituito ha '/' nel path tra folder ags e nome servizio
                this.pathOutputAGS = mapServerInit.PhysicalOutputDirectory.Replace('/', '\\');
            }
            catch (Exception ex)
            {
                this.LogError(this.soeName + ": " + ex.Message, MethodBase.GetCurrentMethod().Name);
            }

            this.LogInfoSimple(this.soeName + ": il costruttore ha concluso", MethodBase.GetCurrentMethod().Name, timer.Elapsed);
        }
Пример #16
0
        /// <summary>
        /// get RouteLayerInfo from Id
        /// </summary>
        /// <param name="routeLayerID">value of routeLayerID</param>
        /// <returns>object RouteLayerInfo</returns>
        private RouteLayerInfo GetRouteLayerInfo(int routeLayerID)
        {
            if (routeLayerID < 0)
            {
                throw new ArgumentOutOfRangeException("routeLayerID");
            }

            IMapServer3    serverObject  = this.GetMapServer();
            IMapLayerInfos mapLayerInfos = serverObject.GetServerInfo(serverObject.DefaultMapName).MapLayerInfos;
            long           count         = mapLayerInfos.Count;

            for (int i = 0; i < count; i++)
            {
                IMapLayerInfo mapLayerInfo = mapLayerInfos.get_Element(i);
                if (mapLayerInfo.ID == routeLayerID)
                {
                    return(new RouteLayerInfo(mapLayerInfo));
                }
            }

            throw new ArgumentOutOfRangeException("routeLayerID");
        }
Пример #17
0
        private string  UseAOToCreateUpdateFeatures(string sql)
        {
            string retString = "in get UseAOToCreateUpdateFeatures >";

            try
            {
                //get map server
                IMapServer3 mapServer = (IMapServer3)serverObjectHelper.ServerObject;

                IMapServerDataAccess dataAccess = (IMapServerDataAccess)mapServer;

                IFeatureClass fc = dataAccess.GetDataSource(mapServer.DefaultMapName, 0) as IFeatureClass;
                retString += ">Attempting to get wse";
                IWorkspace ws = (fc as IDataset).Workspace;
                //string sql = @"exec dbo.apLITSaveChanges @curGeoLocID = 5, @NewGeoLocId = 2, @address = '222W.Pine', @windowsLogin = '******', @city = 'wern', @zipCode = '12345', @Latitude = 1, @longitude = 2, @facilityname = 'asdf', @appID = 'asdf', @serverName = 'asdf', @status = 'r'";
                ws.ExecuteSQL(sql);
                return("ok");
            }
            catch (Exception ex)
            {
                return("ERROR " + ex.ToString());
            }
        }
Пример #18
0
        /// <summary>
        /// Create a table description, which includes generalization options
        /// </summary>
        /// <param name="mapServer"></param>
        /// <param name="layerId"></param>
        /// <param name="zoomLevel"></param>
        /// <returns></returns>
        private IMapTableDescription GetTableDescription(IMapServer3 mapServer, int layerId, int zoomLevel)
        {
            ILayerDescriptions layerDescs =
                mapServer.GetServerInfo(mapServer.DefaultMapName).DefaultMapDescription.LayerDescriptions;
            int count = layerDescs.Count;

            for (int i = 0; i < count; i++)
            {
                ILayerDescription3 layerDesc = (ILayerDescription3)layerDescs.get_Element(i);

                if (layerDesc.ID == layerId)
                {
                    layerDesc.LayerResultOptions = new LayerResultOptionsClass();
                    layerDesc.LayerResultOptions.GeometryResultOptions = new GeometryResultOptionsClass();
                    // Generalize geometries based on zoom level
                    layerDesc.LayerResultOptions.GeometryResultOptions.GeneralizeGeometries   = true;
                    layerDesc.LayerResultOptions.GeometryResultOptions.MaximumAllowableOffset = 2000 / (zoomLevel + 1);

                    return((IMapTableDescription)layerDesc);
                }
            }

            throw new ArgumentOutOfRangeException("layerID");
        }
        private IMapLayerInfo GetLayerInfo(IMapServer3 mapServer, int layerID)
        {
            IMapLayerInfo layerInfo;

            IMapLayerInfos layerInfos = mapServer.GetServerInfo(mapServer.DefaultMapName).MapLayerInfos;
            long c = layerInfos.Count;

            for (int i = 0; i < c; i++)
            {
                layerInfo = layerInfos.get_Element(i);
                if (layerInfo.ID == layerID)
                    return layerInfo;
            }

            throw new ArgumentOutOfRangeException("layerID");
        }
        private IMapTableDescription GetTableDesc(IMapServer3 mapServer, int layerID)
        {
            ILayerDescriptions layerDescs = mapServer.GetServerInfo(mapServer.DefaultMapName).DefaultMapDescription.LayerDescriptions;
            long c = layerDescs.Count;

            for (int i = 0; i < c; i++)
            {
                ILayerDescription3 layerDesc = (ILayerDescription3)layerDescs.get_Element(i);

                if (layerDesc.ID == layerID)
                {
                    layerDesc.LayerResultOptions = new LayerResultOptionsClass();
                    layerDesc.LayerResultOptions.GeometryResultOptions = new GeometryResultOptionsClass();
                    layerDesc.LayerResultOptions.GeometryResultOptions.DensifyGeometries = true;

                    return (IMapTableDescription)layerDesc;
                }
            }

            throw new ArgumentOutOfRangeException("layerID");
        }
Пример #21
0
        private esriUnits GetMapServiceUnits(IMapServer3 mapServer)
        {
            IMapServerInfo mapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName);

            return(mapServerInfo.MapUnits);
        }
Пример #22
0
        private ISpatialReference GetSpatialReferenceFromMapService(IMapServer3 mapServer)
        {
            IMapServerInfo mapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName);

            return(mapServerInfo.DefaultMapDescription.SpatialReference);
        }
Пример #23
0
        /// <summary>
        /// Gets the table description.
        /// </summary>
        /// <param name="mapServer">The map server.</param>
        /// <param name="layerId">The layer id.</param>
        /// <returns></returns>
        /// <remarks>Sets the result options to return field names and densify geometries</remarks>
        private IMapTableDescription GetTableDesc(IMapServer3 mapServer, int layerId)
        {
            ILayerDescriptions layerDescs = mapServer.GetServerInfo(mapServer.DefaultMapName).DefaultMapDescription.LayerDescriptions;
            long c = layerDescs.Count;

            for (int i = 0; i < c; i++)
            {
                ILayerDescription3 layerDesc = (ILayerDescription3)layerDescs.get_Element(i);

                if (layerDesc.ID == layerId)
                {
                    layerDesc.LayerResultOptions = new LayerResultOptionsClass();
                    layerDesc.LayerResultOptions.ReturnFieldNamesInResults = true;

                    //optionally apply densify or generalise operation to geometries
                    //layerDesc.LayerResultOptions.GeometryResultOptions = new GeometryResultOptionsClass();
                    //layerDesc.LayerResultOptions.GeometryResultOptions.DensifyGeometries = false;

                    return (IMapTableDescription)layerDesc;
                }
            }

            throw new ArgumentOutOfRangeException("layerId");
        }
Пример #24
0
 private esriUnits GetMapServiceUnits(IMapServer3 mapServer)
 {
     IMapServerInfo mapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName);
     return mapServerInfo.MapUnits;
 }
Пример #25
0
 private ISpatialReference GetSpatialReferenceFromMapService(IMapServer3 mapServer)
 {
     IMapServerInfo mapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName);
     return mapServerInfo.DefaultMapDescription.SpatialReference;
 }
Пример #26
0
        private ILayerDescription3 GetLayerDesc(IMapServer3 mapServer, int layerId)
        {
            ILayerDescriptions layerDescs = mapServer.GetServerInfo(mapServer.DefaultMapName).DefaultMapDescription.LayerDescriptions;
            long c = layerDescs.Count;

            for (int i = 0; i < c; i++)
            {
                ILayerDescription3 layerDesc = (ILayerDescription3)layerDescs.get_Element(i);

                if (layerDesc.ID == layerId)
                {
                    return layerDesc;
                }
            }

            throw new ArgumentOutOfRangeException("layerId");
        }
Пример #27
0
        /// <summary>
        /// Create a table description, which includes generalization options
        /// </summary>
        /// <param name="mapServer"></param>
        /// <param name="layerId"></param>
        /// <param name="zoomLevel"></param>
        /// <returns></returns>
        private IMapTableDescription GetTableDescription(IMapServer3 mapServer, int layerId, int zoomLevel)
        {
            ILayerDescriptions layerDescs =
                mapServer.GetServerInfo(mapServer.DefaultMapName).DefaultMapDescription.LayerDescriptions;
            int count = layerDescs.Count;

            for (int i = 0; i < count; i++)
            {
                ILayerDescription3 layerDesc = (ILayerDescription3)layerDescs.get_Element(i);

                if (layerDesc.ID == layerId)
                {
                    layerDesc.LayerResultOptions = new LayerResultOptionsClass();
                    layerDesc.LayerResultOptions.GeometryResultOptions = new GeometryResultOptionsClass();
                    // Generalize geometries based on zoom level
                    layerDesc.LayerResultOptions.GeometryResultOptions.GeneralizeGeometries = true;
                    layerDesc.LayerResultOptions.GeometryResultOptions.MaximumAllowableOffset = 2000 / (zoomLevel + 1);

                    return (IMapTableDescription)layerDesc;
                }
            }

            throw new ArgumentOutOfRangeException("layerID");
        }
Пример #28
0
        public void Construct(IPropertySet props)
        {
            configProps = props;
            // Read the properties.

            if (props.GetProperty("FieldName") != null)
            {
                m_mapFieldToQuery = props.GetProperty("FieldName") as string;
            }
            else
            {
                throw new ArgumentNullException();
            }
            if (props.GetProperty("LayerName") != null)
            {
                m_mapLayerNameToQuery = props.GetProperty("LayerName") as string;
            }
            else
            {
                throw new ArgumentNullException();
            }
            try
            {
                // Get the feature layer to be queried.
                // Since the layer is a property of the SOE, this only has to be done once.
                IMapServer3    mapServer = (IMapServer3)serverObjectHelper.ServerObject;
                string         mapName   = mapServer.DefaultMapName;
                IMapLayerInfo  layerInfo;
                IMapLayerInfos layerInfos = mapServer.GetServerInfo(mapName).MapLayerInfos;
                // Find the index position of the map layer to query.
                int c          = layerInfos.Count;
                int layerIndex = 0;
                for (int i = 0; i < c; i++)
                {
                    layerInfo = layerInfos.get_Element(i);
                    if (layerInfo.Name == m_mapLayerNameToQuery)
                    {
                        layerIndex = i;
                        break;
                    }
                }
                // Use IMapServerDataAccess to get the data
                IMapServerDataAccess dataAccess = (IMapServerDataAccess)mapServer;
                // Get access to the source feature class.
                m_fcToQuery = (IFeatureClass)dataAccess.GetDataSource(mapName, layerIndex);
                if (m_fcToQuery == null)
                {
                    logger.LogMessage(ServerLogger.msgType.error, "Construct", 8000, "SOE custom error: Layer name not found.");
                    return;
                }
                // Make sure the layer contains the field specified by the SOE's configuration.
                if (m_fcToQuery.FindField(m_mapFieldToQuery) == -1)
                {
                    logger.LogMessage(ServerLogger.msgType.error, "Construct", 8000, "SOE custom error: Field not found in layer.");
                }
            }
            catch
            {
                logger.LogMessage(ServerLogger.msgType.error, "Construct", 8000, "SOE custom error: Could not get the feature layer.");
            }
        }
Пример #29
0
        /// <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("{}"));
            }
        }