์๋ ํ์ธ์, ๋ฆฌ์น๋ก๋ ํ๋ก์ ํธ์์ GIS(์ง๋ฆฌ์ ๋ณด์์คํ ) ์์ง๋์ด๋ง๊ณผ ์ง๋ ์๊ฐํ ์ปดํฌ๋ํธ ์ค๊ณ๋ฅผ ์ด๋ K์ ๋๋ค. ์ ํฌ ์๋น์ค์์ ์ ์ ๋ง์กฑ๋๊ฐ ๊ฐ์ฅ ๋์ ๊ธฐ๋ฅ์ ๋ฐ๋ก ๊ณ ์๊ณต์ง์๋ค์ ๋ถ๋์ฐ ๋ณด์ ํํฉ์ ์ ๊ตญ ์ง๋์ ํ์ผ๋ก ๋ฟ๋ ค ์๊ฐ์ ์ผ๋ก ๋ณด์ฌ์ฃผ๋ '์์ฐ ์ง๋(Asset Map)'์ ๋๋ค. ํ ์คํธ๋ก ๋ ์ํํธ ๋ฐ ํ ์ง ์ฃผ์๋ฅผ ๊ฒฝ์๋ ์ขํ๋ก ๋ฐ๊พธ๋ ๊ณผ์ ์ ์ง์ค์ฝ๋ฉ(Geocoding)์ด๋ผ๊ณ ํฉ๋๋ค. ์ด ๊ฐ๋จํด ๋ณด์ด๋ ๋ณํ ๊ณผ์ ์์ ๋ง์ฃผํ ๋์ฐํ ์ฃผ์์ ํ์ค๊ณผ, ์ ํฌ ๊ฐ๋ฐํ์ด ๊ตฌํํ ๊ธฐ๋ฐํ ํด๊ฒฐ์ฑ ์ธ '์ค๋งํธ ํด๋ฐฑ ์๊ณ ๋ฆฌ์ฆ'์ ์๊ฐํฉ๋๋ค.
1. ๋นํ์ค ์ฃผ์ ๋ฐ์ดํฐ์ ๋๋ฌด: ์ฃผ์๊ณ์ ๋์ฅํ
๊ณต์ง์๋ค์ด ์์ฑํด ๋ธ ๋ถ๋์ฐ ์ฃผ์ ํ ์คํธ๋ ํ์ค ๋๋ก๋ช ์ฃผ์ ์ฒด๊ณ์๋ ์ฒ๋ง๊ด๋ ๋จ์ด์ง ์ผ์์ ํ ์คํธ์์ต๋๋ค. ์์ปจ๋ ๋ค์๊ณผ ๊ฐ์ ํ์์ ๋ถ๊ท์นํ ์ฃผ์๋ค์ด ๋ฌด์ํ ์์์ก์ต๋๋ค.
"๊ฒฝ๊ธฐ๋ ์ฑ๋จ์ ๋ถ๋น๊ตฌ ์ผํ๋ 624 ๋ด๋ค๋ง์ 7๋จ์ง ์ํํธ 701๋ [๋ณธ์ธ์์ ]"(์์ ๊ด๊ณ ๊ดํธ ๋ฌธ๊ตฌ ์ฝ์ )"๊ฒฝ์๋ถ๋ ์๋์ ํ์ฒ๋ฉด ๊ฐ์ ๋ฆฌ 1600๋ฒ์ง ์ธ 3ํ์ง"(์ง๋ฒ ํผ์ฉ ๋ฐ ๋ค์ค ํ์ง ํ๊ธฐ)"์์ธ ์ข ๋ก๊ตฌ ํํ๋ 15-10๋ฒ์ง ์ง์ 2์ธต ์ฃผํ ์ค 201ํธ (๋ฐฐ์ฐ์์์ ์ง๋ถ 1/2)"(์ง๋ถ ์ ๋ณด ๊ฒฐํฉ)
์ด ์ํ ๊ทธ๋๋ก ์นด์นด์ค ๋งต ๋ก์ปฌ API๋ ๊ตญํ ๋ถ ๋ธ์ด์๋(V-world) ์ง์ค์ฝ๋ฉ API์ ์ง์ด๋ฃ์ผ๋ฉด API ์์ง์ "์ฃผ์ ๊ฒ์ ๊ฒฐ๊ณผ ์์ (Status Code 404)" ์๋ฌ๋ฅผ ๋ฑ์ผ๋ฉฐ ๋ณํ์จ์ด 50% ๋ฏธ๋ง์ผ๋ก ๋ ๋จ์ด์ก์ต๋๋ค. ์ง๋์ ์ ๋ฐ ์ด์์ด ํ์๊ฒ ๋น์ด๋ฒ๋ฆฌ๋ ์ฐธ๊ทน์ด ๋ฐ์ํ ๊ฒ์
๋๋ค.
2. ๋ฆฌ์น๋ก๋ ์ฃผ์ ์ ์ ๋ฐ ์ค๋งํธ ํด๋ฐฑ ํ์ดํ๋ผ์ธ
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ ํฌ๋ ๋ฐ์ดํฐ ์ ์ ํ์ดํ๋ผ์ธ ์ ๋ฉด์ ์ ๊ทํํ์ ํด๋ ์ (Cleanser)์ Y๋ถ์ ํด๋ฐฑ ์์ง์ ๊ฐ๋ํ์ต๋๋ค. ํ๋ฆ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋
ธ์ด์ฆ ๊ดํธ ๋ฌธ๊ตฌ ์ ๊ฑฐ: ์ฃผ์ ๋ท๋ถ๋ถ์ ๋ถ์
"[๋ณธ์ธ์์ ]","(๋ฐฐ์ฐ์์ง๋ถ 1/2)","์ธ 2ํ์ง"๋ฑ์ ์ ํ ๋ ธ์ด์ฆ ํ ์คํธ๋ฅผ Regex ํจํด์ผ๋ก ์ ๋ถ ์ ๊ฑฐํ๊ณ ํ์ค ํํ์ ๋ฌธ์์ด๋ง ๋ฐ๋ผ๋ ๋๋ค. - 1์ฐจ ์ ๋ฐ ์ง์ค์ฝ๋ฉ ์๋: ์ ์ ๋ ์ฃผ์ ์ ์ฒด๋ก API๋ฅผ ํธ์ถํด ์ ๋ฐ ์ขํ(์ง๋ฒ/๋๋ก๋ช ์์ค) ๋ณํ์ ๋ ธ๋ฆฝ๋๋ค.
- ๋ฒ์ง์ ์์ฐจ์ ์ ์ญ ํด๋ฐฑ (์ค๋งํธ ํด๋ฐฑ): 1์ฐจ ๋ณํ ์คํจ ์, ์ฃผ์ ๋ฌธ์์ด์ ์ฐ์ธก ๋ ๋จ์ด(ํธ์ค ๋ฒํธ, ๋ ๋ฒํธ, ์์ธ ์ง๋ฒ)๋ฅผ ์คํ์ด์ค ๊ธฐ์ค์ผ๋ก ํ๋์ฉ ์๋ผ๊ฐ๋ฉฐ API ์ฌ์๋๋ฅผ ๋ฐ๋ณตํฉ๋๋ค. Y-ํด๋ฐฑ ์๊ณ ๋ฆฌ์ฆ์ด ์ ์ฉ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ์ฌ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
async function geocodeWithFallback(rawAddress) {
// 1๋จ๊ณ: ๊ดํธ ์ฃผ์ ๋ฐ ๋
ธ์ด์ฆ ์ ๊ฑฐ
let cleanAddress = rawAddress.replace(/\s*\[.*?\]|\s*\(.*?\)/g, "").trim();
cleanAddress = cleanAddress.split(" ์ธ ")[0].trim(); // ์ธ ํ์ง ์ ๊ฑฐ
const addressTokens = cleanAddress.split(" ");
// 2๋จ๊ณ: ๋ฒ์ง์ ์๋ฅด๋ฉฐ ํด๋ฐฑ ๋ฃจํ ์คํ
for (let i = addressTokens.length; i > 1; i--) {
const trialAddress = addressTokens.slice(0, i).join(" ");
try {
const response = await callGeocodingAPI(trialAddress);
if (response.success) {
return {
coords: response.coords,
precision: i === addressTokens.length ? "EXACT" : "APPROXIMATE",
level: i // ๋งค์นญ์ ์ฑ๊ณตํ ์ฃผ์ ํ ํฐ ๊น์ด ์ ์ฅ
};
}
} catch (e) {
console.error("Geocoding Error:", e);
}
}
return null; // ์ต์ข
์คํจ
}
3. 97.2% ๋งค์นญ ์ฑ๊ณต์ ๊ฒฐ๊ณผ์ GIS ์์ฌ์
์ค๋งํธ Y-ํด๋ฐฑ ์๊ณ ๋ฆฌ์ฆ ๋์ ๊ฒฐ๊ณผ, ๋ฆฌ์น๋ก๋์ ์ฃผ์-์ขํ ๋ณํ ์ฑ๊ณต๋ฅ ์ ๊ธฐ์กด 48.7%์์ ๋ฌด๋ ค 97.2%๋ก ๋น์ฝ์ ์ผ๋ก ํฅ์๋์์ต๋๋ค. ์๋ฒฝํ ์ง๋ฒ ์ฃผ์๊ฐ ์๋๋๋ผ๋ ์ต์ํ ์ยท๋ฉดยท๋ ๋จ์ ํน์ ๊ตฌยท๊ตฐ ๋จ์์ ์ค์ฌ ์ขํ(APPROXIMATE ์์ค)๋ก ์ง๋ ์์ ๊ณต์ง์์ ๋ถ๋์ฐ ๋ณด์ ํํฉ์ด ์ด์ดํ ๋งตํ๋์์ต๋๋ค. ์ด๋ฌํ ๊ธฐ์ ์ ๋๋ฐฉ์ธ์ด ๋ชจ์ฌ, ์ผ๋ฐ ์๋ฏผ ๋๊ตฌ๋ ์ง๋๋ก ๊ณต์ง์ ๋ถ๋์ฐ ๋ณด์ ํด๋ฌ์คํฐ๋ฅผ ์ ์ฒด์ ์ผ๋ก ํ์ธํ ์ ์๊ฒ ๋์์ต๋๋ค. ์คํ์์ค GIS ๋ฐ์ดํฐ ์ ์ ์ ์ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ก์ ํ ํ๋ก์ ํธ์๋ ํฐ ๋ณดํฌ์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.