Turf.js를 사용하여 지구상 두 점 사이의 거리를 측정하다

입문


작업의 특정 두 점 사이의 거리를 측정할 필요가 있기 때문이다
이전에 다른 PJ에서 사용했던 Turf.js라는 라이브러리가 있어서 해봤어요.

작업 환경

  • node 12.0.0
  • npm 6.9.0
  • Turf.js 6.9.0
  • 전제 조건

  • 여러 곳의 위도, 경도를 데이터로 가지고 있다
  • 데이터가 json 형식의 파일(lists.json)
  • 가능하면 외부 파일로 내보내서 확인하려면
  • 상술한 특정점과의 거리를 측정해야 한다
  • 지구상(구면상) 두 점 사이의 계산
  • lists.json
    [
        {
            "NAME": "名古屋駅",
            "LATITUDE": 35.170406,
            "LONGITUDE": 136.881695,
            "Distance": 267.50358367757696
        },
        {
            "NAME": "大阪駅",
            "LATITUDE": 34.702485,
            "LONGITUDE": 135.495951,
            "Distance": 403.0278954652313
        }
    ]
    

    사전 준비


    우선 이번 작업을 진행하기 위해 목록을 작성해야 합니다.
    mkdir turf_test
    cd turf_test
    

    Turf.js 정보


    참조슬라이드에서 직접 인용한 말
    경량, 고속, 개방형 네트워크 맵 GIS 라이브러리
    하계.
    공식 홈페이지만 봐도 많이 할 수 있어요.
    Turf.공식 사이트
    다양한 부분만 만들 수 있을 뿐, 전부 넣으면 상당한 용량을 가질 수 있다.
    npm install @turf/turf
    
    위의 명령으로 설치하면 호스트와 관련된 라이브러리를 포함하여 17.3MB가 있습니다.
    모두 넣은 상태에서도 사용할 수 있지만 공식 홈페이지를 보면 모듈화가 상당히 철저한 것 같아 용도에 맞는 것만 넣는다.
    나는 여기서 전제조건을 떠올린다.
    기본적으로 2시 사이만 측정하면 되니까 공식 사이트에서 이를 실현할 수 있는 것을 찾았다.
    distance가 그거랑 맞는 것 같아.
    distance 설명
    기재된 설명을 직접 번역하다.(구글 번역 감사합니다)
    Calculates the distance between two points in degrees, radians, miles, or kilometers. This uses the Haversine formula to account for global curvature.
    도, 호도, 마일 또는 킬로미터로 두 점 사이의 거리를 계산하다.Haversine 공식을 사용하여 전체 곡률을 고려합니다.
    설명만 봐도 이번 조건을 충족시킨 것 같다.
    그래서 이걸 설치하려고요.

    distance 구현


    해당 기능에 대한 설명@turf/distance만 봐도 충분하다.
    동적 관찰을 할 때의 축심점.
    npm init
    npm install @turf/distance
    
    참고로 이 모듈만 있으면 131KB밖에 안 돼요.
    우선 공식 게재된 내용을 실행해 보자.
    이번에는 행복의 종착역에서 바로 두드리려고 한다.
    파일을 작성합니다.
    touch index.js
    
    이번에 도쿄역에서 나고야역까지의 거리를 측정하다.
    우선 공식 사이트에 실린 테스트 코드
    테스트 코드
    var from = turf.point([-75.343, 39.984]);
    var to = turf.point([-75.534, 39.123]);
    var options = {units: 'miles'};
    
    var distance = turf.distance(from, to, options);
    
    참고로 공식은 라이브러리가 모두 들어가는 것을 전제로 하는 코드인 것 같아서 다음과 같이 변경합니다.
    index.js
    // turf.js呼び出し
    const { point } = require('@turf/helpers')
    const distance = require('@turf/distance').default
    
    const from = point([139.766765, 35.681283]); //[経度, 緯度] 東京駅
    const to = point([136.881695, 35.170406]); //[経度, 緯度] 名古屋駅
    const options = { units: 'kilometers' }; // degrees, radians, miles, kilometersが指定可能
    
    const result = distance(from, to, options);
    console.log(result) // 267.50358367757696
    
    node index.js
    // consoleに右記が出力 → 267.50358367757696
    
    대략 267Km 정도의 거리가 있다.
    구글맵으로 거리 측정을 해 보세요.

    아마 있을 거예요.

    파일 외부에서 읽기 및 내보내기

  • 여러 곳의 위도, 경도를 데이터로 가지고 있다
  • 데이터가 json 형식의 파일(lists.json)
  • 가능하면 외부 파일로 내보내서 확인하려면
  • 상술한 내용을 포함하여 모두 코드에 빠졌다.
    이 작업을 수행하면 results.json 이 해당 디렉토리에 토출됩니다.
    Node.js에서 외부 파일의 가져오기, 내보내기 설명을 생략합니다.
    index.js
    // turf.js
    const { point } = require('@turf/helpers')
    const distance = require('@turf/distance').default
    
    // 設定ファイルの読み込み
    const fs = require('fs');
    const util = require('util');
    const readFile = util.promisify(fs.readFile);
    let results = []
    
    const now = new Date()
    
    const isNumber = (value => {
      return ((typeof value === 'number') && (isFinite(value)));
    })
    
    let errorTarget = ''
    readFile('lists.json', 'utf-8')
      .then((data) => {
        lists = JSON.parse(data);
    
        lists.forEach((d, index) => {
          if ((d.LONGITUDE && d.LATITUDE) && (isNumber(d.LONGITUDE) && isNumber(d.LATITUDE))) {
            let pt1 = point([139.766765, 35.681283], { 'name': '東京駅' })
            let pt2 = point([Number(d.LONGITUDE), Number(d.LATITUDE)], { 'name': d.name })
    
            const result = distance(pt1, pt2, { units: 'kilometers' })
            d.DISTANCE = result
            results.push(d)
          }
        })
      })
      .catch((err) => {
        console.log(err)
        throw err;
      }).finally(() => {
        fs.writeFileSync(`results.json`, JSON.stringify(results, null, '    '));
      })
    
    
    

    제품


    결국 토해낸 산물은 다음과 같다.
    results.json
    [
        {
            "NAME": "名古屋駅",
            "LATITUDE": 35.170406,
            "LONGITUDE": 136.881695,
            "DISTANCE": 267.50358367757696
        },
        {
            "NAME": "大阪駅",
            "LATITUDE": 34.702485,
            "LONGITUDE": 135.495951,
            "DISTANCE": 403.0278954652313
        }
    ]
    

    총결산


    처음엔 구글 API가 유료인 줄 알았는데 때려야 돼요.
    의외로 간단해서 깜짝 놀랐어요.
    공식 홈페이지만 봐도 상당한 기능을 볼 수 있기 때문에 다른 기능도 활용하고 싶다.
    끝까지 읽어줘서 고마워요.

    참고 자료

  • https://day-journal.com/memo/turf-js-005/

  • https://www.slideshare.net/takahi/javascript-gis-turfjs
  • 좋은 웹페이지 즐겨찾기