leaflet.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import { loadResource } from "../../static/utils/resources.js";
  2. import { cleanObject } from "../../static/utils/json.js";
  3. export default {
  4. template: "<div></div>",
  5. props: {
  6. center: Array,
  7. zoom: Number,
  8. options: Object,
  9. draw_control: Object,
  10. resource_path: String,
  11. hide_drawn_items: Boolean,
  12. },
  13. async mounted() {
  14. await this.$nextTick(); // NOTE: wait for window.path_prefix to be set
  15. await Promise.all([
  16. loadResource(window.path_prefix + `${this.resource_path}/leaflet/leaflet.css`),
  17. loadResource(window.path_prefix + `${this.resource_path}/leaflet/leaflet.js`),
  18. ]);
  19. if (this.draw_control) {
  20. await Promise.all([
  21. loadResource(window.path_prefix + `${this.resource_path}/leaflet-draw/leaflet.draw.css`),
  22. loadResource(window.path_prefix + `${this.resource_path}/leaflet-draw/leaflet.draw.js`),
  23. ]);
  24. }
  25. this.map = L.map(this.$el, {
  26. ...this.options,
  27. center: this.center,
  28. zoom: this.zoom,
  29. });
  30. for (const type of [
  31. "baselayerchange",
  32. "overlayadd",
  33. "overlayremove",
  34. "zoomlevelschange",
  35. "resize",
  36. "unload",
  37. "viewreset",
  38. "load",
  39. "zoomstart",
  40. "movestart",
  41. "zoom",
  42. "move",
  43. "zoomend",
  44. "moveend",
  45. "popupopen",
  46. "popupclose",
  47. "autopanstart",
  48. "tooltipopen",
  49. "tooltipclose",
  50. "locationerror",
  51. "locationfound",
  52. "click",
  53. "dblclick",
  54. "mousedown",
  55. "mouseup",
  56. "mouseover",
  57. "mouseout",
  58. "mousemove",
  59. "contextmenu",
  60. "keypress",
  61. "keydown",
  62. "keyup",
  63. "preclick",
  64. "zoomanim",
  65. ]) {
  66. this.map.on(type, (e) => {
  67. this.$emit(`map-${type}`, {
  68. ...e,
  69. originalEvent: undefined,
  70. target: undefined,
  71. sourceTarget: undefined,
  72. center: [e.target.getCenter().lat, e.target.getCenter().lng],
  73. zoom: e.target.getZoom(),
  74. });
  75. });
  76. }
  77. for (const type of ["layeradd", "layerremove"]) {
  78. this.map.on(type, (e) => {
  79. this.$emit(`map-${type}`, {
  80. id: e.layer.id,
  81. leaflet_id: e.layer._leaflet_id,
  82. });
  83. });
  84. }
  85. if (this.draw_control) {
  86. for (const key in L.Draw.Event) {
  87. const type = L.Draw.Event[key];
  88. this.map.on(type, async (e) => {
  89. await this.$nextTick(); // NOTE: allow drawn layers to be added
  90. const cleanedObject = cleanObject(e, [
  91. "_map",
  92. "_events",
  93. "_eventParents",
  94. "_handlers",
  95. "_mapToAdd",
  96. "_initHooksCalled",
  97. ]);
  98. this.$emit(type, {
  99. ...cleanedObject,
  100. target: undefined,
  101. sourceTarget: undefined,
  102. });
  103. });
  104. }
  105. const drawnItems = new L.FeatureGroup();
  106. this.map.addLayer(drawnItems);
  107. const drawControl = new L.Control.Draw({
  108. draw: this.draw_control.draw,
  109. edit: {
  110. ...this.draw_control.edit,
  111. featureGroup: drawnItems,
  112. },
  113. });
  114. this.map.addControl(drawControl);
  115. if (!this.hide_drawn_items) {
  116. this.map.on("draw:created", (e) => drawnItems.addLayer(e.layer));
  117. }
  118. }
  119. const connectInterval = setInterval(async () => {
  120. if (window.socket.id === undefined) return;
  121. this.$emit("init", { socket_id: window.socket.id });
  122. clearInterval(connectInterval);
  123. }, 100);
  124. },
  125. methods: {
  126. add_layer(layer, id) {
  127. const l = L[layer.type](...layer.args);
  128. l.id = id;
  129. l.addTo(this.map);
  130. },
  131. remove_layer(id) {
  132. this.map.eachLayer((layer) => layer.id === id && this.map.removeLayer(layer));
  133. },
  134. clear_layers() {
  135. this.map.eachLayer((layer) => this.map.removeLayer(layer));
  136. },
  137. run_map_method(name, ...args) {
  138. if (name.startsWith(":")) {
  139. name = name.slice(1);
  140. args = args.map((arg) => new Function(`return (${arg})`)());
  141. }
  142. return runMethod(this.map, name, args);
  143. },
  144. run_layer_method(id, name, ...args) {
  145. let result = null;
  146. this.map.eachLayer((layer) => {
  147. if (layer.id !== id) return;
  148. if (name.startsWith(":")) {
  149. name = name.slice(1);
  150. args = args.map((arg) => new Function(`return (${arg})`)());
  151. }
  152. result = runMethod(layer, name, args);
  153. });
  154. return result;
  155. },
  156. },
  157. };