김장현
1 year ago
2 changed files with 489 additions and 22 deletions
@ -1,29 +1,485 @@ |
|||||||
import mapboxgl from 'mapbox-gl'; |
|
||||||
import { MAPBOX_TOKEN } from '../../../configs/constants'; |
import { MAPBOX_TOKEN } from '../../../configs/constants'; |
||||||
import { useContext, useEffect, useRef, useState } from 'react'; |
import React, { useEffect, useState, useRef } from 'react'; |
||||||
import ReactMapboxGl, { Layer, Feature } from 'react-mapbox-gl'; |
import { useSelector, useDispatch } from 'react-redux'; |
||||||
|
import { DronMarker } from './dron/DronMarker'; |
||||||
|
import { DronHistory } from './dron/DronHistory'; |
||||||
|
import NaverMapControl from './NaverMapControl'; |
||||||
|
import { NaverMapSearch } from './search/NaverMapSearch'; |
||||||
|
import { FeatureAirZone } from './feature/FeatureAirZone'; |
||||||
|
import geoJson from '../geojson/airArea.json'; |
||||||
|
import DronPlan from './dron/DronPlan'; |
||||||
|
import NewDronPlan from './dron/NewDronPlan'; |
||||||
|
import { NewDronHistory } from './dron/NewDronHistroy'; |
||||||
|
import DronToast from './dron/DronToast'; |
||||||
|
import SensorZone from './sensor/SensorZone'; |
||||||
|
import 'mapbox-gl/dist/mapbox-gl.css'; |
||||||
|
import mapboxgl from 'mapbox-gl'; |
||||||
|
|
||||||
mapboxgl.accessToken = MAPBOX_TOKEN; |
// mapboxgl.accessToken = MAPBOX_TOKEN;
|
||||||
export default function MapBoxTest() { |
export default function MapBoxTest() { |
||||||
|
// const mapContainer = useRef(null);
|
||||||
|
// const map = useRef(null);
|
||||||
|
// useEffect(() => {
|
||||||
|
// if (map.current) return;
|
||||||
|
// map.current = new mapboxgl.Map({
|
||||||
|
// container: mapContainer.current,
|
||||||
|
// style: 'mapbox://styles/mapbox/streets-v12',
|
||||||
|
// center: [126.793722, 37.558522],
|
||||||
|
// zoom: 9
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <div id='map'>
|
||||||
|
// <div
|
||||||
|
// style={{ width: '100%', height: '100vh' }}
|
||||||
|
// ref={mapContainer}
|
||||||
|
// className='map-container'
|
||||||
|
// />
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
const dispatch = useDispatch(); |
||||||
|
const naver = window.naver; |
||||||
|
|
||||||
|
const [mapObject, setMapObject] = useState(null); |
||||||
|
const [arrPolyline, setArrPolyline] = useState([]); |
||||||
|
|
||||||
|
const [poly, setPoly] = useState([]); |
||||||
const mapContainer = useRef(null); |
const mapContainer = useRef(null); |
||||||
const map = useRef(null); |
|
||||||
|
const airPort = [ |
||||||
|
{ |
||||||
|
title: '김포공항', |
||||||
|
buffer: 9300, |
||||||
|
center: new naver.maps.LatLng(37.558522, 126.793722), |
||||||
|
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5] |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: '인천공항', |
||||||
|
buffer: 9300, |
||||||
|
center: new naver.maps.LatLng(37.4588105, 126.4409428), |
||||||
|
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5] |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: '제주공항', |
||||||
|
buffer: 9300, |
||||||
|
center: new naver.maps.LatLng(33.506848, 126.4930205), |
||||||
|
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5] |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: '정석비행장', |
||||||
|
buffer: 9300, |
||||||
|
center: new naver.maps.LatLng(33.3943517, 126.7142598), |
||||||
|
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5] |
||||||
|
} |
||||||
|
]; |
||||||
|
|
||||||
|
const uamPosition = [ |
||||||
|
{ |
||||||
|
name: 'V1', |
||||||
|
lat: 37.4797865, |
||||||
|
lon: 126.540668 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'V2', |
||||||
|
|
||||||
|
lat: 37.521245, |
||||||
|
lon: 126.6107763 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'V3', |
||||||
|
lat: 37.5642352, |
||||||
|
lon: 126.6243464 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'V4', |
||||||
|
lat: 37.3658236, |
||||||
|
lon: 126.6650669 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'V5', |
||||||
|
lat: 37.4520753, |
||||||
|
lon: 126.7074861 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'R1', |
||||||
|
lat: 37.492581, |
||||||
|
lon: 126.5801572 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'R2', |
||||||
|
lat: 37.542031, |
||||||
|
lon: 126.6036588 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'R3', |
||||||
|
lat: 37.5764269, |
||||||
|
lon: 126.6005224 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'R4', |
||||||
|
lat: 37.5790407, |
||||||
|
lon: 126.6600404 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'R5', |
||||||
|
lat: 37.524016, |
||||||
|
lon: 126.649562 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'R6', |
||||||
|
lat: 37.5506488, |
||||||
|
lon: 126.693722 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'R7', |
||||||
|
lat: 37.4712333, |
||||||
|
lon: 126.6023981 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'R8', |
||||||
|
lat: 37.4046495, |
||||||
|
lon: 126.6202759 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'R9', |
||||||
|
lat: 37.3450207, |
||||||
|
lon: 126.6296542 |
||||||
|
} |
||||||
|
]; |
||||||
|
|
||||||
|
let features = geoJson.features; |
||||||
|
|
||||||
useEffect(() => { |
useEffect(() => { |
||||||
if (map.current) return; |
NaverMapInit(); |
||||||
map.current = new mapboxgl.Map({ |
|
||||||
container: mapContainer.current, |
// const map = new mapboxgl.Map({
|
||||||
style: 'mapbox://styles/mapbox/streets-v12', |
// container: mapContainer.current,
|
||||||
center: [126.793722, 37.558522], |
// style: 'mapbox://styles/mapbox/streets-v11',
|
||||||
zoom: 9 |
// center: [-74.5, 40],
|
||||||
|
// zoom: 9
|
||||||
|
// });
|
||||||
|
airPort?.map(air => polyArea(air)); |
||||||
|
}, []); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
uamPosition.map(uam => { |
||||||
|
const name = uam.name; |
||||||
|
const position = new naver.maps.LatLng(uam.lat, uam.lon); |
||||||
|
|
||||||
|
const cont = |
||||||
|
name.substr(0, 1) == 'R' |
||||||
|
? [ |
||||||
|
'<div style="border-radius:50%; background:#429629; border: 4px solid #ffffff; padding:5px; width:40px; height:40px; text-align:center">', |
||||||
|
`<span style="color:#ffffff">${name}</span>`, |
||||||
|
'</div>' |
||||||
|
] |
||||||
|
: [ |
||||||
|
'<div style="border-radius:50%; background:#ffffff; border: 4px solid #15298A; padding:5px; width:40px; height:40px; text-align:center ">', |
||||||
|
`<span style="color:#000000">${name}</span>`, |
||||||
|
'</div>' |
||||||
|
]; |
||||||
|
|
||||||
|
const marker = new naver.maps.Marker({ |
||||||
|
position: position, |
||||||
|
map: mapObject, |
||||||
|
icon: { |
||||||
|
content: cont.join(''), |
||||||
|
anchor: new naver.maps.Point(20, 20) |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
}, [mapObject]); |
||||||
|
let popup; |
||||||
|
const NaverMapInit = () => { |
||||||
|
mapboxgl.accessToken = MAPBOX_TOKEN; |
||||||
|
// const mapOptions = {
|
||||||
|
// center: new naver.maps.LatLng(37.520357, 126.610166),
|
||||||
|
// // center: new naver.maps.LatLng(36.56793936069445, 127.85101412107547),
|
||||||
|
// // zoom: 10,
|
||||||
|
// zoom: 14,
|
||||||
|
// zoomControl: true,
|
||||||
|
// mapTypeId: naver.maps.MapTypeId.NORMAR,
|
||||||
|
// zoomControlOptions: {
|
||||||
|
// position: naver.maps.Position.TOP_LEFT,
|
||||||
|
|
||||||
|
// style: naver.maps.ZoomControlStyle.SMALL
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
const map = new mapboxgl.Map({ |
||||||
|
container: 'map', // container ID
|
||||||
|
style: 'mapbox://styles/mapbox/streets-v12', // style URL
|
||||||
|
center: [127.85101412107547, 37.520357], // starting position [lng, lat]
|
||||||
|
zoom: 10 // starting zoom
|
||||||
|
}); |
||||||
|
setMapObject(map); |
||||||
|
|
||||||
|
map.on('load', () => { |
||||||
|
const layers = map.getStyle().layers; |
||||||
|
map.setLayoutProperty('country-label', 'text-field', ['get', `name_kr`]); |
||||||
|
const labelLayerId = layers.find( |
||||||
|
layer => layer.type === 'symbol' && layer.layout['text-field'] |
||||||
|
).id; |
||||||
|
map.addSource('mapbox-dem', { |
||||||
|
type: 'raster-dem', |
||||||
|
url: 'mapbox://mapbox.mapbox-terrain-dem-v1', |
||||||
|
tileSize: 512, |
||||||
|
maxZoom: 16 |
||||||
|
}); |
||||||
|
map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 }); |
||||||
|
map.addSource('maine', { |
||||||
|
type: 'geojson', |
||||||
|
data: { |
||||||
|
...geoJson |
||||||
|
} |
||||||
}); |
}); |
||||||
|
map.addLayer({ |
||||||
|
id: 'maine', |
||||||
|
type: 'fill', |
||||||
|
source: 'maine', // reference the data source
|
||||||
|
layout: {}, |
||||||
|
paint: { |
||||||
|
'fill-color': '#0080ff', // blue color fill
|
||||||
|
'fill-opacity': 0.5 |
||||||
|
} |
||||||
|
}); |
||||||
|
map.addLayer({ |
||||||
|
id: 'sky', |
||||||
|
type: 'sky', |
||||||
|
paint: { |
||||||
|
'sky-type': 'atmosphere', |
||||||
|
'sky-atmosphere-sun': [0.0, 90.0], |
||||||
|
'sky-atmosphere-sun-intensity': 15 |
||||||
|
} |
||||||
|
}); |
||||||
|
map.addLayer( |
||||||
|
{ |
||||||
|
id: 'add-3d-buildings', |
||||||
|
source: 'composite', |
||||||
|
'source-layer': 'building', |
||||||
|
filter: ['==', 'extrude', 'true'], |
||||||
|
type: 'fill-extrusion', |
||||||
|
minzoom: 15, |
||||||
|
paint: { |
||||||
|
'fill-extrusion-color': '#aaa', |
||||||
|
|
||||||
|
// Use an 'interpolate' expression to
|
||||||
|
// add a smooth transition effect to
|
||||||
|
// the buildings as the user zooms in.
|
||||||
|
'fill-extrusion-height': [ |
||||||
|
'interpolate', |
||||||
|
['linear'], |
||||||
|
['zoom'], |
||||||
|
15, |
||||||
|
0, |
||||||
|
15.05, |
||||||
|
['get', 'height'] |
||||||
|
], |
||||||
|
'fill-extrusion-base': [ |
||||||
|
'interpolate', |
||||||
|
['linear'], |
||||||
|
['zoom'], |
||||||
|
15, |
||||||
|
0, |
||||||
|
15.05, |
||||||
|
['get', 'min_height'] |
||||||
|
], |
||||||
|
'fill-extrusion-opacity': 0.6 |
||||||
|
} |
||||||
|
}, |
||||||
|
labelLayerId |
||||||
|
); |
||||||
|
}); |
||||||
|
map.on('mouseenter', 'maine', e => { |
||||||
|
const feature = e.features[0]; |
||||||
|
const properties = feature.properties; |
||||||
|
|
||||||
|
// Remove the existing popup if it exists
|
||||||
|
if (popup) { |
||||||
|
popup.remove(); |
||||||
|
} |
||||||
|
|
||||||
|
// Create a new popup with the feature's properties
|
||||||
|
popup = new mapboxgl.Popup() |
||||||
|
.setLngLat(e.lngLat) |
||||||
|
.setHTML( |
||||||
|
Object.entries(properties) |
||||||
|
.map(([key, value]) => `${key}: ${value}`) |
||||||
|
.join('<br>') |
||||||
|
) |
||||||
|
.addTo(map); |
||||||
}); |
}); |
||||||
|
|
||||||
|
map.on('mouseleave', 'maine', () => { |
||||||
|
if (popup) { |
||||||
|
popup.remove(); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
const createUamArea = uam => { |
||||||
|
const title = uam.title; |
||||||
|
const position = new naver.maps.LatLng(uam.lat, uam.lon); |
||||||
|
|
||||||
|
const circle = new naver.maps.Circle({ |
||||||
|
strokeColor: '#283046', |
||||||
|
strokeOpacity: 1, |
||||||
|
fillColor: '#7367F0', |
||||||
|
fillOpacity: 0.1, |
||||||
|
center: position, |
||||||
|
// map: mapObject,
|
||||||
|
radius: 100, |
||||||
|
clickable: true |
||||||
|
}); |
||||||
|
|
||||||
|
// circle.setMap(mapObject);
|
||||||
|
}; |
||||||
|
|
||||||
|
const handleHistoryInit = line => { |
||||||
|
setArrPolyline([...arrPolyline, line]); |
||||||
|
}; |
||||||
|
|
||||||
|
const polyArea = air => { |
||||||
|
//격자 공역
|
||||||
|
const polyArr = []; |
||||||
|
const radius = air.buffer; |
||||||
|
const position = air.center; |
||||||
|
const color = '#000'; |
||||||
|
const opacity = 0.7; |
||||||
|
|
||||||
|
let angle = 0; |
||||||
|
for (let i = 0; i < 4; i++) { |
||||||
|
angle += 90; |
||||||
|
let buffer = 0; |
||||||
|
// for (let j = 0; j < 4; j++) {
|
||||||
|
for (let j = 0; j < 9; j++) { |
||||||
|
// buffer += 2000;
|
||||||
|
buffer += 1000; |
||||||
|
|
||||||
|
const coord = new naver.maps.EPSG3857.getDestinationCoord( |
||||||
|
position, |
||||||
|
angle, |
||||||
|
buffer |
||||||
|
); |
||||||
|
|
||||||
|
let reduce = 0; |
||||||
|
reduce = air.reduce[j]; |
||||||
|
|
||||||
|
// 2km reduce
|
||||||
|
// [218.6, 905.4, 2195, 4560.2]
|
||||||
|
|
||||||
|
if (angle % 180 == 0) { |
||||||
|
const polyEW = new naver.maps.Polyline({ |
||||||
|
path: [ |
||||||
|
new naver.maps.EPSG3857.getDestinationCoord( |
||||||
|
coord, |
||||||
|
90, |
||||||
|
radius - reduce |
||||||
|
), |
||||||
|
new naver.maps.EPSG3857.getDestinationCoord( |
||||||
|
coord, |
||||||
|
270, |
||||||
|
radius - reduce |
||||||
|
) |
||||||
|
], |
||||||
|
strokeWeight: 0.8, |
||||||
|
strokeOpacity: opacity, |
||||||
|
strokeColor: color |
||||||
|
// map: map
|
||||||
|
}); |
||||||
|
polyArr.push(polyEW); |
||||||
|
} else { |
||||||
|
const polyNS = new naver.maps.Polyline({ |
||||||
|
path: [ |
||||||
|
new naver.maps.EPSG3857.getDestinationCoord( |
||||||
|
coord, |
||||||
|
0, |
||||||
|
radius - reduce |
||||||
|
), |
||||||
|
new naver.maps.EPSG3857.getDestinationCoord( |
||||||
|
coord, |
||||||
|
180, |
||||||
|
radius - reduce |
||||||
|
) |
||||||
|
], |
||||||
|
strokeWeight: 0.8, |
||||||
|
strokeOpacity: opacity, |
||||||
|
strokeColor: color |
||||||
|
// map: props.map
|
||||||
|
}); |
||||||
|
polyArr.push(polyNS); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
const NS = new naver.maps.Polyline({ |
||||||
|
path: [ |
||||||
|
new naver.maps.EPSG3857.getDestinationCoord(position, 0, radius), |
||||||
|
new naver.maps.EPSG3857.getDestinationCoord(position, 180, radius) |
||||||
|
], |
||||||
|
strokeWeight: 0.8, |
||||||
|
strokeOpacity: opacity, |
||||||
|
strokeColor: color |
||||||
|
// map: props.map
|
||||||
|
}); |
||||||
|
polyArr.push(NS); |
||||||
|
const EW = new naver.maps.Polyline({ |
||||||
|
path: [ |
||||||
|
new naver.maps.EPSG3857.getDestinationCoord(position, 90, radius), |
||||||
|
new naver.maps.EPSG3857.getDestinationCoord(position, 270, radius) |
||||||
|
], |
||||||
|
strokeWeight: 0.8, |
||||||
|
strokeOpacity: opacity, |
||||||
|
strokeColor: color |
||||||
|
// map: props.map
|
||||||
|
}); |
||||||
|
polyArr.push(EW); |
||||||
|
|
||||||
|
setPoly(m => [...m, polyArr]); |
||||||
|
}; |
||||||
|
|
||||||
return ( |
return ( |
||||||
<div id='map'> |
<> |
||||||
<div |
<div |
||||||
style={{ width: '100%', height: '100vh' }} |
id='map' |
||||||
ref={mapContainer} |
ref={mapContainer} |
||||||
className='map-container' |
style={{ width: '100%', height: '100vh' }} |
||||||
/> |
></div> |
||||||
</div> |
{mapObject != null ? ( |
||||||
|
<> |
||||||
|
<DronMarker map={mapObject} naver={mapboxgl} /> |
||||||
|
|
||||||
|
{/* <DronPlan map={mapObject} naver={naver} /> |
||||||
|
<NewDronPlan map={mapObject} naver={naver} /> |
||||||
|
|
||||||
|
<NaverMapControl map={mapObject} /> */} |
||||||
|
|
||||||
|
{/* <DronHistory |
||||||
|
map={mapObject} |
||||||
|
naver={naver} |
||||||
|
arrPolyline={arrPolyline} |
||||||
|
handleHistoryInit={handleHistoryInit} |
||||||
|
/> */} |
||||||
|
{/* <NewDronHistory |
||||||
|
map={mapObject} |
||||||
|
naver={naver} |
||||||
|
arrPolyline={arrPolyline} |
||||||
|
handleHistoryInit={handleHistoryInit} |
||||||
|
/> */} |
||||||
|
|
||||||
|
{/* <DronToast /> |
||||||
|
|
||||||
|
<FeatureAirZone |
||||||
|
map={mapObject} |
||||||
|
naver={naver} |
||||||
|
features={features} |
||||||
|
poly={poly} |
||||||
|
/> */} |
||||||
|
{/* <NaverMapSearch map={mapObject} naver={naver} /> */} |
||||||
|
{/* <SensorZone map={mapObject} naver={naver} /> */} |
||||||
|
</> |
||||||
|
) : null} |
||||||
|
|
||||||
|
{/* */} |
||||||
|
</> |
||||||
); |
); |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue