Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

projected bounds and nonexistent tiles #62

Open
alexander-travov opened this issue Feb 18, 2014 · 11 comments
Open

projected bounds and nonexistent tiles #62

alexander-travov opened this issue Feb 18, 2014 · 11 comments

Comments

@alexander-travov
Copy link

Hello.

I have problems with setting map bounds in projected coordinates.

My map is in oblique stereographic projection: '+proj=sterea +lat_0=50 +lon_0=100 +k_0=1.0 +x_0=0 +y_0=0'. Its extent is [minx, miny, maxx, maxy]: [-6e6, -4e6, 4e6, 6e6].

If I don't set any bounds, I get lots of requests to nonexistent tiles. See map_without_bounds.

Setting L.Proj.CRS constructor bounds option does not prevent requests. See map_with_crs_bounds.

To deal with it L.TileLayer constructor accepts bounds option, but in latlng coordinates. If I set bounds like that ...

var map = L.map('map', {
    crs: new L.Proj.CRS('EPSG:9809',
        '+proj=sterea +lat_0=50 +lon_0=100 +k_0=1.0 +x_0=0 +y_0=0',
        {
            resolutions: [39062.5, 19531.25, 9765.625, 4882.8125, 2441.40625, 1220.703125],
            origin: [-6e6, 6e6]
        }
    ),
    center: L.latLng(68, 90),
    zoom: 3,
    layers: [
        new L.TileLayer(
            'http://81.5.88.53/russia_tiles/{z}/{x}/{y}.png',
            {
                maxZoom: 5,
                minZoom: 2,
                continuousWorld: true,
                bounds: L.latLngBounds(L.latLng(70, 30), L.latLng(40, 150))
            }
        )
    ]
});

Leaflet requests map tiles from nonrectangular area. See map_with_layer_latlng_bounds.

Is there a way to set layer bounds in projected coordinates.

@perliedman
Copy link
Contributor

I would start with trying

    new L.TileLayer(
        'http://81.5.88.53/russia_tiles/{z}/{x}/{y}.png',
        {
            maxZoom: 5,
            minZoom: 2,
            continuousWorld: true,
            noWrap: true,   /* <-- enables bounds checking in L.TileLayer */
            bounds: L.latLngBounds(L.latLng(70, 30), L.latLng(40, 150))
        }

(added noWrap option.) Combine this with the bounds option. I think it should work.

Also worth noting, is that this is one of the use cases that have been greatly improved in the development version of Leaflet (master branch) - CRS, projection, bounds and wrap have all been greatly improved and should be clearer to use.

@alexander-travov
Copy link
Author

Thanks for advice.

Unfortunately, noWrap option didn't do the trick.

Problem is not that L.tileLayers's bounds does not work. It works, but only accepts bounds in latlng coordinates. Therefore in general you get a nonrectangular map in your custom projection.

I was wondering, if there is a way to set L.tileLayer's bounds in coordinates of custom projection. Like OpenLayers.Map maxExtent or restrictedExtent.

When I use Leaflet version from master branch, I get Uncaught TypeError: Cannot read property 'min' of undefined in L.CRS.getProjectedBounds

@perliedman
Copy link
Contributor

Sorry, I meant Proj4Leaflet's bounds option, which is in projected coordinates. That will affect what getSize returns, which in turn should fix tile loading if noWrap is enabled.

@alexander-travov
Copy link
Author

I got the desired behavior with leaflet-master. Works even without noWrap

  var map = L.map('map', {
      crs: new L.Proj.CRS('EPSG:9809',
          '+proj=sterea +lat_0=50 +lon_0=100 +k_0=1.0 +x_0=0 +y_0=0',
          {
              resolutions: [39062.5, 19531.25, 9765.625, 4882.8125, 2441.40625, 1220.703125],
              origin: [-6e6, 6e6],
              bounds: L.bounds(L.point(-6e6, -4e6), L.point(4e6, 6e6))
          }
      ),
      center: L.latLng(68, 90),
      zoom: 3,
      layers: [
          L.tileLayer(
              'http://81.5.88.53/russia_tiles/{z}/{x}/{y}.png',
              {
                  maxZoom: 5,
                  minZoom: 2,
                  //noWrap: true,
                  continuousWorld: true
              }
          )
      ]
  });

But I believe there is error in leaflet-master/leaflet-src.js in

    getProjectedBounds: function (zoom) {
        if (this.infinite) { return null; }

        var b = this.projection.bounds, // <-- projection does not have bounds property
                // Thus it generates Uncaught TypeError: Cannot read property 'min' of undefined
            s = this.scale(zoom),
            min = this.transformation.transform(b.min, s),
            max = this.transformation.transform(b.max, s);

        return L.bounds(min, max);
    },

so I changed this to

    getProjectedBounds: function (zoom) {
        if (this.infinite) { return null; }

        var b = this.options.bounds,
            s = this.scale(zoom),
            min = this.transformation.transform(b.min, s),
            max = this.transformation.transform(b.max, s);

        return L.bounds(min, max);
    },

and everything worked.

@alexander-travov
Copy link
Author

BTW leaflet-0.7.2 does not react to L.Proj.CRS's bounds option

@alexander-travov
Copy link
Author

Created pull request: Leaflet/Leaflet#2474

@perliedman
Copy link
Contributor

Ok, I didn't know you mixed current Proj4Leaflet (written for Leaflet 0.7.2) and Leaflet master, which has a lot of changes regarding CRS and Projection. That will be a problem.

My suggestion above relates to current Proj4Leaflet (master) and Leaflet 0.7.2.

If you want to use Leaflet master, you should look at the Proj4Leaflet branch https://github.com/kartena/Proj4Leaflet/tree/leaflet-proj-refactor

@alexander-travov
Copy link
Author

Thank you. Leaflet's master works with Proj4Leaflet's leaflet-proj-refactor branch smoothly. L.Proj.CRS bounds works as expected without Leaflet monkey-patching.

With Leaflet's master and Proj4Leaflet's master I get exception in getProjectedBounds.

I could not make leaflet-0.7.2 react to L.Proj.CRS bounds option. Always get requests for tiles out of bounds. With and without noWrap.

@perliedman
Copy link
Contributor

Ok, thanks for the information. I'll try to find some time to look into why it doesn't work with 0.7.2.

@tcoopman
Copy link

tcoopman commented Oct 3, 2014

Any updates on this. With the current master of leaflet, I also need the refactor branch to get proj4leaflet working.

(An fiddle here: http://jsfiddle.net/6x77qua0/4/ (this.projection.bounds also fails when not on the correct branch)

@perliedman
Copy link
Contributor

Leaflet master (that will become 1.0) is quite heavily refactored regarding CRS/projection handling. An updated version of Proj4Leaflet that should work with Leaflet master/1.0 is in this branch: https://github.com/kartena/Proj4Leaflet/tree/leaflet-proj-refactor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants