First note that your coordinates span the entire globe which is a sphere not a rectangle so if you simply map this data to a rectangle you'll get deformed data similar to what you see on a flat map of the world. There are projection methods that map patches from spherical coordinates onto a flat surface but I havn't done that. You'll need to look around some cartography Web sites for those sorts of algorithms.
The Graphics object supports transformations that can represent translation, scaling, and rotation. The trick is to figure out hwo to translate and scale so your data appears where you want it. Here's a subroutine that sets the transformation for a Graphics object to map data coordinates with corners at (data_ul_x, data_ul_y)-(data_lr_x, data_lr_y) to the device coordinates (dev_ul_x, dev_ul_y)-(dev_lr_x, data_lr_y).
Private Sub ScaleControl(ByVal gr As Graphics, _
ByVal data_ul_x As Single, ByVal data_ul_y As Single, _
ByVal data_lr_x As Single, ByVal data_lr_y As Single, _
ByVal dev_ul_x As Single, ByVal dev_ul_y As Single, _
ByVal dev_ll_x As Single, ByVal dev_ll_y As Single)
' Start from scratch.
gr.ResetTransform()
' Move (data_ul_x, data_ul_y) to the origin.
gr.TranslateTransform(-data_ul_x, -data_ul_y, _
MatrixOrder.Append)
' Scale so the data rectangle's width and height
' match those of the device rectangle.
gr.ScaleTransform( _
(dev_ll_x - dev_ul_x) / (data_lr_x - data_ul_x), _
(dev_ll_y - dev_ul_y) / (data_lr_y - data_ul_y), _
MatrixOrder.Append)
' Move the origin to (dev_ul_x, dev_ul_y).
gr.TranslateTransform(dev_ul_x, dev_ul_y, _
MatrixOrder.Append)
End Sub
For your example, the data coordinates would be the lat and long of the area you want to display. The device coordinates would be the corners of the PictureBox or whatever control you are drawing on.
You should pick the data bounds so the area's width/height ratio is the same as the control's width/height ratio so the data isn't stretched or squashed.
Rotating objects is not much harder than all this. The idea is: translate the object's center of rotation (for example, you might rotate around its middle) to the origin, rotate it, and then translate the origin back to the original center of rotation. So to draw a map with a rotated object:
1. Use ScaleControl to set up the map's basic transformation.
2. Draw the stuff that doesn't need rotation.
3. Save the transformation. I think you can store the Graphics object's Transform property. Or there's a method that essentially makes a checkpoint that you can later return to.
4. For each object that needs rotation:
A. Add a translation to move the center of rotation to the origin.
B. Add a rotation.
C. Add the inverse of the translation for step 4A.
D. Draw the object.
E. Restore the transformation you saved in step 3.
Each step isn't too complicated but taken all together it can be pretty confusing.
I hope that helps.
Rod
[email protected]
Author of "Visual Basic 2005 Programmer's Reference"
http://www.vb-helper.com/vb_prog_ref.htm