I'm trying to leverage GeopackageJS for use in a mapping application using OpenLayers 6, but the documentation seems to be really iffy-- the link to the API documentation actually 404s and the examples on the actual github seem to be woefully out of date. I've had to build most of my understanding using the geopackage.js script itself as well as some helpful Stack Exchange answers.

The map I'm displaying is in an EPSG:4326 projection and I have the current solution using one that I found from this GIS Stack Exchange answer. I have a custom tile loader that essentially looks like this:

var promise = geopackage.getTileFromXYZ(this.gpkg, this.gpkg.getTileTables()[0], x, y, z, 256, 256);
promise.then(function(base64) {
    tile.getImage().src = base64

The problem is that getTileFromXYZ specifically has the TileRetreiver fetch the tile in EPSG:3857. So either the tile gets stretched and distorted to fit onto the EPSG:4326 map I have or it doesn't line up with the projection. The release notes for GeoPackageJS explicitly say they added a method to retrieve tiles in EPSG:4326 in version 1.1.4 but I cannot find any method that actually exposes that kind of logic.

Does anyone know what I'm missing or if there's a good example page or documentation I should be looking at?

  • You cannot put tiles directly on to the map, they go to some layer. You can set CRS of this layer to EPSG:3857 and since it's raster layer, it's tiles will be automatically transformed to whatever CRS yout map's view has.
    – TomazicM
    Jul 2, 2020 at 18:18
  • You may get some ideas of how to use GeopackageJS in OpenLayers by looking at the code of leaflet-geopackage.js library (included in distribution of GeopackageJS) that enables use of GeopackageJS in Leaflet. Tiles are tiles and features are features in both OpenLayers and Leaflet.
    – TomazicM
    Jul 2, 2020 at 18:49
  • TomazicM: Yes, sorry I might have not made that perfectly clear in my answer. It is going onto a layer, and I am aware that it is automatically being transformed, but the images appear to be distorted in order to fit onto the CRS. Since GeopackageJS release notes state that EPSG:4326 can be retrieved directly that's what I was hoping for. I'll take a look into leaflet-geopackage.js Jul 2, 2020 at 19:10
  • If your view crs is unprojected EPSG:4326, displayed maps will always be distorted, except at the equator. Further you go from equator to North or South, more distorted the map will be. Set the crs of the view to projected EPSG:3857 and you should be OK.
    – TomazicM
    Jul 2, 2020 at 19:16

1 Answer 1


To answer my own question, the best bet to do this is to utilize the draw4326TileInCanvas function. If you don't pass in a canvas it actually returns back a base64 representation of the tile! So your tileLoadFunction should look something like this:

tileLoadFunction: function(tile, url) {
    var tileCoord = url.split(",");
    tileCoord[0] = parseInt(tileCoord[0]);
    tileCoord[1] = parseInt(tileCoord[1]);
    tielCoord[2] = parseInt(tileCoord[2]);

    var z = tileCoord[0];

    var ext = this._source.tileGrid.getTileCoordExtent(tileCoord);
    //gpkg is the loaded in geopackage earlier in the script
    //tileSize is the size of tiles utilized by your map

    var promise = geopackage.draw4326TileInCanvas(gpkg, "table_name", ext[1], ext[0], ext[3], ext[2], z, tileSize, tileSize, null);
    promise.then(function(base64) {
        tile.getImage().src = base64;

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.