smoothglue_django_map 0.0.5__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.
- smoothglue_django_map-0.0.5/LICENSE +11 -0
- smoothglue_django_map-0.0.5/PKG-INFO +104 -0
- smoothglue_django_map-0.0.5/README.md +84 -0
- smoothglue_django_map-0.0.5/pyproject.toml +108 -0
- smoothglue_django_map-0.0.5/smoothglue/__init__.py +0 -0
- smoothglue_django_map-0.0.5/smoothglue/map/__init__.py +0 -0
- smoothglue_django_map-0.0.5/smoothglue/map/admin.py +17 -0
- smoothglue_django_map-0.0.5/smoothglue/map/apps.py +7 -0
- smoothglue_django_map-0.0.5/smoothglue/map/fixtures/imagerylayer.json +82 -0
- smoothglue_django_map-0.0.5/smoothglue/map/migrations/0001_initial.py +51 -0
- smoothglue_django_map-0.0.5/smoothglue/map/migrations/__init__.py +0 -0
- smoothglue_django_map-0.0.5/smoothglue/map/models.py +32 -0
- smoothglue_django_map-0.0.5/smoothglue/map/serializers/__init__.py +0 -0
- smoothglue_django_map-0.0.5/smoothglue/map/serializers/imagery_layer.py +15 -0
- smoothglue_django_map-0.0.5/smoothglue/map/tests/__init__.py +0 -0
- smoothglue_django_map-0.0.5/smoothglue/map/tests/boot_django.py +34 -0
- smoothglue_django_map-0.0.5/smoothglue/map/tests/loadtests.py +30 -0
- smoothglue_django_map-0.0.5/smoothglue/map/tests/test_coordinate_utils.py +12 -0
- smoothglue_django_map-0.0.5/smoothglue/map/tests/test_map_layers.py +23 -0
- smoothglue_django_map-0.0.5/smoothglue/map/urls.py +13 -0
- smoothglue_django_map-0.0.5/smoothglue/map/utils/coordinate_utils.py +70 -0
- smoothglue_django_map-0.0.5/smoothglue/map/views.py +11 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Copyright 2020–2025, BrainGu LLC. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software is part of SmoothGlue™, a proprietary product developed by BrainGu LLC.
|
|
4
|
+
|
|
5
|
+
This software is proprietary and confidential. It may not be copied, modified, distributed,
|
|
6
|
+
or used in any form except under a valid commercial license agreement with BrainGu.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED,
|
|
9
|
+
INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
10
|
+
|
|
11
|
+
To inquire about licensing, contact: legal@braingu.com
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: smoothglue_django_map
|
|
3
|
+
Version: 0.0.5
|
|
4
|
+
Summary: A Django app to do anything with Django.
|
|
5
|
+
License: Proprietary
|
|
6
|
+
Keywords: Interoperability,API Integration,Edge Computing,Application Framework,Data-Driven Development,Map
|
|
7
|
+
Author: SmoothGlue
|
|
8
|
+
Maintainer: BrainGu
|
|
9
|
+
Maintainer-email: smoothglue@braingu.com
|
|
10
|
+
Requires-Python: >= 3.12
|
|
11
|
+
Classifier: License :: Other/Proprietary License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Requires-Dist: django (>=3.2)
|
|
16
|
+
Requires-Dist: smoothglue-django-core (>=1.5.3,<2.0.0)
|
|
17
|
+
Project-URL: Homepage, https://braingu.com/solutions/smoothglue/
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# SmoothGlue Django Map App
|
|
21
|
+
|
|
22
|
+
This Django app provides backend api to support front end Map features such as Map Imagery Layers, CZML / GeoJSON python helper classes (coming soon), etc.
|
|
23
|
+
|
|
24
|
+
## Development
|
|
25
|
+
|
|
26
|
+
### Set Up Virtual Environment and Install Required Packages
|
|
27
|
+
|
|
28
|
+
This project uses [Poetry](https://python-poetry.org/) for dependency management and packaging.
|
|
29
|
+
|
|
30
|
+
1. Install Poetry if you haven't already.
|
|
31
|
+
2. Run `poetry install` to create a virtual environment and install dependencies.
|
|
32
|
+
|
|
33
|
+
### Running Management Commands With Your App
|
|
34
|
+
|
|
35
|
+
- **smoothglue/map/tests/boot_django.py** to set up a Django environment using Django’s settings.configure() and django.setup() to allow interacting with your app outside of a project.
|
|
36
|
+
|
|
37
|
+
- The settings.configure() call inside this file takes a list of arguments that are equivalent to the variables defined in a settings.py file. Anything you would need in your settings.py to make your app run gets passed into settings.configure().
|
|
38
|
+
- This file is used by the test runner and other scripts to bootstrap the environment.
|
|
39
|
+
|
|
40
|
+
- **djangoshell.py** to spawn a Django shell that’s aware of your app
|
|
41
|
+
- **loaddata.py "some argument"** load fixture data into your app's database and test out
|
|
42
|
+
- **run_test.sh** to run all tests for your app (executes `smoothglue/map/tests/loadtests.py`)
|
|
43
|
+
- **makemigrations.py** to create a migration file
|
|
44
|
+
- **migrate.py** to perform table migrations
|
|
45
|
+
|
|
46
|
+
## Using App Package (Locally)
|
|
47
|
+
|
|
48
|
+
The steps for using your package locally are:
|
|
49
|
+
|
|
50
|
+
### Build Your App
|
|
51
|
+
|
|
52
|
+
Run `poetry build` inside the main level of this repo. This creates a directory called `dist` and builds your new package into source and binary formats (e.g., **smoothglue_django_map-<version>.tar.gz** and **smoothglue_django_map-<version>-py3-none-any.whl**).
|
|
53
|
+
|
|
54
|
+
### Install App Inside a Django Project
|
|
55
|
+
|
|
56
|
+
1. Before installing the package, make sure that there is a virtual environment set up inside of the Django project you want to install your app into.
|
|
57
|
+
|
|
58
|
+
2. Then use pip or poetry to install the package:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Using pip
|
|
62
|
+
pip install [path to your newly packaged file]
|
|
63
|
+
|
|
64
|
+
# Using Poetry
|
|
65
|
+
poetry add [path to your newly packaged file]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
3. Update the `settings.py` file inside that Django project to point to the new app name:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
INSTALLED_APPS = [
|
|
72
|
+
"smoothglue.map",
|
|
73
|
+
...,
|
|
74
|
+
]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
4. Update the `urls.py` file inside that Django project to point to the new app name: :
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
urlpatterns = [
|
|
81
|
+
path("", include("smoothglue.map.urls")),
|
|
82
|
+
...,
|
|
83
|
+
]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
5. Run the development server to confirm the project continues to work.
|
|
87
|
+
|
|
88
|
+
[GIF COMING SOON]
|
|
89
|
+
|
|
90
|
+
## Install App From Gitlab PyPI Package (Official Use)
|
|
91
|
+
|
|
92
|
+
1. Before installing the package, make sure that there is a virtual environment set up inside of the Django project you want to install the app into.
|
|
93
|
+
|
|
94
|
+
2. Use pip and the following command inside the Django project:
|
|
95
|
+
```python
|
|
96
|
+
pip install <app_name> --index-url https://__token__:<your_personal_token>@code.dsop.structsure.io/api/v4/projects/<project_id>/packages/pypi/simple
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Other File Descriptions
|
|
100
|
+
|
|
101
|
+
- MANIFEST.in - Tells the build process which non common files and folders that should be packaged
|
|
102
|
+
- pyproject.toml - Package and project metadata / configuration
|
|
103
|
+
- tox.ini - Used to configure different types of packages,
|
|
104
|
+
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# SmoothGlue Django Map App
|
|
2
|
+
|
|
3
|
+
This Django app provides backend api to support front end Map features such as Map Imagery Layers, CZML / GeoJSON python helper classes (coming soon), etc.
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
### Set Up Virtual Environment and Install Required Packages
|
|
8
|
+
|
|
9
|
+
This project uses [Poetry](https://python-poetry.org/) for dependency management and packaging.
|
|
10
|
+
|
|
11
|
+
1. Install Poetry if you haven't already.
|
|
12
|
+
2. Run `poetry install` to create a virtual environment and install dependencies.
|
|
13
|
+
|
|
14
|
+
### Running Management Commands With Your App
|
|
15
|
+
|
|
16
|
+
- **smoothglue/map/tests/boot_django.py** to set up a Django environment using Django’s settings.configure() and django.setup() to allow interacting with your app outside of a project.
|
|
17
|
+
|
|
18
|
+
- The settings.configure() call inside this file takes a list of arguments that are equivalent to the variables defined in a settings.py file. Anything you would need in your settings.py to make your app run gets passed into settings.configure().
|
|
19
|
+
- This file is used by the test runner and other scripts to bootstrap the environment.
|
|
20
|
+
|
|
21
|
+
- **djangoshell.py** to spawn a Django shell that’s aware of your app
|
|
22
|
+
- **loaddata.py "some argument"** load fixture data into your app's database and test out
|
|
23
|
+
- **run_test.sh** to run all tests for your app (executes `smoothglue/map/tests/loadtests.py`)
|
|
24
|
+
- **makemigrations.py** to create a migration file
|
|
25
|
+
- **migrate.py** to perform table migrations
|
|
26
|
+
|
|
27
|
+
## Using App Package (Locally)
|
|
28
|
+
|
|
29
|
+
The steps for using your package locally are:
|
|
30
|
+
|
|
31
|
+
### Build Your App
|
|
32
|
+
|
|
33
|
+
Run `poetry build` inside the main level of this repo. This creates a directory called `dist` and builds your new package into source and binary formats (e.g., **smoothglue_django_map-<version>.tar.gz** and **smoothglue_django_map-<version>-py3-none-any.whl**).
|
|
34
|
+
|
|
35
|
+
### Install App Inside a Django Project
|
|
36
|
+
|
|
37
|
+
1. Before installing the package, make sure that there is a virtual environment set up inside of the Django project you want to install your app into.
|
|
38
|
+
|
|
39
|
+
2. Then use pip or poetry to install the package:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Using pip
|
|
43
|
+
pip install [path to your newly packaged file]
|
|
44
|
+
|
|
45
|
+
# Using Poetry
|
|
46
|
+
poetry add [path to your newly packaged file]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
3. Update the `settings.py` file inside that Django project to point to the new app name:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
INSTALLED_APPS = [
|
|
53
|
+
"smoothglue.map",
|
|
54
|
+
...,
|
|
55
|
+
]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
4. Update the `urls.py` file inside that Django project to point to the new app name: :
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
urlpatterns = [
|
|
62
|
+
path("", include("smoothglue.map.urls")),
|
|
63
|
+
...,
|
|
64
|
+
]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
5. Run the development server to confirm the project continues to work.
|
|
68
|
+
|
|
69
|
+
[GIF COMING SOON]
|
|
70
|
+
|
|
71
|
+
## Install App From Gitlab PyPI Package (Official Use)
|
|
72
|
+
|
|
73
|
+
1. Before installing the package, make sure that there is a virtual environment set up inside of the Django project you want to install the app into.
|
|
74
|
+
|
|
75
|
+
2. Use pip and the following command inside the Django project:
|
|
76
|
+
```python
|
|
77
|
+
pip install <app_name> --index-url https://__token__:<your_personal_token>@code.dsop.structsure.io/api/v4/projects/<project_id>/packages/pypi/simple
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Other File Descriptions
|
|
81
|
+
|
|
82
|
+
- MANIFEST.in - Tells the build process which non common files and folders that should be packaged
|
|
83
|
+
- pyproject.toml - Package and project metadata / configuration
|
|
84
|
+
- tox.ini - Used to configure different types of packages,
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "smoothglue_django_map"
|
|
3
|
+
version = "0.0.6"
|
|
4
|
+
description = "Enhance your development with SmoothGlue™, Map component for providing backend related map APIs."
|
|
5
|
+
authors = ["BrainGu <smoothglue@braingu.com>"]
|
|
6
|
+
maintainers = ["BrainGu <smoothglue@braingu.com>"]
|
|
7
|
+
license = "Proprietary"
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
homepage = "https://braingu.com/solutions/smoothglue/"
|
|
10
|
+
keywords = [
|
|
11
|
+
"Interoperability",
|
|
12
|
+
"API Integration",
|
|
13
|
+
"Edge Computing",
|
|
14
|
+
"Application Framework",
|
|
15
|
+
"Data-Driven Development",
|
|
16
|
+
"Map"
|
|
17
|
+
]
|
|
18
|
+
packages = [
|
|
19
|
+
{ include = "smoothglue" },
|
|
20
|
+
{ include = "smoothglue/map" },
|
|
21
|
+
{ include = "smoothglue/map/serializers" },
|
|
22
|
+
{ include = "smoothglue/map/migrations" },
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[tool.poetry.dependencies]
|
|
26
|
+
python = "^3.12"
|
|
27
|
+
|
|
28
|
+
[tool.poetry.group.dev.dependencies]
|
|
29
|
+
pre-commit = "^3.7.1"
|
|
30
|
+
black = "^24.4.2"
|
|
31
|
+
isort = "^5.13.2"
|
|
32
|
+
|
|
33
|
+
pylint = "^3.2.5"
|
|
34
|
+
pylint-plugin-utils = "^0.8.2"
|
|
35
|
+
pylint-django = "^2.5.5"
|
|
36
|
+
[build-system]
|
|
37
|
+
requires = ["poetry-core"]
|
|
38
|
+
build-backend = "poetry.core.masonry.api"
|
|
39
|
+
|
|
40
|
+
[project]
|
|
41
|
+
name = "smoothglue_django_map"
|
|
42
|
+
version = "0.0.5"
|
|
43
|
+
dependencies = [
|
|
44
|
+
"django>=3.2",
|
|
45
|
+
"smoothglue-django-core (>=1.5.3,<2.0.0)",
|
|
46
|
+
]
|
|
47
|
+
description = "A Django app to do anything with Django."
|
|
48
|
+
readme = "README.md"
|
|
49
|
+
requires-python = ">= 3.12"
|
|
50
|
+
authors = [
|
|
51
|
+
{name = "SmoothGlue"},
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[tool.setuptools]
|
|
55
|
+
packages = ["smoothglue.map", "smoothglue.map.serializers", "smoothglue.map.migrations", "smoothglue.map.fixtures"]
|
|
56
|
+
|
|
57
|
+
[project.urls]
|
|
58
|
+
Homepage = "https://braingu.com/solutions/smoothglue/"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
[tool.black]
|
|
62
|
+
exclude = '''
|
|
63
|
+
/(
|
|
64
|
+
| venv
|
|
65
|
+
| migrations
|
|
66
|
+
)/
|
|
67
|
+
'''
|
|
68
|
+
|
|
69
|
+
[tool.pylint.main]
|
|
70
|
+
recursive = true
|
|
71
|
+
fail-under = 10
|
|
72
|
+
max-attributes = 15
|
|
73
|
+
ignore-paths = [
|
|
74
|
+
"^.*migrations\\/.*$",
|
|
75
|
+
"^.*venv\\/.*$"
|
|
76
|
+
]
|
|
77
|
+
no-docstring-rgx = "(?:^_|^[Tt]est.+|Mock.+)"
|
|
78
|
+
load-plugins = ["pylint_django"]
|
|
79
|
+
|
|
80
|
+
[tool.pylint."messages control"]
|
|
81
|
+
disable = [
|
|
82
|
+
"missing-module-docstring",
|
|
83
|
+
"E5110",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[tool.isort]
|
|
87
|
+
profile = "black"
|
|
88
|
+
|
|
89
|
+
[tool.pylint.design]
|
|
90
|
+
exclude-too-few-public-methods = ["abc.ABC"]
|
|
91
|
+
|
|
92
|
+
[tool.coverage.run]
|
|
93
|
+
include = [
|
|
94
|
+
"smoothglue/*",
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
[tool.coverage.report]
|
|
98
|
+
exclude_also = [
|
|
99
|
+
"class DefaultUploadProcessor",
|
|
100
|
+
"class DefaultValidator",
|
|
101
|
+
"class TestValidator",
|
|
102
|
+
"class TestPostProcessor",
|
|
103
|
+
# ignore abstract base classes
|
|
104
|
+
"class .+\\((?:abc\\.)?ABC\\)",
|
|
105
|
+
# ignore storage provider initalizers
|
|
106
|
+
"def init_minio_client",
|
|
107
|
+
"def init_s3_client"
|
|
108
|
+
]
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from django.contrib import admin
|
|
2
|
+
|
|
3
|
+
from smoothglue.core.admin import DataAdmin
|
|
4
|
+
from smoothglue.map.models import ImageryLayer
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ImageryLayerAdmin(DataAdmin):
|
|
8
|
+
list_display = (
|
|
9
|
+
"name",
|
|
10
|
+
"provider_type",
|
|
11
|
+
"is_active",
|
|
12
|
+
)
|
|
13
|
+
list_editable = ("is_active",)
|
|
14
|
+
list_filter = ("provider_type",)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
admin.site.register(ImageryLayer, ImageryLayerAdmin)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"model": "map.imagerylayer",
|
|
4
|
+
"pk": "021904c4-68f0-4207-8bee-9efed7ec56fe",
|
|
5
|
+
"fields": {
|
|
6
|
+
"name": "World Physical Map",
|
|
7
|
+
"url": "https://services.arcgisonline.com/arcgis/rest/services/World_Physical_Map/MapServer",
|
|
8
|
+
"provider_type": "AG",
|
|
9
|
+
"sort_order": 8
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"model": "map.imagerylayer",
|
|
14
|
+
"pk": "319836c0-2812-4454-8e26-137f4e80f8de",
|
|
15
|
+
"fields": {
|
|
16
|
+
"name": "NatGeo World Map",
|
|
17
|
+
"url": "https://services.arcgisonline.com/arcgis/rest/services/NatGeo_World_Map/MapServer",
|
|
18
|
+
"provider_type": "AG",
|
|
19
|
+
"sort_order": 7
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"model": "map.imagerylayer",
|
|
24
|
+
"pk": "421d599f-9898-4cac-bcb0-48c9d123a57f",
|
|
25
|
+
"fields": {
|
|
26
|
+
"name": "FAA Sectional",
|
|
27
|
+
"url": "https://tfsgis.tfs.tamu.edu/arcgis/rest/services/Aviation/FAA_Sectional_Charts/MapServer",
|
|
28
|
+
"provider_type": "AG",
|
|
29
|
+
"sort_order": 6
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"model": "map.imagerylayer",
|
|
34
|
+
"pk": "4835b616-f678-442c-a9ba-5b96eecdf405",
|
|
35
|
+
"fields": {
|
|
36
|
+
"name": "World Shaded Relief",
|
|
37
|
+
"url": "https://services.arcgisonline.com/arcgis/rest/services/World_Shaded_Relief/MapServer",
|
|
38
|
+
"provider_type": "AG",
|
|
39
|
+
"sort_order": 5
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"model": "map.imagerylayer",
|
|
44
|
+
"pk": "6667aa56-34b4-43fe-ab33-7da3d038ed6e",
|
|
45
|
+
"fields": {
|
|
46
|
+
"name": "World Street Map",
|
|
47
|
+
"url": "https://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer",
|
|
48
|
+
"provider_type": "AG",
|
|
49
|
+
"sort_order": 4
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"model": "map.imagerylayer",
|
|
54
|
+
"pk": "89fcdb03-eed9-4b23-a3e7-5fb1ec6ca56d",
|
|
55
|
+
"fields": {
|
|
56
|
+
"name": "World Topo Maps",
|
|
57
|
+
"url": "https://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer",
|
|
58
|
+
"provider_type": "AG",
|
|
59
|
+
"sort_order": 3
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"model": "map.imagerylayer",
|
|
64
|
+
"pk": "e4611332-23d9-4a08-96db-b7860ebc4d00",
|
|
65
|
+
"fields": {
|
|
66
|
+
"name": "World Terrain Base",
|
|
67
|
+
"url": "https://services.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer",
|
|
68
|
+
"provider_type": "NO",
|
|
69
|
+
"sort_order": 2
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"model": "map.imagerylayer",
|
|
74
|
+
"pk": "e6227ca5-9e8a-4793-9e63-d8ffa6e858b7",
|
|
75
|
+
"fields": {
|
|
76
|
+
"name": "World Imagery",
|
|
77
|
+
"url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
|
|
78
|
+
"provider_type": "AG",
|
|
79
|
+
"sort_order": 1
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Generated by Django 4.2.13 on 2024-06-18 00:51
|
|
2
|
+
|
|
3
|
+
import uuid
|
|
4
|
+
|
|
5
|
+
from django.db import migrations, models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Migration(migrations.Migration):
|
|
9
|
+
initial = True
|
|
10
|
+
|
|
11
|
+
dependencies = []
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.CreateModel(
|
|
15
|
+
name="ImageryLayer",
|
|
16
|
+
fields=[
|
|
17
|
+
(
|
|
18
|
+
"id",
|
|
19
|
+
models.UUIDField(
|
|
20
|
+
default=uuid.uuid4,
|
|
21
|
+
editable=False,
|
|
22
|
+
primary_key=True,
|
|
23
|
+
serialize=False,
|
|
24
|
+
unique=True,
|
|
25
|
+
),
|
|
26
|
+
),
|
|
27
|
+
("name", models.CharField(blank=True, max_length=64, unique=True)),
|
|
28
|
+
("url", models.CharField(blank=True, max_length=512)),
|
|
29
|
+
(
|
|
30
|
+
"provider_type",
|
|
31
|
+
models.CharField(
|
|
32
|
+
choices=[
|
|
33
|
+
("NO", "None"),
|
|
34
|
+
("AG", "ArcGis Map Server"),
|
|
35
|
+
("TL", "Tile Map Service"),
|
|
36
|
+
("BG", "Bing Map Imagery"),
|
|
37
|
+
("GG", "Google Earth Enterprise"),
|
|
38
|
+
("OS", "Open Street Map"),
|
|
39
|
+
("WM", "Web Map Tile Service"),
|
|
40
|
+
("UT", "Url Template Imagery"),
|
|
41
|
+
("GO", "Geo Server"),
|
|
42
|
+
],
|
|
43
|
+
default="NO",
|
|
44
|
+
max_length=2,
|
|
45
|
+
),
|
|
46
|
+
),
|
|
47
|
+
("sort_order", models.IntegerField(blank=True, null=True)),
|
|
48
|
+
("is_active", models.BooleanField(default=True)),
|
|
49
|
+
],
|
|
50
|
+
),
|
|
51
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
|
|
3
|
+
from django.db import models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ImageryLayer(models.Model):
|
|
7
|
+
class MapImageryProviderType(models.TextChoices):
|
|
8
|
+
NONE = "NO", "None"
|
|
9
|
+
ARCGIS = "AG", "ArcGis Map Server"
|
|
10
|
+
TILE = "TL", "Tile Map Service"
|
|
11
|
+
BING = "BG", "Bing Map Imagery"
|
|
12
|
+
GOOGLE = "GG", "Google Earth Enterprise"
|
|
13
|
+
OPEN = "OS", "Open Street Map"
|
|
14
|
+
WEBMAP = "WM", "Web Map Tile Service"
|
|
15
|
+
URL = "UT", "Url Template Imagery"
|
|
16
|
+
GEO = "GO", "Geo Server"
|
|
17
|
+
|
|
18
|
+
id = models.UUIDField(
|
|
19
|
+
primary_key=True, unique=True, default=uuid.uuid4, editable=False
|
|
20
|
+
)
|
|
21
|
+
name = models.CharField(max_length=64, unique=True, blank=True, null=False)
|
|
22
|
+
url = models.CharField(max_length=512, blank=True, null=False)
|
|
23
|
+
provider_type = models.CharField(
|
|
24
|
+
max_length=2,
|
|
25
|
+
choices=MapImageryProviderType.choices,
|
|
26
|
+
default=MapImageryProviderType.NONE,
|
|
27
|
+
)
|
|
28
|
+
sort_order = models.IntegerField(blank=True, null=True)
|
|
29
|
+
is_active = models.BooleanField(default=True)
|
|
30
|
+
|
|
31
|
+
def __str__(self) -> str:
|
|
32
|
+
return f"{self.name} - {self.provider_type}"
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
|
|
3
|
+
from smoothglue.core.serializers.dynamic import DynamicModelSerializer
|
|
4
|
+
from smoothglue.map.models import ImageryLayer
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ImageryLayerSerializer(DynamicModelSerializer):
|
|
8
|
+
|
|
9
|
+
provider_type = serializers.CharField(
|
|
10
|
+
source="get_provider_type_display", read_only=True
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
class Meta:
|
|
14
|
+
model = ImageryLayer
|
|
15
|
+
fields = ["id", "name", "url", "provider_type", "sort_order", "is_active"]
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# boot_django.py
|
|
2
|
+
#
|
|
3
|
+
# This file sets up and configures Django. It's used by scripts that need to
|
|
4
|
+
# execute as if running in a Django server.
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
import django
|
|
8
|
+
from django.conf import settings
|
|
9
|
+
|
|
10
|
+
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "smoothglue/map"))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def boot_django():
|
|
14
|
+
# The settings.configure() call takes a list of args that are equivalent to variables
|
|
15
|
+
# defined in a settings.py file.
|
|
16
|
+
# Anything you would need in your settings.py to make your app run gets passed here
|
|
17
|
+
settings.configure(
|
|
18
|
+
BASE_DIR=BASE_DIR,
|
|
19
|
+
DEBUG=True,
|
|
20
|
+
DATABASES={
|
|
21
|
+
"default": {
|
|
22
|
+
"ENGINE": "django.db.backends.sqlite3",
|
|
23
|
+
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
INSTALLED_APPS=[
|
|
27
|
+
"django.contrib.contenttypes",
|
|
28
|
+
"django.contrib.auth",
|
|
29
|
+
"smoothglue.map",
|
|
30
|
+
],
|
|
31
|
+
TIME_ZONE="UTC",
|
|
32
|
+
USE_TZ=True,
|
|
33
|
+
)
|
|
34
|
+
django.setup()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from unittest import TestSuite
|
|
5
|
+
|
|
6
|
+
from smoothglue.map.tests.boot_django import boot_django
|
|
7
|
+
|
|
8
|
+
boot_django()
|
|
9
|
+
|
|
10
|
+
default_labels = ["smoothglue/map/tests"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_suite(labels=default_labels):
|
|
14
|
+
from django.test.runner import DiscoverRunner
|
|
15
|
+
|
|
16
|
+
runner = DiscoverRunner(verbosity=1)
|
|
17
|
+
failures = runner.run_tests(labels)
|
|
18
|
+
if failures:
|
|
19
|
+
sys.exit(failures)
|
|
20
|
+
|
|
21
|
+
# In case this is called from setuptools, return a test suite
|
|
22
|
+
return TestSuite()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
if __name__ == "__main__":
|
|
26
|
+
labels = default_labels
|
|
27
|
+
if len(sys.argv[1:]) > 0:
|
|
28
|
+
labels = sys.argv[1:]
|
|
29
|
+
|
|
30
|
+
get_suite(labels)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from django.test import TestCase
|
|
2
|
+
|
|
3
|
+
from smoothglue.map.utils.coordinate_utils import get_decimal_degrees_from_dms_string
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestCoordinateUtilsSerializer(TestCase):
|
|
7
|
+
|
|
8
|
+
def test_serializer_valid(self):
|
|
9
|
+
|
|
10
|
+
coordinate_str = "373420.50N1272218.92E"
|
|
11
|
+
result = get_decimal_degrees_from_dms_string(coordinate_str)
|
|
12
|
+
self.assertEqual(result, [127.37192222222221, 37.572361111111114])
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from django.test import TestCase
|
|
2
|
+
|
|
3
|
+
from smoothglue.core.tests.utils import CommonSerializer
|
|
4
|
+
from smoothglue.map.models import ImageryLayer
|
|
5
|
+
from smoothglue.map.serializers.imagery_layer import ImageryLayerSerializer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestImageryLayerJsonSerializer(TestCase):
|
|
9
|
+
def setUp(self):
|
|
10
|
+
self.image_layer_data = {
|
|
11
|
+
"name": "test",
|
|
12
|
+
"url": "http://braingu.com",
|
|
13
|
+
"provider_type": "ArcGisMapServerImageryProvider",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
self.required_fields = []
|
|
17
|
+
|
|
18
|
+
def test_serializer_valid(self):
|
|
19
|
+
CommonSerializer(serializer=ImageryLayerSerializer).test_model_serializer_valid(
|
|
20
|
+
model=ImageryLayer,
|
|
21
|
+
required_fields=self.required_fields,
|
|
22
|
+
data=self.image_layer_data,
|
|
23
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from django.urls import include, path
|
|
2
|
+
from rest_framework import routers
|
|
3
|
+
|
|
4
|
+
from smoothglue.map import views
|
|
5
|
+
|
|
6
|
+
ROUTER = routers.DefaultRouter()
|
|
7
|
+
|
|
8
|
+
ROUTER.register(
|
|
9
|
+
r"imagelayersviews", views.ImageryLayerViewset, basename="imagelayersviews"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
urlpatterns = [path("", include(ROUTER.urls))]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def get_decimal_degrees_from_dms_string(dms_string):
|
|
5
|
+
"""
|
|
6
|
+
Convert set data representing lat lon as a Degree Minute Second (DMS) value to Decimal Degrees
|
|
7
|
+
using formula: Decimal Degrees = degrees + (minutes/60) + (seconds/3600)
|
|
8
|
+
|
|
9
|
+
ACO coordinate set data comes in 2 varieties:
|
|
10
|
+
LATS (e.g. LATS:431026N1165028W) and LATM (e.g. LATM:4302N11553W)
|
|
11
|
+
Assumptions:
|
|
12
|
+
LATS format is Degrees Minutes Seconds and broken down as follows:
|
|
13
|
+
Index: 0 1 2 3 4 5 6 7
|
|
14
|
+
LATS: 43 10 26 N 116 50 28 W
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
index_dict = {
|
|
18
|
+
"lat_degree_index": 0,
|
|
19
|
+
"lat_minute_index": 1,
|
|
20
|
+
"lat_second_index": 2,
|
|
21
|
+
"lat_millisecond_index": 3,
|
|
22
|
+
"lat_direction_index": 4,
|
|
23
|
+
"lon_degree_index": 5,
|
|
24
|
+
"lon_minute_index": 6,
|
|
25
|
+
"lon_second_index": 7,
|
|
26
|
+
"lon_millisecond_index": 8,
|
|
27
|
+
"lon_direction_index": 9,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
pattern = r"\s*(\d{2})+(\d{2})+(\d{2})+(\.\d{2})+([N|S])*(\d{3})+(\d{2})+(\d{2})+(\.\d{2})+([E|W])"
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
lat_lon_set = re.findall(pattern, dms_string)[0]
|
|
34
|
+
except IndexError as exc:
|
|
35
|
+
raise ValueError(
|
|
36
|
+
f"There was an error parsing coordinate: {dms_string}."
|
|
37
|
+
) from exc
|
|
38
|
+
|
|
39
|
+
lat_decimal = (
|
|
40
|
+
int(lat_lon_set[index_dict["lat_degree_index"]])
|
|
41
|
+
+ int(lat_lon_set[index_dict["lat_minute_index"]]) / 60
|
|
42
|
+
)
|
|
43
|
+
lon_decimal = (
|
|
44
|
+
int(lat_lon_set[index_dict["lon_degree_index"]])
|
|
45
|
+
+ int(lat_lon_set[index_dict["lon_minute_index"]]) / 60
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
lat_decimal += (
|
|
49
|
+
float(
|
|
50
|
+
lat_lon_set[index_dict["lat_second_index"]]
|
|
51
|
+
+ lat_lon_set[index_dict["lat_millisecond_index"]]
|
|
52
|
+
)
|
|
53
|
+
/ 3600
|
|
54
|
+
)
|
|
55
|
+
lon_decimal += (
|
|
56
|
+
float(
|
|
57
|
+
lat_lon_set[index_dict["lon_second_index"]]
|
|
58
|
+
+ lat_lon_set[index_dict["lon_millisecond_index"]]
|
|
59
|
+
)
|
|
60
|
+
/ 3600
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
if (
|
|
64
|
+
lat_lon_set[index_dict["lon_direction_index"]] == "S"
|
|
65
|
+
or lat_lon_set[index_dict["lon_direction_index"]] == "W"
|
|
66
|
+
):
|
|
67
|
+
lon_decimal *= -1
|
|
68
|
+
|
|
69
|
+
# GeoJSON coordinates are in (lon, lat) format
|
|
70
|
+
return [lon_decimal, lat_decimal]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from django_filters.rest_framework import DjangoFilterBackend
|
|
2
|
+
|
|
3
|
+
from smoothglue.core.views import ListModelViewSet
|
|
4
|
+
from smoothglue.map.models import ImageryLayer
|
|
5
|
+
from smoothglue.map.serializers.imagery_layer import ImageryLayerSerializer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ImageryLayerViewset(ListModelViewSet):
|
|
9
|
+
filter_backends = [DjangoFilterBackend]
|
|
10
|
+
queryset = ImageryLayer.objects.filter(is_active=True).order_by("sort_order")
|
|
11
|
+
serializer_class = ImageryLayerSerializer
|