SimplePointDataset.vb
' Copyright 2010 ESRI ' ' All rights reserved under the copyright laws of the United States ' and applicable international laws, treaties, and conventions. ' ' You may freely redistribute and use this sample code, with or ' without modification, provided you include the original copyright ' notice and use restrictions. ' ' See the use restrictions. ' Imports Microsoft.VisualBasic Imports System Imports System.Runtime.InteropServices Imports ESRI.ArcGIS.esriSystem Imports ESRI.ArcGIS.Geodatabase Imports ESRI.ArcGIS.Geometry ''' <summary> ''' Summary description for SimplePointDataset. ''' </summary> <ComVisible(False)> _ Friend Class SimplePointDataset Implements IPlugInDatasetInfo, IPlugInDatasetHelper #Region "Class members" Private m_wkspString, m_datasetString As String Private m_bound As IEnvelope Private m_fullPath As String #End Region #Region "Class constructor" Public Sub New(ByVal wkspString As String, ByVal datasetString As String) 'HIGHLIGHT: constructor checks valid workspace string path and dataset name m_wkspString = wkspString m_fullPath = System.IO.Path.Combine(wkspString, datasetString) If System.IO.Path.HasExtension(datasetString) Then m_datasetString = System.IO.Path.GetFileNameWithoutExtension(datasetString) Else m_datasetString = datasetString m_fullPath &= ".csp" 'add the extension End If End Sub #End Region #Region "IPlugInDatasetInfo Members " 'HIGHLIGHT: IPlugInDatasetInfo - lightweight! Public ReadOnly Property LocalDatasetName() As String Implements IPlugInDatasetInfo.LocalDatasetName Get Return m_datasetString End Get End Property Public ReadOnly Property ShapeFieldName() As String Implements IPlugInDatasetInfo.ShapeFieldName Get If Me.DatasetType = esriDatasetType.esriDTTable Then Return Nothing End If Return "Shape" End Get End Property Public ReadOnly Property DatasetType() As esriDatasetType Implements IPlugInDatasetInfo.DatasetType Get ' return esriDatasetType.esriDTTable; ' return esriDatasetType.esriDTFeatureClass; Return esriDatasetType.esriDTFeatureDataset End Get End Property Public ReadOnly Property GeometryType() As esriGeometryType Implements IPlugInDatasetInfo.GeometryType Get Return geometryTypeByID(-1) 'might not be always easy to get End Get End Property #End Region #Region "IPlugInDatasetHelper Members" Public ReadOnly Property Bounds() As ESRI.ArcGIS.Geometry.IEnvelope Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.Bounds Get If Me.DatasetType = esriDatasetType.esriDTTable Then Return Nothing End If If m_bound Is Nothing Then ' #Region "use cursor go through records, or we can parse the file directly" m_bound = New EnvelopeClass() m_bound.SpatialReference = Me.spatialReference Dim flds As IFields = Me.Fields(0) Dim fieldMapArray As Integer() = New Integer(flds.FieldCount - 1) {} Dim i As Integer = 0 Do While i < flds.FieldCount fieldMapArray(i) = -1 'shape field always ignored? i += 1 Loop Dim x1 As Double = 999999, y1 As Double = 999999, x2 As Double = 0, y2 As Double = 0 'assumes all positive value in the file 'Set with appropriate geometry Dim workGeom As IGeometry Dim cursor As IPlugInCursorHelper If Me.DatasetType = esriDatasetType.esriDTFeatureDataset Then workGeom = New PolygonClass() cursor = Me.FetchAll(2, Nothing, fieldMapArray) Else workGeom = New PointClass() cursor = Me.FetchAll(0, Nothing, fieldMapArray) End If workGeom.SpatialReference = Me.spatialReference Do While True Try cursor.QueryShape(workGeom) If workGeom.Envelope.XMin < x1 Then x1 = workGeom.Envelope.XMin End If If workGeom.Envelope.XMax > x2 Then x2 = workGeom.Envelope.XMax End If If workGeom.Envelope.YMin < y1 Then y1 = workGeom.Envelope.YMin End If If workGeom.Envelope.YMax > y2 Then y2 = workGeom.Envelope.YMax End If cursor.NextRecord() Catch comEx As COMException System.Diagnostics.Debug.WriteLine(comEx.Message) Exit Do 'catch E_FAIL when cursor reaches the end, exit loop Catch ex As Exception System.Diagnostics.Debug.WriteLine(ex.Message) End Try Loop m_bound.PutCoords(x1, y1, x2, y2) ' #End Region End If 'HIGHLIGHT: return clone envelope for bound Dim cloneEnv As IClone = CType(m_bound, IClone) Return CType(cloneEnv.Clone(), IEnvelope) End Get End Property Public ReadOnly Property ClassCount() As Integer Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.ClassCount Get If Me.DatasetType = esriDatasetType.esriDTFeatureDataset Then Return 12 End If Return 1 End Get End Property Public ReadOnly Property ClassIndex(ByVal Name As String) As Integer Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.ClassIndex Get Dim i As Integer = 0 Do While i < Me.ClassCount If Name.Equals(Me.ClassName(i)) Then Return i End If i += 1 Loop Return -1 End Get End Property Public ReadOnly Property ClassName(ByVal Index As Integer) As String Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.ClassName Get If Index Mod 3 = 0 Then m_datasetString = "Point" End If If Index Mod 3 = 1 Then m_datasetString = "Polyline" End If If Index Mod 3 = 2 Then m_datasetString = "Polygon" End If If (Index >= 3 AndAlso Index < 6) OrElse Index >= 9 Then m_datasetString &= "M" End If If Index >= 6 Then m_datasetString &= "Z" End If Return m_datasetString End Get End Property #Region "Fetching - returns cursor" 'HIGHLIGHT: Fetching Public Function FetchAll(ByVal ClassIndex As Integer, ByVal WhereClause As String, ByVal FieldMap As Object) As ESRI.ArcGIS.Geodatabase.IPlugInCursorHelper Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.FetchAll Try Dim allCursor As SimplePointCursor = New SimplePointCursor(m_fullPath, Me.Fields(ClassIndex), -1, CType(FieldMap, System.Array), Nothing, Me.geometryTypeByID(ClassIndex)) setMZ(allCursor, ClassIndex) Return CType(allCursor, IPlugInCursorHelper) Catch ex As Exception System.Diagnostics.Debug.WriteLine(ex.Message) Return Nothing End Try End Function Public Function FetchByEnvelope(ByVal ClassIndex As Integer, ByVal env As ESRI.ArcGIS.Geometry.IEnvelope, ByVal strictSearch As Boolean, ByVal WhereClause As String, ByVal FieldMap As Object) As ESRI.ArcGIS.Geodatabase.IPlugInCursorHelper Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.FetchByEnvelope If Me.DatasetType = esriDatasetType.esriDTTable Then Return Nothing End If 'env passed in always has same spatial reference as the data 'for identify, it will check if search geometry intersect dataset bound 'but not ITable.Search(pSpatialQueryFilter, bRecycle) etc 'so here we should check if input env falls within extent Dim boundEnv As IEnvelope = Me.Bounds boundEnv.Project(env.SpatialReference) If boundEnv.IsEmpty Then Return Nothing 'or raise error? End If Try Dim spatialCursor As SimplePointCursor = New SimplePointCursor(m_fullPath, Me.Fields(ClassIndex), -1, CType(FieldMap, System.Array), env, Me.geometryTypeByID(ClassIndex)) setMZ(spatialCursor, ClassIndex) Return CType(spatialCursor, IPlugInCursorHelper) Catch ex As Exception System.Diagnostics.Debug.WriteLine(ex.Message) Return Nothing End Try End Function Public Function FetchByID(ByVal ClassIndex As Integer, ByVal ID As Integer, ByVal FieldMap As Object) As ESRI.ArcGIS.Geodatabase.IPlugInCursorHelper Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.FetchByID Try Dim idCursor As SimplePointCursor = New SimplePointCursor(m_fullPath, Me.Fields(ClassIndex), ID, CType(FieldMap, System.Array), Nothing, Me.geometryTypeByID(ClassIndex)) setMZ(idCursor, ClassIndex) Return CType(idCursor, IPlugInCursorHelper) Catch ex As Exception 'will catch NextRecord error if it reaches EOF without finding a record System.Diagnostics.Debug.WriteLine(ex.Message) Return Nothing End Try End Function #End Region Public ReadOnly Property Fields(ByVal ClassIndex As Integer) As ESRI.ArcGIS.Geodatabase.IFields Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.Fields Get Dim fieldEdit As IFieldEdit Dim flds As IFields Dim fieldsEdit As IFieldsEdit Dim fcDesc As IObjectClassDescription If Me.DatasetType = esriDatasetType.esriDTTable Then fcDesc = New ObjectClassDescriptionClass() Else fcDesc = New FeatureClassDescriptionClass() End If flds = fcDesc.RequiredFields fieldsEdit = CType(flds, IFieldsEdit) fieldEdit = New FieldClass() fieldEdit.Length_2 = 1 fieldEdit.Name_2 = "ColumnOne" fieldEdit.Type_2 = esriFieldType.esriFieldTypeString fieldsEdit.AddField(CType(fieldEdit, IField)) 'HIGHLIGHT: Add extra int column fieldEdit = New FieldClass() fieldEdit.Name_2 = "Extra" fieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger fieldsEdit.AddField(CType(fieldEdit, IField)) 'HIGHLIGHT: Set shape field geometry definition If Me.DatasetType <> esriDatasetType.esriDTTable Then Dim field As IField = flds.Field(flds.FindField("Shape")) fieldEdit = CType(field, IFieldEdit) Dim geomDefEdit As IGeometryDefEdit = CType(field.GeometryDef, IGeometryDefEdit) geomDefEdit.GeometryType_2 = geometryTypeByID(ClassIndex) Dim shapeSRef As ISpatialReference = Me.spatialReference ' #Region "M & Z" 'M If (ClassIndex >= 3 AndAlso ClassIndex <= 5) OrElse ClassIndex >= 9 Then geomDefEdit.HasM_2 = True shapeSRef.SetMDomain(0, 1000) Else geomDefEdit.HasM_2 = False End If 'Z If ClassIndex >= 6 Then geomDefEdit.HasZ_2 = True shapeSRef.SetZDomain(0, 1000) Else geomDefEdit.HasZ_2 = False End If ' #End Region geomDefEdit.SpatialReference_2 = shapeSRef End If Return flds End Get End Property Public ReadOnly Property OIDFieldIndex(ByVal ClassIndex As Integer) As Integer Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.OIDFieldIndex Get Return 0 End Get End Property Public ReadOnly Property ShapeFieldIndex(ByVal ClassIndex As Integer) As Integer Implements ESRI.ArcGIS.Geodatabase.IPlugInDatasetHelper.ShapeFieldIndex Get 'add table to ArcMap via add data dialog calls this method, so if it's a table 'you must return -1 or else ArcMap crashes If Me.DatasetType = esriDatasetType.esriDTTable Then Return -1 End If Return 1 End Get End Property #End Region #Region "internal helper methods" Private Function geometryTypeByID(ByVal ClassIndex As Integer) As esriGeometryType If Me.DatasetType = esriDatasetType.esriDTTable Then Return esriGeometryType.esriGeometryNull End If If ClassIndex Mod 3 = 0 Then Return esriGeometryType.esriGeometryPoint ElseIf ClassIndex Mod 3 = 1 Then Return esriGeometryType.esriGeometryPolyline Else Return esriGeometryType.esriGeometryPolygon End If End Function Private ReadOnly Property spatialReference() As ISpatialReference Get If Me.DatasetType = esriDatasetType.esriDTTable Then Return Nothing End If 'singleton Dim srefFact As ISpatialReferenceFactory2 = New SpatialReferenceEnvironmentClass() Return srefFact.CreateProjectedCoordinateSystem(Convert.ToInt32(esriSRProjCSType.esriSRProjCS_World_Robinson)) ' WGS1984UTM_10N)); End Get End Property Private Sub setMZ(ByVal sptCursor As SimplePointCursor, ByVal Index As Integer) sptCursor.HasM = ((Index >= 3 AndAlso Index < 6) OrElse Index >= 9) sptCursor.HasZ = (Index >= 6) End Sub #End Region End Class