nasa-gibs / gibs-web-examples

Examples of using GIBS with various web mapping libraries

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leaflet 1.x Compatibilty with Granule Browse

cmay87 opened this issue · comments

commented

I'm currently working with the single scene browse implementation with leaeflet 1.x through GIBS. I'm having difficulties generating the correct tile numbering due to the difference in leaflet's slippy tiles (with a 1x1 top pyramid) as opposed to the 2x1 top pyramid that GIBS expects. I also noticed that all leaflet examples are using version 0.7.x.

I've included a sample script below - I believe the key is using Proj4 to create a custom CSR that has scaling and transformation formulas to convert tile coordinates to the 15.625m TileMatrixSet.

<title>GIBS Browse Test</title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> <script src="https://leafletjs-cdn.s3.amazonaws.com/content/leaflet/master/leaflet.js"></script>
    <!-- https://github.com/proj4js/proj4js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.3/proj4-src.js"></script>

    <!-- https://github.com/kartena/Proj4Leaflet -->
    <script src="http://glovis.usgs.gov/next/js/leaflet_plugins/proj4leaflet_new.js"></script> 

    <div id="map" style="background: #000000;  height: 660px;"></div>

    <script type="text/javascript">
        $(document).ready(function () {
            var proj1 = new L.Proj.CRS(
                "EPSG:4326",
                "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs", {
                    origin: [-180, 90],
                    resolutions: [
                        0.5625,
                        0.28125,
                        0.140625,
                        0.0703125,
                        0.03515625,
                        0.017578125,
                        0.0087890625,
                        0.00439453125,
                        0.002197265625
                    ],
                    // Values are x and y here instead of lat and long elsewhere.
                    bounds: [
                       [-180, -90],
                       [180, 90]
                    ]
                }
            );
           
            var webCrs = L.extend({}, L.CRS, {
                code: 'EPSG:4326',
                projection: L.Projection.LonLat,
                transformation: new L.Transformation(1 / 360, 0.5, -1 / 360, 0.5),
                scale: function (zoom) {
                    return 512 * Math.pow(2, zoom);
                }
             });                 
           
            var wmsCrs = L.extend({}, L.CRS, {
                projection: L.Projection.SphericalMercator,
                transformation: new L.Transformation(1, 0, 1, 0),
                scale: function (zoom) {
                    return 512 * Math.pow(2, zoom);
                }
            }); 
           
            //NOTE :: We will need it to work with the map being in it's default projection
            var map = new L.Map('map', {
                inertia: false,
                boxZoom: true,
                worldCopyJump: true,
                zoomControl: false,
                doubleClickZoom: false,
                preferCanvas: true,
                unloadInvisibleTiles: false,
                updateWhenIdle: true,
                crs: L.CRS.EPSG3857 //This is the map default - which matches our config
            });
            
            L.control.scale({
                position: 'bottomright'
            }).addTo(map);

            var layerOptions = {
                layer: '',
                minZoom: 2,
                maxZoom: 20,
                tileSize: 256,
                subdomains: "abc",
                continuousWorld: true, // Prevent Leaflet from retrieving non-existent tiles on the borders.
                attribution: 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'
            };

            map.addLayer(L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', layerOptions));
            map.setView(new L.LatLng(-36.4621, -79.6164), 12);

            
            var webCrs = L.extend({}, L.CRS, {
                projection: L.Projection.LonLat,
                transformation: new L.Transformation(1, 0, 1, 0),
                scale: function (zoom) {
                    return 512 * Math.pow(2, zoom);
               }
            });                
            
            //NOTE :: dds.cr.usgs.gov/gibs_test is an internal proxy that points to sit.gibs.earthdata.nasa.gov to simplify our firewall rules to sit.gibs.earthdata.nasa.gov
            var sceneBrowse = L.tileLayer('https://dds.cr.usgs.gov/gibs_test/wmts/epsg4326/std/ASTER_L1T_Radiance_Terrain_Corrected_v3_STD/default/2016-01-01T15:29:32Z/15.625m/{z}/{x}/{y}.png', {
                format: 'image/png',
                transparent: true,
                tileSize: 512,
                attribution: 'GIBS!!!',
                crs: webCrs//L.CRS.EPSG4326
            });
            
            sceneBrowse.on('tileload', function(event)
            {
                console.log('Tile ' + event.coords.z + '/' + event.coords.x + '/' + event.coords.y/* + ' - ' + event.tile.currentSrc*/);
            });
            
            map.addLayer(sceneBrowse);
            
            //Add a polygon to the map so we know we're looking within the granule location
            var geoJson = {type:"Polygon",coordinates:[[[-80.0854,-36.807],[-79.1354,-36.7959],[-79.1516,-36.1163],[-80.0934,-36.1271],[-80.0854,-36.807]]]};
            var layerStyle = {
                color: '#ff0000', 
                fillColor: '#ff0000', 
                fillOpacity: 0.1, 
                opacity: 1, 
                weight: 2
            };
            
            L.GeoJSON.geometryToLayer(geoJson).setStyle(layerStyle).addTo(map);
        });
    </script>
</body>

@cmay87 I would suggest looking into this library https://github.com/mylen/leaflet.TileLayer.WMTS that offers a WMTS tilelayers class for leaflet. Hope this helps.

It also looks to me that the layerOptions you set for the OSM layer do not apply to the GIBS layer, since they are different CRS/EPSGs and tile sizes. Not sure if that is a red herring or not

commented

I looked into that library and is doesn't impact the tile coordinates any different - it is also written for leaflet 0.7.x and I know they did a bunch of WMS WMTS related changes between those versions. As far as the layerOptions they are independent of each other - notice that the GIBS layer isn't using the layerOptions object (I added the OSM map for geographic reference only).

We actually load our browse in at 512 tilesize with OSM using 256 map tiles so it's able to handle tile size differences on a layer by layer basis.

commented

I think I see the root of the cause. It looks like the crs option isn't available in the base TileLayer class so I'll have to extend the WMS class to allow for projection transformations to occur similar to the plugin that was mentioned. Long story short - the only projection information that L.TileLayer uses in leaflet 1.x is the maps projection.

The examples have been updated with Leaflet version 1.3.3.