# Help with "projected XY to screen xy" conversion algorithm?

I'm trying to convert coordinates from any given coordinate system (be they the coordinates of a graph figure or a map, meaning they can span across both negative and positive values across any of the four +- quadrants), over to screen coordinates. I also want an easy way as part of the solution to be able to zoom to a small area within the coordinate system.

I already tried an algorithm of my own, which was overly complicated and would fail on occasion (for simplicity I have now removed it from the post).

Update

Thanks to the helpful answers below, especially by Martin F, I now have a solution that works as expected with all types of coordinate systems, be they drawing, geographical, negative, flipped, etc. Specifically this has been a great addition to three Python libraries I've been working on: for autozooming to a geographical entity in Shapy, for drawing any kind of coordinates on an image in PyDraw, and for map zooming in GeoVis.

Martin's answer describes the theoretical ideal of how to do it, but here's how I did it for my case. The user specifies the topleft and bottomright xy corners in the coordinate system of their data which they want to appear in the same corners on a graphical image, thus allowing zooming and flipping sides/updown. In my case the graphics drawer has its 0,0 coordinate in the topleft corner. To prepare the equation I just needed a single scalex/y variable.

Update2:

I also added how I constrained the dimensions to keep them the same size, which can be useful in many cases.

``````#input
IMG = ...
XLEFT,YTOP,XRIGHT,YBOTTOM = ...
CONSTRAIN = True

#constrain dimensions to avoid distortion
if CONSTRAIN:
xwidth = max(XLEFT,XRIGHT) - min(XLEFT,XRIGHT)
yheight = max(YTOP,YBOTTOM) - min(YTOP,YBOTTOM)
if xwidth > yheight:
YBOTTOM = YTOP+xwidth
elif yheight > xwidth:
XRIGHT = XLEFT+yheight

#prepare scale values
imgwidth = float(IMG.width)
imgheight = float(IMG.height)
scalex = imgwidth / (XRIGHT - XLEFT)
scaley = 0 - imgheight / (YTOP - YBOTTOM)
``````

With that, the coordinate conversion of `inx` and `iny` is calculated as:

``````newx = scalex * (inx - XLEFT)
newy = imgheight + scaley * (iny - YBOTTOM)
``````
• I have a very untrained eye. however I think I see the you are using the bottom left of all cs systems as 0,0. this would only be accurate on a subset of systems, the rest would be based on the origin lon and origin lat, The other factor that would make for inaccuracy would be the fact that some cs have false north/easting. There are libraries to do these calculations on the correct parameters though. Jun 3, 2014 at 14:20
• @BradNesom: This is not a "projection" from lon-lat to XY; it is merely 4-parameter transformation (scale and shift) from "already projected" XY to screen xy. Jun 3, 2014 at 16:24
• Mind editing some of the code for readability? Add spaces around operators + - * / and spaces after commas. And encode any variables mentioned in the text within ` (graves?) Jun 3, 2014 at 16:36
• lat lon is not what I was referring to. recent edits seem to have changed the meaning of the op question. In the code this must be a very small snippet indeed if you are converting all values to positive and still keeping track of which direction the axis of those values are. It seems there is more to this question not being relayed. What happens if the projected cs is albers? or do you not allow any projections other than your choice? Jun 3, 2014 at 17:02
• @BradNesom: I edited the wording slightly so as to match what i see the code trying to do. I don't believe the Q has anything to do with map projections -- just simple conversion from one plane system to another. The OP can confirm though. (I could be wrong.) Jun 3, 2014 at 17:20

``````scale_x = (img_right - img_left) / (x_right - x_left)
• the reverse y situation (where geographic and screen coordinates run in opposite directions) seems to be handled simply by the user inputting the `YTOP` value as being higher than the `YBOTTOM` value (the reverse of screen coordinates). That way it's flexible and can handle any type of flipped/reverse coordinate system. Works for me at least. I also started thinking about the distortion issue that you mentioned and made a way to constrain both scales so they equal eachother if desired (see update2). Jun 9, 2014 at 13:48