├── .gitignore ├── LICENSE.txt ├── MANIFEST ├── MANIFEST.in ├── README.md ├── UPLOAD_NOTES.txt ├── docs ├── Makefile ├── make.bat └── source │ ├── _templates │ └── nav.rst │ ├── api-docs.rst │ ├── conf.py │ ├── contributing.rst │ ├── examples.rst │ ├── getting-started.rst │ ├── index.rst │ ├── maps_are_beautiful.jpg │ ├── maps_are_beautiful2.jpg │ ├── navigation.rst │ ├── technical.rst │ ├── trial.rst │ └── tutorials.rst ├── pyqtlet ├── __init__.py ├── leaflet │ ├── __init__.py │ ├── control │ │ ├── __init__.py │ │ ├── control.py │ │ ├── draw.py │ │ └── layers.py │ ├── core │ │ ├── __init__.py │ │ └── evented.py │ ├── layer │ │ ├── __init__.py │ │ ├── featuregroup.py │ │ ├── imageoverlay.py │ │ ├── layer.py │ │ ├── layergroup.py │ │ ├── marker │ │ │ ├── __init__.py │ │ │ └── marker.py │ │ ├── tile │ │ │ ├── __init__.py │ │ │ ├── gridlayer.py │ │ │ └── tilelayer.py │ │ └── vector │ │ │ ├── __init__.py │ │ │ ├── circle.py │ │ │ ├── circlemarker.py │ │ │ ├── path.py │ │ │ ├── polygon.py │ │ │ ├── polyline.py │ │ │ └── rectangle.py │ └── map │ │ ├── __init__.py │ │ └── map.py ├── mapwidget.py └── web │ ├── custom.js │ ├── map.html │ └── modules │ ├── leaflet_134 │ ├── images │ │ ├── layers-2x.png │ │ ├── layers.png │ │ ├── marker-icon-2x.png │ │ ├── marker-icon.png │ │ └── marker-shadow.png │ ├── leaflet-src.esm.js │ ├── leaflet-src.esm.js.map │ ├── leaflet-src.js │ ├── leaflet-src.js.map │ ├── leaflet.css │ ├── leaflet.js │ └── leaflet.js.map │ └── leaflet_draw_104 │ ├── .codeclimate.yml │ ├── .editorconfig │ ├── .eslintrc │ ├── .gitattributes │ ├── .gitignore │ ├── .travis.yml │ ├── BREAKINGCHANGES.md │ ├── CHANGELOG.md │ ├── ISSUE_TEMPLATE.md │ ├── Jakefile.js │ ├── MIT-LICENSE.md │ ├── README.md │ ├── TODO.md │ ├── build │ ├── build.html │ ├── build.js │ ├── deps.js │ ├── docs-index.leafdoc │ ├── docs-misc.leafdoc │ ├── docs.js │ ├── hintrc.json │ ├── leafdoc-templates │ │ ├── comments.hbs │ │ ├── constructor.hbs │ │ ├── crs.hbs │ │ ├── destructor.hbs │ │ ├── event.hbs │ │ ├── example.hbs │ │ ├── factory.hbs │ │ ├── function.hbs │ │ ├── html.hbs │ │ ├── inherited.hbs │ │ ├── method.hbs │ │ ├── namespace.hbs │ │ ├── option.hbs │ │ ├── pane.hbs │ │ ├── projection.hbs │ │ ├── property.hbs │ │ ├── section.hbs │ │ └── supersection.hbs │ ├── leaflet.draw-include.js │ └── publish.sh │ ├── dist │ ├── images │ │ ├── layers-2x.png │ │ ├── layers.png │ │ ├── marker-icon-2x.png │ │ ├── marker-icon.png │ │ ├── marker-shadow.png │ │ ├── spritesheet-2x.png │ │ ├── spritesheet.png │ │ └── spritesheet.svg │ ├── leaflet.draw-src.css │ ├── leaflet.draw-src.js │ ├── leaflet.draw-src.map │ ├── leaflet.draw.css │ └── leaflet.draw.js │ ├── docs │ ├── css │ │ ├── main.css │ │ └── normalize.css │ ├── examples-0.7.x │ │ ├── basic.html │ │ ├── edithandlers.html │ │ ├── full.html │ │ ├── libs │ │ │ ├── Leaflet.draw.drag-src.js │ │ │ ├── images │ │ │ │ ├── layers-2x.png │ │ │ │ ├── layers.png │ │ │ │ ├── marker-icon-2x.png │ │ │ │ ├── marker-icon.png │ │ │ │ ├── marker-icon@2x.png │ │ │ │ └── marker-shadow.png │ │ │ ├── leaflet-src.js │ │ │ ├── leaflet.css │ │ │ ├── leaflet.geometryutil.js │ │ │ ├── leaflet.snap.js │ │ │ ├── spectrum.css │ │ │ └── spectrum.js │ │ └── snapping.html │ ├── examples │ │ ├── basic.html │ │ ├── edithandlers.html │ │ ├── full.html │ │ ├── libs │ │ │ ├── Leaflet.draw.drag-src.js │ │ │ ├── images │ │ │ │ ├── layers-2x.png │ │ │ │ ├── layers.png │ │ │ │ ├── marker-icon-2x.png │ │ │ │ ├── marker-icon.png │ │ │ │ └── marker-shadow.png │ │ │ ├── leaflet-src.js │ │ │ ├── leaflet-src.map │ │ │ ├── leaflet.css │ │ │ ├── leaflet.geometryutil.js │ │ │ ├── leaflet.snap.js │ │ │ ├── spectrum.css │ │ │ └── spectrum.js │ │ ├── popup.html │ │ └── snapping.html │ ├── highlight │ │ ├── LICENSE │ │ ├── highlight.pack.js │ │ └── styles │ │ │ └── github-gist.css │ ├── images │ │ ├── favicon.ico │ │ ├── forum-round.png │ │ ├── github-round.png │ │ ├── sprite.png │ │ ├── sprite.svg │ │ ├── twitter-round.png │ │ └── twitter.png │ ├── js │ │ └── docs.js │ ├── leaflet-draw-0.4.12.html │ ├── leaflet-draw-0.4.14.html │ ├── leaflet-draw-0.4.2.html │ ├── leaflet-draw-0.4.3.html │ ├── leaflet-draw-0.4.4.html │ ├── leaflet-draw-0.4.5.html │ ├── leaflet-draw-0.4.7.html │ ├── leaflet-draw-0.4.9.html │ ├── leaflet-draw-1.0.0.html │ ├── leaflet-draw-1.0.1.html │ └── leaflet-draw-latest.html │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── spec │ ├── after.js │ ├── before.js │ ├── expect.js │ ├── happen.js │ ├── index.html │ ├── karma.conf.js │ ├── sinon.js │ ├── spec.hintrc.js │ └── suites │ │ ├── DrawControlSpec.js │ │ ├── EditSpec.js │ │ ├── GeometryUtilSpec.js │ │ ├── LatLngUtilSpec.js │ │ └── SpecHelper.js │ └── src │ ├── Control.Draw.js │ ├── Leaflet.Draw.Event.js │ ├── Leaflet.draw.js │ ├── Toolbar.js │ ├── Tooltip.js │ ├── copyright.js │ ├── draw │ ├── DrawToolbar.js │ └── handler │ │ ├── Draw.Circle.js │ │ ├── Draw.CircleMarker.js │ │ ├── Draw.Feature.js │ │ ├── Draw.Marker.js │ │ ├── Draw.Polygon.js │ │ ├── Draw.Polyline.js │ │ ├── Draw.Rectangle.js │ │ └── Draw.SimpleShape.js │ ├── edit │ ├── EditToolbar.js │ └── handler │ │ ├── Edit.Circle.js │ │ ├── Edit.CircleMarker.js │ │ ├── Edit.Marker.js │ │ ├── Edit.Poly.js │ │ ├── Edit.Rectangle.js │ │ ├── Edit.SimpleShape.js │ │ ├── EditToolbar.Delete.js │ │ └── EditToolbar.Edit.js │ ├── ext │ ├── GeometryUtil.js │ ├── LatLngUtil.js │ ├── LineUtil.Intersect.js │ ├── Polygon.Intersect.js │ ├── Polyline.Intersect.js │ └── TouchEvents.js │ ├── images │ ├── spritesheet-2x.png │ ├── spritesheet.png │ └── spritesheet.svg │ └── leaflet.draw.css ├── requirements.txt ├── setup.cfg └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | */__pycache__ 3 | 4 | *.swp 5 | 6 | trial.py 7 | docs/build 8 | 9 | dist/* 10 | 11 | .idea 12 | .python-version 13 | venv 14 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018, Samarth Hattangady, Skylark Drones 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | The views and conclusions contained in the software and documentation are those 25 | of the authors and should not be interpreted as representing official policies, 26 | either expressed or implied, of the pyqtlet project. 27 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include setup.cfg 2 | include setup.py 3 | include pyqtlet/__init__.py 4 | include pyqtlet/mapwidget.py 5 | 6 | recursive-include pyqtlet/web * 7 | 8 | recursive-include pyqtlet/leaflet * 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pyqtlet 2 | 3 | --- 4 | 5 | ### NOTE: 6 | This repository is no longer in active development. To follow a fork that is being updated, please follow https://github.com/JaWeilBaum/pyqtlet2. 7 | 8 | --- 9 | 10 | pyqtlet is a wrapper for Leaflet maps in PyQt5. In construction and design, it mimics the [official leaflet api](http://leafletjs.com/reference-1.3.0.html) as much as possible. 11 | 12 | pyqtlet is currently in v0.3.0. To get started, visit the [Getting Started page](http://pyqtlet.readthedocs.io/en/latest/getting-started.html) 13 | 14 | Further details about implementation, API docs etc can also be found on the [pyqtlet site](http://pyqtlet.readthedocs.io/en/latest/index.html) 15 | 16 | ## Installation 17 | 18 | ``` bash 19 | pip3 install PyQt5 20 | pip3 install pyqtlet 21 | ``` 22 | 23 | ``` bash 24 | # To test whether it is successfully working 25 | python3 26 | >>> from pyqtlet import L, MapWidget 27 | >>> # No errors 28 | ``` 29 | 30 | ## Usage 31 | 32 | ``` python 33 | import sys 34 | from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget 35 | from pyqtlet import L, MapWidget 36 | 37 | 38 | class MapWindow(QWidget): 39 | def __init__(self): 40 | # Setting up the widgets and layout 41 | super().__init__() 42 | self.mapWidget = MapWidget() 43 | self.layout = QVBoxLayout() 44 | self.layout.addWidget(self.mapWidget) 45 | self.setLayout(self.layout) 46 | 47 | # Working with the maps with pyqtlet 48 | self.map = L.map(self.mapWidget) 49 | self.map.setView([12.97, 77.59], 10) 50 | L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(self.map) 51 | self.marker = L.marker([12.934056, 77.610029]) 52 | self.marker.bindPopup('Maps are a treasure.') 53 | self.map.addLayer(self.marker) 54 | self.show() 55 | 56 | if __name__ == '__main__': 57 | app = QApplication(sys.argv) 58 | widget = MapWindow() 59 | sys.exit(app.exec_()) 60 | ``` 61 | 62 | ## Using Unimplemented Leaflet Features 63 | At this time, there is noone actively adding features to pyqtlet. This means that there 64 | are a lot of Leaflet features that are not implemented in pyqtlet. However, there is still 65 | a way to access these features via the `runJavaScript` api. This allows arbitrary code to 66 | be run within the map window. 67 | 68 | For example, if we want to change the marker icon in the above example, add the following 69 | 2 lines of code after the `self.map.addLayer(self.marker)` statement. 70 | 71 | ``` python 72 | # Create a icon called markerIcon in the js runtime. 73 | self.map.runJavaScript('var markerIcon = L.icon({iconUrl: "https://leafletjs.com/examples/custom-icons/leaf-red.png"});') 74 | # Edit the existing python object by accessing it's jsName property 75 | self.map.runJavaScript(f'{self.marker.jsName}.setIcon(markerIcon);') 76 | ``` 77 | 78 | This technique will allow users to use all the features available in leaflet. 79 | 80 | ## Contributing 81 | In terms of contributing, there is a lot of work that still needs to be done. 82 | Specifically, there are a lot of leaflet features that need to be ported into pyqtlet. All contributions welcome. 83 | For further details, visit the [contributing page](http://pyqtlet.readthedocs.io/en/latest/contributing.html). 84 | -------------------------------------------------------------------------------- /UPLOAD_NOTES.txt: -------------------------------------------------------------------------------- 1 | Before every upload, things to change: 2 | ===================================== 3 | 4 | 1. Version in `setup.py` 5 | 2. Version in `pyqtlet/__init__.py` 6 | 7 | Build for pypi 8 | -------------- 9 | 10 | 1. re -rf dist/ 11 | 2. python3 setup.pt sdist 12 | 3. Commit, tag, push with tags 13 | 14 | Push to test pypi and test. 15 | --------------------------- 16 | # NOTE: Test pypi takes some time to update 17 | 18 | 1. python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/* 19 | 2. pip install --index-url https://test.pypi.org/simple/ pyqtlet==version 20 | 21 | Push to pypi 22 | ------------ 23 | 1. python3 -m twine upload --repository-url https://upload.pypi.org/legacy/ dist/* 24 | 25 | Done 26 | ---- 27 | 28 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = pyqtlet 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | set SPHINXPROJ=pyqtlet 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /docs/source/_templates/nav.rst: -------------------------------------------------------------------------------- 1 | Navigation 2 | ========== 3 | 4 | .. toctree:: 5 | 6 | getting-started 7 | api-docs 8 | tutorials 9 | examples 10 | contributing 11 | 12 | -------------------------------------------------------------------------------- /docs/source/api-docs.rst: -------------------------------------------------------------------------------- 1 | API Documentation 2 | ================= 3 | 4 | pyqtlet was designed to mimic the `Official Leaflet API `_ 5 | as much as possible, similar to how PyQt5 mimics Qt. This allows a large amount of 6 | laziness when it actually comes to writing the API docs for the module. 7 | 8 | The documentation will only cover what methods have been implemented in pyqtlet. 9 | The details about functionality, options etc. should be obtained from the Leaflet site. 10 | In case of any discrepancies or specially implemented features, they will be mentioned 11 | here in the docs. Otherwise, expect the method to be identical to its JS counterpart. 12 | 13 | L.Evented 14 | --------- 15 | Baseclass for all pyqtlet objects. All objects will inherit these methods 16 | 17 | Methods 18 | ^^^^^^^ 19 | * getJsResponse(str:js, function:callback) 20 | Runs the javascript and then triggers callback with the response 21 | * runJavaScript(str:js) 22 | Runs the javascript in the leaflet runtime 23 | 24 | L.map 25 | ----- 26 | L.map should be initialised with the mapWidget instead of the id of the map div. 27 | 28 | Signals 29 | ^^^^^^^ 30 | * clicked 31 | * zoom 32 | * drawCreated 33 | 34 | Methods 35 | ^^^^^^^ 36 | * addControl 37 | * addLayer 38 | * flyTo 39 | * getCenter `[requires callback]` 40 | * getBounds `[requires callback]` 41 | * getZoom `[requires callback]` 42 | * getState: `[requires callback]` 43 | gets center, zoom, bounds, minZoom, maxZoom, size, pixelBounds, pixelOrigin and pixelWorldBounds 44 | * hasLayer 45 | * panTo 46 | * removeControl 47 | * removeLayer 48 | * setMaxBounds 49 | * fitBounds 50 | * setMaxZoom 51 | * setMinZoom 52 | * setView 53 | 54 | L.Layer 55 | ------- 56 | Base class for all layer classes 57 | 58 | Methods 59 | ^^^^^^^ 60 | * addTo 61 | * bindPopup 62 | * bindTooltip 63 | * removeFrom 64 | * unbindPopup 65 | * unbindTooltip 66 | 67 | L.imageOverlay 68 | -------------- 69 | 70 | L.tileLayer 71 | ----------- 72 | 73 | L.marker 74 | -------- 75 | 76 | Methods 77 | ^^^^^^^ 78 | * setLatLng 79 | * setOpacity 80 | 81 | L.circleMarker 82 | -------------- 83 | 84 | L.polyline 85 | ---------- 86 | 87 | L.polygon 88 | --------- 89 | 90 | L.rectangle 91 | ----------- 92 | 93 | L.circle 94 | -------- 95 | 96 | L.layerGroup 97 | ------------ 98 | 99 | Methods 100 | ^^^^^^^ 101 | * addLayer 102 | * removeLayer 103 | * clearLayers 104 | * toGeoJSON 105 | 106 | L.featureGroup 107 | -------------- 108 | Inherits from layerGroup 109 | 110 | Methods 111 | ^^^^^^^ 112 | * createAndAddDrawnLayer(drawnLayer, options=None) 113 | creates and adds layer to the feature group 114 | drawnLayer: dict as returned by the 'draw:created' event. 115 | 116 | L.control.layers 117 | ---------------- 118 | 119 | L.control.draw 120 | -------------- 121 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # pyqtlet documentation build configuration file, created by 5 | # sphinx-quickstart on Tue May 15 11:36:23 2018. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | # 20 | # import os 21 | # import sys 22 | # sys.path.insert(0, os.path.abspath('.')) 23 | 24 | 25 | # -- General configuration ------------------------------------------------ 26 | 27 | # If your documentation needs a minimal Sphinx version, state it here. 28 | # 29 | # needs_sphinx = '1.0' 30 | 31 | # Add any Sphinx extension module names here, as strings. They can be 32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 33 | # ones. 34 | extensions = ['sphinx.ext.autodoc', 35 | 'sphinx.ext.todo', 36 | 'sphinx.ext.viewcode', 37 | 'sphinx.ext.githubpages'] 38 | 39 | # Add any paths that contain templates here, relative to this directory. 40 | templates_path = ['_templates'] 41 | 42 | # The suffix(es) of source filenames. 43 | # You can specify multiple suffix as a list of string: 44 | # 45 | # source_suffix = ['.rst', '.md'] 46 | source_suffix = '.rst' 47 | 48 | # The master toctree document. 49 | master_doc = 'index' 50 | 51 | # General information about the project. 52 | project = 'pyqtlet' 53 | copyright = '2018, Skylark Drones' 54 | author = 'Samarth Hattangady' 55 | 56 | # The version info for the project you're documenting, acts as replacement for 57 | # |version| and |release|, also used in various other places throughout the 58 | # built documents. 59 | # 60 | # The short X.Y version. 61 | version = '0.2' 62 | # The full version, including alpha/beta/rc tags. 63 | release = 'beta' 64 | 65 | # The language for content autogenerated by Sphinx. Refer to documentation 66 | # for a list of supported languages. 67 | # 68 | # This is also used if you do content translation via gettext catalogs. 69 | # Usually you set "language" from the command line for these cases. 70 | language = None 71 | 72 | # List of patterns, relative to source directory, that match files and 73 | # directories to ignore when looking for source files. 74 | # This patterns also effect to html_static_path and html_extra_path 75 | exclude_patterns = [] 76 | 77 | # The name of the Pygments (syntax highlighting) style to use. 78 | pygments_style = 'sphinx' 79 | 80 | # If true, `todo` and `todoList` produce output, else they produce nothing. 81 | todo_include_todos = True 82 | 83 | 84 | # -- Options for HTML output ---------------------------------------------- 85 | 86 | # The theme to use for HTML and HTML Help pages. See the documentation for 87 | # a list of builtin themes. 88 | # 89 | html_theme = 'alabaster' 90 | html_sidebars = { 91 | '**': [ 92 | 'about.html', 93 | 'relations.html', 94 | 'navigation.html', 95 | 'searchbox.html' 96 | ] 97 | } 98 | 99 | # Theme options are theme-specific and customize the look and feel of a theme 100 | # further. For a list of options available for each theme, see the 101 | # documentation. 102 | # 103 | # html_theme_options = { 104 | # 'extra_nav_links': [''] 105 | # } 106 | 107 | # Add any paths that contain custom static files (such as style sheets) here, 108 | # relative to this directory. They are copied after the builtin static files, 109 | # so a file named "default.css" will overwrite the builtin "default.css". 110 | html_static_path = ['_static'] 111 | 112 | 113 | # -- Options for HTMLHelp output ------------------------------------------ 114 | 115 | # Output file base name for HTML help builder. 116 | htmlhelp_basename = 'pyqtletdoc' 117 | 118 | 119 | # -- Options for LaTeX output --------------------------------------------- 120 | 121 | latex_elements = { 122 | # The paper size ('letterpaper' or 'a4paper'). 123 | # 124 | # 'papersize': 'letterpaper', 125 | 126 | # The font size ('10pt', '11pt' or '12pt'). 127 | # 128 | # 'pointsize': '10pt', 129 | 130 | # Additional stuff for the LaTeX preamble. 131 | # 132 | # 'preamble': '', 133 | 134 | # Latex figure (float) alignment 135 | # 136 | # 'figure_align': 'htbp', 137 | } 138 | 139 | # Grouping the document tree into LaTeX files. List of tuples 140 | # (source start file, target name, title, 141 | # author, documentclass [howto, manual, or own class]). 142 | latex_documents = [ 143 | (master_doc, 'pyqtlet.tex', 'pyqtlet Documentation', 144 | 'Samarth Hattangady, Skylark Drones', 'manual'), 145 | ] 146 | 147 | 148 | # -- Options for manual page output --------------------------------------- 149 | 150 | # One entry per manual page. List of tuples 151 | # (source start file, name, description, authors, manual section). 152 | man_pages = [ 153 | (master_doc, 'pyqtlet', 'pyqtlet Documentation', 154 | [author], 1) 155 | ] 156 | 157 | 158 | # -- Options for Texinfo output ------------------------------------------- 159 | 160 | # Grouping the document tree into Texinfo files. List of tuples 161 | # (source start file, target name, title, author, 162 | # dir menu entry, description, category) 163 | texinfo_documents = [ 164 | (master_doc, 'pyqtlet', 'pyqtlet Documentation', 165 | author, 'pyqtlet', 'One line description of project.', 166 | 'Miscellaneous'), 167 | ] 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /docs/source/contributing.rst: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | If you want to contribute to this project, please feel free to go ahead. 5 | 6 | Some areas of contribution I'm looking for: 7 | 8 | 1. Solving the getJsResponse async problem as listed in :doc:`technical`. 9 | 2. Feature completeness. There are a lot of methods and signals that have not yet been 10 | created. If you need to use any of them and are looking to add them, it is a fairly 11 | straightforward process, and all help would be appreciated. It might also be an 12 | interesting project to autogenerate all the code... I have no idea how one could 13 | go about doing that, but I believe it might be possible 14 | 3. API documentation. Sphinx-apidoc doesn't seem to be able to do what I need. It treats all 15 | methods, attributes and pyqtSignals as equal. I would like to see if its possible 16 | to figure out an approach that is able to separate the signals and make a separate 17 | list of them. 18 | 19 | Any other contributions, in terms of bug reports, feature requests and anything else are 20 | appreciated as well. 21 | -------------------------------------------------------------------------------- /docs/source/examples.rst: -------------------------------------------------------------------------------- 1 | Examples 2 | ======== 3 | 4 | Simple Setup App 5 | ---------------- 6 | 7 | This is a simple app that sets up pyqtlet and shows the basic functionality of the 8 | package. 9 | 10 | .. code:: python 11 | 12 | import sys 13 | from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget 14 | from pyqtlet import L, MapWidget 15 | 16 | 17 | class MapWindow(QWidget): 18 | def __init__(self): 19 | # Setting up the widgets and layout 20 | super().__init__() 21 | self.mapWidget = MapWidget() 22 | self.layout = QVBoxLayout() 23 | self.layout.addWidget(self.mapWidget) 24 | self.setLayout(self.layout) 25 | 26 | # Working with the maps with pyqtlet 27 | self.map = L.map(self.mapWidget) 28 | self.map.setView([12.97, 77.59], 10) 29 | L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(self.map) 30 | self.marker = L.marker([12.934056, 77.610029]) 31 | self.marker.bindPopup('Maps are a treasure.') 32 | self.map.addLayer(self.marker) 33 | self.show() 34 | 35 | if __name__ == '__main__': 36 | app = QApplication(sys.argv) 37 | widget = MapWindow() 38 | sys.exit(app.exec_()) 39 | 40 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Pyqtlet 2 | ======= 3 | 4 | pyqtlet brings `Leaflet `_ maps to `PyQt5 `_. 5 | 6 | `Leaflet `_ is the most popular mapping library on the web. It has most mapping features that you might need, excellent documentation, and a host of plugins. In contstruction and design, pyqtlet attempts to mimic the `official Leaflet API `_ as much as possible. 7 | 8 | pyqtlet allows you to bring in these leaflet maps into PyQt5 in just a couple of lines. It provides a mapWidget (which is a QWidget) as well as a namespace (L) in order to mimic the Leaflet API. 9 | 10 | .. code-block:: python 11 | 12 | from pyqtlet import L, MapWidget 13 | 14 | class Application(QMainWindow): 15 | ... 16 | self.mapWidget = MapWidget() 17 | self.map = L.map(self.mapWidget) 18 | self.map.setView([12.97, 77.59], 10) 19 | ... 20 | self.layout.add(self.mapWidget) 21 | 22 | 23 | If you have are just starting out, you might want to start off with the :doc:`getting-started` page. 24 | 25 | .. toctree:: 26 | :hidden: 27 | 28 | getting-started 29 | api-docs 30 | examples 31 | tutorials 32 | technical 33 | contributing 34 | -------------------------------------------------------------------------------- /docs/source/maps_are_beautiful.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/docs/source/maps_are_beautiful.jpg -------------------------------------------------------------------------------- /docs/source/maps_are_beautiful2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/docs/source/maps_are_beautiful2.jpg -------------------------------------------------------------------------------- /docs/source/navigation.rst: -------------------------------------------------------------------------------- 1 | Navigation 2 | ========== 3 | 4 | .. toctree:: 5 | 6 | getting-started 7 | api-docs 8 | tutorials 9 | examples 10 | contributing 11 | 12 | -------------------------------------------------------------------------------- /docs/source/trial.rst: -------------------------------------------------------------------------------- 1 | trial module 2 | ============ 3 | 4 | .. automodule:: trial 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/source/tutorials.rst: -------------------------------------------------------------------------------- 1 | Tutorials 2 | ========= 3 | 4 | `Out to Lunch. Please return at a more appropriate time.` 5 | -------------------------------------------------------------------------------- /pyqtlet/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Bringing Leaflet maps to PyQt. 3 | """ 4 | 5 | __author__ = 'Samarth Hattangady ' 6 | __version__ = '0.3.3' 7 | 8 | from .mapwidget import MapWidget 9 | from .leaflet import L 10 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/__init__.py: -------------------------------------------------------------------------------- 1 | from .map import Map 2 | from .layer import LayerGroup, FeatureGroup, imageOverlay 3 | from .layer.tile import TileLayer 4 | from .layer.marker import Marker 5 | from .layer.vector import Circle, CircleMarker, Polygon, Polyline, Rectangle 6 | from .control import Control 7 | 8 | class L: 9 | """ 10 | Leaflet namespace that holds reference to all the leaflet objects 11 | """ 12 | map = Map 13 | tileLayer = TileLayer 14 | imageOverlay = imageOverlay 15 | marker = Marker 16 | circleMarker = CircleMarker 17 | polyline = Polyline 18 | polygon = Polygon 19 | rectangle = Rectangle 20 | circle = Circle 21 | layerGroup = LayerGroup 22 | featureGroup = FeatureGroup 23 | control = Control 24 | 25 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/control/__init__.py: -------------------------------------------------------------------------------- 1 | from .layers import Layers 2 | from .draw import Draw 3 | 4 | class Control: 5 | layers = Layers 6 | draw = Draw 7 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/control/control.py: -------------------------------------------------------------------------------- 1 | import json 2 | import logging 3 | import os 4 | import time 5 | 6 | from PyQt5.QtCore import pyqtSlot, pyqtSignal 7 | 8 | from ..core import Evented 9 | 10 | class Control(Evented): 11 | 12 | # controlId is a static variable shared between all controls 13 | # It is used to give unique names to controls 14 | controlId = 0 15 | # addedToMap and removedFromMap are signals for controls to 16 | # know when they're added and removed from maps 17 | addedToMap = pyqtSignal() 18 | removedFromMap = pyqtSignal() 19 | 20 | @property 21 | def map(self): 22 | return self._map 23 | 24 | @map.setter 25 | def map(self, map_): 26 | self._map = map_ 27 | if map_ is None: 28 | self.removedFromMap.emit() 29 | else: 30 | self.addedToMap.emit() 31 | 32 | @property 33 | def jsName(self): 34 | return self._controlName 35 | 36 | @property 37 | def controlName(self): 38 | return self._controlName 39 | 40 | @controlName.setter 41 | def controlName(self, name): 42 | self._controlName = name 43 | 44 | def __init__(self): 45 | super().__init__() 46 | self._controlName = self._getNewControlName() 47 | 48 | def addTo(self, map_): 49 | map_.addControl(self) 50 | 51 | def removeFrom(self, map_): 52 | map_.removeControl(self) 53 | 54 | def _getNewControlName(self): 55 | controlName = 'c{}'.format(self.controlId) 56 | Control.controlId += 1 57 | return controlName 58 | 59 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/control/draw.py: -------------------------------------------------------------------------------- 1 | from .control import Control 2 | # NOTE: Importing FeatureGroup here may not be the best idea 3 | from ..layer.featuregroup import FeatureGroup 4 | 5 | DEFAULT_POSITION = 'topleft' 6 | DEFAULT_CIRCLE = False 7 | DEFAULT_RECTANGLE = False 8 | 9 | class Draw(Control): 10 | 11 | def __init__(self, options={}, handleFeatureGroup=True): 12 | super().__init__() 13 | self.options = options 14 | self.handleFeatureGroup = handleFeatureGroup 15 | self.featureGroup = None 16 | self._handleOptions() 17 | self._initJs() 18 | if handleFeatureGroup: 19 | self.addedToMap.connect(self.addDrawnToFeatureGroup) 20 | 21 | def _initJs(self): 22 | jsObject = 'new L.Control.Draw(' 23 | if self.options: 24 | jsObject += '{options}'.format(options=self._stringifyForJs(self.options)) 25 | jsObject += ')' 26 | self._createJsObject(jsObject) 27 | 28 | def _handleOptions(self): 29 | # If there are no options, then we want to set the default options 30 | self.options['position'] = self.options.get('position', DEFAULT_POSITION) 31 | draw = self.options.get('draw', {}) 32 | if draw is not False: 33 | # We want to make sure the user wants draw functionality 34 | draw['circle'] = draw.get('circle', DEFAULT_CIRCLE) 35 | draw['rectangle'] = draw.get('rectangle', DEFAULT_RECTANGLE) 36 | self.options['draw'] = draw 37 | edit = self.options.get('edit', {}) 38 | if edit is not False: 39 | # We want to make sure the user wants edit functionality 40 | featureGroup = edit.get('featureGroup', None) 41 | if featureGroup is None and self.handleFeatureGroup: 42 | # If a feature group has not been set, create one and add it 43 | featureGroup = FeatureGroup() 44 | edit['featureGroup'] = featureGroup 45 | self.featureGroup = featureGroup 46 | self.options['edit'] = edit 47 | 48 | def addDrawnToFeatureGroup(self): 49 | self.map.addLayer(self.featureGroup) 50 | self.map.drawCreated.connect(self.featureGroup.createAndAddDrawnLayer) 51 | 52 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/control/layers.py: -------------------------------------------------------------------------------- 1 | from .control import Control 2 | 3 | class Layers(Control): 4 | 5 | def __init__(self, layers=[], overlays={}, options=None): 6 | super().__init__() 7 | self.layers = layers 8 | self.overlays = overlays 9 | self.options = options 10 | self._initJs() 11 | 12 | def _initJs(self): 13 | jsObject = 'L.control.layers({layers}'.format(layers=self._stringifyForJs(self.layers)) 14 | if self.overlays is not None: 15 | jsObject += ', {overlays}'.format(overlays=self._stringifyForJs(self.overlays)) 16 | if self.options is not None: 17 | jsObject += ', {options}'.format(options=self._stringifyForJs(self.options)) 18 | jsObject += ')' 19 | self._createJsObject(jsObject) 20 | 21 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/core/__init__.py: -------------------------------------------------------------------------------- 1 | from .evented import Evented 2 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/__init__.py: -------------------------------------------------------------------------------- 1 | from .featuregroup import FeatureGroup 2 | from .layer import Layer 3 | from .layergroup import LayerGroup 4 | from .imageoverlay import imageOverlay 5 | 6 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/featuregroup.py: -------------------------------------------------------------------------------- 1 | from .layergroup import LayerGroup 2 | from ..layer import marker, vector 3 | 4 | class FeatureGroup(LayerGroup): 5 | """ 6 | Used to group several layers and handle them as one. If you add it to the map, any layers added or removed from the group will be added/removed on the map as well. 7 | """ 8 | 9 | def _initJs(self): 10 | leafletJsObject = 'new L.featureGroup()' 11 | self._createJsObject(leafletJsObject) 12 | 13 | def createAndAddDrawnLayer(self, drawnLayer, options=None): 14 | layerType = drawnLayer['layerType'] 15 | if layerType == 'polygon': 16 | coords = drawnLayer['layer']['_latlngs']['0'] 17 | coords = [coords[p] for p in coords] 18 | self.addLayer(vector.Polygon(coords, options)) 19 | elif layerType == 'marker': 20 | coords = drawnLayer['layer']['_latlng'] 21 | self.addLayer(marker.Marker(coords, options)) 22 | elif layerType == 'polyline': 23 | coords = drawnLayer['layer']['_latlngs'] 24 | coords = [coords[p] for p in coords] 25 | self.addLayer(vector.Polyline(coords, options)) 26 | elif layerType == 'rectangle': 27 | coords = drawnLayer['layer']['_latlngs']['0'] 28 | coords = [coords[p] for p in coords] 29 | self.addLayer(vector.Rectangle(coords, options)) 30 | elif layerType == 'circle': 31 | coords = drawnLayer['layer']['_latlng'] 32 | radius = drawnLayer['layer']['options']['radius'] 33 | self.addLayer(vector.Circle([coords['lat'], coords['lng']], radius)) 34 | 35 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/imageoverlay.py: -------------------------------------------------------------------------------- 1 | from .layer import Layer 2 | 3 | class imageOverlay(Layer): 4 | def __init__(self, imageURL, bounds, options=None): 5 | super().__init__() 6 | self.imageURL = imageURL 7 | self.bounds = bounds 8 | self.options = options 9 | self._initJs() 10 | 11 | def _initJs(self): 12 | leafletJsObject = 'L.imageOverlay("{imageURL}",{bounds}'.format(imageURL=self.imageURL,bounds=self.bounds) 13 | if self.options: 14 | leafletJsObject += ', {options}'.format(options=self.options) 15 | leafletJsObject += ')' 16 | self._createJsObject(leafletJsObject) 17 | 18 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/layer.py: -------------------------------------------------------------------------------- 1 | from ..core import Evented 2 | 3 | class Layer(Evented): 4 | 5 | # layerId is a static variable shared between all layers 6 | # It is used to give unique names to layers 7 | layerId = 0 8 | 9 | @property 10 | def layerName(self): 11 | return self._layerName 12 | 13 | @layerName.setter 14 | def layerName(self, name): 15 | self._layerName = name 16 | 17 | @property 18 | def jsName(self): 19 | return self._layerName 20 | 21 | @property 22 | def map(self): 23 | return self._map 24 | 25 | @map.setter 26 | def map(self, map_): 27 | self._map = map_ 28 | 29 | def __init__(self): 30 | super().__init__() 31 | self._map = None 32 | self._layerName = self._getNewLayerName() 33 | 34 | def _getNewLayerName(self): 35 | layerName = 'l{}'.format(self.layerId) 36 | Layer.layerId += 1 37 | return layerName 38 | 39 | def addTo(self, map_): 40 | map_.addLayer(self) 41 | 42 | def removeFrom(self, map_): 43 | map_.removeLayer(self) 44 | 45 | def bindPopup(self, content, options=None): 46 | js = '{layerName}.bindPopup("{content}"'.format( 47 | layerName=self._layerName, content=content) 48 | if options: 49 | js += ', {options}'.format(self._stringifyForJs(options)) 50 | js += ')' 51 | self.runJavaScript(js) 52 | 53 | def unbindPopup(self): 54 | js = '{layerName}.unbindPopup()'.format(layerName=self._layerName) 55 | self.runJavaScript(js) 56 | 57 | def bindTooltip(self, content, options=None): 58 | js = '{layerName}.bindTooltip("{content}"'.format( 59 | layerName=self._layerName, content=content) 60 | if options: 61 | js += ', {options}'.format(self._stringifyForJs(options)) 62 | js += ')' 63 | self.runJavaScript(js) 64 | 65 | def unbindTooltip(self): 66 | js = '{layerName}.unbindTooltip()'.format(layerName=self._layerName) 67 | self.runJavaScript(js) 68 | 69 | 70 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/layergroup.py: -------------------------------------------------------------------------------- 1 | from .layer import Layer 2 | 3 | class LayerGroup(Layer): 4 | """ 5 | Used to group several layers and handle them as one. If you add it to the map, any layers added or removed from the group will be added/removed on the map as well. 6 | """ 7 | 8 | @property 9 | def layers(self): 10 | return self._layers 11 | 12 | def __init__(self): 13 | super().__init__() 14 | self._layers = [] 15 | self._initJs() 16 | 17 | def _initJs(self): 18 | leafletJsObject = 'new L.layerGroup()' 19 | self._createJsObject(leafletJsObject) 20 | 21 | def addLayer(self, layer): 22 | self._layers.append(layer) 23 | js = '{layerGroup}.addLayer({layerName})'.format(layerGroup=self._layerName, 24 | layerName=layer._layerName) 25 | self.runJavaScript(js) 26 | 27 | def removeLayer(self, layer): 28 | if not layer in self._layers: 29 | # TODO Raise ValueError? 30 | return 31 | self._layers.remove(layer) 32 | js = '{layerGroup}.removeLayer({layerName})'.format(layerGroup=self._layerName, 33 | layerName=layer._layerName) 34 | self.runJavaScript(js) 35 | 36 | def clearLayers(self): 37 | js = '{layerGroup}.clearLayers()'.format(layerGroup=self._layerName) 38 | self.runJavaScript(js) 39 | 40 | def toGeoJSON(self, callback): 41 | self.getJsResponse('{layer}.toGeoJSON()'.format(layer=self.jsName), callback) 42 | 43 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/marker/__init__.py: -------------------------------------------------------------------------------- 1 | from .marker import Marker 2 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/marker/marker.py: -------------------------------------------------------------------------------- 1 | from ..layer import Layer 2 | 3 | class Marker(Layer): 4 | def __init__(self, latLng, options=None): 5 | super().__init__() 6 | self.latLng = latLng 7 | self.options = options 8 | self._initJs() 9 | 10 | def _initJs(self): 11 | leafletJsObject = 'L.marker({latLng}'.format(latLng=self.latLng) 12 | if self.options: 13 | leafletJsObject += ', {options}'.format(options=self.options) 14 | leafletJsObject += ')' 15 | self._createJsObject(leafletJsObject) 16 | 17 | def setLatLng(self, latLng): 18 | js = '{layerName}.setLatLng({latLng})'.format( 19 | layerName=self._layerName, latLng=latLng) 20 | self.runJavaScript(js) 21 | 22 | def setOpacity(self, opacity): 23 | js = '{layerName}.setOpacity({latLng})'.format( 24 | layerName=self._layerName, opacity=opacity) 25 | self.runJavaScript(js) 26 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/tile/__init__.py: -------------------------------------------------------------------------------- 1 | from .gridlayer import GridLayer 2 | from .tilelayer import TileLayer 3 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/tile/gridlayer.py: -------------------------------------------------------------------------------- 1 | from .. import Layer 2 | 3 | class GridLayer(Layer): 4 | pass 5 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/tile/tilelayer.py: -------------------------------------------------------------------------------- 1 | from . import GridLayer 2 | 3 | class TileLayer(GridLayer): 4 | def __init__(self, urlTemplate, options=None): 5 | super().__init__() 6 | self.urlTemplate = urlTemplate 7 | self.options = options 8 | self._initJs() 9 | 10 | def _initJs(self): 11 | leafletJsObject = 'L.tileLayer("{urlTemplate}"'.format(urlTemplate=self.urlTemplate) 12 | if self.options: 13 | leafletJsObject += ', {options}'.format(options=self.options) 14 | leafletJsObject += ')' 15 | self._createJsObject(leafletJsObject) 16 | 17 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/vector/__init__.py: -------------------------------------------------------------------------------- 1 | from .circle import Circle 2 | from .circlemarker import CircleMarker 3 | from .polygon import Polygon 4 | from .polyline import Polyline 5 | from .rectangle import Rectangle 6 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/vector/circle.py: -------------------------------------------------------------------------------- 1 | from .circlemarker import CircleMarker 2 | 3 | 4 | class Circle(CircleMarker): 5 | def __init__(self, latLng, radius, options=None): 6 | self.radius = radius 7 | super().__init__(latLng, options) 8 | 9 | def _initJs(self): 10 | leafletJsObject = 'L.circle({latLng},{radius}'.format(latLng=self.latLng, 11 | radius=self.radius) 12 | if self.options: 13 | leafletJsObject += ', {options}'.format(options=self.options) 14 | leafletJsObject += ')' 15 | self._createJsObject(leafletJsObject) 16 | 17 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/vector/circlemarker.py: -------------------------------------------------------------------------------- 1 | from .path import Path 2 | 3 | 4 | class CircleMarker(Path): 5 | def __init__(self, latLng, options=None): 6 | super().__init__() 7 | self.latLng = latLng 8 | self.options = options 9 | self._initJs() 10 | 11 | def _initJs(self): 12 | leafletJsObject = 'L.circleMarker({latLng}'.format(latLng=self.latLng) 13 | if self.options: 14 | leafletJsObject += ', {options}'.format(options=self.options) 15 | leafletJsObject += ')' 16 | self._createJsObject(leafletJsObject) 17 | 18 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/vector/path.py: -------------------------------------------------------------------------------- 1 | from ..layer import Layer 2 | 3 | 4 | class Path(Layer): 5 | pass 6 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/vector/polygon.py: -------------------------------------------------------------------------------- 1 | from .polyline import Polyline 2 | 3 | 4 | class Polygon(Polyline): 5 | def __init__(self, latLngs, options=None): 6 | super().__init__(latLngs, options) 7 | 8 | def _initJs(self): 9 | leafletJsObject = 'L.polygon({latLngs}'.format(latLngs=self.latLngs) 10 | if self.options: 11 | leafletJsObject += ', {options}'.format(options=self.options) 12 | leafletJsObject += ')' 13 | self._createJsObject(leafletJsObject) 14 | 15 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/vector/polyline.py: -------------------------------------------------------------------------------- 1 | from .path import Path 2 | 3 | 4 | class Polyline(Path): 5 | def __init__(self, latLngs, options=None): 6 | super().__init__() 7 | self.latLngs = latLngs 8 | self.options = options 9 | self._initJs() 10 | 11 | def _initJs(self): 12 | leafletJsObject = 'L.polyline({latLngs}'.format(latLngs=self.latLngs) 13 | if self.options: 14 | leafletJsObject += ', {options}'.format(options=self.options) 15 | leafletJsObject += ')' 16 | self._createJsObject(leafletJsObject) 17 | 18 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/layer/vector/rectangle.py: -------------------------------------------------------------------------------- 1 | from .polygon import Polygon 2 | 3 | 4 | class Rectangle(Polygon): 5 | def __init__(self, latLngs, options=None): 6 | super().__init__(latLngs, options) 7 | 8 | def _initJs(self): 9 | leafletJsObject = 'L.rectangle({latLngs}'.format(latLngs=self.latLngs) 10 | if self.options: 11 | leafletJsObject += ', {options}'.format(options=self.options) 12 | leafletJsObject += ')' 13 | self._createJsObject(leafletJsObject) 14 | 15 | -------------------------------------------------------------------------------- /pyqtlet/leaflet/map/__init__.py: -------------------------------------------------------------------------------- 1 | from .map import Map 2 | -------------------------------------------------------------------------------- /pyqtlet/mapwidget.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | 4 | from PyQt5.QtCore import QEventLoop, QObject, QUrl, pyqtSignal 5 | from PyQt5.QtWebChannel import QWebChannel 6 | from PyQt5.QtWebEngineWidgets import ( QWebEngineView, QWebEnginePage, QWebEngineSettings, 7 | QWebEngineScript ) 8 | 9 | 10 | class MapWidget(QWebEngineView): 11 | """ 12 | The MapWidget class is a QWebEngineView that houses the leaflet map. 13 | Since it is a QWidget, it can be added to any QLayout. 14 | """ 15 | 16 | @property 17 | def page(self): 18 | return self._page 19 | 20 | @property 21 | def channel(self): 22 | return self._channel 23 | 24 | def __init__(self): 25 | super().__init__() 26 | self._page = QWebEnginePage() 27 | self.setPage(self._page) 28 | self._channel = QWebChannel() 29 | self._page.setWebChannel(self._channel) 30 | self._loadPage() 31 | 32 | def _loadPage(self): 33 | html_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'web', 'map.html') 34 | # QEventLoop is used to make the page loading behave syncronously 35 | init_loop = QEventLoop() 36 | self._page.loadFinished.connect(init_loop.quit) 37 | self._page.load(QUrl().fromLocalFile(html_path)) 38 | init_loop.exec() 39 | 40 | -------------------------------------------------------------------------------- /pyqtlet/web/custom.js: -------------------------------------------------------------------------------- 1 | function copyWithoutCircularReferences(references, object) { 2 | var cleanObject = {}; 3 | Object.keys(object).forEach(function(key) { 4 | var value = object[key]; 5 | if (value && typeof value === 'object') { 6 | if (references.indexOf(value) < 0) { 7 | references.push(value); 8 | cleanObject[key] = copyWithoutCircularReferences(references, value); 9 | references.pop(); 10 | } else { 11 | cleanObject[key] = '###_Circular_###'; 12 | } 13 | } else if (typeof value !== 'function') { 14 | cleanObject[key] = value; 15 | } 16 | }); 17 | return cleanObject; 18 | } 19 | 20 | // NOTE: There is an assumption here that the map var will be called map 21 | // Might not be the case if there are multiple maps. 22 | function getMapState() { 23 | var center = map.getCenter(); 24 | var zoom = map.getZoom(); 25 | var bounds = map.getBounds(); 26 | var minZoom = map.getMinZoom(); 27 | var maxZoom = map.getMaxZoom(); 28 | var size = map.getSize(); 29 | var pixelBounds = map.getPixelBounds(); 30 | var pixelOrigin = map.getPixelOrigin(); 31 | var pixelWorldBounds = map.getPixelWorldBounds(); 32 | return { 33 | center: center, 34 | zoom: zoom, 35 | bounds: bounds, 36 | minZoom: minZoom, 37 | maxZoom: maxZoom, 38 | size: size, 39 | pixelBounds: pixelBounds, 40 | pixelOrigin: pixelOrigin, 41 | pixelWorldBounds: pixelWorldBounds 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pyqtlet/web/map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Map 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_134/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_134/images/layers-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_134/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_134/images/layers.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_134/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_134/images/marker-icon-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_134/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_134/images/marker-icon.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_134/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_134/images/marker-shadow.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | fixme: 3 | enabled: true 4 | duplication: 5 | enabled: true 6 | config: 7 | languages: 8 | - javascript 9 | eslint: 10 | enabled: true 11 | ratings: 12 | paths: 13 | - "**.js" 14 | exclude_paths: 15 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = tab 3 | indent_size = 2 4 | insert_final_newline = true 5 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-unused-vars": 0, 4 | "quotes": 0, 5 | "no-shadow": 0, 6 | "no-irregular-whitespace": 0, 7 | "no-console": 0, 8 | "no-extend-native": 0 9 | }, 10 | "env": { 11 | "mocha": true 12 | }, 13 | "globals": { 14 | "expect": false, 15 | "sinon": false, 16 | "happen": false, 17 | "Hand": false, 18 | "takeScreenshot": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | tmp/**/* 4 | .idea 5 | *.iml 6 | _site 7 | *.sublime-* 8 | coverage/ 9 | *.js.html 10 | .mailmap 11 | bower.json 12 | component.json 13 | debug/local/ 14 | Gemfile.lock 15 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6.1" 4 | - "6.0" 5 | - "5.11" 6 | - "5.10" 7 | - "5.9" 8 | - "5.8" 9 | - "5.7" 10 | - "5.6" 11 | - "5.5" 12 | - "5.4" 13 | - "5.3" 14 | - "5.2" 15 | - "5.1" 16 | - "5.0" 17 | - "4.4" 18 | - "4.3" 19 | - "4.2" 20 | - "4.1" 21 | - "4.0" 22 | - "0.12" 23 | - "0.11" 24 | - "0.10" 25 | - "0.8" 26 | - "0.6" 27 | - "iojs" 28 | - "iojs-v1.0.4" 29 | 30 | matrix: 31 | allow_failures: 32 | - node_js: "0.8" 33 | - node_js: "0.6" 34 | - node_js: "0.12" 35 | - node_js: "0.11" 36 | - node_js: "0.10" 37 | - node_js: "0.8" 38 | - node_js: "0.6" 39 | - node_js: "iojs" 40 | - node_js: "iojs-v1.0.4" 41 | 42 | before_script: 43 | - npm install -g jake -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/BREAKINGCHANGES.md: -------------------------------------------------------------------------------- 1 | # How to upgrade from 0.3 to 0.4 2 | 3 | There are a number of changes to the plugin in 0.4 that may break peoples implementations of Leaflet.draw 0.3. 4 | 5 | ### L.Tooltip is now L.Draw.Tooltip 6 | 7 | ``` 8 | var tooltip = new L.Tooltip(map); 9 | ``` 10 | 11 | Is now 12 | 13 | ``` 14 | var tooltip = new L.Draw.Tooltip(map); 15 | ``` 16 | 17 | See ./src/Tooltip.js 18 | 19 | # How to upgrade from 0.1 to 0.2 20 | 21 | There are a number of changes to the plugin in 0.2 that may break peoples implementations of Leaflet.draw 0.1. I will try my best to list any changes here. 22 | 23 | ## Event consolidation 24 | 25 | Leaflet.draw 0.1 had a created event for each different shape that was created. 0.2 now consolidates these into a single created shape. 26 | 27 | The vector or marker is accessed by the `layer` property of the event arguments, the type of layer by the `layerType`. 28 | 29 | #### New way 30 | 31 | ```js 32 | map.on(L.Draw.Event.CREATED, function (e) { 33 | var type = e.layerType, 34 | layer = e.layer; 35 | 36 | if (type === 'marker') { 37 | // Do any marker specific logic here 38 | } 39 | 40 | map.addLayer(layer); 41 | }); 42 | ``` 43 | 44 | #### Old way 45 | 46 | ```js 47 | map.on('draw:poly-created', function (e) { 48 | map.addLayer(e.poly); 49 | }); 50 | map.on('draw:rectangle-created', function (e) { 51 | map.addLayer(e.rect); 52 | }); 53 | map.on('draw:circle-created', function (e) { 54 | map.addLayer(e.circ); 55 | }); 56 | map.on('draw:marker-created', function (e) { 57 | e.marker.bindPopup('A popup!'); 58 | map.addLayer(e.marker); 59 | }); 60 | ``` 61 | 62 | ## Draw handler started/stopped event change 63 | 64 | Renamed the drawing started and stopped events to be the same as the created standard. 65 | 66 | `drawing` -> `draw:drawstart` and `drawing-disabled` -> `draw:drawstop`. 67 | 68 | The event argument has also changed from `drawingType` -> `layerType`. 69 | 70 | ## CSS changes 71 | 72 | There has been a whole bunch of CSS changes, if you have customized any of these please see [leaflet.draw.css](https://github.com/Leaflet/Leaflet.draw/blob/master/dist/leaflet.draw.css). 73 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | - [ ] I'm reporting a bug, not asking for help 2 | - [ ] I've looked at the [documentation](http://leaflet.github.io/Leaflet.draw/dist/reference-0.4.1.html) to make sure the behaviour is documented and expected 3 | - [ ] I'm sure this is a Leaflet Draw code issue, not an issue with my own code nor with the framework I'm using (Cordova, Ionic, Angular, React…) 4 | - [ ] I've searched through the issues to make sure it's not yet reported 5 | 6 | ---- 7 | 8 | ## How to reproduce 9 | 10 | - Leaflet version I'm using: 11 | - Leaflet Draw version I'm using: 12 | - Browser (with version) I'm using: 13 | - OS/Platform (with version) I'm using: 14 | - step 1 15 | - step 2 16 | 17 | ## What behaviour I'm expecting and which behaviour I'm seeing 18 | 19 | ## Minimal example reproducing the issue 20 | 21 | - [ ] this example is as simple as possible 22 | - [ ] this example does not rely on any third party code 23 | 24 | Using [jsfiddle](https://jsfiddle.net/ddproxy/mvp7hgou/) or another example site. -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/Jakefile.js: -------------------------------------------------------------------------------- 1 | /* 2 | Leaflet.draw building and linting scripts. 3 | 4 | To use, install Node, then run the following commands in the project root: 5 | 6 | npm install -g jake 7 | npm install 8 | 9 | To check the code for errors and build Leaflet from source, run "jake". 10 | To run the tests, run "jake test". To build the documentation, run "jake docs". 11 | 12 | For a custom build, open build/build.html in the browser and follow the instructions. 13 | */ 14 | 15 | var build = require('./build/build.js'), 16 | buildDocs = require('./build/docs'), 17 | git = require('git-rev'); 18 | 19 | function hint(msg, args) { 20 | return function () { 21 | console.log(msg); 22 | jake.exec('node node_modules/eslint/bin/eslint.js ' + args, 23 | {printStdout: true}, function () { 24 | console.log('\tCheck passed.\n'); 25 | complete(); 26 | }); 27 | }; 28 | } 29 | 30 | // Returns the version string in package.json, plus a semver build metadata if 31 | // this is not an official release 32 | function calculateVersion(officialRelease, callback) { 33 | var version = require('./package.json').version; 34 | 35 | if (officialRelease) { 36 | callback(version); 37 | } else { 38 | git.short(function (str) { 39 | callback(version + '+' + str); 40 | }); 41 | } 42 | } 43 | 44 | 45 | desc('Check Leaflet.draw source for errors with ESHint'); 46 | task('lint', {async: true}, hint('Checking for JS errors...', 'src')); 47 | 48 | desc('Check Leaflet.draw specs source for errors with ESLint'); 49 | task('lintspec', {async: true}, hint('Checking for specs JS errors...', 'spec/suites')); 50 | 51 | desc('Combine and compress Leaflet Draw source files'); 52 | task('build', {async: true}, function (compsBase32, buildName, officialRelease) { 53 | calculateVersion(officialRelease, function (v) { 54 | build.build(complete, v, compsBase32, buildName); 55 | }); 56 | }); 57 | 58 | desc('Run PhantomJS tests'); 59 | task('test', ['lint', 'lintspec'], {async: true}, function () { 60 | build.test(complete); 61 | }); 62 | 63 | desc('Build documentation'); 64 | task('docs', {}, function () { 65 | buildDocs(); 66 | }); 67 | 68 | task('default', ['build', 'test']); 69 | 70 | jake.addListener('complete', function () { 71 | process.exit(); 72 | }); -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/MIT-LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2012-2017 Jon West, Jacob Toye, and Leaflet 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/TODO.md: -------------------------------------------------------------------------------- 1 | ### Done 2 | 3 | * ~~Tidy up css: include leaflet-control-toolbar for common styles~~ 4 | * ~~Rename _shapes variable in Control.Draw to make better sense.~~ 5 | * ~~Should the ext classes be renamed to Polyline.Intersect or similar?~~ 6 | * ~~Make Control.Draw inherit from Control.Toolbar.~~ 7 | * ~~Rename Handler.Draw -> Vector.Draw. What about markers? they aren't vectors, is there a better name? Maybe Feature?~~ 8 | * ~~Add enbled/disabled states for the delete & edit buttons.~~ 9 | * ~~Move control/handler files out of draw folder.~~ 10 | * ~~Rename the draw events from draw:feature t0 feature-created.~~ 11 | * ~~Revert to the correct colour for the feature that was just deselected.~~ 12 | * ~~Rename the Handler activated/deactivated events to enabled/disabled.~~ 13 | * ~~Add option for setting the selected color.~~ 14 | * ~~Check and calls to L.Feature.Draw.prototype, are they correct? In Draw.Circle it hink it should be referencing L.Draw.SimpleShape~~ 15 | * ~~Add in cancel buttons for selected button.~~ 16 | * ~~Have special behavior for selected markers. Do we just set the background color?~~ 17 | * ~~Turn the cancel button UI into a button container for things like undo.~~ 18 | * ~~Add Save to edit mode. Same as cancel but does not revert any shapes.~~ 19 | * ~~rename selectableLayers = layerGroup~~ 20 | * ~~refactor the repositioning of the actions toolbar for Control.Draw.~~ 21 | * ~~If more than 1 button in actions toolbar but not first is showing then margin is wrong.~~ 22 | * ~~Support cancelling delete?~~ 23 | * ~~Rename the _showCancel/_hideCancel methods in Control.Toolbar~~ 24 | * ~~See if any common code can move to Control.Toolbar from Control.Draw.~~ 25 | * ~~Fix the bottom border radius when the actions buttons are at the bottom~~ 26 | * ~~Fix up the toolbar rounded corners when only 1 item in the toolbar.~~ 27 | * ~~Handle layers being added/removed to the layergroup. i.e. need to be placed in edit mode or have a delete handler added~~ 28 | * ~Add support for tooltips for the edit mode.~ 29 | * ~Add handlers for Circle and Rectangle editing. (Needs a way to hook into L.Cicle and L.Rectangle)~ 30 | * ~Fix styles to look more like new Leaflet zoom in/out.~ 31 | * ~Polyline is styled as filled for edit mode.~ 32 | * ~Add visual style change to toolbar buttons on mouse over.~ 33 | * ~Add handlers to earch corner of the rectangle for resizing.~ 34 | * ~Bug: if you go edit mode, then go to draw mode.~ 35 | * ~Handle controls from being removed from map.~ 36 | * ~Add link to http://glyphicons.com/~ 37 | * ~Redo the select/delete icons.~ 38 | * ~Merge the event change pull and add edit/delete versions.~ 39 | * ~When switching from edit to delete and having edit a feature it should reset/cancel instead of saving.~ 40 | * ~Move clone methods from Edit.Feature~ 41 | * ~Renamed Edit.Feature -> Edit and Delete.Feature -> Delete, is confusing since Edit.feature is not the same as Edit.Circle etc~ 42 | * ~Get Leaflet control-design branch merged to master.~ 43 | * ~Fix action toolbar styles to match new toolbar height.~ 44 | * ~Make Tooltip sexy!~ 45 | * ~IE actions bar position.~ 46 | * ~IE editable marker background and border.~ 47 | * ~Search for TODO~ 48 | * ~Update Deps. Maybe should make it more advanced to allow people to custom build without parts? Like edit only or draw only? Also file names ahve changed.~ 49 | * ~Add some proper documentation. I.e. for the events & methods.~ 50 | * ~Add a thanks section to README. Shramov, BrunboB, tnightingale & Glyphicons. Others?~ 51 | * ~Write up a breaking changes for when 0.2 goes live. (See below)~ 52 | * ~Add events to docs~ 53 | * ~Fix the draw:enabled event. This is not used for the edit toolbar. It is simply used to state that drawing has started then ended.~ 54 | * ~Custom build tool.~ 55 | * ~Move Poly.Edit.js~ 56 | * ~Add ability to update the options after control is initialized.~ 57 | * ~Make a git tag of Leaflet.draw 0.1~ 58 | * ~Document changing the options of a draw handler.~ 59 | 60 | ### TODO 61 | 62 | * Fix all the Show Code links in the ReadMe. -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/deps.js: -------------------------------------------------------------------------------- 1 | var deps = { 2 | Core: { 3 | src: [ 4 | 'Leaflet.draw.js', 5 | 'Leaflet.Draw.Event.js' 6 | ], 7 | desc: 'The core of the plugin. Currently only includes the version.' 8 | }, 9 | 10 | DrawHandlers: { 11 | src: [ 12 | 'draw/handler/Draw.Feature.js', 13 | 'draw/handler/Draw.Polyline.js', 14 | 'draw/handler/Draw.Polygon.js', 15 | 'draw/handler/Draw.SimpleShape.js', 16 | 'draw/handler/Draw.Rectangle.js', 17 | 'draw/handler/Draw.Marker.js', 18 | 'draw/handler/Draw.CircleMarker.js', 19 | 'draw/handler/Draw.Circle.js' 20 | ], 21 | desc: 'Drawing handlers for: polylines, polygons, rectangles, circles, circlemarkers and markers.', 22 | deps: ['Core'] 23 | }, 24 | 25 | EditHandlers: { 26 | src: [ 27 | 'edit/handler/Edit.Marker.js', 28 | 'edit/handler/Edit.Poly.js', 29 | 'edit/handler/Edit.SimpleShape.js', 30 | 'edit/handler/Edit.Rectangle.js', 31 | 'edit/handler/Edit.CircleMarker.js', 32 | 'edit/handler/Edit.Circle.js' 33 | ], 34 | desc: 'Editing handlers for: polylines, polygons, rectangles, circlemarkers and circles.', 35 | deps: ['Core'] 36 | }, 37 | 38 | Extensions: { 39 | src: [ 40 | 'ext/TouchEvents.js', 41 | 'ext/LatLngUtil.js', 42 | 'ext/GeometryUtil.js', 43 | 'ext/LineUtil.Intersect.js', 44 | 'ext/Polyline.Intersect.js', 45 | 'ext/Polygon.Intersect.js' 46 | ], 47 | desc: 'Extensions of leaflet classes.' 48 | }, 49 | 50 | CommonUI: { 51 | src: [ 52 | 'Control.Draw.js', 53 | 'Toolbar.js', 54 | 'Tooltip.js' 55 | ], 56 | desc: 'Common UI components used.', 57 | deps: ['Extensions'] 58 | }, 59 | 60 | DrawUI: { 61 | src: [ 62 | 'draw/DrawToolbar.js' 63 | ], 64 | desc: 'Draw toolbar.', 65 | deps: ['DrawHandlers', 'CommonUI'] 66 | }, 67 | 68 | EditUI: { 69 | src: [ 70 | 'edit/EditToolbar.js', 71 | 'edit/handler/EditToolbar.Edit.js', 72 | 'edit/handler/EditToolbar.Delete.js' 73 | ], 74 | desc: 'Edit toolbar.', 75 | deps: ['EditHandlers', 'CommonUI'] 76 | } 77 | }; 78 | 79 | if (typeof exports !== 'undefined') { 80 | exports.deps = deps; 81 | } 82 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/docs-index.leafdoc: -------------------------------------------------------------------------------- 1 | This file just defines the order of the classes in the docs. 2 | 3 | @class L.Draw 4 | @class L.drawLocal 5 | @class L.Draw.Toolbar 6 | @class L.Draw.Event 7 | 8 | @class L.Draw.Feature 9 | @class L.Draw.SimpleShape 10 | @class L.Draw.Marker 11 | @class L.Draw.CircleMarker 12 | @class L.Draw.Circle 13 | @class L.Draw.Polyline 14 | @class L.Draw.Rectangle 15 | @class L.Draw.Polygon 16 | 17 | @class L.Edit.SimpleShape 18 | @class L.Edit.Marker 19 | @class L.Edit.CircleMarker 20 | @class L.Edit.Circle 21 | @class L.Edit.Polyline 22 | @class L.Edit.Rectangle 23 | @class L.EditToolbar.Edit 24 | @class L.EditToolbar.Delete 25 | 26 | @class L.GeometryUtil 27 | @class L.LatLngUtil 28 | @class L.LineUtil 29 | @class L.Polygon 30 | @class L.Polyline 31 | @class L.Map.TouchExtend 32 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/docs.js: -------------------------------------------------------------------------------- 1 | 2 | var packageDef = require('../package.json'); 3 | 4 | function buildDocs() { 5 | 6 | console.log('Building Leaflet Draw documentation with Leafdoc'); 7 | 8 | var LeafDoc = require('leafdoc'); 9 | var doc = new LeafDoc({ 10 | templateDir: 'build/leafdoc-templates', 11 | showInheritancesWhenEmpty: true, 12 | leadingCharacter: '@' 13 | }); 14 | 15 | //doc.setLeadingChar('@'); 16 | doc.addFile('build/docs-index.leafdoc', false); 17 | doc.addDir('src'); 18 | doc.addFile('build/docs-misc.leafdoc', false); 19 | 20 | 21 | var out = doc.outputStr(); 22 | 23 | var fs = require('fs'); 24 | 25 | fs.writeFileSync('docs/leaflet-draw-latest.html', out); 26 | fs.writeFileSync('docs/leaflet-draw-' + packageDef.version + '.html', out); 27 | } 28 | 29 | module.exports = buildDocs; 30 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/hintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser": true, 3 | "node": true, 4 | "globals": { 5 | "L": true, 6 | "define": true 7 | }, 8 | "strict": false, 9 | "bitwise": true, 10 | "camelcase": true, 11 | "curly": true, 12 | "eqeqeq": true, 13 | "forin": false, 14 | "immed": true, 15 | "latedef": true, 16 | "newcap": true, 17 | "noarg": true, 18 | "noempty": true, 19 | "nonew": true, 20 | "undef": true, 21 | "unused": true, 22 | "quotmark": "single", 23 | "indent": 4, 24 | "trailing": true, 25 | "white": true, 26 | "smarttabs": true, 27 | "maxlen": 150, 28 | "maxstatements": 20, 29 | "maxcomplexity": 5 30 | "maxparams": 4, 31 | "maxdepth": 4 32 | } 33 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/comments.hbs: -------------------------------------------------------------------------------- 1 | {{{rawmarkdown comments}}} -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/constructor.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{#each documentables}} 8 | 9 | 14 | 15 | 16 | {{/each}} 17 |
ConstructorDescription
{{name}}( 10 | {{~#each params~}} 11 | {{#if type}}<{{{type type}}}> {{/if}}{{name}} 12 | {{~#unless @last}}, {{/unless}}{{/each~}} 13 | ){{{markdown comments}}}
18 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/crs.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{#each documentables}} 8 | 9 | 10 | 11 | 12 | {{/each}} 13 |
CRSDescription
{{name}}{{{markdown comments}}}
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/destructor.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{#each documentables}} 8 | 9 | 14 | 15 | 16 | {{/each}} 17 |
DestructorDescription
{{name}}( 10 | {{~#each params~}} 11 | {{#if type}}<{{{type type}}}> {{/if}}{{name}} 12 | {{~#unless @last}}, {{/unless}}{{/each~}} 13 | ){{{markdown comments}}}
18 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/event.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{#each documentables}} 9 | 10 | 12 | 13 | 14 | {{/each}} 15 |
EventDataDescription
{{name}} 11 | {{{type type}}}{{{markdown comments}}}
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/example.hbs: -------------------------------------------------------------------------------- 1 | 2 | {{#each documentables}} 3 | {{{rawmarkdown comments}}} 4 | {{/each}} -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/factory.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{#each documentables}} 8 | 9 | 14 | 15 | 16 | {{/each}} 17 |
FactoryDescription
{{name}}( 10 | {{~#each params~}} 11 | {{#if type}}<{{{type type}}}> {{/if}}{{name}} 12 | {{~#unless @last}}, {{/unless}}{{/each~}} 13 | ){{{markdown comments}}}
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/function.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{#each documentables}} 9 | 10 | 15 | 16 | 17 | 18 | {{/each}} 19 |
FunctionReturnsDescription
{{name}}( 11 | {{~#each params~}} 12 | {{#if type}}<{{{type type}}}> {{/if}}{{name}} 13 | {{~#unless @last}}, {{/unless}}{{/each~}} 14 | ){{{type type}}}{{{markdown comments}}}
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/inherited.hbs: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |
{{{inherited}}}
6 |
7 |
8 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/method.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{#each documentables}} 9 | 10 | 15 | 16 | 17 | 18 | {{/each}} 19 |
MethodReturnsDescription
{{name}}( 11 | {{~#each params~}} 12 | {{#if type}}<{{{type type}}}> {{/if}}{{name}} 13 | {{~#unless @last}}, {{/unless}}{{/each~}} 14 | ){{{type type}}}{{{rawmarkdown comments}}}
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/namespace.hbs: -------------------------------------------------------------------------------- 1 | {{#if name ~}} 2 |

{{name}}

3 | {{~ else ~}} 4 | 5 | {{/if}} 6 | {{{rawmarkdown comments}}} 7 | {{{supersections}}} -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/option.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{#each documentables}} 10 | 11 | 12 | 14 | 15 | 16 | {{/each}} 17 |
OptionTypeDefaultDescription
{{name}}{{{type type}}} 13 | {{defaultValue}}{{{markdown comments}}}
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/pane.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{#each documentables}} 10 | 11 | 12 | 14 | 15 | 16 | {{/each}} 17 |
PaneTypeZ-indexDescription
{{name}}{{{type type}}} 13 | {{defaultValue}}{{{markdown comments}}}
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/projection.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{#each documentables}} 8 | 9 | 10 | 11 | 12 | {{/each}} 13 |
ProjectionDescription
{{name}}{{{markdown comments}}}
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/property.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{#each documentables}} 9 | 10 | 12 | 13 | 14 | {{/each}} 15 |
PropertyTypeDescription
{{name}} 11 | {{{type type}}}{{{markdown comments}}}
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/section.hbs: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{#if name}}

{{name}}

{{/if}} 4 | 5 | {{#if comments~}} 6 |
{{{markdown comments}}}
7 | {{/if}} 8 | 9 | {{{documentables}}} 10 | 11 |
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leafdoc-templates/supersection.hbs: -------------------------------------------------------------------------------- 1 |
2 |

{{name}}

3 | {{markdown comments}} 4 | {{{sections}}} 5 | 6 | {{{inheritances}}} 7 |
-------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/leaflet.draw-include.js: -------------------------------------------------------------------------------- 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(""); 41 | } 42 | })(); -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/build/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION=$(node --eval "console.log(require('./package.json').version);") 4 | 5 | npm test || exit 1 6 | 7 | git checkout -b build 8 | 9 | jake build[,,true] 10 | jake docs 11 | 12 | git add \ 13 | dist/leaflet.draw.js \ 14 | dist/leaflet.draw-src.js \ 15 | dist/leaflet.draw-src.map \ 16 | dist/leaflet.draw.css \ 17 | dist/leaflet.draw-src.css \ 18 | docs/* \ 19 | -f 20 | 21 | git commit -m "v$VERSION" 22 | 23 | git tag v$VERSION -f 24 | git push --tags -f 25 | 26 | npm publish 27 | 28 | git checkout master 29 | git branch -D build 30 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/dist/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/dist/images/layers-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/dist/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/dist/images/layers.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/dist/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/dist/images/marker-icon-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/dist/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/dist/images/marker-icon.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/dist/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/dist/images/marker-shadow.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/dist/images/spritesheet-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/dist/images/spritesheet-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/dist/images/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/dist/images/spritesheet.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/dist/leaflet.draw.css: -------------------------------------------------------------------------------- 1 | .leaflet-draw-section{position:relative}.leaflet-draw-toolbar{margin-top:12px}.leaflet-draw-toolbar-top{margin-top:0}.leaflet-draw-toolbar-notop a:first-child{border-top-right-radius:0}.leaflet-draw-toolbar-nobottom a:last-child{border-bottom-right-radius:0}.leaflet-draw-toolbar a{background-image:url('images/spritesheet.png');background-image:linear-gradient(transparent,transparent),url('images/spritesheet.svg');background-repeat:no-repeat;background-size:300px 30px;background-clip:padding-box}.leaflet-retina .leaflet-draw-toolbar a{background-image:url('images/spritesheet-2x.png');background-image:linear-gradient(transparent,transparent),url('images/spritesheet.svg')} 2 | .leaflet-draw a{display:block;text-align:center;text-decoration:none}.leaflet-draw a .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.leaflet-draw-actions{display:none;list-style:none;margin:0;padding:0;position:absolute;left:26px;top:0;white-space:nowrap}.leaflet-touch .leaflet-draw-actions{left:32px}.leaflet-right .leaflet-draw-actions{right:26px;left:auto}.leaflet-touch .leaflet-right .leaflet-draw-actions{right:32px;left:auto}.leaflet-draw-actions li{display:inline-block} 3 | .leaflet-draw-actions li:first-child a{border-left:0}.leaflet-draw-actions li:last-child a{-webkit-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.leaflet-right .leaflet-draw-actions li:last-child a{-webkit-border-radius:0;border-radius:0}.leaflet-right .leaflet-draw-actions li:first-child a{-webkit-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.leaflet-draw-actions a{background-color:#919187;border-left:1px solid #AAA;color:#FFF;font:11px/19px "Helvetica Neue",Arial,Helvetica,sans-serif;line-height:28px;text-decoration:none;padding-left:10px;padding-right:10px;height:28px} 4 | .leaflet-touch .leaflet-draw-actions a{font-size:12px;line-height:30px;height:30px}.leaflet-draw-actions-bottom{margin-top:0}.leaflet-draw-actions-top{margin-top:1px}.leaflet-draw-actions-top a,.leaflet-draw-actions-bottom a{height:27px;line-height:27px}.leaflet-draw-actions a:hover{background-color:#a0a098}.leaflet-draw-actions-top.leaflet-draw-actions-bottom a{height:26px;line-height:26px}.leaflet-draw-toolbar .leaflet-draw-draw-polyline{background-position:-2px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polyline{background-position:0 -1px} 5 | .leaflet-draw-toolbar .leaflet-draw-draw-polygon{background-position:-31px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polygon{background-position:-29px -1px}.leaflet-draw-toolbar .leaflet-draw-draw-rectangle{background-position:-62px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-rectangle{background-position:-60px -1px}.leaflet-draw-toolbar .leaflet-draw-draw-circle{background-position:-92px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circle{background-position:-90px -1px} 6 | .leaflet-draw-toolbar .leaflet-draw-draw-marker{background-position:-122px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-marker{background-position:-120px -1px}.leaflet-draw-toolbar .leaflet-draw-draw-circlemarker{background-position:-273px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circlemarker{background-position:-271px -1px}.leaflet-draw-toolbar .leaflet-draw-edit-edit{background-position:-152px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit{background-position:-150px -1px} 7 | .leaflet-draw-toolbar .leaflet-draw-edit-remove{background-position:-182px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove{background-position:-180px -1px}.leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled{background-position:-212px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled{background-position:-210px -1px}.leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled{background-position:-242px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled{background-position:-240px -2px} 8 | .leaflet-mouse-marker{background-color:#fff;cursor:crosshair}.leaflet-draw-tooltip{background:#363636;background:rgba(0,0,0,0.5);border:1px solid transparent;-webkit-border-radius:4px;border-radius:4px;color:#fff;font:12px/18px "Helvetica Neue",Arial,Helvetica,sans-serif;margin-left:20px;margin-top:-21px;padding:4px 8px;position:absolute;visibility:hidden;white-space:nowrap;z-index:6}.leaflet-draw-tooltip:before{border-right:6px solid black;border-right-color:rgba(0,0,0,0.5);border-top:6px solid transparent;border-bottom:6px solid transparent;content:"";position:absolute;top:7px;left:-7px} 9 | .leaflet-error-draw-tooltip{background-color:#f2dede;border:1px solid #e6b6bd;color:#b94a48}.leaflet-error-draw-tooltip:before{border-right-color:#e6b6bd}.leaflet-draw-tooltip-single{margin-top:-12px}.leaflet-draw-tooltip-subtext{color:#f8d5e4}.leaflet-draw-guide-dash{font-size:1%;opacity:.6;position:absolute;width:5px;height:5px}.leaflet-edit-marker-selected{background-color:rgba(254,87,161,0.1);border:4px dashed rgba(254,87,161,0.6);-webkit-border-radius:4px;border-radius:4px;box-sizing:content-box} 10 | .leaflet-edit-move{cursor:move}.leaflet-edit-resize{cursor:pointer}.leaflet-oldie .leaflet-draw-toolbar{border:1px solid #999} -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Leaflet.draw drawing and editing tools 5 | 6 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
54 | 55 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/edithandlers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Leaflet.draw vector editing handlers 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/full.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Leaflet.draw vector editing handlers 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/layers-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/layers.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/marker-icon-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/marker-icon.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/marker-icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/marker-icon@2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples-0.7.x/libs/images/marker-shadow.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Leaflet.draw drawing and editing tools 5 | 6 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
54 | 55 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples/edithandlers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Leaflet.draw vector editing handlers 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples/full.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Leaflet.draw vector editing handlers 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/layers-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/layers.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/marker-icon-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/marker-icon.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/examples/libs/images/marker-shadow.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/highlight/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006, Ivan Sagalaev 2 | All rights reserved. 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of highlight.js nor the names of its contributors 12 | may be used to endorse or promote products derived from this software 13 | without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY 16 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/highlight/styles/github-gist.css: -------------------------------------------------------------------------------- 1 | /** 2 | * GitHub Gist Theme 3 | * Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro 4 | */ 5 | 6 | .hljs { 7 | display: block; 8 | background:#f8f8f8; 9 | padding: 0.5em; 10 | color: #333333; 11 | overflow-x: auto; 12 | -webkit-text-size-adjust: none; 13 | } 14 | 15 | .hljs-comment, 16 | .bash .hljs-shebang, 17 | .java .hljs-javadoc, 18 | .javascript .hljs-javadoc { 19 | color: #969896; 20 | } 21 | 22 | .hljs-string, 23 | .apache .hljs-sqbracket, 24 | .coffeescript .hljs-subst, 25 | .coffeescript .hljs-regexp, 26 | .cpp .hljs-preprocessor, 27 | .c .hljs-preprocessor, 28 | .javascript .hljs-regexp, 29 | .json .hljs-attribute, 30 | .makefile .hljs-variable, 31 | .markdown .hljs-value, 32 | .markdown .hljs-link_label, 33 | .markdown .hljs-strong, 34 | .markdown .hljs-emphasis, 35 | .markdown .hljs-blockquote, 36 | .nginx .hljs-regexp, 37 | .nginx .hljs-number, 38 | .objectivec .hljs-preprocessor .hljs-title, 39 | .perl .hljs-regexp, 40 | .php .hljs-regexp, 41 | .xml .hljs-value, 42 | .less .hljs-built_in, 43 | .scss .hljs-built_in { 44 | color: #df5000; 45 | } 46 | 47 | .hljs-keyword, 48 | .css .hljs-at_rule, 49 | .css .hljs-important, 50 | .http .hljs-request, 51 | .ini .hljs-setting, 52 | .java .hljs-javadoctag, 53 | .javascript .hljs-tag, 54 | .javascript .hljs-javadoctag, 55 | .nginx .hljs-title, 56 | .objectivec .hljs-preprocessor, 57 | .php .hljs-phpdoc, 58 | .sql .hljs-built_in, 59 | .less .hljs-tag, 60 | .less .hljs-at_rule, 61 | .scss .hljs-tag, 62 | .scss .hljs-at_rule, 63 | .scss .hljs-important, 64 | .stylus .hljs-at_rule, 65 | .go .hljs-typename, 66 | .swift .hljs-preprocessor { 67 | color: #a71d5d; 68 | } 69 | 70 | .apache .hljs-common, 71 | .apache .hljs-cbracket, 72 | .apache .hljs-keyword, 73 | .bash .hljs-literal, 74 | .bash .hljs-built_in, 75 | .coffeescript .hljs-literal, 76 | .coffeescript .hljs-built_in, 77 | .coffeescript .hljs-number, 78 | .cpp .hljs-number, 79 | .cpp .hljs-built_in, 80 | .c .hljs-number, 81 | .c .hljs-built_in, 82 | .cs .hljs-number, 83 | .cs .hljs-built_in, 84 | .css .hljs-attribute, 85 | .css .hljs-hexcolor, 86 | .css .hljs-number, 87 | .css .hljs-function, 88 | .http .hljs-literal, 89 | .http .hljs-attribute, 90 | .java .hljs-number, 91 | .javascript .hljs-built_in, 92 | .javascript .hljs-literal, 93 | .javascript .hljs-number, 94 | .json .hljs-number, 95 | .makefile .hljs-keyword, 96 | .markdown .hljs-link_reference, 97 | .nginx .hljs-built_in, 98 | .objectivec .hljs-literal, 99 | .objectivec .hljs-number, 100 | .objectivec .hljs-built_in, 101 | .php .hljs-literal, 102 | .php .hljs-number, 103 | .python .hljs-number, 104 | .ruby .hljs-prompt, 105 | .ruby .hljs-constant, 106 | .ruby .hljs-number, 107 | .ruby .hljs-subst .hljs-keyword, 108 | .ruby .hljs-symbol, 109 | .sql .hljs-number, 110 | .puppet .hljs-function, 111 | .less .hljs-number, 112 | .less .hljs-hexcolor, 113 | .less .hljs-function, 114 | .less .hljs-attribute, 115 | .scss .hljs-preprocessor, 116 | .scss .hljs-number, 117 | .scss .hljs-hexcolor, 118 | .scss .hljs-function, 119 | .scss .hljs-attribute, 120 | .stylus .hljs-number, 121 | .stylus .hljs-hexcolor, 122 | .stylus .hljs-attribute, 123 | .stylus .hljs-params, 124 | .go .hljs-built_in, 125 | .go .hljs-constant, 126 | .swift .hljs-built_in, 127 | .swift .hljs-number { 128 | color: #0086b3; 129 | } 130 | 131 | .apache .hljs-tag, 132 | .cs .hljs-xmlDocTag, 133 | .css .hljs-tag, 134 | .xml .hljs-title, 135 | .stylus .hljs-tag { 136 | color: #63a35c; 137 | } 138 | 139 | .bash .hljs-variable, 140 | .cs .hljs-preprocessor, 141 | .cs .hljs-preprocessor .hljs-keyword, 142 | .css .hljs-attr_selector, 143 | .css .hljs-value, 144 | .ini .hljs-value, 145 | .ini .hljs-keyword, 146 | .javascript .hljs-tag .hljs-title, 147 | .makefile .hljs-constant, 148 | .nginx .hljs-variable, 149 | .xml .hljs-tag, 150 | .scss .hljs-variable { 151 | color: #333333; 152 | } 153 | 154 | .bash .hljs-title, 155 | .coffeescript .hljs-title, 156 | .cpp .hljs-title, 157 | .c .hljs-title, 158 | .cs .hljs-title, 159 | .css .hljs-id, 160 | .css .hljs-class, 161 | .css .hljs-pseudo, 162 | .ini .hljs-title, 163 | .java .hljs-title, 164 | .javascript .hljs-title, 165 | .makefile .hljs-title, 166 | .objectivec .hljs-title, 167 | .perl .hljs-sub, 168 | .php .hljs-title, 169 | .python .hljs-decorator, 170 | .python .hljs-title, 171 | .ruby .hljs-parent, 172 | .ruby .hljs-title, 173 | .xml .hljs-attribute, 174 | .puppet .hljs-title, 175 | .less .hljs-id, 176 | .less .hljs-pseudo, 177 | .less .hljs-class, 178 | .scss .hljs-id, 179 | .scss .hljs-pseudo, 180 | .scss .hljs-class, 181 | .stylus .hljs-class, 182 | .stylus .hljs-id, 183 | .stylus .hljs-pseudo, 184 | .stylus .hljs-title, 185 | .swift .hljs-title, 186 | .diff .hljs-chunk { 187 | color: #795da3; 188 | } 189 | 190 | .coffeescript .hljs-reserved, 191 | .coffeescript .hljs-attribute { 192 | color: #1d3e81; 193 | } 194 | 195 | .diff .hljs-chunk { 196 | font-weight: bold; 197 | } 198 | 199 | .diff .hljs-addition { 200 | color: #55a532; 201 | background-color: #eaffea; 202 | } 203 | 204 | .diff .hljs-deletion { 205 | color: #bd2c00; 206 | background-color: #ffecec; 207 | } 208 | 209 | .markdown .hljs-link_url { 210 | text-decoration: underline; 211 | } 212 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/images/favicon.ico -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/images/forum-round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/images/forum-round.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/images/github-round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/images/github-round.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/images/sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/images/sprite.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/images/twitter-round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/images/twitter-round.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/images/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/docs/images/twitter.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/docs/js/docs.js: -------------------------------------------------------------------------------- 1 | 2 | var tocCopy = document.createElement('div'); 3 | tocCopy.id = 'toc-copy'; 4 | 5 | var toc = document.querySelector('#toc'); 6 | 7 | if (toc) { 8 | tocCopy.innerHTML = toc.innerHTML; 9 | document.getElementsByClassName('container')[0].appendChild(tocCopy); 10 | 11 | var menus = document.querySelectorAll('#toc-copy ul'); 12 | 13 | for (var i = 0; i < menus.length; i++) { 14 | menus[i].addEventListener('mouseover', function() { 15 | this.previousElementSibling.classList.add('hover') 16 | }); 17 | 18 | menus[i].addEventListener('mouseout', function() { 19 | this.previousElementSibling.classList.remove('hover') 20 | }); 21 | } 22 | 23 | var labels = document.querySelectorAll('#toc-copy h4'); 24 | 25 | for (var i = 0; i < labels.length; i++) { 26 | labels[i].addEventListener('click', function() { 27 | this.classList.toggle('active') 28 | }); 29 | } 30 | 31 | tocCopy.addEventListener('click', function(e) { 32 | if (e.target.nodeName != 'H4') { 33 | this.classList.toggle('active'); 34 | } 35 | }); 36 | 37 | var scrollPos = function scrollPos () { 38 | var scroll = window.scrollY; 39 | 40 | if (scroll >= (toc.offsetHeight + toc.offsetTop)) { 41 | document.body.classList.add('scrolled'); 42 | } else { 43 | document.body.classList.remove('scrolled'); 44 | } 45 | } 46 | 47 | scrollPos(); 48 | 49 | window.addEventListener('scroll', function(e) { 50 | scrollPos(); 51 | }); 52 | } 53 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Leaflet Draw Documentation 4 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leaflet-draw", 3 | "version": "1.0.4", 4 | "description": "Vector drawing plugin for Leaflet", 5 | "devDependencies": { 6 | "eslint": "^3.5.0 <3.6.0", 7 | "eslint-config-mourner": "^2.0.3", 8 | "git-rev": "^0.2.1", 9 | "happen": "^0.3.2", 10 | "jake": "^8.0.15", 11 | "karma": "^1.7.1", 12 | "karma-chrome-launcher": "^2.2.0", 13 | "karma-coverage": "~1.1.1", 14 | "karma-firefox-launcher": "~1.0.0", 15 | "karma-mocha": "^1.2.0", 16 | "karma-phantomjs-launcher": "^1.0.2", 17 | "karma-safari-launcher": "~1.0.0", 18 | "leafdoc": "^1.4.0", 19 | "leaflet": "^0.7.0", 20 | "mocha": "^3.5.3", 21 | "phantomjs-prebuilt": "^2.1.16", 22 | "prosthetic-hand": "^1.3.1", 23 | "source-map": "^0.5.7", 24 | "uglify-js": "^2.8.29", 25 | "jshint": "^2.9.6", 26 | "uglifycss": "0.0.25" 27 | }, 28 | "main": "dist/leaflet.draw.js", 29 | "style": "dist/leaflet.draw.css", 30 | "directories": { 31 | "doc": "docs/", 32 | "example": "docs/example", 33 | "lib": "src/" 34 | }, 35 | "files": [ 36 | "dist/*", 37 | "docs/*" 38 | ], 39 | "scripts": { 40 | "build": "jake build -f ./Jakefile.js", 41 | "test": "jake test", 42 | "docs": "jake docs", 43 | "release": "./build/publish.sh" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "https://github.com/Leaflet/Leaflet.draw.git" 48 | }, 49 | "keywords": [ 50 | "maps", 51 | "leaflet", 52 | "client", 53 | "vector", 54 | "drawing", 55 | "draw" 56 | ], 57 | "contributors": [ 58 | { 59 | "name": "Jon West", 60 | "email": "ddproxy@gmail.com" 61 | }, 62 | { 63 | "name": "Jacob Toye" 64 | } 65 | ], 66 | "license": "MIT", 67 | "readmeFilename": "README.md", 68 | "eslintConfig": { 69 | "root": true, 70 | "globals": { 71 | "L": true 72 | }, 73 | "env": { 74 | "commonjs": true, 75 | "amd": true, 76 | "node": false 77 | }, 78 | "extends": "mourner", 79 | "rules": { 80 | "no-mixed-spaces-and-tabs": [ 81 | 2, 82 | "smart-tabs" 83 | ], 84 | "indent": [ 85 | 2, 86 | "tab", 87 | { 88 | "VariableDeclarator": 0 89 | } 90 | ], 91 | "curly": 2, 92 | "spaced-comment": 2, 93 | "strict": 0, 94 | "wrap-iife": 0, 95 | "key-spacing": 0, 96 | "consistent-return": 0 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/after.js: -------------------------------------------------------------------------------- 1 | // put after Leaflet files as imagePath can't be detected in a PhantomJS env 2 | L.Icon.Default.imagePath = "../dist/images/"; 3 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/before.js: -------------------------------------------------------------------------------- 1 | // set up before Leaflet files to test L#noConflict later 2 | L = 'test'; 3 | 4 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/happen.js: -------------------------------------------------------------------------------- 1 | // https://github.com/tmcw/happen 2 | 3 | !(function(context) { 4 | var h = {}; 5 | 6 | // Make inheritance bearable: clone one level of properties 7 | function extend(child, parent) { 8 | for (var property in parent) { 9 | if (typeof child[property] == 'undefined') { 10 | child[property] = parent[property]; 11 | } 12 | } 13 | return child; 14 | } 15 | 16 | h.once = function(x, o) { 17 | var evt; 18 | 19 | if (o.type.slice(0, 3) === 'key') { 20 | if (typeof Event === 'function') { 21 | evt = new Event(o.type); 22 | evt.keyCode = o.keyCode || 0; 23 | evt.charCode = o.charCode || 0; 24 | evt.shift = o.shift || false; 25 | evt.meta = o.meta || false; 26 | evt.ctrl = o.ctrl || false; 27 | evt.alt = o.alt || false; 28 | } else { 29 | evt = document.createEvent('KeyboardEvent'); 30 | // https://developer.mozilla.org/en/DOM/event.initKeyEvent 31 | // https://developer.mozilla.org/en/DOM/KeyboardEvent 32 | evt[(evt.initKeyEvent) ? 'initKeyEvent' 33 | : 'initKeyboardEvent']( 34 | o.type, // in DOMString typeArg, 35 | true, // in boolean canBubbleArg, 36 | true, // in boolean cancelableArg, 37 | null, // in nsIDOMAbstractView viewArg, Specifies UIEvent.view. This value may be null. 38 | o.ctrl || false, // in boolean ctrlKeyArg, 39 | o.alt || false, // in boolean altKeyArg, 40 | o.shift || false, // in boolean shiftKeyArg, 41 | o.meta || false, // in boolean metaKeyArg, 42 | o.keyCode || 0, // in unsigned long keyCodeArg, 43 | o.charCode || 0 // in unsigned long charCodeArg); 44 | ); 45 | } 46 | } else { 47 | evt = document.createEvent('MouseEvents'); 48 | // https://developer.mozilla.org/en/DOM/event.initMouseEvent 49 | evt.initMouseEvent(o.type, 50 | true, // canBubble 51 | true, // cancelable 52 | window, // 'AbstractView' 53 | o.clicks || 0, // click count 54 | o.screenX || 0, // screenX 55 | o.screenY || 0, // screenY 56 | o.clientX || 0, // clientX 57 | o.clientY || 0, // clientY 58 | o.ctrl || 0, // ctrl 59 | o.alt || false, // alt 60 | o.shift || false, // shift 61 | o.meta || false, // meta 62 | o.button || false, // mouse button 63 | null // relatedTarget 64 | ); 65 | } 66 | 67 | x.dispatchEvent(evt); 68 | }; 69 | 70 | var shortcuts = ['click', 'mousedown', 'mouseup', 'mousemove', 'keydown', 'keyup', 'keypress'], 71 | s, i = 0; 72 | 73 | while (s = shortcuts[i++]) { 74 | h[s] = (function(s) { 75 | return function(x, o) { 76 | h.once(x, extend(o || {}, { type: s })); 77 | }; 78 | })(s); 79 | } 80 | 81 | h.dblclick = function(x, o) { 82 | h.once(x, extend(o || {}, { 83 | type: 'dblclick', 84 | clicks: 2 85 | })); 86 | }; 87 | 88 | this.happen = h; 89 | 90 | if (typeof module !== 'undefined') { 91 | module.exports = this.happen; 92 | } 93 | })(this); 94 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Spec Runner 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | module.exports = function (config) { 3 | 4 | var libSources = require(__dirname+'/../build/build.js').getFiles(); 5 | var leafletSources = require(__dirname+'/../node_modules/leaflet/build/build.js').getFiles(); 6 | 7 | for (var i=0; i < leafletSources.length; i++) { 8 | leafletSources[i] = __dirname+"/../node_modules/leaflet/" + leafletSources[i]; 9 | } 10 | 11 | var files = [ 12 | "spec/before.js", 13 | "spec/sinon.js", 14 | "spec/expect.js" 15 | ].concat(leafletSources, libSources, [ 16 | "spec/after.js", 17 | "node_modules/happen/happen.js", 18 | "node_modules/prosthetic-hand/dist/prosthetic-hand.js", 19 | "spec/suites/SpecHelper.js", 20 | "spec/suites/**/*.js", 21 | "dist/*.css", 22 | {pattern: "dist/images/*.png", included: false} 23 | ]); 24 | 25 | config.set({ 26 | // base path, that will be used to resolve files and exclude 27 | basePath: '../', 28 | 29 | plugins: [ 30 | 'karma-mocha', 31 | 'karma-phantomjs-launcher'], 32 | 33 | // frameworks to use 34 | frameworks: ['mocha'], 35 | 36 | // list of files / patterns to load in the browser 37 | files: files, 38 | exclude: [], 39 | 40 | // test results reporter to use 41 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' 42 | reporters: ['dots'], 43 | 44 | // web server port 45 | port: 9876, 46 | 47 | // level of logging 48 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 49 | logLevel: config.LOG_WARN, 50 | 51 | // enable / disable colors in the output (reporters and logs) 52 | colors: true, 53 | 54 | // enable / disable watching file and executing tests whenever any file changes 55 | autoWatch: false, 56 | 57 | // Start these browsers, currently available: 58 | // - Chrome 59 | // - ChromeCanary 60 | // - Firefox 61 | // - Opera 62 | // - Safari (only Mac) 63 | // - PhantomJS 64 | // - IE (only Windows) 65 | browsers: [ 66 | 'PhantomJSCustom' 67 | ], 68 | 69 | customLaunchers: { 70 | 'PhantomJSCustom': { 71 | base: 'PhantomJS', 72 | flags: ['--load-images=true'], 73 | options: { 74 | onCallback: function (data) { 75 | if (data.render) { 76 | page.render(data.render); 77 | } 78 | } 79 | } 80 | } 81 | }, 82 | 83 | // If browser does not capture in given timeout [ms], kill it 84 | captureTimeout: 5000, 85 | 86 | // Continuous Integration mode 87 | // if true, it capture browsers, run tests and exit 88 | singleRun: true 89 | }); 90 | }; 91 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/spec.hintrc.js: -------------------------------------------------------------------------------- 1 | { 2 | "browser": true, 3 | "node": true, 4 | "predef": ["define", "L", "expect", "describe", "it", "sinon", "happen", "beforeEach", "afterEach"], 5 | "strict": false, 6 | "bitwise": true, 7 | "camelcase": true, 8 | "curly": true, 9 | "eqeqeq": true, 10 | "forin": false, 11 | "immed": true, 12 | "latedef": true, 13 | "newcap": true, 14 | "noarg": true, 15 | "noempty": true, 16 | "nonew": true, 17 | "undef": true, 18 | // "unused": true, 19 | // "quotmark": "single", 20 | "indent": 4, 21 | "trailing": true, 22 | "white": true, 23 | "smarttabs": true 24 | // "maxlen": 120 25 | } -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/suites/DrawControlSpec.js: -------------------------------------------------------------------------------- 1 | describe("Control.Draw", function () { 2 | var map, control, container; 3 | 4 | beforeEach(function () { 5 | map = L.map(document.createElement('div')); 6 | control = new L.Control.Draw({}); 7 | map.addControl(control); 8 | container = control.getContainer(); 9 | }); 10 | 11 | it("exists", function () { 12 | expect(container.innerHTML).to.be.ok(); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/suites/EditSpec.js: -------------------------------------------------------------------------------- 1 | describe("L.Edit", function () { 2 | var map; 3 | 4 | beforeEach(function () { 5 | map = new L.Map(document.createElement('div')).setView([0, 0], 15); 6 | }); 7 | 8 | describe("L.Edit.Marker", function () { 9 | var marker; 10 | 11 | beforeEach(function () { 12 | marker = new L.Marker(new L.LatLng(1, 2)).addTo(map); 13 | marker.editing.enable(); 14 | }); 15 | 16 | it("Has the leaflet-edit-marker-selected class applied when enabled.", function () { 17 | var editingClass = 'leaflet-edit-marker-selected'; 18 | 19 | expect(marker.editing.enabled()).to.equal(true); 20 | expect(L.DomUtil.hasClass(marker._icon, editingClass)).to.equal(true); 21 | }); 22 | 23 | it("Lacks the leaflet-edit-marker-selected class when disabled.", function () { 24 | var editingClass = 'leaflet-edit-marker-selected'; 25 | 26 | marker.editing.disable(); 27 | 28 | expect(marker.editing.enabled()).to.equal(false); 29 | expect(L.DomUtil.hasClass(marker._icon, editingClass)).to.equal(false); 30 | }); 31 | }); 32 | 33 | describe("L.Edit.CircleMarker", function () { 34 | var circleMarker; 35 | 36 | beforeEach(function () { 37 | circleMarker = new L.CircleMarker(new L.LatLng(1, 2)).addTo(map); 38 | circleMarker.editing.enable(); 39 | }); 40 | 41 | it("Is activated correctly when editing.enable() is called.", function () {}); 42 | 43 | it("Moves the circlemarker to the correct latlng", function () { 44 | var newLatLng = new L.LatLng(3, 5); 45 | 46 | circleMarker.editing._move(newLatLng); 47 | expect(circleMarker.getLatLng()).to.eql(newLatLng); 48 | }); 49 | }); 50 | 51 | describe("L.Edit.Circle", function () { 52 | var circle; 53 | 54 | beforeEach(function () { 55 | circle = new L.Circle(new L.LatLng(1, 2), 5).addTo(map); 56 | circle.editing.enable(); 57 | }); 58 | 59 | it("Is activated correctly when editing.enable() is called.", function () {}); 60 | 61 | it("Moves the circle to the correct latlng", function () { 62 | var newLatLng = new L.LatLng(3, 5); 63 | 64 | circle.editing._move(newLatLng); 65 | expect(circle.getLatLng()).to.eql(newLatLng); 66 | }); 67 | }); 68 | 69 | describe("L.Edit.Poly", function () { 70 | var edit, 71 | drawnItems, 72 | poly; 73 | 74 | beforeEach(function () { 75 | drawnItems = new L.FeatureGroup().addTo(map); 76 | edit = new L.EditToolbar.Edit(map, { 77 | featureGroup: drawnItems, 78 | poly: { 79 | allowIntersection : false 80 | }, 81 | selectedPathOptions: L.EditToolbar.prototype.options.edit.selectedPathOptions 82 | }); 83 | poly = new L.Polyline(L.latLng(41, -87), L.latLng(42, -88)); 84 | }); 85 | 86 | it("Should change the style of the polyline during editing mode.", function () { 87 | var originalOptions = L.extend({}, poly.options); 88 | 89 | drawnItems.addLayer(poly); 90 | edit.enable(); 91 | 92 | expect(poly.editing.enabled()).to.equal(true); 93 | expect(poly.options).not.to.eql(originalOptions); 94 | }); 95 | 96 | it("Should revert to original styles when editing is toggled.", function () { 97 | var originalOptions = L.extend({maintainColor: false, poly : {allowIntersection: false} }, poly.options); 98 | 99 | drawnItems.addLayer(poly); 100 | edit.enable(); 101 | edit.disable(); 102 | 103 | expect(poly.options).to.eql(originalOptions); 104 | }); 105 | 106 | it("Should set allowIntersection to be false when setting is set", function () { 107 | 108 | drawnItems.addLayer(poly); 109 | edit.enable(); 110 | 111 | expect(poly.editing.enabled()).to.equal(true); 112 | expect(poly.options.poly.allowIntersection).to.equal(false); 113 | 114 | }); 115 | 116 | }); 117 | 118 | describe("L.EditToolbar.Delete", function () { 119 | var drawnItems,marker,circle,poly,deleteToollbar; 120 | 121 | beforeEach(function () { 122 | drawnItems = new L.FeatureGroup().addTo(map); 123 | deleteToollbar = new L.EditToolbar.Delete(map, { 124 | featureGroup: drawnItems 125 | }); 126 | marker = new L.Marker(new L.LatLng(1, 2)); 127 | circle = new L.Circle(new L.LatLng(1, 2), 5); 128 | poly = new L.Polyline(L.latLng(41, -87), L.latLng(42, -88)); 129 | drawnItems.addLayer(marker).addLayer(circle).addLayer(poly); 130 | }); 131 | 132 | it("The drawlayer should has 3 features on it.", function () { 133 | expect(drawnItems.getLayers().length).to.eql(3); 134 | }); 135 | 136 | it("After clearing the drawlayer it should have no features.", function () { 137 | deleteToollbar.enable(); 138 | deleteToollbar.removeAllLayers(); 139 | deleteToollbar.disable(); 140 | expect(drawnItems.getLayers().length).to.eql(0); 141 | }); 142 | 143 | it("The map should fire the events for clearing.", function () { 144 | var events = []; 145 | map.on(L.Draw.Event.DELETESTART,function (event) { 146 | events.push(event.type); 147 | }) 148 | map.on(L.Draw.Event.DELETED,function (event) { 149 | events.push(event.type); 150 | }) 151 | map.on(L.Draw.Event.DELETESTOP,function (event) { 152 | events.push(event.type); 153 | }) 154 | deleteToollbar.enable(); 155 | deleteToollbar.removeAllLayers(); 156 | deleteToollbar.disable(); 157 | expect(events[0]).to.eql(L.Draw.Event.DELETESTART); 158 | expect(events[1]).to.eql(L.Draw.Event.DELETED); 159 | expect(events[2]).to.eql(L.Draw.Event.DELETESTOP); 160 | }); 161 | 162 | }); 163 | }); 164 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/suites/LatLngUtilSpec.js: -------------------------------------------------------------------------------- 1 | describe("L.LatLngUtil", function () { 2 | it("cloneLatLngs", function () { 3 | var latLngs = [{ lat: 0, lng: 0 }], 4 | clone = L.LatLngUtil.cloneLatLngs(latLngs); 5 | 6 | expect(clone[0].lat).to.eql(latLngs[0].lat); 7 | 8 | clone[0].lat = 10; 9 | expect(latLngs[0].lat).to.eql(0); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/spec/suites/SpecHelper.js: -------------------------------------------------------------------------------- 1 | if (!Array.prototype.map) { 2 | Array.prototype.map = function (fun /*, thisp */) { 3 | "use strict"; 4 | 5 | if (this === void 0 || this === null) { 6 | throw new TypeError(); 7 | } 8 | 9 | var t = Object(this), 10 | len = t.length >>> 0; 11 | 12 | if (typeof fun !== 'function') { 13 | throw new TypeError(); 14 | } 15 | 16 | var res = new Array(len), 17 | thisp = arguments[1]; 18 | 19 | for (var i = 0; i < len; i++) { 20 | if (i in t) { 21 | res[i] = fun.call(thisp, t[i], i, t); 22 | } 23 | } 24 | 25 | return res; 26 | }; 27 | } -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/Control.Draw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.Control.Draw 3 | * @aka L.Draw 4 | */ 5 | L.Control.Draw = L.Control.extend({ 6 | 7 | // Options 8 | options: { 9 | position: 'topleft', 10 | draw: {}, 11 | edit: false 12 | }, 13 | 14 | // @method initialize(): void 15 | // Initializes draw control, toolbars from the options 16 | initialize: function (options) { 17 | if (L.version < '0.7') { 18 | throw new Error('Leaflet.draw 0.2.3+ requires Leaflet 0.7.0+. Download latest from https://github.com/Leaflet/Leaflet/'); 19 | } 20 | 21 | L.Control.prototype.initialize.call(this, options); 22 | 23 | var toolbar; 24 | 25 | this._toolbars = {}; 26 | 27 | // Initialize toolbars 28 | if (L.DrawToolbar && this.options.draw) { 29 | toolbar = new L.DrawToolbar(this.options.draw); 30 | 31 | this._toolbars[L.DrawToolbar.TYPE] = toolbar; 32 | 33 | // Listen for when toolbar is enabled 34 | this._toolbars[L.DrawToolbar.TYPE].on('enable', this._toolbarEnabled, this); 35 | } 36 | 37 | if (L.EditToolbar && this.options.edit) { 38 | toolbar = new L.EditToolbar(this.options.edit); 39 | 40 | this._toolbars[L.EditToolbar.TYPE] = toolbar; 41 | 42 | // Listen for when toolbar is enabled 43 | this._toolbars[L.EditToolbar.TYPE].on('enable', this._toolbarEnabled, this); 44 | } 45 | L.toolbar = this; //set global var for editing the toolbar 46 | }, 47 | 48 | // @method onAdd(): container 49 | // Adds the toolbar container to the map 50 | onAdd: function (map) { 51 | var container = L.DomUtil.create('div', 'leaflet-draw'), 52 | addedTopClass = false, 53 | topClassName = 'leaflet-draw-toolbar-top', 54 | toolbarContainer; 55 | 56 | for (var toolbarId in this._toolbars) { 57 | if (this._toolbars.hasOwnProperty(toolbarId)) { 58 | toolbarContainer = this._toolbars[toolbarId].addToolbar(map); 59 | 60 | if (toolbarContainer) { 61 | // Add class to the first toolbar to remove the margin 62 | if (!addedTopClass) { 63 | if (!L.DomUtil.hasClass(toolbarContainer, topClassName)) { 64 | L.DomUtil.addClass(toolbarContainer.childNodes[0], topClassName); 65 | } 66 | addedTopClass = true; 67 | } 68 | 69 | container.appendChild(toolbarContainer); 70 | } 71 | } 72 | } 73 | 74 | return container; 75 | }, 76 | 77 | // @method onRemove(): void 78 | // Removes the toolbars from the map toolbar container 79 | onRemove: function () { 80 | for (var toolbarId in this._toolbars) { 81 | if (this._toolbars.hasOwnProperty(toolbarId)) { 82 | this._toolbars[toolbarId].removeToolbar(); 83 | } 84 | } 85 | }, 86 | 87 | // @method setDrawingOptions(options): void 88 | // Sets options to all toolbar instances 89 | setDrawingOptions: function (options) { 90 | for (var toolbarId in this._toolbars) { 91 | if (this._toolbars[toolbarId] instanceof L.DrawToolbar) { 92 | this._toolbars[toolbarId].setOptions(options); 93 | } 94 | } 95 | }, 96 | 97 | _toolbarEnabled: function (e) { 98 | var enabledToolbar = e.target; 99 | 100 | for (var toolbarId in this._toolbars) { 101 | if (this._toolbars[toolbarId] !== enabledToolbar) { 102 | this._toolbars[toolbarId].disable(); 103 | } 104 | } 105 | } 106 | }); 107 | 108 | L.Map.mergeOptions({ 109 | drawControlTooltips: true, 110 | drawControl: false 111 | }); 112 | 113 | L.Map.addInitHook(function () { 114 | if (this.options.drawControl) { 115 | this.drawControl = new L.Control.Draw(); 116 | this.addControl(this.drawControl); 117 | } 118 | }); 119 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/Leaflet.Draw.Event.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ### Events 3 | * Once you have successfully added the Leaflet.draw plugin to your map you will want to respond to the different 4 | * actions users can initiate. The following events will be triggered on the map: 5 | * 6 | * @class L.Draw.Event 7 | * @aka Draw.Event 8 | * 9 | * Use `L.Draw.Event.EVENTNAME` constants to ensure events are correct. 10 | * 11 | * @example 12 | * ```js 13 | * map.on(L.Draw.Event.CREATED; function (e) { 14 | * var type = e.layerType, 15 | * layer = e.layer; 16 | * 17 | * if (type === 'marker') { 18 | * // Do marker specific actions 19 | * } 20 | * 21 | * // Do whatever else you need to. (save to db; add to map etc) 22 | * map.addLayer(layer); 23 | *}); 24 | * ``` 25 | */ 26 | L.Draw.Event = {}; 27 | /** 28 | * @event draw:created: PolyLine; Polygon; Rectangle; Circle; Marker | String 29 | * 30 | * Layer that was just created. 31 | * The type of layer this is. One of: `polyline`; `polygon`; `rectangle`; `circle`; `marker` 32 | * Triggered when a new vector or marker has been created. 33 | * 34 | */ 35 | L.Draw.Event.CREATED = 'draw:created'; 36 | 37 | /** 38 | * @event draw:edited: LayerGroup 39 | * 40 | * List of all layers just edited on the map. 41 | * 42 | * 43 | * Triggered when layers in the FeatureGroup; initialised with the plugin; have been edited and saved. 44 | * 45 | * @example 46 | * ```js 47 | * map.on('draw:edited', function (e) { 48 | * var layers = e.layers; 49 | * layers.eachLayer(function (layer) { 50 | * //do whatever you want; most likely save back to db 51 | * }); 52 | * }); 53 | * ``` 54 | */ 55 | L.Draw.Event.EDITED = 'draw:edited'; 56 | 57 | /** 58 | * @event draw:deleted: LayerGroup 59 | * 60 | * List of all layers just removed from the map. 61 | * 62 | * Triggered when layers have been removed (and saved) from the FeatureGroup. 63 | */ 64 | L.Draw.Event.DELETED = 'draw:deleted'; 65 | 66 | /** 67 | * @event draw:drawstart: String 68 | * 69 | * The type of layer this is. One of:`polyline`; `polygon`; `rectangle`; `circle`; `marker` 70 | * 71 | * Triggered when the user has chosen to draw a particular vector or marker. 72 | */ 73 | L.Draw.Event.DRAWSTART = 'draw:drawstart'; 74 | 75 | /** 76 | * @event draw:drawstop: String 77 | * 78 | * The type of layer this is. One of: `polyline`; `polygon`; `rectangle`; `circle`; `marker` 79 | * 80 | * Triggered when the user has finished a particular vector or marker. 81 | */ 82 | 83 | L.Draw.Event.DRAWSTOP = 'draw:drawstop'; 84 | 85 | /** 86 | * @event draw:drawvertex: LayerGroup 87 | * 88 | * List of all layers just being added from the map. 89 | * 90 | * Triggered when a vertex is created on a polyline or polygon. 91 | */ 92 | L.Draw.Event.DRAWVERTEX = 'draw:drawvertex'; 93 | 94 | /** 95 | * @event draw:editstart: String 96 | * 97 | * The type of edit this is. One of: `edit` 98 | * 99 | * Triggered when the user starts edit mode by clicking the edit tool button. 100 | */ 101 | 102 | L.Draw.Event.EDITSTART = 'draw:editstart'; 103 | 104 | /** 105 | * @event draw:editmove: ILayer 106 | * 107 | * Layer that was just moved. 108 | * 109 | * Triggered as the user moves a rectangle; circle or marker. 110 | */ 111 | L.Draw.Event.EDITMOVE = 'draw:editmove'; 112 | 113 | /** 114 | * @event draw:editresize: ILayer 115 | * 116 | * Layer that was just moved. 117 | * 118 | * Triggered as the user resizes a rectangle or circle. 119 | */ 120 | L.Draw.Event.EDITRESIZE = 'draw:editresize'; 121 | 122 | /** 123 | * @event draw:editvertex: LayerGroup 124 | * 125 | * List of all layers just being edited from the map. 126 | * 127 | * Triggered when a vertex is edited on a polyline or polygon. 128 | */ 129 | L.Draw.Event.EDITVERTEX = 'draw:editvertex'; 130 | 131 | /** 132 | * @event draw:editstop: String 133 | * 134 | * The type of edit this is. One of: `edit` 135 | * 136 | * Triggered when the user has finshed editing (edit mode) and saves edits. 137 | */ 138 | L.Draw.Event.EDITSTOP = 'draw:editstop'; 139 | 140 | /** 141 | * @event draw:deletestart: String 142 | * 143 | * The type of edit this is. One of: `remove` 144 | * 145 | * Triggered when the user starts remove mode by clicking the remove tool button. 146 | */ 147 | L.Draw.Event.DELETESTART = 'draw:deletestart'; 148 | 149 | /** 150 | * @event draw:deletestop: String 151 | * 152 | * The type of edit this is. One of: `remove` 153 | * 154 | * Triggered when the user has finished removing shapes (remove mode) and saves. 155 | */ 156 | L.Draw.Event.DELETESTOP = 'draw:deletestop'; 157 | 158 | /** 159 | * @event draw:toolbaropened: String 160 | * 161 | * Triggered when a toolbar is opened. 162 | */ 163 | L.Draw.Event.TOOLBAROPENED = 'draw:toolbaropened'; 164 | 165 | /** 166 | * @event draw:toolbarclosed: String 167 | * 168 | * Triggered when a toolbar is closed. 169 | */ 170 | L.Draw.Event.TOOLBARCLOSED = 'draw:toolbarclosed'; 171 | 172 | /** 173 | * @event draw:markercontext: String 174 | * 175 | * Triggered when a marker is right clicked. 176 | */ 177 | L.Draw.Event.MARKERCONTEXT = 'draw:markercontext'; -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/Leaflet.draw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Leaflet.draw assumes that you have already included the Leaflet library. 3 | */ 4 | L.drawVersion = '0.4.2'; 5 | /** 6 | * @class L.Draw 7 | * @aka Draw 8 | * 9 | * 10 | * To add the draw toolbar set the option drawControl: true in the map options. 11 | * 12 | * @example 13 | * ```js 14 | * var map = L.map('map', {drawControl: true}).setView([51.505, -0.09], 13); 15 | * 16 | * L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { 17 | * attribution: '© OpenStreetMap contributors' 18 | * }).addTo(map); 19 | * ``` 20 | * 21 | * ### Adding the edit toolbar 22 | * To use the edit toolbar you must initialise the Leaflet.draw control and manually add it to the map. 23 | * 24 | * ```js 25 | * var map = L.map('map').setView([51.505, -0.09], 13); 26 | * 27 | * L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { 28 | * attribution: '© OpenStreetMap contributors' 29 | * }).addTo(map); 30 | * 31 | * // FeatureGroup is to store editable layers 32 | * var drawnItems = new L.FeatureGroup(); 33 | * map.addLayer(drawnItems); 34 | * 35 | * var drawControl = new L.Control.Draw({ 36 | * edit: { 37 | * featureGroup: drawnItems 38 | * } 39 | * }); 40 | * map.addControl(drawControl); 41 | * ``` 42 | * 43 | * The key here is the featureGroup option. This tells the plugin which FeatureGroup contains the layers that 44 | * should be editable. The featureGroup can contain 0 or more features with geometry types Point, LineString, and Polygon. 45 | * Leaflet.draw does not work with multigeometry features such as MultiPoint, MultiLineString, MultiPolygon, 46 | * or GeometryCollection. If you need to add multigeometry features to the draw plugin, convert them to a 47 | * FeatureCollection of non-multigeometries (Points, LineStrings, or Polygons). 48 | */ 49 | L.Draw = {}; 50 | 51 | /** 52 | * @class L.drawLocal 53 | * @aka L.drawLocal 54 | * 55 | * The core toolbar class of the API — it is used to create the toolbar ui 56 | * 57 | * @example 58 | * ```js 59 | * var modifiedDraw = L.drawLocal.extend({ 60 | * draw: { 61 | * toolbar: { 62 | * buttons: { 63 | * polygon: 'Draw an awesome polygon' 64 | * } 65 | * } 66 | * } 67 | * }); 68 | * ``` 69 | * 70 | * The default state for the control is the draw toolbar just below the zoom control. 71 | * This will allow map users to draw vectors and markers. 72 | * **Please note the edit toolbar is not enabled by default.** 73 | */ 74 | L.drawLocal = { 75 | // format: { 76 | // numeric: { 77 | // delimiters: { 78 | // thousands: ',', 79 | // decimal: '.' 80 | // } 81 | // } 82 | // }, 83 | draw: { 84 | toolbar: { 85 | // #TODO: this should be reorganized where actions are nested in actions 86 | // ex: actions.undo or actions.cancel 87 | actions: { 88 | title: 'Cancel drawing', 89 | text: 'Cancel' 90 | }, 91 | finish: { 92 | title: 'Finish drawing', 93 | text: 'Finish' 94 | }, 95 | undo: { 96 | title: 'Delete last point drawn', 97 | text: 'Delete last point' 98 | }, 99 | buttons: { 100 | polyline: 'Draw a polyline', 101 | polygon: 'Draw a polygon', 102 | rectangle: 'Draw a rectangle', 103 | circle: 'Draw a circle', 104 | marker: 'Draw a marker', 105 | circlemarker: 'Draw a circlemarker' 106 | } 107 | }, 108 | handlers: { 109 | circle: { 110 | tooltip: { 111 | start: 'Click and drag to draw circle.' 112 | }, 113 | radius: 'Radius' 114 | }, 115 | circlemarker: { 116 | tooltip: { 117 | start: 'Click map to place circle marker.' 118 | } 119 | }, 120 | marker: { 121 | tooltip: { 122 | start: 'Click map to place marker.' 123 | } 124 | }, 125 | polygon: { 126 | tooltip: { 127 | start: 'Click to start drawing shape.', 128 | cont: 'Click to continue drawing shape.', 129 | end: 'Click first point to close this shape.' 130 | } 131 | }, 132 | polyline: { 133 | error: 'Error: shape edges cannot cross!', 134 | tooltip: { 135 | start: 'Click to start drawing line.', 136 | cont: 'Click to continue drawing line.', 137 | end: 'Click last point to finish line.' 138 | } 139 | }, 140 | rectangle: { 141 | tooltip: { 142 | start: 'Click and drag to draw rectangle.' 143 | } 144 | }, 145 | simpleshape: { 146 | tooltip: { 147 | end: 'Release mouse to finish drawing.' 148 | } 149 | } 150 | } 151 | }, 152 | edit: { 153 | toolbar: { 154 | actions: { 155 | save: { 156 | title: 'Save changes', 157 | text: 'Save' 158 | }, 159 | cancel: { 160 | title: 'Cancel editing, discards all changes', 161 | text: 'Cancel' 162 | }, 163 | clearAll: { 164 | title: 'Clear all layers', 165 | text: 'Clear All' 166 | } 167 | }, 168 | buttons: { 169 | edit: 'Edit layers', 170 | editDisabled: 'No layers to edit', 171 | remove: 'Delete layers', 172 | removeDisabled: 'No layers to delete' 173 | } 174 | }, 175 | handlers: { 176 | edit: { 177 | tooltip: { 178 | text: 'Drag handles or markers to edit features.', 179 | subtext: 'Click cancel to undo changes.' 180 | } 181 | }, 182 | remove: { 183 | tooltip: { 184 | text: 'Click on a feature to remove.' 185 | } 186 | } 187 | } 188 | } 189 | }; 190 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/Tooltip.js: -------------------------------------------------------------------------------- 1 | L.Draw = L.Draw || {}; 2 | /** 3 | * @class L.Draw.Tooltip 4 | * @aka Tooltip 5 | * 6 | * The tooltip class — it is used to display the tooltip while drawing 7 | * This will be depreciated 8 | * 9 | * @example 10 | * 11 | * ```js 12 | * var tooltip = L.Draw.Tooltip(); 13 | * ``` 14 | * 15 | */ 16 | L.Draw.Tooltip = L.Class.extend({ 17 | 18 | // @section Methods for modifying draw state 19 | 20 | // @method initialize(map): void 21 | // Tooltip constructor 22 | initialize: function (map) { 23 | this._map = map; 24 | this._popupPane = map._panes.popupPane; 25 | this._visible = false; 26 | 27 | this._container = map.options.drawControlTooltips ? 28 | L.DomUtil.create('div', 'leaflet-draw-tooltip', this._popupPane) : null; 29 | this._singleLineLabel = false; 30 | 31 | this._map.on('mouseout', this._onMouseOut, this); 32 | }, 33 | 34 | // @method dispose(): void 35 | // Remove Tooltip DOM and unbind events 36 | dispose: function () { 37 | this._map.off('mouseout', this._onMouseOut, this); 38 | 39 | if (this._container) { 40 | this._popupPane.removeChild(this._container); 41 | this._container = null; 42 | } 43 | }, 44 | 45 | // @method updateContent(labelText): this 46 | // Changes the tooltip text to string in function call 47 | updateContent: function (labelText) { 48 | if (!this._container) { 49 | return this; 50 | } 51 | labelText.subtext = labelText.subtext || ''; 52 | 53 | // update the vertical position (only if changed) 54 | if (labelText.subtext.length === 0 && !this._singleLineLabel) { 55 | L.DomUtil.addClass(this._container, 'leaflet-draw-tooltip-single'); 56 | this._singleLineLabel = true; 57 | } 58 | else if (labelText.subtext.length > 0 && this._singleLineLabel) { 59 | L.DomUtil.removeClass(this._container, 'leaflet-draw-tooltip-single'); 60 | this._singleLineLabel = false; 61 | } 62 | 63 | this._container.innerHTML = 64 | (labelText.subtext.length > 0 ? 65 | '' + labelText.subtext + '' + '
' : '') + 66 | '' + labelText.text + ''; 67 | 68 | if (!labelText.text && !labelText.subtext) { 69 | this._visible = false; 70 | this._container.style.visibility = 'hidden'; 71 | } else { 72 | this._visible = true; 73 | this._container.style.visibility = 'inherit'; 74 | } 75 | 76 | return this; 77 | }, 78 | 79 | // @method updatePosition(latlng): this 80 | // Changes the location of the tooltip 81 | updatePosition: function (latlng) { 82 | var pos = this._map.latLngToLayerPoint(latlng), 83 | tooltipContainer = this._container; 84 | 85 | if (this._container) { 86 | if (this._visible) { 87 | tooltipContainer.style.visibility = 'inherit'; 88 | } 89 | L.DomUtil.setPosition(tooltipContainer, pos); 90 | } 91 | 92 | return this; 93 | }, 94 | 95 | // @method showAsError(): this 96 | // Applies error class to tooltip 97 | showAsError: function () { 98 | if (this._container) { 99 | L.DomUtil.addClass(this._container, 'leaflet-error-draw-tooltip'); 100 | } 101 | return this; 102 | }, 103 | 104 | // @method removeError(): this 105 | // Removes the error class from the tooltip 106 | removeError: function () { 107 | if (this._container) { 108 | L.DomUtil.removeClass(this._container, 'leaflet-error-draw-tooltip'); 109 | } 110 | return this; 111 | }, 112 | 113 | _onMouseOut: function () { 114 | if (this._container) { 115 | this._container.style.visibility = 'hidden'; 116 | } 117 | } 118 | }); 119 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/copyright.js: -------------------------------------------------------------------------------- 1 | /* 2 | Leaflet.draw {VERSION}, a plugin that adds drawing and editing tools to Leaflet powered maps. 3 | (c) 2012-2017, Jacob Toye, Jon West, Smartrak, Leaflet 4 | 5 | https://github.com/Leaflet/Leaflet.draw 6 | http://leafletjs.com 7 | */ 8 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/draw/DrawToolbar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.DrawToolbar 3 | * @aka Toolbar 4 | */ 5 | L.DrawToolbar = L.Toolbar.extend({ 6 | 7 | statics: { 8 | TYPE: 'draw' 9 | }, 10 | 11 | options: { 12 | polyline: {}, 13 | polygon: {}, 14 | rectangle: {}, 15 | circle: {}, 16 | marker: {}, 17 | circlemarker: {} 18 | }, 19 | 20 | // @method initialize(): void 21 | initialize: function (options) { 22 | // Ensure that the options are merged correctly since L.extend is only shallow 23 | for (var type in this.options) { 24 | if (this.options.hasOwnProperty(type)) { 25 | if (options[type]) { 26 | options[type] = L.extend({}, this.options[type], options[type]); 27 | } 28 | } 29 | } 30 | 31 | this._toolbarClass = 'leaflet-draw-draw'; 32 | L.Toolbar.prototype.initialize.call(this, options); 33 | }, 34 | 35 | // @method getModeHandlers(): object 36 | // Get mode handlers information 37 | getModeHandlers: function (map) { 38 | return [ 39 | { 40 | enabled: this.options.polyline, 41 | handler: new L.Draw.Polyline(map, this.options.polyline), 42 | title: L.drawLocal.draw.toolbar.buttons.polyline 43 | }, 44 | { 45 | enabled: this.options.polygon, 46 | handler: new L.Draw.Polygon(map, this.options.polygon), 47 | title: L.drawLocal.draw.toolbar.buttons.polygon 48 | }, 49 | { 50 | enabled: this.options.rectangle, 51 | handler: new L.Draw.Rectangle(map, this.options.rectangle), 52 | title: L.drawLocal.draw.toolbar.buttons.rectangle 53 | }, 54 | { 55 | enabled: this.options.circle, 56 | handler: new L.Draw.Circle(map, this.options.circle), 57 | title: L.drawLocal.draw.toolbar.buttons.circle 58 | }, 59 | { 60 | enabled: this.options.marker, 61 | handler: new L.Draw.Marker(map, this.options.marker), 62 | title: L.drawLocal.draw.toolbar.buttons.marker 63 | }, 64 | { 65 | enabled: this.options.circlemarker, 66 | handler: new L.Draw.CircleMarker(map, this.options.circlemarker), 67 | title: L.drawLocal.draw.toolbar.buttons.circlemarker 68 | } 69 | ]; 70 | }, 71 | 72 | // @method getActions(): object 73 | // Get action information 74 | getActions: function (handler) { 75 | return [ 76 | { 77 | enabled: handler.completeShape, 78 | title: L.drawLocal.draw.toolbar.finish.title, 79 | text: L.drawLocal.draw.toolbar.finish.text, 80 | callback: handler.completeShape, 81 | context: handler 82 | }, 83 | { 84 | enabled: handler.deleteLastVertex, 85 | title: L.drawLocal.draw.toolbar.undo.title, 86 | text: L.drawLocal.draw.toolbar.undo.text, 87 | callback: handler.deleteLastVertex, 88 | context: handler 89 | }, 90 | { 91 | title: L.drawLocal.draw.toolbar.actions.title, 92 | text: L.drawLocal.draw.toolbar.actions.text, 93 | callback: this.disable, 94 | context: this 95 | } 96 | ]; 97 | }, 98 | 99 | // @method setOptions(): void 100 | // Sets the options to the toolbar 101 | setOptions: function (options) { 102 | L.setOptions(this, options); 103 | 104 | for (var type in this._modes) { 105 | if (this._modes.hasOwnProperty(type) && options.hasOwnProperty(type)) { 106 | this._modes[type].handler.setOptions(options[type]); 107 | } 108 | } 109 | } 110 | }); 111 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/draw/handler/Draw.Circle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.Draw.Circle 3 | * @aka Draw.Circle 4 | * @inherits L.Draw.SimpleShape 5 | */ 6 | L.Draw.Circle = L.Draw.SimpleShape.extend({ 7 | statics: { 8 | TYPE: 'circle' 9 | }, 10 | 11 | options: { 12 | shapeOptions: { 13 | stroke: true, 14 | color: '#3388ff', 15 | weight: 4, 16 | opacity: 0.5, 17 | fill: true, 18 | fillColor: null, //same as color by default 19 | fillOpacity: 0.2, 20 | clickable: true 21 | }, 22 | showRadius: true, 23 | metric: true, // Whether to use the metric measurement system or imperial 24 | feet: true, // When not metric, use feet instead of yards for display 25 | nautic: false // When not metric, not feet use nautic mile for display 26 | }, 27 | 28 | // @method initialize(): void 29 | initialize: function (map, options) { 30 | // Save the type so super can fire, need to do this as cannot do this.TYPE :( 31 | this.type = L.Draw.Circle.TYPE; 32 | 33 | this._initialLabelText = L.drawLocal.draw.handlers.circle.tooltip.start; 34 | 35 | L.Draw.SimpleShape.prototype.initialize.call(this, map, options); 36 | }, 37 | 38 | _drawShape: function (latlng) { 39 | // Calculate the distance based on the version 40 | if (L.GeometryUtil.isVersion07x()) { 41 | var distance = this._startLatLng.distanceTo(latlng); 42 | } else { 43 | var distance = this._map.distance(this._startLatLng, latlng); 44 | } 45 | 46 | if (!this._shape) { 47 | this._shape = new L.Circle(this._startLatLng, distance, this.options.shapeOptions); 48 | this._map.addLayer(this._shape); 49 | } else { 50 | this._shape.setRadius(distance); 51 | } 52 | }, 53 | 54 | _fireCreatedEvent: function () { 55 | var circle = new L.Circle(this._startLatLng, this._shape.getRadius(), this.options.shapeOptions); 56 | L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, circle); 57 | }, 58 | 59 | _onMouseMove: function (e) { 60 | var latlng = e.latlng, 61 | showRadius = this.options.showRadius, 62 | useMetric = this.options.metric, 63 | radius; 64 | 65 | this._tooltip.updatePosition(latlng); 66 | if (this._isDrawing) { 67 | this._drawShape(latlng); 68 | 69 | // Get the new radius (rounded to 1 dp) 70 | radius = this._shape.getRadius().toFixed(1); 71 | 72 | var subtext = ''; 73 | if (showRadius) { 74 | subtext = L.drawLocal.draw.handlers.circle.radius + ': ' + 75 | L.GeometryUtil.readableDistance(radius, useMetric, this.options.feet, this.options.nautic); 76 | } 77 | this._tooltip.updateContent({ 78 | text: this._endLabelText, 79 | subtext: subtext 80 | }); 81 | } 82 | } 83 | }); 84 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/draw/handler/Draw.CircleMarker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.Draw.CircleMarker 3 | * @aka Draw.CircleMarker 4 | * @inherits L.Draw.Marker 5 | */ 6 | L.Draw.CircleMarker = L.Draw.Marker.extend({ 7 | statics: { 8 | TYPE: 'circlemarker' 9 | }, 10 | 11 | options: { 12 | stroke: true, 13 | color: '#3388ff', 14 | weight: 4, 15 | opacity: 0.5, 16 | fill: true, 17 | fillColor: null, //same as color by default 18 | fillOpacity: 0.2, 19 | clickable: true, 20 | zIndexOffset: 2000 // This should be > than the highest z-index any markers 21 | }, 22 | 23 | // @method initialize(): void 24 | initialize: function (map, options) { 25 | // Save the type so super can fire, need to do this as cannot do this.TYPE :( 26 | this.type = L.Draw.CircleMarker.TYPE; 27 | 28 | this._initialLabelText = L.drawLocal.draw.handlers.circlemarker.tooltip.start; 29 | 30 | L.Draw.Feature.prototype.initialize.call(this, map, options); 31 | }, 32 | 33 | 34 | _fireCreatedEvent: function () { 35 | var circleMarker = new L.CircleMarker(this._marker.getLatLng(), this.options); 36 | L.Draw.Feature.prototype._fireCreatedEvent.call(this, circleMarker); 37 | }, 38 | 39 | _createMarker: function (latlng) { 40 | return new L.CircleMarker(latlng, this.options); 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/draw/handler/Draw.Feature.js: -------------------------------------------------------------------------------- 1 | L.Draw = L.Draw || {}; 2 | 3 | /** 4 | * @class L.Draw.Feature 5 | * @aka Draw.Feature 6 | */ 7 | L.Draw.Feature = L.Handler.extend({ 8 | 9 | // @method initialize(): void 10 | initialize: function (map, options) { 11 | this._map = map; 12 | this._container = map._container; 13 | this._overlayPane = map._panes.overlayPane; 14 | this._popupPane = map._panes.popupPane; 15 | 16 | // Merge default shapeOptions options with custom shapeOptions 17 | if (options && options.shapeOptions) { 18 | options.shapeOptions = L.Util.extend({}, this.options.shapeOptions, options.shapeOptions); 19 | } 20 | L.setOptions(this, options); 21 | 22 | var version = L.version.split('.'); 23 | //If Version is >= 1.2.0 24 | if (parseInt(version[0], 10) === 1 && parseInt(version[1], 10) >= 2) { 25 | L.Draw.Feature.include(L.Evented.prototype); 26 | } else { 27 | L.Draw.Feature.include(L.Mixin.Events); 28 | } 29 | }, 30 | 31 | // @method enable(): void 32 | // Enables this handler 33 | enable: function () { 34 | if (this._enabled) { 35 | return; 36 | } 37 | 38 | L.Handler.prototype.enable.call(this); 39 | 40 | this.fire('enabled', {handler: this.type}); 41 | 42 | this._map.fire(L.Draw.Event.DRAWSTART, {layerType: this.type}); 43 | }, 44 | 45 | // @method disable(): void 46 | disable: function () { 47 | if (!this._enabled) { 48 | return; 49 | } 50 | 51 | L.Handler.prototype.disable.call(this); 52 | 53 | this._map.fire(L.Draw.Event.DRAWSTOP, {layerType: this.type}); 54 | 55 | this.fire('disabled', {handler: this.type}); 56 | }, 57 | 58 | // @method addHooks(): void 59 | // Add's event listeners to this handler 60 | addHooks: function () { 61 | var map = this._map; 62 | 63 | if (map) { 64 | L.DomUtil.disableTextSelection(); 65 | 66 | map.getContainer().focus(); 67 | 68 | this._tooltip = new L.Draw.Tooltip(this._map); 69 | 70 | L.DomEvent.on(this._container, 'keyup', this._cancelDrawing, this); 71 | } 72 | }, 73 | 74 | // @method removeHooks(): void 75 | // Removes event listeners from this handler 76 | removeHooks: function () { 77 | if (this._map) { 78 | L.DomUtil.enableTextSelection(); 79 | 80 | this._tooltip.dispose(); 81 | this._tooltip = null; 82 | 83 | L.DomEvent.off(this._container, 'keyup', this._cancelDrawing, this); 84 | } 85 | }, 86 | 87 | // @method setOptions(object): void 88 | // Sets new options to this handler 89 | setOptions: function (options) { 90 | L.setOptions(this, options); 91 | }, 92 | 93 | _fireCreatedEvent: function (layer) { 94 | this._map.fire(L.Draw.Event.CREATED, {layer: layer, layerType: this.type}); 95 | }, 96 | 97 | // Cancel drawing when the escape key is pressed 98 | _cancelDrawing: function (e) { 99 | if (e.keyCode === 27) { 100 | this._map.fire('draw:canceled', {layerType: this.type}); 101 | this.disable(); 102 | } 103 | } 104 | }); 105 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/draw/handler/Draw.Marker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.Draw.Marker 3 | * @aka Draw.Marker 4 | * @inherits L.Draw.Feature 5 | */ 6 | L.Draw.Marker = L.Draw.Feature.extend({ 7 | statics: { 8 | TYPE: 'marker' 9 | }, 10 | 11 | options: { 12 | icon: new L.Icon.Default(), 13 | repeatMode: false, 14 | zIndexOffset: 2000 // This should be > than the highest z-index any markers 15 | }, 16 | 17 | // @method initialize(): void 18 | initialize: function (map, options) { 19 | // Save the type so super can fire, need to do this as cannot do this.TYPE :( 20 | this.type = L.Draw.Marker.TYPE; 21 | 22 | this._initialLabelText = L.drawLocal.draw.handlers.marker.tooltip.start; 23 | 24 | L.Draw.Feature.prototype.initialize.call(this, map, options); 25 | }, 26 | 27 | // @method addHooks(): void 28 | // Add listener hooks to this handler. 29 | addHooks: function () { 30 | L.Draw.Feature.prototype.addHooks.call(this); 31 | 32 | if (this._map) { 33 | this._tooltip.updateContent({text: this._initialLabelText}); 34 | 35 | // Same mouseMarker as in Draw.Polyline 36 | if (!this._mouseMarker) { 37 | this._mouseMarker = L.marker(this._map.getCenter(), { 38 | icon: L.divIcon({ 39 | className: 'leaflet-mouse-marker', 40 | iconAnchor: [20, 20], 41 | iconSize: [40, 40] 42 | }), 43 | opacity: 0, 44 | zIndexOffset: this.options.zIndexOffset 45 | }); 46 | } 47 | 48 | this._mouseMarker 49 | .on('click', this._onClick, this) 50 | .addTo(this._map); 51 | 52 | this._map.on('mousemove', this._onMouseMove, this); 53 | this._map.on('click', this._onTouch, this); 54 | } 55 | }, 56 | 57 | // @method removeHooks(): void 58 | // Remove listener hooks from this handler. 59 | removeHooks: function () { 60 | L.Draw.Feature.prototype.removeHooks.call(this); 61 | 62 | if (this._map) { 63 | this._map 64 | .off('click', this._onClick, this) 65 | .off('click', this._onTouch, this); 66 | if (this._marker) { 67 | this._marker.off('click', this._onClick, this); 68 | this._map 69 | .removeLayer(this._marker); 70 | delete this._marker; 71 | } 72 | 73 | this._mouseMarker.off('click', this._onClick, this); 74 | this._map.removeLayer(this._mouseMarker); 75 | delete this._mouseMarker; 76 | 77 | this._map.off('mousemove', this._onMouseMove, this); 78 | } 79 | }, 80 | 81 | _onMouseMove: function (e) { 82 | var latlng = e.latlng; 83 | 84 | this._tooltip.updatePosition(latlng); 85 | this._mouseMarker.setLatLng(latlng); 86 | 87 | if (!this._marker) { 88 | this._marker = this._createMarker(latlng); 89 | // Bind to both marker and map to make sure we get the click event. 90 | this._marker.on('click', this._onClick, this); 91 | this._map 92 | .on('click', this._onClick, this) 93 | .addLayer(this._marker); 94 | } 95 | else { 96 | latlng = this._mouseMarker.getLatLng(); 97 | this._marker.setLatLng(latlng); 98 | } 99 | }, 100 | 101 | _createMarker: function (latlng) { 102 | return new L.Marker(latlng, { 103 | icon: this.options.icon, 104 | zIndexOffset: this.options.zIndexOffset 105 | }); 106 | }, 107 | 108 | _onClick: function () { 109 | this._fireCreatedEvent(); 110 | 111 | this.disable(); 112 | if (this.options.repeatMode) { 113 | this.enable(); 114 | } 115 | }, 116 | 117 | _onTouch: function (e) { 118 | // called on click & tap, only really does any thing on tap 119 | this._onMouseMove(e); // creates & places marker 120 | this._onClick(); // permanently places marker & ends interaction 121 | }, 122 | 123 | _fireCreatedEvent: function () { 124 | var marker = new L.Marker.Touch(this._marker.getLatLng(), {icon: this.options.icon}); 125 | L.Draw.Feature.prototype._fireCreatedEvent.call(this, marker); 126 | } 127 | }); 128 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/draw/handler/Draw.Polygon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.Draw.Polygon 3 | * @aka Draw.Polygon 4 | * @inherits L.Draw.Polyline 5 | */ 6 | L.Draw.Polygon = L.Draw.Polyline.extend({ 7 | statics: { 8 | TYPE: 'polygon' 9 | }, 10 | 11 | Poly: L.Polygon, 12 | 13 | options: { 14 | showArea: false, 15 | showLength: false, 16 | shapeOptions: { 17 | stroke: true, 18 | color: '#3388ff', 19 | weight: 4, 20 | opacity: 0.5, 21 | fill: true, 22 | fillColor: null, //same as color by default 23 | fillOpacity: 0.2, 24 | clickable: true 25 | }, 26 | // Whether to use the metric measurement system (truthy) or not (falsy). 27 | // Also defines the units to use for the metric system as an array of 28 | // strings (e.g. `['ha', 'm']`). 29 | metric: true, 30 | feet: true, // When not metric, to use feet instead of yards for display. 31 | nautic: false, // When not metric, not feet use nautic mile for display 32 | // Defines the precision for each type of unit (e.g. {km: 2, ft: 0} 33 | precision: {} 34 | }, 35 | 36 | // @method initialize(): void 37 | initialize: function (map, options) { 38 | L.Draw.Polyline.prototype.initialize.call(this, map, options); 39 | 40 | // Save the type so super can fire, need to do this as cannot do this.TYPE :( 41 | this.type = L.Draw.Polygon.TYPE; 42 | }, 43 | 44 | _updateFinishHandler: function () { 45 | var markerCount = this._markers.length; 46 | 47 | // The first marker should have a click handler to close the polygon 48 | if (markerCount === 1) { 49 | this._markers[0].on('click', this._finishShape, this); 50 | } 51 | 52 | // Add and update the double click handler 53 | if (markerCount > 2) { 54 | this._markers[markerCount - 1].on('dblclick', this._finishShape, this); 55 | // Only need to remove handler if has been added before 56 | if (markerCount > 3) { 57 | this._markers[markerCount - 2].off('dblclick', this._finishShape, this); 58 | } 59 | } 60 | }, 61 | 62 | _getTooltipText: function () { 63 | var text, subtext; 64 | 65 | if (this._markers.length === 0) { 66 | text = L.drawLocal.draw.handlers.polygon.tooltip.start; 67 | } else if (this._markers.length < 3) { 68 | text = L.drawLocal.draw.handlers.polygon.tooltip.cont; 69 | subtext = this._getMeasurementString(); 70 | } else { 71 | text = L.drawLocal.draw.handlers.polygon.tooltip.end; 72 | subtext = this._getMeasurementString(); 73 | } 74 | 75 | return { 76 | text: text, 77 | subtext: subtext 78 | }; 79 | }, 80 | 81 | _getMeasurementString: function () { 82 | var area = this._area, 83 | measurementString = ''; 84 | 85 | 86 | if (!area && !this.options.showLength) { 87 | return null; 88 | } 89 | 90 | if (this.options.showLength) { 91 | measurementString = L.Draw.Polyline.prototype._getMeasurementString.call(this); 92 | } 93 | 94 | if (area) { 95 | measurementString += '
' + L.GeometryUtil.readableArea(area, this.options.metric, this.options.precision); 96 | } 97 | 98 | return measurementString; 99 | }, 100 | 101 | _shapeIsValid: function () { 102 | return this._markers.length >= 3; 103 | }, 104 | 105 | _vertexChanged: function (latlng, added) { 106 | var latLngs; 107 | 108 | // Check to see if we should show the area 109 | if (!this.options.allowIntersection && this.options.showArea) { 110 | latLngs = this._poly.getLatLngs(); 111 | 112 | this._area = L.GeometryUtil.geodesicArea(latLngs); 113 | } 114 | 115 | L.Draw.Polyline.prototype._vertexChanged.call(this, latlng, added); 116 | }, 117 | 118 | _cleanUpShape: function () { 119 | var markerCount = this._markers.length; 120 | 121 | if (markerCount > 0) { 122 | this._markers[0].off('click', this._finishShape, this); 123 | 124 | if (markerCount > 2) { 125 | this._markers[markerCount - 1].off('dblclick', this._finishShape, this); 126 | } 127 | } 128 | } 129 | }); 130 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/draw/handler/Draw.Rectangle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.Draw.Rectangle 3 | * @aka Draw.Rectangle 4 | * @inherits L.Draw.SimpleShape 5 | */ 6 | L.Draw.Rectangle = L.Draw.SimpleShape.extend({ 7 | statics: { 8 | TYPE: 'rectangle' 9 | }, 10 | 11 | options: { 12 | shapeOptions: { 13 | stroke: true, 14 | color: '#3388ff', 15 | weight: 4, 16 | opacity: 0.5, 17 | fill: true, 18 | fillColor: null, //same as color by default 19 | fillOpacity: 0.2, 20 | clickable: true 21 | }, 22 | showArea: true, //Whether to show the area in the tooltip 23 | metric: true // Whether to use the metric measurement system or imperial 24 | }, 25 | 26 | // @method initialize(): void 27 | initialize: function (map, options) { 28 | // Save the type so super can fire, need to do this as cannot do this.TYPE :( 29 | this.type = L.Draw.Rectangle.TYPE; 30 | 31 | this._initialLabelText = L.drawLocal.draw.handlers.rectangle.tooltip.start; 32 | 33 | L.Draw.SimpleShape.prototype.initialize.call(this, map, options); 34 | }, 35 | 36 | // @method disable(): void 37 | disable: function () { 38 | if (!this._enabled) { 39 | return; 40 | } 41 | 42 | this._isCurrentlyTwoClickDrawing = false; 43 | L.Draw.SimpleShape.prototype.disable.call(this); 44 | }, 45 | 46 | _onMouseUp: function (e) { 47 | if (!this._shape && !this._isCurrentlyTwoClickDrawing) { 48 | this._isCurrentlyTwoClickDrawing = true; 49 | return; 50 | } 51 | 52 | // Make sure closing click is on map 53 | if (this._isCurrentlyTwoClickDrawing && !_hasAncestor(e.target, 'leaflet-pane')) { 54 | return; 55 | } 56 | 57 | L.Draw.SimpleShape.prototype._onMouseUp.call(this); 58 | }, 59 | 60 | _drawShape: function (latlng) { 61 | if (!this._shape) { 62 | this._shape = new L.Rectangle(new L.LatLngBounds(this._startLatLng, latlng), this.options.shapeOptions); 63 | this._map.addLayer(this._shape); 64 | } else { 65 | this._shape.setBounds(new L.LatLngBounds(this._startLatLng, latlng)); 66 | } 67 | }, 68 | 69 | _fireCreatedEvent: function () { 70 | var rectangle = new L.Rectangle(this._shape.getBounds(), this.options.shapeOptions); 71 | L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, rectangle); 72 | }, 73 | 74 | _getTooltipText: function () { 75 | var tooltipText = L.Draw.SimpleShape.prototype._getTooltipText.call(this), 76 | shape = this._shape, 77 | showArea = this.options.showArea, 78 | latLngs, area, subtext; 79 | 80 | if (shape) { 81 | latLngs = this._shape._defaultShape ? this._shape._defaultShape() : this._shape.getLatLngs(); 82 | area = L.GeometryUtil.geodesicArea(latLngs); 83 | subtext = showArea ? L.GeometryUtil.readableArea(area, this.options.metric) : ''; 84 | } 85 | 86 | return { 87 | text: tooltipText.text, 88 | subtext: subtext 89 | }; 90 | } 91 | }); 92 | 93 | function _hasAncestor(el, cls) { 94 | while ((el = el.parentElement) && !el.classList.contains(cls)) { 95 | ; 96 | } 97 | return el; 98 | } 99 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/draw/handler/Draw.SimpleShape.js: -------------------------------------------------------------------------------- 1 | L.SimpleShape = {}; 2 | /** 3 | * @class L.Draw.SimpleShape 4 | * @aka Draw.SimpleShape 5 | * @inherits L.Draw.Feature 6 | */ 7 | L.Draw.SimpleShape = L.Draw.Feature.extend({ 8 | options: { 9 | repeatMode: false 10 | }, 11 | 12 | // @method initialize(): void 13 | initialize: function (map, options) { 14 | this._endLabelText = L.drawLocal.draw.handlers.simpleshape.tooltip.end; 15 | 16 | L.Draw.Feature.prototype.initialize.call(this, map, options); 17 | }, 18 | 19 | // @method addHooks(): void 20 | // Add listener hooks to this handler. 21 | addHooks: function () { 22 | L.Draw.Feature.prototype.addHooks.call(this); 23 | if (this._map) { 24 | this._mapDraggable = this._map.dragging.enabled(); 25 | 26 | if (this._mapDraggable) { 27 | this._map.dragging.disable(); 28 | } 29 | 30 | //TODO refactor: move cursor to styles 31 | this._container.style.cursor = 'crosshair'; 32 | 33 | this._tooltip.updateContent({text: this._initialLabelText}); 34 | 35 | this._map 36 | .on('mousedown', this._onMouseDown, this) 37 | .on('mousemove', this._onMouseMove, this) 38 | .on('touchstart', this._onMouseDown, this) 39 | .on('touchmove', this._onMouseMove, this); 40 | 41 | // we should prevent default, otherwise default behavior (scrolling) will fire, 42 | // and that will cause document.touchend to fire and will stop the drawing 43 | // (circle, rectangle) in touch mode. 44 | // (update): we have to send passive now to prevent scroll, because by default it is {passive: true} now, which means, 45 | // handler can't event.preventDefault 46 | // check the news https://developers.google.com/web/updates/2016/06/passive-event-listeners 47 | document.addEventListener('touchstart', L.DomEvent.preventDefault, {passive: false}); 48 | } 49 | }, 50 | 51 | // @method removeHooks(): void 52 | // Remove listener hooks from this handler. 53 | removeHooks: function () { 54 | L.Draw.Feature.prototype.removeHooks.call(this); 55 | if (this._map) { 56 | if (this._mapDraggable) { 57 | this._map.dragging.enable(); 58 | } 59 | 60 | //TODO refactor: move cursor to styles 61 | this._container.style.cursor = ''; 62 | 63 | this._map 64 | .off('mousedown', this._onMouseDown, this) 65 | .off('mousemove', this._onMouseMove, this) 66 | .off('touchstart', this._onMouseDown, this) 67 | .off('touchmove', this._onMouseMove, this); 68 | 69 | L.DomEvent.off(document, 'mouseup', this._onMouseUp, this); 70 | L.DomEvent.off(document, 'touchend', this._onMouseUp, this); 71 | 72 | document.removeEventListener('touchstart', L.DomEvent.preventDefault); 73 | 74 | // If the box element doesn't exist they must not have moved the mouse, so don't need to destroy/return 75 | if (this._shape) { 76 | this._map.removeLayer(this._shape); 77 | delete this._shape; 78 | } 79 | } 80 | this._isDrawing = false; 81 | }, 82 | 83 | _getTooltipText: function () { 84 | return { 85 | text: this._endLabelText 86 | }; 87 | }, 88 | 89 | _onMouseDown: function (e) { 90 | this._isDrawing = true; 91 | this._startLatLng = e.latlng; 92 | 93 | L.DomEvent 94 | .on(document, 'mouseup', this._onMouseUp, this) 95 | .on(document, 'touchend', this._onMouseUp, this) 96 | .preventDefault(e.originalEvent); 97 | }, 98 | 99 | _onMouseMove: function (e) { 100 | var latlng = e.latlng; 101 | 102 | this._tooltip.updatePosition(latlng); 103 | if (this._isDrawing) { 104 | this._tooltip.updateContent(this._getTooltipText()); 105 | this._drawShape(latlng); 106 | } 107 | }, 108 | 109 | _onMouseUp: function () { 110 | if (this._shape) { 111 | this._fireCreatedEvent(); 112 | } 113 | 114 | this.disable(); 115 | if (this.options.repeatMode) { 116 | this.enable(); 117 | } 118 | } 119 | }); 120 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/edit/EditToolbar.js: -------------------------------------------------------------------------------- 1 | /*L.Map.mergeOptions({ 2 | editControl: true 3 | });*/ 4 | /** 5 | * @class L.EditToolbar 6 | * @aka EditToolbar 7 | */ 8 | L.EditToolbar = L.Toolbar.extend({ 9 | statics: { 10 | TYPE: 'edit' 11 | }, 12 | 13 | options: { 14 | edit: { 15 | selectedPathOptions: { 16 | dashArray: '10, 10', 17 | 18 | fill: true, 19 | fillColor: '#fe57a1', 20 | fillOpacity: 0.1, 21 | 22 | // Whether to user the existing layers color 23 | maintainColor: false 24 | } 25 | }, 26 | remove: {}, 27 | poly: null, 28 | featureGroup: null /* REQUIRED! TODO: perhaps if not set then all layers on the map are selectable? */ 29 | }, 30 | 31 | // @method intialize(): void 32 | initialize: function (options) { 33 | // Need to set this manually since null is an acceptable value here 34 | if (options.edit) { 35 | if (typeof options.edit.selectedPathOptions === 'undefined') { 36 | options.edit.selectedPathOptions = this.options.edit.selectedPathOptions; 37 | } 38 | options.edit.selectedPathOptions = L.extend({}, this.options.edit.selectedPathOptions, options.edit.selectedPathOptions); 39 | } 40 | 41 | if (options.remove) { 42 | options.remove = L.extend({}, this.options.remove, options.remove); 43 | } 44 | 45 | if (options.poly) { 46 | options.poly = L.extend({}, this.options.poly, options.poly); 47 | } 48 | 49 | this._toolbarClass = 'leaflet-draw-edit'; 50 | L.Toolbar.prototype.initialize.call(this, options); 51 | 52 | this._selectedFeatureCount = 0; 53 | }, 54 | 55 | // @method getModeHandlers(): object 56 | // Get mode handlers information 57 | getModeHandlers: function (map) { 58 | var featureGroup = this.options.featureGroup; 59 | return [ 60 | { 61 | enabled: this.options.edit, 62 | handler: new L.EditToolbar.Edit(map, { 63 | featureGroup: featureGroup, 64 | selectedPathOptions: this.options.edit.selectedPathOptions, 65 | poly: this.options.poly 66 | }), 67 | title: L.drawLocal.edit.toolbar.buttons.edit 68 | }, 69 | { 70 | enabled: this.options.remove, 71 | handler: new L.EditToolbar.Delete(map, { 72 | featureGroup: featureGroup 73 | }), 74 | title: L.drawLocal.edit.toolbar.buttons.remove 75 | } 76 | ]; 77 | }, 78 | 79 | // @method getActions(): object 80 | // Get actions information 81 | getActions: function (handler) { 82 | var actions = [ 83 | { 84 | title: L.drawLocal.edit.toolbar.actions.save.title, 85 | text: L.drawLocal.edit.toolbar.actions.save.text, 86 | callback: this._save, 87 | context: this 88 | }, 89 | { 90 | title: L.drawLocal.edit.toolbar.actions.cancel.title, 91 | text: L.drawLocal.edit.toolbar.actions.cancel.text, 92 | callback: this.disable, 93 | context: this 94 | } 95 | ]; 96 | 97 | if (handler.removeAllLayers) { 98 | actions.push({ 99 | title: L.drawLocal.edit.toolbar.actions.clearAll.title, 100 | text: L.drawLocal.edit.toolbar.actions.clearAll.text, 101 | callback: this._clearAllLayers, 102 | context: this 103 | }); 104 | } 105 | 106 | return actions; 107 | }, 108 | 109 | // @method addToolbar(map): L.DomUtil 110 | // Adds the toolbar to the map 111 | addToolbar: function (map) { 112 | var container = L.Toolbar.prototype.addToolbar.call(this, map); 113 | 114 | this._checkDisabled(); 115 | 116 | this.options.featureGroup.on('layeradd layerremove', this._checkDisabled, this); 117 | 118 | return container; 119 | }, 120 | 121 | // @method removeToolbar(): void 122 | // Removes the toolbar from the map 123 | removeToolbar: function () { 124 | this.options.featureGroup.off('layeradd layerremove', this._checkDisabled, this); 125 | 126 | L.Toolbar.prototype.removeToolbar.call(this); 127 | }, 128 | 129 | // @method disable(): void 130 | // Disables the toolbar 131 | disable: function () { 132 | if (!this.enabled()) { 133 | return; 134 | } 135 | 136 | this._activeMode.handler.revertLayers(); 137 | 138 | L.Toolbar.prototype.disable.call(this); 139 | }, 140 | 141 | _save: function () { 142 | this._activeMode.handler.save(); 143 | if (this._activeMode) { 144 | this._activeMode.handler.disable(); 145 | } 146 | }, 147 | 148 | _clearAllLayers: function () { 149 | this._activeMode.handler.removeAllLayers(); 150 | if (this._activeMode) { 151 | this._activeMode.handler.disable(); 152 | } 153 | }, 154 | 155 | _checkDisabled: function () { 156 | var featureGroup = this.options.featureGroup, 157 | hasLayers = featureGroup.getLayers().length !== 0, 158 | button; 159 | 160 | if (this.options.edit) { 161 | button = this._modes[L.EditToolbar.Edit.TYPE].button; 162 | 163 | if (hasLayers) { 164 | L.DomUtil.removeClass(button, 'leaflet-disabled'); 165 | } else { 166 | L.DomUtil.addClass(button, 'leaflet-disabled'); 167 | } 168 | 169 | button.setAttribute( 170 | 'title', 171 | hasLayers ? 172 | L.drawLocal.edit.toolbar.buttons.edit 173 | : L.drawLocal.edit.toolbar.buttons.editDisabled 174 | ); 175 | } 176 | 177 | if (this.options.remove) { 178 | button = this._modes[L.EditToolbar.Delete.TYPE].button; 179 | 180 | if (hasLayers) { 181 | L.DomUtil.removeClass(button, 'leaflet-disabled'); 182 | } else { 183 | L.DomUtil.addClass(button, 'leaflet-disabled'); 184 | } 185 | 186 | button.setAttribute( 187 | 'title', 188 | hasLayers ? 189 | L.drawLocal.edit.toolbar.buttons.remove 190 | : L.drawLocal.edit.toolbar.buttons.removeDisabled 191 | ); 192 | } 193 | } 194 | }); 195 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/edit/handler/Edit.Circle.js: -------------------------------------------------------------------------------- 1 | L.Edit = L.Edit || {}; 2 | /** 3 | * @class L.Edit.Circle 4 | * @aka Edit.Circle 5 | * @inherits L.Edit.CircleMarker 6 | */ 7 | L.Edit.Circle = L.Edit.CircleMarker.extend({ 8 | 9 | _createResizeMarker: function () { 10 | var center = this._shape.getLatLng(), 11 | resizemarkerPoint = this._getResizeMarkerPoint(center); 12 | 13 | this._resizeMarkers = []; 14 | this._resizeMarkers.push(this._createMarker(resizemarkerPoint, this.options.resizeIcon)); 15 | }, 16 | 17 | _getResizeMarkerPoint: function (latlng) { 18 | // From L.shape.getBounds() 19 | var delta = this._shape._radius * Math.cos(Math.PI / 4), 20 | point = this._map.project(latlng); 21 | return this._map.unproject([point.x + delta, point.y - delta]); 22 | }, 23 | 24 | _resize: function (latlng) { 25 | var moveLatLng = this._moveMarker.getLatLng(); 26 | 27 | // Calculate the radius based on the version 28 | if (L.GeometryUtil.isVersion07x()) { 29 | radius = moveLatLng.distanceTo(latlng); 30 | } else { 31 | radius = this._map.distance(moveLatLng, latlng); 32 | } 33 | this._shape.setRadius(radius); 34 | 35 | if (this._map.editTooltip) { 36 | this._map._editTooltip.updateContent({ 37 | text: L.drawLocal.edit.handlers.edit.tooltip.subtext + '
' + L.drawLocal.edit.handlers.edit.tooltip.text, 38 | subtext: L.drawLocal.draw.handlers.circle.radius + ': ' + 39 | L.GeometryUtil.readableDistance(radius, true, this.options.feet, this.options.nautic) 40 | }); 41 | } 42 | 43 | this._shape.setRadius(radius); 44 | 45 | this._map.fire(L.Draw.Event.EDITRESIZE, {layer: this._shape}); 46 | } 47 | }); 48 | 49 | L.Circle.addInitHook(function () { 50 | if (L.Edit.Circle) { 51 | this.editing = new L.Edit.Circle(this); 52 | 53 | if (this.options.editable) { 54 | this.editing.enable(); 55 | } 56 | } 57 | }); 58 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/edit/handler/Edit.CircleMarker.js: -------------------------------------------------------------------------------- 1 | L.Edit = L.Edit || {}; 2 | /** 3 | * @class L.Edit.CircleMarker 4 | * @aka Edit.Circle 5 | * @inherits L.Edit.SimpleShape 6 | */ 7 | L.Edit.CircleMarker = L.Edit.SimpleShape.extend({ 8 | _createMoveMarker: function () { 9 | var center = this._shape.getLatLng(); 10 | 11 | this._moveMarker = this._createMarker(center, this.options.moveIcon); 12 | }, 13 | 14 | _createResizeMarker: function () { 15 | // To avoid an undefined check in L.Edit.SimpleShape.removeHooks 16 | this._resizeMarkers = []; 17 | }, 18 | 19 | _move: function (latlng) { 20 | if (this._resizeMarkers.length) { 21 | var resizemarkerPoint = this._getResizeMarkerPoint(latlng); 22 | // Move the resize marker 23 | this._resizeMarkers[0].setLatLng(resizemarkerPoint); 24 | } 25 | 26 | // Move the circle 27 | this._shape.setLatLng(latlng); 28 | 29 | this._map.fire(L.Draw.Event.EDITMOVE, {layer: this._shape}); 30 | }, 31 | }); 32 | 33 | L.CircleMarker.addInitHook(function () { 34 | if (L.Edit.CircleMarker) { 35 | this.editing = new L.Edit.CircleMarker(this); 36 | 37 | if (this.options.editable) { 38 | this.editing.enable(); 39 | } 40 | } 41 | 42 | this.on('add', function () { 43 | if (this.editing && this.editing.enabled()) { 44 | this.editing.addHooks(); 45 | } 46 | }); 47 | 48 | this.on('remove', function () { 49 | if (this.editing && this.editing.enabled()) { 50 | this.editing.removeHooks(); 51 | } 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/edit/handler/Edit.Marker.js: -------------------------------------------------------------------------------- 1 | L.Edit = L.Edit || {}; 2 | 3 | /** 4 | * @class L.Edit.Marker 5 | * @aka Edit.Marker 6 | */ 7 | L.Edit.Marker = L.Handler.extend({ 8 | // @method initialize(): void 9 | initialize: function (marker, options) { 10 | this._marker = marker; 11 | L.setOptions(this, options); 12 | }, 13 | 14 | // @method addHooks(): void 15 | // Add listener hooks to this handler 16 | addHooks: function () { 17 | var marker = this._marker; 18 | 19 | marker.dragging.enable(); 20 | marker.on('dragend', this._onDragEnd, marker); 21 | this._toggleMarkerHighlight(); 22 | }, 23 | 24 | // @method removeHooks(): void 25 | // Remove listener hooks from this handler 26 | removeHooks: function () { 27 | var marker = this._marker; 28 | 29 | marker.dragging.disable(); 30 | marker.off('dragend', this._onDragEnd, marker); 31 | this._toggleMarkerHighlight(); 32 | }, 33 | 34 | _onDragEnd: function (e) { 35 | var layer = e.target; 36 | layer.edited = true; 37 | this._map.fire(L.Draw.Event.EDITMOVE, {layer: layer}); 38 | }, 39 | 40 | _toggleMarkerHighlight: function () { 41 | var icon = this._marker._icon; 42 | 43 | // Don't do anything if this layer is a marker but doesn't have an icon. Markers 44 | // should usually have icons. If using Leaflet.draw with Leaflet.markercluster there 45 | // is a chance that a marker doesn't. 46 | if (!icon) { 47 | return; 48 | } 49 | 50 | // This is quite naughty, but I don't see another way of doing it. (short of setting a new icon) 51 | icon.style.display = 'none'; 52 | 53 | if (L.DomUtil.hasClass(icon, 'leaflet-edit-marker-selected')) { 54 | L.DomUtil.removeClass(icon, 'leaflet-edit-marker-selected'); 55 | // Offset as the border will make the icon move. 56 | this._offsetMarker(icon, -4); 57 | 58 | } else { 59 | L.DomUtil.addClass(icon, 'leaflet-edit-marker-selected'); 60 | // Offset as the border will make the icon move. 61 | this._offsetMarker(icon, 4); 62 | } 63 | 64 | icon.style.display = ''; 65 | }, 66 | 67 | _offsetMarker: function (icon, offset) { 68 | var iconMarginTop = parseInt(icon.style.marginTop, 10) - offset, 69 | iconMarginLeft = parseInt(icon.style.marginLeft, 10) - offset; 70 | 71 | icon.style.marginTop = iconMarginTop + 'px'; 72 | icon.style.marginLeft = iconMarginLeft + 'px'; 73 | } 74 | }); 75 | 76 | L.Marker.addInitHook(function () { 77 | if (L.Edit.Marker) { 78 | this.editing = new L.Edit.Marker(this); 79 | 80 | if (this.options.editable) { 81 | this.editing.enable(); 82 | } 83 | } 84 | }); 85 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/edit/handler/Edit.Rectangle.js: -------------------------------------------------------------------------------- 1 | L.Edit = L.Edit || {}; 2 | /** 3 | * @class L.Edit.Rectangle 4 | * @aka Edit.Rectangle 5 | * @inherits L.Edit.SimpleShape 6 | */ 7 | L.Edit.Rectangle = L.Edit.SimpleShape.extend({ 8 | _createMoveMarker: function () { 9 | var bounds = this._shape.getBounds(), 10 | center = bounds.getCenter(); 11 | 12 | this._moveMarker = this._createMarker(center, this.options.moveIcon); 13 | }, 14 | 15 | _createResizeMarker: function () { 16 | var corners = this._getCorners(); 17 | 18 | this._resizeMarkers = []; 19 | 20 | for (var i = 0, l = corners.length; i < l; i++) { 21 | this._resizeMarkers.push(this._createMarker(corners[i], this.options.resizeIcon)); 22 | // Monkey in the corner index as we will need to know this for dragging 23 | this._resizeMarkers[i]._cornerIndex = i; 24 | } 25 | }, 26 | 27 | _onMarkerDragStart: function (e) { 28 | L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, e); 29 | 30 | // Save a reference to the opposite point 31 | var corners = this._getCorners(), 32 | marker = e.target, 33 | currentCornerIndex = marker._cornerIndex; 34 | 35 | this._oppositeCorner = corners[(currentCornerIndex + 2) % 4]; 36 | 37 | this._toggleCornerMarkers(0, currentCornerIndex); 38 | }, 39 | 40 | _onMarkerDragEnd: function (e) { 41 | var marker = e.target, 42 | bounds, center; 43 | 44 | // Reset move marker position to the center 45 | if (marker === this._moveMarker) { 46 | bounds = this._shape.getBounds(); 47 | center = bounds.getCenter(); 48 | 49 | marker.setLatLng(center); 50 | } 51 | 52 | this._toggleCornerMarkers(1); 53 | 54 | this._repositionCornerMarkers(); 55 | 56 | L.Edit.SimpleShape.prototype._onMarkerDragEnd.call(this, e); 57 | }, 58 | 59 | _move: function (newCenter) { 60 | var latlngs = this._shape._defaultShape ? this._shape._defaultShape() : this._shape.getLatLngs(), 61 | bounds = this._shape.getBounds(), 62 | center = bounds.getCenter(), 63 | offset, newLatLngs = []; 64 | 65 | // Offset the latlngs to the new center 66 | for (var i = 0, l = latlngs.length; i < l; i++) { 67 | offset = [latlngs[i].lat - center.lat, latlngs[i].lng - center.lng]; 68 | newLatLngs.push([newCenter.lat + offset[0], newCenter.lng + offset[1]]); 69 | } 70 | 71 | this._shape.setLatLngs(newLatLngs); 72 | 73 | // Reposition the resize markers 74 | this._repositionCornerMarkers(); 75 | 76 | this._map.fire(L.Draw.Event.EDITMOVE, {layer: this._shape}); 77 | }, 78 | 79 | _resize: function (latlng) { 80 | var bounds; 81 | 82 | // Update the shape based on the current position of this corner and the opposite point 83 | this._shape.setBounds(L.latLngBounds(latlng, this._oppositeCorner)); 84 | 85 | // Reposition the move marker 86 | bounds = this._shape.getBounds(); 87 | this._moveMarker.setLatLng(bounds.getCenter()); 88 | 89 | this._map.fire(L.Draw.Event.EDITRESIZE, {layer: this._shape}); 90 | }, 91 | 92 | _getCorners: function () { 93 | var bounds = this._shape.getBounds(), 94 | nw = bounds.getNorthWest(), 95 | ne = bounds.getNorthEast(), 96 | se = bounds.getSouthEast(), 97 | sw = bounds.getSouthWest(); 98 | 99 | return [nw, ne, se, sw]; 100 | }, 101 | 102 | _toggleCornerMarkers: function (opacity) { 103 | for (var i = 0, l = this._resizeMarkers.length; i < l; i++) { 104 | this._resizeMarkers[i].setOpacity(opacity); 105 | } 106 | }, 107 | 108 | _repositionCornerMarkers: function () { 109 | var corners = this._getCorners(); 110 | 111 | for (var i = 0, l = this._resizeMarkers.length; i < l; i++) { 112 | this._resizeMarkers[i].setLatLng(corners[i]); 113 | } 114 | } 115 | }); 116 | 117 | L.Rectangle.addInitHook(function () { 118 | if (L.Edit.Rectangle) { 119 | this.editing = new L.Edit.Rectangle(this); 120 | 121 | if (this.options.editable) { 122 | this.editing.enable(); 123 | } 124 | } 125 | }); 126 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/edit/handler/EditToolbar.Delete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.EditToolbar.Delete 3 | * @aka EditToolbar.Delete 4 | */ 5 | L.EditToolbar.Delete = L.Handler.extend({ 6 | statics: { 7 | TYPE: 'remove' // not delete as delete is reserved in js 8 | }, 9 | 10 | // @method intialize(): void 11 | initialize: function (map, options) { 12 | L.Handler.prototype.initialize.call(this, map); 13 | 14 | L.Util.setOptions(this, options); 15 | 16 | // Store the selectable layer group for ease of access 17 | this._deletableLayers = this.options.featureGroup; 18 | 19 | if (!(this._deletableLayers instanceof L.FeatureGroup)) { 20 | throw new Error('options.featureGroup must be a L.FeatureGroup'); 21 | } 22 | 23 | // Save the type so super can fire, need to do this as cannot do this.TYPE :( 24 | this.type = L.EditToolbar.Delete.TYPE; 25 | 26 | var version = L.version.split('.'); 27 | //If Version is >= 1.2.0 28 | if (parseInt(version[0], 10) === 1 && parseInt(version[1], 10) >= 2) { 29 | L.EditToolbar.Delete.include(L.Evented.prototype); 30 | } else { 31 | L.EditToolbar.Delete.include(L.Mixin.Events); 32 | } 33 | 34 | }, 35 | 36 | // @method enable(): void 37 | // Enable the delete toolbar 38 | enable: function () { 39 | if (this._enabled || !this._hasAvailableLayers()) { 40 | return; 41 | } 42 | this.fire('enabled', {handler: this.type}); 43 | 44 | this._map.fire(L.Draw.Event.DELETESTART, {handler: this.type}); 45 | 46 | L.Handler.prototype.enable.call(this); 47 | 48 | this._deletableLayers 49 | .on('layeradd', this._enableLayerDelete, this) 50 | .on('layerremove', this._disableLayerDelete, this); 51 | }, 52 | 53 | // @method disable(): void 54 | // Disable the delete toolbar 55 | disable: function () { 56 | if (!this._enabled) { 57 | return; 58 | } 59 | 60 | this._deletableLayers 61 | .off('layeradd', this._enableLayerDelete, this) 62 | .off('layerremove', this._disableLayerDelete, this); 63 | 64 | L.Handler.prototype.disable.call(this); 65 | 66 | this._map.fire(L.Draw.Event.DELETESTOP, {handler: this.type}); 67 | 68 | this.fire('disabled', {handler: this.type}); 69 | }, 70 | 71 | // @method addHooks(): void 72 | // Add listener hooks to this handler 73 | addHooks: function () { 74 | var map = this._map; 75 | 76 | if (map) { 77 | map.getContainer().focus(); 78 | 79 | this._deletableLayers.eachLayer(this._enableLayerDelete, this); 80 | this._deletedLayers = new L.LayerGroup(); 81 | 82 | this._tooltip = new L.Draw.Tooltip(this._map); 83 | this._tooltip.updateContent({text: L.drawLocal.edit.handlers.remove.tooltip.text}); 84 | 85 | this._map.on('mousemove', this._onMouseMove, this); 86 | } 87 | }, 88 | 89 | // @method removeHooks(): void 90 | // Remove listener hooks from this handler 91 | removeHooks: function () { 92 | if (this._map) { 93 | this._deletableLayers.eachLayer(this._disableLayerDelete, this); 94 | this._deletedLayers = null; 95 | 96 | this._tooltip.dispose(); 97 | this._tooltip = null; 98 | 99 | this._map.off('mousemove', this._onMouseMove, this); 100 | } 101 | }, 102 | 103 | // @method revertLayers(): void 104 | // Revert the deleted layers back to their prior state. 105 | revertLayers: function () { 106 | // Iterate of the deleted layers and add them back into the featureGroup 107 | this._deletedLayers.eachLayer(function (layer) { 108 | this._deletableLayers.addLayer(layer); 109 | layer.fire('revert-deleted', {layer: layer}); 110 | }, this); 111 | }, 112 | 113 | // @method save(): void 114 | // Save deleted layers 115 | save: function () { 116 | this._map.fire(L.Draw.Event.DELETED, {layers: this._deletedLayers}); 117 | }, 118 | 119 | // @method removeAllLayers(): void 120 | // Remove all delateable layers 121 | removeAllLayers: function () { 122 | // Iterate of the delateable layers and add remove them 123 | this._deletableLayers.eachLayer(function (layer) { 124 | this._removeLayer({layer: layer}); 125 | }, this); 126 | this.save(); 127 | }, 128 | 129 | _enableLayerDelete: function (e) { 130 | var layer = e.layer || e.target || e; 131 | 132 | layer.on('click', this._removeLayer, this); 133 | }, 134 | 135 | _disableLayerDelete: function (e) { 136 | var layer = e.layer || e.target || e; 137 | 138 | layer.off('click', this._removeLayer, this); 139 | 140 | // Remove from the deleted layers so we can't accidentally revert if the user presses cancel 141 | this._deletedLayers.removeLayer(layer); 142 | }, 143 | 144 | _removeLayer: function (e) { 145 | var layer = e.layer || e.target || e; 146 | 147 | this._deletableLayers.removeLayer(layer); 148 | 149 | this._deletedLayers.addLayer(layer); 150 | 151 | layer.fire('deleted'); 152 | }, 153 | 154 | _onMouseMove: function (e) { 155 | this._tooltip.updatePosition(e.latlng); 156 | }, 157 | 158 | _hasAvailableLayers: function () { 159 | return this._deletableLayers.getLayers().length !== 0; 160 | } 161 | }); 162 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/ext/GeometryUtil.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var defaultPrecision = { 4 | km: 2, 5 | ha: 2, 6 | m: 0, 7 | mi: 2, 8 | ac: 2, 9 | yd: 0, 10 | ft: 0, 11 | nm: 2 12 | }; 13 | 14 | 15 | /** 16 | * @class L.GeometryUtil 17 | * @aka GeometryUtil 18 | */ 19 | L.GeometryUtil = L.extend(L.GeometryUtil || {}, { 20 | // Ported from the OpenLayers implementation. See https://github.com/openlayers/openlayers/blob/master/lib/OpenLayers/Geometry/LinearRing.js#L270 21 | 22 | // @method geodesicArea(): number 23 | geodesicArea: function (latLngs) { 24 | var pointsCount = latLngs.length, 25 | area = 0.0, 26 | d2r = Math.PI / 180, 27 | p1, p2; 28 | 29 | if (pointsCount > 2) { 30 | for (var i = 0; i < pointsCount; i++) { 31 | p1 = latLngs[i]; 32 | p2 = latLngs[(i + 1) % pointsCount]; 33 | area += ((p2.lng - p1.lng) * d2r) * 34 | (2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r)); 35 | } 36 | area = area * 6378137.0 * 6378137.0 / 2.0; 37 | } 38 | 39 | return Math.abs(area); 40 | }, 41 | 42 | // @method formattedNumber(n, precision): string 43 | // Returns n in specified number format (if defined) and precision 44 | formattedNumber: function (n, precision) { 45 | var formatted = parseFloat(n).toFixed(precision), 46 | format = L.drawLocal.format && L.drawLocal.format.numeric, 47 | delimiters = format && format.delimiters, 48 | thousands = delimiters && delimiters.thousands, 49 | decimal = delimiters && delimiters.decimal; 50 | 51 | if (thousands || decimal) { 52 | var splitValue = formatted.split('.'); 53 | formatted = thousands ? splitValue[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + thousands) : splitValue[0]; 54 | decimal = decimal || '.'; 55 | if (splitValue.length > 1) { 56 | formatted = formatted + decimal + splitValue[1]; 57 | } 58 | } 59 | 60 | return formatted; 61 | }, 62 | 63 | // @method readableArea(area, isMetric, precision): string 64 | // Returns a readable area string in yards or metric. 65 | // The value will be rounded as defined by the precision option object. 66 | readableArea: function (area, isMetric, precision) { 67 | var areaStr, 68 | units, 69 | precision = L.Util.extend({}, defaultPrecision, precision); 70 | 71 | if (isMetric) { 72 | units = ['ha', 'm']; 73 | type = typeof isMetric; 74 | if (type === 'string') { 75 | units = [isMetric]; 76 | } else if (type !== 'boolean') { 77 | units = isMetric; 78 | } 79 | 80 | if (area >= 1000000 && units.indexOf('km') !== -1) { 81 | areaStr = L.GeometryUtil.formattedNumber(area * 0.000001, precision['km']) + ' km²'; 82 | } else if (area >= 10000 && units.indexOf('ha') !== -1) { 83 | areaStr = L.GeometryUtil.formattedNumber(area * 0.0001, precision['ha']) + ' ha'; 84 | } else { 85 | areaStr = L.GeometryUtil.formattedNumber(area, precision['m']) + ' m²'; 86 | } 87 | } else { 88 | area /= 0.836127; // Square yards in 1 meter 89 | 90 | if (area >= 3097600) { //3097600 square yards in 1 square mile 91 | areaStr = L.GeometryUtil.formattedNumber(area / 3097600, precision['mi']) + ' mi²'; 92 | } else if (area >= 4840) { //4840 square yards in 1 acre 93 | areaStr = L.GeometryUtil.formattedNumber(area / 4840, precision['ac']) + ' acres'; 94 | } else { 95 | areaStr = L.GeometryUtil.formattedNumber(area, precision['yd']) + ' yd²'; 96 | } 97 | } 98 | 99 | return areaStr; 100 | }, 101 | 102 | // @method readableDistance(distance, units): string 103 | // Converts a metric distance to one of [ feet, nauticalMile, metric or yards ] string 104 | // 105 | // @alternative 106 | // @method readableDistance(distance, isMetric, useFeet, isNauticalMile, precision): string 107 | // Converts metric distance to distance string. 108 | // The value will be rounded as defined by the precision option object. 109 | readableDistance: function (distance, isMetric, isFeet, isNauticalMile, precision) { 110 | var distanceStr, 111 | units, 112 | precision = L.Util.extend({}, defaultPrecision, precision); 113 | 114 | if (isMetric) { 115 | units = typeof isMetric == 'string' ? isMetric : 'metric'; 116 | } else if (isFeet) { 117 | units = 'feet'; 118 | } else if (isNauticalMile) { 119 | units = 'nauticalMile'; 120 | } else { 121 | units = 'yards'; 122 | } 123 | 124 | switch (units) { 125 | case 'metric': 126 | // show metres when distance is < 1km, then show km 127 | if (distance > 1000) { 128 | distanceStr = L.GeometryUtil.formattedNumber(distance / 1000, precision['km']) + ' km'; 129 | } else { 130 | distanceStr = L.GeometryUtil.formattedNumber(distance, precision['m']) + ' m'; 131 | } 132 | break; 133 | case 'feet': 134 | distance *= 1.09361 * 3; 135 | distanceStr = L.GeometryUtil.formattedNumber(distance, precision['ft']) + ' ft'; 136 | 137 | break; 138 | case 'nauticalMile': 139 | distance *= 0.53996; 140 | distanceStr = L.GeometryUtil.formattedNumber(distance / 1000, precision['nm']) + ' nm'; 141 | break; 142 | case 'yards': 143 | default: 144 | distance *= 1.09361; 145 | 146 | if (distance > 1760) { 147 | distanceStr = L.GeometryUtil.formattedNumber(distance / 1760, precision['mi']) + ' miles'; 148 | } else { 149 | distanceStr = L.GeometryUtil.formattedNumber(distance, precision['yd']) + ' yd'; 150 | } 151 | break; 152 | } 153 | return distanceStr; 154 | }, 155 | 156 | // @method isVersion07x(): boolean 157 | // Returns true if the Leaflet version is 0.7.x, false otherwise. 158 | isVersion07x: function () { 159 | var version = L.version.split('.'); 160 | //If Version is == 0.7.* 161 | return parseInt(version[0], 10) === 0 && parseInt(version[1], 10) === 7; 162 | }, 163 | }); 164 | 165 | })(); 166 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/ext/LatLngUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.LatLngUtil 3 | * @aka LatLngUtil 4 | */ 5 | L.LatLngUtil = { 6 | // Clones a LatLngs[], returns [][] 7 | 8 | // @method cloneLatLngs(LatLngs[]): L.LatLngs[] 9 | // Clone the latLng point or points or nested points and return an array with those points 10 | cloneLatLngs: function (latlngs) { 11 | var clone = []; 12 | for (var i = 0, l = latlngs.length; i < l; i++) { 13 | // Check for nested array (Polyline/Polygon) 14 | if (Array.isArray(latlngs[i])) { 15 | clone.push(L.LatLngUtil.cloneLatLngs(latlngs[i])); 16 | } else { 17 | clone.push(this.cloneLatLng(latlngs[i])); 18 | } 19 | } 20 | return clone; 21 | }, 22 | 23 | // @method cloneLatLng(LatLng): L.LatLng 24 | // Clone the latLng and return a new LatLng object. 25 | cloneLatLng: function (latlng) { 26 | return L.latLng(latlng.lat, latlng.lng); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/ext/LineUtil.Intersect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.LineUtil 3 | * @aka Util 4 | * @aka L.Utils 5 | */ 6 | L.Util.extend(L.LineUtil, { 7 | 8 | // @method segmentsIntersect(): boolean 9 | // Checks to see if two line segments intersect. Does not handle degenerate cases. 10 | // http://compgeom.cs.uiuc.edu/~jeffe/teaching/373/notes/x06-sweepline.pdf 11 | segmentsIntersect: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2, /*Point*/ p3) { 12 | return this._checkCounterclockwise(p, p2, p3) !== 13 | this._checkCounterclockwise(p1, p2, p3) && 14 | this._checkCounterclockwise(p, p1, p2) !== 15 | this._checkCounterclockwise(p, p1, p3); 16 | }, 17 | 18 | // check to see if points are in counterclockwise order 19 | _checkCounterclockwise: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) { 20 | return (p2.y - p.y) * (p1.x - p.x) > (p1.y - p.y) * (p2.x - p.x); 21 | } 22 | }); 23 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/ext/Polygon.Intersect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.Polygon 3 | * @aka Polygon 4 | */ 5 | L.Polygon.include({ 6 | 7 | // @method intersects(): boolean 8 | // Checks a polygon for any intersecting line segments. Ignores holes. 9 | intersects: function () { 10 | var polylineIntersects, 11 | points = this._getProjectedPoints(), 12 | len, firstPoint, lastPoint, maxIndex; 13 | 14 | if (this._tooFewPointsForIntersection()) { 15 | return false; 16 | } 17 | 18 | polylineIntersects = L.Polyline.prototype.intersects.call(this); 19 | 20 | // If already found an intersection don't need to check for any more. 21 | if (polylineIntersects) { 22 | return true; 23 | } 24 | 25 | len = points.length; 26 | firstPoint = points[0]; 27 | lastPoint = points[len - 1]; 28 | maxIndex = len - 2; 29 | 30 | // Check the line segment between last and first point. Don't need to check the first line segment (minIndex = 1) 31 | return this._lineSegmentsIntersectsRange(lastPoint, firstPoint, maxIndex, 1); 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/ext/Polyline.Intersect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class L.Polyline 3 | * @aka Polyline 4 | */ 5 | L.Polyline.include({ 6 | 7 | // @method intersects(): boolean 8 | // Check to see if this polyline has any linesegments that intersect. 9 | // NOTE: does not support detecting intersection for degenerate cases. 10 | intersects: function () { 11 | var points = this._getProjectedPoints(), 12 | len = points ? points.length : 0, 13 | i, p, p1; 14 | 15 | if (this._tooFewPointsForIntersection()) { 16 | return false; 17 | } 18 | 19 | for (i = len - 1; i >= 3; i--) { 20 | p = points[i - 1]; 21 | p1 = points[i]; 22 | 23 | 24 | if (this._lineSegmentsIntersectsRange(p, p1, i - 2)) { 25 | return true; 26 | } 27 | } 28 | 29 | return false; 30 | }, 31 | 32 | // @method newLatLngIntersects(): boolean 33 | // Check for intersection if new latlng was added to this polyline. 34 | // NOTE: does not support detecting intersection for degenerate cases. 35 | newLatLngIntersects: function (latlng, skipFirst) { 36 | // Cannot check a polyline for intersecting lats/lngs when not added to the map 37 | if (!this._map) { 38 | return false; 39 | } 40 | 41 | return this.newPointIntersects(this._map.latLngToLayerPoint(latlng), skipFirst); 42 | }, 43 | 44 | // @method newPointIntersects(): boolean 45 | // Check for intersection if new point was added to this polyline. 46 | // newPoint must be a layer point. 47 | // NOTE: does not support detecting intersection for degenerate cases. 48 | newPointIntersects: function (newPoint, skipFirst) { 49 | var points = this._getProjectedPoints(), 50 | len = points ? points.length : 0, 51 | lastPoint = points ? points[len - 1] : null, 52 | // The previous previous line segment. Previous line segment doesn't need testing. 53 | maxIndex = len - 2; 54 | 55 | if (this._tooFewPointsForIntersection(1)) { 56 | return false; 57 | } 58 | 59 | return this._lineSegmentsIntersectsRange(lastPoint, newPoint, maxIndex, skipFirst ? 1 : 0); 60 | }, 61 | 62 | // Polylines with 2 sides can only intersect in cases where points are collinear (we don't support detecting these). 63 | // Cannot have intersection when < 3 line segments (< 4 points) 64 | _tooFewPointsForIntersection: function (extraPoints) { 65 | var points = this._getProjectedPoints(), 66 | len = points ? points.length : 0; 67 | // Increment length by extraPoints if present 68 | len += extraPoints || 0; 69 | 70 | return !points || len <= 3; 71 | }, 72 | 73 | // Checks a line segment intersections with any line segments before its predecessor. 74 | // Don't need to check the predecessor as will never intersect. 75 | _lineSegmentsIntersectsRange: function (p, p1, maxIndex, minIndex) { 76 | var points = this._getProjectedPoints(), 77 | p2, p3; 78 | 79 | minIndex = minIndex || 0; 80 | 81 | // Check all previous line segments (beside the immediately previous) for intersections 82 | for (var j = maxIndex; j > minIndex; j--) { 83 | p2 = points[j - 1]; 84 | p3 = points[j]; 85 | 86 | if (L.LineUtil.segmentsIntersect(p, p1, p2, p3)) { 87 | return true; 88 | } 89 | } 90 | 91 | return false; 92 | }, 93 | 94 | _getProjectedPoints: function () { 95 | if (!this._defaultShape) { 96 | return this._originalPoints; 97 | } 98 | var points = [], 99 | _shape = this._defaultShape(); 100 | 101 | for (var i = 0; i < _shape.length; i++) { 102 | points.push(this._map.latLngToLayerPoint(_shape[i])); 103 | } 104 | return points; 105 | } 106 | }); 107 | -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/images/spritesheet-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/src/images/spritesheet-2x.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/images/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skylarkdrones/pyqtlet/2242f63b0dce6dd6357aaa0c6fe23a991451bfdd/pyqtlet/web/modules/leaflet_draw_104/src/images/spritesheet.png -------------------------------------------------------------------------------- /pyqtlet/web/modules/leaflet_draw_104/src/images/spritesheet.svg: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 23 | 25 | image/svg+xml 26 | 28 | 29 | 30 | 31 | 32 | 34 | 54 | 57 | 60 | 65 | 70 | 75 | 76 | 81 | 86 | 91 | 96 | 99 | 104 | 109 | 115 | 116 | 119 | 124 | 129 | 130 | 131 | 135 | 142 | 149 | 150 | 155 | 156 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | PyQt5==5.11.3 2 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | 3 | setup( 4 | name='pyqtlet', 5 | packages=[ 6 | 'pyqtlet', 7 | 'pyqtlet.web', 8 | 'pyqtlet.web.modules.leaflet_134', 9 | 'pyqtlet.web.modules.leaflet_134.images', 10 | 'pyqtlet.web.modules.leaflet_draw_104', 11 | 'pyqtlet.web.modules.leaflet_draw_104.dist', 12 | 'pyqtlet.web.modules.leaflet_draw_104.dist.images', 13 | 'pyqtlet.leaflet', 14 | 'pyqtlet.leaflet.control', 15 | 'pyqtlet.leaflet.core', 16 | 'pyqtlet.leaflet.layer', 17 | 'pyqtlet.leaflet.layer.marker', 18 | 'pyqtlet.leaflet.layer.tile', 19 | 'pyqtlet.leaflet.layer.vector', 20 | 'pyqtlet.leaflet.map', 21 | ], 22 | package_data={ 23 | 'pyqtlet.web': ['*'], 'pyqtlet.web.modules': ['*'], 24 | 'pyqtlet.web.modules.leaflet_134': ['*'], 25 | 'pyqtlet.web.modules.leaflet_134.images': ['*'], 26 | 'pyqtlet.web.modules.leaflet_draw_104': ['*'], 27 | 'pyqtlet.web.modules.leaflet_draw_104.dist': ['*'], 28 | 'pyqtlet.web.modules.leaflet_draw_104.dist.images': ['*'], 29 | }, 30 | version='0.3.3', 31 | description='Bringing leaflet maps to PyQt', 32 | author='Samarth Hattangady', 33 | author_email='samhattangady@gmail.com', 34 | url='https://github.com/skylarkdrones/pyqtlet', 35 | keywords=['leaflet', 'pyqt', 'maps'], 36 | classifiers=[], 37 | ) 38 | --------------------------------------------------------------------------------