[GIS] help with TMS (gdal2tiles) Openlayers 3 and custom projection

coordinate systemgdalgdal2tilesopenlayerstile-map-service

I work with a local italian projection (EPSG:3003 Monte Mario Italy zone 1) and I had loaded this projection in my project for evitate to reproject all of my data.

I had created the tile pyramid with the last version of gdal2tiles (the version shipped with the last version of maptiler open source [see http://trac.osgeo.org/gdal/ticket/2052] to be able to generate jpeg tiles instead of png tiles)

my problem is that I don't be able to assign the correct extent to my page.
If I assign to the montemarioProjection the extent for italy, also this extent is applied to my map, but my map contains only the municipality of modena.
My extent of tms of modena, calculated by gdal2tiles, seems to be ignored.

when i try to pan to a certain coordinate point in monte mario coordinate system, map goes in a wrong place, because is not positioned well.

some examples:
(HERE I HAD ASSIGNED TO MONTE MARIO ONLY MODENA EXTENT AS EXTENT, NOT ITALY)

EXAMPLE 1 http://mappe-t.comune.modena.it/ortofoto/2014/ol3_ortofoto.html

(HERE I HAD ASSIGNED TO MONTE MARIO HIS REAL EXTENT AND TRIED TO FORCE MAP ORIGIN,
BUT IT WAS IGNORED. I HAVE TO REMOVE extent parameter from ol.layer.tile and ol.view)

EXAMPLE 2
http://mappe-t.comune.modena.it/ortofoto/2014/ol3_ortofoto2.html

see lines 111-115

origin:  tileGrid: new ol.tilegrid.TileGrid({
                //tileGrid: new ol.tilegrid.XYZ({
                    origin: tms_origin,
                    resolutions: tms_resolutions
                }),

IF LOOK AT MOUSEPOSITION CONTROL, THE COORDINATES IS WRONG IN EXAMPLE 1 AND 2

HERE IS ALL OF MY CODE FROM EXAMPLE 2 (WITHOUT COMMENTED PARTS)

    var tms_extent = [ 1640349.34499999997206, 4935769.97499999962747, 1659997.04499999992549, 4956992.87500000000000 ];
    var tms_origin = [1640349.34499999997206, 4935769.97499999962747];

    var tms_resolutions = [ 
                        12.79999999999997, 6.39999999999999, 3.19999999999999, 1.60000000000000,
                        0.80000000000000, 0.40000000000000, 0.20000000000000, 0.10000000000000
            ];


    var city_center = [ 1652769.73, 4945475.55 ];

    var monteMarioSystemCode = 'EPSG:3003';
    var projectionMonteMario = ol.proj.get(monteMarioSystemCode);
    var extent_italia_monte_mario = [1290679.24, 4194066.17, 2226886.34, 5259894.49];
    projectionMonteMario.setExtent(extent_italia_monte_mario);

    var map = new ol.Map({

        controls: ol.control.defaults({ attribution: false }).extend(
                [ new ol.control.ZoomSlider(), 
                  new ol.control.ScaleLine(),
                  new ol.control.MousePosition({
                      coordinateFormat: ol.coordinate.createStringXY(4),
                      projection: monteMarioSystemCode,
                      undefinedHTML: ' '
                    })
                 ]),

        layers : [ new ol.layer.Tile({

            source : new ol.source.XYZ({
                crossOrigin     : null,

                //experimental parameter
                projection      : monteMarioSystemCode,

                //experimental parameter (necessary because gdal2tiles generate tiles in TMS mode not in XYZ mode)
                tileUrlFunction : function(coordinate) {
                    if (coordinate == null) {
                        return "";
                    }
                    // type of ol.TileCoord is recently changed to an array of three numbers: [z, x, y]
                    var z = coordinate[0];
                    var x = coordinate[1];
                    var y = (1 << z) - coordinate[2] - 1;
                    return 'http://mappe-t.comune.modena.it/ortofoto/2014/tms2014/' + z + '/' + x + '/' + y + '.jpg';
                },
                //this works only for tiles generated in XYZ format, es maptiler pro
                //url       : 'http://mappe-t.comune.modena.it/ortofoto/2014/tms2014/{z}/{x}/{y}.jpg'

                //experimental parameter (inherited from ol.source.TileImage)

                tileGrid: new ol.tilegrid.TileGrid({
                    origin: tms_origin,
                    resolutions: tms_resolutions
                }),

            })
        }) ],
        renderer : 'canvas',
        target : 'map',
        view : new ol.View({
            projection      : monteMarioSystemCode,
            center          : city_center,
            maxZoom         : 10,
            minZoom         : 3,
            zoom            : 3
        })
    });

TMS TILE MAP RESOURCE
http://mappe-t.comune.modena.it/ortofoto/2014/tms2014/tilemapresource.xml

Best Answer

I've found a working solution based on openlayers version 3.7

Here is a working example:

http://mappe-t.comune.modena.it/prove/demo_ol3/tms_ol3_with_popup.html

basically is necessary to create a custom TileImage source

this is my code

/*
    CONFIGURATION PARAMETERS DESUMED FROM gdal2tiles generated file
    http://mappe.comune.modena.it/ortofoto/2014/tilemapresource.xml
    */

    var tms_resolutions_2014 = [ 102.39999999999979, 51.19999999999990, 25.59999999999995, 12.79999999999997,
                              6.39999999999999, 3.19999999999999, 1.60000000000000, 0.80000000000000,
                              0.40000000000000, 0.20000000000000, 0.10000000000000 ];

    var extent_ortofoto_2014 = [1640349.34499999997206, 4935769.97499999962747, 1659997.04499999992549, 4956992.87500000000000];

    /* CONFIGURATION PARAMETERS DESUMED FROM http://epsg.io/3003 */
    var coordSystemCode = 'EPSG:3003';
    var projectionMonteMario = ol.proj.get(coordSystemCode);
    //var extent_italy_monte_mario    = [1290679.24, 4194066.17, 2226886.34, 5259894.49];
    var extent_italy_monte_mario    = [1290650.93, 4192956.42, 2226749.10, 5261004.57];
    projectionMonteMario.setExtent(extent_italy_monte_mario);


    //TMS LAYER. IS CONFIGURED AS A CUSTOM TileImage source

    var tmsModena = new ol.layer.Tile({

        preload: 1,
        source: new ol.source.TileImage({
            crossOrigin: null,
            extent: extent_ortofoto_2014,
            projection: projectionMonteMario,
            tileGrid: new ol.tilegrid.TileGrid({
                extent: extent_ortofoto_2014,
                origin: [extent_ortofoto_2014[0], extent_ortofoto_2014[1]],
                resolutions: tms_resolutions_2014

            }),
            tileUrlFunction: function(coordinate) {

                if (coordinate === null) return undefined;

                // TMS Style URL
                var z = coordinate[0];
                var x = coordinate[1];
                var y = coordinate[2];
                var url = 'http://mappe.comune.modena.it/ortofoto/2014/'+z+'/'+ x +'/'+y +'.jpg';
                return url;
            }
        })
    });