Click here to Skip to main content
15,892,746 members
Articles / Programming Languages / C#

Drawing Component to build GIS and CAM applications

Rate me:
Please Sign up or sign in to vote.
4.72/5 (14 votes)
21 Nov 20055 min read 107.9K   8K   123  
An object oriented drawing component for building GIS and CAM applications with multiple views of geometrical model, multiple resolution handling, layers, optimized graphics and more.
using System;

using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
//using System.Windows.Forms;

using System.Runtime.InteropServices;
using GeomModel;
using GdalImage;


namespace GDalGIS
{
	public class GdalImageCanvasItem : CanvasItem
	{
		float x;
		float y;
		float width;
		float height;
		private bool is_selected = false;
		private GdalImage.GeoImage m_geo_image = new GdalImage.GeoImage();

		

		public float Left
		{
			get 
			{
				return x;
			}
			set 
			{
				x = value;
			}
		}

		public float Top
		{
			get 
			{
				return y;
			}
			set 
			{
				y = value;
			}
		}

		public float Width
		{
			get 
			{
				return width;
			}
			set 
			{
				width = value;
			}
		}

		public float Height
		{
			get 
			{
				return height;
			}
			set 
			{
				height = value;
			}
		}

		public override bool createFromRectangle(RectangleF r)
		{
			x = r.X;
			y = r.Y;
			//width = r.Width;
			//height = r.Height;

			return true;
		}

		public GdalImageCanvasItem(CanvasLayer l)
		{
			layer = l;
			layer.add(this);
			
			width = 0;
			height = 0;
		}

		public GdalImageCanvasItem(string fname,CanvasLayer l)
		{
			layer = l;
			layer.add(this);

			m_geo_image.Open(fname);
			
			x = m_geo_image.X();
			y = m_geo_image.Y();
			width = m_geo_image.Width();
			height = m_geo_image.Height();
		}

		public override bool isSelected()
		{
			return is_selected;
		}

		public override void select(bool m)
		{
			is_selected = m;
		}

		public override bool isCloseToPoint(PointF pnt,float dist)
		{
			RectangleF rect1 = new RectangleF(x,y,width,height);
			if(rect1.Contains(pnt))
				return true;

			return false;
		}


		public override RectangleF boundingBox()
		{
			return new RectangleF(x,y,width,height);
		}

		public override float X()
		{
			return x;
		}

		public override float Y()
		{
			return y;
		}

		public override void move(PointF p)
		{
			x = p.X;
			y = p.Y;
		}

		public override void moveBy(float xs,float ys)
		{
			x+=xs;
			y+=ys;
		}

		public override void draw(Graphics graph,System.Drawing.Drawing2D.Matrix trans)
		{
			if(width == 0 &&
				height == 0)
				return;

			if(!layer.Visiable)
				return;
			/*
			// create 0,0 and width,height points
			PointF [] points = {new PointF(graph.ClipBounds.X,graph.ClipBounds.Y), 
								   new PointF(graph.ClipBounds.Right,graph.ClipBounds.Bottom)};
			//trans.TransformPoints(points);
			int w = (int)(points[1].X - points[0].X);
			int h = (int)(points[1].Y - points[0].Y);

			RectangleF bmp_rect = new RectangleF(points[0].X,points[0].Y,
				points[1].X-points[0].X,
				points[1].Y-points[0].Y);


			System.Drawing.Drawing2D.Matrix inv_trans = trans.Clone();
			inv_trans.Invert();
			
			PointF [] src_points = {new PointF(graph.ClipBounds.X,graph.ClipBounds.Y), 
									   new PointF(graph.ClipBounds.Right,graph.ClipBounds.Bottom)};
			
			inv_trans.TransformPoints(src_points);
			RectangleF src_rect = new RectangleF(src_points[0].X,src_points[0].Y,
										src_points[1].X-src_points[0].X,
										src_points[1].Y-src_points[0].Y);
			
			Bitmap bitmap = new Bitmap((int)bmp_rect.Width,
										(int)bmp_rect.Height);
			
			this.m_geo_image.Draw(ref src_rect,ref bmp_rect,bitmap);
		
			graph.DrawImage(bitmap, bmp_rect,
				new RectangleF(0,0,bmp_rect.Width,bmp_rect.Height),
				GraphicsUnit.Pixel); 

			bitmap.Dispose();
			*/
			this.m_geo_image.Draw(graph,trans);
		}
	}

