ํ”„๋กœ์ ํŠธ์—์„œ ์ง€์—ญ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ธ๊ตฌ์ง ๊ฒŒ์‹œ๊ธ€์„ ๋“ฑ๋กํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

 ์ด ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„์— ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ–ˆ๊ณ , ๊ตฌํ˜„์— ๋งŽ์€ ์‹œ๊ฐ„์„ ํˆฌ์žํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ทธ ๊ณผ์ •์„ ๋˜์งš์–ด๋ณด๊ณ  ๊ณต์œ ํ•˜๊ณ ์ž ํ•œ๋‹ค!

 

 ๊ตฌํ˜„์„ ์œ„ํ•ด ๋น„์Šทํ•˜๊ฒŒ ๋™๋„ค ๊ธฐ๋ฐ˜์˜ ์„œ๋น„์Šค(๋‹น๊ทผ๋งˆ์ผ“, ๋ฐฐ๋ฏผ..)์—์„œ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”์ง€ ๋งŽ์ด ์ฐพ์•„๋ดค์—ˆ๋‹ค. ์ •ํ™•ํžˆ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”์ง€๋Š” ์•Œ ์ˆ˜ ์—†์—ˆ์ง€๋งŒ, ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์˜ ๋‹น๊ทผ๋งˆ์ผ“ ํด๋ก  ์ฝ”๋”ฉ๊ณผ ์—ฌ๋Ÿฌ ํ…Œํฌ ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ๋‚˜๋ฆ„๋Œ€๋กœ ํ”„๋กœ์ ํŠธ์— ๋งž๊ฒŒ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

 

 

 

 

๊ธฐ๋Šฅ ์†Œ๊ฐœ


์ดˆ๊ธฐ ๋ฒ„์ „ ํ™”๋ฉด

 

 

๊ตฌ์ธ๊ตฌ์ง ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก

  • ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ ์‹œ, ๊ตฌ์ธ๊ตฌ์ง์˜ ์ƒ์„ธ ์กฐ๊ฑด๊ณผ ๊ฑฐ์  ์ง€์—ญ(ex. ์„œ์šธํŠน๋ณ„์‹œ ๊ฐ•๋‚จ๊ตฌ ์—ญ์‚ผ๋™)์„ ์ž…๋ ฅํ•œ๋‹ค.

 

๊ตฌ์ธ๊ตฌ์ง ๊ฒŒ์‹œ๊ธ€ ๊ฒ€์ƒ‰

  • ๊ฒŒ์‹œ๊ธ€ ๊ฒ€์ƒ‰ ์‹œ, ๊ฑฐ์  ์ง€์—ญ(ex. ์„œ์šธํŠน๋ณ„์‹œ ๊ฐ•๋‚จ๊ตฌ ์—ญ์‚ผ๋™)์„ ์„ ํƒํ•˜๊ณ , ๊ทธ ๋ฐ˜๊ฒฝ(nkm)๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

 

์œ ์‚ฌ ์„œ๋น„์Šค ๋ถ„์„


 ๊ฒฐ๊ตญ ๋‚ด๊ฐ€ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๋™๋„ค ๊ธฐ๋ฐ˜์˜ ์ค‘๊ณ  ๋ฌผํ’ˆ ๊ฑฐ๋ž˜ ์„œ๋น„์Šค์ธ '๋‹น๊ทผ๋งˆ์ผ“'๊ณผ ์œ ์‚ฌํ•˜๋‹ค. ๋‹น๊ทผ๋งˆ์ผ“์€ GPS๋กœ ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์˜ ๋™๋„ค ์ฃผ๋ณ€์˜ ์ค‘๊ณ  ๊ฒŒ์‹œ๊ธ€์„ ๋ณด์—ฌ์ค€๋‹ค.

 

 

๋‹น๊ทผ๋งˆ์ผ“ - ๋‚ด ๋™๋„ค ์„ค์ • ํ™”๋ฉด

 

 

