<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://bf2tech.uturista.pt/index.php?action=history&amp;feed=atom&amp;title=Cookbook%3APloting_Object_Positions_on_a_Map_Image</id>
	<title>Cookbook:Ploting Object Positions on a Map Image - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://bf2tech.uturista.pt/index.php?action=history&amp;feed=atom&amp;title=Cookbook%3APloting_Object_Positions_on_a_Map_Image"/>
	<link rel="alternate" type="text/html" href="https://bf2tech.uturista.pt/index.php?title=Cookbook:Ploting_Object_Positions_on_a_Map_Image&amp;action=history"/>
	<updated>2026-08-06T00:31:27Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.40.1</generator>
	<entry>
		<id>https://bf2tech.uturista.pt/index.php?title=Cookbook:Ploting_Object_Positions_on_a_Map_Image&amp;diff=94&amp;oldid=prev</id>
		<title>Pireax: Created page with &quot;==  Problem  ==  You want to plot the position of objects or events in the BF2 game world on a map; for example, you want to plot the positions of player deaths, the positions...&quot;</title>
		<link rel="alternate" type="text/html" href="https://bf2tech.uturista.pt/index.php?title=Cookbook:Ploting_Object_Positions_on_a_Map_Image&amp;diff=94&amp;oldid=prev"/>
		<updated>2018-06-21T19:30:31Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;==  Problem  ==  You want to plot the position of objects or events in the BF2 game world on a map; for example, you want to plot the positions of player deaths, the positions...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==  Problem  ==&lt;br /&gt;
