ArcObjects Library Reference  

SimplePointCursor

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