leaflet-js 0.6.beta4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (226) hide show
  1. checksums.yaml +6 -14
  2. data/CHANGELOG.rdoc +3 -0
  3. data/leaflet-js.gemspec +2 -2
  4. data/lib/leaflet.draw/CHANGELOG.md +45 -0
  5. data/lib/leaflet.draw/README.md +70 -23
  6. data/lib/leaflet.draw/build/deps.js +1 -0
  7. data/lib/leaflet.draw/dist/images/spritesheet-2x.png +0 -0
  8. data/lib/leaflet.draw/dist/images/spritesheet.png +0 -0
  9. data/lib/leaflet.draw/dist/leaflet.draw-src.js +489 -136
  10. data/lib/leaflet.draw/dist/leaflet.draw.css +34 -2
  11. data/lib/leaflet.draw/dist/leaflet.draw.ie.css +5 -0
  12. data/lib/leaflet.draw/dist/leaflet.draw.js +2 -2
  13. data/lib/leaflet.draw/examples/basic.html +14 -7
  14. data/lib/leaflet.draw/examples/libs/images/layers-2x.png +0 -0
  15. data/lib/leaflet.draw/examples/libs/images/layers.png +0 -0
  16. data/lib/leaflet.draw/examples/libs/images/marker-icon-2x.png +0 -0
  17. data/lib/leaflet.draw/examples/libs/leaflet-src.js +1129 -608
  18. data/lib/leaflet.draw/examples/libs/leaflet.css +85 -66
  19. data/lib/leaflet.draw/package.json +2 -2
  20. data/lib/leaflet.draw/spec/suites/DrawControlSpec.js +1 -1
  21. data/lib/leaflet.draw/spec/suites/GeometryUtilSpec.js +25 -0
  22. data/lib/leaflet.draw/spec/suites/LatLngUtilSpec.js +9 -0
  23. data/lib/leaflet.draw/src/Control.Draw.js +1 -0
  24. data/lib/leaflet.draw/src/Leaflet.draw.js +89 -1
  25. data/lib/leaflet.draw/src/Toolbar.js +2 -6
  26. data/lib/leaflet.draw/src/Tooltip.js +20 -7
  27. data/lib/leaflet.draw/src/draw/DrawToolbar.js +26 -22
  28. data/lib/leaflet.draw/src/draw/handler/Draw.Circle.js +11 -6
  29. data/lib/leaflet.draw/src/draw/handler/Draw.Feature.js +6 -2
  30. data/lib/leaflet.draw/src/draw/handler/Draw.Marker.js +7 -2
  31. data/lib/leaflet.draw/src/draw/handler/Draw.Polygon.js +29 -7
  32. data/lib/leaflet.draw/src/draw/handler/Draw.Polyline.js +44 -21
  33. data/lib/leaflet.draw/src/draw/handler/Draw.Rectangle.js +3 -3
  34. data/lib/leaflet.draw/src/draw/handler/Draw.SimpleShape.js +14 -1
  35. data/lib/leaflet.draw/src/edit/EditToolbar.js +86 -16
  36. data/lib/leaflet.draw/src/edit/handler/Edit.Poly.js +10 -7
  37. data/lib/leaflet.draw/src/edit/handler/Edit.SimpleShape.js +1 -2
  38. data/lib/leaflet.draw/src/edit/handler/EditToolbar.Delete.js +15 -3
  39. data/lib/leaflet.draw/src/edit/handler/EditToolbar.Edit.js +56 -38
  40. data/lib/leaflet.draw/src/ext/GeometryUtil.js +68 -0
  41. data/lib/leaflet.draw/src/images/spritesheet.svg +41 -0
  42. data/lib/leaflet.label/CHANGELOG.md +32 -0
  43. data/lib/leaflet.label/README.md +21 -4
  44. data/lib/leaflet.label/build/build.js +2 -2
  45. data/lib/leaflet.label/build/deps.js +2 -0
  46. data/lib/leaflet.label/build/hintrc.js +4 -0
  47. data/lib/leaflet.label/dist/leaflet.label-src.js +266 -83
  48. data/lib/leaflet.label/dist/leaflet.label.css +23 -4
  49. data/lib/leaflet.label/dist/leaflet.label.js +1 -1
  50. data/lib/leaflet.label/example/label.html +6 -3
  51. data/lib/leaflet.label/libs/leaflet/images/layers-2x.png +0 -0
  52. data/lib/leaflet.label/libs/leaflet/images/layers.png +0 -0
  53. data/lib/leaflet.label/libs/leaflet/images/marker-icon-2x.png +0 -0
  54. data/lib/leaflet.label/libs/leaflet/leaflet-src.js +1129 -608
  55. data/lib/leaflet.label/libs/leaflet/leaflet.css +85 -66
  56. data/lib/leaflet.label/libs/leaflet/leaflet.js +6 -5
  57. data/lib/leaflet.label/package.json +19 -0
  58. data/lib/leaflet.label/src/BaseMarkerMethods.js +129 -0
  59. data/lib/leaflet.label/src/CircleMarker.Label.js +7 -0
  60. data/lib/leaflet.label/src/Label.js +161 -37
  61. data/lib/leaflet.label/src/Leaflet.label.js +1 -1
  62. data/lib/leaflet.label/src/Map.Label.js +0 -2
  63. data/lib/leaflet.label/src/Marker.Label.js +15 -120
  64. data/lib/leaflet.label/src/Path.Label.js +11 -11
  65. data/lib/leaflet/CHANGELOG.md +299 -31
  66. data/lib/leaflet/CONTRIBUTING.md +3 -3
  67. data/lib/leaflet/FAQ.md +138 -0
  68. data/lib/leaflet/Jakefile.js +24 -4
  69. data/lib/leaflet/PLUGIN-GUIDE.md +127 -0
  70. data/lib/leaflet/README.md +10 -6
  71. data/lib/leaflet/build/build.html +3 -19
  72. data/lib/leaflet/build/build.js +21 -51
  73. data/lib/leaflet/build/deps.js +10 -7
  74. data/lib/leaflet/build/hintrc.js +6 -4
  75. data/lib/leaflet/debug/hacks/jitter.html +0 -1
  76. data/lib/leaflet/debug/map/canvas.html +11 -12
  77. data/lib/leaflet/debug/map/controls.html +3 -4
  78. data/lib/leaflet/debug/map/geolocation.html +0 -1
  79. data/lib/leaflet/debug/map/iframe.html +11 -0
  80. data/lib/leaflet/debug/map/image-overlay.html +0 -1
  81. data/lib/leaflet/debug/map/map-mobile.html +0 -1
  82. data/lib/leaflet/debug/map/map.html +1 -2
  83. data/lib/leaflet/debug/map/max-bounds.html +2 -1
  84. data/lib/leaflet/debug/map/opacity.html +223 -0
  85. data/lib/leaflet/debug/map/scroll.html +6 -1
  86. data/lib/leaflet/debug/map/simple-proj.html +0 -1
  87. data/lib/leaflet/debug/map/wms-marble.html +4 -5
  88. data/lib/leaflet/debug/map/wms.html +0 -1
  89. data/lib/leaflet/debug/map/zoomlevels.html +0 -1
  90. data/lib/leaflet/debug/tests/add_remove_layers.html +5 -6
  91. data/lib/leaflet/debug/tests/bringtoback.html +0 -1
  92. data/lib/leaflet/debug/tests/canvasloop.html +47 -0
  93. data/lib/leaflet/debug/tests/click_on_canvas.html +0 -1
  94. data/lib/leaflet/debug/tests/dragging_and_copyworldjump.html +61 -0
  95. data/lib/leaflet/debug/tests/opacity.html +0 -1
  96. data/lib/leaflet/debug/tests/popupcontextmenuclicks.html +59 -0
  97. data/lib/leaflet/debug/tests/remove_while_dragging.html +4 -5
  98. data/lib/leaflet/debug/tests/removetilewhilepan.html +0 -1
  99. data/lib/leaflet/debug/tests/reuse_popups.html +0 -1
  100. data/lib/leaflet/debug/tests/rtl.html +42 -0
  101. data/lib/leaflet/debug/tests/rtl2.html +27 -0
  102. data/lib/leaflet/debug/tests/set_icon_reuse_dom.html +43 -0
  103. data/lib/leaflet/debug/tests/svg_clicks.html +3 -4
  104. data/lib/leaflet/debug/vector/bounds-extend.html +0 -1
  105. data/lib/leaflet/debug/vector/feature-group-bounds.html +0 -1
  106. data/lib/leaflet/debug/vector/geojson.html +0 -1
  107. data/lib/leaflet/debug/vector/rectangle.html +0 -1
  108. data/lib/leaflet/debug/vector/touchzoomemu.html +2 -3
  109. data/lib/leaflet/debug/vector/vector-bounds.html +0 -1
  110. data/lib/leaflet/debug/vector/vector-canvas.html +0 -1
  111. data/lib/leaflet/debug/vector/vector-mobile.html +0 -1
  112. data/lib/leaflet/debug/vector/vector-simple.html +0 -1
  113. data/lib/leaflet/debug/vector/vector.html +0 -1
  114. data/lib/leaflet/dist/images/layers-2x.png +0 -0
  115. data/lib/leaflet/dist/images/layers.png +0 -0
  116. data/lib/leaflet/dist/leaflet.css +85 -66
  117. data/lib/leaflet/package.json +25 -20
  118. data/lib/leaflet/spec/after.js +1 -1
  119. data/lib/leaflet/spec/index.html +21 -13
  120. data/lib/leaflet/spec/karma.conf.js +51 -50
  121. data/lib/leaflet/spec/spec.hintrc.js +25 -0
  122. data/lib/leaflet/spec/suites/LeafletSpec.js +2 -2
  123. data/lib/leaflet/spec/suites/SpecHelper.js +37 -21
  124. data/lib/leaflet/spec/suites/control/Control.LayersSpec.js +1 -1
  125. data/lib/leaflet/spec/suites/core/ClassSpec.js +12 -12
  126. data/lib/leaflet/spec/suites/core/EventsSpec.js +74 -18
  127. data/lib/leaflet/spec/suites/core/UtilSpec.js +69 -25
  128. data/lib/leaflet/spec/suites/dom/DomEventSpec.js +16 -16
  129. data/lib/leaflet/spec/suites/dom/DomUtilSpec.js +9 -16
  130. data/lib/leaflet/spec/suites/dom/PosAnimationSpec.js +27 -0
  131. data/lib/leaflet/spec/suites/geo/CRSSpec.js +47 -0
  132. data/lib/leaflet/spec/suites/geo/LatLngBoundsSpec.js +22 -14
  133. data/lib/leaflet/spec/suites/geo/LatLngSpec.js +22 -8
  134. data/lib/leaflet/spec/suites/geo/ProjectionSpec.js +21 -20
  135. data/lib/leaflet/spec/suites/geometry/BoundsSpec.js +15 -15
  136. data/lib/leaflet/spec/suites/geometry/PointSpec.js +12 -12
  137. data/lib/leaflet/spec/suites/geometry/TransformationSpec.js +4 -4
  138. data/lib/leaflet/spec/suites/layer/FeatureGroupSpec.js +59 -9
  139. data/lib/leaflet/spec/suites/layer/GeoJSONSpec.js +213 -17
  140. data/lib/leaflet/spec/suites/layer/LayerGroupSpec.js +6 -6
  141. data/lib/leaflet/spec/suites/layer/PopupSpec.js +65 -5
  142. data/lib/leaflet/spec/suites/layer/TileLayerSpec.js +16 -15
  143. data/lib/leaflet/spec/suites/layer/marker/MarkerSpec.js +94 -0
  144. data/lib/leaflet/spec/suites/layer/vector/CircleMarkerSpec.js +7 -7
  145. data/lib/leaflet/spec/suites/layer/vector/PolygonSpec.js +38 -2
  146. data/lib/leaflet/spec/suites/layer/vector/PolylineGeometrySpec.js +4 -4
  147. data/lib/leaflet/spec/suites/layer/vector/PolylineSpec.js +2 -2
  148. data/lib/leaflet/spec/suites/map/MapSpec.js +318 -26
  149. data/lib/leaflet/spec/suites/map/handler/Map.DragSpec.js +38 -0
  150. data/lib/leaflet/src/Leaflet.js +2 -2
  151. data/lib/leaflet/src/control/Control.Attribution.js +6 -0
  152. data/lib/leaflet/src/control/Control.Layers.js +33 -24
  153. data/lib/leaflet/src/control/Control.Zoom.js +12 -4
  154. data/lib/leaflet/src/control/Control.js +10 -0
  155. data/lib/leaflet/src/copyright.js +2 -1
  156. data/lib/leaflet/src/core/Browser.js +11 -10
  157. data/lib/leaflet/src/core/Events.js +15 -11
  158. data/lib/leaflet/src/core/Util.js +19 -14
  159. data/lib/leaflet/src/dom/DomEvent.DoubleTap.js +13 -12
  160. data/lib/leaflet/src/dom/DomEvent.Pointer.js +155 -0
  161. data/lib/leaflet/src/dom/DomEvent.js +57 -19
  162. data/lib/leaflet/src/dom/DomUtil.js +89 -34
  163. data/lib/leaflet/src/dom/Draggable.js +26 -89
  164. data/lib/leaflet/src/dom/PosAnimation.js +13 -2
  165. data/lib/leaflet/src/geo/LatLng.js +16 -5
  166. data/lib/leaflet/src/geo/LatLngBounds.js +5 -2
  167. data/lib/leaflet/src/geo/crs/CRS.EPSG3395.js +2 -2
  168. data/lib/leaflet/src/geo/crs/CRS.js +5 -0
  169. data/lib/leaflet/src/geo/projection/Projection.Mercator.js +3 -3
  170. data/lib/leaflet/src/geometry/LineUtil.js +2 -2
  171. data/lib/leaflet/src/images/layers.svg +8 -0
  172. data/lib/leaflet/src/images/marker.svg +61 -1
  173. data/lib/leaflet/src/layer/FeatureGroup.js +24 -7
  174. data/lib/leaflet/src/layer/GeoJSON.js +97 -56
  175. data/lib/leaflet/src/layer/ImageOverlay.js +9 -0
  176. data/lib/leaflet/src/layer/LayerGroup.js +8 -3
  177. data/lib/leaflet/src/layer/Popup.js +56 -34
  178. data/lib/leaflet/src/layer/marker/DivIcon.js +4 -2
  179. data/lib/leaflet/src/layer/marker/Icon.Default.js +1 -1
  180. data/lib/leaflet/src/layer/marker/Icon.js +15 -18
  181. data/lib/leaflet/src/layer/marker/Marker.Drag.js +7 -5
  182. data/lib/leaflet/src/layer/marker/Marker.Popup.js +22 -5
  183. data/lib/leaflet/src/layer/marker/Marker.js +75 -32
  184. data/lib/leaflet/src/layer/tile/TileLayer.Anim.js +14 -26
  185. data/lib/leaflet/src/layer/tile/TileLayer.Canvas.js +7 -6
  186. data/lib/leaflet/src/layer/tile/TileLayer.WMS.js +14 -10
  187. data/lib/leaflet/src/layer/tile/TileLayer.js +53 -32
  188. data/lib/leaflet/src/layer/vector/CircleMarker.js +11 -0
  189. data/lib/leaflet/src/layer/vector/MultiPoly.js +10 -0
  190. data/lib/leaflet/src/layer/vector/Path.SVG.js +14 -3
  191. data/lib/leaflet/src/layer/vector/Path.VML.js +12 -2
  192. data/lib/leaflet/src/layer/vector/Path.js +7 -3
  193. data/lib/leaflet/src/layer/vector/Polygon.js +14 -3
  194. data/lib/leaflet/src/layer/vector/canvas/CircleMarker.Canvas.js +9 -0
  195. data/lib/leaflet/src/layer/vector/canvas/Path.Canvas.js +1 -0
  196. data/lib/leaflet/src/map/Map.js +192 -125
  197. data/lib/leaflet/src/map/anim/Map.PanAnimation.js +29 -19
  198. data/lib/leaflet/src/map/anim/Map.ZoomAnimation.js +21 -9
  199. data/lib/leaflet/src/map/ext/Map.Geolocation.js +11 -4
  200. data/lib/leaflet/src/map/handler/Map.BoxZoom.js +26 -12
  201. data/lib/leaflet/src/map/handler/Map.DoubleClickZoom.js +10 -3
  202. data/lib/leaflet/src/map/handler/Map.Drag.js +12 -6
  203. data/lib/leaflet/src/map/handler/Map.Keyboard.js +5 -2
  204. data/lib/leaflet/src/map/handler/Map.ScrollWheelZoom.js +7 -1
  205. data/lib/leaflet/src/map/handler/Map.Tap.js +107 -0
  206. data/lib/leaflet/src/map/handler/Map.TouchZoom.js +9 -3
  207. data/vendor/assets/images/layers-2x.png +0 -0
  208. data/vendor/assets/images/layers.png +0 -0
  209. data/vendor/assets/images/spritesheet-2x.png +0 -0
  210. data/vendor/assets/images/spritesheet.png +0 -0
  211. data/vendor/assets/javascripts/leaflet.draw.js +2 -4
  212. data/vendor/assets/javascripts/leaflet.js +3 -1
  213. data/vendor/assets/javascripts/leaflet.label.js +2 -0
  214. data/vendor/assets/stylesheets/leaflet.css.erb +337 -318
  215. data/vendor/assets/stylesheets/leaflet.draw.css.erb +35 -3
  216. data/vendor/assets/stylesheets/leaflet.draw.ie.css +5 -0
  217. data/vendor/assets/stylesheets/leaflet.label.css +23 -4
  218. metadata +40 -14
  219. data/lib/leaflet.draw/examples/libs/leaflet.ie.css +0 -51
  220. data/lib/leaflet.label/libs/leaflet/leaflet.ie.css +0 -51
  221. data/lib/leaflet/dist/leaflet-src.js +0 -8579
  222. data/lib/leaflet/dist/leaflet.ie.css +0 -51
  223. data/lib/leaflet/dist/leaflet.js +0 -8
  224. data/lib/leaflet/spec/happen.js +0 -93
  225. data/lib/leaflet/src/dom/DomEvent.MsTouch.js +0 -146
  226. data/vendor/assets/stylesheets/leaflet.ie.css +0 -51
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NDc5OWQ2N2Q2OWIxNDE2YWI0YzA3ZjQzMDE3MzE0ZjkyZWY3YjVlYg==
5
- data.tar.gz: !binary |-
6
- YWJmZGZkOGRhMTAyYTYxMjQyYmM3ZjE1ODVhYzAwNzYwZmUwYWYyOQ==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- MWZkY2UyYzJkNWJkNDFlOWNiZDE0MWFiYTliNDM2NzA0NmY0ZTUwNDRlNjJh
10
- MGZlOTgyNjQyNTcwMDA0MTQwNTJhMDQyNGZiNWJkZWRkNjJiYjI5ZjQzYTVi
11
- ZDEwMWExODYxYTIxNzBiODNjYTRjZDRhODc5ZDUwNTgwY2FlOTQ=
12
- data.tar.gz: !binary |-
13
- ZDI0OTgwOGIwOGY1ZTc4MTFlYjZkZmQ4MTQ4ZmRiM2E1ZGQ4NWUzZGFiMDYx
14
- NjNhYTA1YzI1NDdjOWNkMzk3ZGI5NTNlMTgwODFhZjdhZDdjNzVjYTNiMGNk
15
- MWU5ZWY4MmNkNzk3ZjczNTc0ZDg0ZTAyMzA3YjgzZWJmNjQ4MmY=
2
+ SHA1:
3
+ metadata.gz: 50833261b9c8db5b4055d089645bdf8b229babf7
4
+ data.tar.gz: 6d8fcde80dee752e9719abf3fdd480b823eed6ab
5
+ SHA512:
6
+ metadata.gz: cb090728b974ad87576c225ad3a343850a6d74c695b825a1f0aaf0434d845019f24a390609229abe180b0259cc65c5bc5c0279f4ce3848b278f875a1030b0774
7
+ data.tar.gz: b6e5a3d76097e3e69fb1dbb90075aad62e8a723d54c75953f0adc2394805f55f697dd66aac3ffec0a3447c1e6fca3feb1bc08eeb3f10e6816268207dffbc20e6
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,8 @@
1
1
  = leaflet-js Changelog
