Last active
July 9, 2018 09:17
-
-
Save martinsik/4523934 to your computer and use it in GitHub Desktop.
Source codes for tutorial on Creating .mbtiles DB for iOS MapBox from hi-res map image http://martinsikora.com/creating-mbtiles-db-for-ios-mapbox-from-hi-res-map-image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sqlite3 | |
import os | |
import glob | |
import sys | |
from pprint import pprint | |
if len(sys.argv) == 1 or sys.argv[1] in ['-h', '--help', 'help', '/?']: | |
print "Usage: python create_mbtiles.py mbtiles_output_db" | |
quit() | |
db_name = sys.argv[1] | |
# probably all mbtiles DBs use 256x256 tile size | |
tile_size = 256 | |
# remove old mbtiles db if it exists | |
if os.path.isfile(db_name): | |
os.remove(db_name) | |
conn = sqlite3.connect(db_name) | |
c = conn.cursor() | |
# create database schema | |
c.execute('CREATE TABLE metadata (name text, value text)') | |
c.execute('CREATE TABLE tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob)') | |
# indicies aren't necessary but for large databases with many zoom levels may increase performance | |
c.execute('CREATE UNIQUE INDEX tile_index ON tiles (zoom_level, tile_column, tile_row)') | |
c.execute('CREATE UNIQUE INDEX name ON metadata (name)') | |
# fill metadata table with some basic info | |
c.execute("INSERT INTO metadata VALUES ('name', 'my_mbtiles_db')") | |
c.execute("INSERT INTO metadata VALUES ('type', 'baselayer')") | |
c.execute("INSERT INTO metadata VALUES ('version', '1.0')") | |
c.execute("INSERT INTO metadata VALUES ('description', '')") | |
c.execute("INSERT INTO metadata VALUES ('format', 'jpg')") | |
# start at zoom level 0 | |
z = 0 | |
# which tile sizes we want to use | |
for size in [256, 512, 1024, 2048]: | |
tilesPerRow = size / tile_size | |
# tilesPerRow ^ 2 is number of tileXXX.jpg we will process for this zoom level | |
for i in range(0, pow(tilesPerRow, 2)): | |
y = i / tilesPerRow | |
x = i % tilesPerRow | |
image = 'tiles' + str(size) + '/tile%03d.jpg' % (y * tilesPerRow + x) | |
# load image and add it to the database | |
with open(image, 'rb') as f: | |
ablob = f.read() | |
# that "tilesPerRow - y - 1" expression is to get y position from bottom, not top | |
c.execute("INSERT INTO tiles VALUES (?, ?, ?, ?)", [ z, x, tilesPerRow - y - 1, buffer(ablob)]) | |
z += 1 | |
conn.commit() | |
conn.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import sqlite3 | |
import os | |
import json | |
# print help? | |
if len(sys.argv) == 1 or sys.argv[1] in ['-h', '--help', 'help', '/?']: | |
print "Usage: python extract.py mbtiles_file_name" | |
quit() | |
mbtiles_file = sys.argv[1] | |
# make sure file exist | |
try: | |
with open(mbtiles_file) as f: pass | |
except IOError as e: | |
print "File '%s' doesn't exists" % mbtiles_file | |
quit() | |
# open sqlite3 database | |
conn = sqlite3.connect(mbtiles_file) | |
# get tile format from metadata table | |
format_row = conn.execute('SELECT value FROM metadata WHERE name = ?', ['format']).fetchone() | |
if format_row: | |
format = format_row[0] | |
else: | |
format = 'png' # default is png | |
# get map name (root dir for extracted tiles) | |
dir_root = mbtiles_file[:mbtiles_file.rfind('.')] | |
if not os.path.exists(dir_root): | |
os.makedirs(dir_root) | |
# dump all metadata as json | |
metadata_dict = { } | |
for row in conn.execute('SELECT name, value FROM metadata'): | |
metadata_dict[row[0]] = row[1] | |
f = open(dir_root + '/metadata.json', 'w+') | |
json.dump(metadata_dict, f) | |
# fetch all tile rows | |
for row in conn.execute('SELECT zoom_level, tile_row, tile_column, tile_data FROM tiles ORDER BY zoom_level, tile_row, tile_column'): | |
# create directory if it doesn't already exist | |
dir_name = dir_root + '/' + str(row[0]) | |
if not os.path.exists(dir_name): | |
os.makedirs(dir_name) | |
# tile_name = str(row[1]) + '_' + str(row[2]) + | |
tile_name = '%d_%d.%s' % (row[1], row[2], format) | |
# dump tile data (png or jpg image) | |
f = open(dir_name + '/' + tile_name, 'w+') | |
f.write(row[3]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
SIZES=("512" "1024" "2048") | |
for i in ${!SIZES[*]} | |
do | |
SIZE=${SIZES[$i]} | |
echo $SIZE | |
# first, resize original image | |
convert -resize $SIZE"x"$SIZE! chernarus2048.jpg chernarus$SIZE"x"$SIZE.jpg | |
mkdir tiles$SIZE | |
# slice resized image into 256x256 tiles | |
convert -crop 256x256 chernarus$SIZE"x"$SIZE.jpg tiles$SIZE/tile%04d.jpg | |
rm chernarus$SIZE"x"$SIZE.jpg | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ViewController.h" | |
#import "MapBox.h" | |
@implementation ViewController | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
RMMBTilesSource *offlineSource = [[RMMBTilesSource alloc] initWithTileSetURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"chernarus" ofType:@"mbtiles"]]]; | |
RMMapView *mapView = [[RMMapView alloc] initWithFrame:self.view.bounds andTilesource:offlineSource]; | |
// default zoom | |
mapView.zoom = 2; | |
// hard code minimal zoom. Try to run in without it to see what happens. | |
mapView.minZoom = 1; | |
// hide MapBox logo | |
mapView.showLogoBug = NO; | |
// hide bottom right "i" icon | |
[mapView setHideAttribution:YES]; | |
mapView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; | |
mapView.adjustTilesForRetinaDisplay = YES; // these tiles aren't designed specifically for retina, so make them legible | |
[self.view addSubview:mapView]; | |
} | |
- (void)didReceiveMemoryWarning | |
{ | |
[super didReceiveMemoryWarning]; | |
// Dispose of any resources that can be recreated. | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment