Пример #1
0
		//**********************************************************************
		//							GTIFPrintDefn()
		//
		//		Report the contents of a GTIFDefn structure ... mostly for
		//		debugging.
		//**********************************************************************
		public static void GTIFPrintDefn(GTIFDefn defn, StreamWriter file)
		{
			projection_t dummyproj;
			geounits_t dummyunit;
			geographic_t dummygeogr;
			geodeticdatum_t dummydatum;
			primemeridian_t dummypm;
			ellipsoid_t dummyellip;
			short dummyshort;
			double dummydouble;
			string name;

			// --------------------------------------------------------------------
			//		Do we have anything to report?
			// --------------------------------------------------------------------
			if(!defn.DefnSet)
			{
				file.WriteLine("No GeoKeys found.");
				return;
			}

			// --------------------------------------------------------------------
			//		Get the PCS name if possible.
			// --------------------------------------------------------------------
			if(defn.PCS!=(pcstype_t)KvUserDefined)
			{
				GTIFGetPCSInfo(defn.PCS, out name, out dummyproj, out dummyunit, out dummygeogr);
				if(name==null) name="name unknown";

				file.WriteLine("PCS = {0} ({1})", (int)defn.PCS, name);
			}

			// --------------------------------------------------------------------
			//	Dump the projection code if possible.
			// --------------------------------------------------------------------
			if(defn.ProjCode!=(projection_t)KvUserDefined)
			{
				GTIFGetProjTRFInfo(defn.ProjCode, out name, out dummyshort, null);
				if(name==null) name="";

				file.WriteLine("Projection = {0} ({1})", (int)defn.ProjCode, name);
			}

			// --------------------------------------------------------------------
			//		Try to dump the projection method name, and parameters if possible.
			// --------------------------------------------------------------------
			if(defn.CTProjection!=(coordtrans_t)KvUserDefined)
			{
				name=GTIFValueName(geokey_t.ProjCoordTransGeoKey, (int)defn.CTProjection);
				if(name==null) name="(unknown)";

				file.WriteLine("Projection Method: "+name);

				for(int i=0; i<defn.nParms; i++)
				{
					if(defn.ProjParmId[i]==0) continue;

					name=GTIFKeyName(defn.ProjParmId[i]);
					if(name==null) name="(unknown)";

					if(i<4)
					{
						string pszAxisName;

						if(name.Contains("Long")) pszAxisName="Long";
						else if(name.Contains("Lat")) pszAxisName="Lat";
						else pszAxisName="?";

						file.WriteLine("\t{0}: {1} ({2})", name, defn.ProjParm[i], GTIFDecToDMS(defn.ProjParm[i], pszAxisName, 2));
					}
					else if(i==4) file.WriteLine("\t{0}: {1}", name, defn.ProjParm[i]);
					else file.WriteLine("\t{0}: {1} m\n", name, defn.ProjParm[i]);
				}
			}

			// --------------------------------------------------------------------
			//		Report the GCS name, and number.
			// --------------------------------------------------------------------
			if(defn.GCS!=(geographic_t)KvUserDefined)
			{
				GTIFGetGCSInfo(defn.GCS, out name, out dummydatum, out dummypm, out dummyunit);
				if(name==null) name="(unknown)";

				file.WriteLine("GCS: {0}/{1}", (int)defn.GCS, name);
			}

			// --------------------------------------------------------------------
			//		Report the datum name.
			// --------------------------------------------------------------------
			if(defn.Datum!=(geodeticdatum_t)KvUserDefined)
			{
				GTIFGetDatumInfo(defn.Datum, out name, out dummyellip);
				if(name==null) name="(unknown)";

				file.WriteLine("Datum: {0}/{1}", (int)defn.Datum, name);
			}

			// --------------------------------------------------------------------
			//		Report the ellipsoid.
			// --------------------------------------------------------------------
			if(defn.Ellipsoid!=(ellipsoid_t)KvUserDefined)
			{
				GTIFGetEllipsoidInfo(defn.Ellipsoid, out name, out dummydouble, out dummydouble);
				if(name==null) name="(unknown)";

				file.WriteLine("Ellipsoid: {0}/{1} ({2:F2},{3:F2})", (int)defn.Ellipsoid, name,
					defn.SemiMajor, defn.SemiMinor);
			}

			// --------------------------------------------------------------------
			//		Report the prime meridian.
			// --------------------------------------------------------------------
			if(defn.PM!=(primemeridian_t)KvUserDefined)
			{
				GTIFGetPMInfo(defn.PM, out name, out dummydouble);
				if(name==null) name="(unknown)";

				file.WriteLine("Prime Meridian: {0}/{1} ({2}/{3})", (int)defn.PM, name, defn.PMLongToGreenwich,
					GTIFDecToDMS(defn.PMLongToGreenwich, "Long", 2));
			}

			// --------------------------------------------------------------------
			//		Report the projection units of measure (currently just linear).
			// --------------------------------------------------------------------
			if(defn.UOMLength!=(geounits_t)KvUserDefined)
			{
				GTIFGetUOMLengthInfo(defn.UOMLength, out name, out dummydouble);
				if(name==null) name="(unknown)";

				file.WriteLine("Projection Linear Units: {0}/{1} ({2}m)", (int)defn.UOMLength, name, defn.UOMLengthInMeters);
			}

			// --------------------------------------------------------------------
			//		Report TOWGS84 parameters.
			// --------------------------------------------------------------------
			if(defn.TOWGS84Count>0)
			{
				file.Write("TOWGS84: ");

				for(int i=0; i<defn.TOWGS84Count; i++)
				{
					if(i>0) file.Write(",");
					file.Write("{0}", defn.TOWGS84[i]);
				}
				file.WriteLine();
			}

			// --------------------------------------------------------------------
			//		Report the projection units of measure (currently just
			//		linear).
			// --------------------------------------------------------------------
			if(defn.UOMLength!=(geounits_t)KvUserDefined)
			{
				string UOMname=null;
				double inMeter=0;

				if(!GTIFGetUOMLengthInfo(defn.UOMLength, out UOMname, out inMeter)) UOMname="(unknown)";
				file.WriteLine("Projection Linear Units: {0}/{1} ({2}m)", defn.UOMLength, UOMname, defn.UOMLengthInMeters);
			}
		}
