Hi again, I've been for the whole last day trying to change SVN QLGT into
supporting what GMapTool calls "pseudo-NT" Garmin maps. They don't call
them "NT maps" because it seems they don't implement the newer compression
algorithm recent Garmin units and Garmin software has, but what GMapTool
does currently is using the GMP subfile structure. To make a long story
short, I failed. Miserably. But, hopefully, I can easy things somewhat for
the people that really understand the code and how to implement this.

A NT Garmin Map as created by GMapTool is identical to a traditional Garmin
maps: it has its FAT, that describe the contained subfiles. But, instead of
having one subfile for each mandatory Garmin map subfile (TRE, RGN), and the
non-mandatoy ones), it can have (but doesn't have to) just one GMP subfile, 
which in turn contains the offsets to rest of the subfiles' headers, each 
header starting at an offset from the beginning of the GMP sufile, as 
described on the following link:
http://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/GMP_Subfile_Format

As I understand the code, current QLGT iterates over the Garmin IMG FAT and
populates a list of subfiles, without making any distinction about the type
of the subfile (except for "MAPSOURC" and "SENDMAP2" types). See source file
CGarminTile.cpp, lines 196-233. As QLGT doesn't implement support for the
GMP subfile (NT type maps) yet, it doesn't go deeper into the subfile, and
and treats the GMP subfile as any other one.

When QLGT starts iterating over the list of subfiles found on the Garmin
IMG FAT, lines 270 to 286, when it detects a subfile of type GMP, it simply
stops processing, as it doesn't know how to go further.

Although, conceptually, to extract the standard subfiles from the GMP container 
is as easy as parsing the GMP header, looking at the different offsets, and
either populating the list of subfiles in the Garmin IMG FAT loop (check each
FAT subfile and if it is a GMP one, go deeper and create as many "fake" FAT
entries in the list as standard subfiles are found inside the GMP), or wait
until the subfile iteration, and when a subfile of type GMP is found,
process it instead of aborting. Offsets in the GMP header to other subfile
headers are equal to zero if the subfiles doesn't exist.

In the URL above there is an explanation of the GMP header, which has a
first part common to other IMG subfiles (see hdr_subfile_part_t at
CGarminTile.h), and a second one with just offsets to standard Gamin IMG
subfile headers, offsets relative to the start of the GMP header. The struct 
for the specific GMP header could look something like this:

  // GMP part header, to 0x34
  struct hdr_gmp_t : public hdr_subfile_part_t
  {
      quint32 offset;      ///< 0x00000015 .. 0x00000018 (always 0x0000)
      quint32 tre_hdr_offset;      ///< 0x00000019 .. 0x0000001C
      quint32 rgn_hdr_offset;      ///< 0x0000001D .. 0x00000020
      quint32 lbl_hdr_offset;      ///< 0x00000021 .. 0x00000024
      quint32 net_hdr_offset;      ///< 0x00000025 .. 0x00000028
      quint32 nod_hdr_offset;      ///< 0x00000029 .. 0x0000002C
      quint32 dem_hdr_offset;      ///< 0x0000002D .. 0x00000030
      quint32 mar_hdr_offset;      ///< 0x00000031 .. 0x00000034
                           ///< 0x00000035 .. (one or more null-terminated 
strings up to 1st subfile)
  };


But, despite the above being quite straightforward, I have been unable to 
implement 
it. At the point the IMG FAT is processed, I seem unable to know what's the
offset to the GMP header start, and quite don't get how to create "fake"
FATblocks for the contained standard headers, as if they where real
subfiles described in the FAT, and not subfiles pointed to from the GMP
header offset list.

If I try to plug the new code to CGarminTile.cpp:274, I don't know the way 
to parse the GMP header, and populate the subfile list from inside the loop,
just before proceeding to readSubfileBasics() for every standard subfile
extracted from the GMP header.

