Home   Help Search Login Register  

Author Topic: Map Grid Ref Coords - for all maps  (Read 2994 times)

0 Members and 1 Guest are viewing this topic.

Offline Dr Eyeball

  • Members
  • *
Map Grid Ref Coords - for all maps
« on: 09 Dec 2007, 12:29:08 »
--- Edit: All problems solved and questions answered ---



I am aware there are some grid ref functions in editor depot. However, they don't seem to work with all terrains (islands).

1. Request: Is someone able to modify their version (preferably Cheetah's getRCoord function) to work specifically with the Sakakah pbo terrain?



2. Query: Looking at the config.cpp properties of a terrain (class CAWorld), is it possible to write a generic grid ref function to work with any terrain/island map by referencing the properties there?

Some of the interesting properties from sara.pbo:
Code: [Select]
class CfgWorlds {
class DefaultClutter {
scaleMin = 0.9;
scaleMax = 1.2;
};
class Sara : CAWorld {
description = "Sahrani";
worldName = "\ca\sara\sara.wrp";
plateFormat = "SA$ - #####";
plateLetters = ABCDEGHIKLMNOPRSTVXZ;
longitude = -40.02; // positive is east
latitude = -39.95; // positive is south
landGrid = 40;

class Grid : Grid {
offsetX = 0;
offsetY = 0;

class Zoom1 {
zoomMax = 0.1;
format = "XY";
formatX = "Aa";
formatY = "00";
stepX = 200;
stepY = 200;
};

class Zoom2 {
zoomMax = 1e+030;
format = "XY";
formatX = "A";
formatY = "0";
stepX = 2000;
stepY = 2000;
};
};
« Last Edit: 10 Dec 2007, 07:55:27 by Dr Eyeball »

Offline T_D

  • CWR
  • **
  • Troubleshooting Device
Re: Map Grid Ref Coords - for all maps
« Reply #1 on: 09 Dec 2007, 23:11:44 »
Here the script from CoC CEX:
Code: [Select]
private ["_x","_y","_cfg","_offsetX","_offsetY","_stepX","_stepY","_el"];
_cfg    =configFile>>"CfgWorlds">>worldName>>"Grid";
_offsetX=getNumber(_cfg>>"offsetX");
_offsetY=getNumber(_cfg>>"offsetY");_offsetY=480;
_stepX  =getNumber(_cfg>>"Zoom1">>"stepX");
_stepY  =getNumber(_cfg>>"Zoom1">>"stepY");

_x=(_this select 0)-_offsetX;
_y=(_this select 1)-_offsetY;


_el=
[
    ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
    ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"],
    ["0","1","2","3","4","5","6","7","8","9"],
    ["0","1","2","3","4","5","6","7","8","9"]
];

_xs=([1,-1]select(_x<0));
_x =((abs _x)-((abs _x)mod _stepX))/_stepX;

_y=100*_stepY-_y;
_ys=([1,-1]select(_y<0));
_y=((abs _y)-((abs _y)mod _stepY))/_stepY;

_xf=_x mod 10;
_xc=(_x-_xf)/10;
if(_xs<0)then{_xf=9-_xf;_xc=count(_el select 0)-1-_xc};_xc=_xc mod(count(_el select 0));_xc=_xc max 0;

_yf=_y mod 10;
_yc=(_y-_yf)/10;
if(_ys<0)then{_yf=9-_yf;_yc=count(_el select 2)-1-_yc};_yc=_yc mod(count(_el select 2));_yc=_yc max 0;

format["%1%2%3%4",_el select 0 select _xc,_el select 1 select _xf,_el select 2 select _yc,_el select 3 select _yf]
   

Offline Dr Eyeball

  • Members
  • *
Re: Map Grid Ref Coords - for all maps
« Reply #2 on: 10 Dec 2007, 00:52:35 »
Thank-you for that info and quick reply. That code looks a lot cleaner.

For the Sakakah map, I still had to adjust the _offsetY line (which may simply be a fault of the map offsetY property itself, which is set to 0):
Code: [Select]
_offsetY=-480*11+160;

Offline wolffy.au

  • Members
  • *
Re: Map Grid Ref Coords - for all maps
« Reply #3 on: 04 Oct 2008, 04:53:52 »
Does anyone have a solution for providing map coords for SaraLite?

I've looked at getRCoords, the above code, GridCord. The above code is the closest, with only the Y offset being incorrect - but everything I've tried doesn't seem to work.

Any ideas anyone?

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: Map Grid Ref Coords - for all maps
« Reply #4 on: 04 Oct 2008, 23:55:46 »
I have worked out the correct "Universal" world-coordinates to grid-coordinates system which is being used in the SPON Map GPS system (well, "Universal" isn't quite right, since it doesn't work on Avgani, but that was because that map uses a slightly different config than any other map I looked at; something I need to update). The secret is that you must know the exact height of the map in metres, which is not in config but which can be calculated using a map control in-game. Without knowing this value, you have to use a different "fudge-factor" for every map to get the correct coordinates, which is what all solutions I've seen so far use.

Unfortunately, SPON Map only calculates the width and height of the map when the SPON Map is first opened and I need to tweak the system slightly so that it does it at the start of the mission. Anyway, the script to look at is "SPON\Map\worldToGrid.sqf" which does the individual conversions and "SPON\Map\showMap.sqf" which measures the height of the current map.
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)

Offline wolffy.au

  • Members
  • *
Re: Map Grid Ref Coords - for all maps
« Reply #5 on: 05 Oct 2008, 01:35:01 »
Thanks for your reply SPON.

I setup a blank mission on Rahamdi to test, but couldn't get it to work. Here are my configs, maybe you can see what I've done wrong.

I've downloaded both SPON Core and Map, and extracted to the SPON/Core and SPON/Map directories respectively.

My stringtable.csv looks like this:

Code: [Select]
LANGUAGE, "English"

#include "SPON\Core\stringtable.csv"
#include "SPON\Map\stringtable.csv"

My extension.ext:
Code: [Select]
#include "SPON\Core\ui\core.hpp"
#include "SPON\Map\ui\map.hpp"

My Init.sqf:
Code: [Select]
[[west], false, true, 6400, 4] call compile preprocessFileLineNumbers "SPON\Map\initMap.sqf";
worldToGrid = compile preprocessFile "SPON\Map\worldToGrid.sqf";

And then, I've got one player on the map, with the following in their Init field:
Code: [Select]
hint format["%1", [position this] call worldToGrid];
Can you see where the problem is? I have the feeling its something really simple... :)

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: Map Grid Ref Coords - for all maps
« Reply #6 on: 05 Oct 2008, 02:29:03 »
Sorry, "extension.ext" should be "description.ext" - I can't write documentation without a safety net ;P

As I said, you can't really just use the function as it is now (it is automatically compiled to SPON_Map_worldToGrid) in your mission outside SPON Map, since it won't work until after the player has actually looked at the SPON Map (well, I suppose you could show the map for a fraction of a second using a script, until it did the measurement, if you really wanted to)! SPON Map doesn't use the function except to show the current GPS position inside SPON Map, so doesn't need the function to work before the dialog is opened...

To test it though, just run the demo mission, sit in a vehicle that gives you GPS and look at the SPON Map ("view map" action). Alternatively, just install the addon version and it will work in any mission. I'm sure I've tested it on Sahrani Life though and found it correct.
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)

