leaflet-js 0.7.9 → 0.8.dev2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (341) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.rdoc +0 -10
  3. data/Rakefile +3 -3
  4. data/leaflet-js.gemspec +7 -13
  5. data/lib/leaflet-js.rb +10 -2
  6. data/lib/leaflet.draw/BREAKINGCHANGES.md +54 -0
  7. data/lib/leaflet.draw/CHANGELOG.md +130 -0
  8. data/lib/leaflet.draw/Jakefile.js +48 -0
  9. data/lib/leaflet.draw/MIT-LICENCE.txt +20 -0
  10. data/lib/leaflet.draw/README.md +427 -0
  11. data/lib/leaflet.draw/TODO.md +62 -0
  12. data/lib/leaflet.draw/build/build.html +243 -0
  13. data/lib/leaflet.draw/build/build.js +187 -0
  14. data/lib/leaflet.draw/build/deps.js +76 -0
  15. data/lib/leaflet.draw/build/hintrc.js +39 -0
  16. data/lib/leaflet.draw/build/leaflet.draw-include.js +42 -0
  17. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/dist/images/spritesheet-2x.png +0 -0
  18. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/dist/images/spritesheet.png +0 -0
  19. data/lib/leaflet.draw/dist/leaflet.draw-src.js +2872 -0
  20. data/lib/leaflet.draw/dist/leaflet.draw.css +295 -0
  21. data/lib/leaflet.draw/dist/leaflet.draw.js +10 -0
  22. data/lib/leaflet.draw/examples/basic.html +113 -0
  23. data/lib/leaflet.draw/examples/edithandlers.html +66 -0
  24. data/{vendor/assets/Leaflet/dist → lib/leaflet.draw/examples/libs}/images/layers-2x.png +0 -0
  25. data/{vendor/assets/Leaflet/dist → lib/leaflet.draw/examples/libs}/images/layers.png +0 -0
  26. data/{vendor/assets/Leaflet/dist → lib/leaflet.draw/examples/libs}/images/marker-icon-2x.png +0 -0
  27. data/{vendor/assets/Leaflet/dist → lib/leaflet.draw/examples/libs}/images/marker-icon.png +0 -0
  28. data/lib/leaflet.draw/examples/libs/images/marker-icon@2x.png +0 -0
  29. data/{vendor/assets/Leaflet/dist → lib/leaflet.draw/examples/libs}/images/marker-shadow.png +0 -0
  30. data/lib/leaflet.draw/examples/libs/leaflet-src.js +9191 -0
  31. data/{vendor/assets/leaflet.css.erb → lib/leaflet.draw/examples/libs/leaflet.css} +2 -2
  32. data/lib/leaflet.draw/package.json +40 -0
  33. data/lib/leaflet.draw/spec/after.js +2 -0
  34. data/lib/leaflet.draw/spec/before.js +3 -0
  35. data/lib/leaflet.draw/spec/expect.js +1253 -0
  36. data/lib/leaflet.draw/spec/happen.js +93 -0
  37. data/lib/leaflet.draw/spec/index.html +38 -0
  38. data/lib/leaflet.draw/spec/karma.conf.js +72 -0
  39. data/lib/leaflet.draw/spec/sinon.js +4223 -0
  40. data/lib/leaflet.draw/spec/spec.hintrc.js +25 -0
  41. data/lib/leaflet.draw/spec/suites/DrawControlSpec.js +14 -0
  42. data/lib/leaflet.draw/spec/suites/GeometryUtilSpec.js +25 -0
  43. data/lib/leaflet.draw/spec/suites/LatLngUtilSpec.js +11 -0
  44. data/lib/leaflet.draw/spec/suites/SpecHelper.js +28 -0
  45. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/Control.Draw.js +9 -9
  46. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/Leaflet.draw.js +1 -2
  47. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/Toolbar.js +0 -0
  48. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/Tooltip.js +0 -0
  49. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/copyright.js +0 -0
  50. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/draw/DrawToolbar.js +0 -4
  51. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/draw/handler/Draw.Circle.js +1 -1
  52. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/draw/handler/Draw.Feature.js +2 -2
  53. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/draw/handler/Draw.Marker.js +0 -0
  54. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/draw/handler/Draw.Polygon.js +0 -0
  55. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/draw/handler/Draw.Polyline.js +0 -0
  56. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/draw/handler/Draw.Rectangle.js +1 -19
  57. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/draw/handler/Draw.SimpleShape.js +1 -7
  58. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/edit/EditToolbar.js +2 -9
  59. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/edit/handler/Edit.Circle.js +0 -0
  60. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/edit/handler/Edit.Poly.js +2 -14
  61. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/edit/handler/Edit.Rectangle.js +0 -0
  62. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/edit/handler/Edit.SimpleShape.js +3 -11
  63. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/edit/handler/EditToolbar.Delete.js +1 -4
  64. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/edit/handler/EditToolbar.Edit.js +83 -17
  65. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/ext/GeometryUtil.js +1 -1
  66. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/ext/LatLngUtil.js +0 -0
  67. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/ext/LineUtil.Intersect.js +0 -0
  68. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/ext/Polygon.Intersect.js +0 -0
  69. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/ext/Polyline.Intersect.js +0 -0
  70. data/{vendor/assets/Leaflet.draw → lib/leaflet.draw}/src/images/spritesheet.svg +0 -0
  71. data/lib/leaflet.label/CHANGELOG.md +67 -0
  72. data/lib/leaflet.label/Jakefile.js +21 -0
  73. data/lib/leaflet.label/MIT-LICENCE.txt +20 -0
  74. data/lib/leaflet.label/README.md +103 -0
  75. data/lib/leaflet.label/build/build.js +155 -0
  76. data/lib/leaflet.label/build/deps.js +26 -0
  77. data/lib/leaflet.label/build/hint.js +30 -0
  78. data/lib/leaflet.label/build/hintrc.js +51 -0
  79. data/lib/leaflet.label/dist/images/death.png +0 -0
  80. data/lib/leaflet.label/dist/leaflet.label-src.js +542 -0
  81. data/{vendor/assets → lib/leaflet.label/dist}/leaflet.label.css +0 -0
  82. data/lib/leaflet.label/dist/leaflet.label.js +9 -0
  83. data/lib/leaflet.label/example/label.html +85 -0
  84. data/lib/leaflet.label/libs/leaflet/images/layers-2x.png +0 -0
  85. data/lib/leaflet.label/libs/leaflet/images/layers.png +0 -0
  86. data/lib/leaflet.label/libs/leaflet/images/marker-icon-2x.png +0 -0
  87. data/lib/leaflet.label/libs/leaflet/images/marker-icon.png +0 -0
  88. data/lib/leaflet.label/libs/leaflet/images/marker-icon@2x.png +0 -0
  89. data/lib/leaflet.label/libs/leaflet/images/marker-shadow.png +0 -0
  90. data/lib/leaflet.label/libs/leaflet/leaflet-src.js +9108 -0
  91. data/lib/leaflet.label/libs/leaflet/leaflet.css +478 -0
  92. data/lib/leaflet.label/libs/leaflet/leaflet.js +9 -0
  93. data/lib/leaflet.label/package.json +19 -0
  94. data/{vendor/assets/Leaflet.label → lib/leaflet.label}/src/BaseMarkerMethods.js +0 -0
  95. data/{vendor/assets/Leaflet.label → lib/leaflet.label}/src/CircleMarker.Label.js +0 -0
  96. data/{vendor/assets/Leaflet.label → lib/leaflet.label}/src/FeatureGroup.Label.js +0 -0
  97. data/{vendor/assets/Leaflet.label → lib/leaflet.label}/src/Label.js +2 -5
  98. data/{vendor/assets/Leaflet.label → lib/leaflet.label}/src/Leaflet.label.js +1 -1
  99. data/{vendor/assets/Leaflet.label → lib/leaflet.label}/src/Map.Label.js +0 -0
  100. data/{vendor/assets/Leaflet.label → lib/leaflet.label}/src/Marker.Label.js +0 -0
  101. data/{vendor/assets/Leaflet.label → lib/leaflet.label}/src/Path.Label.js +0 -0
  102. data/{vendor/assets/Leaflet.label → lib/leaflet.label}/src/copyright.js +0 -0
  103. data/lib/leaflet/CHANGELOG.md +1007 -0
  104. data/lib/leaflet/CONTRIBUTING.md +155 -0
  105. data/lib/leaflet/FAQ.md +138 -0
  106. data/lib/leaflet/Jakefile.js +56 -0
  107. data/lib/leaflet/LICENSE +23 -0
  108. data/lib/leaflet/PLUGIN-GUIDE.md +127 -0
  109. data/lib/leaflet/README.md +34 -0
  110. data/lib/leaflet/build/build.html +227 -0
  111. data/lib/leaflet/build/build.js +190 -0
  112. data/lib/leaflet/build/deps.js +258 -0
  113. data/lib/leaflet/build/hintrc.js +40 -0
  114. data/lib/leaflet/debug/css/mobile.css +6 -0
  115. data/lib/leaflet/debug/css/screen.css +5 -0
  116. data/lib/leaflet/debug/hacks/jitter.html +42 -0
  117. data/lib/leaflet/debug/leaflet-include.js +59 -0
  118. data/lib/leaflet/debug/map/canvas.html +49 -0
  119. data/lib/leaflet/debug/map/controls.html +49 -0
  120. data/lib/leaflet/debug/map/geolocation.html +34 -0
  121. data/lib/leaflet/debug/map/grid.html +45 -0
  122. data/lib/leaflet/debug/map/iframe.html +11 -0
  123. data/lib/leaflet/debug/map/image-overlay.html +43 -0
  124. data/lib/leaflet/debug/map/map-mobile.html +34 -0
  125. data/lib/leaflet/debug/map/map.html +61 -0
  126. data/lib/leaflet/debug/map/max-bounds.html +38 -0
  127. data/lib/leaflet/debug/map/opacity.html +223 -0
  128. data/lib/leaflet/debug/map/scroll.html +41 -0
  129. data/lib/leaflet/debug/map/simple-proj.html +59 -0
  130. data/lib/leaflet/debug/map/wms-marble.html +30 -0
  131. data/lib/leaflet/debug/map/wms.html +40 -0
  132. data/lib/leaflet/debug/map/zoomlevels.html +45 -0
  133. data/lib/leaflet/debug/tests/add_remove_layers.html +87 -0
  134. data/lib/leaflet/debug/tests/bringtoback.html +37 -0
  135. data/lib/leaflet/debug/tests/canvasloop.html +47 -0
  136. data/lib/leaflet/debug/tests/click_on_canvas.html +58 -0
  137. data/lib/leaflet/debug/tests/click_on_canvas_broken.html +49 -0
  138. data/lib/leaflet/debug/tests/dragging_and_copyworldjump.html +61 -0
  139. data/lib/leaflet/debug/tests/opacity.html +56 -0
  140. data/lib/leaflet/debug/tests/popupcontextmenuclicks.html +59 -0
  141. data/lib/leaflet/debug/tests/remove_while_dragging.html +28 -0
  142. data/lib/leaflet/debug/tests/removetilewhilepan.html +41 -0
  143. data/lib/leaflet/debug/tests/reuse_popups.html +40 -0
  144. data/lib/leaflet/debug/tests/rtl.html +42 -0
  145. data/lib/leaflet/debug/tests/rtl2.html +27 -0
  146. data/lib/leaflet/debug/tests/set_icon_reuse_dom.html +43 -0
  147. data/lib/leaflet/debug/tests/svg_clicks.html +54 -0
  148. data/lib/leaflet/debug/vector/bounds-extend.html +88 -0
  149. data/lib/leaflet/debug/vector/feature-group-bounds.html +90 -0
  150. data/lib/leaflet/debug/vector/geojson-sample.js +53 -0
  151. data/lib/leaflet/debug/vector/geojson.html +173 -0
  152. data/lib/leaflet/debug/vector/rectangle.html +53 -0
  153. data/lib/leaflet/debug/vector/route.js +1 -0
  154. data/lib/leaflet/debug/vector/touchzoomemu.html +194 -0
  155. data/lib/leaflet/debug/vector/us-states.js +54 -0
  156. data/lib/leaflet/debug/vector/vector-bounds.html +69 -0
  157. data/lib/leaflet/debug/vector/vector-canvas.html +92 -0
  158. data/lib/leaflet/debug/vector/vector-mobile.html +38 -0
  159. data/lib/leaflet/debug/vector/vector-simple.html +47 -0
  160. data/lib/leaflet/debug/vector/vector.html +37 -0
  161. data/lib/leaflet/debug/vector/vector2.html +58 -0
  162. data/lib/leaflet/dist/images/layers-2x.png +0 -0
  163. data/lib/leaflet/dist/images/layers.png +0 -0
  164. data/lib/leaflet/dist/images/marker-icon-2x.png +0 -0
  165. data/lib/leaflet/dist/images/marker-icon.png +0 -0
  166. data/lib/leaflet/dist/images/marker-shadow.png +0 -0
  167. data/lib/leaflet/dist/leaflet.css +494 -0
  168. data/lib/leaflet/package.json +28 -0
  169. data/lib/leaflet/spec/after.js +2 -0
  170. data/lib/leaflet/spec/expect.js +1253 -0
  171. data/lib/leaflet/spec/index.html +87 -0
  172. data/lib/leaflet/spec/karma.conf.js +68 -0
  173. data/lib/leaflet/spec/sinon.js +4223 -0
  174. data/lib/leaflet/spec/spec.hintrc.js +25 -0
  175. data/lib/leaflet/spec/suites/SpecHelper.js +42 -0
  176. data/lib/leaflet/spec/suites/control/Control.AttributionSpec.js +68 -0
  177. data/lib/leaflet/spec/suites/control/Control.LayersSpec.js +67 -0
  178. data/lib/leaflet/spec/suites/control/Control.ScaleSpec.js +6 -0
  179. data/lib/leaflet/spec/suites/core/ClassSpec.js +166 -0
  180. data/lib/leaflet/spec/suites/core/EventsSpec.js +416 -0
  181. data/lib/leaflet/spec/suites/core/UtilSpec.js +237 -0
  182. data/lib/leaflet/spec/suites/dom/DomEventSpec.js +102 -0
  183. data/lib/leaflet/spec/suites/dom/DomUtilSpec.js +59 -0
  184. data/lib/leaflet/spec/suites/dom/PosAnimationSpec.js +27 -0
  185. data/lib/leaflet/spec/suites/geo/CRSSpec.js +151 -0
  186. data/lib/leaflet/spec/suites/geo/LatLngBoundsSpec.js +144 -0
  187. data/lib/leaflet/spec/suites/geo/LatLngSpec.js +102 -0
  188. data/lib/leaflet/spec/suites/geo/ProjectionSpec.js +96 -0
  189. data/lib/leaflet/spec/suites/geometry/BoundsSpec.js +87 -0
  190. data/lib/leaflet/spec/suites/geometry/LineUtilSpec.js +75 -0
  191. data/lib/leaflet/spec/suites/geometry/PointSpec.js +104 -0
  192. data/lib/leaflet/spec/suites/geometry/PolyUtilSpec.js +27 -0
  193. data/lib/leaflet/spec/suites/geometry/TransformationSpec.js +31 -0
  194. data/lib/leaflet/spec/suites/layer/FeatureGroupSpec.js +86 -0
  195. data/lib/leaflet/spec/suites/layer/GeoJSONSpec.js +282 -0
  196. data/lib/leaflet/spec/suites/layer/LayerGroupSpec.js +71 -0
  197. data/lib/leaflet/spec/suites/layer/PopupSpec.js +119 -0
  198. data/lib/leaflet/spec/suites/layer/marker/MarkerSpec.js +117 -0
  199. data/lib/leaflet/spec/suites/layer/tile/GridLayerSpec.js +70 -0
  200. data/lib/leaflet/spec/suites/layer/tile/TileLayerSpec.js +88 -0
  201. data/lib/leaflet/spec/suites/layer/vector/CircleMarkerSpec.js +53 -0
  202. data/lib/leaflet/spec/suites/layer/vector/CircleSpec.js +18 -0
  203. data/lib/leaflet/spec/suites/layer/vector/PolygonSpec.js +96 -0
  204. data/lib/leaflet/spec/suites/layer/vector/PolylineGeometrySpec.js +35 -0
  205. data/lib/leaflet/spec/suites/layer/vector/PolylineSpec.js +55 -0
  206. data/lib/leaflet/spec/suites/map/MapSpec.js +553 -0
  207. data/lib/leaflet/spec/suites/map/handler/Map.DragSpec.js +38 -0
  208. data/{vendor/assets/Leaflet → lib/leaflet}/src/Leaflet.js +16 -11
  209. data/{vendor/assets/Leaflet → lib/leaflet}/src/control/Control.Attribution.js +1 -23
  210. data/{vendor/assets/Leaflet → lib/leaflet}/src/control/Control.Layers.js +42 -57
  211. data/lib/leaflet/src/control/Control.Scale.js +102 -0
  212. data/{vendor/assets/Leaflet → lib/leaflet}/src/control/Control.Zoom.js +11 -18
  213. data/{vendor/assets/Leaflet → lib/leaflet}/src/control/Control.js +7 -9
  214. data/lib/leaflet/src/copyright.js +4 -0
  215. data/lib/leaflet/src/core/Browser.js +65 -0
  216. data/{vendor/assets/Leaflet → lib/leaflet}/src/core/Class.js +8 -13
  217. data/lib/leaflet/src/core/Events.js +226 -0
  218. data/{vendor/assets/Leaflet → lib/leaflet}/src/core/Handler.js +0 -0
  219. data/lib/leaflet/src/core/Util.js +196 -0
  220. data/{vendor/assets/Leaflet → lib/leaflet}/src/dom/DomEvent.DoubleTap.js +20 -27
  221. data/lib/leaflet/src/dom/DomEvent.Pointer.js +107 -0
  222. data/{vendor/assets/Leaflet → lib/leaflet}/src/dom/DomEvent.js +70 -59
  223. data/lib/leaflet/src/dom/DomUtil.js +213 -0
  224. data/{vendor/assets/Leaflet → lib/leaflet}/src/dom/Draggable.js +10 -19
  225. data/{vendor/assets/Leaflet → lib/leaflet}/src/dom/PosAnimation.Timer.js +0 -0
  226. data/{vendor/assets/Leaflet → lib/leaflet}/src/dom/PosAnimation.js +4 -3
  227. data/lib/leaflet/src/geo/LatLng.js +67 -0
  228. data/{vendor/assets/Leaflet → lib/leaflet}/src/geo/LatLngBounds.js +0 -0
  229. data/lib/leaflet/src/geo/crs/CRS.EPSG3395.js +13 -0
  230. data/lib/leaflet/src/geo/crs/CRS.EPSG3857.js +17 -0
  231. data/{vendor/assets/Leaflet → lib/leaflet}/src/geo/crs/CRS.EPSG4326.js +2 -3
  232. data/lib/leaflet/src/geo/crs/CRS.Earth.js +19 -0
  233. data/{vendor/assets/Leaflet → lib/leaflet}/src/geo/crs/CRS.Simple.js +10 -1
  234. data/lib/leaflet/src/geo/crs/CRS.js +63 -0
  235. data/{vendor/assets/Leaflet → lib/leaflet}/src/geo/projection/Projection.LonLat.js +5 -1
  236. data/lib/leaflet/src/geo/projection/Projection.Mercator.js +43 -0
  237. data/lib/leaflet/src/geo/projection/Projection.SphericalMercator.js +31 -0
  238. data/{vendor/assets/Leaflet → lib/leaflet}/src/geometry/Bounds.js +0 -0
  239. data/{vendor/assets/Leaflet → lib/leaflet}/src/geometry/LineUtil.js +16 -5
  240. data/{vendor/assets/Leaflet → lib/leaflet}/src/geometry/Point.js +10 -0
  241. data/{vendor/assets/Leaflet → lib/leaflet}/src/geometry/PolyUtil.js +0 -0
  242. data/{vendor/assets/Leaflet → lib/leaflet}/src/geometry/Transformation.js +0 -0
  243. data/{vendor/assets/Leaflet → lib/leaflet}/src/images/layers.svg +0 -0
  244. data/lib/leaflet/src/images/logo.svg +85 -0
  245. data/{vendor/assets/Leaflet → lib/leaflet}/src/images/marker.svg +0 -0
  246. data/{vendor/assets/Leaflet → lib/leaflet}/src/layer/FeatureGroup.js +3 -20
  247. data/lib/leaflet/src/layer/GeoJSON.js +275 -0
  248. data/lib/leaflet/src/layer/ImageOverlay.js +123 -0
  249. data/lib/leaflet/src/layer/Layer.Popup.js +87 -0
  250. data/lib/leaflet/src/layer/Layer.js +150 -0
  251. data/{vendor/assets/Leaflet → lib/leaflet}/src/layer/LayerGroup.js +12 -14
  252. data/{vendor/assets/Leaflet → lib/leaflet}/src/layer/Popup.js +65 -83
  253. data/{vendor/assets/Leaflet → lib/leaflet}/src/layer/marker/DivIcon.js +3 -8
  254. data/{vendor/assets/Leaflet → lib/leaflet}/src/layer/marker/Icon.Default.js +6 -12
  255. data/{vendor/assets/Leaflet → lib/leaflet}/src/layer/marker/Icon.js +8 -25
  256. data/{vendor/assets/Leaflet → lib/leaflet}/src/layer/marker/Marker.Drag.js +13 -11
  257. data/lib/leaflet/src/layer/marker/Marker.Popup.js +16 -0
  258. data/{vendor/assets/Leaflet → lib/leaflet}/src/layer/marker/Marker.js +52 -103
  259. data/lib/leaflet/src/layer/tile/GridLayer.js +536 -0
  260. data/lib/leaflet/src/layer/tile/TileLayer.WMS.js +79 -0
  261. data/lib/leaflet/src/layer/tile/TileLayer.js +148 -0
  262. data/lib/leaflet/src/layer/vector/Canvas.js +292 -0
  263. data/lib/leaflet/src/layer/vector/Circle.js +67 -0
  264. data/lib/leaflet/src/layer/vector/CircleMarker.js +72 -0
  265. data/lib/leaflet/src/layer/vector/Path.js +79 -0
  266. data/lib/leaflet/src/layer/vector/Polygon.js +75 -0
  267. data/lib/leaflet/src/layer/vector/Polyline.js +223 -0
  268. data/{vendor/assets/Leaflet → lib/leaflet}/src/layer/vector/Rectangle.js +27 -27
  269. data/lib/leaflet/src/layer/vector/Renderer.js +75 -0
  270. data/lib/leaflet/src/layer/vector/SVG.VML.js +134 -0
  271. data/lib/leaflet/src/layer/vector/SVG.js +189 -0
  272. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/Map.js +83 -199
  273. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/anim/Map.PanAnimation.js +0 -0
  274. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/anim/Map.ZoomAnimation.js +30 -38
  275. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/ext/Map.Geolocation.js +8 -8
  276. data/lib/leaflet/src/map/handler/Map.BoxZoom.js +105 -0
  277. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/handler/Map.DoubleClickZoom.js +0 -0
  278. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/handler/Map.Drag.js +12 -10
  279. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/handler/Map.Keyboard.js +19 -17
  280. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/handler/Map.ScrollWheelZoom.js +10 -6
  281. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/handler/Map.Tap.js +8 -6
  282. data/{vendor/assets/Leaflet → lib/leaflet}/src/map/handler/Map.TouchZoom.js +16 -32
  283. data/vendor/assets/images/layers-2x.png +0 -0
  284. data/vendor/assets/images/layers.png +0 -0
  285. data/vendor/assets/images/marker-icon-2x.png +0 -0
  286. data/vendor/assets/images/marker-icon.png +0 -0
  287. data/vendor/assets/images/marker-shadow.png +0 -0
  288. data/vendor/assets/images/spritesheet-2x.png +0 -0
  289. data/vendor/assets/images/spritesheet.png +0 -0
  290. data/vendor/assets/{leaflet-js.js → javascripts/leaflet-js.js} +2 -2
  291. data/vendor/assets/javascripts/leaflet.draw.js +37 -0
  292. data/vendor/assets/javascripts/leaflet.js +149 -0
  293. data/vendor/assets/javascripts/leaflet.label.js +11 -0
  294. data/vendor/assets/{leaflet-js.css → stylesheets/leaflet-js.css} +0 -0
  295. data/vendor/assets/stylesheets/leaflet.css.erb +478 -0
  296. data/vendor/assets/{leaflet.draw.css.erb → stylesheets/leaflet.draw.css.erb} +2 -2
  297. data/vendor/assets/{leaflet.draw.ie.css → stylesheets/leaflet.draw.ie.css} +0 -0
  298. data/vendor/assets/stylesheets/leaflet.label.css +52 -0
  299. metadata +298 -137
  300. data/lib/leaflet-js/engine.rb +0 -7
  301. data/lib/leaflet-js/version.rb +0 -3
  302. data/vendor/assets/Leaflet.draw/src/edit/handler/Edit.Marker.js +0 -75
  303. data/vendor/assets/Leaflet/src/control/Control.Scale.js +0 -112
  304. data/vendor/assets/Leaflet/src/copyright.js +0 -5
  305. data/vendor/assets/Leaflet/src/core/Browser.js +0 -66
  306. data/vendor/assets/Leaflet/src/core/Events.js +0 -178
  307. data/vendor/assets/Leaflet/src/core/Util.js +0 -182
  308. data/vendor/assets/Leaflet/src/dom/DomEvent.Pointer.js +0 -156
  309. data/vendor/assets/Leaflet/src/dom/DomUtil.js +0 -289
  310. data/vendor/assets/Leaflet/src/geo/LatLng.js +0 -99
  311. data/vendor/assets/Leaflet/src/geo/crs/CRS.EPSG3395.js +0 -14
  312. data/vendor/assets/Leaflet/src/geo/crs/CRS.EPSG3857.js +0 -21
  313. data/vendor/assets/Leaflet/src/geo/crs/CRS.js +0 -32
  314. data/vendor/assets/Leaflet/src/geo/projection/Projection.Mercator.js +0 -56
  315. data/vendor/assets/Leaflet/src/geo/projection/Projection.SphericalMercator.js +0 -27
  316. data/vendor/assets/Leaflet/src/geo/projection/Projection.js +0 -5
  317. data/vendor/assets/Leaflet/src/layer/GeoJSON.js +0 -286
  318. data/vendor/assets/Leaflet/src/layer/ImageOverlay.js +0 -141
  319. data/vendor/assets/Leaflet/src/layer/marker/Marker.Popup.js +0 -90
  320. data/vendor/assets/Leaflet/src/layer/tile/TileLayer.Anim.js +0 -110
  321. data/vendor/assets/Leaflet/src/layer/tile/TileLayer.Canvas.js +0 -61
  322. data/vendor/assets/Leaflet/src/layer/tile/TileLayer.WMS.js +0 -87
  323. data/vendor/assets/Leaflet/src/layer/tile/TileLayer.js +0 -597
  324. data/vendor/assets/Leaflet/src/layer/vector/Circle.js +0 -98
  325. data/vendor/assets/Leaflet/src/layer/vector/CircleMarker.js +0 -45
  326. data/vendor/assets/Leaflet/src/layer/vector/MultiPoly.js +0 -57
  327. data/vendor/assets/Leaflet/src/layer/vector/Path.Popup.js +0 -65
  328. data/vendor/assets/Leaflet/src/layer/vector/Path.SVG.js +0 -230
  329. data/vendor/assets/Leaflet/src/layer/vector/Path.VML.js +0 -135
  330. data/vendor/assets/Leaflet/src/layer/vector/Path.js +0 -119
  331. data/vendor/assets/Leaflet/src/layer/vector/Polygon.js +0 -92
  332. data/vendor/assets/Leaflet/src/layer/vector/Polyline.js +0 -164
  333. data/vendor/assets/Leaflet/src/layer/vector/canvas/Circle.Canvas.js +0 -18
  334. data/vendor/assets/Leaflet/src/layer/vector/canvas/CircleMarker.Canvas.js +0 -9
  335. data/vendor/assets/Leaflet/src/layer/vector/canvas/Path.Canvas.js +0 -204
  336. data/vendor/assets/Leaflet/src/layer/vector/canvas/Polygon.Canvas.js +0 -37
  337. data/vendor/assets/Leaflet/src/layer/vector/canvas/Polyline.Canvas.js +0 -30
  338. data/vendor/assets/Leaflet/src/map/handler/Map.BoxZoom.js +0 -118
  339. data/vendor/assets/leaflet.draw.js +0 -38
  340. data/vendor/assets/leaflet.js +0 -155
  341. data/vendor/assets/leaflet.label.js +0 -11
