Hi,
when adding a query layer to ArcMap by ArcObjects code the extent of the newly created layer will be calculated based on data by default. This causes significant performance issues (i.e. full table scans with several millions rows).
When redefining a query layer in ArcMap manually an options-dialog is provided where you can choose between "Input Extent" and "Use Spatial Reference Extent" (see http://desktop.arcgis.com/en/arcmap/10.3/map/working-with-layers/creating-a-query-layer.htm).
The second option is what I need. Is there any ArcObjects interface to force this? Is there any way to prevent the extent calculation and to use a given Extent?
I've tried without effect to deal with:
- Setting ILayer2.AreaOfInterest before loading layer
- Setting SpatialDomain in IFeatureClass.SpatialReference of the query class
- Loading a layerfile is no option in my case (the extent will be saved in layerfile)
Thank you.
Sample code:
Protected Sub AddNewQueryLayerToFocusMap(ByVal sqlWorkspace As ISqlWorkspace, _
ByVal featureClassName As String, _
ByVal geomType As esriGeometryType, _
ByVal spatialRef As ISpatialReference,
ByVal map As IMap)
Dim query = String.Format("SELECT * FROM {0}", featureClassName)
Dim queryDesc = sqlWorkspace.GetQueryDescription(query)
queryDesc.OIDFields = "OBJECTID"
queryDesc.GeometryType = geomType
queryDesc.SpatialReference = spatialRef
' Ensure that the specified name for the Query Layer feature class is not
' already being used.
Dim newName = String.Empty
sqlWorkspace.CheckDatasetName(featureClassName, queryDesc, newName)
Dim queryClass = sqlWorkspace.OpenQueryClass(newName, queryDesc)
Dim featureClass = TryCast(queryClass, IFeatureClass)
Dim featureLayer = New FeatureLayerClass() With {.FeatureClass = featureClass}
map.AddLayer(featureLayer) '==> extent calculation will be performed
End Sub
Unfortunately, there is no built-in functionality that would allow one to choose between "Input Extent" and "Use Spatial Reference". This requires usage of Custom Layers and overriding the default behaviour of a feature layers extent property (IFeatureLayer.Extent). See http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/#/Creating_custom_layers/000100000...http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/#/Creating_custom_layers/000100000... for details.
See custom layer class below which makes it possible to define a fixed extent for a underlying feature layer:
<Guid("3460FB55-4326-4d28-9F96-D62211B0C754"), ClassInterface(ClassInterfaceType.None), ComVisible(True), ProgId("CustomLayer")> _Public NotInheritable Class CustomLayer Inherits BaseCustomLayer Implements IIdentify Implements ILegendInfo Private _featureLayer As IFeatureLayer Private _env As IEnvelope Public Sub New(feautreLayer As IFeatureLayer, ByVal env As IEnvelope) _featureLayer = feautreLayer End Sub Public Overrides Sub Draw(drawPhase As ESRI.ArcGIS.esriSystem.esriDrawPhase, Display As ESRI.ArcGIS.Display.IDisplay, trackCancel As ESRI.ArcGIS.esriSystem.ITrackCancel) _featureLayer.Draw(drawPhase, Display, trackCancel) End Sub Public Overrides ReadOnly Property Extent() As IEnvelope Get Return _env End Get End Property Public Function Identify(pGeom As IGeometry) As ESRI.ArcGIS.esriSystem.IArray Implements IIdentify.Identify Return CType(_featureLayer, IIdentify).Identify(pGeom) End Function Public ReadOnly Property LegendGroup(Index As Integer) As ILegendGroup Implements ILegendInfo.LegendGroup Get Return CType(_featureLayer, ILegendInfo).LegendGroup(Index) End Get End Property Public ReadOnly Property LegendGroupCount As Integer Implements ILegendInfo.LegendGroupCount Get Return CType(_featureLayer, ILegendInfo).LegendGroupCount End Get End Property Public ReadOnly Property LegendItem As ILegendItem Implements ILegendInfo.LegendItem Get Return CType(_featureLayer, ILegendInfo).LegendItem End Get End Property Public Property SymbolsAreGraduated As Boolean Implements ILegendInfo.SymbolsAreGraduated Get Return CType(_featureLayer, ILegendInfo).SymbolsAreGraduated End Get Set(value As Boolean) CType(_featureLayer, ILegendInfo).SymbolsAreGraduated = value End Set End Property
Did you ever find a workaround for this (e.g. some way to pass in the known extent)?
Please see the workaround I mentioned in my previous posting, which is working for my purposes. Implementing a custom layer enables you to write you own code to determine layers's extent and passing to custom layer class.
I didn't find any other approaches to fix this problem.