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