Пример #2
0
		//**********************************************************************
		//							GTIFGetDefn()
		//**********************************************************************
		//
		// @param psGTIF GeoTIFF information handle as returned by GTIFNew.
		// @param psDefn Pointer to an existing GTIFDefn structure. This structure
		// does not need to have been pre-initialized at all.
		//
		// @return true if the function has been successful, otherwise false.
		//
		// This function reads the coordinate system definition from a GeoTIFF file,
		// and normalizes it into a set of component information using
		// definitions from CSV (Comma Seperated Value ASCII) files derived from
		// EPSG tables. This function is intended to simplify correct support for
		// reading files with defined PCS (Projected Coordinate System) codes that
		// wouldn't otherwise be directly known by application software by reducing
		// it to the underlying projection method, parameters, datum, ellipsoid,
		// prime meridian and units.
		//
		// The application should pass a pointer to an existing uninitialized
		// GTIFDefn structure, and GTIFGetDefn() will fill it in. The fuction
		// currently always returns TRUE but in the future will return FALSE if
		// CSV files are not found. In any event, all geokeys actually found in the
		// file will be copied into the GTIFDefn. However, if the CSV files aren't
		// found codes implied by other codes will not be set properly.
		//
		// GTIFGetDefn() will not generally work if the EPSG derived CSV files cannot
		// be found. By default a modest attempt will be made to find them, but
		// in general it is necessary for the calling application to override the
		// logic to find them. This can be done by calling the SetCSVFilenameHook()
		// function to override the search method based on application knowledge of
		// where they are found.
		//
		// The normalization methodology operates by fetching tags from the GeoTIFF
		// file, and then setting all other tags implied by them in the structure. The
		// implied relationships are worked out by reading definitions from the 
		// various EPSG derived CSV tables.
		//
		// For instance, if a PCS (ProjectedCSTypeGeoKey) is found in the GeoTIFF file
		// this code is used to lookup a record in the horiz_cs.csv CSV
		// file. For example given the PCS 26746 we can find the name
		// (NAD27 / California zone VI), the GCS 4257 (NAD27), and the ProjectionCode
		// 10406 (California CS27 zone VI). The GCS, and ProjectionCode can in turn
		// be looked up in other tables until all the details of units, ellipsoid,
		// prime meridian, datum, projection (LambertConfConic_2SP) and projection
		// parameters are established. A full listgeo dump of a file
		// for this result might look like the following, all based on a single PCS
		// value:
		//
		//	%listgeo -norm ~/data/geotiff/pci_eg/spaf27.tif
		//	Geotiff_Information:
		//		Version: 1
		//		Key_Revision: 1.0
		//		Tagged_Information:
		//			ModelTiepointTag (2,3):
		//				0			0			0
		//				1577139.71	634349.176	0
		//			ModelPixelScaleTag (1,3):
		//				195.509321	198.32184	0
		//			End_Of_Tags.
		//		Keyed_Information:
		//			GTModelTypeGeoKey (Short,1): ModelTypeProjected
		//			GTRasterTypeGeoKey (Short,1): RasterPixelIsArea
		//			ProjectedCSTypeGeoKey (Short,1): PCS_NAD27_California_VI
		//			End_Of_Keys.
		//		End_Of_Geotiff.
		//
		//	PCS = 26746 (NAD27 / California zone VI)
		//	Projection = 10406 (California CS27 zone VI)
		//	Projection Method: CT_LambertConfConic_2SP
		//		ProjStdParallel1GeoKey: 33.883333
		//		ProjStdParallel2GeoKey: 32.766667
		//		ProjFalseOriginLatGeoKey: 32.166667
		//		ProjFalseOriginLongGeoKey: -116.233333
		//		ProjFalseEastingGeoKey: 609601.219202
		//		ProjFalseNorthingGeoKey: 0.000000
		//	GCS: 4267/NAD27
		//	Datum: 6267/North American Datum 1927
		//	Ellipsoid: 7008/Clarke 1866 (6378206.40,6356583.80)
		//	Prime Meridian: 8901/Greenwich (0.000000)
		//	Projection Linear Units: 9003/US survey foot (0.304801m)
		//
		// Note that GTIFGetDefn() does not inspect or return the tiepoints and scale.
		// This must be handled seperately as it normally would. It is intended to
		// simplify capture and normalization of the coordinate system definition.
		// Note that GTIFGetDefn() also does the following things:
		//
		//	*	Convert all angular values to decimal degrees.
		//	*	Convert all linear values to meters.
		//	*	Return the linear units and conversion to meters for the tiepoints and
		//		scale (though the tiepoints and scale remain in their native units).
		//	*	When reading projection parameters a variety of differences between
		//		different GeoTIFF generators are handled, and a normalized set of
		//		parameters for each projection are always returned.
		//
		// Code fields in the GTIFDefn are filled with KvUserDefined if there is not value to
		// assign. The parameter lists for each of the underlying projection transform methods
		// can be found at the Projections (http://www.remotesensing.org/geotiff/proj_list) page.
		// Note that nParms will be set based on the maximum parameter used. Some of the
		// parameters may not be used in which case the GTIFDefn::ProjParmId[] will be zero.
		// This is done to retain correspondence to the EPSG parameter numbering scheme.
		//
		//The geotiff_proj4.cs module distributed with libgeotiff can be used as an example of
		// code that converts a GTIFDefn into another projection system.
		//
		// @see GTIFKeySet(), SetCSVFilenameHook()
		public static bool GTIFGetDefn(GTIF gtif, GTIFDefn defn)
		{
			// --------------------------------------------------------------------
			//		Initially we default all the information we can.
			// --------------------------------------------------------------------
			defn.DefnSet=true;
			defn.Model=(modeltype_t)KvUserDefined;
			defn.PCS=(pcstype_t)KvUserDefined;
			defn.GCS=(geographic_t)KvUserDefined;
			defn.UOMLength=(geounits_t)KvUserDefined;
			defn.UOMLengthInMeters=1.0;
			defn.UOMAngle=(geounits_t)KvUserDefined;
			defn.UOMAngleInDegrees=1.0;
			defn.Datum=(geodeticdatum_t)KvUserDefined;
			defn.Ellipsoid=(ellipsoid_t)KvUserDefined;
			defn.SemiMajor=0.0;
			defn.SemiMinor=0.0;
			defn.PM=(primemeridian_t)KvUserDefined;
			defn.PMLongToGreenwich=0.0;
			defn.TOWGS84Count=0;
			for(int i=0; i<defn.TOWGS84.Length; i++) defn.TOWGS84[i]=0;

			defn.ProjCode=(projection_t)KvUserDefined;
			defn.Projection=KvUserDefined;
			defn.CTProjection=(coordtrans_t)KvUserDefined;

			defn.nParms=0;
			for(int i=0; i<MAX_GTIF_PROJPARMS; i++)
			{
				defn.ProjParm[i]=0.0;
				defn.ProjParmId[i]=0;
			}

			defn.MapSys=KvUserDefined;
			defn.Zone=0;

			// --------------------------------------------------------------------
			//		Do we have any geokeys?
			// --------------------------------------------------------------------
			int nKeyCount=0;
			int[] anVersion=new int[3];
			GTIFDirectoryInfo(gtif, anVersion, out nKeyCount);

			if(nKeyCount==0)
			{
				defn.DefnSet=false;
				return false;
			}

			// --------------------------------------------------------------------
			//		Try to get the overall model type.
			// --------------------------------------------------------------------
			GTIFKeyGet(gtif, geokey_t.GTModelTypeGeoKey, out defn.Model, 0, 1);

			// --------------------------------------------------------------------
			//		Extract the Geog units.
			// --------------------------------------------------------------------
			geounits_t nGeogUOMLinear=geounits_t.Linear_Meter;
			GTIFKeyGet(gtif, geokey_t.GeogLinearUnitsGeoKey, out nGeogUOMLinear, 0, 1);

			// --------------------------------------------------------------------
			//		Try to get a PCS.
			// --------------------------------------------------------------------
			string dummy;

			if(GTIFKeyGet(gtif, geokey_t.ProjectedCSTypeGeoKey, out defn.PCS, 0, 1)==1
				&&defn.PCS!=(pcstype_t)KvUserDefined) // Translate this into useful information.
				GTIFGetPCSInfo(defn.PCS, out dummy, out defn.ProjCode, out defn.UOMLength, out defn.GCS);

			// --------------------------------------------------------------------
			//		If we have the PCS code, but didn't find it in the CSV files
			//		(likely because we can't find them) we will try some "jiffy
			//		rules" for UTM and state plane.
			// --------------------------------------------------------------------
			if(defn.PCS!=(pcstype_t)KvUserDefined&&defn.ProjCode==(projection_t)KvUserDefined)
			{
				int mapSys, zone;
				geographic_t GCS=defn.GCS;

				mapSys=GTIFPCSToMapSys(defn.PCS, out GCS, out zone);
				if(mapSys!=KvUserDefined)
				{
					defn.ProjCode=GTIFMapSysToProj(mapSys, zone);
					defn.GCS=GCS;
				}
			}

			// --------------------------------------------------------------------
			//		If the Proj_ code is specified directly, use that.
			// --------------------------------------------------------------------
			if(defn.ProjCode==(projection_t)KvUserDefined)
				GTIFKeyGet(gtif, geokey_t.ProjectionGeoKey, out defn.ProjCode, 0, 1);

			if(defn.ProjCode!=(projection_t)KvUserDefined)
			{
				// We have an underlying projection transformation value. Look
				// this up. For a PCS of "WGS 84 / UTM 11" the transformation
				// would be Transverse Mercator, with a particular set of options.
				// The nProjTRFCode itself would correspond to the name
				// "UTM zone 11N", and doesn't include datum info.

				GTIFGetProjTRFInfo(defn.ProjCode, out dummy, out defn.Projection, defn.ProjParm);

				// Set the GeoTIFF identity of the parameters.
				defn.CTProjection=EPSGProjMethodToCTProjMethod(defn.Projection);

				SetGTParmIds(defn.CTProjection, defn.ProjParmId, null);
				defn.nParms=7;
			}

			// --------------------------------------------------------------------
			//		Try to get a GCS. If found, it will override any implied by
			//		the PCS.
			// --------------------------------------------------------------------
			GTIFKeyGet(gtif, geokey_t.GeographicTypeGeoKey, out defn.GCS, 0, 1);
			if(defn.GCS<(geographic_t)1||defn.GCS>=(geographic_t)KvUserDefined)
				defn.GCS=(geographic_t)KvUserDefined;

			// --------------------------------------------------------------------
			//		Derive the datum, and prime meridian from the GCS.
			// --------------------------------------------------------------------
			if(defn.GCS!=(geographic_t)KvUserDefined)
				GTIFGetGCSInfo(defn.GCS, out dummy, out defn.Datum, out defn.PM, out defn.UOMAngle);

			// --------------------------------------------------------------------
			//		Handle the GCS angular units. GeogAngularUnitsGeoKey
			//		overrides the GCS or PCS setting.
			// --------------------------------------------------------------------
			GTIFKeyGet(gtif, geokey_t.GeogAngularUnitsGeoKey, out defn.UOMAngle, 0, 1);
			if(defn.UOMAngle!=(geounits_t)KvUserDefined)
				GTIFGetUOMAngleInfo(defn.UOMAngle, out dummy, out defn.UOMAngleInDegrees);

			// --------------------------------------------------------------------
			//		Check for a datum setting, and then use the datum to derive
			//		an ellipsoid.
			// --------------------------------------------------------------------
			GTIFKeyGet(gtif, geokey_t.GeogGeodeticDatumGeoKey, out defn.Datum, 0, 1);
			if(defn.Datum!=(geodeticdatum_t)KvUserDefined)
				GTIFGetDatumInfo(defn.Datum, out dummy, out defn.Ellipsoid);

			// --------------------------------------------------------------------
			//		Check for an explicit ellipsoid. Use the ellipsoid to
			//		derive the ellipsoid characteristics, if possible.
			// --------------------------------------------------------------------
			GTIFKeyGet(gtif, geokey_t.GeogEllipsoidGeoKey, out defn.Ellipsoid, 0, 1);
			if(defn.Ellipsoid!=(ellipsoid_t)KvUserDefined)
				GTIFGetEllipsoidInfo(defn.Ellipsoid, out dummy, out defn.SemiMajor, out defn.SemiMinor);

			// --------------------------------------------------------------------
			//		Check for overridden ellipsoid parameters. It would be nice
			//		to warn if they conflict with provided information, but for
			//		now we just override.
			// --------------------------------------------------------------------
			GTIFKeyGet(gtif, geokey_t.GeogSemiMajorAxisGeoKey, out defn.SemiMajor, 0, 1);
			GTIFKeyGet(gtif, geokey_t.GeogSemiMinorAxisGeoKey, out defn.SemiMinor, 0, 1);

			double invFlattening;
			if(GTIFKeyGet(gtif, geokey_t.GeogInvFlatteningGeoKey, out invFlattening, 0, 1)==1)
			{
				if(invFlattening!=0.0) defn.SemiMinor=defn.SemiMajor*(1-1.0/invFlattening);
				else defn.SemiMinor=defn.SemiMajor;
			}

			// --------------------------------------------------------------------
			//		Get the prime meridian info.
			// --------------------------------------------------------------------
			GTIFKeyGet(gtif, geokey_t.GeogPrimeMeridianGeoKey, out defn.PM, 0, 1);

			if(defn.PM!=(primemeridian_t)KvUserDefined) GTIFGetPMInfo(defn.PM, out dummy, out defn.PMLongToGreenwich);
			else
			{
				GTIFKeyGet(gtif, geokey_t.GeogPrimeMeridianLongGeoKey, out defn.PMLongToGreenwich, 0, 1);
				defn.PMLongToGreenwich=GTIFAngleToDD(defn.PMLongToGreenwich, defn.UOMAngle);
			}

			// --------------------------------------------------------------------
			//		Get the TOWGS84 parameters.
			// --------------------------------------------------------------------
			defn.TOWGS84Count=GTIFKeyGet(gtif, geokey_t.GeogTOWGS84GeoKey, out defn.TOWGS84, 0, 7);

			// --------------------------------------------------------------------
			//		Have the projection units of measure been overridden? We
			//		should likely be doing something about angular units too,
			//		but these are very rarely not decimal degrees for actual
			//		file coordinates.
			// --------------------------------------------------------------------
			GTIFKeyGet(gtif, geokey_t.ProjLinearUnitsGeoKey, out defn.UOMLength, 0, 1);
			if(defn.UOMLength!=(geounits_t)KvUserDefined)
				GTIFGetUOMLengthInfo(defn.UOMLength, out dummy, out defn.UOMLengthInMeters);

			// --------------------------------------------------------------------
			//		Handle a variety of user defined transform types.
			// --------------------------------------------------------------------
			if(GTIFKeyGet(gtif, geokey_t.ProjCoordTransGeoKey, out defn.CTProjection, 0, 1)==1)
				GTIFFetchProjParms(gtif, defn);

			// --------------------------------------------------------------------
			//		Try to set the zoned map system information.
			// --------------------------------------------------------------------
			defn.MapSys=GTIFProjToMapSys(defn.ProjCode, out defn.Zone);

			// --------------------------------------------------------------------
			//		If this is UTM, and we were unable to extract the projection
			//		parameters from the CSV file, just set them directly now,
			//		since it's pretty easy, and a common case.
			// --------------------------------------------------------------------
			if((defn.MapSys==MapSys_UTM_North||defn.MapSys==MapSys_UTM_South)&&
				defn.CTProjection==(coordtrans_t)KvUserDefined)
			{
				defn.CTProjection=coordtrans_t.CT_TransverseMercator;
				defn.nParms=7;
				defn.ProjParmId[0]=geokey_t.ProjNatOriginLatGeoKey;
				defn.ProjParm[0]=0.0;

				defn.ProjParmId[1]=geokey_t.ProjNatOriginLongGeoKey;
				defn.ProjParm[1]=defn.Zone*6-183.0;

				defn.ProjParmId[4]=geokey_t.ProjScaleAtNatOriginGeoKey;
				defn.ProjParm[4]=0.9996;

				defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
				defn.ProjParm[5]=500000.0;

				defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

				if(defn.MapSys==MapSys_UTM_North) defn.ProjParm[6]=0.0;
				else defn.ProjParm[6]=10000000.0;
			}

			return true;
		}