Offline wolffy.au

  • Members
  • *
Re: Map Grid Ref Coords - for all maps
« Reply #7 on: 05 Oct 2008, 05:30:59 »
Ok, so I've attempted to take apart your scripts SPON and make a single worldToGrid function. Here's the code so far, but it only works if I have the map open at the time, so it can zoom out all the way. Is there anyway around this?

Code: [Select]
// -----------------------------------------------------------------------------
//
// Copyright (C) 2008 Bil Bas (bil dot bagpuss {at} gmail dot com \ Spooner)
// License: GNU General Public License, version 3 <http://www.gnu.org/licenses/>
//
// Description:
//   Gives grid coordinates from world (map) position.
//
// Parameters:
//   0: _position - 2 element array containing X and Y position [Array [X, Y]].
//
// -----------------------------------------------------------------------------
private ["_validNumDigits", "_xWorld", "_yWorld", "_grid", "_upperA",
"_lowerA", "_formatX", "_firstX", "_secondX", "_numberFormat",
"_stepX1", "_stepX2", "_stepY1", "_stepY2", "_coord", "_accuracyTo",
"_offsetX", "_offsetY"];

_position = _this select 0;
_numDigitsAccuracy = 4;

UPPER_A = 65;
LOWER_A = 97;

// -----------------------------------------------------------------------------
// Mod that gives inverted mod for negative numbers.
SPON_Map_mod =
{
_value = _this select 0;
_mod = _this select 1;

if (_value >= 0) then
{
_value mod _mod; // Return.
}
else
{
_mod + (_value mod _mod); // Return.
};
};

SPON_Map_display = findDisplay 12;
SPON_Map_mapControl = SPON_Map_display displayCtrl 51;

// Temporarily zoom out as much as possible and measure the screen.
SPON_Map_mapControl ctrlMapAnimAdd [0, 1000, [9999999999, 9999999999]];
ctrlMapAnimCommit SPON_Map_mapControl;
waitUntil { ctrlMapAnimDone SPON_Map_mapControl; };
 
_centre = SPON_Map_mapControl ctrlMapScreenToWorld [0.5, 0.5];
SPON_Map_mapHeight = _centre select 1;

// Look at the map to see how it is configured.
_grid = configFile >> "CfgWorlds" >> worldName >> "Grid";

_offsetX = getNumber (_grid >> "offsetX");
_offsetY = getNumber (_grid >> "offsetY");

_xWorld = (_position select 0) - _offsetX;
_yWorld = (SPON_Map_mapHeight - (_position select 1)) - _offsetY;

_formatX = toArray (getText (_grid >> "Zoom1" >> "formatX"));

_stepX1 = getNumber (_grid >> "Zoom1" >> "stepX");
_stepX2 = getNumber (_grid >> "Zoom2" >> "stepX");
_stepY1 = getNumber (_grid >> "Zoom1" >> "stepY");
_stepY2 = getNumber (_grid >> "Zoom2" >> "stepY");

_firstX = switch (toString [_formatX select 0]) do
{
case "A": { toString [UPPER_A + ([(floor (_xWorld / _stepX2)), 26] call SPON_Map_mod)] };
case "a": { toString [LOWER_A + ([(floor (_xWorld / _stepX2)), 26] call SPON_Map_mod)] };
case "0": { [(floor (_xWorld / _stepX2)), 10] call SPON_Map_mod };
};

_secondX = switch (toString [_formatX select 1]) do
{
case "A": { toString [UPPER_A + ([(floor (_xWorld / _stepX1)), 10] call SPON_Map_mod)] };
case "a": { toString [LOWER_A + ([(floor (_xWorld / _stepX1)), 10] call SPON_Map_mod)] };
case "0": { [(floor (_xWorld / _stepX1)), 10] call SPON_Map_mod };
};

_numberFormat = switch (_numDigitsAccuracy) do
{
case 2: { "%1%5" };
case 4: { "%1%2%5%6" };
case 6: { "%1%2%3%5%6%7" };
case 8: { "%1%2%3%4%5%6%7%8" };
};

_coord = format [_numberFormat,
_firstX,
_secondX,
[floor (_xWorld / (_stepX1 / 10)), 10] call SPON_Map_mod,
[floor (_xWorld / (_stepX1 / 100)), 10] call SPON_Map_mod,

[floor (_yWorld / _stepY2), 10] call SPON_Map_mod,
[floor (_yWorld / _stepY1), 10] call SPON_Map_mod,
[floor (_yWorld / (_stepY1 / 10)), 10] call SPON_Map_mod,
[floor (_yWorld / (_stepY1 / 100)), 10] call SPON_Map_mod
];

hint format["%1", _coord];
_coord; // Return.
« Last Edit: 06 Oct 2008, 02:32:44 by Spooner »

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: Map Grid Ref Coords - for all maps
« Reply #8 on: 05 Oct 2008, 22:26:34 »
You only need to calculate SPON_Map_mapHeight once, which SPON Map does for you anyway when it is first opened. You don't need to calculate it every time you use the function.

Code: (execVM this from init.sqf, to set up the value for map-height as soon as map is shown; only need to measure it once) [Select]
waitUntil { not (isNull (findDisplay 12)) };

_display = findDisplay 12;
_mapControl = _display displayCtrl 51;

// Temporarily zoom out as much as possible and measure the screen.
_mapControl ctrlMapAnimAdd [0, 1000, [9999999999, 9999999999]];
ctrlMapAnimCommit _mapControl;
waitUntil { ctrlMapAnimDone _mapControl; };
 
 _centre = _mapControl ctrlMapScreenToWorld [0.5, 0.5];
TAG_mapHeight = _centre select 1;
Not sure whether you can't just use the briefing map for the measuring (but be sure to move it back to the player's position after moving it to do the measurement). Not thought of that before...

Also, if you are fiddling with my stuff you need to remove my tags, otherwise it won't be compatible with the regular SPON Map. You also don't need to create the SPON Map specific globals that I use; if you alter the values of SPON_Map_display and SPON_Map_mapControl as you have done, then your script will break SPON Map.

Also, please use #defines, as I do, to avoid creating more globals without tags:
Code: [Select]
#define UPPER_A 65
#define LOWER_A 97
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)

Offline Dr Eyeball

  • Members
  • *
Re: Map Grid Ref Coords - for all maps
« Reply #9 on: 01 Nov 2008, 13:13:16 »
One of the ommissions most seem to be making is that some islands use classes: Zoom0 & Zoom1, but others use Zoom1 & Zoom2.

