Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
Basic offline support
Browse files Browse the repository at this point in the history
  • Loading branch information
incanus authored and jfirebaugh committed Dec 21, 2015
1 parent 913f49c commit 8f3d5fa
Show file tree
Hide file tree
Showing 13 changed files with 362 additions and 11 deletions.
59 changes: 59 additions & 0 deletions carryover.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python

import sqlite3
import sys
import zlib

in_db = sqlite3.connect('cache.db')

with in_db:
in_db.row_factory = sqlite3.Row
in_cur = in_db.cursor()
in_cur.execute('select url, data, kind, compressed from http_cache where status = 1 order by kind asc')
in_rows = in_cur.fetchall()
out_db = sqlite3.connect('cache.mbtiles')
with out_db:
out_cur = out_db.cursor()
out_cur.executescript("""
drop table if exists tiles;
create table tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob);
create unique index tile_index on tiles (zoom_level, tile_column, tile_row);
drop table if exists metadata;
create table metadata (name text,value text);
create unique index name on metadata (name);
""")
for in_row in in_rows:
kind = in_row['kind']
data = in_row['data']
if in_row['compressed'] == 1:
data = zlib.decompress(data)
if kind == 3:
parts = in_row['url'].split('/')
z = int(parts[4])
x = int(parts[5])
y = int(parts[6].split('.')[0])
y = pow(2, z) - y - 1
out_cur.execute('insert into tiles (zoom_level, tile_column, tile_row, tile_data) ' \
'values (?, ?, ?, ?)', (z, x, y, sqlite3.Binary(data)))
print 'inserted tile %s,%s,%s (%s bytes)' % (z, x, y, len(data))
elif kind in (2, 4, 5):
if kind == 2:
prefix = 'gl_source'
elif kind == 4:
prefix = 'gl_glyph'
else:
prefix = 'gl_sprite_image'
out_cur.execute('insert into metadata (name, value) values (?, ?)',
(prefix + '_' + in_row['url'], sqlite3.Binary(data)))
label = prefix.replace('gl_', '').replace('_', ' ')
print 'inserted %s (%s bytes)' % (label, len(data))
elif kind in (1, 6):
if kind == 1:
prefix = 'gl_style'
else:
prefix = 'gl_sprite_metadata'
out_cur.execute('insert into metadata (name, value) values (?, ?)',
(prefix + '_' + in_row['url'], data))
label = prefix.replace('gl_', '').replace('_', ' ')
print 'inserted %s (%s bytes)' % (label, len(data))
out_db.commit()
2 changes: 2 additions & 0 deletions include/mbgl/ios/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ IB_DESIGNABLE
* @return An initialized map view. */
- (instancetype)initWithFrame:(CGRect)frame styleURL:(nullable NSURL *)styleURL;

- (instancetype)initWithFrame:(CGRect)frame styleURL:(nullable NSURL *)styleURL offlineMapPath:(NSString *)offlineMapPath;

#pragma mark - Accessing Map Properties

/** @name Accessing Map Properties */
Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/storage/default_file_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class FileCache;

class DefaultFileSource : public FileSource {
public:
DefaultFileSource(FileCache*, const std::string& root = "");
DefaultFileSource(FileCache*, const std::string& root = "", const std::string& offlinePath = "");
~DefaultFileSource() override;

void setAccessToken(const std::string&);
Expand Down
13 changes: 12 additions & 1 deletion include/mbgl/util/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define MBGL_UTIL_STRING

#include <string>
#include <vector>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
Expand All @@ -22,7 +23,6 @@ inline std::string toString(int8_t num) {
return boost::lexical_cast<std::string>(int(num));
}


template<size_t max, typename... Args>
inline std::string sprintf(const char *msg, Args... args) {
char res[max];
Expand All @@ -35,6 +35,17 @@ inline std::string sprintf(const std::string &msg, Args... args) {
return sprintf<max>(msg.c_str(), args...);
}

inline std::vector<std::string> split(const std::string& text, const std::string& delimiter) {
std::vector<std::string> tokens;
size_t start = 0, end = 0;
while ((end = text.find(delimiter, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}

} // namespace util
} // namespace mbgl

Expand Down
10 changes: 9 additions & 1 deletion ios/app/MBXViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ - (void)viewDidLoad
{
[super viewDidLoad];

self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
NSString *offlineMapPath = [[NSBundle mainBundle] pathForResource:@"cache" ofType:@"mbtiles"];

self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds
styleURL:[MGLStyle streetsStyleURL]
offlineMapPath:offlineMapPath];
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.mapView.delegate = self;
[self.view addSubview:self.mapView];
Expand Down Expand Up @@ -91,6 +95,10 @@ - (void)viewDidLoad
[self.mapView addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]];

[self restoreState:nil];

[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(45.468780541878154, -122.65276581137326)
zoomLevel:15
animated:YES];
}

- (void)saveState:(__unused NSNotification *)notification
Expand Down
Binary file added ios/app/cache.mbtiles
Binary file not shown.
3 changes: 2 additions & 1 deletion ios/app/mapboxgl-app.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
'./polyline.geojson',
'./threestates.geojson',
'./Settings.bundle/',
'./app-info.plist'
'./app-info.plist',
'./cache.mbtiles'
],

