일단 API 키를 발급 후도메인 등록까지 마쳤으면 지도를 띄우는 과정 중 절반은 해낸거나 마찬가지임
그게 없으면 아예 지도를 띄울수없응게
다음과정은
html에 발급받은 API key를 넣고 카카오맵 api를 호출하는 자바스크립트를 호출해준다
html div에 지도 map을 추가해준 다음, 자바스크립트 코드에 map 객체를 생성해주면 끝
*API 키는 카카오에 등록한 사용자가 맞다는 일종의 인증 방법
대충 글로 적어본 과정은 위와같으며 아래는 코드에 적용한 방법
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, maximum-scale=1"/>
<title>페이지 타이틀。</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<div id="map" style="width:700px;height:500px;"></div>
<script src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.ajax-cross-origin.min.js"></script>
<!-- 기본 지도 app key -->
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=APP API KEY=발급받은 키 입력&libraries=services"></script>
<!-- 기본 지도 기능에서 클러스터 추가 사용 -->
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=APP API KEY&libraries=services,clusterer,drawing"></script>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
위처럼 html 파일을 작성하면 width 너비가 700, height 높이가 500인 지도를 웹페이지에 표출할수있다
(아래 자바스크립트 코드도 작성해야됨)
지도를 사용자 디바이스 너비에맞게 css를 조절하는게 좀 까다로웠는데
일단 지도 띄우는것만 시도해보는 것이므로 그냥 고정값을 줘봤다
+아래에 변형해본 css를 추가해보았으니 참고해서 응용해보자
기본 지도 app key 부분은 카카오맵 지도 api에서 제공하는 기본적인 기능을 사용할 때 호출하는 방식이고
아래의 기본지도 기능에서 클러스터를 추가했다는 부분은 지도 api에서 제공하는 기능들 중
좀더 심화된 기능을 사용할 때 사용한다
따라서 기본적인 지도의 경도 위도, 주소등의 정보만 이용할 때는 서비스만 사용해도 되고,
지도 데이터를 시각화하거나 지도 위에 뭔가 그려내고자 할 때는 아래의 ,clusterer,drawing 를 추가해주면 된다
javascript
//지도 생성에 사용
var map;
var mapContainer;
window.onload = function() {
mapContainer = document.getElementById('map'), // 지도를 표시할 div
mapOption = {
center: new kakao.maps.LatLng(37.566826, 126.9786567), // 지도의 중심좌표
level: 3 // 지도의 확대 레벨
};
// 지도를 생성합니다
map = new kakao.maps.Map(mapContainer, mapOption);
}
페이지가 로드될 때 지도 객체를 새로 생성하게 함
페이지가 로드되고, 생성된 지도에 클릭 이벤트, 지도 위 마커 생성 등 지도의 기능을 계속 사용하기 위해
전역으로 map, mapcontainer를 선언하여 사용했다
mapOption 객체
center는 경도 위도 좌표를 주고 지도를 생성할 때 디폴트로 열리는 위치를 선언함
level 지도의 확대, 축소된 정도 (1~14까지 가능, 1이 최대 확대된 정도)
지도 클러스터 기능 예시
이런식으로 지도에 묶어서 보여줄수있는게 클러스터(집단) 기능
아래는 내가 임의로 css를 이것저것 추가해보고 지도 사이즈를 내가 사용하기 적합하게 바꾼 내용
/* 지도 */
.map_wrap {
position:absolute; overflow:hidden; width:100%;
height:1024px;
}
사실 높이부분이 아직도 마음에 안드는데 이건 내가 위아래에 다른 요소를 추가한다고 찌그러진거라
일단 너비는 위와같이 참고하면 디바이스 너비에맞게 100%를 유지한다
이 css를 적용하려면 html map에 style 대신 class="map_wrap"를 적용해주면 됨
const str = '주소 : 서울특별시 강남구 삼성동 영동대로 513';
var sl = str.length;
console.log(str.substr(5,sl-5));
// expected output: "서울특별시 강남구 삼성동 영동대로 513"
//str.substr(A,B);
//A: str 문자열 중에서 자를 위치 (배열처럼 0부터 시작)
//B: A에서부터 몇개의 문자를 자를것인지 개수 입력
예를들어, http://a.com?name=egoing&job=programmer 에서 &job=programmer 중 '&'는 하나의 파라미터가 끝나고 다음 파라미터가 온다는 의미이다.
그런데 다음과 같이 job의 값에 &문자가 포함된다면 시스템은 job의 값을 제대로 인식할수 없게 된다. http://a.com?name=egoing&job=programmer&blogger
이런 문제를 회피하기 위해서 다음과 같이 치환해준다. http://a.com?name=egoing&job=programmer%26blogger 그럼 시스템에서는 %26을 &로 해석하여 원래의 의도대로 값을 해석할 수 있게 된다. 이러한 처리를 이스케이핑(escaping)라고 부른다.
encodeURI 사용예시
활용 예시
//주소 url인코딩 네이버 지도 API 응용본
const uri = 'nmap://place?lat='+lat_+'&lng='+long_+'&name='+Addr+'&appname=www.naver.com';
const encoded = encodeURI(uri);
//인코딩 값 테스트용 출력
console.log('주소 url 인코딩 : ' +encoded);
기존에 사용하는 lat_, long_, Addr 변수들을 사용하여 변수 uri에 넣은 다음
//이미지 업로드 파일
//imgUpload.js
const multer = require('multer')
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploadImg')
//이미지 업로드시킬 폴더 위치
},
filename: function (req, file, cb) {
cb(null, file.originalname)
//서버에 저장할 파일 명
}
})
var upload = multer({ storage: storage })
//storage는 업로드 될 폴더 위치
module.exports = {
upload
};
서버에서 post 요청 저리하는 부분
main.js
//server.js
var express = require('express')
//이미지 업로드
var img = require('./imgUpload.js')
//파일 1개를 업로드 하는 경우
app.post('/upload', img.upload.single('file'), function (req, res, next) {
console.log('이미지 업로드 ㅇㅋ');
})
클라이언트에서 post 요청으로 이미지 서버로 넘기기
index.js
//서버에 이미지 업로드 post 요청
//index.js
function imgUpload(){
console.log('이미지 업로드 한 경우');
let formdata = new FormData();
var file = document.getElementById('imgUpload').files[0];
formdata.append('file', file);
fetch("/upload",{
method : "POST",
body: formdata
})
}
sdk.js?appkey=AppKey&libraries=services:4 A parser-blocking,
cross site (i.e. different eTLD+1) script,
http://t1.daumcdn.net/mapjsapi/js/main/4.4.1/kakao.js, is invoked via document.write.
The network request for this script MAY be blocked by the browser in this or
a future page load due to poor network connectivity.
If blocked in this page load, it will be confirmed in a subsequent console message.
See https://www.chromestatus.com/feature/5718547946799104 for more details.
var fs = require('fs');
var express = require('express')
var app = express()
//인덱스 페이지
app.get('/', function(request, response) {
fs.readFile('index.html', function (error, data) {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.end(data);
console.log('메인페이지');
});
});
//===== 데이터베이스 연결 =====//
var MongoClient = require('mongodb').MongoClient;
//데이터베이스 객체를 위한 변수 선언
var database;
//데이터베이스에 연결
function connectDB() {
var databaseUrl = 'mongodb://localhost:27017/DB';
MongoClient.connect(databaseUrl, function(err, db) {
if (err) throw err;
console.log('데이터베이스에 연결되었습니다. : ' + databaseUrl);
// database 변수에 할당
database = db;
//database.collection is not a function 오류나서 추가해봄
database = db.db('DB');
});
}
app.listen(80, function() {
console.log('Example app listening on port 80!')
connectDB();
});
처음 디비 연동할 때, connectDB함수에서 database.collection is not a function이라는 오류를 맞닥뜨려서
추가한 내용 : database = db.db('DB');
몽고디비 버전마다 디비 연결 시 방법 차이가 있는것같은데 일단 나는 저방식으로 해결이 됐다
같은 이름의 컬렉션을 반복해서 추가할 경우, 에러가 발생하니 한번 생성한 컬렉션 이름은 잘 숙지하고
컬렉션을 추가할경우, 겹치지 않게 지정하자
Node.js MongoDB 컬렉션에 데이터 추가 (1개 일 때)
//DB에 등록
app.post('/register',function(request, response){
var body = request.body;
console.log('saveDB 호출');
saveDB(body.gansik);
response.end();
});
//데이터베이스 등록
function saveDB(body){
var databaseUrl = 'mongodb://localhost:27017/DB';
MongoClient.connect(databaseUrl, function(err, db) {
if (err) throw err;
database = db.db("gansik");
database.collection("gansik").insertOne(body, function(err, res) {
if (err) throw err;
console.log("등록이 완료되었습니다.");
db.close();
});
});
}
아직 1개씩만 저장하는 단계라 insertOne을 사용함
2개 이상의 데이터를 한번에 저장할 경우, insertMany 메서드를 사용한다
2개이상 저장 예시는 아래 사이트 참고
Node.js MongoDB 컬렉션에 저장된 DB 조회하기
//DB에서 가져오기
app.post('/find',function(request, response){
var body = request.body;
console.log('findDB 호출');
findDB();
});
function findDB(){
var url = "mongodb://localhost:27017/DB";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
database = db.db("gansik");
//모든 db 조회 가능
database.collection("gansik").find({}).toArray(function(err, result) {
if (err) throw err;
console.log('DB에서 가져온 결과 : ');
console.log(result);
db.close();
});
});
}
콜백으로 받은 result를 출력해보면 여태까지 DB에 저장된 모든값들이 find().pretty() 양식으로 출력된다
Node.js 특정 키의 값만 출력하고 싶은 경우
MongoClient.connect(url, function(err, db) {
if (err) throw err;
database = db.db("gansik");
//특정 db 조회 가능 - 이 예시는 _id랑 price값 출력 - find.pretty 양식으로 출력안되고 그냥 출력됨
database.collection("gansik").find({}, { projection: { price:1} }).toArray(function(err, result) {
if (err) throw err;
console.log('DB에서 가져온 결과 : lat long menu');
// console.log(' : '+result.lat_ +', '+result.long_+', '+result.menu);
console.log(result);
response.send(JSON.stringify(result));
db.close();
});
});
price 키에 해당하는 값과 디폴트로 정해진 _id의 값만이 출력됨
만약 price에 0 값을 주거나 아예 입력을 하지 않는다면 price의 값은 출력이 되지않는다
따라서 특정 필드를 unique로 정해준 상태가 아니어서
_id가 디폴트로 정해진 경우, {projection:{ _id: 0} } 을 입력한다면 _id 값은 출력되지 않음
특정 필드에 해당하는 값만 출력하고 싶을 때 사용하면 유용하겠다
Node.js 특정 키의 값만 출력하는 법 적용 예제
MongoClient.connect(url, function(err, db) {
if (err) throw err;
database = db.db("gansik");
//0이면 그 필드값은 안보이고 필드 값이 1일경우의 값만 보임
// _id 제외, name, menu, loc, price 출력 가능 - find.pretty 양식으로 출력됨
database.collection("gansik").find({}, { projection: { _id:0, name:1, menu:1, loc:1, price:1} }).toArray(function(err, result) {
if (err) throw err;
console.log(result);
response.send(JSON.stringify(result));
db.close();
});
});
_id는 출력되지 않으며 저장된 디비에서 모든 name, menu, loc, price의 값들만 출력이 가능하다
Node.js MongoDB 특정 값을 가진 데이터 조회하기
MongoClient.connect(url, function(err, db) {
if (err) throw err;
database = db.db("gansik");
var findDB_ = menu;
//쿼리 = 필터 사용해서 특정 값 조회 price가 2000원인 값의 모든 필드 조회 가능
var query = { menu: findDB_ };
database.collection("gansik").find(query).toArray(function(err, result) {
if (err) throw err;
console.log(result);
response.send(JSON.stringify(result));
db.close();
});
});
query에는 위에 적힌것처럼 저장된 DB에서
menu라는 키(key) 중에서 findDB_의 값을 가진 메뉴를 찾도록 한다
문자열을 검색해도 되고 나의 경우는 클라이언트가 요청한 정보를 검색하는걸 해보고싶어서
파라미터로 전달받은 변수 findDB_를 사용했다
Node.js DB에 있는 컬렉션 제거하기
var databaseUrl = 'mongodb://localhost:27017/gansikDB';
console.log('drop the db');
MongoClient.connect(databaseUrl, function(err, db) {
if (err) throw err;
database = db.db("gansik");
database.collection("gansik").drop(function(err, delOK) {
if (err) throw err;
if (delOK) console.log("Collection deleted");
db.close();
});
});
// Parse URL-encoded bodies (as sent by HTML forms)
app.use(express.urlencoded());
// Parse JSON bodies (as sent by API clients)
app.use(express.json());
// Access the parse results as request.body
app.post('/', function(request, response){
console.log(request.body.user.name);
console.log(request.body.user.email);
});
자바스크립트 JSON 데이터 POST로 서버에 전달해본 사용예시
function register(){
var menu = document.getElementById("menu").value;
var price = document.getElementById("price").value;
var pay = document.getElementById("pay").value;
var obj={"menu":menu,"price":price,"pay":pay};
//POST 데이터를 보낼 url - ex) localhost/register
fetch('/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
data:obj
})
});
}
이렇게하면 json 구조는 { data : {"menu": menu, "price": price, "pay": pay} }가 된다
app.post('/registerAddr',function(request, response){
var body = request.body;
console.log('body : ' + body.data.menu);
//input으로 받은 menu 값 출력 확인
});