How to accurately make a map for a map-overlay

2019-04-15 03:35发布

问题:

I have images covering the whole of South Africa. These are in Tiff format and have coordinates embedded into them. I am trying to take these images (about 20 images) and use them as an map overlay in my iPhone app. My problem lies with cutting the maps up into tiles (accurately).

MapTiler is the application which I plan on using to cut these massive images up into the tiles, but it askes me for several details. I have to choose from:

  • Custom definition of the system (WKT, Proj. 4, ...)
  • WGS84 - Latitude and longitude (geodetic)
  • Universal Transverse Mercator - UTM (projected)
  • Specify the id-number from the EPSG/ESRI database
  • Search the coordinate system by name

I have no clue as to what each one is/does.

My tiff files also has a .tfw file with them (same name, different extension) - which I have no idea what this is. (I did not create the images, but believe they might be accurate since its from the Government's Geo-Department)

I simply ran this map through MapTiler on all default settings to see that it was not near-perfectly aligned over the normal Google Maps' map. With this said, I believe I have to manually realign these images on e.g. Google Earth before I send it through MapTiler to cut up and process.

My questions:

  • Does MapTiler pick up the .tfw automatically? - since these might hold the correct coords.
  • How can I easily (e.g. via picking points on the image and then on the true map) realign/place these images?

Hope someone has some tips on this!

Any unclarity, please comment/ask!

Thanks for your time.

[EDIT]

I opened the .tfw file with NotePad and this was all that is in there:

      0.0004024840
     -0.0000001596
     -0.0000002286
     -0.0003809100
     17.0984027750
    -32.6997115702

回答1:

If MapTiler isn't doing what you need you should consider resorting to the utility behind the GUI. GDAL (http://www.gdal.org/gdal_utilities.html) will do almost everything you need to prep your geotifs for iOS, it's what I'm using to do exactly that. Instructions from here on assume you've got GDAL installed.

First off you need to be sure the coordinates really are embedded in the tif.

gdalinfo your.tif

Read through that output and if it doesn't mention which projection and coordinates it is using, then you need to keep that world file with the tif for now.

Depending on the size of your source files you may want to merge them before tiling. This will result in slightly better edges where a single tile contains data from two adjacent geotifs. If the 20 geotifs make a perfect rectangle and it fits within the maximum tif dimensions use the following:

gdalwarp -co COMPRESS=LZW originals/*.tif  output.tif -srcnodata 0 -dstnodata 0 -multi

The bits on the end are to make any unused pixels transparent and to use multiple processors if you have them. If the command above complains about transparency or alpha channels you'll need to convert your tifs to rgba using this:

gdal_translate -co COMPRESS=LZW old.tif new.tif -expand rgba

Now to actually tiling:

gdal2tiles.py --zoom 6-16 your.tif outputfolder

This will make tiles of your.tif at the specified zoom levels and save them in outputfolder. It'll also create .kml files and the transparent tiles around the edges where the tif was rotated to find the tileset's projection. These three lines will sort that out. the 334c is the size of a transparent 256x256 .png on my drive in bytes. It'll be different on yours so find one such file and adjust the value. Also be very careful with paths here, automating any deletion can go wrong so double check everything. First you remove the .kml files, then remove any 100% transparent .pngs, then you remove any directories that are now empty:

rm -r */*/*.kml
find ./ -type f -size 334c -exec rm -f {} \;
find ./ -depth -empty -type d -exec 

But you're not finished. Like I mentioned earlier, some tiles will cover an area that contains data from two tifs. If you've tiled them up separately and each tileset will contain the same tile, half of it with data, half of it transparent. If you just merge those folders the tile from the first tif will overwrite the tile from the second tif and it'll still be half/half. So you need to merge the individual tiles. Luckily for you I've hacked together a Perl script to do just that. Please don't judge me on my Perl abilities. I've never read up on it, I just found a script nearby and hacked it.

#! /usr/bin/perl

use File::Slurp;
use File::Copy;

$baseDir = "/Volumes/Elemental/geotifs/destination";
$incomingDir = "/Volumes/Elemental/geotifs/sourcetiles";


my @files = read_dir($incomingDir);
foreach my $zoomlevel(@files) { 

    if(-d "$incomingDir/$zoomlevel") {
        #mkdir "$imgdir/$nextZoom/";

            unless(-e "$baseDir/$zoomlevel")
            {
                mkdir "$baseDir/$zoomlevel";
            }

            my @subdirs = read_dir("$incomingDir/$zoomlevel");

            foreach my $x(@subdirs) {
                    #print "subdir called $imgdir/$zoomlevel/$x\n";

                    if(-d "$incomingDir/$zoomlevel/$x") {
                        unless(-e "$baseDir/$zoomlevel/$x")
                        {
                            mkdir "$baseDir/$zoomlevel/$x";
                        }

                         my @mapfiles = read_dir("$incomingDir/$zoomlevel/$x");
                         foreach my $y(@mapfiles) {

                            if (-e "$baseDir/$zoomlevel/$x/$y")
                            {
                                print "Have to merge /$zoomlevel/$x/$y \n";
                                qx(convert $baseDir/$zoomlevel/$x/$y $incomingDir/$zoomlevel/$x/$y -composite $baseDir/$zoomlevel/$x/$y);
                            } else {
                                copy("$incomingDir/$zoomlevel/$x/$y","$baseDir/$zoomlevel/$x/$y");
                            }

                         }
                    }
            }
    }

}

Save that as a .pl file, modify the base and incoming directories and run it to copy all the tiles from incomingDir into baseDir. I've used 'convert' here from ImageMagick, so if you don't have that library installed you'll need to replace that line. I suspect there is something in Apple's image library that you could use but I use IM for other stuff so I didn't look further.

Merge all your tilesets and you've done what you set out to do, but there is one more step I'd recommend. The PNGs that GDAL produces are of average size I'd guess. But you'll have many thousands of them and iPhones have limited disk space. So get hold of pngnq and compress all the PNGs. I didn't notice any loss in quality on mine, my don't throw away your original until you've check the output.

pngnq -n 256 */*/*.png

I've been dealing with file sets that contain too many pngs so I had to break up the command to do each zoom layer separately, it'd be pretty easy to make a short script to ensure every file was covered. Now you'll have a duplicate of every png like so: original.png -> original-nq8.png. Here's a shell script I wrote to cycle through them and copy the nq8 version over the original

for OriginalFile
do

Location=`dirname "$OriginalFile"`
FileName="$OriginalFile"

newName=`echo $FileName | sed 's/-nq8//g'`

if [ $newName != "$FileName" ]
then
  mv "$FileName" "$newName"
fi

done

Save that as .sh and run it from the command line like so:

./removeNq8.sh */*/*nq8.png

Again you'll probably have to break it up for the larger zoom levels because you'll have so many pngs to deal with.

Will all the done I usually reduce the total file size by will over 30% and I can drop the folder straight into the TileMap example by Apple and it works. Please let me know if this helps. I've been meaning to write up a full tutorial and I'd like to know if this as clear enough and any steps I missed.

P.S. I've assumed the geotifs you're starting with have no map collar around them, if they do you can check out my little article on removing them: http://craig.stanton.net.nz/2011/06/07/merging-geotiffs/



回答2:

I'm not familiar with tfw files, nor am I familiar with MapTiler, but I can take some guesses and add some background for the coordinate systems, as I worked for Lockheed Martin as a rocket scientist (really) in a previous life...

First of all, TL;DR, I'm going to guess that UTM is your system of choice.

The custom definition probably will require you to write some nastiness to make the system understand your custom format. The id-number and coordinate number specification by name are probably for more interoperability. The systems I'm aware of are:

  • WGS84 is a model of the Earth as an oblate (squashed) sphereoid that was standardized in 1984; it allows one to specify a location in lat,lon,alt against this idealized model of the Earth. In other words, it's an equation of what the globe would look like if everything was smooth and at "sea level".

  • UTM is a model of the earth flattened like one would see in a map. It allows one to specify a location as northing,easting from the equator and prime meridian. These values are in meters and are the last two numbers in your .tfw file

For more information about what's in the .tfw file, I found this link. If I read it correctly, it seems that it is just a text file with some metadata - and the last two numbers of your .tfw file should indicate where the top-left pixel of your image should go.

And this description in Wikipedia is a great description of how to find a location on a Mercator projected map.

Finally, a little Googling seems to indicate that Google Maps uses WGS84 as its coordinate frame. You could try to convert your location from your .tfw file to lat,lon,alt using an online tool such as this one and see if that correctly positions your images on Google Maps. If so, you've cracked your positioning problem: you can find some more automated solution to reposition all of your data.