goodmap 1.1.7__py3-none-any.whl
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.
- goodmap/__init__.py +1 -0
- goodmap/clustering.py +75 -0
- goodmap/config.py +42 -0
- goodmap/core.py +46 -0
- goodmap/core_api.py +467 -0
- goodmap/data_models/location.py +68 -0
- goodmap/data_validator.py +119 -0
- goodmap/db.py +1466 -0
- goodmap/exceptions.py +100 -0
- goodmap/formatter.py +27 -0
- goodmap/goodmap.py +89 -0
- goodmap/templates/goodmap-admin.html +743 -0
- goodmap/templates/map.html +124 -0
- goodmap-1.1.7.dist-info/METADATA +142 -0
- goodmap-1.1.7.dist-info/RECORD +17 -0
- goodmap-1.1.7.dist-info/WHEEL +4 -0
- goodmap-1.1.7.dist-info/licenses/LICENSE.md +21 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block head_meta %}
|
|
4
|
+
|
|
5
|
+
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
|
|
6
|
+
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
|
|
7
|
+
crossorigin=""/>
|
|
8
|
+
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css" />
|
|
9
|
+
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css" />
|
|
10
|
+
|
|
11
|
+
{% endblock %}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
{% block left_panel %}
|
|
15
|
+
<div id="filter-form"></div>
|
|
16
|
+
{% endblock %}
|
|
17
|
+
|
|
18
|
+
{% block content %}
|
|
19
|
+
|
|
20
|
+
<style>
|
|
21
|
+
.loading-popup {
|
|
22
|
+
position: fixed;
|
|
23
|
+
top: 0;
|
|
24
|
+
left: 0;
|
|
25
|
+
width: 100%;
|
|
26
|
+
height: 100%;
|
|
27
|
+
display: none;
|
|
28
|
+
align-items: center;
|
|
29
|
+
justify-content: center;
|
|
30
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
31
|
+
color: white;
|
|
32
|
+
font-size: 24px;
|
|
33
|
+
z-index: 1000;
|
|
34
|
+
}
|
|
35
|
+
</style>
|
|
36
|
+
|
|
37
|
+
<div id="loadingPopup" class="loading-popup">
|
|
38
|
+
{{ gettext('Loading') }}...
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div id="map" class="map h-100 w-100"></div>
|
|
42
|
+
|
|
43
|
+
<script type="text/javascript">
|
|
44
|
+
|
|
45
|
+
(function() {
|
|
46
|
+
// Following code will show a loading popup when an API request is in progress
|
|
47
|
+
// TODO Fetching /api/data code should be moved to a separate file and included in the base template.
|
|
48
|
+
// Code could be refactored to use a more modern approach (e.g. fetch API, async/await) or even moved
|
|
49
|
+
// to a goodmap-frontend code. For more check issue #95 (https://github.com/Problematy/goodmap/issues/95)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
// Intercept XMLHttpRequest
|
|
53
|
+
const originalOpen = XMLHttpRequest.prototype.open;
|
|
54
|
+
const originalSend = XMLHttpRequest.prototype.send;
|
|
55
|
+
|
|
56
|
+
XMLHttpRequest.prototype.open = function(method, url) {
|
|
57
|
+
if (url.includes('/api/data')) { // Adjust this condition to match your API endpoint
|
|
58
|
+
this.addEventListener('loadstart', showLoading);
|
|
59
|
+
this.addEventListener('loadend', hideLoading);
|
|
60
|
+
}
|
|
61
|
+
return originalOpen.apply(this, arguments);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
XMLHttpRequest.prototype.send = function() {
|
|
65
|
+
return originalSend.apply(this, arguments);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Intercept fetch
|
|
69
|
+
const originalFetch = window.fetch;
|
|
70
|
+
|
|
71
|
+
window.fetch = async function(url, options) {
|
|
72
|
+
if (url.includes('/api/data')) { // Adjust this condition to match your API endpoint
|
|
73
|
+
showLoading();
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const response = await originalFetch(url, options);
|
|
77
|
+
return response;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
throw error;
|
|
80
|
+
} finally {
|
|
81
|
+
if (url.includes('/api/data')) {
|
|
82
|
+
hideLoading();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
let requestCount = 0;
|
|
87
|
+
|
|
88
|
+
function showLoading() {
|
|
89
|
+
requestCount++;
|
|
90
|
+
if (requestCount === 1) { // Only show on the first request
|
|
91
|
+
const loadingPopup = document.getElementById('loadingPopup');
|
|
92
|
+
if (loadingPopup) {
|
|
93
|
+
loadingPopup.style.display = 'flex';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function hideLoading() {
|
|
99
|
+
requestCount--;
|
|
100
|
+
if (requestCount === 0) { // Only hide when all requests have completed
|
|
101
|
+
const loadingPopup = document.getElementById('loadingPopup');
|
|
102
|
+
if (loadingPopup) {
|
|
103
|
+
loadingPopup.style.display = 'none';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
})();
|
|
109
|
+
|
|
110
|
+
</script>
|
|
111
|
+
<script>
|
|
112
|
+
window.APP_LANG = "{{ current_language }}";
|
|
113
|
+
window.SECONDARY_COLOR = "{{ secondary_color }}";
|
|
114
|
+
window.PRIMARY_COLOR = "{{ primary_color }}";
|
|
115
|
+
|
|
116
|
+
window.SHOW_SUGGEST_NEW_POINT_BUTTON = {{ feature_flags.SHOW_SUGGEST_NEW_POINT_BUTTON | default(false) | tojson }};
|
|
117
|
+
window.SHOW_SEARCH_BAR = {{ feature_flags.SHOW_SEARCH_BAR | default(false) | tojson }};
|
|
118
|
+
window.USE_LAZY_LOADING = {{ feature_flags.USE_LAZY_LOADING | default(false) | tojson }};
|
|
119
|
+
window.USE_SERVER_SIDE_CLUSTERING = {{ feature_flags.USE_SERVER_SIDE_CLUSTERING | default(false) | tojson }};
|
|
120
|
+
window.SHOW_ACCESSIBILITY_TABLE = {{ feature_flags.SHOW_ACCESSIBILITY_TABLE | default(false) | tojson }};
|
|
121
|
+
window.FEATURE_FLAGS = {{ feature_flags | tojson }};
|
|
122
|
+
</script>
|
|
123
|
+
<script src="{{ goodmap_frontend_lib_url }}"></script>
|
|
124
|
+
{% endblock %}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: goodmap
|
|
3
|
+
Version: 1.1.7
|
|
4
|
+
Summary: Map engine to serve all the people :)
|
|
5
|
+
License-File: LICENSE.md
|
|
6
|
+
Author: Krzysztof Kolodzinski
|
|
7
|
+
Author-email: krzysztof.kolodzinski@problematy.pl
|
|
8
|
+
Requires-Python: >=3.10,<4.0
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Provides-Extra: docs
|
|
16
|
+
Requires-Dist: Babel (>=2.10.3,<3.0.0)
|
|
17
|
+
Requires-Dist: Flask (==3.0.3)
|
|
18
|
+
Requires-Dist: Flask-Babel (>=4.0.0,<5.0.0)
|
|
19
|
+
Requires-Dist: Flask-WTF (>=1.2.1,<2.0.0)
|
|
20
|
+
Requires-Dist: PyYAML (>=6.0,<7.0)
|
|
21
|
+
Requires-Dist: aiohttp (>=3.8.4,<4.0.0)
|
|
22
|
+
Requires-Dist: deprecation (>=2.1.0,<3.0.0)
|
|
23
|
+
Requires-Dist: flask-restx (>=1.3.0,<2.0.0)
|
|
24
|
+
Requires-Dist: google-cloud-storage (>=2.7.0,<3.0.0)
|
|
25
|
+
Requires-Dist: gql (>=3.4.0,<4.0.0)
|
|
26
|
+
Requires-Dist: gunicorn (>=20.1.0,<21.0.0)
|
|
27
|
+
Requires-Dist: humanize (>=4.6.0,<5.0.0)
|
|
28
|
+
Requires-Dist: myst-parser (>=4.0.0,<5.0.0) ; extra == "docs"
|
|
29
|
+
Requires-Dist: numpy (>=2.2.0,<3.0.0)
|
|
30
|
+
Requires-Dist: platzky (>=1.0.0,<2.0.0)
|
|
31
|
+
Requires-Dist: pydantic (>=2.7.1,<3.0.0)
|
|
32
|
+
Requires-Dist: pysupercluster-problematy (>=0.7.8,<0.8.0)
|
|
33
|
+
Requires-Dist: scipy (>=1.15.1,<2.0.0)
|
|
34
|
+
Requires-Dist: sphinx (>=8.0.0,<9.0.0) ; extra == "docs"
|
|
35
|
+
Requires-Dist: sphinx-rtd-theme (>=3.0.0,<4.0.0) ; extra == "docs"
|
|
36
|
+
Requires-Dist: tomli (>=2.0.0,<3.0.0) ; extra == "docs"
|
|
37
|
+
Description-Content-Type: text/markdown
|
|
38
|
+
|
|
39
|
+

|
|
40
|
+
[](https://coveralls.io/github/Problematy/goodmap)
|
|
41
|
+
|
|
42
|
+
# Good Map
|
|
43
|
+
|
|
44
|
+
Map engine to serve all the people ;)
|
|
45
|
+
|
|
46
|
+
## Setup
|
|
47
|
+
|
|
48
|
+
#### 0. Clone the repo
|
|
49
|
+
```
|
|
50
|
+
git clone --recursive
|
|
51
|
+
```
|
|
52
|
+
Remember, everytime you want to pull the newest changes, run:
|
|
53
|
+
```
|
|
54
|
+
git pull
|
|
55
|
+
git submodule update
|
|
56
|
+
```
|
|
57
|
+
because `goodmap` contains a submodule.
|
|
58
|
+
|
|
59
|
+
#TODO remove all submodule connected instructions after removing platzky submodule (see #157)
|
|
60
|
+
|
|
61
|
+
#### 1. Use python 3.10
|
|
62
|
+
If you have a different version of Python on your system, install python 3.10 alongside. For that, you can use [`pyenv`](https://github.com/pyenv/pyenv). Follow the [documentation](https://github.com/pyenv/pyenv?tab=readme-ov-file#installation). Useful commands: `pyenv help <command>`, `pyenv install`, `pyenv shell`, `pyenv versions`.
|
|
63
|
+
|
|
64
|
+
#### 2. Install `poetry` in Python 3.10
|
|
65
|
+
`poetry` can create virtual environments associated with a project. \
|
|
66
|
+
Make sure you are in the Python 3.10 environment and install:
|
|
67
|
+
```
|
|
68
|
+
pip install poetry
|
|
69
|
+
```
|
|
70
|
+
Useful commands: `poetry -h <command>`, `poetry env list`, `poetry env info`.
|
|
71
|
+
|
|
72
|
+
#### 3. Install dependencies
|
|
73
|
+
```
|
|
74
|
+
poetry install
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
#### 4. You're ready
|
|
78
|
+
|
|
79
|
+
When you enter the project directory, you can invoke any commands in your project like this:
|
|
80
|
+
```
|
|
81
|
+
poetry run <command>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Running App locally
|
|
85
|
+
|
|
86
|
+
### TL;DR
|
|
87
|
+
If you don't want to go through all the configuration, e.g. you just simply want to test if everything works,
|
|
88
|
+
you can simply run app with test dataset provided in `examples` directory:
|
|
89
|
+
|
|
90
|
+
> poetry run flask --app 'goodmap.goodmap:create_app(config_path="./examples/e2e_test_config.yml")' run
|
|
91
|
+
|
|
92
|
+
### Configuration
|
|
93
|
+
|
|
94
|
+
If you want to serve app with your configuration rename config-template.yml to config.yml and change its contents according to your needs.
|
|
95
|
+
|
|
96
|
+
Afterwards run it with:
|
|
97
|
+
> poetry run flask --app 'goodmap.goodmap:create_app(config_path="/PATH/TO/YOUR/CONFIG")' --debug run
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
| Option | Description |
|
|
101
|
+
|--------------------------|------------------------------------------------------------------------------------------------------------------------------------|
|
|
102
|
+
| USE_LAZY_LOADING | Loads point data only after the user clicks a point. If set to false, point data is loaded together with the initial map. |
|
|
103
|
+
| FAKE_LOGIN | If set to true, allows access to the admin panel by simply selecting the role instead of logging in. **DO NOT USE IN PRODUCTION!** |
|
|
104
|
+
| SHOW_ACCESSIBILITY_TABLE | If set as true it shows special view to help with accessing application. |
|
|
105
|
+
|
|
106
|
+
## Database
|
|
107
|
+
|
|
108
|
+
The database is stored in JSON, in the `map` section. For an example database see `examples/e2e_test_data.json`. The first subsection `data` consists of the actual datapoints, representing points on a map.
|
|
109
|
+
|
|
110
|
+
Datapoints have fields. The next subsections define special types of fields:
|
|
111
|
+
- `obligatory_fields` - here are explicitely stated all the fields that the application assumes are presnt in all datapoints. E.g.
|
|
112
|
+
```
|
|
113
|
+
"position",
|
|
114
|
+
"name",
|
|
115
|
+
"accessible_by"
|
|
116
|
+
```
|
|
117
|
+
TODO: `obligatory_fields` is a new subsection, start using it in the actual application
|
|
118
|
+
- `categories` - fields that can somehow be used in the app, for example by which datapoints can be filtered. Every category has a specified list of allowed values. E.g.
|
|
119
|
+
```
|
|
120
|
+
"accessible_by": ["bikes", "cars", "pedestrians"]
|
|
121
|
+
```
|
|
122
|
+
- `visible_data` - when a datapoint will be rendered as a pin on a map, these fields will be shown in the box when clicking on a pin. E.g.
|
|
123
|
+
```
|
|
124
|
+
"name",
|
|
125
|
+
"type_of_place"
|
|
126
|
+
```
|
|
127
|
+
- `meta-data` - some special data like
|
|
128
|
+
```
|
|
129
|
+
"uuid"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
You can define the fields in all these subsections. Besides these types of fields, there is no restriction on the number of fields a datapoint can have.
|
|
133
|
+
|
|
134
|
+
## Examples
|
|
135
|
+
|
|
136
|
+
You can find examples of working configuration and database in `examples/` directory:
|
|
137
|
+
- `e2e_test_config.yml` - Basic configuration example
|
|
138
|
+
- `e2e_test_data.json` - Example database with sample location data
|
|
139
|
+
- `mongo_e2e_test_config.yml` - MongoDB configuration example
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
goodmap/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
2
|
+
goodmap/clustering.py,sha256=ULB-fPNOUDblgpBK4vzuo0o2yqIcvG84F3R6Za2X_l4,2905
|
|
3
|
+
goodmap/config.py,sha256=sseE4sceFB8OBuFsrRpQJvjv0Vg5KFdkzihBX_hbE2c,1313
|
|
4
|
+
goodmap/core.py,sha256=rzMhOIYnR1jxTX6uHQJKIPLYxdUm4_v2d6LrtHtJpHU,1465
|
|
5
|
+
goodmap/core_api.py,sha256=gzFYeek65_4kLET0NPMlSqTz1UGlQl7Dam6lxDtrTIk,19586
|
|
6
|
+
goodmap/data_models/location.py,sha256=brDdaICyYPs8QrWEkRXkUybQS3IJaZGbkDWa6hqhFAg,2008
|
|
7
|
+
goodmap/data_validator.py,sha256=lBmVAPxvSmEOdUGeVYSjUvVVmKfPyq4CWoHfczTtEMM,4090
|
|
8
|
+
goodmap/db.py,sha256=TcqYGbK5yk6S735Si1AzjNqcbB1nsd9pFGOy5qN9Vec,46589
|
|
9
|
+
goodmap/exceptions.py,sha256=jkFAUoc5LHk8iPjxHxbcRp8W6qFCSEA25A8XaSwxwyo,2906
|
|
10
|
+
goodmap/formatter.py,sha256=VlUHcK1HtM_IEU0VE3S5TOkZLVheMdakvUeW2tCKdq0,783
|
|
11
|
+
goodmap/goodmap.py,sha256=q6okPopWBH6jDkKJcGDegebaapHLFUVilJ3p3aKi97k,2960
|
|
12
|
+
goodmap/templates/goodmap-admin.html,sha256=39PJ1drk_xdkyzXgPZZNXYq9gA9oTVeR8hsgeae6E0g,35614
|
|
13
|
+
goodmap/templates/map.html,sha256=aEIL6M7AlBZ34asV5R1syKq9IA1tBZNhiBMA9ovco7I,4105
|
|
14
|
+
goodmap-1.1.7.dist-info/METADATA,sha256=4tjNpCJPcQY-OnSzw2MiWyjGocISorq4oIyZqtJOqX8,5868
|
|
15
|
+
goodmap-1.1.7.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
16
|
+
goodmap-1.1.7.dist-info/licenses/LICENSE.md,sha256=nkCQOR7uheLRvHRfXmwx9LhBnMcPeBU9d4ebLojDiQU,1067
|
|
17
|
+
goodmap-1.1.7.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 problematy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|