	public class Api 
	{
		[DllImport("gdal12.dll",
			 EntryPoint = "OGRRegisterAll",
			 ExactSpelling = true,    // Bypass A or W suffix search
			 CharSet = CharSet.Ansi,    // We want ANSI String
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern void OGRRegisterAll();

		[DllImport("gdal12.dll",
			 EntryPoint = "OGROpen",
			 ExactSpelling = true,    // Bypass A or W suffix search
			 CharSet = CharSet.Ansi,    // We want ANSI String
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGROpen  (  
			[MarshalAs(UnmanagedType.LPStr)]
			string    pszName,  
			int    bUpdate,  
			IntPtr  pahDriverList); 
		  
		[DllImport("gdal12.dll",
			EntryPoint = "OGR_FD_GetName",
			ExactSpelling = true,    // Bypass A or W suffix search
			CharSet = CharSet.Ansi,    // We want ANSI String
			CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_FD_GetName_api (IntPtr fld_def_h); 
		
		public static string OGR_FD_GetName(IntPtr fld_def_h)
		{
			return Marshal.PtrToStringAnsi(OGR_FD_GetName_api(fld_def_h));
		}

		[DllImport("gdal12.dll",
		EntryPoint = "OGR_DS_ExecuteSQL",
		ExactSpelling = true,    // Bypass A or W suffix search
		CharSet = CharSet.Ansi,    // We want ANSI String
		CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_DS_ExecuteSQL (
			IntPtr hDS,
			[MarshalAs(UnmanagedType.LPStr)]
			string    pszName,
			IntPtr filter,
			[MarshalAs(UnmanagedType.LPStr)]
			string sql_dial
			); 

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_DS_GetLayerCount",
			 ExactSpelling = true,    // Bypass A or W suffix search
			 CharSet = CharSet.Ansi,    // We want ANSI String
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OGR_DS_GetLayerCount (IntPtr hDS);   
 
		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_DS_GetLayer",
			 ExactSpelling = true,    // Bypass A or W suffix search
			 CharSet = CharSet.Ansi,    // We want ANSI String
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_DS_GetLayer (IntPtr ds_h, int lay_id); 
/*
		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_DS_GetName",
			 ExactSpelling = true,    // Bypass A or W suffix search
			 CharSet = CharSet.Ansi,    // We want ANSI String
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_DS_GetName_api (IntPtr ds_h); 

		[DllImport("gdal12.dll")]
		public static extern int OGR_DS_GetLayerCount( IntPtr lay_h);
*/

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_L_GetFeatureCount",
			 ExactSpelling = true,    // Bypass A or W suffix search
			 CharSet = CharSet.Ansi,    // We want ANSI String
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OGR_L_GetFeatureCount( IntPtr lay_h, int flag);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_L_GetLayerDefn",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_L_GetLayerDefn(IntPtr lay_h);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_FD_GetFieldCount",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OGR_FD_GetFieldCount(IntPtr f_def_h);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_FD_GetFieldDefn",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_FD_GetFieldDefn(IntPtr f_def_h,int indx);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_Fld_GetNameRef",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_Fld_GetNameRef_api(IntPtr fld_def_h);

		public static string OGR_Fld_GetNameRef(IntPtr fld_def_h)
		{
			return Marshal.PtrToStringAnsi(OGR_Fld_GetNameRef_api(fld_def_h));
		}

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_GetFieldTypeName",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_GetFieldTypeName_api(int type_id);

		public static string OGR_GetFieldTypeName(int type_id)
		{
			return Marshal.PtrToStringAnsi(OGR_GetFieldTypeName_api(type_id));
		}

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_Fld_GetType",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OGR_Fld_GetType(IntPtr fld_def_h);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_F_GetFieldAsString",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_F_GetFieldAsString_api(IntPtr f_h,int fld_id); 
	
		public static string OGR_F_GetFieldAsString(IntPtr f_h,int fld_id)
		{
			if(f_h == IntPtr.Zero)
			{
				return "undef";
			}
			return Marshal.PtrToStringAnsi(OGR_F_GetFieldAsString_api(f_h,fld_id));
		}

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_L_GetFeature",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_L_GetFeature(IntPtr lay_h,int f_indx);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_F_GetGeometryRef",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_F_GetGeometryRef(IntPtr feature_h);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_G_GetGeometryRef",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_G_GetGeometryRef(IntPtr geom_h,int sub_geom);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_G_GetGeometryType",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OGR_G_GetGeometryType(IntPtr feature_h);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_G_GetGeometryName",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_G_GetGeometryName_api(IntPtr feature_h);

		public static string OGR_G_GetGeometryName(IntPtr feature_h)
		{
			return Marshal.PtrToStringAnsi(OGR_G_GetGeometryName_api(feature_h));
		}
		 
		[DllImport("gdal12.dll",
		EntryPoint = "OGR_G_CreateGeometry",
		ExactSpelling = true,    
		CharSet = CharSet.Ansi,    
		CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OGR_G_CreateGeometry(int g_type);


		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_G_GetPointCount",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OGR_G_GetPointCount(IntPtr geom_h);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_G_GetGeometryCount",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OGR_G_GetGeometryCount(IntPtr geom_h);

		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_G_GetX",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern float OGR_G_GetX(IntPtr geom_h,int i);
 
		[DllImport("gdal12.dll",
			 EntryPoint = "OGR_G_GetY",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern float OGR_G_GetY(IntPtr geom_h,int i); 

		[DllImport("gdal12.dll",
			 EntryPoint = "OSRNewSpatialReference",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OSRNewSpatialReference();

		[DllImport("gdal12.dll",
			 EntryPoint = "OSRSetWellKnownGeogCS",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OSRSetWellKnownGeogCS( IntPtr hSRS,
			[MarshalAs(UnmanagedType.LPStr)]
			string pszName );

		[DllImport("gdal12.dll",
			 EntryPoint = "OSRSetProjCS",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OSRSetProjCS( IntPtr hSRS, 
			[MarshalAs(UnmanagedType.LPStr)]
			string pszName );

		[DllImport("gdal12.dll",
			 EntryPoint = "OSRSetUTM",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern int OSRSetUTM( IntPtr hSRS, int nZone, int bNorth );

		[DllImport("gdal12.dll",
			 EntryPoint = "OCTNewCoordinateTransformation",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr OCTNewCoordinateTransformation( IntPtr hSourceSRS,
			IntPtr hTargetSRS );
		
		[DllImport("gdal12.dll",
			 EntryPoint = "OCTDestroyCoordinateTransformation",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		public static extern void OCTDestroyCoordinateTransformation();

		[DllImport("gdal12.dll",
			 EntryPoint = "OCTTransform",
			 ExactSpelling = true,    
			 CharSet = CharSet.Ansi,    
			 CallingConvention = CallingConvention.Cdecl)]
		unsafe public static extern int OCTTransform(IntPtr hCT,
			int nCount, 
			//[MarshalAs(UnmanagedType.LPArray),In,Out]
			double * x, 
			//[MarshalAs(UnmanagedType.LPArray),In,Out]
			double * y, 
			//[MarshalAs(UnmanagedType.LPArray),In,Out]
			double * z);
	}

	public class SpatialReference 
	{
		public IntPtr m_ref;
		public SpatialReference()
		{
			m_ref = Api.OSRNewSpatialReference();			
		}
		
		public bool SetProjCS(string cs)
		{
			return (Api.OSRSetProjCS(m_ref,cs) == 0);
		}

		public bool SetWellKnownGeogCS(string cs)
		{
			return (Api.OSRSetWellKnownGeogCS(m_ref,cs) == 0);
		}

		public bool SetUTM(int zone,int sph)
		{
			return (Api.OSRSetUTM(m_ref,zone,sph) == 0);
		}
	}

	public class CoordinateTransform
	{
		IntPtr m_ref;
		public CoordinateTransform(SpatialReference src,SpatialReference dst)
		{
			m_ref = Api.OCTNewCoordinateTransformation(src.m_ref,dst.m_ref);
		}

		unsafe public bool transform(PointF [] bbox_points)
		{
			int n = bbox_points.Length;
			double [] xl = new double[n];
			double [] yl = new double[n];
			double [] zl = new double[n];
			for(int i=0; i<n; i++)
			{
				xl[i] = bbox_points[i].X;
				yl[i] = bbox_points[i].Y;
				zl[0] = 0;
			}
			
			transform(xl,yl,zl);
			
			for(int i=0; i<n; i++)
			{
				bbox_points[i].X = (float)xl[i];
				bbox_points[i].Y = (float)yl[i];
			}
			return true;
		}


		unsafe public bool transform(double [] x,double [] y, double [] z)
		{
			if(x.Length != y.Length || x.Length != z.Length )
				return false;

			int res;
			fixed(double* xp=x, yp=y, zp=z)
			{
				res = Api.OCTTransform(m_ref,x.Length,xp,yp,zp);
				int k = res;
			}
			return true;
		}

	/*	public bool transformPnt(ref double x,ref double y,ref double z)
		{
			Api.OCTTransform(m_ref,1,x,y,z);
			return true;
		}
		*/
	}

	public class DataLayer
	{
		private IntPtr m_lay_h;
		private CanvasGeomModel m_canvas_model = null;
		private ArrayList m_shapes;
		int m_num_of_features = 0;
		string m_lay_name;
		private DataSet m_ds = null;
		private int m_first_row = 0;
		private int m_last_row = 4000;
		private int m_max_capacity = 4000;
		private int m_rows_num = 100;
		private int numFields = 0;
		ArrayList m_fields = new ArrayList();
		public string getName()
		{
			return m_lay_name;
		}

		public void Clear()
		{
			m_first_row = 0;
			m_last_row = 4000;
			m_rows_num = 0;
			numFields = 0;
			/*
			if(m_lay_h != IntPtr.Zero)
			{
				Marshal.FreeHGlobal(m_lay_h);
			}
			*/
			if(m_ds != null)
				m_ds.Clear();

			GeomModel.CanvasLayer lay = m_canvas_model.layerByName(m_lay_name);
			foreach(int sh_indx in m_shapes)
			{
				m_canvas_model.DeleteItem(sh_indx);
			}
		}

		public ArrayList Fields
		{
			get
			{
				return m_fields;
			}
		}

		public bool setLabel(string field_name)
		{
			int fld_indx = this.m_fields.IndexOf(field_name);
			if(fld_indx < 0)
				return false;

			GeomModel.CanvasLayer lay = m_canvas_model.layerByName(m_lay_name);
			foreach(int sh_indx in m_shapes)
			{
				int indx = m_shapes.BinarySearch(sh_indx);
				IntPtr feature_h = Api.OGR_L_GetFeature(m_lay_h,indx);
				if(feature_h == IntPtr.Zero)
					continue;
				string val = Api.OGR_F_GetFieldAsString(feature_h,fld_indx);
				lay.ShapeAddLabel(sh_indx,val);
			}

			return true;
		}

		public DataLayer(IntPtr lay,DataSet ds,CanvasGeomModel canvas_model,string lay_name)
		{
			m_lay_h = lay;
			m_ds = ds;
			m_shapes = new ArrayList();
			m_canvas_model = canvas_model;
			m_lay_name = lay_name;
		}

		public bool readRows(int first_row,int rows_num)
		{
			if(first_row >= m_num_of_features)
				return false;

			m_first_row = first_row;
			m_last_row = first_row+rows_num;
			if(m_last_row > m_num_of_features)
				m_last_row = m_num_of_features;
		
			DataTable t = m_ds.Tables[m_lay_name];
			t.Rows.Clear();
			
			for(int n = m_first_row; n<m_last_row; n++)
			{
				IntPtr feature_h = Api.OGR_L_GetFeature(m_lay_h,n);
			
				IntPtr geom_h = Api.OGR_F_GetGeometryRef(feature_h);	
				string g_name = Api.OGR_G_GetGeometryName(geom_h);
				
				int g_type = Api.OGR_G_GetGeometryType(geom_h);
				int g_cnt = Api.OGR_G_GetGeometryCount(geom_h);

				int g_p_cnt = 0;
				IntPtr ext_ring_h = geom_h;
				// get exterior if polygon is selected
				if(g_cnt > 0)
				{
					ext_ring_h = Api.OGR_G_GetGeometryRef(geom_h,0);
				}
				g_p_cnt = Api.OGR_G_GetPointCount(ext_ring_h);

				DataRow workRow = t.NewRow();

				workRow[0] = n.ToString();
				for(int fld_indx=0; fld_indx<numFields; fld_indx++)
				{
					string val = Api.OGR_F_GetFieldAsString(feature_h,fld_indx);
					workRow[fld_indx+1] = val;
				}

				workRow[numFields+1] = g_name;
				workRow[numFields+2] = g_type.ToString();
				workRow[numFields+3] = g_p_cnt.ToString();

				t.Rows.Add(workRow);
			}
			return true;
		}

		int createPointItem(IntPtr ext_ring_h,CanvasLayer lay)
		{
			float x = Api.OGR_G_GetX(ext_ring_h,0);
			float y = Api.OGR_G_GetY(ext_ring_h,0);

			GeomModel.PointCanvasItem p_item = new GeomModel.PointCanvasItem(x,y,4,lay);
			int shape_indx = m_canvas_model.Add(p_item);

			//workRow[numFields+3] = p_item.boundingBox().ToString();
			//m_shapes.Add(shape_indx);
			return shape_indx;
		}

		int createPolygonItem(IntPtr geom_h,CanvasLayer lay)
		{
			int g_cnt = Api.OGR_G_GetGeometryCount(geom_h);
			IntPtr ext_ring_h = geom_h;
			int shape_indx = 0;
			if(g_cnt > 0)
			{
							
				ext_ring_h = Api.OGR_G_GetGeometryRef(geom_h,0);
			}
			int g_p_cnt = Api.OGR_G_GetPointCount(ext_ring_h);
				
						
			ArrayList p_points = new ArrayList();
			for(int p=0; p<g_p_cnt; p++)
			{
				p_points.Add(new PointF(Api.OGR_G_GetX(ext_ring_h,p),Api.OGR_G_GetY(ext_ring_h,p)));
			}
					
			if(p_points.Count > 1)
			{
				GeomModel.PolyCanvasItem p_item = new GeomModel.PolyCanvasItem(p_points,lay);
				shape_indx = m_canvas_model.Add(p_item);

				//workRow[numFields+3] = p_item.boundingBox().ToString();
//				m_shapes.Add(shape_indx);
			}
			
			return shape_indx;
		}

		public bool load()
		{
			m_first_row = 0;
			IntPtr layerDefn_h = Api.OGR_L_GetLayerDefn( m_lay_h );
			numFields = Api.OGR_FD_GetFieldCount( layerDefn_h );
		
			//m_lay_name = lay_name;			
			GeomModel.CanvasLayer lay = m_canvas_model.layerByName(m_lay_name);
			if(lay == null)
			{
				lay = m_canvas_model.createLayer(m_lay_name,Color.Pink,0,true);
			}
			DataTable t = m_ds.Tables.Add(m_lay_name);
			
			t.Columns.Add("ShapeID", typeof(String));
			for(int i=0; i<numFields; i++)
			{
				IntPtr fieldDefn = Api.OGR_FD_GetFieldDefn( layerDefn_h, i );
				string field_name = Api.OGR_Fld_GetNameRef(fieldDefn);
				t.Columns.Add(field_name, typeof(String));
				m_fields.Add(field_name);
			}

			t.Columns.Add("Geom name", typeof(String));
			t.Columns.Add("Geom type", typeof(String));
			t.Columns.Add("Geom p.num.", typeof(String));
			t.Columns.Add("Geom p.", typeof(String));

			// populate table:
			int num_of_features;
			m_num_of_features = num_of_features = Api.OGR_L_GetFeatureCount(m_lay_h,1);
		
			if(m_num_of_features < m_max_capacity)
				m_rows_num = m_max_capacity;
			/*	if(num_of_features > 4000)
					num_of_features = 4000;
	*/
			for(int n=0; n<num_of_features; n++)
			{
								
				IntPtr feature_h = Api.OGR_L_GetFeature(m_lay_h,n);
			
				IntPtr geom_h = Api.OGR_F_GetGeometryRef(feature_h);	
				string g_name = Api.OGR_G_GetGeometryName(geom_h);
				
				int g_type = Api.OGR_G_GetGeometryType(geom_h);
				
				
				int g_p_cnt = 0;
				
				// get exterior if polygon is selected
				int shape_indx = 0;
				switch(g_type)
				{
					case 1:
					{
						shape_indx = createPointItem(geom_h,lay);												
					}
					break;

					case 2:
					case 3:
					{
						shape_indx = this.createPolygonItem(geom_h,lay);
					}
					break;

					case 6:
					{
						int cnt = Api.OGR_G_GetGeometryCount(geom_h);
						for(int i=0; i<cnt; i++)
						{
							IntPtr geom_h_i = Api.OGR_G_GetGeometryRef(geom_h,i);
							shape_indx = this.createPolygonItem(geom_h_i,lay);
						}
					}
					break;

					default:
					{
						
						
					}
					break;
				}
				m_shapes.Add(shape_indx);
				//workRow["Address"] = "Torono";			
			}

			return readRows(m_first_row,m_rows_num);
		}

		public int getShapeID(int row)
		{
			return (int)m_shapes[row+m_first_row];
		}

		/*public int getLayerCount()
		{
			return Api.OGR_DS_GetLayerCount(m_hds);
		}
*/
		public int getFeaturesCount()
		{
			//IntPtr l_h = Api.OGR_DS_GetLayer(m_hds,lay_id);
			//return Api.OGR_L_GetFeatureCount(l_h,1);
			return m_num_of_features;
		}

		public Hashtable getDataRowOfShape(int sh_indx)
		{
			if(sh_indx >= m_num_of_features)
				return null;

			int indx = m_shapes.BinarySearch(sh_indx);
			IntPtr feature_h = Api.OGR_L_GetFeature(m_lay_h,indx);
			DataTable t = m_ds.Tables[m_lay_name];
			//DataRow workRow = t.NewRow();

			//workRow[0] = n.ToString();
			Hashtable workRow = new Hashtable();
			for(int fld_indx=0; fld_indx<numFields; fld_indx++)
			{
				string key = t.Columns[fld_indx+1].ColumnName;
				string val = Api.OGR_F_GetFieldAsString(feature_h,fld_indx);
				//string val = "empty";
				workRow[key] = val;
			}

			return workRow;
		}

		public int getRowOfShape(int sh_indx)
		{
			int indx = m_shapes.BinarySearch(sh_indx);
			
			if(indx < 0)
				return -1;

			if(indx > m_first_row && indx < m_last_row)
			{
				return indx - m_first_row;
			}
			
			int start = indx - m_rows_num/2;
			
			if( start < 0)
				start = 0;
			
			if(readRows(start,m_rows_num))
			{
				return indx - m_first_row;
			}

			return -1;
		}	
	}

	public class DataSource 
	{
		private DataSet ds;
		//IntPtr m_hds;
		private SortedList m_ogr_data_sources = new SortedList();
		private SortedList m_layer_to_data_sources = new SortedList();
		private Hashtable m_layers;
		private CanvasGeomModel m_canvas_model = null;

		public ArrayList getFields(string lay_name)
		{
			if(!m_layers.Contains(lay_name))
				return new ArrayList();

			DataLayer l = (DataLayer)m_layers[lay_name];
			return l.Fields;
		}

		public bool setLabel(string lay_name,string field_name)
		{
			if(!m_layers.Contains(lay_name))
				return false;

			DataLayer l = (DataLayer)m_layers[lay_name];
			return l.setLabel(field_name);
		}

		public bool setCanvasModel(CanvasGeomModel m)
		{			
			m_canvas_model = m;
			return true;
		}

		public bool exeSql(string sql_cmd,string lay_name,string fname)
		{
			if(!m_ogr_data_sources.ContainsKey(fname))
				return false;

			IntPtr hds = (IntPtr)this.m_ogr_data_sources[fname];
			IntPtr geom_filter = Api.OGR_G_CreateGeometry(3);
			IntPtr l_h = Api.OGR_DS_ExecuteSQL(hds,sql_cmd,IntPtr.Zero,"");
			
			if(l_h == IntPtr.Zero)
				return false;

			DataLayer new_layer = new DataLayer(l_h,ds,m_canvas_model,lay_name);
							
			m_layers.Add(lay_name,new_layer);
			new_layer.load();
			return true;
		}

		public ArrayList Files
		{
			get
			{
				return new ArrayList(m_ogr_data_sources.Keys);
			}
		}

		public bool Clear()
		{
			foreach(DataLayer dl in m_layers.Values)
			{
				dl.Clear();
			}
			
			m_layers.Clear();
			foreach(string fname in m_ogr_data_sources.Keys)
			{
				IntPtr hds = (IntPtr)m_ogr_data_sources[fname];
				Marshal.FreeHGlobal(hds);
			}
			m_layer_to_data_sources.Clear();
			return true;
		}

		public bool deleteLayer(string layer_name)
		{
			if(!m_layers.ContainsKey(layer_name))
				return false;

			DataLayer dl = (DataLayer)m_layers[layer_name];
			dl.Clear();
			m_layers.Remove(layer_name);
			
			// remove data source if all its layers removed:
			IntPtr hds = (IntPtr)m_layer_to_data_sources[layer_name];
			m_layer_to_data_sources.Remove(layer_name);

			int indx = m_layer_to_data_sources.IndexOfValue(hds);
			if(indx != -1)
			{
				int ds_indx = m_ogr_data_sources.IndexOfValue(hds);
				m_ogr_data_sources.RemoveAt(ds_indx);
				Marshal.FreeHGlobal(hds);
				
			}

			return true;
		}

		public bool open(string fname)
		{
			FileInfo f = new FileInfo(fname);
			string f_base = f.Name;			
			string ds_name = f_base.Replace(".","_");
			
			Api.OGRRegisterAll();
			IntPtr hds = Api.OGROpen(fname,0,IntPtr.Zero);
			if(hds == IntPtr.Zero)
				return false;

			m_ogr_data_sources.Add(fname,hds);
			

			// read all layers:
			int num_of_layers = Api.OGR_DS_GetLayerCount(hds);
			for(int l=0; l<num_of_layers; l++)
			{
				
				IntPtr l_h = Api.OGR_DS_GetLayer(hds,0);
				IntPtr lay_dfn = Api.OGR_L_GetLayerDefn(l_h);
				string lay_name = Api.OGR_FD_GetName(lay_dfn);
				DataLayer new_layer = new DataLayer(l_h,ds,m_canvas_model,lay_name);
				m_layer_to_data_sources.Add(lay_name,hds);
				/*
					if(!new_layer.open(fname,lay_name))
					return false;
				*/					
				m_layers.Add(lay_name,new_layer);
				new_layer.load();
			}

			return true;
		}

		public ArrayList getLayers()
		{
			ArrayList names = new ArrayList();
			foreach (string n in m_layers.Keys)
			{
				names.Add(n);
			}

			return names;
		}

		public DataSource()
		{
			ds = new DataSet();
			m_layers = new Hashtable();			
		}

		public DataSet getDS()
		{
			return ds;
		}

		public int getRowOfShape(string lay_name,int indx)
		{
			if(!m_layers.Contains(lay_name))
				return -1;

			DataLayer l = (DataLayer)m_layers[lay_name];
			return l.getRowOfShape(indx);
		}

		
		public Hashtable getDataRowOfShape(string lay_name,int indx)
			{
				if(!m_layers.Contains(lay_name))
					return null;

				DataLayer l = (DataLayer)m_layers[lay_name];
				return l.getDataRowOfShape(indx);
			}

		public int getShapeID(string lay_name,int row)
		{
			if(lay_name == null)
				return 0;

			if(!m_layers.Contains(lay_name))
				return 0;

			DataLayer l = (DataLayer)m_layers[lay_name];
			return l.getShapeID(row);
		}

		/*public int getLayerCount(string lay_name)
		{
			if(!m_layers.Contains(lay_name))
				return 0;

			DataLayer l = (DataLayer)m_layers[lay_name];
			return l.getLayerCount();
		}
*/
		public int getFeaturesCount(string lay_name)
		{
			if(!m_layers.Contains(lay_name))
				return 0;

			//IntPtr l_h = Api.OGR_DS_GetLayer(m_hds,lay_id);
			//return Api.OGR_L_GetFeatureCount(l_h,1);
			DataLayer l = (DataLayer)m_layers[lay_name];
			return l.getFeaturesCount();
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Canada Canada
Baranovsky Eduard has been a software developer for more then 10 years. He has an experence in image processing, computer graphics and distributed systems design.

Comments and Discussions