/// <summary>
        /// Returns a GeographicCoordinateSystem object from a code.
        /// </summary>
        /// <param name="code">The EPSG code.</param>
        /// <returns>An object that implements the IGeographicCoordinateSystem interface.</returns>
        public IGeographicCoordinateSystem CreateGeographicCoordinateSystem(string code)
        {
            if (code == null)
            {
                throw new ArgumentNullException("code");
            }
            string sqlQuery = "SELECT COORD_REF_SYS_NAME, COORD_REF_SYS_CODE, AREA_OF_USE_CODE, " +
                              "	COORD_REF_SYS_KIND, DATUM_CODE, COORD_SYS_CODE, " +
                              "	SOURCE_GEOGCRS_CODE, PROJECTION_CONV_CODE, CMPD_VERTCRS_CODE, CRS_SCOPE, CMPD_HORIZCRS_CODE, REMARKS, DATA_SOURCE " +
                              "FROM  [Coordinate Reference System] " +
                              "WHERE COORD_REF_SYS_CODE = {0}";


            sqlQuery = String.Format(System.Globalization.CultureInfo.InvariantCulture, sqlQuery, code);
            IDataReader reader = Database.ExecuteQuery(_databaseConnection, sqlQuery);

            if (!reader.Read())
            {
                throw new ArgumentException(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Geographic Coordinate System with a code {0} not found in the CRS table in the EPSG database.", code));
            }
            ;

            string coordSysCode        = reader["COORD_SYS_CODE"].ToString().ToLower();
            string coordSysName        = reader["COORD_REF_SYS_NAME"].ToString();
            string name                = reader["COORD_REF_SYS_NAME"].ToString();
            string horizontalDatumCode = reader["DATUM_CODE"].ToString();
            string coordRefKind        = reader["COORD_REF_SYS_KIND"].ToString();
            string datasource          = reader["DATA_SOURCE"].ToString();    // should always be EPSG??
            string remarks             = reader["REMARKS"].ToString();

            if (coordRefKind.ToLower() != "geographic 2d")
            {
                throw new ArgumentException(String.Format("CRS code {0} is not a geographic coordinate system but a {1}.", code, coordRefKind));
            }

            Database.CheckOneRow(reader, code, "Geographic CRC code");

            string           primeMeridianCode = "";
            IPrimeMeridian   primeMeridian     = null;
            IHorizontalDatum horizontalDatum   = null;

            if (horizontalDatumCode == "")
            {
                horizontalDatum   = HorizontalDatum.WGS84;              //this.CreateHorizontalDatum( horizontalDatumCode );
                primeMeridianCode = this.CreatePrimeMeridianCodeFromDatum(horizontalDatumCode);
                primeMeridian     = this.CreatePrimeMeridian(primeMeridianCode);
            }
            else
            {
                horizontalDatum   = this.CreateHorizontalDatum(horizontalDatumCode);
                primeMeridianCode = this.CreatePrimeMeridianCodeFromDatum(horizontalDatumCode);
                primeMeridian     = this.CreatePrimeMeridian(primeMeridianCode);
            }

            // we get the information for the axis
            IAxisInfo[]  axisInfos   = GetAxisInfo(coordSysCode);
            IAngularUnit angularUnit = new AngularUnit(1);


            IAxisInfo axisInfo1 = axisInfos[0];
            IAxisInfo axisInfo2 = axisInfos[1];
            IGeographicCoordinateSystem geographicCoordSys = new GeographicCoordinateSystem(angularUnit, horizontalDatum, primeMeridian, axisInfo1, axisInfo2, remarks, datasource, code, name, "", "");

            return(geographicCoordSys);
        }
        private static IGeographicCoordinateSystem ReadGeographicCoordinateSystem(XmlTextReader reader)
        {
            if (!(reader.NodeType==XmlNodeType.Element &&  reader.Name=="CS_GeographicCoordinateSystem"))
            {
                throw new ParseException(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Expected a IGeographicCoordinateSystem but got a {0} at line {1} col {2}",reader.Name,reader.LineNumber,reader.LinePosition));
            }
            string authority="",authorityCode="",abbreviation="",name="";
            reader.Read();
            ReadInfo(reader, ref authority,ref authorityCode, ref abbreviation, ref name);
            //reader.Read();
            ArrayList list = new ArrayList();
            while (reader.NodeType==XmlNodeType.Element && reader.Name=="CS_AxisInfo")
            {
                IAxisInfo axis = ReadAxisInfo( reader );
                list.Add(axis);
                reader.Read();
            }
            IAxisInfo[] axisInfos = new IAxisInfo[list.Count];
            axisInfos = (IAxisInfo[])list.ToArray(typeof(IAxisInfo));
            IHorizontalDatum horizontalDatum = ReadHorizontalDatum( reader );
            //reader.Read();
            IAngularUnit angularUnit = ReadAngularUnit( reader );
            //reader.Read();
            IPrimeMeridian primeMeridian = ReadPrimeMeridian( reader );

            reader.Read();
            IGeographicCoordinateSystem geographicCoordinateSystem = new GeographicCoordinateSystem(angularUnit,horizontalDatum,
                primeMeridian, axisInfos[0], axisInfos[1],"",
                authority,authorityCode,name,"",abbreviation);
            return geographicCoordinateSystem;
        }
		/// <summary>
		/// Returns a GeographicCoordinateSystem object from a code.
		/// </summary>
		/// <param name="code">The EPSG code.</param>
		/// <returns>An object that implements the IGeographicCoordinateSystem interface.</returns>
		public IGeographicCoordinateSystem CreateGeographicCoordinateSystem(string code)
		{
			if (code==null)
			{
				throw new ArgumentNullException("code");
			}
			string sqlQuery =	"SELECT COORD_REF_SYS_NAME, COORD_REF_SYS_CODE, AREA_OF_USE_CODE, "+
								"	COORD_REF_SYS_KIND, DATUM_CODE, COORD_SYS_CODE, "+
								"	SOURCE_GEOGCRS_CODE, PROJECTION_CONV_CODE, CMPD_VERTCRS_CODE, CRS_SCOPE, CMPD_HORIZCRS_CODE, REMARKS, DATA_SOURCE "+
								"FROM  [Coordinate Reference System] "+
								"WHERE COORD_REF_SYS_CODE = {0}";

			
			sqlQuery = String.Format(sqlQuery,code);
			IDataReader reader = Database.ExecuteQuery(_databaseConnection, sqlQuery);
			if (!reader.Read())
			{
				throw new ArgumentException(String.Format("Geographic Coordinate System with a code {0} not found in the CRS table in the EPSG database.",code));
			};

			string coordSysCode = reader["COORD_SYS_CODE"].ToString().ToLower();
			string coordSysName = reader["COORD_REF_SYS_NAME"].ToString();
			string name = reader["COORD_REF_SYS_NAME"].ToString();
			string horizontalDatumCode = reader["DATUM_CODE"].ToString();
			string coordRefKind = reader["COORD_REF_SYS_KIND"].ToString();
			string datasource = reader["DATA_SOURCE"].ToString(); // should always be EPSG??
			string remarks = reader["REMARKS"].ToString();
			
			if (coordRefKind.ToLower() != "geographic 2d")
			{
				throw new ArgumentException(String.Format("CRS code {0} is not a geographic coordinate system but a {1}.",code,coordRefKind));
			}

			Database.CheckOneRow(reader,code,"Geographic CRC code");

			string primeMeridianCode = "";
			IPrimeMeridian primeMeridian = null;
			IHorizontalDatum horizontalDatum= null;
			if (horizontalDatumCode=="")
			{
				horizontalDatum = HorizontalDatum.WGS84;//this.CreateHorizontalDatum( horizontalDatumCode );
				primeMeridianCode = this.CreatePrimeMeridianCodeFromDatum(horizontalDatumCode);
				primeMeridian  = this.CreatePrimeMeridian( primeMeridianCode );
			}
			else
			{
				horizontalDatum = this.CreateHorizontalDatum( horizontalDatumCode );
				primeMeridianCode = this.CreatePrimeMeridianCodeFromDatum(horizontalDatumCode);
				primeMeridian  = this.CreatePrimeMeridian( primeMeridianCode );
			}

			// we get the information for the axis 
			IAxisInfo[] axisInfos = GetAxisInfo(coordSysCode);
			IAngularUnit angularUnit = new AngularUnit(1);
			
			
			IAxisInfo axisInfo1 = axisInfos[0];
			IAxisInfo axisInfo2 = axisInfos[1];
			IGeographicCoordinateSystem geographicCoordSys = new GeographicCoordinateSystem(angularUnit, horizontalDatum, primeMeridian, axisInfo1, axisInfo2,remarks,datasource,code,name,"","");
			return geographicCoordSys;
			
		}
        private static IGeographicCoordinateSystem ReadGeographicCoordinateSystem(WktStreamTokenizer tokenizer)
        {
            /*
            GEOGCS["OSGB 1936",
            DATUM["OSGB 1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]]TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6277"]]
            PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]]
            AXIS["Geodetic latitude","NORTH"]
            AXIS["Geodetic longitude","EAST"]
            AUTHORITY["EPSG","4277"]
            ]
            */

            tokenizer.ReadToken("[");
            string name=tokenizer.ReadDoubleQuotedWord();
            tokenizer.ReadToken(",");
            tokenizer.ReadToken("DATUM");
            IHorizontalDatum horizontalDatum = ReadHorizontalDatum(tokenizer);
            tokenizer.ReadToken("PRIMEM");
            IPrimeMeridian primeMeridian = ReadPrimeMeridian(tokenizer);
            tokenizer.ReadToken("AXIS");
            IAxisInfo axis0 = ReadAxisInfo(tokenizer);
            tokenizer.ReadToken(",");
            tokenizer.ReadToken("AXIS");
            IAxisInfo axis1 = ReadAxisInfo(tokenizer);
            tokenizer.ReadToken(",");
            string authority="";
            string authorityCode="";
            tokenizer.ReadAuthority(ref authority, ref authorityCode);
            tokenizer.ReadToken("]");
            // ?? assume angular unit is degrees.
            IAngularUnit angularUnit = new AngularUnit(180/Math.PI);
            IGeographicCoordinateSystem geographicCS = new GeographicCoordinateSystem(angularUnit, horizontalDatum,
                    primeMeridian,axis0, axis1,"",authority,authorityCode,name,"","");
            return geographicCS;
        }