django-gisserver 1.5.0__tar.gz → 2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. {django_gisserver-1.5.0 → django_gisserver-2.1}/CHANGES.md +91 -0
  2. {django_gisserver-1.5.0/django_gisserver.egg-info → django_gisserver-2.1}/PKG-INFO +34 -8
  3. {django_gisserver-1.5.0 → django_gisserver-2.1}/README.md +10 -3
  4. {django_gisserver-1.5.0 → django_gisserver-2.1/django_gisserver.egg-info}/PKG-INFO +34 -8
  5. {django_gisserver-1.5.0 → django_gisserver-2.1}/django_gisserver.egg-info/SOURCES.txt +25 -11
  6. {django_gisserver-1.5.0 → django_gisserver-2.1}/django_gisserver.egg-info/requires.txt +7 -1
  7. django_gisserver-2.1/gisserver/__init__.py +1 -0
  8. django_gisserver-2.1/gisserver/compat.py +23 -0
  9. {django_gisserver-1.5.0 → django_gisserver-2.1}/gisserver/conf.py +7 -0
  10. django_gisserver-2.1/gisserver/crs.py +401 -0
  11. django_gisserver-2.1/gisserver/db.py +215 -0
  12. django_gisserver-2.1/gisserver/exceptions.py +294 -0
  13. django_gisserver-2.1/gisserver/extensions/__init__.py +4 -0
  14. {django_gisserver-1.5.0/gisserver/parsers/fes20 → django_gisserver-2.1/gisserver/extensions}/functions.py +131 -31
  15. django_gisserver-2.1/gisserver/extensions/queries.py +266 -0
  16. {django_gisserver-1.5.0 → django_gisserver-2.1}/gisserver/features.py +253 -181
  17. django_gisserver-2.1/gisserver/geometries.py +111 -0
  18. django_gisserver-2.1/gisserver/management/commands/loadgeojson.py +311 -0
  19. django_gisserver-2.1/gisserver/operations/__init__.py +0 -0
  20. django_gisserver-2.1/gisserver/operations/base.py +266 -0
  21. django_gisserver-2.1/gisserver/operations/wfs20.py +516 -0
  22. django_gisserver-2.1/gisserver/output/__init__.py +39 -0
  23. django_gisserver-2.1/gisserver/output/base.py +283 -0
  24. {django_gisserver-1.5.0 → django_gisserver-2.1}/gisserver/output/csv.py +78 -75
  25. {django_gisserver-1.5.0 → django_gisserver-2.1}/gisserver/output/geojson.py +37 -37
  26. {django_gisserver-1.5.0 → django_gisserver-2.1}/gisserver/output/gml32.py +287 -259
  27. django_gisserver-1.5.0/gisserver/output/utils.py → django_gisserver-2.1/gisserver/output/iters.py +30 -2
  28. {django_gisserver-1.5.0 → django_gisserver-2.1}/gisserver/output/results.py +73 -61
  29. django_gisserver-2.1/gisserver/output/stored.py +143 -0
  30. django_gisserver-2.1/gisserver/output/utils.py +91 -0
  31. django_gisserver-2.1/gisserver/output/xmlschema.py +161 -0
  32. django_gisserver-2.1/gisserver/parsers/__init__.py +13 -0
  33. django_gisserver-2.1/gisserver/parsers/ast.py +426 -0
  34. django_gisserver-2.1/gisserver/parsers/fes20/__init__.py +100 -0
  35. django_gisserver-2.1/gisserver/parsers/fes20/expressions.py +386 -0
  36. django_gisserver-2.1/gisserver/parsers/fes20/filters.py +168 -0
  37. django_gisserver-2.1/gisserver/parsers/fes20/identifiers.py +132 -0
  38. django_gisserver-2.1/gisserver/parsers/fes20/lookups.py +146 -0
  39. django_gisserver-2.1/gisserver/parsers/fes20/operators.py +924 -0
  40. django_gisserver-2.1/gisserver/parsers/fes20/sorting.py +154 -0
  41. django_gisserver-2.1/gisserver/parsers/gml/__init__.py +46 -0
  42. django_gisserver-2.1/gisserver/parsers/gml/base.py +58 -0
  43. django_gisserver-2.1/gisserver/parsers/gml/geometries.py +161 -0
  44. django_gisserver-2.1/gisserver/parsers/ows/__init__.py +25 -0
  45. django_gisserver-2.1/gisserver/parsers/ows/kvp.py +198 -0
  46. django_gisserver-2.1/gisserver/parsers/ows/requests.py +160 -0
  47. django_gisserver-2.1/gisserver/parsers/query.py +179 -0
  48. django_gisserver-2.1/gisserver/parsers/values.py +123 -0
  49. django_gisserver-2.1/gisserver/parsers/wfs20/__init__.py +39 -0
  50. django_gisserver-2.1/gisserver/parsers/wfs20/adhoc.py +253 -0
  51. django_gisserver-2.1/gisserver/parsers/wfs20/base.py +148 -0
  52. django_gisserver-2.1/gisserver/parsers/wfs20/projection.py +103 -0
  53. django_gisserver-2.1/gisserver/parsers/wfs20/requests.py +483 -0
  54. django_gisserver-2.1/gisserver/parsers/wfs20/stored.py +193 -0
  55. django_gisserver-2.1/gisserver/parsers/xml.py +261 -0
  56. django_gisserver-2.1/gisserver/projection.py +367 -0
  57. django_gisserver-2.1/gisserver/static/gisserver/index.css +20 -0
  58. django_gisserver-2.1/gisserver/templates/gisserver/base.html +12 -0
  59. django_gisserver-2.1/gisserver/templates/gisserver/index.html +20 -0
  60. django_gisserver-2.1/gisserver/templates/gisserver/service_description.html +22 -0
  61. {django_gisserver-1.5.0 → django_gisserver-2.1}/gisserver/templates/gisserver/wfs/2.0.0/get_capabilities.xml +9 -9
  62. django_gisserver-2.1/gisserver/templates/gisserver/wfs/feature_field.html +10 -0
  63. django_gisserver-2.1/gisserver/templates/gisserver/wfs/feature_type.html +45 -0
  64. django_gisserver-2.1/gisserver/templatetags/__init__.py +0 -0
  65. django_gisserver-2.1/gisserver/templatetags/gisserver_tags.py +30 -0
  66. {django_gisserver-1.5.0 → django_gisserver-2.1}/gisserver/types.py +445 -313
  67. django_gisserver-2.1/gisserver/views.py +489 -0
  68. {django_gisserver-1.5.0 → django_gisserver-2.1}/pyproject.toml +4 -3
  69. {django_gisserver-1.5.0 → django_gisserver-2.1}/setup.py +12 -4
  70. django_gisserver-1.5.0/gisserver/__init__.py +0 -1
  71. django_gisserver-1.5.0/gisserver/db.py +0 -140
  72. django_gisserver-1.5.0/gisserver/exceptions.py +0 -166
  73. django_gisserver-1.5.0/gisserver/geometries.py +0 -358
  74. django_gisserver-1.5.0/gisserver/operations/base.py +0 -448
  75. django_gisserver-1.5.0/gisserver/operations/wfs20.py +0 -492
  76. django_gisserver-1.5.0/gisserver/output/__init__.py +0 -74
  77. django_gisserver-1.5.0/gisserver/output/base.py +0 -229
  78. django_gisserver-1.5.0/gisserver/output/xmlschema.py +0 -122
  79. django_gisserver-1.5.0/gisserver/parsers/__init__.py +0 -13
  80. django_gisserver-1.5.0/gisserver/parsers/base.py +0 -149
  81. django_gisserver-1.5.0/gisserver/parsers/fes20/__init__.py +0 -42
  82. django_gisserver-1.5.0/gisserver/parsers/fes20/expressions.py +0 -272
  83. django_gisserver-1.5.0/gisserver/parsers/fes20/filters.py +0 -97
  84. django_gisserver-1.5.0/gisserver/parsers/fes20/identifiers.py +0 -94
  85. django_gisserver-1.5.0/gisserver/parsers/fes20/operators.py +0 -668
  86. django_gisserver-1.5.0/gisserver/parsers/fes20/query.py +0 -285
  87. django_gisserver-1.5.0/gisserver/parsers/fes20/sorting.py +0 -75
  88. django_gisserver-1.5.0/gisserver/parsers/gml/__init__.py +0 -54
  89. django_gisserver-1.5.0/gisserver/parsers/gml/base.py +0 -37
  90. django_gisserver-1.5.0/gisserver/parsers/gml/geometries.py +0 -100
  91. django_gisserver-1.5.0/gisserver/parsers/tags.py +0 -102
  92. django_gisserver-1.5.0/gisserver/parsers/values.py +0 -40
  93. django_gisserver-1.5.0/gisserver/queries/__init__.py +0 -37
  94. django_gisserver-1.5.0/gisserver/queries/adhoc.py +0 -185
  95. django_gisserver-1.5.0/gisserver/queries/base.py +0 -186
  96. django_gisserver-1.5.0/gisserver/queries/projection.py +0 -240
  97. django_gisserver-1.5.0/gisserver/queries/stored.py +0 -206
  98. django_gisserver-1.5.0/gisserver/static/gisserver/index.css +0 -4
  99. django_gisserver-1.5.0/gisserver/templates/gisserver/index.html +0 -26
  100. django_gisserver-1.5.0/gisserver/templates/gisserver/service_description.html +0 -16
  101. django_gisserver-1.5.0/gisserver/templates/gisserver/wfs/2.0.0/describe_stored_queries.xml +0 -20
  102. django_gisserver-1.5.0/gisserver/templates/gisserver/wfs/2.0.0/list_stored_queries.xml +0 -14
  103. django_gisserver-1.5.0/gisserver/templates/gisserver/wfs/feature_field.html +0 -10
  104. django_gisserver-1.5.0/gisserver/templates/gisserver/wfs/feature_type.html +0 -23
  105. django_gisserver-1.5.0/gisserver/templatetags/gisserver_tags.py +0 -10
  106. django_gisserver-1.5.0/gisserver/views.py +0 -324
  107. {django_gisserver-1.5.0 → django_gisserver-2.1}/LICENSE +0 -0
  108. {django_gisserver-1.5.0 → django_gisserver-2.1}/MANIFEST.in +0 -0
  109. {django_gisserver-1.5.0 → django_gisserver-2.1}/django_gisserver.egg-info/dependency_links.txt +0 -0
  110. {django_gisserver-1.5.0 → django_gisserver-2.1}/django_gisserver.egg-info/not-zip-safe +0 -0
  111. {django_gisserver-1.5.0 → django_gisserver-2.1}/django_gisserver.egg-info/top_level.txt +0 -0
  112. {django_gisserver-1.5.0/gisserver/operations → django_gisserver-2.1/gisserver/management}/__init__.py +0 -0
  113. {django_gisserver-1.5.0/gisserver/templatetags → django_gisserver-2.1/gisserver/management/commands}/__init__.py +0 -0
  114. {django_gisserver-1.5.0 → django_gisserver-2.1}/setup.cfg +0 -0
