Compare commits

..

No commits in common. "master" and "2.6.2" have entirely different histories.

527 changed files with 32610 additions and 40609 deletions

View file

@ -5,7 +5,7 @@
"es6": true
},
"parserOptions": {
"ecmaVersion": 2021,
"ecmaVersion": 2020,
"sourceType": "module"
}
}

View file

@ -1,23 +0,0 @@
# Doc: https://github.com/marketplace/actions/close-stale-issues
name: Close inactive issues
on:
schedule:
- cron: "30 1 * * *"
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/stale@v5
with:
days-before-issue-stale: 30
days-before-issue-close: 14
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1
repo-token: ${{ secrets.GITHUB_TOKEN }}
any-of-labels: need infos,support

View file

@ -1,26 +0,0 @@
name: Release Charts
on:
push:
branches:
- master
jobs:
release:
# depending on default permission settings for your org (contents being read-only or read-write for workloads), you will have to add permissions
# see: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Publish Helm charts
uses: stefanprodan/helm-gh-pages@v1.7.0
with:
charts_dir: charts
linting: off
token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -4,9 +4,7 @@ on:
push:
branches: [master]
pull_request:
path:
- umap/*
- pyproject.toml
branches: [master]
jobs:
tests:
@ -22,11 +20,7 @@ jobs:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis
options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
ports:
- 6379:6379
strategy:
fail-fast: false
matrix:
@ -54,8 +48,6 @@ jobs:
DJANGO_SETTINGS_MODULE: 'umap.tests.settings'
UMAP_SETTINGS: 'umap/tests/settings.py'
PLAYWRIGHT_TIMEOUT: '20000'
REDIS_HOST: localhost
REDIS_PORT: 6379
lint:
runs-on: ubuntu-latest
steps:
@ -63,7 +55,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
python-version: '3.11'
- name: Install dependencies
run: |
python3 -m pip install -e .[test,dev]
@ -74,3 +66,18 @@ jobs:
- name: Run Docs
run: make docs
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python3 -m pip install -r docs/requirements.txt
- name: Run Docs
run: mkdocs build

6
.gitignore vendored
View file

@ -10,7 +10,6 @@ node_modules
umap.conf
/data
/static
package-lock.json
### Python ###
# Byte-compiled / optimized / DLL files
@ -25,8 +24,3 @@ test-results/
### Transifex ###
tx
# Helm
charts/*/charts
helmfile.yaml
charts/*/Chart.lock

View file

@ -1,9 +1,10 @@
# This part installs deps needed at runtime.
FROM python:3.12-slim AS common
FROM python:3.11-slim AS common
RUN apt-get update && \
apt-get install -y --no-install-recommends \
tini \
uwsgi \
sqlite3 \
libpq-dev \
gdal-bin \
@ -38,7 +39,7 @@ WORKDIR /srv/umap
COPY . /srv/umap
RUN /venv/bin/pip install .[docker,s3,sync]
RUN /venv/bin/pip install .[docker]
FROM common

View file

@ -7,7 +7,7 @@ install: ## Install the dependencies
.PHONY: develop
develop: ## Install the test and dev dependencies
python3 -m pip install -e .[test,dev,sync,s3]
python3 -m pip install -e .[test,dev]
playwright install
.PHONY: format
@ -46,13 +46,6 @@ docker: ## Create a new Docker image and publish it
docker build -t umap/umap:${VERSION} .
docker push umap/umap:${VERSION}
.PHONY: helm
helm: ## Build the helm chart and publish it
$(eval VERSION=$(shell hatch version))
$(eval PACKAGE=$(shell helm package --dependency-update --app-version ${VERSION} ./charts/umap | grep "Successfully packaged" | awk '{print $$NF}'))
@echo "Successfully packaged helm chart in: ${PACKAGE}"
helm push ${PACKAGE} oci://registry-1.docker.io/umap
.PHONY: build
build: ## Build the Python package before release
@hatch build --clean
@ -65,7 +58,7 @@ publish: ## Publish the Python package to Pypi
test: testpy testjs
testpy:
pytest -vv umap/tests/ --dist=loadgroup --reruns 1 --maxfail 10
pytest -vv umap/tests/ --dist=loadgroup
test-integration:
pytest -xv umap/tests/integration/ --dist=loadgroup
@ -89,10 +82,6 @@ tx_push:
tx push -s
tx_pull:
tx pull
changelog:
$(eval VERSION=$(shell hatch version))
@# Bearer token is readonly
@printf $(shell curl -sL -X POST -H "Authorization: Bearer ${GITHUB_TOKEN}" https://api.github.com/repos/umap-project/umap/releases/generate-notes -d '{"target_commitish":"master","previous_tag_name":"", "tag_name": "${VERSION}"}' | jq .body | sed 's/https:\/\/github.com\/umap-project\/umap\/pull\//#/g' | sed 's/`/\\`/g')
jsdir = umap/static/umap/js/
filepath = "${jsdir}*.js"

View file

@ -1,8 +1,4 @@
{
"files": {
"include": ["umap/static/umap/js/**"],
"ignore": ["umap/static/umap/vendors/**"]
},
"formatter": {
"enabled": true,
"formatWithErrors": false,
@ -18,11 +14,7 @@
"rules": {
"style": {
"useBlockStatements": "off",
"noShoutyConstants": "warn",
"noParameterAssign": "off"
},
"complexity": {
"noForEach": "off"
"noShoutyConstants": "warn"
},
"performance": {
"noDelete": "off"

View file

@ -1,23 +0,0 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View file

@ -1,16 +0,0 @@
apiVersion: v2
name: umap
description: A Helm chart to deploy umap on Kubernetes
type: application
version: 0.1.0
appVersion: "2.7.2"
dependencies:
- name: cnpg-cluster
version: 2.0.1
repository: https://charts.enix.io/
alias: cnpg
condition: cnpg.enabled

View file

@ -1,73 +0,0 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "umap.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "umap.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "umap.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "umap.labels" -}}
helm.sh/chart: {{ include "umap.chart" . }}
{{ include "umap.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "umap.selectorLabels" -}}
app.kubernetes.io/name: {{ include "umap.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "umap.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "umap.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Get the name of the persistent volume claim
*/}}
{{- define "umap.pvcName" -}}
{{- if .Values.persistence.existingClaim -}}
{{- printf "%s" (tpl .Values.persistence.existingClaim $) -}}
{{- else -}}
{{- printf "%s" (include "umap.fullname" .) -}}
{{- end -}}
{{- end -}}

View file

@ -1,110 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "umap.fullname" . }}
labels:
{{- include "umap.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "umap.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/secret-config.yaml") . | sha256sum }}
checksum/env: {{ include (print $.Template.BasePath "/secret-env.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "umap.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "umap.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.port }}
protocol: TCP
startupProbe:
httpGet:
path: /stats
port: http
livenessProbe:
httpGet:
path: /stats
port: http
readinessProbe:
httpGet:
path: /stats
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- if .Values.cnpg.enabled }}
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: {{ .Release.Name }}-cnpg-app
key: uri
- name: UMAP_SETTINGS
value: /etc/umap/umap.conf
{{- end }}
envFrom:
- secretRef:
{{- if .Values.umap.envFromSecret }}
name: {{ .Values.umap.envFromSecret }}
{{- else }}
name: {{ include "umap.fullname" . }}-env
{{- end }}
volumeMounts:
- name: config
mountPath: /etc/umap/
readOnly: true
- name: statics
mountPath: /srv/umap/static
{{- if .Values.persistence.enabled }}
- name: data
mountPath: /srv/umap/uploads/
{{- end }}
volumes:
- name: config
secret:
{{- if .Values.umap.configFromSecret }}
secretName: {{ .Values.umap.configFromSecret }}
{{- else }}
secretName: {{ include "umap.fullname" . }}-config
{{- end }}
- name: statics
emptyDir: {}
{{- if .Values.persistence.enabled }}
- name: data
persistentVolumeClaim:
claimName: {{ include "umap.pvcName" . }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View file

@ -1,31 +0,0 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "umap.fullname" . }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ingressClassName: {{ .Values.ingress.className }}
tls:
- hosts:
{{- range .Values.ingress.hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ include "umap.fullname" . }}-tls
rules:
{{- range .Values.ingress.hosts }}
- host: {{ . | quote }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ include "umap.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}

View file

@ -1,24 +0,0 @@
{{- if and (.Values.persistence.enabled) (not .Values.persistence.existingClaim) }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
{{- if .Values.persistence.annotations }}
annotations:
{{- toYaml .Values.persistence.annotations | nindent 4 }}
{{- end }}
name: {{ include "umap.pvcName" . }}
labels:
{{- include "umap.labels" . | nindent 4 }}
spec:
accessModes:
{{- range .Values.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
{{- with .Values.persistence.resources }}
resources:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if .Values.persistence.storageClassName }}
storageClassName: {{ .Values.persistence.storageClassName | quote }}
{{- end }}
{{- end }}

View file

@ -1,11 +0,0 @@
{{ if not .Values.umap.configFromSecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "umap.fullname" . }}-config
labels:
{{- include "umap.labels" . | nindent 4 }}
type: Opaque
data:
umap.conf: {{ .Values.umap.config | b64enc }}
{{- end }}

View file

@ -1,13 +0,0 @@
{{ if not .Values.umap.envFromSecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "umap.fullname" . }}-env
labels:
{{- include "umap.labels" . | nindent 4 }}
type: Opaque
data:
{{- range $key, $value := .Values.umap.environment }}
{{ $key }}: "{{ $value | b64enc }}"
{{- end }}
{{- end }}

View file

@ -1,15 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "umap.fullname" . }}
labels:
{{- include "umap.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "umap.selectorLabels" . | nindent 4 }}

View file

@ -1,13 +0,0 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "umap.serviceAccountName" . }}
labels:
{{- include "umap.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
{{- end }}

View file

@ -1,125 +0,0 @@
# Default values for umap.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: umap/umap
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Automatically mount a ServiceAccount's API credentials?
automount: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podLabels: {}
podSecurityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
service:
type: ClusterIP
port: 8000
ingress:
enabled: false
className: ""
annotations: {}
hosts:
- example.org
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
umap:
# Set environment variables supported by umap here
# see: https://docs.umap-project.org/en/stable/config/settings/
environment:
SECRET_KEY: CHANGE_ME
STATIC_ROOT: /srv/umap/static
MEDIA_ROOT: /srv/umap/uploads
# Configure environment variables using an existing secret in the same namespace.
# In this case the values above are not used
envFromSecret: null
# You can also provide umap.conf content here:
config: |
from umap.settings.base import *
# See: https://github.com/umap-project/umap/blob/master/umap/settings/local.py.sample
# Configure config file using an existing secret in the same namespace.
# In this case the values above are not used
configFromSecret: null
persistence:
enabled: true
accessModes:
- ReadWriteOnce
annotations: {}
existingClaim: ""
storageClassName: ""
resources:
requests:
storage: 1Gi
# Configure Cloudnative-pg operator for Postgis database
# Alternatively, you can disable CNPG and provide your own
# Postgis database by setting the `umap.environment.DATABASE_URL`
cnpg:
enabled: true
replicaCount: 2
image:
repository: ghcr.io/cloudnative-pg/postgis
tag: 14
persistence:
storageClass: ""
size: 1Gi
clusterExtraSpec:
bootstrap:
initdb:
postInitTemplateSQL:
- CREATE EXTENSION postgis;
- CREATE EXTENSION postgis_topology;
- CREATE EXTENSION fuzzystrmatch;
- CREATE EXTENSION postgis_tiger_geocoder;
# See available values here: https://artifacthub.io/packages/helm/enix/cnpg-cluster?modal=values

View file

@ -1,14 +1,6 @@
services:
version: '3'
# Usefull only to use the real time collaboration
redis:
image: redis:latest
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 1s
timeout: 3s
retries: 5
command: ["redis-server"]
services:
db:
healthcheck:
@ -24,35 +16,18 @@ services:
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
image: umap/umap:3.0.2
image: umap/umap:2.0.2
ports:
- "${PORT-8000}:8000"
environment:
- STATIC_ROOT=/srv/umap/static
- MEDIA_ROOT=/srv/umap/uploads
- DATABASE_URL=postgis://postgres@db/postgres
- SECRET_KEY=some-long-and-weirdly-unrandom-secret-key
- SITE_URL=https://umap.local/
- UMAP_ALLOW_ANONYMOUS=True
- DEBUG=1
- REALTIME_ENABLED=1
- REDIS_URL=redis://redis:6379
volumes:
- data:/srv/umap/uploads
- static:/srv/umap/static
proxy:
image: nginx:latest
ports:
- "8000:80"
volumes:
- ./docker/nginx.conf:/etc/nginx/nginx.conf:ro
- static:/static:ro
- data:/data:ro
depends_on:
- app
volumes:
data:
static:
db:

View file

@ -9,5 +9,5 @@ umap collectstatic --noinput
umap wait_for_database
# then migrate the database
umap migrate
# run the server
exec uvicorn --proxy-headers --no-access-log --host 0.0.0.0 umap.asgi:application
# run uWSGI
exec uwsgi --ini docker/uwsgi.ini

View file

@ -1,111 +0,0 @@
events {
worker_connections 1024; # Adjust this to your needs
}
http {
proxy_cache_path /tmp/nginx_ajax_proxy_cache levels=1:2 keys_zone=ajax_proxy:10m inactive=60m;
proxy_cache_key "$uri$is_args$args";
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
types {
application/javascript mjs;
}
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# Server block
server {
listen 80;
server_name localhost;
# Static file serving
location /static/ {
alias /static/;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
expires 365d;
access_log /dev/null;
}
# Geojson files
location /uploads/ {
alias /data/;
expires 30d;
}
location /favicon.ico {
alias /static/favicon.ico;
}
# X-Accel-Redirect
location /internal/ {
internal;
gzip_vary on;
gzip_static on;
add_header X-DataLayer-Version $upstream_http_x_datalayer_version;
alias /data/;
}
# Ajax proxy
location ~ ^/proxy/(.*) {
internal;
add_header X-Proxy-Cache $upstream_cache_status always;
proxy_cache_background_update on;
proxy_cache_use_stale updating;
proxy_cache ajax_proxy;
proxy_cache_valid 1m; # Default. Umap will override using X-Accel-Expires
set $target_url $1;
# URL is encoded, so we need a few hack to clean it back.
if ( $target_url ~ (.+)%3A%2F%2F(.+) ){ # fix :// between scheme and destination
set $target_url $1://$2;
}
if ( $target_url ~ (.+?)%3A(.*) ){ # fix : between destination and port
set $target_url $1:$2;
}
if ( $target_url ~ (.+?)%2F(.*) ){ # fix / after port, the rest will be decoded by proxy_pass
set $target_url $1/$2;
}
resolver 8.8.8.8;
add_header X-Proxy-Target $target_url; # For debugging
proxy_pass_request_headers off;
proxy_set_header Content-Type $http_content_type;
proxy_set_header Content-Encoding $http_content_encoding;
proxy_set_header Content-Length $http_content_length;
proxy_read_timeout 10s;
proxy_connect_timeout 5s;
proxy_ssl_server_name on;
proxy_pass $target_url;
proxy_intercept_errors on;
error_page 301 302 307 = @handle_proxy_redirect;
}
location @handle_proxy_redirect {
resolver 8.8.8.8;
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
# Proxy pass to ASGI server
location / {
proxy_pass http://app:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_buffering off;
}
}
}

12
docker/uwsgi.ini Normal file
View file

@ -0,0 +1,12 @@
[uwsgi]
http = :$(PORT)
home = /venv
module = umap.wsgi:application
master = True
vacuum = True
max-requests = 5000
processes = 4
enable-threads = true
static-map = /static=/srv/umap/static
static-map = /uploads=/srv/umap/uploads
buffer-size = 32768

View file

@ -1,11 +1,5 @@
# Articles
## [Créer des cartes interactives personnalisées : uMap ou Leaflet ?](https://www.d-booker.fr/content/242-creer-des-cartes-interactives-personnalisees-umap-ou-leaflet) (2025-02-01)
> Dans ce guide, nous comparerons deux solutions libres populaires : uMap, une plateforme en ligne intuitive, et Leaflet, une bibliothèque JavaScript puissante.
[Article complet →](https://www.d-booker.fr/content/242-creer-des-cartes-interactives-personnalisees-umap-ou-leaflet){ .md-button }
## [Vers uMap 3 😱](https://www.openstreetmap.org/user/David%20Larlet/diary/404654#vers-umap-3-) (2024-07-16)
> La dernière version 2.4.X ouvre la voie à deux fonctionnalités majeures demandées : la collaboration en temps réel et les assistants dimport de données à distance en un clic.

View file

@ -77,7 +77,6 @@ Toute propriété de l'élément sera disponible, ainsi que:
- `{locale}` → la langue sous la forme `fr` ou `fr_CA` quand une variante est utilisée
- `{lang}` → la langue sous la forme `fr` ou `fr-ca` quand une variante est utilisée
- `{measure}` → la longueur d'une ligne ou la surface d'un polygone
- `{gain}`/`{loss}` → la dénivelée positive/négative d'une ligne (seulement si elle contient les altitudes)
- `{rank}` → la rang d'un élément dans son calque
- `{layer}` → le nom du calque de l'élément
- `{zoom}` → le zoom actuel de la carte
@ -92,27 +91,3 @@ Toute propriété de l'élément sera disponible, ainsi que:
- `{zoom}` → le zoom actuel de la carte
- `{lat}` → la latitude du centre actuel de la carte
- `{lng}` → la longitude du centre actuel de la carte
## Quels statuts peut avoir une carte ? {: #map-statuses}
### En accès
* **Brouillon (privé)**: Vous seul et votre équipe pouvez accéder à la carte.
* **Tout le monde (public)**: Tout le monde peut accéder à la carte, qui est visible dans la recherche et la page daccueil. La carte est indexée dans les moteurs de recherche (Google, etc.).
* **Quiconque a le lien**: La carte est visible par toutes les personnes qui en ont le lien. Elle nest pas indexée dans les moteurs de recherche.
* **Éditeurs et équipe seulement**: Vous seul et votre équipe pouvez accéder à la carte.
Les personnes affichant une carte à laquelle elles nont pas accès auront une page derreur 403.
### En édition
* **Propriétaire uniquement**: Vous seul pouvez modifier la carte.
* **Éditeurs et équipe seulement**: Vous seul et votre équipe pouvez modifier la carte.
* **Tout le monde**: Tout le monde peut modifier la carte, même les comptes anonymes.
Pour les cartes créées sans compte :
* **Modifiable seulement avec le lien dédition secret**: Seules les personnes avec un lien dédition pourront modifier la carte.
Ces réglages sont aussi disponibles pour chaque calque.

View file

@ -7,7 +7,6 @@
- Utiliser un portail *open data*
- Créditer la source des données pour respecter la licence
## Procédons par étapes
Jusquici toutes les cartes que nous avons créées montrent des données
@ -157,11 +156,8 @@ calque*. Les différents types de calques sont :
cercle.
- **Heatmap** : les données sont représentées sous forme de *carte de
chaleur*.
- **Choroplèthe** : cet affichage est adapté aux polygones, et permet
- **Cloroplèthe** : cet affichage est adapté aux polygones, et permet
de graduer leur couleur.
- **Cercles proportionnels** : cette représentation est adaptée pour
des valeurs quantitatives absolues (qui peuvent sajouter).
La surface des cercles est proportionnelle à la quantité.
Les types *Avec cluster* et *Heatmap* sont plutôt adaptés aux calques
contenant uniquement des points. Lorsquon choisit un de ces modes, un

View file

@ -1,141 +0,0 @@
!!! abstract "Ce que nous allons apprendre"
- Créer un gabarit Grist compatible uMap
- Géocoder des adresses (:fontawesome-solid-landmark-flag: pour les agents publics seulement)
- Rendre un document Grist public
- Lier le CSV de Grist avec un calque uMap
Un [un film tutoriel](https://tube.numerique.gouv.fr/w/kya6m1aFtgDcy2LMkgUBya?start=12s)
a été créé pour montrer le déroulé de ce tutoriel.
## 1. Créer un gabarit Grist compatible uMap
!!! osm-instance "Pour le grand public, les associations…"
Rendez-vous sur le [site officiel de Grist](https://www.getgrist.com/) ou votre propre instance.
!!! french-instance "Pour les agents publics"
Rendez-vous sur le site Grist agents publics via
[La Suite Numérique](https://lasuite.numerique.gouv.fr/services/grist).
Créer un nouveau document vide :
![Interface pour créer un nouveau document Grist.](../../static/tutoriels/grist-new-document.png)
Ajouter les colonnes nécessaires, plus au moins ces trois colonnes : `Adresse`, `Latitude`, `Longitude`.
![Interface dun nouveau document Grist vide.](../../static/tutoriels/grist-empty-document.png)
!!! warning
Attention, il faut mettre les colonnes `Latitude` et `Longitude` en type `Texte` :
![Interface pour renseigner le type des colonnes.](../../static/tutoriels/grist-column-type-text.png)
## 2. Géocoder des adresses (:fontawesome-solid-landmark-flag: pour les agents publics seulement)
!!! french-instance "Pour les agents publics"
Cette conversion nest accessible quaux agents publics, elle consiste
à convertir automatiquement les adresses en coordonnées géographiques
(latitude, longitude). Si vous avez déjà ces informations dans votre
document, vous pouvez passer à létape 3 ci-dessous.
Il faut maintenant ajouter loutil de géocodage développé par lANCT.
Pour ça, cliquer sur « Ajouter une vue à la page » :
![Interface pour créer une vue Grist.](../../static/tutoriels/grist-empty-view.png)
Puis choisir `Custom`, sélectionner le nom de la table dans la source des données
(ici « Table1 »), et aussi sélectionner la table dans `Select by` :
![Interface pour créer une vue custom Grist.](../../static/tutoriels/grist-custom-view.png)
Dans la colonne de droite, si on est sur linstance Grist de lANCT,
choisir « Geocodeur » dans la liste déroulante,
sinon choisir `Custom URL` et ajouter lURL suivante:
<https://betagouv.github.io/grist-custom-widgets-fr-admin/geocode>
Dans le panneau de droite, sélectionner les colonnes permettant de connecter
loutil à notre tableau :
![Interface pour associer les colonnes sur une vue Grist.](../../static/tutoriels/grist-columns-view.png)
La colonne `Adresse` comme source, puis bien référence les colonnes `Latitude` et `Longitude`.
On peut optionnellement ajouter une colonne `Adresse normalisée` (dans le tableur)
et la référencer ici, dans ce cas le géocodeur affichera ladresse quil a trouvé.
Ça permet un contrôle de plus.
Renseigner ensuite une ou plusieurs lignes de données,
en essayant davoir une adresse aussi précise que possible :
![Interface pour convertir via une vue Grist.](../../static/tutoriels/grist-conversion-view.png)
Puis cliquer sur « Traitement spécifique » pour ne traiter
que la ligne sélectionnée, ou bien sur « Traitement global »
pour traiter toutes les lignes du document.
![Interface pour convertir via une vue Grist (résultat).](../../static/tutoriels/grist-conversion-view-result.png)
## 3. Rendre un document Grist public
Il faut ensuite rendre le document Grist public pour pouvoir ensuite le référencer côté uMap.
Pour ça, aller dans « Gérer les utilisateurs » :
![Interface pour gérer les utilisateurs dans Grist.](../../static/tutoriels/grist-user-management.png)
Puis activer laccès public :
![Interface pour ouvrir les permissions dans Grist.](../../static/tutoriels/grist-permissions-management.png)
## 4. Lier le CSV de Grist avec un calque uMap
Pour copier lURL quon va indiquer côté uMap, cest ici
(clic droit « enregistrer le lien ») :
![Interface pour copier le lien vers lexport CSV dans Grist.](../../static/tutoriels/grist-download-csv.png)
Le lien devrait ressembler à quelque chose comme ça :
https://grist.incubateur.net/o/docs/api/docs/4McELEs6kBpQAkmzupHy9F/download/csv?viewSection=1&tableId=Table1&activeSortSpec=%5B%5D&filters=%5B%5D&linkingFilter=%7B%22filters%22%3A%7B%7D%2C%22operations%22%3A%7B%7D%7D
Maintenant, créer une carte sur uMap et ajouter un calque :
![Interface pour ajouter un calque dans uMap.](../../static/tutoriels/grist-umap-newlayer.png)
![Interface pour ajouter un calque dans uMap avec un nom.](../../static/tutoriels/grist-umap-newlayer-name.png)
Dans « Données distantes », ajouter lURL de Grist et choisir le format `CSV` :
![Interface pour ajouter un calque dans uMap avec une URL.](../../static/tutoriels/grist-umap-newlayer-url.png)
Pour une meilleure expérience utilisateurs, vous pouvez choisir
loption `Proxy` avec un cache de la bonne durée selon la fréquence
de mise à jour des données dans Grist :
![Interface pour ajouter un calque dans uMap avec un proxy.](../../static/tutoriels/grist-umap-newlayer-proxy.png)
Pour améliorer l'intégration des données, allez dans les paramètres avancés
de la carte, puis dans les propriétés par défaut et :
- ajouter `Nom` comme clé pour le libellé, le filtre et la recherche
- ajouter `Catégorie` pour générer des filtres automatiques
![Interface pour ajouter un calque avec des filtres dans uMap.](../../static/tutoriels/grist-umap-newlayer-advanced.png)
Et voilà !
![Interface de la carte finale dans uMap.](../../static/tutoriels/grist-umap-result.png)

View file

@ -11,14 +11,8 @@ lieux (domicile, vacances, travail, etc.). Procédons par étapes.
### 1. Le mode édition
!!! osm-instance "Pour le grand public, les associations…"
Rendez-vous sur linstance uMap dOSM <https://umap.openstreetmap.fr/>
!!! french-instance "Pour les agents publics"
Rendez-vous sur le site uMap agents publics <https://umap.incubateur.anct.gouv.fr/>
et connectez-vous en haut à gauche. La connexion utilise ProConnect.
Rendez-vous sur le site <http://umap.openstreetmap.fr/> et cliquez sur
le bouton **Créer une carte** suivant :
<shot-scraper
data-output="static/tutoriels/create-map.png"
@ -89,8 +83,6 @@ reviendrons.
Maintenant, sauvegardez la carte avec le bouton **Enregistrer** : un
texte est affiché en haut de la carte, comme celui ci-dessous :
#### Pour le grand public sur l'instance OSM
<shot-scraper
data-output="static/tutoriels/create-map-alert.png"
data-url="https://umap.openstreetmap.fr/fr/map/new/"
@ -111,14 +103,6 @@ Nous verrons dans [le prochain tutoriel](3-create-account.md)
comment créer son catalogue de cartes en utilisant un compte, il nest alors pas
nécessaire de conserver de lien secret.
#### Pour les agents publics sur linstance qui leur est dédiée
Sils ne se sont pas connectés avant de créer leur carte, le message est différent :
![Le lien vers la connexion MonComptePro](../../static/tutoriels/proconnect-connexion.png)
Il nest pas possible denregistrer les modifications apportées à une carte anonyme sur cette instance.
### 3. Ajouter un marqueur
Commencez par déplacer et zoomer la carte pour visualiser lendroit
@ -141,7 +125,7 @@ Le curseur prend la forme dun signe
le bouton gauche de la souris : un *marqueur bleu* et carré est créé à
cet endroit et un panneau apparaît à droite.
![Un marqueur uMap.](../../static/tutoriels/2-je-cree-ma-premiere-carte-umap/umap_marqueur.jpg)
![umap_marqueur.jpg](../../static/tutoriels/2-je-cree-ma-premiere-carte-umap/umap_marqueur.jpg)
Ce panneau vous permet
dassocier un nom et une description au marqueur :
@ -196,19 +180,13 @@ actuels**.
### 5. Enregistrer la carte
Toute modification de la carte doit être sauvegardée
Toute modification de la carte doit être sauvegardée sur le serveur uMap
en cliquant sur le bouton **Enregistrer** en haut à droite. Cette
opération enregistre toutes les modifications depuis la dernière
sauvegarde : vous pouvez donc réaliser plusieurs modifications à la
suite puis les enregistrer. A linverse le bouton **Annuler** permet de
supprimer toutes les modifications depuis la dernière sauvegarde.
!!! note
Lenregistrement se fait sur les serveurs dOpenStreetMap dans le cas
dune utilisation duMap OSM ou ceux de lANCT si uMap pour
les agents publics est utilisé.
Après avoir enregistré les modifications, le bouton Annuler est remplacé
par **Désactiver lédition**. Cela vous permet de quitter le mode
édition pour voir la carte en mode consultation. Vous pouvez alors

View file

@ -1,44 +1,41 @@
!!! abstract "Ce que nous allons apprendre"
- utiliser un compte pour retrouver ses cartes
- créer une équipe
- partager une carte avec une équipe
- Utiliser un compte pour retrouver ses cartes
- Changer la forme, la couleur et le pictogramme dun marqueur
- Créer et modifier une ligne
- Contrôler laffichage des étiquettes
## Procédons par étapes
Nous avons appris dans [le tutoriel précédent](2-first-map.md) comment créer une
carte anonyme contenant un marqueur. Nous allons à présent créer un compte et une équipe.
Nota : il ny a pas de carte anonyme sur
[linstance uMap pour les agents publics](https://umap.incubateur.anct.gouv.fr/fr/).
Nous avons appris dans
[le tutoriel précédent](2-first-map.md) comment créer une
carte anonyme contenant un marqueur. Nous allons à présent créer une
carte plus complète : la carte de nos vacances au [Camping de la plage
Goulien](http://www.openstreetmap.org/way/119055693) sur la Presquîle
de Crozon en Bretagne.
Au lieu de créer une carte anonyme, nous allons utiliser un compte pour
créer cette carte.
### 1. Utiliser un compte
**uMap** permet dassocier ses cartes à un compte. Cela présente plusieurs
avantages importants par rapport à la création de cartes anonymes :
**uMap** permet dassocier ses cartes à un compte. Cela présente deux
avantages importants par rapport à la création de cartes anonymes :
- les cartes créées avec un compte constituent un catalogue permettant
daccéder facilement à ses cartes
- on peut modifier chaque carte du catalogue sans avoir besoin de
conserver un lien dédition
- on peut gérer ses cartes en équipe et afficher le nom de léquipe comme auteur
- pour les agents publics sur uMap ANCT : une fois connecté avec MonComptePro, on peut utiliser dautres outils en association avec uMap, comme Grist.
Le logiciel umap ne gère pas directement de comptes utilisateurs : la
gestion des comptes dépend de la configuration du logiciel.
#### Pour le grand public, les associations…
Sur <https://umap.openstreetmap.fr>, vous pouvez utiliser un compte que vous
Le logiciel umap ne gère pas directement de comptes utilisateurs : la
gestion des comptes dépend de la configuration du logiciel. Sur
<http://umap.openstreetmap.fr>, vous pouvez utiliser un compte que vous
avez ouvert sur un site Web au choix : OpenStreetMap, Github,
ou Bitbucket. Si vous navez aucun compte sur ces outils, cest le
moment de vous inscrire sur le site www.openstreetmap.org : cliquez
**Créer un compte** dans le coin supérieur droit et suivez les
instructions - une adresse mail vous sera demandée ([plus
dinfos](https://openstreetmap.fr/inscription-openstreetmap)).
dinfos](http://openstreetmap.fr/inscription-openstreetmap)).
![umap_header.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_header.png)
@ -55,53 +52,158 @@ permettant daccéder à lensemble des cartes créées avec ce compte.
Notez lURL de la barre dadresse quand vous consultez votre catalogue
de cartes : celle-ci contient le nom de votre compte - par exemple
<https://umap.openstreetmap.fr/fr/user/cartocite/>. Vous pouvez
<http://umap.openstreetmap.fr/fr/user/cartocite/>. Vous pouvez
lutiliser pour accéder à votre catalogue de cartes, même sans être
connecté à votre compte : vous pouvez diffuser cette URL, les
récipiendaires ne pourront pas modifier vos cartes.
#### :fontawesome-solid-landmark-flag: Pour les agents publics
Toutes les cartes que vous créez en étant connecté à votre compte sont
ajoutées à votre catalogue.
1. Se connectez à ProConnect : <https://moncomptepro.beta.gouv.fr/> <br>
Toute personne qui travaille pour un service public y a accès.
2. Créez un compte, lopération peut prendre quelques minutes.
3. Sur [le site uMap pour les agents publics](https://umap.incubateur.anct.gouv.fr/fr/),
cliquez sur `Me Connecter`.
### 2. Créer un joli marqueur
On peut accéder à la page de création de compte ProConnect directement
depuis [uMap pour les agents publics](https://umap.incubateur.anct.gouv.fr/fr/).
Commençons par créer une carte : donnons-lui un nom, définissons une
emprise et ajoutons un marqueur à [lemplacement du
camping](http://www.openstreetmap.org/?mlat=48.2387&mlon=-4.5434#map=16/48.2387/-4.5434).
Nous avons vu dans [le tutoriel précédent](2-first-map.md) comment effectuer ces opérations.
Le tableau de bord souvre, il affiche lensemble des cartes que
vous créez ainsi que les équipes auxquelles vous participez.
![umap_marqueur_props.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_marqueur_props.png)
!!! french-instance "Pour les agents publics"
Associer une carte à une équipe vous permet dafficher le nom de cette équipe au lieu du vôtre sur une carte (noms de votre commune, de votre service,…). Une équipe peut se composer dune seule personne.
Ce gros marqueur bleu nest pas très explicite pour figurer un camping.
Remédions à cela. Dans le panneau latéral visible lorsquun marqueur est
sélectionné, le menu **Propriétés de la forme** permet de modifier
lapparence du marqueur :
### 2. Créer une équipe
- **Couleur** : cliquer sur `définir` permet de choisir une couleur.
Notez que vous pouvez définir une couleur par [son nom
CSS](http://www.w3schools.com/cssref/css_colors.asp) ou par son code
héxadécimal, que vous pouvez choisir par exemple avec ce [sélecteur
de couleurs](http://htmlcolorcodes.com/fr/selecteur-de-couleur/).
- **Forme de licône** : le choix `Par défaut` correspond au marqueur
actuel, les autres choix sont Cercle, Goutte et Épingle.
- **Image de licône** : cliquer sur `définir` pour choisir parmi une
centaine de pictogrammes. Notez que le picto nest affiché que pour
les formes dicônes `Par défaut` et `Goutte`.
Une fois connecté sur linstance uMap,
cliquer sur « Mon espace », puis « Mes équipes » :
Voici le marqueur obtenu avec les propriétés ci-contre :
![Lien vers longlet des équipes](../../static/tutoriels/my-teams.png)
![umap_camping.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_camping.png)
Puis sur « Nouvelle équipe » et renseigner les informations
#### Modifier un marqueur
![Formulaire dédition des équipes](../../static/tutoriels/my-teams-form.png)
![umap_modifier_marqueur.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_modifier_marqueur.png)
Lorsquun nouvel utilisateur est associé à une équipe,
il voit léquipe safficher sur son tableau de bord,
il accède à toutes les cartes qui sont partagées et il peut les modifier.
Pour modifier un marqueur de la carte, plusieurs possibilités soffrent à vous :
!!! note
Tous les membres dune équipe partagent les mêmes droits dédition sur une carte
qui est associée à une équipe. Une équipe peut être supprimée,
ou son nom modifié en un simple clic.
- un clic sur le marqueur vous permet soit dafficher le panneau
dédition (stylo), soit de supprimer le marqueur (corbeille)
- **shift-clic** est un raccourci qui affiche directement le panneau
dédition
- un glisser-déposer vous permet de déplacer le marqueur sur la carte
### 3. Partager une carte avec une équipe
### 3. Créer une ligne
Une fois léquipe créée, il reste encore à donner les droits de modification
dune carte à ses membres. Pour ce faire : ouvrez la carte,
puis sur cliquez sur « Editer » et cliquez en haut de page
à droite du titre sur « Visibilité : Définir qui peut voir et modifier la carte ».
Le premier jour de vacances nous allons en kayak de mer jusquà la
Pointe de Dinan à louest de la plage de Goulien. Traçons litinéraire
suivi.
<shot-scraper
data-output="static/tutoriels/draw-polyline.png"
data-url="https://umap.openstreetmap.fr/fr/map/new/"
data-alt="Bouton de dessin dune ligne."
data-width="46"
data-height="47"
data-selector=".leaflet-toolbar-icon.umap-draw-polyline"
data-padding="5"
>Bouton de dessin dune ligne.</shot-scraper>
Le bouton **Dessiner une ligne** permet de tracer, point par point,
une ligne constiutée de plusieurs segments.
Cliquez à nouveau sur le dernier point tracé pour
terminer la ligne : apparaît alors à droite un panneau permettant de
donner un nom et une description à la ligne, comme pour les marqueurs.
#### Modifier une ligne
A tout moment vous pouvez sélectionner une ligne en double-cliquant
dessus. Vous pouvez alors éditer ses propriétés dans le panneau latéral,
ou modifier son tracé sur la carte :
- **supprimer un point** de la ligne, matérialisé par un carré blanc,
en cliquant dessus
- **déplacer un point** par un glisser-déposer
- **insérer un point** en cliquant sur un carré gris se trouvant au
milieu de chaque segment
- **allonger la ligne** avec un Ctrl-Clic lorsque le curseur est placé
sur le premier ou dernier point
- **couper la ligne** en deux : Clic droit sur un point puis choisir
loption `Scinder la ligne`
![umap_ligne.jpg](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_ligne.jpg)
#### Propriétés dune ligne
![umap_ligne_props.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_ligne_props.png)
Les propriétés dune
ligne permettent de définir sa couleur et dautres paramètres
définissant son *style* :
- l**opacité** va de transparent à gauche à totalement opaque à
droite. Plus le trait est épais plus il peut être transparent.
- l**épaisseur** est définie en pixels, sa valeur par défaut est 3 :
glisser le curseur vers la droite pour un trait plus épais (qui sera
plus facile à sélectionner).
Les **propriétés avancées** permettent de :
- **simplifier** le tracé permet de réduire le nombre de points pour
ladapter au niveau de zoom. Il est en général inutile de simplifier
un tracé réalisé *à la main*.
- définir un **traitillé**, par une série de chiffres séparés par des
virgules : longueur (en pixels) visible, longueur invisible,
longueur visible, etc. Lépaisseur du trait doit être prise en
compte : plus les traits sont épais plus les intervalles doivent
être grands.
Voici le style de trait obtenu avec les propriétés ci-contre :
![umap_ligne_tirets.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_ligne_tirets.png)
### 4. Ajouter des étiquettes
![etiquettes.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/etiquettes.png)
Pour aider lidentification des
différents éléments de notre carte, nous pouvons leur associer une
étiquette. Longlet **Options dinteraction** permet de contrôler
laffichage dune étiquette associée à chaque élément :
- **Afficher une étiquette** active son affichage, elle est alors
placée automatiquement
- **Direction de létiquette** vous permet de fixer la position, à
droite ou à gauche de lélément, ou encore au-dessus ou en-dessous
- **Afficher seulement au survol** de la souris est une option
intéressante si la carte est dense : afficher toutes les étiquettes
surchagerait la carte
- **Étiquette cliquable** permet dafficher linfobulle correspondante
si lutilisateur clique sur létiquette, et non seulement en cas de
clic sur la *géométrie* de lélément.
## Faisons le point
Notre deuxième carte est déjà plus intéressante que la première, et nous
savons la retrouver facilement. Nous avons vu comment créer, *styliser*
et modifier points et lignes. Nous navons pas traité ici des polygones,
qui représentent des surfaces. Certaines fonctionnalités propres aux
polygones méritent dêtre détaillées, ce que nous ferons dans le
tutoriel [Le cas des polygones](8-polygons.md).
Pour le moment voyons comment nous pouvons davantage
[personnaliser notre carte](4-customize-map.md).
??? info "Licence"
Travail initié par Antoine Riche sur [CartoCité](https://wiki.cartocite.fr/doku.php?id=umap:3_-_j_utilise_un_compte_et_cree_une_belle_carte) sous licence [CC-BY-SA 4](https://creativecommons.org/licenses/by-sa/4.0/deed.fr).
![Panneau de permissions pour la sélection des équipes](../../static/tutoriels/my-teams-permissions.png)

View file

@ -85,8 +85,8 @@ carte peut vous aider à en choisir un plutôt quun autre, par exemple :
!!! note
Tous les fonds de carte utilisés par uMap, à
lexception des images aériennes de lIGN, sont réalisés à partir des
Tous les fonds de carte utilisés par umap, à
lexception des images aériennes de lIGN, sont réalisées à partir des
données OpenStreetMap. Ils sont produits par des associations, des
entreprises ou des bénévoles qui les mettent gracieusement à
disposition.
@ -170,11 +170,9 @@ Dans les deux cas un message vous demande de confirmer lopération.
## Faisons le point
Vous savez créer, modifier et personnaliser une carte.
Vous savez styliser vos marqueurs, lignes et polygones.
Enfin vous savez gérer votre catalogue de cartes.
Vous allez découvrir comment importer des données en « un clic »
issues de lopen data et gagner du temps par rapport au dessin de toutes les formes.
Ce tutoriel nous mène à la fin du niveau débutant. Vous savez créer,
modifier et personnaliser une carte. Vous savez styliser vos marqueurs,
lignes et polygones. Enfin vous savez gérer votre catalogue de cartes.
Une fois ces opérations maîtrisées, les tutoriels de niveau
intermédiaire vous apprendront à structurer vos cartes avec des calques

View file

@ -1,158 +0,0 @@
!!! abstract "Ce que nous allons apprendre"
- Changer la forme, la couleur et le pictogramme dun marqueur
- Créer et modifier une ligne
- Contrôler laffichage des étiquettes
Voici comment réaliser une carte contenant de jolis marqueurs et des lignes
avec pour exemple la carte de nos vacances au
[Camping de la plage Goulien](https://www.openstreetmap.org/way/119055693)
sur la Presquîle de Crozon en Bretagne.
### 1. Créer un joli marqueur
Commençons par créer une carte : donnons-lui un nom, définissons une
emprise et ajoutons un marqueur à [lemplacement du
camping](http://www.openstreetmap.org/?mlat=48.2387&mlon=-4.5434#map=16/48.2387/-4.5434).
Nous avons vu dans [le tutoriel précédent](2-first-map.md) comment effectuer ces opérations.
![umap_marqueur_props.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_marqueur_props.png)
Ce gros marqueur bleu nest pas très explicite pour figurer un camping.
Remédions à cela. Dans le panneau latéral visible lorsquun marqueur est
sélectionné, le menu **Propriétés de la forme** permet de modifier
lapparence du marqueur :
- **Couleur** : cliquer sur `définir` permet de choisir une couleur.
Notez que vous pouvez définir une couleur par [son nom
CSS](http://www.w3schools.com/cssref/css_colors.asp) ou par son code
héxadécimal, que vous pouvez choisir par exemple avec ce [sélecteur
de couleurs](http://htmlcolorcodes.com/fr/selecteur-de-couleur/).
- **Forme de licône** : le choix `Par défaut` correspond au marqueur
actuel, les autres choix sont Cercle, Goutte et Épingle.
- **Image de licône** : cliquer sur `définir` pour choisir parmi une
centaine de pictogrammes. Notez que le picto nest affiché que pour
les formes dicônes `Par défaut` et `Goutte`.
Voici le marqueur obtenu avec les propriétés ci-contre :
![umap_camping.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_camping.png)
#### Modifier un marqueur
![umap_modifier_marqueur.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_modifier_marqueur.png)
Pour modifier un marqueur de la carte, plusieurs possibilités soffrent à vous :
- un clic sur le marqueur vous permet soit dafficher le panneau
dédition (stylo), soit de supprimer le marqueur (corbeille)
- **shift-clic** est un raccourci qui affiche directement le panneau
dédition
- un glisser-déposer vous permet de déplacer le marqueur sur la carte
### 2. Créer une ligne
Le premier jour de vacances nous allons en kayak de mer jusquà la
Pointe de Dinan à louest de la plage de Goulien. Traçons litinéraire
suivi.
<shot-scraper
data-output="static/tutoriels/draw-polyline.png"
data-url="https://umap.openstreetmap.fr/fr/map/new/"
data-alt="Bouton de dessin dune ligne."
data-width="46"
data-height="47"
data-selector=".leaflet-toolbar-icon.umap-draw-polyline"
data-padding="5"
>Bouton de dessin dune ligne.</shot-scraper>
Le bouton **Dessiner une ligne** permet de tracer, point par point,
une ligne constiutée de plusieurs segments.
Cliquez à nouveau sur le dernier point tracé pour
terminer la ligne : apparaît alors à droite un panneau permettant de
donner un nom et une description à la ligne, comme pour les marqueurs.
#### Modifier une ligne
A tout moment vous pouvez sélectionner une ligne en double-cliquant
dessus. Vous pouvez alors éditer ses propriétés dans le panneau latéral,
ou modifier son tracé sur la carte :
- **supprimer un point** de la ligne, matérialisé par un carré blanc,
en cliquant dessus
- **déplacer un point** par un glisser-déposer
- **insérer un point** en cliquant sur un carré gris se trouvant au
milieu de chaque segment
- **allonger la ligne** avec un Ctrl-Clic lorsque le curseur est placé
sur le premier ou dernier point
- **couper la ligne** en deux : Clic droit sur un point puis choisir
loption `Scinder la ligne`
![umap_ligne.jpg](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_ligne.jpg)
#### Propriétés dune ligne
![umap_ligne_props.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_ligne_props.png)
Les propriétés dune
ligne permettent de définir sa couleur et dautres paramètres
définissant son *style* :
- l**opacité** va de transparent à gauche à totalement opaque à
droite. Plus le trait est épais plus il peut être transparent.
- l**épaisseur** est définie en pixels, sa valeur par défaut est 3 :
glisser le curseur vers la droite pour un trait plus épais (qui sera
plus facile à sélectionner).
Les **propriétés avancées** permettent de :
- **simplifier** le tracé permet de réduire le nombre de points pour
ladapter au niveau de zoom. Il est en général inutile de simplifier
un tracé réalisé *à la main*.
- définir un **traitillé**, par une série de chiffres séparés par des
virgules : longueur (en pixels) visible, longueur invisible,
longueur visible, etc. Lépaisseur du trait doit être prise en
compte : plus les traits sont épais plus les intervalles doivent
être grands.
Voici le style de trait obtenu avec les propriétés ci-contre :
![umap_ligne_tirets.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/umap_ligne_tirets.png)
### 3. Ajouter des étiquettes
![etiquettes.png](../../static/tutoriels/3-jutilise-un-compte-et-cree-une-belle-carte/etiquettes.png)
Pour aider lidentification des
différents éléments de notre carte, nous pouvons leur associer une
étiquette. Longlet **Options dinteraction** permet de contrôler
laffichage dune étiquette associée à chaque élément :
- **Afficher une étiquette** active son affichage, elle est alors
placée automatiquement
- **Direction de létiquette** vous permet de fixer la position, à
droite ou à gauche de lélément, ou encore au-dessus ou en-dessous
- **Afficher seulement au survol** de la souris est une option
intéressante si la carte est dense : afficher toutes les étiquettes
surchagerait la carte
- **Étiquette cliquable** permet dafficher linfobulle correspondante
si lutilisateur clique sur létiquette, et non seulement en cas de
clic sur la *géométrie* de lélément.
## Faisons le point
Notre deuxième carte est déjà plus intéressante que la première, et nous
savons la retrouver facilement. Nous avons vu comment créer, *styliser*
et modifier points et lignes. Nous navons pas traité ici des polygones,
qui représentent des surfaces. Certaines fonctionnalités propres aux
polygones méritent dêtre détaillées, ce que nous ferons dans le
tutoriel [Le cas des polygones](8-polygons.md).
Pour le moment voyons comment nous pouvons davantage
[personnaliser notre carte](4-customize-map.md).
??? info "Licence"
Travail initié par Antoine Riche sur [CartoCité](https://wiki.cartocite.fr/doku.php?id=umap:3_-_j_utilise_un_compte_et_cree_une_belle_carte) sous licence [CC-BY-SA 4](https://creativecommons.org/licenses/by-sa/4.0/deed.fr).

View file

@ -1,221 +0,0 @@
!!! abstract "Ce que nous allons apprendre"
- consulter des sources de données
- découvrir des exemples de cartes
- cloner une carte uMap
- cas pratique : utiliser un jeu de données placé sur data.gouv.fr
## Lopen data (données ouvertes)
Outre les données produites par ma communauté OpenStreetMap, accessibles sur [GeoDataMine](https://geodatamine.fr/) et dans [lassistant dimport de données de uMap](6-one-click-data-import.md), les ressources dopen data sont nombreuses et variées. En effet, les collectivités de plus de 3 500 habitants et les services publics doivent placer leurs données en open data conformément à la [Loi pour une République numérique](https://www.vie-publique.fr/eclairage/20301-loi-republique-numerique-7-octobre-2016-loi-lemaire-quels-changements). Le service public de la donnée organise leur publication sur [data.gouv.fr](https://www.data.gouv.fr/fr/) qui est un portail généraliste.
Il existe également des bases plus adaptées à des jeux de données, par exemple les archives, des données géographiques, socio-économiques… Les collectivités mettent parfois aussi directement leurs données à disposition sur leurs portails open data. Des éditeurs de solutions proposent également des bases de données.
## 1. Formats de données utilisés par uMap
### geojson
Ce format est utilisé pour des données de type point, ligne, chaîne de caractères, polygone.
Toutes les propriétés sont importées dans uMap.
❓ Usage très large dans uMap.
### gpx
Ce format ouvert permet léchange de coordonnées géographiques issues de GPS, points de cheminement (*waypoints*), traces (*tracks*) ou itinéraires (*routes*).
Propriétés importées dans uMap : `name`, `desc`. (format pour des itinéraires)
❓ Les fichiers gpx peuvent provenir denregistrements personnels, par exemple de traces recueillies randonnées.
### kml
Format propriétaire qui contient des coordonnées géographiques, balisage, styles pour représenter des points, des lignes et des polygones.
Propriétés importées dans uMap : `name`, `description`.
### csv
Cest un format texte ouvert représentant des données tabulaires sous forme de valeurs séparées par des virgules. Pour utiliser un fichier Excel, il faut dabord le convertir en `.csv`.
Propriétés importées dans uMap : virgule, tabulation ou point virgule pour séparer des valeurs. La projection SRS WGS84 est implicite. Seuls les points géométriques sont importés. Limportation se référera au titre dans les entêtes de colonnes de `lat` et `lon` au début de lentête, et est insensible à la casse (peu importe les majuscules ou minuscules). Toutes les autres colonnes sont importées en tant que propriétés.
❓ Usage très large dans uMap, aussi bien pour des données en *open data* que pour ses propres données.
### umap
Cest le format denregistrement dune carte, très utilisé par exemple pour cloner une carte sur linstance OSM et limporter sur linstance uMap pour les agents publics. uMap importe toutes les données de la carte, y compris les calques et les propriétés. Il sagit dun bon moyen de sauvegarder sa carte uMap.
❓ Voir plus loin, comment cloner une carte uMap.
Ainsi quosm et georss.
## 2. Sorienter sur data.gouv.fr
La plateforme [data.gouv.fr](https://www.data.gouv.fr/fr/) propose des données harmonisées, précise la date de mise à jour et permet de contacter ladministrateur qui a déposé le jeu de données. Il suffit dutiliser loutil de recherche pour préciser sa demande puis sélectionner le résultat voulu.
La principale difficulté : savoir quel jeu de données répondrait au besoin. Dans ce cas, il est conseillé de regarder aussi les « thématiques » et les « réutilisations » en bas de page daccueil.
## 3. Gallica ! les archives de la Bibliothèque Nationale de France
La [base Gallica](https://gallica.bnf.fr/accueil/fr/content/accueil-fr?mode=desktop) est particulièrement utile pour afficher dans uMap des images, des cartes postales, des fonds de cartes anciennes. Il nest pas obligatoire de télécharger lillustration, certaines cartes se contentent de placer le lien pour quelle saffiche :
### Vues de villes aux XVIe et XVIIe siècles
![Capture décran de la carte](../../static/tutoriels/find-data-villes.png)
[Lien vers la carte en ligne](https://umap.openstreetmap.fr/fr/map/vues-de-villes-aux-xvie-et-xviie-siecles_635544#7/46.241/-1.329){ .md-button }
Deux exemples utilisant un plan ancien comme fond, en plus des images anciennes qui saffichent en cliquant sur un pointeur :
### Photographies de Marseille 1862 à 1866 par A. Terris
![Capture décran de la carte](../../static/tutoriels/find-data-photos-marseille.png)
[Lien vers la carte en ligne](https://umap.openstreetmap.fr/nl/map/photographies-de-marseille-1862-a-1866-par-a-terri_277962#14/43.2909/5.3815){ .md-button }
### Metz 1872
![Capture décran de la carte](../../static/tutoriels/find-data-metz-1872.png)
[Lien vers la carte en ligne](https://umap.incubateur.anct.gouv.fr/fr/map/metz-1872_50#13/49.1201/6.1419){ .md-button }
Dans ces deux derniers cas, le fond de carte doit être « redressé » avant dêtre utilisé dans uMap comme [fond personnalisé](https://forum.openstreetmap.fr/t/integrer-un-fonds-de-carte-personnalise-sur-umap/19606).
## 4. Bases de données statistiques
uMap permet de représenter des données quantitatives par le biais de [cercles proportionnels](8-proportional-circles.md) ou de [cartes choroplèthes](10-embed-remote-data.md#produire-une-carte-de-chaleur-ou-heatmap) cest à dire des plages de couleurs.
L[INSEE](https://www.insee.fr/fr/accueil) et [Eurostat](https://ec.europa.eu/eurostat/fr/data/database) permettent de télécharger des fichiers statistiques généralistes.
Une fois un fichier enregistré, il faut vérifier le format des données et le modifier au besoin. Attention par exemple aux cellules fusionnées et aux espaces entre les séries de zéro.
## 5. Cloner une carte uMap
Pour utiliser les données dune carte sur un autre fond, en faire plusieurs versions, il suffit de cloner la carte.
Exemple de besoin : présenter sur un site Internet la même carte plusieurs fois, en diversifiant le centrage et les fonds de cartes. La même carte initiale fournit plusieurs vues provenant de clones.
!!! french-instance "Pour les agents publics"
Cette fonctionnalité permet également dimporter sur [linstance uMap agents publics](https://umap.incubateur.anct.gouv.fr/fr/) une carte réalisée sur une autre instance.
Voici les actions :
- sauvegardez la carte que vous souhaitez cloner
- créez une nouvelle carte - pour cloner la carte sur une nouvelle instance : connectez-vous à la nouvelle instance puis créez cette nouvelle carte et
- importez la carte.
Les deux cartes co-existent, une modification sur une carte nimpacte pas lautre carte. Si la carte est partagée sur un site Internet, il faut veiller à **mettre à jour le lien** en cas de changement dinstance.
### 1. Sauvegarder la carte
Cliquez à gauche sur « Partager et télécharger »
<shot-scraper
data-output="static/tutoriels/control-embed.png"
data-url="https://umap.openstreetmap.fr/en/map/new/"
data-alt="Icône du partage et de lintégration."
data-selector=".leaflet-control-embed"
data-width="48"
data-height="48"
data-padding="5"
>Permet de partager la carte ou den exporter les données.</shot-scraper>
puis une fois lécran latéral affiché :
![Capture décran du panneau de téléchargement de la carte](../../static/tutoriels/find-data-download.png)
Cliquez sur « Sauvegarde complète » en bas.
### 2. Créer une carte et importer le fichier
Quitter cet écran, créer une nouvelle carte puis cliquer à droite sur « Importer des données » puis une fois lécran latéral affiché :
![Capture décran du module dimport](../../static/tutoriels/find-data-import-umap.jpg)
Le format de limport reconnaît uMap et le précise.
Cliquez sur « Importer », puis enregistrez.
## 6. Cas pratique : utiliser un jeu de données placé sur data.gouv.fr
Pour un usage dans uMap, les fichiers doivent contenir les coordonnées géographiques des objets. Si le fichier choisi nen contient pas, voir [ici](12-display-grist-data.md#2-geocoder-des-adresses-pour-les-agents-publics-seulement) comment les ajouter (géocodage).
Voici les actions pour dresser la carte des arbres remarquables à Metz : rechercher les données, les importer dans uMap et les retravailler pour améliorer le placement des étiquettes.
### Rechercher les données
La plateforme ouverte des données publiques françaises recense des milliers de jeux de données. Rechercher « Arbres Metz » dans loutil de recherche.
Deux solutions pour utiliser ces données :
* récupérer le fichier au format json : il faudra mettre à jour la carte de temps en temps lorsque les données sources sont mises à jour. Bénéfice : une carte à jour à une date précise.
ou
* utiliser le lien vers les données : dans ce cas, la carte se mettra automatiquement à jour (suppression darbres coupés par exemple, ajout de nouveaux). Inconvénient : la carte est une carte au temps T, on ne conserve pas lhistorique dans ce cas.
![Capture décran du site datagouv](../../static/tutoriels/find-data-datagouv.jpg)
Vous avez le choix. Une fois le fichier téléchargé ou le lien copié, cliquer dans la carte sur uMap le bouton "Importer des données" dans la barre de droite puis dans le cadre au choix :
* Parcourir les fichiers téléchargés et choisir le fichier des arbres remarquables au format Geojson
ou
* Coller lURL stable dansla ligne prévue
![Capture décran du panneau dimport (1)](../../static/tutoriels/find-data-import-panel-1.png)
![Capture décran du panneau dimport (2)](../../static/tutoriels/find-data-import-panel-2.png)
Dans « Choisir le format des données » : sélectionner `Geojson`. Dans le cas où vous choisissez lURL stable, vous pouvez choisir `Associer au calque comme données distantes` et dans ce cas la carte se met automatiquement à jour si le fichier est modifié.
Choisir `Copier dans le calque` pour que la carte reste telle quelle à une date T.
La carte se centre automatiquement sur Metz et tous les arbres remarquables sont placés :
![Capture décran de la carte](../../static/tutoriels/find-data-screenshot-trees.png)
Les informations présentes dans le fichier sont répercutées et accessibles dans un tableau ou en cliquant sur chaque arbre.
### Modifier lapparence des pointeurs pour adapter à la charte dun site
Sélectionner le calque dans la barre de droite et modifier ses réglages en cliquant sur le petit stylo :
![Capture décran du panneau de visualisation](../../static/tutoriels/find-data-visualize-data.png)
Nom : Arbres remarquables (ou par exemple Feuillus ou Arbres de plus de 50 ans…), autant de possibilités que de calques et de couleurs. Puis cliquer sur les propriétés de la forme pour choisir la couleur et la forme du pointeur, mais aussi les options dinteraction : afficher une étiquette au survol par exemple.
![Capture décran de la carte et du panneau de personnalisation](../../static/tutoriels/find-data-trees-customisation.png)
### Afficher les noms des arbres au survol
Toutes les données affichables dans létiquette sont présentées dans les colonnes du tableau associé au calque. Cliquez sur lexplorateur de données à gauche puis sur le visuel "Éditer dans un tableau" (juste à gauche de la corbeille):
<shot-scraper
data-output="static/tutoriels/control-browse.png"
data-url="https://umap.openstreetmap.fr/en/map/new/"
data-alt="Icône du sélecteur de calque(s)."
data-selector=".umap-control-browse"
data-width="48"
data-height="48"
data-padding="5"
>Icône du sélecteur de calque(s).</shot-scraper>
Dans le cas du fichier des arbres remarquables de Metz, le nom des arbres est renseigné comme `nom_commun` et `nom_latin`. Or dans uMap, par défaut, les étiquettes qui saffichent utilisent `name`. Pour que le nom commun saffiche, il faut remplacer `name` par `nom_commun` à droite dans les « Propriétés avancées » (Panneau dinformation de ce calque):
![Capture décran de la carte et du panneau de personnalisation](../../static/tutoriels/find-data-trees-customisation-advanced.png)
Pour que létiquette saffiche seulement au survol, choisir `Caché` un peu plus bas dans « Afficher une étiquette ».
!!! note
- Pour sentraîner, ouvrir les réglages, la carte peut être clonée ici :
https://umap.incubateur.anct.gouv.fr/fr/map/diaporama-des-arbres-remarquables-a-metz_528
- Pour cloner une carte, voir lexplication au point 5 plus haut.

View file

@ -132,6 +132,18 @@ cette photo. Pour cela nous devons :
#### Afficher vos photos
Si vous disposez dun serveur vous pouvez lutiliser stocker vos photos.
Si ce nest pas le cas vous pouvez utiliser un service comme
**[Framapic](https://framapic.org/)**, un service de stockage libre que
lassociation **[Framasoft](https://framasoft.org/)** met à la
disposition de tous sans contre-partie. Lopération est très simple :
1. stockez votre photo sur Framapic par un glisser-déposer depuis votre
explorateur de fichier vers le navigateur
2. copiez le lien daffichage de la photo
3. collez ce lien entre **double accolades** dans la description de
linfobulle : `{{https://framapic.org/xxx/yyy.jpg}}`
![lienframapic.png](../../static/tutoriels/5-je-cree-des-infobulles-multimedia/lienframapic.png)
#### Modifier la taille dune image

View file

@ -1,99 +0,0 @@
!!! abstract "Ce que nous allons apprendre"
- Importer le contour dune commune
- Importer les contours des départements ou des régions
- Importer un point dintérêt (bibliothèques, parkings, …) qui est enregistré sur OpenStreetMap
## Procédons par étapes
Il est conseillé de vérifier si les données nexistent pas avant de se lancer dans leur dessin. On peut gagner un temps précieux avec lassistant dimportation intégré dans uMap et conserver une carte qui nest pas trop lourde au chargement.
Voilà les deux actions à effectuer une fois une carte préexistante, ou une nouvelle carte vierge ouverte :
- Cliquez sur loutil dimport de données dans la barre de droite puis sélectionnez les données déjà prêtes à lemploi
- Cliquez sur « Importer » et le cas échéant enjolivez la carte, car des figurés par défaut sont utilisés
uMap permet dutiliser des données produites par de nombreux services et placées en open data sous différents formats. Nous verrons ultérieurement (niveau intermédiaire) où rechercher ces sources. Dores et déjà, vous pouvez utiliser lassistant dimportation pour récupérer en un clic des contours administratifs et des points dintérêt.
### Ressources disponibles (20/09/2024)
Au 20 septembre 2024, les imports suivants sont disponibles :
- contour dune commune
- contours des départements et des régions
- données issues dOpenStreetMap placées dans [GeoDataMine](https://geodatamine.fr/). Comme son nom lindique, GeoDataMine est une véritable mine de données très utiles pour les services publics :
- Aire de jeux
- Aménagements cyclables
- Banques et DAB
- Base Adresse
- Bibliothèques
- Cimetière
- Cinémas
- Commerces
- Covoiturage
- Déchets et recyclage… jusquà Toilettes
- overpass : pour se familiariser avec les types de requêtes à renseigner dans lassistant, consulter les tutos plus avancés et la [page wiki](https://wiki.openstreetmap.org/wiki/Overpass_turbo/Wizard)
!!! note
Il manque des données ? Nhésitez pas à contribuer pour les ajouter et vous en serez les premiers bénéficiaires !
### Cliquez sur loutil dimport des données
Voici un bref passage en revu des différents imports proposés et pour finir limport de la localisation des bibliothèques de Clermont- Ferrand :
![Gif animé montrant lusage de lassistant dimport](../../static/tutoriels/importer.gif)
## 1. Importer le contour dune commune
Cliquez sur loutil dimportation en bas de la barre de droite, puis cliquez sur le lien « Assistants dimport ».
Cliquez sur « Communes France » et sélectionnez la commune souhaitée dans une liste déroulante. Une fois la commune sélectionnée, le format est reconnu automatiquement (geojson) puis le type de calque (cliquer sur « ? » pour savoir quel choix opérer)
1. Pour que les données soient simplement copiées, choisir « Copier dans le calque ».
2. Pour que la carte évolue si le contour change, choisir « Associer au calque comme donnée distante ».
!!! note
Le code affiché nest pas le code postal mais le code INSEE de la commune.
Voici le résultat avec la commune dArles (la plus vaste de France métropolitaine, un gain certain si on fait léconomie de dessiner son contour !)
![Une carte avec le dessin de la commune dArles importée](../../static/tutoriels/importer-arles.png)
Une fois cet import réalisé, tout est réglable : couleur de contour, de fond, affichage oui non dune étiquette.
## 2. Importer les contours des départements ou des régions
Cliquez sur loutil dimportation en bas de la barre de droite, puis cliquez sur le lien « Assistants dimport ».
Cliquez sur « Contours nationaux » puis soit départements, soit régions et enfin le type de calque (voir supra lexplication). Tous les départements sont importés :
![Une carte avec le dessin de chaque département importé](../../static/tutoriels/importer-departements.png)
## 3. Importer un point dintérêt issu de GeoDataMine
Cliquez sur loutil dimportation en bas de la barre de droite, puis cliquez sur le lien « Assistants dimport ».
Cliquez sur « GeoDataMine (thèmes OSM) » et sélectionnez les informations souhaitées, routes, bâtiments, commerces, services publics, …
Par exemple, en sélectionnant les points deau potable de la CA du Grand Avignon, puis « Copier dans un calque »
![Une carte avec les points deau potable issus dOpenStreetMap](../../static/tutoriels/importer-geodatamine.png)
Voici une réelle économie de temps plutôt que de placer pointeur après pointeur tous les points deau.
## 4. La carte combinée
Bien entendu, on peut tout à fait combiner les différentes couches dinformation et présenter par exemple la carte des Points deau potable dans la CA du Grand Avignon, avec les contours des communes qui composent lEPCI, du département et de la région :
### Points deau potable du Grand Avignon
![Une carte combinant plusieurs imports](../../static/tutoriels/importer-multi.png)
[Voir la carte en plein écran](https://umap.openstreetmap.fr/fr/map/points-deau-potable-grand-avignon_1116739?scaleControl=false&miniMap=false&scrollWheelZoom=true&zoomControl=true&editMode=disabled&moreControl=true&searchControl=null&tilelayersControl=null&embedControl=null&datalayersControl=true&onLoadPanel=none&captionBar=false&captionMenus=true#11/43.9889/4.7962){ .md-button }
Il faudra dans ce cas supprimer toutes les informations inutiles dans le tableau de données qui est accessible dans la barre de gauche pour chaque calque.
Pour gagner du temps : sélectionner tous les départements et désélectionner seulement le Vaucluse, puis cliquer sur « Supprimer les lignes sélectionnées ».

View file

@ -1,62 +0,0 @@
!!! abstract "Ce que nous allons apprendre"
- Vérifier le formats du fichier
- Importer le fichier dans uMap
- Régler lapparences des cercles
## Procédons par étapes
Nous allons importer des données quantitatives et les représenter sous forme de cercles proportionnels. On peut aussi représenter des données distantes par cercles proportionnels (voir les tutoriels plus avancés).
### 1. Vérifier le format du fichier
Pour être utilisable dans uMap, le fichier doit être enregistré au format `.csv`, il doit intégrer les cordonnées géographiques. Sans ces deux conditions, le fichier de données nest pas traité.
Il faut également éviter les mises en forme du type espace entre des blocs de trois zéros, sans quoi les cercles ne seront pas proportionnels, mais tous de même taille.
Si la latitude et la longitude ne sont pas présentes, le fichier doit être géocodé.
Le site de la Base Adresse Nationale propose un outil très pratique : <https://adresse.data.gouv.fr/csv>
Il suffit de placer un fichier au format `.csv` contenant des adresses et de cliquer sur « géocodage ». Loutil en ligne ajoute les coordonnées géographiques des adresses.
### 2. Importer le fichier dans uMap
Cliquer sur loutil dimportation en barre de droite :
<shot-scraper
data-output="static/tutoriels/upload-data.png"
data-url="https://umap.openstreetmap.fr/fr/map/new/"
data-alt="Bouton dimport de données."
data-width="46"
data-height="47"
data-selector=".leaflet-toolbar-icon.upload-data"
data-padding="5"
>Bouton dimport de données.</shot-scraper>
Puis choisir le fichier, par exemple ici la population municipale du Cher, le format est `.csv` et cliquer sur « importer » :
![](../../static/tutoriels/circles-markers.png)
Toutes les communes sont représentées par un pointeur. Il reste juste à préciser que les données de ce calque doivent être affichées par cercles proportionnels. Pour ce faire, cliquer sur loutil « Gérer les calques » en barre de droite :
<shot-scraper
data-output="static/tutoriels/control-browse.png"
data-url="https://umap.openstreetmap.fr/en/map/new/"
data-alt="Icône du sélecteur de calque(s)."
data-selector=".umap-control-browse"
data-width="48"
data-height="48"
data-padding="5"
>Icône du sélecteur de calque(s).</shot-scraper>
Puis dans le menu déroulant, sélectionner « Cercles proportionnels » et la donnée de votre tableau que vous voulez représenter en cercles proportionnels :
![](../../static/tutoriels/circles-proportional.jpg)
Il est tout à fait possible de régler la proportionnalité sur les barres de rayon minimum et maximum pour modifier le rendu : lécart est alors amplifié ou plutôt écrasé.
!!! notes
Pour modifier les couleurs des cercles, voir le tutoriel
[Dessiner sur sa carte](/fr/tutorials/4-draw-items/).

View file

@ -1,20 +1,12 @@
# Vidéos uMap
## Faire la carte de son marché de Noël
<iframe title="Faire la carte de son marché de Noël" width="560" height="315" src="https://tube.numerique.gouv.fr/videos/embed/7d3a95ad-37dc-4af1-ac15-17992cb95869" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe>
## Atelier « Afficher des donnees Grist dans uMap »
<iframe title="Atelier Afficher des donnees Grist dans uMap" width="560" height="315" src="https://tube.numerique.gouv.fr/videos/embed/517beed6-ed57-430d-ad76-61e0c4784338" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe>
## Transformer un tableau Grist en carte avec uMap
<iframe title="Transformer une table Grist en carte avec uMap" width="560" height="315" src="https://tube.numerique.gouv.fr/videos/embed/9e5b09d5-c660-41a0-8591-cae347c88e65" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe>
## uMap incubé par lÉtat, ça donne quoi ?
<iframe title="uMap incubé par lÉtat, ça donne quoi ?" width="560" height="315" src="https://peertube.openstreetmap.fr/videos/embed/c564dcfd-4b0b-4796-86ac-ca8624226cd3" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe>
<iframe title="24 - uMap incubé par lÉtat, ça donne quoi ?" width="560" height="315" src="https://peertube.openstreetmap.fr/videos/embed/c564dcfd-4b0b-4796-86ac-ca8624226cd3" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe>
## uMap a 10 ans, bilan et perspectives

View file

@ -1,5 +1,5 @@
# Force rtfd to use a recent version of mkdocs
mkdocs==1.6.1
pymdown-extensions==10.14.3
mkdocs-material==9.6.12
mkdocs-static-i18n==1.3.0
pymdown-extensions==10.9
mkdocs-material==9.5.34
mkdocs-static-i18n==1.2.3

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 977 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,001 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 786 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 816 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 653 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 734 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View file

@ -4,29 +4,3 @@
.md-typeset a {
color: #7990be !important;
}
:root {
--md-admonition-icon--french-instance: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M272 0l80 0c8.8 0 16 7.2 16 16l0 64c0 8.8-7.2 16-16 16l-80 0 0 32 192 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L48 192c-17.7 0-32-14.3-32-32s14.3-32 32-32l192 0 0-112c0-8.8 7.2-16 16-16l16 0zM64 224l64 0 0 192 40 0 0-192 64 0 0 192 48 0 0-192 64 0 0 192 40 0 0-192 64 0 0 196.3c.6 .3 1.2 .7 1.8 1.1l48 32c11.7 7.8 17 22.4 12.9 35.9S494.1 512 480 512L32 512c-14.1 0-26.5-9.2-30.6-22.7s1.1-28.1 12.9-35.9l48-32c.6-.4 1.2-.7 1.8-1.1L64 224z"/></svg>');
--md-admonition-icon--osm-instance: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2.672 23.969c-.352-.089-.534-.234-1.471-1.168C.085 21.688.014 21.579.018 20.999c0-.645-.196-.414 3.368-3.986c3.6-3.608 3.415-3.451 4.064-3.449c.302 0 .378.016.62.14l.277.14l1.744-1.744l-.218-.343c-.425-.662-.825-1.629-1.006-2.429a7.66 7.66 0 0 1 1.479-6.44c2.49-3.12 6.959-3.812 10.26-1.588c1.812 1.218 2.99 3.099 3.328 5.314c.07.467.07 1.579 0 2.074a7.55 7.55 0 0 1-2.205 4.402a6.7 6.7 0 0 1-1.943 1.401c-.959.483-1.775.71-2.881.803c-1.573.131-3.32-.305-4.656-1.163l-.343-.218l-1.744 1.744l.14.28c.125.241.14.316.14.617c.003.651.156.467-3.426 4.049c-2.761 2.756-3.186 3.164-3.398 3.261c-.271.125-.69.171-.945.106zM17.485 13.95a6.43 6.43 0 0 0 4.603-3.51c1.391-2.899.455-6.306-2.227-8.108c-.638-.43-1.529-.794-2.367-.962c-.581-.117-1.809-.104-2.414.025a6.6 6.6 0 0 0-2.452 1.064c-.444.315-1.177 1.048-1.487 1.487a6.384 6.384 0 0 0 .38 7.907a6.4 6.4 0 0 0 3.901 2.136c.509.078 1.542.058 2.065-.037zm-3.738 7.376a81 81 0 0 1-2.196-.651c-.025-.028 1.207-4.396 1.257-4.449c.023-.026 4.242 1.152 4.414 1.236c.062.026-.003.288-.525 2.102a399 399 0 0 0-.635 2.236c-.025.087-.069.156-.097.156c-.028-.003-1.028-.287-2.219-.631zm2.912.524c0-.053 1.227-4.333 1.246-4.347c.047-.034 4.324-1.23 4.341-1.211c.019.019-1.199 4.337-1.23 4.36c-.02.019-4.126 1.191-4.259 1.218c-.054.011-.098 0-.098-.019zm-7.105-1.911c.846-.852 1.599-1.627 1.674-1.728c.171-.218.405-.732.472-1.015c.026-.118.053-.352.058-.522l.011-.307l.182-.051c.103-.028.193-.044.202-.034c.023.025-1.207 4.321-1.246 4.36c-.02.016-.677.213-1.464.436l-1.425.405l1.537-1.542zm8.289-3.06a1.4 1.4 0 0 1-.059-.187l-.044-.156l.156-.028c1.339-.227 2.776-.856 3.908-1.713c.16-.125.252-.171.265-.134c.054.165.272.95.265.959c-.034.034-4.48 1.282-4.492 1.261zm-15.083-1.3c-.05-.039-1.179-3.866-1.264-4.29c-.016-.084.146-.044 2.174.536c2.121.604 2.192.629 2.222.74c.028.098.011.129-.125.223c-.084.059-.769.724-1.523 1.479a64 64 0 0 1-1.39 1.367c-.016 0-.056-.025-.093-.054zm.821-4.378c-1.188-.343-2.164-.623-2.167-.626c-.016-.012 1.261-4.433 1.285-4.46c.022-.022 4.422 1.211 4.469 1.252c.009.009-.269 1.017-.618 2.239c-.576 2.02-.643 2.224-.723 2.22c-.05-.003-1.059-.285-2.247-.626zm2.959.538c.012-.031.212-.723.444-1.534l.42-1.476l.056.321c.093.556.265 1.188.464 1.741c.106.296.187.539.181.545c-.008.006-.332.101-.719.212c-.389.109-.741.21-.786.224q-.085.025-.059-.034zM4.905 6.112c-1.187-.339-2.167-.635-2.18-.654c-.04-.062-1.246-4.321-1.23-4.338c.026-.025 4.31 1.204 4.351 1.246c.047.051 1.28 4.379 1.246 4.376L4.91 6.113zm2.148-1.713l-.519-1.806l-.078-.28l1.693-.483c.934-.265 1.724-.495 1.76-.508c.034-.016-.083.14-.26.336A8.7 8.7 0 0 0 7.69 5.23a4 4 0 0 0-.132.561c0 .293-.115-.025-.505-1.39z"/></svg>');
}
.md-typeset .admonition.french-instance,
.md-typeset details.french-instance {
border-color: rgb(0, 0, 145);
}
.md-typeset .french-instance > .admonition-title::before,
.md-typeset .french-instance > summary::before {
background-color: rgb(0, 0, 145);
-webkit-mask-image: var(--md-admonition-icon--french-instance);
mask-image: var(--md-admonition-icon--french-instance);
}
.md-typeset .admonition.osm-instance,
.md-typeset details.osm-instance {
border-color: #77cc6d;
}
.md-typeset .osm-instance > .admonition-title::before,
.md-typeset .osm-instance > summary::before {
background-color: #77cc6d;
-webkit-mask-image: var(--md-admonition-icon--osm-instance);
mask-image: var(--md-admonition-icon--osm-instance);
}

View file

@ -77,7 +77,6 @@ Any property of the feature will be available, plus:
- `{locale}` → the locale in the form `en` or `en_US` when a variant is used
- `{lang}` → the lang in the form `en` or `en-us` when a variant is used
- `{measure}` → the length of a line or the area of a polygon
- `{gain}`/`{loss}` → the elevation gain/loss of a line (only if it contains the altitude information)
- `{rank}` → the rank of the feature in the layer
- `{layer}` → the name of the feature's layer
- `{zoom}` → the current map zoom
@ -92,27 +91,3 @@ Any property of the feature will be available, plus:
- `{zoom}` → the current map zoom
- `{lat}` → the latitude of the current map center
- `{lng}` → the longitude of the current map center
## Which statuses can have a map? {: #map-statuses}
### Access statuses
* **Draft (private)**: Only you and your collaborators are able to see the map.
* **Everybody (public)**: Everybody can see your map, it is listed on search results and potentially the homepage. It is indexed by search engines like Google.
* **Anyone with link**: The map will be accessible only to people knowing the link. The map is not indexed by search engines.
* **Editors and team only**: Only you and your collaborators will be able to see the map.
Providing a link of a map to unallowed people will display a `403 Forbidden` error.
### Edit statuses
* **Owner only**: only the owner of the map can edit it.
* **Editors and team only**: the owner, editors and members of the linked team will be able to edit the map.
* **Everyone**: Everybody can edit the map without even being logged in.
Only for maps created without an account:
* **Only editable with secret edit link**: Only people with a secret link will be able to edit the map.
These settings are also available for each layer.

View file

@ -1,4 +0,0 @@
!!! example "This is an ongoing work."
[Let us know](https://github.com/umap-project/umap/issues)
if you are interested [to translate it from French](/fr/tutorials/12-display-grist-data/).

View file

@ -1,4 +0,0 @@
!!! example "This is an ongoing work."
[Let us know](https://github.com/umap-project/umap/issues)
if you are interested [to translate it from French](/fr/tutorials/4-draw-items/).

View file

@ -1,4 +0,0 @@
!!! example "This is an ongoing work."
[Let us know](https://github.com/umap-project/umap/issues)
if you are interested [to translate it from French](/fr/tutorials/4-find-data/).

View file

@ -1,4 +0,0 @@
!!! example "This is an ongoing work."
[Let us know](https://github.com/umap-project/umap/issues)
if you are interested [to translate it from French](/fr/tutorials/6-one-click-data-import/).

View file

@ -1,4 +0,0 @@
!!! example "This is an ongoing work."
[Let us know](https://github.com/umap-project/umap/issues)
if you are interested [to translate it from French](/fr/tutorials/8-proportional-circles/).

View file

@ -1,405 +1,16 @@
# Changelog
## 3.0.5 - 2025-04-25
* allow to save a remote data with unloaded data by @yohanboniface in #2657
* allow to save/undo/sync drag'n'drop of datalayers by @yohanboniface in #2677
* setting center and zoom manually should set dirty status by @yohanboniface in #2676
* fix error when saving and deleting heatmap layer by @yohanboniface in #2681
* make rules reordering syncable, savable and undoable by @yohanboniface in #2672
* loading remote data should not make the map dirty by @yohanboniface in #2679
* implement a design system for UI consistency by @davidbgk in #2654
* pass CSRF_TRUSTED_ORIGINS env to settings by @lippoliv in #2656
* do not display "saved" message if some request failed by @yohanboniface in #2669
* show an error message if saving layer failed by @yohanboniface in #2670
* naive support for GeometryCollection as Feature geometry by @yohanboniface in #2658
* add a back button in rules form by @yohanboniface in #2673
## New Contributors
* @lippoliv made their first contribution in #2656
## 3.0.4 - 2025-04-14
* do not show "back to home" button in iframes by @yohanboniface in #2644
* remove "hide home button" shown twice in map settings by @yohanboniface in #2645
* adapt Helm chart to match La Suite's expectations by @ohemelaar in #2646
* update colors by @yohanboniface in #2647
## 3.0.3 - 2025-04-11
* do not try to remove a feature not yet added by @yohanboniface in #2637
* document that nginx needs to be added in Docker stack to serve statics by @yohanboniface in #2636
* display back help button in switch fields by @yohanboniface in #2634
* use Last-Modified header from remote data when available by @yohanboniface in #2624
* fix text overflow on search results by @yohanboniface in #2628
* redirect to user dashboard after map delete by @yohanboniface in #2626
* add missing margin-bottom in importers by @yohanboniface in #2627
* fix pictogram categories always hidden by @yohanboniface in #2630
* display search category on list page by @davidbgk in #2635
* allow to hide the layer switcher from bottom bar by @davidbgk in #2639
* hidden download button in browser when embedControl=false by @yohanboniface in #2640
* allow to hide the back to home button by @davidbgk in #2638
## 3.0.2 - 2025-04-08
* fix copiable input CSS by @yohanboniface in #2616
* fix categorized layer crashing with null value by @yohanboniface in #2621
* properly call endEdit for markers by @yohanboniface in #2617
* fix result tools buttons background color by @yohanboniface in #2620
* fix min-height of select in caption bar by @yohanboniface in #2622
* give priority to small usernames on autocomplete by @yohanboniface in #2604
## 3.0.1 - 2025-04-07
* fix showLabel wrongly using MultiChoices by @yohanboniface in #2609
## 3.0.0 - 2025-04-07
This is the first release to officially support colaborative real-time map editing.
It introduces ASGI deployement, to support websockets, and adds Redis in the stack.
But it's still possible to continue deploying in WSGI for now, and Redis is only
mandatory when using the real-time feature.
How to use the real-time editing feature in your instance:
- you need to deploy with ASGI, see https://docs.umap-project.org/en/stable/deploy/asgi/
- you need to set `REALTIME_ENABLED=True` in your settings
Other notable changes:
- a first version of a real undo/redo
- map categories; those are defined through the `UMAP_TAGS` settings
Note: you may want to update your search index to include the category search,
see https://docs.umap-project.org/en/stable/config/settings/#umap_search_configuration
### Breaking change
* The Docker image will not serve assets and data files anymore, an Nginx container must
be configured. See [docker-compose.yml](https://github.com/umap-project/umap/blob/master/docker-compose.yml)
for an example.
### New features
* add collaborative real-time map editing
* add atomic undo redo by @yohanboniface in #2570
* expose active sessions in stats endpoint by @yohanboniface in #2544
* add more users counts in /stats/ by @yohanboniface in #2555
* add new "Back to home" icon by @yohanboniface in #2551
* add experimental BAN importer by @yohanboniface in #2565
* add titles in the text formatting dialog by @yohanboniface in #2584
* layers selector in bottom bar by @yohanboniface in #2579
* display maps list as a grid now by @yohanboniface in #2590
* add Map.tags and allow to edit from client by @yohanboniface in #2530
* add minimal "raw" icon shape by @yohanboniface in #2597
### Bug fixes
* cast value to string before calling trim by @yohanboniface in #2567
* import iconUrl as absolute when possible by @yohanboniface in #2563
* iconUrl field was broken on older browsers by @yohanboniface in #2575
* do not fail when trying to read metadata of a missing geojson by @yohanboniface in #2592
* remote data loading on import from umap backup by @davidbgk in #2598
* do not export layer ids in umap backup by @davidbgk in #2600
* use the multichoices for ttl in remote data form by @davidbgk in #2599
### Internal changes
* refactor search UX by @yohanboniface in #2545
* new icon, colors and title for search buttons by @yohanboniface in #2556
* use real redraw for datalayer, instead of hide/show by @yohanboniface in #2568
* order importers by name instead of id by @yohanboniface in #2578
* update the Dockerfile to expose websockets by @almet in #2576
* remove confirm delete for features and datalayers by @yohanboniface in #2603
### Accessibility
* a11y: turn embeded maps into inert elements by @davidbgk in #2533
### Changed templates
- auth/user_detail.html
- auth/user_stars.html
- umap/content.html
- umap/home.html
- umap/map_fragment.html
- umap/map_list.html
- umap/search.html
- umap/search_bar.html
- umap/team_detail.html
## 2.9.3 - 2025-03-07
* be explicit in the message that logout is needed after adding a new oauth provider
## 2.9.2 - 2025-03-04
* measure/drawing tooltip was misplaced by @yohanboniface in #2541
* be defensive when getting the backend name from the session by @yohanboniface in #2540
## 2.9.1 - 2025-03-03
* be more persuasive in deprecating twitter login backend by @yohanboniface in #2538
## 2.9.0 - 2025-03-03
This release is mainly about making the sync feature deployable and more stable (but still
not yet activated by default).
### New features
* display map's "created at" and "modified at" in the caption by @yohanboniface in #2424
* allow to define sortKey at layer level by @yohanboniface in #2449
* move star button to caption by @yohanboniface in #2442
* add a debounce for Input and Textarea fields by @yohanboniface in #2445
* soft delete datalayers by @yohanboniface in #2459
* add DEPRECATED_AUTHENTICATION_PROVIDERS setting by @yohanboniface in #2461
* expose teams in users CSV export by @davidbgk in #2484
* add title attribute to layers in browser by @yohanboniface in #2489
* make the tooltip sticky in hover mode for paths by @yohanboniface in #2507
* make vertex icons bigger (and round) by @yohanboniface in #2506
* add a quick link to layer's permalink by @yohanboniface in #2529
### Bug fixes
* display a more usefull message when error in remote data by @yohanboniface in #2443
* fix circle icon no longer hihlighted by @yohanboniface in #2440
* keep layer visibility after clicking on toggle all by @yohanboniface in #2439
* update map.modified_at when saving a datalayer by @yohanboniface in #2423
* do not consume ctrl-Z in textarea or input by @yohanboniface in #2441
* Fix categorized layers colors palette not updating by @yohanboniface in #2447
* reference secret-env by fullname instead release-name by @swarnat in #2406
* correctly parse http link including another http link in the path by @yohanboniface in #2460
* display current configured oauth as icon instead of text by @yohanboniface in #2375
* better buttons positionning for the homepage by @davidbgk in #2463
* catch cluster error at zoom in certain situation by @yohanboniface in #2464
* display a more descriptive alert on invalid geojson error by @yohanboniface in #2466
* do not try to backup an undefined geojson by @yohanboniface in #2468
* do not error when escape during marker creation by @davidbgk in #2483
* do not import empty features by @yohanboniface in #2485
* do not display an error for an empty CSV by @yohanboniface in #2505
* try to reconnect after network error when getting token by @yohanboniface in #2502
* wait for websocket full connection by @yohanboniface in #2503
* feature edit status not disabled on hide by @yohanboniface in #2534
### Internal changes
* deactivate cancel and hide button when sync is active by @yohanboniface in #2413
* do not try to reconnect after end edit by @yohanboniface in #2412
* handle sync of datalayer delete by @yohanboniface in #2416
* internalize FormBuilder by @yohanboniface in #2420
* POC of using Redis for pubsub by @yohanboniface in #2426
* include site description within page titles by @davidbgk in #2455
* Sync show usernames by @yohanboniface in #2444
* only allow to set a map as sync when it is already saved by @yohanboniface in #2465
* move DrawToolbar and SettingsToolbar to bar.js module by @yohanboniface in #2482
* add very minimal documentation for deploying uMap with ASGI by @yohanboniface in #2480
* use default value from schema for non inheritable fields by @yohanboniface in #2513
* sync save state by @yohanboniface in #2487
* use our contexmenu class for inplace toolbar by @yohanboniface in #2510
* make sure we sync a line when hitting esc while drawing by @yohanboniface in #2526
* make datalayer upsert idempotent by @yohanboniface in #2528
### Accessibility
* set an aria-label for unlabelled search input by @davidbgk in #2531
* switch to better contrasted links by @davidbgk in #2532
### New Contributors
* @swarnat made their first contribution in #2406
## 2.8.2 - 2024-12-26
### Bug fixes
* fix create marker from search result by @yohanboniface in #2404
* fix startMarker/Polyline/Polygon on right click by @yohanboniface in #2403
## 2.8.1 - 2024-12-24
### Bug fixes
* honour carriage returns in layer description (in caption panel) by @yohanboniface in #2386
* update star icon on star/unstar by @yohanboniface in #2387
* reconnect websocket on disconnection by @almet in #2389
* fix duplicated content during sync by @yohanboniface in #2388
* main help button was broken by @yohanboniface in #2393
* split zoomTo to accept bounds by @davidbgk in #2394
* zoom to droped file once loaded by @davidbgk in #2401
* do not load all datalayers at once by @yohanboniface in #2402
* add a 403.html template by @yohanboniface in #2396
## 2.8.0 - 2024-12-18
### What's Changed
This release is mainly about being able to deploy uMap on helm/k8s, with a S3-compatible storage. Doing so,
we introduce two new map statuses:
- "draft" (which is now the default, unless you change the UMAP_DEFAULT_SHARE_STATUS setting), which
makes the maps private by default
- "deleted", which make that now a delete will be a soft delete (and the command `umap empty_trash`
could be run to do the real delete).
Also pursuing the code cleaning (more modules and spliting uMap core code from Leaflet rendering one).
Finally, this is now the javascript who create the datalayer uuid, and then push it to the back. This
is for preparing for the synchronisation between clients.
### Breaking change
* if you use `X-Accel-Redirect` with Nginx, you **must** make sure that the `X-DataLayer-Version` header
is forwarded to the client. This is the line you usually need to add in your Nginx `/internal/` config:
add_header X-DataLayer-Version $upstream_http_x_datalayer_version;
See the [documentation](deploy/nginx.md) for more informations.
### New features
* add umap helm chart for Kubernetes deployment by @NaPs in #2286
* support storing layer data in S3 like servers by @yohanboniface in #2304
* introduce Map.share_status=DRAFT and DELETED by @yohanboniface in #2357
* highlight importer URL field when it is fulfilled by @yohanboniface in #2323
* swap import and settings buttons in edit toolbar by @yohanboniface in #2329
* make expression persistent in the overpass importer by @yohanboniface in #2339
* add basic autocompletion on inputs expecting a field name by @yohanboniface in #2281
* allow to configure the default label keys per instance by @yohanboniface in #2291
* display an image from Panoramax in OSM template when tag is defined by @yohanboniface in #2338
* add a disabled/active mode to the submit button of import panel by @yohanboniface in #2341
* open importers in a dialog instead of in the form by @yohanboniface in #2327
* display wikipedia link in OSM popup template when possible by @yohanboniface in #2358
* move labelKey field on the top datalayer form by @yohanboniface in #2350
* add elevation gain and loss in extended properties by @yohanboniface in #2343
* add a back button to importers dialog by @yohanboniface in #2364
* load all datalayers in parallel by @yohanboniface in #2370
* parse files in parallel at import when multiple by @yohanboniface in #2372
* allow to edit datalayer name in datalayers list by @yohanboniface in #2349
* experimental popup template for wikipedia by @yohanboniface in #2365
### Bug fixes
* honour custom labelKey in default popup template by @yohanboniface in #2271
* honour `rules` and `slideshow` when importing a umap file by @yohanboniface in #2270
* use our fork of csv2geojson to be able to parse lat/lon with commas by @yohanboniface in #2263
* allow spaces in iframe query strings in HTML formatting by @yohanboniface in #2292
* do not fail when navigating with popup arrows in cluster mode by @yohanboniface in #2307
* better login page styles and incentive by @davidbgk in #2293
* compute length of all shapes for MultiLineString (not only first) by @yohanboniface in #2310
* avoid map-panning on mobile using two fingers navigation by @fttriquet in #2340
* do not try to restore a newly created layer on reset by @yohanboniface in #2381
* do not unset map dirty status if it has not yet been saved once by @yohanboniface in #2382
* refactor importer feedback by @yohanboniface in #2363
* make sure we set X-DataLayer-Version even when using X-Accel-Redirect by @yohanboniface in #2361
* bring marker to front on highlight by @yohanboniface in #2377
* show private/draft maps in team maps for members by @yohanboniface in #2373
### Internal changes
* introduce SaveManager class by @yohanboniface in #2240
* split umap.js in two modules by @yohanboniface in #2257
* make the client create the DataLayer.id by @yohanboniface in #2259
* move editToolBar and captionBar to modules by @yohanboniface in #2272
* update browserslist to be more explicit by @davidbgk in #2277
* explicitely set postgis as db engine by @yohanboniface in #2285
* add logo for social_core.backends.keycloak.KeycloakOAuth2 by @tomamplius in #2258
### Changed templates
* umap/css.html:
* added `umap/css/bar.css`
* added `umap/css/popup.css`
* umap/js.html:
* added `umap/css/bar.js`
* umap/templates/registration/login.html
* umap/templates/umap/map_init.html
* changed the way we instanciate `Umap` (instead of `U.Map`)
* umap/templates/umap/user_dashboard.html
* changed the way we instanciate `Umap` (instead of `U.Map`)
### New Contributors
* @NaPs made their first contribution in #2286
* @tomamplius made their first contribution in #2258
* @fttriquet made their first contribution in #2340
## 2.7.1 - 2024-10-25
### Bug fixes
* use shutil.move instead of Path.rename to move to purgatory by @yohanboniface in #2236
* always unset editedFeature on editPanel close by @yohanboniface in #2237
## 2.7.0 - 2024-10-24
### New features
* delete datalayer's files on delete by @yohanboniface in #2158
- deleted files will be moved to `UMAP_PURGATORY_ROOT`, so set this setting to
somewhere meaningful for your instance (default is `/tmp/umappurgatory`)
* very minimal CSV export of users and maps in admin by @yohanboniface in #2131
* add a setting to prevent users from editing their profile by @davidbgk in #2133
* allow to search by code INSEE in communes importer by @yohanboniface in #2188
* add a profile drop-down menu by @yohanboniface in #2194
* only add visible markers (and tooltips) to DOM by @yohanboniface in #2204
* add a global toolbox in browser by @yohanboniface in #2160
* add importer for French cadastre by @yohanboniface in #2223
* display the number of connected peers in the interface. by @almet in #2177
* allow to run umap with asgi by @yohanboniface in #2209
### Bug fixes
* make sure maps of demo instances of uMap are no indexed by @yohanboniface in #2203
* fix contextmenu positionning when map is not full screen by @yohanboniface in #2198
* honour carriage returns in permanent credits by @yohanboniface in #2206
* do not show browser counter when layer is empty or not loaded by @yohanboniface in #2217
* fix dispeared icons from panel titles by @yohanboniface in #2222
* use correct icon for layer download advanced action by @yohanboniface in #2224
* do not try to create legend for non loaded classified layer by @yohanboniface in #2234
* icon alignement in browser, and user icon-xxx class by @yohanboniface in #2132
* editing coordinates manually would not be saved by @yohanboniface in #2147
* remoteData helpEntries were not on the right format by @yohanboniface in #2183
* polygon with interactive=false was still interactive by @yohanboniface in #2151
* allow to draw new proprotional circles and to drag them by @yohanboniface in #2172
* make sure anonymous is owner at create by @yohanboniface in #2189
### Internal changes
* deactivate contextmenu and shortcuts in map preview by @yohanboniface in #2199
* use pytest-rerunfailed by @yohanboniface in #2205
* simplify contextmenu items by @yohanboniface in #2216
* Docker: `version` is obsolete. by @Luen in #2220
* get Github release notes from command line by @yohanboniface in #2130
* rework permissions panel by @yohanboniface in #2121
* new tutorial and improvements by @C-Sophie by @davidbgk in #2156 #2167
* use GeoRSStoGeoJSON as ES module by @yohanboniface in #2168
* add clean_tilelayer management command by @yohanboniface in #1670
* send remote operations to peers when they join by @almet in #2082
* spawn the websocket server in the docker image. by @almet in #2175
* use our own contextmenu by @yohanboniface in #2109
* display user maps in admin and add in csv export by @yohanboniface in #2169
* remove zoom in and out from contextmenu by @yohanboniface in #2195
### Changed templates
* umap/css.html:
- removed `umap/vendors/contextmenu/leaflet.contextmenu.min.css`
- added `umap/css/contextmenu.css`
* umap/js.html:
- removed `umap/vendors/contextmenu/leaflet.contextmenu.min.js`
* umap/templates/umap/map_detail.html:
- changed robot directive
* umap/templates/umap/dashboard_menu.html
- use of `UMAP_ALLOW_EDIT_PROFILE`
Thanks @Luen for their first contribution!
## 2.6.3 - 2024-09-11
* delete shape from edit toolbar by @yohanboniface in #2126
* fix merge lines on vertex click by @yohanboniface in #2128
* clicking feature in the browser would not open popup in cluster by @yohanboniface in #2129
## 2.6.2 - 2024-09-10
### Bug fixes
* fix German translation breaking home page in /de/
- fix German translation breaking home page in /de/
## 2.6.1 - 2024-09-10
### Bug fixes
* fix `teams.all()` called by mistake on anonymous users
- fix `teams.all()` called by mistake on anonymous users
## 2.6.0 - 2024-09-10

View file

@ -28,14 +28,6 @@ Can be set through env var too: `ALLOWED_HOSTS=umap.mydomain.org,u.mydomain.org`
Set it to `True` for easier debugging in case of error.
#### DEPRECATED_AUTHENTICATION_BACKENDS
List of auth backends to deprecate. Defining this will display a message to
all users using this provider, to encourage them to configure another provider to
their account.
DEPRECATED_AUTHENTICATION_BACKENDS = ["social_core.backends.twitter_oauth2.TwitterOAuth2"]
#### EMAIL_BACKEND
Must be configured if you want uMap to send emails to anonymous users.
@ -88,19 +80,6 @@ Nginx configuration.
See [Django documentation for MEDIA_ROOT](https://docs.djangoproject.com/en/4.2/ref/settings/#media-root)
#### REALTIME_ENABLED
Setting `REALTIME_ENABLED` to `True` will allow users to enable real-time collaboration.
A switch will be available for them in the "advanced properties" of the map.
See [the documentation about ASGI deployment](../deploy/asgi.md) for more information.
#### REDIS_URL
Connection URL to the Redis server. Only need for the real-time editing.
Default: `redis://localhost:6379`
#### SECRET_KEY
Must be defined to something unique and secret.
@ -110,6 +89,13 @@ Running uMap / Django with a known SECRET_KEY defeats many of Djangos securit
See [Django documentation for SECRET_KEY](https://docs.djangoproject.com/en/4.2/ref/settings/#secret-key)
#### SITE_URL
The final URL of you instance, including the protocol:
`SITE_URL=http://umap.org`
#### SHORT_SITE_URL
If you have a short domain for sharing links.
@ -119,26 +105,7 @@ Eg.: `SHORT_SITE_URL=https://u.umap.org`
#### SITE_NAME
The name of the site, to be used in header.
#### SITE_DESCRIPTION
The description of the site, to be used in HTML title.
#### SITE_URL
The final URL of you instance, including the protocol:
`SITE_URL=http://umap.org`
#### SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET
If you use OpenStreetMap as OAuth 2 provider, you can use those settings.
Otherwise, use any valid [python-social-auth configuration](https://python-social-auth.readthedocs.io/en/latest/configuration/django.html).
The name of the site, to be used in header and HTML title.
#### STATIC_ROOT
@ -148,12 +115,6 @@ Nginx configuration.
See [Django documentation for STATIC_ROOT](https://docs.djangoproject.com/en/4.2/ref/settings/#static-root)
#### STORAGES
See [storage](storage.md).
#### USE_I18N
Default is True. Set it to False if you don't want uMap to localize the app.
@ -183,12 +144,6 @@ Should uMap allows user without an account to create maps (default is False).
Can be set through env var: `UMAP_ALLOW_ANONYMOUS=1`
#### UMAP_ALLOW_EDIT_PROFILE
Should uMap allows users to edit their profile (default is True).
Can be unset through env var: `UMAP_ALLOW_EDIT_PROFILE=0`
#### UMAP_CUSTOM_TEMPLATES
To be used when you want to override some HTML templates:
@ -214,6 +169,11 @@ UMAP_EXTRA_URLS = {
}
```
#### UMAP_KEEP_VERSIONS
How many datalayer versions to keep. 10 by default.
#### UMAP_DEFAULT_EDIT_STATUS
Define the map default edit status.
@ -304,16 +264,6 @@ Available importers:
- `communesfr`: download French communes boundaries, from https://geo.api.gouv.fr/
- `datasets`: define URLs you want to promote to users, with a `name` and a `format`
#### UMAP_KEEP_VERSIONS
How many datalayer versions to keep. 10 by default.
#### UMAP_LABEL_KEYS
List of properties to consider as "Feature label" (to show in popup or in browser).
UMAP_LABEL_KEYS = ["name", "title"]
#### UMAP_MAPS_PER_PAGE
How many maps to show in maps list, like search or home page.
@ -343,10 +293,7 @@ CREATE EXTENSION btree_gin;
ALTER TEXT SEARCH CONFIGURATION umapdict ALTER MAPPING FOR hword, hword_part, word WITH unaccent, simple;
# Now create the index
CREATE INDEX IF NOT EXISTS search_idx ON umap_map USING GIN(to_tsvector('umapdict', COALESCE(name, ''::character varying)::text), share_status, tags);
# You should also create an index for tag filtering:
CREATE INDEX IF NOT EXISTS tags_idx ON umap_map USING GIN(share_status, tags);
CREATE INDEX IF NOT EXISTS search_idx ON umap_map USING GIN(to_tsvector('umapdict', COALESCE(name, ''::character varying)::text), share_status);
```
Then set:
@ -368,3 +315,61 @@ Should uMap gzip datalayers geojson.
Can be set to `X-Accel-Redirect` to enable the [NGINX X-Accel](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/) feature.
See the NGINX documentation in addition.
#### SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET
If you use OpenStreetMap as OAuth 2 provider, you can use those settings.
Otherwise, use any valid [python-social-auth configuration](https://python-social-auth.readthedocs.io/en/latest/configuration/django.html).
#### WEBSOCKET_ENABLED
A WebSocket server is packaged with uMap, and can be turned-on to activate
"real-time collaboration". In practice, in order to enable it, a few settings
are exposed.
Setting `WEBSOCKET_ENABLED` to `True` will **not** enable real-time
collaboration on all the maps served by the server. Instead, a switch will be
available in the "advanced properties" of the map.
The websocket server can be started with the following command:
```bash
umap run_websocket_server
```
And can take optional settings `--host` and `--port` (default values are defined in
the settings).
Configuration example:
```python
WEBSOCKET_ENABLED = True
WEBSOCKET_BACK_HOST = "localhost"
WEBSOCKET_BACK_PORT = 8002
WEBSOCKET_FRONT_URI = "ws://localhost:8002"
```
These settings can also be set with the (same names) environment variables.
#### WEBSOCKET_BACK_HOST
#### WEBSOCKET_BACK_PORT
The internal host and port the websocket server will connect to.
#### WEBSOCKET_FRONT_URI
The connection string that will be used by the client to connect to the
websocket server. In practice, as it's useful to put the WebSocket server behind
TLS encryption, the values defined by `WEBSOCKET_FRONT_URI` are different than
the values defined by `WEBSOCKET_BACK_PORT` and `WEBSOCKET_BACK_HOST`.
This value is comprised of three parts:
```
protocol://host:port
```
- `protocol`: can either be `ws` for plain unencrypted WebSockets, or `wss` when using TLS encryption.
- `host`: is the address where the connection will be sent. It should be public facing.
- `port`: is the port that is open on the host.

View file

@ -1,81 +0,0 @@
# Storage
uMap stores metadata (such as owner, permissions…) in PostgreSQL, and the data itself (the content of a layer)
in geojson format, by default on the local file system, but optionally in a S3 like server.
This can be configured through the `STORAGES` settings. uMap will use three keys:
- `default`, used only for the pictogram files, it can use whatever storage suits your needs
- `staticfiles`, used to store the static files, it can use whatever storage suits your needs,
but by default uses a custom storage that will add hash to the filenames, to be sure they
are not kept in any cache after a release
- `data`, used to store the layers data. This one should follow the uMap needs, and currently
uMap provides only two options: `umap.storage.fs.FSDataStorage` and `umap.storage.s3.S3DataStorage`
## Default settings:
This will use the file system for everything, including the data.
```
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"data": {
"BACKEND": "umap.storage.fs.FSDataStorage",
},
"staticfiles": {
"BACKEND": "umap.storage.staticfiles.UmapManifestStaticFilesStorage",
},
}
```
## Using S3
To use an S3 like server for the layers data, the first thing is to install
the needed dependencies: `pip install umap-project[s3]`.
Then, change the `STORAGES` settings with something like this:
```
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"access_key": "xxx",
"secret_key": "yyy",
"bucket_name": "umap-pictograms",
"endpoint_url": "http://127.0.0.1:9000",
"default_acl": "public-read",
},
},
"data": {
# Whatch out, this is a dedicated uMap class!
"BACKEND": "umap.storage.s3.S3DataStorage",
"OPTIONS": {
"access_key": "xxx",
"secret_key": "yyy",
"bucket_name": "umap-data",
"endpoint_url": "http://127.0.0.1:9000",
},
},
"staticfiles": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"access_key": "xxx",
"secret_key": "yyy",
"bucket_name": "umapstatics",
"endpoint_url": "http://127.0.0.1:9000",
"default_acl": "public-read",
},
},
}
```
As you can see in this example, both `staticfiles` and `default` use the storage class provided
by `django-storages` (`storages.backends.s3.S3Storage`), but the `data` one uses a specific class
(`umap.storage.s3.S3DataStorage`).
In order to store old versions of a layer, the versioning should be activated in the bucket.
See more about the configuration on the [django-storages documentation](https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html).

View file

@ -1,92 +0,0 @@
# ASGI
While uMap has been historically deployed using the WSGI specification,
there is now an **experimental** ASGI endpoint. This will be the way to
deploy uMap to use the live collaborative editing feature, which needs
websockets.
## Nginx
When using ASGI, the [nginx](nginx.md), the `/` entrypoint should be:
```
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://umap/;
}
```
Also add this mapping for the `$connection_upgrade` variable:
```
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
```
## Uvicorn
Uvicorn must be installed in the umap virtualenv:
/path/to/umap/venv/bin/pip install uvicorn
And could then be run like this:
/path/to/umap/venv/bin/uvicorn \
--proxy-headers \
--uds /srv/umap/umap.sock \
--no-access-log \
umap.asgi:application
## Systemd
Here is an example service to manage uvicorn with systemd:
```
[Unit]
Description=umap
After=network.target
Requires=postgresql.service
[Service]
Type=simple
User=umap
WorkingDirectory=/srv/umap/
PrivateTmp=true
EnvironmentFile=/srv/umap/env
ExecStart=/srv/umap/venv/bin/uvicorn \
--proxy-headers \
--uds /srv/umap/uvicorn.sock \
--no-access-log \
umap.asgi:application
ExecReload=/bin/kill -HUP ${MAINPID}
RestartSec=1
Restart=always
[Install]
WantedBy=multi-user.target
```
Then to install it and enable it, copy it to `/etc/systemd/system/umap.service`
and run:
sudo systemctl enable umap.service
## Env
Uvicorn can be [configured](https://www.uvicorn.org/deployment/) from env vars,
for example to define the number of workers:
```env title="/srv/umap/env"
UVICORN_WORKERS=4
```

View file

@ -3,6 +3,7 @@
An official uMap docker image is [available on the docker hub](https://hub.docker.com/r/umap/umap). But, if you prefer to run it with docker compose, here is the configuration file:
```yaml title="docker-compose.yml"
version: '3'
services:
db:
# check https://hub.docker.com/r/postgis/postgis to see available versions
@ -14,7 +15,7 @@ services:
app:
# Check https://hub.docker.com/r/umap/umap/tags to find the latest version
image: umap/umap:2.9.3
image: umap/umap:2.0.2
ports:
# modify the external port (8001, on the left) if desired, but make sure it matches SITE_URL, below
- "8001:8000"
@ -48,45 +49,3 @@ User accounts can be managed via the Django admin page ({SITE_URL}/admin). The r
```bash
umap createsuperuser
```
## Developping with Docker
If you want to develop with podman or docker, here are commands that might be useful, given that you have a postgreSQL server running locally and that your settings are located at `umap.conf`:
You can build the docker image with:
```bash
podman build -t umap .
```
And run it with:
```bash
podman run -v ./umap.conf:/tmp/umap.conf -e UMAP_SETTINGS=/tmp/umap.conf -it --network host umap
```
## Real time collaboration
To enable real time collaboration when using Docker, a Redis service must be added. Something like this in `docker-compose.py` world:
```yaml title="docker-compose.yml"
services
redis:
image: redis:latest
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
command: ["redis-server"]
app:
depends_on:
redis:
condition: service_healthy
environment:
- REALTIME_ENABLED=1
- REDIS_URL=redis://redis:6379
```

View file

@ -1,7 +0,0 @@
# Helm
To deploy using helm:
helm install <my-release> oci://registry-1.docker.io/umap/umap
Helm chart is pushed here: https://hub.docker.com/repository/docker/umap/umap/tags

View file

@ -1,10 +1,84 @@
# Configuring Nginx
See [WSGI](wsgi.md) or [ASGI](asgi.md) for a basic setup.
Here are some configuration files to use umap with nginx and [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/), a server for python, which will handle your processes for you.
Then consider adding this configuration
```nginx title="nginx.conf"
upstream umap {
server unix:///srv/umap/uwsgi.sock;
}
## Static files and geojson
server {
# the port your site will be served on
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
# the domain name it will serve for
server_name your-domain.org;
charset utf-8;
# max upload size
client_max_body_size 5M; # adjust to taste
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass umap;
include /srv/umap/uwsgi_params;
}
}
```
## uWSGI
```nginx title="uwsgi_params"
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
```
```ini title="uwsgi.ini"
[uwsgi]
uid = umap
gid = users
# Python related settings
# the base directory (full path)
chdir = /srv/umap/
# umap's wsgi module
module = umap.wsgi
# the virtualenv (full path)
home = /srv/umap/venv
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 4
# the socket (use the full path to be safe)
socket = /srv/umap/uwsgi.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
stats = /srv/umap/stats.sock
# clear environment on exit
vacuum = true
plugins = python3
```
## Static files
```nginx title="nginx.conf"
location /static {
@ -42,53 +116,6 @@ UMAP_XSENDFILE_HEADER = 'X-Accel-Redirect'
internal;
gzip_vary on;
gzip_static on;
# Next line is very important!
add_header X-DataLayer-Version $upstream_http_x_datalayer_version;
alias /path/to/umap/var/data/;
}
```
## Ajax proxy
In order for users to load CORS protected data within a map, Nginx can act as a proxy.
Here is an example configuration for this:
```
location ~ ^/proxy/(.*) {
internal;
add_header X-Proxy-Cache $upstream_cache_status always;
proxy_cache_background_update on;
proxy_cache_use_stale updating;
proxy_cache ajax_proxy;
proxy_cache_valid 1m; # Default. Umap will override using X-Accel-Expires
set $target_url $1;
# URL is encoded, so we need a few hack to clean it back.
if ( $target_url ~ (.+)%3A%2F%2F(.+) ){ # fix :// between scheme and destination
set $target_url $1://$2;
}
if ( $target_url ~ (.+?)%3A(.*) ){ # fix : between destination and port
set $target_url $1:$2;
}
if ( $target_url ~ (.+?)%2F(.*) ){ # fix / after port, the rest will be decoded by proxy_pass
set $target_url $1/$2;
}
resolver 8.8.8.8;
add_header X-Proxy-Target $target_url; # For debugging
proxy_pass_request_headers off;
proxy_set_header Content-Type $http_content_type;
proxy_set_header Content-Encoding $http_content_encoding;
proxy_set_header Content-Length $http_content_length;
proxy_read_timeout 10s;
proxy_connect_timeout 5s;
proxy_ssl_server_name on;
proxy_pass $target_url;
proxy_intercept_errors on;
error_page 301 302 307 = @handle_proxy_redirect;
}
location @handle_proxy_redirect {
resolver 8.8.8.8;
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
```

View file

@ -1,37 +0,0 @@
# Deploying uMap
uMap is a python package, running [Django](https://docs.djangoproject.com/en/5.2/howto/deployment/),
so anyone experimented with this stack will find it familiar, but there are some speficic details
to know about.
## Data
One important design point of uMap is that while metadata are stored in a PostgreSQL database, the
data itself is stored in the file system, as geojson files. This design choice has been made
to make uMap scale better, as there are much more reads than writes, and when some
map is shared a lot (like on a national media) we want to be able to serve it without needing an
overcomplex and costly stack.
So when a request for data is made (that is on a *DataLayer*), the flow is that uMap will read
the request headers to check for permissions, and then it will forward the request to Nginx,
that will properly serve the data (a geojson file), without consuming a python worker, and with
much more efficiency than python.
In DEBUG mode, uMap will serve the geojson itself, but this is not recommended in production,
unless you have a very small audience.
Data can also be stored in a [S3 like storage](../config/storage/#using-s3).
## Assets (JS, CSS…)
As any web app, uMap also needs static files to be served. In DEBUG mode, Django will do this
kindly, but not in production. See [Nginx configuration](nginx.md) for this.
Assets can also be stored in a [S3 like storage](../config/storage/#using-s3).
## python app (metadata, permissions…)
uMap needs a python server, which can either be of [WSGI](wsgi.md) or [ASGI](asgi.md) (this later
is needed in order to use the collaborative live editing).
## Redis
Still when using the collaborative live editing, uMap needs a [Redis](../config/settings.md#redis_url) server, to act as pubsub.

View file

@ -1,87 +0,0 @@
# WSGI
WSGI is the historical standard to serve python in general, and uMap in this case.
From recently, uMap also supports [ASGI](asgi.md), which is required to use the
collaborative editing feature.
## uWSGI
In Nginx host, use:
```nginx title="nginx.conf"
upstream umap {
server unix:///srv/umap/umap.sock;
}
server {
# the port your site will be served on
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
# the domain name it will serve for
server_name your-domain.org;
charset utf-8;
# max upload size
client_max_body_size 5M; # adjust to taste
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass umap;
include /srv/umap/uwsgi_params;
}
}
```
```nginx title="uwsgi_params"
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
```
```ini title="uwsgi.ini"
[uwsgi]
uid = umap
gid = users
# Python related settings
# the base directory (full path)
chdir = /srv/umap/
# umap's wsgi module
module = umap.wsgi
# the virtualenv (full path)
home = /srv/umap/venv
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 4
# the socket (use the full path to be safe)
socket = /srv/umap/umap.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
stats = /srv/umap/stats.sock
# clear environment on exit
vacuum = true
plugins = python3
```
See also [Django documentation](https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/).

View file

@ -63,3 +63,15 @@ When the data layers are initialized, they can have two states:
To mark what needs to be synced with the server, uMap currently mark objects as "dirty". Something marked as "dirty" has changed on the client, but is not yet saved on the server.
Each map, datalayer and permission objects can be marked as "dirty". When a change is made on an object, it will mark its parent as "dirty" as well, so it can be updated accordingly.
### Saving data to the server with `umap.save()`
Here is what's being done when you call `map.save()`:
1. `map.saveSelf()`, posting `name`, `center` and `settings` to the server, and then
2. calls `permission.save()`, which will post the permissions to the server, and then call back
3. `map.continueSaving()`, which will take the first dirtyLayer and call
4. `datalayer.save()` on it. It does the following:
1. Post the data (`name`, `displayOnLoad`, `rank`, `settings`, and `geojson`)
2. Calls `permission.save()`, posting `edit_status` to the server, and then calling `map.continue_saving()` and remove the datalayer from `dirtyDatalayers`.
5. When the `dirtyDatalayers` list is empty, we are done.

View file

@ -22,14 +22,14 @@
- commit new translations `git commit -am "i18n"`
2. Test collectstatic: `umap collectstatic --no-input`
2. Bump version: `make patch|minor`
2. Ask automatic release notes to Github: `make changelog` and paste it in `docs/changelog.md`
3. `git commit -am "2.X.Y"`
4. `git tag 2.X.Y`
5. `git push && git push --tag`
6. Go to [Github release page](https://github.com/umap-project/umap/releases/new) and paste release notes
7. `make build`
8. `make publish`
9. `make docker`
6. Go to [Github release page](https://github.com/umap-project/umap/releases/new) and Generate release notes + paste it in `docs/changelog.md` + finish Github process for a new release
7. Commit the changelog `git commit -am "changelog"`
8. `make build`
9. `make publish`
10. `make docker`
### Deploying instances

View file

@ -1,5 +1,5 @@
# Force rtfd to use a recent version of mkdocs
mkdocs==1.6.1
pymdown-extensions==10.14.3
mkdocs-material==9.6.12
mkdocs-static-i18n==1.3.0
pymdown-extensions==10.9
mkdocs-material==9.5.34
mkdocs-static-i18n==1.2.3

View file

@ -15,15 +15,10 @@ nav:
- Configuration:
- Settings: config/settings.md
- Customize: config/customize.md
- Storage: config/storage.md
- Icon packs: config/icons.md
- Deployment:
- Overview: deploy/overview.md
- Docker: deploy/docker.md
- Helm: deploy/helm.md
- Nginx: deploy/nginx.md
- ASGI: deploy/asgi.md
- WSGI: deploy/wsgi.md
- Changelog: changelog.md
theme:
name: material

8627
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,8 @@
"fetch-mock": "^9.11.0",
"happen": "~0.1.3",
"lebab": "^3.2.1",
"mocha": "10.7.3",
"mocha": "^10.3.0",
"optimist": "~0.4.0",
"sinon": "^15.1.0",
"uglify-js": "~3.17.4"
},
@ -37,16 +38,18 @@
"homepage": "http://wiki.openstreetmap.org/wiki/UMap",
"dependencies": {
"@dwayneparton/geojson-to-gpx": "^0.2.0",
"@placemarkio/tokml": "0.3.4",
"@tmcw/togeojson": "^7.1.0",
"colorbrewer": "1.5.7",
"csv2geojson": "github:umap-project/csv2geojson#patched",
"dompurify": "3.2.4",
"georsstogeojson": "^0.2.0",
"@placemarkio/tokml": "^0.3.3",
"@tmcw/togeojson": "^5.8.0",
"colorbrewer": "^1.5.6",
"csv2geojson": "5.1.2",
"dompurify": "^3.0.11",
"georsstogeojson": "^0.1.0",
"jsdom": "^24.0.0",
"leaflet": "1.9.4",
"leaflet-editable": "^1.3.1",
"leaflet-contextmenu": "^1.4.0",
"leaflet-editable": "^1.3.0",
"leaflet-editinosm": "0.2.3",
"leaflet-formbuilder": "0.2.10",
"leaflet-fullscreen": "1.0.2",
"leaflet-hash": "0.2.1",
"leaflet-i18n": "0.3.5",
@ -56,14 +59,14 @@
"leaflet-minimap": "^3.6.1",
"leaflet-toolbar": "umap-project/Leaflet.toolbar",
"leaflet.heat": "0.2.0",
"leaflet.locatecontrol": "0.81.1",
"leaflet.locatecontrol": "^0.79.0",
"leaflet.markercluster": "^1.5.3",
"leaflet.path.drag": "0.0.6",
"leaflet.photon": "0.9.2",
"leaflet.photon": "0.9.1",
"osmtogeojson": "^3.0.0-beta.5",
"simple-statistics": "7.8.5"
"simple-statistics": "^7.8.3"
},
"browserslist": [
"defaults and fully supports es6-module"
"> 0.5%, last 2 versions, Firefox ESR, not dead, not op_mini all"
]
}

Some files were not shown because too many files have changed in this diff Show more