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)
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