Mobile GMaps Home Page
 FAQFAQ    SearchSearch    MemberlistMemberlist    UsergroupsUsergroups   RegisterRegister  
 ProfileProfile    Log in to check your private messagesLog in to check your private messages    Log inLog in 

Format of .mgm files with multiple tiles

 
Post new topic   Reply to topic   printer-friendly view    MGMaps Forum Index -> Stored Maps
View previous topic :: View next topic  
Author Message
Cristian Streng
Founder


Joined: 28 Oct 2005
Posts: 4585

Phone Type: (many)

PostPosted: Tue Dec 02, 2008 9:53 pm    Post subject: Format of .mgm files with multiple tiles Reply with quote

From http://forum.mgmaps.com/viewtopic.php?p=11687#11687:
ambra wrote:
Pyrpolizer asked me to explain how multiple tiles MGM's are made, so here's the answer for other users that might be interested.


The file has header, and body.
Header consists of 2+6*(number of tiles) bytes. You probably already know that number of tiles per file can be only power of 2. The body consists of image files added one after another.

In zoom level 1 the whole world consists of 4 tiles, that's 2 tiles in west-east direction (X-coordinate) and 2 tiles in north-south direction (Y-coordinate).
In zoom level 2, every tile in zoom level 1 is split to 4 tiles, so the whole world consists of 16 tiles (4×4 tiles).
If you follow the logic, you can see that in zoom level n, the whole world consists of (2^n) × (2^n) tiles, (2^n) tiles in X-direction, and (2^n) tiles in Y-direction.

You saw that MGMaps names tiles with {$x}_{$y}.mgm, where $x is X-coordinate of the tile, and $y is Y-coordinate of the tile. "0_0.mgm" is always upper left tile in every zoom level. "1_1.mgm" is lower right tile in zoom level 1. "255_255.mgm" is lower right tile in zoom level 8.

Now, if you want to make a file with many tiles, first you need to make "empty MGM file" that consists only of header - 2+6*(number of tiles) zero-bytes (0x00h). First two bytes show how many tiles are already in the the file. First two bytes are followed by (num of tiles) groups of 6 bytes, so for every possible tile there's 6 bytes in the header. First two bytes in every group tell relative coordinates in this MGM file, and next four bytes tell absolute position of next tile that would be added to MGM file.

So, here's the example.

Let's say you want to make 32-tiles per file MGM. 32=8*4, so you'll have 8 tiles in X-direction, and 4 tiles in Y-direction (if x and y are not equal, x is always larger than y, x=2*y exactly).
Let's say you have tiles in zoom level 8. You usually won't have all of them (depending on the area shape), but they will all have names if form $x_$y.mgm where 0<=$x<=255, 0<=$y<=255. That's 65536 possible tiles in zoom level 8 for the whole World. If you want 32 tiles per file MGM's you can have maximum 65536/32=2048 MGM files for the whole World.

Let's say you want to place tile "146_57.mgm" in 32 tiles per file MGM. Absoule coordinates of that tile are absX=146, absY=57. If you split absX by 8, you'll get whole part and remaining. Whole part will be used for naming MGM, and remaining is relative position of the tle in resulting MGM file. In this example 146/8 -> mgmX=18, relX=2. [WRONG: You must decrement, because tiles are numbered from zero.] You do the same for Y-coordinate: 57/4 -> mgmY=14, relY=1.

