├── .gitignore
├── .gitmodules
├── .travis.yml
├── CONTRIBUTING.rst
├── LICENSE.txt
├── README.rst
├── docker-compose.yml
├── docs
├── Makefile
├── make.bat
└── source
│ ├── actions.rst
│ ├── caveats
│ └── sld.rst
│ ├── conf.py
│ ├── img
│ ├── actions
│ │ ├── add_catalog.png
│ │ ├── add_style.png
│ │ ├── catalog_added.png
│ │ ├── confirm_delete.png
│ │ ├── create_catalog.png
│ │ ├── create_workspace.png
│ │ ├── define_group.png
│ │ ├── define_gwc.png
│ │ ├── dragdrop.png
│ │ ├── dragdrop_external.png
│ │ ├── editsld.png
│ │ ├── extent_drag.png
│ │ ├── new_style.png
│ │ ├── order_in_group.png
│ │ ├── plugin_menu.png
│ │ ├── plugin_repo.png
│ │ ├── plugin_repo_added.png
│ │ ├── publish_layer.png
│ │ ├── publish_layers.png
│ │ ├── publish_project.png
│ │ ├── publish_style.png
│ │ ├── seed.png
│ │ └── seed_status.png
│ └── intro
│ │ ├── about.png
│ │ ├── add_catalog.png
│ │ ├── config.png
│ │ ├── description_panel.png
│ │ ├── description_table.png
│ │ ├── duplicated_layer.png
│ │ ├── explorer.png
│ │ ├── gray_catalog.png
│ │ ├── tracking.png
│ │ ├── undocked.png
│ │ └── version_warning.png
│ ├── index.rst
│ ├── installation.rst
│ ├── intro.rst
│ └── settingsconf.rst
├── geoserverexplorer
├── __init__.py
├── extlibs
│ ├── geoserver
│ │ ├── __init__.py
│ │ ├── catalog.py
│ │ ├── layer.py
│ │ ├── layergroup.py
│ │ ├── namespace.py
│ │ ├── resource.py
│ │ ├── store.py
│ │ ├── style.py
│ │ ├── support.py
│ │ ├── util.py
│ │ └── workspace.py
│ └── site.py
├── geoserver
│ ├── __init__.py
│ ├── auth.py
│ ├── basecatalog.py
│ ├── gwc.py
│ ├── settings.py
│ └── util.py
├── gui
│ ├── __init__.py
│ ├── confirm.py
│ ├── contextualhelp.py
│ ├── dialogs
│ │ ├── __init__.py
│ │ ├── catalogdialog.py
│ │ ├── groupdialog.py
│ │ ├── gsnamedialog.py
│ │ ├── gwclayer.py
│ │ ├── layerdialog.py
│ │ ├── projectdialog.py
│ │ ├── resources.qrc
│ │ ├── resources_rc.py
│ │ ├── sldeditor.py
│ │ ├── styledialog.py
│ │ └── workspacedialog.py
│ ├── explorer.py
│ ├── exploreritems.py
│ ├── explorertree.py
│ ├── extentpanel.py
│ ├── gsexploreritems.py
│ ├── gsnameutils.py
│ ├── gsoperations.py
│ ├── gwcexploreritems.py
│ ├── parametereditor.py
│ └── rectangletool.py
├── images
│ ├── add-page-blue.png
│ ├── add-style-to-layer.png
│ ├── add.png
│ ├── bottom.png
│ ├── browser.gif
│ ├── browser.png
│ ├── clean.png
│ ├── config.png
│ ├── create-store-from-layer.png
│ ├── default-style.png
│ ├── default-workspace.png
│ ├── delete.gif
│ ├── desktop.svg
│ ├── down.png
│ ├── edit.png
│ ├── edit_sld.png
│ ├── geonode.png
│ ├── geoserver.png
│ ├── geoserver_gray.png
│ ├── grid.jpg
│ ├── group.gif
│ ├── gwc.png
│ ├── help.png
│ ├── import_into_qgis.png
│ ├── layer.png
│ ├── layer_line.png
│ ├── layer_point.png
│ ├── layer_polygon.png
│ ├── layer_unknown.png
│ ├── new_table.png
│ ├── pencil.png
│ ├── process.png
│ ├── publish-to-geoserver.png
│ ├── refresh.png
│ ├── rename.png
│ ├── seed.png
│ ├── sql_window.png
│ ├── style.png
│ ├── table.png
│ ├── top.png
│ ├── tree.gif
│ ├── up.png
│ ├── warning.png
│ ├── warning32.png
│ ├── workspace.png
│ └── wrong.gif
├── metadata.txt
├── plugin.py
├── qgis
│ ├── __init__.py
│ ├── catalog.py
│ ├── exporter.py
│ ├── layers.py
│ ├── layerwatcher.py
│ ├── sldadapter.py
│ ├── uri.py
│ └── utils.py
├── resources
│ ├── grayscale.sld
│ └── rgb.sld
├── settings.json
└── test
│ ├── __init__.py
│ ├── catalogtests.py
│ ├── coveragerc
│ ├── data
│ ├── geo.dbf
│ ├── geo.prj
│ ├── geo.qpj
│ ├── geo.shp
│ ├── geo.shx
│ ├── land.dbf
│ ├── land.prj
│ ├── land.qpj
│ ├── land.shp
│ ├── land.shx
│ ├── qgis_plugin_test_dem.tif
│ ├── qgis_plugin_test_dem.tif.aux.xml
│ ├── qgis_plugin_test_dem_exact.tif
│ ├── qgis_plugin_test_dem_rbg.tif
│ ├── qgis_plugin_test_demascii.asc
│ ├── qgis_plugin_test_pt1.dbf
│ ├── qgis_plugin_test_pt1.prj
│ ├── qgis_plugin_test_pt1.qpj
│ ├── qgis_plugin_test_pt1.shp
│ ├── qgis_plugin_test_pt1.shx
│ ├── qgis_plugin_test_pt1json.geojson
│ ├── qgis_plugin_test_pt2.dbf
│ ├── qgis_plugin_test_pt2.prj
│ ├── qgis_plugin_test_pt2.qpj
│ ├── qgis_plugin_test_pt2.shp
│ ├── qgis_plugin_test_pt2.shx
│ ├── qgis_plugin_test_pt3.dbf
│ ├── qgis_plugin_test_pt3.prj
│ ├── qgis_plugin_test_pt3.qpj
│ ├── qgis_plugin_test_pt3.shp
│ ├── qgis_plugin_test_pt3.shx
│ ├── qgis_plugin_test_pt4.dbf
│ ├── qgis_plugin_test_pt4.prj
│ ├── qgis_plugin_test_pt4.qpj
│ ├── qgis_plugin_test_pt4.shp
│ ├── qgis_plugin_test_pt4.shx
│ ├── symbology
│ │ ├── graticule.dbf
│ │ ├── graticule.prj
│ │ ├── graticule.qpj
│ │ ├── graticule.shp
│ │ ├── graticule.shx
│ │ ├── irregular_lines.cpg
│ │ ├── irregular_lines.dbf
│ │ ├── irregular_lines.prj
│ │ ├── irregular_lines.qpj
│ │ ├── irregular_lines.shp
│ │ ├── irregular_lines.shx
│ │ ├── irregular_polygons.cpg
│ │ ├── irregular_polygons.dbf
│ │ ├── irregular_polygons.prj
│ │ ├── irregular_polygons.qpj
│ │ ├── irregular_polygons.shp
│ │ ├── irregular_polygons.shx
│ │ ├── labels_lines_01_parallel.qgs
│ │ ├── labels_lines_02_curved.qgs
│ │ ├── labels_lines_03_curved_on_line.qgs
│ │ ├── labels_lines_04_curved_below_line.qgs
│ │ ├── labels_lines_05_horizontal.qgs
│ │ ├── labels_points_01_simple.qgs
│ │ ├── labels_points_02_rotated_points.qgs
│ │ ├── labels_points_03_halo_and_displace.qgs
│ │ ├── labels_points_04_quadrant.qgs
│ │ ├── labels_points_05_cartographic.qgs
│ │ ├── labels_points_06_cartographic_from_symbol.qgs
│ │ ├── labels_polygons_01_offset_centroid.qgs
│ │ ├── labels_polygons_02_around_centroid.qgs
│ │ ├── labels_polygons_03_using_perimeter.qgs
│ │ ├── labels_polygons_04_horizontal.qgs
│ │ ├── labels_polygons_05_free.qgs
│ │ ├── labels_polygons_06_curved_perimeter.qgs
│ │ ├── lines.dbf
│ │ ├── lines.prj
│ │ ├── lines.qgs
│ │ ├── lines.qpj
│ │ ├── lines.shp
│ │ ├── lines.shx
│ │ ├── points.dbf
│ │ ├── points.prj
│ │ ├── points.qgs
│ │ ├── points.qpj
│ │ ├── points.shp
│ │ ├── points.shx
│ │ ├── polygons.qgs
│ │ ├── qgis.jpeg
│ │ ├── raster_grayscale.qgs
│ │ ├── raster_grayscale_inverted.qgs
│ │ ├── raster_hillshade.qgs
│ │ ├── raster_palleted.qgs
│ │ ├── raster_pseudocolor.qgs
│ │ ├── raster_pseudocolor_discrete.qgs
│ │ ├── raster_pseudocolor_exact.qgs
│ │ ├── raster_rendered_rgb.qgs
│ │ └── symbology_test.qgs
│ ├── test.qgs
│ └── test_font.qgs
│ ├── deletetests.py
│ ├── dragdroptests.py
│ ├── functional.txt
│ ├── guitests.py
│ ├── integrationtest.py
│ ├── resources
│ ├── font.sld
│ ├── raster.sld
│ ├── vector.2.16.sld
│ ├── vector.sld
│ └── vector_hook.py
│ ├── symbologytests.py
│ ├── testplugin.py
│ └── utils.py
├── pavement.py
├── pylintrc
├── requirements-dev.txt
├── requirements.txt
├── rundockertests.sh
└── travis_secrets.tar.gz.enc
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 |
5 | # C extensions
6 | *.so
7 |
8 | # Distribution / packaging
9 | .Python
10 | env/
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | lib/
17 | lib64/
18 | parts/
19 | sdist/
20 | var/
21 | *.egg-info/
22 | .installed.cfg
23 | *.egg
24 | geoserverexplorer/docs/
25 | geoserverexplorer/extlibs/
26 |
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .cache
43 | nosetests.xml
44 | coverage.xml
45 |
46 | # Translations
47 | *.mo
48 | *.pot
49 |
50 | # Django stuff:
51 | *.log
52 |
53 | # Sphinx documentation
54 | docs/_build/
55 |
56 | # PyBuilder
57 | target/
58 | #ext-libs
59 | #ext-src
60 | geoserverexplorer.zip
61 | ssh_config
62 |
63 | #QGIS Backup files
64 | *.qgs~
65 | *.qgz~
66 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "docs/themes"]
2 | path = docs/themes
3 | url = https://github.com/boundlessgeo/sphinx-theme
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 | addons:
3 | hosts:
4 | - suite410.boundless.test
5 | services:
6 | - docker
7 | env:
8 | global:
9 | - PLUGIN_NAME=geoserverexplorer
10 | - secure: "oy82iDfs5KWE2nmMgwqX/uNZs9frXzb212VpPy8wpz5q3pERQiFLuttXinIZbi9KJq92R2hpmEPCLrpnH4de5s1c8N0pJtBc17Sx28DqJcZIcogpO/zXnQfj/w3s6Gw5p+N0KW4LMruGe+wlu3zJadg0i+Bck2haSkO9C2fO62lnas9Hp86wjKAqxbvYIf3XnFHLyB1ICQEQjbXNyrwdP1dXTeoUbFn8UaKhinxRV6OtutDgRDua3ZkFuPGBDqKX3//9xoGze6r2Xo/Y99C7hJkjRHOz0RkJu0khXsw3TlZlKVo1OfkWh1NsdcuZsm7gKpNqAp77BRLWorSxRxCSjyVhqDlqguwSN7MrT/5xQjn0mj/XDnuzhNzTntxOPpeWmXSNskpxKhwcpRd2jni6Wd5W1/UpoBC2Ueo8YBpE/0wVNMUd1q5XVZjBvBc715OnrvI3Z6i002yWUaj6uQHBWG9IP6lGBTfl/271648KCpVdtj4mCQTsv9aTVgFZbc4cQQfSw6kH1IxdRi+7+ulK/O2eoZcnaihzlyfdoHv1pbuKNQCqkqeUYAQG+RXwez0ckch8cRuOcPxF0Y/5DyVmExjgK7O1DPPDWDFvsmThML+wY3lY/ZAH46Sebhch34TLyopjUoTaumhwcm84T3goxUUJTPbg+iEJkOF0EkdCRTQ="
11 | - secure: "g1apYRlEgftoThS0apF09OuPICw9pIp6OQKsED/ObyuqA+htP+AX6pprqG517BakJW2WMbTCaG0a3S4d+EnyQ3E/NIRtEivdR6/aVNiLHaOJXlSBKw4gWHX0F3ZyiVRMqRSJ2xVSHlNWqmSmUaUkSUJr9FUNYr/zGHVAg3DjUC7Z8wVVQIwBHrNtcfwsDM3cQOpB4tUAQkxOxF5Nb+jVx/7Cw6QGhsEy66XRWhK8d4R56XaC5uf5pmYZcGZaS69Y3O89dnMmY7A63HliXQpTtYjhZ4FF7WAGzuNFENNYVYo30gRUi1cv7CoWd+RE/3qGMGpcxs/lAU3lD5OLu5O7P/apmfFwKKJ0cS+fXKuI+gYMzpWIM/gBulTnNMzVHzWisy+1dVzsAZxzX4XRCb0rD/W89c770k85F/WNYGpUdSE8J7XDSFHV95FfmKIeAjSo1NSt8xijarz6YmxoktDjIWiogtpiLkOp6vhijbo6GiER+6kQ3JjUXWPbl+EOmsqFHUKMq0osclNqS+NWoqFZ7onQvK3L/uvza72eqM2OSqIXy2ilau4nlVNUl4P6IQmmZWlJmAqtmBO/O1f6NV6FO8czliEW6vQJbu2kojvqrFglYnUXNcJzKf/oH9g1ZY4Cw7qsf8s/NkYTN1wBFr9mTJ4B3ZfUgeQohNNZE1Xo8Ws="
12 | matrix:
13 | - QGIS_VERSION_TAG=master PYTHON_EXECUTABLE=python3 PIP_EXECUTABLE=pip3
14 | before_install:
15 | - echo "$DOCKER_PWD" | docker login -u "$DOCKER_USER" --password-stdin
16 | - docker-compose up -d
17 | - docker-compose ps
18 | - sleep 10
19 | - docker-compose exec qgis-testing-environment sh -c "qgis_setup.sh ${PLUGIN_NAME}"
20 | - docker-compose exec qgis-testing-environment sh -c "pip3 install paver"
21 | script:
22 | - docker-compose exec qgis-testing-environment sh -c "cd /tests_directory && paver setup && paver package --tests"
23 | - docker version
24 | - docker-compose version
25 | - docker-compose exec qgis-testing-environment sh -c "GSPORT=8082 GSHOSTNAME=suite410.boundless.test qgis_testrunner.sh geoserverexplorer.test.catalogtests"
26 | - docker-compose exec qgis-testing-environment sh -c "GSPORT=8082 GSHOSTNAME=suite410.boundless.test qgis_testrunner.sh geoserverexplorer.test.deletetests"
27 | - docker-compose exec qgis-testing-environment sh -c "GSPORT=8082 GSHOSTNAME=suite410.boundless.test qgis_testrunner.sh geoserverexplorer.test.dragdroptests"
28 | - docker-compose exec qgis-testing-environment sh -c "GSPORT=8082 GSHOSTNAME=suite410.boundless.test qgis_testrunner.sh geoserverexplorer.test.guitests"
29 | notifications:
30 | slack:
31 | secure: "BGVhes7seUF5U0T7PNGUxEu0MFmFVSeuF6FL+nOgtDfibX2IqWb+L7lWddJ+ZePvVYBzORTZs2vYJNQkIBPK2zDoX95rT56J+7ej6aVdxWE9dpd5BKf6IC9WBKyvSBv2gRm7J/zfSAIyKDHorY2MvemfuufDCfNoFEO0YNEKZxx3gc5A3xc3F1SCs1N8vp2DKQ0AA+Afg6G5QfEDLpW7xEYLZG/WEtS2zQIw4l/SqyszpvQEoCXblpLe1T/o6jlsuUPzZTMdaPpay2w2IyTs/IQaGUAIKThcL869Tu0TDkfFC209tRaCr2H2Fru9HCLutyX3oPgP4rwT7wI4Yg0TX47no8mBUNE3EHsh6hoKNhi8fXAzNnAZe/qDh0pFs/1yX9UTbMiq9UDa6CqHjH8dSnX8LRcs77dJlolNi9Na875y4L4VOuAqa2dScdHfjsX0WApO/t5e+RarduPfFgHZw1AkpuoW++fPmYt6geBDYyP3sX/f0z//LzIGDtrjNiIgvIlyPWnIBd++mMqLyLkjl2zr7l35JqjGDYKjzJuOPZXCHfvkmcIV7GO17HCs7P9VuyA56sycVp8iJSfYI4X26LW1l5BPVPy2muprSHyj+PnTG96vrcGM/mV2Gb1VcFaZ6RxC5jqgqnCXQ33PC7XpiKVCW80L5di0wYqH8drisnA="
32 | after_success:
33 | - |
34 | if [ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ]; then
35 | mkdir /home/travis/.ssh/
36 | chmod 700 /home/travis/.ssh/
37 | openssl aes-256-cbc -K $encrypted_255ebb4dc86b_key -iv $encrypted_255ebb4dc86b_iv -in travis_secrets.tar.gz.enc -out travis_secrets.tar.gz -d
38 | tar xzvf travis_secrets.tar.gz
39 | mv id_rsa.qgisrepoguest /home/travis/.ssh/id_rsa.qgisrepoguest
40 | mv ssh_config /home/travis/.ssh/config
41 | chmod 600 /home/travis/.ssh/id_rsa.qgisrepoguest
42 | chmod 600 /home/travis/.ssh/config
43 | export RELEASE_ZIPNAME=${PLUGIN_NAME}.zip
44 | echo "Uploading ${RELEASE_ZIPNAME} to QGIS Dev..."
45 | scp ${PLUGIN_NAME}.zip qgisrepoguest:${UPLOADS}/${RELEASE_ZIPNAME}
46 | export GIT_REV=$(git rev-parse --short HEAD | tr -d '\n')
47 | ssh qgisrepoguest "${UPDATER} update --dev --role desktop-qgis-plugin-dev --git-hash ${GIT_REV} ${RELEASE_ZIPNAME}"
48 | fi
49 |
--------------------------------------------------------------------------------
/CONTRIBUTING.rst:
--------------------------------------------------------------------------------
1 | Contributing
2 | ============
3 |
4 | Pull Requests
5 | -------------
6 |
7 | Pull requests are welcome,:
8 |
9 | * For small changes (under a file in size) a committer can apply the fix on your behalf.
10 |
11 | * For changes over one file in size we ask that you add your details (or your employer details) in the file ``__copyright__``).
12 |
13 | We trust you (and your employer) understand the `GPL License `_ used by this plugin and QGIS. This is why we asks you note your copyright details above.
14 |
15 | The complete list of `contributors `_ is available on github.
16 |
17 | Committers
18 | ----------
19 |
20 | The project committers:
21 |
22 | * `Victor Olaya `_ (Boundless)
23 | * `Larry Shaffer `_ (Boundless)
24 | * `Luigi Pirelli `_ (Boundless)
25 | * `Alexander Bruy `_ (Boundless)
26 |
27 | This is a small project that communicates via pull request.
28 |
29 | To request commit access issue a pull request against this CONTRIBUTING.rst file. Existing committers can review (+1,0,-1) and merge the change accordingly.
30 |
31 | By the same token committers that are inactive can be retired via a pull request.
32 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | .. image:: https://travis-ci.org/boundlessgeo/qgis-geoserver-plugin.svg?branch=master
2 | :target: https://travis-ci.org/boundlessgeo/qgis-geoserver-plugin
3 |
4 | GeoServer Explorer
5 | ==================
6 |
7 | A plugin to configure and manage GeoServer from QGIS.
8 |
9 | Installation
10 | ------------
11 |
12 | The plugin is available through QGIS official plugin repository. Nevertheless, to install it using this repository, run the following in a terminal (you will need to have `paver `_ installed):
13 |
14 | ::
15 |
16 | $ paver setup
17 | $ paver install
18 |
19 | The first command will fetch the dependencies required by the plugin.
20 | The second one will install the plugin in your local QGIS plugins folder. In case you have already downloadd the GeoServer Explorer plugin, this second step will silently fail, in order to make it work go to your local plugin directory (e.g., "$HOME/.qgis2/python/plugins" and remove the "geoserverexplorer" folder, then run ``paver install`` again).
21 | Open QGIS and you should already see the GeoServer Explorer plugin available in your QGIS plugin manager.
22 |
23 | Documentation
24 | -------------
25 |
26 | Thew plugin is documented `here `_.
27 |
28 | Getting Help
29 | ------------
30 |
31 | If you have questions, please use the project `mailing list `_
32 |
33 | Use the Github project for any bug reports. Pull requests are welcome.
34 |
35 | Cloning this repository
36 | -----------------------
37 |
38 | This repository uses external repositories as submodules. Therefore in order to include the external repositories during cloning you should use the *--recursive* option:
39 |
40 | ``git clone --recursive http://github.com/boundlessgeo/qgis-geoserver-plugin.git``
41 |
42 | Also, to update the submodules whenever there are changes in the remote repositories one should do:
43 |
44 | ``git submodule update --remote``
45 |
46 |
47 | Run unit tests
48 | -----------------------
49 |
50 | just execute the script ``rundockertests.sh``
51 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '2'
2 |
3 | services:
4 |
5 | suite410:
6 | image: boundlessgeo/suite-desktop-testing:4.10
7 | environment:
8 | - TOMCAT_SSL_ENABLED_PROTOCOLS=${TOMCAT_SSL_ENABLED_PROTOCOLS}
9 | ports:
10 | - "8082:8080"
11 | - "8444:8443"
12 | networks:
13 | desktop-network:
14 | aliases:
15 | - suite410.boundless.test
16 |
17 | qgis-testing-environment:
18 | image: elpaso/qgis-testing-environment:${QGIS_VERSION_TAG}
19 | volumes:
20 | - /tmp/.X11-unix:/tmp/.X11-unix
21 | - ./:/tests_directory
22 | environment:
23 | DISPLAY: ':99'
24 | QT_X11_NO_MITSHM: '1'
25 |
26 | volumes:
27 | bs_data_100:
28 | bs_data:
29 |
30 | networks:
31 | desktop-network:
32 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # (c) 2016 Boundless, http://boundlessgeo.com
3 | # This code is licensed under the GPL 2.0 license.
4 | #
5 | # Makefile for Sphinx documentation
6 | #
7 |
8 | # You can set these variables from the command line.
9 | SPHINXOPTS =
10 | SPHINXBUILD = sphinx-build
11 | PAPER =
12 | BUILDDIR = build
13 |
14 | # Internal variables.
15 | PAPEROPT_a4 = -D latex_paper_size=a4
16 | PAPEROPT_letter = -D latex_paper_size=letter
17 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
18 | # the i18n builder cannot share the environment and doctrees with the others
19 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
20 |
21 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
22 |
23 | help:
24 | @echo "Please use \`make ' where is one of"
25 | @echo " html to make standalone HTML files"
26 | @echo " dirhtml to make HTML files named index.html in directories"
27 | @echo " singlehtml to make a single large HTML file"
28 | @echo " pickle to make pickle files"
29 | @echo " json to make JSON files"
30 | @echo " htmlhelp to make HTML files and a HTML help project"
31 | @echo " qthelp to make HTML files and a qthelp project"
32 | @echo " devhelp to make HTML files and a Devhelp project"
33 | @echo " epub to make an epub"
34 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
35 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
36 | @echo " text to make text files"
37 | @echo " man to make manual pages"
38 | @echo " texinfo to make Texinfo files"
39 | @echo " info to make Texinfo files and run them through makeinfo"
40 | @echo " gettext to make PO message catalogs"
41 | @echo " changes to make an overview of all changed/added/deprecated items"
42 | @echo " linkcheck to check all external links for integrity"
43 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
44 |
45 | clean:
46 | -rm -rf $(BUILDDIR)/*
47 |
48 | html:
49 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
50 | @echo
51 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
52 |
53 | dirhtml:
54 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
55 | @echo
56 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
57 |
58 | singlehtml:
59 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
60 | @echo
61 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
62 |
63 | pickle:
64 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
65 | @echo
66 | @echo "Build finished; now you can process the pickle files."
67 |
68 | json:
69 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
70 | @echo
71 | @echo "Build finished; now you can process the JSON files."
72 |
73 | htmlhelp:
74 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
75 | @echo
76 | @echo "Build finished; now you can run HTML Help Workshop with the" \
77 | ".hhp project file in $(BUILDDIR)/htmlhelp."
78 |
79 | qthelp:
80 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
81 | @echo
82 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
83 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
84 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenGeoSuiteQGISplugin.qhcp"
85 | @echo "To view the help file:"
86 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenGeoSuiteQGISplugin.qhc"
87 |
88 | devhelp:
89 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
90 | @echo
91 | @echo "Build finished."
92 | @echo "To view the help file:"
93 | @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenGeoSuiteQGISplugin"
94 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenGeoSuiteQGISplugin"
95 | @echo "# devhelp"
96 |
97 | epub:
98 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
99 | @echo
100 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
101 |
102 | latex:
103 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
104 | @echo
105 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
106 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
107 | "(use \`make latexpdf' here to do that automatically)."
108 |
109 | latexpdf:
110 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
111 | @echo "Running LaTeX files through pdflatex..."
112 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
113 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
114 |
115 | text:
116 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
117 | @echo
118 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
119 |
120 | man:
121 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
122 | @echo
123 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
124 |
125 | texinfo:
126 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
127 | @echo
128 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
129 | @echo "Run \`make' in that directory to run these through makeinfo" \
130 | "(use \`make info' here to do that automatically)."
131 |
132 | info:
133 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
134 | @echo "Running Texinfo files through makeinfo..."
135 | make -C $(BUILDDIR)/texinfo info
136 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
137 |
138 | gettext:
139 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
140 | @echo
141 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
142 |
143 | changes:
144 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
145 | @echo
146 | @echo "The overview file is in $(BUILDDIR)/changes."
147 |
148 | linkcheck:
149 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
150 | @echo
151 | @echo "Link check complete; look for any errors in the above output " \
152 | "or in $(BUILDDIR)/linkcheck/output.txt."
153 |
154 | doctest:
155 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
156 | @echo "Testing of doctests in the sources finished, look at the " \
157 | "results in $(BUILDDIR)/doctest/output.txt."
158 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | REM
3 | REM (c) 2016 Boundless, http://boundlessgeo.com
4 | REM This code is licensed under the GPL 2.0 license.
5 | REM
6 |
7 | REM Command file for Sphinx documentation
8 |
9 | if "%SPHINXBUILD%" == "" (
10 | set SPHINXBUILD=sphinx-build
11 | )
12 | set BUILDDIR=build
13 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
14 | set I18NSPHINXOPTS=%SPHINXOPTS% source
15 | if NOT "%PAPER%" == "" (
16 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
17 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
18 | )
19 |
20 | if "%1" == "" goto help
21 |
22 | if "%1" == "help" (
23 | :help
24 | echo.Please use `make ^` where ^ is one of
25 | echo. html to make standalone HTML files
26 | echo. dirhtml to make HTML files named index.html in directories
27 | echo. singlehtml to make a single large HTML file
28 | echo. pickle to make pickle files
29 | echo. json to make JSON files
30 | echo. htmlhelp to make HTML files and a HTML help project
31 | echo. qthelp to make HTML files and a qthelp project
32 | echo. devhelp to make HTML files and a Devhelp project
33 | echo. epub to make an epub
34 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
35 | echo. text to make text files
36 | echo. man to make manual pages
37 | echo. texinfo to make Texinfo files
38 | echo. gettext to make PO message catalogs
39 | echo. changes to make an overview over all changed/added/deprecated items
40 | echo. linkcheck to check all external links for integrity
41 | echo. doctest to run all doctests embedded in the documentation if enabled
42 | goto end
43 | )
44 |
45 | if "%1" == "clean" (
46 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
47 | del /q /s %BUILDDIR%\*
48 | goto end
49 | )
50 |
51 | if "%1" == "html" (
52 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
53 | if errorlevel 1 exit /b 1
54 | echo.
55 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
56 | goto end
57 | )
58 |
59 | if "%1" == "dirhtml" (
60 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
61 | if errorlevel 1 exit /b 1
62 | echo.
63 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
64 | goto end
65 | )
66 |
67 | if "%1" == "singlehtml" (
68 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
69 | if errorlevel 1 exit /b 1
70 | echo.
71 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
72 | goto end
73 | )
74 |
75 | if "%1" == "pickle" (
76 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
77 | if errorlevel 1 exit /b 1
78 | echo.
79 | echo.Build finished; now you can process the pickle files.
80 | goto end
81 | )
82 |
83 | if "%1" == "json" (
84 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
85 | if errorlevel 1 exit /b 1
86 | echo.
87 | echo.Build finished; now you can process the JSON files.
88 | goto end
89 | )
90 |
91 | if "%1" == "htmlhelp" (
92 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
93 | if errorlevel 1 exit /b 1
94 | echo.
95 | echo.Build finished; now you can run HTML Help Workshop with the ^
96 | .hhp project file in %BUILDDIR%/htmlhelp.
97 | goto end
98 | )
99 |
100 | if "%1" == "qthelp" (
101 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
102 | if errorlevel 1 exit /b 1
103 | echo.
104 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
105 | .qhcp project file in %BUILDDIR%/qthelp, like this:
106 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OpenGeoSuiteQGISplugin.qhcp
107 | echo.To view the help file:
108 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OpenGeoSuiteQGISplugin.ghc
109 | goto end
110 | )
111 |
112 | if "%1" == "devhelp" (
113 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
114 | if errorlevel 1 exit /b 1
115 | echo.
116 | echo.Build finished.
117 | goto end
118 | )
119 |
120 | if "%1" == "epub" (
121 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
122 | if errorlevel 1 exit /b 1
123 | echo.
124 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
125 | goto end
126 | )
127 |
128 | if "%1" == "latex" (
129 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
130 | if errorlevel 1 exit /b 1
131 | echo.
132 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
133 | goto end
134 | )
135 |
136 | if "%1" == "text" (
137 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
138 | if errorlevel 1 exit /b 1
139 | echo.
140 | echo.Build finished. The text files are in %BUILDDIR%/text.
141 | goto end
142 | )
143 |
144 | if "%1" == "man" (
145 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
146 | if errorlevel 1 exit /b 1
147 | echo.
148 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
149 | goto end
150 | )
151 |
152 | if "%1" == "texinfo" (
153 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
154 | if errorlevel 1 exit /b 1
155 | echo.
156 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
157 | goto end
158 | )
159 |
160 | if "%1" == "gettext" (
161 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
162 | if errorlevel 1 exit /b 1
163 | echo.
164 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
165 | goto end
166 | )
167 |
168 | if "%1" == "changes" (
169 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
170 | if errorlevel 1 exit /b 1
171 | echo.
172 | echo.The overview file is in %BUILDDIR%/changes.
173 | goto end
174 | )
175 |
176 | if "%1" == "linkcheck" (
177 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
178 | if errorlevel 1 exit /b 1
179 | echo.
180 | echo.Link check complete; look for any errors in the above output ^
181 | or in %BUILDDIR%/linkcheck/output.txt.
182 | goto end
183 | )
184 |
185 | if "%1" == "doctest" (
186 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
187 | if errorlevel 1 exit /b 1
188 | echo.
189 | echo.Testing of doctests in the sources finished, look at the ^
190 | results in %BUILDDIR%/doctest/output.txt.
191 | goto end
192 | )
193 |
194 | :end
195 |
--------------------------------------------------------------------------------
/docs/source/caveats/sld.rst:
--------------------------------------------------------------------------------
1 | This document describes the symbology elements from QGIS that are supported when publishing a QGIS layer to GeoServer using the OpenGeo Suite plugin. Layers with symbologies using these elements are guaranteed to have the same styling once published to GeoServer. Otherwise, differences must be found.
2 |
3 | General
4 | ========
5 |
6 | All units have to be in milimeters.
7 |
8 | Data defined properties are not supported for any type of symbology or element.
9 |
10 | Layer transparency is supported, but layer blending is not.
11 |
12 | SVG icons are supported as long as the symbology only uses one version of the icon in terms of color properties. That is, if the symbology uses the SVG plane icon, it is not possible to have a categorized symbology in which one of the categories uses the icon with a red color and another one where it is used with a blue color. This is due to the fact that QGIS support parameters in SVG files, while GeoServer does not.
13 |
14 | Point layers
15 | ============
16 |
17 | Supported symbology types: Single Symbol, Categorized, Graduated
18 |
19 | Supported symbol layer types:
20 |
21 | # Simple marker: All properties of markers are supported except Angle, Offset and Anchor point.
22 |
23 | All simple marker shapes are supported except pentagon
24 |
25 | # SVG markers. All properties of SVG markers are supported except Angle, Offset and Anchor point.
26 |
27 | Multi-layered symbols can be used, as long as the same SVG icon is not used with different properties in different symbol layers, as described in the General section.
28 |
29 |
30 |
31 | Line layers
32 | ============
33 |
34 | Supported symbology types: Single Symbol, Categorized, Graduated
35 |
36 | Supported symbol layer types:
37 |
38 | # Simple line: All properties of markers are supported except custom dash pattern
39 |
40 | # Marker line. Supported, but parameters are not used. Only marker definition itself is used.
41 |
42 | Multi-layered symbols can be used, as long as the same SVG icon is not used with different properties in different symbol layers, as described in the General section.
43 |
44 |
45 | Polygon layers
46 | ===============
47 |
48 | Supported symbology types: Single Symbol, Categorized, Graduated
49 |
50 | Supported symbol layer types:
51 |
52 | # Simple fill: All properties are supported
53 |
54 | # Line pattern fill: Only the Distance parameter is supported. The lines that define the pattern must be single-layered and the layer type must be "Simple line"
55 |
56 | # SVGFill: All parameters are supported except Rotation
57 |
58 | Multi-layered symbols can be used, as long as the same SVG icon is not used with different properties in different symbol layers, as described in the General section.
59 |
60 |
61 | Labelling
62 | ============
63 |
64 | Only parameters in the Text and Placement sections are supported.
65 |
66 | Text section
67 | --------------
68 |
69 | Supported parameters: Style, Size, Color. Size only supported in points
70 |
71 | Placement section
72 | ------------------
73 |
74 | Supported parameters: Displacement, Rotation (in "Offset from point" option)
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/docs/source/img/actions/add_catalog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/add_catalog.png
--------------------------------------------------------------------------------
/docs/source/img/actions/add_style.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/add_style.png
--------------------------------------------------------------------------------
/docs/source/img/actions/catalog_added.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/catalog_added.png
--------------------------------------------------------------------------------
/docs/source/img/actions/confirm_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/confirm_delete.png
--------------------------------------------------------------------------------
/docs/source/img/actions/create_catalog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/create_catalog.png
--------------------------------------------------------------------------------
/docs/source/img/actions/create_workspace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/create_workspace.png
--------------------------------------------------------------------------------
/docs/source/img/actions/define_group.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/define_group.png
--------------------------------------------------------------------------------
/docs/source/img/actions/define_gwc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/define_gwc.png
--------------------------------------------------------------------------------
/docs/source/img/actions/dragdrop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/dragdrop.png
--------------------------------------------------------------------------------
/docs/source/img/actions/dragdrop_external.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/dragdrop_external.png
--------------------------------------------------------------------------------
/docs/source/img/actions/editsld.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/editsld.png
--------------------------------------------------------------------------------
/docs/source/img/actions/extent_drag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/extent_drag.png
--------------------------------------------------------------------------------
/docs/source/img/actions/new_style.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/new_style.png
--------------------------------------------------------------------------------
/docs/source/img/actions/order_in_group.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/order_in_group.png
--------------------------------------------------------------------------------
/docs/source/img/actions/plugin_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/plugin_menu.png
--------------------------------------------------------------------------------
/docs/source/img/actions/plugin_repo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/plugin_repo.png
--------------------------------------------------------------------------------
/docs/source/img/actions/plugin_repo_added.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/plugin_repo_added.png
--------------------------------------------------------------------------------
/docs/source/img/actions/publish_layer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/publish_layer.png
--------------------------------------------------------------------------------
/docs/source/img/actions/publish_layers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/publish_layers.png
--------------------------------------------------------------------------------
/docs/source/img/actions/publish_project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/publish_project.png
--------------------------------------------------------------------------------
/docs/source/img/actions/publish_style.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/publish_style.png
--------------------------------------------------------------------------------
/docs/source/img/actions/seed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/seed.png
--------------------------------------------------------------------------------
/docs/source/img/actions/seed_status.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/actions/seed_status.png
--------------------------------------------------------------------------------
/docs/source/img/intro/about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/about.png
--------------------------------------------------------------------------------
/docs/source/img/intro/add_catalog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/add_catalog.png
--------------------------------------------------------------------------------
/docs/source/img/intro/config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/config.png
--------------------------------------------------------------------------------
/docs/source/img/intro/description_panel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/description_panel.png
--------------------------------------------------------------------------------
/docs/source/img/intro/description_table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/description_table.png
--------------------------------------------------------------------------------
/docs/source/img/intro/duplicated_layer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/duplicated_layer.png
--------------------------------------------------------------------------------
/docs/source/img/intro/explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/explorer.png
--------------------------------------------------------------------------------
/docs/source/img/intro/gray_catalog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/gray_catalog.png
--------------------------------------------------------------------------------
/docs/source/img/intro/tracking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/tracking.png
--------------------------------------------------------------------------------
/docs/source/img/intro/undocked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/undocked.png
--------------------------------------------------------------------------------
/docs/source/img/intro/version_warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/docs/source/img/intro/version_warning.png
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | .. (c) 2016 Boundless, http://boundlessgeo.com
2 | This code is licensed under the GPL 2.0 license.
3 |
4 | .. _geoserver_explorer_docs:
5 |
6 | GeoServer Explorer Documentation
7 | ================================
8 |
9 | The GeoServer Explorer plugin is used to configure GeoServer through QGIS. It allows you to easily configure your GeoServer instance, from preparing data and styling to publishing directly to a catalog, all through the QGIS interface. This manual describes how to use the GeoServer Explorer plugin and the operations that it supports .
10 |
11 | .. toctree::
12 | :glob:
13 | :maxdepth: 2
14 |
15 | installation
16 | intro
17 | actions
18 | settingsconf
19 |
--------------------------------------------------------------------------------
/docs/source/installation.rst:
--------------------------------------------------------------------------------
1 | .. (c) 2018 Boundless, http://boundlessgeo.com
2 | This code is licensed under the GPL 2.0 license.
3 |
4 | Installation
5 | ============
6 |
7 | The **Geoserver Explorer** plugin is available in the QGIS official Plugin Repository.
8 |
9 | To install the plugin:
10 |
11 | #. Open QGIS.
12 | #. Go to :menuselection:`Plugins --> Install and manager plugins`.
13 | #. Select the :guilabel:`All` tab.
14 | #. Type the name of the plugin in the :guilabel:`search` bar to filter list of plugins.
15 | #. Select the plugin from the list.
16 | #. Click :guilabel:`Install plugin`.
17 |
18 | .. For instructions on how to install QGIS plugins, please refer to `QGIS Users manual `_.
19 |
--------------------------------------------------------------------------------
/docs/source/settingsconf.rst:
--------------------------------------------------------------------------------
1 | .. _geoserverexplorer_plugin_settings:
2 |
3 | Plugin settings
4 | ===============
5 |
6 | The plugin can be adjusted using the following settings, to be found in its settings dialog (:menuselection:`Web --> GeoServer --> Plugin Settings`).
7 |
8 | General
9 | -------
10 |
11 | .. list-table::
12 | :header-rows: 1
13 | :stub-columns: 1
14 | :widths: 20 80
15 | :class: non-responsive
16 |
17 | * - Option
18 | - Description
19 | * - Show description panel
20 | - Show description panel
21 | * - Ask confirmation before deleting
22 | - Ask confirmation before deleting
23 | * - Show toolbar
24 | - Show toolbar
25 | * - Keep a list of previous catalog connections
26 | - Keep a list of previous catalog connections
27 | * - Track layers and publish styles automatically
28 | - Track layers and publish styles automatically when they change
29 | * - Delete style when deleting layer
30 | - Delete style when deleting layer
31 | * - Delete resource when deleting layer
32 | - Delete resource when deleting layer
33 | * - Overwrite layers when uploading group
34 | - Overwrite layers when uploading group
35 | * - AuthCatalog XML cache time in seconds
36 | - AuthCatalog XML cache time in seconds
37 | * - QGIS manage SLD uom correctly
38 | - QGIS manage SLD uom correctly
39 | * - Size scale factor. !Unused if uom is managed!
40 | - Size scale factor. !Unused if uom is managed!
41 |
--------------------------------------------------------------------------------
/geoserverexplorer/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | import sys
7 | import os
8 | import site
9 |
10 | site.addsitedir(os.path.abspath(os.path.dirname(__file__) + '/extlibs'))
11 |
12 | # ABP: TORM import gsconfig from here
13 | # sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/ext-src/gsconfig/src'))
14 | #import httplib2
15 | #httplib2.debuglevel = 1
16 |
17 |
18 | from geoserverexplorer.qgis.catalog import *
19 |
20 | def classFactory(iface):
21 | from geoserverexplorer.plugin import GeoServerExplorerPlugin
22 | return GeoServerExplorerPlugin(iface)
23 |
--------------------------------------------------------------------------------
/geoserverexplorer/extlibs/geoserver/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/extlibs/geoserver/__init__.py
--------------------------------------------------------------------------------
/geoserverexplorer/extlibs/geoserver/layergroup.py:
--------------------------------------------------------------------------------
1 | '''
2 | gsconfig is a python library for manipulating a GeoServer instance via the GeoServer RESTConfig API.
3 |
4 | The project is distributed under a MIT License .
5 | '''
6 |
7 | from geoserver.support import ResourceInfo, bbox, write_bbox, write_string, xml_property, build_url
8 |
9 | try:
10 | from past.builtins import basestring
11 | except ImportError:
12 | pass
13 |
14 |
15 | def _maybe_text(n):
16 | if n is None:
17 | return None
18 | else:
19 | return n.text
20 |
21 |
22 | def _layer_list(node, element):
23 | if node is not None:
24 | return [_maybe_text(n.find("name")) for n in node.findall(element)]
25 |
26 |
27 | def _style_list(node):
28 | if node is not None:
29 | return [_maybe_text(n.find("name")) for n in node.findall("style")]
30 |
31 |
32 | def _write_layers(builder, layers, parent, element, attributes):
33 | builder.start(parent, dict())
34 | for l in layers:
35 | builder.start(element, attributes or dict())
36 | if l is not None:
37 | builder.start("name", dict())
38 | builder.data(l)
39 | builder.end("name")
40 | builder.end(element)
41 | builder.end(parent)
42 |
43 |
44 | def _write_styles(builder, styles):
45 | builder.start("styles", dict())
46 | for s in styles:
47 | builder.start("style", dict())
48 | if s is not None:
49 | builder.start("name", dict())
50 | builder.data(s)
51 | builder.end("name")
52 | builder.end("style")
53 | builder.end("styles")
54 |
55 |
56 | class LayerGroup(ResourceInfo):
57 | """
58 | Represents a layer group in geoserver
59 | """
60 |
61 | resource_type = "layerGroup"
62 | save_method = "PUT"
63 |
64 | def __init__(self, catalog, name, workspace=None):
65 | super(LayerGroup, self).__init__()
66 |
67 | assert isinstance(name, basestring)
68 |
69 | self.catalog = catalog
70 | self.name = name
71 | self.workspace = workspace
72 |
73 | # the XML format changed in 2.3.x - the element listing all the layers
74 | # and the entries themselves have changed
75 | if self.catalog.gsversion() == "2.2.x":
76 | parent, element, attributes = "layers", "layer", None
77 | else:
78 | parent, element, attributes = "publishables", "published", {'type': 'layer'}
79 |
80 | self._layer_parent = parent
81 | self._layer_element = element
82 | self._layer_attributes = attributes
83 | self.writers = dict(
84 | name = write_string("name"),
85 | styles = _write_styles,
86 | layers = lambda b, l: _write_layers(b, l, parent, element, attributes),
87 | bounds = write_bbox("bounds"),
88 | workspace = write_string("workspace"),
89 | mode = write_string("mode"),
90 | abstractTxt = write_string("abstractTxt"),
91 | title = write_string("title")
92 | )
93 |
94 | @property
95 | def href(self):
96 | uri = "layergroups/{}.xml".format(self.name)
97 | if self.workspace is not None:
98 | workspace_name = getattr(self.workspace, 'name', self.workspace)
99 | uri = "workspaces/{}/{}".format(workspace_name, uri)
100 | return "{}/{}".format(self.catalog.service_url, uri)
101 |
102 | styles = xml_property("styles", _style_list)
103 | bounds = xml_property("bounds", bbox)
104 | mode = xml_property("mode")
105 | abstract = xml_property("abstractTxt")
106 | title = xml_property("title")
107 |
108 | def _layers_getter(self):
109 | if "layers" in self.dirty:
110 | return self.dirty["layers"]
111 | else:
112 | if self.dom is None:
113 | self.fetch()
114 | node = self.dom.find(self._layer_parent)
115 | return _layer_list(node, self._layer_element) if node is not None else None
116 |
117 | def _layers_setter(self, value):
118 | self.dirty["layers"] = value
119 |
120 | def _layers_delete(self):
121 | self.dirty["layers"] = None
122 |
123 | layers = property(_layers_getter, _layers_setter, _layers_delete)
124 |
125 | def __str__(self):
126 | return "" % self.name
127 |
128 | __repr__ = __str__
129 |
130 |
131 | class UnsavedLayerGroup(LayerGroup):
132 | save_method = "POST"
133 |
134 | def __init__(self, catalog, name, layers, styles, bounds, mode, abstract, title, workspace = None):
135 | super(UnsavedLayerGroup, self).__init__(catalog, name, workspace=workspace)
136 | bounds = bounds if bounds is not None else ("-180", "180", "-90", "90", "EPSG:4326")
137 | self.dirty.update(
138 | name = name,
139 | layers = layers,
140 | styles = styles,
141 | bounds = bounds,
142 | workspace = workspace,
143 | mode = mode.upper(),
144 | abstractTxt = abstract,
145 | title = title
146 | )
147 |
148 | @property
149 | def href(self):
150 | query = {'name': self.name}
151 | path_parts = ['layergroups']
152 | if self.workspace is not None:
153 | workspace_name = getattr(self.workspace, 'name', self.workspace)
154 | path_parts = ["workspaces", workspace_name] + path_parts
155 | return build_url(self.catalog.service_url, path_parts, query)
156 |
--------------------------------------------------------------------------------
/geoserverexplorer/extlibs/geoserver/namespace.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/extlibs/geoserver/namespace.py
--------------------------------------------------------------------------------
/geoserverexplorer/extlibs/geoserver/style.py:
--------------------------------------------------------------------------------
1 | '''
2 | gsconfig is a python library for manipulating a GeoServer instance via the GeoServer RESTConfig API.
3 |
4 | The project is distributed under a MIT License .
5 | '''
6 |
7 | from geoserver.support import ResourceInfo, build_url, xml_property
8 | try:
9 | from past.builtins import basestring
10 | except ImportError:
11 | pass
12 |
13 |
14 | class Style(ResourceInfo):
15 | supported_formats = ["sld10", "sld11", "zip"]
16 | content_types = {
17 | "sld10": "application/vnd.ogc.sld+xml",
18 | "sld11": "application/vnd.ogc.se+xml",
19 | "zip": "application/zip"
20 | }
21 |
22 | def __init__(self, catalog, name, workspace=None, style_format="sld10"):
23 | super(Style, self).__init__()
24 | assert isinstance(name, basestring)
25 | assert style_format in Style.supported_formats
26 |
27 | self.catalog = catalog
28 | self.workspace = workspace
29 | self.name = name
30 | self.style_format = style_format
31 | self._sld_dom = None
32 |
33 | @property
34 | def fqn(self):
35 | return self.name if not self.workspace else '%s:%s' % (self.workspace, self.name)
36 |
37 | @property
38 | def href(self):
39 | return self._build_href('.xml')
40 |
41 | @property
42 | def body_href(self):
43 | return self._build_href('.sld')
44 |
45 | @property
46 | def create_href(self):
47 | return self._build_href('.xml', True)
48 |
49 | @property
50 | def content_type(self):
51 | return Style.content_types[self.style_format]
52 |
53 | def _build_href(self, extension, create=False):
54 | path_parts = ["styles"]
55 | query = {}
56 | if not create:
57 | path_parts.append(self.name + extension)
58 | else:
59 | query['name'] = self.name
60 | if self.workspace is not None:
61 | path_parts = ["workspaces", getattr(self.workspace, 'name', self.workspace)] + path_parts
62 | return build_url(self.catalog.service_url, path_parts, query)
63 |
64 | filename = xml_property("filename")
65 |
66 | def _get_sld_dom(self):
67 | if self._sld_dom is None:
68 | self._sld_dom = self.catalog.get_xml(self.body_href)
69 | return self._sld_dom
70 |
71 | @property
72 | def sld_title(self):
73 | user_style = self._get_sld_dom().find("{http://www.opengis.net/sld}NamedLayer/{http://www.opengis.net/sld}UserStyle")
74 | if not user_style:
75 | user_style = self._get_sld_dom().find("{http://www.opengis.net/sld}UserLayer/{http://www.opengis.net/sld}UserStyle")
76 |
77 | if user_style:
78 | try:
79 | # it is not mandatory
80 | title_node = user_style.find("{http://www.opengis.net/sld}Title")
81 | except:
82 | title_node = None
83 |
84 | return title_node.text if title_node is not None else None
85 |
86 | @property
87 | def sld_name(self):
88 | user_style = self._get_sld_dom().find("{http://www.opengis.net/sld}NamedLayer/{http://www.opengis.net/sld}UserStyle")
89 | if not user_style:
90 | user_style = self._get_sld_dom().find("{http://www.opengis.net/sld}UserLayer/{http://www.opengis.net/sld}UserStyle")
91 |
92 | if user_style:
93 | try:
94 | # it is not mandatory
95 | name_node = user_style.find("{http://www.opengis.net/sld}Name")
96 | except:
97 | name_node = None
98 |
99 | return name_node.text if name_node is not None else None
100 |
101 | @property
102 | def sld_body(self):
103 | resp = self.catalog.http_request(self.body_href)
104 | return resp.content
105 |
106 | def update_body(self, body):
107 | headers = {"Content-Type": self.content_type}
108 | self.catalog.http_request(
109 | self.body_href, body, "PUT", headers)
110 |
--------------------------------------------------------------------------------
/geoserverexplorer/extlibs/geoserver/util.py:
--------------------------------------------------------------------------------
1 | '''
2 | gsconfig is a python library for manipulating a GeoServer instance via the GeoServer RESTConfig API.
3 |
4 | The project is distributed under a MIT License .
5 | '''
6 |
7 | # shapefile_and_friends = None
8 | # shapefile_plus_sidecars = shapefile_and_friends("test/data/states")
9 |
10 |
11 | def shapefile_and_friends(path):
12 | return dict((ext, path + "." + ext) for ext in ['shx', 'shp', 'dbf', 'prj'])
13 |
--------------------------------------------------------------------------------
/geoserverexplorer/extlibs/geoserver/workspace.py:
--------------------------------------------------------------------------------
1 | '''
2 | gsconfig is a python library for manipulating a GeoServer instance via the GeoServer RESTConfig API.
3 |
4 | The project is distributed under a MIT License .
5 | '''
6 |
7 | from geoserver.support import xml_property, write_bool, ResourceInfo, build_url
8 |
9 |
10 | def workspace_from_index(catalog, node):
11 | name = node.find("name")
12 | return Workspace(catalog, name.text)
13 |
14 |
15 | class Workspace(ResourceInfo):
16 |
17 | resource_type = "workspace"
18 |
19 | def __init__(self, catalog, name):
20 | super(Workspace, self).__init__()
21 | self.catalog = catalog
22 | self.name = name
23 |
24 | @property
25 | def href(self):
26 | return build_url(self.catalog.service_url, ["workspaces", self.name + ".xml"])
27 |
28 | @property
29 | def coveragestore_url(self):
30 | return build_url(self.catalog.service_url, ["workspaces", self.name, "coveragestores.xml"])
31 |
32 | @property
33 | def datastore_url(self):
34 | return build_url(self.catalog.service_url, ["workspaces", self.name, "datastores.xml"])
35 |
36 | @property
37 | def wmsstore_url(self):
38 | return "%s/workspaces/%s/wmsstores.xml" % (self.catalog.service_url, self.name)
39 |
40 | def __repr__(self):
41 | return "%s @ %s" % (self.name, self.href)
42 |
--------------------------------------------------------------------------------
/geoserverexplorer/extlibs/site.py:
--------------------------------------------------------------------------------
1 | def __boot():
2 | import sys
3 | import os
4 | PYTHONPATH = os.environ.get('PYTHONPATH')
5 | if PYTHONPATH is None or (sys.platform == 'win32' and not PYTHONPATH):
6 | PYTHONPATH = []
7 | else:
8 | PYTHONPATH = PYTHONPATH.split(os.pathsep)
9 |
10 | pic = getattr(sys, 'path_importer_cache', {})
11 | stdpath = sys.path[len(PYTHONPATH):]
12 | mydir = os.path.dirname(__file__)
13 |
14 | for item in stdpath:
15 | if item == mydir or not item:
16 | continue # skip if current dir. on Windows, or my own directory
17 | importer = pic.get(item)
18 | if importer is not None:
19 | loader = importer.find_module('site')
20 | if loader is not None:
21 | # This should actually reload the current module
22 | loader.load_module('site')
23 | break
24 | else:
25 | try:
26 | import imp # Avoid import loop in Python 3
27 | stream, path, descr = imp.find_module('site', [item])
28 | except ImportError:
29 | continue
30 | if stream is None:
31 | continue
32 | try:
33 | # This should actually reload the current module
34 | imp.load_module('site', stream, path, descr)
35 | finally:
36 | stream.close()
37 | break
38 | else:
39 | raise ImportError("Couldn't find the real 'site' module")
40 |
41 | known_paths = dict([(makepath(item)[1], 1) for item in sys.path]) # 2.2 comp
42 |
43 | oldpos = getattr(sys, '__egginsert', 0) # save old insertion position
44 | sys.__egginsert = 0 # and reset the current one
45 |
46 | for item in PYTHONPATH:
47 | addsitedir(item)
48 |
49 | sys.__egginsert += oldpos # restore effective old position
50 |
51 | d, nd = makepath(stdpath[0])
52 | insert_at = None
53 | new_path = []
54 |
55 | for item in sys.path:
56 | p, np = makepath(item)
57 |
58 | if np == nd and insert_at is None:
59 | # We've hit the first 'system' path entry, so added entries go here
60 | insert_at = len(new_path)
61 |
62 | if np in known_paths or insert_at is None:
63 | new_path.append(item)
64 | else:
65 | # new path after the insert point, back-insert it
66 | new_path.insert(insert_at, item)
67 | insert_at += 1
68 |
69 | sys.path[:] = new_path
70 |
71 |
72 | if __name__ == 'site':
73 | __boot()
74 | del __boot
75 |
--------------------------------------------------------------------------------
/geoserverexplorer/geoserver/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | class GeoserverException(Exception):
7 | def __init__(self, message, details=None):
8 | super().__init__(message)
9 | self.details = details
10 |
--------------------------------------------------------------------------------
/geoserverexplorer/geoserver/auth.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | ***************************************************************************
5 | A catalog that uses QgsNetworkAccessManager
6 | ---------------------
7 | Date : August 2016
8 | Copyright : (C) 2016 Boundless, http://boundlessgeo.com
9 | Email : apasotti at boundlessgeo dot com
10 | ***************************************************************************
11 | * *
12 | * This program is free software; you can redistribute it and/or modify *
13 | * it under the terms of the GNU General Public License as published by *
14 | * the Free Software Foundation; either version 2 of the License, or *
15 | * (at your option) any later version. *
16 | * *
17 | ***************************************************************************
18 | """
19 |
20 | __author__ = 'Alessandro Pasotti'
21 | __date__ = 'August 2016'
22 |
23 | from datetime import timedelta, datetime
24 | from xml.etree.ElementTree import XML
25 | from xml.parsers.expat import ExpatError
26 | from geoserver.catalog import FailedRequestError
27 | from qgiscommons2.network.networkaccessmanager import NetworkAccessManager
28 | from .basecatalog import BaseCatalog
29 |
30 | class AuthCatalog(BaseCatalog):
31 |
32 | def __init__(self, service_url, authid, cache_time):
33 | # Do not call parent constructor, this is a patching class
34 | self.authid = authid
35 | self.cache_time = cache_time
36 | self.service_url = service_url.strip("/")
37 | self._cache = dict()
38 | self._version = None
39 | self.nam = NetworkAccessManager(self.authid, exception_class=FailedRequestError, debug=False)
40 | self.username = ''
41 | self.password = ''
42 |
43 | def http_request(self, url, data=None, method='get', headers = {}):
44 | resp, content = self.nam.request(url, method, data, headers)
45 | return resp
46 |
47 | def setup_connection(self):
48 | pass
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/geoserverexplorer/geoserver/basecatalog.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | ***************************************************************************
5 | A GS config catalog with superpowers
6 | ---------------------
7 | Date : August 2016
8 | Copyright : (C) 2016 Boundless, http://boundlessgeo.com
9 | Email : apasotti at boundlessgeo dot com
10 | ***************************************************************************
11 | * *
12 | * This program is free software; you can redistribute it and/or modify *
13 | * it under the terms of the GNU General Public License as published by *
14 | * the Free Software Foundation; either version 2 of the License, or *
15 | * (at your option) any later version. *
16 | * *
17 | ***************************************************************************
18 | """
19 | from builtins import str
20 | from datetime import datetime, timedelta
21 |
22 | __author__ = 'Alessandro Pasotti'
23 | __date__ = 'August 2016'
24 |
25 | from geoserver.catalog import Catalog, FailedRequestError
26 | from geoserver.support import build_url
27 | from geoserver.layer import Layer
28 | from qgis.gui import *
29 | from qgis.utils import iface
30 | import json
31 | from xml.etree.ElementTree import XML
32 | from xml.parsers.expat import ExpatError
33 |
34 | class BaseLayer(Layer):
35 | """Patched to get correct resources from workspaces"""
36 |
37 | @property
38 | def resource(self):
39 | if self.dom is None:
40 | self.fetch()
41 | name = self.dom.find("resource/name").text
42 | if self.name.find(':') != -1:
43 | return self.catalog.get_resource(name, workspace=self.name.split(':')[0])
44 | return self.catalog.get_resource(name)
45 |
46 |
47 | class BaseCatalog(Catalog):
48 |
49 | def layersEndpointUrl(self):
50 | return self.service_url[:self.service_url.find("/rest")]
51 |
52 | def _get_res(self, name):
53 | return [r for r in self.get_resources() if r.name == name]
54 |
55 | def get_namespaced_name(self, layer_name):
56 | """
57 | Prefix the layer name with the workspace by querying all the resources
58 | and finding the workspace from the one that matches the layer name.
59 | If the layer exists in several workspaces, the first match is returned.
60 | Return layer_name if the layer resource does not exists.
61 | """
62 | if layer_name.find(':') != -1:
63 | return layer_name
64 | res = self._get_res(layer_name)
65 | try:
66 | return "%s:%s" % (res[0].workspace.name, layer_name)
67 | except IndexError:
68 | return layer_name
69 |
70 |
71 | def get_layers(self, resource=None):
72 | """Prefix the layer name with ws name"""
73 | lyrs = super().get_layers(resource)
74 | # Start patch:
75 | layers = {}
76 | result = []
77 | for l in lyrs:
78 | try:
79 | layers[l.name].append(l)
80 | except KeyError:
81 | layers[l.name] = [l]
82 | # Prefix all names
83 | noAscii = False
84 | for name, ls in list(layers.items()):
85 | try:
86 | if len(ls) == 1:
87 | l = ls[0]
88 | l.name = self.get_namespaced_name(l.name)
89 | result.append(l)
90 | else:
91 | i = 0
92 | res = self._get_res(ls[0].name)
93 | for l in ls:
94 | l.name = "%s:%s" % (res[i].workspace.name, l.name)
95 | i += 1
96 | result.append(l)
97 | except UnicodeDecodeError:
98 | noAscii = True
99 |
100 | if noAscii:
101 | iface.messageBar().pushMessage("Warning", "Some layers contain non-ascii characters and could not be loaded",
102 | level = QgsMessageBar.WARNING,
103 | duration = 10)
104 | return result
105 |
106 |
107 |
--------------------------------------------------------------------------------
/geoserverexplorer/geoserver/settings.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 |
7 | from builtins import str
8 | from builtins import object
9 | import httplib2
10 | from xml.etree.ElementTree import XML
11 | import xml.etree.ElementTree as ET
12 | from urllib.parse import urlparse
13 | from geoserver.support import build_url
14 | from geoserverexplorer.geoserver.auth import AuthCatalog
15 |
16 | class Settings(object):
17 |
18 | def __init__(self, catalog):
19 | self.catalog = catalog
20 |
21 | def settings(self):
22 | settings = {}
23 | settings_url = build_url(self.catalog.service_url, ['settings.xml'])
24 | resp = self.catalog.http_request(settings_url, 'GET')
25 | if resp.status_code != 200:
26 | raise Exception('Settings listing failed: ' + resp.text)
27 | dom = XML(resp.text)
28 | sections = ['settings', 'jai','coverageAccess']
29 | for section in sections:
30 | params = []
31 | node = dom.find(section)
32 | if node is not None: #it will be none if the catalog does not support this operation
33 | for entry in node:
34 | if len(entry) == 0:
35 | params.append((entry.tag, entry.text))
36 | else:
37 | for subentry in entry:
38 | params.append((entry.tag + '/' + subentry.tag, subentry.text))
39 | settings[section] = params
40 |
41 | return settings
42 |
43 | def update(self, settings):
44 | root = ET.Element('global')
45 | for section in settings:
46 | params = settings[section]
47 | element = ET.SubElement(root, section)
48 | for name, value in params:
49 | if '/' in name:
50 | name, subname = name.split('/')
51 | subelement = element.find(name)
52 | if subelement is None:
53 | subelement = ET.SubElement(element, name)
54 | subsubelement = ET.SubElement(subelement, subname)
55 | subsubelement.text = str(value)
56 | else:
57 | subelement = ET.SubElement(element, name)
58 | subelement.text = str(value)
59 |
60 | xml = ET.tostring(root)
61 | settings_url = build_url(self.catalog.service_url, ['settings.xml'])
62 | headers = {'Content-type': 'text/xml'}
63 | resp = self.catalog.http_request(settings_url, xml, 'PUT', headers = headers)
64 | if resp.status_code != 200:
65 | raise Exception('Settings update failed: ' + resp.text)
66 |
--------------------------------------------------------------------------------
/geoserverexplorer/geoserver/util.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from zipfile import ZipFile
7 | import tempfile
8 | from os import path
9 |
10 |
11 | def name(named):
12 | """Get the name out of an object. This varies based on the type of the input:
13 | * the "name" of a string is itself
14 | * the "name" of None is itself
15 | * the "name" of an object with a property named name is that property -
16 | as long as it's a string
17 | * otherwise, we raise a ValueError
18 | """
19 | if isinstance(named, str) or named is None:
20 | return named
21 | elif hasattr(named, 'name'):
22 | if isinstance(named.name, str):
23 | return named.name
24 | elif callable(named.name) and isinstance(named.name(), str):
25 | return named.name()
26 | else:
27 | raise ValueError("Can't interpret %s as a name or a configuration object" % named)
28 |
29 | def getLayerFromStyle(style):
30 | '''Tries to find out which layer is using a given style.
31 | Returns none if cannot find a layer using the style'''
32 | cat = style.catalog
33 | layers = cat.get_layers()
34 | for layer in layers:
35 | if layer.default_style.name == style.name:
36 | return layer
37 | alternateStyles = layer.styles
38 | for alternateStyle in alternateStyles:
39 | if style.name == alternateStyle.name:
40 | return layer
41 |
42 | def groupsWithLayer(catalog, layer):
43 | grps = catalog.get_layergroups()
44 | grpswlyr = []
45 | for grp in grps:
46 | lyrs = grp.layers
47 | if lyrs is None:
48 | continue
49 | for lyr in lyrs:
50 | if layer.name == lyr:
51 | grpswlyr.append(grp)
52 | break
53 | return grpswlyr
54 |
55 | def removeLayerFromGroups(catalog, layer, groups=None):
56 | grps = groups or catalog.get_layergroups()
57 | for grp in grps:
58 | lyrs = grp.layers
59 | if lyrs is None:
60 | continue
61 | if layer.name not in lyrs:
62 | continue
63 | styles = grp.styles
64 | idx = lyrs.index(layer.name)
65 | del lyrs[idx]
66 | del styles[idx]
67 | grp.dirty.update(layers=lyrs, styles=styles)
68 | catalog.save(grp)
69 |
70 | def addLayerToGroups(catalog, layer, groups, workspace=None):
71 | '''This assumes the layer style with same name as layer already exists,
72 | otherwise None is assigned'''
73 | for grp in groups:
74 | lyrs = grp.layers
75 | styles = grp.styles
76 | lyrs.append(layer.name)
77 | style = catalog.get_styles(layer.name, workspace=workspace)[0]
78 | styles.append(style)
79 | grp.dirty.update(layers=lyrs, styles=styles)
80 | catalog.save(grp)
81 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from qgis.utils import iface
7 | from qgis.core import Qgis, QgsMessageLog
8 |
9 | def setInfo(msg):
10 | iface.messageBar().pushMessage("Info", msg,
11 | level = Qgis.Info,
12 | duration = 10)
13 |
14 | def setWarning(msg):
15 | iface.messageBar().pushMessage("Warning", msg,
16 | level = Qgis.Warning,
17 | duration = 10)
18 |
19 | def setError(msg, trace=None):
20 | iface.messageBar().pushMessage("Geoserver", msg, level=Qgis.Warning, duration=10)
21 | if trace is not None:
22 | QgsMessageLog.logMessage("{}:{}".format(msg, trace), level=Qgis.Critical)
23 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/confirm.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | '''
7 | Routines to ask for confirmation when performing certain operations
8 | '''
9 | from builtins import str
10 | from qgis.PyQt.QtGui import *
11 | from qgis.PyQt.QtCore import *
12 | from qgis.PyQt.QtWidgets import *
13 | from geoserverexplorer.gui.dialogs.gsnamedialog import getGSLayerName
14 | from geoserverexplorer.gui.gsnameutils import isNameValid, xmlNameRegex
15 | from qgiscommons2.settings import pluginSetting
16 |
17 | def publishLayer(catalog, layer, workspace=None, overwrite=False):
18 | name = layer.name()
19 | gslayers = [lyr.name for lyr in catalog.catalog.get_layers()]
20 | # TODO: remove when duplicate names on different workspaces are supported
21 | # we shoud check for unique names only on a given workspace
22 | if (name in gslayers and not overwrite) or not isNameValid(name, gslayers, 0, xmlNameRegex()):
23 | name = getGSLayerName(name=name, names=gslayers, unique=False)
24 | catalog.publishLayer(layer, workspace, True, name)
25 |
26 |
27 | def confirmDelete():
28 | askConfirmation = pluginSetting("ConfirmDelete")
29 | if not askConfirmation:
30 | return True
31 | msg = "You confirm that you want to delete the selected elements?"
32 | reply = QMessageBox.question(None, "Delete confirmation",
33 | msg, QMessageBox.Yes |
34 | QMessageBox.No, QMessageBox.No)
35 | return reply != QMessageBox.No
36 |
37 | # noinspection PyPep8Naming
38 | class DeleteDependentsDialog(QDialog):
39 |
40 | def __init__(self, dependent, parent=None):
41 | super(DeleteDependentsDialog, self).__init__(parent)
42 | self.title = "Confirm Deletion"
43 | self.msg = "The following elements depend on the elements to delete " \
44 | "and will be deleted as well:"
45 | typeorder = ['LayerGroup', 'Layer', 'GwcLayer', 'Other']
46 | names = dict()
47 | for dep in dependent:
48 | cls = dep.__class__.__name__
49 | name = dep.name
50 | title = ''
51 | if hasattr(dep, 'resource'):
52 | if hasattr(dep.resource, 'title'):
53 | if dep.resource.title != name:
54 | title = dep.resource.title
55 | desc = "- {0}: {1}{2}".format(
56 | cls,
57 | name,
58 | " ({0})".format(title) if title else ''
59 | )
60 | if cls in names:
61 | names[cls].append(desc)
62 | else:
63 | if cls in typeorder:
64 | names[cls] = [desc]
65 | else:
66 | if 'Other' in names:
67 | names['Other'].append(desc)
68 | else:
69 | names['Other'] = [desc]
70 |
71 | self.deletes = "
".join(
72 | ["
".join(sorted(list(set(names[typ]))))
73 | for typ in typeorder if typ in names])
74 | self.question = "Do you really want to delete all these elements?"
75 | self.buttonBox = None
76 | self.initGui()
77 |
78 | def initGui(self):
79 | self.setWindowTitle(self.title)
80 | layout = QVBoxLayout()
81 |
82 | msgLabel = QLabel(self.msg)
83 | msgLabel.setWordWrap(True)
84 | layout.addWidget(msgLabel)
85 |
86 | deletesView = QTextEdit()
87 | deletesView.setText(str(self.deletes))
88 | deletesView.setReadOnly(True)
89 | deletesView.setLineWrapMode(QTextEdit.NoWrap)
90 | layout.addWidget(deletesView)
91 |
92 | questLabel = QLabel(self.question)
93 | questLabel.setWordWrap(True)
94 | questLabel.setAlignment(Qt.AlignHCenter)
95 | layout.addWidget(questLabel)
96 |
97 | self.buttonBox = QDialogButtonBox(
98 | QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
99 | layout.addWidget(self.buttonBox)
100 |
101 | self.setLayout(layout)
102 | # noinspection PyUnresolvedReferences
103 | self.buttonBox.accepted.connect(self.accept)
104 | # noinspection PyUnresolvedReferences
105 | self.buttonBox.rejected.connect(self.reject)
106 |
107 | self.setMinimumWidth(400)
108 | self.setMinimumHeight(400)
109 | self.resize(500, 400)
110 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/contextualhelp.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | """
7 | Contextual help components for use in dialogs, etc.
8 | """
9 |
10 | import os
11 | from qgis.PyQt.QtGui import *
12 | from qgis.PyQt.QtCore import *
13 | from qgis.PyQt.QtWidgets import *
14 |
15 | # noinspection PyAttributeOutsideInit, PyPep8Naming
16 | class InfoIcon(QLabel):
17 | def __init__(self, tip, parent=None):
18 | QLabel.__init__(self, parent)
19 | self.tiptxt = tip
20 | self.setSizePolicy(QSizePolicy.Fixed,
21 | QSizePolicy.Fixed)
22 | self.setMaximumSize(QSize(16, 16))
23 | self.setMinimumSize(QSize(16, 16))
24 | infopx = QPixmap(
25 | os.path.dirname(os.path.dirname(__file__)) + "/images/help.png")
26 | self.setPixmap(infopx)
27 |
28 | self.setMouseTracking(True)
29 |
30 | def mouseMoveEvent(self, event):
31 | # QToolTip.showText(self.mapToGlobal(event.pos()),
32 | # self.tiptxt, self, self.rect())
33 | QToolTip.showText(self.mapToGlobal(event.pos()),
34 | self.tiptxt, self)
35 | event.ignore()
36 |
37 |
38 | # noinspection PyPep8Naming
39 | def infoIcon(tip, parent=None):
40 | return InfoIcon(tip, parent)
41 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/dialogs/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/dialogs/gsnamedialog.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | """
7 | Dialog to create a user-defined name for a GeoServer component, with optional
8 | validation.
9 | """
10 |
11 | from qgis.PyQt.QtGui import *
12 | from qgis.PyQt.QtCore import *
13 | from qgis.PyQt.QtWidgets import *
14 |
15 | APP = None
16 | if __name__ == '__main__':
17 | import sys
18 | # instantiate QApplication before importing QtGui subclasses
19 | APP = QApplication(sys.argv)
20 |
21 | from geoserverexplorer.gui.gsnameutils import GSNameWidget
22 | from geoserverexplorer.qgis.utils import UserCanceledOperation
23 | from geoserverexplorer.gui.gsnameutils import GSNameWidget, \
24 | xmlNameFixUp, xmlNameRegex, xmlNameRegexMsg
25 |
26 |
27 | # noinspection PyAttributeOutsideInit, PyPep8Naming
28 | class GSNameDialog(QDialog):
29 |
30 | def __init__(self, boxtitle='', boxmsg='', name='', namemsg='',
31 | nameregex='', nameregexmsg='', names=None,
32 | unique=False, maxlength=0, parent=None):
33 | super(GSNameDialog, self).__init__(parent)
34 | self.boxtitle = boxtitle
35 | self.boxmsg = boxmsg
36 | self.nameBox = GSNameWidget(
37 | name=name,
38 | namemsg=namemsg,
39 | nameregex=nameregex,
40 | nameregexmsg=nameregexmsg,
41 | names=names,
42 | unique=unique,
43 | maxlength=maxlength
44 | )
45 | self.initGui()
46 |
47 | def initGui(self):
48 | self.setWindowTitle('Define name')
49 | vertlayout = QVBoxLayout()
50 |
51 | self.groupBox = QGroupBox()
52 | self.groupBox.setTitle(self.boxtitle)
53 | self.groupBox.setLayout(vertlayout)
54 |
55 | if self.boxmsg:
56 | self.groupBoxMsg = QLabel(self.boxmsg)
57 | self.groupBoxMsg.setWordWrap(True)
58 | self.groupBox.layout().addWidget(self.groupBoxMsg)
59 |
60 | self.groupBox.layout().addWidget(self.nameBox)
61 |
62 | layout = QVBoxLayout()
63 | layout.addWidget(self.groupBox)
64 | self.buttonBox = QDialogButtonBox(
65 | QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
66 | self.okButton = self.buttonBox.button(QDialogButtonBox.Ok)
67 | self.cancelButton = self.buttonBox.button(QDialogButtonBox.Cancel)
68 | layout.addWidget(self.buttonBox)
69 |
70 | self.setLayout(layout)
71 |
72 | self.nameBox.nameValidityChanged.connect(self.okButton.setEnabled)
73 | self.nameBox.overwritingChanged.connect(self.updateButtons)
74 |
75 | # noinspection PyUnresolvedReferences
76 | self.buttonBox.accepted.connect(self.accept)
77 | # noinspection PyUnresolvedReferences
78 | self.buttonBox.rejected.connect(self.reject)
79 |
80 | self.setMinimumWidth(240)
81 |
82 | # respond to intial validation
83 | self.okButton.setEnabled(self.nameBox.isValid())
84 | self.updateButtons(self.nameBox.overwritingName())
85 |
86 | def definedName(self):
87 | return self.nameBox.definedName()
88 |
89 | def overwritingName(self):
90 | return self.nameBox.overwritingName()
91 |
92 | @pyqtSlot(bool)
93 | def updateButtons(self, overwriting):
94 | txt = "Overwrite" if overwriting else "OK"
95 | self.okButton.setText(txt)
96 | self.okButton.setDefault(not overwriting)
97 | self.cancelButton.setDefault(overwriting)
98 |
99 |
100 | class GSXmlNameDialog(GSNameDialog):
101 |
102 | def __init__(self, kind, **kwargs):
103 | unique = kwargs.get('unique', False)
104 | super(GSXmlNameDialog, self).__init__(
105 | boxtitle='GeoServer {0} name'.format(kind),
106 | boxmsg='Define unique {0}'.format(kind) +
107 | ' or overwrite existing' if not unique else '',
108 | name=xmlNameFixUp(kwargs.get('name', '')),
109 | namemsg=kwargs.get('namemsg', ''),
110 | nameregex=kwargs.get('nameregex', xmlNameRegex()),
111 | nameregexmsg=kwargs.get('nameregexmsg', xmlNameRegexMsg()),
112 | names=kwargs.get('names', None),
113 | unique=unique,
114 | maxlength=kwargs.get('maxlength', 0),
115 | parent=kwargs.get('parent', None))
116 |
117 |
118 | def getGSXmlName(kind, **kwargs):
119 | dlg = GSXmlNameDialog(kind=kind, **kwargs)
120 | QApplication.setOverrideCursor(QCursor(Qt.ArrowCursor))
121 | res = dlg.exec_()
122 | QApplication.restoreOverrideCursor()
123 | if res:
124 | return dlg.definedName()
125 | else:
126 | raise UserCanceledOperation()
127 |
128 |
129 | def getGSLayerName(**kwargs):
130 | return getGSXmlName('layer', **kwargs)
131 |
132 |
133 | def getGSStoreName(**kwargs):
134 | return getGSXmlName('data store', **kwargs)
135 |
136 |
137 | if __name__ == '__main__':
138 | from geoserverexplorer.gui.gsnameutils import \
139 | xmlNameFixUp, xmlNameRegex, xmlNameRegexMsg
140 | gdlg = GSNameDialog(
141 | boxtitle='GeoServer data store name',
142 | boxmsg='My groupbox message',
143 | namemsg='Sample is generated from PostgreSQL connection name.',
144 | # name=xmlNameFixUp('My PG connection'),
145 | name='name_one',
146 | nameregex=xmlNameRegex(),
147 | nameregexmsg=xmlNameRegexMsg(),
148 | names=['name_one', 'name_two'],
149 | unique=False,
150 | maxlength=10)
151 | gdlg.exec_()
152 | # fix_print_with_import
153 | print(gdlg.definedName())
154 | # fix_print_with_import
155 | print(gdlg.overwritingName())
156 | # and with no kwargs
157 | gdlg = GSNameDialog()
158 | gdlg.exec_()
159 | # fix_print_with_import
160 | print(gdlg.definedName())
161 | # fix_print_with_import
162 | print(gdlg.overwritingName())
163 | # gdlg.show()
164 | # gdlg.raise_()
165 | # gdlg.activateWindow()
166 | # sys.exit(APP.exec_())
167 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/dialogs/projectdialog.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from qgis.PyQt.QtGui import *
7 | from qgis.PyQt.QtWidgets import *
8 |
9 | class PublishProjectDialog(QDialog):
10 |
11 | def __init__(self, catalog, parent = None):
12 | super(PublishProjectDialog, self).__init__(parent)
13 | self.catalog = catalog
14 | self.workspace = None
15 | self.ok = False
16 | self.initGui()
17 |
18 |
19 | def initGui(self):
20 |
21 | layout = QVBoxLayout()
22 | self.setWindowTitle('Publish project')
23 |
24 | verticalLayout = QVBoxLayout()
25 | horizontalLayout = QHBoxLayout()
26 | horizontalLayout.setSpacing(30)
27 | horizontalLayout.setMargin(0)
28 | workspaceLabel = QLabel('Workspace')
29 | self.workspaceBox = QComboBox()
30 | self.workspaces = self.catalog.get_workspaces()
31 | try:
32 | defaultWorkspace = self.catalog.get_default_workspace()
33 | defaultWorkspace.fetch()
34 | defaultName = defaultWorkspace.dom.find('name').text
35 | except:
36 | defaultName = None
37 | workspaceNames = [w.name for w in self.workspaces]
38 | self.workspaceBox.addItems(workspaceNames)
39 | if defaultName is not None:
40 | self.workspaceBox.setCurrentIndex(workspaceNames.index(defaultName))
41 | horizontalLayout.addWidget(workspaceLabel)
42 | horizontalLayout.addWidget(self.workspaceBox)
43 | verticalLayout.addLayout(horizontalLayout)
44 |
45 | self.destGroupBox = QGroupBox()
46 | self.destGroupBox.setLayout(verticalLayout)
47 |
48 | verticalLayout = QVBoxLayout()
49 |
50 | horizontalLayout = QHBoxLayout()
51 | horizontalLayout.setSpacing(30)
52 | horizontalLayout.setMargin(0)
53 | groupLabel = QLabel('Global group name')
54 | self.groupNameBox = QLineEdit()
55 | self.groupNameBox.setPlaceholderText("[leave empty if no global group should be created]")
56 | horizontalLayout.addWidget(groupLabel)
57 | horizontalLayout.addWidget(self.groupNameBox)
58 | verticalLayout.addLayout(horizontalLayout)
59 |
60 | self.groupGroupBox = QGroupBox()
61 | self.groupGroupBox.setLayout(verticalLayout)
62 |
63 | layout.addWidget(self.destGroupBox)
64 | layout.addWidget(self.groupGroupBox)
65 |
66 | self.overwriteBox = QCheckBox()
67 | self.overwriteBox.setChecked(False)
68 | self.overwriteBox.setText("Overwrite without asking")
69 | layout.addWidget(self.overwriteBox)
70 |
71 | self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Close)
72 | layout.addWidget(self.buttonBox)
73 |
74 | self.setLayout(layout)
75 |
76 | self.buttonBox.accepted.connect(self.okPressed)
77 | self.buttonBox.rejected.connect(self.cancelPressed)
78 |
79 | self.resize(400,200)
80 |
81 |
82 | def okPressed(self):
83 | self.workspace = self.workspaces[self.workspaceBox.currentIndex()]
84 | self.overwrite = self.overwriteBox.isChecked()
85 | self.groupName = self.groupNameBox.text()
86 | if self.groupName.strip() == "":
87 | self.groupName = None
88 | self.ok = True
89 | self.close()
90 |
91 | def cancelPressed(self):
92 | self.ok = False
93 | self.workspace = None
94 | self.close()
95 |
96 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/dialogs/resources.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | ../../images/minus.png
4 | ../../images/plus.png
5 |
6 |
7 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/dialogs/sldeditor.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from qgis.PyQt.Qsci import QsciScintilla
7 | from qgis.PyQt.QtGui import *
8 | from qgis.PyQt.QtCore import *
9 | from qgis.PyQt.QtWidgets import *
10 | import xml.dom.minidom
11 |
12 |
13 | class SldEditorDialog(QDialog):
14 |
15 | def __init__(self, style, explorer, parent = None):
16 | super(SldEditorDialog, self).__init__(parent)
17 |
18 | self.style = style
19 | self.explorer = explorer
20 | self.initGui()
21 |
22 | def initGui(self):
23 | self.resize(600, 350)
24 | self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint |
25 | Qt.WindowMinMaxButtonsHint)
26 | self.setWindowTitle('Edit SLD style')
27 |
28 | layout = QVBoxLayout()
29 | buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
30 | sld = "\n".join([line for line in
31 | xml.dom.minidom.parseString(self.style.sld_body).toprettyxml().splitlines() if line.strip()])
32 | self.editor = SldEditorWidget(sld)
33 | layout.addWidget(self.editor)
34 | layout.addWidget(buttonBox)
35 | self.setLayout(layout)
36 |
37 | buttonBox.accepted.connect(self.okPressed)
38 | buttonBox.rejected.connect(self.cancelPressed)
39 |
40 | def okPressed(self):
41 | self.explorer.run(self.style.update_body, "Update SLD body", [], self.editor.text())
42 | self.close()
43 |
44 | def cancelPressed(self):
45 | self.close()
46 |
47 |
48 |
49 | class SldEditorWidget(QsciScintilla):
50 | ARROW_MARKER_NUM = 8
51 |
52 | def __init__(self, text, parent=None):
53 | super(SldEditorWidget, self).__init__(parent)
54 |
55 | font = QFont()
56 | font.setFamily('Courier')
57 | font.setFixedPitch(True)
58 | font.setPointSize(10)
59 | self.setFont(font)
60 | self.setMarginsFont(font)
61 |
62 | fontmetrics = QFontMetrics(font)
63 | self.setMarginsFont(font)
64 | self.setMarginWidth(0, fontmetrics.width("00000") + 6)
65 | self.setMarginLineNumbers(0, True)
66 | self.setMarginsBackgroundColor(QColor("#cccccc"))
67 |
68 | self.setBraceMatching(QsciScintilla.SloppyBraceMatch)
69 |
70 | self.setCaretLineVisible(True)
71 | self.setCaretLineBackgroundColor(QColor("#ffe4e4"))
72 |
73 | #lexer = QsciLexerXML()
74 | #lexer.setDefaultFont(font)
75 | #self.setLexer(lexer)
76 | self.SendScintilla(QsciScintilla.SCI_STYLESETFONT, 1, 'Courier'.encode())
77 |
78 | self.setText(text)
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/dialogs/workspacedialog.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from builtins import str
7 | from qgis.PyQt.QtGui import *
8 | from qgis.PyQt.QtWidgets import *
9 |
10 | APP = None
11 | if __name__ == '__main__':
12 | import sys
13 | # instantiate QApplication before importing QtGui subclasses
14 | APP = QApplication(sys.argv)
15 |
16 | from geoserverexplorer.gui.gsnameutils import GSNameWidget, xmlNameRegexMsg, xmlNameRegex
17 |
18 |
19 | class DefineWorkspaceDialog(QDialog):
20 |
21 | def __init__(self, workspaces=None, parent=None):
22 | super(DefineWorkspaceDialog, self).__init__(parent)
23 | self.workspaces = workspaces if workspaces is not None else []
24 | self.uri = None
25 | self.name = None
26 | self.initGui()
27 |
28 |
29 | def initGui(self):
30 | self.setWindowTitle('New workspace')
31 | verticalLayout = QVBoxLayout()
32 |
33 | horizontalLayout = QHBoxLayout()
34 | horizontalLayout.setSpacing(30)
35 | horizontalLayout.setMargin(0)
36 | nameLabel = QLabel('Workspace name')
37 | nameLabel.setMinimumWidth(150)
38 | self.nameBox = GSNameWidget(
39 | namemsg='',
40 | name='workspace',
41 | nameregex=xmlNameRegex(),
42 | nameregexmsg=xmlNameRegexMsg(),
43 | names=self.workspaces,
44 | unique=True,
45 | maxlength=10)
46 | self.nameBox.setMinimumWidth(250)
47 | horizontalLayout.addWidget(nameLabel)
48 | horizontalLayout.addWidget(self.nameBox)
49 | verticalLayout.addLayout(horizontalLayout)
50 |
51 | horizontalLayout = QHBoxLayout()
52 | horizontalLayout.setSpacing(30)
53 | horizontalLayout.setMargin(0)
54 | uriLabel = QLabel('URI')
55 | uriLabel.setMinimumWidth(150)
56 | self.uriBox = QLineEdit()
57 | self.uriBox.setText('')
58 | self.uriBox.setPlaceholderText('Required')
59 | self.uriBox.setMinimumWidth(250)
60 | horizontalLayout.addWidget(uriLabel)
61 | horizontalLayout.addWidget(self.uriBox)
62 | verticalLayout.addLayout(horizontalLayout)
63 |
64 | self.groupBox = QGroupBox()
65 | self.groupBox.setLayout(verticalLayout)
66 |
67 | layout = QVBoxLayout()
68 | layout.addWidget(self.groupBox)
69 | self.spacer = QSpacerItem(20,20, QSizePolicy.Minimum, QSizePolicy.Expanding)
70 | layout.addItem(self.spacer)
71 |
72 | self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
73 | self.okButton = self.buttonBox.button(QDialogButtonBox.Ok)
74 | layout.addWidget(self.buttonBox)
75 | self.setLayout(layout)
76 |
77 | self.buttonBox.accepted.connect(self.okPressed)
78 | self.buttonBox.rejected.connect(self.cancelPressed)
79 |
80 | self.nameBox.nameValidityChanged.connect(self.updateOkButton)
81 | self.uriBox.textChanged.connect(self.updateOkButton)
82 | self.updateOkButton()
83 |
84 | def getWorkspace(self):
85 | return self.workspace
86 |
87 | def updateOkButton(self):
88 | ok = self.nameBox.isValid() and self.uriBox.text() != ''
89 | self.okButton.setEnabled(ok)
90 |
91 | def okPressed(self):
92 | self.uri = str(self.uriBox.text())
93 | self.name = str(self.nameBox.definedName())
94 | self.close()
95 |
96 | def cancelPressed(self):
97 | self.uri = None
98 | self.name = None
99 | self.close()
100 |
101 | if __name__ == '__main__':
102 | wsdlg = DefineWorkspaceDialog(workspaces=['ws_one', 'ws_two'])
103 | wsdlg.exec_()
104 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/explorer.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from builtins import str
7 | import os
8 | from qgis.PyQt.QtGui import *
9 | from qgis.PyQt.QtCore import *
10 | from qgis.PyQt.QtWidgets import *
11 | import sip
12 | from qgis.core import *
13 | from qgis.gui import *
14 | from qgis.utils import iface
15 | from geoserverexplorer.geoserver import GeoserverException
16 | from geoserverexplorer.gui.exploreritems import *
17 | import traceback
18 | from geoserverexplorer.gui.explorertree import ExplorerTreeWidget
19 | from geoserverexplorer.qgis.utils import UserCanceledOperation
20 | from qgiscommons2.settings import pluginSetting
21 | from geoserver.catalog import FailedRequestError
22 | from geoserverexplorer.gui import setInfo, setWarning, setError
23 |
24 | class GeoServerExplorer(QDockWidget):
25 |
26 | def __init__(self, parent = None):
27 | super(GeoServerExplorer, self).__init__(parent)
28 | self.setObjectName('GeoServerExplorer')
29 | self.initGui()
30 |
31 | def initGui(self):
32 | self.progressMaximum = 0
33 | self.isProgressVisible = False
34 | self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
35 | self.dockWidgetContents = QWidget()
36 | self.setWindowTitle('GeoServer Explorer')
37 | self.splitter = QSplitter()
38 | self.splitter.setOrientation(Qt.Vertical)
39 | self.subwidget = QWidget()
40 | self.explorerTree = self.tree = ExplorerTreeWidget(self)
41 | showToolbar = pluginSetting("ShowToolbar")
42 | self.toolbar = QToolBar()
43 | self.toolbar.setToolButtonStyle(Qt.ToolButtonIconOnly)
44 | self.toolbar.setVisible(showToolbar)
45 | self.setToolbarActions([])
46 | self.splitter.addWidget(self.explorerTree)
47 | self.log = QTextEdit()
48 | self.description = QWidget()
49 | self.descriptionLayout = QVBoxLayout()
50 | self.descriptionLayout.setSpacing(2)
51 | self.descriptionLayout.setMargin(0)
52 | self.description.setLayout(self.descriptionLayout)
53 | self.splitter.addWidget(self.description)
54 | self.setDescriptionWidget()
55 | showDescription = pluginSetting("ShowDescription")
56 | self.description.setVisible(showDescription)
57 | self.progress = None
58 | self.layout = QVBoxLayout()
59 | self.layout.setSpacing(2)
60 | self.layout.setMargin(0)
61 | self.layout.addWidget(self.toolbar)
62 | self.layout.addWidget(self.splitter)
63 | self.dockWidgetContents.setLayout(self.layout)
64 | self.setWidget(self.dockWidgetContents)
65 |
66 | self.topLevelChanged.connect(self.dockStateChanged)
67 |
68 | def dockStateChanged(self, floating):
69 | if floating:
70 | self.resize(800, 450)
71 | self.splitter.setOrientation(Qt.Horizontal)
72 | else:
73 | self.splitter.setOrientation(Qt.Vertical)
74 |
75 | def setToolbarActions(self, actions):
76 | self.toolbar.clear()
77 | for action in actions:
78 | if action.icon().isNull():
79 | icon = QIcon(os.path.dirname(__file__) + "/../images/process.png")
80 | action.setIcon(icon)
81 |
82 | for action in actions:
83 | button = QPushButton()
84 | button.setIcon(action.icon())
85 | button.setToolTip(action.text())
86 | button.setEnabled(action.isEnabled())
87 | button.clicked.connect(action.trigger)
88 | self.toolbar.addWidget(button)
89 |
90 | self.toolbar.update()
91 |
92 | def refreshContent(self):
93 | showDescription = pluginSetting("ShowDescription")
94 | self.description.setVisible(showDescription)
95 | showToolbar = pluginSetting("ShowToolbar")
96 | self.toolbar.setVisible(showToolbar)
97 | self.refreshDescription()
98 |
99 | def catalogs(self):
100 | if self.explorerTree is None:
101 | return {}
102 | return self.explorerTree.gsItem._catalogs
103 |
104 | def run(self, command, msg, refresh, *params):
105 | noerror = True
106 | QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
107 | try:
108 | command(*params)
109 | for item in refresh:
110 | if item is not None:
111 | item.refreshContent(self)
112 | if None in refresh:
113 | self.refreshContent()
114 | if msg is not None and not self.isProgressVisible:
115 | setInfo("Operation " + msg + " correctly executed")
116 | except UserCanceledOperation:
117 | pass
118 | except Exception as e:
119 | if isinstance(e, FailedRequestError):
120 | setError("Error connecting to server (See log for more details)", traceback.format_exc())
121 | elif isinstance(e, GeoserverException):
122 | setError(str(e), e.details)
123 | else:
124 | setError(str(e) + " (See log for more details)", traceback.format_exc())
125 | noerror = False
126 | finally:
127 | QApplication.restoreOverrideCursor()
128 | self.refreshDescription()
129 |
130 | return noerror
131 |
132 | def resetActivity(self):
133 | if self.progress is not None:
134 | iface.messageBar().clearWidgets()
135 | self.isProgressVisible = False
136 | self.progress = None
137 | self.progressMaximum = 0
138 |
139 | def setProgress(self, value):
140 | if self.progress is not None and not sip.isdeleted(self.progress):
141 | self.progress.setValue(value)
142 |
143 | def setProgressMaximum(self, value, msg = ""):
144 | self.progressMaximum = value
145 | self.isProgressVisible = True
146 | self.progressMessageBar = iface.messageBar().createMessage(msg)
147 | self.progress = QProgressBar()
148 | self.progress.setMaximum(self.progressMaximum)
149 | self.progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
150 | self.progressMessageBar.layout().addWidget(self.progress)
151 | iface.messageBar().pushWidget(self.progressMessageBar, Qgis.Info)
152 |
153 | def setDescriptionWidget(self, widget = None):
154 | item = self.descriptionLayout.itemAt(0)
155 | if item:
156 | self.descriptionLayout.removeItem(item)
157 | item.widget().close()
158 | if widget is None:
159 | widget = QTextBrowser()
160 | widget.setHtml(u'Select an item above for contextual description
')
161 |
162 | self.descriptionLayout.addWidget(widget)
163 |
164 | def refreshDescription(self):
165 | item = self.explorerTree.lastClickedItem()
166 | if item is not None:
167 | try:
168 | self.explorerTree.treeItemClicked(item, 0)
169 | except:
170 | self.setDescriptionWidget(None)
171 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/exploreritems.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from geoserverexplorer.geoserver import util
7 | from qgis.PyQt import QtGui, QtCore, QtWidgets
8 |
9 | class TreeItem(QtWidgets.QTreeWidgetItem):
10 | def __init__(self, element, icon = None, text = None):
11 | QtWidgets.QTreeWidgetItem.__init__(self)
12 | self.element = element
13 | self.setData(0, QtCore.Qt.UserRole, element)
14 | self._text = text
15 | text = text if text is not None else util.name(element)
16 | self.setText(0, text)
17 | if icon is not None:
18 | self.setIcon(0, icon)
19 | self.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable)
20 |
21 | def refresh(self):
22 | text = self._text if self._text is not None else util.name(self.element)
23 | self.setText(0, text)
24 |
25 | def refreshContent(self, explorer):
26 | self.takeChildren()
27 | self.refresh()
28 | if hasattr(self, 'populate'):
29 | explorer.run(self.populate, None, [])
30 |
31 | def descriptionWidget(self, tree, explorer):
32 | text = self.getDescriptionHtml(tree, explorer)
33 | class MyBrowser(QtWidgets.QTextBrowser):
34 | def loadResource(self, type, name):
35 | return None
36 | self.description = MyBrowser()
37 | self.description.setOpenLinks(False)
38 | def linkClicked(url):
39 | self.linkClicked(tree, explorer, url)
40 | self.description.anchorClicked.connect(linkClicked)
41 | self.description.setHtml(text)
42 | return self.description
43 |
44 | def getDescriptionHtml(self, tree, explorer):
45 | typesok, html = self._checkAllSelectionTypes(self, tree)
46 | if typesok:
47 | html += self._getDescriptionHtml(tree, explorer)
48 | txt = self.text(0)
49 | items = tree.selectedItems()
50 | if len(items) > 1:
51 | txt = "Multiple Selection"
52 | img = ""
53 | if hasattr(self, "iconPath"):
54 | img = '
'
55 | header = u' ' + img + " " + txt + '
'
56 | html = u"""
57 |
58 |
59 |
60 |
73 |
74 |
75 | %s %s
76 |
77 |
78 | """ % (header, html)
79 | return html
80 |
81 | def _getDescriptionHtml(self, tree, explorer):
82 | html = ""
83 | typesok, typesmsg = self._checkAllSelectionTypes(self, tree)
84 | if not typesok:
85 | return typesmsg
86 | else:
87 | html += typesmsg
88 | actions = self.contextMenuActions(tree, explorer)
89 | items = tree.selectedItems()
90 | if len(items) > 1:
91 | actions = self.multipleSelectionContextMenuActions(
92 | tree, explorer, items)
93 | actsenabled = [act for act in actions if act.isEnabled()]
94 | if actsenabled:
95 | html += "Available actions
'
99 | return html
100 |
101 | def linkClicked(self, tree, explorer, url):
102 | actionName = url.toString()
103 | actions = self.contextMenuActions(tree, explorer)
104 | items = tree.selectedItems()
105 | if len(items) > 1:
106 | actions = self.multipleSelectionContextMenuActions(
107 | tree, explorer, items)
108 | for action in actions:
109 | if action.text() == actionName:
110 | action.trigger()
111 | return
112 |
113 | def _checkAllSelectionTypes(self, item, tree):
114 | allTypes, allParentTypes = tree.getSelectionTypes()
115 | if (allTypes and len(allTypes) != 1) or (allParentTypes and len(allParentTypes) != 1):
116 | return False, "Incompatible item types"
117 | items = tree.selectedItems()
118 | if len(items) > 1 and tree.currentItem() in items:
119 | return True, "Current item: {0}
".format(item.text(0))
120 | return True, ""
121 |
122 | def contextMenuActions(self, tree, explorer):
123 | return []
124 |
125 | def multipleSelectionContextMenuActions(self, tree, explorer, selected):
126 | return []
127 |
128 | def acceptDroppedItem(self, tree, explorer, item):
129 | return []
130 |
131 | def acceptDroppedItems(self, tree, explorer, items):
132 | if len(items) > 1:
133 | explorer.setProgressMaximum(len(items))
134 | toUpdate = []
135 | try:
136 | for i, item in enumerate(items):
137 | toUpdate.extend(self.acceptDroppedItem(tree, explorer, item))
138 | explorer.setProgress(i + 1)
139 | finally:
140 | explorer.resetActivity()
141 | return toUpdate
142 |
143 | def acceptDroppedUris(self, tree, explorer, uris):
144 | return []
145 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/extentpanel.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from builtins import str
7 | from geoserverexplorer.gui.rectangletool import RectangleMapTool
8 | from qgis.core import *
9 | from qgis.utils import iface
10 | from qgis.PyQt.QtGui import *
11 | from qgis.PyQt.QtWidgets import *
12 |
13 | class ExtentSelectionPanel(QWidget):
14 |
15 | def __init__(self, dialog):
16 | super(ExtentSelectionPanel, self).__init__(None)
17 | self.dialog = dialog
18 | self.horizontalLayout = QHBoxLayout(self)
19 | self.horizontalLayout.setSpacing(2)
20 | self.horizontalLayout.setMargin(0)
21 | self.text = QLineEdit()
22 | if hasattr(self.text, 'setPlaceholderText'):
23 | self.text.setPlaceholderText("[xmin,xmax,ymin,ymax] Leave blank to use full extent")
24 | self.horizontalLayout.addWidget(self.text)
25 | self.pushButton = QPushButton()
26 | self.pushButton.setText("Define in canvas")
27 | self.pushButton.clicked.connect(self.selectOnCanvas)
28 | self.horizontalLayout.addWidget(self.pushButton)
29 | self.setLayout(self.horizontalLayout)
30 | canvas = iface.mapCanvas()
31 | self.prevMapTool = canvas.mapTool()
32 | self.tool = RectangleMapTool(canvas)
33 | self.tool.rectangleCreated.connect(self.fillCoords)
34 |
35 | def selectOnCanvas(self):
36 | canvas = iface.mapCanvas()
37 | canvas.setMapTool(self.tool)
38 | self.dialog.showMinimized()
39 |
40 | def fillCoords(self):
41 | r = self.tool.rectangle()
42 | self.setValueFromRect(r)
43 |
44 | def setValueFromRect(self,r):
45 | s = str(r.xMinimum()) + "," + str(r.xMaximum()) + "," + str(r.yMinimum()) + "," + str(r.yMaximum())
46 | self.text.setText(s)
47 | self.tool.reset()
48 | canvas = iface.mapCanvas()
49 | canvas.setMapTool(self.prevMapTool)
50 | self.dialog.showNormal()
51 | self.dialog.raise_()
52 | self.dialog.activateWindow()
53 |
54 | def getValue(self):
55 | text = self.text.text().strip()
56 | if text == "":
57 | return None
58 | else:
59 | return text.split(",")
60 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/parametereditor.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from builtins import range
7 | from qgis.PyQt import QtCore, QtGui, QtWidgets
8 |
9 | class ParameterEditor(QtWidgets.QWidget):
10 | def __init__(self, settings, explorer):
11 | self.explorer = explorer
12 | self.settings = settings
13 | self.parameters = settings.settings()
14 | QtWidgets.QWidget.__init__(self)
15 | self.setupUi()
16 |
17 | def setupUi(self):
18 | layout = QtWidgets.QVBoxLayout()
19 | layout.setSpacing(2)
20 | layout.setMargin(0)
21 | self.tree = QtWidgets.QTreeWidget()
22 | self.tree.setAlternatingRowColors(True)
23 | self.tree.headerItem().setText(0, "Setting")
24 | self.tree.headerItem().setText(1, "Value")
25 | self.tree.setColumnWidth(0, 150)
26 | layout.addWidget(self.tree)
27 | for section in self.parameters:
28 | params = self.parameters[section]
29 | paramsItem = QtWidgets.QTreeWidgetItem()
30 | paramsItem.setText(0, section)
31 | for name, value in params:
32 | item = QtWidgets.QTreeWidgetItem()
33 | item.setText(0, name)
34 | item.setText(1, value)
35 | item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
36 | paramsItem.addChild(item)
37 | self.tree.addTopLevelItem(paramsItem)
38 | button = QtWidgets.QPushButton()
39 | button.setText("Save")
40 | button.clicked.connect(self.saveSettings)
41 | buttonBox = QtWidgets.QDialogButtonBox()
42 | buttonBox.setOrientation(QtCore.Qt.Horizontal)
43 | buttonBox.addButton(button, QtWidgets.QDialogButtonBox.ActionRole)
44 | layout.addWidget(buttonBox)
45 | self.setLayout(layout)
46 |
47 |
48 | def saveSettings(self):
49 | parameters = {}
50 | for i in range(self.tree.invisibleRootItem().childCount()):
51 | sectionItem = self.tree.invisibleRootItem().child(i)
52 | sectionParameters = []
53 | for j in range(sectionItem.childCount()):
54 | parameterItem = sectionItem.child(j)
55 | sectionParameters.append((parameterItem.text(0), parameterItem.text(1)))
56 | parameters[sectionItem.text(0)] = sectionParameters
57 | self.explorer.run(self.settings.update, "Update settings", [], parameters)
58 |
59 |
60 |
--------------------------------------------------------------------------------
/geoserverexplorer/gui/rectangletool.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from qgis.core import *
7 | from qgis.gui import *
8 | from qgis.PyQt import QtCore
9 |
10 | class RectangleMapTool(QgsMapToolEmitPoint):
11 |
12 | rectangleCreated = QtCore.pyqtSignal()
13 |
14 | def __init__(self, canvas):
15 | self.canvas = canvas
16 | QgsMapToolEmitPoint.__init__(self, self.canvas)
17 |
18 | self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
19 | self.rubberBand.setColor(QtCore.Qt.red )
20 | self.rubberBand.setWidth( 1 )
21 |
22 | self.reset()
23 |
24 | def reset(self):
25 | self.startPoint = self.endPoint = None
26 | self.isEmittingPoint = False
27 | self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)
28 |
29 | def canvasPressEvent(self, e):
30 | self.startPoint = self.toMapCoordinates( e.pos() )
31 | self.endPoint = self.startPoint
32 | self.isEmittingPoint = True
33 |
34 | self.showRect(self.startPoint, self.endPoint)
35 |
36 | def canvasReleaseEvent(self, e):
37 | self.isEmittingPoint = False
38 | if self.rectangle() != None:
39 | self.rectangleCreated.emit()
40 |
41 | def canvasMoveEvent(self, e):
42 | if not self.isEmittingPoint:
43 | return
44 |
45 | self.endPoint = self.toMapCoordinates( e.pos() )
46 | self.showRect(self.startPoint, self.endPoint)
47 |
48 | def showRect(self, startPoint, endPoint):
49 | self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)
50 | if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():
51 | return
52 |
53 | point1 = QgsPointXY(startPoint.x(), startPoint.y())
54 | point2 = QgsPointXY(startPoint.x(), endPoint.y())
55 | point3 = QgsPointXY(endPoint.x(), endPoint.y())
56 | point4 = QgsPointXY(endPoint.x(), startPoint.y())
57 |
58 | self.rubberBand.addPoint( point1, False )
59 | self.rubberBand.addPoint( point2, False )
60 | self.rubberBand.addPoint( point3, False )
61 | self.rubberBand.addPoint( point4, True ) # true to update canvas
62 | self.rubberBand.show()
63 |
64 | def rectangle(self):
65 | if self.startPoint == None or self.endPoint == None:
66 | return None
67 | elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y():
68 | return None
69 |
70 | return QgsRectangle(self.startPoint, self.endPoint)
71 |
72 | def setRectangle(self, rect):
73 | if rect == self.rectangle():
74 | return False
75 |
76 | if rect == None:
77 | self.reset()
78 | else:
79 | self.startPoint = QgsPointXY(rect.xMaximum(), rect.yMaximum())
80 | self.endPoint = QgsPointXY(rect.xMinimum(), rect.yMinimum())
81 | self.showRect(self.startPoint, self.endPoint)
82 | return True
83 |
84 | def deactivate(self):
85 | QgsMapTool.deactivate(self)
86 | self.deactivated.emit()
87 |
--------------------------------------------------------------------------------
/geoserverexplorer/images/add-page-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/add-page-blue.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/add-style-to-layer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/add-style-to-layer.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/add.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/bottom.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/browser.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/browser.gif
--------------------------------------------------------------------------------
/geoserverexplorer/images/browser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/browser.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/clean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/clean.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/config.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/create-store-from-layer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/create-store-from-layer.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/default-style.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/default-style.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/default-workspace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/default-workspace.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/delete.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/delete.gif
--------------------------------------------------------------------------------
/geoserverexplorer/images/desktop.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/geoserverexplorer/images/down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/down.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/edit.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/edit_sld.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/edit_sld.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/geonode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/geonode.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/geoserver.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/geoserver.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/geoserver_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/geoserver_gray.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/grid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/grid.jpg
--------------------------------------------------------------------------------
/geoserverexplorer/images/group.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/group.gif
--------------------------------------------------------------------------------
/geoserverexplorer/images/gwc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/gwc.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/help.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/import_into_qgis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/import_into_qgis.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/layer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/layer.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/layer_line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/layer_line.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/layer_point.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/layer_point.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/layer_polygon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/layer_polygon.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/layer_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/layer_unknown.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/new_table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/new_table.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/pencil.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/pencil.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/process.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/publish-to-geoserver.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/publish-to-geoserver.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/refresh.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/rename.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/rename.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/seed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/seed.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/sql_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/sql_window.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/style.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/style.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/table.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/top.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/tree.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/tree.gif
--------------------------------------------------------------------------------
/geoserverexplorer/images/up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/up.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/warning.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/warning32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/warning32.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/workspace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/workspace.png
--------------------------------------------------------------------------------
/geoserverexplorer/images/wrong.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/images/wrong.gif
--------------------------------------------------------------------------------
/geoserverexplorer/metadata.txt:
--------------------------------------------------------------------------------
1 | [general]
2 | name=GeoServer Explorer
3 | description=Configure and manage GeoServer from QGIS
4 | about=Easily configure GeoServer through QGIS. Prepare data and styling or publish directly to a catalog directly from the QGIS interface, or add a service from GeoServer into your QGIS project.
5 | category=Web
6 | qgisMinimumVersion=3.0
7 | version=1.0
8 |
9 | author=Boundless (Victor Olaya)
10 | email=info@boundlessgeo.com
11 |
12 | icon=images/desktop.svg
13 | tags=boundless,geoserver
14 |
15 | homepage=https://github.com/boundlessgeo/qgis-geoserver-plugin
16 | tracker=https://github.com/boundlessgeo/qgis-geoserver-plugin/issues
17 | repository=https://github.com/boundlessgeo/qgis-geoserver-plugin
18 |
19 | experimental=False
20 | deprecated=False
21 |
22 |
--------------------------------------------------------------------------------
/geoserverexplorer/plugin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 |
7 | from builtins import object
8 | import os
9 | from geoserverexplorer.gui.explorer import GeoServerExplorer
10 | from qgis.PyQt.QtGui import *
11 | from qgis.PyQt.QtCore import *
12 | from qgis.PyQt.QtWidgets import *
13 | from qgis import utils
14 | from qgis.core import QgsMessageLog
15 | from geoserverexplorer.qgis import layerwatcher
16 | from qgiscommons2.settings import pluginSetting, setPluginSetting, readSettings
17 | from qgiscommons2.gui import addHelpMenu, removeHelpMenu, addAboutMenu, removeAboutMenu
18 | from qgiscommons2.gui.settings import addSettingsMenu, removeSettingsMenu
19 |
20 | class GeoServerExplorerPlugin(object):
21 |
22 | def __init__(self, iface):
23 | self.iface = iface
24 | readSettings()
25 | try:
26 | from qgistester.tests import addTestModule
27 | from geoserverexplorer.test import testplugin
28 | addTestModule(testplugin, "GeoServer")
29 | except Exception as ex:
30 | pass
31 |
32 | def unload(self):
33 | self.explorer.deleteLater()
34 | removeSettingsMenu("GeoServer", self.iface.removePluginWebMenu)
35 | removeHelpMenu("GeoServer", self.iface.removePluginWebMenu)
36 | removeAboutMenu("GeoServer", self.iface.removePluginWebMenu)
37 | self.iface.removePluginWebMenu(u"GeoServer", self.explorerAction)
38 | layerwatcher.disconnectLayerWasAdded()
39 | try:
40 | from qgistester.tests import removeTestModule
41 | from geoserverexplorer.test import testplugin
42 | removeTestModule(testplugin, "GeoServer")
43 | except Exception as ex:
44 | pass
45 |
46 | def initGui(self):
47 | icon = QIcon(os.path.dirname(__file__) + "/images/geoserver.png")
48 | self.explorerAction = QAction(icon, "GeoServer Explorer", self.iface.mainWindow())
49 | self.explorerAction.triggered.connect(self.openExplorer)
50 | self.iface.addPluginToWebMenu(u"GeoServer", self.explorerAction)
51 |
52 | self.explorer = GeoServerExplorer()
53 | self.iface.addDockWidget(Qt.RightDockWidgetArea, self.explorer)
54 | if not pluginSetting("ExplorerVisible"):
55 | self.explorer.hide()
56 | self.explorer.visibilityChanged.connect(self._explorerVisibilityChanged)
57 |
58 | addSettingsMenu("GeoServer", self.iface.addPluginToWebMenu)
59 | addHelpMenu("GeoServer", self.iface.addPluginToWebMenu)
60 | addAboutMenu("GeoServer", self.iface.addPluginToWebMenu)
61 |
62 | layerwatcher.connectLayerWasAdded(self.explorer)
63 |
64 | def _explorerVisibilityChanged(self, visible):
65 | setPluginSetting("ExplorerVisible", visible)
66 |
67 | def openExplorer(self):
68 | self.explorer.show()
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/geoserverexplorer/qgis/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 |
--------------------------------------------------------------------------------
/geoserverexplorer/qgis/exporter.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | '''
7 | This module provides methods to export layers so they can be used as valid data
8 | for uploading to GeoServer.
9 | '''
10 |
11 | from builtins import str
12 | from qgis.core import *
13 | from geoserverexplorer.qgis import utils
14 | import os
15 | from qgis.PyQt import QtCore
16 | from qgis.utils import iface
17 | from qgis.gui import QgsMessageBar
18 | from qgiscommons2.files import tempFilenameInTempFolder
19 |
20 | def exportVectorLayer(layer):
21 | '''accepts a QgsVectorLayer or a string with a filepath'''
22 | settings = QtCore.QSettings()
23 | systemEncoding = settings.value( "/UI/encoding", "System" )
24 | if isinstance(layer, QgsMapLayer):
25 | filename = str(layer.source())
26 | destFilename = str(layer.name())
27 | else:
28 | filename = str(layer)
29 | destFilename = str(os.path.splitext(os.path.basename(filename))[0])
30 | if (not filename.lower().endswith("shp")):
31 | if not isinstance(layer, QgsMapLayer):
32 | layer = QgsVectorLayer(filename, "layer", "ogr")
33 | if not layer.isValid() or layer.type() != QgsMapLayer.VectorLayer:
34 | raise Exception ("Error reading file {} or it is not a valid vector layer file".format(filename))
35 | output = tempFilenameInTempFolder(destFilename + ".shp")
36 | QgsVectorFileWriter.writeAsVectorFormat(layer, output, systemEncoding, layer.crs(), "ESRI Shapefile")
37 | QgsMessageLog.logMessage("Layer '%s' had to be exported to shapefile for importing. Data might be lost." % layer.name(),
38 | level = Qgis.Warning)
39 | return output
40 | else:
41 | return filename
42 |
43 |
44 |
45 | def exportRasterLayer(layer):
46 | if (not str(layer.source()).lower().endswith("tif") ):
47 | filename = str(layer.name())
48 | output = tempFilenameInTempFolder(filename + ".tif")
49 | writer = QgsRasterFileWriter(output)
50 | writer.setOutputFormat("GTiff");
51 | writer.writeRaster(layer.pipe(), layer.width(), layer.height(), layer.extent(), layer.crs())
52 | del writer
53 | return output
54 | else:
55 | return str(layer.source())
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/geoserverexplorer/qgis/layers.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from qgis.core import *
7 |
8 | ALL_TYPES = -1
9 |
10 | class WrongLayerNameException(BaseException) :
11 | pass
12 |
13 | def resolveLayer(name):
14 | layers = getAllLayers()
15 | for layer in layers:
16 | if layer.name() == name:
17 | return layer
18 | raise WrongLayerNameException()
19 |
20 | def getPublishableLayers():
21 | layers = getAllLayers()
22 | return [layer for layer in layers if layer.dataProvider().name() != "wms"]
23 |
24 | def getAllLayers():
25 | return list(QgsProject.instance().mapLayers().values())
26 |
27 | def getAllLayersAsDict():
28 | return {layer.source(): layer for layer in getAllLayers()}
29 |
30 | def getPublishableLayersAsDict():
31 | return {layer.source(): layer for layer in getPublishableLayers()}
32 |
33 | def getGroups():
34 | groups = {}
35 | root = QgsProject.instance().layerTreeRoot()
36 | for child in root.children():
37 | if isinstance(child, QgsLayerTreeGroup):
38 | layers = []
39 | for subchild in child.children():
40 | if isinstance(subchild, QgsLayerTreeLayer):
41 | layers.append(subchild.layer())
42 | groups[child.name()] = layers
43 |
44 | return groups
45 |
46 | def layerFromUri(uri):
47 | allLayers = getAllLayers()
48 | source = uri.uri.split("|")[0]
49 | for layer in getAllLayers():
50 | if layer.source() == source and layer.name() == uri.name:
51 | return layer
52 |
53 |
--------------------------------------------------------------------------------
/geoserverexplorer/qgis/layerwatcher.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from geoserverexplorer.qgis.utils import isTrackedLayer
7 | from geoserverexplorer.qgis import uri as uri_utils
8 | from geoserverexplorer.qgis.sldadapter import adaptGsToQgs
9 | from qgis.core import *
10 | from qgis.gui import *
11 | from qgis.utils import iface
12 | from geoserverexplorer.qgis.utils import readTrackedLayers
13 | from functools import partial
14 | from qgis.PyQt import QtCore, QtGui, QtWidgets
15 | from geoserverexplorer.qgis.utils import getTrackingInfo, removeTrackedLayer
16 | from geoserver.catalog import Catalog
17 | from geoserverexplorer.qgis.catalog import CatalogWrapper
18 | from qgiscommons2.settings import pluginSetting
19 | from qgiscommons2.files import tempFilename
20 | from geoserverexplorer.gui import setInfo, setWarning, setError
21 |
22 | _explorer = None
23 |
24 | def layerAdded(qgislayer):
25 | try:
26 | if qgislayer.providerType().lower() != "wfs":
27 | return
28 | except:
29 | pass #Not all layers have a providerType method
30 | catalogs = list(_explorer.explorerTree.gsItem._catalogs.values())
31 | for cat in catalogs:
32 | if cat.layersEndpointUrl() in qgislayer.source():
33 | for layer in cat.get_layers():
34 | uri = uri_utils.layerUri(layer)
35 | if uri == qgislayer.source():
36 | try:
37 | sld = layer.default_style.sld_body.decode()
38 | sld = adaptGsToQgs(sld)
39 | sldfile = tempFilename("sld")
40 | with open(sldfile, 'w') as f:
41 | f.write(sld)
42 | msg, ok = qgislayer.loadSldStyle(sldfile)
43 | if not ok:
44 | raise Exception("Could not load style for layer %s" % qgislayer.name())
45 | qgislayer.styleChanged.connect(partial(updatePublishedStyle, qgislayer))
46 | except Exception as e:
47 | setWarning("Could not set style for layer %s" % qgislayer.name())
48 | return
49 |
50 |
51 | _currentMessageBarLayer = None
52 |
53 | def _resetCurrentMessageBarLayer():
54 | global _currentMessageBarLayer
55 | _currentMessageBarLayer = None
56 |
57 | def updatePublishedStyle(layer):
58 | global _currentMessageBarLayer
59 | track = pluginSetting("TrackLayers")
60 | if track and isTrackedLayer(layer):
61 | if iface.messageBar().currentItem() is None:
62 | _resetCurrentMessageBarLayer()
63 | if _currentMessageBarLayer != layer:
64 | _currentMessageBarLayer = layer
65 | widget = iface.messageBar().createMessage("",
66 | "This layer was uploaded to a geoserver catalog. Do you want to update the published style?")
67 | updateButton = QtWidgets.QPushButton(widget)
68 | updateButton.setText("Update")
69 | def updateStyle():
70 | url = getTrackingInfo(layer)
71 | catalog = Catalog(url)
72 | wrapper = CatalogWrapper(catalog)
73 | wrapper.publishStyle(layer)
74 | iface.messageBar().popWidget()
75 | _resetCurrentMessageBarLayer()
76 | updateButton.pressed.connect(updateStyle)
77 | widget.layout().addWidget(updateButton)
78 | stopTrackingButton = QtWidgets.QPushButton(widget)
79 | stopTrackingButton.setText("Stop tracking this layer")
80 | def stopTracking():
81 | removeTrackedLayer(layer)
82 | iface.messageBar().popWidget()
83 | _resetCurrentMessageBarLayer()
84 | stopTrackingButton.pressed.connect(stopTracking)
85 | widget.layout().addWidget(stopTrackingButton)
86 | iface.messageBar().pushWidget(widget, Qgis.Info)
87 | iface.messageBar().currentItem().geoserverLayer = layer
88 | #iface.messageBar().widgetRemoved.connect(_resetCurrentMessageBarLayer)
89 |
90 |
91 | def connectLayerWasAdded(explorer):
92 | global _explorer
93 | _explorer = explorer
94 | QgsProject.instance().layerWasAdded.connect(layerAdded)
95 | readTrackedLayers()
96 |
97 | def disconnectLayerWasAdded():
98 | QgsProject.instance().layerWasAdded.disconnect(layerAdded)
99 |
--------------------------------------------------------------------------------
/geoserverexplorer/qgis/uri.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 |
7 | import urllib.request, urllib.parse, urllib.error
8 | from qgis.core import *
9 | from geoserver.layer import Layer
10 | from geoserver.layergroup import LayerGroup
11 | from geoserverexplorer.geoserver.auth import AuthCatalog
12 |
13 |
14 | def addAuth(_params, catalog):
15 | if isinstance(catalog, AuthCatalog):
16 | _params['authcfg'] = catalog.authid
17 | else:
18 | _params['PASSWORD'] = catalog.password
19 | _params['USERNAME'] = catalog.username
20 |
21 | def layerUri(layer):
22 |
23 | def _get_namespaced_name(ws_name, layer_name):
24 | """Prefix ws name in case it is not already there"""
25 | if layer_name.find(':') != -1:
26 | return layer_name
27 | return ws_name + ":" + layer_name
28 |
29 | resource = layer.resource
30 | catalog = layer.catalog
31 | if resource.resource_type == 'featureType':
32 | params = {
33 | 'SERVICE': 'WFS',
34 | 'VERSION': '1.0.0',
35 | 'REQUEST': 'GetFeature',
36 | 'TYPENAME': _get_namespaced_name(resource.workspace.name, layer.name),
37 | 'SRSNAME': resource.projection,
38 | }
39 | addAuth(params, catalog)
40 | uri = layer.catalog.layersEndpointUrl() + '/wfs?' + urllib.parse.unquote(urllib.parse.urlencode(params))
41 | elif resource.resource_type == 'coverage':
42 | params = {
43 | 'identifier': _get_namespaced_name(resource.workspace.name, resource.name),
44 | 'format': 'GeoTIFF',
45 | 'url': layer.catalog.layersEndpointUrl() + '/wcs',
46 | 'cache': 'PreferNetwork'
47 | }
48 | addAuth(params, catalog)
49 | uri = urllib.parse.unquote(urllib.parse.urlencode(params))
50 | else:
51 | params = {
52 | 'layers': _get_namespaced_name(resource.workspace.name, resource.name),
53 | 'format': 'image/png',
54 | 'url': layer.catalog.layersEndpointUrl() + '/wms',
55 | 'styles': '',
56 | 'crs': resource.projection
57 | }
58 | addAuth(params, catalog)
59 | uri = urllib.parse.unquote(urllib.parse.urlencode(params))
60 |
61 | return uri
62 |
63 | def groupUri(group):
64 | params = {
65 | 'layers': group.name,
66 | 'format': 'image/png',
67 | 'url': group.catalog.layersEndpointUrl() + '/wms',
68 | 'styles': '',
69 | }
70 | addAuth(params, group.catalog)
71 | uri = urllib.parse.unquote(urllib.parse.urlencode(params))
72 | return uri
73 |
74 | def layerMimeUri(element):
75 | if isinstance(element, Layer):
76 | layer = element
77 | uri = layerUri(layer)
78 | resource = layer.resource
79 | if resource.resource_type == 'featureType':
80 | layertype = 'vector'
81 | provider = 'WFS'
82 | elif resource.resource_type == 'coverage':
83 | layertype = 'raster'
84 | provider = 'wcs'
85 | else:
86 | layertype = 'raster'
87 | provider = 'wms'
88 | escapedName = resource.title.replace( ":", "\\:" );
89 | escapedUri = uri.replace( ":", "\\:" );
90 | mimeUri = ':'.join([layertype, provider, escapedName, escapedUri])
91 | return mimeUri
92 | elif isinstance(element, LayerGroup):
93 | uri = groupUri(element)
94 | escapedName = resource.title.replace( ":", "\\:" );
95 | escapedUri = uri.replace( ":", "\\:" );
96 | mimeUri = ':'.join(["raster", "wms", escapedName, escapedUri])
97 | return mimeUri
98 |
--------------------------------------------------------------------------------
/geoserverexplorer/qgis/utils.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | import os
7 | import uuid
8 | import time
9 | from qgis.core import *
10 | from qgis.utils import *
11 | from qgis.PyQt.QtGui import *
12 | from qgis.PyQt.QtCore import *
13 | from qgis.PyQt.QtWidgets import *
14 |
15 | from geoserverexplorer.qgis import layers as qgislayers
16 | from geoserverexplorer.qgis import uri as uri_utils
17 | import json
18 |
19 | class UserCanceledOperation(Warning):
20 | pass
21 |
22 | def checkLayers():
23 | layers = qgislayers.getAllLayers()
24 | if len(layers) == 0:
25 | QMessageBox.warning(iface.mainWindow(), 'QGIS layers needed',
26 | "No suitable layers can be found in your current QGIS project.\n"
27 | "You must open the layers in QGIS to be able to work with them.",
28 | QMessageBox.Ok)
29 | return False
30 | return True
31 |
32 |
33 | def userFolder():
34 | folder = os.path.join(QgsApplication.qgisSettingsDirPath(), 'geoserver')
35 | try:
36 | os.mkdir(folder)
37 | except OSError:
38 | pass
39 | return folder
40 |
41 |
42 | def isWindows():
43 | return os.name == 'nt'
44 |
45 | tracked = []
46 |
47 | def formatSource(source):
48 | if isinstance(source, QgsRasterLayer):
49 | return None
50 | if isinstance(source, QgsVectorLayer):
51 | source = source.source()
52 | source = os.path.normcase(source)
53 |
54 | def addTrackedLayer(layer, catalogUrl):
55 | global tracked
56 | source = formatSource(layer.source())
57 | if getTrackingInfo(layer) is None:
58 | tracked.append([source, catalogUrl])
59 | saveTrackedLayers()
60 |
61 | def removeTrackedLayer(layer):
62 | global tracked
63 | source = formatSource(layer.source())
64 | for i, s in enumerate(tracked):
65 | if s[0] == source:
66 | del tracked[i]
67 | saveTrackedLayers()
68 | return
69 |
70 | def saveTrackedLayers():
71 | filename = os.path.join(userFolder(), "trackedlayers")
72 | with open(filename, "w") as f:
73 | f.write(json.dumps(tracked))
74 |
75 | def readTrackedLayers():
76 | try:
77 | global tracked
78 | filename = os.path.join(userFolder(), "trackedlayers")
79 | if os.path.exists(filename):
80 | with open(filename) as f:
81 | tracked = json.load(f)
82 | except:
83 | pass
84 |
85 | def isTrackedLayer(layer):
86 | return (formatSource(layer.source()) in [t[0] for t in tracked])
87 |
88 | def getTrackingInfo(layer):
89 | source = formatSource(layer.source())
90 | for obj in tracked:
91 | if obj[0] == source:
92 | return obj[1]
93 |
--------------------------------------------------------------------------------
/geoserverexplorer/resources/grayscale.sld:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | grayscale_raster
5 |
6 | Grayscale raster
7 |
8 |
9 | name
10 |
11 | Single symbol
12 |
13 | 1.0
14 |
15 |
16 | 1
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/geoserverexplorer/resources/rgb.sld:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | rgb_raster
5 |
6 | RGB raster
7 |
8 |
9 | name
10 |
11 | Single symbol
12 |
13 | 1.0
14 |
15 |
16 | 1
17 |
18 |
19 | 2
20 |
21 |
22 | 3
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/geoserverexplorer/settings.json:
--------------------------------------------------------------------------------
1 | [
2 | {"name":"ShowDescription",
3 | "label": "Show description panel",
4 | "description": "Show description panel",
5 | "type": "bool",
6 | "default": true,
7 | "group": "General"
8 | },
9 | {"name":"ConfirmDelete",
10 | "label": "Ask confirmation before deleting",
11 | "description": "Ask confirmation before deleting",
12 | "type": "bool",
13 | "default": true,
14 | "group": "General"
15 | },
16 | {"name":"ShowToolbar",
17 | "label": "Show toolbar",
18 | "description": "Show toolbar",
19 | "type": "bool",
20 | "default": false,
21 | "group": "General"
22 | },
23 | {"name":"SaveCatalogs",
24 | "label": "Keep a list of previous catalog connections",
25 | "description": "Keep a list of previous catalog connections",
26 | "type": "bool",
27 | "default": true,
28 | "group": "General"
29 | },
30 | {"name":"TrackLayers",
31 | "label": "Track layers and publish styles automatically",
32 | "description": "Track layers and publish styles automatically when they change",
33 | "type": "bool",
34 | "default": true,
35 | "group": "General"
36 | },
37 | {"name":"DeleteStyle",
38 | "label": "Delete style when deleting layer",
39 | "description": "Delete style when deleting layer",
40 | "type": "bool",
41 | "default": true,
42 | "group": "General"
43 | },
44 | {"name":"Recurse",
45 | "label": "Delete resource when deleting layer",
46 | "description": "Delete resource when deleting layer",
47 | "type": "bool",
48 | "default": true,
49 | "group": "General"
50 | },
51 | {"name":"OverwriteGroupLayers",
52 | "label": "Overwrite layers when uploading group",
53 | "description": "Overwrite layers when uploading group",
54 | "type": "bool",
55 | "default": true,
56 | "group": "General"
57 | },
58 | {"name":"AuthCatalogXMLCacheTime",
59 | "label": "AuthCatalog XML cache time in seconds",
60 | "description": "AuthCatalog XML cache time in seconds",
61 | "type": "number",
62 | "default": 180,
63 | "group": "General"
64 | },
65 | {"name":"SldUomManaging",
66 | "label": "QGIS manage SLD uom correctly",
67 | "description": "QGIS manage SLD uom correctly",
68 | "type": "bool",
69 | "default": true,
70 | "group": "General"
71 | },
72 | {"name":"SldScaleFactor",
73 | "label": "Size scale factor. !Unused if uom is managed!",
74 | "description": "Size scale factor. !Unused if uom is managed!",
75 | "type": "number",
76 | "default": 4,
77 | "group": "General"
78 | }
79 | ]
80 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/coveragerc:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | # .coveragerc to control coverage.py
7 | [report]
8 | exclude_lines =
9 | pragma: no cover
10 | if __name__ == '__main__':
11 | if __name__ == "__main__":
12 | ignore_errors = True
13 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/geo.dbf:
--------------------------------------------------------------------------------
1 | _) A GEOFORM C
Plain_311 Plain_411 Hill_211 Hill_112 Hill_411 Hill_311 Hill_312 Hill_411 Hill_312 Hill_111 Hill_211 Hill_112 Hill_212 Hill_112 Hill_111 Hill_411 Hill_311 Hill_212 Hill_111 Hill_112 Hill_312 Hill_312 Hill_211 Hill_312 Hill_411 Hill_212 Hill_112 Hill_112 Hill_112 Hill_111 Hill_311 Hill_111 Hill_312 Hill_312 Hill_112 ? Hill_111 Hill_411 Hill_111 Hill_311 Hill_411
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/geo.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/geo.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/geo.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/geo.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/geo.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/geo.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/land.dbf:
--------------------------------------------------------------------------------
1 | _ A LANDCOVER C
urban_areas agricultural_areas agricultural_areas fishponds fishponds grasslands_pastures natural_forest agricultural_areas natural_forest agricultural_areas agricultural_areas grasslands_pastures natural_forest agricultural_areas grasslands_pastures natural_forest grasslands_pastures grasslands_pastures natural_forest natural_forest grasslands_pastures urban_areas grasslands_pastures natural_forest
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/land.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/land.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/land.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/land.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/land.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/land.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_dem.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_dem.tif
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_dem.tif.aux.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 1212.428
6 | 2357.572
7 | 1000
8 | 0
9 | 0
10 | 1|0|0|1|0|0|0|1|0|0|0|2|2|0|0|1|0|2|2|0|1|1|3|0|3|3|0|1|2|1|0|2|3|1|2|3|2|2|5|5|3|1|3|1|0|5|1|1|2|5|3|6|5|3|3|3|0|2|3|7|2|4|4|5|7|6|3|3|4|3|5|9|9|3|3|11|0|10|1|12|3|5|2|4|5|4|18|6|8|4|7|6|4|20|4|2|3|4|4|4|14|7|6|7|2|7|5|8|4|5|3|9|7|6|14|4|5|5|2|5|10|8|7|5|12|2|7|12|8|6|8|6|4|7|8|7|5|5|9|4|11|13|7|7|8|5|7|10|12|12|16|6|10|8|10|16|10|13|12|5|6|9|24|6|10|13|8|9|10|14|13|12|4|16|10|9|30|5|11|8|14|9|9|19|10|13|11|9|9|25|18|8|8|14|11|14|18|11|9|8|11|16|10|22|7|14|17|12|14|8|23|7|13|14|9|11|13|31|6|14|13|13|15|12|30|13|10|11|13|13|12|32|19|16|11|17|14|12|36|12|8|15|21|15|14|34|18|21|11|19|11|29|13|20|19|18|23|15|32|19|13|15|16|17|19|36|26|16|17|13|14|12|33|13|22|12|22|16|11|36|20|12|17|14|19|14|39|17|14|19|17|18|14|38|11|16|15|14|20|18|38|18|17|24|16|15|14|38|18|30|20|18|22|29|18|15|19|19|22|23|47|23|21|15|22|26|21|43|27|27|23|23|17|26|47|28|22|22|17|29|17|37|24|28|18|31|22|20|46|17|12|24|22|28|18|51|27|23|21|20|20|26|42|25|22|20|29|19|24|42|21|25|26|23|23|47|27|22|19|30|22|23|44|31|30|23|23|27|29|40|21|20|29|29|20|30|54|24|23|25|25|25|24|60|23|23|21|25|25|36|48|31|27|20|31|34|31|47|26|31|23|29|27|32|52|27|26|34|33|38|20|64|26|36|29|38|24|63|35|31|31|32|25|32|59|25|27|32|24|37|24|64|21|36|31|26|31|31|46|22|29|30|35|30|44|73|29|29|37|41|27|26|78|26|33|28|27|26|46|70|28|28|24|41|35|25|56|28|25|28|21|31|32|71|18|29|32|38|32|66|36|27|28|28|36|30|69|30|35|35|40|31|29|61|26|26|22|31|29|26|71|34|22|30|24|39|25|51|25|33|29|28|30|30|49|20|25|28|29|36|29|58|20|31|20|29|31|23|61|18|23|40|27|25|27|55|29|27|32|42|27|26|53|25|35|30|31|35|69|28|35|25|23|46|20|47|31|19|31|30|27|28|50|57|37|49|42|36|21|59|34|28|30|21|36|23|51|26|21|26|14|30|31|45|23|14|21|20|19|16|46|24|17|28|22|20|12|34|35|25|14|18|16|16|48|24|17|24|18|14|34|18|21|18|17|27|19|48|19|11|19|24|11|21|45|19|21|20|19|19|21|33|18|13|17|24|14|15|32|25|17|14|21|18|14|33|17|17|17|17|22|24|37|20|16|24|26|19|22|35|19|23|19|20|25|22|46|20|18|11|13|20|48|13|17|27|15|20|17|36|21|13|18|20|23|11|39|10|15|19|26|14|20|24|13|9|23|18|17|16|32|18|19|18|18|18|14|28|30|16|29|10|20|17|33|14|18|16|13|18|20|47|26|14|25|18|14|22|47|24|15|21|20|16|36|21|29|26|19|32|25|51|21|39|31|26|27|36|51|28|28|21|26|22|27|55|22|40|71|16|18|24|34|23|19|21|18|18|22|30|21|22|15|21|19|18|41|19|15|25|18|18|19|39|16|18|23|25|15|17|59|30|29|29|24|37|49|25|24|22|30|28|31|53|33|22|19|34|30|31|55|19|17|18|26|31|28|46|23|11|25|16|25|25|52|26|16|25|34|24|18|59|19|27|25|27|20|22|37|26|19|15|23|25|21|41|7|15|15|13|11|15|20|9|11|9|10|9|22|16|8|9|12|16|6|24|16|9|8|7|10|12|19|13|9|6|13|7|7|16|7|12|9|5|7|7|16|7|7|6|9|7|8|15|5|5|6|5|9|9|10|9|8|2|7|7|2|21|2|5|5|4|7|5|10|4|6|6|3|6|9|2|5|2|3|9|3|5|4|4|4|6|4|3|7|2|5|1|3|0|10|6|2|3|1|2|1|0|9|4|3|6|3|1|2|2|4|2|0|3|3|2|3|1|0|1|0|2|2|2|0|1|2|0|1|1|1|0|1|1
11 |
12 |
13 |
14 | 2357
15 | 1821.8091628944
16 | 1213
17 | 244.4154810232
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_dem_exact.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_dem_exact.tif
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_dem_rbg.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_dem_rbg.tif
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_demascii.asc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_demascii.asc
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt1.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt1.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt1.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt1.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt1.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt1.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt2.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt2.dbf
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt2.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt2.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt2.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt2.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt2.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt2.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt3.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt3.dbf
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt3.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt3.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt3.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt3.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt3.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt3.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt4.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt4.dbf
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt4.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt4.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt4.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt4.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/qgis_plugin_test_pt4.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/qgis_plugin_test_pt4.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/graticule.dbf:
--------------------------------------------------------------------------------
1 | _d A n N
2 |
2 3 4 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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/graticule.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",
2 | DATUM["World Geodetic System 1984",
3 | SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]],
4 | AUTHORITY["EPSG","6326"]],
5 | PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]],
6 | UNIT["degree", 0.017453292519943295],
7 | AXIS["Geodetic longitude", EAST],
8 | AXIS["Geodetic latitude", NORTH],
9 | AUTHORITY["EPSG","4326"]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/graticule.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/graticule.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/graticule.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/graticule.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/graticule.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_lines.cpg:
--------------------------------------------------------------------------------
1 | UTF-8
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_lines.dbf:
--------------------------------------------------------------------------------
1 | v a [ id N
2 | label C P
**********Lorem ipsum dolor sit amet 2Lorem ipsum dolor sit amet 1Lorem ipsum dolor sit amet **********Lorem ipsum dolor sit amet
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_lines.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_lines.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_lines.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/irregular_lines.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_lines.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/irregular_lines.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_polygons.cpg:
--------------------------------------------------------------------------------
1 | UTF-8
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_polygons.dbf:
--------------------------------------------------------------------------------
1 | v a [ id N
2 | labels C P
1Lorem ipsum dolor 2Lorem ipsum dolor 3
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_polygons.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_polygons.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_polygons.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/irregular_polygons.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/irregular_polygons.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/irregular_polygons.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/lines.dbf:
--------------------------------------------------------------------------------
1 | v d A n N
2 |
2 3 4 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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/lines.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/lines.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/lines.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/lines.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/lines.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/lines.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/points.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/points.dbf
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/points.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/points.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/points.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/points.shp
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/points.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/points.shx
--------------------------------------------------------------------------------
/geoserverexplorer/test/data/symbology/qgis.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/geoserverexplorer/test/data/symbology/qgis.jpeg
--------------------------------------------------------------------------------
/geoserverexplorer/test/deletetests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from builtins import map
7 | import unittest
8 | import os
9 | import sys
10 | from qgis.PyQt.QtCore import *
11 | from qgis.core import *
12 | from qgis.utils import iface
13 | from geoserverexplorer.test.utils import PT1, safeName, PT2, WORKSPACE, WORKSPACEB, shapefile_and_friends
14 | from geoserverexplorer.test.integrationtest import ExplorerIntegrationTest
15 | from geoserverexplorer.qgis import layers
16 | from qgiscommons2.settings import pluginSetting, setPluginSetting
17 |
18 | class DeleteTests(ExplorerIntegrationTest):
19 |
20 | @classmethod
21 | def setUpClass(cls):
22 | # do workspace popuplation
23 | super(DeleteTests, cls).setUpClass()
24 |
25 | cls.ws = cls.cat.get_workspaces(WORKSPACE)[0]
26 |
27 | # load project
28 | projectFile = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "test.qgs")
29 | if os.path.normcase(projectFile) != os.path.normcase(QgsProject.instance().fileName()):
30 | iface.addProject(projectFile)
31 | # set flags to instruct GUI interaction
32 | cls.confirmDelete = pluginSetting("ConfirmDelete")
33 | setPluginSetting("ConfirmDelete", False)
34 |
35 | @classmethod
36 | def tearDownClass(cls):
37 | super(DeleteTests, cls).tearDownClass()
38 | setPluginSetting("ConfirmDelete", cls.confirmDelete)
39 |
40 | def testDeleteLayerAndStyle(self):
41 | # step 1: publish a layer. publish load layer and style
42 | self.catWrapper.publishLayer(PT1, self.ws, name=PT1)
43 | layer = self.cat.get_layer(PT1)
44 | self.assertIsNotNone(layer)
45 | style = self.cat.get_styles(PT1)[0]
46 | self.assertIsNotNone(style)
47 | self.getLayersItem().refreshContent(self.explorer)
48 | self.getStylesItem().refreshContent(self.explorer)
49 | # step 2: set flag to remove also style
50 | deleteStyle = pluginSetting("DeleteStyle")
51 | setPluginSetting("DeleteStyle", True)
52 | # step 3: then remove layer and style
53 | layerItem = self.getLayerItem(PT1)
54 | self.assertIsNotNone(layerItem)
55 | layerItem.deleteLayer(self.tree, self.explorer)
56 | layerItem = self.getLayerItem(PT1)
57 | self.assertIsNone(layerItem)
58 | styleItem = self.getStyleItem(PT1)
59 | self.assertIsNone(styleItem)
60 | # step 4: republish PT1 and it's style
61 | self.catWrapper.publishLayer(PT1)
62 | layer = self.cat.get_layer(PT1)
63 | self.assertIsNotNone(layer)
64 | style = self.cat.get_styles(PT1)[0]
65 | self.assertIsNotNone(style)
66 | self.getLayersItem().refreshContent(self.explorer)
67 | self.getStylesItem().refreshContent(self.explorer)
68 | # step 5: set flag to remove layer BUT not style
69 | setPluginSetting("DeleteStyle", False)
70 | # step 6: remove layer and check style is not erased
71 | layerItem = self.getLayerItem(PT1)
72 | layerItem.deleteLayer(self.tree, self.explorer)
73 | layerItem = self.getLayerItem(PT1)
74 | self.assertIsNone(layerItem)
75 | styleItem = self.getStyleItem(PT1)
76 | self.assertIsNotNone(styleItem)
77 | # step 7: then remove style
78 | styleItem.deleteStyle(self.tree, self.explorer)
79 | styleItem = self.getStyleItem(PT1)
80 | self.assertIsNone(styleItem)
81 | # step 8: set flag in original mode
82 | setPluginSetting("DeleteStyle", deleteStyle)
83 |
84 | def testDeleteLayersWithSameName(self):
85 | """
86 | Test that when there are more than one layer with
87 | the same name they can be deleted
88 | """
89 | wsb = self.catWrapper.catalog.get_workspaces(WORKSPACEB)[0]
90 |
91 | # Need to use prefixed names when retrieving
92 | pt1 = self.ws.name + ':' + PT1
93 | pt1b = wsb.name + ':' + PT1
94 | self.catWrapper.publishLayer(PT1, self.ws, name=PT1)
95 | self.assertIsNotNone(self.catWrapper.catalog.get_layer(pt1))
96 |
97 | # Add second layer with the same name
98 | self.catWrapper.publishLayer(PT1, wsb, name=PT1)
99 | self.assertIsNotNone(self.catWrapper.catalog.get_layer(pt1b))
100 |
101 | self.getLayersItem().refreshContent(self.explorer)
102 |
103 | # step 3: then remove layers
104 | layerItem = self.getLayerItem(pt1)
105 | self.assertIsNotNone(layerItem)
106 | layerItem.deleteLayer(self.tree, self.explorer)
107 | layerItem = self.getLayerItem(pt1)
108 | self.assertIsNone(layerItem)
109 |
110 | layerItem = self.getLayerItem(pt1b)
111 | self.assertIsNotNone(layerItem)
112 | layerItem.deleteLayer(self.tree, self.explorer)
113 | layerItem = self.getLayerItem(pt1b)
114 | self.assertIsNone(layerItem)
115 |
116 |
117 | def testDeleteWorkspace(self):
118 | wsname = safeName("another_workspace")
119 | self.cat.create_workspace(wsname, "http://anothertesturl.com")
120 | self.getWorkspacesItem().refreshContent(self.explorer)
121 | wsItem = self.getWorkspaceItem(wsname)
122 | wsItem.deleteWorkspace(self.tree, self.explorer)
123 | self.getWorkspacesItem().refreshContent(self.explorer)
124 | wsItem = self.getWorkspaceItem(wsname)
125 | self.assertIsNone(wsItem)
126 | ws = self.cat.get_workspaces(wsname)
127 | self.assertTrue(len(ws) == 0 )
128 |
129 |
130 | def testDeleteGWCLayer(self):
131 | name = WORKSPACE + ":" + PT2
132 | item = self.getGWCLayerItem(name)
133 | item.deleteLayer(self.explorer)
134 | item = self.getGWCLayerItem(name)
135 | self.assertIsNone(item)
136 |
137 |
138 | ##################################################################################################
139 |
140 | def suite():
141 | suite = unittest.makeSuite(DeleteTests, 'test')
142 | return suite
143 |
144 | # run all tests using unittest skipping nose or testplugin
145 | def run_all():
146 | # demo_test = unittest.TestLoader().loadTestsFromTestCase(DeleteTests)
147 | unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite())
148 |
149 | # run a subset of tests using unittest skipping nose or testplugin
150 | def run_subset():
151 | unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suiteSubset())
152 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/dragdroptests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from builtins import map
7 | import unittest
8 | import os
9 | import sys
10 | from geoserverexplorer.test.utils import PT1, WORKSPACE, WORKSPACEB, STYLE, PT2, PT3,\
11 | GROUP, GEOLOGY_GROUP, LANDUSE, GEOFORMS
12 | from geoserverexplorer.test.integrationtest import ExplorerIntegrationTest
13 | from geoserverexplorer.qgis import layers
14 |
15 | class DragDropTests(ExplorerIntegrationTest):
16 |
17 | #===========================================================================
18 | # Drag & drop URIs (i.e. from QGIS browser) to a Explorer tree item
19 | #===========================================================================
20 |
21 | def testDropVectorLayerUriInCatalogItem(self):
22 | uri = os.path.join(os.path.dirname(__file__), "data", PT1 + ".shp")
23 | self.catalogItem.acceptDroppedUris(self.tree, self.explorer, [uri])
24 | layer = self.cat.get_layer(PT1)
25 | self.assertIsNotNone(layer)
26 | self.cat.get_stores(PT1, WORKSPACE)[0]
27 | self.cat.delete(self.cat.get_layer(PT1), recurse = True)
28 | self.cat.delete(self.cat.get_styles(PT1)[0], purge = True)
29 |
30 | def testDropVectorLayerUriInWorkspaceItem(self):
31 | uri = os.path.join(os.path.dirname(__file__), "data", PT1 + ".shp")
32 | item = self.getWorkspaceItem(WORKSPACEB)
33 | self.assertIsNotNone(item)
34 | item.acceptDroppedUris(self.tree, self.explorer, [uri])
35 | layer = self.cat.get_layer(PT1)
36 | self.assertIsNotNone(layer)
37 | self.cat.get_stores(PT1, WORKSPACEB)[0]
38 | self.cat.delete(self.cat.get_layer(PT1), recurse = True)
39 | self.cat.delete(self.cat.get_styles(PT1)[0], purge = True)
40 |
41 | def testDropVectorLayerUriInLayersItem(self):
42 | uri = os.path.join(os.path.dirname(__file__), "data", PT1 + ".shp")
43 | item = self.getLayersItem()
44 | item.acceptDroppedUris(self.tree, self.explorer, [uri])
45 | layer = self.cat.get_layer(PT1)
46 | self.assertIsNotNone(layer)
47 | self.cat.get_stores(PT1, WORKSPACE)[0]
48 | self.cat.delete(self.cat.get_layer(PT1), recurse = True)
49 | self.cat.delete(self.cat.get_styles(PT1)[0], purge = True)
50 |
51 | #===========================================================================
52 | # Drag & drop explorer tree element(s) into another explorer tree element
53 | #===========================================================================
54 |
55 |
56 | def testDropGsStyleInGsLayerItem(self):
57 | styleItem = self.getStyleItem(STYLE)
58 | self.assertIsNotNone(styleItem)
59 | layerItem = self.getLayerItem(PT2)
60 | self.assertIsNotNone(layerItem)
61 | layerItem.acceptDroppedItems(self.tree, self.explorer, [styleItem])
62 | self.assertIsNotNone(self._getItemUnder(layerItem, STYLE))
63 |
64 | def testDropGsLayerInGsGroupItem(self):
65 | groupItem = self.getGroupItem(GROUP)
66 | childCount = groupItem.childCount()
67 | layerItem = self.getLayerItem(PT3)
68 | groupItem.acceptDroppedItems(self.tree, self.explorer, [layerItem])
69 | self.assertEquals(childCount + 1, groupItem.childCount())
70 |
71 |
72 | ##################################################################################################
73 |
74 | def suiteSubset():
75 | # set tests you want to execute adding in the following list
76 | tests = ['testDropVectorLayerUriInCatalogItem']
77 | suite = unittest.TestSuite(list(map(DragDropTests, tests)))
78 | return suite
79 |
80 | def suite():
81 | suite = unittest.TestSuite()
82 | suite.addTests(unittest.makeSuite(DragDropTests, 'test'))
83 | return suite
84 |
85 | # run all tests using unittest skipping nose or testplugin
86 | def run_all():
87 | unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite())
88 |
89 | # run a subset of tests using unittest skipping nose or testplugin
90 | def run_subset():
91 | unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suiteSubset())
92 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/functional.txt:
--------------------------------------------------------------------------------
1 | GEOSERVER
2 |
3 | CATALOG
4 | -Connect to catalog
5 | -Connect to catalog with wrong url or credentials: should show "could not connect to catalog" message in message bar
6 | -Check connections are persisted if corresponding option is enabled
7 | -Connect to previous workspace that is not enabled (icon is grayed-out)
8 | Check that clicking on the catalog item displays catalog info in the description panel
9 | -Remove catalog:
10 | -Check it removes it from the tree
11 | -Check that, when reopening the explorer, it is not in the list of previous catalogs
12 | -Check that, once deleted, the description panel is not available and the buttons corresponding to the dialog are not present in the toolbar
13 | -Dragging a layer from the QGIS browser into a catalog item should add the resource to the workspace and create a layer that publishes it
14 |
15 | WORKSPACE
16 | -Create new workspace
17 | -Create new worskpace with existing name: should show error message in message bar
18 | -Create new worskpace with wrong/missing uri: should show error message in message bar
19 | -Set workspace as default.
20 | -Check that "set as default workspace" is disabled for the current default workspace
21 | -Delete non-empty workspace:
22 | - Delete empty with all its datastores not used by any layer. It should be deleted without warning
23 | - Delete empty with at least a datastore used by a layer. It should show warning and clicking on ok should delete the workspace and the dependent layers
24 | -Delete empty workspace
25 | -Delete datastore that is used in a layer.
26 | -It should show a confirmation dialog saying that the layer will also be deleted.
27 | -Accept and check that both elements are deleted
28 | -Clean (remove unused stores) workspace:
29 | -Import a layer. It will create a store and a layer
30 | -Delete the layer, making sure that the option to delete the underlying resource is not enabled. That will leave an unused resource
31 | -Run the "Clean (remove unused elements)" option. That should delete the resource
32 | -Dragging a layer from the QGIS browser into a workspace item should add the resource to the workspace and create a layer that publishes it
33 |
34 | LAYER
35 | -Add style to layer
36 | -Add style to layer indicating that it should be considered as the default style
37 | -Make style default
38 | -Add style to layer dragging style item
39 | -Remove style from layer
40 | -Check that default style cannot be removed from layer (option should be disabled)
41 | -Delete layer
42 | -with "delete style" option enabled, check that the style is deleted if and only if no other layer uses that layer
43 | -with "delete resource" layer, check that it also deletes the resource
44 | -Modify layer info using the description panel
45 | -modify abstract
46 | -modify title
47 | -modify SRS
48 | -Add layer to QGIS project
49 | - Both for raster and vector layers
50 | - Both using the context menu action and dragging and dropping on the QGIS canvas
51 | -Dragging a layer from the QGIS browser into a layer item should add the resource to the default workspace and create a layer that publishes it
52 | -Dragging into the "GeoServer Layers" item should do the same.
53 |
54 | GROUPS
55 | -Create group by selecting several layers, right-clicking and using "create group"
56 | -check that it shows error on message bar if name is empty
57 | -Create group by using the "new group" option in the groups item
58 | -check that it shows error on message bar if name is empty
59 | -check that it shows error on message bar if no layer is selected (empty group)
60 | -check that no group is created if clicked on "cancel"
61 | -check that "(de)select option works fine"
62 | -check that when the dialog is opened layers have their default style selected
63 | -Delete group.
64 | -Delete layer that is used in a group.
65 | -It should show a confirmation dialog saying that the group will also be deleted.
66 | -Accept and check that both elements are deleted
67 | -Edit group:
68 | -check that previous layers are in the group definition
69 | -check that group layers have the corresponding style and that style is saved when closing
70 | -check that non-group layers have their default style selected
71 | -check that group is modified when closing
72 | -check that group is not modified if clicking "cancel"
73 | -Remove layer from group
74 | -Check that layer cannot be removed from group when only the group only contains one layer (cannot create empty group)
75 | -Change rendering order (up/down/to top/to bottom)
76 | -Edit group by dragging a layer item on group item
77 | -Edit group by dragging a layer item on a layer item under a group item (should add it to the parent group of the layer item)
78 |
79 |
80 | STYLES
81 | -Import style from style
82 | -check that no style is imported if clicking cancel on dialog
83 | -check that it uses QGIS layer name when name box is left empty
84 | -check that it uses entered name when name box is not empty
85 | -Import style by dragging a QGIS style item
86 | -Clean (remove unused styles):
87 | -Import a layer. It will create a style and a layer
88 | -Delete the layer, making sure that the option to delete the layer style is not enabled. That will leave an unused style
89 | -Run the "Clean (remove unused styles)" option. That should delete the style
90 | -Consolidate styles
91 | -Import several layers with the same style
92 | -Run "consolidate styles". It should leave only the first of those styles, delete the other ones, and use that first one in the layers that used the remaining ones
93 | -Edit style: Set the "prompt for CRS" option in the Options.../CRS group. When editing a stlye, it should not ask for the CRS but go directly to the styling dialog
94 | -Edit SLD
95 | -Delete style.
96 | -If style is used by layer, it should ask for confirmation and warn that the layer will also be deleted. Check that all layers using the style are deleted
97 |
98 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/integrationtest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from builtins import range
7 | import unittest
8 | from qgis.PyQt.QtCore import QSettings
9 | from geoserverexplorer.gui.explorer import GeoServerExplorer
10 | from geoserverexplorer.test import utils
11 | from geoserverexplorer.gui.gsexploreritems import GsCatalogItem
12 | import os
13 | from qgis.utils import iface
14 | from qgis.core import *
15 | from qgiscommons2.settings import pluginSetting, setPluginSetting
16 |
17 | class ExplorerIntegrationTest(unittest.TestCase):
18 |
19 | @classmethod
20 | def setUpClass(cls):
21 | cls.explorer = GeoServerExplorer()
22 | # Disable cache
23 | cls.cache_time = pluginSetting("AuthCatalogXMLCacheTime")
24 | setPluginSetting("AuthCatalogXMLCacheTime", 1)
25 | cls.catWrapper = utils.getGeoServerCatalog()
26 | cls.cat = cls.catWrapper.catalog
27 | utils.populateCatalog(cls.cat)
28 | cls.catalogItem = GsCatalogItem(cls.cat, "catalog")
29 | cls.explorer.explorerTree.gsItem.addChild(cls.catalogItem)
30 | cls.catalogItem.populate()
31 | cls.tree = cls.explorer.tree
32 | projectFile = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "test.qgs")
33 | iface.addProject(projectFile)
34 |
35 | @classmethod
36 | def tearDownClass(cls):
37 | utils.cleanCatalog(cls.cat)
38 | setPluginSetting("AuthCatalogXMLCacheTime", cls.cache_time)
39 |
40 | def _getItemUnder(self, parent, name):
41 |
42 | def _get_item(name, parent):
43 | for idx in range(parent.childCount()):
44 | item = parent.child(idx)
45 | try:
46 | if item.element.name == name:
47 | return item
48 | except:
49 | if item.text(0) == name:
50 | return item
51 | return None
52 |
53 | result = _get_item(name, parent)
54 | if result is None and name.find(':') != -1:
55 | result = _get_item(name.split(':')[1], parent)
56 | return result
57 |
58 | def getStoreItem(self, ws, name):
59 | return self._getItemUnder(self.getWorkspaceItem(ws), name)
60 |
61 | def getWorkspaceItem(self, name):
62 | return self._getItemUnder(self.getWorkspacesItem(), name)
63 |
64 | def getLayerItem(self, name):
65 | name = self.cat.get_namespaced_name(name)
66 | return self._getItemUnder(self.getLayersItem(), name)
67 |
68 | def getGroupItem(self, name):
69 | return self._getItemUnder(self.getGroupsItem(), name)
70 |
71 | def getStyleItem(self, name):
72 | return self._getItemUnder(self.getStylesItem(), name)
73 |
74 | def getWorkspacesItem(self):
75 | return self.catalogItem.child(0)
76 |
77 | def getLayersItem(self):
78 | return self.catalogItem.child(1)
79 |
80 | def getGroupsItem(self):
81 | return self.catalogItem.child(2)
82 |
83 | def getStylesItem(self):
84 | return self.catalogItem.child(3)
85 |
86 | def getGWCLayersItem(self):
87 | return self.catalogItem.child(4)
88 |
89 | def getGWCLayerItem(self, name):
90 | return self._getItemUnder(self.getGWCLayersItem(), name)
91 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/resources/font.sld:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | qgis_plugin_test_pt1
5 | qgis_plugin_test_pt1
6 |
7 |
8 | Single symbol
9 |
10 |
11 |
12 | ttf://DejaVu Sans#0x46
13 |
14 | #570cd7
15 |
16 |
17 | 7
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/resources/raster.sld:
--------------------------------------------------------------------------------
1 | qgis_plugin_test_demqgis_plugin_test_demname
--------------------------------------------------------------------------------
/geoserverexplorer/test/resources/vector.2.16.sld:
--------------------------------------------------------------------------------
1 |
2 |
3 | qgis_plugin_test_pt1
4 |
5 | qgis_plugin_test_pt1
6 |
7 | name
8 |
9 | 85.0000 - 116.8400
10 |
11 |
12 |
13 | VALUE
14 | 85
15 |
16 |
17 | VALUE
18 | 116.84
19 |
20 |
21 |
22 |
23 |
24 |
25 | circle
26 |
27 | #f1eef6
28 |
29 |
30 |
31 | 28.000000
32 |
33 |
34 |
35 |
36 | 116.8400 - 148.6800
37 |
38 |
39 |
40 | VALUE
41 | 116.84
42 |
43 |
44 | VALUE
45 | 148.68
46 |
47 |
48 |
49 |
50 |
51 |
52 | circle
53 |
54 | #bdc9e1
55 |
56 |
57 |
58 | 28.000000
59 |
60 |
61 |
62 |
63 | 148.6800 - 180.5200
64 |
65 |
66 |
67 | VALUE
68 | 148.68
69 |
70 |
71 | VALUE
72 | 180.52
73 |
74 |
75 |
76 |
77 |
78 |
79 | circle
80 |
81 | #74a9cf
82 |
83 |
84 |
85 | 28.000000
86 |
87 |
88 |
89 |
90 | 180.5200 - 212.3600
91 |
92 |
93 |
94 | VALUE
95 | 180.52
96 |
97 |
98 | VALUE
99 | 212.36
100 |
101 |
102 |
103 |
104 |
105 |
106 | circle
107 |
108 | #2b8cbe
109 |
110 |
111 |
112 | 28.000000
113 |
114 |
115 |
116 |
117 | 212.3600 - 244.2000
118 |
119 |
120 |
121 | VALUE
122 | 212.36
123 |
124 |
125 | VALUE
126 | 244.2
127 |
128 |
129 |
130 |
131 |
132 |
133 | circle
134 |
135 | #045a8d
136 |
137 |
138 |
139 | 28.000000
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/resources/vector.sld:
--------------------------------------------------------------------------------
1 |
2 |
3 | qgis_plugin_test_pt1
4 |
5 | qgis_plugin_test_pt1
6 |
7 | name
8 |
9 | 85.0000 - 116.8400
10 |
11 |
12 |
13 | VALUE
14 | 85
15 |
16 |
17 | VALUE
18 | 116.84
19 |
20 |
21 |
22 |
23 |
24 |
25 | circle
26 |
27 | #f1eef6
28 |
29 |
30 |
31 | 8.000000
32 |
33 |
34 |
35 |
36 | 116.8400 - 148.6800
37 |
38 |
39 |
40 | VALUE
41 | 116.84
42 |
43 |
44 | VALUE
45 | 148.68
46 |
47 |
48 |
49 |
50 |
51 |
52 | circle
53 |
54 | #bdc9e1
55 |
56 |
57 |
58 | 8.000000
59 |
60 |
61 |
62 |
63 | 148.6800 - 180.5200
64 |
65 |
66 |
67 | VALUE
68 | 148.68
69 |
70 |
71 | VALUE
72 | 180.52
73 |
74 |
75 |
76 |
77 |
78 |
79 | circle
80 |
81 | #74a9cf
82 |
83 |
84 |
85 | 8.000000
86 |
87 |
88 |
89 |
90 | 180.5200 - 212.3600
91 |
92 |
93 |
94 | VALUE
95 | 180.52
96 |
97 |
98 | VALUE
99 | 212.36
100 |
101 |
102 |
103 |
104 |
105 |
106 | circle
107 |
108 | #2b8cbe
109 |
110 |
111 |
112 | 8.000000
113 |
114 |
115 |
116 |
117 | 212.3600 - 244.2000
118 |
119 |
120 |
121 | VALUE
122 | 212.36
123 |
124 |
125 | VALUE
126 | 244.2
127 |
128 |
129 |
130 |
131 |
132 |
133 | circle
134 |
135 | #045a8d
136 |
137 |
138 |
139 | 8.000000
140 |
141 |
142 |
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/resources/vector_hook.py:
--------------------------------------------------------------------------------
1 | ##[Example scripts]=group
2 | ##input=vector
3 | ##output=output vector
4 |
5 | from qgis.core import *
6 | from processing.tools.vector import VectorWriter
7 |
8 | vectorLayer = processing.getObject(input)
9 |
10 | provider = vectorLayer.dataProvider()
11 |
12 | writer = VectorWriter(output, None, provider.fields(),
13 | provider.geometryType(), vectorLayer.crs())
14 |
15 | features = processing.features(vectorLayer)
16 |
17 | writer.addFeature(next(features.iter))
18 |
19 | del writer
20 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/symbologytests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | from builtins import map
7 | import unittest
8 | import os
9 | import sys
10 | from geoserverexplorer.qgis import layers, catalog
11 | from geoserverexplorer.qgis.sldadapter import adaptGsToQgs,\
12 | getGsCompatibleSld
13 | from qgis.core import *
14 | from qgis.utils import iface
15 | from qgis.PyQt.QtCore import *
16 | from geoserverexplorer.test import utils
17 | from geoserverexplorer.test.utils import PT1, DEM, DEM2, PT1JSON, DEMASCII,\
18 | GEOLOGY_GROUP, GEOFORMS, LANDUSE, HOOK, WORKSPACE, WORKSPACEB
19 | import re
20 |
21 | class SymbologyTests(unittest.TestCase):
22 | '''
23 | Tests for the CatalogWrapper class that provides additional capabilities to a gsconfig catalog
24 | Requires a Geoserver catalog running on localhost:8080 with default credentials
25 | '''
26 |
27 | @classmethod
28 | def setUpClass(cls):
29 | ''' 'test' workspace cannot exist in the test catalog'''
30 | cls.cat = utils.getGeoServerCatalog()
31 | utils.cleanCatalog(cls.cat.catalog)
32 | cls.cat.catalog.create_workspace(WORKSPACE, "http://geoserver.com")
33 | cls.ws = cls.cat.catalog.get_workspaces(WORKSPACE)[0]
34 | projectFile = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "test_font.qgs")
35 | iface.addProject(projectFile)
36 |
37 | @classmethod
38 | def tearDownClass(cls):
39 | utils.cleanCatalog(cls.cat.catalog)
40 |
41 | def testVectorFontStylingUpload(self):
42 | layer = layers.resolveLayer(PT1)
43 | sld, icons = getGsCompatibleSld(layer)
44 | self.assertTrue("ttf://DejaVu Sans#0x46" in sld)
45 |
46 | ##################################################################################################
47 |
48 |
49 | def suite():
50 | suite = unittest.makeSuite(SymbologyTests, 'test')
51 | return suite
52 |
53 | # run all tests using unittest skipping nose or testplugin
54 | def run_all():
55 | # demo_test = unittest.TestLoader().loadTestsFromTestCase(CatalogTests)
56 | unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite())
57 |
58 | # run a subset of tests using unittest skipping nose or testplugin
59 | def run_subset():
60 | unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suiteSubset())
61 |
--------------------------------------------------------------------------------
/geoserverexplorer/test/testplugin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # (c) 2016 Boundless, http://boundlessgeo.com
4 | # This code is licensed under the GPL 2.0 license.
5 | #
6 | import unittest
7 | import os
8 | import sys
9 | from functools import partial
10 | from geoserverexplorer.test import utils
11 | from geoserverexplorer.test.catalogtests import suiteAuth as catalogSuiteAuth
12 | from geoserverexplorer.test.catalogtests import suiteNoAuth as catalogSuiteNoAuth
13 | from geoserverexplorer.test.deletetests import suite as deleteSuite
14 | from geoserverexplorer.test.dragdroptests import suite as dragdropSuite
15 | from geoserverexplorer.test.guitests import suite as guiSuite
16 | from geoserverexplorer.test.symbologytests import suite as symbologySuite
17 |
18 | # Tests for the QGIS Tester plugin. To know more see
19 | # https://github.com/boundlessgeo/qgis-tester-plugin
20 |
21 | # Tests assume a Geoserver 2.8 instance at localhost:8080 or GSHOSTNAME:GSPORT
22 | # and default admin/geoserver credentials
23 |
24 | def functionalTests():
25 | try:
26 | from qgistester.test import Test
27 | except:
28 | return []
29 |
30 | allTests = []
31 | dragdropTest = Test("Verify dragging browser element into workspace")
32 | dragdropTest.addStep("Setting up catalog and explorer", utils.setUpCatalogAndExplorer)
33 | dragdropTest.addStep("Setting up test data project", utils.loadTestData)
34 | dragdropTest.addStep("Drag layer from browser 'Project home->qgis_plugin_test_pt1.shp' into\ntest_catalog->Workspaces->test_workspace")
35 | dragdropTest.addStep("Checking new layer", utils.checkNewLayer)
36 | dragdropTest.setCleanup(utils.clean)
37 |
38 | allTests.append(dragdropTest)
39 |
40 | for testProject in utils.testProjects():
41 | renderingTest = Test("Verify rendering of uploaded style (%s)" % os.path.basename(testProject))
42 | renderingTest.addStep("Preparing data", partial(utils.openAndUpload, testProject))
43 | renderingTest.addStep("Check that WMS layer is correctly rendered")
44 | renderingTest.setCleanup(utils.clean)
45 | allTests.append(renderingTest)
46 |
47 | return allTests
48 |
49 | def unitTests():
50 | _tests = []
51 | _tests.extend(catalogSuiteNoAuth())
52 | _tests.extend(catalogSuiteAuth())
53 | _tests.extend(deleteSuite())
54 | _tests.extend(dragdropSuite())
55 | _tests.extend(guiSuite())
56 | _tests.extend(symbologySuite())
57 | return _tests
58 |
59 | def settings():
60 | return {"GSHOSTNAME": utils.GSHOSTNAME,
61 | "GSPORT": utils.GSPORT,
62 | "GSUSER":utils.GSUSER,
63 | "GSPASSWORD":utils.GSPASSWORD}
64 |
65 | def runAllUnitTests():
66 | ''' run all unittests - No funcgtional test managed only by Tester Plugin '''
67 | suite = unittest.TestSuite()
68 | suite.addTest(catalogSuite())
69 | suite.addTest(deleteSuite())
70 | suite.addTest(dragdropSuite())
71 | suite.addTest(guiSuite())
72 | suite.addTest(symbologySuite())
73 | unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite)
74 |
--------------------------------------------------------------------------------
/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | pylint
2 | pep8
3 | autopep8
4 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # (c) 2016 Boundless, http://boundlessgeo.com
3 | # This code is licensed under the GPL 2.0 license.
4 | #
5 | python-dateutil
6 | requests==2.5.0
7 | qgiscommons
8 | httplib2
9 |
10 | # test requirements
11 |
12 |
13 |
--------------------------------------------------------------------------------
/rundockertests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Run docker tests on your local machine
3 |
4 | xhost +
5 |
6 | PLUGIN_NAME="geoserverexplorer"
7 | export QGIS_VERSION_TAG="master_2"
8 |
9 | docker-compose down -v
10 | docker-compose up -d
11 | sleep 10
12 |
13 | DOCKER_RUN_COMMAND="docker-compose exec qgis-testing-environment sh -c"
14 |
15 | # Setup
16 | $DOCKER_RUN_COMMAND "qgis_setup.sh $PLUGIN_NAME"
17 | $DOCKER_RUN_COMMAND "pip install paver"
18 | $DOCKER_RUN_COMMAND "cd /tests_directory && paver setup"
19 |
20 | # Run the tests
21 | $DOCKER_RUN_COMMAND "DISPLAY=:0 qgis_testrunner.sh geoserverexplorer.test.catalogtests"
22 | $DOCKER_RUN_COMMAND "qgis_testrunner.sh geoserverexplorer.test.deletetests"
23 | $DOCKER_RUN_COMMAND "qgis_testrunner.sh geoserverexplorer.test.guitests"
24 | $DOCKER_RUN_COMMAND "qgis_testrunner.sh geoserverexplorer.test.dragdroptests"
25 | $DOCKER_RUN_COMMAND "qgis_testrunner.sh geoserverexplorer.test.pkicatalogtests"
26 | $DOCKER_RUN_COMMAND "qgis_testrunner.sh geoserverexplorer.test.pkideletetests"
27 | $DOCKER_RUN_COMMAND "qgis_testrunner.sh geoserverexplorer.test.pkiguitests"
28 | $DOCKER_RUN_COMMAND "qgis_testrunner.sh geoserverexplorer.test.pkidragdroptests"
29 | $DOCKER_RUN_COMMAND "qgis_testrunner.sh geoserverexplorer.test.pkiowstests"
30 |
--------------------------------------------------------------------------------
/travis_secrets.tar.gz.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/planetfederal/qgis-geoserver-plugin/95e3fd13dbcbefce40d36a037bc3529678659450/travis_secrets.tar.gz.enc
--------------------------------------------------------------------------------