๊ทผ์ฒ˜ ๋™๋„ค

 

  • ๋™๋„ค ๋ฒ”์œ„(๊ฐ€๊นŒ์šด ๋™๋„ค~๋จผ ๋™๋„ค)๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด, ํ™ˆ ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๋Š” ๊ฒŒ์‹œ๊ธ€์˜ ๋ฒ”์œ„๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค.
  • ๋™๋„ค์˜ ๋ฒ”์œ„๋Š” ๊ฐ€๊นŒ์šด ๋™๋„ค๋ถ€ํ„ฐ ๋จผ ๋™๋„ค๊นŒ์ง€ 4๋‹จ๊ณ„๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋‹จ๊ณ„ ๋ณ„ ๋™๋„ค๊ฐ€ ์ •ํ•ด์ ธ ์žˆ๋‹ค.
  • ๋™๋„ค๋Š” ํ–‰์ •๋™์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค.

 

 

 

๋‹น๊ทผ์€ ์ด๋ฏธ 4๋‹จ๊ณ„๋กœ ๋‚ด ๊ทผ์ฒ˜ ๋™๋„ค๊ฐ€ ์ •ํ•ด์ ธ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๊ทผ์ฒ˜ ๋™๋„ค๊ฐ€ ๋‹น๊ทผ์—์„œ ์ •ํ•œ ์–ด๋– ํ•œ ๊ธฐ์ค€์œผ๋กœ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐ๋˜์–ด ๋”ฐ๋กœ ์ €์žฅ๋˜์–ด ์žˆ์ง€ ์•Š์„๊นŒ..

 

๋‚ด ํ”„๋กœ์ ํŠธ๋Š” ์œ ์ €๊ฐ€ ๊ฒ€์ƒ‰ํ•  ๋•Œ๋งˆ๋‹ค km๋ฅผ ์กฐ์ ˆํ•ด ๋™๋„ค์˜ ๋ฒ”์œ„๋ฅผ ์กฐ์ ˆํ•ด์•ผ ํ•œ๋‹ค. ์ด ๋ถ€๋ถ„์—์„œ ๋‹ค๋ฅด๋‹ค.

 

 

 

 

๋™๋„ค๋ฅผ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃฐ๊นŒ?


1. ๋™๋„ค ๋ถ„๋ฅ˜ ์ฒด๊ณ„ : ๋ฒ•์ •๋™๊ณผ ํ–‰์ •๋™

 ์šฐ์„ , ์ „๊ตญ์˜ ๋ชจ๋“  ๋™๋„ค๋ฅผ ์•Œ์•„๋‚ด์•ผ ํ•œ๋‹ค. ์šฐ๋ฆฌ๋‚˜๋ผ์—์„œ ๋™๋„ค๋ฅผ ๋ถ„๋ฅ˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

 

๋ฒ•์ •๋™

  • ๋ฒ•๋ฅ ๋กœ ์ง€์ •ํ•œ ๊ณ ์œ  ์ง€๋ช…. ๋ฒ•์  ๋ฌธ์„œ์— ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋ช…์นญ ๋ณ€๋™์ด ๊ฑฐ์˜ ์—†๋‹ค.

ํ–‰์ •๋™

  • ํ–‰์ • ํŽธ์˜๋ฅผ ์œ„ํ•ด ์„ค์ •ํ•œ ๊ตฌ์—ญ. ํ–‰์ •๋™๋งˆ๋‹ค ์ฃผ๋ฏผ์„ผํ„ฐ๊ฐ€ ์žˆ๋‹ค.
  • ์ฃผ๋ฏผ ์ˆ˜์˜ ์ฆ๊ฐ์— ๋”ฐ๋ผ ์ˆ˜์‹œ๋กœ ์„ค์น˜, ํ์ง€๋  ์ˆ˜๋„ ์žˆ๋‹ค.

 

ํ–‰์ •๋™, ๋ฒ•์ •๋™ ์—‘์…€ ํŒŒ์ผ

 

์ถœ์ฒ˜ : https://realty.chosun.com/site/data/html_dir/2019/12/13/2019121301421.html

 

 

 ๋ฒ•์ •๋™๊ณผ ํ–‰์ •๋™์˜ ์ฐจ์ด๋Š” ์ด๋ฆ„์„ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์œ„์— ์ฒจ๋ถ€๋œ ์ด๋ฏธ์ง€๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ์˜ˆ๋ฅผ ๋“ค์–ด, ์„œ์šธ ํŠน๋ณ„์‹œ ์ข…๋กœ๊ตฌ์˜ ๋ฒ•์ •๋™์œผ๋กœ ์ฒญ์šด๋™, ํšจ์ž๋™ ๋“ฑ์ด ์žˆ๋‹ค. ํ•˜์ง€๋งŒ, ํ–‰์ •๋™์œผ๋กœ๋Š” ๋ช…์นญ์ด ์ฒญ์šดํšจ์ž๋™์œผ๋กœ ํ†ตํ•ฉ๋˜์–ด ์žˆ๋‹ค.

 

 ์†กํŒŒ๊ตฌ์ฒ˜๋Ÿผ ์ธ๊ตฌ๊ฐ€ ๋งŽ์€ ๋ฒ•์ •๋™์ด๋ผ๋ฉด ํ•œ ๋ฒ•์ •๋™์— ํ–‰์ •๋™์ด ์—ฌ๋Ÿฌ ๊ฐœ ์ƒ๊ธธ ์ˆ˜๋„ ์žˆ๋‹ค. ๋ฐ˜๋Œ€๋กœ ์ธ๊ตฌ๊ฐ€ ์ ์œผ๋ฉด ๋ฒ•์ •๋™ ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ํ•˜๋‚˜์˜ ํ–‰์ •๋™์œผ๋กœ ๋ฌถ์„ ์ˆ˜๋„ ์žˆ๋‹ค.

 

 ๋”ฐ๋ผ์„œ, ์–ด๋–ค ๋ถ„๋ฅ˜ ์ฒด๊ณ„๋ฅผ ์“ฐ๋Š”์ง€์— ๋”ฐ๋ผ ๋™๋„ค ๋ถ„๋ฅ˜์™€ ๊ทผ์ฒ˜ ๋™๋„ค์˜ ๋ฒ”์œ„๊ฐ€ ๋‹ฌ๋ผ์ง€๊ฒŒ ๋œ๋‹ค.

 

 

 

 

 

2. ๋ฒ•์ •๋™ ์„ ํƒ ์ด์œ 

 ์ด์ „๋ถ€ํ„ฐ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์˜ ํ™”๋ฉด์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ํ–‰์ •๋™ ์ฒด๊ณ„๋ฅผ ์“ฐ๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐฑ์—”๋“œ์—์„œ๋„ ํ–‰์ •๋™ ์ฒด๊ณ„๋ฅผ ์“ฐ๊ธฐ๋กœ ํ–ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ํ–‰์ •๋™ ์ฒด๊ณ„๋กœ ๊ตฌํ˜„ ์ค‘์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ๊ฒฐ๊ตญ ๊ทธ๋ž˜์„œ ๋ฒ•์ •๋™ ์ฒด๊ณ„๋กœ ๋ฐ”๊พธ๊ฒŒ ๋˜์—ˆ๋‹ค.

 

 

1) ์นด์นด์˜ค๋งต API ๊ฒ€์ƒ‰ ๊ณผ์ •์—์„œ ์—๋Ÿฌ

 ๋’ค์—์„œ ์„ค๋ช…ํ•˜๊ฒ ์ง€๋งŒ, ์—‘์…€๋กœ ์–ป๊ฒŒ ๋œ ๋ชจ๋“  ๋™๋„ค์˜ ์ขŒํ‘œ๊ฐ’์„ ์–ป๊ธฐ ์œ„ํ•ด ์นด์นด์˜ค๋งต API๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์—‘์…€ ๋ฐ์ดํ„ฐ์™€ ์นด์นด์˜ค๋งต ์ƒ์˜ ํ–‰์ •๋™๊ณผ ๋ช…์นญ์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์–ด ๊ฒ€์ƒ‰์ด ์•ˆ ๋˜์—ˆ๋‹ค.

 

