Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

What steps do I need to do in order to calculate longitude and latitude for a specific pixel in a georeferenced image? For example this image http://www.shadedreliefarchive.com/medit_Mideast_africa_copy.html contains information, .tfw file:

1627.32174969982000 
0.00000000000000 
0.00000000000000 
-1627.32174969982000 
-4957506.34276705000000 
6096922.76188281000000 

and .prj file:

PROJCS["Lambert Azimuthal Equal-Area",
       GEOGCS["GCS_WGS_1984",
              DATUM["D_WGS_1984", SPHEROID["WGS_1984", 6378137, 298.257223563]],
              PRIMEM["Greenwich", 0],
              UNIT["Degree", 0.017453292519943295]],
       PROJECTION["Lambert_Azimuthal_Equal_Area"],
       PARAMETER["false_easting", 0],
       PARAMETER["false_northing", 0],
       PARAMETER["latitude_of_origin", 0],
       PARAMETER["central_meridian", 20],
       PARAMETER["xy_plane_rotation", 0],
       UNIT["Meter", 1]]

I've created this snippet of javascript to compute new x1 and y1 values for specific pixels in the image:

var A = 1627.32174969982000,
    D = 0.00000000000000,
    B = 0.00000000000000,
    E = -1627.32174969982000,
    C = -4957506.34276705000000,
    F = 6096922.76188281000000;

function x1(x, y) { return A*x + B*y + C; }

function y1(x, y) { return D*x + E*y + F; }

What more do I have to do to get longitude and latitude? For example C, F represents the top-left corner of the image, right? Then how do I translate C, F to get longitude and latitude?

I want do do it using javascript only, have looked at http://proj4js.org/ but don't really understand what to do with the values I get...

share|improve this question
1  
don't you need to reproject the raster image with a GIS package first? –  Mapperz Apr 12 '11 at 14:10
    
Hopefully not, I would like to have a function to convert pixel positions in the image to long/lat positions and also preferable the reverse translation. –  antonj Apr 12 '11 at 14:25
    
Just a comment: usually people use the coordinates of pixel centers for computing their (lat, lon). If that's your intention, then in your snippet you should therefore first add 1/2 to each of x and y (assuming they are row and column indices). –  whuber Apr 12 '11 at 14:56
    
@whuber, that sounds reasonable –  antonj Apr 12 '11 at 15:11
    
@whuber @antonj -- just a note that the .tfw already includes an offset to the pixel center; adding another 1/2 will put you at the bottom right of the pixel. (Line 5 & 6, the "origin" of the affine transform in the .tfw, are the coordinates of the center of the top-left pixel, not the coordinates of the top-left of the top-left pixel.) –  Dan S. Apr 12 '11 at 15:55

2 Answers 2

The .tfw represents the affine transform for the image -- how image pixel coordinates map to coordinates in the space defined by the .prj.

Here's an explanation of the values: http://en.wikipedia.org/wiki/World_file

(What isn't in Wikipedia these days?)

Getting to geographic coordinates is thus a two-step process:

  • Find the coordinates of the pixel in the projected coordinate system
  • Unproject this coordinate back to the geographic coordinate system to arrive at lat & lon.

The formula for the first step:

X_proj = C + (A * X_img) + (B * Y_img) 
Y_proj = F + (E * Y_img) + (D * X_img)

Note: I'm using the variables A..F from the article I linked, not from your code above! I don't believe they correspond; the Wikipedia article chose labels that don't correspond to line numbers.

Now you have X & Y coordinates in your desired coordinate system. Since you're using Javascript (using proj4js; forgive me if I haven't tested the code below):

var source = new Proj4js.Proj('PROJ4_ARGS_FOR_YOUR_PROJECTION');
var dest = new Proj4js.Proj('EPSG:4326') // geographic coordinates + WGS84 (which matches the ellipsoid used in your .prj)

var p = new Proj4js.Point(X_proj, Y_proj)
Proj4js.transform(source, dest, p)

// p.x & p.y are now lat & lon. (or lon & lat, can't recall coord order)

I (ab)used spatialrefrence.org to convert your .prj into arguments for Proj4; you can see it here by clicking on 'proj4': http://spatialreference.org/ref/sr-org/7119/ In general, .prj to proj4 args is a purely mechanical transformation.

Cheers!

share|improve this answer
    
Thanks I don't understand what happens at spatialreference.org but I have some stuff to test now :) –  antonj Apr 12 '11 at 16:03
1  
@antonj -- It's just the lazy (and web-linkable) way I used to convert your .prj parameters into proj4j arguments. The site gives you lots of ways to download a spatial reference, but the "proj4" link is the one you care about. They're all the same spatial reference info, just different formats. E.g. the "Lambert Azimuthal Equal-Area" in your .prj translates directly into the +proj=laea argument on the "proj4" version; the "central-meridian" of 20 translates to +lon_0=20, etc. –  Dan S. Apr 12 '11 at 16:15

I'm not much of a js programmer, but this works for me:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>Geographic Coordinate Transformations in Javascript</TITLE>

<script src="lib/OLprototype.js"></script>
<script src="lib/proj4js-combined.js"></script>

<SCRIPT type="text/javascript">
// Put your projection definition here.
Proj4js.defs["EPSG:3575"] = "+proj=laea +lat_0=90 +lon_0=10 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs";

var A = 1627.32174969982000,
    D = 0.00000000000000,
    B = 0.00000000000000,
    E = -1627.32174969982000,
    C = -4957506.34276705000000,
    F = 6096922.76188281000000;

function frompixel(px, py) {
    px += 0.5; // Add a half-pixel offset to get the coordinates of the centre of the pixel.
    py += 0.5;
    return {x : A*px + B*py + C, y: D*px + E*py + F};
}

function tolatlong(x, y) {
    var src = new Proj4js.Proj('EPSG:3575'); // Same code as you defined above. Alternatively, let proj4js get the definition from spatialreference.org
    var dest = new Proj4js.Proj('EPSG:4326');
    var p = frompixel(x, y);

    document.write('From coordinates: ');
    document.writeln(p.x, ',', p.y);

    // This is the bit that does the transformation from map coordinates to lat/long.
    Proj4js.transform(src, dest, p);
    document.write('To lat/long: ');
    document.writeln(p.x, ',', p.y);
}
</SCRIPT>

</HEAD>
<BODY>
    <SCRIPT type="text/javascript">
    tolatlong(100, 100);
    </SCRIPT>
</BODY>
</HTML>

Naturally, you will have to play around with the code a bit to integrate it with your web page, but the principle should be right.

share|improve this answer
    
Amusing... we gave, more or less, the exact same answer at the exact same time. ;) –  Dan S. Apr 12 '11 at 15:23
    
It's good to know we both stand a reasonable chance of being right :) –  MerseyViking Apr 12 '11 at 15:29
    
Upon a closer read, I'm not certain your +0.5 is correct. (See the comment I left in the discussion on the main question.) –  Dan S. Apr 12 '11 at 15:58
    
Thanks, although I don't understand where you got "EPSG:3575" from? –  antonj Apr 12 '11 at 16:05
    
@antonj -- that's the EPSG code for the projection MerseyViking is using, which incidentally is not the same one as in your question. (Frequently used projections have a code assigned to them by the EPSG. I bet yours has an EPSG code too, but it wasn't included in the .prj). –  Dan S. Apr 12 '11 at 16:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.