Browse Source

인천, 제주공항 격자선분 로직 중복코드 제거 및 파일분리

master
junh_eee(이준희) 7 months ago
parent
commit
c67f29025c
  1. 112
      src/components/map/mapbox/feature/FeatureAirSquare.js
  2. 220
      src/components/map/mapbox/feature/FeatureAirZone.js

112
src/components/map/mapbox/feature/FeatureAirSquare.js

@ -0,0 +1,112 @@
import * as turf from '@turf/turf';
const handlerCoords = (latLng, buffer, angle) => {
const coords = turf.destination(
turf.point([latLng[0], latLng[1]]),
buffer / 1000,
angle,
{ units: 'kilometers' }
).geometry.coordinates;
return coords;
};
const handlerLine = (id, latLng, buffer, angleArr) => {
const line = {
id: id,
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [
handlerCoords(latLng, buffer, angleArr[0]),
handlerCoords(latLng, buffer, angleArr[1])
]
},
properties: {
stroke: '#000',
'stroke-width': 0.8,
'stroke-opacity': 0.7
}
};
return line;
};
export const airSquareLine = (air, map) => {
const squareLineArr = [];
const radius = air.buffer;
const position = air.center;
let angle = 0;
let layerId = 1;
// 사분면 선분
for (let quadrant = 0; quadrant < 4; quadrant++) {
angle += 90;
let buffer = 0;
// 한 면당 안쪽 가운데 선 제외하고 선분 9개
for (let strokeCnt = 0; strokeCnt < 9; strokeCnt++) {
// 1미터 간격
buffer += 1000;
const coord = handlerCoords(position, buffer, angle);
let reduce = 0;
reduce = air.reduce[strokeCnt];
if (angle % 180 === 0) {
const widthLine = handlerLine(
layerId++,
coord,
radius - reduce,
[90, 270]
);
squareLineArr.push(widthLine);
} else {
const lengthLine = handlerLine(
layerId++,
coord,
radius - reduce,
[0, 180]
);
squareLineArr.push(lengthLine);
}
}
}
// 정 가운데 선분
const centerWidthLine = handlerLine(layerId++, position, radius, [90, 270]);
const centerLengthLine = handlerLine(layerId++, position, radius, [0, 180]);
squareLineArr.push(centerWidthLine);
squareLineArr.push(centerLengthLine);
// map에 레이어 존재 시 삭제
if (map.getLayer(air.title)) {
map.removeLayer(air.title);
map.removeSource(air.title);
}
// source, layer 추가
map.addSource(air.title, {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: squareLineArr
}
});
map.addLayer({
id: air.title,
type: 'line',
source: air.title,
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': '#000',
'line-width': 0.8,
'line-opacity': 0.7
}
});
};

220
src/components/map/mapbox/feature/FeatureAirZone.js

@ -3,6 +3,7 @@ import { useEffect } from 'react';
import geoJson from '../../geojson/airArea.json';
import * as turf from '@turf/turf';
import { useSelector } from '@src/redux/store';
import { airSquareLine } from './FeatureAirSquare';
// 격자 공역 Source
const airPort = [
@ -31,31 +32,15 @@ export default function FeatureAirZone(props) {
const mapState = useSelector(state => state.mapState);
useEffect(() => {
if (mapState.flightAreaMarker) {
const markers = mapState.flightAreaMarker;
markers.forEach(marker => {
marker.getElement().addEventListener('mouseover', e => {
const data = {};
data.coord = marker.getLngLat();
data.title = marker.properties.name;
data.description = marker.properties.description;
featureAirZoneInit();
}, []);
infowindowOpen(data);
});
marker.getElement().addEventListener('mouseout', () => {
if (popup) {
popup.remove();
}
});
});
useEffect(() => {
if (mapState.flightAreaMarker) {
flightAreaMarkerEvent();
}
}, [mapState.flightAreaMarker]);
useEffect(() => {
featureAirZoneInit();
}, []);
// 공역 정보 표출 window 생성
const infowindowOpen = data => {
const content =
@ -148,6 +133,27 @@ export default function FeatureAirZone(props) {
}
};
// 이착륙장 마커 이벤트 로직
const flightAreaMarkerEvent = () => {
const markers = mapState.flightAreaMarker;
markers.forEach(marker => {
marker.getElement().addEventListener('mouseover', e => {
const data = {};
data.coord = marker.getLngLat();
data.title = marker.properties.name;
data.description = marker.properties.description;
infowindowOpen(data);
});
marker.getElement().addEventListener('mouseout', () => {
if (popup) {
popup.remove();
}
});
});
};
// 공역 생성 함수
const featureAirZoneInit = () => {
const useGeoJson = {
@ -167,180 +173,10 @@ export default function FeatureAirZone(props) {
});
// 격자 공역 생성
airPort.map((air, idx) => polyArea(air, idx));
airPort.map(air => airSquareLine(air, props.map));
// 마우스 오버 이벤트 생성
featureAirEvent(markers);
};
// 격자 공역 셋팅 함수
const polyArea = (air, idx) => {
const polyArr = [];
const radius = air.buffer;
const position = air.center;
const color = '#000';
const opacity = 0.7;
let angle = 0;
let layerId = 1;
for (let i = 0; i < 4; i++) {
angle += 90;
let buffer = 0;
for (let j = 0; j < 9; j++) {
buffer += 1000;
const coord = turf.destination(
turf.point([position[0], position[1]]),
buffer / 1000,
angle,
{ units: 'kilometers' }
).geometry.coordinates;
let reduce = 0;
reduce = air.reduce[j];
if (angle % 180 === 0) {
const polyEW = {
id: layerId++,
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [
turf.destination(
turf.point([coord[0], coord[1]]),
(radius - reduce) / 1000,
90,
{ units: 'kilometers' }
).geometry.coordinates,
turf.destination(
turf.point([coord[0], coord[1]]),
(radius - reduce) / 1000,
270,
{ units: 'kilometers' }
).geometry.coordinates
]
},
properties: {
stroke: color,
'stroke-width': 0.8,
'stroke-opacity': opacity
}
};
polyArr.push(polyEW);
} else {
const polyNS = {
id: layerId++,
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [
turf.destination(
turf.point([coord[0], coord[1]]),
(radius - reduce) / 1000,
0,
{ units: 'kilometers' }
).geometry.coordinates,
turf.destination(
turf.point([coord[0], coord[1]]),
(radius - reduce) / 1000,
180,
{ units: 'kilometers' }
).geometry.coordinates
]
},
properties: {
stroke: color,
'stroke-width': 0.8,
'stroke-opacity': opacity
}
};
polyArr.push(polyNS);
}
}
}
const NS = {
id: layerId++,
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [
turf.destination(
turf.point([position[0], position[1]]),
radius / 1000,
0,
{ units: 'kilometers' }
).geometry.coordinates,
turf.destination(
turf.point([position[0], position[1]]),
radius / 1000,
180,
{ units: 'kilometers' }
).geometry.coordinates
]
},
properties: {
stroke: color,
'stroke-width': 0.8,
'stroke-opacity': opacity
}
};
polyArr.push(NS);
const EW = {
id: layerId++,
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [
turf.destination(
turf.point([position[0], position[1]]),
radius / 1000,
90,
{ units: 'kilometers' }
).geometry.coordinates,
turf.destination(
turf.point([position[0], position[1]]),
radius / 1000,
270,
{ units: 'kilometers' }
).geometry.coordinates
]
},
properties: {
stroke: color,
'stroke-width': 0.8,
'stroke-opacity': opacity
}
};
polyArr.push(EW);
if (props.map.getLayer(air.title)) {
props.map.removeLayer(air.title);
props.map.removeSource(air.title);
}
props.map.addSource(air.title, {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: polyArr
}
});
props.map.addLayer({
id: air.title,
type: 'line',
source: air.title,
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': color,
'line-width': 0.8,
'line-opacity': opacity
}
});
};
return null;
}

Loading…
Cancel
Save