About the Simple point plug-in data source Sample
[C#]
SimplePointCursor.cs
using System; using System.Runtime.InteropServices; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; namespace ESRI.ArcGIS.Samples.SimplePointPlugin { /// <summary> /// Summary description for SimplePointCursor. /// </summary> [ComVisible(false)] internal class SimplePointCursor : IPlugInCursorHelper { private bool m_bIsFinished = false; private int m_iInterate = -1; private string m_sbuffer; private System.IO.StreamReader m_pStreamReader; private int m_iOID = -1; private System.Array m_fieldMap; private IFields m_fields; private IEnvelope m_searchEnv; private IGeometry m_wkGeom; private IPoint[] m_workPts; #region HRESULTs definitions private const int E_FAIL = unchecked((int)0x80004005); private const int S_FALSE = 1; #endregion private bool m_bM, m_bZ; public SimplePointCursor(string filePath, IFields fields, int OID, System.Array fieldMap, IEnvelope queryEnv, esriGeometryType geomType) { //HIGHLIGHT: 0 - Set up cursor m_bIsFinished = false; m_pStreamReader = new System.IO.StreamReader(filePath); m_fields = fields; m_iOID = OID; m_fieldMap = fieldMap; m_searchEnv = queryEnv; switch (geomType) { case esriGeometryType.esriGeometryPolygon: m_wkGeom = new Polygon() as IGeometry; m_workPts = new PointClass[5]; for (int i = 0; i < m_workPts.Length; i++) m_workPts[i] = new PointClass(); break; case esriGeometryType.esriGeometryPolyline: m_wkGeom = new PolylineClass() as IGeometry; m_workPts = new PointClass[5]; for (int i = 0; i < m_workPts.Length; i++) m_workPts[i] = new PointClass(); break; case esriGeometryType.esriGeometryPoint: m_wkGeom = new PointClass() as IGeometry; break; default: //doesn't need to set worker geometry if it is table break; } //advance cursor so data is readily available this.NextRecord(); } #region IPlugInCursorHelper Members #region Queries... //HIGHLIGHT: 2 - Query & read data public int QueryValues(IRowBuffer Row) { try { if (m_sbuffer == null) return -1; for (int i = 0; i < m_fieldMap.GetLength(0); i++) { //HIGHLIGHT: 2.2 QueryValues - field map interpretation if (m_fieldMap.GetValue(i).Equals(-1)) continue; IField valField = m_fields.get_Field(i); char parse = m_sbuffer[m_sbuffer.Length - 1]; switch (valField.Type) { case esriFieldType.esriFieldTypeInteger: case esriFieldType.esriFieldTypeDouble: case esriFieldType.esriFieldTypeSmallInteger: case esriFieldType.esriFieldTypeSingle: Row.set_Value(i, Convert.ToInt32(parse)); //get ascii code # for the character break; case esriFieldType.esriFieldTypeString: Row.set_Value(i, parse.ToString()); break; } } return m_iInterate; //HIGHLIGHT: 2.3 QueryValues - return OID } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return -1; } } public void QueryShape(IGeometry pGeometry) { if (pGeometry == null) return; try { double x, y; x = Convert.ToDouble(m_sbuffer.Substring(0, 6)); y = Convert.ToDouble(m_sbuffer.Substring(6, 6)); #region set M and Z aware if (m_bZ) ((IZAware)pGeometry).ZAware = true; if (m_bM) ((IMAware)pGeometry).MAware = true; #endregion //HIGHLIGHT: 2.1 QueryShape - (advanced) geometry construction if (pGeometry is IPoint) { ((IPoint)pGeometry).PutCoords(x, y); if (m_bM) ((IPoint)pGeometry).M = m_iInterate; if (m_bZ) ((IPoint)pGeometry).Z = m_iInterate * 100; } else if (pGeometry is IPolyline) buildPolyline((IPointCollection)pGeometry, x, y); else if (pGeometry is IPolygon) buildPolygon((IPointCollection)pGeometry, x, y); else pGeometry.SetEmpty(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(" Error: " + ex.Message); pGeometry.SetEmpty(); } } #endregion #region Next... //HIGHLIGHT: 1 - Looping mechanism public bool IsFinished() { return m_bIsFinished; } public void NextRecord() { if (m_bIsFinished) //error already thrown once return; //OID search has been performed if (m_iOID > -1 && m_sbuffer != null) { m_pStreamReader.Close(); m_bIsFinished = true; throw new COMException("End of SimplePoint Plugin cursor", E_FAIL); } else { //HIGHLIGHT: 1.1 Next - Read the file for text m_sbuffer = ReadFile(m_pStreamReader, m_iOID); if (m_sbuffer == null) { //finish reading, close the stream reader so resources will be released m_pStreamReader.Close(); m_bIsFinished = true; //HIGHLIGHT: 1.2 Next - Raise E_FAIL to notify end of cursor throw new COMException("End of SimplePoint Plugin cursor", E_FAIL); } //HIGHLIGHT: 1.3 Next - Search by envelope; or return all records and let post-filtering do //the work for you (performance overhead) else if (m_searchEnv != null && !(m_searchEnv.IsEmpty)) { this.QueryShape(m_wkGeom); IRelationalOperator pRelOp = (IRelationalOperator)m_wkGeom; if (!pRelOp.Disjoint((IGeometry)m_searchEnv)) return; //HIGHLIGHT: 1.4 Next - valid record within search geometry - stop advancing else this.NextRecord(); } } } #endregion #endregion #region Geometry construction public bool HasM { set { m_bM = value; } } public bool HasZ { set { m_bZ = value; } } private void buildPolygon(IPointCollection pGonColl, double x, double y) { m_workPts[0].PutCoords(x - 500, y - 500); m_workPts[1].PutCoords(x + 500, y - 500); m_workPts[2].PutCoords(x + 500, y + 500); m_workPts[3].PutCoords(x - 500, y + 500); m_workPts[4].PutCoords(x - 500, y - 500); try { bool add = (pGonColl.PointCount == 0); object missingVal = System.Reflection.Missing.Value; for (int i = 0; i< m_workPts.Length; i++) { ((IZAware)m_workPts[i]).ZAware = m_bZ; ((IMAware)m_workPts[i]).MAware = m_bM; if (m_bM) m_workPts[i].M = i % 4; if (m_bZ) m_workPts[i].Z = (i % 4) * 100; //match start and end points if (add) pGonColl.AddPoint(m_workPts[i], ref missingVal, ref missingVal); //The Add method only accepts either a before index or an after index. else pGonColl.UpdatePoint(i, m_workPts[i]); } } catch (Exception Ex) {System.Diagnostics.Debug.WriteLine(Ex.Message);} //Attempted to store an element of the incorrect type into the array. } private void buildPolyline(IPointCollection pGonColl, double x, double y) { m_workPts[0].PutCoords(x - 500, y - 500); m_workPts[1].PutCoords(x + 500, y - 500); m_workPts[2].PutCoords(x + 500, y + 500); m_workPts[3].PutCoords(x - 500, y + 500); m_workPts[4].PutCoords(x, y); try { bool add = (pGonColl.PointCount == 0); object missingVal = System.Reflection.Missing.Value; for (int i = 0; i< m_workPts.Length; i++) { ((IZAware)m_workPts[i]).ZAware = m_bZ; ((IMAware)m_workPts[i]).MAware = m_bM; if (m_bM) m_workPts[i].M = i; if (m_bZ) m_workPts[i].Z = i * 100; //add it point by point - .Net IDL limitation to do batch update? if (add) //pGonColl.AddPoints(5, ref m_workPts[0]);//strange error of type mismatch pGonColl.AddPoint(m_workPts[i], ref missingVal, ref missingVal); //The Add method only accepts either a before index or an after index. else pGonColl.UpdatePoint(i, m_workPts[i]); } //Can I user replace point collection or addPointcollection? } catch (Exception Ex) {System.Diagnostics.Debug.WriteLine(Ex.Message);} //Attempted to store an element of the incorrect type into the array. } #endregion private string ReadFile(System.IO.StreamReader sr, int lineNumber) { m_iInterate++; string buffer = sr.ReadLine(); if (buffer == null) return null; if (lineNumber > -1 && lineNumber != m_iInterate) buffer = ReadFile(sr, lineNumber); //System.Diagnostics.Debug.WriteLine(buffer); return buffer; } } }
[Visual Basic .NET]
SimplePointCursor.vb
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 SimplePointCursor. ''' </summary> <ComVisible(False)> _ Friend Class SimplePointCursor Implements IPlugInCursorHelper #Region "Class members" Private m_bIsFinished As Boolean = False Private m_iInterate As Integer = -1 Private m_sbuffer As String Private m_pStreamReader As System.IO.StreamReader Private m_iOID As Integer = -1 Private m_fieldMap As System.Array Private m_fields As IFields Private m_searchEnv As IEnvelope Private m_wkGeom As IGeometry Private m_workPts As IPoint() #End Region #Region "HRESULTs definitions" Private Const E_FAIL As Long = (CInt(&H80004005)) Private Const S_FALSE As Long = 1 #End Region #Region "class members" Private m_bM, m_bZ As Boolean #End Region #Region "Class constructor" Public Sub New(ByVal filePath As String, ByVal fields As IFields, ByVal OID As Integer, ByVal fieldMap As System.Array, ByVal queryEnv As IEnvelope, ByVal geomType As esriGeometryType) 'HIGHLIGHT: 0 - Set up cursor m_bIsFinished = False m_pStreamReader = New System.IO.StreamReader(filePath) m_fields = fields m_iOID = OID m_fieldMap = fieldMap m_searchEnv = queryEnv Select Case geomType Case esriGeometryType.esriGeometryPolygon m_wkGeom = TryCast(New PolygonClass(), IGeometry) m_workPts = New PointClass(4) {} Dim i As Integer = 0 Do While i < m_workPts.Length m_workPts(i) = New PointClass() i += 1 Loop Case esriGeometryType.esriGeometryPolyline m_wkGeom = TryCast(New PolylineClass(), IGeometry) m_workPts = New PointClass(4) {} Dim i As Integer = 0 Do While i < m_workPts.Length m_workPts(i) = New PointClass() i += 1 Loop Case esriGeometryType.esriGeometryPoint Dim point As IPoint = New Point m_wkGeom = TryCast(point, IGeometry) Case Else 'doesn't need to set worker geometry if it is table End Select 'advance cursor so data is readily available Me.NextRecord() End Sub #End Region #Region "IPlugInCursorHelper Members" #Region "Queries..." 'HIGHLIGHT: 2 - Query & read data Public Function QueryValues(ByVal Row As IRowBuffer) As Integer Implements IPlugInCursorHelper.QueryValues Try If m_sbuffer Is Nothing Then Return -1 End If Dim i As Integer = 0 Do While i < m_fieldMap.GetLength(0) 'HIGHLIGHT: 2.2 QueryValues - field map interpretation If m_fieldMap.GetValue(i).Equals(-1) Then i += 1 Continue Do End If Dim valField As IField = m_fields.Field(i) Dim parse As Char = m_sbuffer.Chars(m_sbuffer.Length - 1) Select Case valField.Type Case esriFieldType.esriFieldTypeInteger, esriFieldType.esriFieldTypeDouble, esriFieldType.esriFieldTypeSmallInteger, esriFieldType.esriFieldTypeSingle Row.Value(i) = Convert.ToInt32(parse) 'get ascii code # for the character Case esriFieldType.esriFieldTypeString Row.Value(i) = parse.ToString() End Select i += 1 Loop Return m_iInterate 'HIGHLIGHT: 2.3 QueryValues - return OID Catch ex As Exception System.Diagnostics.Debug.WriteLine(ex.Message) Return -1 End Try End Function Public Sub QueryShape(ByVal pGeometry As IGeometry) Implements IPlugInCursorHelper.QueryShape If pGeometry Is Nothing Then Return End If Try Dim x, y As Double x = Convert.ToDouble(m_sbuffer.Substring(0, 6)) y = Convert.ToDouble(m_sbuffer.Substring(6, 6)) ' #Region "set M and Z aware" If m_bZ Then CType(pGeometry, IZAware).ZAware = True End If If m_bM Then CType(pGeometry, IMAware).MAware = True End If ' #End Region 'HIGHLIGHT: 2.1 QueryShape - (advanced) geometry construction If TypeOf pGeometry Is IPoint Then CType(pGeometry, IPoint).PutCoords(x, y) If m_bM Then CType(pGeometry, IPoint).M = m_iInterate End If If m_bZ Then CType(pGeometry, IPoint).Z = m_iInterate * 100 End If ElseIf TypeOf pGeometry Is IPolyline Then buildPolyline(CType(pGeometry, IPointCollection), x, y) ElseIf TypeOf pGeometry Is IPolygon Then buildPolygon(CType(pGeometry, IPointCollection), x, y) Else pGeometry.SetEmpty() End If Catch ex As Exception System.Diagnostics.Debug.WriteLine(" Error: " & ex.Message) pGeometry.SetEmpty() End Try End Sub #End Region #Region "Next..." 'HIGHLIGHT: 1 - Looping mechanism Public Function IsFinished() As Boolean Implements IPlugInCursorHelper.IsFinished Return m_bIsFinished End Function Public Sub NextRecord() Implements IPlugInCursorHelper.NextRecord If m_bIsFinished Then 'error already thrown once Return End If 'OID search has been performed If m_iOID > -1 AndAlso Not m_sbuffer Is Nothing Then m_pStreamReader.Close() m_bIsFinished = True Throw New COMException("End of SimplePoint Plugin cursor", E_FAIL) Else 'HIGHLIGHT: 1.1 Next - Read the file for text m_sbuffer = ReadFile(m_pStreamReader, m_iOID) If m_sbuffer Is Nothing Then 'finish reading, close the stream reader so resources will be released m_pStreamReader.Close() m_bIsFinished = True 'HIGHLIGHT: 1.2 Next - Raise E_FAIL to notify end of cursor Throw New COMException("End of SimplePoint Plugin cursor", E_FAIL) 'HIGHLIGHT: 1.3 Next - Search by envelope; or return all records and let post-filtering do 'the work for you (performance overhead) ElseIf Not m_searchEnv Is Nothing AndAlso Not (m_searchEnv.IsEmpty) Then Me.QueryShape(m_wkGeom) Dim pRelOp As IRelationalOperator = CType(m_wkGeom, IRelationalOperator) If (Not pRelOp.Disjoint(CType(m_searchEnv, IGeometry))) Then Return 'HIGHLIGHT: 1.4 Next - valid record within search geometry - stop advancing Else Me.NextRecord() End If End If End If End Sub #End Region #End Region #Region "Geometry construction" Public WriteOnly Property HasM() As Boolean Set(ByVal value As Boolean) m_bM = value End Set End Property Public WriteOnly Property HasZ() As Boolean Set(ByVal value As Boolean) m_bZ = value End Set End Property Private Sub buildPolygon(ByVal pGonColl As IPointCollection, ByVal x As Double, ByVal y As Double) m_workPts(0).PutCoords(x - 500, y - 500) m_workPts(1).PutCoords(x + 500, y - 500) m_workPts(2).PutCoords(x + 500, y + 500) m_workPts(3).PutCoords(x - 500, y + 500) m_workPts(4).PutCoords(x - 500, y - 500) Try Dim add As Boolean = (pGonColl.PointCount = 0) Dim missingVal As Object = System.Reflection.Missing.Value Dim i As Integer = 0 Do While i < m_workPts.Length CType(m_workPts(i), IZAware).ZAware = m_bZ CType(m_workPts(i), IMAware).MAware = m_bM If m_bM Then m_workPts(i).M = i Mod 4 End If If m_bZ Then m_workPts(i).Z = (i Mod 4) * 100 'match start and end points End If If add Then pGonColl.AddPoint(m_workPts(i), missingVal, missingVal) 'The Add method only accepts either a before index or an after index. Else pGonColl.UpdatePoint(i, m_workPts(i)) End If i += 1 Loop Catch Ex As Exception System.Diagnostics.Debug.WriteLine(Ex.Message) End Try 'Attempted to store an element of the incorrect type into the array. End Sub Private Sub buildPolyline(ByVal pGonColl As IPointCollection, ByVal x As Double, ByVal y As Double) m_workPts(0).PutCoords(x - 500, y - 500) m_workPts(1).PutCoords(x + 500, y - 500) m_workPts(2).PutCoords(x + 500, y + 500) m_workPts(3).PutCoords(x - 500, y + 500) m_workPts(4).PutCoords(x, y) Try Dim add As Boolean = (pGonColl.PointCount = 0) Dim missingVal As Object = System.Reflection.Missing.Value Dim i As Integer = 0 Do While i < m_workPts.Length CType(m_workPts(i), IZAware).ZAware = m_bZ CType(m_workPts(i), IMAware).MAware = m_bM If m_bM Then m_workPts(i).M = i End If If m_bZ Then m_workPts(i).Z = i * 100 End If 'add it point by point - .Net IDL limitation to do batch update? If add Then 'pGonColl.AddPoints(5, ref m_workPts[0]);//strange error of type mismatch pGonColl.AddPoint(m_workPts(i), missingVal, missingVal) 'The Add method only accepts either a before index or an after index. Else pGonColl.UpdatePoint(i, m_workPts(i)) End If i += 1 Loop 'Can I user replace point collection or addPointcollection? Catch Ex As Exception System.Diagnostics.Debug.WriteLine(Ex.Message) End Try 'Attempted to store an element of the incorrect type into the array. End Sub #End Region #Region "private methods" Private Function ReadFile(ByVal sr As System.IO.StreamReader, ByVal lineNumber As Integer) As String m_iInterate += 1 Dim buffer As String = sr.ReadLine() If buffer Is Nothing Then Return Nothing End If If lineNumber > -1 AndAlso lineNumber <> m_iInterate Then buffer = ReadFile(sr, lineNumber) End If 'System.Diagnostics.Debug.WriteLine(buffer); Return buffer End Function #End Region End Class