2
2
 
3
+ === 0.7.0 (November 21, 2013)
4
+ * Update to leaflet 0.7.0
5
+
3
6
  === 0.6.beta4 (May 2, 2013)
4
7
  * Unix is case senstive!
5
8
 
data/leaflet-js.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  Gem::Specification.new do |spec|
3
3
  spec.name = 'leaflet-js'
4
- spec.version = '0.6.beta4'
4
+ spec.version = '0.7.0'
5
5
  spec.homepage = 'https://github.com/cfis/leaflet-js'
6
6
  spec.summary = <<-EOS
7
7
  Wraps the Leaflet Javascript Mapping Library in a Rails asset gem. Also include Leaflet.Label
@@ -25,4 +25,4 @@ EOS
25
25
  'vendor/assets/javascripts/*'])
26
26
  spec.required_ruby_version = '>= 1.9.3'
27
27
  spec.date = Time.now
28
- end
28
+ end
@@ -5,6 +5,45 @@ Leaflet.draw Changelog
5
5
 
6
6
  An in-progress version being developed on the master branch.
7
7
 
8
+ ### Improvements
9
+
10
+ * Restrict editing polygons so that at least 3 points are present. (by [@Zverik](https://github.com/Zverik). [#200](https://github.com/Leaflet/Leaflet.draw/pull/200)
11
+ * Tooltips initially start hidden until the mouse has been moved. (by [@Zverik](https://github.com/Zverik). [#210](https://github.com/Leaflet/Leaflet.draw/pull/210)
12
+
13
+ ### Bugfixes
14
+
15
+ * Fix edit toolbar so diabled state is represented correctly. (by [@joeybaker](https://github.com/joeybaker)). [#203](https://github.com/Leaflet/Leaflet.draw/pull/203)
16
+ * Fixed path middle marker positions. (by [@Zverik](https://github.com/Zverik)). [#208](https://github.com/Leaflet/Leaflet.draw/pull/208)
17
+ * Fix issue where toolbar buttons would have focus after clicked so couldn't use escape to cancel until clicked map at least once.
18
+ * Fix toolbar icons for retina displays. (by [@dwnoble](https://github.com/dwnoble)). [#217](https://github.com/Leaflet/Leaflet.draw/pull/217)
19
+ * Ensure that options are not shared between draw handler classes. (by [@yohanboniface](https://github.com/yohanboniface). [#219](https://github.com/Leaflet/Leaflet.draw/pull/219)
20
+
21
+ ## 0.2.2 (October 4, 2013)
22
+
23
+ ### Improvements
24
+
25
+ * Refactored the `L.drawLocal' object to be better structured and use this object whereever text is used. *NOTE: THIS IS A NEW FORMAT, SO WILL BRESK ANY EXISTING CUSTOM `L.drawLocal` SETTINGS*.
26
+ * Added Imperial measurements to compliment the existing Metric measurements when drawing a polyline or polygon.
27
+ * Added `draw:editstart` and `draw:editstop` events. (by [@bhell](https://github.com/bhell)). [#175](https://github.com/Leaflet/Leaflet.draw/pull/175)
28
+ * Added `repeatMode` option that will allow repeated drawing of features. (by [@jayhogan](https://github.com/jayhogan) and [@cscheid](https://github.com/cscheid)). [#178](https://github.com/Leaflet/Leaflet.draw/pull/178)
29
+ * Added abilit to set circle radius measurement to imperial units.
30
+ * Added disabled state for edit/delete buttons when no layers present. (inspired by [@snkashis](https://github.com/snkashis)). [#136](https://github.com/Leaflet/Leaflet.draw/pull/136)
31
+ * Add `showLength` and `showRadius` options to circle and polyline. (by [@Zverik](https://github.com/Zverik)). [#195](https://github.com/Leaflet/Leaflet.draw/pull/195)
32
+ * Add option to disable tooltips. (by [@Zverik](https://github.com/Zverik)). [#196](https://github.com/Leaflet/Leaflet.draw/pull/196)
33
+
34
+ ### Bugfixes
35
+
36
+ * Fixed bug where edit handlers could not be disabled.
37
+ * Added support for displaying the toolbar on the right hand side of the map. (by [@paulcpederson](https://github.com/paulcpederson)). [#164](https://github.com/Leaflet/Leaflet.draw/pull/164)
38
+ * Add flexible width action buttons. (by [@Grsmto](https://github.com/Grsmto)). [#181](https://github.com/Leaflet/Leaflet.draw/pull/181)
39
+ * Check for icon existence before disabling edit state. (by [@tmcw](https://github.com/tmcw)). [#182](https://github.com/Leaflet/Leaflet.draw/pull/182)
40
+ * Only update guideslines when guidelines are present. (by [@jayhogan](https://github.com/jayhogan)). [#188](https://github.com/Leaflet/Leaflet.draw/pull/188)
41
+ * Fixes to localization code so it can be correctly set after files have been loaded.
42
+ * Fix for firing `draw:edit` twice for Draw.SimpleShape. (by [@cazacugmihai](https://github.com/cazacugmihai)). [#192](https://github.com/Leaflet/Leaflet.draw/pull/192)
43
+ * Fix last edit menu buttons from wrapping. (by [@moiarcsan](https://github.com/moiarcsan)). [#198](https://github.com/Leaflet/Leaflet.draw/pull/198)
44
+
45
+ ## 0.2.1 (July 5, 2013)
46
+
8
47
  ### Improvements
9
48
 
10
49
  * `draw:edited` now returns a `FeatureGroup` of features edited. (by [@jmkelly](https://github.com/jmkelly)). [#95](https://github.com/Leaflet/Leaflet.draw/pull/95)
@@ -12,6 +51,10 @@ An in-progress version being developed on the master branch.
12
51
  * Added Leaflet version check to inform developers that Leaflet 0.6+ is required.
13
52
  * Added ability to finish drawing polygons by double clicking. (inspired by [@snkashis](https://github.com/snkashis)). [#121](https://github.com/Leaflet/Leaflet.label/pull/121)
14
53
  * Added test environment. (by [@iirvine](https://github.com/iirvine)). [#123](https://github.com/Leaflet/Leaflet.draw/pull/123)
54
+ * Added `L.drawLocal` object to allow users to customize the text used in the plugin. Addresses localization issues. (by [@Starefossen](https://github.com/Starefossen)). [#87](https://github.com/Leaflet/Leaflet.draw/pull/87)
55
+ * Added ability to disable edit mode path and marker styles. (inspired by [@markgibbons25](https://github.com/markgibbons25)). [#121](https://github.com/Leaflet/Leaflet.label/pull/137)
56
+ * Added area calculation when drawing a polygon.
57
+ * Polyline and Polygon tooltips update on click as well as mouse move.
15
58
 
16
59
  ### Bugfixes
17
60
 
@@ -19,6 +62,8 @@ An in-progress version being developed on the master branch.
19
62
  * Fixed issue where not passing in the context to `off()` would result in the event from not being unbound.(by [@koppelbakje](https://github.com/koppelbakje)). [#95](https://github.com/Leaflet/Leaflet.draw/pull/112)
20
63
  * Fixed issue where removing the draw control from the map would result in an error.
21
64
  * Fixed bug where removing points created by dragging midpoints would cause the polyline to not reflect any newly created points.
65
+ * Fixed regression where handlers were not able to be disabled.(by [@yohanboniface](https://github.com/yohanboniface)). [#139](https://github.com/Leaflet/Leaflet.draw/pull/139)
66
+ * Fixed bug where L.Draw.Polyline would try to remove a non-existant handler if the user cancelled and the polyline only had a single point.
22
67
 
23
68
  ## 0.2.0 (February 20, 2013)
24
69
 
@@ -1,5 +1,5 @@
1
1
  # Important
2
- You will need to download the latest Leaflet from master in the [Github repo](https://github.com/Leaflet/Leaflet) before Leaflet.draw 0.2.0 will work.
2
+ Leaflet.draw 0.2.0 requires [Leaflet 0.6](https://github.com/Leaflet/Leaflet/archive/v0.6.zip) or higher.
3
3
 
4
4
  #Leaflet.draw
5
5
  Adds support for drawing and editing vectors and markers on [Leaflet maps](https://github.com/Leaflet/Leaflet). Check out the [demo](http://leaflet.github.com/Leaflet.draw/)
@@ -11,7 +11,7 @@ Leaflet.draw 0.2.0 changes a LOT of things from 0.1. Please see [BREAKING CHANGE
11
11
  ## Table of Contents
12
12
  [Using the plugin](#using)
13
13
  [Advanced Options](#options)
14
- [Command tasks](#tasks)
14
+ [Common tasks](#commontasks)
15
15
  [Thanks](#thanks)
16
16
 
17
17
  <a name="using" />
@@ -128,6 +128,22 @@ Triggered when the user has finshed a particular vector or marker.
128
128
  | --- | --- | ---
129
129
  | layerType | String | The type of layer this is. One of: `polyline`, `polygon`, `rectangle`, `circle`, `marker`
130
130
 
131
+ #### draw:editstart
132
+
133
+ Triggered when the user starts edit mode by clicking the edit or remove tool button.
134
+
135
+ | Property | Type | Description
136
+ | --- | --- | ---
137
+ | handler | String | The type of edit this is. One of: `edit`, `remove`
138
+
139
+ #### draw:editstop
140
+
141
+ Triggered when the user has finshed editing (edit or remove mode) and saves edits.
142
+
143
+ | Property | Type | Description
144
+ | --- | --- | ---
145
+ | handler | String | The type of edit this is. One of: `edit`, `remove`
146
+
131
147
  <a name="options" />
132
148
  ## Advanced options
133
149
 
@@ -150,55 +166,64 @@ These options will allow you to configure the draw toolbar and it's handlers.
150
166
 
151
167
  | Option | Type | Default | Description
152
168
  | --- | --- | --- | ---
153
- | polyline | [PolylineOptions](#polylineoptions) | `{ title: 'Draw a polyline' }` | Polyline draw handler options.
154
- | polygon | [PolygonOptions](#polygonoptions) | `{ title: 'Draw a polygon' }` | Polygon draw handler options.
155
- | rectangle | [RectangleOptions](#rectangleoptions) | `{ title: 'Draw a rectangle' }` | Rectangle draw handler options.
156
- | circle | [CircleOptions](#circleoptions) | `{ title: 'Draw a circle' }` | Circle draw handler options.
157
- | marker | [MarkerOptions](#markeroptions) | `{ title: 'Add a marker' }` | Marker draw handler options.
169
+ | polyline | [PolylineOptions](#polylineoptions) | `{ }` | Polyline draw handler options. Set to `false` to disable handler.
170
+ | polygon | [PolygonOptions](#polygonoptions) | `{ }` | Polygon draw handler options. Set to `false` to disable handler.
171
+ | rectangle | [RectangleOptions](#rectangleoptions) | `{ }` | Rectangle draw handler options. Set to `false` to disable handler.
172
+ | circle | [CircleOptions](#circleoptions) | `{ }` | Circle draw handler options. Set to `false` to disable handler.
173
+ | marker | [MarkerOptions](#markeroptions) | `{ }` | Marker draw handler options. Set to `false` to disable handler.
158
174
 
159
175
  ### Draw handler options
160
176
 
161
177
  The following options will allow you to configure the individual draw handlers.
162
178
 
163
179
  <a name="polylineoptions" />
164
- <a name="polygonoptions" />
165
- #### PolylineOptions and PolygonOptions
180
+ #### PolylineOptions
166
181
 
167
182
  Polyline and Polygon drawing handlers take the same options.
168
183
 
169
184
  | Option | Type | Default | Description
170
185
  | --- | --- | --- | ---
171
- | title | String | `'Draw a Polyline (Polygon)'` | The title used for the polyline/polygon button.
172
186
  | allowIntersection | Bool | `true` | Determines if line segements can cross.
173
187
  | drawError | Object | [See code](https://github.com/Leaflet/Leaflet.draw/blob/master/src/draw/handler/Draw.Polyline.js#L10) | Configuration options for the error that displays if an intersection is detected.
174
188
  | guidelineDistance | Number | `20` | Distance in pixels between each guide dash.
175
189
  | shapeOptions | [Leaflet Polyline options](http://leafletjs.com/reference.html#polyline-options) | [See code](https://github.com/Leaflet/Leaflet.draw/blob/master/src/draw/handler/Draw.Polyline.js#L20) | The options used when drawing the polyline/polygon on the map.
190
+ | metric | Bool | `true` | Determines which measurement system (metric or imperial) is used.
176
191
  | zIndexOffset | Number | `2000` | This should be a high number to ensure that you can draw over all other layers on the map.
192
+ | repeatMode | Bool | `false` | Determines if the draw tool remains enabled after drawing a shape.
193
+
194
+ <a name="polygonoptions" />
195
+ #### PolygonOptions
196
+
197
+ Polygon options include all of the Polyline options plus the option to show the approximate area.
198
+
199
+ | Option | Type | Default | Description
200
+ | --- | --- | --- | ---
201
+ | showArea | Bool | `false` | Show the area of the drawn polygon in m², ha or km². **The area is only approximate and become less accurate the larger the polygon is.**
177
202
 
178
203
  <a name="rectangleoptions" />
179
204
  #### RectangleOptions
180
205
 
181
206
  | Option | Type | Default | Description
182
207
  | --- | --- | --- | ---
183
- | title | String | `'Draw a rectangle.'` | The title used for the rectangle button.
184
208
  | shapeOptions | [Leaflet Path options](http://leafletjs.com/reference.html#path-options) | [See code](https://github.com/Leaflet/Leaflet.draw/blob/master/src/draw/handler/Draw.Rectangle.js#L7) | The options used when drawing the rectangle on the map.
209
+ | repeatMode | Bool | `false` | Determines if the draw tool remains enabled after drawing a shape.
185
210
 
186
211
  <a name="circleoptions" />
187
212
  #### CircleOptions
188
213
 
189
214
  | Option | Type | Default | Description
190
215
  | --- | --- | --- | ---
191
- | title | String | `'Draw a circle.'` | The title used for the circle button.
192
216
  | shapeOptions | [Leaflet Path options](http://leafletjs.com/reference.html#path-options) | [See code](https://github.com/Leaflet/Leaflet.draw/blob/master/src/draw/handler/Draw.Circle.js#L7) | The options used when drawing the circle on the map.
217
+ | repeatMode | Bool | `false` | Determines if the draw tool remains enabled after drawing a shape.
193
218
 
194
219
  <a name="markeroptions" />
195
220
  #### MarkerOptions
196
221
 
197
222
  | Option | Type | Default | Description
198
223
  | --- | --- | --- | ---
199
- | title | String | `'Add a marker.'` | The title used for the marker button.
200
224
  | icon | [Leaflet Icon](http://leafletjs.com/reference.html#icon) | `L.Icon.Default()` | The icon displayed when drawing a marker.
201
225
  | zIndexOffset | Number | `2000` | This should be a high number to ensure that you can draw over all other layers on the map.
226
+ | repeatMode | Bool | `false` | Determines if the draw tool remains enabled after drawing a shape.
202
227
 
203
228
  <a name="editoptions" />
204
229
  ### EditOptions
@@ -208,23 +233,38 @@ These options will allow you to configure the draw toolbar and its handlers.
208
233
  | Option | Type | Default | Description
209
234
  | --- | --- | --- | ---
210
235
  | featureGroup | [Leaflet FeatureGroup](http://leafletjs.com/reference.html#featuregroup) | `null` | This is the FeatureGroup that stores all editable shapes. **THIS iS REQUIRED FOR THE EDIT TOOLBAR TO WORK**
211
- | edit | [EditHandlerOptions](#edithandleroptions) | `{ title: 'Edit layers' }` | Edit handler options.
212
- | remove | [DeleteHandlerOptions](#deletehandleroptions) | `{ title: 'Delete layers' }` | Delete handler options.
236
+ | edit | [EditHandlerOptions](#edithandleroptions) | `{ }` | Edit handler options. Set to `false` to disable handler.
237
+ | remove | [DeleteHandlerOptions](#deletehandleroptions) | `{ }` | Delete handler options. Set to `false` to disable handler.
213
238
 
214
239
  <a name="edithandleroptions" />
215
240
  #### EditHandlerOptions
216
241
 
217
242
  | Option | Type | Default | Description
218
243
  | --- | --- | --- | ---
219
- | title | String | `'Edit Layers'` | The title used for the edit button.
220
- | selectedPathOptions | [Leaflet Path options](http://leafletjs.com/reference.html#path-options) | [See code](https://github.com/Leaflet/Leaflet.draw/blob/master/src/edit/handler/EditToolbar.Edit.js#L9) | The path options for how the layers will look like while in edit mode.
244
+ | selectedPathOptions | [Leaflet Path options](http://leafletjs.com/reference.html#path-options) | [See code](https://github.com/Leaflet/Leaflet.draw/blob/master/src/edit/handler/EditToolbar.Edit.js#L9) | The path options for how the layers will look like while in edit mode. If this is set to null the editable path options will not be set.
221
245
 
222
246
  <a name="deletehandleroptions" />
223
247
  #### DeleteHandlerOptions
224
248
 
225
249
  | Option | Type | Default | Description
226
250
  | --- | --- | --- | ---
227
- | title | String | `'Remove Layers'` | The title used for the delete button.
251
+
252
+ <a name="drawlocal" />
253
+ #### Customizing language and text in Leaflet.draw
254
+
255
+ Leaflet.draw uses the `L.drawLocal` configuration object to set any text used in the plugin. Customizing this will allow support for changing the text or supporting another language.
256
+
257
+ See [Leaflet.draw.js](https://github.com/Leaflet/Leaflet.draw/blob/master/src/Leaflet.draw.js) for the default strings.
258
+
259
+ E.g.
260
+
261
+ ````js
262
+ // Set the button title text for the polygon button
263
+ L.drawLocal.draw.toolbar.buttons.polygon = 'Draw a sexy polygon!';
264
+
265
+ // Set the tooltip start text for the rectangle
266
+ L.drawLocal.draw.handlers.rectangle.tooltip.start = 'Not telling...';
267
+ ````
228
268
 
229
269
  <a name="commontasks" />
230
270
  ## Common tasks
@@ -261,7 +301,6 @@ var options = {
261
301
  position: 'topright',
262
302
  draw: {
263
303
  polyline: {
264
- title: 'Draw a kick ass polyline!'
265
304
  shapeOptions: {
266
305
  color: '#f357a1',
267
306
  weight: 10
@@ -270,7 +309,7 @@ var options = {
270
309
  polygon: {
271
310
  allowIntersection: false, // Restricts shapes to simple polygons
272
311
  drawError: {
273
- color: '#e1e100, // Color the shape will turn when intersects
312
+ color: '#e1e100', // Color the shape will turn when intersects
274
313
  message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect
275
314
  },
276
315
  shapeOptions: {
@@ -345,13 +384,21 @@ You can change a draw handlers options after initialization by using the `setDra
345
384
  E.g. to change the colour of the rectangle:
346
385
 
347
386
  ````js
348
- drawControl.setDrawingOptions(
387
+ drawControl.setDrawingOptions({
349
388
  rectangle: {
350
- color: '#0000FF'
389
+ shapeOptions: {
390
+ color: '#0000FF'
391
+ }
351
392
  }
352
- );
393
+ });
353
394
  ````
354
395
 
396
+ ### Creating a custom build
397
+
398
+ If you only require certain handlers (and not the UI), you may wish to create a custom build. You can generate the relevant jake command using the [build html file](https://github.com/Leaflet/Leaflet.draw/blob/master/build/build.html).
399
+
400
+ See [edit handlers example](https://github.com/Leaflet/Leaflet.draw/blob/master/examples/edithandlers.html) which uses only the edit handlers.
401
+
355
402
  <a name="thanks" />
356
403
  ## Thanks
357
404
 
@@ -34,6 +34,7 @@ var deps = {
34
34
  Extensions: {
35
35
  src: [
36
36
  'ext/LatLngUtil.js',
37
+ 'ext/GeometryUtil.js',
37
38
  'ext/LineUtil.Intersect.js',
38
39
  'ext/Polyline.Intersect.js',
39
40
  'ext/Polygon.Intersect.js'
@@ -11,7 +11,95 @@
11
11
  * Leaflet.draw assumes that you have already included the Leaflet library.
12
12
  */
13
13
 
14
- L.drawVersion = '0.2.0-dev';
14
+ L.drawVersion = '0.2.3-dev';
15
+
16
+ L.drawLocal = {
17
+ draw: {
18
+ toolbar: {
19
+ actions: {
20
+ title: 'Cancel drawing',
21
+ text: 'Cancel'
22
+ },
23
+ buttons: {
24
+ polyline: 'Draw a polyline',
25
+ polygon: 'Draw a polygon',
26
+ rectangle: 'Draw a rectangle',
27
+ circle: 'Draw a circle',
28
+ marker: 'Draw a marker'
29
+ }
30
+ },
31
+ handlers: {
32
+ circle: {
33
+ tooltip: {
34
+ start: 'Click and drag to draw circle.'
35
+ }
36
+ },
37
+ marker: {
38
+ tooltip: {
39
+ start: 'Click map to place marker.'
40
+ }
41
+ },
42
+ polygon: {
43
+ tooltip: {
44
+ start: 'Click to start drawing shape.',
45
+ cont: 'Click to continue drawing shape.',
46
+ end: 'Click first point to close this shape.'
47
+ }
48
+ },
49
+ polyline: {
50
+ error: '<strong>Error:</strong> shape edges cannot cross!',
51
+ tooltip: {
52
+ start: 'Click to start drawing line.',
53
+ cont: 'Click to continue drawing line.',
54
+ end: 'Click last point to finish line.'
55
+ }
56
+ },
57
+ rectangle: {
58
+ tooltip: {
59
+ start: 'Click and drag to draw rectangle.'
60
+ }
61
+ },
62
+ simpleshape: {
63
+ tooltip: {
64
+ end: 'Release mouse to finish drawing.'
65
+ }
66
+ }
67
+ }
68
+ },
69
+ edit: {
70
+ toolbar: {
71
+ actions: {
72
+ save: {
73
+ title: 'Save changes.',
74
+ text: 'Save'
75
+ },
76
+ cancel: {
77
+ title: 'Cancel editing, discards all changes.',
78
+ text: 'Cancel'
79
+ }
80
+ },
81
+ buttons: {
82
+ edit: 'Edit layers.',
83
+ editDisabled: 'No layers to edit.',
84
+ remove: 'Delete layers.',
85
+ removeDisabled: 'No layers to delete.'
86
+ }
87
+ },
88
+ handlers: {
89
+ edit: {
90
+ tooltip: {
91
+ text: 'Drag handles, or marker to edit feature.',
92
+ subtext: 'Click cancel to undo changes.'
93
+ }
94
+ },
95
+ remove: {
96
+ tooltip: {
97
+ text: 'Click on a feature to remove'
98
+ }
99
+ }
100
+ }
101
+ }
102
+ };
15
103
 
16
104
  L.Draw = {};
17
105
 
@@ -28,7 +116,7 @@ L.Draw.Feature = L.Handler.extend({
28
116
  if (options && options.shapeOptions) {
29
117
  options.shapeOptions = L.Util.extend({}, this.options.shapeOptions, options.shapeOptions);
30
118
  }
31
- L.Util.extend(this.options, options);
119
+ L.setOptions(this, options);
32
120
  },
33
121
 
34
122
  enable: function () {
@@ -52,9 +140,13 @@ L.Draw.Feature = L.Handler.extend({
52
140
  },
53
141
 
54
142
  addHooks: function () {
55
- if (this._map) {
143
+ var map = this._map;
144
+
145
+ if (map) {
56
146
  L.DomUtil.disableTextSelection();
57
147
 
148
+ map.getContainer().focus();
149
+
58
150
  this._tooltip = new L.Tooltip(this._map);
59
151
 
60
152
  L.DomEvent.addListener(this._container, 'keyup', this._cancelDrawing, this);
@@ -97,9 +189,9 @@ L.Draw.Polyline = L.Draw.Feature.extend({
97
189
 
98
190
  options: {
99
191
  allowIntersection: true,
192
+ repeatMode: false,
100
193
  drawError: {
101
194
  color: '#b00b00',
102
- message: '<strong>Error:</strong> shape edges cannot cross!',
103
195
  timeout: 2500
104
196
  },
105
197
  icon: new L.DivIcon({
@@ -115,10 +207,15 @@ L.Draw.Polyline = L.Draw.Feature.extend({
115
207
  fill: false,
116
208
  clickable: true
117
209
  },
210
+ metric: true, // Whether to use the metric meaurement system or imperial
211
+ showLength: true, // Whether to display distance in the tooltip
118
212
  zIndexOffset: 2000 // This should be > than the highest z-index any map layers
119
213
  },
120
214
 
121
215
  initialize: function (map, options) {
216
+ // Need to set this here to ensure the correct message is used.
217
+ this.options.drawError.message = L.drawLocal.draw.handlers.polyline.error;
218
+
122
219
  // Merge default drawError options with custom options
123
220
  if (options && options.drawError) {
124
221
  options.drawError = L.Util.extend({}, this.options.drawError, options.drawError);
@@ -206,6 +303,9 @@ L.Draw.Polyline = L.Draw.Feature.extend({
206
303
 
207
304
  this._fireCreatedEvent();
208
305
  this.disable();
306
+ if (this.options.repeatMode) {
307
+ this.enable();
308
+ }
209
309
  },
210
310
 
211
311
  //Called to verify the shape is valid when the user tries to finish it
@@ -226,8 +326,7 @@ L.Draw.Polyline = L.Draw.Feature.extend({
226
326
  // should this be moved to _updateGuide() ?
227
327
  this._currentLatLng = latlng;
228
328
 
229
- // Update the label
230
- this._tooltip.updatePosition(latlng);
329
+ this._updateTooltip(latlng);
231
330
 
232
331
  // Update the guide line
233
332
  this._updateGuide(newPos);
@@ -263,6 +362,8 @@ L.Draw.Polyline = L.Draw.Feature.extend({
263
362
  this._vertexAdded(latlng);
264
363
 
265
364
  this._clearGuides();
365
+
366
+ this._updateTooltip();
266
367
  },
267
368
 
268
369
  _updateFinishHandler: function () {
@@ -290,15 +391,10 @@ L.Draw.Polyline = L.Draw.Feature.extend({
290
391
  },
291
392
 
292
393
  _updateGuide: function (newPos) {
293
- newPos = newPos || this._map.latLngToLayerPoint(this._currentLatLng);
294
-
295
394
  var markerCount = this._markers.length;
296
395
 
297
396
  if (markerCount > 0) {
298
- // Update the tooltip text, as long it's not showing and error
299
- if (!this._errorShown) {
300
- this._tooltip.updateContent(this._getTooltipText());
301
- }
397
+ newPos = newPos || this._map.latLngToLayerPoint(this._currentLatLng);
302
398
 
303
399
  // draw the guide line
304
400
  this._clearGuides();
@@ -309,6 +405,18 @@ L.Draw.Polyline = L.Draw.Feature.extend({
309
405
  }
310
406
  },
311
407
 
408
+ _updateTooltip: function (latLng) {
409
+ var text = this._getTooltipText();
410
+
411
+ if (latLng) {
412
+ this._tooltip.updatePosition(latLng);
413
+ }
414
+
415
+ if (!this._errorShown) {
416
+ this._tooltip.updateContent(text);
417
+ }
418
+ },
419
+
312
420
  _drawGuide: function (pointA, pointB) {
313
421
  var length = Math.floor(Math.sqrt(Math.pow((pointB.x - pointA.x), 2) + Math.pow((pointB.y - pointA.y), 2))),
314
422
  i,
@@ -359,28 +467,24 @@ L.Draw.Polyline = L.Draw.Feature.extend({
359
467
  },
360
468
 
361
469
  _getTooltipText: function () {
362
- var labelText,
363
- distance,
364
- distanceStr;
470
+ var showLength = this.options.showLength,
471
+ labelText, distance, distanceStr;
365
472
 
366
473
  if (this._markers.length === 0) {
367
474
  labelText = {
368
- text: 'Click to start drawing line.'
475
+ text: L.drawLocal.draw.handlers.polyline.tooltip.start
369
476
  };
370
477
  } else {
371
- // calculate the distance from the last fixed point to the mouse position
372
- distance = this._measurementRunningTotal + this._currentLatLng.distanceTo(this._markers[this._markers.length - 1].getLatLng());
373
- // show metres when distance is < 1km, then show km
374
- distanceStr = distance > 1000 ? (distance / 1000).toFixed(2) + ' km' : Math.ceil(distance) + ' m';
478
+ distanceStr = showLength ? this._getMeasurementString() : '';
375
479
 
376
480
  if (this._markers.length === 1) {
377
481
  labelText = {
378
- text: 'Click to continue drawing line.',
482
+ text: L.drawLocal.draw.handlers.polyline.tooltip.cont,
379
483
  subtext: distanceStr
380
484
  };
381
485
  } else {
382
486
  labelText = {
383
- text: 'Click last point to finish line.',
487
+ text: L.drawLocal.draw.handlers.polyline.tooltip.end,
384
488
  subtext: distanceStr
385
489
  };
386
490
  }
@@ -388,6 +492,17 @@ L.Draw.Polyline = L.Draw.Feature.extend({
388
492
  return labelText;
389
493
  },
390
494
 
495
+ _getMeasurementString: function () {
496
+ var currentLatLng = this._currentLatLng,
497
+ previousLatLng = this._markers[this._markers.length - 1].getLatLng(),
498
+ distance;
499
+
500
+ // calculate the distance from the last fixed point to the mouse position
501
+ distance = this._measurementRunningTotal + currentLatLng.distanceTo(previousLatLng);
502
+
503
+ return L.GeometryUtil.readableDistance(distance, this.options.metric);
504
+ },
505
+
391
506
  _showErrorTooltip: function () {
392
507
  this._errorShown = true;
393
508
 
@@ -438,7 +553,7 @@ L.Draw.Polyline = L.Draw.Feature.extend({
438
553
  },
439
554
 
440
555
  _cleanUpShape: function () {
441
- if (this._markers.length > 0) {
556
+ if (this._markers.length > 1) {
442
557
  this._markers[this._markers.length - 1].off('click', this._finishShape, this);
443
558
  }
444
559
  },
@@ -449,6 +564,7 @@ L.Draw.Polyline = L.Draw.Feature.extend({
449
564
  }
450
565
  });
451
566
 
567
+
452
568
  L.Draw.Polygon = L.Draw.Polyline.extend({
453
569
  statics: {
454
570
  TYPE: 'polygon'
@@ -457,6 +573,7 @@ L.Draw.Polygon = L.Draw.Polyline.extend({
457
573
  Poly: L.Polygon,
458
574
 
459
575
  options: {
576
+ showArea: false,
460
577
  shapeOptions: {
461
578
  stroke: true,
462
579
  color: '#f06eaa',
@@ -495,25 +612,46 @@ L.Draw.Polygon = L.Draw.Polyline.extend({
495
612
  },
496
613
 
497
614
  _getTooltipText: function () {
498
- var text;
615
+ var text, subtext;
616
+
499
617
  if (this._markers.length === 0) {
500
- text = 'Click to start drawing shape.';
618
+ text = L.drawLocal.draw.handlers.polygon.tooltip.start;
501
619
  } else if (this._markers.length < 3) {
502
- text = 'Click to continue drawing shape.';
620
+ text = L.drawLocal.draw.handlers.polygon.tooltip.cont;
503
621
  } else {
504
- text = 'Double click to close this shape.';
622
+ text = L.drawLocal.draw.handlers.polygon.tooltip.end;
623
+ subtext = this._getMeasurementString();
505
624
  }
625
+
506
626
  return {
507
- text: text
627
+ text: text,
628
+ subtext: subtext
508
629
  };
509
630
  },
510
631
 
632
+ _getMeasurementString: function () {
633
+ var area = this._area;
634
+
635
+ if (!area) {
636
+ return null;
637
+ }
638
+
639
+ return L.GeometryUtil.readableArea(area, this.options.metric);
640
+ },
641
+
511
642
  _shapeIsValid: function () {
512
643
  return this._markers.length >= 3;
513
644
  },
514
645
 
515
646
  _vertexAdded: function () {
516
- //calc area here
647
+ // Check to see if we should show the area
648
+ if (this.options.allowIntersection || !this.options.showArea) {
649
+ return;
650
+ }
651
+
652
+ var latLngs = this._poly.getLatLngs();
653
+
654
+ this._area = L.GeometryUtil.geodesicArea(latLngs);
517
655
  },
518
656
 
519
657
  _cleanUpShape: function () {
@@ -529,9 +667,20 @@ L.Draw.Polygon = L.Draw.Polyline.extend({
529
667
  }
530
668
  });
531
669
 
670
+
532
671
  L.SimpleShape = {};
533
672
 
534
673
  L.Draw.SimpleShape = L.Draw.Feature.extend({
674
+ options: {
675
+ repeatMode: false
676
+ },
677
+
678
+ initialize: function (map, options) {
679
+ this._endLabelText = L.drawLocal.draw.handlers.simpleshape.tooltip.end;
680
+
681
+ L.Draw.Feature.prototype.initialize.call(this, map, options);
682
+ },
683
+
535
684
  addHooks: function () {
536
685
  L.Draw.Feature.prototype.addHooks.call(this);
537
686
  if (this._map) {
@@ -583,7 +732,7 @@ L.Draw.SimpleShape = L.Draw.Feature.extend({
583
732
 
584
733
  this._tooltip.updatePosition(latlng);
585
734
  if (this._isDrawing) {
586
- this._tooltip.updateContent({ text: 'Release mouse to finish drawing.' });
735
+ this._tooltip.updateContent({ text: this._endLabelText });
587
736
  this._drawShape(latlng);
588
737
  }
589
738
  },
@@ -594,6 +743,9 @@ L.Draw.SimpleShape = L.Draw.Feature.extend({
594
743
  }
595
744
 
596
745
  this.disable();
746
+ if (this.options.repeatMode) {
747
+ this.enable();
748
+ }
597
749
  }
598
750
  });
599
751
 
@@ -619,11 +771,11 @@ L.Draw.Rectangle = L.Draw.SimpleShape.extend({
619
771
  // Save the type so super can fire, need to do this as cannot do this.TYPE :(
620
772
  this.type = L.Draw.Rectangle.TYPE;
621
773
 
774
+ this._initialLabelText = L.drawLocal.draw.handlers.rectangle.tooltip.start;
775
+
622
776
  L.Draw.SimpleShape.prototype.initialize.call(this, map, options);
623
777
  },
624
778
 
625
- _initialLabelText: 'Click and drag to draw rectangle.',
626
-
627
779
  _drawShape: function (latlng) {
628
780
  if (!this._shape) {
629
781
  this._shape = new L.Rectangle(new L.LatLngBounds(this._startLatLng, latlng), this.options.shapeOptions);
@@ -639,6 +791,7 @@ L.Draw.Rectangle = L.Draw.SimpleShape.extend({
639
791
  }
640
792
  });
641
793
 
794
+
642
795
  L.Draw.Circle = L.Draw.SimpleShape.extend({
643
796
  statics: {
644
797
  TYPE: 'circle'
@@ -654,18 +807,20 @@ L.Draw.Circle = L.Draw.SimpleShape.extend({
654
807
  fillColor: null, //same as color by default
655
808
  fillOpacity: 0.2,
656
809
  clickable: true
657
- }
810
+ },
811
+ showRadius: true,
812
+ metric: true // Whether to use the metric meaurement system or imperial
658
813
  },
659
814
 
660
815
  initialize: function (map, options) {
661
816
  // Save the type so super can fire, need to do this as cannot do this.TYPE :(
662
817
  this.type = L.Draw.Circle.TYPE;
663
818
 
819
+ this._initialLabelText = L.drawLocal.draw.handlers.circle.tooltip.start;
820
+
664
821
  L.Draw.SimpleShape.prototype.initialize.call(this, map, options);
665
822
  },
666
823
 
667
- _initialLabelText: 'Click and drag to draw circle.',
668
-
669
824
  _drawShape: function (latlng) {
670
825
  if (!this._shape) {
671
826
  this._shape = new L.Circle(this._startLatLng, this._startLatLng.distanceTo(latlng), this.options.shapeOptions);
@@ -682,6 +837,9 @@ L.Draw.Circle = L.Draw.SimpleShape.extend({
682
837
 
683
838
  _onMouseMove: function (e) {
684
839
  var latlng = e.latlng,
840
+ metric = this.options.metric,
841
+ showRadius = this.options.showRadius,
842
+ useMetric = this.options.metric,
685
843
  radius;
686
844
 
687
845
  this._tooltip.updatePosition(latlng);
@@ -692,13 +850,14 @@ L.Draw.Circle = L.Draw.SimpleShape.extend({
692
850
  radius = this._shape.getRadius().toFixed(1);
693
851
 
694
852
  this._tooltip.updateContent({
695
- text: 'Release mouse to finish drawing.',
696
- subtext: 'Radius: ' + radius + ' m'
853
+ text: this._endLabelText,
854
+ subtext: showRadius ? 'Radius: ' + L.GeometryUtil.readableDistance(radius, useMetric) : ''
697
855
  });
698
856
  }
699
857
  }
700
858
  });
701
859
 
860
+
702
861
  L.Draw.Marker = L.Draw.Feature.extend({
703
862
  statics: {
704
863
  TYPE: 'marker'
@@ -706,6 +865,7 @@ L.Draw.Marker = L.Draw.Feature.extend({
706
865
 
707
866
  options: {
708
867
  icon: new L.Icon.Default(),
868
+ repeatMode: false,
709
869
  zIndexOffset: 2000 // This should be > than the highest z-index any markers
710
870
  },
711
871
 
@@ -720,7 +880,7 @@ L.Draw.Marker = L.Draw.Feature.extend({
720
880
  L.Draw.Feature.prototype.addHooks.call(this);
721
881
 
722
882
  if (this._map) {
723
- this._tooltip.updateContent({ text: 'Click map to place marker.' });
883
+ this._tooltip.updateContent({ text: L.drawLocal.draw.handlers.marker.tooltip.start });
724
884
 
725
885
  // Same mouseMarker as in Draw.Polyline
726
886
  if (!this._mouseMarker) {
@@ -781,6 +941,7 @@ L.Draw.Marker = L.Draw.Feature.extend({
781
941
  .addLayer(this._marker);
782
942
  }
783
943
  else {
944
+ latlng = this._mouseMarker.getLatLng();
784
945
  this._marker.setLatLng(latlng);
785
946
  }
786
947
  },
@@ -789,6 +950,9 @@ L.Draw.Marker = L.Draw.Feature.extend({
789
950
  this._fireCreatedEvent();
790
951
 
791
952
  this.disable();
953
+ if (this.options.repeatMode) {
954
+ this.enable();
955
+ }
792
956
  },
793
957
 
794
958
  _fireCreatedEvent: function () {
@@ -797,6 +961,7 @@ L.Draw.Marker = L.Draw.Feature.extend({
797
961
  }
798
962
  });
799
963
 
964
+
800
965
  L.Edit = L.Edit || {};
801
966
 
802
967
  /*
@@ -845,7 +1010,7 @@ L.Edit.Poly = L.Handler.extend({
845
1010
  this._markers = [];
846
1011
 
847
1012
  var latlngs = this._poly._latlngs,
848
- i, j, len, marker;
1013
+ i, j, len, marker;
849
1014
 
850
1015
  // TODO refactor holes implementation in Polygon to support it here
851
1016
 
@@ -923,10 +1088,13 @@ L.Edit.Poly = L.Handler.extend({
923
1088
  },
924
1089
 
925
1090
  _onMarkerClick: function (e) {
926
- // we want to remove the marker on click, but if latlng count < 3, polyline would be invalid
927
- if (this._poly._latlngs.length < 3) { return; }
1091
+ var minPoints = L.Polygon && (this._poly instanceof L.Polygon) ? 4 : 3,
1092
+ marker = e.target;
928
1093
 
929
- var marker = e.target;
1094
+ // If removing this point would create an invalid polyline/polygon don't remove
1095
+ if (this._poly._latlngs.length < minPoints) {
1096
+ return;
1097
+ }
930
1098
 
931
1099
  // remove the marker
932
1100
  this._removeMarker(marker);
@@ -1030,10 +1198,10 @@ L.Edit.Poly = L.Handler.extend({
1030
1198
 
1031
1199
  _getMiddleLatLng: function (marker1, marker2) {
1032
1200
  var map = this._poly._map,
1033
- p1 = map.latLngToLayerPoint(marker1.getLatLng()),
1034
- p2 = map.latLngToLayerPoint(marker2.getLatLng());
1201
+ p1 = map.project(marker1.getLatLng()),
1202
+ p2 = map.project(marker2.getLatLng());
1035
1203
 
1036
- return map.layerPointToLatLng(p1._add(p2)._divideBy(2));
1204
+ return map.unproject(p1._add(p2)._divideBy(2));
1037
1205
  }
1038
1206
  });
1039
1207
 
@@ -1192,7 +1360,6 @@ L.Edit.SimpleShape = L.Handler.extend({
1192
1360
  var marker = e.target;
1193
1361
  marker.setOpacity(1);
1194
1362
 
1195
- this._shape.fire('edit');
1196
1363
  this._fireEdit();
1197
1364
  },
1198
1365
 
@@ -1205,6 +1372,7 @@ L.Edit.SimpleShape = L.Handler.extend({
1205
1372
  }
1206
1373
  });
1207
1374
 
1375
+
1208
1376
  L.Edit = L.Edit || {};
1209
1377
 
1210
1378
  L.Edit.Rectangle = L.Edit.SimpleShape.extend({
@@ -1406,6 +1574,75 @@ L.LatLngUtil = {
1406
1574
  }
1407
1575
  };
1408
1576
 
1577
+ L.GeometryUtil = {
1578
+ // Ported from the OpenLayers implementation. See https://github.com/openlayers/openlayers/blob/master/lib/OpenLayers/Geometry/LinearRing.js#L270
1579
+ geodesicArea: function (latLngs) {
1580
+ var pointsCount = latLngs.length,
1581
+ area = 0.0,
1582
+ d2r = L.LatLng.DEG_TO_RAD,
1583
+ p1, p2;
1584
+
1585
+ if (pointsCount > 2) {
1586
+ for (var i = 0; i < pointsCount; i++) {
1587
+ p1 = latLngs[i];
1588
+ p2 = latLngs[(i + 1) % pointsCount];
1589
+ area += ((p2.lng - p1.lng) * d2r) *
1590
+ (2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r));
1591
+ }
1592
+ area = area * 6378137.0 * 6378137.0 / 2.0;
1593
+ }
1594
+
1595
+ return Math.abs(area);
1596
+ },
1597
+
1598
+ readableArea: function (area, isMetric) {
1599
+ var areaStr;
1600
+
1601
+ if (isMetric) {
1602
+ if (area >= 10000) {
1603
+ areaStr = (area * 0.0001).toFixed(2) + ' ha';
1604
+ } else {
1605
+ areaStr = area.toFixed(2) + ' m&sup2;';
1606
+ }
1607
+ } else {
1608
+ area *= 0.836127; // Square yards in 1 meter
1609
+
1610
+ if (area >= 3097600) { //3097600 square yards in 1 square mile
1611
+ areaStr = (area / 3097600).toFixed(2) + ' mi&sup2;';
1612
+ } else if (area >= 4840) {//48040 square yards in 1 acre
1613
+ areaStr = (area / 4840).toFixed(2) + ' acres';
1614
+ } else {
1615
+ areaStr = Math.ceil(area) + ' yd&sup2;';
1616
+ }
1617
+ }
1618
+
1619
+ return areaStr;
1620
+ },
1621
+
1622
+ readableDistance: function (distance, isMetric) {
1623
+ var distanceStr;
1624
+
1625
+ if (isMetric) {
1626
+ // show metres when distance is < 1km, then show km
1627
+ if (distance > 1000) {
1628
+ distanceStr = (distance / 1000).toFixed(2) + ' km';
1629
+ } else {
1630
+ distanceStr = Math.ceil(distance) + ' m';
1631
+ }
1632
+ } else {
1633
+ distance *= 1.09361;
1634
+
1635
+ if (distance > 1760) {
1636
+ distanceStr = (distance / 1760).toFixed(2) + ' miles';
1637
+ } else {
1638
+ distanceStr = Math.ceil(distance) + ' yd';
1639
+ }
1640
+ }
1641
+
1642
+ return distanceStr;
1643
+ }
1644
+ };
1645
+
1409
1646
  L.Util.extend(L.LineUtil, {
1410
1647
  // Checks to see if two line segments intersect. Does not handle degenerate cases.
1411
1648
  // http://compgeom.cs.uiuc.edu/~jeffe/teaching/373/notes/x06-sweepline.pdf
@@ -1628,6 +1865,7 @@ L.Control.Draw = L.Control.extend({
1628
1865
  });
1629
1866
 
1630
1867
  L.Map.mergeOptions({
1868
+ drawControlTooltips: true,
1631
1869
  drawControl: false
1632
1870
  });
1633
1871
 
@@ -1685,7 +1923,7 @@ L.Toolbar = L.Class.extend({
1685
1923
  this._actionsContainer = null;
1686
1924
  },
1687
1925
 
1688
- _initModeHandler: function (handler, container, buttonIndex, classNamePredix) {
1926
+ _initModeHandler: function (handler, container, buttonIndex, classNamePredix, buttonTitle) {
1689
1927
  var type = handler.type;
1690
1928
 
1691
1929
  this._modes[type] = {};
@@ -1693,7 +1931,7 @@ L.Toolbar = L.Class.extend({
1693
1931
  this._modes[type].handler = handler;
1694
1932
 
1695
1933
  this._modes[type].button = this._createButton({
1696
- title: this.options[type].title,
1934
+ title: buttonTitle,
1697
1935
  className: classNamePredix + '-' + type,
1698
1936
  container: container,
1699
1937
  callback: this._modes[type].handler.enable,
@@ -1766,9 +2004,7 @@ L.Toolbar = L.Class.extend({
1766
2004
 
1767
2005
  _createActions: function (buttons) {
1768
2006
  var container = L.DomUtil.create('ul', 'leaflet-draw-actions'),
1769
- buttonWidth = 50,
1770
2007
  l = buttons.length,
1771
- containerWidth = (l * buttonWidth) + (l - 1), //l - 1 = the borders
1772
2008
  li, button;
1773
2009
 
1774
2010
  for (var i = 0; i < l; i++) {
@@ -1788,8 +2024,6 @@ L.Toolbar = L.Class.extend({
1788
2024
  });
1789
2025
  }
1790
2026
 
1791
- container.style.width = containerWidth + 'px';
1792
-
1793
2027
  return container;
1794
2028
  },
1795
2029
 
@@ -1831,16 +2065,21 @@ L.Tooltip = L.Class.extend({
1831
2065
  this._map = map;
1832
2066
  this._popupPane = map._panes.popupPane;
1833
2067
 
1834
- this._container = L.DomUtil.create('div', 'leaflet-draw-tooltip', this._popupPane);
2068
+ this._container = map.options.drawControlTooltips ? L.DomUtil.create('div', 'leaflet-draw-tooltip', this._popupPane) : null;
1835
2069
  this._singleLineLabel = false;
1836
2070
  },
1837
2071
 
1838
2072
  dispose: function () {
1839
- this._popupPane.removeChild(this._container);
1840
- this._container = null;
2073
+ if (this._container) {
2074
+ this._popupPane.removeChild(this._container);
2075
+ this._container = null;
2076
+ }
1841
2077
  },
1842
2078
 
1843
2079
  updateContent: function (labelText) {
2080
+ if (!this._container) {
2081
+ return this;
2082
+ }
1844
2083
  labelText.subtext = labelText.subtext || '';
1845
2084
 
1846
2085
  // update the vertical position (only if changed)
@@ -1861,20 +2100,28 @@ L.Tooltip = L.Class.extend({
1861
2100
  },
1862
2101
 
1863
2102
  updatePosition: function (latlng) {
1864
- var pos = this._map.latLngToLayerPoint(latlng);
2103
+ var pos = this._map.latLngToLayerPoint(latlng),
2104
+ tooltipContainer = this._container;
1865
2105
 
1866
- L.DomUtil.setPosition(this._container, pos);
2106
+ if (this._container) {
2107
+ tooltipContainer.style.visibility = 'inherit';
2108
+ L.DomUtil.setPosition(tooltipContainer, pos);
2109
+ }
1867
2110
 
1868
2111
  return this;
1869
2112
  },
1870
2113
 
1871
2114
  showAsError: function () {
1872
- L.DomUtil.addClass(this._container, 'leaflet-error-draw-tooltip');
2115
+ if (this._container) {
2116
+ L.DomUtil.addClass(this._container, 'leaflet-error-draw-tooltip');
2117
+ }
1873
2118
  return this;
1874
2119
  },
1875
2120
 
1876
2121
  removeError: function () {
1877
- L.DomUtil.removeClass(this._container, 'leaflet-error-draw-tooltip');
2122
+ if (this._container) {
2123
+ L.DomUtil.removeClass(this._container, 'leaflet-error-draw-tooltip');
2124
+ }
1878
2125
  return this;
1879
2126
  }
1880
2127
  });
@@ -1882,24 +2129,23 @@ L.Tooltip = L.Class.extend({
1882
2129
  L.DrawToolbar = L.Toolbar.extend({
1883
2130
 
1884
2131
  options: {
1885
- polyline: {
1886
- title: 'Draw a polyline'
1887
- },
1888
- polygon: {
1889
- title: 'Draw a polygon'
1890
- },
1891
- rectangle: {
1892
- title: 'Draw a rectangle'
1893
- },
1894
- circle: {
1895
- title: 'Draw a circle'
1896
- },
1897
- marker: {
1898
- title: 'Add a marker'
1899
- }
2132
+ polyline: {},
2133
+ polygon: {},
2134
+ rectangle: {},
2135
+ circle: {},
2136
+ marker: {}
1900
2137
  },
1901
2138
 
1902
2139
  initialize: function (options) {
2140
+ // Ensure that the options are merged correctly since L.extend is only shallow
2141
+ for (var type in this.options) {
2142
+ if (this.options.hasOwnProperty(type)) {
2143
+ if (options[type]) {
2144
+ options[type] = L.extend({}, this.options[type], options[type]);
2145
+ }
2146
+ }
2147
+ }
2148
+
1903
2149
  L.Toolbar.prototype.initialize.call(this, options);
1904
2150
  },
1905
2151
 
@@ -1916,7 +2162,8 @@ L.DrawToolbar = L.Toolbar.extend({
1916
2162
  new L.Draw.Polyline(map, this.options.polyline),
1917
2163
  this._toolbarContainer,
1918
2164
  buttonIndex++,
1919
- buttonClassPrefix
2165
+ buttonClassPrefix,
2166
+ L.drawLocal.draw.toolbar.buttons.polyline
1920
2167
  );
1921
2168
  }
1922
2169
 
@@ -1925,7 +2172,8 @@ L.DrawToolbar = L.Toolbar.extend({
1925
2172
  new L.Draw.Polygon(map, this.options.polygon),
1926
2173
  this._toolbarContainer,
1927
2174
  buttonIndex++,
1928
- buttonClassPrefix
2175
+ buttonClassPrefix,
2176
+ L.drawLocal.draw.toolbar.buttons.polygon
1929
2177
  );
1930
2178
  }
1931
2179
 
@@ -1934,7 +2182,8 @@ L.DrawToolbar = L.Toolbar.extend({
1934
2182
  new L.Draw.Rectangle(map, this.options.rectangle),
1935
2183
  this._toolbarContainer,
1936
2184
  buttonIndex++,
1937
- buttonClassPrefix
2185
+ buttonClassPrefix,
2186
+ L.drawLocal.draw.toolbar.buttons.rectangle
1938
2187
  );
1939
2188
  }
1940
2189
 
@@ -1943,7 +2192,8 @@ L.DrawToolbar = L.Toolbar.extend({
1943
2192
  new L.Draw.Circle(map, this.options.circle),
1944
2193
  this._toolbarContainer,
1945
2194
  buttonIndex++,
1946
- buttonClassPrefix
2195
+ buttonClassPrefix,
2196
+ L.drawLocal.draw.toolbar.buttons.circle
1947
2197
  );
1948
2198
  }
1949
2199
 
@@ -1952,7 +2202,8 @@ L.DrawToolbar = L.Toolbar.extend({
1952
2202
  new L.Draw.Marker(map, this.options.marker),
1953
2203
  this._toolbarContainer,
1954
2204
  buttonIndex++,
1955
- buttonClassPrefix
2205
+ buttonClassPrefix,
2206
+ L.drawLocal.draw.toolbar.buttons.marker
1956
2207
  );
1957
2208
  }
1958
2209
 
@@ -1962,8 +2213,8 @@ L.DrawToolbar = L.Toolbar.extend({
1962
2213
  // Create the actions part of the toolbar
1963
2214
  this._actionsContainer = this._createActions([
1964
2215
  {
1965
- title: 'Cancel drawing',
1966
- text: 'Cancel',
2216
+ title: L.drawLocal.draw.toolbar.actions.title,
2217
+ text: L.drawLocal.draw.toolbar.actions.text,
1967
2218
  callback: this.disable,
1968
2219
  context: this
1969
2220
  }
@@ -1994,16 +2245,33 @@ L.DrawToolbar = L.Toolbar.extend({
1994
2245
  L.EditToolbar = L.Toolbar.extend({
1995
2246
  options: {
1996
2247
  edit: {
1997
- title: 'Edit layers',
1998
- selectedPathOptions: null // See Edit handler options, this is used to customize the style of selected paths
1999
- },
2000
- remove: {
2001
- title: 'Delete layers'
2248
+ selectedPathOptions: {
2249
+ color: '#fe57a1', /* Hot pink all the things! */
2250
+ opacity: 0.6,
2251
+ dashArray: '10, 10',
2252
+
2253
+ fill: true,
2254
+ fillColor: '#fe57a1',
2255
+ fillOpacity: 0.1
2256
+ }
2002
2257
  },
2258
+ remove: {},
2003
2259
  featureGroup: null /* REQUIRED! TODO: perhaps if not set then all layers on the map are selectable? */
2004
2260
  },
2005
2261
 
2006
2262
  initialize: function (options) {
2263
+ // Need to set this manually since null is an acceptable value here
2264
+ if (options.edit) {
2265
+ if (typeof options.edit.selectedPathOptions === 'undefined') {
2266
+ options.edit.selectedPathOptions = this.options.edit.selectedPathOptions;
2267
+ }
2268
+ options.edit = L.extend({}, this.options.edit, options.edit);
2269
+ }
2270
+
2271
+ if (options.remove) {
2272
+ options.remove = L.extend({}, this.options.remove, options.remove);
2273
+ }
2274
+
2007
2275
  L.Toolbar.prototype.initialize.call(this, options);
2008
2276
 
2009
2277
  this._selectedFeatureCount = 0;
@@ -2012,32 +2280,35 @@ L.EditToolbar = L.Toolbar.extend({
2012
2280
  addToolbar: function (map) {
2013
2281
  var container = L.DomUtil.create('div', 'leaflet-draw-section'),
2014
2282
  buttonIndex = 0,
2015
- buttonClassPrefix = 'leaflet-draw-edit';
2283
+ buttonClassPrefix = 'leaflet-draw-edit',
2284
+ featureGroup = this.options.featureGroup;
2016
2285
 
2017
- this._toolbarContainer = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar'),
2286
+ this._toolbarContainer = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar');
2018
2287
 
2019
2288
  this._map = map;
2020
2289
 
2021
2290
  if (this.options.edit) {
2022
2291
  this._initModeHandler(
2023
2292
  new L.EditToolbar.Edit(map, {
2024
- featureGroup: this.options.featureGroup,
2293
+ featureGroup: featureGroup,
2025
2294
  selectedPathOptions: this.options.edit.selectedPathOptions
2026
2295
  }),
2027
2296
  this._toolbarContainer,
2028
2297
  buttonIndex++,
2029
- buttonClassPrefix
2298
+ buttonClassPrefix,
2299
+ L.drawLocal.edit.toolbar.buttons.edit
2030
2300
  );
2031
2301
  }
2032
2302
 
2033
2303
  if (this.options.remove) {
2034
2304
  this._initModeHandler(
2035
2305
  new L.EditToolbar.Delete(map, {
2036
- featureGroup: this.options.featureGroup
2306
+ featureGroup: featureGroup
2037
2307
  }),
2038
2308
  this._toolbarContainer,
2039
2309
  buttonIndex++,
2040
- buttonClassPrefix
2310
+ buttonClassPrefix,
2311
+ L.drawLocal.edit.toolbar.buttons.remove
2041
2312
  );
2042
2313
  }
2043
2314
 
@@ -2047,14 +2318,14 @@ L.EditToolbar = L.Toolbar.extend({
2047
2318
  // Create the actions part of the toolbar
2048
2319
  this._actionsContainer = this._createActions([
2049
2320
  {
2050
- title: 'Save changes.',
2051
- text: 'Save',
2321
+ title: L.drawLocal.edit.toolbar.actions.save.title,
2322
+ text: L.drawLocal.edit.toolbar.actions.save.text,
2052
2323
  callback: this._save,
2053
2324
  context: this
2054
2325
  },
2055
2326
  {
2056
- title: 'Cancel editing, discards all changes.',
2057
- text: 'Cancel',
2327
+ title: L.drawLocal.edit.toolbar.actions.cancel.title,
2328
+ text: L.drawLocal.edit.toolbar.actions.cancel.text,
2058
2329
  callback: this.disable,
2059
2330
  context: this
2060
2331
  }
@@ -2064,9 +2335,19 @@ L.EditToolbar = L.Toolbar.extend({
2064
2335
  container.appendChild(this._toolbarContainer);
2065
2336
  container.appendChild(this._actionsContainer);
2066
2337
 
2338
+ this._checkDisabled();
2339
+
2340
+ featureGroup.on('layeradd layerremove', this._checkDisabled, this);
2341
+
2067
2342
  return container;
2068
2343
  },
2069
2344
 
2345
+ removeToolbar: function () {
2346
+ L.Toolbar.prototype.removeToolbar.call(this);
2347
+
2348
+ this.options.featureGroup.off('layeradd layerremove', this._checkDisabled, this);
2349
+ },
2350
+
2070
2351
  disable: function () {
2071
2352
  if (!this.enabled()) { return; }
2072
2353
 
@@ -2078,9 +2359,50 @@ L.EditToolbar = L.Toolbar.extend({
2078
2359
  _save: function () {
2079
2360
  this._activeMode.handler.save();
2080
2361
  this._activeMode.handler.disable();
2362
+ },
2363
+
2364
+ _checkDisabled: function () {
2365
+ var featureGroup = this.options.featureGroup,
2366
+ hasLayers = featureGroup.getLayers().length !== 0,
2367
+ button;
2368
+
2369
+ if (this.options.edit) {
2370
+ button = this._modes[L.EditToolbar.Edit.TYPE].button;
2371
+
2372
+ if (hasLayers) {
2373
+ L.DomUtil.removeClass(button, 'leaflet-disabled');
2374
+ } else {
2375
+ L.DomUtil.addClass(button, 'leaflet-disabled');
2376
+ }
2377
+
2378
+ button.setAttribute(
2379
+ 'title',
2380
+ hasLayers ?
2381
+ L.drawLocal.edit.toolbar.buttons.edit
2382
+ : L.drawLocal.edit.toolbar.buttons.editDisabled
2383
+ );
2384
+ }
2385
+
2386
+ if (this.options.remove) {
2387
+ button = this._modes[L.EditToolbar.Delete.TYPE].button;
2388
+
2389
+ if (hasLayers) {
2390
+ L.DomUtil.removeClass(button, 'leaflet-disabled');
2391
+ } else {
2392
+ L.DomUtil.addClass(button, 'leaflet-disabled');
2393
+ }
2394
+
2395
+ button.setAttribute(
2396
+ 'title',
2397
+ hasLayers ?
2398
+ L.drawLocal.edit.toolbar.buttons.remove
2399
+ : L.drawLocal.edit.toolbar.buttons.removeDisabled
2400
+ );
2401
+ }
2081
2402
  }
2082
2403
  });
2083
2404
 
2405
+
2084
2406
  L.EditToolbar.Edit = L.Handler.extend({
2085
2407
  statics: {
2086
2408
  TYPE: 'edit'
@@ -2088,28 +2410,14 @@ L.EditToolbar.Edit = L.Handler.extend({
2088
2410
 
2089
2411
  includes: L.Mixin.Events,
2090
2412
 
2091
- options: {
2092
- selectedPathOptions: {
2093
- color: '#fe57a1', /* Hot pink all the things! */
2094
- opacity: 0.6,
2095
- dashArray: '10, 10',
2096
-
2097
- fill: true,
2098
- fillColor: '#fe57a1',
2099
- fillOpacity: 0.1
2100
- }
2101
- },
2102
-
2103
2413
  initialize: function (map, options) {
2104
2414
  L.Handler.prototype.initialize.call(this, map);
2105
2415
 
2106
2416
  // Set options to the default unless already set
2107
- options.selectedPathOptions = options.selectedPathOptions || this.options.selectedPathOptions;
2108
-
2109
- L.Util.setOptions(this, options);
2417
+ this._selectedPathOptions = options.selectedPathOptions;
2110
2418
 
2111
2419
  // Store the selectable layer group for ease of access
2112
- this._featureGroup = this.options.featureGroup;
2420
+ this._featureGroup = options.featureGroup;
2113
2421
 
2114
2422
  if (!(this._featureGroup instanceof L.FeatureGroup)) {
2115
2423
  throw new Error('options.featureGroup must be a L.FeatureGroup');
@@ -2122,7 +2430,9 @@ L.EditToolbar.Edit = L.Handler.extend({
2122
2430
  },
2123
2431
 
2124
2432
  enable: function () {
2125
- if (this._enabled) { return; }
2433
+ if (this._enabled || !this._hasAvailableLayers()) {
2434
+ return;
2435
+ }
2126
2436
 
2127
2437
  L.Handler.prototype.enable.call(this);
2128
2438
 
@@ -2131,12 +2441,14 @@ L.EditToolbar.Edit = L.Handler.extend({
2131
2441
  .on('layerremove', this._disableLayerEdit, this);
2132
2442
 
2133
2443
  this.fire('enabled', {handler: this.type});
2444
+ this._map.fire('draw:editstart', { handler: this.type });
2134
2445
  },
2135
2446
 
2136
2447
  disable: function () {
2137
2448
  if (!this._enabled) { return; }
2138
2449
 
2139
2450
  this.fire('disabled', {handler: this.type});
2451
+ this._map.fire('draw:editstop', { handler: this.type });
2140
2452
 
2141
2453
  this._featureGroup
2142
2454
  .off('layeradd', this._enableLayerEdit, this)
@@ -2146,11 +2458,18 @@ L.EditToolbar.Edit = L.Handler.extend({
2146
2458
  },
2147
2459
 
2148
2460
  addHooks: function () {
2149
- if (this._map) {
2461
+ var map = this._map;
2462
+
2463
+ if (map) {
2464
+ map.getContainer().focus();
2465
+
2150
2466
  this._featureGroup.eachLayer(this._enableLayerEdit, this);
2151
2467
 
2152
2468
  this._tooltip = new L.Tooltip(this._map);
2153
- this._tooltip.updateContent({ text: 'Drag handles, or marker to edit feature.', subtext: 'Click cancel to undo changes.' });
2469
+ this._tooltip.updateContent({
2470
+ text: L.drawLocal.edit.handlers.edit.tooltip.text,
2471
+ subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
2472
+ });
2154
2473
 
2155
2474
  this._map.on('mousemove', this._onMouseMove, this);
2156
2475
  }
@@ -2227,6 +2546,9 @@ L.EditToolbar.Edit = L.Handler.extend({
2227
2546
  },
2228
2547
 
2229
2548
  _toggleMarkerHighlight: function (marker) {
2549
+ if (!marker._icon) {
2550
+ return;
2551
+ }
2230
2552
  // This is quite naughty, but I don't see another way of doing it. (short of setting a new icon)
2231
2553
  var icon = marker._icon;
2232
2554
 
@@ -2256,26 +2578,38 @@ L.EditToolbar.Edit = L.Handler.extend({
2256
2578
 
2257
2579
  _enableLayerEdit: function (e) {
2258
2580
  var layer = e.layer || e.target || e,
2259
- options = L.Util.extend({}, this.options.selectedPathOptions);
2581
+ isMarker = layer instanceof L.Marker,
2582
+ pathOptions;
2583
+
2584
+ // Don't do anything if this layer is a marker but doesn't have an icon. Markers
2585
+ // should usually have icons. If using Leaflet.draw with Leafler.markercluster there
2586
+ // is a chance that a marker doesn't.
2587
+ if (isMarker && !layer._icon) {
2588
+ return;
2589
+ }
2260
2590
 
2261
2591
  // Back up this layer (if haven't before)
2262
2592
  this._backupLayer(layer);
2263
2593
 
2264
2594
  // Update layer style so appears editable
2265
- if (layer instanceof L.Marker) {
2266
- this._toggleMarkerHighlight(layer);
2267
- } else {
2268
- layer.options.previousOptions = layer.options;
2595
+ if (this._selectedPathOptions) {
2596
+ pathOptions = L.Util.extend({}, this._selectedPathOptions);
2269
2597
 
2270
- // Make sure that Polylines are not filled
2271
- if (!(layer instanceof L.Circle) && !(layer instanceof L.Polygon) && !(layer instanceof L.Rectangle)) {
2272
- options.fill = false;
2273
- }
2598
+ if (isMarker) {
2599
+ this._toggleMarkerHighlight(layer);
2600
+ } else {
2601
+ layer.options.previousOptions = layer.options;
2274
2602
 
2275
- layer.setStyle(options);
2603
+ // Make sure that Polylines are not filled
2604
+ if (!(layer instanceof L.Circle) && !(layer instanceof L.Polygon) && !(layer instanceof L.Rectangle)) {
2605
+ pathOptions.fill = false;
2606
+ }
2607
+
2608
+ layer.setStyle(pathOptions);
2609
+ }
2276
2610
  }
2277
2611
 
2278
- if (layer instanceof L.Marker) {
2612
+ if (isMarker) {
2279
2613
  layer.dragging.enable();
2280
2614
  layer.on('dragend', this._onMarkerDragEnd);
2281
2615
  } else {
@@ -2288,13 +2622,15 @@ L.EditToolbar.Edit = L.Handler.extend({
2288
2622
  layer.edited = false;
2289
2623
 
2290
2624
  // Reset layer styles to that of before select
2291
- if (layer instanceof L.Marker) {
2292
- this._toggleMarkerHighlight(layer);
2293
- } else {
2294
- // reset the layer style to what is was before being selected
2295
- layer.setStyle(layer.options.previousOptions);
2296
- // remove the cached options for the layer object
2297
- delete layer.options.previousOptions;
2625
+ if (this._selectedPathOptions) {
2626
+ if (layer instanceof L.Marker) {
2627
+ this._toggleMarkerHighlight(layer);
2628
+ } else {
2629
+ // reset the layer style to what is was before being selected
2630
+ layer.setStyle(layer.options.previousOptions);
2631
+ // remove the cached options for the layer object
2632
+ delete layer.options.previousOptions;
2633
+ }
2298
2634
  }
2299
2635
 
2300
2636
  if (layer instanceof L.Marker) {
@@ -2312,9 +2648,14 @@ L.EditToolbar.Edit = L.Handler.extend({
2312
2648
 
2313
2649
  _onMouseMove: function (e) {
2314
2650
  this._tooltip.updatePosition(e.latlng);
2651
+ },
2652
+
2653
+ _hasAvailableLayers: function () {
2654
+ return this._featureGroup.getLayers().length !== 0;
2315
2655
  }
2316
2656
  });
2317
2657
 
2658
+
2318
2659
  L.EditToolbar.Delete = L.Handler.extend({
2319
2660
  statics: {
2320
2661
  TYPE: 'remove' // not delete as delete is reserved in js
@@ -2339,7 +2680,9 @@ L.EditToolbar.Delete = L.Handler.extend({
2339
2680
  },
2340
2681
 
2341
2682
  enable: function () {
2342
- if (this._enabled) { return; }
2683
+ if (this._enabled || !this._hasAvailableLayers()) {
2684
+ return;
2685
+ }
2343
2686
 
2344
2687
  L.Handler.prototype.enable.call(this);
2345
2688
 
@@ -2348,6 +2691,7 @@ L.EditToolbar.Delete = L.Handler.extend({
2348
2691
  .on('layerremove', this._disableLayerDelete, this);
2349
2692
 
2350
2693
  this.fire('enabled', { handler: this.type});
2694
+ this._map.fire('draw:editstart', { handler: this.type });
2351
2695
  },
2352
2696
 
2353
2697
  disable: function () {
@@ -2360,15 +2704,20 @@ L.EditToolbar.Delete = L.Handler.extend({
2360
2704
  .off('layerremove', this._disableLayerDelete, this);
2361
2705
 
2362
2706
  this.fire('disabled', { handler: this.type});
2707
+ this._map.fire('draw:editstop', { handler: this.type });
2363
2708
  },
2364
2709
 
2365
2710
  addHooks: function () {
2366
- if (this._map) {
2711
+ var map = this._map;
2712
+
2713
+ if (map) {
2714
+ map.getContainer().focus();
2715
+
2367
2716
  this._deletableLayers.eachLayer(this._enableLayerDelete, this);
2368
2717
  this._deletedLayers = new L.layerGroup();
2369
2718
 
2370
2719
  this._tooltip = new L.Tooltip(this._map);
2371
- this._tooltip.updateContent({ text: 'Click on a feature to remove.' });
2720
+ this._tooltip.updateContent({ text: L.drawLocal.edit.handlers.remove.tooltip.text });
2372
2721
 
2373
2722
  this._map.on('mousemove', this._onMouseMove, this);
2374
2723
  }
@@ -2422,6 +2771,10 @@ L.EditToolbar.Delete = L.Handler.extend({
2422
2771
 
2423
2772
  _onMouseMove: function (e) {
2424
2773
  this._tooltip.updatePosition(e.latlng);
2774
+ },
2775
+
2776
+ _hasAvailableLayers: function () {
2777
+ return this._deletableLayers.getLayers().length !== 0;
2425
2778
  }
2426
2779
  });
2427
2780