@@ -0,0 +1,76 @@
1
+ var deps = {
2
+ Core: {
3
+ src: [
4
+ 'Leaflet.draw.js'
5
+ ],
6
+ desc: 'The core of the plugin. Currently only includes the version.'
7
+ },
8
+
9
+ DrawHandlers: {
10
+ src: [
11
+ 'draw/handler/Draw.Feature.js',
12
+ 'draw/handler/Draw.Polyline.js',
13
+ 'draw/handler/Draw.Polygon.js',
14
+ 'draw/handler/Draw.SimpleShape.js',
15
+ 'draw/handler/Draw.Rectangle.js',
16
+ 'draw/handler/Draw.Circle.js',
17
+ 'draw/handler/Draw.Marker.js'
18
+ ],
19
+ desc: 'Drawing handlers for: polylines, polygons, rectangles, circles and markers.',
20
+ deps: ['Core']
21
+ },
22
+
23
+ EditHandlers: {
24
+ src: [
25
+ 'edit/handler/Edit.Poly.js',
26
+ 'edit/handler/Edit.SimpleShape.js',
27
+ 'edit/handler/Edit.Rectangle.js',
28
+ 'edit/handler/Edit.Circle.js'
29
+ ],
30
+ desc: 'Editing handlers for: polylines, polygons, rectangles, and circles.',
31
+ deps: ['Core']
32
+ },
33
+
34
+ Extensions: {
35
+ src: [
36
+ 'ext/LatLngUtil.js',
37
+ 'ext/GeometryUtil.js',
38
+ 'ext/LineUtil.Intersect.js',
39
+ 'ext/Polyline.Intersect.js',
40
+ 'ext/Polygon.Intersect.js'
41
+ ],
42
+ desc: 'Extensions of leaflet classes.'
43
+ },
44
+
45
+ CommonUI: {
46
+ src: [
47
+ 'Control.Draw.js',
48
+ 'Toolbar.js',
49
+ 'Tooltip.js'
50
+ ],
51
+ desc: 'Common UI components used.',
52
+ deps: ['Extensions']
53
+ },
54
+
55
+ DrawUI: {
56
+ src: [
57
+ 'draw/DrawToolbar.js'
58
+ ],
59
+ desc: 'Draw toolbar.',
60
+ deps: ['DrawHandlers', 'CommonUI']
61
+ },
62
+
63
+ EditUI: {
64
+ src: [
65
+ 'edit/EditToolbar.js',
66
+ 'edit/handler/EditToolbar.Edit.js',
67
+ 'edit/handler/EditToolbar.Delete.js'
68
+ ],
69
+ desc: 'Edit toolbar.',
70
+ deps: ['EditHandlers', 'CommonUI']
71
+ }
72
+ };
73
+
74
+ if (typeof exports !== 'undefined') {
75
+ exports.deps = deps;
76
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ // environment
3
+ "browser": true,
4
+ "node": true,
5
+ "globals": {
6
+ "L": true,
7
+ "define": true
8
+ },
9
+ "strict": false,
10
+
11
+ // code style
12
+ "bitwise": true,
13
+ "camelcase": true,
14
+ "curly": true,
15
+ "eqeqeq": true,
16
+ "forin": false,
17
+ "immed": true,
18
+ "latedef": true,
19
+ "newcap": true,
20
+ "noarg": true,
21
+ "noempty": true,
22
+ "nonew": true,
23
+ "undef": true,
24
+ "unused": true,
25
+ "quotmark": "single",
26
+
27
+ // whitespace
28
+ "indent": 4,
29
+ "trailing": true,
30
+ "white": true,
31
+ "smarttabs": true,
32
+ "maxlen": 150
33
+
34
+ // code simplicity - not enforced but nice to check from time to time
35
+ // "maxstatements": 20,
36
+ // "maxcomplexity": 5
37
+ // "maxparams": 4,
38
+ // "maxdepth": 4
39
+ }
@@ -0,0 +1,42 @@
1
+ (function() {
2
+ function getFiles() {
3
+ var memo = {},
4
+ files = [],
5
+ i, src;
6
+
7
+ function addFiles(srcs) {
8
+ for (var j = 0, len = srcs.length; j < len; j++) {
9
+ memo[srcs[j]] = true;
10
+ }
11
+ }
12
+
13
+ for (i in deps) {
14
+ addFiles(deps[i].src);
15
+ }
16
+
17
+ for (src in memo) {
18
+ files.push(src);
19
+ }
20
+
21
+ return files;
22
+ }
23
+ var scripts = getFiles();
24
+
25
+ function getSrcUrl() {
26
+ var scripts = document.getElementsByTagName('script');
27
+ for (var i = 0; i < scripts.length; i++) {
28
+ var src = scripts[i].src;
29
+ if (src) {
30
+ var res = src.match(/^(.*)leaflet.draw-include\.js$/);
31
+ if (res) {
32
+ return res[1] + '../src/';
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ var path = getSrcUrl();
39
+ for (var i = 0; i < scripts.length; i++) {
40
+ document.writeln("<script src='" + path + scripts[i] + "'></script>");
41
+ }
42
+ })();
@@ -0,0 +1,2872 @@
1
+ /*
2
+ Leaflet.draw, a plugin that adds drawing and editing tools to Leaflet powered maps.
3
+ (c) 2012-2013, Jacob Toye, Smartrak
4
+
5
+ https://github.com/Leaflet/Leaflet.draw
6
+ http://leafletjs.com
7
+ https://github.com/jacobtoye
8
+ */
9
+ (function (window, document, undefined) {/*
10
+ * Leaflet.draw assumes that you have already included the Leaflet library.
11
+ */
12
+
13
+ L.drawVersion = '0.2.4-dev';
14
+
15
+ L.drawLocal = {
16
+ draw: {
17
+ toolbar: {
18
+ actions: {
19
+ title: 'Cancel drawing',
20
+ text: 'Cancel'
21
+ },
22
+ undo: {
23
+ title: 'Delete last point drawn',
24
+ text: 'Delete last point'
25
+ },
26
+ buttons: {
27
+ polyline: 'Draw a polyline',
28
+ polygon: 'Draw a polygon',
29
+ rectangle: 'Draw a rectangle',
30
+ circle: 'Draw a circle',
31
+ marker: 'Draw a marker'
32
+ }
33
+ },
34
+ handlers: {
35
+ circle: {
36
+ tooltip: {
37
+ start: 'Click and drag to draw circle.'
38
+ }
39
+ },
40
+ marker: {
41
+ tooltip: {
42
+ start: 'Click map to place marker.'
43
+ }
44
+ },
45
+ polygon: {
46
+ tooltip: {
47
+ start: 'Click to start drawing shape.',
48
+ cont: 'Click to continue drawing shape.',
49
+ end: 'Click first point to close this shape.'
50
+ }
51
+ },
52
+ polyline: {
53
+ error: '<strong>Error:</strong> shape edges cannot cross!',
54
+ tooltip: {
55
+ start: 'Click to start drawing line.',
56
+ cont: 'Click to continue drawing line.',
57
+ end: 'Click last point to finish line.'
58
+ }
59
+ },
60
+ rectangle: {
61
+ tooltip: {
62
+ start: 'Click and drag to draw rectangle.'
63
+ }
64
+ },
65
+ simpleshape: {
66
+ tooltip: {
67
+ end: 'Release mouse to finish drawing.'
68
+ }
69
+ }
70
+ }
71
+ },
72
+ edit: {
73
+ toolbar: {
74
+ actions: {
75
+ save: {
76
+ title: 'Save changes.',
77
+ text: 'Save'
78
+ },
79
+ cancel: {
80
+ title: 'Cancel editing, discards all changes.',
81
+ text: 'Cancel'
82
+ }
83
+ },
84
+ buttons: {
85
+ edit: 'Edit layers.',
86
+ editDisabled: 'No layers to edit.',
87
+ remove: 'Delete layers.',
88
+ removeDisabled: 'No layers to delete.'
89
+ }
90
+ },
91
+ handlers: {
92
+ edit: {
93
+ tooltip: {
94
+ text: 'Drag handles, or marker to edit feature.',
95
+ subtext: 'Click cancel to undo changes.'
96
+ }
97
+ },
98
+ remove: {
99
+ tooltip: {
100
+ text: 'Click on a feature to remove'
101
+ }
102
+ }
103
+ }
104
+ }
105
+ };
106
+
107
+
108
+ L.Draw = {};
109
+
110
+ L.Draw.Feature = L.Handler.extend({
111
+ includes: L.Mixin.Events,
112
+
113
+ initialize: function (map, options) {
114
+ this._map = map;
115
+ this._container = map._container;
116
+ this._overlayPane = map._panes.overlayPane;
117
+ this._popupPane = map._panes.popupPane;
118
+
119
+ // Merge default shapeOptions options with custom shapeOptions
120
+ if (options && options.shapeOptions) {
121
+ options.shapeOptions = L.Util.extend({}, this.options.shapeOptions, options.shapeOptions);
122
+ }
123
+ L.setOptions(this, options);
124
+ },
125
+
126
+ enable: function () {
127
+ if (this._enabled) { return; }
128
+
129
+ this.fire('enabled', { handler: this.type });
130
+
131
+ this._map.fire('draw:drawstart', { layerType: this.type });
132
+
133
+ L.Handler.prototype.enable.call(this);
134
+ },
135
+
136
+ disable: function () {
137
+ if (!this._enabled) { return; }
138
+
139
+ L.Handler.prototype.disable.call(this);
140
+
141
+ this._map.fire('draw:drawstop', { layerType: this.type });
142
+
143
+ this.fire('disabled', { handler: this.type });
144
+ },
145
+
146
+ addHooks: function () {
147
+ var map = this._map;
148
+
149
+ if (map) {
150
+ L.DomUtil.disableTextSelection();
151
+
152
+ map.getContainer().focus();
153
+
154
+ this._tooltip = new L.Tooltip(this._map);
155
+
156
+ L.DomEvent.on(this._container, 'keyup', this._cancelDrawing, this);
157
+ }
158
+ },
159
+
160
+ removeHooks: function () {
161
+ if (this._map) {
162
+ L.DomUtil.enableTextSelection();
163
+
164
+ this._tooltip.dispose();
165
+ this._tooltip = null;
166
+
167
+ L.DomEvent.off(this._container, 'keyup', this._cancelDrawing, this);
168
+ }
169
+ },
170
+
171
+ setOptions: function (options) {
172
+ L.setOptions(this, options);
173
+ },
174
+
175
+ _fireCreatedEvent: function (layer) {
176
+ this._map.fire('draw:created', { layer: layer, layerType: this.type });
177
+ },
178
+
179
+ // Cancel drawing when the escape key is pressed
180
+ _cancelDrawing: function (e) {
181
+ if (e.keyCode === 27) {
182
+ this.disable();
183
+ }
184
+ }
185
+ });
186
+
187
+ L.Draw.Polyline = L.Draw.Feature.extend({
188
+ statics: {
189
+ TYPE: 'polyline'
190
+ },
191
+
192
+ Poly: L.Polyline,
193
+
194
+ options: {
195
+ allowIntersection: true,
196
+ repeatMode: false,
197
+ drawError: {
198
+ color: '#b00b00',
199
+ timeout: 2500
200
+ },
201
+ icon: new L.DivIcon({
202
+ iconSize: new L.Point(8, 8),
203
+ className: 'leaflet-div-icon leaflet-editing-icon'
204
+ }),
205
+ guidelineDistance: 20,
206
+ maxGuideLineLength: 4000,
207
+ shapeOptions: {
208
+ stroke: true,
209
+ color: '#f06eaa',
210
+ weight: 4,
211
+ opacity: 0.5,
212
+ fill: false,
213
+ clickable: true
214
+ },
215
+ metric: true, // Whether to use the metric meaurement system or imperial
216
+ showLength: true, // Whether to display distance in the tooltip
217
+ zIndexOffset: 2000 // This should be > than the highest z-index any map layers
218
+ },
219
+
220
+ initialize: function (map, options) {
221
+ // Need to set this here to ensure the correct message is used.
222
+ this.options.drawError.message = L.drawLocal.draw.handlers.polyline.error;
223
+
224
+ // Merge default drawError options with custom options
225
+ if (options && options.drawError) {
226
+ options.drawError = L.Util.extend({}, this.options.drawError, options.drawError);
227
+ }
228
+
229
+ // Save the type so super can fire, need to do this as cannot do this.TYPE :(
230
+ this.type = L.Draw.Polyline.TYPE;
231
+
232
+ L.Draw.Feature.prototype.initialize.call(this, map, options);
233
+ },
234
+
235
+ addHooks: function () {
236
+ L.Draw.Feature.prototype.addHooks.call(this);
237
+ if (this._map) {
238
+ this._markers = [];
239
+
240
+ this._markerGroup = new L.LayerGroup();
241
+ this._map.addLayer(this._markerGroup);
242
+
243
+ this._poly = new L.Polyline([], this.options.shapeOptions);
244
+
245
+ this._tooltip.updateContent(this._getTooltipText());
246
+
247
+ // Make a transparent marker that will used to catch click events. These click
248
+ // events will create the vertices. We need to do this so we can ensure that
249
+ // we can create vertices over other map layers (markers, vector layers). We
250
+ // also do not want to trigger any click handlers of objects we are clicking on
251
+ // while drawing.
252
+ if (!this._mouseMarker) {
253
+ this._mouseMarker = L.marker(this._map.getCenter(), {
254
+ icon: L.divIcon({
255
+ className: 'leaflet-mouse-marker',
256
+ iconAnchor: [20, 20],
257
+ iconSize: [40, 40]
258
+ }),
259
+ opacity: 0,
260
+ zIndexOffset: this.options.zIndexOffset
261
+ });
262
+ }
263
+
264
+ this._mouseMarker
265
+ .on('mousedown', this._onMouseDown, this)
266
+ .addTo(this._map);
267
+
268
+ this._map
269
+ .on('mousemove', this._onMouseMove, this)
270
+ .on('mouseup', this._onMouseUp, this)
271
+ .on('zoomend', this._onZoomEnd, this);
272
+ }
273
+ },
274
+
275
+ removeHooks: function () {
276
+ L.Draw.Feature.prototype.removeHooks.call(this);
277
+
278
+ this._clearHideErrorTimeout();
279
+
280
+ this._cleanUpShape();
281
+
282
+ // remove markers from map
283
+ this._map.removeLayer(this._markerGroup);
284
+ delete this._markerGroup;
285
+ delete this._markers;
286
+
287
+ this._map.removeLayer(this._poly);
288
+ delete this._poly;
289
+
290
+ this._mouseMarker
291
+ .off('mousedown', this._onMouseDown, this)
292
+ .off('mouseup', this._onMouseUp, this);
293
+ this._map.removeLayer(this._mouseMarker);
294
+ delete this._mouseMarker;
295
+
296
+ // clean up DOM
297
+ this._clearGuides();
298
+
299
+ this._map
300
+ .off('mousemove', this._onMouseMove, this)
301
+ .off('zoomend', this._onZoomEnd, this);
302
+ },
303
+
304
+ deleteLastVertex: function () {
305
+ if (this._markers.length <= 1) {
306
+ return;
307
+ }
308
+
309
+ var lastMarker = this._markers.pop(),
310
+ poly = this._poly,
311
+ latlng = this._poly.spliceLatLngs(poly.getLatLngs().length - 1, 1)[0];
312
+
313
+ this._markerGroup.removeLayer(lastMarker);
314
+
315
+ if (poly.getLatLngs().length < 2) {
316
+ this._map.removeLayer(poly);
317
+ }
318
+
319
+ this._vertexChanged(latlng, false);
320
+ },
321
+
322
+ addVertex: function (latlng) {
323
+ var markersLength = this._markers.length;
324
+
325
+ if (markersLength > 0 && !this.options.allowIntersection && this._poly.newLatLngIntersects(latlng)) {
326
+ this._showErrorTooltip();
327
+ return;
328
+ }
329
+ else if (this._errorShown) {
330
+ this._hideErrorTooltip();
331
+ }
332
+
333
+ this._markers.push(this._createMarker(latlng));
334
+
335
+ this._poly.addLatLng(latlng);
336
+
337
+ if (this._poly.getLatLngs().length === 2) {
338
+ this._map.addLayer(this._poly);
339
+ }
340
+
341
+ this._vertexChanged(latlng, true);
342
+ },
343
+
344
+ _finishShape: function () {
345
+ var intersects = this._poly.newLatLngIntersects(this._poly.getLatLngs()[0], true);
346
+
347
+ if ((!this.options.allowIntersection && intersects) || !this._shapeIsValid()) {
348
+ this._showErrorTooltip();
349
+ return;
350
+ }
351
+
352
+ this._fireCreatedEvent();
353
+ this.disable();
354
+ if (this.options.repeatMode) {
355
+ this.enable();
356
+ }
357
+ },
358
+
359
+ //Called to verify the shape is valid when the user tries to finish it
360
+ //Return false if the shape is not valid
361
+ _shapeIsValid: function () {
362
+ return true;
363
+ },
364
+
365
+ _onZoomEnd: function () {
366
+ this._updateGuide();
367
+ },
368
+
369
+ _onMouseMove: function (e) {
370
+ var newPos = e.layerPoint,
371
+ latlng = e.latlng;
372
+
373
+ // Save latlng
374
+ // should this be moved to _updateGuide() ?
375
+ this._currentLatLng = latlng;
376
+
377
+ this._updateTooltip(latlng);
378
+
379
+ // Update the guide line
380
+ this._updateGuide(newPos);
381
+
382
+ // Update the mouse marker position
383
+ this._mouseMarker.setLatLng(latlng);
384
+
385
+ L.DomEvent.preventDefault(e.originalEvent);
386
+ },
387
+
388
+ _vertexChanged: function (latlng, added) {
389
+ this._updateFinishHandler();
390
+
391
+ this._updateRunningMeasure(latlng, added);
392
+
393
+ this._clearGuides();
394
+
395
+ this._updateTooltip();
396
+ },
397
+
398
+ _onMouseDown: function (e) {
399
+ var originalEvent = e.originalEvent;
400
+ this._mouseDownOrigin = L.point(originalEvent.clientX, originalEvent.clientY);
401
+ },
402
+
403
+ _onMouseUp: function (e) {
404
+ if (this._mouseDownOrigin) {
405
+ // We detect clicks within a certain tolerance, otherwise let it
406
+ // be interpreted as a drag by the map
407
+ var distance = L.point(e.originalEvent.clientX, e.originalEvent.clientY)
408
+ .distanceTo(this._mouseDownOrigin);
409
+ if (Math.abs(distance) < 9 * (window.devicePixelRatio || 1)) {
410
+ this.addVertex(e.latlng);
411
+ }
412
+ }
413
+ this._mouseDownOrigin = null;
414
+ },
415
+
416
+ _updateFinishHandler: function () {
417
+ var markerCount = this._markers.length;
418
+ // The last marker should have a click handler to close the polyline
419
+ if (markerCount > 1) {
420
+ this._markers[markerCount - 1].on('click', this._finishShape, this);
421
+ }
422
+
423
+ // Remove the old marker click handler (as only the last point should close the polyline)
424
+ if (markerCount > 2) {
425
+ this._markers[markerCount - 2].off('click', this._finishShape, this);
426
+ }
427
+ },
428
+
429
+ _createMarker: function (latlng) {
430
+ var marker = new L.Marker(latlng, {
431
+ icon: this.options.icon,
432
+ zIndexOffset: this.options.zIndexOffset * 2
433
+ });
434
+
435
+ this._markerGroup.addLayer(marker);
436
+
437
+ return marker;
438
+ },
439
+
440
+ _updateGuide: function (newPos) {
441
+ var markerCount = this._markers.length;
442
+
443
+ if (markerCount > 0) {
444
+ newPos = newPos || this._map.latLngToLayerPoint(this._currentLatLng);
445
+
446
+ // draw the guide line
447
+ this._clearGuides();
448
+ this._drawGuide(
449
+ this._map.latLngToLayerPoint(this._markers[markerCount - 1].getLatLng()),
450
+ newPos
451
+ );
452
+ }
453
+ },
454
+
455
+ _updateTooltip: function (latLng) {
456
+ var text = this._getTooltipText();
457
+
458
+ if (latLng) {
459
+ this._tooltip.updatePosition(latLng);
460
+ }
461
+
462
+ if (!this._errorShown) {
463
+ this._tooltip.updateContent(text);
464
+ }
465
+ },
466
+
467
+ _drawGuide: function (pointA, pointB) {
468
+ var length = Math.floor(Math.sqrt(Math.pow((pointB.x - pointA.x), 2) + Math.pow((pointB.y - pointA.y), 2))),
469
+ guidelineDistance = this.options.guidelineDistance,
470
+ maxGuideLineLength = this.options.maxGuideLineLength,
471
+ // Only draw a guideline with a max length
472
+ i = length > maxGuideLineLength ? length - maxGuideLineLength : guidelineDistance,
473
+ fraction,
474
+ dashPoint,
475
+ dash;
476
+
477
+ //create the guides container if we haven't yet
478
+ if (!this._guidesContainer) {
479
+ this._guidesContainer = L.DomUtil.create('div', 'leaflet-draw-guides', this._overlayPane);
480
+ }
481
+
482
+ //draw a dash every GuildeLineDistance
483
+ for (; i < length; i += this.options.guidelineDistance) {
484
+ //work out fraction along line we are
485
+ fraction = i / length;
486
+
487
+ //calculate new x,y point
488
+ dashPoint = {
489
+ x: Math.floor((pointA.x * (1 - fraction)) + (fraction * pointB.x)),
490
+ y: Math.floor((pointA.y * (1 - fraction)) + (fraction * pointB.y))
491
+ };
492
+
493
+ //add guide dash to guide container
494
+ dash = L.DomUtil.create('div', 'leaflet-draw-guide-dash', this._guidesContainer);
495
+ dash.style.backgroundColor =
496
+ !this._errorShown ? this.options.shapeOptions.color : this.options.drawError.color;
497
+
498
+ L.DomUtil.setPosition(dash, dashPoint);
499
+ }
500
+ },
501
+
502
+ _updateGuideColor: function (color) {
503
+ if (this._guidesContainer) {
504
+ for (var i = 0, l = this._guidesContainer.childNodes.length; i < l; i++) {
505
+ this._guidesContainer.childNodes[i].style.backgroundColor = color;
506
+ }
507
+ }
508
+ },
509
+
510
+ // removes all child elements (guide dashes) from the guides container
511
+ _clearGuides: function () {
512
+ if (this._guidesContainer) {
513
+ while (this._guidesContainer.firstChild) {
514
+ this._guidesContainer.removeChild(this._guidesContainer.firstChild);
515
+ }
516
+ }
517
+ },
518
+
519
+ _getTooltipText: function () {
520
+ var showLength = this.options.showLength,
521
+ labelText, distanceStr;
522
+
523
+ if (this._markers.length === 0) {
524
+ labelText = {
525
+ text: L.drawLocal.draw.handlers.polyline.tooltip.start
526
+ };
527
+ } else {
528
+ distanceStr = showLength ? this._getMeasurementString() : '';
529
+
530
+ if (this._markers.length === 1) {
531
+ labelText = {
532
+ text: L.drawLocal.draw.handlers.polyline.tooltip.cont,
533
+ subtext: distanceStr
534
+ };
535
+ } else {
536
+ labelText = {
537
+ text: L.drawLocal.draw.handlers.polyline.tooltip.end,
538
+ subtext: distanceStr
539
+ };
540
+ }
541
+ }
542
+ return labelText;
543
+ },
544
+
545
+ _updateRunningMeasure: function (latlng, added) {
546
+ var markersLength = this._markers.length,
547
+ previousMarkerIndex, distance;
548
+
549
+ if (this._markers.length === 1) {
550
+ this._measurementRunningTotal = 0;
551
+ } else {
552
+ previousMarkerIndex = markersLength - (added ? 2 : 1);
553
+ distance = latlng.distanceTo(this._markers[previousMarkerIndex].getLatLng());
554
+
555
+ this._measurementRunningTotal += distance * (added ? 1 : -1);
556
+ }
557
+ },
558
+
559
+ _getMeasurementString: function () {
560
+ var currentLatLng = this._currentLatLng,
561
+ previousLatLng = this._markers[this._markers.length - 1].getLatLng(),
562
+ distance;
563
+
564
+ // calculate the distance from the last fixed point to the mouse position
565
+ distance = this._measurementRunningTotal + currentLatLng.distanceTo(previousLatLng);
566
+
567
+ return L.GeometryUtil.readableDistance(distance, this.options.metric);
568
+ },
569
+
570
+ _showErrorTooltip: function () {
571
+ this._errorShown = true;
572
+
573
+ // Update tooltip
574
+ this._tooltip
575
+ .showAsError()
576
+ .updateContent({ text: this.options.drawError.message });
577
+
578
+ // Update shape
579
+ this._updateGuideColor(this.options.drawError.color);
580
+ this._poly.setStyle({ color: this.options.drawError.color });
581
+
582
+ // Hide the error after 2 seconds
583
+ this._clearHideErrorTimeout();
584
+ this._hideErrorTimeout = setTimeout(L.Util.bind(this._hideErrorTooltip, this), this.options.drawError.timeout);
585
+ },
586
+
587
+ _hideErrorTooltip: function () {
588
+ this._errorShown = false;
589
+
590
+ this._clearHideErrorTimeout();
591
+
592
+ // Revert tooltip
593
+ this._tooltip
594
+ .removeError()
595
+ .updateContent(this._getTooltipText());
596
+
597
+ // Revert shape
598
+ this._updateGuideColor(this.options.shapeOptions.color);
599
+ this._poly.setStyle({ color: this.options.shapeOptions.color });
600
+ },
601
+
602
+ _clearHideErrorTimeout: function () {
603
+ if (this._hideErrorTimeout) {
604
+ clearTimeout(this._hideErrorTimeout);
605
+ this._hideErrorTimeout = null;
606
+ }
607
+ },
608
+
609
+ _cleanUpShape: function () {
610
+ if (this._markers.length > 1) {
611
+ this._markers[this._markers.length - 1].off('click', this._finishShape, this);
612
+ }
613
+ },
614
+
615
+ _fireCreatedEvent: function () {
616
+ var poly = new this.Poly(this._poly.getLatLngs(), this.options.shapeOptions);
617
+ L.Draw.Feature.prototype._fireCreatedEvent.call(this, poly);
618
+ }
619
+ });
620
+
621
+
622
+ L.Draw.Polygon = L.Draw.Polyline.extend({
623
+ statics: {
624
+ TYPE: 'polygon'
625
+ },
626
+
627
+ Poly: L.Polygon,
628
+
629
+ options: {
630
+ showArea: false,
631
+ shapeOptions: {
632
+ stroke: true,
633
+ color: '#f06eaa',
634
+ weight: 4,
635
+ opacity: 0.5,
636
+ fill: true,
637
+ fillColor: null, //same as color by default
638
+ fillOpacity: 0.2,
639
+ clickable: true
640
+ }
641
+ },
642
+
643
+ initialize: function (map, options) {
644
+ L.Draw.Polyline.prototype.initialize.call(this, map, options);
645
+
646
+ // Save the type so super can fire, need to do this as cannot do this.TYPE :(
647
+ this.type = L.Draw.Polygon.TYPE;
648
+ },
649
+
650
+ _updateFinishHandler: function () {
651
+ var markerCount = this._markers.length;
652
+
653
+ // The first marker should have a click handler to close the polygon
654
+ if (markerCount === 1) {
655
+ this._markers[0].on('click', this._finishShape, this);
656
+ }
657
+
658
+ // Add and update the double click handler
659
+ if (markerCount > 2) {
660
+ this._markers[markerCount - 1].on('dblclick', this._finishShape, this);
661
+ // Only need to remove handler if has been added before
662
+ if (markerCount > 3) {
663
+ this._markers[markerCount - 2].off('dblclick', this._finishShape, this);
664
+ }
665
+ }
666
+ },
667
+
668
+ _getTooltipText: function () {
669
+ var text, subtext;
670
+
671
+ if (this._markers.length === 0) {
672
+ text = L.drawLocal.draw.handlers.polygon.tooltip.start;
673
+ } else if (this._markers.length < 3) {
674
+ text = L.drawLocal.draw.handlers.polygon.tooltip.cont;
675
+ } else {
676
+ text = L.drawLocal.draw.handlers.polygon.tooltip.end;
677
+ subtext = this._getMeasurementString();
678
+ }
679
+
680
+ return {
681
+ text: text,
682
+ subtext: subtext
683
+ };
684
+ },
685
+
686
+ _getMeasurementString: function () {
687
+ var area = this._area;
688
+
689
+ if (!area) {
690
+ return null;
691
+ }
692
+
693
+ return L.GeometryUtil.readableArea(area, this.options.metric);
694
+ },
695
+
696
+ _shapeIsValid: function () {
697
+ return this._markers.length >= 3;
698
+ },
699
+
700
+ _vertexChanged: function (latlng, added) {
701
+ var latLngs;
702
+
703
+ // Check to see if we should show the area
704
+ if (!this.options.allowIntersection && this.options.showArea) {
705
+ latLngs = this._poly.getLatLngs();
706
+
707
+ this._area = L.GeometryUtil.geodesicArea(latLngs);
708
+ }
709
+
710
+ L.Draw.Polyline.prototype._vertexChanged.call(this, latlng, added);
711
+ },
712
+
713
+ _cleanUpShape: function () {
714
+ var markerCount = this._markers.length;
715
+
716
+ if (markerCount > 0) {
717
+ this._markers[0].off('click', this._finishShape, this);
718
+
719
+ if (markerCount > 2) {
720
+ this._markers[markerCount - 1].off('dblclick', this._finishShape, this);
721
+ }
722
+ }
723
+ }
724
+ });
725
+
726
+
727
+ L.SimpleShape = {};
728
+
729
+ L.Draw.SimpleShape = L.Draw.Feature.extend({
730
+ options: {
731
+ repeatMode: false
732
+ },
733
+
734
+ initialize: function (map, options) {
735
+ this._endLabelText = L.drawLocal.draw.handlers.simpleshape.tooltip.end;
736
+
737
+ L.Draw.Feature.prototype.initialize.call(this, map, options);
738
+ },
739
+
740
+ addHooks: function () {
741
+ L.Draw.Feature.prototype.addHooks.call(this);
742
+ if (this._map) {
743
+ this._mapDraggable = this._map.dragging.enabled();
744
+
745
+ if (this._mapDraggable) {
746
+ this._map.dragging.disable();
747
+ }
748
+
749
+ //TODO refactor: move cursor to styles
750
+ this._container.style.cursor = 'crosshair';
751
+
752
+ this._tooltip.updateContent({ text: this._initialLabelText });
753
+
754
+ this._map
755
+ .on('mousedown', this._onMouseDown, this)
756
+ .on('mousemove', this._onMouseMove, this);
757
+ }
758
+ },
759
+
760
+ removeHooks: function () {
761
+ L.Draw.Feature.prototype.removeHooks.call(this);
762
+ if (this._map) {
763
+ if (this._mapDraggable) {
764
+ this._map.dragging.enable();
765
+ }
766
+
767
+ //TODO refactor: move cursor to styles
768
+ this._container.style.cursor = '';
769
+
770
+ this._map
771
+ .off('mousedown', this._onMouseDown, this)
772
+ .off('mousemove', this._onMouseMove, this);
773
+
774
+ L.DomEvent.off(document, 'mouseup', this._onMouseUp, this);
775
+
776
+ // If the box element doesn't exist they must not have moved the mouse, so don't need to destroy/return
777
+ if (this._shape) {
778
+ this._map.removeLayer(this._shape);
779
+ delete this._shape;
780
+ }
781
+ }
782
+ this._isDrawing = false;
783
+ },
784
+
785
+ _onMouseDown: function (e) {
786
+ this._isDrawing = true;
787
+ this._startLatLng = e.latlng;
788
+
789
+ L.DomEvent
790
+ .on(document, 'mouseup', this._onMouseUp, this)
791
+ .preventDefault(e.originalEvent);
792
+ },
793
+
794
+ _onMouseMove: function (e) {
795
+ var latlng = e.latlng;
796
+
797
+ this._tooltip.updatePosition(latlng);
798
+ if (this._isDrawing) {
799
+ this._tooltip.updateContent({ text: this._endLabelText });
800
+ this._drawShape(latlng);
801
+ }
802
+ },
803
+
804
+ _onMouseUp: function () {
805
+ if (this._shape) {
806
+ this._fireCreatedEvent();
807
+ }
808
+
809
+ this.disable();
810
+ if (this.options.repeatMode) {
811
+ this.enable();
812
+ }
813
+ }
814
+ });
815
+
816
+ L.Draw.Rectangle = L.Draw.SimpleShape.extend({
817
+ statics: {
818
+ TYPE: 'rectangle'
819
+ },
820
+
821
+ options: {
822
+ shapeOptions: {
823
+ stroke: true,
824
+ color: '#f06eaa',
825
+ weight: 4,
826
+ opacity: 0.5,
827
+ fill: true,
828
+ fillColor: null, //same as color by default
829
+ fillOpacity: 0.2,
830
+ clickable: true
831
+ }
832
+ },
833
+
834
+ initialize: function (map, options) {
835
+ // Save the type so super can fire, need to do this as cannot do this.TYPE :(
836
+ this.type = L.Draw.Rectangle.TYPE;
837
+
838
+ this._initialLabelText = L.drawLocal.draw.handlers.rectangle.tooltip.start;
839
+
840
+ L.Draw.SimpleShape.prototype.initialize.call(this, map, options);
841
+ },
842
+
843
+ _drawShape: function (latlng) {
844
+ if (!this._shape) {
845
+ this._shape = new L.Rectangle(new L.LatLngBounds(this._startLatLng, latlng), this.options.shapeOptions);
846
+ this._map.addLayer(this._shape);
847
+ } else {
848
+ this._shape.setBounds(new L.LatLngBounds(this._startLatLng, latlng));
849
+ }
850
+ },
851
+
852
+ _fireCreatedEvent: function () {
853
+ var rectangle = new L.Rectangle(this._shape.getBounds(), this.options.shapeOptions);
854
+ L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, rectangle);
855
+ }
856
+ });
857
+
858
+
859
+ L.Draw.Circle = L.Draw.SimpleShape.extend({
860
+ statics: {
861
+ TYPE: 'circle'
862
+ },
863
+
864
+ options: {
865
+ shapeOptions: {
866
+ stroke: true,
867
+ color: '#f06eaa',
868
+ weight: 4,
869
+ opacity: 0.5,
870
+ fill: true,
871
+ fillColor: null, //same as color by default
872
+ fillOpacity: 0.2,
873
+ clickable: true
874
+ },
875
+ showRadius: true,
876
+ metric: true // Whether to use the metric meaurement system or imperial
877
+ },
878
+
879
+ initialize: function (map, options) {
880
+ // Save the type so super can fire, need to do this as cannot do this.TYPE :(
881
+ this.type = L.Draw.Circle.TYPE;
882
+
883
+ this._initialLabelText = L.drawLocal.draw.handlers.circle.tooltip.start;
884
+
885
+ L.Draw.SimpleShape.prototype.initialize.call(this, map, options);
886
+ },
887
+
888
+ _drawShape: function (latlng) {
889
+ if (!this._shape) {
890
+ this._shape = new L.Circle(this._startLatLng, this._startLatLng.distanceTo(latlng), this.options.shapeOptions);
891
+ this._map.addLayer(this._shape);
892
+ } else {
893
+ this._shape.setRadius(this._startLatLng.distanceTo(latlng));
894
+ }
895
+ },
896
+
897
+ _fireCreatedEvent: function () {
898
+ var circle = new L.Circle(this._startLatLng, this._shape.getRadius(), this.options.shapeOptions);
899
+ L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, circle);
900
+ },
901
+
902
+ _onMouseMove: function (e) {
903
+ var latlng = e.latlng,
904
+ showRadius = this.options.showRadius,
905
+ useMetric = this.options.metric,
906
+ radius;
907
+
908
+ this._tooltip.updatePosition(latlng);
909
+ if (this._isDrawing) {
910
+ this._drawShape(latlng);
911
+
912
+ // Get the new radius (rounded to 1 dp)
913
+ radius = this._shape.getRadius().toFixed(1);
914
+
915
+ this._tooltip.updateContent({
916
+ text: this._endLabelText,
917
+ subtext: showRadius ? 'Radius: ' + L.GeometryUtil.readableDistance(radius, useMetric) : ''
918
+ });
919
+ }
920
+ }
921
+ });
922
+
923
+
924
+ L.Draw.Marker = L.Draw.Feature.extend({
925
+ statics: {
926
+ TYPE: 'marker'
927
+ },
928
+
929
+ options: {
930
+ icon: new L.Icon.Default(),
931
+ repeatMode: false,
932
+ zIndexOffset: 2000 // This should be > than the highest z-index any markers
933
+ },
934
+
935
+ initialize: function (map, options) {
936
+ // Save the type so super can fire, need to do this as cannot do this.TYPE :(
937
+ this.type = L.Draw.Marker.TYPE;
938
+
939
+ L.Draw.Feature.prototype.initialize.call(this, map, options);
940
+ },
941
+
942
+ addHooks: function () {
943
+ L.Draw.Feature.prototype.addHooks.call(this);
944
+
945
+ if (this._map) {
946
+ this._tooltip.updateContent({ text: L.drawLocal.draw.handlers.marker.tooltip.start });
947
+
948
+ // Same mouseMarker as in Draw.Polyline
949
+ if (!this._mouseMarker) {
950
+ this._mouseMarker = L.marker(this._map.getCenter(), {
951
+ icon: L.divIcon({
952
+ className: 'leaflet-mouse-marker',
953
+ iconAnchor: [20, 20],
954
+ iconSize: [40, 40]
955
+ }),
956
+ opacity: 0,
957
+ zIndexOffset: this.options.zIndexOffset
958
+ });
959
+ }
960
+
961
+ this._mouseMarker
962
+ .on('click', this._onClick, this)
963
+ .addTo(this._map);
964
+
965
+ this._map.on('mousemove', this._onMouseMove, this);
966
+ }
967
+ },
968
+
969
+ removeHooks: function () {
970
+ L.Draw.Feature.prototype.removeHooks.call(this);
971
+
972
+ if (this._map) {
973
+ if (this._marker) {
974
+ this._marker.off('click', this._onClick, this);
975
+ this._map
976
+ .off('click', this._onClick, this)
977
+ .removeLayer(this._marker);
978
+ delete this._marker;
979
+ }
980
+
981
+ this._mouseMarker.off('click', this._onClick, this);
982
+ this._map.removeLayer(this._mouseMarker);
983
+ delete this._mouseMarker;
984
+
985
+ this._map.off('mousemove', this._onMouseMove, this);
986
+ }
987
+ },
988
+
989
+ _onMouseMove: function (e) {
990
+ var latlng = e.latlng;
991
+
992
+ this._tooltip.updatePosition(latlng);
993
+ this._mouseMarker.setLatLng(latlng);
994
+
995
+ if (!this._marker) {
996
+ this._marker = new L.Marker(latlng, {
997
+ icon: this.options.icon,
998
+ zIndexOffset: this.options.zIndexOffset
999
+ });
1000
+ // Bind to both marker and map to make sure we get the click event.
1001
+ this._marker.on('click', this._onClick, this);
1002
+ this._map
1003
+ .on('click', this._onClick, this)
1004
+ .addLayer(this._marker);
1005
+ }
1006
+ else {
1007
+ latlng = this._mouseMarker.getLatLng();
1008
+ this._marker.setLatLng(latlng);
1009
+ }
1010
+ },
1011
+
1012
+ _onClick: function () {
1013
+ this._fireCreatedEvent();
1014
+
1015
+ this.disable();
1016
+ if (this.options.repeatMode) {
1017
+ this.enable();
1018
+ }
1019
+ },
1020
+
1021
+ _fireCreatedEvent: function () {
1022
+ var marker = new L.Marker(this._marker.getLatLng(), { icon: this.options.icon });
1023
+ L.Draw.Feature.prototype._fireCreatedEvent.call(this, marker);
1024
+ }
1025
+ });
1026
+
1027
+
1028
+ L.Edit = L.Edit || {};
1029
+
1030
+ /*
1031
+ * L.Edit.Poly is an editing handler for polylines and polygons.
1032
+ */
1033
+
1034
+ L.Edit.Poly = L.Handler.extend({
1035
+ options: {
1036
+ icon: new L.DivIcon({
1037
+ iconSize: new L.Point(8, 8),
1038
+ className: 'leaflet-div-icon leaflet-editing-icon'
1039
+ })
1040
+ },
1041
+
1042
+ initialize: function (poly, options) {
1043
+ this._poly = poly;
1044
+ L.setOptions(this, options);
1045
+ },
1046
+
1047
+ addHooks: function () {
1048
+ if (this._poly._map) {
1049
+ if (!this._markerGroup) {
1050
+ this._initMarkers();
1051
+ }
1052
+ this._poly._map.addLayer(this._markerGroup);
1053
+ }
1054
+ },
1055
+
1056
+ removeHooks: function () {
1057
+ if (this._poly._map) {
1058
+ this._poly._map.removeLayer(this._markerGroup);
1059
+ delete this._markerGroup;
1060
+ delete this._markers;
1061
+ }
1062
+ },
1063
+
1064
+ updateMarkers: function () {
1065
+ this._markerGroup.clearLayers();
1066
+ this._initMarkers();
1067
+ },
1068
+
1069
+ _initMarkers: function () {
1070
+ if (!this._markerGroup) {
1071
+ this._markerGroup = new L.LayerGroup();
1072
+ }
1073
+ this._markers = [];
1074
+
1075
+ var latlngs = this._poly._latlngs,
1076
+ i, j, len, marker;
1077
+
1078
+ // TODO refactor holes implementation in Polygon to support it here
1079
+
1080
+ for (i = 0, len = latlngs.length; i < len; i++) {
1081
+
1082
+ marker = this._createMarker(latlngs[i], i);
1083
+ marker.on('click', this._onMarkerClick, this);
1084
+ this._markers.push(marker);
1085
+ }
1086
+
1087
+ var markerLeft, markerRight;
1088
+
1089
+ for (i = 0, j = len - 1; i < len; j = i++) {
1090
+ if (i === 0 && !(L.Polygon && (this._poly instanceof L.Polygon))) {
1091
+ continue;
1092
+ }
1093
+
1094
+ markerLeft = this._markers[j];
1095
+ markerRight = this._markers[i];
1096
+
1097
+ this._createMiddleMarker(markerLeft, markerRight);
1098
+ this._updatePrevNext(markerLeft, markerRight);
1099
+ }
1100
+ },
1101
+
1102
+ _createMarker: function (latlng, index) {
1103
+ var marker = new L.Marker(latlng, {
1104
+ draggable: true,
1105
+ icon: this.options.icon
1106
+ });
1107
+
1108
+ marker._origLatLng = latlng;
1109
+ marker._index = index;
1110
+
1111
+ marker.on('drag', this._onMarkerDrag, this);
1112
+ marker.on('dragend', this._fireEdit, this);
1113
+
1114
+ this._markerGroup.addLayer(marker);
1115
+
1116
+ return marker;
1117
+ },
1118
+
1119
+ _removeMarker: function (marker) {
1120
+ var i = marker._index;
1121
+
1122
+ this._markerGroup.removeLayer(marker);
1123
+ this._markers.splice(i, 1);
1124
+ this._poly.spliceLatLngs(i, 1);
1125
+ this._updateIndexes(i, -1);
1126
+
1127
+ marker
1128
+ .off('drag', this._onMarkerDrag, this)
1129
+ .off('dragend', this._fireEdit, this)
1130
+ .off('click', this._onMarkerClick, this);
1131
+ },
1132
+
1133
+ _fireEdit: function () {
1134
+ this._poly.edited = true;
1135
+ this._poly.fire('edit');
1136
+ },
1137
+
1138
+ _onMarkerDrag: function (e) {
1139
+ var marker = e.target;
1140
+
1141
+ L.extend(marker._origLatLng, marker._latlng);
1142
+
1143
+ if (marker._middleLeft) {
1144
+ marker._middleLeft.setLatLng(this._getMiddleLatLng(marker._prev, marker));
1145
+ }
1146
+ if (marker._middleRight) {
1147
+ marker._middleRight.setLatLng(this._getMiddleLatLng(marker, marker._next));
1148
+ }
1149
+
1150
+ this._poly.redraw();
1151
+ },
1152
+
1153
+ _onMarkerClick: function (e) {
1154
+ var minPoints = L.Polygon && (this._poly instanceof L.Polygon) ? 4 : 3,
1155
+ marker = e.target;
1156
+
1157
+ // If removing this point would create an invalid polyline/polygon don't remove
1158
+ if (this._poly._latlngs.length < minPoints) {
1159
+ return;
1160
+ }
1161
+
1162
+ // remove the marker
1163
+ this._removeMarker(marker);
1164
+
1165
+ // update prev/next links of adjacent markers
1166
+ this._updatePrevNext(marker._prev, marker._next);
1167
+
1168
+ // remove ghost markers near the removed marker
1169
+ if (marker._middleLeft) {
1170
+ this._markerGroup.removeLayer(marker._middleLeft);
1171
+ }
1172
+ if (marker._middleRight) {
1173
+ this._markerGroup.removeLayer(marker._middleRight);
1174
+ }
1175
+
1176
+ // create a ghost marker in place of the removed one
1177
+ if (marker._prev && marker._next) {
1178
+ this._createMiddleMarker(marker._prev, marker._next);
1179
+
1180
+ } else if (!marker._prev) {
1181
+ marker._next._middleLeft = null;
1182
+
1183
+ } else if (!marker._next) {
1184
+ marker._prev._middleRight = null;
1185
+ }
1186
+
1187
+ this._fireEdit();
1188
+ },
1189
+
1190
+ _updateIndexes: function (index, delta) {
1191
+ this._markerGroup.eachLayer(function (marker) {
1192
+ if (marker._index > index) {
1193
+ marker._index += delta;
1194
+ }
1195
+ });
1196
+ },
1197
+
1198
+ _createMiddleMarker: function (marker1, marker2) {
1199
+ var latlng = this._getMiddleLatLng(marker1, marker2),
1200
+ marker = this._createMarker(latlng),
1201
+ onClick,
1202
+ onDragStart,
1203
+ onDragEnd;
1204
+
1205
+ marker.setOpacity(0.6);
1206
+
1207
+ marker1._middleRight = marker2._middleLeft = marker;
1208
+
1209
+ onDragStart = function () {
1210
+ var i = marker2._index;
1211
+
1212
+ marker._index = i;
1213
+
1214
+ marker
1215
+ .off('click', onClick, this)
1216
+ .on('click', this._onMarkerClick, this);
1217
+
1218
+ latlng.lat = marker.getLatLng().lat;
1219
+ latlng.lng = marker.getLatLng().lng;
1220
+ this._poly.spliceLatLngs(i, 0, latlng);
1221
+ this._markers.splice(i, 0, marker);
1222
+
1223
+ marker.setOpacity(1);
1224
+
1225
+ this._updateIndexes(i, 1);
1226
+ marker2._index++;
1227
+ this._updatePrevNext(marker1, marker);
1228
+ this._updatePrevNext(marker, marker2);
1229
+
1230
+ this._poly.fire('editstart');
1231
+ };
1232
+
1233
+ onDragEnd = function () {
1234
+ marker.off('dragstart', onDragStart, this);
1235
+ marker.off('dragend', onDragEnd, this);
1236
+
1237
+ this._createMiddleMarker(marker1, marker);
1238
+ this._createMiddleMarker(marker, marker2);
1239
+ };
1240
+
1241
+ onClick = function () {
1242
+ onDragStart.call(this);
1243
+ onDragEnd.call(this);
1244
+ this._fireEdit();
1245
+ };
1246
+
1247
+ marker
1248
+ .on('click', onClick, this)
1249
+ .on('dragstart', onDragStart, this)
1250
+ .on('dragend', onDragEnd, this);
1251
+
1252
+ this._markerGroup.addLayer(marker);
1253
+ },
1254
+
1255
+ _updatePrevNext: function (marker1, marker2) {
1256
+ if (marker1) {
1257
+ marker1._next = marker2;
1258
+ }
1259
+ if (marker2) {
1260
+ marker2._prev = marker1;
1261
+ }
1262
+ },
1263
+
1264
+ _getMiddleLatLng: function (marker1, marker2) {
1265
+ var map = this._poly._map,
1266
+ p1 = map.project(marker1.getLatLng()),
1267
+ p2 = map.project(marker2.getLatLng());
1268
+
1269
+ return map.unproject(p1._add(p2)._divideBy(2));
1270
+ }
1271
+ });
1272
+
1273
+ L.Polyline.addInitHook(function () {
1274
+
1275
+ // Check to see if handler has already been initialized. This is to support versions of Leaflet that still have L.Handler.PolyEdit
1276
+ if (this.editing) {
1277
+ return;
1278
+ }
1279
+
1280
+ if (L.Edit.Poly) {
1281
+ this.editing = new L.Edit.Poly(this);
1282
+
1283
+ if (this.options.editable) {
1284
+ this.editing.enable();
1285
+ }
1286
+ }
1287
+
1288
+ this.on('add', function () {
1289
+ if (this.editing && this.editing.enabled()) {
1290
+ this.editing.addHooks();
1291
+ }
1292
+ });
1293
+
1294
+ this.on('remove', function () {
1295
+ if (this.editing && this.editing.enabled()) {
1296
+ this.editing.removeHooks();
1297
+ }
1298
+ });
1299
+ });
1300
+
1301
+
1302
+ L.Edit = L.Edit || {};
1303
+
1304
+ L.Edit.SimpleShape = L.Handler.extend({
1305
+ options: {
1306
+ moveIcon: new L.DivIcon({
1307
+ iconSize: new L.Point(8, 8),
1308
+ className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-move'
1309
+ }),
1310
+ resizeIcon: new L.DivIcon({
1311
+ iconSize: new L.Point(8, 8),
1312
+ className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize'
1313
+ })
1314
+ },
1315
+
1316
+ initialize: function (shape, options) {
1317
+ this._shape = shape;
1318
+ L.Util.setOptions(this, options);
1319
+ },
1320
+
1321
+ addHooks: function () {
1322
+ if (this._shape._map) {
1323
+ this._map = this._shape._map;
1324
+
1325
+ if (!this._markerGroup) {
1326
+ this._initMarkers();
1327
+ }
1328
+ this._map.addLayer(this._markerGroup);
1329
+ }
1330
+ },
1331
+
1332
+ removeHooks: function () {
1333
+ if (this._shape._map) {
1334
+ this._unbindMarker(this._moveMarker);
1335
+
1336
+ for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
1337
+ this._unbindMarker(this._resizeMarkers[i]);
1338
+ }
1339
+ this._resizeMarkers = null;
1340
+
1341
+ this._map.removeLayer(this._markerGroup);
1342
+ delete this._markerGroup;
1343
+ }
1344
+
1345
+ this._map = null;
1346
+ },
1347
+
1348
+ updateMarkers: function () {
1349
+ this._markerGroup.clearLayers();
1350
+ this._initMarkers();
1351
+ },
1352
+
1353
+ _initMarkers: function () {
1354
+ if (!this._markerGroup) {
1355
+ this._markerGroup = new L.LayerGroup();
1356
+ }
1357
+
1358
+ // Create center marker
1359
+ this._createMoveMarker();
1360
+
1361
+ // Create edge marker
1362
+ this._createResizeMarker();
1363
+ },
1364
+
1365
+ _createMoveMarker: function () {
1366
+ // Children override
1367
+ },
1368
+
1369
+ _createResizeMarker: function () {
1370
+ // Children override
1371
+ },
1372
+
1373
+ _createMarker: function (latlng, icon) {
1374
+ var marker = new L.Marker(latlng, {
1375
+ draggable: true,
1376
+ icon: icon,
1377
+ zIndexOffset: 10
1378
+ });
1379
+
1380
+ this._bindMarker(marker);
1381
+
1382
+ this._markerGroup.addLayer(marker);
1383
+
1384
+ return marker;
1385
+ },
1386
+
1387
+ _bindMarker: function (marker) {
1388
+ marker
1389
+ .on('dragstart', this._onMarkerDragStart, this)
1390
+ .on('drag', this._onMarkerDrag, this)
1391
+ .on('dragend', this._onMarkerDragEnd, this);
1392
+ },
1393
+
1394
+ _unbindMarker: function (marker) {
1395
+ marker
1396
+ .off('dragstart', this._onMarkerDragStart, this)
1397
+ .off('drag', this._onMarkerDrag, this)
1398
+ .off('dragend', this._onMarkerDragEnd, this);
1399
+ },
1400
+
1401
+ _onMarkerDragStart: function (e) {
1402
+ var marker = e.target;
1403
+ marker.setOpacity(0);
1404
+
1405
+ this._shape.fire('editstart');
1406
+ },
1407
+
1408
+ _fireEdit: function () {
1409
+ this._shape.edited = true;
1410
+ this._shape.fire('edit');
1411
+ },
1412
+
1413
+ _onMarkerDrag: function (e) {
1414
+ var marker = e.target,
1415
+ latlng = marker.getLatLng();
1416
+
1417
+ if (marker === this._moveMarker) {
1418
+ this._move(latlng);
1419
+ } else {
1420
+ this._resize(latlng);
1421
+ }
1422
+
1423
+ this._shape.redraw();
1424
+ },
1425
+
1426
+ _onMarkerDragEnd: function (e) {
1427
+ var marker = e.target;
1428
+ marker.setOpacity(1);
1429
+
1430
+ this._fireEdit();
1431
+ },
1432
+
1433
+ _move: function () {
1434
+ // Children override
1435
+ },
1436
+
1437
+ _resize: function () {
1438
+ // Children override
1439
+ }
1440
+ });
1441
+
1442
+
1443
+ L.Edit = L.Edit || {};
1444
+
1445
+ L.Edit.Rectangle = L.Edit.SimpleShape.extend({
1446
+ _createMoveMarker: function () {
1447
+ var bounds = this._shape.getBounds(),
1448
+ center = bounds.getCenter();
1449
+
1450
+ this._moveMarker = this._createMarker(center, this.options.moveIcon);
1451
+ },
1452
+
1453
+ _createResizeMarker: function () {
1454
+ var corners = this._getCorners();
1455
+
1456
+ this._resizeMarkers = [];
1457
+
1458
+ for (var i = 0, l = corners.length; i < l; i++) {
1459
+ this._resizeMarkers.push(this._createMarker(corners[i], this.options.resizeIcon));
1460
+ // Monkey in the corner index as we will need to know this for dragging
1461
+ this._resizeMarkers[i]._cornerIndex = i;
1462
+ }
1463
+ },
1464
+
1465
+ _onMarkerDragStart: function (e) {
1466
+ L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, e);
1467
+
1468
+ // Save a reference to the opposite point
1469
+ var corners = this._getCorners(),
1470
+ marker = e.target,
1471
+ currentCornerIndex = marker._cornerIndex;
1472
+
1473
+ this._oppositeCorner = corners[(currentCornerIndex + 2) % 4];
1474
+
1475
+ this._toggleCornerMarkers(0, currentCornerIndex);
1476
+ },
1477
+
1478
+ _onMarkerDragEnd: function (e) {
1479
+ var marker = e.target,
1480
+ bounds, center;
1481
+
1482
+ // Reset move marker position to the center
1483
+ if (marker === this._moveMarker) {
1484
+ bounds = this._shape.getBounds();
1485
+ center = bounds.getCenter();
1486
+
1487
+ marker.setLatLng(center);
1488
+ }
1489
+
1490
+ this._toggleCornerMarkers(1);
1491
+
1492
+ this._repositionCornerMarkers();
1493
+
1494
+ L.Edit.SimpleShape.prototype._onMarkerDragEnd.call(this, e);
1495
+ },
1496
+
1497
+ _move: function (newCenter) {
1498
+ var latlngs = this._shape.getLatLngs(),
1499
+ bounds = this._shape.getBounds(),
1500
+ center = bounds.getCenter(),
1501
+ offset, newLatLngs = [];
1502
+
1503
+ // Offset the latlngs to the new center
1504
+ for (var i = 0, l = latlngs.length; i < l; i++) {
1505
+ offset = [latlngs[i].lat - center.lat, latlngs[i].lng - center.lng];
1506
+ newLatLngs.push([newCenter.lat + offset[0], newCenter.lng + offset[1]]);
1507
+ }
1508
+
1509
+ this._shape.setLatLngs(newLatLngs);
1510
+
1511
+ // Reposition the resize markers
1512
+ this._repositionCornerMarkers();
1513
+ },
1514
+
1515
+ _resize: function (latlng) {
1516
+ var bounds;
1517
+
1518
+ // Update the shape based on the current position of this corner and the opposite point
1519
+ this._shape.setBounds(L.latLngBounds(latlng, this._oppositeCorner));
1520
+
1521
+ // Reposition the move marker
1522
+ bounds = this._shape.getBounds();
1523
+ this._moveMarker.setLatLng(bounds.getCenter());
1524
+ },
1525
+
1526
+ _getCorners: function () {
1527
+ var bounds = this._shape.getBounds(),
1528
+ nw = bounds.getNorthWest(),
1529
+ ne = bounds.getNorthEast(),
1530
+ se = bounds.getSouthEast(),
1531
+ sw = bounds.getSouthWest();
1532
+
1533
+ return [nw, ne, se, sw];
1534
+ },
1535
+
1536
+ _toggleCornerMarkers: function (opacity) {
1537
+ for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
1538
+ this._resizeMarkers[i].setOpacity(opacity);
1539
+ }
1540
+ },
1541
+
1542
+ _repositionCornerMarkers: function () {
1543
+ var corners = this._getCorners();
1544
+
1545
+ for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
1546
+ this._resizeMarkers[i].setLatLng(corners[i]);
1547
+ }
1548
+ }
1549
+ });
1550
+
1551
+ L.Rectangle.addInitHook(function () {
1552
+ if (L.Edit.Rectangle) {
1553
+ this.editing = new L.Edit.Rectangle(this);
1554
+
1555
+ if (this.options.editable) {
1556
+ this.editing.enable();
1557
+ }
1558
+ }
1559
+ });
1560
+
1561
+
1562
+ L.Edit = L.Edit || {};
1563
+
1564
+ L.Edit.Circle = L.Edit.SimpleShape.extend({
1565
+ _createMoveMarker: function () {
1566
+ var center = this._shape.getLatLng();
1567
+
1568
+ this._moveMarker = this._createMarker(center, this.options.moveIcon);
1569
+ },
1570
+
1571
+ _createResizeMarker: function () {
1572
+ var center = this._shape.getLatLng(),
1573
+ resizemarkerPoint = this._getResizeMarkerPoint(center);
1574
+
1575
+ this._resizeMarkers = [];
1576
+ this._resizeMarkers.push(this._createMarker(resizemarkerPoint, this.options.resizeIcon));
1577
+ },
1578
+
1579
+ _getResizeMarkerPoint: function (latlng) {
1580
+ // From L.shape.getBounds()
1581
+ var delta = this._shape._radius * Math.cos(Math.PI / 4),
1582
+ point = this._map.project(latlng);
1583
+ return this._map.unproject([point.x + delta, point.y - delta]);
1584
+ },
1585
+
1586
+ _move: function (latlng) {
1587
+ var resizemarkerPoint = this._getResizeMarkerPoint(latlng);
1588
+
1589
+ // Move the resize marker
1590
+ this._resizeMarkers[0].setLatLng(resizemarkerPoint);
1591
+
1592
+ // Move the circle
1593
+ this._shape.setLatLng(latlng);
1594
+ },
1595
+
1596
+ _resize: function (latlng) {
1597
+ var moveLatLng = this._moveMarker.getLatLng(),
1598
+ radius = moveLatLng.distanceTo(latlng);
1599
+
1600
+ this._shape.setRadius(radius);
1601
+ }
1602
+ });
1603
+
1604
+ L.Circle.addInitHook(function () {
1605
+ if (L.Edit.Circle) {
1606
+ this.editing = new L.Edit.Circle(this);
1607
+
1608
+ if (this.options.editable) {
1609
+ this.editing.enable();
1610
+ }
1611
+ }
1612
+
1613
+ this.on('add', function () {
1614
+ if (this.editing && this.editing.enabled()) {
1615
+ this.editing.addHooks();
1616
+ }
1617
+ });
1618
+
1619
+ this.on('remove', function () {
1620
+ if (this.editing && this.editing.enabled()) {
1621
+ this.editing.removeHooks();
1622
+ }
1623
+ });
1624
+ });
1625
+
1626
+ /*
1627
+ * L.LatLngUtil contains different utility functions for LatLngs.
1628
+ */
1629
+
1630
+ L.LatLngUtil = {
1631
+ // Clones a LatLngs[], returns [][]
1632
+ cloneLatLngs: function (latlngs) {
1633
+ var clone = [];
1634
+ for (var i = 0, l = latlngs.length; i < l; i++) {
1635
+ clone.push(this.cloneLatLng(latlngs[i]));
1636
+ }
1637
+ return clone;
1638
+ },
1639
+
1640
+ cloneLatLng: function (latlng) {
1641
+ return L.latLng(latlng.lat, latlng.lng);
1642
+ }
1643
+ };
1644
+
1645
+ L.GeometryUtil = L.extend(L.GeometryUtil || {}, {
1646
+ // Ported from the OpenLayers implementation. See https://github.com/openlayers/openlayers/blob/master/lib/OpenLayers/Geometry/LinearRing.js#L270
1647
+ geodesicArea: function (latLngs) {
1648
+ var pointsCount = latLngs.length,
1649
+ area = 0.0,
1650
+ d2r = L.LatLng.DEG_TO_RAD,
1651
+ p1, p2;
1652
+
1653
+ if (pointsCount > 2) {
1654
+ for (var i = 0; i < pointsCount; i++) {
1655
+ p1 = latLngs[i];
1656
+ p2 = latLngs[(i + 1) % pointsCount];
1657
+ area += ((p2.lng - p1.lng) * d2r) *
1658
+ (2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r));
1659
+ }
1660
+ area = area * 6378137.0 * 6378137.0 / 2.0;
1661
+ }
1662
+
1663
+ return Math.abs(area);
1664
+ },
1665
+
1666
+ readableArea: function (area, isMetric) {
1667
+ var areaStr;
1668
+
1669
+ if (isMetric) {
1670
+ if (area >= 10000) {
1671
+ areaStr = (area * 0.0001).toFixed(2) + ' ha';
1672
+ } else {
1673
+ areaStr = area.toFixed(2) + ' m&sup2;';
1674
+ }
1675
+ } else {
1676
+ area *= 0.836127; // Square yards in 1 meter
1677
+
1678
+ if (area >= 3097600) { //3097600 square yards in 1 square mile
1679
+ areaStr = (area / 3097600).toFixed(2) + ' mi&sup2;';
1680
+ } else if (area >= 4840) {//48040 square yards in 1 acre
1681
+ areaStr = (area / 4840).toFixed(2) + ' acres';
1682
+ } else {
1683
+ areaStr = Math.ceil(area) + ' yd&sup2;';
1684
+ }
1685
+ }
1686
+
1687
+ return areaStr;
1688
+ },
1689
+
1690
+ readableDistance: function (distance, isMetric) {
1691
+ var distanceStr;
1692
+
1693
+ if (isMetric) {
1694
+ // show metres when distance is < 1km, then show km
1695
+ if (distance > 1000) {
1696
+ distanceStr = (distance / 1000).toFixed(2) + ' km';
1697
+ } else {
1698
+ distanceStr = Math.ceil(distance) + ' m';
1699
+ }
1700
+ } else {
1701
+ distance *= 1.09361;
1702
+
1703
+ if (distance > 1760) {
1704
+ distanceStr = (distance / 1760).toFixed(2) + ' miles';
1705
+ } else {
1706
+ distanceStr = Math.ceil(distance) + ' yd';
1707
+ }
1708
+ }
1709
+
1710
+ return distanceStr;
1711
+ }
1712
+ });
1713
+
1714
+ L.Util.extend(L.LineUtil, {
1715
+ // Checks to see if two line segments intersect. Does not handle degenerate cases.
1716
+ // http://compgeom.cs.uiuc.edu/~jeffe/teaching/373/notes/x06-sweepline.pdf
1717
+ segmentsIntersect: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2, /*Point*/ p3) {
1718
+ return this._checkCounterclockwise(p, p2, p3) !==
1719
+ this._checkCounterclockwise(p1, p2, p3) &&
1720
+ this._checkCounterclockwise(p, p1, p2) !==
1721
+ this._checkCounterclockwise(p, p1, p3);
1722
+ },
1723
+
1724
+ // check to see if points are in counterclockwise order
1725
+ _checkCounterclockwise: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
1726
+ return (p2.y - p.y) * (p1.x - p.x) > (p1.y - p.y) * (p2.x - p.x);
1727
+ }
1728
+ });
1729
+
1730
+ L.Polyline.include({
1731
+ // Check to see if this polyline has any linesegments that intersect.
1732
+ // NOTE: does not support detecting intersection for degenerate cases.
1733
+ intersects: function () {
1734
+ var points = this._originalPoints,
1735
+ len = points ? points.length : 0,
1736
+ i, p, p1;
1737
+
1738
+ if (this._tooFewPointsForIntersection()) {
1739
+ return false;
1740
+ }
1741
+
1742
+ for (i = len - 1; i >= 3; i--) {
1743
+ p = points[i - 1];
1744
+ p1 = points[i];
1745
+
1746
+
1747
+ if (this._lineSegmentsIntersectsRange(p, p1, i - 2)) {
1748
+ return true;
1749
+ }
1750
+ }
1751
+
1752
+ return false;
1753
+ },
1754
+
1755
+ // Check for intersection if new latlng was added to this polyline.
1756
+ // NOTE: does not support detecting intersection for degenerate cases.
1757
+ newLatLngIntersects: function (latlng, skipFirst) {
1758
+ // Cannot check a polyline for intersecting lats/lngs when not added to the map
1759
+ if (!this._map) {
1760
+ return false;
1761
+ }
1762
+
1763
+ return this.newPointIntersects(this._map.latLngToLayerPoint(latlng), skipFirst);
1764
+ },
1765
+
1766
+ // Check for intersection if new point was added to this polyline.
1767
+ // newPoint must be a layer point.
1768
+ // NOTE: does not support detecting intersection for degenerate cases.
1769
+ newPointIntersects: function (newPoint, skipFirst) {
1770
+ var points = this._originalPoints,
1771
+ len = points ? points.length : 0,
1772
+ lastPoint = points ? points[len - 1] : null,
1773
+ // The previous previous line segment. Previous line segment doesn't need testing.
1774
+ maxIndex = len - 2;
1775
+
1776
+ if (this._tooFewPointsForIntersection(1)) {
1777
+ return false;
1778
+ }
1779
+
1780
+ return this._lineSegmentsIntersectsRange(lastPoint, newPoint, maxIndex, skipFirst ? 1 : 0);
1781
+ },
1782
+
1783
+ // Polylines with 2 sides can only intersect in cases where points are collinear (we don't support detecting these).
1784
+ // Cannot have intersection when < 3 line segments (< 4 points)
1785
+ _tooFewPointsForIntersection: function (extraPoints) {
1786
+ var points = this._originalPoints,
1787
+ len = points ? points.length : 0;
1788
+ // Increment length by extraPoints if present
1789
+ len += extraPoints || 0;
1790
+
1791
+ return !this._originalPoints || len <= 3;
1792
+ },
1793
+
1794
+ // Checks a line segment intersections with any line segments before its predecessor.
1795
+ // Don't need to check the predecessor as will never intersect.
1796
+ _lineSegmentsIntersectsRange: function (p, p1, maxIndex, minIndex) {
1797
+ var points = this._originalPoints,
1798
+ p2, p3;
1799
+
1800
+ minIndex = minIndex || 0;
1801
+
1802
+ // Check all previous line segments (beside the immediately previous) for intersections
1803
+ for (var j = maxIndex; j > minIndex; j--) {
1804
+ p2 = points[j - 1];
1805
+ p3 = points[j];
1806
+
1807
+ if (L.LineUtil.segmentsIntersect(p, p1, p2, p3)) {
1808
+ return true;
1809
+ }
1810
+ }
1811
+
1812
+ return false;
1813
+ }
1814
+ });
1815
+
1816
+
1817
+ L.Polygon.include({
1818
+ // Checks a polygon for any intersecting line segments. Ignores holes.
1819
+ intersects: function () {
1820
+ var polylineIntersects,
1821
+ points = this._originalPoints,
1822
+ len, firstPoint, lastPoint, maxIndex;
1823
+
1824
+ if (this._tooFewPointsForIntersection()) {
1825
+ return false;
1826
+ }
1827
+
1828
+ polylineIntersects = L.Polyline.prototype.intersects.call(this);
1829
+
1830
+ // If already found an intersection don't need to check for any more.
1831
+ if (polylineIntersects) {
1832
+ return true;
1833
+ }
1834
+
1835
+ len = points.length;
1836
+ firstPoint = points[0];
1837
+ lastPoint = points[len - 1];
1838
+ maxIndex = len - 2;
1839
+
1840
+ // Check the line segment between last and first point. Don't need to check the first line segment (minIndex = 1)
1841
+ return this._lineSegmentsIntersectsRange(lastPoint, firstPoint, maxIndex, 1);
1842
+ }
1843
+ });
1844
+
1845
+ L.Control.Draw = L.Control.extend({
1846
+
1847
+ options: {
1848
+ position: 'topleft',
1849
+ draw: {},
1850
+ edit: false
1851
+ },
1852
+
1853
+ initialize: function (options) {
1854
+ if (L.version < '0.7') {
1855
+ throw new Error('Leaflet.draw 0.2.3+ requires Leaflet 0.7.0+. Download latest from https://github.com/Leaflet/Leaflet/');
1856
+ }
1857
+
1858
+ L.Control.prototype.initialize.call(this, options);
1859
+
1860
+ var id, toolbar;
1861
+
1862
+ this._toolbars = {};
1863
+
1864
+ // Initialize toolbars
1865
+ if (L.DrawToolbar && this.options.draw) {
1866
+ toolbar = new L.DrawToolbar(this.options.draw);
1867
+ id = L.stamp(toolbar);
1868
+ this._toolbars[id] = toolbar;
1869
+
1870
+ // Listen for when toolbar is enabled
1871
+ this._toolbars[id].on('enable', this._toolbarEnabled, this);
1872
+ }
1873
+
1874
+ if (L.EditToolbar && this.options.edit) {
1875
+ toolbar = new L.EditToolbar(this.options.edit);
1876
+ id = L.stamp(toolbar);
1877
+ this._toolbars[id] = toolbar;
1878
+
1879
+ // Listen for when toolbar is enabled
1880
+ this._toolbars[id].on('enable', this._toolbarEnabled, this);
1881
+ }
1882
+ },
1883
+
1884
+ onAdd: function (map) {
1885
+ var container = L.DomUtil.create('div', 'leaflet-draw'),
1886
+ addedTopClass = false,
1887
+ topClassName = 'leaflet-draw-toolbar-top',
1888
+ toolbarContainer;
1889
+
1890
+ for (var toolbarId in this._toolbars) {
1891
+ if (this._toolbars.hasOwnProperty(toolbarId)) {
1892
+ toolbarContainer = this._toolbars[toolbarId].addToolbar(map);
1893
+
1894
+ if (toolbarContainer) {
1895
+ // Add class to the first toolbar to remove the margin
1896
+ if (!addedTopClass) {
1897
+ if (!L.DomUtil.hasClass(toolbarContainer, topClassName)) {
1898
+ L.DomUtil.addClass(toolbarContainer.childNodes[0], topClassName);
1899
+ }
1900
+ addedTopClass = true;
1901
+ }
1902
+
1903
+ container.appendChild(toolbarContainer);
1904
+ }
1905
+ }
1906
+ }
1907
+
1908
+ return container;
1909
+ },
1910
+
1911
+ onRemove: function () {
1912
+ for (var toolbarId in this._toolbars) {
1913
+ if (this._toolbars.hasOwnProperty(toolbarId)) {
1914
+ this._toolbars[toolbarId].removeToolbar();
1915
+ }
1916
+ }
1917
+ },
1918
+
1919
+ setDrawingOptions: function (options) {
1920
+ for (var toolbarId in this._toolbars) {
1921
+ if (this._toolbars[toolbarId] instanceof L.DrawToolbar) {
1922
+ this._toolbars[toolbarId].setOptions(options);
1923
+ }
1924
+ }
1925
+ },
1926
+
1927
+ _toolbarEnabled: function (e) {
1928
+ var id = '' + L.stamp(e.target);
1929
+
1930
+ for (var toolbarId in this._toolbars) {
1931
+ if (this._toolbars.hasOwnProperty(toolbarId) && toolbarId !== id) {
1932
+ this._toolbars[toolbarId].disable();
1933
+ }
1934
+ }
1935
+ }
1936
+ });
1937
+
1938
+ L.Map.mergeOptions({
1939
+ drawControlTooltips: true,
1940
+ drawControl: false
1941
+ });
1942
+
1943
+ L.Map.addInitHook(function () {
1944
+ if (this.options.drawControl) {
1945
+ this.drawControl = new L.Control.Draw();
1946
+ this.addControl(this.drawControl);
1947
+ }
1948
+ });
1949
+
1950
+
1951
+ L.Toolbar = L.Class.extend({
1952
+ includes: [L.Mixin.Events],
1953
+
1954
+ initialize: function (options) {
1955
+ L.setOptions(this, options);
1956
+
1957
+ this._modes = {};
1958
+ this._actionButtons = [];
1959
+ this._activeMode = null;
1960
+ },
1961
+
1962
+ enabled: function () {
1963
+ return this._activeMode !== null;
1964
+ },
1965
+
1966
+ disable: function () {
1967
+ if (!this.enabled()) { return; }
1968
+
1969
+ this._activeMode.handler.disable();
1970
+ },
1971
+
1972
+ addToolbar: function (map) {
1973
+ var container = L.DomUtil.create('div', 'leaflet-draw-section'),
1974
+ buttonIndex = 0,
1975
+ buttonClassPrefix = this._toolbarClass || '',
1976
+ modeHandlers = this.getModeHandlers(map),
1977
+ i;
1978
+
1979
+ this._toolbarContainer = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar');
1980
+ this._map = map;
1981
+
1982
+ for (i = 0; i < modeHandlers.length; i++) {
1983
+ if (modeHandlers[i].enabled) {
1984
+ this._initModeHandler(
1985
+ modeHandlers[i].handler,
1986
+ this._toolbarContainer,
1987
+ buttonIndex++,
1988
+ buttonClassPrefix,
1989
+ modeHandlers[i].title
1990
+ );
1991
+ }
1992
+ }
1993
+
1994
+ // if no buttons were added, do not add the toolbar
1995
+ if (!buttonIndex) {
1996
+ return;
1997
+ }
1998
+
1999
+ // Save button index of the last button, -1 as we would have ++ after the last button
2000
+ this._lastButtonIndex = --buttonIndex;
2001
+
2002
+ // Create empty actions part of the toolbar
2003
+ this._actionsContainer = L.DomUtil.create('ul', 'leaflet-draw-actions');
2004
+
2005
+ // Add draw and cancel containers to the control container
2006
+ container.appendChild(this._toolbarContainer);
2007
+ container.appendChild(this._actionsContainer);
2008
+
2009
+ return container;
2010
+ },
2011
+
2012
+ removeToolbar: function () {
2013
+ // Dispose each handler
2014
+ for (var handlerId in this._modes) {
2015
+ if (this._modes.hasOwnProperty(handlerId)) {
2016
+ // Unbind handler button
2017
+ this._disposeButton(
2018
+ this._modes[handlerId].button,
2019
+ this._modes[handlerId].handler.enable,
2020
+ this._modes[handlerId].handler
2021
+ );
2022
+
2023
+ // Make sure is disabled
2024
+ this._modes[handlerId].handler.disable();
2025
+
2026
+ // Unbind handler
2027
+ this._modes[handlerId].handler
2028
+ .off('enabled', this._handlerActivated, this)
2029
+ .off('disabled', this._handlerDeactivated, this);
2030
+ }
2031
+ }
2032
+ this._modes = {};
2033
+
2034
+ // Dispose the actions toolbar
2035
+ for (var i = 0, l = this._actionButtons.length; i < l; i++) {
2036
+ this._disposeButton(
2037
+ this._actionButtons[i].button,
2038
+ this._actionButtons[i].callback,
2039
+ this
2040
+ );
2041
+ }
2042
+ this._actionButtons = [];
2043
+ this._actionsContainer = null;
2044
+ },
2045
+
2046
+ _initModeHandler: function (handler, container, buttonIndex, classNamePredix, buttonTitle) {
2047
+ var type = handler.type;
2048
+
2049
+ this._modes[type] = {};
2050
+
2051
+ this._modes[type].handler = handler;
2052
+
2053
+ this._modes[type].button = this._createButton({
2054
+ title: buttonTitle,
2055
+ className: classNamePredix + '-' + type,
2056
+ container: container,
2057
+ callback: this._modes[type].handler.enable,
2058
+ context: this._modes[type].handler
2059
+ });
2060
+
2061
+ this._modes[type].buttonIndex = buttonIndex;
2062
+
2063
+ this._modes[type].handler
2064
+ .on('enabled', this._handlerActivated, this)
2065
+ .on('disabled', this._handlerDeactivated, this);
2066
+ },
2067
+
2068
+ _createButton: function (options) {
2069
+ var link = L.DomUtil.create('a', options.className || '', options.container);
2070
+ link.href = '#';
2071
+
2072
+ if (options.text) {
2073
+ link.innerHTML = options.text;
2074
+ }
2075
+
2076
+ if (options.title) {
2077
+ link.title = options.title;
2078
+ }
2079
+
2080
+ L.DomEvent
2081
+ .on(link, 'click', L.DomEvent.stopPropagation)
2082
+ .on(link, 'mousedown', L.DomEvent.stopPropagation)
2083
+ .on(link, 'dblclick', L.DomEvent.stopPropagation)
2084
+ .on(link, 'click', L.DomEvent.preventDefault)
2085
+ .on(link, 'click', options.callback, options.context);
2086
+
2087
+ return link;
2088
+ },
2089
+
2090
+ _disposeButton: function (button, callback) {
2091
+ L.DomEvent
2092
+ .off(button, 'click', L.DomEvent.stopPropagation)
2093
+ .off(button, 'mousedown', L.DomEvent.stopPropagation)
2094
+ .off(button, 'dblclick', L.DomEvent.stopPropagation)
2095
+ .off(button, 'click', L.DomEvent.preventDefault)
2096
+ .off(button, 'click', callback);
2097
+ },
2098
+
2099
+ _handlerActivated: function (e) {
2100
+ // Disable active mode (if present)
2101
+ this.disable();
2102
+
2103
+ // Cache new active feature
2104
+ this._activeMode = this._modes[e.handler];
2105
+
2106
+ L.DomUtil.addClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
2107
+
2108
+ this._showActionsToolbar();
2109
+
2110
+ this.fire('enable');
2111
+ },
2112
+
2113
+ _handlerDeactivated: function () {
2114
+ this._hideActionsToolbar();
2115
+
2116
+ L.DomUtil.removeClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
2117
+
2118
+ this._activeMode = null;
2119
+
2120
+ this.fire('disable');
2121
+ },
2122
+
2123
+ _createActions: function (handler) {
2124
+ var container = this._actionsContainer,
2125
+ buttons = this.getActions(handler),
2126
+ l = buttons.length,
2127
+ li, di, dl, button;
2128
+
2129
+ // Dispose the actions toolbar (todo: dispose only not used buttons)
2130
+ for (di = 0, dl = this._actionButtons.length; di < dl; di++) {
2131
+ this._disposeButton(this._actionButtons[di].button, this._actionButtons[di].callback);
2132
+ }
2133
+ this._actionButtons = [];
2134
+
2135
+ // Remove all old buttons
2136
+ while (container.firstChild) {
2137
+ container.removeChild(container.firstChild);
2138
+ }
2139
+
2140
+ for (var i = 0; i < l; i++) {
2141
+ if ('enabled' in buttons[i] && !buttons[i].enabled) {
2142
+ continue;
2143
+ }
2144
+
2145
+ li = L.DomUtil.create('li', '', container);
2146
+
2147
+ button = this._createButton({
2148
+ title: buttons[i].title,
2149
+ text: buttons[i].text,
2150
+ container: li,
2151
+ callback: buttons[i].callback,
2152
+ context: buttons[i].context
2153
+ });
2154
+
2155
+ this._actionButtons.push({
2156
+ button: button,
2157
+ callback: buttons[i].callback
2158
+ });
2159
+ }
2160
+ },
2161
+
2162
+ _showActionsToolbar: function () {
2163
+ var buttonIndex = this._activeMode.buttonIndex,
2164
+ lastButtonIndex = this._lastButtonIndex,
2165
+ toolbarPosition = this._activeMode.button.offsetTop - 1;
2166
+
2167
+ // Recreate action buttons on every click
2168
+ this._createActions(this._activeMode.handler);
2169
+
2170
+ // Correctly position the cancel button
2171
+ this._actionsContainer.style.top = toolbarPosition + 'px';
2172
+
2173
+ if (buttonIndex === 0) {
2174
+ L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
2175
+ L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-top');
2176
+ }
2177
+
2178
+ if (buttonIndex === lastButtonIndex) {
2179
+ L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
2180
+ L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
2181
+ }
2182
+
2183
+ this._actionsContainer.style.display = 'block';
2184
+ },
2185
+
2186
+ _hideActionsToolbar: function () {
2187
+ this._actionsContainer.style.display = 'none';
2188
+
2189
+ L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
2190
+ L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
2191
+ L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-top');
2192
+ L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
2193
+ }
2194
+ });
2195
+
2196
+
2197
+ L.Tooltip = L.Class.extend({
2198
+ initialize: function (map) {
2199
+ this._map = map;
2200
+ this._popupPane = map._panes.popupPane;
2201
+
2202
+ this._container = map.options.drawControlTooltips ? L.DomUtil.create('div', 'leaflet-draw-tooltip', this._popupPane) : null;
2203
+ this._singleLineLabel = false;
2204
+ },
2205
+
2206
+ dispose: function () {
2207
+ if (this._container) {
2208
+ this._popupPane.removeChild(this._container);
2209
+ this._container = null;
2210
+ }
2211
+ },
2212
+
2213
+ updateContent: function (labelText) {
2214
+ if (!this._container) {
2215
+ return this;
2216
+ }
2217
+ labelText.subtext = labelText.subtext || '';
2218
+
2219
+ // update the vertical position (only if changed)
2220
+ if (labelText.subtext.length === 0 && !this._singleLineLabel) {
2221
+ L.DomUtil.addClass(this._container, 'leaflet-draw-tooltip-single');
2222
+ this._singleLineLabel = true;
2223
+ }
2224
+ else if (labelText.subtext.length > 0 && this._singleLineLabel) {
2225
+ L.DomUtil.removeClass(this._container, 'leaflet-draw-tooltip-single');
2226
+ this._singleLineLabel = false;
2227
+ }
2228
+
2229
+ this._container.innerHTML =
2230
+ (labelText.subtext.length > 0 ? '<span class="leaflet-draw-tooltip-subtext">' + labelText.subtext + '</span>' + '<br />' : '') +
2231
+ '<span>' + labelText.text + '</span>';
2232
+
2233
+ return this;
2234
+ },
2235
+
2236
+ updatePosition: function (latlng) {
2237
+ var pos = this._map.latLngToLayerPoint(latlng),
2238
+ tooltipContainer = this._container;
2239
+
2240
+ if (this._container) {
2241
+ tooltipContainer.style.visibility = 'inherit';
2242
+ L.DomUtil.setPosition(tooltipContainer, pos);
2243
+ }
2244
+
2245
+ return this;
2246
+ },
2247
+
2248
+ showAsError: function () {
2249
+ if (this._container) {
2250
+ L.DomUtil.addClass(this._container, 'leaflet-error-draw-tooltip');
2251
+ }
2252
+ return this;
2253
+ },
2254
+
2255
+ removeError: function () {
2256
+ if (this._container) {
2257
+ L.DomUtil.removeClass(this._container, 'leaflet-error-draw-tooltip');
2258
+ }
2259
+ return this;
2260
+ }
2261
+ });
2262
+
2263
+ L.DrawToolbar = L.Toolbar.extend({
2264
+
2265
+ options: {
2266
+ polyline: {},
2267
+ polygon: {},
2268
+ rectangle: {},
2269
+ circle: {},
2270
+ marker: {}
2271
+ },
2272
+
2273
+ initialize: function (options) {
2274
+ // Ensure that the options are merged correctly since L.extend is only shallow
2275
+ for (var type in this.options) {
2276
+ if (this.options.hasOwnProperty(type)) {
2277
+ if (options[type]) {
2278
+ options[type] = L.extend({}, this.options[type], options[type]);
2279
+ }
2280
+ }
2281
+ }
2282
+
2283
+ this._toolbarClass = 'leaflet-draw-draw';
2284
+ L.Toolbar.prototype.initialize.call(this, options);
2285
+ },
2286
+
2287
+ getModeHandlers: function (map) {
2288
+ return [
2289
+ {
2290
+ enabled: this.options.polyline,
2291
+ handler: new L.Draw.Polyline(map, this.options.polyline),
2292
+ title: L.drawLocal.draw.toolbar.buttons.polyline
2293
+ },
2294
+ {
2295
+ enabled: this.options.polygon,
2296
+ handler: new L.Draw.Polygon(map, this.options.polygon),
2297
+ title: L.drawLocal.draw.toolbar.buttons.polygon
2298
+ },
2299
+ {
2300
+ enabled: this.options.rectangle,
2301
+ handler: new L.Draw.Rectangle(map, this.options.rectangle),
2302
+ title: L.drawLocal.draw.toolbar.buttons.rectangle
2303
+ },
2304
+ {
2305
+ enabled: this.options.circle,
2306
+ handler: new L.Draw.Circle(map, this.options.circle),
2307
+ title: L.drawLocal.draw.toolbar.buttons.circle
2308
+ },
2309
+ {
2310
+ enabled: this.options.marker,
2311
+ handler: new L.Draw.Marker(map, this.options.marker),
2312
+ title: L.drawLocal.draw.toolbar.buttons.marker
2313
+ }
2314
+ ];
2315
+ },
2316
+
2317
+ // Get the actions part of the toolbar
2318
+ getActions: function (handler) {
2319
+ return [
2320
+ {
2321
+ enabled: handler.deleteLastVertex,
2322
+ title: L.drawLocal.draw.toolbar.undo.title,
2323
+ text: L.drawLocal.draw.toolbar.undo.text,
2324
+ callback: handler.deleteLastVertex,
2325
+ context: handler
2326
+ },
2327
+ {
2328
+ title: L.drawLocal.draw.toolbar.actions.title,
2329
+ text: L.drawLocal.draw.toolbar.actions.text,
2330
+ callback: this.disable,
2331
+ context: this
2332
+ }
2333
+ ];
2334
+ },
2335
+
2336
+ setOptions: function (options) {
2337
+ L.setOptions(this, options);
2338
+
2339
+ for (var type in this._modes) {
2340
+ if (this._modes.hasOwnProperty(type) && options.hasOwnProperty(type)) {
2341
+ this._modes[type].handler.setOptions(options[type]);
2342
+ }
2343
+ }
2344
+ }
2345
+ });
2346
+
2347
+
2348
+ /*L.Map.mergeOptions({
2349
+ editControl: true
2350
+ });*/
2351
+
2352
+ L.EditToolbar = L.Toolbar.extend({
2353
+ options: {
2354
+ edit: {
2355
+ selectedPathOptions: {
2356
+ color: '#fe57a1', /* Hot pink all the things! */
2357
+ opacity: 0.6,
2358
+ dashArray: '10, 10',
2359
+
2360
+ fill: true,
2361
+ fillColor: '#fe57a1',
2362
+ fillOpacity: 0.1
2363
+ }
2364
+ },
2365
+ remove: {},
2366
+ featureGroup: null /* REQUIRED! TODO: perhaps if not set then all layers on the map are selectable? */
2367
+ },
2368
+
2369
+ initialize: function (options) {
2370
+ // Need to set this manually since null is an acceptable value here
2371
+ if (options.edit) {
2372
+ if (typeof options.edit.selectedPathOptions === 'undefined') {
2373
+ options.edit.selectedPathOptions = this.options.edit.selectedPathOptions;
2374
+ }
2375
+ options.edit = L.extend({}, this.options.edit, options.edit);
2376
+ }
2377
+
2378
+ if (options.remove) {
2379
+ options.remove = L.extend({}, this.options.remove, options.remove);
2380
+ }
2381
+
2382
+ this._toolbarClass = 'leaflet-draw-edit';
2383
+ L.Toolbar.prototype.initialize.call(this, options);
2384
+
2385
+ this._selectedFeatureCount = 0;
2386
+ },
2387
+
2388
+ getModeHandlers: function (map) {
2389
+ var featureGroup = this.options.featureGroup;
2390
+ return [
2391
+ {
2392
+ enabled: this.options.edit,
2393
+ handler: new L.EditToolbar.Edit(map, {
2394
+ featureGroup: featureGroup,
2395
+ selectedPathOptions: this.options.edit.selectedPathOptions
2396
+ }),
2397
+ title: L.drawLocal.edit.toolbar.buttons.edit
2398
+ },
2399
+ {
2400
+ enabled: this.options.remove,
2401
+ handler: new L.EditToolbar.Delete(map, {
2402
+ featureGroup: featureGroup
2403
+ }),
2404
+ title: L.drawLocal.edit.toolbar.buttons.remove
2405
+ }
2406
+ ];
2407
+ },
2408
+
2409
+ getActions: function () {
2410
+ return [
2411
+ {
2412
+ title: L.drawLocal.edit.toolbar.actions.save.title,
2413
+ text: L.drawLocal.edit.toolbar.actions.save.text,
2414
+ callback: this._save,
2415
+ context: this
2416
+ },
2417
+ {
2418
+ title: L.drawLocal.edit.toolbar.actions.cancel.title,
2419
+ text: L.drawLocal.edit.toolbar.actions.cancel.text,
2420
+ callback: this.disable,
2421
+ context: this
2422
+ }
2423
+ ];
2424
+ },
2425
+
2426
+ addToolbar: function (map) {
2427
+ var container = L.Toolbar.prototype.addToolbar.call(this, map);
2428
+
2429
+ this._checkDisabled();
2430
+
2431
+ this.options.featureGroup.on('layeradd layerremove', this._checkDisabled, this);
2432
+
2433
+ return container;
2434
+ },
2435
+
2436
+ removeToolbar: function () {
2437
+ this.options.featureGroup.off('layeradd layerremove', this._checkDisabled, this);
2438
+
2439
+ L.Toolbar.prototype.removeToolbar.call(this);
2440
+ },
2441
+
2442
+ disable: function () {
2443
+ if (!this.enabled()) { return; }
2444
+
2445
+ this._activeMode.handler.revertLayers();
2446
+
2447
+ L.Toolbar.prototype.disable.call(this);
2448
+ },
2449
+
2450
+ _save: function () {
2451
+ this._activeMode.handler.save();
2452
+ this._activeMode.handler.disable();
2453
+ },
2454
+
2455
+ _checkDisabled: function () {
2456
+ var featureGroup = this.options.featureGroup,
2457
+ hasLayers = featureGroup.getLayers().length !== 0,
2458
+ button;
2459
+
2460
+ if (this.options.edit) {
2461
+ button = this._modes[L.EditToolbar.Edit.TYPE].button;
2462
+
2463
+ if (hasLayers) {
2464
+ L.DomUtil.removeClass(button, 'leaflet-disabled');
2465
+ } else {
2466
+ L.DomUtil.addClass(button, 'leaflet-disabled');
2467
+ }
2468
+
2469
+ button.setAttribute(
2470
+ 'title',
2471
+ hasLayers ?
2472
+ L.drawLocal.edit.toolbar.buttons.edit
2473
+ : L.drawLocal.edit.toolbar.buttons.editDisabled
2474
+ );
2475
+ }
2476
+
2477
+ if (this.options.remove) {
2478
+ button = this._modes[L.EditToolbar.Delete.TYPE].button;
2479
+
2480
+ if (hasLayers) {
2481
+ L.DomUtil.removeClass(button, 'leaflet-disabled');
2482
+ } else {
2483
+ L.DomUtil.addClass(button, 'leaflet-disabled');
2484
+ }
2485
+
2486
+ button.setAttribute(
2487
+ 'title',
2488
+ hasLayers ?
2489
+ L.drawLocal.edit.toolbar.buttons.remove
2490
+ : L.drawLocal.edit.toolbar.buttons.removeDisabled
2491
+ );
2492
+ }
2493
+ }
2494
+ });
2495
+
2496
+
2497
+ L.EditToolbar.Edit = L.Handler.extend({
2498
+ statics: {
2499
+ TYPE: 'edit'
2500
+ },
2501
+
2502
+ includes: L.Mixin.Events,
2503
+
2504
+ initialize: function (map, options) {
2505
+ L.Handler.prototype.initialize.call(this, map);
2506
+
2507
+ // Set options to the default unless already set
2508
+ this._selectedPathOptions = options.selectedPathOptions;
2509
+
2510
+ // Store the selectable layer group for ease of access
2511
+ this._featureGroup = options.featureGroup;
2512
+
2513
+ if (!(this._featureGroup instanceof L.FeatureGroup)) {
2514
+ throw new Error('options.featureGroup must be a L.FeatureGroup');
2515
+ }
2516
+
2517
+ this._uneditedLayerProps = {};
2518
+
2519
+ // Save the type so super can fire, need to do this as cannot do this.TYPE :(
2520
+ this.type = L.EditToolbar.Edit.TYPE;
2521
+ },
2522
+
2523
+ enable: function () {
2524
+ if (this._enabled || !this._hasAvailableLayers()) {
2525
+ return;
2526
+ }
2527
+ this.fire('enabled', {handler: this.type});
2528
+ //this disable other handlers
2529
+
2530
+ this._map.fire('draw:editstart', { handler: this.type });
2531
+ //allow drawLayer to be updated before beginning edition.
2532
+
2533
+ L.Handler.prototype.enable.call(this);
2534
+ this._featureGroup
2535
+ .on('layeradd', this._enableLayerEdit, this)
2536
+ .on('layerremove', this._disableLayerEdit, this);
2537
+ },
2538
+
2539
+ disable: function () {
2540
+ if (!this._enabled) { return; }
2541
+ this._featureGroup
2542
+ .off('layeradd', this._enableLayerEdit, this)
2543
+ .off('layerremove', this._disableLayerEdit, this);
2544
+ L.Handler.prototype.disable.call(this);
2545
+ this._map.fire('draw:editstop', { handler: this.type });
2546
+ this.fire('disabled', {handler: this.type});
2547
+ },
2548
+
2549
+ addHooks: function () {
2550
+ var map = this._map;
2551
+
2552
+ if (map) {
2553
+ map.getContainer().focus();
2554
+
2555
+ this._featureGroup.eachLayer(this._enableLayerEdit, this);
2556
+
2557
+ this._tooltip = new L.Tooltip(this._map);
2558
+ this._tooltip.updateContent({
2559
+ text: L.drawLocal.edit.handlers.edit.tooltip.text,
2560
+ subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
2561
+ });
2562
+
2563
+ this._map.on('mousemove', this._onMouseMove, this);
2564
+ }
2565
+ },
2566
+
2567
+ removeHooks: function () {
2568
+ if (this._map) {
2569
+ // Clean up selected layers.
2570
+ this._featureGroup.eachLayer(this._disableLayerEdit, this);
2571
+
2572
+ // Clear the backups of the original layers
2573
+ this._uneditedLayerProps = {};
2574
+
2575
+ this._tooltip.dispose();
2576
+ this._tooltip = null;
2577
+
2578
+ this._map.off('mousemove', this._onMouseMove, this);
2579
+ }
2580
+ },
2581
+
2582
+ revertLayers: function () {
2583
+ this._featureGroup.eachLayer(function (layer) {
2584
+ this._revertLayer(layer);
2585
+ }, this);
2586
+ },
2587
+
2588
+ save: function () {
2589
+ var editedLayers = new L.LayerGroup();
2590
+ this._featureGroup.eachLayer(function (layer) {
2591
+ if (layer.edited) {
2592
+ editedLayers.addLayer(layer);
2593
+ layer.edited = false;
2594
+ }
2595
+ });
2596
+ this._map.fire('draw:edited', {layers: editedLayers});
2597
+ },
2598
+
2599
+ _backupLayer: function (layer) {
2600
+ var id = L.Util.stamp(layer);
2601
+
2602
+ if (!this._uneditedLayerProps[id]) {
2603
+ // Polyline, Polygon or Rectangle
2604
+ if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) {
2605
+ this._uneditedLayerProps[id] = {
2606
+ latlngs: L.LatLngUtil.cloneLatLngs(layer.getLatLngs())
2607
+ };
2608
+ } else if (layer instanceof L.Circle) {
2609
+ this._uneditedLayerProps[id] = {
2610
+ latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()),
2611
+ radius: layer.getRadius()
2612
+ };
2613
+ } else if (layer instanceof L.Marker) { // Marker
2614
+ this._uneditedLayerProps[id] = {
2615
+ latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng())
2616
+ };
2617
+ }
2618
+ }
2619
+ },
2620
+
2621
+ _revertLayer: function (layer) {
2622
+ var id = L.Util.stamp(layer);
2623
+ layer.edited = false;
2624
+ if (this._uneditedLayerProps.hasOwnProperty(id)) {
2625
+ // Polyline, Polygon or Rectangle
2626
+ if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) {
2627
+ layer.setLatLngs(this._uneditedLayerProps[id].latlngs);
2628
+ } else if (layer instanceof L.Circle) {
2629
+ layer.setLatLng(this._uneditedLayerProps[id].latlng);
2630
+ layer.setRadius(this._uneditedLayerProps[id].radius);
2631
+ } else if (layer instanceof L.Marker) { // Marker
2632
+ layer.setLatLng(this._uneditedLayerProps[id].latlng);
2633
+ }
2634
+ }
2635
+ },
2636
+
2637
+ _toggleMarkerHighlight: function (marker) {
2638
+ if (!marker._icon) {
2639
+ return;
2640
+ }
2641
+ // This is quite naughty, but I don't see another way of doing it. (short of setting a new icon)
2642
+ var icon = marker._icon;
2643
+
2644
+ icon.style.display = 'none';
2645
+
2646
+ if (L.DomUtil.hasClass(icon, 'leaflet-edit-marker-selected')) {
2647
+ L.DomUtil.removeClass(icon, 'leaflet-edit-marker-selected');
2648
+ // Offset as the border will make the icon move.
2649
+ this._offsetMarker(icon, -4);
2650
+
2651
+ } else {
2652
+ L.DomUtil.addClass(icon, 'leaflet-edit-marker-selected');
2653
+ // Offset as the border will make the icon move.
2654
+ this._offsetMarker(icon, 4);
2655
+ }
2656
+
2657
+ icon.style.display = '';
2658
+ },
2659
+
2660
+ _offsetMarker: function (icon, offset) {
2661
+ var iconMarginTop = parseInt(icon.style.marginTop, 10) - offset,
2662
+ iconMarginLeft = parseInt(icon.style.marginLeft, 10) - offset;
2663
+
2664
+ icon.style.marginTop = iconMarginTop + 'px';
2665
+ icon.style.marginLeft = iconMarginLeft + 'px';
2666
+ },
2667
+
2668
+ _enableLayerEdit: function (e) {
2669
+ var layer = e.layer || e.target || e,
2670
+ isMarker = layer instanceof L.Marker,
2671
+ pathOptions;
2672
+
2673
+ // Don't do anything if this layer is a marker but doesn't have an icon. Markers
2674
+ // should usually have icons. If using Leaflet.draw with Leafler.markercluster there
2675
+ // is a chance that a marker doesn't.
2676
+ if (isMarker && !layer._icon) {
2677
+ return;
2678
+ }
2679
+
2680
+ // Back up this layer (if haven't before)
2681
+ this._backupLayer(layer);
2682
+
2683
+ // Update layer style so appears editable
2684
+ if (this._selectedPathOptions) {
2685
+ pathOptions = L.Util.extend({}, this._selectedPathOptions);
2686
+
2687
+ if (isMarker) {
2688
+ this._toggleMarkerHighlight(layer);
2689
+ } else {
2690
+ layer.options.previousOptions = L.Util.extend({ dashArray: null }, layer.options);
2691
+
2692
+ // Make sure that Polylines are not filled
2693
+ if (!(layer instanceof L.Circle) && !(layer instanceof L.Polygon) && !(layer instanceof L.Rectangle)) {
2694
+ pathOptions.fill = false;
2695
+ }
2696
+
2697
+ layer.setStyle(pathOptions);
2698
+ }
2699
+ }
2700
+
2701
+ if (isMarker) {
2702
+ layer.dragging.enable();
2703
+ layer.on('dragend', this._onMarkerDragEnd);
2704
+ } else {
2705
+ layer.editing.enable();
2706
+ }
2707
+ },
2708
+
2709
+ _disableLayerEdit: function (e) {
2710
+ var layer = e.layer || e.target || e;
2711
+ layer.edited = false;
2712
+
2713
+ // Reset layer styles to that of before select
2714
+ if (this._selectedPathOptions) {
2715
+ if (layer instanceof L.Marker) {
2716
+ this._toggleMarkerHighlight(layer);
2717
+ } else {
2718
+ // reset the layer style to what is was before being selected
2719
+ layer.setStyle(layer.options.previousOptions);
2720
+ // remove the cached options for the layer object
2721
+ delete layer.options.previousOptions;
2722
+ }
2723
+ }
2724
+
2725
+ if (layer instanceof L.Marker) {
2726
+ layer.dragging.disable();
2727
+ layer.off('dragend', this._onMarkerDragEnd, this);
2728
+ } else {
2729
+ layer.editing.disable();
2730
+ }
2731
+ },
2732
+
2733
+ _onMarkerDragEnd: function (e) {
2734
+ var layer = e.target;
2735
+ layer.edited = true;
2736
+ },
2737
+
2738
+ _onMouseMove: function (e) {
2739
+ this._tooltip.updatePosition(e.latlng);
2740
+ },
2741
+
2742
+ _hasAvailableLayers: function () {
2743
+ return this._featureGroup.getLayers().length !== 0;
2744
+ }
2745
+ });
2746
+
2747
+
2748
+ L.EditToolbar.Delete = L.Handler.extend({
2749
+ statics: {
2750
+ TYPE: 'remove' // not delete as delete is reserved in js
2751
+ },
2752
+
2753
+ includes: L.Mixin.Events,
2754
+
2755
+ initialize: function (map, options) {
2756
+ L.Handler.prototype.initialize.call(this, map);
2757
+
2758
+ L.Util.setOptions(this, options);
2759
+
2760
+ // Store the selectable layer group for ease of access
2761
+ this._deletableLayers = this.options.featureGroup;
2762
+
2763
+ if (!(this._deletableLayers instanceof L.FeatureGroup)) {
2764
+ throw new Error('options.featureGroup must be a L.FeatureGroup');
2765
+ }
2766
+
2767
+ // Save the type so super can fire, need to do this as cannot do this.TYPE :(
2768
+ this.type = L.EditToolbar.Delete.TYPE;
2769
+ },
2770
+
2771
+ enable: function () {
2772
+ if (this._enabled || !this._hasAvailableLayers()) {
2773
+ return;
2774
+ }
2775
+ this.fire('enabled', { handler: this.type});
2776
+
2777
+ this._map.fire('draw:deletestart', { handler: this.type });
2778
+
2779
+ L.Handler.prototype.enable.call(this);
2780
+
2781
+ this._deletableLayers
2782
+ .on('layeradd', this._enableLayerDelete, this)
2783
+ .on('layerremove', this._disableLayerDelete, this);
2784
+ },
2785
+
2786
+ disable: function () {
2787
+ if (!this._enabled) { return; }
2788
+
2789
+ this._deletableLayers
2790
+ .off('layeradd', this._enableLayerDelete, this)
2791
+ .off('layerremove', this._disableLayerDelete, this);
2792
+
2793
+ L.Handler.prototype.disable.call(this);
2794
+
2795
+ this._map.fire('draw:deletestop', { handler: this.type });
2796
+
2797
+ this.fire('disabled', { handler: this.type});
2798
+ },
2799
+
2800
+ addHooks: function () {
2801
+ var map = this._map;
2802
+
2803
+ if (map) {
2804
+ map.getContainer().focus();
2805
+
2806
+ this._deletableLayers.eachLayer(this._enableLayerDelete, this);
2807
+ this._deletedLayers = new L.layerGroup();
2808
+
2809
+ this._tooltip = new L.Tooltip(this._map);
2810
+ this._tooltip.updateContent({ text: L.drawLocal.edit.handlers.remove.tooltip.text });
2811
+
2812
+ this._map.on('mousemove', this._onMouseMove, this);
2813
+ }
2814
+ },
2815
+
2816
+ removeHooks: function () {
2817
+ if (this._map) {
2818
+ this._deletableLayers.eachLayer(this._disableLayerDelete, this);
2819
+ this._deletedLayers = null;
2820
+
2821
+ this._tooltip.dispose();
2822
+ this._tooltip = null;
2823
+
2824
+ this._map.off('mousemove', this._onMouseMove, this);
2825
+ }
2826
+ },
2827
+
2828
+ revertLayers: function () {
2829
+ // Iterate of the deleted layers and add them back into the featureGroup
2830
+ this._deletedLayers.eachLayer(function (layer) {
2831
+ this._deletableLayers.addLayer(layer);
2832
+ }, this);
2833
+ },
2834
+
2835
+ save: function () {
2836
+ this._map.fire('draw:deleted', { layers: this._deletedLayers });
2837
+ },
2838
+
2839
+ _enableLayerDelete: function (e) {
2840
+ var layer = e.layer || e.target || e;
2841
+
2842
+ layer.on('click', this._removeLayer, this);
2843
+ },
2844
+
2845
+ _disableLayerDelete: function (e) {
2846
+ var layer = e.layer || e.target || e;
2847
+
2848
+ layer.off('click', this._removeLayer, this);
2849
+
2850
+ // Remove from the deleted layers so we can't accidently revert if the user presses cancel
2851
+ this._deletedLayers.removeLayer(layer);
2852
+ },
2853
+
2854
+ _removeLayer: function (e) {
2855
+ var layer = e.layer || e.target || e;
2856
+
2857
+ this._deletableLayers.removeLayer(layer);
2858
+
2859
+ this._deletedLayers.addLayer(layer);
2860
+ },
2861
+
2862
+ _onMouseMove: function (e) {
2863
+ this._tooltip.updatePosition(e.latlng);
2864
+ },
2865
+
2866
+ _hasAvailableLayers: function () {
2867
+ return this._deletableLayers.getLayers().length !== 0;
2868
+ }
2869
+ });
2870
+
2871
+
2872
+ }(window, document));