Recently I have been trying to get a custom map working with Longitude and Latitude that plotted in the x and y in iOS. It also needed to work with a zoom and offset. It was a bit of an argus journey but I got there in the end.
What you will need is a projections type(map type) and the formula for the conversion. Ideally a projection type that compensates for the curvature of the earth.
I settled for a Miller Cylindrical projection. The problem with the maps is finding an accurate map. You can use maps with offsets but getting started it helps if you have an accurate map. I ended up going through a lot of maps before I found an accurate one. It had a white border that I had to crop off but otherwise it was perfect.
DONT FORGET TO CROP THE WHITE BOARDER IF YOU SCALE IT UP
http://en.wikipedia.org/wiki/File:Miller_projection_SW.jpg
I scaled it up for testing purposes up to a height of 6563 and a width 8933 cropped.
Here is the Objective-C code and little C to get he job done:
[objc] // this simple c function can go under the imports and above the @implementation //you can use this method to do the conversion //replace this with the height and width of you image lon = DegreesToRadians(lon); x = lon; x = (( width / 2 ) + ( width / (2 * M_PI) ) * x); return CGPointMake(x,y); As you can see the the hight and width is hard coded. What if your map needs an offset and you also need to have a dynamic size to compensate for zoom levels. [objc] // this simple c function can go under the imports and above the @implementation //you can use this method to do the conversion //the height and width need to be set dynamically in your code //you get the offset value by calculating the number of pixels it //you get the offset value by calculating the number of pixels it lon = DegreesToRadians(lon); x = lon; x = (( width / 2 ) + ( width / (2 * M_PI) ) * x) – widthOffset; return CGPointMake(x,y);
//add this at the top of your m file with the rest
#import
CGFloat DegreesToRadians(CGFloat degrees){ return degrees * M_PI / 180;};
– (CGPoint)XYfromLong:(float)lon andLat:(float)lat
{
double x, y;
double height = 6563;
double width = 8933;
lat = DegreesToRadians(lat);
y = 1.25 * log( tan( 0.25 * M_PI + 0.4 * lat ) );
y = ( height / 2 ) – ( height / ( 2 * 2.303412543 ) ) * y;
}
[/objc]
//add this at the top of your m file with the rest
#import
CGFloat DegreesToRadians(CGFloat degrees){ return degrees * M_PI / 180;};
– (CGPoint)XYfromLong:(float)lon andLat:(float)lat
{
double x, y;
double height = dynamicHeightValue;
double width = dynamicWidthValue;
//needs to be moved in the y then divide that by the map height
//it is unlikely the y will need an offset
double heightOffset = (height * 0.0243)
//needs to be moved in the x then divide that by the map width
double widthOffset = (width * 0.0461)
lat = DegreesToRadians(lat);
y = 1.25 * log( tan( 0.25 * M_PI + 0.4 * lat ) );
y = (( height / 2 ) – ( height / ( 2 * 2.303412543 ) ) * y) – heightOffset;
}
[/objc]