본문 바로가기
코딩 강좌/웹 지도 만들기

다각형 외부의 점에서 가장 가까운 점 다각형 내 위치 찾기

by 요긴소프트 2024. 11. 4.
728x90
반응형

turf.jsleaflet을 이용해 지도상의 특정 위치에서 가장 가까운 다각형 위의 점을 찾는 코드입니다. 마지막에 첨부된 내용을 파일로 저장해 브라우저로 열어보시면 아래와 같은 실행결과를 확인할 수 있습니다.

코드의 전체적인 흐름은 아래와 같습니다.

// 지도 초기화:
// 호주 중심부 근처(-26°, 128°)에 지도를 생성하고 줌 레벨을 5로 설정합니다.
var map = L.map("map").setView([-26, 128], 5);

// 타일 레이어 추가:
// Carto의 밝은 스타일 지도 타일을 배경으로 추가합니다.
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png'...)

// 다각형 생성:
// 호주 내부에 직사각형 모양의 다각형을 생성합니다.
// 좌표점: (126,-28), (140,-28), (140,-20), (126,-20)
// 빨간색으로 채우고 투명도는 0.1로 설정합니다.
const polygon = turf.polygon([...])

// 다각형을 선으로 변환:
// 생성된 다각형의 외곽선만 추출합니다.
const line = turf.polygonToLine(polygon);

// 포인트 생성:
// 다각형 외부에 한 점을 생성합니다.
var point = turf.point([124.5, -28.3]);

// 최근접점 계산:
// 생성된 점에서 가장 가까운 선 위의 점을 계산합니다.
var snapped = turf.nearestPointOnLine(line, point);

// 시각화:
// 다각형, 선, 원본 점, 최근접점을 지도에 표시합니다.
// 다각형과 선은 빨간색으로 표시됩니다.
// 이 코드는 주로 지리적 데이터 처리와 시각화에 사용되며, 특히 점과 선 사이의 최단 거리를 계산하는 기능을 보여줍니다.
L.geoJson(polygon...).addTo(map);
L.geoJson(line...).addTo(map);
L.geoJson(point...).addTo(map);
L.geoJson(snapped...).addTo(map);

 

turf.js로 다양한 공간정보 연산을 빠르고 손쉽게 처리할 수 있습니다.

 

전체 코드는 다음과 같습니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>turf로 가장 가까운 점 찾기</title>
		<style>
			body {
				margin:0; padding: 0;
			}
			#map {
				width: 100%;
				height: 100vh;
			}
		</style>
		<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
		<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
		<script src="https://cdn.jsdelivr.net/npm/@turf/turf@7.0.0/turf.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
	<div id="map"></div>
		<script>
		var map = L.map("map").setView([-26, 128], 5);

		L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
			attribution: '&copy; <a href="https://carto.com/">Carto Maps</a> contributors'
		}).addTo(map);

		const polygon = turf.polygon(
			[
				[
					[126, -28],
					[140, -28],
					[140, -20],
					[126, -20],
					[126, -28],
				],
			],
			{
				fill: "#F00",
				"fill-opacity": 0.1,
			},
		);

		const line = turf.polygonToLine(polygon);
		
		var point = turf.point([124.5, -28.3]);

		var snapped = turf.nearestPointOnLine(line, point, { units: "kilometers" });
		
		L.geoJson(polygon, {fillColor: 'red'}).addTo(map);
		L.geoJson(line, {color: 'red'}).addTo(map);
		L.geoJson(point).addTo(map);
		L.geoJson(snapped).addTo(map);
		
		</script>
</body>
</html>
728x90
반응형