mapbox-gl-draw-rectangle.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. "use strict";
  2. var doubleClickZoom = {
  3. enable: function enable(ctx) {
  4. setTimeout(function () {
  5. // First check we've got a map and some context.
  6. if (!ctx.map || !ctx.map.doubleClickZoom || !ctx._ctx || !ctx._ctx.store || !ctx._ctx.store.getInitialConfigValue) return;
  7. // Now check initial state wasn't false (we leave it disabled if so)
  8. if (!ctx._ctx.store.getInitialConfigValue("doubleClickZoom")) return;
  9. ctx.map.doubleClickZoom.enable();
  10. }, 0);
  11. },
  12. disable: function disable(ctx) {
  13. setTimeout(function () {
  14. if (!ctx.map || !ctx.map.doubleClickZoom) return;
  15. // Always disable here, as it's necessary in some cases.
  16. ctx.map.doubleClickZoom.disable();
  17. }, 0);
  18. }
  19. };
  20. var DrawRectangle = {
  21. // When the mode starts this function will be called.
  22. onSetup: function onSetup(opts) {
  23. var rectangle = this.newFeature({
  24. type: "Feature",
  25. properties: {},
  26. geometry: {
  27. type: "Polygon",
  28. coordinates: [[]]
  29. }
  30. });
  31. this.addFeature(rectangle);
  32. this.clearSelectedFeatures();
  33. doubleClickZoom.disable(this);
  34. this.updateUIClasses({mouse: "add"});
  35. this.setActionableState({
  36. trash: true
  37. });
  38. return {
  39. rectangle: rectangle
  40. };
  41. },
  42. // support mobile taps
  43. onTap: function onTap(state, e) {
  44. // emulate 'move mouse' to update feature coords
  45. if (state.startPoint) this.onMouseMove(state, e);
  46. // emulate onClick
  47. this.onClick(state, e);
  48. },
  49. // Whenever a user clicks on the map, Draw will call `onClick`
  50. onClick: function onClick(state, e) {
  51. // if state.startPoint exist, means its second click
  52. //change to simple_select mode
  53. if (state.startPoint && state.startPoint[0] !== e.lngLat.lng && state.startPoint[1] !== e.lngLat.lat) {
  54. this.updateUIClasses({mouse: "pointer"});
  55. state.endPoint = [e.lngLat.lng, e.lngLat.lat];
  56. this.changeMode("simple_select", {featuresId: state.rectangle.id});
  57. }
  58. // on first click, save clicked point coords as starting for rectangle
  59. var startPoint = [e.lngLat.lng, e.lngLat.lat];
  60. state.startPoint = startPoint;
  61. },
  62. onMouseMove: function onMouseMove(state, e) {
  63. // if startPoint, update the feature coordinates, using the bounding box concept
  64. // we are simply using the startingPoint coordinates and the current Mouse Position
  65. // coordinates to calculate the bounding box on the fly, which will be our rectangle
  66. if (state.startPoint) {
  67. state.rectangle.updateCoordinate("0.0", state.startPoint[0], state.startPoint[1]); //minX, minY - the starting point
  68. state.rectangle.updateCoordinate("0.1", e.lngLat.lng, state.startPoint[1]); // maxX, minY
  69. state.rectangle.updateCoordinate("0.2", e.lngLat.lng, e.lngLat.lat); // maxX, maxY
  70. state.rectangle.updateCoordinate("0.3", state.startPoint[0], e.lngLat.lat); // minX,maxY
  71. state.rectangle.updateCoordinate("0.4", state.startPoint[0], state.startPoint[1]); //minX,minY - ending point (equals to starting point)
  72. }
  73. },
  74. // Whenever a user clicks on a key while focused on the map, it will be sent here
  75. onKeyUp: function onKeyUp(state, e) {
  76. if (e.keyCode === 27) return this.changeMode("simple_select");
  77. },
  78. onStop: function onStop(state) {
  79. doubleClickZoom.enable(this);
  80. this.updateUIClasses({mouse: "none"});
  81. this.activateUIButton();
  82. // check to see if we've deleted this feature
  83. if (this.getFeature(state.rectangle.id) === undefined) return;
  84. //remove last added coordinate
  85. state.rectangle.removeCoordinate("0.4");
  86. if (state.rectangle.isValid()) {
  87. this.map.fire("draw.create", {
  88. features: [state.rectangle.toGeoJSON()]
  89. });
  90. } else {
  91. this.deleteFeature([state.rectangle.id], {silent: true});
  92. this.changeMode("simple_select", {}, {silent: true});
  93. }
  94. },
  95. toDisplayFeatures: function toDisplayFeatures(state, geojson, display) {
  96. var isActivePolygon = geojson.properties.id === state.rectangle.id;
  97. geojson.properties.active = isActivePolygon ? "true" : "false";
  98. if (!isActivePolygon) return display(geojson);
  99. // Only render the rectangular polygon if it has the starting point
  100. if (!state.startPoint) return;
  101. return display(geojson);
  102. },
  103. onTrash: function onTrash(state) {
  104. this.deleteFeature([state.rectangle.id], {silent: true});
  105. this.changeMode("simple_select");
  106. }
  107. };