&lt;br /&gt;
You want to plot the position of objects or events in the BF2 game world on a map; for example, you want to plot the positions of player deaths, the positions of control points, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Solution  ==&lt;br /&gt;
&lt;br /&gt;
There are three parts to this recipie. . .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Getting a copy of the HUD map  ===&lt;br /&gt;
&lt;br /&gt;
[[File:GoO_commander.jpg|thumb|right|alt=commanderMap.dds|commanderMap.dds]]&lt;br /&gt;
&lt;br /&gt;
First we have to get a hold of an image of the BF2 map we&amp;#039;re interested in and convert it into a format we can use as a base to plot on top of.&lt;br /&gt;
&lt;br /&gt;
The directory &amp;lt;code&amp;gt;Battlefield 2/mods/bf2/Levels&amp;lt;/code&amp;gt; contains subdirectories for each map available as part of the standard &amp;quot;bf2&amp;quot; mod (the retail game). On a computer that has the client version of BF2 installed (not just a dedicated server), go into that directory and find the subdirectory for the map you want; for purposes of illustration, we&amp;#039;ll work with Gulf of Oman, which is in the directory &amp;lt;code&amp;gt;Battlefield 2/mods/bf2/Levels/Gulf_of_Oman&amp;lt;/code&amp;gt;; change into that directory.&lt;br /&gt;
&lt;br /&gt;
[[File:GoO_ingame.jpg |thumb|right|alt=ingameMap.dds|ingameMap.dds]]&lt;br /&gt;
&lt;br /&gt;
Inside it you should see a file called &amp;lt;code&amp;gt;client.zip&amp;lt;/code&amp;gt;. Unzip that file, and decend into the resulting new directory. Inside it, go into the &amp;lt;code&amp;gt;Hud&amp;lt;/code&amp;gt;, then again into the &amp;lt;code&amp;gt;Minimap&amp;lt;/code&amp;gt; directory--so now you should be in the directory &amp;lt;code&amp;gt;Battlefield 2/mods/bf2/Levels/Gulf_of_Oman/client/Hud/Minimap&amp;lt;/code&amp;gt;. In this directory are two files, &amp;lt;code&amp;gt;commanderMap.dds&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ingameMap.dds&amp;lt;/code&amp;gt;. Get copies of these.&lt;br /&gt;
&lt;br /&gt;
These files are in the &amp;quot;DDS&amp;quot; or &amp;quot;[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/DDSFileReference/ddsfileformat.asp DirectDraw Surface]&amp;quot; format. This format is designed for high-performance use by 3D accelerators--which is nice, but we need to change them into a format we can actually do something with, like [http://en.wikipedia.org/wiki/Png PNG] or [http://en.wikipedia.org/wiki/Jpeg JPEG]. Get a copy of the [http://eliteforce2.filefront.com/file/DDS_Converter;29412 DDS Converter] program, and use it to convert these files into PNG or JPEG format.&lt;br /&gt;
&lt;br /&gt;
Once you&amp;#039;ve done so you can see what the differences are between the two images: both are 512x512 pixels in size, but &amp;lt;code&amp;gt;commanderMap.dds&amp;lt;/code&amp;gt; is a monochrome satellite view, whereas &amp;lt;code&amp;gt;ingameMap.dds&amp;lt;/code&amp;gt; is a full-color aerial view. Depending on what you&amp;#039;re doing, you may want to select one of these images over the other. We will refer to the map image you choose as the &amp;quot;HUD image&amp;quot; in the remainder of this recipie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Converting game coordinates to HUD image coordinates  ===&lt;br /&gt;
&lt;br /&gt;
See the page on [[BF2_Coordinates|BF2 Coordinates]] for detailed information about the Battlefield 2 coordinate system. We need to convert coordinates in this system (which typically runs from -1024 to +1024 along each dimension) into the coordinates of a specific pixel in our 512x512 HUD image--so we need to do some scaling. Additionally, we&amp;#039;re going to be plotting points on the HUD image using the [http://www.pythonware.com/products/pil Python Imaging Library] (or &amp;quot;PIL&amp;quot;), which addresses pixels in an image with the vertical axis reversed from how BF2 game coordinates work.&lt;br /&gt;
&lt;br /&gt;
Here are the formulas that will work to convert coordinates on a map with a world size of 2048x2048 (i.e. all basic BF2 maps except &amp;#039;&amp;#039;Strike at Karkand&amp;#039;&amp;#039;) into the specific PIL coordinates for the pixel on the HUD image that corresponds to those game coordinates:&lt;br /&gt;
&lt;br /&gt;
: X&amp;lt;sub&amp;gt;HUD&amp;lt;/sub&amp;gt; = X&amp;lt;sub&amp;gt;Game&amp;lt;/sub&amp;gt; / 4 + 256&lt;br /&gt;
&lt;br /&gt;
: Y&amp;lt;sub&amp;gt;HUD&amp;lt;/sub&amp;gt; = 256 - Z&amp;lt;sub&amp;gt;Game&amp;lt;/sub&amp;gt; / 4&lt;br /&gt;
&lt;br /&gt;
Note that PIL uses X and Y axes, whereas BF2 bizarely uses X and Z. We throw out the BF2 Y coordinate, which represents altitude, because we&amp;#039;re doing a 2-dimensional plot.&lt;br /&gt;
&lt;br /&gt;
The mathematics for deriving these conversions should be intuitively obvious, and are left as an exercise for the reader (I always wanted to say that. . .).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===  Plotting points on the the HUD image  ===&lt;br /&gt;
&lt;br /&gt;
Exactly how you plot points on your HUD image will really depend on what it is you are trying to accomplish, but here&amp;#039;s an example of how to use [http://www.pythonware.com/products/pil PIL] to plot points on the image corresponding to tuples of game coordinates contained in a list. Note that PIL must be installed in your Python interpreter for this to work; also note that this is not written to run as part of BF2--it&amp;#039;s written as a stand-alone program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[File:Eye_of_the_North_Retail_3D_Box.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
 import Image, ImageDraw, ImageColor  # These modules are part of PIL&lt;br /&gt;
 &lt;br /&gt;
 def plotPoints(baseImage, resultImage, gamePoints):&lt;br /&gt;
     # Convert a set of 3-tuple game coordinates (X,Y,Z) into pixel coordinates&lt;br /&gt;
     pixelPoints = []&lt;br /&gt;
     for gamePoint in gamePoints:&lt;br /&gt;
         pixelPoints.append( (gamePoint[0] / 4 + 256,&lt;br /&gt;
                              256 - gamePoint[2] / 4) )&lt;br /&gt;
    &lt;br /&gt;
     # Read in the base image file and initialize it for drawing&lt;br /&gt;
     hud = Image.open(baseImage)&lt;br /&gt;
     drawable = ImageDraw.Draw(hud)&lt;br /&gt;
    &lt;br /&gt;
     # Plot points at each set of pixel coordinates&lt;br /&gt;
     drawable.point(pixelPoints, fill = ImageColor.getrgb(&amp;quot;red&amp;quot;) )&lt;br /&gt;
    &lt;br /&gt;
     # Write our completed image to disk. We use PNG here because individual&lt;br /&gt;
     # pixels of a different color tend to not show up well in JPEGs.&lt;br /&gt;
     hud.save(resultImage, &amp;quot;PNG&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s what the output of this code looks like; the data for this image is a set of coordinates of player deaths (106 of them) gathered in a round of single-player play on the &amp;#039;&amp;#039;Gulf of Oman&amp;#039;&amp;#039; map with the 16-player version of the map--so it shows the locations of deaths accrued by 1 human player and 15 bots:&lt;br /&gt;
[[File:GoO_commander.jpg|frame|center|alt=commanderMap.dds|Sample output of Python code; the locations of 106 player deaths are plotted.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Discussion  ==&lt;br /&gt;
&lt;br /&gt;
The Python code shown above was written to try to clearly illustrate the concepts of this recipie, but will almost certainly need modification for your own use. For example, single pixels are awfully hard to see--it works much better to draw a small cluster of pixels, or even a small icon, for each each point you want to plot.&lt;br /&gt;
&lt;br /&gt;
Also note that this code runs separately from Battlefield 2. It&amp;#039;s fast enough that you could probably run it from BF2&amp;#039;s Python interpreter, at the end of each round, for example, but it wouldn&amp;#039;t be a good idea to run it more frequently than that.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Submitted By  ==&lt;br /&gt;
&lt;br /&gt;
--Woody&lt;/div&gt;</summary>
		<author><name>Pireax</name></author>
	</entry>
</feed>