728x90
웹사이트에 지도 추가하기(자바스크립트)
https://developers.google.com/codelabs/maps-platform/maps-platform-101-js?hl=ko#0
1.시작하기 전에
자바스크립트로 구글 맵스에 몇 개의 핀을 찍어서 렌더링 해주는 작업을 해보자.
수행하는 내용
- Maps JavaScript API 동적으로 로드
- 첫 지도 로드
- 마커 및 마커 클러스터링 사용
- Maps JavaScript API 이벤트 시스템 사용하여 사용자 상호작용 제공
- 동적으로 지도 조정
- 지도에 그리기
2. 사전 준비사항
이게 필요하다
- Maps JavaScript API
- MarkerClustererPlus 오픈소스 마커 클러스터링 라이브러리
3. 설정하기
- API키 만들기
- 마켓 플레이스에서 Google Maps Platform API 및 SDK 설정. https://console.cloud.google.com/marketplace?hl=ko
프로젝트 파일을 가져온 뒤에, /starter 경로에서 npm 패키지들을 npm install로 설치하고, npm start로 실행해주자.
package.json
{
"name": "codelab-js-maps-api-101",
"version": "1.0.0",
"description": "An example app to accompany the Google Maps Platform 101: JavaScript codelab",
"main": "/src/app.js",
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Alex Muramoto",
"license": "Apache-2.0",
"dependencies": {
"@google/markerclustererplus": "^5.0.3",
"@googlemaps/js-api-loader": "^1.12.1",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
}
}
참고로 코드 위에서 자바스크립트를 쓰려면 위 패키지들을 설치해야 한다.
https://www.npmjs.com/package/@googlemaps/map-loader
4. Maps JavaScript API 로드
웹용 구글 맵스 플랫폼을 사용하기 위해서는 Maps JavaScript API를 사용한다고 한다. 이 API 덕분에 지도, 마커, 그리기 등을 자바스크립트로 제어할 수 있다.
5. 지도 표시하기
// get Loader class from package import { Loader } from "@googlemaps/js-api-loader"; // create apiOptions obj const apiOptions = { apiKey: "AIzaSyAOpVCT2pyx9Y4gOz3VHodjLEhLfdl56cU", }; const loader = new Loader(apiOptions); // Promise loader.load().then(() => { console.log("Mas JS API Loaded!"); const map = displayMap(); }); function displayMap() { const mapOptions = { center: { lat: -33.860664, lng: 151.208138 }, zoom: 14, }; const mapDiv = document.getElementById("map"); // Create instance of Google.maps.Map // - To create new map to mark something const map = new google.maps.Map(mapDiv, mapOptions); return map; } |
promise를 위해 loader.load().then()으로 해야한다. 튜토리얼에서는 load()가 빠져있다.
6. 클라우드 기반 지도 스타일 지정(선택)
7. 지도에 마커 추가하기
/** * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Loader } from "@googlemaps/js-api-loader"; import MarkerClusterer from "@google/markerclustererplus"; // Toilet Data SEOUL // https://data.seoul.go.kr/dataList/OA-365/S/1/datasetView.do const API_KEY = "5761714251736c61313131596d466857"; // // 변수명 타입 변수설명 값설명 // KEY String(필수) 인증키 OpenAPI 에서 발급된 인증키 // TYPE String(필수) 요청파일타입 xml : xml, xml파일 : xmlf, 엑셀파일 : xls, json파일 : json // SERVICE String(필수) 서비스명 GeoInfoPublicToiletWGS // START_INDEX INTEGER(필수) 요청시작위치 정수 입력 (페이징 시작번호 입니다 : 데이터 행 시작번호) // END_INDEX INTEGER(필수) 요청종료위치 정수 입력 (페이징 끝번호 입니다 : 데이터 행 끝번호) // OBJECTID NUMBER(선택) 고유번호 고유번호 let testVar; async function getData() { const url = `http://openapi.seoul.go.kr:8088/${API_KEY}/json/GeoInfoPublicToiletWGS/1/1000`; const response = await fetch(url); const data = await response.json(); const row = data["GeoInfoPublicToiletWGS"]["row"]; const toiletData = {}; for (let i = 0; i < row.length; i++) { toiletData[i] = { // row[i]["GU_NM"], // row[i]["HNR_NAM"], lat: Number(row[i]["LAT"]), lng: Number(row[i]["LNG"]), }; } // return toiletData; console.log(toiletData); } getData(); // Google Maps API const apiOptions = { apiKey: "AIzaSyAOpVCT2pyx9Y4gOz3VHodjLEhLfdl56cU", }; const loader = new Loader(apiOptions); loader.load().then(() => { console.log("Maps JS API loaded"); const watchID = navigator.geolocation.watchPosition((pos) => { const userCenter = [pos.coords.latitude, pos.coords.longitude]; console.log(userCenter); const map = displayMap(userCenter); const markers = addMarkers(map); clusterMarkers(map, markers); addPanToMarker(map, markers); }); }); function displayMap(userCenter) { const mapOptions = { center: { lat: userCenter[0], lng: userCenter[1] }, zoom: 17, mapId: "YOUR_MAP_ID", }; const mapDiv = document.getElementById("map"); return new google.maps.Map(mapDiv, mapOptions); } function addMarkers(map) { // const locations = { // operaHouse: { lat: -33.8567844, lng: 151.213108 }, // tarongaZoo: { lat: -33.8472767, lng: 151.2188164 }, // manlyBeach: { lat: -33.8209738, lng: 151.2563253 }, // hyderPark: { lat: -33.8690081, lng: 151.2052393 }, // theRocks: { lat: -33.8587568, lng: 151.2058246 }, // circularQuay: { lat: -33.858761, lng: 151.2055688 }, // harbourBridge: { lat: -33.852228, lng: 151.2038374 }, // kingsCross: { lat: -33.8737375, lng: 151.222569 }, // botanicGardens: { lat: -33.864167, lng: 151.216387 }, // museumOfSydney: { lat: -33.8636005, lng: 151.2092542 }, // maritimeMuseum: { lat: -33.869395, lng: 151.198648 }, // kingStreetWharf: { lat: -33.8665445, lng: 151.1989808 }, // aquarium: { lat: -33.869627, lng: 151.202146 }, // darlingHarbour: { lat: -33.87488, lng: 151.1987113 }, // barangaroo: { lat: -33.8605523, lng: 151.1972205 }, // }; const locations = { 0: { lat: 37.5014009, lng: 127.1586471 }, 1: { lat: 37.6449368, lng: 127.0737283 }, ..., 997: { lat: 37.5798176, lng: 126.8142929 }, 998: { lat: 37.5437052, lng: 126.8452413 }, 999: { lat: 37.5472954, lng: 126.8740311 }, }; const markers = []; for (const location in locations) { const markerOptions = { map: map, position: locations[location], icon: "./img/custom_pin.png", }; const marker = new google.maps.Marker(markerOptions); markers.push(marker); } return markers; } function clusterMarkers(map, markers) { const clustererOptions = { imagePath: "./img/m" }; const markerCluster = new MarkerClusterer(map, markers, clustererOptions); } function addPanToMarker(map, markers) { let circle; markers.map((marker) => { marker.addListener("click", (event) => { const location = { lat: event.latLng.lat(), lng: event.latLng.lng() }; map.panTo(location); if (circle) { circle.setMap(null); } circle = drawCircle(map, location); }); }); } function drawCircle(map, location) { const circleOptions = { strokeColor: "#FF0000", strokeOpacity: 0.5, strokeWeight: 1, map: map, center: location, radius: 100, }; const circle = new google.maps.Circle(circleOptions); return circle; } |
구글 Maps API 사용법
https://www.daleseo.com/google-maps-api/
<!DOCTYPE html> <html> <head> <title>Simple Map</title> <meta name="viewport" content="initial-scale=1.0"> <meta charset="utf-8"> <link href="styles.css" rel="stylesheet"> <script src="app.js"></script> <script defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAOpVCT2pyx9Y4gOz3VHodjLEhLfdl56cU&callback=initMap" ></script> </head> <body> <div style="height: 600px" id="map"></div> </body> </html> |
완성본
window.initMap = function () { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 37.5400456, lng: 126.9921017 }, zoom: 10, }); const malls = [ { label: "C", name: "코엑스몰", lat: 37.5115557, lng: 127.0595261 }, { label: "G", name: "고투몰", lat: 37.5062379, lng: 127.0050378 }, { label: "D", name: "동대문시장", lat: 37.566596, lng: 127.007702 }, { label: "I", name: "IFC몰", lat: 37.5251644, lng: 126.9255491 }, { label: "L", name: "롯데월드타워몰", lat: 37.5125585, lng: 127.1025353 }, { label: "M", name: "명동지하상가", lat: 37.563692, lng: 126.9822107 }, { label: "T", name: "타임스퀘어", lat: 37.5173108, lng: 126.9033793 }, ]; // create boundary obj const bounds = new google.maps.LatLngBounds(); // information window pop up when clicked const infowindow = new google.maps.InfoWindow(); malls.forEach(({ label, name, lat, lng }) => { const marker = new google.maps.Marker({ position: { lat, lng }, label, map: map, }); bounds.extend(marker.position); marker.addListener("click", () => { map.panTo(marker.position); // move center to clicked marker infowindow.setContent(name); infowindow.open({ anchor: marker, map, }); }); }); map.fitBounds(bounds); }; |
마커로 위치 표시
window.initMap = function () { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 37.5400456, lng: 126.9921017 }, zoom: 10, }); const malls = [ { label: "C", name: "코엑스몰", lat: 37.5115557, lng: 127.0595261 }, { label: "G", name: "고투몰", lat: 37.5062379, lng: 127.0050378 }, { label: "D", name: "동대문시장", lat: 37.566596, lng: 127.007702 }, { label: "I", name: "IFC몰", lat: 37.5251644, lng: 126.9255491 }, { label: "L", name: "롯데월드타워몰", lat: 37.5125585, lng: 127.1025353 }, { label: "M", name: "명동지하상가", lat: 37.563692, lng: 126.9822107 }, { label: "T", name: "타임스퀘어", lat: 37.5173108, lng: 126.9033793 }, ]; // create boundary obj const bounds = new google.maps.LatLngBounds(); // information window pop up when clicked const infowindow = new google.maps.InfoWindow(); malls.forEach(({ label, name, lat, lng }) => { const marker = new google.maps.Marker({ position: { lat, lng }, label, map: map, }); bounds.extend(marker.position); marker.addListener("click", () => { map.panTo(marker.position); // move center to clicked marker infowindow.setContent(name); infowindow.open({ anchor: marker, map, }); }); }); map.fitBounds(bounds); }; |
지도 경계 조정
마커 위치를 고려하여 딱 맞게 지도를 축소하기
window.initMap = function () { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 37.5400456, lng: 126.9921017 }, zoom: 10, }); const malls = [ { label: "C", name: "코엑스몰", lat: 37.5115557, lng: 127.0595261 }, { label: "G", name: "고투몰", lat: 37.5062379, lng: 127.0050378 }, { label: "D", name: "동대문시장", lat: 37.566596, lng: 127.007702 }, { label: "I", name: "IFC몰", lat: 37.5251644, lng: 126.9255491 }, { label: "L", name: "롯데월드타워몰", lat: 37.5125585, lng: 127.1025353 }, { label: "M", name: "명동지하상가", lat: 37.563692, lng: 126.9822107 }, { label: "T", name: "타임스퀘어", lat: 37.5173108, lng: 126.9033793 }, ]; // create boundary obj const bounds = new google.maps.LatLngBounds(); // information window pop up when clicked const infowindow = new google.maps.InfoWindow(); malls.forEach(({ label, name, lat, lng }) => { const marker = new google.maps.Marker({ position: { lat, lng }, label, map: map, }); bounds.extend(marker.position); marker.addListener("click", () => { map.panTo(marker.position); // move center to clicked marker infowindow.setContent(name); infowindow.open({ anchor: marker, map, }); }); }); map.fitBounds(bounds); }; |
클릭 시 정보 보여주기
window.initMap = function () { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 37.5400456, lng: 126.9921017 }, zoom: 10, }); const malls = [ { label: "C", name: "코엑스몰", lat: 37.5115557, lng: 127.0595261 }, { label: "G", name: "고투몰", lat: 37.5062379, lng: 127.0050378 }, { label: "D", name: "동대문시장", lat: 37.566596, lng: 127.007702 }, { label: "I", name: "IFC몰", lat: 37.5251644, lng: 126.9255491 }, { label: "L", name: "롯데월드타워몰", lat: 37.5125585, lng: 127.1025353 }, { label: "M", name: "명동지하상가", lat: 37.563692, lng: 126.9822107 }, { label: "T", name: "타임스퀘어", lat: 37.5173108, lng: 126.9033793 }, ]; // create boundary obj const bounds = new google.maps.LatLngBounds(); // information window pop up when clicked const infowindow = new google.maps.InfoWindow(); malls.forEach(({ label, name, lat, lng }) => { const marker = new google.maps.Marker({ position: { lat, lng }, label, map: map, }); bounds.extend(marker.position); marker.addListener("click", () => { map.panTo(marker.position); // move center to clicked marker infowindow.setContent(name); infowindow.open({ anchor: marker, map, }); }); }); map.fitBounds(bounds); }; |
지도 중심 이동하기
window.initMap = function () { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 37.5400456, lng: 126.9921017 }, zoom: 10, }); const malls = [ { label: "C", name: "코엑스몰", lat: 37.5115557, lng: 127.0595261 }, { label: "G", name: "고투몰", lat: 37.5062379, lng: 127.0050378 }, { label: "D", name: "동대문시장", lat: 37.566596, lng: 127.007702 }, { label: "I", name: "IFC몰", lat: 37.5251644, lng: 126.9255491 }, { label: "L", name: "롯데월드타워몰", lat: 37.5125585, lng: 127.1025353 }, { label: "M", name: "명동지하상가", lat: 37.563692, lng: 126.9822107 }, { label: "T", name: "타임스퀘어", lat: 37.5173108, lng: 126.9033793 }, ]; // create boundary obj const bounds = new google.maps.LatLngBounds(); // information window pop up when clicked const infowindow = new google.maps.InfoWindow(); malls.forEach(({ label, name, lat, lng }) => { const marker = new google.maps.Marker({ position: { lat, lng }, label, map: map, }); bounds.extend(marker.position); marker.addListener("click", () => { map.panTo(marker.position); // move center to clicked marker infowindow.setContent(name); infowindow.open({ anchor: marker, map, }); }); }); map.fitBounds(bounds); }; |
마커로 위치 표시
728x90
'Research > Javascript' 카테고리의 다른 글
Regex_replacing special chrs and space (0) | 2023.09.22 |
---|---|
Javascript_비동기 프로그래밍 (0) | 2023.04.13 |
Javascript_for, for in, for of는 무엇이 다른가(번역) (0) | 2023.02.06 |
forEach()는 Return으로 말릴 수 없는 짱구 (0) | 2022.11.28 |
'_hash(input)'의 언더바? Private property (0) | 2022.11.25 |
댓글