Browse Source

mapbox 주석

master
junh_eee(이준희) 1 year ago
parent
commit
01764adb94
  1. 4
      package.json
  2. 4
      public/index.html
  3. 966
      src/components/map/mapbox/MapBoxMap.js
  4. 1214
      src/components/map/mapbox/dron/DronMarker.js
  5. 784
      src/components/map/mapbox/feature/FeatureAirZone.js

4
package.json

@ -13,7 +13,6 @@
"@fullcalendar/timegrid": "5.7.2",
"@fullcalendar/timeline": "5.7.2",
"@hookform/resolvers": "1.3.4",
"@mapbox/mapbox-gl-language": "1.0.1",
"@stomp/stompjs": "^6.1.0",
"@turf/buffer": "^6.5.0",
"@turf/turf": "6.5.0",
@ -56,7 +55,6 @@
"jsts": "^2.9.0",
"jwt-decode": "^3.1.2",
"leaflet": "1.6.0",
"mapbox-gl": "^2.15.0",
"moment": "2.29.1",
"nouislider": "14.6.2",
"nouislider-react": "3.3.8",
@ -84,7 +82,6 @@
"react-indiana-drag-scroll": "^2.0.1",
"react-intl": "3.11.0",
"react-leaflet": "3.1.0",
"react-mapbox-gl": "^5.1.1",
"react-paginate": "7.0.0",
"react-perfect-scrollbar": "1.5.5",
"react-player": "2.6.2",
@ -111,7 +108,6 @@
"sweetalert2": "10.14.0",
"sweetalert2-react-content": "3.0.1",
"swiper": "6.0.4",
"threebox-plugin": "2.2.7",
"typesafe-actions": "^5.1.0",
"uppy": "1.21.2",
"webpack": "4.43.0",

4
public/index.html

@ -13,12 +13,12 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link
<!-- <link
rel="stylesheet"
href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.1/mapbox-gl-directions.css"
type="text/css"
/>
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.1/mapbox-gl-directions.js"></script>
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.1/mapbox-gl-directions.js"></script> -->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<script

966
src/components/map/mapbox/MapBoxMap.js

File diff suppressed because it is too large Load Diff

1214
src/components/map/mapbox/dron/DronMarker.js

File diff suppressed because it is too large Load Diff

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

