読者です 読者をやめる 読者になる 読者になる

Leaflet v1.0.0-rc.2で北上でないCRSでmap.fitBounds()が動かない件

北が上にならないCRSで、map.fitBoundsが動かなかった。目的のL.LatLngBoundsのスクリーン上の左上座標と右下座標を、CRSを考慮せずにそれぞれgetNorthWestとgetSouthEastで取得していたためだった。

Map.jsのgetBoundsZoomを下記の様に修正して対応。

修正前

getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number
    bounds = L.latLngBounds(bounds);
    padding = L.point(padding || [0, 0]);

    var zoom = this.getZoom() || 0,
        min = this.getMinZoom(),
        max = this.getMaxZoom(),
        nw = bounds.getNorthWest(),
        se = bounds.getSouthEast(),
        size = this.getSize().subtract(padding),
        boundsSize = this.project(se, zoom).subtract(this.project(nw, zoom)),
        snap = L.Browser.any3d ? this.options.zoomSnap : 1;

    var scale = Math.min(size.x / boundsSize.x, size.y / boundsSize.y);
    zoom = this.getScaleZoom(scale, zoom);

    if (snap) {
        zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level
        zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap;
    }

    return Math.max(min, Math.min(max, zoom));
},

修正後

getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number
    bounds = L.latLngBounds(bounds);
    padding = L.point(padding || [0, 0]);

    var zoom = this.getZoom() || 0,
        min = this.getMinZoom(),
        max = this.getMaxZoom(),
        nw = bounds.getNorthWest(),
        se = bounds.getSouthEast(),
        size = this.getSize().subtract(padding);

    // pt2 > pt1でないと動かない。
    var pt1 = this.project(se, zoom),
        pt2 = this.project(nw, zoom);        
    if (pt2.y > pt1.y){
        var pt2y = pt2.y;
        pt2.y = pt1.y;
        pt1.y = pt2y;
    }
    var boundsSize = pt1.subtract(pt2),
        snap = L.Browser.any3d ? this.options.zoomSnap : 1;

    var scale = Math.min(size.x / boundsSize.x, size.y / boundsSize.y);
    zoom = this.getScaleZoom(scale, zoom);

    if (snap) {
        zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level
        zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap;
    }

    return Math.max(min, Math.min(max, zoom));
},

他にもいろいろ、普通の使い方でないところでつまづきそう。