I have checked the GMP header information in the URL above against several
real world and manually crafted IMG files, and the specification looks
correct. The GMP entry in the FAT has the correct size for the GMP subfile,
and the GMP subfile seems to start the first after the end of the FAT
(offset 0x2000, as NT maps seem to use block size ok 1KB instead of 512B).

00002000  35 00 47 41 52 4d 49 4e  20 47 4d 50 01 00 db 07  |5.GARMIN GMP....|
00002010  05 1d 11 10 00 00 00 00  00 3f 00 00 00 0d 01 00  |.........?......|
00002020  00 8a 01 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00002030  00 00 00 00 00 47 6d 61  70 54 6f 6f 6c 00 00 bc  |.....GmapTool...|
00002040  00 47 41 52 4d 49 4e 20  54 52 45 01 00 db 07 05  |.GARMIN TRE.....|
00002050  1d 11 10 00 83 09 1d 5d  42 fd 2b eb 1c ab 05 fd  |.......]B.+.....|
00002060  50 d2 00 00 1c 00 00 00  54 02 00 00 fc cf 00 00  |P.......T.......|
00002070  4e 02 00 00 06 00 00 00  03 00 00 00 00 00 0d 19  |N...............|
00002080  00 00 01 03 11 00 01 00  00 6c d2 00 00 28 00 00  |.........l...(..|
00002090  00 02 00 00 00 00 00 94  d2 00 00 2a 00 00 00 02  |...........*....|
000020a0  00 00 00 00 00 be d2 00  00 39 00 00 00 03 00 00  |.........9......|
000020b0  00 00 00 0c c3 fe 02 00  00 00 00 a5 d3 00 00 19  |................|
000020c0  ac 00 00 0d 00 07 06 00  00 f7 d2 00 00 ae 00 00  |................|
000020d0  00 03 00 18 00 18 00 0a  00 ba eb 58 4c a7 ed 08  |...........XL...|
000020e0  89 b9 eb 5c 89 b9 eb 5c  89 00 00 00 00 be 7f 01  |...\...\........|
000020f0  00 00 00 00 00 00 00 00  00 00 00 00 01 00 03 4d  |...............M|
00002100  61 70 54 6b 20 33 2e 30  2e 31 00 00 00 7d 00 47  |apTk 3.0.1...}.G|
00002110  41 52 4d 49 4e 20 52 47  4e 01 00 db 07 05 1d 11  |ARMIN RGN.......|
00002120  10 00 be 7f 01 00 59 4d  18 00 17 cd 19 00 83 55  |......YM.......U|

Starting at the second row, second byte in the second column (3f) there is
the four-byte "Absolute offset of start of .TRE header", and as you can see
in the ASCII dump on the right, it's OK. Same for the next four bytes, the
"Absolute offset of start of .RGN header" (0d 01 00 00), etc.

Starting at 0x00002040, the standard TRE header, so (83 09 1d) should be
the "North boundary" of the map, (5d 42 fd) should be the "East boundary",
etc. That is, once we get to the start of the TRE (or RGN, or LBL, or
whatever) real header, business as usual. The only added complexity in the
presence of the GMP header is one additional level of indirection to locate
the start of the standard headers.

I'm sorry if the above has been too verbose (can't give much deeper insight
into the thing), I've tried to do it myself, but at this point I think my
investigation was worth the effort, because maybe one of you can code waht
I have been unable to implement. And, of course, willing to receive
feedback and give additional information if needed, including test files,
compiling test versions of QLGT to check changes on real world files, etc.

Hope this helps making QLGT pseudo-NT Garmin maps compatible. Can't find a
valid reason why people making Garmin maps with "free" tools from free data
have chosen to enable the "NT map" bit for no apparent good reason, but it
seems making QLGT aware of these maps is quite easy for the people more
experienced with the code.

Greetings,

-- 
Jose Luis Domingo Lopez
Linux Registered User #189436     Linux Kubuntu 11.04 (Linux 
2.6.38-8-generic-pae)

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
Qlandkartegt-users mailing list
Qlandkartegt-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/qlandkartegt-users

Reply via email to