map.html 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css" rel="stylesheet" />
  5. <script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js"></script>
  6. <script src="https://atlas.microsoft.com/sdk/javascript/service/2/atlas-service.min.js"></script>
  7. <script>
  8. /*
  9. This module contains the HtmlMarkerLayer class, which is a layer that renders HTML markers on the map.
  10. Source: https://learn.microsoft.com/en-us/samples/azure-samples/azure-maps-html-marker-layer/azure-maps-html-marker-layer-module/
  11. azure-maps-html-marker-layer Version: 0.0.1
  12. MIT License - Copyright (c) Microsoft Corporation.
  13. */
  14. !function(e, y) {
  15. "use strict";
  16. var o = function(e, t) {
  17. return (o = Object.setPrototypeOf || {
  18. __proto__: []
  19. }instanceof Array && function(e, t) {
  20. e.__proto__ = t
  21. }
  22. || function(e, t) {
  23. for (var r in t)
  24. t.hasOwnProperty(r) && (e[r] = t[r])
  25. }
  26. )(e, t)
  27. };
  28. function t(e, t) {
  29. function r() {
  30. this.constructor = e
  31. }
  32. o(e, t),
  33. e.prototype = null === t ? Object.create(t) : (r.prototype = t.prototype,
  34. new r)
  35. }
  36. var n = function() {
  37. return (n = Object.assign || function(e) {
  38. for (var t, r = 1, o = arguments.length; r < o; r++)
  39. for (var a in t = arguments[r])
  40. Object.prototype.hasOwnProperty.call(t, a) && (e[a] = t[a]);
  41. return e
  42. }
  43. ).apply(this, arguments)
  44. };
  45. function a(e, n, s, l) {
  46. return new (s = s || Promise)(function(r, t) {
  47. function o(e) {
  48. try {
  49. i(l.next(e))
  50. } catch (e) {
  51. t(e)
  52. }
  53. }
  54. function a(e) {
  55. try {
  56. i(l.throw(e))
  57. } catch (e) {
  58. t(e)
  59. }
  60. }
  61. function i(e) {
  62. var t;
  63. e.done ? r(e.value) : ((t = e.value)instanceof s ? t : new s(function(e) {
  64. e(t)
  65. }
  66. )).then(o, a)
  67. }
  68. i((l = l.apply(e, n || [])).next())
  69. }
  70. )
  71. }
  72. function g(r, o) {
  73. var a, i, n, e, s = {
  74. label: 0,
  75. sent: function() {
  76. if (1 & n[0])
  77. throw n[1];
  78. return n[1]
  79. },
  80. trys: [],
  81. ops: []
  82. };
  83. return e = {
  84. next: t(0),
  85. throw: t(1),
  86. return: t(2)
  87. },
  88. "function" == typeof Symbol && (e[Symbol.iterator] = function() {
  89. return this
  90. }
  91. ),
  92. e;
  93. function t(t) {
  94. return function(e) {
  95. return function(t) {
  96. if (a)
  97. throw new TypeError("Generator is already executing.");
  98. for (; s; )
  99. try {
  100. if (a = 1,
  101. i && (n = 2 & t[0] ? i.return : t[0] ? i.throw || ((n = i.return) && n.call(i),
  102. 0) : i.next) && !(n = n.call(i, t[1])).done)
  103. return n;
  104. switch (i = 0,
  105. n && (t = [2 & t[0], n.value]),
  106. t[0]) {
  107. case 0:
  108. case 1:
  109. n = t;
  110. break;
  111. case 4:
  112. return s.label++,
  113. {
  114. value: t[1],
  115. done: !1
  116. };
  117. case 5:
  118. s.label++,
  119. i = t[1],
  120. t = [0];
  121. continue;
  122. case 7:
  123. t = s.ops.pop(),
  124. s.trys.pop();
  125. continue;
  126. default:
  127. if (!(n = 0 < (n = s.trys).length && n[n.length - 1]) && (6 === t[0] || 2 === t[0])) {
  128. s = 0;
  129. continue
  130. }
  131. if (3 === t[0] && (!n || t[1] > n[0] && t[1] < n[3])) {
  132. s.label = t[1];
  133. break
  134. }
  135. if (6 === t[0] && s.label < n[1]) {
  136. s.label = n[1],
  137. n = t;
  138. break
  139. }
  140. if (n && s.label < n[2]) {
  141. s.label = n[2],
  142. s.ops.push(t);
  143. break
  144. }
  145. n[2] && s.ops.pop(),
  146. s.trys.pop();
  147. continue
  148. }
  149. t = o.call(r, s)
  150. } catch (e) {
  151. t = [6, e],
  152. i = 0
  153. } finally {
  154. a = n = 0
  155. }
  156. if (5 & t[0])
  157. throw t[1];
  158. return {
  159. value: t[0] ? t[1] : void 0,
  160. done: !0
  161. }
  162. }([t, e])
  163. }
  164. }
  165. }
  166. var r = (i.merge = function(e, t) {
  167. for (var r = window || global, o = 0, a = e.split("."); o < a.length; o++) {
  168. var i = a[o];
  169. if (!r[i])
  170. return t;
  171. r = r[i]
  172. }
  173. return n(n({}, r), t)
  174. }
  175. ,
  176. i);
  177. function i() {}
  178. var s, l = (t(u, s = y.layer.BubbleLayer),
  179. u.prototype.getOptions = function() {
  180. return Object.assign({}, this._options)
  181. }
  182. ,
  183. u.prototype.setOptions = function(e) {
  184. var t = this._options
  185. , r = {}
  186. , o = !1;
  187. e.source && t.source !== e.source && (t.source = e.source,
  188. r.source = e.source,
  189. o = !0),
  190. e.sourceLayer && t.sourceLayer !== e.sourceLayer && (t.sourceLayer = e.sourceLayer,
  191. r.sourceLayer = e.sourceLayer,
  192. o = !0),
  193. e.filter && t.filter !== e.filter && (t.filter = e.filter,
  194. r.filter = e.filter,
  195. o = !0),
  196. "number" == typeof e.minZoom && t.minZoom !== e.minZoom && (t.minZoom = e.minZoom,
  197. r.minZoom = e.minZoom),
  198. "number" == typeof e.maxZoom && t.maxZoom !== e.maxZoom && (t.maxZoom = e.maxZoom,
  199. r.maxZoom = e.maxZoom),
  200. void 0 !== e.visible && t.visible !== e.visible && (t.visible = e.visible,
  201. r.visible = e.visible),
  202. e.markerCallback && t.markerCallback != e.markerCallback && (t.markerCallback = e.markerCallback,
  203. o = !0),
  204. "boolean" == typeof e.updateWhileMoving && t.updateWhileMoving !== e.updateWhileMoving && (t.updateWhileMoving = e.updateWhileMoving),
  205. o ? this._clearCache(!0) : this._updateMarkers(),
  206. s.prototype.setOptions.call(this, r)
  207. }
  208. ,
  209. u.prototype.update = function() {
  210. this._clearCache(!0),
  211. this._updateMarkers()
  212. }
  213. ,
  214. u.prototype.onAdd = function(e) {
  215. var t = this
  216. , r = e.events;
  217. e && (r.remove("moveend", t._updateMarkers),
  218. r.remove("move", t._mapMoved),
  219. r.remove("sourcedata", t._sourceUpdated)),
  220. (r = (t._map = e).events).add("moveend", t._updateMarkers),
  221. r.add("move", t._mapMoved),
  222. r.add("sourcedata", t._sourceUpdated),
  223. s.prototype.onAdd.call(this, e)
  224. }
  225. ,
  226. u.prototype.onRemove = function() {
  227. var e = this
  228. , t = e._map;
  229. if (t) {
  230. var r = t.events;
  231. r.remove("moveend", e._updateMarkers),
  232. r.remove("move", e._mapMoved),
  233. r.remove("sourcedata", e._sourceUpdated)
  234. }
  235. e._clearCache(!1),
  236. e._map = null,
  237. s.prototype.onRemove.call(this)
  238. }
  239. ,
  240. u.prototype._getSourceClass = function() {
  241. var e = this.getSource();
  242. return "string" == typeof e && null !== this._map ? this._map.sources.getById(e) : e instanceof y.source.Source ? e : null
  243. }
  244. ,
  245. u.prototype._clearCache = function(e) {
  246. var t = this;
  247. if (t._markerCache = {},
  248. t._map)
  249. for (var r = 0, o = t._markers.length; r < o; r++) {
  250. var a = t._markers[r];
  251. t._removeEvents(a),
  252. a._eventsAttached = !1,
  253. t._map.markers.remove(a)
  254. }
  255. t._markers = [],
  256. t._markerIds = [],
  257. e && t._updateMarkers()
  258. }
  259. ,
  260. u.prototype._getMarker = function(o, a, i) {
  261. var n = this
  262. , s = n._markerCache
  263. , e = n._options;
  264. if (o = o || a.join(",") + JSON.stringify(i || {}),
  265. s[o])
  266. return s[o];
  267. var t = e.markerCallback(o, a, i);
  268. if (!(t instanceof y.HtmlMarker))
  269. return new Promise(function(r) {
  270. t.then(function(e) {
  271. var t = n._getExtendedMarker(e, o, a, i);
  272. t && (s[o] = t,
  273. r(t))
  274. })
  275. }
  276. );
  277. var r = n._getExtendedMarker(t, o, a, i);
  278. return r ? (s[o] = r,
  279. Promise.resolve(r)) : null
  280. }
  281. ,
  282. u.prototype._getExtendedMarker = function(e, t, r, o) {
  283. var a = e;
  284. return a ? (a.properties = o,
  285. a.id = t,
  286. a.setOptions({
  287. position: r
  288. }),
  289. a) : null
  290. }
  291. ,
  292. u.prototype._addEvents = function(t) {
  293. var r = this;
  294. r._supportedEvents.forEach(function(e) {
  295. r.map.events.add(e, t, r._wrappedEvent)
  296. })
  297. }
  298. ,
  299. u.prototype._removeEvents = function(t) {
  300. var r = this;
  301. r._supportedEvents.forEach(function(e) {
  302. r.map.events.remove(e, t, r._wrappedEvent)
  303. })
  304. }
  305. ,
  306. u);
  307. function u(e, t, r) {
  308. var o = s.call(this, e, t) || this;
  309. return o._options = {
  310. minZoom: 0,
  311. maxZoom: 24,
  312. visible: !0,
  313. updateWhileMoving: !1,
  314. filter: ["==", ["geometry-type"], "Point"],
  315. markerCallback: function(e, t, r) {
  316. return r.cluster ? new y.HtmlMarker({
  317. position: t,
  318. text: r.point_count_abbreviated
  319. }) : new y.HtmlMarker({
  320. position: t
  321. })
  322. }
  323. },
  324. o._markers = [],
  325. o._markerIds = [],
  326. o._markerCache = {},
  327. o._supportedEvents = ["click", "contextmenu", "dblclick", "drag", "dragstart", "dragend", "keydown", "keypress", "keyup", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup"],
  328. o._mapMoved = function() {
  329. o._options.updateWhileMoving && o._updateMarkers()
  330. }
  331. ,
  332. o._sourceUpdated = function(e) {
  333. var t = o._getSourceClass();
  334. t && t.getId() === e.source.id && (o._timer && clearTimeout(o._timer),
  335. o._timer = setTimeout(o._sourceUpdater, 33))
  336. }
  337. ,
  338. o._sourceUpdater = function() {
  339. o._timer = null,
  340. o._clearCache(!0)
  341. }
  342. ,
  343. o._updateMarkers = function() {
  344. return a(o, void 0, void 0, function() {
  345. var t, r, o, a, i, n, s, l, u, c, p, d, m, h, f, v, _, k;
  346. return g(this, function(e) {
  347. switch (e.label) {
  348. case 0:
  349. if (r = (t = this)._map,
  350. o = t._markers,
  351. a = t._options,
  352. i = r ? r.getCamera().zoom : void 0,
  353. !(a.visible && void 0 !== i && i >= a.minZoom && i <= a.maxZoom))
  354. return [3, 5];
  355. n = t.getSource(),
  356. s = "string" == typeof n ? n : n.getId(),
  357. l = r.map.querySourceFeatures(s, {
  358. sourceLayer: t.getOptions().sourceLayer,
  359. filter: a.filter
  360. }),
  361. u = [],
  362. c = [],
  363. v = f = h = m = d = p = void 0,
  364. k = 0,
  365. _ = l.length,
  366. e.label = 1;
  367. case 1:
  368. return k < _ ? (p = v = null,
  369. l[k]instanceof y.Shape ? "Point" === (h = l[k]).getType() && (m = h.getCoordinates(),
  370. d = h.getProperties(),
  371. p = h.getId()) : "Point" === (f = l[k]).geometry.type && (m = f.geometry.coordinates,
  372. (d = f.properties) && d.cluster ? p = "cluster_" + f.properties.cluster_id : f.id && (p = f.id)),
  373. m ? [4, t._getMarker(p, m, d)] : [3, 3]) : [3, 4];
  374. case 2:
  375. (v = e.sent())._eventsAttached || (t._addEvents(v),
  376. v._eventsAttached = !0),
  377. v && (v.id && c.push(v.id),
  378. v.id && -1 !== t._markerIds.indexOf(v.id) || (u.push(v),
  379. r.markers.add(v))),
  380. e.label = 3;
  381. case 3:
  382. return k++,
  383. [3, 1];
  384. case 4:
  385. for (k = o.length - 1; 0 <= k; k--)
  386. o[k].id && -1 !== c.indexOf(o[k].id) || (r.markers.remove(o[k]),
  387. o.splice(k, 1));
  388. return t._markers = o.concat(u),
  389. t._markerIds = c,
  390. [3, 6];
  391. case 5:
  392. 0 < t._markers.length && (r.markers.remove(t._markers),
  393. t._markers = []),
  394. e.label = 6;
  395. case 6:
  396. return [2]
  397. }
  398. })
  399. })
  400. }
  401. ,
  402. o._wrappedEvent = function(e) {
  403. o.map.events.invoke(e.type, o, e)
  404. }
  405. ,
  406. s.prototype.setOptions.call(o, {
  407. color: "transparent",
  408. radius: 0,
  409. strokeWidth: 0
  410. }),
  411. o.setOptions(r || {}),
  412. o
  413. }
  414. var b, c = Object.freeze({
  415. __proto__: null,
  416. HtmlMarkerLayer: l
  417. }), p = (t(C, b = y.HtmlMarker),
  418. C.prototype.getTotalValue = function() {
  419. return this._total
  420. }
  421. ,
  422. C.prototype.getSliceValue = function(e) {
  423. var t = this._options.values;
  424. return 0 <= e && e < t.length ? t[e] : 0
  425. }
  426. ,
  427. C.prototype.getSlicePercentage = function(e) {
  428. return 0 < this._total ? Math.round(this.getSliceValue(e) / this._total * 1e4) / 100 : 0
  429. }
  430. ,
  431. C.prototype.getOptions = function() {
  432. return Object.assign({}, b.prototype.getOptions.call(this), this._options)
  433. }
  434. ,
  435. C.prototype.setOptions = function(e) {
  436. var t = this._options
  437. , r = JSON.stringify
  438. , o = !1;
  439. e.radius && 0 < e.radius && e.radius != t.radius && (t.radius = e.radius,
  440. o = !0),
  441. 0 <= e.innerRadius && e.innerRadius != t.innerRadius && (t.innerRadius = e.innerRadius,
  442. o = !0),
  443. e.colors && r(e.colors) !== r(t.colors) && (t.colors = e.colors,
  444. o = !0),
  445. e.fillColor && r(e.fillColor) !== r(t.fillColor) && (t.fillColor = e.fillColor,
  446. o = !0),
  447. e.strokeColor && e.strokeColor !== t.strokeColor && (t.strokeColor = e.strokeColor,
  448. o = !0),
  449. 0 <= e.strokeWidth && e.strokeWidth != t.strokeWidth && (t.strokeWidth = e.strokeWidth,
  450. o = !0),
  451. void 0 !== e.tooltipCallback && t.tooltipCallback != e.tooltipCallback && (t.tooltipCallback = e.tooltipCallback,
  452. o = !0),
  453. e.values && r(e.values) !== r(t.values) && (t.values = e.values,
  454. o = !0),
  455. void 0 !== e.text && e.text !== t.text && (b.prototype.setOptions.call(this, {
  456. text: e.text
  457. }),
  458. o = !0),
  459. void 0 !== e.textClassName && e.textClassName !== t.textClassName && (t.textClassName = e.textClassName,
  460. o = !0),
  461. o && this._render(),
  462. b.prototype.setOptions.call(this, e)
  463. }
  464. ,
  465. C.prototype._render = function() {
  466. var e = this
  467. , t = e._options
  468. , r = t.values
  469. , o = t.radius
  470. , a = 0
  471. , i = 0;
  472. if (r) {
  473. e._total = r.reduce(function(e, t) {
  474. return e + t
  475. }, 0);
  476. for (var n = C._moreColors, s = Math.random, l = Math.round, u = 0; r.length > t.colors.length; )
  477. n.length < r.length && n.push("hsl(" + l(360 * s()) + "," + (l(20 * s()) + 70) + "%," + (l(40 * s()) + 30) + "%)"),
  478. t.colors.push(n[u]),
  479. u++;
  480. var c = o + t.strokeWidth
  481. , p = ['<svg xmlns="http://www.w3.org/2000/svg" width="' + 2 * c + 'px" height="' + 2 * c + 'px">']
  482. , d = ""
  483. , m = void 0;
  484. if (0 < t.innerRadius && t.innerRadius <= t.radius && (m = "piechart-innercircle-" + l(1e7 * s()),
  485. p.push('<defs><mask id="' + m + '"><rect width="100%" height="100%" fill="white"/><circle r="' + t.innerRadius + '" cx="' + c + '" cy="' + c + '" fill="black"/></mask></defs>\n <circle r="' + t.innerRadius + '" cx="' + c + '" cy="' + c + '" style="fill:' + t.fillColor + ";stroke:" + t.strokeColor + ";stroke-width:" + 2 * t.strokeWidth + 'px;"/>')),
  486. 0 < e._total)
  487. for (var h = t.tooltipCallback, f = 2 * Math.PI / e._total, v = 0; v < r.length; v++) {
  488. i = f * r[v],
  489. h && (d = h(e, v));
  490. var _ = v < t.colors.length ? t.colors[v] : n[v];
  491. p.push(e._createSlice(c, c, o, a, i, _, d, m)),
  492. a += i
  493. }
  494. var k = e.getOptions().text;
  495. k && p.push('<text x="' + c + '" y="' + (c + 7) + '" style="font-size:16px;font-family:arial;fill:#000;font-weight:bold;" class="' + (t.textClassName || "") + '" text-anchor="middle">' + k + "</text>"),
  496. p.push("</svg>"),
  497. b.prototype.getOptions.call(this).htmlContent.innerHTML = p.join("")
  498. }
  499. }
  500. ,
  501. C.prototype._createSlice = function(e, t, r, o, a, i, n, s) {
  502. var l = this._options
  503. , u = Math.PI
  504. , c = "";
  505. if (s && (c = ' mask="url(#' + s + '"'),
  506. 2 * u * .99 < a)
  507. return '<circle r="' + r + '" cx="' + e + '" cy="' + t + '" style="fill:' + i + ";stroke:" + l.strokeColor + ";stroke-width:" + l.strokeWidth + 'px;"' + c + "><title>" + n + "</title></circle>";
  508. var p = Math.sin
  509. , d = Math.cos
  510. , m = e + r * p(o)
  511. , h = t - r * d(o)
  512. , f = e + r * p(o + a)
  513. , v = t - r * d(o + a)
  514. , _ = (l.innerRadius,
  515. p(o),
  516. l.innerRadius,
  517. d(o),
  518. l.innerRadius,
  519. p(o + a),
  520. l.innerRadius,
  521. d(o + a),
  522. 0);
  523. return u < a && (_ = 1),
  524. '<path d="M' + e + " " + t + " L " + m + " " + h + " A " + r + "," + r + " 0 " + _ + " 1 " + f + " " + v + 'z" style="fill:' + i + ";stroke:" + l.strokeColor + ";stroke-width:" + l.strokeWidth + 'px;"' + c + "><title>" + n + "</title></path>"
  525. }
  526. ,
  527. C._moreColors = [],
  528. C);
  529. function C(e) {
  530. var t = b.call(this, e) || this;
  531. return t._options = {
  532. values: [],
  533. radius: 40,
  534. colors: ["#d7191c", "#fdae61", "#ffffbf", "#abdda4", "#2b83ba"],
  535. fillColor: "transparent",
  536. strokeWidth: 0,
  537. strokeColor: "#666666",
  538. innerRadius: 0
  539. },
  540. t._total = 0,
  541. t.properties = {},
  542. b.prototype.setOptions.call(t, {
  543. htmlContent: document.createElement("div"),
  544. pixelOffset: [0, 0],
  545. anchor: "center"
  546. }),
  547. t.setOptions(e),
  548. t
  549. }
  550. var d = r.merge("atlas.layer", c);
  551. e.PieChartMarker = p,
  552. e.layer = d
  553. }(this.atlas = this.atlas || {}, atlas);
  554. </script>
  555. </head>
  556. <style>
  557. html,
  558. body {
  559. width: 100%;
  560. height: 100%;
  561. padding: 0;
  562. margin: 0;
  563. overflow: hidden;
  564. font-family: segoeui;
  565. }
  566. #mapContainer {
  567. position: relative;
  568. width: 100%;
  569. height: 100%;
  570. }
  571. </style>
  572. <body>
  573. <div id="mapContainer"></div>
  574. <script>
  575. var map;
  576. var symbolLayers = [];
  577. var layersData = {};
  578. var pointsData = {};
  579. var dataSource;
  580. var id = 1;
  581. var controls = [];
  582. function initializeMap(longitude, latitude, mapServiceToken) {
  583. try {
  584. //Initialize a map instance.
  585. map = new atlas.Map('mapContainer', {
  586. center: [longitude, latitude],
  587. zoom: 3,
  588. view: 'Auto',
  589. //Add authentication details for connecting to Azure Maps.
  590. // Note: an invalid token doesn't seem to throw any errors.
  591. authOptions: {
  592. authType: 'subscriptionKey',
  593. subscriptionKey: mapServiceToken
  594. }
  595. });
  596. map.events.add('ready', function () {
  597. dataSource = new atlas.source.DataSource();
  598. map.sources.add(dataSource);
  599. });
  600. }
  601. catch (error) {
  602. sendErrorInfo(error);
  603. }
  604. }
  605. function addSymbolLayer() {
  606. try {
  607. var layerSource = new atlas.source.DataSource();
  608. var newLayer = new atlas.layer.HtmlMarkerLayer(layerSource, null, {
  609. markerCallback: (id, position, properties) => {
  610. const pin = new atlas.HtmlMarker({
  611. position: position,
  612. id: id
  613. });
  614. pin.getElement().setAttribute('tabindex', 0);
  615. return pin;
  616. }
  617. });
  618. layersData[newLayer.getId()] = layerSource;
  619. pointsData[newLayer.getId()] = {};
  620. symbolLayers.push(newLayer);
  621. map.events.add('ready', function () {
  622. map.sources.add(layerSource);
  623. map.layers.add(newLayer);
  624. map.events.add('click', newLayer, sendPushpinClickInfo);
  625. });
  626. }
  627. catch (error) {
  628. sendErrorInfo(error);
  629. }
  630. return newLayer.getId();
  631. }
  632. function addPoint(longitude, latitude, layerId) {
  633. var point = new atlas.data.Feature(new atlas.data.Point([longitude, latitude]), {name: 'MapElement'}, id);
  634. id++;
  635. try {
  636. map.events.add('ready', function () {
  637. layersData[layerId].add([point]);
  638. pointsData[layerId][point.id] = point;
  639. });
  640. }
  641. catch (error) {
  642. sendErrorInfo(error);
  643. }
  644. return point.id;
  645. }
  646. function updatePoint(longitude, latitude, pointId, layerId) {
  647. try {
  648. map.events.add('ready', function () {
  649. pointsData[layerId][pointId].setCoordinates([longitude, latitude]);
  650. logSymbolLayers();
  651. });
  652. }
  653. catch (error) {
  654. sendErrorInfo(error);
  655. }
  656. }
  657. function removePoint(pointId, layerId) {
  658. try {
  659. map.events.add('ready', function() {
  660. layersData[layerId].remove(pointsData[layerId][pointId]);
  661. delete pointsData[layerId][pointId];
  662. });
  663. }
  664. catch (error) {
  665. sendErrorInfo(error);
  666. }
  667. }
  668. function clearLayer(layerId) {
  669. try {
  670. map.events.add( 'ready', function() {
  671. layersData[layerId].clear();
  672. pointsData[layerId] = {};
  673. });
  674. }
  675. catch (error) {
  676. sendErrorInfo(error);
  677. }
  678. }
  679. function clearMap() {
  680. try {
  681. map.events.add( 'ready', function() {
  682. symbolLayers = [];
  683. layersData = {};
  684. pointsData = {};
  685. });
  686. }
  687. catch (error) {
  688. sendErrorInfo(error);
  689. }
  690. }
  691. function interactiveControlsVisible(enable) {
  692. if (enable) {
  693. controls = [
  694. new atlas.control.ZoomControl(),
  695. new atlas.control.CompassControl(),
  696. new atlas.control.PitchControl(),
  697. new atlas.control.StyleControl()
  698. ]
  699. map.controls.add(controls, {
  700. position: "top-right"
  701. });
  702. } else {
  703. map.controls.remove(controls);
  704. controls = [];
  705. }
  706. }
  707. function updateCenter(latitude, longitude) {
  708. try {
  709. map.setCamera({
  710. center: [longitude, latitude]
  711. });
  712. }
  713. catch (error) {
  714. sendErrorInfo(error);
  715. }
  716. }
  717. function updateZoom(level) {
  718. try {
  719. map.setCamera({
  720. zoom: level
  721. });
  722. }
  723. catch (error) {
  724. sendErrorInfo(error);
  725. }
  726. }
  727. function updateMapServiceToken(mapServiceToken) {
  728. try {
  729. clearMap();
  730. var location = map.getCamera().center;
  731. longitude = location[0];
  732. latitude = location[1];
  733. // create a new map with the new API key
  734. initializeMap(longitude, latitude, mapServiceToken);
  735. } catch (error) {
  736. sendErrorInfo(error);
  737. }
  738. }
  739. function sendPushpinClickInfo(e) {
  740. try {
  741. const latitude = e.target.options.position[0];
  742. const longitude = e.target.options.position[1];
  743. const pointClicked = e.target.id || 'Unknown';
  744. const coordinate = {
  745. latitude,
  746. longitude,
  747. };
  748. const message = {
  749. type: 'pushpinClickEvent',
  750. coordinate,
  751. layer: 0,
  752. point: pointClicked,
  753. text: 'Pushpin clicked!',
  754. };
  755. console.log('Sending message:', message);
  756. window.chrome.webview.postMessage(message);
  757. } catch (error) {
  758. sendErrorInfo(error);
  759. }
  760. }
  761. function getMapLayers() {
  762. try {
  763. layers = map.layers.getLayers();
  764. console.log("Number of layers: " + layers.length + "\n");
  765. // print out the name and type of each layer
  766. for (var i = 0; i < layers.length; i++) {
  767. if (layers[i] instanceof atlas.layer.SymbolLayer) {
  768. console.log(layers[i].getId() + " is a SymbolLayer\n");
  769. console.log("Source: " + layers[i].getSource() + "\n");
  770. }
  771. }
  772. }
  773. catch (error) {
  774. sendErrorInfo(error);
  775. }
  776. }
  777. function logSymbolLayers() {
  778. try {
  779. // print out each symbolLayer in symbolLayers by id
  780. console.log("Number of symbol layers: " + symbolLayers.length + "\n");
  781. for (var i = 0; i < symbolLayers.length; i++) {
  782. console.log("Id: " + symbolLayers[i].getId() + "\n");
  783. }
  784. }
  785. catch (error) {
  786. sendErrorInfo(error);
  787. }
  788. }
  789. function getSymbolLayers() {
  790. return symbolLayers;
  791. }
  792. function sendErrorInfo(e) {
  793. console.log(e);
  794. const coordinate = {
  795. "latitude": 0,
  796. "longitude": 0,
  797. }
  798. const message = {
  799. "type": "javascriptError",
  800. "coordinate": coordinate,
  801. "text": e.stack
  802. };
  803. window.chrome.webview.postMessage(message);
  804. }
  805. </script>
  806. </body>
  807. </html>