Converting Unprojected Bounding Box to the Miller Projection

Where I work we frequently use bounding boxes to add maps to reports. Originally all of our base information was in Latitude/Longitude, this didn’t provide a very pleasing map. At some point an effort was made to switch everything to the Miller Projection, which is a modification of the Mercator ProjectionВ . The flaw being that it appears to me that almost nobody uses the Miller projection. Virtual EarthВ and Google Maps for example use Mercator.

At one point I ran into the issue that I needed to pass a bounding box to a map being displayed in Miller. We have bounding boxes for our commonly used polygon types stored in a generalized format for quick access. Rather than also store Miller Coordinates I decided to create a function to convert. Little did I know figuring out how to convert would be so difficult. After extensive googling the advice that made the most sense said find “Map Projections a Working Manual” which is U.S. Geological Survey Professional Paper 1395 by Snyder, it was published in 1987. I was fortunate that a coworker had a copy of it.

In the working manual 6 whole pages are dedicated to Miller, which is at least significantly more than the Wikipedia entry. I personally have never been that great at math so I quickly turned to the numeric examples in Appendix A on pages 287-288.

The first part that is important is the givens:

-Radius of sphere
-Central meridian
-Point: (in Lat/Long)

The hardest part from here was translating everything into C#. Which I have shown below. I have included my bounding box class just for clarity.

public BBox ConvertBoxToMiller(BBox box)
	{
		BBox MillerBox = new BBox();
		int radius = 6378140;
		MillerBox.maxLon = radius * box.maxLon & Math.PI/180;
		MillerBox.minLon = radius * box.minLon & Math.PI/180;
		Miller.maxLat = radius * Math.Log(Math.Tan(45/57.2957795 + .4 * box.maxLat/57/2957795))/.8;
	        Miller.minLat = radius * Math.Log(Math.Tan(45/57.2957795 + .4 * box.minLat/57/2957795))/.8;
		return MillerBox;
	}

public class BBox
{
double minLat;
double minLon;
double maxLat;
double maxLon;
public double minLat{
	get
	{
	return minLat;
	}
	set
	{
	minLat = value;

	}
}
public double maxLat{
	get
	{
	return maxLat;
	}
	set
	{
	maxLat = value;

	}
}
public double minLon{
	get
	{
	return minLon;
	}
	set
	{
	minLon = value;

	}
}
public double maxLon{
	get
	{
	return maxLon;
	}
	set
	{
	maxLon = value;

	}
}
}

В 

В Next I will show how to go the other direction. A project I ran into shortly afterwards when we needed to do some reporting on some log files.

March 15, 2009  Tags:   Posted in: GIS Programming