티스토리 뷰

목차


    반응형

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