2016-11-24 2 views
2

私は、カスタムCRS(EPSG:32633)でリーフレットマップをセットアップしました。マップは一般的にうまくいきますが、ピンチを使用して地図をズームしてモバイルデバイスをズームしようとするとフリーズします。リーフレットのカスタムCRSでピンチをズームするのがなぜ機能しないのですか?

ピンチとズームの間で発生するエラーは、「キャッチされていないエラー:無効なLatLngオブジェクト:(NaN、NaN)」です。ここ

は、問題を再現するために使用することができるjsfiddleだ:

http://jsfiddle.net/thL5bbnv/2/

ここで(jsfiddleにも使用される)コードは次のとおり

// Defining the projection system 
L.Projection.UTM33 = { 
    ZONE: 33, 
    R_MINOR: 6356752.3142, 
    R_MAJOR: 6378137, 
    DEG_TO_RAD: Math.PI/180, 
    RAD_TO_DEG: 180/Math.PI, 

    bounds: L.bounds([-2500000, 3500000], [3045984, 9045984]), 

    project: function(latlng) { 
    var latRad = latlng.lat * this.DEG_TO_RAD, 
     longRad = latlng.lng * this.DEG_TO_RAD, 
     longOriginRad = (-183 + (6 * this.ZONE)) * this.DEG_TO_RAD, 
     eccs = 1 - ((this.R_MINOR/this.R_MAJOR) * (this.R_MINOR/this.R_MAJOR)), 
     k0 = 0.9996, 
     eccps = eccs/(1 - eccs), 
     n = this.R_MAJOR/Math.sqrt(1 - eccs * Math.sin(latRad) * Math.sin(latRad)), 
     t = Math.tan(latRad) * Math.tan(latRad), 
     c = eccps * Math.cos(latRad) * Math.cos(latRad), 
     a = Math.cos(latRad) * (longRad - longOriginRad), 
     m = this.R_MAJOR * ((1 - eccs/4 - 3 * eccs * eccs/64 - 5 * eccs * eccs * eccs/256) * latRad - (3 * eccs/8 + 3 * eccs * eccs/32 + 45 * eccs * eccs * eccs/1024) * Math.sin(2 * latRad) + (15 * eccs * eccs/256 + 45 * eccs * eccs * eccs/1024) * Math.sin(4 * latRad) - (35 * eccs * eccs * eccs/3072) * Math.sin(6 * latRad)), 
     x = k0 * n * (a + (1 - t + c) * a * a * a/6 + (5 - 18 * t + t * t + 72 * c - 58 * eccps) * a * a * a * a * a/120) + 500000.0, 
     y = k0 * (m + n * Math.tan(latRad) * (a * a/2 + (5 - t + 9 * c + 4 * c * c) * a * a * a * a/24.0 + (61.0 - 58 * t + t * t + 600.0 * c - 330.0 * eccps) * a * a * a * a * a * a/720)); 

    return new L.Point(x, y); 
    }, 

    unproject: function(point) { 
    var eccs = 1 - ((this.R_MINOR/this.R_MAJOR) * (this.R_MINOR/this.R_MAJOR)), 
     e1 = (1 - Math.sqrt(1 - eccs))/(1 + Math.sqrt(1 - eccs)), 
     k0 = 0.9996, 
     x = point.x - 500000, 
     y = point.y, 
     longOrigin = (this.ZONE - 1) * 6 - 180 + 3, 
     eccps = (eccs)/(1 - eccs), 
     m = y/k0, 
     mu = m/(this.R_MAJOR * (1 - eccs/4 - 3 * eccs * eccs/64 - 5 * eccs * eccs * eccs/256)), 
     phi1Rad = (mu + (3 * e1/2 - 27 * e1 * e1 * e1/32) * Math.sin(2 * mu) + (21 * e1 * e1/16 - 55 * e1 * e1 * e1 * e1/32) * Math.sin(4 * mu) + (151 * e1 * e1 * e1/96) * Math.sin(6 * mu)), 
     n1 = this.R_MAJOR/Math.sqrt(1 - eccs * Math.sin(phi1Rad) * Math.sin(phi1Rad)), 
     t1 = Math.tan(phi1Rad) * Math.tan(phi1Rad), 
     c1 = eccps * Math.cos(phi1Rad) * Math.cos(phi1Rad), 
     r1 = this.R_MAJOR * (1 - eccs)/Math.pow(1 - eccs * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5), 
     d = x/(n1 * k0), 
     lng = ((longOrigin * this.DEG_TO_RAD + ((d - (1 + 2 * t1 + c1) * d * d * d/6 + (5 - 2 * c1 + 28 * t1 - 3 * c1 * c1 + 8 * eccps + 24 * t1 * t1) * d * d * d * d * d/120)/Math.cos(phi1Rad))) * this.RAD_TO_DEG), 
     lat = ((phi1Rad - (n1 * Math.tan(phi1Rad)/r1) * (d * d/2 - (5 + 3 * t1 + 10 * c1 - 4 * c1 * c1 - 9 * eccps) * d * d * d * d/24 + (61 + 90 * t1 + 298 * c1 + 45 * t1 * t1 - 252 * eccps - 3 * c1 * c1) * d * d * d * d * d * d/720)) * this.RAD_TO_DEG); 

    return new L.LatLng(lat, lng); 
    } 
}; 

