measure.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import Draw from 'ol/interaction/Draw';
  2. import Overlay from 'ol/Overlay';
  3. import {
  4. Circle as CircleStyle,
  5. Fill,
  6. Stroke,
  7. Style
  8. } from 'ol/style';
  9. import {
  10. LineString,
  11. Polygon
  12. } from 'ol/geom';
  13. import VectorSource from "ol/source/Vector";
  14. import VectorLayer from "ol/layer/Vector";
  15. import {
  16. getArea,
  17. getLength
  18. } from 'ol/sphere';
  19. import {
  20. unByKey
  21. } from 'ol/Observable';
  22. class measureTool {
  23. constructor(map) {
  24. this.map = map;
  25. this.source = new VectorSource();
  26. this.vector = new VectorLayer({
  27. source: this.source,
  28. zIndex: 1000,
  29. style: new Style({
  30. fill: new Fill({
  31. color: 'rgba(255, 255, 255, 0.2)',
  32. }),
  33. stroke: new Stroke({
  34. color: '#ffcc33',
  35. width: 2,
  36. }),
  37. image: new CircleStyle({
  38. radius: 7,
  39. fill: new Fill({
  40. color: '#ffcc33',
  41. }),
  42. }),
  43. }),
  44. });
  45. this.map.addLayer(this.vector);
  46. /**
  47. * Currently drawn feature.
  48. * @type {import("../src/ol/Feature.js").default}
  49. */
  50. this.sketch;
  51. /**
  52. * The help tooltip element.
  53. * @type {HTMLElement}
  54. */
  55. this.helpTooltipElement;
  56. /**
  57. * Overlay to show the help messages.
  58. * @type {Overlay}
  59. */
  60. this.helpTooltip;
  61. /**
  62. * The measure tooltip element.
  63. * @type {HTMLElement}
  64. */
  65. this.measureTooltipElement;
  66. /**
  67. * Overlay to show the measurement.
  68. * @type {Overlay}
  69. */
  70. this.measureTooltip;
  71. this.overlayArr = [];
  72. /**
  73. * Message to show when the user is drawing a polygon.
  74. * @type {string}
  75. */
  76. this.continuePolygonMsg = '继续点击地图绘制测量区域';
  77. /**
  78. * Message to show when the user is drawing a line.
  79. * @type {string}
  80. */
  81. this.continueLineMsg = '继续点击地图绘制测量路线';
  82. this.draw; // global so we can remove it later
  83. this.createHelpTooltip();
  84. }
  85. start(measureType) {
  86. let that = this;
  87. const type = measureType == 'area' ? 'Polygon' : 'LineString';
  88. this.draw = new Draw({
  89. source: this.source,
  90. type: type,
  91. style: new Style({
  92. fill: new Fill({
  93. color: 'rgba(255, 255, 255, 0.2)',
  94. }),
  95. stroke: new Stroke({
  96. color: 'rgba(0, 0, 0, 0.5)',
  97. lineDash: [10, 10],
  98. width: 2,
  99. }),
  100. image: new CircleStyle({
  101. radius: 5,
  102. stroke: new Stroke({
  103. color: 'rgba(0, 0, 0, 0.7)',
  104. }),
  105. fill: new Fill({
  106. color: 'rgba(255, 255, 255, 0.2)',
  107. }),
  108. }),
  109. }),
  110. });
  111. this.map.addInteraction(this.draw);
  112. this.pointermove_event = this.map.on('pointermove', function (evt) {
  113. if (evt.dragging) {
  114. return;
  115. }
  116. /** @type {string} */
  117. let helpMsg = '点击地图进行测量';
  118. if (that.sketch) {
  119. const geom = that.sketch.getGeometry();
  120. if (geom instanceof Polygon) {
  121. helpMsg = that.continuePolygonMsg;
  122. } else if (geom instanceof LineString) {
  123. helpMsg = that.continueLineMsg;
  124. }
  125. }
  126. that.helpTooltipElement.innerHTML = helpMsg;
  127. that.helpTooltip.setPosition(evt.coordinate);
  128. that.helpTooltipElement.classList.remove('hidden');
  129. });
  130. this.map.getViewport().addEventListener('mouseout', d);
  131. function d(params) {
  132. if (that.helpTooltipElement == null || that.helpTooltipElement == undefined) {
  133. that.map.getViewport().removeEventListener('mouseout', d);
  134. return;
  135. }
  136. that.helpTooltipElement.classList.add('hidden');
  137. }
  138. let listener;
  139. this.draw.on('drawstart', function (evt) {
  140. that.createMeasureTooltip()
  141. // set sketch
  142. that.sketch = evt.feature;
  143. /** @type {import("../src/ol/coordinate.js").Coordinate|undefined} */
  144. let tooltipCoord = evt.coordinate;
  145. listener = that.sketch.getGeometry().on('change', function (evt) {
  146. const geom = evt.target;
  147. let output;
  148. if (geom instanceof Polygon) {
  149. output = that.formatArea(geom);
  150. tooltipCoord = geom.getInteriorPoint().getCoordinates();
  151. } else if (geom instanceof LineString) {
  152. output = that.formatLength(geom);
  153. tooltipCoord = geom.getLastCoordinate();
  154. }
  155. that.measureTooltipElement.innerHTML = output;
  156. that.measureTooltip.setPosition(tooltipCoord);
  157. });
  158. });
  159. this.draw.on('drawend', function () {
  160. that.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
  161. that.measureTooltip.setOffset([0, -7]);
  162. that.overlayArr.push(that.measureTooltip);
  163. // unset sketch
  164. that.sketch = null;
  165. // unset tooltip so that a new one can be created
  166. // that.measureTooltipElement.innerHTML = "";
  167. unByKey(listener);
  168. });
  169. }
  170. /**
  171. * Creates a new help tooltip
  172. */
  173. createHelpTooltip() {
  174. this.helpTooltipElement = document.createElement('div');
  175. this.helpTooltipElement.className = 'ol-tooltip hidden';
  176. this.helpTooltip = new Overlay({
  177. element: this.helpTooltipElement,
  178. offset: [15, 0],
  179. positioning: 'center-left',
  180. });
  181. this.map.addOverlay(this.helpTooltip);
  182. }
  183. /**
  184. * Creates a new measure tooltip
  185. */
  186. createMeasureTooltip() {
  187. this.measureTooltipElement = document.createElement('div');
  188. this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
  189. this.measureTooltip = new Overlay({
  190. element: this.measureTooltipElement,
  191. offset: [0, -15],
  192. positioning: 'bottom-center',
  193. stopEvent: false,
  194. insertFirst: false,
  195. });
  196. this.map.addOverlay(this.measureTooltip);
  197. }
  198. /**
  199. * Format length output.
  200. * @param {LineString} line The line.
  201. * @return {string} The formatted length.
  202. */
  203. formatLength(line) {
  204. const length = getLength(line);
  205. let output;
  206. if (length > 100) {
  207. output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
  208. } else {
  209. output = Math.round(length * 100) / 100 + ' ' + 'm';
  210. }
  211. return output;
  212. };
  213. /**
  214. * Format area output.
  215. * @param {Polygon} polygon The polygon.
  216. * @return {string} Formatted area.
  217. */
  218. formatArea(polygon) {
  219. const area = getArea(polygon);
  220. let output;
  221. if (area > 10000) {
  222. output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>';
  223. } else {
  224. output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>';
  225. }
  226. return output;
  227. };
  228. stop() {
  229. let that = this;
  230. if (this.draw) {
  231. this.map.removeInteraction(this.draw);
  232. this.draw = null;
  233. unByKey(this.pointermove_event);
  234. if (this.helpTooltip) {
  235. this.helpTooltip.setPosition(undefined)
  236. }
  237. if (this.measureTooltip) {
  238. this.measureTooltip.setPosition(undefined)
  239. }
  240. if (this.overlayArr.length > 0) {
  241. this.overlayArr.map(function (item) {
  242. that.map.removeOverlay(item);
  243. })
  244. this.overlayArr = [];
  245. }
  246. if (this.source.getFeatures().length != 0) {
  247. this.source.getFeatures().forEach(function (feature) {
  248. that.source.removeFeature(feature)
  249. })
  250. }
  251. }
  252. }
  253. }
  254. export default measureTool