World File Format Creation – How to Get Values to Create World File Format for Raster

craster

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?

Best Answer

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.