류림스 공간

[항해99 55일차] 2022.04.30 TIL (지도 모듈 파일) 본문

TIL/2022 TIL

[항해99 55일차] 2022.04.30 TIL (지도 모듈 파일)

ryurim 2022. 4. 30. 21:49
반응형

오늘은 실시간으로 좌표가 변경될 때마다 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
반응형
Comments