ex)

์—‘์…€ ๋ฐ์ดํ„ฐ ์ƒ - ์„œ์šธ ์ค‘๋ž‘๊ตฌ ๋ฉด๋ชฉ์ œ3.8๋™

์นด์นด์˜ค ์ง€๋„ ์ƒ - ์„œ์šธ ์ค‘๋ž‘๊ตฌ ๋ฉด๋ชฉ 3.8๋™

 

 

 

 2) ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ ์œ ๋ฆฌ

 ํ–‰์ •๋™์˜ ๋ฌธ์ œ์ ์€ ํ–‰์ •์  ํŽธ์˜๋ฅผ ์œ„ํ•ด ์ธ๊ตฌ์ˆ˜๋กœ ๋ช…์นญ๊ณผ ์˜์—ญ์„ ์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€๋™์ด ์žฆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์œ ์ง€๋ณด์ˆ˜์„ ์ƒ๊ฐํ•œ๋‹ค๋ฉด ๋ช…์นญ ๋ณ€๋™์ด ๊ฑฐ์˜ ์—†๋Š” ๋ฒ•์ •๋™์ด ์œ ๋ฆฌํ•˜๋‹ค.

 

 

์ฐธ๊ณ ) ๋ฐฐ๋ฏผ์—์„œ๋„ ์ง€๋ฆฌ ๊ด€๋ฆฌ ์ฒด๊ณ„๋ฅผ ํ–‰์ •๋™์—์„œ ๋ฒ•์ •๋™์œผ๋กœ ์ „ํ™˜ํ–ˆ๋˜ ์ด์•ผ๊ธฐ๊ฐ€ ์žˆ๋‹ค. ํ–‰์ •๋™ ๋ฌธ์ œ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ๊ฒ€์ƒ‰ํ•˜๋‹ค๊ฐ€ ๋ฐœ๊ฒฌํ–ˆ๋‹ค!

[์šฐ์•„ํ•œํ…Œํฌ์„ธ๋ฏธ๋‚˜] ํ–‰์ •๋™์„ ๋ฒ•์ •๋™์œผ๋กœ, ๋ฐฐ๋ฏผ ์ง€๋ฆฌ ์ฒด๊ณ„ ํ”„๋กœ์ ํŠธ ์‚ดํŽด๋ณด๊ธฐ

 

 

 

 

 

3. ๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ?

 ์šฐ์„ , ๋ฒ•์ •๋™์ฝ”๋“œ์— ๊ทœ์น™์ด ์žˆ๋Š”์ง€ ์‚ดํŽด๋ดค๋‹ค. ๊ทผ์ฒ˜ ๋™๋„ค ๊ฐ„ ์ฝ”๋“œ๊ฐ€ ์œ ์‚ฌํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 ํ•˜์ง€๋งŒ, ๋ฒ•์ •๋™์ฝ”๋“œ์˜ ์ฐจ์ด๊ฐ€ ์ž‘๋‹ค๊ณ  ํ•ด์„œ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€๊นŒ์šด ๋™๋„ค๋Š” ์•„๋‹ˆ๋‹ค. ๊ฒฝ๊ธฐ๋„ ์„ฑ๋‚จ์‹œ์™€ ์˜์ •๋ถ€์‹œ๋Š” ์ฝ”๋“œ์˜ ์ˆซ์ž๊ฐ€ ์„œ๋กœ ๊ฐ€๊น์ง€๋งŒ, ์‹ค์ œ๋กœ ๊ฑฐ๋ฆฌ๋Š” ๊ฒฝ๊ธฐ ๋‚จ๋ถ€์™€ ๋ถ๋ถ€๋กœ ์—„์ฒญ๋‚œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.

 

์„ฑ๋‚จ์‹œ์™€ ์˜์ •๋ถ€์‹œ์˜ ๋ฒ•์ •๋™ ์ฝ”๋“œ

 

 

 

๊ทธ๋ ‡๋‹ค๋ฉด, ๋™๋„ค ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ๊ตฌํ•ด์•ผ ํ•œ๋‹ค.

๊ฒฐ๊ตญ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜๋ ค๋ฉด ๊ฐ ๋™๋„ค ๋ณ„ ์ขŒํ‘œ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค.

 

 

 

 

 

๋™๋„ค ๋ณ„ ์ขŒํ‘œ ๊ตฌํ•˜๊ธฐ


๋ฒ•์ •๋™ ๋ณ„ ์ขŒํ‘œ๊ฐ’ ์ €์žฅ ๊ฒฐ๊ณผ

 

 

1. ์ „์ฒด ๋™๋„ค ๋ฐ์ดํ„ฐ ๊ตฌํ•˜๊ธฐ

 ์ „๊ตญ์˜ ๋ฒ•์ •๋™ ๋ฐ์ดํ„ฐ๋Š” ํ–‰์ •์•ˆ์ „๋ถ€ ์ž๋ฃŒ๋ฅผ ํ†ตํ•ด์„œ xlsx(์—‘์…€) ํŒŒ์ผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

 xlsx ํŒŒ์ผ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•  ์ˆ˜ ์žˆ๋Š” Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ์ „๊ตญ์˜ ๋ชจ๋“  ๋™๋„ค์˜ ์‹œ๋„์ฝ”๋“œ, ์‹œ๋„๋ช…, ์‹œ๊ตฐ๊ตฌ๋ช…, ์๋ฉด๋™๋ช…์„ ์ถ”์ถœํ•ด DB์— ์ €์žฅํ–ˆ๋‹ค.

 

 

์ž์„ธํ•œ ๊ณผ์ •์€ ์•„๋ž˜ ํฌ์ŠคํŠธ์—์„œ ๋ณด๋ฉด ๋œ๋‹ค.

https://programmingiraffe.tistory.com/184

 

[Project] 4๋ฒˆ์งธ ํ”„๋กœ์ ํŠธ - ๋ฒ•์ •๋™, ์ขŒํ‘œ๊ฐ’ ๋ฐ์ดํ„ฐ DB์— ์ €์žฅํ•˜๊ธฐ(1)

์ตœ๊ทผ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋œ ๊ธฐ๋Šฅ์€ '์ง€์—ญ ๊ธฐ๋ฐ˜ ๊ฒŒ์‹œ๊ธ€ ๊ฒ€์ƒ‰'์ด๋‹ค. ๋„ˆ๋ฌด๋‚˜๋„ ์œ ๋ช…ํ•œ ์„œ๋น„์Šค์ธ ๋‹น๊ทผ๋งˆ์ผ“์˜ ํ™ˆํ™”๋ฉด์—์„œ ๋‚ด๊ฐ€ ์‚ด๊ณ  ์žˆ๋Š” ๋™๋„ค ๊ทผ์ฒ˜์— ์žˆ๋Š” ์ค‘๊ณ ๊ฑฐ๋ž˜ ๊ฒŒ์‹œ๊ธ€์„ ๋ณด๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด

programmingiraffe.tistory.com

 

 

 

 

 

2. ์ „์ฒด ๋™๋„ค ์ขŒํ‘œ ๊ตฌํ•˜๊ธฐ

 ํ•˜์ง€๋งŒ, ๋ฒ•์ •๋™ ๋ณ„ ์ขŒํ‘œ๊ฐ’์€ ๋”ฐ๋กœ ํŒŒ์ผ๋กœ ์–ป๊ธฐ ํž˜๋“ค์—ˆ๊ณ , ์žˆ๋‹ค ํ•˜๋”๋ผ๋„ ํ•˜๋‚˜์˜ ์ขŒํ‘œ(์œ„๋„, ๊ฒฝ๋„)๋กœ ์ถ”์ถœํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์› ๋‹ค.

 

 ๊ทธ๋ž˜์„œ ์นด์นด์˜ค๋งต API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ•์ •๋™์„ ์ง€๋„์—์„œ ๊ฒ€์ƒ‰ํ•ด ์ขŒํ‘œ(์œ„๋„, ๊ฒฝ๋„)๋กœ ๋ณ€ํ™˜ํ•˜๋„๋ก ํ–ˆ๋‹ค. ์ด ๋ถ€๋ถ„ ๋˜ํ•œ, ๋ฒ•์ •๋™ ์ถ”์ถœํ•˜๋Š” ๋ถ€๋ถ„๊ณผ ํ•จ๊ป˜ Python์œผ๋กœ ์นด์นด์˜ค API์™€ ํ†ต์‹ ํ•ด์„œ ์œ„๋„, ๊ฒฝ๋„ ๊ฐ’์„ ๊ฐ€์ ธ์™€ DB์— ์ €์žฅํ•˜๋„๋ก ํ–ˆ๋‹ค.

 

 

์ž์„ธํ•œ ๊ณผ์ •์€ ์•„๋ž˜ ํฌ์ŠคํŠธ์—์„œ ๋ณด๋ฉด ๋œ๋‹ค.

https://programmingiraffe.tistory.com/185

 

[Project] 4๋ฒˆ์งธ ํ”„๋กœ์ ํŠธ - ๋ฒ•์ •๋™, ์ขŒํ‘œ๊ฐ’ ๋ฐ์ดํ„ฐ DB์— ์ €์žฅํ•˜๊ธฐ(2)

์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ ๋ฒ•์ •๋™ ์—‘์…€ ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์ด์ฌ์œผ๋กœ ๊ฐ€๊ณตํ•˜์—ฌ DB์— ์ €์žฅํ•˜๋Š” ๊ณผ์ •์— ๋Œ€ํ•ด ์ผ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ๋ฒ•์ •๋™์˜ ์ขŒํ‘œ๊ฐ’(์œ„๋„, ๊ฒฝ๋„)๋ฅผ ์ €์žฅํ•˜๋Š” ๊ณผ์ •์— ๋Œ€ํ•ด ์“ฐ๊ณ ์ž ํ•œ๋‹ค!     1.

programmingiraffe.tistory.com

 

 

 

 

 

 

๋ฐ˜๊ฒฝ nKm ์ด๋‚ด ๋™๋„ค ๊ฒ€์ƒ‰ํ•˜๊ธฐ


 ์‚ฌ์šฉ์ž์˜ ๊ฑฐ์  ์ง€์—ญ ๊ทผ์ฒ˜์˜ ๊ฒŒ์‹œ๊ธ€์„ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์šฐ์„  ๊ฑฐ์  ์ง€์—ญ์œผ๋กœ๋ถ€ํ„ฐ nKm ์ด๋‚ด์— ์žˆ๋Š” ๋™๋„ค๋ฅผ ์•Œ์•„์•ผ ํ–ˆ๋‹ค.

์šฐ์„  ๊ณ ๋ คํ•œ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

1) DB์—์„œ ์ง์ ‘ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•ด ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•

2) Geocoding ๊ด€๋ จ API๋ฅผ ์‚ฌ์šฉ(https://nominatim.org/)

 

 

 ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ฒ˜์Œ์—๋Š” API๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด 12์ดˆ๋กœ ์—„์ฒญ ์˜ค๋ž˜ ๊ฑธ๋ ค์„œ ์ง์ ‘ DB์—์„œ ๊ณ„์‚ฐ์„ ํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค!

 

 

 

1. ์ฟผ๋ฆฌ๋กœ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐํ•˜๊ธฐ

MySQL ์ฟผ๋ฆฌ ์ค‘์— ๋‘ ์ขŒํ‘œ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค. 

ST_DISTANCE_SPHERE(POINT(lng1, lat1), POINT(lng2, lat2))

๊ฒฝ๋„, ์œ„๋„๋กœ ๋œ ๋‘ POINT๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค. 

 

 

@Query(
            value = "SELECT address_code " +
                    "FROM address " +
                    "WHERE ST_Distance_Sphere(POINT(:lng, :lat), POINT(lng, lat)) <= :distance * 1000 ",
            nativeQuery = true
    )
    List<String> getNearbyAddressCode(@Param("lat") double lat,
                                      @Param("lng") double lng,
                                      @Param("distance") Integer distance);

 

 

๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐ๋งŒ 20ms์˜ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜์—ˆ๋‹ค.

 

 

 

 

 

์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•ด ์ตœ์ ํ™”


 ํ•˜์ง€๋งŒ ๋งค๋ฒˆ ๊ฒŒ์‹œ๊ธ€ ๊ฒ€์ƒ‰ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ๋งˆ๋‹ค DB์—์„œ ์ฟผ๋ฆฌ๋กœ ๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ๊ฒ€์ƒ‰ํ•ด์•ผ ํ•œ๋‹ค. ๋งค๋ฒˆ ๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์€ ๋น„ํšจ์œจ์ ์ธ ์ž‘์—…์ด๋‹ค. ํŠธ๋ž˜ํ”ฝ์ด ์ปค์„œ ์š”์ฒญ์ด ๋งŽ์•„์ง€๊ฒŒ ๋œ๋‹ค๋ฉด, ๋งค๋ฒˆ ๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ์€ ์ถ”๊ฐ€์ ์ธ ๋ถ€๋‹ด์ด ๋  ๊ฒƒ์ด๋‹ค.

 

๊ทธ๋ž˜์„œ ์บ์‹ฑ์„ ํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

 

 

๋กœ์ปฌ ์บ์‹œ vs Redis ์บ์‹œ

 ์บ์‹ฑ์„ ํ•˜๋Š” ๋ฐ, ์Šคํ”„๋ง ์„œ๋ฒ„ ๋‚ด์˜ ๋กœ์ปฌ ์บ์‹œ๋ฅผ ์“ฐ๊ฑฐ๋‚˜ ์™ธ๋ถ€์—์„œ Redis์™€ ๊ฐ™์€ ์บ์‹œ๋ฅผ ์“ธ ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐ, ๋กœ์ปฌ ์บ์‹œ๋ฅผ ์“ฐ๊ธฐ๋กœ ํ–ˆ๋‹ค.

 

  • ์™ธ๋ถ€์— ๋”ฐ๋กœ Redis๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์€ ์ถ”๊ฐ€์ ์ธ ๊ด€๋ฆฌ์™€ ๋น„์šฉ์ด ๋“ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๊ทผ์ฒ˜ ๋™๋„ค ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ ์„œ๋ฒ„์— ๊ณต์œ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ์ž‘์•„์„œ ์„œ๋ฒ„ ๋ฉ”๋ชจ๋ฆฌ๋กœ๋„ ์ถฉ๋ถ„ํžˆ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

 

๊ตฌํ˜„

์ดˆ๊ธฐํ™” ์‹œ, ๊ฐ ๋ฒ•์ •๋™ ์ฝ”๋“œ์™€ ๋ฐ˜๊ฒฝ๋ณ„๋กœ ๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๋กœ์ปฌ ์บ์‹œ์— ์ €์žฅํ•˜๋„๋ก ํ–ˆ๋‹ค.

@Component
@RequiredArgsConstructor
public class AddressCacheInitializer {
    private final AddressRepository addressRepository;
    private final CacheManager cacheManager;

    @PostConstruct
    public void initializeCache() {
        List<Address> addressList = addressRepository.findAll(); // DB์—์„œ ๋ฒ•์ •๋™ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

        Cache cache = cacheManager.getCache("nearbyAddresses"); // ์บ์‹œ ๊ฐ€์ ธ์˜ค๊ธฐ

        for (Address address : addressList) {
            for (int km = 1; km <= 5; km++) {
                List<String> nearbyAddresses = calculateNearby(address, addressList, km);
                String cacheKey = address.getAddressCode() + "-" + km; // ์บ์‹œ ํ‚ค ์„ค์ •
                cache.put(cacheKey, nearbyAddresses); // ์บ์‹œ์— ์ €์žฅ
            }
        }
    }

    @Cacheable(value = "nearbyAddresses", key = "#addressCode + '-' + #km")
    public List<String> getNearbyAddresses(String addressCode, int km) {
        throw new IllegalStateException("Data should be preloaded into the cache.");
    }

    private List<String> calculateNearby(Address current, List<Address> allAddresses, double maxDistance) {
        double latDiff = maxDistance / 6371.0 * (180 / Math.PI);
        double lonDiff = maxDistance / (6371.0 * Math.cos(Math.toRadians(current.getLat()))) * (180 / Math.PI); // ๊ฒฝ๋„ ๋ฒ”์œ„

        double minLat = current.getLat() - latDiff;
        double maxLat = current.getLat() + latDiff;
        double minLon = current.getLng() - lonDiff;
        double maxLon = current.getLng() + lonDiff;

        return allAddresses.stream()
                .filter(other -> !other.getAddressCode().equals(current.getAddressCode()))
                .filter(other -> other.getLat() >= minLat && other.getLat() <= maxLat)
                .filter(other -> other.getLng() >= minLon && other.getLng() <= maxLon)
                .filter(other -> calculateDistance(current, other) <= maxDistance) // ์ตœ์ข… ๊ฑฐ๋ฆฌ ํ™•์ธ
                .map(Address::getAddressCode)
                .collect(Collectors.toList());
    }

    private double calculateDistance(Address a, Address b) {
        final double EARTH_RADIUS = 6371.0;
        double latDistance = Math.toRadians(b.getLat() - a.getLat());
        double lonDistance = Math.toRadians(b.getLng() - a.getLng());
        double haversine = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(a.getLat())) * Math.cos(Math.toRadians(b.getLng()))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        return 2 * Math.atan2(Math.sqrt(haversine), Math.sqrt(1 - haversine)) * EARTH_RADIUS;
    }
}

 

  • initializeCache() : ์–ดํ”Œ๋ฆฌ์บ์ด์…˜ ์‹œ์ž‘ ์‹œ ์ดˆ๊ธฐํ™” ์ž‘์—…์ด ์ด๋ฃจ์–ด์ง€๊ฒŒ ๋œ๋‹ค. ๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ๊ณ„์‚ฐํ•ด  ๋ฒ•์ •๋™์ฝ”๋“œ-๊ฑฐ๋ฆฌ key๋กœ ํ•˜์—ฌ ๋กœ์ปฌ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.
  • getNearbyAddresses(String addressCode, int km) : ๋ฒ•์ •๋™ ์ฝ”๋“œ์™€ ๋ฐ˜๊ฒฝ์— ํ•ด๋‹นํ•˜๋Š” ๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ๋กœ์ปฌ ์บ์‹œ์—์„œ ๊ฒ€์ƒ‰ํ•ด ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

 

 

 

 

๊ฒฐ๊ณผ

์–ดํ”Œ๋ฆฌ์บ์ด์…˜์ด ์‹œ์ž‘๋  ๋•Œ, 5033๊ฐœ ๋ฒ•์ •๋™์˜ ๊ทผ์ฒ˜ ๋™๋„ค ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด๊ฐ”๋‹ค.

 

์บ์‹ฑ์„ ์ ์šฉํ•˜๋‹ˆ ๊ทผ์ฒ˜ ๋™๋„ค๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐ, ์•ฝ 0.1ms ์‹œ๊ฐ„์ด ์†Œ์š”๋˜์—ˆ๋‹ค.

giraffe_