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.
More from Maploser
- Update from Google Map on my Problem
- Layar for the iPhone
- My Personal Map
- Update to my Google Maps Error Report
- GeoNerds in the Wave
Maploser Recommends
- WordPress as a CMS (Adam Estrada)
- Customizing config.xml in the ESRI FlexViewer (Adam Estrada)
- How to copy music from your iPod to your iPhone (Adam Estrada)
March 15, 2009
Tags: Add new tag Posted in: GIS Programming
