국토 지리원의 고도 타일을 자바 스크립트로 제대로 얻으십시오.

추가
파이썬 버전도 썼다.
국토 지리원의 고도 타일을 파이썬으로 가져 오기 - Qiita

1. 지리원 타일에 대해서



1.1. 개요



타일 ​​좌표를 지정하여 특정 URL에 요청을 던지면 지도 이미지나 고도 등 다양한 종류의 타일을 얻을 수 있다. URL은 타일의 종류마다 다르고, 일람은 지리원 타일 목록 로 확인할 수 있다.

1.2. 고도 타일



명칭대로 각 지점의 고도가 기재된 타일로, 사양은 고도 타일의 상세 사양 에 기재되어 있다.
각각의 타일은 $256\times 256$픽셀로, 텍스트 형식과 PNG 형식이 제공되고 있지만, 이하에서는 간단하기 위해 텍스트 형식을 취급한다.

주의점


  • 단순히 표고가 콤마 단락으로 기재되고 있을 뿐이지만, 표고치가 존재하지 않는 화소(바다 등)는 「e」의 문자가 들어가 있는 것에 주의.

  • 지리원 타일 목록 를 보면 DEM5A , DEM5B , DEM10B , DEMGM 등 여러 종류의 고도 타일이 제공되고 있다. 각각 대응하는 줌 레벨이나 측량 방법·정확도가 다르므로 고도 값에 대해을 읽고 적절한 것을 선택하는 것.
  • 동쪽 방향이 X, 남쪽 방향이 Y로되어 있으며 디스플레이의 좌표계와 궁합이 좋다

  • 2. 구현



    Fetch API 을 이용하여 아래와 같은 fetchTile 함수를 사용하면 다루기 쉽다.
  • 쉼표로 구분 된 텍스트 형식으로 얻은 응답을 줄 바꿈 코드로 줄로 나눕니다
  • 각 행은 쉼표로 더 나누어집니다
  • 고도 수치는 Float로 변환
  • "e"문자(예: 바다)를 고도 0[m]으로 변환

  • 등의 전처리를 행하여, 2차원 배열로서 타일을 취득할 수 있도록 하고 있다.
    function fetchTile(coord) {
        return new Promise(resolve => {
            fetch(`https://cyberjapandata.gsi.go.jp/xyz/dem/${coord.z}/${coord.x}/${coord.y}.txt`)
                .then(response => response.text())
                .then(text => text.split("\n"))
                .then(rows => rows.slice(0, rows.length - 1)) // Last row: empty
                .then(rows => rows.map(r => r.split(",").map(d => d === "e" ? 0 : parseFloat(d)))) // e: sea
                .then(data => resolve(data))
                .catch(error => {throw error});
        });
    }
    

    이 구현에서는 DEM10B의 고도 타일(대응하는 줌 레벨이 0-14로 가장 넓은)을 취득하고 있지만, 필요에 따라서 URL의 부분을 변경(혹은 fetchTile의 인수로 지정할 수 있도록 수정) 한다 좋다.

    3. 타일 취득 방법



    3.1. fetchTile 함수 사용법



    타일 ​​좌표를 앞에서 설명한 fetchTile 함수에 주어 다음과 같이 한다.
    const nabewariTile = {z: 13, x: 7262, y: 3232}; // 鍋割山のタイル座標
    fetchTile(nabewariTile).then(d => {
        // dを利用
    });
    

    3.2. 타일 좌표를 확인하는 방법



    (1) 육안으로 확인



    지도에서 타일 좌표를 확인하고 싶으면 타일 ​​좌표 확인 페이지 가 편리.
    예를 들어 냄비 할산은

    되어 있다.

    (2) 위도 경도로부터 계산



    어느 지점의 위도 경도를 지정하고, 그 지점이 속하는 타일 좌표를 알고 싶은 경우, 이하와 같은 함수를 준비한다.
    function getTileCoords(lat, lon, zoom) {
        const xTile = parseInt(Math.floor((lon + 180) / 360 * (1 << zoom)));
        const yTile = parseInt(Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * (1 << zoom)));
        return { "z": zoom, "x": xTile, "y": yTile };
    }
    

    이상

    좋은 웹페이지 즐겨찾기