map-mngr.js 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511
  1. import { LayerInfo, LayerIndex, LayerType, FacilityComm, TrafficGrade, TrafficGradeDesc, EditLinkLineSize, EditLinkColor } from "./map-const.js";
  2. import { TMapConfig } from "./map-config.js";
  3. import { TMapLayer } from "./map-layer.js";
  4. import { TTraffic, TLink, TIfsc, TRoad, _trafMap, _linkMap, _ifscMap, _roadMap } from "./obj-traffic.js";
  5. // https://github.com/Viglino/ol-ext
  6. let _mapMngr = null;
  7. class TLayerMap {
  8. constructor(ALayerInfo, ALayer) {
  9. this.lyrInfo = ALayerInfo;
  10. this.layer = ALayer;
  11. }
  12. }
  13. function copyToClipboard(val) {
  14. const t = document.createElement("textarea");
  15. document.body.appendChild(t);
  16. t.value = val;
  17. t.select();
  18. document.execCommand("copy");
  19. document.body.removeChild(t);
  20. }
  21. export class TFclt {
  22. constructor(ANmbr, AName, AX, AY) {
  23. this.NMBR = ANmbr;
  24. this.NAME = AName;
  25. this.LAT = AX;
  26. this.LNG = AY;
  27. this.COMM = "0";
  28. }
  29. }
  30. export class TMapMngr {
  31. constructor(AMapId, ATooltipId) {
  32. _mapMngr = this;
  33. this.mapId = AMapId;
  34. this.tooltipId = ATooltipId;
  35. this.linkEditMode = false;
  36. this.config = new TMapConfig();
  37. this.currZoom = this.config.mapDefZoom;
  38. this.lyrInfoMap = new Map(); // 레이어 이름으로 레이어 인덱스를 찾기위한 맵
  39. this.layerArr = new Array(LayerIndex.MAX); // 레이어정보를 저장하고 있는 배열
  40. this.showTrafficTip = true; // 소통정보 툴팁 표출여부 플래그
  41. this.showTrafficLyr = true; // 소통정보 레이어 표출여부 플래그
  42. this.showIncidentLyr = true; // 돌발 레이어 표출여부 플래그
  43. this.selectFeature = null; // 객체 또는 좌표 선택시 표출할 화살표 feature
  44. this.isMeasurement = false; // 거리재기, 명적재기 등 작업 여부 플래그
  45. this.selectMode = false; // 객체 선택 모드 플래그
  46. this.selLinkWidth = 4; // 선택 링크 굵기
  47. this.selLink = null; // 소통정보 폴리라인 선택 객체
  48. this.selLinkStyle = null; // 소통정보 폴리라인 선택 스타일
  49. this.mapApp = {};
  50. this.editMode = false; // 지도 편집 모드 플래그
  51. this.editLayerIdx = -1; // 편집 레이어 인덱스
  52. this.editObj = null;
  53. this.editFeature = null;
  54. this.editCoords = null;
  55. this.onFcltDragEndFunc = null;
  56. this.selectLayerIdx = -1; // 선택 레이어 인덱스
  57. this.timerSelectArrow = null; // 객체선택 타이머
  58. this.onMapMoveEndFunc = null;
  59. this.onMouseClickFunc = null;
  60. this.onContextMenuFunc = null;
  61. this.onSelectObjFunc = null;
  62. this.centerPos = null;
  63. this.resizeMapUpdateTimer = null;
  64. this.mapApp.Drag = function () {
  65. ol.interaction.Pointer.call(this, {
  66. handleDownEvent: _mapMngr.mapApp.Drag.prototype.handleDownEvent,
  67. handleDragEvent: _mapMngr.mapApp.Drag.prototype.handleDragEvent,
  68. handleUpEvent: _mapMngr.mapApp.Drag.prototype.handleUpEvent,
  69. });
  70. _mapMngr.initEditMode();
  71. };
  72. ol.inherits(this.mapApp.Drag, ol.interaction.Pointer);
  73. this.mapApp.Drag.prototype.handleDownEvent = function (evt) {
  74. if (_mapMngr.editMode == false) return false;
  75. //const map = evt.map;
  76. const feature = _mapMngr.map.forEachFeatureAtPixel(evt.pixel, function (feature) {
  77. return feature;
  78. });
  79. if (feature) {
  80. const obj = feature.get("obj");
  81. if (!obj) return false;
  82. if (_mapMngr.editLayerIdx != obj.lyrIdx) return false;
  83. if (obj.edit == false) return false;
  84. _mapMngr.editObj = obj;
  85. _mapMngr.editCoords = evt.coordinate;
  86. _mapMngr.editFeature = feature;
  87. }
  88. return !!feature;
  89. };
  90. this.mapApp.Drag.prototype.handleDragEvent = function (evt) {
  91. if (_mapMngr.editMode == false) return;
  92. if (_mapMngr.editFeature) {
  93. const deltaX = evt.coordinate[0] - _mapMngr.editCoords[0];
  94. const deltaY = evt.coordinate[1] - _mapMngr.editCoords[1];
  95. const geometry = _mapMngr.editFeature.getGeometry();
  96. geometry.translate(deltaX, deltaY);
  97. _mapMngr.editCoords[0] = evt.coordinate[0];
  98. _mapMngr.editCoords[1] = evt.coordinate[1];
  99. }
  100. };
  101. this.mapApp.Drag.prototype.handleUpEvent = function () {
  102. if (_mapMngr.editMode == false) return false;
  103. if (!_mapMngr.editObj) return false;
  104. if (_mapMngr.onFcltDragEndFunc) {
  105. try {
  106. const obj = _mapMngr.editObj;
  107. _mapMngr.onFcltDragEndFunc(obj.lyrInfo.lyrIdx, obj.lyrInfo.lyrName, obj.NMBR, _mapMngr.editCoords[0], _mapMngr.editCoords[1]);
  108. } catch (err) {
  109. console.error(err);
  110. }
  111. }
  112. _mapMngr.initEditMode();
  113. return false;
  114. };
  115. const scaleLineControl = new ol.control.ScaleLine();
  116. this.map = new ol.Map({
  117. controls: ol.control
  118. .defaults({
  119. attributionOptions: {
  120. collapsible: true,
  121. },
  122. })
  123. .extend([scaleLineControl]),
  124. interactions: ol.interaction.defaults({ doubleClickZoom: false }).extend([new this.mapApp.Drag()]),
  125. // interactions: ol.interaction.defaults({c: false}).extend([
  126. // new ol.interaction.MouseWheelZoom({
  127. // constrainResolution: true
  128. // })
  129. // ]),
  130. layers: [
  131. //this.config.baseMapLyr.normal,
  132. //this.config.baseMapLyr.satellite,
  133. this.config.baseMapGroup,
  134. this.config.trafGroup,
  135. this.config.poiGroup,
  136. this.config.eventGroup,
  137. ],
  138. logo: false,
  139. target: document.getElementById(AMapId),
  140. renderer: "canvas",
  141. view: this.config.mapView,
  142. });
  143. this.initMapLayer();
  144. this.currZoom = Math.round(this.map.getView().getZoom());
  145. this.selectFeature = this.layerArr[LayerIndex.Select].makePoiLayer([127.109873, 37.283203]); /*맵을 만든다음에 Select Layer를 생성해야함*/
  146. this.tooltip = document.getElementById(ATooltipId);
  147. this.tooltipOverlay = new ol.Overlay({
  148. element: this.tooltip,
  149. offset: [10, 0],
  150. positioning: "bottom-left",
  151. });
  152. this.map.addOverlay(this.tooltipOverlay);
  153. let layerSwitcher = new ol.control.LayerSwitcher({
  154. tipLabel: "레이어",
  155. groupSelectStyle: "children",
  156. });
  157. //this.map.addControl(layerSwitcher);
  158. document.getElementsByClassName("ol-zoom")[0].style.display = "none";
  159. const zoomLevelText = document.getElementById("zoom_level");
  160. if (zoomLevelText) {
  161. zoomLevelText.value = this.currZoom;
  162. }
  163. // 줌변경 및 지도표출영역 변경 이벤트 체크
  164. this.map.on("moveend", function (e) {
  165. const currZoom = Math.round(_mapMngr.map.getView().getZoom());
  166. if (_mapMngr.currZoom != currZoom) {
  167. _mapMngr.currZoom = currZoom;
  168. if (zoomLevelText) {
  169. zoomLevelText.value = _mapMngr.currZoom;
  170. }
  171. // 줌이 변경된 경우에만 지도를 다시 그린다
  172. _mapMngr.refreshMap();
  173. }
  174. _mapMngr.centerPos = _mapMngr.map.getView().getCenter();
  175. const bound = _mapMngr.map.getView().calculateExtent(_mapMngr.map.getSize());
  176. const swLat = bound[0]; //left
  177. const swLng = bound[1]; //bottom
  178. const neLat = bound[2]; //right
  179. const neLng = bound[3]; //top
  180. if (_mapMngr.onMapMoveEndFunc) {
  181. _mapMngr.onMapMoveEndFunc(_mapMngr.currZoom, _mapMngr.centerPos[0], _mapMngr.centerPos[1], swLat, swLng, neLat, neLng);
  182. }
  183. });
  184. // 컨텍스트 메뉴 핸들러
  185. this.map.getViewport().addEventListener("contextmenu", function (e) {
  186. e.preventDefault();
  187. const f = _mapMngr.map.forEachFeatureAtPixel(_mapMngr.map.getEventPixel(e), function (feature, layer) {
  188. return feature;
  189. });
  190. if (f) {
  191. const coord = f.getGeometry().getCoordinates();
  192. const obj = f.get("obj");
  193. if (!obj) {
  194. return;
  195. }
  196. const lyrInfo = obj.lyrInfo;
  197. const lyrType = lyrInfo.lyrType;
  198. try {
  199. if (_mapMngr.onContextMenuFunc != null) {
  200. if (lyrType <= LayerType.VMSI) {
  201. const xy = coord[0];
  202. _mapMngr.onContextMenuFunc(obj.lyrInfo.lyrIdx, obj.lyrInfo.lyrName, obj.NMBR, xy[0], xy[1], e.x, e.y);
  203. } else {
  204. _mapMngr.onContextMenuFunc(obj.lyrInfo.lyrIdx, obj.lyrInfo.lyrName, obj.NMBR, coord[0], coord[1], e.x, e.y);
  205. }
  206. }
  207. } catch (err) {
  208. console.error(err);
  209. }
  210. } else {
  211. if (_mapMngr.onMouseClickFunc != null) {
  212. _mapMngr.onMouseClickFunc(-1, -1, -1, -1, -1, -1, -1);
  213. }
  214. }
  215. });
  216. // checking mouse click event
  217. this.map.on("click", function (e) {
  218. const f = _mapMngr.map.forEachFeatureAtPixel(e.pixel, function (feature) {
  219. return feature;
  220. });
  221. if (f) {
  222. const coord = f.getGeometry().getCoordinates();
  223. const obj = f.get("obj");
  224. if (!obj) {
  225. return;
  226. }
  227. const lyrInfo = obj.lyrInfo;
  228. const lyrType = lyrInfo.lyrType;
  229. let xy = [];
  230. if (lyrType <= LayerType.VMSI) {
  231. xy = e.coordinate; //coord[0];
  232. } else if (coord) {
  233. xy[0] = coord[0];
  234. xy[1] = coord[1];
  235. } else if (obj.coordinates) {
  236. xy[0] = obj.coordinates[0];
  237. xy[1] = obj.coordinates[1];
  238. }
  239. if (_mapMngr.selectMode) {
  240. copyToClipboard(obj.NMBR);
  241. try {
  242. if (_mapMngr.onSelectObjFunc != null) {
  243. _mapMngr.onSelectObjFunc(obj.lyrInfo.lyrIdx, obj.lyrInfo.lyrName, obj.NMBR, xy[0], xy[1], e.pixel[0], e.pixel[1]);
  244. }
  245. } catch (err) {
  246. console.error(err);
  247. }
  248. } else {
  249. try {
  250. if (_mapMngr.onMouseClickFunc != null) {
  251. _mapMngr.onMouseClickFunc(obj.lyrInfo.lyrIdx, obj.lyrInfo.lyrName, obj.NMBR, xy[0], xy[1], e.pixel[0], e.pixel[1]);
  252. }
  253. } catch (err) {
  254. console.error(err);
  255. }
  256. }
  257. } else {
  258. if (_mapMngr.onMouseClickFunc != null) {
  259. _mapMngr.onMouseClickFunc(-1, -1, -1, -1, -1, e.pixel[0], e.pixel[1]);
  260. }
  261. }
  262. });
  263. this.map.on("pointermove", this.onMouseMove);
  264. this.map.getViewport().addEventListener("mouseout", this.onMapMouseOut);
  265. } // constructor
  266. onMapMouseOut( e ) {
  267. _mapMngr.tooltip.style.display = "none";
  268. if (_mapMngr.selLink != null && _mapMngr.selLinkStyle != null) {
  269. _mapMngr.selLink.setStyle(_mapMngr.selLinkStyle);
  270. _mapMngr.selLink = null;
  271. _mapMngr.selLinkStyle = null;
  272. }
  273. }
  274. onMouseMove(e) {
  275. _mapMngr.tooltip.style.display = "none";
  276. if (e.dragging) {
  277. return;
  278. }
  279. if (_mapMngr.isMeasurement) {
  280. return;
  281. }
  282. _mapMngr.map.getTarget().style.cursor = "";
  283. if (_mapMngr.selLink !== null && _mapMngr.selLinkStyle !== null) {
  284. _mapMngr.selLink.setStyle(_mapMngr.selLinkStyle);
  285. _mapMngr.selLink = null;
  286. _mapMngr.selLinkStyle = null;
  287. }
  288. const f = _mapMngr.map.forEachFeatureAtPixel(e.pixel, function (feature) {
  289. return feature;
  290. });
  291. if (f) {
  292. _mapMngr.map.getTarget().style.cursor = "pointer";
  293. const obj = f.get("obj");
  294. if (!obj) {
  295. return;
  296. }
  297. const lyrInfo = obj.lyrInfo;
  298. const lyrType = lyrInfo.lyrType;
  299. if (lyrType === LayerType.TRAF || lyrType === LayerType.LINK || lyrType === LayerType.IFSC || lyrType === LayerType.ROAD) {
  300. _mapMngr.selLink = f;
  301. _mapMngr.selLinkStyle = f.getStyle();
  302. const style = new ol.style.Style({
  303. stroke: new ol.style.Stroke({
  304. color: "red",
  305. width: _mapMngr.selLinkWidth + 4,
  306. }),
  307. });
  308. f.setStyle(style);
  309. }
  310. let iwContent = "";
  311. if (_mapMngr.editMode) {
  312. let NAME;
  313. if (lyrType === LayerType.TRAF || lyrType === LayerType.LINK || lyrType === LayerType.IFSC || lyrType === LayerType.ROAD) {
  314. NAME = `${obj.obj.STRT_NM} -> ${obj.obj.END_NM}`;
  315. } else {
  316. NAME = obj.NAME;
  317. }
  318. iwContent = '<div id="edit-tooltip">' + NAME + "</div>";
  319. } else {
  320. if (lyrType === LayerType.TRAF || lyrType === LayerType.LINK || lyrType === LayerType.IFSC || lyrType === LayerType.ROAD) {
  321. if (_mapMngr.showTrafficTip) {
  322. const refObj = obj.obj;
  323. const grade = Number(refObj.cmtrGradCd);
  324. const info = TrafficGradeDesc[grade];
  325. const road = refObj.NAME;
  326. const path = `${refObj.STRT_NM} -> ${refObj.END_NM}`;
  327. const cnt = path ? path.length : 250;
  328. const widSize = cnt > 20 ? 380 : 250;
  329. //iwContent = '<div export class="mapPop traffic_' + grade + '" style="width:' + widSize + 'px !important;">';
  330. iwContent = '<div export class="mapPop traffic_' + grade + '" >';
  331. iwContent += '<div export class="head"><span export class="title">' + road + '</span><span export class="traffic">' + info + "</span></div>";
  332. iwContent += '<div export class="cont">';
  333. iwContent += "<dl><dt>" + path + "</dt>";
  334. let sectLength = "-";
  335. if (refObj.SECT_LNGT) {
  336. sectLength = refObj.SECT_LNGT.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  337. }
  338. let sped = "-";
  339. if (refObj.sped) {
  340. sped = refObj.sped.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  341. }
  342. iwContent += "<dd>구간거리 : " + sectLength + " m<br/>평균속도 : " + sped + " km/h</dd>";
  343. iwContent += "</dl></div>";
  344. }
  345. } else if (lyrType === LayerType.FCLT) {
  346. if (lyrInfo) {
  347. const lyrName = "[" + lyrInfo.lyrName + "]";
  348. const COMM = obj.COMM;
  349. let path = obj.NAME;
  350. if (lyrName === "[교차로카메라]") {
  351. const direction = ["북", "동", "남", "서", "북동", "남동", "북서", "남서"];
  352. if (obj.drct_dvsn_cd >= 0) path = obj.NAME + " (" + direction[obj.drct_dvsn_cd - 1] + ")";
  353. }
  354. if (path === null || path === undefined || path === "") {
  355. path = "-";
  356. }
  357. let grade = 1;
  358. let info = "";
  359. const commStts = Number(obj.COMM);
  360. switch (commStts) {
  361. case FacilityComm.Normal.state:
  362. info = FacilityComm.Normal.desc;
  363. grade = TrafficGrade.Light.grade;
  364. break;
  365. case FacilityComm.Error.state:
  366. info = FacilityComm.Error.desc;
  367. grade = TrafficGrade.Heavy.grade;
  368. break;
  369. case FacilityComm.Module.state:
  370. info = FacilityComm.Module.desc;
  371. grade = TrafficGrade.Moderate.grade;
  372. break;
  373. default:
  374. info = FacilityComm.Unknown.desc;
  375. grade = TrafficGrade.NoData.grade;
  376. break;
  377. }
  378. const cnt = path ? path.length : 250;
  379. const widSize = cnt > 20 ? 380 : 250;
  380. iwContent = '<div export class="mapPop traffic_' + grade + '" style="width:' + widSize + 'px !important;">';
  381. iwContent += '<div export class="head"><span export class="title">' + lyrName;
  382. iwContent += '</span><span export class="traffic">' + info + "</span></div>";
  383. iwContent += '<div export class="cont">';
  384. iwContent += "<dl><dt>" + path + "</dt>";
  385. if (obj.NMBR) {
  386. iwContent += "<dd>NO : " + obj.NMBR;
  387. }
  388. if (obj.ID) {
  389. iwContent += "<br/> ID : " + obj.ID + "</dd>";
  390. }
  391. if (lyrName === "[교차로카메라]") {
  392. let traff = "-";
  393. if (obj.info1) {
  394. traff = obj.info1.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  395. }
  396. iwContent += "<dd>교통량 : " + traff + " 대</dd>";
  397. }
  398. iwContent += "</dl></div>";
  399. }
  400. } else if (lyrType === LayerType.BIS) {
  401. if (lyrInfo) {
  402. const lyrName = "[" + lyrInfo.lyrName + "]";
  403. const path = obj.NAME;
  404. let grade = 1;
  405. let info = "";
  406. const commStts = Number(obj.COMM);
  407. switch (commStts) {
  408. case FacilityComm.Normal.state:
  409. info = FacilityComm.Normal.desc;
  410. grade = TrafficGrade.Light.grade;
  411. break;
  412. case FacilityComm.Error.state:
  413. info = FacilityComm.Error.desc;
  414. grade = TrafficGrade.Heavy.grade;
  415. break;
  416. case FacilityComm.Module.state:
  417. info = FacilityComm.Module.desc;
  418. grade = TrafficGrade.Moderate.grade;
  419. break;
  420. default:
  421. info = FacilityComm.Unknown.desc;
  422. grade = TrafficGrade.NoData.grade;
  423. break;
  424. }
  425. const cnt = path ? path.length : 250;
  426. const widSize = cnt > 20 ? 380 : 250;
  427. iwContent = '<div export class="mapPop traffic_' + grade + '" style="width:' + widSize + 'px !important;">';
  428. iwContent += '<div export class="head"><span export class="title">' + lyrName + "</span></div>";
  429. iwContent += '<div export class="cont">';
  430. iwContent += "<dl><dt>" + path + "</dt>";
  431. iwContent += "<dd>" + obj.NMBR + "<br/></dd>";
  432. iwContent += "</dl></div>";
  433. }
  434. } else if (lyrType === LayerType.PARK) {
  435. if (lyrInfo) {
  436. const lyrName = "[" + lyrInfo.lyrName + "]";
  437. const COMM = obj.COMM;
  438. const path = obj.NAME;
  439. let grade = 1;
  440. let info = "";
  441. const commStts = Number(obj.COMM);
  442. switch (commStts) {
  443. case FacilityComm.Normal.state:
  444. info = FacilityComm.Normal.desc;
  445. grade = TrafficGrade.Light.grade;
  446. break;
  447. case FacilityComm.Error.state:
  448. info = FacilityComm.Error.desc;
  449. grade = TrafficGrade.Heavy.grade;
  450. break;
  451. case FacilityComm.Module.state:
  452. info = FacilityComm.Module.desc;
  453. grade = TrafficGrade.Moderate.grade;
  454. break;
  455. default:
  456. info = FacilityComm.Unknown.desc;
  457. grade = TrafficGrade.NoData.grade;
  458. break;
  459. }
  460. const cnt = path ? path.length : 250;
  461. const widSize = cnt > 20 ? 380 : 250;
  462. iwContent = '<div export class="mapPop traffic_' + grade + '" style="width:' + widSize + 'px !important;">';
  463. iwContent += '<div export class="head"><span export class="title">' + lyrName + "</div>";
  464. iwContent += '<div export class="cont">';
  465. iwContent += "<dl><dt>" + path + "</dt>";
  466. iwContent += "<dd>주차면수: " + obj.parkingCnt + "<br/>위치: " + obj.location + "</dd>";
  467. iwContent += "</dl></div>";
  468. }
  469. } else if (lyrType === LayerType.INCD) {
  470. if (lyrInfo) {
  471. const nmbr = obj.NMBR;
  472. const REG_DT = obj.REG_DT;
  473. const STR_DT = obj.STR_DT;
  474. const END_DT = obj.END_DT;
  475. const INCLOC = obj.INCLOC;
  476. const path = obj.TITLE;
  477. const INCTYPECD = obj.COMM;
  478. let grade = 1;
  479. let info = obj.INCTYPENM;
  480. switch (Number(INCTYPECD)) {
  481. case 1:
  482. grade = TrafficGrade.Heavy.grade;
  483. break; /*사고*/
  484. case 2:
  485. grade = TrafficGrade.Moderate.grade;
  486. break; /*공사*/
  487. case 3:
  488. case 5:
  489. case 6:
  490. grade = TrafficGrade.Light.grade;
  491. break; /*행사*/
  492. default:
  493. grade = TrafficGrade.NoData.grade;
  494. break; /*기상*/
  495. }
  496. const cnt = path ? path.length : 250;
  497. const widSize = cnt > 40 ? 450 : 250;
  498. iwContent = '<div export class="mapPop traffic_' + grade + '" style="width:' + widSize + 'px !important;">';
  499. iwContent += '<div export class="head"><span export class="title">' + nmbr + '</span><span export class="traffic">' + info + "</span></div>";
  500. iwContent += '<div export class="cont">';
  501. iwContent += "<dl><dt>" + path + "</dt>";
  502. iwContent +=
  503. "<dd>등록시각: " +
  504. getParseDateTime(REG_DT) +
  505. "<br/>시작시각: " +
  506. getParseDateTime(STR_DT) +
  507. "<br/>종료시각: " +
  508. getParseDateTime(END_DT) +
  509. "<br/>발생장소: " +
  510. INCLOC +
  511. "</dd>";
  512. iwContent += "</dl></div>";
  513. }
  514. }
  515. }
  516. if (lyrInfo.showTooltip && iwContent != "") {
  517. _mapMngr.tooltip.style.display = "";
  518. _mapMngr.tooltipOverlay.setPosition(e.coordinate);
  519. _mapMngr.tooltip.innerHTML = iwContent;
  520. }
  521. }
  522. }
  523. setOverlay(overlay) {
  524. overlay.forEach((el) => {
  525. this.map.addOverlay(el);
  526. });
  527. }
  528. // 초기 레이어 정보 설정
  529. initMapLayer() {
  530. this.layerArr.forEach((obj) => {
  531. obj = null;
  532. });
  533. this.layerArr[LayerIndex.Traffic] = new TMapLayer(this.map, LayerType.TRAF, LayerInfo.Traffic, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  534. this.layerArr[LayerIndex.Link1] = new TMapLayer(this.map, LayerType.LINK, LayerInfo.Link1, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  535. this.layerArr[LayerIndex.Link2] = new TMapLayer(this.map, LayerType.LINK, LayerInfo.Link2, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  536. this.layerArr[LayerIndex.Link3] = new TMapLayer(this.map, LayerType.LINK, LayerInfo.Link3, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  537. this.layerArr[LayerIndex.Link4] = new TMapLayer(this.map, LayerType.LINK, LayerInfo.Link4, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  538. this.layerArr[LayerIndex.Link5] = new TMapLayer(this.map, LayerType.LINK, LayerInfo.Link5, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  539. this.layerArr[LayerIndex.Ifsc1] = new TMapLayer(this.map, LayerType.IFSC, LayerInfo.Ifsc1, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  540. this.layerArr[LayerIndex.Ifsc2] = new TMapLayer(this.map, LayerType.IFSC, LayerInfo.Ifsc2, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  541. this.layerArr[LayerIndex.Ifsc3] = new TMapLayer(this.map, LayerType.IFSC, LayerInfo.Ifsc3, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  542. this.layerArr[LayerIndex.Ifsc4] = new TMapLayer(this.map, LayerType.IFSC, LayerInfo.Ifsc4, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  543. this.layerArr[LayerIndex.Ifsc5] = new TMapLayer(this.map, LayerType.IFSC, LayerInfo.Ifsc5, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  544. this.layerArr[LayerIndex.Road1] = new TMapLayer(this.map, LayerType.ROAD, LayerInfo.Road1, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  545. this.layerArr[LayerIndex.Road2] = new TMapLayer(this.map, LayerType.ROAD, LayerInfo.Road2, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  546. this.layerArr[LayerIndex.Road3] = new TMapLayer(this.map, LayerType.ROAD, LayerInfo.Road3, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  547. this.layerArr[LayerIndex.Road4] = new TMapLayer(this.map, LayerType.ROAD, LayerInfo.Road4, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  548. this.layerArr[LayerIndex.Road5] = new TMapLayer(this.map, LayerType.ROAD, LayerInfo.Road5, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  549. this.layerArr[LayerIndex.VmsIfsc] = new TMapLayer(this.map, LayerType.VMSI, LayerInfo.VmsIfsc, 16, 16, true, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  550. this.layerArr[LayerIndex.Node] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Node, 16, 16, false, "0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5^0.5");
  551. this.layerArr[LayerIndex.Cctv] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Cctv, 48, 48, true, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  552. this.layerArr[LayerIndex.Vms] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Vms, 48, 48, true, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  553. this.layerArr[LayerIndex.Vds] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Vds, 48, 48, true, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  554. this.layerArr[LayerIndex.VdsDet] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.VdsDet, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  555. this.layerArr[LayerIndex.VdsR] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.VdsR, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  556. this.layerArr[LayerIndex.VdsRDet] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.VdsRDet, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  557. this.layerArr[LayerIndex.VdsC] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.VdsC, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  558. this.layerArr[LayerIndex.VdsCDet] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.VdsCDet, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  559. this.layerArr[LayerIndex.Avi] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Avi, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  560. this.layerArr[LayerIndex.Rse] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Rse, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  561. this.layerArr[LayerIndex.Dsrc] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Dsrc, 48, 48, true, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  562. this.layerArr[LayerIndex.Park] = new TMapLayer(this.map, LayerType.PARK, LayerInfo.Park, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  563. this.layerArr[LayerIndex.PVms] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.PVms, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  564. this.layerArr[LayerIndex.Station] = new TMapLayer(this.map, LayerType.BIS, LayerInfo.Station, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  565. this.layerArr[LayerIndex.Bit] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Bit, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  566. this.layerArr[LayerIndex.Bit2] = new TMapLayer(this.map, LayerType.BIS, LayerInfo.Bit2, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  567. this.layerArr[LayerIndex.Bus] = new TMapLayer(this.map, LayerType.BIS, LayerInfo.Bus, 48, 48, false, "1.5^1.5^1.5^1.5^1.5^1.5^1.5^1.5^1.5^1.5");
  568. this.layerArr[LayerIndex.Sig] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Sig, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  569. this.layerArr[LayerIndex.SigDet] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.SigDet, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  570. this.layerArr[LayerIndex.Signal] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Signal, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  571. this.layerArr[LayerIndex.WCam] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.WCam, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  572. this.layerArr[LayerIndex.CCam] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.CCam, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  573. this.layerArr[LayerIndex.ICam] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.ICam, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  574. this.layerArr[LayerIndex.CCol] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.CCol, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  575. this.layerArr[LayerIndex.SPCam] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.SPCam, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  576. this.layerArr[LayerIndex.Event] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Event, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  577. this.layerArr[LayerIndex.Wthr] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Wthr, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  578. this.layerArr[LayerIndex.Atmp] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Atmp, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  579. this.layerArr[LayerIndex.Crs] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Crs, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  580. this.layerArr[LayerIndex.CrsCam] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.CrsCam, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  581. this.layerArr[LayerIndex.Incd] = new TMapLayer(this.map, LayerType.INCD, LayerInfo.Incd, 48, 48, true, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  582. this.layerArr[LayerIndex.Position] = new TMapLayer(this.map, LayerType.FCLT, LayerInfo.Position, 48, 48, false, "0.5^0.5^0.6^0.6^0.7^0.7^0.8^0.8^1.0^1.2");
  583. this.layerArr[LayerIndex.Select] = new TMapLayer(this.map, LayerType.Select, LayerInfo.Select, 19, 27, false, "0.7^0.7^0.8^1.0^1.0^1.0^1.2^1.4^1.6^1.8");
  584. this.layerArr.forEach((obj) => {
  585. if (obj != null) {
  586. this.lyrInfoMap.set(obj.lyrName, obj);
  587. }
  588. });
  589. this.layerArr[LayerIndex.Traffic].setLayerVisible([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
  590. this.layerArr[LayerIndex.Link1].setLayerVisible([16]);
  591. this.layerArr[LayerIndex.Link2].setLayerVisible([17, 18, 19]);
  592. this.layerArr[LayerIndex.Ifsc1].setLayerVisible([14]);
  593. this.layerArr[LayerIndex.Ifsc2].setLayerVisible([15]);
  594. this.layerArr[LayerIndex.Road1].setLayerVisible([10]);
  595. this.layerArr[LayerIndex.Road2].setLayerVisible([11, 12, 13]);
  596. }
  597. setLayerVisible(ALayerTypeIdx, ...AZoomLevels) {
  598. this.layerArr[ALayerTypeIdx].setLayerVisible(AZoomLevels);
  599. }
  600. // 배경맵 토글
  601. toggleBaseMap() {
  602. if (this.config.baseMapLyr.normal.getVisible()) {
  603. this.config.baseMapLyr.satellite.setVisible(true);
  604. this.config.baseMapLyr.normal.setVisible(false);
  605. } else {
  606. this.config.baseMapLyr.normal.setVisible(true);
  607. this.config.baseMapLyr.satellite.setVisible(false);
  608. }
  609. this.toggleTrafficPolyBackColor();
  610. }
  611. toggleTrafficPolyBackColor() {
  612. for (let ii = LayerIndex.Link1; ii < LayerIndex.Road5; ii++) {
  613. if (this.layerArr[ii].backPolyColor == "#000") {
  614. this.layerArr[ii].backPolyColor = "#FFFFFF";
  615. } else {
  616. this.layerArr[ii].backPolyColor = "#000";
  617. }
  618. this.layerArr[ii].refreshLayer(true);
  619. }
  620. }
  621. // zoom in
  622. zoomIn() {
  623. if (this.map !== null && this.currZoom < this.config.mapMaxZoom) {
  624. this.map.getView().animate({ zoom: this.map.getView().getZoom() + 1, duration: 400 });
  625. }
  626. }
  627. // zoom out
  628. zoomOut() {
  629. if (this.map !== null && this.currZoom > this.config.mapMinZoom) {
  630. this.map.getView().animate({ zoom: this.map.getView().getZoom() - 1, duration: 400 });
  631. }
  632. }
  633. // 표준영역 이동
  634. stdExtent() {
  635. if (this.map != null) {
  636. this.map.getView().animate({ center: this.config.mapCenter, zoom: this.config.mapDefZoom, duration: 400 });
  637. }
  638. }
  639. showTrafficTooltip(AIsShow) {
  640. this.showTrafficTip = AIsShow;
  641. }
  642. showIncidentLayer(AIsShow) {
  643. this.showIncidentLyr = AIsShow;
  644. this.showLayer(LayerIndex.Incd, this.showIncidentLyr);
  645. }
  646. setLayerSelectMode(ALyrIdx, AIsSelect) {
  647. this.selectLayerIdx = AIsSelect ? ALyrIdx : -1;
  648. this.selectMode = AIsSelect;
  649. }
  650. setSelectMode(AIsSelect) {
  651. this.selectMode = AIsSelect;
  652. }
  653. setEditColor() {
  654. EditLinkColor[0] = "#888888";
  655. EditLinkColor[1] = "#15B337";
  656. EditLinkColor[2] = "#FFAA00";
  657. EditLinkColor[3] = "#FF0000";
  658. }
  659. setTrafficGradDesc(jsonData) {
  660. if (jsonData && jsonData.length > 0) {
  661. jsonData.map((item) => {
  662. if (item.cmmn_cd) {
  663. let idx = item.cmmn_cd.substring(item.cmmn_cd.length - 1, item.cmmn_cd.length);
  664. TrafficGradeDesc[idx] = item.cmmn_cd_kor_nm;
  665. }
  666. });
  667. }
  668. }
  669. setEditMode(ALyrIdx, AIsEdit) {
  670. this.editLayerIdx = AIsEdit ? ALyrIdx : -1;
  671. this.editMode = AIsEdit;
  672. const lyrInfo = this.layerArr[Number(ALyrIdx)];
  673. if (lyrInfo) {
  674. lyrInfo.setEditMode(AIsEdit);
  675. }
  676. this.initEditMode();
  677. }
  678. initEditMode() {
  679. this.editObj = null;
  680. this.editFeature = null;
  681. this.editCoords = null;
  682. }
  683. getCenter() {
  684. return _mapMngr.map.getView().getCenter();
  685. }
  686. checkFcltEditMode(ALyrIdx) {
  687. if (!this.editMode) {
  688. console.error(`checkFcltEditMode: Is not edit mode`);
  689. return null;
  690. }
  691. const lyrIdx = Number(ALyrIdx);
  692. const lyrInfo = this.layerArr[lyrIdx];
  693. if (!lyrInfo) {
  694. console.error(`checkFcltEditMode: Unknown Layer Index, ${ALyrIdx}`);
  695. return null;
  696. }
  697. if (lyrInfo.lyrType < LayerType.NODE || lyrInfo.lyrType > LayerType.PARK) {
  698. console.error(`checkFcltEditMode: Not supported Layer Index, ${ALyrIdx}`);
  699. return null;
  700. }
  701. return lyrInfo;
  702. }
  703. showFcltObjectText(ALyrIdx, AIsShow) {
  704. const lyrInfo = this.checkFcltEditMode(ALyrIdx);
  705. if (!lyrInfo) {
  706. console.error("showFcltObjectText layer not found");
  707. return;
  708. }
  709. lyrInfo.setShowText(Boolean(AIsShow));
  710. }
  711. editFcltObject(ALyrIdx, ANmbr, AIsEdit, AComm) {
  712. const lyrInfo = this.checkFcltEditMode(ALyrIdx);
  713. if (!lyrInfo) {
  714. return;
  715. }
  716. const obj = lyrInfo.findObject(ANmbr);
  717. if (!obj) {
  718. return;
  719. }
  720. obj.setEditObject(Boolean(AIsEdit), AComm);
  721. }
  722. deleteFcltObject(ALyrIdx, ANmbr) {
  723. const lyrInfo = this.checkFcltEditMode(ALyrIdx);
  724. if (!lyrInfo) {
  725. return;
  726. }
  727. lyrInfo.deleteFcltObject(ANmbr);
  728. }
  729. createFcltObject(ALyrIdx, ANmbr, AId, AName, AComm, AXCrdn, AYCrdn) {
  730. const lyrInfo = this.checkFcltEditMode(ALyrIdx);
  731. if (!lyrInfo) {
  732. return;
  733. }
  734. let x_crdn = _mapMngr.centerPos[0];
  735. let y_crdn = _mapMngr.centerPos[1];
  736. if (AXCrdn && AYCrdn) {
  737. x_crdn = Number(AXCrdn);
  738. y_crdn = Number(AYCrdn);
  739. }
  740. lyrInfo.createFcltObject(ANmbr, AId, AName, AComm, x_crdn, y_crdn);
  741. }
  742. initFcltObject(ALyrIdx, AFcltObjs) {
  743. const lyrInfo = this.checkFcltEditMode(ALyrIdx);
  744. if (!lyrInfo) {
  745. return;
  746. }
  747. lyrInfo.usage = true;
  748. const poiLayer = lyrInfo.initFcltObject(AFcltObjs);
  749. if (poiLayer) {
  750. let layerArr = this.config.poiGroup.getLayers().getArray();
  751. if (layerArr.length == 0) {
  752. this.config.poiGroup.getLayers().push(poiLayer);
  753. }
  754. // else {
  755. // layerArr.forEach((lyr) => {
  756. // console.log(lyr);
  757. // });
  758. // }
  759. }
  760. }
  761. initEditLink(ALyrIdx) {
  762. if (!this.editMode) {
  763. console.error(`initEditLink: Is not edit mode`);
  764. return;
  765. }
  766. const lyrIdx = Number(ALyrIdx);
  767. const lyrInfo = this.layerArr[lyrIdx];
  768. if (!lyrInfo) {
  769. console.error(`initEditLink: Unknown Layer Index, ${ALyrIdx}`);
  770. return;
  771. }
  772. if (lyrInfo.lyrType > LayerType.Road5) {
  773. console.error(`initEditLink: Not supported Layer Index, ${ALyrIdx}`);
  774. return;
  775. }
  776. this.linkEditMode = true;
  777. const objs = this.getLayerObject(ALyrIdx);
  778. objs.forEach((obj) => {
  779. if (obj.color !== 0) {
  780. obj.color = 0;
  781. obj.setEditMarkerStyle(this.currZoom);
  782. }
  783. });
  784. }
  785. updateEditLink(ALyrIdx, ANmbr, ASeqColor, AIsClick) {
  786. if (!this.editMode) {
  787. console.error(`updateEditLink: Is not edit mode`);
  788. return;
  789. }
  790. const lyrIdx = Number(ALyrIdx);
  791. const lyrInfo = this.layerArr[lyrIdx];
  792. if (!lyrInfo) {
  793. console.error(`updateEditLink: Unknown Layer Index, ${ALyrIdx}`);
  794. return;
  795. }
  796. if (lyrInfo.lyrType > LayerType.Road5) {
  797. console.error(`updateEditLink: Not supported Layer Index, ${ALyrIdx}`);
  798. return;
  799. }
  800. const obj = lyrInfo.findObject(ANmbr);
  801. if (!obj) {
  802. console.error(`updateEditLink, Not found object: ${ALyrIdx}, ${ANmbr}`);
  803. return;
  804. }
  805. if (!obj.marker) {
  806. console.error(`updateEditLink, Not found feature object: ${ALyrIdx}, ${ANmbr}`);
  807. return;
  808. }
  809. obj.color = Number(ASeqColor);
  810. obj.setEditMarkerStyle(this.currZoom);
  811. if (AIsClick) {
  812. _mapMngr.selLinkStyle = obj.marker.getStyle();
  813. }
  814. }
  815. initTraf(ALyrIdx, ARefresh) {
  816. const objs = this.getLayerObject(ALyrIdx);
  817. objs.forEach((obj) => {
  818. obj.cmtrGradCd = "0";
  819. obj.sped = 0;
  820. });
  821. if (ARefresh) {
  822. this.refreshLayer(ALyrIdx);
  823. }
  824. }
  825. updateTraf(ALyrIdx, AObjs) {
  826. this.initTraf(ALyrIdx, false);
  827. const objs = this.getLayerObject(ALyrIdx);
  828. //console.log(objs);
  829. if (objs) {
  830. // 모든 데이터 초기화
  831. AObjs.forEach((obj) => {
  832. const traf = objs.get(obj.id);
  833. if (traf) {
  834. traf.cmtrGradCd = obj.cmtr_grad_cd.slice(-1);
  835. //traf.color = Number(traf.cmtrGradCd);
  836. traf.sped = obj.sped;
  837. //console.log(`${obj.id}, ${traf.cmtrGradCd}, ${traf.sped}`);
  838. //console.log(traf);
  839. }
  840. });
  841. }
  842. this.refreshLayer(ALyrIdx);
  843. }
  844. addFeature(ALyrIdx, AFeature) {
  845. const lyrIdx = Number(ALyrIdx);
  846. const lyrInfo = this.layerArr[lyrIdx];
  847. if (lyrInfo) {
  848. lyrInfo.addFeature(AFeature);
  849. }
  850. }
  851. getInfo() {
  852. return {
  853. zoom: _mapMngr.currZoom,
  854. center: _mapMngr.centerPos,
  855. };
  856. }
  857. // 레이어 객체 선택
  858. getLayer(ALyrIdx) {
  859. const lyrIdx = Number(ALyrIdx);
  860. if (lyrIdx >= LayerIndex.Traffic && lyrIdx <= LayerIndex.Incd) {
  861. return this.layerArr[lyrIdx];
  862. }
  863. return null;
  864. }
  865. // 소통정보 레이어 보이기/숨기기(소통정보 레이어만 해당)
  866. showTrafficLayer(AIsShow) {
  867. this.showTrafficLyr = AIsShow;
  868. if (this.config.trafGroup.getVisible() != this.showTrafficLyr) {
  869. this.config.trafGroup.setVisible(this.showTrafficLyr);
  870. }
  871. }
  872. showFacilityGroupLayer(AIsShow) {
  873. if (this.config.poiGroup.getVisible() != AIsShow) {
  874. this.config.poiGroup.setVisible(AIsShow);
  875. }
  876. }
  877. showEventGroupLayer(AIsShow) {
  878. if (this.config.eventGroup.getVisible() != AIsShow) {
  879. this.config.eventGroup.setVisible(AIsShow);
  880. }
  881. }
  882. // 레이어 화면 보이기/숨기기(POI 레이어 만 해당)
  883. showFacilityLayer(ALyrName, AShow) {
  884. const lyrInfo = this.lyrInfoMap.get(ALyrName);
  885. if (!lyrInfo) {
  886. console.error("showFacilityLayer, 레이어를 찾을 수 없습니다: " + ALyrName);
  887. //alert("[showFacilityLayer] 레이어를 찾을 수 없습니다.: " + ALyrName);
  888. return;
  889. }
  890. if (lyrInfo.lyrIdx >= LayerIndex.Traffic && lyrInfo.lyrIdx <= LayerIndex.VmsIfsc) {
  891. return;
  892. }
  893. this.showLayer(lyrInfo.lyrIdx, AShow);
  894. }
  895. // 레이어 화면 보이기/숨기기(POI 레이어 만 해당)
  896. showLayer(ALyrIdx, AIsShow) {
  897. const lyrInfo = this.layerArr[ALyrIdx];
  898. if (!lyrInfo) {
  899. console.error("showLayer, Unknown LayerIndex, " + ALyrIdx);
  900. alert("showLayer: Unknown LayerIndex, " + ALyrIdx);
  901. return;
  902. }
  903. if (ALyrIdx >= LayerIndex.Traffic && ALyrIdx <= LayerIndex.VmsIfsc) {
  904. this.showTrafficLyr = AIsShow;
  905. for (let ii = LayerIndex.Traffic; ii <= LayerIndex.VmsIfsc; ii++) {
  906. if (this.layerArr[ii] != null) {
  907. this.layerArr[ii].lyrVisible = ii == ALyrIdx;
  908. this.layerArr[ii].refreshLayer();
  909. }
  910. }
  911. }
  912. lyrInfo.lyrVisible = AIsShow;
  913. lyrInfo.refreshLayer();
  914. }
  915. // 레이어 이름설정
  916. setLayerName(ALyrIdx, ALyrName) {
  917. const lyrInfo = this.layerArr[ALyrIdx];
  918. if (!lyrInfo) {
  919. console.error("setLayerName, Unknown LayerIndex, " + ALyrIdx);
  920. alert("setLayerName: Unknown LayerIndex, " + ALyrIdx);
  921. return;
  922. }
  923. lyrInfo.lyrName = ALyrName;
  924. }
  925. // 레이어 툴팁설정
  926. setLayerTooltip(ALyrIdx, AIsShow) {
  927. const lyrInfo = this.layerArr[ALyrIdx];
  928. if (!lyrInfo) {
  929. console.error("setLayerTooltip, Unknown LayerIndex, " + ALyrIdx);
  930. alert("setLayerTooltip: Unknown LayerIndex, " + ALyrIdx);
  931. return;
  932. }
  933. lyrInfo.showTooltip = AIsShow;
  934. }
  935. // 레이어 이미지 설정
  936. setLayerImage(ALyrIdx, AImage) {
  937. const lyrInfo = this.layerArr[ALyrIdx];
  938. if (!lyrInfo) {
  939. console.error("setLayerImage, Unknown LayerIndex, " + ALyrIdx);
  940. alert("setLayerImage: Unknown LayerIndex, " + ALyrIdx);
  941. return;
  942. }
  943. //lyrInfo.image = "/images" + AImage;
  944. lyrInfo.image = AImage;
  945. }
  946. // 벡터 레이어 생성
  947. makeLayer(ALyrIdx, AJsonData) {
  948. const lyrInfo = this.layerArr[ALyrIdx];
  949. if (!lyrInfo) {
  950. console.error("makeLayer, Not found layer: " + ALyrIdx);
  951. return;
  952. }
  953. lyrInfo.usage = true;
  954. if (ALyrIdx >= LayerIndex.Traffic && ALyrIdx <= LayerIndex.VmsIfsc) {
  955. let trafLayer = null;
  956. if (ALyrIdx == LayerIndex.Traffic) {
  957. trafLayer = lyrInfo.makeTrafficLayer(_trafMap, AJsonData);
  958. } else if (ALyrIdx >= LayerIndex.Link1 && ALyrIdx <= LayerIndex.Link5) {
  959. trafLayer = lyrInfo.makeTrafficLayer(_linkMap, AJsonData);
  960. } else if (ALyrIdx >= LayerIndex.Ifsc1 && ALyrIdx <= LayerIndex.Ifsc5) {
  961. trafLayer = lyrInfo.makeTrafficLayer(_ifscMap, AJsonData);
  962. } else if (ALyrIdx >= LayerIndex.Road1 && ALyrIdx <= LayerIndex.Road5) {
  963. trafLayer = lyrInfo.makeTrafficLayer(_roadMap, AJsonData);
  964. }
  965. if (trafLayer != null) {
  966. try {
  967. this.config.trafGroup.getLayers().push(trafLayer);
  968. } catch (error) {}
  969. }
  970. } else {
  971. const poiLayer = lyrInfo.makePoiLayer(AJsonData);
  972. if (poiLayer != null) {
  973. if (ALyrIdx == LayerIndex.Incd) {
  974. this.map.removeLayer(poiLayer);
  975. this.map.addLayer(poiLayer);
  976. } else {
  977. try {
  978. this.config.poiGroup.getLayers().push(poiLayer);
  979. } catch (error) {}
  980. }
  981. }
  982. }
  983. }
  984. // 벡터 레이어 생성
  985. makeEventLayer(ALyrIdx, AJsonData) {
  986. const lyrInfo = this.layerArr[ALyrIdx];
  987. if (!lyrInfo) {
  988. console.error("makeEventLayer, Not found layer: " + ALyrIdx);
  989. return;
  990. }
  991. lyrInfo.usage = true;
  992. if (ALyrIdx >= LayerIndex.Traffic && ALyrIdx <= LayerIndex.VmsIfsc) {
  993. let trafLayer = null;
  994. if (ALyrIdx == LayerIndex.Traffic) {
  995. trafLayer = lyrInfo.makeTrafficLayer(_trafMap, AJsonData);
  996. } else if (ALyrIdx >= LayerIndex.Link1 && ALyrIdx <= LayerIndex.Link5) {
  997. trafLayer = lyrInfo.makeTrafficLayer(_linkMap, AJsonData);
  998. } else if (ALyrIdx >= LayerIndex.Ifsc1 && ALyrIdx <= LayerIndex.Ifsc5) {
  999. trafLayer = lyrInfo.makeTrafficLayer(_ifscMap, AJsonData);
  1000. } else if (ALyrIdx >= LayerIndex.Road1 && ALyrIdx <= LayerIndex.Road5) {
  1001. trafLayer = lyrInfo.makeTrafficLayer(_roadMap, AJsonData);
  1002. }
  1003. if (trafLayer != null) {
  1004. try {
  1005. this.config.eventGroup.getLayers().push(trafLayer);
  1006. } catch (error) {}
  1007. }
  1008. } else {
  1009. const poiLayer = lyrInfo.makePoiLayer(AJsonData);
  1010. if (poiLayer != null) {
  1011. if (ALyrIdx == LayerIndex.Incd) {
  1012. this.map.removeLayer(poiLayer);
  1013. this.map.addLayer(poiLayer);
  1014. } else {
  1015. try {
  1016. this.config.eventGroup.getLayers().push(poiLayer);
  1017. } catch (error) {}
  1018. }
  1019. }
  1020. }
  1021. }
  1022. refreshLayer(ALyrIdx) {
  1023. const lyrInfo = this.layerArr[ALyrIdx];
  1024. if (!lyrInfo) {
  1025. console.error("makeEventLayer, Not found layer: " + ALyrIdx);
  1026. return;
  1027. }
  1028. lyrInfo.refreshLayer(true);
  1029. }
  1030. // 레이어 객체 오브젝트 생성(소통정보 레이어만 해당)
  1031. makeTrafficObject(ALyrType, AJsonData) {
  1032. switch (ALyrType) {
  1033. // case LayerType.TRAF:
  1034. // _trafMap.clear();
  1035. // AJsonData.forEach((el) => {
  1036. // _linkMap.set(el.link_id, new TLink(this, el));
  1037. // });
  1038. // break;
  1039. case LayerType.LINK:
  1040. _linkMap.clear();
  1041. AJsonData.forEach((el) => {
  1042. _linkMap.set(el.link_id, new TLink(this, el));
  1043. });
  1044. break;
  1045. case LayerType.IFSC:
  1046. _ifscMap.clear();
  1047. AJsonData.forEach((el) => {
  1048. _ifscMap.set(el.ifsc_id, new TIfsc(this, el));
  1049. });
  1050. break;
  1051. case LayerType.ROAD:
  1052. _roadMap.clear();
  1053. AJsonData.forEach((el) => {
  1054. _roadMap.set(el.road_id, new TRoad(this, el));
  1055. });
  1056. break;
  1057. default:
  1058. console.error("makeTrafficObject: Unknown LayerType, ", ALyrType);
  1059. }
  1060. }
  1061. // 시설물 상태정보 업데이트
  1062. updateFacilityObject(ALyrIdx, AJsonData) {
  1063. const lyrInfo = this.layerArr[ALyrIdx];
  1064. if (!lyrInfo) {
  1065. console.error("updateFacilityObject, Not found layer: " + ALyrIdx);
  1066. return;
  1067. }
  1068. //시설물 아이디가 시설물별로 다르게 되어 있어서 하나의 함수로 처리하기 곤란함.
  1069. //switch 문으로 구분해서처리해야함.
  1070. //이전에서 처리하면 전체 통합 정보도 생성할수 있기 때문에 이전에서 처리하도록 하는게 좋음.
  1071. //AJsonData.forEach((el, idx) => {
  1072. // const obj = lyrInfo.findObject(el.cctv_ctlr_nmbr);
  1073. // if (obj) {
  1074. // obj.updateStts(el.cmnc_stts_cd, el.updt_dt);
  1075. // }
  1076. //});
  1077. }
  1078. // 소통정보 업데이트
  1079. updateTrafficObject(ALyrType, AJsonData) {
  1080. let fromIdx = 0;
  1081. let toIdx = 0;
  1082. switch (ALyrType) {
  1083. case LayerType.LINK:
  1084. AJsonData.forEach((el, idx) => {
  1085. const obj = _linkMap.get(el.id);
  1086. if (obj) {
  1087. obj.updateTraf(el);
  1088. }
  1089. });
  1090. fromIdx = LayerIndex.Link1;
  1091. toIdx = LayerIndex.Link5;
  1092. break;
  1093. case LayerType.IFSC:
  1094. AJsonData.forEach((el, idx) => {
  1095. const obj = _ifscMap.get(el.id);
  1096. if (obj) {
  1097. obj.updateTraf(el);
  1098. }
  1099. });
  1100. fromIdx = LayerIndex.Ifsc1;
  1101. toIdx = LayerIndex.Ifsc5;
  1102. break;
  1103. case LayerType.ROAD:
  1104. AJsonData.forEach((el, idx) => {
  1105. const obj = _roadMap.get(el.id);
  1106. if (obj) {
  1107. obj.updateTraf(el);
  1108. }
  1109. });
  1110. fromIdx = LayerIndex.Road1;
  1111. toIdx = LayerIndex.Road5;
  1112. break;
  1113. default:
  1114. console.error("makeTrafficObject: Unknown LayerType, ", ALyrType);
  1115. return;
  1116. }
  1117. for (let ii = fromIdx; ii <= toIdx; ii++) {
  1118. const lyrInfo = this.layerArr[ii];
  1119. if (lyrInfo) {
  1120. lyrInfo.refreshLayer(false);
  1121. }
  1122. }
  1123. }
  1124. // 지도영역 다시 그리기(화면이 리사이즈 될 경우 등)
  1125. updateSize() {
  1126. if (this.resizeMapUpdateTimer) {
  1127. clearTimeout(this.resizeMapUpdateTimer);
  1128. }
  1129. this.resizeMapUpdateTimer = setTimeout(() => {
  1130. this.map.updateSize();
  1131. // let layerArr = this.config.baseMapLyr.satellite.getLayers().getArray();
  1132. // layerArr.forEach((layer) => layer.redraw());
  1133. // this.config.baseMapLyr.satellite.layers.forEach((lyr) => lyr.redraw());
  1134. // this.config.baseMapLyr.normal.layers.forEach((lyr) => lyr.redraw());
  1135. // this.config.baseMapLyr.satellite.redraw();
  1136. // this.config.baseMapLyr.normal.redraw();
  1137. }, 450);
  1138. }
  1139. // 지도화면 refresh
  1140. refreshMap() {
  1141. if (this.editMode) {
  1142. // 편집 모드
  1143. this.selLinkWidth = EditLinkLineSize[this.currZoom];
  1144. //for (let ii = LayerIndex.Traffic; ii <= LayerIndex.Road5; ii++) {
  1145. // this.layerArr[ii].refreshEditLayer();
  1146. //}
  1147. let lyrCnt = 0;
  1148. this.layerArr.forEach((lyr) => {
  1149. if (lyr != null) {
  1150. if (this.linkEditMode || lyr.lyrIdx >= LayerIndex.Cctv) {
  1151. lyr.refreshEditLayer();
  1152. lyrCnt++;
  1153. }
  1154. }
  1155. });
  1156. } else {
  1157. this.layerArr.forEach((lyr) => {
  1158. if (lyr != null) {
  1159. lyr.refreshLayer(true);
  1160. }
  1161. });
  1162. }
  1163. }
  1164. setZoom(AZoom) {
  1165. if (AZoom) {
  1166. // 줌이 설정된경우
  1167. const reqZoom = Number(AZoom);
  1168. if (reqZoom != 0) {
  1169. if (this.currZoom != reqZoom) {
  1170. this.map.getView().setZoom(reqZoom);
  1171. }
  1172. }
  1173. }
  1174. }
  1175. movePos(ALat, ALng, AZoom) {
  1176. if (AZoom) {
  1177. // 줌이 설정된경우
  1178. const reqZoom = Number(AZoom);
  1179. if (reqZoom != 0) {
  1180. if (this.currZoom != reqZoom) {
  1181. this.map.getView().setZoom(reqZoom);
  1182. }
  1183. }
  1184. }
  1185. const pos = [Number(ALat), Number(ALng)];
  1186. this.map.getView().setCenter(pos);
  1187. }
  1188. // 좌표로 이동하고 화살표를 보여준다.
  1189. // selectPos(ALat, ALng, AZoom) {
  1190. // const reqZoom = Number(AZoom);
  1191. // if (reqZoom != 0) {
  1192. // if (this.currZoom != reqZoom) {
  1193. // this.map.getView().setZoom(reqZoom);
  1194. // }
  1195. // }
  1196. // this.showSelectArrow(ALat, ALng);
  1197. // }
  1198. // 객체선택 화살표 표출
  1199. selectPos(ALat, ALng, AZoom) {
  1200. this.movePos(ALat, ALng, AZoom);
  1201. const pos = [Number(ALat), Number(ALng)];
  1202. const lyrInfo = this.layerArr[LayerIndex.Select];
  1203. if (this.timerSelectArrow) {
  1204. window.clearTimeout(this.timerSelectArrow);
  1205. lyrInfo.lyrVisible = false;
  1206. lyrInfo.refreshLayer();
  1207. }
  1208. this.selectFeature.setStyle(
  1209. new ol.style.Style({
  1210. image: new ol.style.Icon({
  1211. anchor: [0.5, lyrInfo.imgH] /*아이콘 중앙*/,
  1212. anchorXUnits: "fraction",
  1213. anchorYUnits: "pixels",
  1214. opacity: 1,
  1215. size: [lyrInfo.imgW, lyrInfo.imgH],
  1216. scale: lyrInfo.scales[this.currZoom],
  1217. src: lyrInfo.image + ".png",
  1218. }),
  1219. })
  1220. );
  1221. this.selectFeature.getGeometry().setCoordinates(pos);
  1222. lyrInfo.lyrVisible = true;
  1223. lyrInfo.refreshLayer();
  1224. this.timerSelectArrow = window.setTimeout(function () {
  1225. this.timerSelectArrow = null;
  1226. lyrInfo.lyrVisible = false;
  1227. lyrInfo.refreshLayer();
  1228. }, 3000);
  1229. }
  1230. hideObjectPosition() {
  1231. const lyrInfo = this.layerArr[LayerIndex.Select];
  1232. lyrInfo.lyrVisible = false;
  1233. lyrInfo.refreshLayer();
  1234. }
  1235. showObjectPosition(ALat, ALng, AImg, AZoom) {
  1236. this.movePos(ALat, ALng, AZoom);
  1237. const pos = [Number(ALat), Number(ALng)];
  1238. const lyrInfo = this.layerArr[LayerIndex.Select];
  1239. this.selectFeature.setStyle(
  1240. new ol.style.Style({
  1241. image: new ol.style.Icon({
  1242. anchor: [0.5, 0.5] /*아이콘 중앙*/,
  1243. anchorXUnits: "fraction",
  1244. anchorYUnits: "pixels",
  1245. opacity: 1,
  1246. //size: [lyrInfo.imgW, lyrInfo.imgH],
  1247. //scale: lyrInfo.scales[this.currZoom],
  1248. src: AImg,
  1249. }),
  1250. })
  1251. );
  1252. this.selectFeature.getGeometry().setCoordinates(pos);
  1253. lyrInfo.lyrVisible = true;
  1254. lyrInfo.refreshLayer();
  1255. }
  1256. // 레이어에 있는 모든 객체를 Map으로 반환
  1257. getLayerObject(ALyrIdx) {
  1258. const lyrIdx = Number(ALyrIdx);
  1259. const lyrInfo = this.layerArr[lyrIdx];
  1260. if (!lyrInfo) {
  1261. console.error(`getLayerObject, Not found layer: ${ALyrIdx}, ${ANmbr}`);
  1262. return;
  1263. }
  1264. return lyrInfo.getLayerObject();
  1265. }
  1266. // 레이어에 있는 모든 객체를 삭제한다.
  1267. removeLayerObject(ALyrIdx) {
  1268. const lyrIdx = Number(ALyrIdx);
  1269. const lyrInfo = this.layerArr[lyrIdx];
  1270. if (!lyrInfo) {
  1271. console.error(`removeLayerObject, Not found layer: ${ALyrIdx}, ${ANmbr}`);
  1272. return;
  1273. }
  1274. lyrInfo.removeLayerObject();
  1275. }
  1276. selectLayerObject(ALyrIdx, ANmbr, AZoom) {
  1277. const lyrIdx = Number(ALyrIdx);
  1278. const lyrInfo = this.layerArr[lyrIdx];
  1279. if (!lyrInfo) {
  1280. console.error(`selectLayerObject, Not found layer: ${ALyrIdx}, ${ANmbr}`);
  1281. return;
  1282. }
  1283. const obj = lyrInfo.findObject(ANmbr);
  1284. if (!obj) return;
  1285. if (!obj.marker) {
  1286. console.error(`selectLayerObject, Not found feature object: ${ALyrIdx}, ${ANmbr}`);
  1287. return;
  1288. }
  1289. const center = obj.marker.getGeometry().getCoordinates();
  1290. if (lyrIdx <= LayerIndex.VmsIfsc) {
  1291. this.selectPos(center[0][0], center[0][1], AZoom);
  1292. } else {
  1293. this.selectPos(center[0], center[1], AZoom);
  1294. }
  1295. }
  1296. // 레이어 객체 선택
  1297. findLayerObject(ALyrIdx, AObjNmbr) {
  1298. const lyrIdx = Number(ALyrIdx);
  1299. if (lyrIdx >= LayerIndex.Traffic && lyrIdx <= LayerIndex.Incd) {
  1300. const obj = this.layerArr[lyrIdx].findObject(AObjNmbr);
  1301. //console.log(obj);
  1302. if (lyrIdx >= LayerIndex.Link1 && lyrIdx <= LayerIndex.Road5) {
  1303. return obj ? obj.refObj : null;
  1304. }
  1305. return obj;
  1306. }
  1307. return null;
  1308. }
  1309. findLinkObject(AObjNmbr) {
  1310. return _linkMap.get(AObjNmbr);
  1311. }
  1312. findIfscObject(AObjNmbr) {
  1313. return _ifscMap.get(AObjNmbr);
  1314. }
  1315. findRoadObject(AObjNmbr) {
  1316. return _roadMap.get(AObjNmbr);
  1317. }
  1318. extentLayer(ALyrIdx) {
  1319. const lyrIdx = Number(ALyrIdx);
  1320. const lyrInfo = this.layerArr[lyrIdx];
  1321. if (!lyrInfo) {
  1322. console.error(`extentLayer: Unknown Layer Index, ${ALyrIdx}`);
  1323. return;
  1324. }
  1325. lyrInfo.extentLayer();
  1326. }
  1327. // 레이어의 해당 객체가 중심이 되도록 영역을 맞춤
  1328. // ANmbrs = Array
  1329. extentLayerObject(ALyrIdx, ANmbrs) {
  1330. const lyrInfo = this.layerArr[ALyrIdx];
  1331. if (!lyrInfo) {
  1332. console.error("extentLayerObject, Not found layer: " + ALyrIdx);
  1333. return;
  1334. }
  1335. if (!ANmbrs || ANmbrs.length == 0) {
  1336. return;
  1337. }
  1338. if (ALyrIdx >= LayerIndex.Traffic && ALyrIdx <= LayerIndex.VmsIfsc) {
  1339. //if (this.editMode) {
  1340. if (ANmbrs.length == 1) {
  1341. const obj = lyrInfo.findObject(ANmbrs[0]);
  1342. if (obj) {
  1343. const extent = obj.marker.getGeometry().getExtent();
  1344. this.map.getView().fit(extent, this.map.getSize());
  1345. }
  1346. } else {
  1347. let extent = ol.extent.createEmpty();
  1348. ANmbrs.forEach((el) => {
  1349. const obj = lyrInfo.findObject(el);
  1350. if (obj) {
  1351. ol.extent.extend(extent, obj.marker.getGeometry().getExtent());
  1352. }
  1353. });
  1354. this.map.getView().fit(extent, this.map.getSize());
  1355. }
  1356. //}
  1357. } else {
  1358. // POI Layer(객체 하나만 선택)
  1359. const obj = lyrInfo.findObject(ANmbrs[0]);
  1360. if (obj) {
  1361. const extent = obj.marker.getGeometry().getExtent();
  1362. this.map.getView().fit(extent, this.map.getSize());
  1363. }
  1364. }
  1365. }
  1366. saveImage(APageName, ADownloadElId) {
  1367. const _map = this.map;
  1368. _map.once("rendercomplete", () => {
  1369. const mapCanvas = document.createElement("canvas");
  1370. const size = _map.getSize();
  1371. mapCanvas.width = size[0];
  1372. mapCanvas.height = size[1];
  1373. const mapContext = mapCanvas.getContext("2d", { willReadFrequently: true });
  1374. Array.prototype.forEach.call(_map.getViewport().querySelectorAll(".ol-layer canvas, canvas.ol-layer"), function (canvas) {
  1375. if (canvas.width > 0) {
  1376. const opacity = canvas.parentNode.style.opacity || canvas.style.opacity;
  1377. mapContext.globalAlpha = opacity === "" ? 1 : Number(opacity);
  1378. const backgroundColor = canvas.parentNode.style.backgroundColor;
  1379. if (backgroundColor) {
  1380. mapContext.fillStyle = backgroundColor;
  1381. mapContext.fillRect(0, 0, canvas.width, canvas.height);
  1382. }
  1383. let matrix;
  1384. const transform = canvas.style.transform;
  1385. if (transform) {
  1386. // Get the transform parameters from the style's transform matrix
  1387. matrix = transform
  1388. .match(/^matrix\(([^\(]*)\)$/)[1]
  1389. .split(",")
  1390. .map(Number);
  1391. } else {
  1392. matrix = [parseFloat(canvas.style.width) / canvas.width, 0, 0, parseFloat(canvas.style.height) / canvas.height, 0, 0];
  1393. }
  1394. // Apply the transform to the export map context
  1395. CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix);
  1396. mapContext.drawImage(canvas, 0, 0);
  1397. }
  1398. });
  1399. const downloadMapName = APageName + " 지도_" + this.currentTime() + ".png";
  1400. const link = document.getElementById(ADownloadElId);
  1401. document.getElementById(ADownloadElId).setAttribute("download", downloadMapName);
  1402. if (navigator.msSaveBlob) {
  1403. navigator.msSaveBlob(mapCanvas.msToBlob(), downloadMapName);
  1404. } else {
  1405. link.href = mapCanvas.toDataURL();
  1406. link.click();
  1407. }
  1408. });
  1409. _map.renderSync();
  1410. }
  1411. currentTime() {
  1412. const d = new Date();
  1413. return (
  1414. d.getFullYear() +
  1415. (d.getMonth() + 1 > 9 ? (d.getMonth() + 1).toString() : "0" + (d.getMonth() + 1)) +
  1416. (d.getDate() > 9 ? d.getDate().toString() : "0" + d.getDate().toString()) +
  1417. (d.getHours() > 9 ? d.getHours().toString() : "0" + d.getHours().toString()) +
  1418. (d.getMinutes() > 9 ? d.getMinutes().toString() : "0" + d.getMinutes().toString()) +
  1419. (d.getSeconds() > 9 ? d.getSeconds().toString() : "0" + d.getSeconds().toString())
  1420. );
  1421. }
  1422. }
  1423. function getParseDateTime(param) {
  1424. if (param.length <= 14) {
  1425. let str = "";
  1426. str += param.substring(0, 4);
  1427. str += "-";
  1428. str += param.substring(4, 6);
  1429. str += "-";
  1430. str += param.substring(6, 8);
  1431. str += " ";
  1432. str += param.substring(8, 10);
  1433. str += ":";
  1434. str += param.substring(10, 12);
  1435. str += ":";
  1436. str += param.substring(12, 14);
  1437. return str;
  1438. } else {
  1439. return param;
  1440. }
  1441. }