[GAS] 두 지점 사이의 경로를 그린 지도 이미지를 스프레드시트에 삽입

소개



이슈 내에서 GoogleMap을 삽입하는 대신 이미지화한 것을 스프레드시트에 삽입하는 프로세스가 있었습니다. Maps.StaticMap 를 사용하면 좋지만, 그 때 임의의 2 지점 사이의 루트도 그릴 필요가 있었기 때문에 루트 검색에는 Maps.DirectionFinder 를 사용했습니다. 본 기사는 그 비망록입니다.

실행 샘플



출발지와 목적지를 입력하고 스크립트를 실행하면 테두리 배치에서 맵 이미지가 삽입됩니다.


상기는 출발지에 東京駅 , 목적지에 スカイツリー 를 지정하고 있습니다. 샘플을 위해, 루트 검색의 이동 수단에 관해서는 대중교통 이용의 TRANSIT 고정으로 해 1 , 복수 후보 중 1번째만을 묘화하고 있습니다.

로직



1-Maps.DirectionFinder로 두 지점 사이의 경로를 가져옵니다.


const directions = Maps.newDirectionFinder()
      .setLanguage('ja')
      .setOrigin(start)
      .setDestination(end)
      .setMode(Maps.DirectionFinder.Mode.TRANSIT) // 公共交通
      .setDepart(new Date())
      .getDirections()

const route = directions.routes[0].overview_polyline.points // エンコードされたルート情報取得

코드중 startend 에는 사전에 취득하고 있는 출발지와 목적지의 값이 들어갑니다 (이번은 도쿄역과 스카이 트리).
directions 는 JSON 형식으로, 이번에 필요한 데이터가 routes 라는 배열로 검색 2 수 있습니다. 후보가 여러 개 있어도 첫 번째 후보만 얻으려고합니다. 이 중, overview_polyline.points 라고 하는 것이, 출발지로부터 목적지까지의 루트 묘화에 필요한 경유 포인트의 위도 경도 정보를 문자열화한 것 3 이 됩니다.

2-Map 설정


const map = new Maps.newStaticMap()
/* 省略 */

map.setSize(800, 450)
  .setLanguage('ja')
  .setPathStyle(4, Maps.StaticMap.Color.RED, null)
  .addPath(route)
Maps.StaticMap 를 이용합니다.
setPathStyle(4, Maps.StaticMap.Color.RED, null) 에서 루트 그리기를 설정합니다. 이번에는 빨간색으로 그립니다. 이번과 같은 인코딩된 데이터 3 가 있는 경우, addPath(route) 로 루트를 paint 합니다. 적절한 형식의 위도 경도 정보 배열 4 에서도 그려집니다.
단순히 2 지점간을 직선으로 그리는 경우에는 다음과 같은 코드가 됩니다.
map.setSize(800, 450)
  /* 省略 */
  .beginPath()
  .addPoint(start)
  .addPoint(end)
  .endPath()

3-PING으로 지정된 셀에 삽입


const Sh  = SpreadsheetApp.getActiveSheet()
const Rng = Sh.getRange('B2:C2')
/* 省略 */

const png = Utilities.newBlob(map.getMapImage(), 'image/png', 'map.png')
const pos = Rng.offset(2,0,1,1)
Sh.insertImage(png, pos.getColumn(), pos.getRow())
Utilities.newBlob() 로 PING 이미지로 변환하고 insertImage() 로 지정된 셀의 왼쪽 위를 시작점으로 삽입합니다.

여담입니다만, insertImage()Range 는 아니고 Sheet 의 메소드군요. 감각적으로는 전자이므로 참조를 보고 당황할 수 있습니다.

또한 변환된 이미지의 링크 URL을 얻으려면 Maps Static API를 이용하기 위한 API 키가 필요합니다.

이번 코드


function insertStaticMap(){
  const map = new Maps.newStaticMap()
  const Sh  = SpreadsheetApp.getActiveSheet()
  const Rng = Sh.getRange('B2:C2') // 出発地と目的地の取得
  const [start, end] = [...Rng.getValues()[0]]

  // 2地点間ルート取得
  const directions = Maps
      .newDirectionFinder()
      .setLanguage('ja')
      .setOrigin(start)
      .setDestination(end)
      .setMode(Maps.DirectionFinder.Mode.TRANSIT) // 公共交通
      .setDepart(new Date())
      .getDirections()

  const route = directions.routes[0].overview_polyline.points // エンコードされたルート情報取得

  // Mapの設定
  map.setSize(800, 450)
  .setLanguage('ja')
  .setPathStyle(4, Maps.StaticMap.Color.RED, null)
  .addPath(route)

  // PINGとして指定セル上に挿入
  const png = Utilities.newBlob(map.getMapImage(), 'image/png', 'map.png')
  const pos = Rng.offset(2,0,1,1)
  Sh.insertImage(png, pos.getColumn(), pos.getRow())
}

입력된 시설명이나 주소에 대해서 에러 판정은 실시하고 있지 않으므로, 참고로 하는 경우는 필요에 따라서 처리를 실장해 주세요. 또, 계속해서 처리를 실행하는 경우, 새롭게 삽입한 화상은 겹쳐서 표시되므로, 이하와 같은 사전 처리가 필요합니다.
const img = Sh.getImages()[0]
if(img)img.remove()

마지막으로



루트 draw 의 필요가 없으면 Maps.DirectionFinder 를 이용한 처리는 불필요합니다. 그 외 마커 스타일이나 줌, 중심 설정등 Maps.StaticMap 로 커스터마이즈 할 수 있는 내용은 공식 참조 를 참조해 주세요.

[참고]


  • Class StaticMap | Apps Script | Google Developers
  • Overview | Maps Static API | Google Developers
  • Class DirectionFinder | Apps Script | Google Developers
  • The Directions API quickstart | Google Developers
  • Encoded Polyline Algorithm Format | Google Maps Platform



  • 지정할 수 있는 이동 수단은 공식 참조을 확인해 주십시오. 셀렉트 메뉴 등에서 선택할 수 있도록 해도 좋다고 생각합니다.

    얻을 수 있는 JSON 형식의 구조 샘플은 공식 문서 에서 확인할 수 있습니다.

    [위도, 경도, ... , 위도, 경도]와 같은 상태로 위도와 경도를 차례로 열거한 1차원 배열을 인코딩한 것이 됩니다. 알고리즘은 여기 로 확인할 수 있습니다.

    3 의 encode 전의 1 차원 배열이 됩니다.

    좋은 웹페이지 즐겨찾기