Is it possible to translate tile requests from a mapping engine wanting Google Map style tiles into tile requests from a geopackage file? If not, where can I find information about how to create a mapping engine that handles the dizzying array of options provided by geopackage (as in, something that would help with understanding how to use srid, min_x, pixel_x_size, tile_width, matrix_width, zoom_level, and screen coords to determine which tiles at which rotation displayed where)

I have used MBTiles in the past to supply tiles to a mapping engine that requested tiles in Google Map style. This worked well as MBTiles uses the same projection and uses TMS for the tiling scheme. This meant I only needed to modify the y value of each request to translate from TMS to Google Maps style.

Two of the problems that I am having trouble figuring out how to overcome in regards to translating google maps tile requests to a specific tile in geopackage is how to handle the potential difference in projection, and how to handle the difference in origin. (By difference in origin I mean Google maps starts 0,0 at the top left corner of the world (because it assumes the whole world has data), whereas geopackage starts at the top left of the data (which might be the whole world but likely will not be))

If it makes any difference I am trying to do this in C++ using Qt and QtLocation.

  • 1
    Its possible that the GeoPackage is basically mbtiles compatible, except for the changed Y convention. Do you know you'll always be dealing with a particular GeoPackage (or GeoPackage profile)? Is using GDAL a possibility?
    – BradHards
    Jan 16, 2015 at 22:47
  • 1)At the moment I don't want to assume a specific setup in GeoPackage, but depending on how this turns out, requiring that might be an option. 2)As this will be run on Android and iOS along with desktop target (by using Qt), I would rather not use GDAL if possible since I seem to remember build issues (I could be wrong on this though, will check later).
    – jp36
    Jan 16, 2015 at 22:56

2 Answers 2


As of Jan 2015, I'm not aware of any open source implementation that fully supports every possible option in geopackage. The spec is authoritative (but likely to be updated) for implementation, so if you want to (or really don't want to, but still have to) write your own map engine, work from that. Look for a sane subset/profile, rather than trying to do it all. For example, choose to only support power-of-two zoom.

If you're able to constrain the problem a bit, the GDAL and spatialite implementations might work for you - both can give back tiles or composite images for a given area. Given your comment about iOS support, spatialite may be difficult. I don't have experience with GDAL on iOS. Those are both open source and can provide examples for how you might do a similar implementation. Even Rouault's blog entry on GeoPackage might also prove useful to either use GDAL or implement something similar.

Given arbitrary SRID, you'd need some way to either reproject the data you want to overlay on the map, or reproject the geopackage rasters and vectors, or both. That is usually proj.4 (used within both GDAL and spatialite, as well as many other tools), which is workable on Android. I can't say how hard it is on iOS.

Correction: GeoPackage origin is still (0,0) but there is no promise that there is any data at that position at any zoom level. The spec says "The tile coordinate (0,0) always refers to the tile in the upper left corner of the tile matrix at any zoom level, regardless of the actual availability of that tile." Actually, there is no promise there is data at any other position - the matrix is allowed to be empty. The background to this decision is to be able to add tiles later. What is allowed to occur though is that the (potentially empty) nominal bounding box in gpkg_tile_matrix_set doesn't need to be the whole world - it is the exact bounds for what might ever be filled in. Consider that a SRID like a UTM zone doesn't make sense to have "whole world" extent.

  • Sorry for the delayed response. 1)Can GDAL be used to supply tiles to a mapping engine that requested tiles in Google Map style? If so how? 2)I was planning to look at proj.4, does that function as an alternative to GDAL or does it supplement it? 3)Question to your correction: I may have misunderstood, I thought in a map of New York, (0,0) would be the top left corner of New York. Is (0,0) instead the top left corner of the world with many empty tiles? 4) If I have to write my own engine, are there any examples/guides that you know of that will speed up the process?
    – jp36
    Jan 20, 2015 at 15:01
  • 1
    I've tried to answer your questions 1, 2 and 4. I've already explained 3 - (0,0) is the notional top left of the tile matrix, and exactly corresponds to the top left of the specified bounding box.
    – BradHards
    Jan 20, 2015 at 20:00
  • Your expanded answer helped a lot. So as a final piece of this question does this make sense. If I convert the tile that is being requested by the mapping engine (in google maps format) into a bounding box (instead of just a tile) and then use gdal to request that specific bounding box as an image (using gdal to handle the projection change from mercator to whatever the geopackage is using).
    – jp36
    Jan 21, 2015 at 15:49

There are a few open source implementations of GeoPackage that you can take a look at here: https://github.com/ngageoint/GeoPackage

GeoPackage iOS is available via pod install for iOS.

GeoPackage Android is available via gradle for Android.

GeoPackage Java is available via the maven central repository for java based desktop applications.

GeoPackage JS is currently being developed and supports Node and opening a GeoPackage file in the browser.

  • This is good information for anyone looking at this issue. Thanks!
    – jp36
    Apr 22, 2016 at 2:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.