1

i have researched regarding making world file format and tried to create one using c++ in windows, can somebody confirm if where i am getting the values from are correct? the literature regarding world file formats are quite vague. i don't use rotation so i assume value D and E are always zero..

Line 1: A: pixel size in the x-direction in map units/pixel.

p->GetDeviceCaps(HORZRES); // HORZRES is defined in wingdi.h as Horizontal width in
pixels

Line 2: D: rotation about y-axis // always 0 as i don't use rotation

Line 3: B: rotation about x-axis // always 0 as i don't use rotation

Line 4: E: pixel size in the y-direction in map units, almost always negative

p->GetDeviceCaps(VERTRES); // VERTRES is defined in wingdi.h as Horizontal width in
pixels

Line 5: C: x-coordinate of the center of the upper left pixel // how do you get this value?

Line 6: F: y-coordinate of the center of the upper left pixel // how do you get this value?

3
  • 1
    To populate the values it is necessary to know what software you are developing for. In most software there is an extent object of the frame that will have all the necessary values. Commented Feb 4, 2015 at 2:21
  • say i am creating a gis application and i need to use the gdi of windows to get those values, how do i go about it? Commented Feb 4, 2015 at 11:30
  • If you are creating an application you must know the extent of the frame and then the number of pixels wide and high... I'll put in an Esri example which may shed some light on it. Commented Feb 4, 2015 at 21:47

1 Answer 1

2

World files, as used by Esri, GDAL etc.. have a standard format:

Normally the rotation is 0 for both values (not rotated) but the values form a 6 parameter Affine Transformation between cells and the world; if you understand the maths then you could conceivably populate those numbers for a fine rotation. Here is some code for a GDAL GeoTransform array that is very similar to a world file:

double GeoTransform[6];
GeoTransform[0] = Xmin;             // Upper Left X
GeoTransform[1] = CellSize;         // W-E pixel size
GeoTransform[2] = 0;                // Rotation, 0 if 'North Up'
GeoTransform[3] = Ymax;             // Upper Left Y
GeoTransform[4] = 0;                // Rotation, 0 if 'North Up'
GeoTransform[5] = -CellSize;        // N-S pixel size

Whereas a world file is populated like:

Cell Width
0
0
Cell Height (negative)
X coordinate of upper left cell (centre)
Y coordinate of upper left cell (centre)

Note that N-S pixel size is always negative as rasters start at the upper left and read downward. All values are in world units (metres, feet, degrees, inches etc.).

Here is an example of how I would calculate/create a world file in Esri objects:

void GetWorldValuesFromActiveView(ESRI.ArcGIS.Framework.IApplication pApp)
{
    ESRI.ArcGIS.ArcMapUI.IMxDocument pDoc = (ESRI.ArcGIS.ArcMapUI.IMxDocument)pApp.Document;            
    ESRI.ArcGIS.Carto.IActiveView pView = pDoc.ActiveView;
    ESRI.ArcGIS.Geometry.IEnvelope pExtent = pView.Extent;      // the display bounds in world units
    ESRI.ArcGIS.esriSystem.tagRECT pPixBnd = pView.ExportFrame; // the display bounds in screen units
    // cells wide and high, I am using absolute value
    // as (very rarely) a screen can have negative coordinates
    int Rows = Math.Abs( pPixBnd.top - pPixBnd.bottom );
    int Cols = Math.Abs( pPixBnd.right - pPixBnd.left );

    double Width = pExtent.XMax - pExtent.XMin; // width in 'world' units
    double Height = pExtent.YMax - pExtent.YMin;
    double CellX = Width / Cols;
    double CellY = Height / Rows;
    double ULX = pExtent.XMin + (CellX / 2);
    double ULY = pExtent.YMax - (CellY / 2);

    using (System.IO.StreamWriter pWorldWrite = new System.IO.StreamWriter("c:\\path\\to\\world\\file.tfw"))
    {
        pWorldWrite.WriteLine(CellX.ToString());
        pWorldWrite.WriteLine("0");
        pWorldWrite.WriteLine("0");
        pWorldWrite.WriteLine("-" + CellY.ToString());
        pWorldWrite.WriteLine(ULX.ToString());
        pWorldWrite.WriteLine(ULY.ToString());
    }
}

As you can see from the application you must know how many pixels the window is but also what extent 'on the ground' that those pixels represent. If you are writing your own application you must know these values at some point as it's intrinsic to rendering to display.

6
  • You need to transform a half-resolution to convert between corner and centre references.
    – Mike T
    Commented Feb 4, 2015 at 2:24
  • @MikeT, some software assumes corner, others assume centre, the trick is knowing which you are working with. The extent rectangle is the edge of the frame so, as you said, you will probably need to add half a cell to the values. Most of the time though a half cell displacement isn't a big deal. Commented Feb 4, 2015 at 2:58
  • thank you for answering the question. However, the answer is still quite vague. can anyone show example on how to do this using gdi in windows? i saw this site when i was researching: spatialhorizons.com/2007/09/26/using-qgis-4-raster-images , but this seems to apply only for rasters with long and lat coordinates. windows gdi seems to work using mm/pixel. Commented Feb 4, 2015 at 3:15
  • 1
    How does windows gdi relate to the world? Surely you're starting with a map of something, what created that map? Geographic coordinates / projected coordinates all work the same in this instance; there is a .prj file often accompanying the image/world that specifies the spatial reference and therefore units. Commented Feb 4, 2015 at 3:33
  • 1
    It's not software dependent. The matrix used in world files are referenced to the cell center, and GDAL's GeoTransform matrix is referenced to the cell corner. No exceptions.
    – Mike T
    Commented Feb 4, 2015 at 5:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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