Пример #3
0
		//***********************************************************************
		//*							GTIFProj4ToLatLong()
		//*
		//*		Convert projection coordinates to lat/long for a particular
		//*		definition.
		//***********************************************************************
		public static bool GTIFProj4ToLatLong(GTIFDefn psDefn, int nPoints, double[] padfX, double[] padfY)
		{
			// --------------------------------------------------------------------
			//		Get a projection definition.
			// --------------------------------------------------------------------
			string pszProjection=GTIFGetProj4Defn(psDefn);
			if(pszProjection==null) return false;

			// --------------------------------------------------------------------
			//		Parse into tokens for pj_init(), and initialize the projection.
			// --------------------------------------------------------------------
			PJ psPJ=Proj.pj_init_plus(pszProjection);
			if(psPJ==null) return false;

			// --------------------------------------------------------------------
			//		Process each of the points.
			// --------------------------------------------------------------------
			for(int i=0; i<nPoints; i++)
			{
				projUV sUV;

				sUV.u=padfX[i];
				sUV.v=padfY[i];

				sUV=Proj.pj_inv(sUV, psPJ);

				padfX[i]=sUV.u*Proj.RAD_TO_DEG;
				padfY[i]=sUV.v*Proj.RAD_TO_DEG;
			}

			return true;
		}