Also, I'm not sure why most island makers are not setting the correct values for offsetX & offsetY.

I thought I would provide this updated pos2grid.cpp COC CEX script which I use and works on all the islands named in the script itself. It may benefit some or help with your analysis.

I've just added the 'Zoom0' check & all the world specific offsets (switch) recently.
Since adding the 'Zoom0' check recently, some of the worldName checks may not be required anymore, but I haven't checked nor removed them yet (if any).

pos2grid.cpp
Code: [Select]
private ["_x","_y","_cfg","_offsetX","_offsetY","_stepX","_stepY","_el","_smallZoom"];
_cfg    =configFile>>"CfgWorlds">>worldName>>"Grid";

_offsetX=getNumber(_cfg>>"offsetX");
_offsetY=getNumber(_cfg>>"offsetY");

_smallZoom = "Zoom1"; // Zoom1/Zoom2 is default used by BIS/ArmA/Sara - _smallZoom can be Zoom0/Zoom1/Zoom2
if (isClass (_cfg>>"Zoom0")) then {_smallZoom = "Zoom0"}; // if Zoom0 exists, assume it uses Zoom0/Zoom1

_stepX=getNumber(_cfg>> _smallZoom >>"stepX");
_stepY=getNumber(_cfg>> _smallZoom >>"stepY");

switch toLower(worldName) do
{
  case 'sara': { _offsetY=-480*-1; }; // uses Zoom1 & Zoom2
  case 'saralite': { _offsetY=-480*5+120; }; // uses Zoom1 & Zoom2
  case 'sakakah': { _offsetY=-480*11+160; }; // uses Zoom1 & Zoom2
  case 'vte_australianao': { _offsetY=-480*30; };
  case 'map_ssara': { _offsetY=-480*5+120; }; // uses Zoom1 & Zoom2, offsetX = -4880; offsetY = -7480;
  case 'intro': { _offsetY=-480*-1; };
  case 'porto': { _offsetY=480*10+320; }; // uses Zoom1 & Zoom2
  case 'syr_darain': { _offsetY=480*10+320; };
  case 'tolafarush': { _offsetY=480*11+320; };
  case 'schmalfelden': { _offsetY=480*10+320; _stepX=100; _stepY=100; }; // uses Zoom0 & Zoom1
  case 'avgani': { _offsetY=480*10+320; _stepX=100; _stepY=100; }; // uses Zoom0 & Zoom1
  case 'map_3demap': { _offsetY=-480*15+0; };
  case 'watkins': { _offsetY=-480*11+160; }; // uses Zoom0 & Zoom1
  case 'uhao': { _offsetY=480*11+320; }; // uses Zoom1 & Zoom2, offsetY = -15360;
};

_x=(_this select 0 select 0)-_offsetX;
_y=(_this select 0 select 1)-_offsetY;


_el=
[
    ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
    ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"],
    ["0","1","2","3","4","5","6","7","8","9"],
    ["0","1","2","3","4","5","6","7","8","9"]
];

_xs=([1,-1]select(_x<0));
_x =((abs _x)-((abs _x)mod _stepX))/_stepX;

_y=100*_stepY-_y;
_ys=([1,-1]select(_y<0));
_y=((abs _y)-((abs _y)mod _stepY))/_stepY;

_xf=_x mod 10;
_xc=(_x-_xf)/10;
if(_xs<0)then{_xf=9-_xf;_xc=count(_el select 0)-1-_xc};_xc=_xc mod(count(_el select 0));_xc=_xc max 0;

_yf=_y mod 10;
_yc=(_y-_yf)/10;
if(_ys<0)then{_yf=9-_yf;_yc=count(_el select 2)-1-_yc};_yc=_yc mod(count(_el select 2));_yc=_yc max 0;

format["%1%2%3%4",_el select 0 select _xc,_el select 1 select _xf,_el select 2 select _yc,_el select 3 select _yf]

Offline Spooner

  • Members
  • *
  • Mostly useless
    • Community Base Addons
Re: Map Grid Ref Coords - for all maps
« Reply #10 on: 01 Nov 2008, 13:42:01 »
Ah, I'd seen that Avgani used zoom0 and zoom1 and was literally just in the process of fixing my algorithm in SPON Map ;P Didn't realise that a couple of other maps used them too.

You need to take into account that some maps use 6-digit coordinates rather than the more normal 4-digit (and that some addons reconfigure the 4-digit maps to 6-digit too).
[Arma 2] CBA: Community Base Addons
[Arma 1] SPON Core (including links to my other scripts)