Now, make "empty MGM" that consists of 2+6*32 zero-bytes. Read first two and see how many are there already in MGM. Read first byte, multiply it by 256, and add second byte. Increment that value (because there will be one more after you're finished). Now, move to the end of file. Add whole "146_57.mgm" tile to end of the MGM file. Remember current position of the file pointer as nextTileLocation. Move to the begining of 6-byte group that repesents the tile you've just added - move to 2+6*(num. of tiles it the file before addition). Write relX, relY, and nextTileLocation. Then move to the beginning of the MGM file to write new number of tiles in the file.

The following example demonstrates 8×8 MGM.

Code:

<?php

// this function makes empty MGM file when there's no one.
// 2+6*8*8 zero-bytes
function MakeEmptyMGM($outfilename) {
  global $tpfx, $tpfy;
  $outfile=fopen($outfilename, "w");
  fwrite($outfile, str_repeat("\0", 2+6*$tpfx*$tpfy));
  fclose($outfile);
}

$tpfx=8;
$tpfy=8;

$filename=$argv[1];

$us=strpos($filename, "_");
$dt=strpos($filename, ".");

// here we get absolute coordinates of the tile out of tile name
$srcx=substr($filename, $us+1, $dt-$us-1);
$srcy=substr($filename, 0, $us);

// these variables represent coordinates of 64-tile MGM file
$dstx=floor($srcx/$tpfx);
$dsty=floor($srcy/$tpfy);

// here are relative coordinates of a tile within MGM file
$relx=$srcx-$dstx*$tpfx;
$rely=$srcy-$dsty*$tpfy;

// this is name of 64-tile MGM file
$outfilename="../mgm/{$dstx}_{$dsty}.mgm";
$srcfilesize=filesize($filename);

// if there's no such file, make it
if (! file_exists($outfilename) ) {
  MakeEmptyMGM($outfilename);
}

// if there is such file, but it's empty, make it with header
if (filesize($outfilename)==0) {
  MakeEmptyMGM($outfilename);
}

// open file for rw operations
$outfile=fopen($outfilename, "r+");

// move to the beginning
fseek($outfile, 0, SEEK_SET);

// get number of tiles already in the file
$tilesinfile=ord(fgetc($outfile))<<8;
$tilesinfile+=ord(fgetc($outfile));

//default file pointer position when MGM is "empty"
$outpos=2+6*$tpfx*$tpfy;

// when there are tiles in MGM find the position in the MGM where next tile
// tile should be placed (could be simpler...)
for ($i=0; $i<$tilesinfile; $i++) {
  $tmp=0;
  fseek($outfile, 2, SEEK_CUR);
  $tmp+=ord(fgetc($outfile))<<24;
  $tmp+=ord(fgetc($outfile))<<16;
  $tmp+=ord(fgetc($outfile))<<8;
  $tmp+=ord(fgetc($outfile));
  $outpos=$tmp;
}

// move to that positiom
fseek($outfile, $outpos, SEEK_SET);

// write the tile
fwrite($outfile, file_get_contents($filename), $srcfilesize);
// you my delete the tile
//unlink($filename);

// get the position where next tile should be placed
$nextoffset=ftell($outfile);

// move to the beginning the MGM
fseek($outfile, 0, SEEK_SET);

// increment number of tiles and write the value
$tilesinfile++;
fwrite($outfile, chr(($tilesinfile>>8) & 0xFF), 1);
fwrite($outfile, chr($tilesinfile & 0xFF), 1);

// move to 6-byte group in the header, repesenting just added tile
fseek($outfile, 2+6*($tilesinfile-1), SEEK_SET);

// write relative coordinates for the tile
fwrite($outfile, chr($relx), 1);
fwrite($outfile, chr($rely), 1);

// write offset for the next tile to be added
fwrite($outfile, chr(($nextoffset>>24) & 0xFF), 1);
fwrite($outfile, chr(($nextoffset>>16) & 0xFF), 1);
fwrite($outfile, chr(($nextoffset>>8) & 0xFF), 1);
fwrite($outfile, chr($nextoffset & 0xFF), 1);

?>
Back to top
View user's profile Send private message Visit poster's website
franc
Power User


Joined: 25 Oct 2009
Posts: 64

Phone Type: Unknown

PostPosted: Mon May 30, 2011 10:50 pm    Post subject: Reply with quote

Is there a way to merge two folders with each mgm-files with 1024 tiles per file?

I have downloaded two different MGMapsCache Folder for the same map-type (OpenCycleMaps) but for a different region.

Is it possible now to merge them in one MGMapsCache-Folder?
If not I have to rename manually when I need the one or the other region-maps, which is unhandy.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic   printer-friendly view    MGMaps Forum Index -> Stored Maps All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum
MGMaps topic RSS feed 


Powered by phpBB © 2001, 2005 phpBB Group