Standalone APRS mobile system using a Maxtrac mobile radio

DaveInDenver

Middle Income Semi-Redneck
Yeah, so what I ended up doing is writing a little script to pull tiles at various levels from opencyclemap.org - I like these way better than the regular openstreetmap.org ones -
and place them in the OSM cache folder. Works well and the PNG files are only 25kb each so the 35,000 or so I pulled is well less than 1GB.
Where you able to get the "API Key Required" message to go away when using the open cycle maps? I have a Thunderforest key but can't figure out the right way to get it to append to the server request. I either get regular mapnik tiles with no watermark or cycle tiles with the watermark.
 
Last edited:

camp4x4

Adventurer
Where you able to get the "API Key Required" message to go away when using the open cycle maps? I have a Thunderforest key but can't figure out the right way to get it to append to the server request. I either get regular mapnik tiles with no watermark or cycle tiles with the watermark.

Yes, but my way is a little hacky. They haven't written in a way to use API keys for the MANY services that structure their URLs the same way. Why... I guess other priorities, but this seems like it would dramatically improve their mapping since there's a number of services that that use this standardized format...

Anyway, here's how I did it:

Xastir caches the OSM tile files it pulls from the service. If the files are already in the cache then it doesn't re-download them, or if you're offline it'll just display the cached files. Xastir's OSM map tiles get cached in /home/pi/.xastir/OSMtiles/cycle/ in the same folder structure as the URL for the Thunderforest map tiles:

https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=<insert-your-apikey-here>

Where {z} is zoom level, {x} is the horizontal map tile number and {y} is the vertical.

So you'll see something like this in the folder tree:

  • cycle
    • 10
      • 170
        • 394.png
        • 395.png
        • 396.png
      • 171
      • 172

Since the closer zoom levels will end up with tens of thousands of tiles for even a moderate area there's no way you can just manually do a few and be good. So, I wrote a little Python script that simply loops through the zoom levels, x coordinate pairs and y coordinate pairs of the area I want. I got the zoom, x and y sets by simply going on the opencyclemaps, zooming out to the minimum zoom level (in my case 10) then right-clicking on the map in the upper left and lower right corners of the area I wanted and doing Copy Image Address to get something like:

https://b.tile.thunderforest.com/cycle/10/169/395.png?apikey=a5dd6a2f1c934394bce6b0fb077203eb
https://c.tile.thunderforest.com/cycle/10/176/400.png?apikey=a5dd6a2f1c934394bce6b0fb077203eb

(that api key seems to be the default one, which is kind of interesting... odd that they don't obscure any of this info... but be nice and enter your own)

One thing about Web Mercator coordinates (the x, y that this system uses) is that the Y axis is actually upside down: 0,0 is the upper left part of the map and 256, 256 is the lower right. So we have the corners 169, 395 and 176, 400. From there we can fill out the other two corners - 169, 400 upper right and 176, 395 lower left - to get an area a box like this:

169,395---------------------176,395





169,400----------------------176,400

The script is pretty simple. Like I said, it loops through the zoom range you give it, pulling all the tiles within the box.

Code:
#! /usr/local/bin/python3

import urllib.request
import os
import shutil

# Enter your min and max zoom levels here:
zmin=10
zmax=15

# Enter your 2 x coordinates here:
x1=170
x2=175

# Enter your 2 y coordinates here:
y1=399
y2=404

# Enter the full path of the folder you want to save to here:
save_to_base_path = "/Volumes/UNTITLED/OSM/"

# Enter your API Key here:
api_key = "a5dd6a2f1c934394bce6b0fb077203eb"

for z in range(zmin,zmax+1):

	for x in range(x1,x2+1):

		for y in range(y1,y2+1):

			file_path = save_to_base_path + str(z) + "/" + str(x) + "/"
			file_name = save_to_base_path + str(z) + "/" + str(x) + "/" + str(y) + ".png"
			if not os.path.exists(file_path):
				os.makedirs(file_path)
			url = "http://tile.thunderforest.com/cycle/" + str(z) + "/" + str(x) + "/" + str(y) + ".png?apikey=" + api_key
			if not os.path.isfile(file_name):
				print(url + " , " + file_name)
				with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
					shutil.copyfileobj(response, out_file)
			else:
				print (file_name + " already exists, skipping.")

	x1 = x1*2
	x2 = x2*2
	y1 = y1*2
	y2 = y2*2

The interesting thing I found about the coordinates, is they double each time you zoom in. Makes it easy for looping. That's why you see the *2 for each coordinate at the end of the z loop.

I had the script save onto a thumb drive on my laptop, then copied over to my RPi, but you could just as easily change the save_to_base_path to be /home/pi/.xastir/OSMtiles/cycle/ and run this directly on the RPi. To run on RPi you'll also need to change the first line to wherever your version of python3 is. For RPi Jessie mine shows as: /usr/bin/python3

I will say that this script took a good 8 hrs to pull a moderate area at 10-15 zoom. Not because of the file size per se, but the file count... each file is only 25kb, but at 15 there's 10's of thousands of them.

Here's the script itself, just change the variables' values and chmod +x to make it executable. Oh, and it uses Python 3, so make sure that's installed.
https://www.dropbox.com/s/s4z9b02pwsunbgn/pullCycleTiles.py?dl=0


I wrote this in about 15 minutes in bed the other night, so looking at it now I may make some improvements to it... could probably set it up as using the URL's directly instead of having to have the numbers in the script. Could also have it prompt for inputs on the save path, zoom levels and URLs... I'll keep working on it. I also want to make it deal with non-square areas, but that's another project for another day.
 
Last edited:

DaveInDenver

Middle Income Semi-Redneck
Cool! LOL, I did write a Perl (yes, I'm ancient) script that cURLs the files to my cache but was wondering if you'd actually modified the code so Xastir could grab new ones on its own. It appears that maps.c is where the logic resides to parse the geo files. Also I'm just using the free account so I'm limited to 150,000 tiles per month, so I've been careful about testing it.
 
Last edited:

camp4x4

Adventurer
Cool! LOL, I did write a Perl (yes, I'm ancient) script that cURLs the files to my cache but was wondering if you'd actually modified the code so Xastir could grab new ones on its own. It appears that maps.c is where the logic resides to parse the geo files. Also I'm just using the free account so I'm limited to 150,000 tiles per month, so I've been careful about testing it.

I'm trying to find where I saw the main developer talking about what it would take. He mentioned 2 places that would need to be modified, and that the geo files would have to be modified with the specific api key... can't seem to find it now...

Bingo! It was talking about Mapbox maps instead of OSM, but same principle: http://xastir.xastir.narkive.com/QUHar6KX/using-mapbox-maps-on-xastir#post13
 
Last edited:

Forum statistics

Threads
185,424
Messages
2,874,295
Members
224,720
Latest member
Bad Taste
Top