리팩토링은 미래의 나에게.. ㅋㅋ
참고용으로만 올려야겠습니다.
네이버지도 with React - Step by Step 2
initGeocoder.js
function initGeocoder(
infoWindow,
map,
searchInputRef,
searchButtonRef,
marker,
setSelectedGeoData,
setSelectButtonDom,
user
) {
map.addListener('click', (e) => {
searchCoordinateToAddress(
infoWindow,
map,
e.coord,
setSelectButtonDom,
setSelectedGeoData,
marker,
user
);
marker.setMap(map);
marker.setPosition(e.coord);
});
searchInputRef.addEventListener('keydown', (e) => {
let keyCode = e.which;
if (keyCode === 13) {
searchAddressToCoordinate(
infoWindow,
searchInputRef,
map,
setSelectedGeoData,
setSelectButtonDom,
marker,
user
);
}
});
searchButtonRef.addEventListener('click', (e) => {
e.preventDefault();
searchAddressToCoordinate(
infoWindow,
searchInputRef,
map,
setSelectedGeoData,
setSelectButtonDom,
marker,
user
);
});
}
export default initGeocoder;
coordToAddress.js
// 좌표기반(지도상 아무 위치 클릭) 마커 및 정보창 열기
function searchCoordinateToAddress(
infoWindow,
map,
latlng,
setSelectButtonDom,
setSelectedGeoData,
marker,
user
) {
infoWindow.close();
window.naver.maps.Service.reverseGeocode(
{
coords: latlng,
orders: [window.naver.maps.Service.OrderType.ADDR,
window.naver.maps.Service.OrderType.ROAD_ADDR].join(',')
},
function (status, response) {
if (status === window.naver.maps.Service.Status.ERROR) {
swal('error', 'Something Wrong!');
return;
}
let items = response.v2.results,
address = '',
htmlAddresses = [];
for (let i = 0, ii = items.length, item, addrType; i < ii; i++) {
item = items[i];
address = makeAddress(item) || '';
addrType = item.name === 'roadaddr' ? '[도로명 주소]' : '[지번 주소]';
htmlAddresses.push(i + 1 + '. ' + addrType + ' ' + address);
}
setSelectedGeoData({
address: {
jibunAddress: htmlAddresses[0]?.substring(11),
roadAddress: htmlAddresses[1]?.substring(12)
},
coord: { lat: latlng.y, long: latlng.x }
});
// setInfoWindowContent 함수 호출
const container = SetInfoWindowContent(
'address',
'',
htmlAddresses,
infoWindow,
null,
null,
marker,
user
);
infoWindow.setContent(container);
infoWindow.setOptions({
anchorSkew: false,
borderColor: '#cecdc7',
anchorSize: {
width: 10,
height: 12
}
});
let centerPosition = marker.getPosition();
centerPosition = {
x: centerPosition.x + 0.001,
y: centerPosition.y,
_lat: centerPosition._lat,
_long: centerPosition._long + 0.001
};
map.setCenter(isMobile() ? centerPosition : marker.getPosition());
infoWindow.open(map, marker.getPosition());
setTimeout(() => {
const infoWindowInnerContent = infoWindow.getContentElement();
const infoWindowOuterContent
= infoWindowInnerContent.parentNode.parentNode;
infoWindowInnerContent.parentNode.style.width = 'fit-content';
infoWindowInnerContent.parentNode.style.height = 'fit-content';
infoWindowInnerContent.parentNode.style.minWidth
= isMobile() ? '250px' : '370px';
infoWindowInnerContent.parentNode.style.maxWidth
= isMobile() ? '250px' : '370px';
infoWindowInnerContent.parentNode.style.fontSize
= isMobile() ? '9px' : '14px';
infoWindowOuterContent.style.top =
infoWindowInnerContent.getBoundingClientRect()
.height < 81 ? '-88px' : '-110px';
setSelectButtonDom(
infoWindowInnerContent.querySelector('#selectCoord')
);
}, 0);
}
);
}
export default searchCoordinateToAddress;
AddressToCoord.js
// 검색기반 마커/정보창 열기
function searchAddressToCoordinate(
infoWindow,
searchInputRef,
map,
setSelectedGeoData,
setSelectButtonDom,
marker,
user
) {
const searchedValue = searchInputRef.value;
if (!searchedValue) {
swal('error', '검색어를 입력해주세요');
return;
}
window.naver.maps.Service.geocode(
{
query: searchedValue
},
function (status, response) {
if (status === window.naver.maps.Service.Status.ERROR) {
swal('error', 'Something Wrong!');
return;
}
if (response.v2.meta.totalCount === 0) {
swal('error', `검색결과가 없습니다. 결과 ${response.v2.meta.totalCount}건`);
return;
}
let htmlAddresses = [],
item = response.v2.addresses[0],
point = new window.naver.maps.Point(item.x, item.y);
if (item.roadAddress) {
htmlAddresses.push('[도로명 주소] ' + item.roadAddress);
}
if (item.jibunAddress) {
htmlAddresses.push('[지번 주소] ' + item.jibunAddress);
}
if (item.englishAddress) {
htmlAddresses.push('[영문명 주소] ' + item.englishAddress);
}
// item.y === lat / item.x === long
setSelectedGeoData({
address: {
jibunAddress: htmlAddresses[1]?.substring(8),
roadAddress: htmlAddresses[0]?.substring(9)
},
coord: { lat: Number(item.y), long: Number(item.x) }
});
// setInfoWindowContent 함수 호출
const container = SetInfoWindowContent(
'address',
searchedValue,
htmlAddresses,
infoWindow,
null,
null,
marker,
user
);
infoWindow.setContent(container);
infoWindow.setOptions({
anchorSkew: false,
borderColor: '#cecdc7',
anchorSize: {
width: 10,
height: 12
}
});
marker.setMap(map);
marker.setPosition(point);
let centerPosition = point;
centerPosition = {
x: centerPosition.x + 0.001, // 모바일에서 안짤리게 해볼려구...
y: centerPosition.y,
_lat: centerPosition._lat,
_long: centerPosition._long + 0.001
};
map.setCenter(isMobile() ? centerPosition : point);
infoWindow.open(map, point);
setTimeout(() => {
const infoWindowInnerContent = infoWindow.getContentElement();
const infoWindowOuterContent
= infoWindowInnerContent.parentNode.parentNode;
infoWindowInnerContent.parentNode.style.width = 'fit-content';
infoWindowInnerContent.parentNode.style.height = 'fit-content';
infoWindowInnerContent.parentNode.style.minWidth
= isMobile() ? '250px' : '400px';
infoWindowInnerContent.parentNode.style.maxWidth
= isMobile() ? '250px' : '400px';
infoWindowInnerContent.parentNode.style.fontSize
= isMobile() ? '9px' : '14px';
infoWindowOuterContent.style.top =
infoWindowInnerContent.getBoundingClientRect()
.height < 100 ? '-88px' : '-130px';
setSelectButtonDom(
infoWindowInnerContent.querySelector('#selectCoord')
);
searchInputRef.value = '';
}, 0);
}
);
}
export default searchAddressToCoordinate;
makeAddress.js
// 주소 문자열 반환
function makeAddress(item) {
if (!item) {
return;
}
const name = item.name,
region = item.region,
land = item.land,
isRoadAddress = name === 'roadaddr';
let sido = '',
sigugun = '',
dongmyun = '',
ri = '',
rest = '';
if (hasArea(region.area1)) sido = region.area1.name;
if (hasArea(region.area2)) sigugun = region.area2.name;
if (hasArea(region.area3)) dongmyun = region.area3.name;
if (hasArea(region.area4)) ri = region.area4.name;
if (land) {
if (hasData(land.number1)) {
if (hasData(land.type) && land.type === '2') rest += '산';
rest += land.number1;
if (hasData(land.number2)) rest += '-' + land.number2;
}
if (isRoadAddress === true) {
if (checkLastString(dongmyun, '면')) {
ri = land.name;
} else {
dongmyun = land.name;
ri = '';
}
if (hasAddition(land.addition0)) rest += ' ' + land.addition0.value;
}
}
return [sido, sigugun, dongmyun, ri, rest].join(' ');
}
function hasArea(area) {
return !!(area && area.name && area.name !== '');
}
function hasData(data) {
return !!(data && data !== '');
}
function checkLastString(word, lastString) {
return new RegExp(lastString + '$').test(word);
}
function hasAddition(addition) {
return !!(addition && addition.value);
}
export default makeAddress;
checkForMarkersRendering.js
// 마커 표시 함수
const showMarker = (map, marker) => marker.setMap(map);
// 마커 숨김 함수
const hideMarker = (marker) => marker.setMap(null);
// 마커가 보이는 지도화면 밖으로 나가면 숨기고 들어오면 표시하는 기능
const checkForMarkersRendering = (map, markers) => {
const mapBounds = map.getBounds();
for (let i = 0; i < markers.length; i += 1) {
const position = markers[i].getPosition();
if (mapBounds.hasLatLng(position)) {
showMarker(map, markers[i]);
} else {
hideMarker(markers[i]);
}
}
};
export default checkForMarkersRendering;
'react' 카테고리의 다른 글
[240705 TIL] sign-in, sign-up 기본 유효성검사 템플릿 (0) | 2024.07.05 |
---|---|
[240624 TIL] 네이버지도 Step by Step 3 (0) | 2024.06.24 |
[240622 WIL 네이버지도 api Step by Step 1 (0) | 2024.06.22 |
[240611 TIL] PrivateRoute (0) | 2024.06.11 |
[240610 TIL] Dom Purify, html-react-parser (0) | 2024.06.10 |