@@ -1,10 +1,101 @@
1
+ # 2025-05-29 (2.1)
2
+
3
+ * Added support for `ArrayField` field in CSV exports.
4
+ * Added support for `models.DurationField` for features.
5
+ * Added proper axis ordering handling.
6
+ * Changed built-in fes functions to match current GeoServer signatures.
7
+ * Improved error handling for invalid filter input (also fixes 500 errors).
8
+ * Improved error handling for database query errors during rendering.
9
+ * Improved error messages for unexpected tags in the XML body.
10
+ * Improved error handling for fes 1.0 arithmetic operators (e.g. typing: `date > 2020-01-01` in QGis).
11
+ * Improved HTML index page, make it easier to override and restyle.
12
+ * Improved documentation, added API documentation.
13
+ * Fixed axis ordering handling for `EPSG:4326` and other longitude/latitude CRS definitions.
14
+ * Fixed comparing to `NULL` when date/time input is invalid.
15
+ * Fixed filter comparisons for `<`, `<=`, `>`, `>=` when using a reversed "value < property" ordering.
16
+ * Fixed crash when receiving WFS 1.0 POST requests.
17
+ * Fixed building readthedocs.
18
+
19
+
20
+ # 2025-04-28 (2.0)
21
+
22
+ * Added support for XML POST requests.
23
+ * Added support for geometry elements on child nodes.
24
+ * Added support for Django 5 `GeneratedField` fields as geometry field.
25
+ * Added `WFSView.check_permissions()` API to simplify permission checking.
26
+ * Added `WFSView.xml_namespace_aliases` attribute to configure custom namespace prefixes.
27
+ * Added example app and docker-compose setup for testing.
28
+ * Added `GISSERVER_EXTRA_OUTPUT_FORMATS` setting to define additional output formats.
29
+ * Added `GISSERVER_GET_FEATURE_OUTPUT_FORMATS` setting to override the default output formats.
30
+ * Added `CRS84` and `WEB_MERCATOR` constants in `gisserver.geometries`.
31
+ * Improved debugging by adding debug-level logging and better error messages.
32
+ * Improved font styling somewhat for browsable HTML pages.
33
+ * Fixed XML namespace support (e.g. handling `<ValueReference>ns0:tagname</ValueReference>`).
34
+ * Fixed bugs found by CITE compliance testing:
35
+ * Support `<fes:PropertyIsLike>` for array elements.
36
+ * Support `<fes:PropertyIsNil>` for geometry elements.
37
+ * Support `resulttype=hits` with `count` arguments.
38
+ * Fixed `ArrayField` detection when `django.contrib.postgres` is not in `INSTALLED_APPS`.
39
+ * Fixed `main_geometry_element` detection.
40
+ * Fixed swapped X/Y coordinates for systems that use a different axis-ordering (e.g. EPSG:3879 for Finland).
41
+ * Fixed GeoJSON CRS value to be `CRS84` (urn:ogc:def:crs:OGC::CRS84) instead of WGS84 (urn:ogc:def:crs:EPSG::4326).
42
+ * Fixed applying the `CRS.backend` when the client requests a custom coordinate system using `srsName`.
43
+ * Fixed rendering JSON exceptions during streaming errors.
44
+ * Fixed internal XML Schema; use proper model CamelCasing for class names (doesn't affect requests).
45
+ * Fixed internal XML schema; remove unneeded inheritance from `gml:AbstractFeatureType` for nested elements.
46
+ * Fixed CI testing.
47
+ * Confirmed support for Python 3.13.
48
+
49
+ This release has a lot of API changes, renamed and moved classes,
50
+ which was needed to implement POST support and XML namespace handling.
51
+
52
+ This won't affect most projects as they use the basic `FeatureType` functionality.
53
+ For implementations that have taken full advantage of our architecture,
54
+ the notable API changes are:
55
+
56
+ * Configuration:
57
+ * `WFSOperation.output_formats` still works, but `get_output_formats()` is preferred.
58
+ * `WFSOperation.parameters` is replaced by ``get_parameters()`` and only lists parameters that need to be mentioned in `GetCapabilities`.
59
+ * The `Parameter` class only exposes choices, parsing happens in `gisserver.parsers.wfs20` now.
60
+ * `FeatureType.xml_namespace` now defines which namespace the feature exists in (defaults to `WFSView.xml_namespace`).
61
+ * Overiding and extending queries:
62
+ * `FeatureType.get_extent()` was replaced with ``GmlBoundedByElement.get_value()``.
63
+ * `gisserver.operations`: renamed `WFSMethod` -> `WFSOperation`.
64
+ * `gisserver.extensions.functions` now tracks filter function registration.
65
+ * `gisserver.extensions.queries` now tracks stored query registration.
66
+ * The `StoredQuery` base class is now `StoredQueryImplementation` providing a `build_query()` method.
67
+ * The internal `CompiledQuery` moved to `gisserver.parsers.query` and receives a `feature_types` array now with a single element.
68
+ (This change reflects the WFS spec and allowing to potentially implement JOIN queries later).
69
+ * Request parsing:
70
+ * `WFSView.ows_request` and `request.ows_request` both provide access to the parsed WFS request.
71
+ * `WFSOperation.parser_class` allows to define a custom parser for a additional WFS operations.
72
+ * The WFS request parsing moved to `gisserver.parsers.wfs20`, which builds an Abstract Syntax Tree (AST) of the XML request.
73
+ * The GET request (KVP format) parsing is now a special-case of the XML-based parsing classes.
74
+ * Output formats:
75
+ * `gisserver.output` no longer exposes the auto-switching DB/non-DB rendering aliases, as `get_output_formats()` can do that easier.
76
+ * `OutputRenderer` only provides the basic XML aliasing, a new `CollectionOutputRenderer` base class provides the collection logic.
77
+ * `OutputRenderer.xml_namespaces` allows defining XML namespace aliases that construct default `xmlns` attributes.
78
+ * All rendering parameters (e.g. output CRS) moved to the `FeatureProjection` logic.
79
+ * The `decorate_queryset()` logic is no longer a classmethod.
80
+ * Internal XSD schema elements:
81
+ * XML tag parsing is reworked for simplicity and namespace handling.
82
+ * Namespace aliases/prefixes are removed entirely, and resolved during rendering.
83
+ * `FeatureType.xml_name` now returns the full XML name, not the QName.
84
+ * `XsdTypes` use fully qualified XML names, not the QName.
85
+ * `XsdElement.xml_name` now returns the full XML name, not the QName.
86
+ * `XsdElement.is_geometry` was unneeded, use `XsdElement.type.is_geometry` now.
87
+ * `XsdElement.orm_path` points to the absolute path, and `XsdElement.local_orm_path` to the relative path.
88
+
89
+
1
90
  # 2024-11-25 (1.5.0)
2
91
 
3
92
  * Added `PROPERTYNAME` support
4
93
  * Added rendering of `<wfs:truncatedResponse>` when errors happen during output streaming.
94
+ * Fixed accessing a feature with 3 geometry fields (fixed our PostgreSQL `ST_Union` syntax).
5
95
  * Make sure Django 4.1+ won't do double prefetches on relations that we prefetch.
6
96
  * Hide the erroneous output formats in `GetCapabilities` that are supported for FME.
7
97
  * Bump requirements to non-vulnerable versions (of lxml and orjson).
98
+ * Improved documentation.
8
99
  * Cleaned up code, removing some internal methods.
9
100
  * Cleaned up leftover Python 3.7 compat code.
10
101
 
@@ -1,12 +1,12 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: django-gisserver
3
- Version: 1.5.0
3
+ Version: 2.1
4
4
  Summary: Django speaking WFS 2.0 (exposing GeoDjango model fields)
5
5
  Home-page: https://github.com/amsterdam/django-gisserver
6
6
  Author: Diederik van der Boor
7
7
  Author-email: opensource@edoburu.nl
8
8
  License: Mozilla Public License 2.0
9
- Classifier: Development Status :: 4 - Beta
9
+ Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Environment :: Web Environment
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.9
16
16
  Classifier: Programming Language :: Python :: 3.10
17
17
  Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
19
20
  Classifier: Framework :: Django
20
21
  Classifier: Framework :: Django :: 3.2
21
22
  Classifier: Framework :: Django :: 4.0
@@ -27,13 +28,14 @@ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
27
28
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
28
29
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
29
30
  Requires: Django (>=3.2)
30
- Requires-Python: >=3.8
31
+ Requires-Python: >=3.9
31
32
  Description-Content-Type: text/markdown
32
33
  License-File: LICENSE
33
34
  Requires-Dist: Django>=3.2
34
- Requires-Dist: defusedxml>=0.6.0
35
+ Requires-Dist: defusedxml>=0.7.1
35
36
  Requires-Dist: lru_dict>=1.1.7
36
37
  Requires-Dist: orjson>=3.9.15
38
+ Requires-Dist: pyproj>=3.6.1
37
39
  Provides-Extra: tests
38
40
  Requires-Dist: django-environ>=0.4.5; extra == "tests"
39
41
  Requires-Dist: psycopg2-binary>=2.8.4; extra == "tests"
@@ -41,6 +43,23 @@ Requires-Dist: lxml>=4.9.1; extra == "tests"
41
43
  Requires-Dist: pytest>=6.2.3; extra == "tests"
42
44
  Requires-Dist: pytest-django>=4.1.0; extra == "tests"
43
45
  Requires-Dist: pytest-cov>=2.11.1; extra == "tests"
46
+ Provides-Extra: docs
47
+ Requires-Dist: Django~=5.0; extra == "docs"
48
+ Requires-Dist: sphinxcontrib-django>=2.5; extra == "docs"
49
+ Requires-Dist: psycopg2-binary>=2.8.4; extra == "docs"
50
+ Dynamic: author
51
+ Dynamic: author-email
52
+ Dynamic: classifier
53
+ Dynamic: description
54
+ Dynamic: description-content-type
55
+ Dynamic: home-page
56
+ Dynamic: license
57
+ Dynamic: license-file
58
+ Dynamic: provides-extra
59
+ Dynamic: requires
60
+ Dynamic: requires-dist
61
+ Dynamic: requires-python
62
+ Dynamic: summary
44
63
 
45
64
  [![Documentation](https://readthedocs.org/projects/django-gisserver/badge/?version=latest)](https://django-gisserver.readthedocs.io/en/latest/?badge=latest)
46
65
  [![Actions](https://github.com/Amsterdam/django-gisserver/actions/workflows/tests.yaml/badge.svg?branch=main)](https://github.com/Amsterdam/django-gisserver/actions/workflows/tests.yaml)
@@ -66,6 +85,12 @@ Django speaking WFS 2.0 to expose geo data.
66
85
 
67
86
  For more details, see: <https://django-gisserver.readthedocs.io/>
68
87
 
88
+ ## Test drive
89
+
90
+ * Run `docker compose up`.
91
+ * Open http://localhost:8000/ to see this works.
92
+ * Connect to http://localhost:8000/wfs/ in your GIS client (e.g. QGis) and zoom to Amsterdam.
93
+ * Add more data on the map using the Django admin, username and password are both "admin".
69
94
 
70
95
  ## Quickstart
71
96
 
@@ -102,12 +127,13 @@ class Restaurant(models.Model):
102
127
  Write a view that exposes this model as a WFS feature:
103
128
 
104
129
  ```python
130
+ from gisserver.crs import CRS, CRS84, WEB_MERCATOR
105
131
  from gisserver.features import FeatureType, ServiceDescription
106
- from gisserver.geometries import CRS, WGS84
107
132
  from gisserver.views import WFSView
108
133
  from .models import Restaurant
109
134
 
110
- RD_NEW = CRS.from_srid(28992)
135
+ # As example, the local coordinate system for The Netherlands
136
+ RD_NEW = CRS.from_string("urn:ogc:def:crs:EPSG::28992")
111
137
 
112
138
 
113
139
  class PlacesWFSView(WFSView):
@@ -130,7 +156,7 @@ class PlacesWFSView(WFSView):
130
156
  FeatureType(
131
157
  Restaurant.objects.all(),
132
158
  fields="__all__",
133
- other_crs=[RD_NEW]
159
+ other_crs=[RD_NEW, CRS84, WEB_MERCATOR]
134
160
  ),
135
161
  ]
136
162
  ```
@@ -22,6 +22,12 @@ Django speaking WFS 2.0 to expose geo data.
22
22
 
23
23
  For more details, see: <https://django-gisserver.readthedocs.io/>
24
24
 
25
+ ## Test drive
26
+
27
+ * Run `docker compose up`.
28
+ * Open http://localhost:8000/ to see this works.
29
+ * Connect to http://localhost:8000/wfs/ in your GIS client (e.g. QGis) and zoom to Amsterdam.
30
+ * Add more data on the map using the Django admin, username and password are both "admin".
25
31
 
26
32
  ## Quickstart
27
33
 
@@ -58,12 +64,13 @@ class Restaurant(models.Model):
58
64
  Write a view that exposes this model as a WFS feature:
59
65
 
60
66
  ```python
67
+ from gisserver.crs import CRS, CRS84, WEB_MERCATOR
61
68
  from gisserver.features import FeatureType, ServiceDescription
62
- from gisserver.geometries import CRS, WGS84
63
69
  from gisserver.views import WFSView
64
70
  from .models import Restaurant
65
71
 
66
- RD_NEW = CRS.from_srid(28992)
72
+ # As example, the local coordinate system for The Netherlands
73
+ RD_NEW = CRS.from_string("urn:ogc:def:crs:EPSG::28992")
67
74
 
68
75
 
69
76
  class PlacesWFSView(WFSView):
@@ -86,7 +93,7 @@ class PlacesWFSView(WFSView):
86
93
  FeatureType(
87
94
  Restaurant.objects.all(),
88
95
  fields="__all__",
89
- other_crs=[RD_NEW]
96
+ other_crs=[RD_NEW, CRS84, WEB_MERCATOR]
90
97
  ),
91
98
  ]
92
99
  ```
@@ -1,12 +1,12 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: django-gisserver
3
- Version: 1.5.0
3
+ Version: 2.1
4
4
  Summary: Django speaking WFS 2.0 (exposing GeoDjango model fields)
5
5
  Home-page: https://github.com/amsterdam/django-gisserver
6
6
  Author: Diederik van der Boor
7
7
  Author-email: opensource@edoburu.nl
8
8
  License: Mozilla Public License 2.0
9
- Classifier: Development Status :: 4 - Beta
9
+ Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Environment :: Web Environment
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.9
16
16
  Classifier: Programming Language :: Python :: 3.10
17
17
  Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
19
20
  Classifier: Framework :: Django
20
21
  Classifier: Framework :: Django :: 3.2
21
22
  Classifier: Framework :: Django :: 4.0
@@ -27,13 +28,14 @@ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
27
28
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
28
29
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
29
30
  Requires: Django (>=3.2)
30
- Requires-Python: >=3.8
31
+ Requires-Python: >=3.9
31
32
  Description-Content-Type: text/markdown
32
33
  License-File: LICENSE
33
34
  Requires-Dist: Django>=3.2
34
- Requires-Dist: defusedxml>=0.6.0
35
+ Requires-Dist: defusedxml>=0.7.1
35
36
  Requires-Dist: lru_dict>=1.1.7
36
37
  Requires-Dist: orjson>=3.9.15
38
+ Requires-Dist: pyproj>=3.6.1
37
39
  Provides-Extra: tests
38
40
  Requires-Dist: django-environ>=0.4.5; extra == "tests"
39
41
  Requires-Dist: psycopg2-binary>=2.8.4; extra == "tests"
@@ -41,6 +43,23 @@ Requires-Dist: lxml>=4.9.1; extra == "tests"
41
43
  Requires-Dist: pytest>=6.2.3; extra == "tests"
42
44
  Requires-Dist: pytest-django>=4.1.0; extra == "tests"
43
45
  Requires-Dist: pytest-cov>=2.11.1; extra == "tests"
46
+ Provides-Extra: docs
47
+ Requires-Dist: Django~=5.0; extra == "docs"
48
+ Requires-Dist: sphinxcontrib-django>=2.5; extra == "docs"
49
+ Requires-Dist: psycopg2-binary>=2.8.4; extra == "docs"
50
+ Dynamic: author
51
+ Dynamic: author-email
52
+ Dynamic: classifier
53
+ Dynamic: description
54
+ Dynamic: description-content-type
55
+ Dynamic: home-page
56
+ Dynamic: license
57
+ Dynamic: license-file
58
+ Dynamic: provides-extra
59
+ Dynamic: requires
60
+ Dynamic: requires-dist
61
+ Dynamic: requires-python
62
+ Dynamic: summary
44
63
 
45
64
  [![Documentation](https://readthedocs.org/projects/django-gisserver/badge/?version=latest)](https://django-gisserver.readthedocs.io/en/latest/?badge=latest)
46
65
  [![Actions](https://github.com/Amsterdam/django-gisserver/actions/workflows/tests.yaml/badge.svg?branch=main)](https://github.com/Amsterdam/django-gisserver/actions/workflows/tests.yaml)
@@ -66,6 +85,12 @@ Django speaking WFS 2.0 to expose geo data.
66
85
 
67
86
  For more details, see: <https://django-gisserver.readthedocs.io/>
68
87
 
88
+ ## Test drive
89
+
90
+ * Run `docker compose up`.
91
+ * Open http://localhost:8000/ to see this works.
92
+ * Connect to http://localhost:8000/wfs/ in your GIS client (e.g. QGis) and zoom to Amsterdam.
93
+ * Add more data on the map using the Django admin, username and password are both "admin".
69
94
 
70
95
  ## Quickstart
71
96
 
@@ -102,12 +127,13 @@ class Restaurant(models.Model):
102
127
  Write a view that exposes this model as a WFS feature:
103
128
 
104
129
  ```python
130
+ from gisserver.crs import CRS, CRS84, WEB_MERCATOR
105
131
  from gisserver.features import FeatureType, ServiceDescription
106
- from gisserver.geometries import CRS, WGS84
107
132
  from gisserver.views import WFSView
108
133
  from .models import Restaurant
109
134
 
110
- RD_NEW = CRS.from_srid(28992)
135
+ # As example, the local coordinate system for The Netherlands
136
+ RD_NEW = CRS.from_string("urn:ogc:def:crs:EPSG::28992")
111
137
 
112
138
 
113
139
  class PlacesWFSView(WFSView):
@@ -130,7 +156,7 @@ class PlacesWFSView(WFSView):
130
156
  FeatureType(
131
157
  Restaurant.objects.all(),
132
158
  fields="__all__",
133
- other_crs=[RD_NEW]
159
+ other_crs=[RD_NEW, CRS84, WEB_MERCATOR]
134
160
  ),
135
161
  ]
136
162
  ```
@@ -11,13 +11,22 @@ django_gisserver.egg-info/not-zip-safe
11
11
  django_gisserver.egg-info/requires.txt
12
12
  django_gisserver.egg-info/top_level.txt
13
13
  gisserver/__init__.py
14
+ gisserver/compat.py
14
15
  gisserver/conf.py
16
+ gisserver/crs.py
15
17
  gisserver/db.py
16
18
  gisserver/exceptions.py
17
19
  gisserver/features.py
18
20
  gisserver/geometries.py
21
+ gisserver/projection.py
19
22
  gisserver/types.py
20
23
  gisserver/views.py
24
+ gisserver/extensions/__init__.py
25
+ gisserver/extensions/functions.py
26
+ gisserver/extensions/queries.py
27
+ gisserver/management/__init__.py
28
+ gisserver/management/commands/__init__.py
29
+ gisserver/management/commands/loadgeojson.py
21
30
  gisserver/operations/__init__.py
22
31
  gisserver/operations/base.py
23
32
  gisserver/operations/wfs20.py
@@ -26,36 +35,41 @@ gisserver/output/base.py
26
35
  gisserver/output/csv.py
27
36
  gisserver/output/geojson.py
28
37
  gisserver/output/gml32.py
38
+ gisserver/output/iters.py
29
39
  gisserver/output/results.py
40
+ gisserver/output/stored.py
30
41
  gisserver/output/utils.py
31
42
  gisserver/output/xmlschema.py
32
43
  gisserver/parsers/__init__.py
33
- gisserver/parsers/base.py
34
- gisserver/parsers/tags.py
44
+ gisserver/parsers/ast.py
45
+ gisserver/parsers/query.py
35
46
  gisserver/parsers/values.py
47
+ gisserver/parsers/xml.py
36
48
  gisserver/parsers/fes20/__init__.py
37
49
  gisserver/parsers/fes20/expressions.py
38
50
  gisserver/parsers/fes20/filters.py
39
- gisserver/parsers/fes20/functions.py
40
51
  gisserver/parsers/fes20/identifiers.py
52
+ gisserver/parsers/fes20/lookups.py
41
53
  gisserver/parsers/fes20/operators.py
42
- gisserver/parsers/fes20/query.py
43
54
  gisserver/parsers/fes20/sorting.py
44
55
  gisserver/parsers/gml/__init__.py
45
56
  gisserver/parsers/gml/base.py
46
57
  gisserver/parsers/gml/geometries.py
47
- gisserver/queries/__init__.py
48
- gisserver/queries/adhoc.py
49
- gisserver/queries/base.py
50
- gisserver/queries/projection.py
51
- gisserver/queries/stored.py
58
+ gisserver/parsers/ows/__init__.py
59
+ gisserver/parsers/ows/kvp.py
60
+ gisserver/parsers/ows/requests.py
61
+ gisserver/parsers/wfs20/__init__.py
62
+ gisserver/parsers/wfs20/adhoc.py
63
+ gisserver/parsers/wfs20/base.py
64
+ gisserver/parsers/wfs20/projection.py
65
+ gisserver/parsers/wfs20/requests.py
66
+ gisserver/parsers/wfs20/stored.py
52
67
  gisserver/static/gisserver/index.css
68
+ gisserver/templates/gisserver/base.html
53
69
  gisserver/templates/gisserver/index.html
54
70
  gisserver/templates/gisserver/service_description.html
55
71
  gisserver/templates/gisserver/wfs/feature_field.html
56
72
  gisserver/templates/gisserver/wfs/feature_type.html
57
- gisserver/templates/gisserver/wfs/2.0.0/describe_stored_queries.xml
58
73
  gisserver/templates/gisserver/wfs/2.0.0/get_capabilities.xml
59
- gisserver/templates/gisserver/wfs/2.0.0/list_stored_queries.xml
60
74
  gisserver/templatetags/__init__.py
61
75
  gisserver/templatetags/gisserver_tags.py
@@ -1,7 +1,13 @@
1
1
  Django>=3.2
2
- defusedxml>=0.6.0
2
+ defusedxml>=0.7.1
3
3
  lru_dict>=1.1.7
4
4
  orjson>=3.9.15
5
+ pyproj>=3.6.1
6
+
7
+ [docs]
8
+ Django~=5.0
9
+ sphinxcontrib-django>=2.5
10
+ psycopg2-binary>=2.8.4
5
11
 
6
12
  [tests]
7
13
  django-environ>=0.4.5
@@ -0,0 +1 @@
1
+ __version__ = "2.1" # follows PEP440
@@ -0,0 +1,23 @@
1
+ """Compatability imports"""
2
+
3
+ import sys
4
+
5
+ import django
6
+ from django.conf import settings
7
+ from django.db import models
8
+
9
+ if (
10
+ "django.contrib.postgres" in settings.INSTALLED_APPS
11
+ or "django.contrib.postgres" in sys.modules
12
+ ):
13
+ from django.contrib.postgres.fields import ArrayField
14
+ else:
15
+ ArrayField = None
16
+
17
+ GeneratedField = models.GeneratedField if django.VERSION >= (5, 0) else None
18
+
19
+
20
+ __all__ = (
21
+ "ArrayField",
22
+ "GeneratedField",
23
+ )
@@ -28,6 +28,13 @@ GISSERVER_SUPPORTED_CRS_ONLY = getattr(settings, "GISSERVER_SUPPORTED_CRS_ONLY",
28
28
  # 0 = No counting, 1 = all pages, 2 = only for the first page.
29
29
  GISSERVER_COUNT_NUMBER_MATCHED = getattr(settings, "GISSERVER_COUNT_NUMBER_MATCHED", 1)
30
30
 
31
+ # -- output rendering
32
+
33
+ GISSERVER_EXTRA_OUTPUT_FORMATS = getattr(settings, "GISSERVER_EXTRA_OUTPUT_FORMATS", {})
34
+ GISSERVER_GET_FEATURE_OUTPUT_FORMATS = getattr(
35
+ settings, "GISSERVER_GET_FEATURE_OUTPUT_FORMATS", {}
36
+ )
37
+
31
38
  # -- max page size
32
39
 
33
40
  # Allow tuning the page size without having to override code.