<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>๐ ๊ฐ๋ก๋ฑ ์์น ๊ธฐ๋ฐ ํ์ฅ ์ถ๋ ์์คํ (์๋ ์์ฐฐ ๋ฒ์ )</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body { font-family: Arial, sans-serif; margin: 0; padding: 0; background: #f9f9f9; }
h3 { text-align: center; background: #007bff; color: white; margin: 0; padding: 10px; }
#panel { padding: 10px; text-align: center; max-width: 400px; margin: 10px auto; }
#panel input, #panel button {
width: 90%; max-width: 350px; padding: 10px; margin: 5px auto;
font-size: 16px; display: block; border: 1px solid #ccc; border-radius: 5px;
}
#map { height: 70vh; width: 100%; }
#clickedCoords {
width: 90%; max-width: 350px; padding: 8px; margin: 5px auto;
border: 1px solid #007bff; background: #eef6ff; font-size: 14px;
border-radius: 5px; text-align: center;
}
#copyBtn {
width: 90%; max-width: 350px; background: #ff9800; color: white;
border: none; padding: 8px; border-radius: 5px; cursor: pointer;
}
#completeBtn {
background: #28a745; color: white; border: none;
padding: 10px; border-radius: 5px; font-size: 16px;
cursor: pointer; width: 90%; max-width: 350px; margin: 10px auto; display: block;
}
#upcomingPanel {
position: fixed; top: 10px; right: 10px; width: 250px; max-height: 60vh;
overflow-y: auto; background: rgba(255,255,255,0.95);
border: 1px solid #007bff; border-radius: 5px; padding: 10px;
font-size: 14px; z-index: 9999; box-shadow: 2px 2px 5px rgba(0,0,0,0.2);
transition: all 0.3s ease; cursor: pointer;
}
#upcomingPanel h4 { margin: 0 0 5px; font-size: 16px; color: #007bff; }
#upcomingList { list-style: none; padding: 0; margin: 0; }
#upcomingList li { padding: 5px 8px; border-bottom: 1px solid #ddd; cursor: pointer; border-radius: 3px; user-select: none; }
#upcomingList li:hover { background: #eef6ff; }
#upcomingPanel.hidden { width: 50px; height: 40px; padding: 5px; overflow: hidden; cursor: pointer; }
#upcomingPanel.hidden h4, #upcomingPanel.hidden ul { display: none; }
#upcomingPanel.hidden::after { content: "⏰"; position: absolute; top: 10px; left: 15px; font-size: 20px; color: #007bff; }
</style>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA5qR9rGB6Qv43IYSMoHKhArm5gJdapXGk&libraries=places"></script>
</head>
<body>
<h3>๐ ๊ฐ๋ก๋ฑ ์์น ๊ธฐ๋ฐ ์ถ๋ ์์คํ (์๋ ์์ฐฐ)</h3>
<div id="panel">
<input type="text" id="keyword" placeholder="ํค์๋๋ฅผ ์ ๋ ฅํ์ธ์ (์: L0, L003, ๋ฒ์, ๋ฒ ํผ, ์ ํ๋ฒํธ ์ผ๋ถ)" />
<button onclick="searchAndShow()">๊ฒ์</button>
<div id="clickedCoords">๐ ์ง๋์์ ์์น๋ฅผ ํด๋ฆญํ๋ฉด ์ขํ๊ฐ ์ฌ๊ธฐ์ ํ์๋ฉ๋๋ค.</div>
<button id="copyBtn" onclick="copyCoords()">์ขํ ๋ณต์ฌ</button>
<button id="completeBtn" onclick="completePatrol()">✅ ์์ฐฐ ์๋ฃ</button>
</div>
<div id="upcomingPanel">
<h4>⏰ ์์ฐฐ ํ ์์ฐฐ์๋ฃ ์๋ง</h4>
<ul id="upcomingList"></ul>
</div>
<div id="map"></div>
<script>
let map, markers = [], infoWindow;
let lastClickedCoord = "";
let activePatrol = null;
let completedPatrols = new Set();
const lampData = {
"L001": { ๋ถ๋ฅ:"๊ฐ๋ก๋ฑ", ๊ณ ์ ์ด๋ฆ:"L001", ์ ํ๋ฒํธ:"02-2345-4444", ์ฃผ์:"์์ธ ์์ฒ๊ตฌ ํฉ์ ๋", ํน์ด์ฌํญ:"์ค์", ์ขํ:"37.385719,126.658645" },
"L002": { ๋ถ๋ฅ:"๊ฐ๋ก๋ฑ", ๊ณ ์ ์ด๋ฆ:"L002", ์ ํ๋ฒํธ:"02-2345-7744", ์ฃผ์:"์์ธ ์์ฒ๊ตฌ ํฉ์ ๋", ํน์ด์ฌํญ:"์ ๊ฒ ํ์", ์ขํ:"37.386500,126.660000" },
"L003": { ๋ถ๋ฅ:"๊ฐ๋ก๋ฑ", ๊ณ ์ ์ด๋ฆ:"L003", ์ ํ๋ฒํธ:"02-2345-4488", ์ฃผ์:"", ํน์ด์ฌํญ:"์ค์", ์ขํ:"37.387000,126.661000" },
"CV1": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV1", ์ ํ๋ฒํธ:"", ์ฃผ์:"์ค๋ชฉ๋ก37๊ธธ 11(๊ทธ๋ฆฐ๋น๋ผ 102ํธ)", ํน์ด์ฌํญ:"25.5.16~25.8.26. 22:00~23:00, 42ํธ)", ์ขํ:"37.526140,126.856032" },
"CV2": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV2", ์ ํ๋ฒํธ:"", ์ฃผ์:"์ค๋ชฉ๋ก24๊ธธ 19-22 2์ธต", ํน์ด์ฌํญ:"7.5~8.4(๋งค์ผ 22~23์)", ์ขํ:"37.522740,126.854003" },
"CV3": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV3", ์ ํ๋ฒํธ:"", ์ฃผ์:"์ค๋ชฉ๋ก34๊ธธ7, 302ํธ", ํน์ด์ฌํญ:"7.8~9.7(๋งค์ผ 22~23์)", ์ขํ:"37.524296,126.855753" },
"CV4": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV4", ์ ํ๋ฒํธ:"", ์ฃผ์:"์ ๋ชฉ๋ก5 ๋ชฉ๋์ผ์ฑ์ํํธ 105๋ 107ํธ", ํน์ด์ฌํญ:"5.22~8.21(๋งค์ผ 13~14, 22~23)", ์ขํ:"37.517046,126.876516" },
"CV5": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV5", ์ ํ๋ฒํธ:"", ์ฃผ์:"๋ชฉ๋๋ก23๊ธธ35 B๋ ์ง์ธต", ํน์ด์ฌํญ:"4.15~8.14(๋งค์ผ 12~13์)", ์ขํ:"37.527701,126.859364" },
"CV6": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV6", ์ ํ๋ฒํธ:"", ์ฃผ์:"์ํ์ ๋ก42 ์ ์๊ณ ๋ฑํ๊ต", ํน์ด์ฌํญ:"6.8~9.7(์~๊ธ 8~9, 22~23์)", ์ขํ:"37.523921,126.860085" },
"CV7": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV7", ์ ํ๋ฒํธ:"", ์ฃผ์:"๋ชฉ๋๋ก11๊ธธ 33 401(ํค์ฆ๋ด๋น๋ฆฌ์ง)", ํน์ด์ฌํญ:"5.23~8.22(๋งค์ผ 23~24์)", ์ขํ:"37.522949,126.861280" },
"CV8": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV8", ์ ํ๋ฒํธ:"", ์ฃผ์:"์ค์๋ก52๊ธธ 50 201ํธ", ํน์ด์ฌํญ:"7.15~8.14(๋งค์ผ 9~10, 21~22)", ์ขํ:"37.525925,126.855922" },
"CV9": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV9", ์ ํ๋ฒํธ:"", ์ฃผ์:"๋ชฉ๋๋ก19๊ธธ 31 ๊ฑดํฅํํฌ๋น 402ํธ", ํน์ด์ฌํญ:"7.8~8.7(์์ฐฐ๋ฏธ์ค์)", ์ขํ:"37.524588,126.861030" },
"CV10": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV10", ์ ํ๋ฒํธ:"", ์ฃผ์:"๋ชฉ๋๋ก 193 5์ธต(์๋ฐ๋ฆฌ์ ํ์)", ํน์ด์ฌํญ:"7.19~8.17(11~12, 21~22))", ์ขํ:"37.525567,126.858867" },
"CV11": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV11", ์ ํ๋ฒํธ:"", ์ฃผ์:"์ ๋ชฉ๋ก5๊ธธ 15 1์ธต(ํ์ดํธ์ค์)", ํน์ด์ฌํญ:"7.19~8.18(13~14์)", ์ขํ:"37.517567,126.872267" },
"CV12": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV12", ์ ํ๋ฒํธ:"", ์ฃผ์:"์ค๋ชฉ๋ก354 101๋ 1002ํธ", ํน์ด์ฌํญ:"7.18~8.17(15~16, 22~23)", ์ขํ:"37.523919,126.876851" },
"CV13": { ๋ถ๋ฅ:"๋ฒ์ฃํผํด์", ๊ณ ์ ์ด๋ฆ:"CV13", ์ ํ๋ฒํธ:"", ์ฃผ์:"์ค๋ชฉ๋ก300 204๋ 701", ํน์ด์ฌํญ:"7.31~8.30(05~06, 19~20)", ์ขํ:"37.524183,126.870829" },
"PP1": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP1", ์ ํ๋ฒํธ:"02-2696-2896", ์ฃผ์:"๋ชฉ๋๋ก 189", ํน์ด์ฌํญ:"์ ์ผ์ํ ์", ์ขํ:"37.525392,126.864424" },
"PP2": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP2", ์ ํ๋ฒํธ:"02-2065-9837", ์ฃผ์:"์ ์ ์ค์๋ก 81", ํน์ด์ฌํญ:"ํ๋๊ณต์ ์ฌ, ์ ์ฌ๋ฐฅ์ ์", ์ขํ:"37.526729,126.860807" },
"PP3": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP3", ์ ํ๋ฒํธ:"02-2696-7731", ์ฃผ์:"์ค์๋ก 326", ํน์ด์ฌํญ:"์ฌ์ ๋งํธ ์ ๋ ธ์", ์ขํ:"37.52496,126.850586" },
"PP4": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP4", ์ ํ๋ฒํธ:"02-2694-9260", ์ฃผ์:"์ ์๋ก 337", ํน์ด์ฌํญ:"์ฐ๋ฆฌ์ํ ์ ์ ๋ ๊ธ์ต์ผํฐ ์ ๋ ธ์", ์ขํ:"37.521859,126.858348" },
"PP5": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP5", ์ ํ๋ฒํธ:"02-2654-0174", ์ฃผ์:"์ ๋ชฉ๋ก 85", ํน์ด์ฌํญ:"์ค๋ชฉ๊ต7๋ฒ์ถ๊ตฌ 240๋ฏธํฐ(๊ณจ๋์น๊ณผ ์)", ์ขํ:"37.522277,126.874334" },
"PP6": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP6", ์ ํ๋ฒํธ:"02-2061-4217", ์ฃผ์:"๋ชฉ๋๋๋ก 152", ํน์ด์ฌํญ:"์ ์ 2์น์์ผํฐ ์", ์ขํ:"37.519302,126.870335" },
"PP7": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP7", ์ ํ๋ฒํธ:"02-2654-0136/02-2644-8193", ์ฃผ์:"์ ์ ๋ 129-85", ํน์ด์ฌํญ:"์ฒญ๊ตฌ์ํํธ 101๋ ์", ์ขํ:"37.51979,126.875529" },
"PP8": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP8", ์ ํ๋ฒํธ:"02-2654-0262", ์ฃผ์:"๋ชฉ๋๋๋ก 12๊ธธ 60", ํน์ด์ฌํญ:"ํ๋์ํํธ ์ ๊ตฌ", ์ขํ:"37.522168,126.877685" },
"PP9": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP9", ์ ํ๋ฒํธ:"02-2061-6579", ์ฃผ์:"์ ๋ชฉ๋ก 5", ํน์ด์ฌํญ:"์ ์ ์ผ์ฑ์ 2๊ด๋ฆฌ์ฌ๋ฌด์ ์", ์ขํ:"37.517164,126.876795" },
"PP10": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP10", ์ ํ๋ฒํธ:"02-2654-4323/02-2654-0138", ์ฃผ์:"์ ๋ชฉ๋ก 10", ํน์ด์ฌํญ:"๋ชฉ๋ํ๋์ํํธ ์๊ฐ ์", ์ขํ:"37.517926,126.876297" },
"PP11": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP11", ์ ํ๋ฒํธ:"02-2652-9138", ์ฃผ์:"์ค๋ชฉ๋ก 245", ํน์ด์ฌํญ:"๋ชฉ๋์ญ ์งํ 1์ธต(ํ์ฅ์ค ์)", ์ขํ:"37.526109,126.8643" },
"PP12": { ๋ถ๋ฅ:"๊ณต์ค์ ํ", ๊ณ ์ ์ด๋ฆ:"PP12", ์ ํ๋ฒํธ:"02-2061-0296", ์ฃผ์:"๋ชฉ๋๋ก 225", ํน์ด์ฌํญ:"ํ์ต๋ณ์ ๋ณธ๊ด 2์ธต", ์ขํ:"37.528466,126.863688" },
};
const patrolSchedule = [
{ id:"CV1(42ํธ)", startDate:"2025-05-16", endDate:"2025-08-26", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"22:00", end:"23:00" }] },
{ id:"CV2(43ํธ)", startDate:"2025-07-05", endDate:"2025-08-04", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"22:00", end:"23:00" }] },
{ id:"CV3(43ํธ)", startDate:"2025-07-08", endDate:"2025-09-07", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"22:00", end:"23:00" }] },
{ id:"CV4(41ํธ)", startDate:"2025-05-22", endDate:"2025-08-21", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"13:00", end:"14:00" },{ start:"22:00", end:"23:00" }] },
{ id:"CV5(42ํธ)", startDate:"2025-04-15", endDate:"2025-08-14", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"12:00", end:"13:00" }] },
{ id:"CV6(43ํธ)", startDate:"2025-06-08", endDate:"2025-09-07", daysOfWeek:[1,2,3,4,5], timeRanges:[{ start:"08:00", end:"09:00" },{ start:"22:00", end:"23:00" }] },
{ id:"CV7(43ํธ)", startDate:"2025-05-23", endDate:"2025-08-22", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"23:00", end:"00:00" }] },
{ id:"CV8(42ํธ)", startDate:"2025-07-15", endDate:"2025-08-14", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"09:00", end:"10:00" },{ start:"21:00", end:"22:00" }] },
{ id:"CV10(42ํธ)", startDate:"2025-07-19", endDate:"2025-08-17", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"11:00", end:"12:00" },{ start:"21:00", end:"22:00" }] },
{ id:"CV11(41ํธ)", startDate:"2025-07-19", endDate:"2025-08-18", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"13:00", end:"14:00" }] },
{ id:"CV11-1(41ํธ)", startDate:"2025-07-19", endDate:"2025-08-18", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"17:00", end:"18:00" },{ start:"21:00", end:"22:00" }] },
{ id:"CV12(41ํธ)", startDate:"2025-07-18", endDate:"2025-08-17", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"15:00", end:"16:00" },{ start:"22:00", end:"23:00" }] },
{ id:"CV13(41ํธ)", startDate:"2025-07-31", endDate:"2025-08-30", daysOfWeek:[0,1,2,3,4,5,6], timeRanges:[{ start:"05:00", end:"06:00" },{ start:"19:00", end:"20:00" }] },
];
// ๋ ์ง ๋ฒ์ ํ์ธ ํจ์
function isWithinDateRange(dateStr,startDateStr,endDateStr){
const d=new Date(dateStr);
return d>=new Date(startDateStr)&&d<=new Date(endDateStr);
}
function isDayAllowed(date,days){return days.includes(date.getDay());}
function parseCoords(s){const[a,b]=s.split(",").map(Number);return{lat:a,lng:b};}
// ๋ ์๋ฆฌ ์ซ์ ํฌ๋งท
function pad(n){ return n.toString().padStart(2,"0"); }
// ์ต์ 2๊ธ์ ์ด์ ์ฐ์ substring ๋ฐํ
function getSubstrings(str, minLen = 2) {
const substrings = [];
for(let len = minLen; len <= str.length; len++) {
for(let i = 0; i <= str.length - len; i++) {
substrings.push(str.substring(i, i + len));
}
}
return substrings;
}
// ํ ์คํธ ์ ๊ทํ (์๋ฌธ์, ๋์ด์ฐ๊ธฐ/ํน์๋ฌธ์ ์ ๊ฑฐ)
function normalizeText(str){
return (str||"").toLowerCase().replace(/[\s\-\_\.,]/g,"");
}
// ๋ฌธ์ ์์๋๋ก ํฌํจ ์ฌ๋ถ ๊ฒ์ฌ (๋์ด์ฐ๊ธฐ ๋ฌด์ํ๊ณ ์์๋ง ๋ง์ผ๋ฉด true)
function isSequenceMatch(text, keyword){
let idx=0;
for(const ch of keyword){
idx=text.indexOf(ch, idx);
if(idx === -1) return false;
idx++;
}
return true;
}
// ์์ฐฐ ์์ ํ์
function showUpcomingPatrols(){
const now=new Date(), nowM=now.getHours()*60+now.getMinutes();
const list=document.getElementById("upcomingList");
list.innerHTML="";
const upcoming=[];
patrolSchedule.forEach(task=>{
if(!isWithinDateRange(now.toISOString().slice(0,10),task.startDate,task.endDate)) return;
if(!isDayAllowed(now,task.daysOfWeek)) return;
task.timeRanges.forEach(r=>{
const [sH,sM] = r.start.split(":").map(Number);
const [eH,eM] = r.end.split(":").map(Number);
const startM = sH*60 + sM - 30;
const endM = eH*60 + eM + 30;
const isOngoing = nowM >= sH*60 + sM && nowM <= eH*60 + eM;
const isInWindow = nowM >= startM && nowM <= endM;
if(isInWindow && !completedPatrols.has(task.id+"|"+sH+"|"+sM)){
upcoming.push({task,hour:sH,minute:sM,endHour:eH,endMinute:eM,isInTime:isOngoing});
}
});
});
if(upcoming.length===0){
list.innerHTML="<li>✅ ์์ ์์</li>";
return;
}
upcoming.sort((a,b)=>(a.hour*60+a.minute)-(b.hour*60+b.minute));
upcoming.forEach(item=>{
const li=document.createElement("li");
li.style.color=item.isInTime ? "blue" : "black";
li.textContent=`${item.task.id} - ${pad(item.hour)}:${pad(item.minute)}~${pad(item.endHour)}:${pad(item.endMinute)}`;
li.onclick=()=>{
activePatrol = { task: item.task, hour: item.hour, minute: item.minute };
const baseId = item.task.id.split("(")[0];
if (!lampData[baseId]) {
alert("ํด๋น ID์ ์ขํ ์ ๋ณด๊ฐ ์์ต๋๋ค.");
return;
}
const pos = parseCoords(lampData[baseId].์ขํ);
window.open(`https://www.google.com/maps/dir/?api=1&destination=${pos.lat},${pos.lng}`, "_blank");
};
list.appendChild(li);
});
}
// ์์ฐฐ ์๋ฃ ๋ฒํผ
function completePatrol(){
if(!activePatrol){
alert("๐ซ ์งํ ์ค์ธ ์์ฐฐ์ด ์์ต๋๋ค.");
return;
}
completedPatrols.add(activePatrol.task.id + "|" + activePatrol.hour + "|" + activePatrol.minute);
alert(`✅ ${activePatrol.task.id} ์์ฐฐ ์๋ฃ!`);
activePatrol = null;
showUpcomingPatrols();
}
// ์ง๋ ๋ฐ ํด๋ฆญ ์ขํ ๋ณต์ฌ
function initMap(){
map=new google.maps.Map(document.getElementById("map"),{center:{lat:37.3857,lng:126.6586},zoom:15});
infoWindow=new google.maps.InfoWindow();
map.addListener("click",e=>{
lastClickedCoord=`${e.latLng.lat().toFixed(6)},${e.latLng.lng().toFixed(6)}`;
document.getElementById("clickedCoords").innerText=`๐ ํด๋ฆญ ์ขํ: ${lastClickedCoord}`;
});
}
function copyCoords(){
if(!lastClickedCoord){
alert("⚠️ ๋จผ์ ์ง๋๋ฅผ ํด๋ฆญํ์ธ์.");
return;
}
navigator.clipboard.writeText(lastClickedCoord).then(()=>alert("✅ ๋ณต์ฌ๋จ: "+lastClickedCoord));
}
function clearMarkers(){
markers.forEach(m=>m.setMap(null));
markers=[];
}
// ๋ง์ปค ์ถ๊ฐ: ํ ๋ฒ ํด๋ฆญ ์ ์ ๋ณด์ฐฝ, ๋ ๋ฒ ํด๋ฆญ ์ ๊ธธ์ฐพ๊ธฐ ์ด๊ธฐ
function addMarker(id, pos, color){
const m = new google.maps.Marker({
position: pos,
map,
label: id,
icon: { url: `http://maps.google.com/mapfiles/ms/icons/${color}-dot.png` }
});
m.addListener("click", () => {
const data = lampData[id];
const content = `
<div style="min-width:150px;">
<strong>${data.๊ณ ์ ์ด๋ฆ}</strong><br/>
๋ถ๋ฅ: ${data.๋ถ๋ฅ}<br/>
์ ํ๋ฒํธ: ${data.์ ํ๋ฒํธ}<br/>
์ฃผ์: ${data.์ฃผ์}<br/>
ํน์ด์ฌํญ: ${data.ํน์ด์ฌํญ}
</div>`;
infoWindow.setContent(content);
infoWindow.open(map, m);
});
m.addListener("dblclick", () => {
const coords = lampData[id].์ขํ.split(",");
const lat = coords[0].trim();
const lng = coords[1].trim();
window.open(`https://www.google.com/maps/dir/?api=1&destination=${lat},${lng}`, "_blank");
});
markers.push(m);
}
// ์นดํ ๊ณ ๋ฆฌ๋ณ ๊ฒ์ ๋ก์ง ํตํฉ
function searchAndShow(){
const kw=document.getElementById("keyword").value.trim();
if(!kw){
alert("⚠️ ํค์๋ ์ ๋ ฅํ์ธ์.");
return;
}
clearMarkers();
const kwNoSpace = kw.replace(/\s+/g, "").toLowerCase();
if(kwNoSpace.length < 2){
alert("⚠️ ๊ฒ์์ด๋ ์ต์ 2๊ธ์ ์ด์ ์ ๋ ฅํด์ฃผ์ธ์.");
return;
}
const res = Object.keys(lampData).filter(id => {
const data = lampData[id];
// ๊ณ ์ ์ด๋ฆ(ID) ํ๋ ๊ฒ์ฌ
const name = normalizeText(data.๊ณ ์ ์ด๋ฆ);
if(name === kwNoSpace) return true; // ์ ํ ์ผ์น
// ID ๊ฐ์ ๊ฒฝ์ฐ L001 ํํ์์ kwNoSpace๊ฐ ์ ๋ฏธ์ฌ๋ก ๋ง์ผ๋ฉด true (์: "001" ์ ๋ ฅ ์ L001 ๋งค์นญ)
if(/^l\d+$/i.test(data.๊ณ ์ ์ด๋ฆ) && data.๊ณ ์ ์ด๋ฆ.toLowerCase().endsWith(kwNoSpace)) return true;
if(isSequenceMatch(name, kwNoSpace)) return true;
// ์ ํ๋ฒํธ ํ๋์์๋ง ๋งค์นญ
const phone = normalizeText(data.์ ํ๋ฒํธ);
if(phone.includes(kwNoSpace)) return true;
// ์ฃผ์, ๋ถ๋ฅ, ํน์ด์ฌํญ ๊ฐ๊ฐ์์๋ง ๋งค์นญ (๋ฌธ์ ์์ ํฌํจ)
const fields = [normalizeText(data.์ฃผ์), normalizeText(data.๋ถ๋ฅ), normalizeText(data.ํน์ด์ฌํญ)];
if(fields.some(f => isSequenceMatch(f, kwNoSpace))) return true;
// ์ขํ ํ๋์์๋ง ๋งค์นญ (์ซ์ ์ผํ ํฌํจ ๊ทธ๋๋ก)
const coords = normalizeText(data.์ขํ);
if(coords.includes(kwNoSpace)) return true;
return false;
}).map(id => ({id, pos: parseCoords(lampData[id].์ขํ)}));
if(res.length === 0){
alert("❌ ๊ฒ์ ๊ฒฐ๊ณผ ์์");
return;
}
const bounds = new google.maps.LatLngBounds();
res.forEach(r => {
addMarker(r.id, r.pos, "blue");
bounds.extend(r.pos);
});
map.fitBounds(bounds);
}
// ์ด๊ธฐํ ๋ฐ ์ด๋ฒคํธ ๋ฐ์ธ๋ฉ
document.addEventListener("DOMContentLoaded", () => {
document.getElementById("upcomingPanel").addEventListener("click", e => {
if(e.target.tagName.toLowerCase() !== "li") {
e.currentTarget.classList.toggle("hidden");
}
});
});
window.onload = () => {
initMap();
showUpcomingPatrols();
setInterval(showUpcomingPatrols, 60000);
};
</script>
</body>
</html>
๋๊ธ ์์:
๋๊ธ ์ฐ๊ธฐ