2016-12-14 2 views
0

저는 OpenLayers 3를 사용하여 고해상도 이미지를 깊이 확대 (지리적 좌표가없고 픽셀 만)합니다.OpenLayers에서 크기가 다른 두 번째 레이어를 추가하는 방법은 무엇입니까?

XYZ은 투영으로 필요한 형식이지만 다른 투영법을 사용해야하므로 하나 이상의 타일링 된 레이어를 추가하는 데 문제가 있습니다. 즉, 내 메인 레이어의 크기는 (X) x (Y)가 픽셀이지만 두 번째 레이어의 크기는 (X * k) x (Y * k)입니다. 따라서 레이어가 서로 일치하지 않습니다. 타일 ​​크기는 두 경우 모두 같습니다. 여기

코드입니다 :

const imWidth = 100440; 
const imHeight = 221312; 

const primaryImageProjection = new ol.proj.Projection({ 
    code: 'PIXELS', 
    units: 'pixels', 
    extent: [0, 0, imWidth, imHeight], 
    getPointResolution: function (resolution, point) { 
    return resolution; 
    } 
}); 
ol.proj.addProjection(primaryImageProjection); 

var heatMapProj = new ol.proj.Projection({ 
    code: 'HEATMAP', 
    units: 'pixels', 
    extent: [0, 0, imWidth, imWidth], 
    getPointResolution: function (resolution, point) { 
    return resolution; 
    } 
}); 
ol.proj.addProjection(heatMapProj); 

const koef = 21.5; 
ol.proj.addCoordinateTransforms('PIXELS', 'HEATMAP', 
    function (coordinate) { 
    return [coordinate[0] * koef, coordinate[1] * koef]; 
    }, 
    function (coordinate) { 
    return [coordinate[0]/koef, coordinate[1]/koef]; 
    }); 

this.map = new ol.Map({ 
    layers: [ 
    new ol.layer.Tile({ 
     source: new ol.source.XYZ({ 
     crossOrigin: crossOrigin, 
     tileSize: [512, 512], 
     tileUrlFunction: (tileCoord, pixelRatio, projection) => { 
      const tileUrlTemplate = 'http://.../?lvl={z}&tx={x}&ty={y}'; 
      const z = 9 - tileCoord[0]; 
      const tileUrl = tileUrlTemplate 
      .replace("{z}", (z).toString()) 
      .replace("{x}", (tileCoord[1]).toString()) 
      .replace("{y}", (((-tileCoord[2]) - 1)).toString()); 
      return tileUrl; 
     }, 
     projection: 'PIXELS' 
     }) 
    }), 
    new ol.layer.Tile({ 
     source: new ol.source.XYZ({ 
     crossOrigin: crossOrigin, 
     tileSize: [512, 512], 
     tileUrlFunction: (tileCoord, pixelRatio, projection) => { 
      const heatMapUrlTemplate = 'http://...?lvl={z}&tx={x}&ty={y}'; 
      var z = 4 - tileCoord[0]; 
      const heatMapUrl = heatMapUrlTemplate 
      .replace('{z}', (z).toString()) 
      .replace('{x}', (tileCoord[1]).toString()) 
      .replace('{y}', (((-tileCoord[2]) - 1)).toString()); 
      return heatMapUrl; 
     }, 
     projection: 'HEATMAP' 
     }), 
     opacity: 0.5 
    }) 
    ], 
    controls: [], 
    target: this.mapSelector, 
    renderer: "canvas", 
    view: new ol.View({ 
    projection: 'PIXELS' 
    }) 
}); 

어떻게이 문제를 해결할 수 있습니까? 어쩌면 예상은 올바른 방법이 아니며 다르게 해결 될 수도 있습니다.

추신 : 내가 getPointResolution 함수를 사용하고 있음을 알 수 있습니다. 그렇지 않으면 콘솔에 "변환을 정의해야합니다"라는 오류 메시지가 표시됩니다. 그리고 dubugging 후 OpenLayers가 내 계획에서 내부적으로 "EPSG : 4326"으로 변형 된 것을 발견했습니다. 평면 이미지 만 사용하고 있기 때문에 구형 좌표를 가질 것으로 기대하지는 않지만 OpenLayers가 필요로하는 것처럼 보입니다.

답변

0

래스터 재 투영 (예 :지도의 여러 투영법)은 실험적 기능이 아닙니다. 하지만 효과를 내기 위해서는 ol.proj.addCoordinateTransforms을 사용하여 레이어의 투영간에 변환 함수를 등록해야합니다. 코드를 보지 않고는 추측하기 어려운이지만,이 같은 트릭 수행해야합니다

var proj1 = new ol.proj.Projection({ 
    code: 'ZOOMIFY1', 
    units: 'pixels', 
    extent: [0, -Y, X, 0] 
}); 
var proj2 = new ol.proj.Projection({ 
    code: 'ZOOMIFY2', 
    units: 'pixels', 
    extent: [0, -Y * k, X * k, 0] 
}); 

ol.proj.addCoordinateTransforms(proj1, proj2, 
    function(coordinate) { 
     return [coordinate[0] * k, coordinate[1] * k]; 
    }, 
    function(coordinate) { 
     return [coordinate[1]/k, coordinate[2]/k]; 
    }); 

지금 당신은 당신이 개 Zoomify 레이어를 구성, 앞서 갈 수 있습니다 - 프로젝션으로 proj1와 제 proj2와 두 번째, 그리고 그들은 잘 정렬해야합니다.

위의 내용은 테스트되지 않았습니다. 작동중인 스 니펫이나 JSFiddle을 제공 할 수 있다면 무언가가 작동하지 않는 경우 제 답변을 수정할 수 있습니다.

+0

고마워요! 코드를 추가하고 동시에 Zoomify에서 XYZ로 전환했습니다. 불행히도 JSFIddle-sample은 이미지 소스가 내부에 있기 때문에 문제가됩니다. 그리고 addCoordinateTransforms는 k = 1을 사용하더라도 나에게 올바른 그림을 생성하지 않습니다. 이미지는 여전히 정렬되지 않습니다. – murad

+0

안녕하세요. 다시 한 번! 이 경우 jsfiddle을 준비했습니다. https://jsfiddle.net/x3jdc1kr/ 한번보세요. 타일의 숫자는 현재 확대/축소 수준에 해당합니다. – murad

관련 문제