김장현
1 year ago
6 changed files with 1259 additions and 491 deletions
@ -1,12 +1,12 @@ |
|||||||
import React from 'react'; |
import React from 'react'; |
||||||
import { GoogleCustomMap } from './google/GoogleMap'; |
import { GoogleCustomMap } from './google/GoogleMap'; |
||||||
import { NaverCustomMap } from './naver/NaverMap'; |
import { NaverCustomMap } from './naver/NaverMap'; |
||||||
import MapBoxTest from './naver/MapBoxTest'; |
import MapBoxMap from './mapbox/MapBoxMap'; |
||||||
|
|
||||||
export const MapControl = props => { |
export const MapControl = props => { |
||||||
return ( |
return ( |
||||||
// <>{props.mapType === 'google' ? <GoogleCustomMap /> : <NaverCustomMap />}</>
|
// <>{props.mapType === 'google' ? <GoogleCustomMap /> : <NaverCustomMap />}</>
|
||||||
// <NaverCustomMap />
|
// <NaverCustomMap />
|
||||||
<MapBoxTest /> |
<MapBoxMap /> |
||||||
); |
); |
||||||
}; |
}; |
||||||
|
@ -0,0 +1,622 @@ |
|||||||
|
import { MAPBOX_TOKEN } from '../../../configs/constants'; |
||||||
|
import { useEffect, useState, useRef } from 'react'; |
||||||
|
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 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;
|
||||||
|
export default function MapBoxMap() { |
||||||
|
// 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 [isMapLoaded, setMapLoaded] = useState(false); |
||||||
|
const [arrPolyline, setArrPolyline] = useState([]); |
||||||
|
const mapContainer = useRef(null); |
||||||
|
|
||||||
|
const uamPosition = { |
||||||
|
type: 'FeatureCollection', |
||||||
|
features: [ |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'V1', |
||||||
|
background: '#ffffff', |
||||||
|
border: '#15298A', |
||||||
|
spanColor: '#000000' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.540668, 37.4797865] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'V2', |
||||||
|
background: '#ffffff', |
||||||
|
border: '#15298A', |
||||||
|
spanColor: '#000000' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.6107763, 37.521245] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'V3', |
||||||
|
background: '#ffffff', |
||||||
|
border: '#15298A', |
||||||
|
spanColor: '#000000' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.6243464, 37.5642352] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'V4', |
||||||
|
background: '#ffffff', |
||||||
|
border: '#15298A', |
||||||
|
spanColor: '#000000' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.6650669, 37.3658236] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'V5', |
||||||
|
background: '#ffffff', |
||||||
|
border: '#15298A', |
||||||
|
spanColor: '#000000' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.7074861, 37.4520753] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'R1', |
||||||
|
background: '#429629', |
||||||
|
border: '#ffffff', |
||||||
|
spanColor: '#ffffff' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.5801572, 37.492581] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'R2', |
||||||
|
background: '#429629', |
||||||
|
border: '#ffffff', |
||||||
|
spanColor: '#ffffff' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.6036588, 37.542031] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'R3', |
||||||
|
background: '#429629', |
||||||
|
border: '#ffffff', |
||||||
|
spanColor: '#ffffff' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.6005224, 37.5764269] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'R4', |
||||||
|
background: '#429629', |
||||||
|
border: '#ffffff', |
||||||
|
spanColor: '#ffffff' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.6600404, 37.5790407] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'R5', |
||||||
|
background: '#429629', |
||||||
|
border: '#ffffff', |
||||||
|
spanColor: '#ffffff' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.649562, 37.524016] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'R6', |
||||||
|
background: '#429629', |
||||||
|
border: '#ffffff', |
||||||
|
spanColor: '#ffffff' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.693722, 37.5506488] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'R7', |
||||||
|
background: '#429629', |
||||||
|
border: '#ffffff', |
||||||
|
spanColor: '#ffffff' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.6023981, 37.4712333] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'R8', |
||||||
|
background: '#429629', |
||||||
|
border: '#ffffff', |
||||||
|
spanColor: '#ffffff' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.6202759, 37.4046495] |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'Feature', |
||||||
|
properties: { |
||||||
|
name: 'R9', |
||||||
|
background: '#429629', |
||||||
|
border: '#ffffff', |
||||||
|
spanColor: '#ffffff' |
||||||
|
}, |
||||||
|
geometry: { |
||||||
|
type: 'Point', |
||||||
|
coordinates: [126.6296542, 37.3450207] |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
NaverMapInit(); |
||||||
|
}, []); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (mapObject) { |
||||||
|
uamPosition.features.map(uam => { |
||||||
|
const el = document.createElement('div'); |
||||||
|
const elChild = document.createElement('span'); |
||||||
|
elChild.innerText = uam.properties.name; |
||||||
|
elChild.style.color = uam.properties.spanColor; |
||||||
|
el.className = 'marker'; |
||||||
|
el.style.background = uam.properties.background; |
||||||
|
el.style.borderRadius = '50%'; |
||||||
|
el.style.border = `4px solid ${uam.properties.border}`; |
||||||
|
el.style.padding = '5px'; |
||||||
|
el.style.width = '40px'; |
||||||
|
el.style.height = '40px'; |
||||||
|
el.style.textAlign = 'center'; |
||||||
|
el.appendChild(elChild); |
||||||
|
|
||||||
|
new mapboxgl.Marker(el) |
||||||
|
.setLngLat(uam.geometry.coordinates) |
||||||
|
.addTo(mapObject); |
||||||
|
}); |
||||||
|
} |
||||||
|
}, [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: 9 // starting zoom
|
||||||
|
}); |
||||||
|
|
||||||
|
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; |
||||||
|
|
||||||
|
// 지형 3d start
|
||||||
|
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.addLayer({ |
||||||
|
id: 'contour-labels', |
||||||
|
type: 'symbol', |
||||||
|
source: { |
||||||
|
type: 'vector', |
||||||
|
url: 'mapbox://mapbox.mapbox-terrain-v2' |
||||||
|
}, |
||||||
|
'source-layer': 'contour', |
||||||
|
layout: { |
||||||
|
visibility: 'visible', |
||||||
|
'symbol-placement': 'line', |
||||||
|
'text-field': ['concat', ['to-string', ['get', 'ele']], 'm'] |
||||||
|
}, |
||||||
|
paint: { |
||||||
|
'icon-color': '#877b59', |
||||||
|
'icon-halo-width': 1, |
||||||
|
'text-color': '#877b59', |
||||||
|
'text-halo-width': 1 |
||||||
|
} |
||||||
|
}); |
||||||
|
map.addLayer({ |
||||||
|
id: 'sky', |
||||||
|
type: 'sky', |
||||||
|
paint: { |
||||||
|
'sky-type': 'atmosphere', |
||||||
|
'sky-atmosphere-sun': [0.0, 90.0], |
||||||
|
'sky-atmosphere-sun-intensity': 15 |
||||||
|
} |
||||||
|
}); |
||||||
|
// 지형 3d end
|
||||||
|
// 등고선 start
|
||||||
|
map.addLayer({ |
||||||
|
id: 'contours', |
||||||
|
type: 'line', |
||||||
|
source: { |
||||||
|
type: 'vector', |
||||||
|
url: 'mapbox://mapbox.mapbox-terrain-v2' |
||||||
|
}, |
||||||
|
'source-layer': 'contour', |
||||||
|
layout: { |
||||||
|
visibility: 'visible', |
||||||
|
'line-join': 'round', |
||||||
|
'line-cap': 'round' |
||||||
|
}, |
||||||
|
paint: { |
||||||
|
'line-color': '#877b59', |
||||||
|
'line-width': 1 |
||||||
|
} |
||||||
|
}); |
||||||
|
// 등고선 end
|
||||||
|
// 3d building
|
||||||
|
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 |
||||||
|
); |
||||||
|
// 3d building
|
||||||
|
setMapObject(map); |
||||||
|
setMapLoaded(true); |
||||||
|
}); |
||||||
|
map.on('mouseover', '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('mouseout', 'maine', () => { |
||||||
|
if (popup) { |
||||||
|
popup.remove(); |
||||||
|
} |
||||||
|
}); |
||||||
|
// airPort?.map(air => polyArea(air, map));
|
||||||
|
}; |
||||||
|
|
||||||
|
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 < 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 = {
|
||||||
|
// 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 = {
|
||||||
|
// 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 = {
|
||||||
|
// 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 = {
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// setPoly(m => [...m, polyArr]);
|
||||||
|
// };
|
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<div |
||||||
|
id='map' |
||||||
|
ref={mapContainer} |
||||||
|
style={{ width: '100%', height: '100vh' }} |
||||||
|
></div> |
||||||
|
{isMapLoaded && mapObject ? ( |
||||||
|
<> |
||||||
|
{/* <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={mapboxgl} /> |
||||||
|
{/* <NaverMapSearch map={mapObject} naver={naver} /> */} |
||||||
|
{/* <SensorZone map={mapObject} naver={naver} /> */} |
||||||
|
</> |
||||||
|
) : null} |
||||||
|
|
||||||
|
{/* */} |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,405 @@ |
|||||||
|
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'; |
||||||
|
|
||||||
|
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 infoWindow; |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
featureAirZoneInit(); |
||||||
|
// featureAirEvent();
|
||||||
|
}, [mapControl]); |
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// const addLayers = () => {
|
||||||
|
// props.poly.forEach((layer, idx) => {
|
||||||
|
// // console.log(layer);
|
||||||
|
// props.map.addSource(`line${idx}`, {
|
||||||
|
// type: 'geojson',
|
||||||
|
// data: {
|
||||||
|
// layer
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// props.map.addLayer(layer);
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
// addLayers();
|
||||||
|
|
||||||
|
// // return () => {
|
||||||
|
// // props.map.remove();
|
||||||
|
// // };
|
||||||
|
// }, [props.poly]);
|
||||||
|
|
||||||
|
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 class="ti">설명</span>' +
|
||||||
|
'<span>' + |
||||||
|
data.description + |
||||||
|
'</span>' + |
||||||
|
'</div>' + |
||||||
|
// '<div class="tooltip-txt-list">' +
|
||||||
|
// '<span class="ti">좌표정보</span>' +
|
||||||
|
// '<span>'+data.coord+'</span>' +
|
||||||
|
// '</div>' +
|
||||||
|
'</div>' + |
||||||
|
// '<span class="arrow"></span>' +
|
||||||
|
'</div>'; |
||||||
|
|
||||||
|
infoWindow = new props.naver.maps.InfoWindow({ |
||||||
|
class: 'tooltip-test', |
||||||
|
content: content, |
||||||
|
maxWidth: 200, |
||||||
|
backgroundColor: '#283046', //박스안쪽영역 컬러
|
||||||
|
// borderColor: '#333', //테두리컬러
|
||||||
|
// borderWidth: 3, //테두리 굵기
|
||||||
|
anchorSize: new props.naver.maps.Size(30, -10), |
||||||
|
anchorSkew: false, |
||||||
|
anchorColor: '#283046', |
||||||
|
|
||||||
|
pixelOffset: new props.naver.maps.Point(20, -20) |
||||||
|
}); |
||||||
|
|
||||||
|
infoWindow.open(props.map, data.coord); |
||||||
|
}; |
||||||
|
|
||||||
|
const featureAirZoneInit = () => { |
||||||
|
let arrGeoJson = []; |
||||||
|
// props.map.data.removeGeoJson(props.geoJson);
|
||||||
|
// let geoJson = originGeoJson;
|
||||||
|
const useGeoJson = { |
||||||
|
...geoJson, |
||||||
|
features: [...geoJson.features, ...gimPo.features] |
||||||
|
}; |
||||||
|
|
||||||
|
// props.map.data.removeGeoJson(useGeoJson);
|
||||||
|
// props.map.removeLayer('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; |
||||||
|
|
||||||
|
props.map.addSource('maine', { |
||||||
|
type: 'geojson', |
||||||
|
data: { |
||||||
|
...useGeoJson |
||||||
|
} |
||||||
|
}); |
||||||
|
props.map.addLayer({ |
||||||
|
id: 'maine', |
||||||
|
type: 'fill', |
||||||
|
source: 'maine', // reference the data source
|
||||||
|
layout: {}, |
||||||
|
paint: { |
||||||
|
'fill-color': ['get', 'color'], |
||||||
|
'fill-opacity': 0.5 |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
airPort.map(air => polyArea(air)); |
||||||
|
|
||||||
|
// useGeoJson.features = arrGeoJson;
|
||||||
|
// props.map.data.addGeoJson(useGeoJson);
|
||||||
|
|
||||||
|
// props.map.data.setStyle(feature => {
|
||||||
|
// var color;
|
||||||
|
|
||||||
|
// //0001 비행금지구역 #FF3648
|
||||||
|
// //0002 비행제한구역 #FFA1AA
|
||||||
|
// //0003 관제권(공항) #FFA800
|
||||||
|
// //0004 비행장(군사) #A16B00
|
||||||
|
// //0005 이착륙장(RC비행장) #AB40FF
|
||||||
|
// //0006 초경량비행장치 #009cad
|
||||||
|
|
||||||
|
// // 공역 색상 변경
|
||||||
|
// const type = feature.getProperty('type');
|
||||||
|
// if (type === '0001') {
|
||||||
|
// color = '#FF3648';
|
||||||
|
// } else if (type === '0002') {
|
||||||
|
// color = '#FFA1AA';
|
||||||
|
// } else if (type === '0003') {
|
||||||
|
// color = '#FFA800';
|
||||||
|
// } else if (type === '0004') {
|
||||||
|
// color = '#A16B00';
|
||||||
|
// } else if (type === '0005') {
|
||||||
|
// color = '#AB40FF';
|
||||||
|
// } else if (type === '0006') {
|
||||||
|
// color = '#009cad';
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// fillColor: color,
|
||||||
|
// strokeColor: color,
|
||||||
|
// strokeWeight: 0.7,
|
||||||
|
// icon: null
|
||||||
|
// };
|
||||||
|
// });
|
||||||
|
}; |
||||||
|
|
||||||
|
const featureAirEvent = () => { |
||||||
|
props.map.data.addListener('click', function (e) { |
||||||
|
// e.feature.setProperty('isColorful', true);
|
||||||
|
}); |
||||||
|
|
||||||
|
props.map.data.addListener('mouseover', function (e) { |
||||||
|
const data = {}; |
||||||
|
data.coord = e.coord; |
||||||
|
data.title = e.feature.property_name; |
||||||
|
data.description = e.feature.property_description; |
||||||
|
props.map.data.overrideStyle(e.feature, { |
||||||
|
strokeWeight: 3 |
||||||
|
// icon: HOME_PATH +'/img/example/pin_spot.png'
|
||||||
|
}); |
||||||
|
|
||||||
|
infowindowOpen(data); |
||||||
|
}); |
||||||
|
|
||||||
|
props.map.data.addListener('mouseout', function (e) { |
||||||
|
props.map.data.revertStyle(); |
||||||
|
|
||||||
|
if (infoWindow) { |
||||||
|
infoWindow.close(); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
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); |
||||||
|
|
||||||
|
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; |
||||||
|
}; |
@ -1,485 +0,0 @@ |
|||||||
import { MAPBOX_TOKEN } from '../../../configs/constants'; |
|
||||||
import React, { useEffect, useState, useRef } from 'react'; |
|
||||||
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;
|
|
||||||
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 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(() => { |
|
||||||
NaverMapInit(); |
|
||||||
|
|
||||||
// const map = new mapboxgl.Map({
|
|
||||||
// container: mapContainer.current,
|
|
||||||
// style: 'mapbox://styles/mapbox/streets-v11',
|
|
||||||
// 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 ( |
|
||||||
<> |
|
||||||
<div |
|
||||||
id='map' |
|
||||||
ref={mapContainer} |
|
||||||
style={{ width: '100%', height: '100vh' }} |
|
||||||
></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