// Defining the utm crs 
L.CRS.EPSG32633 = L.extend({}, L.CRS.Earth, { 
    code: "EPSG:32633", 
    projection: L.Projection.UTM33, 
    transformation: new L.Transformation(1, 2500000, -1, 9045984), 
    scale: function(zoom) { 
    return 1/(21664/Math.pow(2, zoom)); 
    } 
}); 

// Creating map with the utm crs 
var map = new L.map('map', { 
    crs: L.CRS.EPSG32633, 
    minZoom: 0, 
    maxZoom: 15, 
    zoomControl: true 
}).on("load", function(e) { 
    // Adding utm basemap 
var layer = new L.TileLayer.WMS('https://opencache.statkart.no/gatekeeper/gk/gk.open', { 
    layers: "topo2", 
    format: "image/png", 
    transparent: false, 
    attribution: "© Kartverket" 
}); 

layer.addTo(e.target); 

}).setView([65.276178, 16.683775], 3); 

UPDATE:ここスタックだが私が得るエラーのトレース:

Uncaught Error: Invalid LatLng object: (NaN, NaN) 
    at o.LatLng (https://unpkg.com/[email protected]/dist/leaflet.js:5:14154) 
    at Object.unproject (http://fiddle.jshell.net/thL5bbnv/2/show/:105:12) 
    at Object.pointToLatLng (https://unpkg.com/[email protected]/dist/leaflet.js:5:18431) 
    at e.unproject (https://unpkg.com/[email protected]/dist/leaflet.js:5:30126) 
    at e.layerPointToLatLng (https://unpkg.com/[email protected]/dist/leaflet.js:5:30242) 
    at e._fireDOMEvent (https://unpkg.com/[email protected]/dist/leaflet.js:6:3634) 
    at e._handleDOMEvent (https://unpkg.com/[email protected]/dist/leaflet.js:6:3071) 
    at HTMLDivElement.h (https://unpkg.com/[email protected]/dist/leaflet.js:6:11270) 
    at e._simulateEvent (https://unpkg.com/[email protected]/dist/leaflet.js:8:31479) 
    at e._onMove (https://unpkg.com/[email protected]/dist/leaflet.js:8:31242)o.LatLng @ leaflet.js:5unproject @ (index):105pointToLatLng @ leaflet.js:5unproject @ leaflet.js:5layerPointToLatLng @ leaflet.js:5_fireDOMEvent @ leaflet.js:6_handleDOMEvent @ leaflet.js:6h @ leaflet.js:6_simulateEvent @ leaflet.js:8_onMove @ leaflet.js:8h @ leaflet.js:6 
leaflet.js:5 Uncaught Error: Invalid LatLng object: (NaN, NaN)(…)o.LatLng @ leaflet.js:5unproject @ (index):105pointToLatLng @ leaflet.js:5unproject @ leaflet.js:5layerPointToLatLng @ leaflet.js:5_fireDOMEvent @ leaflet.js:6_handleDOMEvent @ leaflet.js:6h @ leaflet.js:6_simulateEvent @ leaflet.js:8_onMove @ leaflet.js:8h @ leaflet.js:6 

私はズームのピンチがなぜ失敗しているのか、問題を解決するために何ができるのかを理解しようとしています。なぜ誰かがズームをピンチにすると、無効なLatLngオブジェクト(NaN、NaN)が発生するでしょうか?

+1

エラーの完全なスタックトレースがありますか? – IvanSanchez

答えて

2

OK、私はmap.getScaleZoom()への呼び出しにまで問題をトレースしています

debug screenshot

この関数は、あなたが

scale: function(zoom) { 
    return 1/(21664/Math.pow(2, zoom)); 
} 
として定義されているマップのCRSの scale方法、に直接依存

CRSのscaleメソッドは、CRSのzoomメソッドの逆のを実装する必要があります。それはLeaflet API documentation for L.CRSでそう言います。

あなたが代わりにL.CRS.Earth.zoom()を使用している...

L.CRS.EPSG32633 = L.extend({}, L.CRS.Earth, { 

L.CRS.EPSG32633zoom方法を定義しますが、...していません。したがって、xの値でscale(zoom(x))が1でなければ、何も失敗します。まず、ズームレベルが1.01から-19.4にジャンプします。次に、LatLngの値は1e+233になります。その後、あなたの投影コードはそれを取り込み、InfinityNaNを噴出し始め、すべてが炎になります。

L.CRS.EPSG32633の方法のうち、scalezoomを偶数になるように修正してください。


かかわらず、バグの、私はProj4Leaflet代わりに投影コードを自分で実装するのに使用することをお勧めし。テスト済みで、維持されており、既知のEPSG予測とCRSをすべてサポートしています。

+0

これがどのように機能するかについての大きな説明に感謝します。私はあなたの提案に従って、拡大方法を逆にした拡大方法を追加しました。 – stanleycas

関連する問題