Пример #4
0
		//**********************************************************************
		//						GTIFFetchProjParms()
		//
		//		Fetch the projection parameters for a particular projection
		//		from a GeoTIFF file, and fill the GTIFDefn structure out
		//		with them.
		//**********************************************************************
		static void GTIFFetchProjParms(GTIF gtif, GTIFDefn defn)
		{
			double NatOriginLong=0.0, NatOriginLat=0.0, RectGridAngle=0.0;
			double FalseEasting=0.0, FalseNorthing=0.0, NatOriginScale=1.0;
			double StdParallel1=0.0, StdParallel2=0.0, Azimuth=0.0;

			// --------------------------------------------------------------------
			//		Get the false easting, and northing if available.
			// --------------------------------------------------------------------
			if(GTIFKeyGet(gtif, geokey_t.ProjFalseEastingGeoKey, out FalseEasting, 0, 1)==0&&
				GTIFKeyGet(gtif, geokey_t.ProjCenterEastingGeoKey, out FalseEasting, 0, 1)==0&&
				GTIFKeyGet(gtif, geokey_t.ProjFalseOriginEastingGeoKey, out FalseEasting, 0, 1)==0) FalseEasting=0.0;

			if(GTIFKeyGet(gtif, geokey_t.ProjFalseNorthingGeoKey, out FalseNorthing, 0, 1)==0&&
				GTIFKeyGet(gtif, geokey_t.ProjCenterNorthingGeoKey, out FalseNorthing, 0, 1)==0&&
				GTIFKeyGet(gtif, geokey_t.ProjFalseOriginNorthingGeoKey, out FalseNorthing, 0, 1)==0) FalseNorthing=0.0;

			switch(defn.CTProjection)
			{
				case coordtrans_t.CT_Stereographic:
					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLatGeoKey, out NatOriginLat, 0, 1)==0) NatOriginLat=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjScaleAtNatOriginGeoKey, out NatOriginScale, 0, 1)==0) NatOriginScale=1.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[0]=NatOriginLat;
					defn.ProjParmId[0]=geokey_t.ProjCenterLatGeoKey;
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjCenterLongGeoKey;
					defn.ProjParm[4]=NatOriginScale;
					defn.ProjParmId[4]=geokey_t.ProjScaleAtNatOriginGeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_LambertConfConic_1SP:
				case coordtrans_t.CT_Mercator:
				case coordtrans_t.CT_ObliqueStereographic:
				case coordtrans_t.CT_TransverseMercator:
				case coordtrans_t.CT_TransvMercator_SouthOriented:
					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLatGeoKey, out NatOriginLat, 0, 1)==0) NatOriginLat=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjScaleAtNatOriginGeoKey, out NatOriginScale, 0, 1)==0) NatOriginScale=1.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[0]=NatOriginLat;
					defn.ProjParmId[0]=geokey_t.ProjNatOriginLatGeoKey;
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjNatOriginLongGeoKey;
					defn.ProjParm[4]=NatOriginScale;
					defn.ProjParmId[4]=geokey_t.ProjScaleAtNatOriginGeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_ObliqueMercator: // hotine
					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLatGeoKey, out NatOriginLat, 0, 1)==0) NatOriginLat=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjAzimuthAngleGeoKey, out Azimuth, 0, 1)==0) Azimuth=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjRectifiedGridAngleGeoKey, out RectGridAngle, 0, 1)==0) RectGridAngle=90.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjScaleAtNatOriginGeoKey, out NatOriginScale, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjScaleAtCenterGeoKey, out NatOriginScale, 0, 1)==0) NatOriginScale=1.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[0]=NatOriginLat;
					defn.ProjParmId[0]=geokey_t.ProjCenterLatGeoKey;
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjCenterLongGeoKey;
					defn.ProjParm[2]=Azimuth;
					defn.ProjParmId[2]=geokey_t.ProjAzimuthAngleGeoKey;
					defn.ProjParm[3]=RectGridAngle;
					defn.ProjParmId[3]=geokey_t.ProjRectifiedGridAngleGeoKey;
					defn.ProjParm[4]=NatOriginScale;
					defn.ProjParmId[4]=geokey_t.ProjScaleAtCenterGeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_CassiniSoldner:
				case coordtrans_t.CT_Polyconic:
					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLatGeoKey, out NatOriginLat, 0, 1)==0) NatOriginLat=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjScaleAtNatOriginGeoKey, out NatOriginScale, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjScaleAtCenterGeoKey, out NatOriginScale, 0, 1)==0) NatOriginScale=1.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[0]=NatOriginLat;
					defn.ProjParmId[0]=geokey_t.ProjNatOriginLatGeoKey;
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjNatOriginLongGeoKey;
					defn.ProjParm[4]=NatOriginScale;
					defn.ProjParmId[4]=geokey_t.ProjScaleAtNatOriginGeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_AzimuthalEquidistant:
				case coordtrans_t.CT_MillerCylindrical:
				case coordtrans_t.CT_Gnomonic:
				case coordtrans_t.CT_LambertAzimEqualArea:
				case coordtrans_t.CT_Orthographic:
				case coordtrans_t.CT_NewZealandMapGrid:
					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLatGeoKey, out NatOriginLat, 0, 1)==0) NatOriginLat=0.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[0]=NatOriginLat;
					defn.ProjParmId[0]=geokey_t.ProjCenterLatGeoKey;
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjCenterLongGeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_Equirectangular:
					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLatGeoKey, out NatOriginLat, 0, 1)==0) NatOriginLat=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjStdParallel1GeoKey, out StdParallel1, 0, 1)==0) StdParallel1=0.0;

					// notdef: should transform to decimal degrees at this point

					defn.ProjParm[0]=NatOriginLat;
					defn.ProjParmId[0]=geokey_t.ProjCenterLatGeoKey;
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjCenterLongGeoKey;
					defn.ProjParm[2]=StdParallel1;
					defn.ProjParmId[2]=geokey_t.ProjStdParallel1GeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_Robinson:
				case coordtrans_t.CT_Sinusoidal:
				case coordtrans_t.CT_VanDerGrinten:
					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjCenterLongGeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_PolarStereographic:
					if(GTIFKeyGet(gtif, geokey_t.ProjStraightVertPoleLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLatGeoKey, out NatOriginLat, 0, 1)==0) NatOriginLat=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjScaleAtNatOriginGeoKey, out NatOriginScale, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjScaleAtCenterGeoKey, out NatOriginScale, 0, 1)==0) NatOriginScale=1.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[0]=NatOriginLat;
					defn.ProjParmId[0]=geokey_t.ProjNatOriginLatGeoKey; ;
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjStraightVertPoleLongGeoKey;
					defn.ProjParm[4]=NatOriginScale;
					defn.ProjParmId[4]=geokey_t.ProjScaleAtNatOriginGeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_LambertConfConic_2SP:
					if(GTIFKeyGet(gtif, geokey_t.ProjStdParallel1GeoKey, out StdParallel1, 0, 1)==0) StdParallel1=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjStdParallel2GeoKey, out StdParallel2, 0, 1)==0) StdParallel1=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLatGeoKey, out NatOriginLat, 0, 1)==0) NatOriginLat=0.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[0]=NatOriginLat;
					defn.ProjParmId[0]=geokey_t.ProjFalseOriginLatGeoKey;
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjFalseOriginLongGeoKey;
					defn.ProjParm[2]=StdParallel1;
					defn.ProjParmId[2]=geokey_t.ProjStdParallel1GeoKey;
					defn.ProjParm[3]=StdParallel2;
					defn.ProjParmId[3]=geokey_t.ProjStdParallel2GeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_AlbersEqualArea:
				case coordtrans_t.CT_EquidistantConic:
					if(GTIFKeyGet(gtif, geokey_t.ProjStdParallel1GeoKey, out StdParallel1, 0, 1)==0) StdParallel1=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjStdParallel2GeoKey, out StdParallel2, 0, 1)==0) StdParallel2=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLatGeoKey, out NatOriginLat, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLatGeoKey, out NatOriginLat, 0, 1)==0) NatOriginLat=0.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[0]=StdParallel1;
					defn.ProjParmId[0]=geokey_t.ProjStdParallel1GeoKey;
					defn.ProjParm[1]=StdParallel2;
					defn.ProjParmId[1]=geokey_t.ProjStdParallel2GeoKey;
					defn.ProjParm[2]=NatOriginLat;
					defn.ProjParmId[2]=geokey_t.ProjNatOriginLatGeoKey;
					defn.ProjParm[3]=NatOriginLong;
					defn.ProjParmId[3]=geokey_t.ProjNatOriginLongGeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;

				case coordtrans_t.CT_CylindricalEqualArea:
					if(GTIFKeyGet(gtif, geokey_t.ProjStdParallel1GeoKey, out StdParallel1, 0, 1)==0) StdParallel1=0.0;

					if(GTIFKeyGet(gtif, geokey_t.ProjNatOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjFalseOriginLongGeoKey, out NatOriginLong, 0, 1)==0&&
						GTIFKeyGet(gtif, geokey_t.ProjCenterLongGeoKey, out NatOriginLong, 0, 1)==0) NatOriginLong=0.0;

					// notdef: should transform to decimal degrees at this point
					defn.ProjParm[0]=StdParallel1;
					defn.ProjParmId[0]=geokey_t.ProjStdParallel1GeoKey;
					defn.ProjParm[1]=NatOriginLong;
					defn.ProjParmId[1]=geokey_t.ProjNatOriginLongGeoKey;
					defn.ProjParm[5]=FalseEasting;
					defn.ProjParmId[5]=geokey_t.ProjFalseEastingGeoKey;
					defn.ProjParm[6]=FalseNorthing;
					defn.ProjParmId[6]=geokey_t.ProjFalseNorthingGeoKey;

					defn.nParms=7;
					break;
			}

			// --------------------------------------------------------------------
			//		Normalize any linear parameters into meters. In GeoTIFF
			//		the linear projection parameter tags are normally in the
			//		units of the coordinate system described.
			// --------------------------------------------------------------------
			for(int iParm=0; iParm<defn.nParms; iParm++)
			{
				switch(defn.ProjParmId[iParm])
				{
					case geokey_t.ProjFalseEastingGeoKey:
					case geokey_t.ProjFalseNorthingGeoKey:
					case geokey_t.ProjFalseOriginEastingGeoKey:
					case geokey_t.ProjFalseOriginNorthingGeoKey:
					case geokey_t.ProjCenterEastingGeoKey:
					case geokey_t.ProjCenterNorthingGeoKey:
						if(defn.UOMLengthInMeters!=0&&defn.UOMLengthInMeters!=1.0) defn.ProjParm[iParm]*=defn.UOMLengthInMeters;
						break;
				}
			}
		}
Пример #5
0
		//************************************************************************
		//*							GTIFGetProj4Defn()
		//************************************************************************
		static string GTIFGetProj4Defn(GTIFDefn defn)
		{
			string projection="";
			string units="";
			double falseEasting, falseNorthing;

			if(defn==null||!defn.DefnSet) return "";

			// ====================================================================
			//		Translate the units of measure.
			//
			//		Note that even with a +units, or +to_meter in effect, it is
			//		still assumed that all the projection parameters are in
			//		meters.
			// ====================================================================
			if(defn.UOMLength==geounits_t.Linear_Meter) units="+units=m ";
			else if(defn.UOMLength==geounits_t.Linear_Foot) units="+units=ft ";
			else if(defn.UOMLength==geounits_t.Linear_Foot_US_Survey) units="+units=us-ft ";
			else if(defn.UOMLength==geounits_t.Linear_Foot_Indian) units="+units=ind-ft ";
			else if(defn.UOMLength==geounits_t.Linear_Link) units="+units=link ";
			else if(defn.UOMLength==geounits_t.Linear_Yard_Indian) units="+units=ind-yd ";
			else if(defn.UOMLength==geounits_t.Linear_Fathom) units="+units=fath ";
			else if(defn.UOMLength==geounits_t.Linear_Mile_International_Nautical) units="+units=kmi ";
			else units=string.Format("+to_meter={0}", defn.UOMLengthInMeters);

			// --------------------------------------------------------------------
			//		false easting and northing are in meters and that is what
			//		PROJ.4 wants regardless of the linear units.
			// --------------------------------------------------------------------
			falseEasting=defn.ProjParm[5];
			falseNorthing=defn.ProjParm[6];

			// ====================================================================
			//		Handle general projection methods.
			// ====================================================================

			// --------------------------------------------------------------------
			//		Geographic.
			// --------------------------------------------------------------------
			if(defn.Model==modeltype_t.ModelTypeGeographic)
			{
				projection+="+proj=latlong ";
			}
			// --------------------------------------------------------------------
			//		UTM - special case override on transverse mercator so things
			//		will be more meaningful to the user.
			// --------------------------------------------------------------------
			else if(defn.MapSys==MapSys_UTM_North)
			{
				projection+=string.Format("+proj=utm +zone={0} ", defn.Zone);
			}
			// --------------------------------------------------------------------
			//		Transverse Mercator
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_TransverseMercator)
			{
				projection+=string.Format(nc, "+proj=tmerc +lat_0={0} +lon_0={1} +k={2} +x_0={3:0.###} +y_0={4:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[4], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Mercator
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_Mercator)
			{
				projection+=string.Format(nc, "+proj=merc +lat_ts={0} +lon_0={1} +k={2} +x_0={3:0.###} +y_0={4:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[4], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Cassini/Soldner
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_CassiniSoldner)
			{
				projection+=string.Format(nc, "+proj=cass +lat_0={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Oblique Stereographic - Should this really map onto
			//		Stereographic?
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_ObliqueStereographic)
			{
				projection+=string.Format(nc, "+proj=stere +lat_0={0} +lon_0={1} +k={2} +x_0={3:0.###} +y_0={4:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[4], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Stereographic
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_Stereographic)
			{
				projection+=string.Format(nc, "+proj=stere +lat_0={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Polar Stereographic
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_PolarStereographic)
			{
				if(defn.ProjParm[0]>0.0)
					projection+=string.Format(nc, "+proj=stere +lat_0=90 +lat_ts={0} +lon_0={1} +k={2} +x_0={3:0.###} +y_0={4:0.###} ",
						defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[4], falseEasting, falseNorthing);
				else
					projection+=string.Format(nc, "+proj=stere +lat_0=-90 +lat_ts={0} +lon_0={1} +k={2} +x_0={3:0.###} +y_0={4:0.###} ",
						defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[4], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Equirectangular
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_Equirectangular)
			{
				projection+=string.Format(nc, "+proj=eqc +lat_0={0} +lon_0={1} +lat_ts={2} +x_0={3:0.###} +y_0={4:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[2], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Gnomonic
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_Gnomonic)
			{
				projection+=string.Format(nc, "+proj=gnom +lat_0={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Orthographic
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_Orthographic)
			{
				projection+=string.Format(nc, "+proj=ortho +lat_0={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Lambert Azimuthal Equal Area
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_LambertAzimEqualArea)
			{
				projection+=string.Format(nc, "+proj=laea +lat_0={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Azimuthal Equidistant
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_AzimuthalEquidistant)
			{
				projection+=string.Format(nc, "+proj=aeqd +lat_0={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Miller Cylindrical
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_MillerCylindrical)
			{
				projection+=string.Format(nc, "+proj=mill +lat_0={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} +R_A ",
					defn.ProjParm[0], defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Polyconic
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_Polyconic)
			{
				projection+=string.Format(nc, "+proj=poly +lat_0={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		AlbersEqualArea
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_AlbersEqualArea)
			{
				projection+=string.Format(nc, "+proj=aea +lat_1={0} +lat_2={1} +lat_0={2} +lon_0={3} +x_0={4:0.###} +y_0={5:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[2], defn.ProjParm[3], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		EquidistantConic
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_EquidistantConic)
			{
				projection+=string.Format(nc, "+proj=eqdc +lat_1={0} +lat_2={1} +lat_0={2} +lon_0={3} +x_0={4:0.###} +y_0={5:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[2], defn.ProjParm[3], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Robinson
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_Robinson)
			{
				projection+=string.Format(nc, "+proj=robin +lon_0={0} +x_0={1:0.###} +y_0={2:0.###} ",
					defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		VanDerGrinten
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_VanDerGrinten)
			{
				projection+=string.Format(nc, "+proj=vandg +lon_0={0} +x_0={1:0.###} +y_0={2:0.###} +R_A ",
					defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		Sinusoidal
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_Sinusoidal)
			{
				projection+=string.Format(nc, "+proj=sinu +lon_0={0} +x_0={1:0.###} +y_0={2:0.###} ",
					defn.ProjParm[1], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		LambertConfConic_2SP
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_LambertConfConic_2SP)
			{
				projection+=string.Format(nc, "+proj=lcc +lat_0={0} +lon_0={1} +lat_1={2} +lat_2={3} +x_0={4:0.###} +y_0={5:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[2], defn.ProjParm[3], falseEasting, falseNorthing);
			}
			// --------------------------------------------------------------------
			//		LambertConfConic_1SP
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_LambertConfConic_1SP)
			{
				projection+=string.Format(nc, "+proj=lcc +lat_0={0} +lat_1={1} +lon_0={2} +k_0={3} +x_0={4:0.###} +y_0={5:0.###} ",
					defn.ProjParm[0], defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[4], defn.ProjParm[5], defn.ProjParm[6]);
			}
			// --------------------------------------------------------------------
			//		CT_CylindricalEqualArea
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_CylindricalEqualArea)
			{
				projection+=string.Format(nc, "+proj=cea +lat_ts={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[5], defn.ProjParm[6]);
			}
			// --------------------------------------------------------------------
			//		NewZealandMapGrid
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_NewZealandMapGrid)
			{
				projection+=string.Format(nc, "+proj=nzmg +lat_0={0} +lon_0={1} +x_0={2:0.###} +y_0={3:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[5], defn.ProjParm[6]);
			}
			// --------------------------------------------------------------------
			//		Transverse Mercator - south oriented.
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_TransvMercator_SouthOriented)
			{
				// this appears to be an unsupported formulation with PROJ.4
			}
			// --------------------------------------------------------------------
			//		ObliqueMercator (Hotine)
			// --------------------------------------------------------------------
			else if(defn.CTProjection==coordtrans_t.CT_ObliqueMercator)
			{
				// not clear how ProjParm[3] - angle from rectified to skewed grid -
				// should be applied ... see the +not_rot flag for PROJ.4.
				// Just ignoring for now.
				projection+=string.Format(nc, "+proj=omerc +lat_0={0} +lonc={1} +alpha={2} +k={3} +x_0={4:0.###} +y_0={5:0.###} ",
					defn.ProjParm[0], defn.ProjParm[1], defn.ProjParm[2], defn.ProjParm[4], defn.ProjParm[5], defn.ProjParm[6]);
			}

			// If we don't have a projection leave here
			if(projection=="") return "";

			// ====================================================================
			//		Handle ellipsoid information.
			// ====================================================================
			if(defn.Ellipsoid==ellipsoid_t.Ellipse_WGS_84) projection+="+ellps=WGS84 ";
			else if(defn.Ellipsoid==ellipsoid_t.Ellipse_Clarke_1866) projection+="+ellps=clrk66 ";
			else if(defn.Ellipsoid==ellipsoid_t.Ellipse_Clarke_1880) projection+="+ellps=clrk80 ";
			else if(defn.Ellipsoid==ellipsoid_t.Ellipse_GRS_1980) projection+="+ellps=GRS80 ";
			else
			{
				if(defn.SemiMajor!=0.0&&defn.SemiMinor!=0.0)
					projection+=string.Format(nc, "+a={0:0.###} +b={1:0.###} ", defn.SemiMajor, defn.SemiMinor);
			}

			return projection+units;
		}