'dependencies': [
Expand Down
9 changes: 9 additions & 0 deletions platform/default/sqlite3.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <mbgl/platform/log.hpp>

#include "sqlite3.hpp"
#include <sqlite3.h>

Expand All @@ -24,8 +26,15 @@ const static bool sqliteVersionCheck = []() {
namespace mapbox {
namespace sqlite {

void trace_callback(void* udp, const char* sql) {
(void)udp;
printf("%s\n", sql);
// mbgl::Log::Debug(mbgl::Event::Database, sql);
};

Database::Database(const std::string &filename, int flags) {
const int err = sqlite3_open_v2(filename.c_str(), &db, flags, nullptr);
// sqlite3_trace(db, trace_callback, NULL);
if (err != SQLITE_OK) {
const auto message = sqlite3_errmsg(db);
db = nullptr;
Expand Down
21 changes: 19 additions & 2 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ @implementation MGLMapView
BOOL _delegateHasStrokeColorsForShapeAnnotations;
BOOL _delegateHasFillColorsForShapeAnnotations;
BOOL _delegateHasLineWidthsForShapeAnnotations;

NSString *_offlineMapPath;
}

#pragma mark - Setup & Teardown -
Expand Down Expand Up @@ -214,6 +216,17 @@ - (instancetype)initWithFrame:(CGRect)frame styleURL:(nullable NSURL *)styleURL
return self;
}

- (instancetype)initWithFrame:(CGRect)frame styleURL:(nullable NSURL *)styleURL offlineMapPath:(NSString *)offlineMapPath
{
if (self = [super initWithFrame:frame])
{
_offlineMapPath = [offlineMapPath copy];
[self commonInit];
self.styleURL = styleURL;
}
return self;
}

- (instancetype)initWithCoder:(nonnull NSCoder *)decoder
{
if (self = [super initWithCoder:decoder])
Expand Down Expand Up @@ -280,10 +293,14 @@ - (void)commonInit
fileCachePath = [libraryDirectory stringByAppendingPathComponent:@"cache.db"];
}
_mbglFileCache = mbgl::SharedSQLiteCache::get([fileCachePath UTF8String]);
_mbglFileSource = new mbgl::DefaultFileSource(_mbglFileCache.get());
_mbglFileSource = new mbgl::DefaultFileSource(_mbglFileCache.get(), "", _offlineMapPath ? _offlineMapPath.UTF8String : "");

// setup mbgl map
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous);
_mbglMap = new mbgl::Map(*_mbglView,
*_mbglFileSource,
mbgl::MapMode::Continuous,
mbgl::GLContextMode::Unique,
mbgl::ConstrainMode::HeightOnly);

// setup refresh driver
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateFromDisplayLink)];
Expand Down
17 changes: 12 additions & 5 deletions src/mbgl/storage/default_file_source.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/online_file_source.hpp>
#include <mbgl/storage/offline_file_source.hpp>

namespace mbgl {

class DefaultFileSource::Impl {
public:
Impl(FileCache* cache, const std::string& root)
: onlineFileSource(cache, root) {
Impl(FileCache* cache, const std::string& root, const std::string& offlinePath)
: offlineFileSource(offlinePath),
onlineFileSource(cache, root) {
}

OfflineFileSource offlineFileSource;
OnlineFileSource onlineFileSource;
};

DefaultFileSource::DefaultFileSource(FileCache* cache, const std::string& root)
: impl(std::make_unique<DefaultFileSource::Impl>(cache, root)) {
DefaultFileSource::DefaultFileSource(FileCache* cache, const std::string& root, const std::string& offlinePath)
: impl(std::make_unique<DefaultFileSource::Impl>(cache, root, offlinePath)) {
}

DefaultFileSource::~DefaultFileSource() = default;
Expand All @@ -27,7 +30,11 @@ std::string DefaultFileSource::getAccessToken() const {
}

std::unique_ptr<FileRequest> DefaultFileSource::request(const Resource& resource, Callback callback) {
return impl->onlineFileSource.request(resource, callback);
if (impl->offlineFileSource.handlesResource(resource)) {
return impl->offlineFileSource.request(resource, callback);
} else {
return impl->onlineFileSource.request(resource, callback);
}
}

} // namespace mbgl
Loading

0 comments on commit 8f3d5fa

Please sign in to comment.