WEB JS

    웹 개발, 어플리케이션에서 활용될 수 있도록 Javascript로 제공되는 지도 플랫폼 입니다.

    Geo-fencing 생성

    소개

    이 튜토리얼에서는 사용자 위치를 이용하여 구역 검색 API(행정 면형 정보 API) 호출, 그 결과를 토대로 행정경계를 표시하고 어느 행정경계에 포함되는지 안내하는 과정에 대해 설명합니다.

    준비

    1. 기본 지도 생성

    기본 지도를 생성합니다.

    // js
    $(function () {
      // 1. 기본 지도 생성
      const options = {
        // 지도 초기 위치
        center: { lat : 37.5100, lng: 127.0504 },
        // 지도 로딩 시 최초 표시 레벨
        zoom: 16,
        // 지도 최소 표시 레벨
        minZoom: 7,
        // 지도 최대 표시 레벨
        maxZoom: 19,
        // 지도 회전 제한 여부
        blockRotation: true,
        // 지도에서 keyboard의 Event를 받을 Target 결정
        keyboardEventTarget: document,
        // Marker를 표시할 레이어의 z-index 
        markerZIndex: 504,
        // Zoom in/out 시 resolution에 따라 고정할 것인지 여부
        constrainResolution: true,
        // 지도가 표시할 영역을 지정 (국내영역 / 해당 영역 밖으로 이동 불가)
        restriction: { west: 124.60, south: 33.114, east: 131.875, north: 42.59 },
        // routo logo 위치 지정 : leftTop, leftBottom, rightTop, rightBottom
        logoPosition: 'leftBottom',
        // routo logo의 상단 또는 하단의 margin 값
        logoPositionMargin: 0
      };
      const map = new routo.maps.Map('map', options);
    });
    
    <!-- html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="map" style="width:100%;height:500px;"></div>
    </body>
    </html>
    

    2. 현재 사용자의 위치 표시

    Javascript navigator.geolocation를 이용하여 현재 사용자의 위치를 지도에 마커로 표시합니다.

    // js
    $(function () {
      // 1. 기본 지도 생성
      const options = {
        // 지도 초기 위치
        center: { lat : 37.5100, lng: 127.0504 },
        // 지도 로딩 시 최초 표시 레벨
        zoom: 16,
        // 지도 최소 표시 레벨
        minZoom: 7,
        // 지도 최대 표시 레벨
        maxZoom: 19,
        // 지도 회전 제한 여부
        blockRotation: true,
        // 지도에서 keyboard의 Event를 받을 Target 결정
        keyboardEventTarget: document,
        // Marker를 표시할 레이어의 z-index 
        markerZIndex: 504,
        // Zoom in/out 시 resolution에 따라 고정할 것인지 여부
        constrainResolution: true,
        // 지도가 표시할 영역을 지정 (국내영역 / 해당 영역 밖으로 이동 불가)
        restriction: { west: 124.60, south: 33.114, east: 131.875, north: 42.59 },
        // routo logo 위치 지정 : leftTop, leftBottom, rightTop, rightBottom
        logoPosition: 'leftBottom',
        // routo logo의 상단 또는 하단의 margin 값
        logoPositionMargin: 0
      };
      const map = new routo.maps.Map('map', options);
    
      // 2. 현재 사용자의 위치 표시
      const getLocation = () => {
        if (navigator.geolocation) { // GPS를 지원하면
          navigator.geolocation.getCurrentPosition(function(position) {
            // 좌표 표시
            $('#coordinates').html(`<p style="margin-top:10px;font-size:15px;text-align: left;">현재 사용자 위치: ${position.coords.latitude + ' ' + position.coords.longitude}</p>`);
    
            // 마커 추가
            const lng = position.coords.longitude;
            const lat = position.coords.latitude;
    
            const markerOption = {
              position: {
                lat: lat,
                lng: lng
              },
              map: map
            };
    
            const userPositionMarker = new routo.maps.Marker(markerOption);
    
            // 마커로 지도 이동
            map.setCenter(markerOption.position);
    
          }, function(error) {
            console.error(error);
          }, {
            enableHighAccuracy: false,
            maximumAge: 0,
            timeout: Infinity
          });
        } else {
          alert('GPS를 지원하지 않습니다');
        }
      }
      getLocation();
    });
    
    <!-- html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="map" style="width:100%;height:500px;"></div>
        <div id="coordinates" style="background-color: beige;"></div>
    </body>
    </html>
    

    3. 구역 검색 API를 이용한 행정경계 표시

    사용자 위치 기반으로 구역 검색 API를 호출하여 행정경계 Polygon을 지도에 표시합니다.

    // js
    $(function () {
      // 1. 기본 지도 생성
      const options = {
        // 지도 초기 위치
        center: { lat : 37.5100, lng: 127.0504 },
        // 지도 로딩 시 최초 표시 레벨
        zoom: 16,
        // 지도 최소 표시 레벨
        minZoom: 7,
        // 지도 최대 표시 레벨
        maxZoom: 19,
        // 지도 회전 제한 여부
        blockRotation: true,
        // 지도에서 keyboard의 Event를 받을 Target 결정
        keyboardEventTarget: document,
        // Marker를 표시할 레이어의 z-index 
        markerZIndex: 504,
        // Zoom in/out 시 resolution에 따라 고정할 것인지 여부
        constrainResolution: true,
        // 지도가 표시할 영역을 지정 (국내영역 / 해당 영역 밖으로 이동 불가)
        restriction: { west: 124.60, south: 33.114, east: 131.875, north: 42.59 },
        // routo logo 위치 지정 : leftTop, leftBottom, rightTop, rightBottom
        logoPosition: 'leftBottom',
        // routo logo의 상단 또는 하단의 margin 값
        logoPositionMargin: 0
      };
      const map = new routo.maps.Map('map', options);
    
      // 2. 현재 사용자의 위치 표시
      const getLocation = () => {
        if (navigator.geolocation) { // GPS를 지원하면
          navigator.geolocation.getCurrentPosition((position) => {
            // 좌표 표시
            $('#coordinates').html(`<p style="margin-top:10px;font-size:15px;text-align: left;">현재 사용자 위치: ${position.coords.latitude + ' ' + position.coords.longitude}</p>`);
            
            // 마커 추가
            const lng = position.coords.longitude;
            const lat = position.coords.latitude;
    
            const markerOption = {
              position: {
                lat: lat,
                lng: lng
              },
              map: map
            };
    
            const userPositionMarker = new routo.maps.Marker(markerOption);
    
            // 마커로 지도 이동
            map.setCenter(markerOption.position);
    
            // 3.구역 검색 API를 이용한 행정경계 표시
            callDistrict(markerOption.position);
    
          }, function(error) {
            console.error(error);
          }, {
            enableHighAccuracy: false,
            maximumAge: 0,
            timeout: Infinity
          });
        } else {
          alert('GPS를 지원하지 않습니다');
        }
      }
      getLocation();
    
    
      // 구역 검색 API를 이용한 행정경계 표시
      const callDistrict = (position) => {
        const key = `12290cd4-7094-43e8-a936-8819196d0332`;
        const districtApiUrl = `https://api.routo.com/v1/district?latlng=${position.lat},${position.lng}&kind=gemd&option=shape&key=${key}`;
        fetch(districtApiUrl).then(function(response) {
          return response.json();
        }).then(function(data) {
          // 행정경계 생성
          const prop = { ...data };
          delete prop.geometry;
    
          // Geometry 좌표 타입 변환(Array => LatLng)
          const convertGeom = [];
          for(let i in data.geometry.coordinates){
            const coordinates = data.geometry.coordinates[i];
            const coords = [];
            for(let j in coordinates){
              const coord = coordinates[j];
              const latlng = new routo.maps.LatLng(coord[1], coord[0]);
              const latlngJson = latlng.toJSON();
              coords.push(latlngJson);
            }
            convertGeom.push(coords);
          }
    
          // Polygon 생성
          const polygon = new routo.maps.Data.Polygon(convertGeom);
    
          // 행정경계 추가
          map.data.add({
            id: 1,
            geometry: polygon,
            properties: prop
          });
    
          // 지도 이동
          map.fitBounds(polygon.getBounds(), [100, 100, 100, 100]);
        }).catch(function(error) {
          console.log(error);
        });
      }
    });
    
    <!-- html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="map" style="width:100%;height:500px;"></div>
    </body>
    </html>
    

    4. 결과 확인

    사용자 위치가 현재 어떤 행정경계에 속하였는지 표시합니다.

    // js
    $(function () {
      // 1. 기본 지도 생성
      const options = {
        // 지도 초기 위치
        center: { lat : 37.5100, lng: 127.0504 },
        // 지도 로딩 시 최초 표시 레벨
        zoom: 16,
        // 지도 최소 표시 레벨
        minZoom: 7,
        // 지도 최대 표시 레벨
        maxZoom: 19,
        // 지도 회전 제한 여부
        blockRotation: true,
        // 지도에서 keyboard의 Event를 받을 Target 결정
        keyboardEventTarget: document,
        // Marker를 표시할 레이어의 z-index 
        markerZIndex: 504,
        // Zoom in/out 시 resolution에 따라 고정할 것인지 여부
        constrainResolution: true,
        // 지도가 표시할 영역을 지정 (국내영역 / 해당 영역 밖으로 이동 불가)
        restriction: { west: 124.60, south: 33.114, east: 131.875, north: 42.59 },
        // routo logo 위치 지정 : leftTop, leftBottom, rightTop, rightBottom
        logoPosition: 'leftBottom',
        // routo logo의 상단 또는 하단의 margin 값
        logoPositionMargin: 0
      };
      const map = new routo.maps.Map('map', options);
    
      // 2. 현재 사용자의 위치 표시
      const getLocation = () => {
        if (navigator.geolocation) { // GPS를 지원하면
          navigator.geolocation.getCurrentPosition((position) => {
            // 좌표 표시
            $('#coordinates').html(`<p style="margin-top:10px;font-size:15px;text-align: left;">현재 사용자 위치: ${position.coords.latitude + ' ' + position.coords.longitude}</p>`);
    
            // 마커 추가
            const lng = position.coords.longitude;
            const lat = position.coords.latitude;
    
            const markerOption = {
              position: {
                lat: lat,
                lng: lng
              },
              map: map
            };
    
            const userPositionMarker = new routo.maps.Marker(markerOption);
    
            // 마커로 지도 이동
            map.setCenter(markerOption.position);
    
            // 3.구역 검색 API를 이용한 행정경계 표시
            callDistrict(markerOption.position);
    
          }, function(error) {
            console.error(error);
          }, {
            enableHighAccuracy: false,
            maximumAge: 0,
            timeout: Infinity
          });
        } else {
          alert('GPS를 지원하지 않습니다');
        }
      }
      getLocation();
    
    
      // 구역 검색 API를 이용한 행정경계 표시
      const callDistrict = (position) => {
        const key = `12290cd4-7094-43e8-a936-8819196d0332`;
        const districtApiUrl = `https://api.routo.com/v1/district?latlng=${position.lat},${position.lng}&kind=gemd&option=shape&key=${key}`;
        fetch(districtApiUrl).then(function(response) {
          return response.json();
        }).then(function(data) {
          // 행정경계 생성
          const prop = { ...data };
          delete prop.geometry;
    
          // Geometry 좌표 타입 변환(Array => LatLng)
          const convertGeom = [];
          for(let i in data.geometry.coordinates){
            const coordinates = data.geometry.coordinates[i];
            const coords = [];
            for(let j in coordinates){
              const coord = coordinates[j];
              const latlng = new routo.maps.LatLng(coord[1], coord[0]);
              const latlngJson = latlng.toJSON();
              coords.push(latlngJson);
            }
            convertGeom.push(coords);
          }
    
          // Polygon 생성
          const polygon = new routo.maps.Data.Polygon(convertGeom);
    
          // 행정경계 추가
          map.data.add({
            id: 1,
            geometry: polygon,
            properties: prop
          });
    
          // 지도 이동
          map.fitBounds(polygon.getBounds(), [100, 100, 100, 100]);
    
          // 4. 결과 확인
          let tag = `당신은 ${prop['state']} ${prop['city']} ${prop['town']} 에 있습니다.`;
          for(let k in prop){
            const attr = k;
            const value = prop[k];
            tag += `<p style="margin-top:10px;font-size:15px;text-align: left;">- ${attr}: ${value}</p>`;
          }
          $('#result').html(tag);
        }).catch(function(error) {
          console.log(error);
        });
      }
    });
    
    <!-- html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="map" style="width:100%;height:500px;"></div>
        <div id="result" style="background-color: beige;"></div>
    </body>
    </html>