@ -1,392 +1,392 @@
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import * as turf from '@turf/turf';
import geoJson from '../../../../components/map/geojson/airArea.json';
import gimPo from '../../../../components/map/geojson/airportAirArea.json';
import '../../../../assets/css/custom.css';
// 격자 공역 Source
const airPort = [
{
title: '김포공항',
buffer: 9300,
center: [126.793722, 37.558522],
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
},
{
title: '인천공항',
buffer: 9300,
center: [126.4409428, 37.4588105],
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
},
{
title: '제주공항',
buffer: 9300,
center: [126.4930205, 33.506848],
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
},
{
title: '정석비행장',
buffer: 9300,
center: [126.7142598, 33.3943517],
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
}
];
export const FeatureAirZone = props => {
const mapControl = useSelector(state => state.controlMapReducer);
let popup;
let infoWindow;
useEffect(() => {
featureAirZoneInit();
}, [mapControl]);
const infowindowOpen = data => {
const content =
'<div class="tooltip-box">' +
'<div class="tooltip-ti">' +
'<span>' +
data.title +
'</span>' +
'</div>' +
'<div class="tooltip-txt">' +
'<div class="tooltip-txt-list">' +
'<span>' +
data.description +
'</span>' +
'</div>' +
'</div>' +
'</div>';
if (popup) {
popup.remove();
}
// Create a popup element
popup = new props.mapboxgl.Popup({
offset: [20, -20],
closeButton: false,
closeOnClick: false,
closeOnMove: true
})
.setLngLat(data.coord)
.setHTML(content)
.addTo(props.map);
};
const featureAirEvent = markers => {
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();
}
});
});
props.map.on('mouseover', 'maine', e => {
props.map.getCanvas().style.cursor = 'pointer';
const feature = e.features[0];
const data = feature.properties;
data.coord = e.lngLat;
data.title = feature.properties.name;
infowindowOpen(data);
});
props.map.on('mouseout', 'maine', () => {
props.map.getCanvas().style.cursor = '';
if (popup) {
popup.remove();
}
});
props.map.on('click', e => {
// 클릭한 지점의 피처들을 얻어옵니다.
const features = props.map.queryRenderedFeatures(e.point, {
layers: ['add-3d-buildings'] // 빌딩 레이어의 ID를 지정합니다.
});
// 빌딩 피처가 있는 경우
if (features.length > 0) {
// 첫 번째 빌딩 피처의 높이 값을 얻어옵니다.
const height = features[0].properties.height;
// 팝업을 생성하고 지도에 추가합니다.
new props.mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(`Building height: ${height}m`)
.addTo(props.map);
}
});
};
// 공역 생성 함수
const featureAirZoneInit = () => {
let arrGeoJson = [];
const useGeoJson = {
...geoJson,
features: [...geoJson.features, ...gimPo.features]
};
// props.map.data.removeGeoJson(useGeoJson);
if (props.map.getLayer('maine')) {
props.map.removeLayer('maine');
props.map.removeSource('maine');
}
// 공역 색상 및 공역 표출 정보에 따른 노출
useGeoJson.features.map(item => {
if (item.properties.type === '0001' && mapControl.area0001) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FF3648' }
});
} else if (item.properties.type === '0002' && mapControl.area0002) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FFA1AA' }
});
} else if (item.properties.type === '0003' && mapControl.area0003) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FFA800' }
});
} else if (item.properties.type === '0004' && mapControl.area0004) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#A16B00' }
});
} else if (item.properties.type === '0005' && mapControl.area0005) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#AB40FF' }
});
} else if (item.properties.type === '0006' && mapControl.area0006) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#009cad' }
});
}
});
useGeoJson.features = arrGeoJson;
// 공역 생성 start
props.map.addSource('maine', {
type: 'geojson',
data: {
...useGeoJson
}
});
props.map.addLayer({
id: 'maine',
type: 'fill',
source: 'maine',
layout: {},
paint: {
'fill-color': ['get', 'color'],
'fill-opacity': 0.5
}
});
// 공역 생성 end
// 비행장 마커 생성
const markers = useGeoJson.features
.filter(i => i.geometry.type === 'Point')
.map(i => {
const marker = new props.mapboxgl.Marker()
.setLngLat(i.geometry.coordinates)
.addTo(props.map);
marker.properties = i.properties;
return marker;
});
// 격자 공역 생성
airPort.map(air => polyArea(air));
// 마우스 오버 이벤트 생성
featureAirEvent(markers);
};
// 격자 공역 셋팅 함수
const polyArea = air => {
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
}
});
// Grid area
};
return null;
};
// import { useEffect, useState } from 'react';
// import { useSelector } from 'react-redux';
// import * as turf from '@turf/turf';
// import geoJson from '../../../../components/map/geojson/airArea.json';
// import gimPo from '../../../../components/map/geojson/airportAirArea.json';
// import '../../../../assets/css/custom.css';
// // 격자 공역 Source
// const airPort = [
// {
// title: '김포공항',
// buffer: 9300,
// center: [126.793722, 37.558522],
// reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
// },
// {
// title: '인천공항',
// buffer: 9300,
// center: [126.4409428, 37.4588105],
// reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
// },
// {
// title: '제주공항',
// buffer: 9300,
// center: [126.4930205, 33.506848],
// reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
// },
// {
// title: '정석비행장',
// buffer: 9300,
// center: [126.7142598, 33.3943517],
// reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
// }
// ];
// export const FeatureAirZone = props => {
// const mapControl = useSelector(state => state.controlMapReducer);
// let popup;
// let infoWindow;
// useEffect(() => {
// featureAirZoneInit();
// }, [mapControl]);
// const infowindowOpen = data => {
// const content =
// '<div class="tooltip-box">' +
// '<div class="tooltip-ti">' +
// '<span>' +
// data.title +
// '</span>' +
// '</div>' +
// '<div class="tooltip-txt">' +
// '<div class="tooltip-txt-list">' +
// '<span>' +
// data.description +
// '</span>' +
// '</div>' +
// '</div>' +
// '</div>';
// if (popup) {
// popup.remove();
// }
// // Create a popup element
// popup = new props.mapboxgl.Popup({
// offset: [20, -20],
// closeButton: false,
// closeOnClick: false,
// closeOnMove: true
// })
// .setLngLat(data.coord)
// .setHTML(content)
// .addTo(props.map);
// };
// const featureAirEvent = markers => {
// 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();
// }
// });
// });
// props.map.on('mouseover', 'maine', e => {
// props.map.getCanvas().style.cursor = 'pointer';
// const feature = e.features[0];
// const data = feature.properties;
// data.coord = e.lngLat;
// data.title = feature.properties.name;
// infowindowOpen(data);
// });
// props.map.on('mouseout', 'maine', () => {
// props.map.getCanvas().style.cursor = '';
// if (popup) {
// popup.remove();
// }
// });
// props.map.on('click', e => {
// // 클릭한 지점의 피처들을 얻어옵니다.
// const features = props.map.queryRenderedFeatures(e.point, {
// layers: ['add-3d-buildings'] // 빌딩 레이어의 ID를 지정합니다.
// });
// // 빌딩 피처가 있는 경우
// if (features.length > 0) {
// // 첫 번째 빌딩 피처의 높이 값을 얻어옵니다.
// const height = features[0].properties.height;
// // 팝업을 생성하고 지도에 추가합니다.
// new props.mapboxgl.Popup()
// .setLngLat(e.lngLat)
// .setHTML(`Building height: ${height}m`)
// .addTo(props.map);
// }
// });
// };
// // 공역 생성 함수
// const featureAirZoneInit = () => {
// let arrGeoJson = [];
// const useGeoJson = {
// ...geoJson,
// features: [...geoJson.features, ...gimPo.features]
// };
// // props.map.data.removeGeoJson(useGeoJson);
// if (props.map.getLayer('maine')) {
// props.map.removeLayer('maine');
// props.map.removeSource('maine');
// }
// // 공역 색상 및 공역 표출 정보에 따른 노출
// useGeoJson.features.map(item => {
// if (item.properties.type === '0001' && mapControl.area0001) {
// arrGeoJson.push({
// ...item,
// properties: { ...item.properties, color: '#FF3648' }
// });
// } else if (item.properties.type === '0002' && mapControl.area0002) {
// arrGeoJson.push({
// ...item,
// properties: { ...item.properties, color: '#FFA1AA' }
// });
// } else if (item.properties.type === '0003' && mapControl.area0003) {
// arrGeoJson.push({
// ...item,
// properties: { ...item.properties, color: '#FFA800' }
// });
// } else if (item.properties.type === '0004' && mapControl.area0004) {
// arrGeoJson.push({
// ...item,
// properties: { ...item.properties, color: '#A16B00' }
// });
// } else if (item.properties.type === '0005' && mapControl.area0005) {
// arrGeoJson.push({
// ...item,
// properties: { ...item.properties, color: '#AB40FF' }
// });
// } else if (item.properties.type === '0006' && mapControl.area0006) {
// arrGeoJson.push({
// ...item,
// properties: { ...item.properties, color: '#009cad' }
// });
// }
// });
// useGeoJson.features = arrGeoJson;
// // 공역 생성 start
// props.map.addSource('maine', {
// type: 'geojson',
// data: {
// ...useGeoJson
// }
// });
// props.map.addLayer({
// id: 'maine',
// type: 'fill',
// source: 'maine',
// layout: {},
// paint: {
// 'fill-color': ['get', 'color'],
// 'fill-opacity': 0.5
// }
// });
// // 공역 생성 end
// // 비행장 마커 생성
// const markers = useGeoJson.features
// .filter(i => i.geometry.type === 'Point')
// .map(i => {
// const marker = new props.mapboxgl.Marker()
// .setLngLat(i.geometry.coordinates)
// .addTo(props.map);
// marker.properties = i.properties;
// return marker;
// });
// // 격자 공역 생성
// airPort.map(air => polyArea(air));
// // 마우스 오버 이벤트 생성
// featureAirEvent(markers);
// };
// // 격자 공역 셋팅 함수
// const polyArea = air => {
// 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
// }
// });
// // Grid area
// };
// return null;
// };

Loading…
Cancel
Save