류림스 공간
[항해99 55일차] 2022.04.30 TIL (지도 모듈 파일) 본문
반응형
오늘은 실시간으로 좌표가 변경될 때마다 axios요청으로 서버쪽에 현재 좌표를 보내주고,
좌표를 통해서 받은 데이터들을
지도에 마커로 뿌려주는 것을 해보았다. 할 게 산더미지만,, 그래도 감이 조금씩 와서 다행이다.
초반엔 ㅠㅠ지도 api쓰기 싫었는데..ㅜㅜ
그냥 순응하고 닥코하는 중이다....
얻을 수 있는 게 있겠지..
메인지도 불러오는 부분
import React, { useEffect, useState } from "react";
import styled from "styled-components";
import { useDispatch , useSelector } from "react-redux";
import { actionCreators as mapActions } from "../../redux/modules/map";
//아이콘
import { TiPlus,TiMinus } from "react-icons/ti";
import { MdMyLocation } from "react-icons/md";
import { Map, MapMarker } from "react-kakao-maps-sdk";
import Position from './Position';
import Search from '../Search';
/** ListMotion-pts20220430 start */
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
import ActionHome from "material-ui/svg-icons/action/home";
import ActionFlightTakeoff from "material-ui/svg-icons/action/flight-takeoff";
import FileCloudDownload from "material-ui/svg-icons/file/cloud-download";
import BottomSheet from "../motion/BottomSheet";
const items = [
{
text: "Editar",
icon: <ActionHome />,
onClick: (toggleAnimation) => {
alert("Editar");
toggleAnimation();
},
},
{
text: "Pesar",
icon: <ActionFlightTakeoff />,
onClick: () => alert("Pesar"),
},
{
text: "Classificar",
icon: <FileCloudDownload />,
onClick: () => alert("Classificar"),
},
];
const MainMap = (props) => {
const dispatch = useDispatch();
const getOffice = useSelector((state) => state.map.office_list);
console.log("getOffice : ", getOffice);
const { kakao } = window;
const [level, setLevel] = useState(3); //지도레벨
const [map, setMap] = useState(); //지도
const [pos, setPos] = useState(); //경도 위도
const [state, setState] = useState({
//기본 설정값
center: {
lat: 33.450701,
lng: 126.570667,
},
errMsg: null,
isLoading: true,
});
useEffect(() => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
setState((prev) => ({
...prev,
center: {
lat: position.coords.latitude, // 위도
lng: position.coords.longitude, // 경도
},
isLoading: false,
}));
},
(err) => {
setState((prev) => ({
...prev,
errMsg: err.message,
isLoading: false,
}));
}
);
} else {
setState((prev) => ({
...prev,
errMsg: "현재 위치를 표시할 수 없어요.",
isLoading: false,
}));
}
//위도 경도
}, []);
const setLocation = () => {
console.log(`현재 지도레벨은 ${level}입니다`);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
map.setCenter(
new kakao.maps.LatLng(
position.coords.latitude,
position.coords.longitude
)
);
});
}
};
return (
<React.Fragment>
<Search/>
<MainContent>
<Map center={state.center} onCreate={(map) => setMap(map)}
onDragEnd={(map) => setPos({
lat: map.getCenter().getLat(),
lng: map.getCenter().getLng(),
swLatLng: {
lat: map.getBounds().getSouthWest().getLat(),
lng: map.getBounds().getSouthWest().getLng(),
},
neLatLng: {
lat: map.getBounds().getNorthEast().getLat(),
lng: map.getBounds().getNorthEast().getLng(),
},
})}
style={{width: "100%", height: "inherit"}}
level={level}
>
{getOffice?.map((position, index) => (
<MapMarker
key={`${position.title}-${position.latlng}`}
position={position.latlng} // 마커를 표시할 위치
image={{
src: "https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/markerStar.png", // 마커이미지의 주소입니다
size: {
widht: 24,
height: 35
}, // 마커이미지의 크기입니다
}}
title={position.title} // 마커의 타이틀, 마커에 마우스를 올리면 타이틀이 표시됩니다
/>
))}
{/* <ZoomControl position={kakao.maps.ControlPosition.TOPRIGHT} /> */}
{/* <MapTypeControl position={kakao.maps.ControlPosition.TOPRIGHT}/> */}
<Lev >
<button onClick={setLocation}>
<MdMyLocation size="24px" />
</button>
<button onClick={() =>
level > 1 ?
(setLevel(level - 1) ):(null)}>
<TiPlus size="21px"/>
</button>
<button onClick={() =>
level < 15 ?
(setLevel(level + 1)):(null)}>
<TiMinus size="21px"/>
</button>
<MuiThemeProvider>
<BottomSheet
items={items}
startHidden={false}
buttonElement={
<button
style={{
margin: "20px auto",
display: "block",
backgroundColor: "cadetblue",
border: "none",
padding: "16px 24px",
color: "#fff",
fontWeight: "bold",
cursor: "pointer",
borderRadius: 6,
fontSize: "20px",
fontFamily: "'Pangolin', cursive",
}}
>
Click me!
</button>
}
/>
</MuiThemeProvider>
</Lev>
</Map>
{/* {pos && console.log('변경된 지도 중심좌표는 ' + pos.lat + ' 이고, 경도는 ' + pos.lng + ' 입니다',
'남서쪽' + pos.swLatLng.lat ,pos.swLatLng.lng, '북동쪽좌표' + pos.neLatLng.lat ,pos.neLatLng.lng)
} */}
{pos && <Position pos={pos} map={map}/>}
</MainContent>
</React.Fragment>
);
};
const MainContent = styled.div`
height: inherit;
position: relative;
`;
const Lev =styled.div`
width:40px;
height:205px;
position:absolute;
bottom:96px;
left:16px;
z-index:99;
display:flex;
flex-direction:column;
gap:5px;
& button {
width: 40px;
height: 40px;
background: #FFFFFF;
border: none;
border-radius:8px;
display:flex;
align-items:center;
justify-content:center;
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.1);
}
`;
export default MainMap;
ㅈ조금 많이 길지만, 아래 보면 .. onDragend이벤트가 발생할때마다 현재 중심좌표 경도 남서쪽, 북동쪽 좌표를 불러오는 이벤트를
발생시키고 {pos && <Position pos={pos} map={map}/>} 포지션 컴포넌트에 주입했다.
포지션 컴포넌트부분
import React, { useEffect } from "react";
import Axios from "axios";
import { useDispatch } from "react-redux";
import { actionCreators as mapActions } from "../../redux/modules/map";
const Position = (props) => {
const { kakao } = window;
const dispatch = useDispatch();
const { pos, map } = props;
//console.log(pos,map)
let kakaoMap = map;
useEffect(() => {
// console.log(pos)
dispatch(mapActions.getOfficeData(pos));
}, [pos]);
return <React.Fragment></React.Fragment>;
};
export default Position;
이렇게 프롭스로 받아서 useEffect pos가 있을 때마다 디스패치를 시켰다.!!!!
리덕스 모듈부분
import { createAction, handleActions } from "redux-actions";
import produce from "immer";
import { RESP } from "../../response";
const SET_OFFICE_LIST = "SET_OFFICE_LIST";
const setOfficeList = createAction(SET_OFFICE_LIST, (office_list) => ({
office_list,
}));
const initialState = {
list: {
map: null,
office_list: [],
marker: [],
overlay: [],
},
};
const getOfficeData = (pos) => {
console.log("pos : ", pos);
return async function (dispatch, getState, { history }) {
try {
// const response = await axios.post(
// "http://54.180.96.119/api/login",
// {},
// {
// headers: {
// Authorization: `BEARER ${localStorage.getItem("token")}`,
// },
// }
// // );
const response = RESP.GETOFFICE;
console.log("response : ", response);
dispatch(setOfficeList(response));
} catch (err) {
console.log("에러발생", err);
alert("로그인 여부 확인에 문제가 생겼습니다.");
}
};
};
export default handleActions(
{
[SET_OFFICE_LIST]: (state, action) =>
produce(state, (draft) => {
console.log("action : ", action);
draft.office_list = action.payload.office_list;
}),
},
initialState
);
const actionCreators = {
getOfficeData,
};
export { actionCreators };
결과 화면
이렇ㄱㅔ 화면엔 아직..제대로 된 마커가 뜨지 않지만...
하나하나씩 해결해나가는 중이다..ㅠㅠ
아직 모자라다...더 잘하고싶어라 ..
728x90
반응형
'TIL > 2022 TIL' 카테고리의 다른 글
[항해99 59일차] 2022.05.03 TIL (지도 줌 인 줌 아웃 할때 이벤트 발생 시키기, 커스텀 오버레이 생성) (0) | 2022.05.04 |
---|---|
[항해99 58일차] 2022.05.02 TIL (모달창 띄우기) (0) | 2022.05.03 |
[항해99 54일차] 2022.04.29 TIL (Debounce 와 Throttle) (0) | 2022.04.30 |
[항해99 53일차] 2022.04.28 TIL (리액트 스와이프 기능) (0) | 2022.04.29 |
[항해99 52일차] 2022.04.27 TIL (와이어 프레임 작성, 카카오 지도 ) (0) | 2022.04.28 |
Comments