Compare commits

...

33 Commits
1.5 ... 1.9

Author SHA1 Message Date
d4d39689cc Merge pull request '# Bugfix' (#425) from 424_Archived_codes_selectable into master
Reviewed-on: #425
2024-08-06 14:28:16 +02:00
2fde3f0fa3 # Bugfix
* fixes bug where archived codes has been selectable due to recursive building of child-parent hierarchy
2024-08-06 14:27:38 +02:00
b62c2e92c9 Merge pull request '# Dependency fix' (#422) from 419_Dependency_upgrade into master
Reviewed-on: #422
2024-07-10 09:30:14 +02:00
1c0fb801e6 # Dependency fix
* fixes dependency mismatch between requests 2.32.3 and kombu (requires < 2.32.0)
2024-07-10 09:29:54 +02:00
a1acff5e90 Merge pull request '# Dependency update' (#420) from 419_Dependency_upgrade into master
Reviewed-on: #420
2024-07-10 09:26:35 +02:00
25a92f59aa # Dependency update
* updates dependencies due to important version changes
2024-07-10 09:26:18 +02:00
884db6f014 Merge pull request '# Readonly map' (#417) from map_client_update_08-07-2024 into master
Reviewed-on: #417
2024-07-08 18:44:00 +02:00
59b7f3c69a # Readonly map
* fixes bug where readonly mode of map client was not readonly at all
2024-07-08 06:59:15 +02:00
0446d50438 Merge pull request '# .env fix' (#415) from env_fix into master
Reviewed-on: #415
2024-07-05 10:51:25 +02:00
12f78c85bf # .env fix
* adds celery setting to .env.sample
2024-07-05 10:50:25 +02:00
78485a4506 Merge pull request '# Requirements update' (#413) from fix_sso into master
Reviewed-on: #413
2024-07-04 11:42:05 +02:00
21a5c84b18 # Requirements update
* due to existing migrations, django-simple-sso needs to be added as a dependency as well as itsdangerous (dependency of django-simple-sso)
    * however, there is no active usage of any of these packages anymore
2024-07-04 11:39:17 +02:00
a93f509d51 Merge pull request 'env' (#411) from env into master
Reviewed-on: #411
2024-07-04 08:36:04 +02:00
38967da201 Merge pull request '407_Drop_django-simple-sso' (#410) from 407_Drop_django-simple-sso into master
Reviewed-on: #410
2024-07-04 07:58:15 +02:00
60d749db2d # Geopackage import configuration
* corrects config for geopackage import support
2024-07-04 07:44:08 +02:00
dff577309e Merge pull request '# Send-to-EGON cmd' (#408) from sending_to_egon_cmd into master
Reviewed-on: #408
2024-06-18 11:49:35 +02:00
ea590d0868 # Send-to-EGON cmd
* adds new custom command send_to_egon for performing EGON sending on a list of intervention ids
2024-06-18 11:48:56 +02:00
e09c15bd51 # Updates sso
* adds env usage for sso settings
2024-06-14 13:04:25 +02:00
c3019f83fd Merge branch 'refs/heads/407_Drop_django-simple-sso' into env
# Conflicts:
#	konova/sub_settings/sso_settings.py
#	requirements.txt
2024-06-14 13:02:33 +02:00
93a71a7055 # Requirements update
* updates requirements.txt
* drops django-simple-sso from codebase and requirements.txt
2024-06-14 13:00:09 +02:00
35b1409359 # Requirements update
* updates requirements.txt
* drops debug-toolbar
2024-06-14 07:42:17 +02:00
c9aeb393b5 Merge pull request '# Comment card' (#406) from comment_card_improvement into master
Reviewed-on: #406
2024-05-21 14:43:49 +02:00
6df46e7642 # Comment card
* adds proper line break rendering in comment card
2024-05-21 14:42:49 +02:00
fe366bc568 Merge pull request '# 404 Extend API' (#405) from 404_Extend_API_shared_acces into master
Reviewed-on: #405
2024-05-21 11:55:20 +02:00
a9f04a28c1 # 404 Extend API
* extends API shared record access with team based sharing
2024-05-21 11:54:06 +02:00
8c9f4888dd Merge pull request '# OAuth fix' (#402) from oauth_https_fix into master
Reviewed-on: #402
2024-05-17 10:59:02 +02:00
5c727b2eaa # OAuth fix
* fixes bug in deployment environment due to http/s usage in url
2024-05-17 10:56:33 +02:00
76b2a78fe2 Merge pull request '# Fix' (#400) from oauth_https_fix into master
Reviewed-on: #400
2024-05-17 07:54:02 +02:00
86db08fca0 # Fix
* fixes bug where oauth requests did not use https in dockered deployment environment
2024-05-17 07:49:46 +02:00
fe1dce6440 Merge pull request '# Hotfix' (#398) from 395_OAuth2_refactoring into master
Reviewed-on: #398
2024-05-16 17:37:38 +02:00
a5e6f5a1db # Hotfix
* changes randomly created code verifier into static one to avoid authentication conflicts on multi process deployment (where each process generates an own verifier...)
2024-05-16 17:37:19 +02:00
b441518334 # Env
* updates env.sample
2024-04-03 13:45:52 +02:00
1a80912960 # Environment
* refactors settings into env usage
* adds proxy usage for schneider parcel fetching (using public web address instead of internal ip address)
2024-04-03 13:45:08 +02:00
27 changed files with 229 additions and 253 deletions

46
.env.sample Normal file
View File

@@ -0,0 +1,46 @@
# General
SECRET_KEY=CHANGE_ME
DEBUG=True
ALLOWED_HOSTS=127.0.0.1,localhost,example.org
BASE_URL=http://localhost:8002
ADMINS=Admin1:mail@example.org,Admin2:mail2@example.org
# Database
DB_USER=postgres
DB_PASSWORD=
DB_NAME=konova
DB_HOST=127.0.0.1
DB_PORT=5432
# Redis (for celery)
REDIS_HOST=CHANGE_ME
REDIS_PORT=CHANGE_ME
# E-Mail
SMTP_HOST=localhost
SMTP_PORT=25
REPLY_TO_ADDR=ksp-servicestelle@sgdnord.rlp.de
DEFAULT_FROM_EMAIL=service@ksp.de
# Proxy
PROXY=CHANGE_ME
GEOPORTAL_RLP_USER=CHANGE_ME
GEOPORTAL_RLP_PASSWORD=CHANGE_ME
# Schneider
SCHNEIDER_BASE_URL=https://schneider.naturschutz.rlp.de
SCHNEIDER_AUTH_TOKEN=CHANGE_ME
SCHNEIDER_AUTH_HEADER=auth
# SSO
SSO_SERVER_BASE_URL=https://login.naturschutz.rlp.de
OAUTH_CODE_VERIFIER=CHANGE_ME
OAUTH_CLIENT_ID=CHANGE_ME
OAUTH_CLIENT_SECRET=CHANGE_ME
# RabbitMQ
## For connections to EGON
EGON_RABBITMQ_HOST=CHANGE_ME
EGON_RABBITMQ_PORT=CHANGE_ME
EGON_RABBITMQ_USER=CHANGE_ME
EGON_RABBITMQ_PW=CHANGE_ME

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@
/.idea/ /.idea/
/.coverage /.coverage
/htmlcov/ /htmlcov/
/.env

View File

@@ -11,6 +11,7 @@ from abc import abstractmethod
from django.contrib.gis import geos from django.contrib.gis import geos
from django.contrib.gis.geos import GEOSGeometry from django.contrib.gis.geos import GEOSGeometry
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.db.models import Q
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
from konova.utils.message_templates import DATA_UNSHARED from konova.utils.message_templates import DATA_UNSHARED
@@ -32,8 +33,8 @@ class AbstractModelAPISerializer:
self.lookup = { self.lookup = {
"id": None, # must be set "id": None, # must be set
"deleted__isnull": True, "deleted__isnull": True,
"users__in": [], # must be set
} }
self.shared_lookup = Q() # must be set, so user or team based share will be used properly
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@abstractmethod @abstractmethod
@@ -76,7 +77,11 @@ class AbstractModelAPISerializer:
else: else:
# Return certain object # Return certain object
self.lookup["id"] = _id self.lookup["id"] = _id
self.lookup["users__in"] = [user]
self.shared_lookup = Q(
Q(users__in=[user]) |
Q(teams__in=list(user.shared_teams))
)
def fetch_and_serialize(self): def fetch_and_serialize(self):
""" Serializes the model entry according to the given lookup data """ Serializes the model entry according to the given lookup data
@@ -86,7 +91,13 @@ class AbstractModelAPISerializer:
Returns: Returns:
serialized_data (dict) serialized_data (dict)
""" """
entries = self.model.objects.filter(**self.lookup).order_by("id") entries = self.model.objects.filter(
**self.lookup
).filter(
self.shared_lookup
).order_by(
"id"
).distinct()
self.paginator = Paginator(entries, self.rpp) self.paginator = Paginator(entries, self.rpp)
requested_entries = self.paginator.page(self.page_number) requested_entries = self.paginator.page(self.page_number)

View File

@@ -6,6 +6,7 @@ Created on: 24.01.22
""" """
from django.db import transaction from django.db import transaction
from django.db.models import Q
from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin
from compensation.models import Compensation from compensation.models import Compensation
@@ -21,8 +22,10 @@ class CompensationAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensa
def prepare_lookup(self, id, user): def prepare_lookup(self, id, user):
super().prepare_lookup(id, user) super().prepare_lookup(id, user)
del self.lookup["users__in"] self.shared_lookup = Q(
self.lookup["intervention__users__in"] = [user] Q(intervention__users__in=[user]) |
Q(intervention__teams__in=user.shared_teams)
)
def intervention_to_json(self, entry): def intervention_to_json(self, entry):
return { return {

View File

@@ -6,6 +6,7 @@ Created on: 28.01.22
""" """
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from api.utils.serializer.v1.serializer import DeductableAPISerializerV1Mixin, AbstractModelAPISerializerV1 from api.utils.serializer.v1.serializer import DeductableAPISerializerV1Mixin, AbstractModelAPISerializerV1
from compensation.models import EcoAccountDeduction, EcoAccount from compensation.models import EcoAccountDeduction, EcoAccount
@@ -28,9 +29,11 @@ class DeductionAPISerializerV1(AbstractModelAPISerializerV1,
""" """
super().prepare_lookup(_id, user) super().prepare_lookup(_id, user)
del self.lookup["users__in"]
del self.lookup["deleted__isnull"] del self.lookup["deleted__isnull"]
self.lookup["intervention__users__in"] = [user] self.shared_lookup = Q(
Q(intervention__users__in=[user]) |
Q(intervention__teams__in=user.shared_teams)
)
def _model_to_geo_json(self, entry): def _model_to_geo_json(self, entry):
""" Adds the basic data """ Adds the basic data

View File

@@ -23,11 +23,6 @@ class AbstractAPIViewV1(AbstractAPIView):
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.lookup = {
"id": None, # must be set in subclasses
"deleted__isnull": True,
"users__in": [], # must be set in subclasses
}
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.serializer = self.serializer() self.serializer = self.serializer()

View File

@@ -75,7 +75,8 @@ class KonovaCode(models.Model):
return self return self
children = KonovaCode.objects.filter( children = KonovaCode.objects.filter(
parent=self parent=self,
is_archived=False,
).order_by( ).order_by(
order_by order_by
) )

View File

@@ -5,6 +5,8 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 30.11.20 Created on: 30.11.20
""" """
from konova.sub_settings.django_settings import env
INTERVENTION_IDENTIFIER_LENGTH = 6 INTERVENTION_IDENTIFIER_LENGTH = 6
INTERVENTION_IDENTIFIER_TEMPLATE = "EIV-{}" INTERVENTION_IDENTIFIER_TEMPLATE = "EIV-{}"
@@ -14,7 +16,7 @@ INTERVENTION_LANIS_LAYER_NAME_UNRECORDED_OLD_ENTRY = "eiv_unrecorded_old_entries
# EGON connection settings via rabbitmq # EGON connection settings via rabbitmq
# NEEDED FOR BACKWARDS COMPATIBILITY # NEEDED FOR BACKWARDS COMPATIBILITY
EGON_RABBITMQ_HOST = "CHANGE_ME" EGON_RABBITMQ_HOST = env("EGON_RABBITMQ_HOST")
EGON_RABBITMQ_PORT = "CHANGE_ME" EGON_RABBITMQ_PORT = env("EGON_RABBITMQ_PORT")
EGON_RABBITMQ_USER = "CHANGE_ME" EGON_RABBITMQ_USER = env("EGON_RABBITMQ_USER")
EGON_RABBITMQ_PW = "CHANGE_ME" EGON_RABBITMQ_PW = env("EGON_RABBITMQ_PW")

View File

@@ -1,6 +1,7 @@
import os import os
from celery import Celery from celery import Celery
from konova.sub_settings.django_settings import env
# Set the default Django settings module for the 'celery' program. # Set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'konova.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'konova.settings')
@@ -17,7 +18,7 @@ app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks() app.autodiscover_tasks()
# Declare redis as broker # Declare redis as broker
app.conf.broker_url = 'redis://localhost:6379/0' app.conf.broker_url = f'redis://{env("REDIS_HOST")}:{env.int("REDIS_PORT")}/0'
@app.task(bind=True) @app.task(bind=True)

View File

@@ -0,0 +1,54 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 18.06.24
"""
from django.db.models import QuerySet
from intervention.models import Intervention
from konova.management.commands.setup import BaseKonovaCommand
class Command(BaseKonovaCommand):
help = "Send specific intervention entries to EGON if there are any payments on them"
def add_arguments(self, parser):
try:
parser.add_argument("--intervention-ids", type=str)
except ValueError as e:
self._write_error(f"Argument error: {e}")
exit(-1)
def __handle_arguments(self, options):
self.intervention_ids = options["intervention_ids"] or ""
self.intervention_ids = self.intervention_ids.split(",")
self.intervention_ids = [x.strip() for x in self.intervention_ids]
def handle(self, *args, **options):
try:
self.__handle_arguments(options)
interventions = self.get_interventions()
self.process_egon_sending(interventions)
except KeyboardInterrupt:
self._break_line()
exit(-1)
def get_interventions(self) -> QuerySet:
"""
Getter for interventions, defined by parameter 'intervention-ids'
Returns:
interventions (QuerySet): The interventions
"""
interventions = Intervention.objects.filter(
id__in=self.intervention_ids,
)
self._write_success(f"... Found {interventions.count()} interventions")
return interventions
def process_egon_sending(self, interventions: QuerySet):
for intervention in interventions:
intervention.send_data_to_egon()
self._write_warning(f"... {intervention.identifier} has been sent to EGON (if it has payments)")

View File

@@ -18,7 +18,6 @@ from konova.sub_settings.proxy_settings import *
from konova.sub_settings.sso_settings import * from konova.sub_settings.sso_settings import *
from konova.sub_settings.table_settings import * from konova.sub_settings.table_settings import *
from konova.sub_settings.lanis_settings import * from konova.sub_settings.lanis_settings import *
from konova.sub_settings.wfs_parcel_settings import *
from konova.sub_settings.logging_settings import * from konova.sub_settings.logging_settings import *
# Max upload size for POST forms # Max upload size for POST forms

View File

@@ -1,78 +0,0 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 17.08.21
"""
from django.http import HttpResponse
from django.urls import re_path
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from itsdangerous import TimedSerializer
from simple_sso.sso_client.client import Client
from user.models import User
class PropagateView(View):
""" View used to receive propagated sso-server user data
"""
client = None
signer = None
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.signer = TimedSerializer(self.client.private_key)
@csrf_exempt
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def post(self, request):
user_data = request.body
user_data = self.signer.loads(user_data)
self.client.build_user(user_data)
return HttpResponse(status=200)
class KonovaSSOClient(Client):
""" Konova specialized derivative of general sso.Client.
Adds some custom behaviour for konova usage.
"""
propagate_view = PropagateView
def get_urls(self):
urls = super().get_urls()
urls += re_path(r'^propagate/$', self.propagate_view.as_view(client=self), name='simple-sso-propagate'),
return urls
def build_user(self, user_data):
""" Creates a user or updates user data
Args:
user_data ():
Returns:
"""
try:
user = User.objects.get(username=user_data['username'])
# Update user data, excluding some changes
skipable_attrs = {
"username",
"is_staff",
"is_superuser",
}
for _attr, _val in user_data.items():
if _attr in skipable_attrs:
continue
setattr(user, _attr, _val)
except User.DoesNotExist:
user = User(**user_data)
user.set_unusable_password()
user.save()
return user

View File

@@ -10,6 +10,8 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/ https://docs.djangoproject.com/en/3.1/ref/settings/
""" """
import os import os
import environ
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.conf.locale.de import formats as de_formats from django.conf.locale.de import formats as de_formats
@@ -24,28 +26,24 @@ BASE_DIR = os.path.dirname(
) )
) )
# Quick-start development settings - unsuitable for production env = environ.Env()
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ # Take environment variables from .env.dev file
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '5=9-)2)h$u9=!zrhia9=lj-2#cpcb8=#$7y+)l$5tto$3q(n_+' SECRET_KEY = env("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = env.bool("DEBUG", default=False)
ADMINS = [ ADMINS = [x.split(':') for x in env.list('ADMINS')]
('KSP-Servicestelle', 'ksp-servicestelle@sgdnord.rlp.de'),
]
BASE_URL = "http://localhost:8001" ALLOWED_HOSTS = env.list("ALLOWED_HOSTS")
ALLOWED_HOSTS = [ BASE_URL = env("BASE_URL")
"127.0.0.1",
"localhost",
]
CSRF_TRUSTED_ORIGINS = [ CSRF_TRUSTED_ORIGINS = [
"http://localhost", # not only host but schema (http/s) as well! BASE_URL
] ]
# Authentication settings # Authentication settings
@@ -83,10 +81,6 @@ INSTALLED_APPS = [
'analysis', 'analysis',
'api', 'api',
] ]
if DEBUG:
INSTALLED_APPS += [
'debug_toolbar',
]
MIDDLEWARE = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
@@ -98,10 +92,6 @@ MIDDLEWARE = [
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
if DEBUG:
MIDDLEWARE += [
"debug_toolbar.middleware.DebugToolbarMiddleware",
]
ROOT_URLCONF = 'konova.urls' ROOT_URLCONF = 'konova.urls'
@@ -131,10 +121,11 @@ WSGI_APPLICATION = 'konova.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis', 'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'konova', 'NAME': env("DB_NAME"),
'USER': 'postgres', 'USER': env("DB_USER"),
'HOST': '127.0.0.1', 'PASSWORD': env("DB_PASSWORD"),
'PORT': '5432', 'HOST': env("DB_HOST"),
'PORT': env("DB_PORT"),
} }
} }
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
@@ -201,28 +192,6 @@ STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'templates/map/client/libs'), # NETGIS map client files os.path.join(BASE_DIR, 'templates/map/client/libs'), # NETGIS map client files
] ]
# DJANGO DEBUG TOOLBAR
INTERNAL_IPS = [
"127.0.0.1"
]
DEBUG_TOOLBAR_CONFIG = {
"DISABLE_PANELS": {
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.request.RequestPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',
'debug_toolbar.panels.profiling.ProfilingPanel',
}
}
# EMAIL (see https://docs.djangoproject.com/en/dev/topics/email/) # EMAIL (see https://docs.djangoproject.com/en/dev/topics/email/)
# CHANGE_ME !!! ONLY FOR DEVELOPMENT !!! # CHANGE_ME !!! ONLY FOR DEVELOPMENT !!!
@@ -230,13 +199,10 @@ if DEBUG:
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend' EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = '/tmp/app-messages' # change this to a proper location EMAIL_FILE_PATH = '/tmp/app-messages' # change this to a proper location
DEFAULT_FROM_EMAIL = "service@ksp.de" # The default email address for the 'from' element DEFAULT_FROM_EMAIL = env("DEFAULT_FROM_EMAIL") # The default email address for the 'from' element
SERVER_EMAIL = DEFAULT_FROM_EMAIL # The default email sender address, which is used by Django to send errors via mail SERVER_EMAIL = DEFAULT_FROM_EMAIL # The default email sender address, which is used by Django to send errors via mail
EMAIL_HOST = "localhost" EMAIL_HOST = env("SMTP_HOST")
EMAIL_REPLY_TO = "ksp-servicestelle@sgdnord.rlp.de" EMAIL_REPLY_TO = env("REPLY_TO_ADDR")
SUPPORT_MAIL_RECIPIENT = EMAIL_REPLY_TO EMAIL_PORT = env("SMTP_PORT")
EMAIL_PORT = "25"
#EMAIL_HOST_USER = ""
#EMAIL_HOST_PASSWORD = ""
EMAIL_USE_TLS = False EMAIL_USE_TLS = False
EMAIL_USE_SSL = False EMAIL_USE_SSL = False

View File

@@ -5,12 +5,13 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 31.01.22 Created on: 31.01.22
""" """
from konova.sub_settings.django_settings import env
proxy = "" proxy = env("PROXY")
PROXIES = { PROXIES = {
"http": proxy, "http": proxy,
"https": proxy, "https": proxy,
} }
CLIENT_PROXY_AUTH_USER = "CHANGE_ME" GEOPORTAL_RLP_USER = env("GEOPORTAL_RLP_USER")
CLIENT_PROXY_AUTH_PASSWORD = "CHANGE_ME" GEOPORTAL_RLP_PASSWORD = env("GEOPORTAL_RLP_PASSWORD")

View File

@@ -5,7 +5,8 @@ Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 14.12.22 Created on: 14.12.22
""" """
from konova.sub_settings.django_settings import env
base_url = "http://127.0.0.1:8002" base_url = env("SCHNEIDER_BASE_URL")
auth_header = "auth" auth_header = env("SCHNEIDER_AUTH_HEADER")
auth_header_token = "CHANGE_ME" auth_header_token = env("SCHNEIDER_AUTH_TOKEN")

View File

@@ -5,21 +5,14 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 31.01.22 Created on: 31.01.22
""" """
import random from konova.sub_settings.django_settings import env
import string
# Django-simple-SSO settings # SSO settings
SSO_SERVER_BASE = "http://127.0.0.1:8000/" SSO_SERVER_BASE = env("SSO_SERVER_BASE_URL")
SSO_SERVER = f"{SSO_SERVER_BASE}sso/" SSO_SERVER = f"{SSO_SERVER_BASE}sso/"
SSO_PRIVATE_KEY = "CHANGE_ME"
SSO_PUBLIC_KEY = "CHANGE_ME"
# OAuth settings # OAuth settings
OAUTH_CODE_VERIFIER = ''.join( OAUTH_CODE_VERIFIER = env("OAUTH_CODE_VERIFIER")
random.choice(
string.ascii_uppercase + string.digits
) for _ in range(random.randint(43, 128))
)
OAUTH_CLIENT_ID = "CHANGE_ME" OAUTH_CLIENT_ID = env("OAUTH_CLIENT_ID")
OAUTH_CLIENT_SECRET = "CHANGE_ME" OAUTH_CLIENT_SECRET = env("OAUTH_CLIENT_SECRET")

View File

@@ -1,12 +0,0 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 31.01.22
"""
# Parcel WFS settings
PARCEL_WFS_BASE_URL = "https://www.geoportal.rlp.de/registry/wfs/519"
PARCEL_WFS_USER = "ksp"
PARCEL_WFS_PW = "CHANGE_ME"

View File

@@ -7,7 +7,7 @@ from django.core.exceptions import ObjectDoesNotExist
@shared_task @shared_task
def celery_update_parcels(geometry_id: str, recheck: bool = True): def celery_update_parcels(geometry_id: str, recheck: bool = True):
from konova.models import Geometry, ParcelIntersection from konova.models import Geometry
try: try:
geom = Geometry.objects.get(id=geometry_id) geom = Geometry.objects.get(id=geometry_id)
geom.parcels.clear() geom.parcels.clear()

View File

@@ -20,7 +20,7 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="scroll-150 font-italic"> <div class="scroll-150 font-italic">
{{obj.comment}} {{obj.comment|linebreaks}}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -13,22 +13,17 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path 1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
import debug_toolbar
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG
from konova.sso.sso import KonovaSSOClient
from konova.views.logout import LogoutView from konova.views.logout import LogoutView
from konova.views.geometry import GeomParcelsView, GeomParcelsContentView from konova.views.geometry import GeomParcelsView, GeomParcelsContentView
from konova.views.home import HomeView from konova.views.home import HomeView
from konova.views.map_proxy import ClientProxyParcelSearch, ClientProxyParcelWFS from konova.views.map_proxy import ClientProxyParcelSearch, ClientProxyParcelWFS
from konova.views.oauth import OAuthLoginView, OAuthCallbackView from konova.views.oauth import OAuthLoginView, OAuthCallbackView
sso_client = KonovaSSOClient(SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY)
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('login/', include(sso_client.get_urls())),
path('oauth/callback/', OAuthCallbackView.as_view(), name="oauth-callback"), path('oauth/callback/', OAuthCallbackView.as_view(), name="oauth-callback"),
path('oauth/login/', OAuthLoginView.as_view(), name="oauth-login"), path('oauth/login/', OAuthLoginView.as_view(), name="oauth-login"),
path('logout/', LogoutView.as_view(), name="logout"), path('logout/', LogoutView.as_view(), name="logout"),
@@ -47,10 +42,5 @@ urlpatterns = [
path('client/proxy/wfs', ClientProxyParcelWFS.as_view(), name="client-proxy-wfs"), path('client/proxy/wfs', ClientProxyParcelWFS.as_view(), name="client-proxy-wfs"),
] ]
if DEBUG:
urlpatterns += [
path('__debug__/', include(debug_toolbar.urls)),
]
handler404 = "konova.views.error.get_404_view" handler404 = "konova.views.error.get_404_view"
handler500 = "konova.views.error.get_500_view" handler500 = "konova.views.error.get_500_view"

View File

@@ -9,7 +9,7 @@ from django.core.mail import send_mail
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from konova.sub_settings.django_settings import DEFAULT_FROM_EMAIL, EMAIL_REPLY_TO, SUPPORT_MAIL_RECIPIENT from konova.sub_settings.django_settings import DEFAULT_FROM_EMAIL, EMAIL_REPLY_TO
class Mailer: class Mailer:
@@ -416,7 +416,7 @@ class Mailer:
"EMAIL_REPLY_TO": EMAIL_REPLY_TO, "EMAIL_REPLY_TO": EMAIL_REPLY_TO,
} }
msg = render_to_string("email/api/verify_token.html", context) msg = render_to_string("email/api/verify_token.html", context)
user_mail_address = [SUPPORT_MAIL_RECIPIENT] user_mail_address = [EMAIL_REPLY_TO]
self.send( self.send(
user_mail_address, user_mail_address,
_("Request for new API token"), _("Request for new API token"),

View File

@@ -11,6 +11,7 @@ from json import JSONDecodeError
import requests import requests
from konova.sub_settings import schneider_settings from konova.sub_settings import schneider_settings
from konova.sub_settings.proxy_settings import PROXIES
class ParcelFetcher: class ParcelFetcher:
@@ -43,6 +44,7 @@ class ParcelFetcher:
response = requests.post( response = requests.post(
url=post_url, url=post_url,
proxies=PROXIES,
data=self.geojson, data=self.geojson,
headers={ headers={
self.auth_header: self.auth_header_token self.auth_header: self.auth_header_token

View File

@@ -18,7 +18,7 @@ from django.utils.translation import gettext_lazy as _
from requests.auth import HTTPDigestAuth from requests.auth import HTTPDigestAuth
from konova.sub_settings.proxy_settings import PROXIES, CLIENT_PROXY_AUTH_USER, CLIENT_PROXY_AUTH_PASSWORD from konova.sub_settings.proxy_settings import PROXIES, GEOPORTAL_RLP_USER, GEOPORTAL_RLP_PASSWORD
class BaseClientProxyView(View): class BaseClientProxyView(View):
@@ -90,7 +90,7 @@ class ClientProxyParcelWFS(BaseClientProxyView):
url = f"{base_url}?{urlencode(params, doseq=True)}" url = f"{base_url}?{urlencode(params, doseq=True)}"
url = url.replace("typename", "typenames") url = url.replace("typename", "typenames")
auth = HTTPDigestAuth(CLIENT_PROXY_AUTH_USER, CLIENT_PROXY_AUTH_PASSWORD) auth = HTTPDigestAuth(GEOPORTAL_RLP_USER, GEOPORTAL_RLP_PASSWORD)
content, response_code = self.perform_url_call(url, auth=auth) content, response_code = self.perform_url_call(url, auth=auth)
error_detected = response_code != 200 error_detected = response_code != 200

View File

@@ -18,6 +18,7 @@ from django.utils.timezone import now
from django.views import View from django.views import View
from api.models import OAuthToken from api.models import OAuthToken
from konova.sub_settings.django_settings import BASE_URL
from konova.sub_settings.sso_settings import SSO_SERVER_BASE, OAUTH_CODE_VERIFIER, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET from konova.sub_settings.sso_settings import SSO_SERVER_BASE, OAUTH_CODE_VERIFIER, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET
@@ -62,6 +63,8 @@ class OAuthLoginView(View):
""" """
oauth_authentication_code_url = f"{SSO_SERVER_BASE}o/authorize/" oauth_authentication_code_url = f"{SSO_SERVER_BASE}o/authorize/"
redirect_uri = f'{BASE_URL}{reverse("oauth-callback")}'
code_verifier, code_challenge = self.__create_code_challenge() code_verifier, code_challenge = self.__create_code_challenge()
urlencode_params = urlencode( urlencode_params = urlencode(
@@ -70,11 +73,7 @@ class OAuthLoginView(View):
"code_challenge": code_challenge, "code_challenge": code_challenge,
"code_challenge_method": "S256", "code_challenge_method": "S256",
"client_id": OAUTH_CLIENT_ID, "client_id": OAUTH_CLIENT_ID,
"redirect_uri": request.build_absolute_uri( "redirect_uri": redirect_uri,
reverse(
"oauth-callback"
)
),
} }
) )
url = f"{oauth_authentication_code_url}?{urlencode_params}" url = f"{oauth_authentication_code_url}?{urlencode_params}"
@@ -95,11 +94,7 @@ class OAuthCallbackView(View):
authentication_code = request.GET.get("code") authentication_code = request.GET.get("code")
oauth_acces_token_url = f"{SSO_SERVER_BASE}o/token/" oauth_acces_token_url = f"{SSO_SERVER_BASE}o/token/"
callback_url = request.build_absolute_uri( callback_url = f'{BASE_URL}{reverse("oauth-callback")}'
reverse(
"oauth-callback"
)
)
params = { params = {
"grant_type": "authorization_code", "grant_type": "authorization_code",

View File

@@ -4,62 +4,62 @@ async-timeout==4.0.3
beautifulsoup4==4.13.0b2 beautifulsoup4==4.13.0b2
billiard==4.2.0 billiard==4.2.0
cached-property==1.5.2 cached-property==1.5.2
celery==5.4.0rc2 celery==5.4.0
certifi==2024.2.2 certifi==2024.7.4
cffi==1.16.0 cffi==1.17.0rc1
chardet==5.2.0 chardet==5.2.0
charset-normalizer==3.3.2 charset-normalizer==3.3.2
click==8.1.7 click==8.1.7
click-didyoumean==0.3.1 click-didyoumean==0.3.1
click-plugins==1.1.1 click-plugins==1.1.1
click-repl==0.3.0 click-repl==0.3.0
coverage==7.4.4 coverage==7.5.4
cryptography==42.0.5 cryptography==42.0.8
Deprecated==1.2.14 Deprecated==1.2.14
Django==5.0.4 Django==5.0.7
django-autocomplete-light==3.11.0 django-autocomplete-light==3.11.0
django-bootstrap-modal-forms==3.0.4 django-bootstrap-modal-forms==3.0.4
django-bootstrap4==24.1 django-bootstrap4==24.3
django-debug-toolbar==4.3.0
django-environ==0.11.2 django-environ==0.11.2
django-filter==24.2 django-filter==24.2
django-fontawesome-5==1.0.18 django-fontawesome-5==1.0.18
django-oauth-toolkit==2.3.0 django-oauth-toolkit==2.4.0
django-simple-sso==1.2.0 django-simple-sso==1.2.0
django-tables2==2.7.0 django-tables2==2.7.0
et-xmlfile==1.1.0 et-xmlfile==1.1.0
gunicorn==22.0.0
idna==3.7 idna==3.7
importlib_metadata==7.1.0 importlib_metadata==8.0.0
itsdangerous==0.24 itsdangerous==0.24
jwcrypto==1.5.6 jwcrypto==1.5.6
kombu==5.3.7 kombu==5.4.0rc1
oauthlib==3.2.2 oauthlib==3.2.2
openpyxl==3.2.0b1 openpyxl==3.2.0b1
packaging==24.0 packaging==24.1
pika==1.3.2 pika==1.3.2
pillow==10.2.0 pillow==10.4.0
prompt-toolkit==3.0.43 prompt_toolkit==3.0.47
psycopg==3.1.18 psycopg==3.2.1
psycopg-binary==3.1.18 psycopg-binary==3.2.1
pycparser==2.22 pycparser==2.22
pyparsing==3.1.2 pyparsing==3.1.2
pypng==0.20220715.0 pypng==0.20220715.0
pyproj==3.6.1 pyproj==3.6.1
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
pytz==2024.1 pytz==2024.1
PyYAML==6.0.1 PyYAML==6.0.2rc1
qrcode==7.3.1 qrcode==7.3.1
redis==5.1.0b4 redis==5.1.0b6
requests==2.31.0 requests<2.32.0
six==1.16.0 six==1.16.0
soupsieve==2.5 soupsieve==2.5
sqlparse==0.4.4 sqlparse==0.5.0
typing_extensions==4.11.0 typing_extensions==4.12.2
tzdata==2024.1 tzdata==2024.1
urllib3==2.2.1 urllib3==2.2.2
vine==5.1.0 vine==5.1.0
wcwidth==0.2.13 wcwidth==0.2.13
webservices==0.7 webservices==0.7
wrapt==1.16.0 wrapt==1.16.0
xmltodict==0.13.0 xmltodict==0.13.0
zipp==3.18.1 zipp==3.19.2

View File

@@ -112,7 +112,7 @@
}, },
"import": "import":
{ {
"geopackageLibURL": "/libs/geopackage/4.2.3/" "geopackageLibURL": "/static/libs/geopackage/4.2.3/"
}, },
"export": "export":
{ {

View File

@@ -16,7 +16,7 @@ netgis.Client=function(a,b){this.build="20220826";this.debug=!1;netgis.util.isSt
this.hideLoader()};netgis.Client.Layers=Object.freeze({PARCEL_DISTRICTS:"parcel-districts",PARCEL_FIELDS:"parcel-fields",PARCEL_FEATURES:"parcel-features",EDIT_LAYER:"edit-layer",PREVIEW_LAYER:"preview-layer"});netgis.Client.prototype.applyConfig=function(a){this.createModules();this.load();this.invoke(netgis.Events.CONTEXT_UPDATE,a);this.initModules(a);this.initConfig(a);this.initOutput(a);this.initEvents();this.importLayers={};this.setMode(netgis.Modes.VIEW)}; this.hideLoader()};netgis.Client.Layers=Object.freeze({PARCEL_DISTRICTS:"parcel-districts",PARCEL_FIELDS:"parcel-fields",PARCEL_FEATURES:"parcel-features",EDIT_LAYER:"edit-layer",PREVIEW_LAYER:"preview-layer"});netgis.Client.prototype.applyConfig=function(a){this.createModules();this.load();this.invoke(netgis.Events.CONTEXT_UPDATE,a);this.initModules(a);this.initConfig(a);this.initOutput(a);this.initEvents();this.importLayers={};this.setMode(netgis.Modes.VIEW)};
netgis.Client.prototype.initElements=function(){}; netgis.Client.prototype.initElements=function(){};
netgis.Client.prototype.initModules=function(a){this.map=new netgis.MapOpenLayers(a);this.map.attach(this.root);this.controls=new netgis.Controls;this.controls.attach(this.root);this.layerPanel=new netgis.Panel("Inhalte");this.layerPanel.attach(this.root);this.layerTree=new netgis.Tree;this.layerTree.container.style.position="absolute";this.layerTree.container.style.width="100%";this.layerTree.container.style.top="12mm";this.layerTree.container.style.bottom="6mm";this.layerTree.container.style.overflow= netgis.Client.prototype.initModules=function(a){this.map=new netgis.MapOpenLayers(a);this.map.attach(this.root);this.controls=new netgis.Controls;this.controls.attach(this.root);this.layerPanel=new netgis.Panel("Inhalte");this.layerPanel.attach(this.root);this.layerTree=new netgis.Tree;this.layerTree.container.style.position="absolute";this.layerTree.container.style.width="100%";this.layerTree.container.style.top="12mm";this.layerTree.container.style.bottom="6mm";this.layerTree.container.style.overflow=
"auto";this.layerTree.attach(this.layerPanel.container);this.toolboxPanel=new netgis.Panel("Werkzeuge");this.toolboxPanel.attach(this.root);this.toolbox=new netgis.Toolbox(a);this.toolbox.attach(this.toolboxPanel.container);this.searchPlace=new netgis.SearchPlace(a);this.searchPlace.attach(this.root);this.parcelPanel=new netgis.Panel("Flurst\u00fccks-Suche");this.parcelPanel.container.style.minWidth="92mm";this.parcelPanel.attach(this.root);this.searchParcel=new netgis.SearchParcel(a);this.searchParcel.attach(this.parcelPanel.container); "auto";this.layerTree.attach(this.layerPanel.container);this.toolboxPanel=new netgis.Panel("Werkzeuge");this.toolboxPanel.attach(this.root);this.toolbox=new netgis.Toolbox(a);this.toolbox.attach(this.toolboxPanel.container);this.searchPlace=new netgis.SearchPlace(a);this.searchPlace.attach(this.root);this.parcelPanel=new netgis.Panel("Flurst\u00fccks-Suche");this.parcelPanel.container.style.minWidth="92mm";this.parcelPanel.attach(this.root);this.searchParcel=new netgis.SearchParcel(a,this);this.searchParcel.attach(this.parcelPanel.container);
this.importModal=new netgis.Modal("Ebene hinzuf\u00fcgen");this.importModal.container.classList.add("netgis-import");this.importModal.attach(this.root);a=document.createElement("div");a.className="netgis-content netgis-form netgis-noselect";this.importModal.content.appendChild(a);var b=document.createElement("label");b.innerHTML="Dateiformat:";a.appendChild(b);var c=document.createElement("select");c.innerHTML="<option value='geojson'>GeoJSON</option><option value='gml'>GML</option><option value='gpkg'>GeoPackage</option><option value='shp'>Shapefile (Zip)</option><option value='spatialite'>Spatialite</option>"; this.importModal=new netgis.Modal("Ebene hinzuf\u00fcgen");this.importModal.container.classList.add("netgis-import");this.importModal.attach(this.root);a=document.createElement("div");a.className="netgis-content netgis-form netgis-noselect";this.importModal.content.appendChild(a);var b=document.createElement("label");b.innerHTML="Dateiformat:";a.appendChild(b);var c=document.createElement("select");c.innerHTML="<option value='geojson'>GeoJSON</option><option value='gml'>GML</option><option value='gpkg'>GeoPackage</option><option value='shp'>Shapefile (Zip)</option><option value='spatialite'>Spatialite</option>";
b.addEventListener("change",this.onImportFileTypeChange.bind(this));b.appendChild(c);this.importFileSelect=c;b=document.createElement("div");b.innerHTML="<h3>Unterst\u00fctzte Koordinatensysteme:</h3><ul><li>World Geodetic System 1984 (EPSG:4326)</li><li>ETRS89 / UTM zone 32N (EPSG:25832)</li></ul>";a.appendChild(b);b=document.createElement("label");b.innerHTML="Datei ausw\u00e4hlen/ablegen:";a.appendChild(b);c=document.createElement("input");c.className="netgis-color-d";c.setAttribute("type","file"); b.addEventListener("change",this.onImportFileTypeChange.bind(this));b.appendChild(c);this.importFileSelect=c;b=document.createElement("div");b.innerHTML="<h3>Unterst\u00fctzte Koordinatensysteme:</h3><ul><li>World Geodetic System 1984 (EPSG:4326)</li><li>ETRS89 / UTM zone 32N (EPSG:25832)</li></ul>";a.appendChild(b);b=document.createElement("label");b.innerHTML="Datei ausw\u00e4hlen/ablegen:";a.appendChild(b);c=document.createElement("input");c.className="netgis-color-d";c.setAttribute("type","file");
c.setAttribute("accept",".geojson,.json");b.appendChild(c);this.importFileInput=c;b=document.createElement("button");b.setAttribute("type","button");b.className="netgis-button netgis-center netgis-color-a netgis-hover-c netgis-shadow";b.innerHTML="<i class='netgis-icon fas fa-check'></i><span>Hinzuf\u00fcgen</span>";b.addEventListener("click",this.onImportFileClick.bind(this));a.appendChild(b);this.importServiceModal=new netgis.Modal("Dienst hinzuf\u00fcgen");this.importServiceModal.container.classList.add("netgis-import"); c.setAttribute("accept",".geojson,.json");b.appendChild(c);this.importFileInput=c;b=document.createElement("button");b.setAttribute("type","button");b.className="netgis-button netgis-center netgis-color-a netgis-hover-c netgis-shadow";b.innerHTML="<i class='netgis-icon fas fa-check'></i><span>Hinzuf\u00fcgen</span>";b.addEventListener("click",this.onImportFileClick.bind(this));a.appendChild(b);this.importServiceModal=new netgis.Modal("Dienst hinzuf\u00fcgen");this.importServiceModal.container.classList.add("netgis-import");
@@ -53,15 +53,16 @@ netgis.Client.prototype.onLayersToggle=function(a){this.layerPanel.toggle();this
netgis.Client.prototype.onLayerTreeItemChange=function(a){var b=a.detail.id;a=a.detail.checked;switch(b){default:for(var c=this.config.layers,d=!1,e=null,f=0;f<c.length;f++){var g=c[f],h=g.id;if(h===b){e=this.map.createLayer(g);d=!0;break}}if(!d)for(h in this.importLayers)if(h===b){e=this.importLayers[b];d=!0;break}d&&(a?(this.map.addLayer(b,e),this.attribution.onLayerShow({id:b})):(this.map.removeLayer(b),this.attribution.onLayerHide({id:b})));break;case "edit-layer":a?this.map.addLayer(netgis.Client.Layers.EDIT_LAYER, netgis.Client.prototype.onLayerTreeItemChange=function(a){var b=a.detail.id;a=a.detail.checked;switch(b){default:for(var c=this.config.layers,d=!1,e=null,f=0;f<c.length;f++){var g=c[f],h=g.id;if(h===b){e=this.map.createLayer(g);d=!0;break}}if(!d)for(h in this.importLayers)if(h===b){e=this.importLayers[b];d=!0;break}d&&(a?(this.map.addLayer(b,e),this.attribution.onLayerShow({id:b})):(this.map.removeLayer(b),this.attribution.onLayerHide({id:b})));break;case "edit-layer":a?this.map.addLayer(netgis.Client.Layers.EDIT_LAYER,
this.map.editLayer):this.map.removeLayer(netgis.Client.Layers.EDIT_LAYER)}};netgis.Client.prototype.onToolboxToggle=function(a){this.toolboxPanel.toggle();this.toolboxPanel.visible()&&(this.layerPanel.hide(),this.parcelPanel.hide())};netgis.Client.prototype.onSearchPlaceToggle=function(a){this.searchPlace.toggle()};netgis.Client.prototype.onSearchPlaceSelect=function(a){a=a.detail;this.map.zoomExtent(a.minx,a.miny,a.maxx,a.maxy)}; this.map.editLayer):this.map.removeLayer(netgis.Client.Layers.EDIT_LAYER)}};netgis.Client.prototype.onToolboxToggle=function(a){this.toolboxPanel.toggle();this.toolboxPanel.visible()&&(this.layerPanel.hide(),this.parcelPanel.hide())};netgis.Client.prototype.onSearchPlaceToggle=function(a){this.searchPlace.toggle()};netgis.Client.prototype.onSearchPlaceSelect=function(a){a=a.detail;this.map.zoomExtent(a.minx,a.miny,a.maxx,a.maxy)};
netgis.Client.prototype.onSearchParcelToggle=function(a){this.parcelPanel.toggle();this.parcelPanel.visible()&&(this.layerPanel.hide(),this.toolboxPanel.hide())};netgis.Client.prototype.onControlsZoom=function(a){this.map.zoom(a.detail)};netgis.Client.prototype.onControlsZoomAll=function(a){this.map.zoomAll()};netgis.Client.prototype.onParcelsPanelToggle=function(a){this.searchParcel.reset()}; netgis.Client.prototype.onSearchParcelToggle=function(a){this.parcelPanel.toggle();this.parcelPanel.visible()&&(this.layerPanel.hide(),this.toolboxPanel.hide())};netgis.Client.prototype.onControlsZoom=function(a){this.map.zoom(a.detail)};netgis.Client.prototype.onControlsZoomAll=function(a){this.map.zoomAll()};netgis.Client.prototype.onParcelsPanelToggle=function(a){this.searchParcel.reset()};
netgis.Client.prototype.onParcelsReset=function(a){this.map.removeLayer(netgis.Client.Layers.PARCEL_DISTRICTS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FIELDS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FEATURES);if(this.parcelPanel.visible()){this.parcelsAdded=[];var b=this.config.searchParcel.districts_service;a=this.map.createLayer(b);var c=this.config.styles.parcel;this.map.setLayerStyleSimple(a,c.fill,c.stroke,c.width);this.map.addLayer(netgis.Client.Layers.PARCEL_DISTRICTS,a); netgis.Client.prototype.onParcelsReset=function(a){this.map.removeLayer(netgis.Client.Layers.PARCEL_DISTRICTS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FIELDS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FEATURES);if(this.parcelPanel.visible()){this.parcelsAdded=[];var b=this.config.searchParcel.districts_service;a=this.map.createLayer(b);var c=this.config.styles.parcel;this.map.setLayerStyleSimple(a,c.fill,c.stroke,c.width);this.map.setLayerOrder(a,99999);this.map.addLayer(netgis.Client.Layers.PARCEL_DISTRICTS,
if(b.minZoom){var d=this;window.setTimeout(function(){d.map.zoomLevel(b.minZoom+1)},50)}this.setMode(netgis.Modes.PARCEL_SELECT)}else this.setMode(netgis.Modes.VIEW)}; a);if(b.minZoom){var d=this;window.setTimeout(function(){d.map.zoomLevel(b.minZoom+1)},50)}this.setMode(netgis.Modes.PARCEL_SELECT)}else this.setMode(netgis.Modes.VIEW)};
netgis.Client.prototype.onParcelsFieldsResponse=function(a){var b=a.detail;this.map.zoomGeoJSON(b.geojson);this.map.removeLayer(netgis.Client.Layers.PARCEL_DISTRICTS);a=this.config.styles.parcel;b=this.map.createLayerGeoJSON(b.geojson,!1);this.map.setLayerStyleSimple(b,a.fill,a.stroke,a.width);this.map.setLayerOrder(b,4E4);this.map.addLayer(netgis.Client.Layers.PARCEL_FIELDS,b)}; netgis.Client.prototype.onParcelsFieldsResponse=function(a){var b=a.detail;this.map.zoomGeoJSON(b.geojson);this.map.removeLayer(netgis.Client.Layers.PARCEL_DISTRICTS);a=this.config.styles.parcel;b=this.map.createLayerGeoJSON(b.geojson,!1);this.map.setLayerStyleSimple(b,a.fill,a.stroke,a.width);this.map.setLayerOrder(b,99999);this.map.addLayer(netgis.Client.Layers.PARCEL_FIELDS,b)};
netgis.Client.prototype.onParcelsResponse=function(a){a=this.map.createLayerWKT(a.detail.parcels);var b=this.config.styles.parcel;this.map.removeLayer(netgis.Client.Layers.PARCEL_DISTRICTS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FIELDS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FEATURES);this.map.setLayerStyleSimple(a,b.fill,b.stroke,b.width);this.map.addLayer(netgis.Client.Layers.PARCEL_FEATURES,a);this.map.zoomLayer(netgis.Client.Layers.PARCEL_FEATURES)}; netgis.Client.prototype.onParcelsResponse=function(a){a=this.map.createLayerWKT(a.detail.parcels);var b=this.config.styles.parcel;this.map.removeLayer(netgis.Client.Layers.PARCEL_DISTRICTS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FIELDS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FEATURES);this.map.setLayerStyleSimple(a,b.fill,b.stroke,b.width);this.map.setLayerOrder(a,99999);this.map.addLayer(netgis.Client.Layers.PARCEL_FEATURES,a);this.map.zoomLayer(netgis.Client.Layers.PARCEL_FEATURES)};
netgis.Client.prototype.onMapFeatureEnter=function(a){a=a.detail;switch(a.layer){case netgis.Client.Layers.PARCEL_DISTRICTS:a=a.properties.gemarkung;this.map.container.setAttribute("title",a);break;case netgis.Client.Layers.PARCEL_FIELDS:a=a.properties.flurname;this.map.container.setAttribute("title",a);break;case netgis.Client.Layers.PARCEL_FEATURES:a="Flur: "+a.properties.fln+" / Z\u00e4hler: "+a.properties.fsn_zae+" / Nenner: "+a.properties.fsn_nen,this.map.container.setAttribute("title",a+" (Klicken zum \u00dcbernehmen der Geometrie)")}}; netgis.Client.prototype.onMapFeatureEnter=function(a){a=a.detail;switch(a.layer){case netgis.Client.Layers.PARCEL_DISTRICTS:a=a.properties.gemarkung;this.map.container.setAttribute("title",a);break;case netgis.Client.Layers.PARCEL_FIELDS:a=a.properties.flurname;this.map.container.setAttribute("title",a);break;case netgis.Client.Layers.PARCEL_FEATURES:a="Flur: "+a.properties.fln+" / Z\u00e4hler: "+a.properties.fsn_zae+" / Nenner: "+a.properties.fsn_nen,this.editable&&(a+=" (Klicken zum \u00dcbernehmen der Geometrie)"),
netgis.Client.prototype.onMapFeatureClick=function(a){a=a.detail;switch(a.layer){default:console.info("Feature Click:",a);break;case netgis.Client.Layers.PARCEL_DISTRICTS:this.searchParcel.setDistrict(a.properties.gemarkung+" ("+a.properties.ldkreis+")",a.properties.gmkgnr);break;case netgis.Client.Layers.PARCEL_FIELDS:this.searchParcel.setFieldNumber(a.properties.flur);break;case netgis.Client.Layers.PARCEL_FEATURES:var b=a.properties.fsk;-1===this.parcelsAdded.indexOf(b)&&(this.map.addEditFeature(this.map.createFeatureJSON(a.properties)), this.map.container.setAttribute("title",a)}};
this.map.updateSnapFeatures(),this.parcelsAdded.push(b))}};netgis.Client.prototype.onMapFeatureLeave=function(a){this.map.container.setAttribute("title","")};netgis.Client.prototype.onParcelsItemEnter=function(a){this.map.setFeatureHover(this.map.findFeature(netgis.Client.Layers.PARCEL_FEATURES,"fsk",a.detail.id),!0)};netgis.Client.prototype.onParcelsItemLeave=function(a){this.map.setFeatureHover(this.map.findFeature(netgis.Client.Layers.PARCEL_FEATURES,"fsk",a.detail.id),!1)}; netgis.Client.prototype.onMapFeatureClick=function(a){a=a.detail;switch(a.layer){default:console.info("Feature Click:",a);break;case netgis.Client.Layers.PARCEL_DISTRICTS:this.searchParcel.setDistrict(a.properties.gemarkung+" ("+a.properties.ldkreis+")",a.properties.gmkgnr);break;case netgis.Client.Layers.PARCEL_FIELDS:this.searchParcel.setFieldNumber(a.properties.flur);break;case netgis.Client.Layers.PARCEL_FEATURES:if(!0===this.editable){var b=a.properties.fsk;-1===this.parcelsAdded.indexOf(b)&&
netgis.Client.prototype.onParcelsItemClick=function(a){this.map.zoomFeature(this.map.findFeature(netgis.Client.Layers.PARCEL_FEATURES,"fsk",a.detail.id))};netgis.Client.prototype.onParcelsImportClick=function(a){a=a.detail;this.map.addEditFeature(this.map.createFeatureWKT(a.geom,{id:a.id}));this.map.updateSnapFeatures()};netgis.Client.prototype.onSetMode=function(a){this.setMode(a.detail)}; (this.map.addEditFeature(this.map.createFeatureJSON(a.properties)),this.map.updateSnapFeatures(),this.parcelsAdded.push(b))}}};netgis.Client.prototype.onMapFeatureLeave=function(a){this.map.container.setAttribute("title","")};netgis.Client.prototype.onParcelsItemEnter=function(a){this.map.setFeatureHover(this.map.findFeature(netgis.Client.Layers.PARCEL_FEATURES,"fsk",a.detail.id),!0)};
netgis.Client.prototype.onSnapToggle=function(a){(a=a.detail.target.checked)?(this.map.updateSnapFeatures(),this.map.setSnapOn()):this.map.setSnapOff();this.toolbox.setSnap(a)};netgis.Client.prototype.onTracingToggle=function(a){a.detail.target.checked?(this.map.updateSnapFeatures(),this.map.setSnapOn(),this.map.setTracingOn(),this.toolbox.setSnap(!0)):this.map.setTracingOff()}; netgis.Client.prototype.onParcelsItemLeave=function(a){this.map.setFeatureHover(this.map.findFeature(netgis.Client.Layers.PARCEL_FEATURES,"fsk",a.detail.id),!1)};netgis.Client.prototype.onParcelsItemClick=function(a){this.map.zoomFeature(this.map.findFeature(netgis.Client.Layers.PARCEL_FEATURES,"fsk",a.detail.id))};netgis.Client.prototype.onParcelsImportClick=function(a){a=a.detail;!1!==this.editable&&(this.map.addEditFeature(this.map.createFeatureWKT(a.geom,{id:a.id})),this.map.updateSnapFeatures())};
netgis.Client.prototype.onSetMode=function(a){this.setMode(a.detail)};netgis.Client.prototype.onSnapToggle=function(a){(a=a.detail.target.checked)?(this.map.updateSnapFeatures(),this.map.setSnapOn()):this.map.setSnapOff();this.toolbox.setSnap(a)};netgis.Client.prototype.onTracingToggle=function(a){a.detail.target.checked?(this.map.updateSnapFeatures(),this.map.setSnapOn(),this.map.setTracingOn(),this.toolbox.setSnap(!0)):this.map.setTracingOff()};
netgis.Client.prototype.onBufferToggle=function(a){if(a=a.detail.target.checked)this.map.onDrawBufferOn();else this.map.onDrawBufferOff();this.toolbox.setBuffer(a)};netgis.Client.prototype.onBufferRadiusChange=function(a){a=Number.parseFloat(a.detail.target.value);this.map.onDrawBufferRadiusChange(a);this.toolbox.setBufferRadius(a)};netgis.Client.prototype.onBufferSegmentsChange=function(a){a=Number.parseInt(a.detail.target.value);this.map.onDrawBufferSegmentsChange(a);this.toolbox.setBufferSegments(a)}; netgis.Client.prototype.onBufferToggle=function(a){if(a=a.detail.target.checked)this.map.onDrawBufferOn();else this.map.onDrawBufferOff();this.toolbox.setBuffer(a)};netgis.Client.prototype.onBufferRadiusChange=function(a){a=Number.parseFloat(a.detail.target.value);this.map.onDrawBufferRadiusChange(a);this.toolbox.setBufferRadius(a)};netgis.Client.prototype.onBufferSegmentsChange=function(a){a=Number.parseInt(a.detail.target.value);this.map.onDrawBufferSegmentsChange(a);this.toolbox.setBufferSegments(a)};
netgis.Client.prototype.onBufferFeatureChange=function(a){this.map.onBufferChange(a.detail)};netgis.Client.prototype.onBufferFeatureAccept=function(a){this.map.onBufferAccept()};netgis.Client.prototype.onImportShapefileShow=function(a){this.modal.onImportShapefileShow(a)};netgis.Client.prototype.onImportGeoJSONShow=function(a){this.modal.onImportGeoJSONShow(a)};netgis.Client.prototype.onImportGMLShow=function(a){this.modal.onImportGMLShow(a)};netgis.Client.prototype.onImportSpatialiteShow=function(a){this.modal.onImportSpatialiteShow(a)}; netgis.Client.prototype.onBufferFeatureChange=function(a){this.map.onBufferChange(a.detail)};netgis.Client.prototype.onBufferFeatureAccept=function(a){this.map.onBufferAccept()};netgis.Client.prototype.onImportShapefileShow=function(a){this.modal.onImportShapefileShow(a)};netgis.Client.prototype.onImportGeoJSONShow=function(a){this.modal.onImportGeoJSONShow(a)};netgis.Client.prototype.onImportGMLShow=function(a){this.modal.onImportGMLShow(a)};netgis.Client.prototype.onImportSpatialiteShow=function(a){this.modal.onImportSpatialiteShow(a)};
netgis.Client.prototype.onImportGeopackageShow=function(a){this.modal.onImportGeopackageShow(a)};netgis.Client.prototype.onExportPDFShow=function(a){this.modal.onExportPDFShow(a)};netgis.Client.prototype.onExportPNGShow=function(a){this.modal.onExportPNGShow(a)};netgis.Client.prototype.onExportJPEGShow=function(a){this.modal.onExportJPEGShow(a)};netgis.Client.prototype.onExportGIFShow=function(a){this.modal.onExportGIFShow(a)};netgis.Client.prototype.onExportPDF=function(a){this.map.onExportPDF(a)}; netgis.Client.prototype.onImportGeopackageShow=function(a){this.modal.onImportGeopackageShow(a)};netgis.Client.prototype.onExportPDFShow=function(a){this.modal.onExportPDFShow(a)};netgis.Client.prototype.onExportPNGShow=function(a){this.modal.onExportPNGShow(a)};netgis.Client.prototype.onExportJPEGShow=function(a){this.modal.onExportJPEGShow(a)};netgis.Client.prototype.onExportGIFShow=function(a){this.modal.onExportGIFShow(a)};netgis.Client.prototype.onExportPDF=function(a){this.map.onExportPDF(a)};
@@ -104,8 +105,8 @@ this.client.on(netgis.Events.PARCEL_SHOW_PREVIEW,this.onParcelShowPreview.bind(t
this.onDrawBufferRadiusChange.bind(this));this.client.on(netgis.Events.DRAW_BUFFER_SEGMENTS_CHANGE,this.onDrawBufferSegmentsChange.bind(this))}; this.onDrawBufferRadiusChange.bind(this));this.client.on(netgis.Events.DRAW_BUFFER_SEGMENTS_CHANGE,this.onDrawBufferSegmentsChange.bind(this))};
netgis.MapOpenLayers.prototype.initMap=function(a){"undefined"!==typeof proj4&&(proj4.defs(a.projections),proj4.defs("urn:ogc:def:crs:OGC:1.3:CRS84",proj4.defs("EPSG:4326")),ol.proj.proj4.register(proj4));this.view=new ol.View({projection:a.map.projection,center:a.map.center,minZoom:a.map.minZoom,maxZoom:a.map.maxZoom,zoom:a.map.zoom});this.setPadding(0,0,0,0);this.map=new ol.Map({target:this.container,view:this.view,pixelRatio:1,moveTolerance:5,controls:[]});a.map.scalebar&&(this.scalebar=new ol.control.ScaleLine({bar:!0}), netgis.MapOpenLayers.prototype.initMap=function(a){"undefined"!==typeof proj4&&(proj4.defs(a.projections),proj4.defs("urn:ogc:def:crs:OGC:1.3:CRS84",proj4.defs("EPSG:4326")),ol.proj.proj4.register(proj4));this.view=new ol.View({projection:a.map.projection,center:a.map.center,minZoom:a.map.minZoom,maxZoom:a.map.maxZoom,zoom:a.map.zoom});this.setPadding(0,0,0,0);this.map=new ol.Map({target:this.container,view:this.view,pixelRatio:1,moveTolerance:5,controls:[]});a.map.scalebar&&(this.scalebar=new ol.control.ScaleLine({bar:!0}),
this.map.addControl(this.scalebar));this.map.on("pointermove",this.onPointerMove.bind(this));this.map.on("click",this.onSingleClick.bind(this));this.map.on("movestart",this.onMoveStart.bind(this));this.map.on("moveend",this.onMoveEnd.bind(this));this.view.on("change:resolution",this.onChangeResolution.bind(this))};netgis.MapOpenLayers.prototype.initStyles=function(a){a=a.styles.select;this.hoverStyle=this.createStyle(a.fill,a.stroke,a.width);this.hoverStyle.setZIndex(1)}; this.map.addControl(this.scalebar));this.map.on("pointermove",this.onPointerMove.bind(this));this.map.on("click",this.onSingleClick.bind(this));this.map.on("movestart",this.onMoveStart.bind(this));this.map.on("moveend",this.onMoveEnd.bind(this));this.view.on("change:resolution",this.onChangeResolution.bind(this))};netgis.MapOpenLayers.prototype.initStyles=function(a){a=a.styles.select;this.hoverStyle=this.createStyle(a.fill,a.stroke,a.width);this.hoverStyle.setZIndex(1)};
netgis.MapOpenLayers.prototype.initDefaultLayers=function(){this.editLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),style:this.styleEdit.bind(this),zIndex:this.editLayerID});this.addLayer(netgis.Client.Layers.EDIT_LAYER,this.editLayer);this.previewLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),style:this.styleSketch.bind(this),zIndex:this.editLayerID+10});this.addLayer(netgis.Client.Layers.PREVIEW_LAYER,this.previewLayer);this.parcelLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}), netgis.MapOpenLayers.prototype.initDefaultLayers=function(){this.editLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),style:this.styleEdit.bind(this),zIndex:this.editLayerID});this.addLayer(netgis.Client.Layers.EDIT_LAYER,this.editLayer);this.previewLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),style:this.styleSketch.bind(this),zIndex:this.editLayerID+1E3});this.addLayer(netgis.Client.Layers.PREVIEW_LAYER,this.previewLayer);this.editEventsOn()};
style:this.styleParcel.bind(this),zIndex:this.editLayerID+20});this.map.addLayer(this.parcelLayer);this.editEventsOn()};netgis.MapOpenLayers.prototype.editEventsOn=function(){this.editLayer.getSource().on("addfeature",this.onEditLayerAdd.bind(this));this.editLayer.getSource().on("changefeature",this.onEditLayerChange.bind(this));this.editLayer.getSource().on("removefeature",this.onEditLayerRemove.bind(this))};netgis.MapOpenLayers.prototype.editEventsOff=function(){}; netgis.MapOpenLayers.prototype.editEventsOn=function(){this.editLayer.getSource().on("addfeature",this.onEditLayerAdd.bind(this));this.editLayer.getSource().on("changefeature",this.onEditLayerChange.bind(this));this.editLayer.getSource().on("removefeature",this.onEditLayerRemove.bind(this))};netgis.MapOpenLayers.prototype.editEventsOff=function(){};
netgis.MapOpenLayers.prototype.initInteractions=function(){this.interactions[netgis.Modes.VIEW]=[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.PANNING]=this.interactions[netgis.Modes.VIEW];this.interactions[netgis.Modes.ZOOMING_IN]=this.interactions[netgis.Modes.VIEW];this.interactions[netgis.Modes.ZOOMING_OUT]=this.interactions[netgis.Modes.VIEW];this.interactions[netgis.Modes.DRAW_POINTS]=[new ol.interaction.Draw({type:"Point",source:this.editLayer.getSource(), netgis.MapOpenLayers.prototype.initInteractions=function(){this.interactions[netgis.Modes.VIEW]=[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.PANNING]=this.interactions[netgis.Modes.VIEW];this.interactions[netgis.Modes.ZOOMING_IN]=this.interactions[netgis.Modes.VIEW];this.interactions[netgis.Modes.ZOOMING_OUT]=this.interactions[netgis.Modes.VIEW];this.interactions[netgis.Modes.DRAW_POINTS]=[new ol.interaction.Draw({type:"Point",source:this.editLayer.getSource(),
style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.DRAW_POINTS][0].on("drawend",this.onDrawPointsEnd.bind(this));this.interactions[netgis.Modes.DRAW_LINES]=[new ol.interaction.Draw({type:"LineString",source:this.editLayer.getSource(),style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.DRAW_LINES][0].on("drawend",this.onDrawLinesEnd.bind(this)); style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.DRAW_POINTS][0].on("drawend",this.onDrawPointsEnd.bind(this));this.interactions[netgis.Modes.DRAW_LINES]=[new ol.interaction.Draw({type:"LineString",source:this.editLayer.getSource(),style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.DRAW_LINES][0].on("drawend",this.onDrawLinesEnd.bind(this));
this.interactions[netgis.Modes.DRAW_POLYGONS]=[new ol.interaction.Draw({type:"Polygon",source:this.editLayer.getSource(),style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.CUT_FEATURE_BEGIN]=[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.CUT_FEATURE_DRAW]=[new ol.interaction.Draw({type:"Polygon",style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom]; this.interactions[netgis.Modes.DRAW_POLYGONS]=[new ol.interaction.Draw({type:"Polygon",source:this.editLayer.getSource(),style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.CUT_FEATURE_BEGIN]=[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.CUT_FEATURE_DRAW]=[new ol.interaction.Draw({type:"Polygon",style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];
@@ -134,7 +135,7 @@ netgis.MapOpenLayers.prototype.styleModify=function(a){var b=new ol.style.Style(
geometry:this.getGeometryPoints(a)});a=a.getGeometry();a instanceof ol.geom.Polygon&&(a=a.getArea(),b.setText(new ol.style.Text({text:[netgis.util.formatArea(a,!0),"4mm sans-serif"],font:this.labelFont,fill:new ol.style.Fill({color:this.config.styles.modify.stroke}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]})));return[b,c]}; geometry:this.getGeometryPoints(a)});a=a.getGeometry();a instanceof ol.geom.Polygon&&(a=a.getArea(),b.setText(new ol.style.Text({text:[netgis.util.formatArea(a,!0),"4mm sans-serif"],font:this.labelFont,fill:new ol.style.Fill({color:this.config.styles.modify.stroke}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]})));return[b,c]};
netgis.MapOpenLayers.prototype.styleSketch=function(a){var b=a.getGeometry(),c=new ol.style.Style({image:new ol.style.Circle({radius:this.config.styles.sketch.pointRadius,fill:new ol.style.Fill({color:this.config.styles.sketch.stroke})}),fill:new ol.style.Fill({color:this.config.styles.sketch.fill}),stroke:new ol.style.Stroke({color:this.config.styles.sketch.stroke,width:this.config.styles.sketch.strokeWidth})});b instanceof ol.geom.Polygon&&(b=b.getArea(),c.setText(new ol.style.Text({text:[netgis.util.formatArea(b, netgis.MapOpenLayers.prototype.styleSketch=function(a){var b=a.getGeometry(),c=new ol.style.Style({image:new ol.style.Circle({radius:this.config.styles.sketch.pointRadius,fill:new ol.style.Fill({color:this.config.styles.sketch.stroke})}),fill:new ol.style.Fill({color:this.config.styles.sketch.fill}),stroke:new ol.style.Stroke({color:this.config.styles.sketch.stroke,width:this.config.styles.sketch.strokeWidth})});b instanceof ol.geom.Polygon&&(b=b.getArea(),c.setText(new ol.style.Text({text:[netgis.util.formatArea(b,
!0),"4mm sans-serif"],font:this.labelFont,fill:new ol.style.Fill({color:this.config.styles.sketch.stroke}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]})));a=new ol.style.Style({image:new ol.style.Circle({radius:this.config.styles.sketch.pointRadius,fill:new ol.style.Fill({color:this.config.styles.sketch.stroke})}),geometry:this.getGeometryPoints(a)});return[c,a]}; !0),"4mm sans-serif"],font:this.labelFont,fill:new ol.style.Fill({color:this.config.styles.sketch.stroke}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]})));a=new ol.style.Style({image:new ol.style.Circle({radius:this.config.styles.sketch.pointRadius,fill:new ol.style.Fill({color:this.config.styles.sketch.stroke})}),geometry:this.getGeometryPoints(a)});return[c,a]};
netgis.MapOpenLayers.prototype.styleParcel=function(){return new ol.style.Style({fill:new ol.style.Fill({color:this.client.config.styles.parcel.fill}),stroke:new ol.style.Stroke({color:this.client.config.styles.parcel.stroke,width:this.client.config.styles.parcel.strokeWidth})})};netgis.MapOpenLayers.prototype.redrawVectorLayers=function(){this.map.getLayers().forEach(function(a,b,c){a instanceof ol.layer.Vector&&a.setStyle(a.getStyle())})}; netgis.MapOpenLayers.prototype.styleParcel=function(){return new ol.style.Style({fill:new ol.style.Fill({color:this.client.config.styles.parcel.fill}),stroke:new ol.style.Stroke({color:this.client.config.styles.parcel.stroke,width:this.client.config.styles.parcel.strokeWidth}),zIndex:99999})};netgis.MapOpenLayers.prototype.redrawVectorLayers=function(){this.map.getLayers().forEach(function(a,b,c){a instanceof ol.layer.Vector&&a.setStyle(a.getStyle())})};
netgis.MapOpenLayers.prototype.getGeometryPoints=function(a){var b=a.getGeometry();if(b instanceof ol.geom.LineString)return new ol.geom.MultiPoint(b.getCoordinates());if(b instanceof ol.geom.Polygon){a=[];b=b.getCoordinates();for(var c=0;c<b.length;c++)for(var d=b[c],e=0;e<d.length;e++)a.push(d[e]);return new ol.geom.MultiPoint(a)}if(b instanceof ol.geom.MultiPolygon){a=[];for(var f=b.getPolygons(),g=0;g<f.length;g++)for(b=f[g].getCoordinates(),c=0;c<b.length;c++)for(d=b[c],e=0;e<d.length;e++)a.push(d[e]); netgis.MapOpenLayers.prototype.getGeometryPoints=function(a){var b=a.getGeometry();if(b instanceof ol.geom.LineString)return new ol.geom.MultiPoint(b.getCoordinates());if(b instanceof ol.geom.Polygon){a=[];b=b.getCoordinates();for(var c=0;c<b.length;c++)for(var d=b[c],e=0;e<d.length;e++)a.push(d[e]);return new ol.geom.MultiPoint(a)}if(b instanceof ol.geom.MultiPolygon){a=[];for(var f=b.getPolygons(),g=0;g<f.length;g++)for(b=f[g].getCoordinates(),c=0;c<b.length;c++)for(d=b[c],e=0;e<d.length;e++)a.push(d[e]);
return new ol.geom.MultiPoint(a)}if(b instanceof ol.geom.MultiLineString){a=[];f=b.getPolygons();for(g=0;g<f.length;g++)for(b=f[g].getCoordinates(),c=0;c<b.length;c++)for(d=b[c],e=0;e<d.length;e++)a.push(d[e]);return new ol.geom.MultiPoint(a)}return b};netgis.MapOpenLayers.prototype.getActiveVectorLayers=function(){for(var a=[],b=this.map.getLayers().getArray(),c=this.layers,d=0;d<c.length;d++){var e=c[d];e instanceof ol.layer.Vector&&-1<b.indexOf(e)&&a.push(e)}return a}; return new ol.geom.MultiPoint(a)}if(b instanceof ol.geom.MultiLineString){a=[];f=b.getPolygons();for(g=0;g<f.length;g++)for(b=f[g].getCoordinates(),c=0;c<b.length;c++)for(d=b[c],e=0;e<d.length;e++)a.push(d[e]);return new ol.geom.MultiPoint(a)}return b};netgis.MapOpenLayers.prototype.getActiveVectorLayers=function(){for(var a=[],b=this.map.getLayers().getArray(),c=this.layers,d=0;d<c.length;d++){var e=c[d];e instanceof ol.layer.Vector&&-1<b.indexOf(e)&&a.push(e)}return a};
netgis.MapOpenLayers.prototype.setMode=function(a){switch(this.mode){case netgis.Modes.BUFFER_FEATURE_EDIT:this.onBufferCancel(null);break;case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:var b=this.drawBufferOn;this.onDrawBufferOff(null);this.drawBufferOn=b;break;case netgis.Modes.MODIFY_FEATURES:this.editLayer.setStyle(this.styleEdit.bind(this))}this.container.classList.remove("netgis-cursor-draw");this.container.classList.remove("netgis-clickable");switch(a){case netgis.Modes.DRAW_POINTS:this.container.classList.add("netgis-cursor-draw"); netgis.MapOpenLayers.prototype.setMode=function(a){switch(this.mode){case netgis.Modes.BUFFER_FEATURE_EDIT:this.onBufferCancel(null);break;case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:var b=this.drawBufferOn;this.onDrawBufferOff(null);this.drawBufferOn=b;break;case netgis.Modes.MODIFY_FEATURES:this.editLayer.setStyle(this.styleEdit.bind(this))}this.container.classList.remove("netgis-cursor-draw");this.container.classList.remove("netgis-clickable");switch(a){case netgis.Modes.DRAW_POINTS:this.container.classList.add("netgis-cursor-draw");
@@ -153,9 +154,10 @@ netgis.MapOpenLayers.prototype.onAddServiceWMS=function(a){var b=this.createLaye
netgis.MapOpenLayers.prototype.onSetExtent=function(a){var b=ol.proj.fromLonLat([a.minx,a.miny],this.client.config.map.projection);a=ol.proj.fromLonLat([a.maxx,a.maxy],this.client.config.map.projection);this.view.fit([b[0],b[1],a[0],a[1]])};netgis.MapOpenLayers.prototype.onChangeZoom=function(a){this.view.animate({zoom:this.view.getZoom()+a,duration:200})};netgis.MapOpenLayers.prototype.onZoomWKT=function(a){a=(new ol.format.WKT).readGeometry(a);this.view.fit(a,{duration:300,padding:[40,40,40,40]})}; netgis.MapOpenLayers.prototype.onSetExtent=function(a){var b=ol.proj.fromLonLat([a.minx,a.miny],this.client.config.map.projection);a=ol.proj.fromLonLat([a.maxx,a.maxy],this.client.config.map.projection);this.view.fit([b[0],b[1],a[0],a[1]])};netgis.MapOpenLayers.prototype.onChangeZoom=function(a){this.view.animate({zoom:this.view.getZoom()+a,duration:200})};netgis.MapOpenLayers.prototype.onZoomWKT=function(a){a=(new ol.format.WKT).readGeometry(a);this.view.fit(a,{duration:300,padding:[40,40,40,40]})};
netgis.MapOpenLayers.prototype.onPointerMove=function(a){var b=a.pixel;a=a.coordinate;var c=null,d=null;this.map.forEachFeatureAtPixel(b,function(a,b){if(b){if(b.get("id")&&netgis.util.isString(b.get("id"))&&-1!==b.get("id").search("import-"))return!1;c=a;d=b;return!0}});switch(this.mode){default:return!0;case netgis.Modes.PARCEL_SELECT:case netgis.Modes.DELETE_FEATURES:case netgis.Modes.CUT_FEATURE_BEGIN:case netgis.Modes.BUFFER_FEATURE_BEGIN:break;case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:return this.updateDrawBufferPreview(), netgis.MapOpenLayers.prototype.onPointerMove=function(a){var b=a.pixel;a=a.coordinate;var c=null,d=null;this.map.forEachFeatureAtPixel(b,function(a,b){if(b){if(b.get("id")&&netgis.util.isString(b.get("id"))&&-1!==b.get("id").search("import-"))return!1;c=a;d=b;return!0}});switch(this.mode){default:return!0;case netgis.Modes.PARCEL_SELECT:case netgis.Modes.DELETE_FEATURES:case netgis.Modes.CUT_FEATURE_BEGIN:case netgis.Modes.BUFFER_FEATURE_BEGIN:break;case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:return this.updateDrawBufferPreview(),
!0}c!==this.hoverFeature&&(this.hoverFeature&&this.featureLeave(this.hoverFeature,this.hoverLayer,b,a),c&&this.featureEnter(c,d,b,a),this.redrawVectorLayers(),this.hoverFeature=c,this.hoverLayer=d);c&&this.featureHover(c,d,b,a)};netgis.MapOpenLayers.prototype.onPointerLeave=function(a){this.hoverFeature&&(this.featureLeave(this.hoverFeature,this.hoverLayer,[a.offsetX,a.offsetY],null),this.hoverLayer=this.hoverFeature=null)}; !0}c!==this.hoverFeature&&(this.hoverFeature&&this.featureLeave(this.hoverFeature,this.hoverLayer,b,a),c&&this.featureEnter(c,d,b,a),this.redrawVectorLayers(),this.hoverFeature=c,this.hoverLayer=d);c&&this.featureHover(c,d,b,a)};netgis.MapOpenLayers.prototype.onPointerLeave=function(a){this.hoverFeature&&(this.featureLeave(this.hoverFeature,this.hoverLayer,[a.offsetX,a.offsetY],null),this.hoverLayer=this.hoverFeature=null)};
netgis.MapOpenLayers.prototype.featureEnter=function(a,b,c,d){b&&(this.container.classList.add("netgis-clickable"),b.get("id")!==netgis.Client.Layers.EDIT_LAYER&&-1===b.get("id").search("import-")&&a.setStyle(this.hoverStyle),netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_ENTER,{pixel:c,coords:d,layer:b.get("id"),properties:a.getProperties()}))};netgis.MapOpenLayers.prototype.featureHover=function(a,b,c,d){}; netgis.MapOpenLayers.prototype.featureEnter=function(a,b,c,d){if(b){this.container.classList.add("netgis-clickable");var e=!1;b.get("id")===netgis.Client.Layers.EDIT_LAYER&&(e=!0);b.get("id")===netgis.Client.Layers.PARCEL_DISTRICTS&&(e=!0);b.get("id")===netgis.Client.Layers.PARCEL_FIELDS&&(e=!0);b.get("id")===netgis.Client.Layers.PARCEL_FEATURES&&(e=!0);e&&a.setStyle(this.hoverStyle);netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_ENTER,{pixel:c,coords:d,layer:b.get("id"),properties:a.getProperties()})}};
netgis.MapOpenLayers.prototype.featureLeave=function(a,b,c,d){b&&(this.container.classList.remove("netgis-clickable"),b.get("id")!==netgis.Client.Layers.EDIT_LAYER&&a.setStyle(null),netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_LEAVE,{pixel:c,coords:d,layer:b.get("id"),properties:a.getProperties()}))};netgis.MapOpenLayers.prototype.findFeature=function(a,b,c){if(a=this.activeLayers[a]){a=a.getSource().getFeatures();for(var d=null,e=0;e<a.length;e++){var f=a[e];if(f.get(b)===c){d=f;break}}return d}}; netgis.MapOpenLayers.prototype.featureHover=function(a,b,c,d){};netgis.MapOpenLayers.prototype.featureLeave=function(a,b,c,d){b&&(this.container.classList.remove("netgis-clickable"),b.get("id")!==netgis.Client.Layers.EDIT_LAYER&&a.setStyle(null),netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_LEAVE,{pixel:c,coords:d,layer:b.get("id"),properties:a.getProperties()}))};
netgis.MapOpenLayers.prototype.setFeatureHover=function(a,b){a.setStyle(b?this.hoverStyle:null)};netgis.MapOpenLayers.prototype.onPointerMove_01=function(a){a=a.pixel;var b=this.hoverFeature,c=this;switch(this.mode){case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:this.updateDrawBufferPreview()}b=null;this.map.forEachFeatureAtPixel(a,function(a,e){e===c.editLayer&&(b=a);return!0});b!==this.hoverFeature&&this.redrawVectorLayers();this.hoverFeature=b}; netgis.MapOpenLayers.prototype.findFeature=function(a,b,c){if(a=this.activeLayers[a]){a=a.getSource().getFeatures();for(var d=null,e=0;e<a.length;e++){var f=a[e];if(f.get(b)===c){d=f;break}}return d}};netgis.MapOpenLayers.prototype.setFeatureHover=function(a,b){a.setStyle(b?this.hoverStyle:null)};
netgis.MapOpenLayers.prototype.onPointerMove_01=function(a){a=a.pixel;var b=this.hoverFeature,c=this;switch(this.mode){case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:this.updateDrawBufferPreview()}b=null;this.map.forEachFeatureAtPixel(a,function(a,e){e===c.editLayer&&(b=a);return!0});b!==this.hoverFeature&&this.redrawVectorLayers();this.hoverFeature=b};
netgis.MapOpenLayers.prototype.onSingleClick=function(a){switch(this.mode){default:this.hoverFeature&&this.hoverLayer&&(a={pixel:a.pixel,coords:a.coordinate,layer:this.hoverLayer.get("id"),id:this.hoverFeature.getId(),properties:this.hoverFeature.getProperties()},netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_CLICK,a));break;case netgis.Modes.DELETE_FEATURES:this.hoverFeature&&(this.editLayer.getSource().removeFeature(this.hoverFeature),this.featureLeave(this.hoverFeature,this.editLayer), netgis.MapOpenLayers.prototype.onSingleClick=function(a){switch(this.mode){default:this.hoverFeature&&this.hoverLayer&&(a={pixel:a.pixel,coords:a.coordinate,layer:this.hoverLayer.get("id"),id:this.hoverFeature.getId(),properties:this.hoverFeature.getProperties()},netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_CLICK,a));break;case netgis.Modes.DELETE_FEATURES:this.hoverFeature&&(this.editLayer.getSource().removeFeature(this.hoverFeature),this.featureLeave(this.hoverFeature,this.editLayer),
this.hoverFeature=null,netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.VIEW));break;case netgis.Modes.CUT_FEATURE_BEGIN:this.hoverFeature&&(this.selected=this.hoverFeature,netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.CUT_FEATURE_DRAW));break;case netgis.Modes.BUFFER_FEATURE_BEGIN:this.hoverFeature&&(this.selected=this.hoverFeature,netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.BUFFER_FEATURE_EDIT))}}; this.hoverFeature=null,netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.VIEW));break;case netgis.Modes.CUT_FEATURE_BEGIN:this.hoverFeature&&(this.selected=this.hoverFeature,netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.CUT_FEATURE_DRAW));break;case netgis.Modes.BUFFER_FEATURE_BEGIN:this.hoverFeature&&(this.selected=this.hoverFeature,netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.BUFFER_FEATURE_EDIT))}};
netgis.MapOpenLayers.prototype.onMoveStart=function(a){};netgis.MapOpenLayers.prototype.onMoveEnd=function(a){};netgis.MapOpenLayers.prototype.onChangeResolution=function(a){}; netgis.MapOpenLayers.prototype.onMoveStart=function(a){};netgis.MapOpenLayers.prototype.onMoveEnd=function(a){};netgis.MapOpenLayers.prototype.onChangeResolution=function(a){};
@@ -194,8 +196,8 @@ function(){var n=document.createElement("canvas");n.width=b;n.height=c;var p=n.g
t.setFillColor(255,255,255);t.rect(x,r+u-11,80,11,"F");t.setFontSize(8);t.text("Datum: "+netgis.util.getTimeStamp(),x+2,r+u-2-4);t.text("Quelle: "+window.location.href,x+2,r+u-2);n=t.output("bloburl",{filename:k.export.defaultFilename+".pdf"});window.open(n,"_blank");break;case "jpeg":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),k.export.defaultFilename+".jpg"):(q.setAttribute("download",k.export.defaultFilename+".jpg"),q.setAttribute("href",n.toDataURL("image/jpeg",1)),q.click()); t.setFillColor(255,255,255);t.rect(x,r+u-11,80,11,"F");t.setFontSize(8);t.text("Datum: "+netgis.util.getTimeStamp(),x+2,r+u-2-4);t.text("Quelle: "+window.location.href,x+2,r+u-2);n=t.output("bloburl",{filename:k.export.defaultFilename+".pdf"});window.open(n,"_blank");break;case "jpeg":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),k.export.defaultFilename+".jpg"):(q.setAttribute("download",k.export.defaultFilename+".jpg"),q.setAttribute("href",n.toDataURL("image/jpeg",1)),q.click());
break;case "png":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),k.export.defaultFilename+".png"):(q.setAttribute("download",k.export.defaultFilename+".png"),q.setAttribute("href",n.toDataURL("image/png",1)),q.click());break;case "gif":q.setAttribute("download",k.export.defaultFilename+".gif"),v=new GIF({workerScript:k.export.gifWebWorker,quality:1}),v.addFrame(n),v.on("finished",function(a){q.setAttribute("href",window.URL.createObjectURL(a));q.click()}),v.render()}h.setTarget(g); break;case "png":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),k.export.defaultFilename+".png"):(q.setAttribute("download",k.export.defaultFilename+".png"),q.setAttribute("href",n.toDataURL("image/png",1)),q.click());break;case "gif":q.setAttribute("download",k.export.defaultFilename+".gif"),v=new GIF({workerScript:k.export.gifWebWorker,quality:1}),v.addFrame(n),v.on("finished",function(a){q.setAttribute("href",window.URL.createObjectURL(a));q.click()}),v.render()}h.setTarget(g);
g.removeChild(m);netgis.util.invoke(f.container,netgis.Events.EXPORT_END,null)});h.renderSync()};l.src=k.export.logo};netgis.MapOpenLayers.prototype.splitMultiPolygons=function(a){a=a.getSource();for(var b=a.getFeatures(),c=[],d=[],e=0;e<b.length;e++){var f=b[e],g=f.getGeometry();if(g instanceof ol.geom.MultiPolygon){g=g.getPolygons();for(var h=0;h<g.length;h++){var k=new ol.Feature({geometry:g[h]});d.push(k)}c.push(f)}}for(e=0;e<c.length;e++)a.removeFeature(c[e]);a.addFeatures(d)};netgis=netgis||{};netgis.Menu=function(){this.root=this.client=null;this.sections=[]}; g.removeChild(m);netgis.util.invoke(f.container,netgis.Events.EXPORT_END,null)});h.renderSync()};l.src=k.export.logo};netgis.MapOpenLayers.prototype.splitMultiPolygons=function(a){a=a.getSource();for(var b=a.getFeatures(),c=[],d=[],e=0;e<b.length;e++){var f=b[e],g=f.getGeometry();if(g instanceof ol.geom.MultiPolygon){g=g.getPolygons();for(var h=0;h<g.length;h++){var k=new ol.Feature({geometry:g[h]});d.push(k)}c.push(f)}}for(e=0;e<c.length;e++)a.removeFeature(c[e]);a.addFeatures(d)};netgis=netgis||{};netgis.Menu=function(){this.root=this.client=null;this.sections=[]};
netgis.Menu.prototype.load=function(){this.root=document.createElement("header");this.root.className="netgis-menu netgis-color-a netgis-shadow";var a=document.createElement("div");this.root.appendChild(a);var b=this.createButton('<i class="fab fa-buffer"></i><span>Inhalte</span>',!0);b.addEventListener("click",this.onToggleClick.bind(this));a.appendChild(b);b=this.createButton('<i class="fas fa-tools"></i><span>Werkzeuge</span>',!0);b.addEventListener("click",this.onToolboxClick.bind(this));a.appendChild(b); netgis.Menu.prototype.load=function(){this.root=document.createElement("header");this.root.className="netgis-menu netgis-color-a netgis-shadow";var a=document.createElement("div");this.root.appendChild(a);var b=this.createButton('<i class="fab fa-buffer"></i><span>Inhalte</span>',!0);b.addEventListener("click",this.onToggleClick.bind(this));a.appendChild(b);!0===this.client.editable&&(b=this.createButton('<i class="fas fa-tools"></i><span>Werkzeuge</span>',!0),b.addEventListener("click",this.onToolboxClick.bind(this)),
b=this.createButton('<i class="fas fa-vector-square"></i><span>Flurst\u00fccke</span>',!0);b.addEventListener("click",this.onSearchParcelClick.bind(this));a.appendChild(b);b=this.createButton('<i class="fas fa-search"></i><span>Suche</span>',!0);b.addEventListener("click",this.onSearchPlaceClick.bind(this));a.appendChild(b);this.client.editable&&(a=this.createMenu('<i class="fas fa-caret-down"></i>Zeichnen').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-map-marker-alt"></i>Punkte', a.appendChild(b));b=this.createButton('<i class="fas fa-vector-square"></i><span>Flurst\u00fccke</span>',!0);b.addEventListener("click",this.onSearchParcelClick.bind(this));a.appendChild(b);b=this.createButton('<i class="fas fa-search"></i><span>Suche</span>',!0);b.addEventListener("click",this.onSearchPlaceClick.bind(this));a.appendChild(b);this.client.editable&&(a=this.createMenu('<i class="fas fa-caret-down"></i>Zeichnen').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-map-marker-alt"></i>Punkte',
this.onDrawPointClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-minus"></i>Linien',this.onDrawLineClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-vector-square"></i>Polygone',this.onDrawPolygonClick.bind(this))),a=this.createMenu('<i class="fas fa-caret-down"></i>Bearbeiten').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-cut"></i>Ausschneiden',this.onCutFeatureClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-arrows-alt"></i>Verschieben', this.onDrawPointClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-minus"></i>Linien',this.onDrawLineClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-vector-square"></i>Polygone',this.onDrawPolygonClick.bind(this))),a=this.createMenu('<i class="fas fa-caret-down"></i>Bearbeiten').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-cut"></i>Ausschneiden',this.onCutFeatureClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-arrows-alt"></i>Verschieben',
this.onModifyFeaturesClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-eraser"></i>L\u00f6schen',this.onDeleteFeaturesClick.bind(this))),a.appendChild(this.createMenuItem('<i class="far fa-dot-circle"></i>Puffern',this.onBufferFeatureClick.bind(this))),a=this.createMenu('<i class="fas fa-caret-down"></i>Import').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GeoJSON',this.onImportGeoJSONClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GML', this.onModifyFeaturesClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-eraser"></i>L\u00f6schen',this.onDeleteFeaturesClick.bind(this))),a.appendChild(this.createMenuItem('<i class="far fa-dot-circle"></i>Puffern',this.onBufferFeatureClick.bind(this))),a=this.createMenu('<i class="fas fa-caret-down"></i>Import').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GeoJSON',this.onImportGeoJSONClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GML',
this.onImportGMLClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>Shapefile',this.onImportShapefileClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>Spatialite',this.onImportSpatialiteClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GeoPackage',this.onImportGeopackageClick.bind(this))),a=this.createMenu('<i class="fas fa-caret-down"></i>Export').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>PDF', this.onImportGMLClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>Shapefile',this.onImportShapefileClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>Spatialite',this.onImportSpatialiteClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GeoPackage',this.onImportGeopackageClick.bind(this))),a=this.createMenu('<i class="fas fa-caret-down"></i>Export').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>PDF',
@@ -218,7 +220,7 @@ l){k=e;m=!0;break}m||(e=c.folders.length,c.folders.push({title:h,parent:k,path:l
l[0];c.layers.push({folder:g,type:netgis.LayerTypes.XYZ,url:k.href,title:f.title,attribution:f.rights,active:f.active});break;case "http://www.opengis.net/spec/owc-geojson/1.0/req/osm":k=l[0],c.layers.push({folder:g,type:netgis.LayerTypes.XYZ,url:k.href,title:f.title,attribution:f.rights,active:f.active})}}b.invoke(netgis.Events.CONTEXT_UPDATE,c)}}}();netgis=netgis||{};netgis.Panel=function(a){this.initElements(a);this.initEvents()};netgis.Panel.prototype.initElements=function(a){var b=document.createElement("section");b.className="netgis-panel netgis-resize-right netgis-color-e netgis-shadow";this.addHeader(b,a,this.onHeaderClick.bind(this));this.container=b};netgis.Panel.prototype.initEvents=function(){this.resizeObserver=(new ResizeObserver(this.onResize.bind(this))).observe(this.container)};netgis.Panel.prototype.attach=function(a){a.appendChild(this.container)}; l[0];c.layers.push({folder:g,type:netgis.LayerTypes.XYZ,url:k.href,title:f.title,attribution:f.rights,active:f.active});break;case "http://www.opengis.net/spec/owc-geojson/1.0/req/osm":k=l[0],c.layers.push({folder:g,type:netgis.LayerTypes.XYZ,url:k.href,title:f.title,attribution:f.rights,active:f.active})}}b.invoke(netgis.Events.CONTEXT_UPDATE,c)}}}();netgis=netgis||{};netgis.Panel=function(a){this.initElements(a);this.initEvents()};netgis.Panel.prototype.initElements=function(a){var b=document.createElement("section");b.className="netgis-panel netgis-resize-right netgis-color-e netgis-shadow";this.addHeader(b,a,this.onHeaderClick.bind(this));this.container=b};netgis.Panel.prototype.initEvents=function(){this.resizeObserver=(new ResizeObserver(this.onResize.bind(this))).observe(this.container)};netgis.Panel.prototype.attach=function(a){a.appendChild(this.container)};
netgis.Panel.prototype.addHeader=function(a,b,c){var d=document.createElement("button");d.className="netgis-button netgis-clip-text netgis-color-c";d.innerHTML="<span>"+b+"</span><i class='netgis-icon fas fa-times'></i>";d.setAttribute("type","button");c&&(d.onclick=c);a&&a.appendChild(d);return d};netgis.Panel.prototype.show=function(){this.container.classList.add("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{panel:this,visible:!0})}; netgis.Panel.prototype.addHeader=function(a,b,c){var d=document.createElement("button");d.className="netgis-button netgis-clip-text netgis-color-c";d.innerHTML="<span>"+b+"</span><i class='netgis-icon fas fa-times'></i>";d.setAttribute("type","button");c&&(d.onclick=c);a&&a.appendChild(d);return d};netgis.Panel.prototype.show=function(){this.container.classList.add("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{panel:this,visible:!0})};
netgis.Panel.prototype.hide=function(){this.container.classList.remove("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{panel:this,visible:!1})};netgis.Panel.prototype.toggle=function(){this.container.classList.toggle("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{panel:this,visible:this.container.classList.contains("netgis-show")})};netgis.Panel.prototype.visible=function(){return this.container.classList.contains("netgis-show")}; netgis.Panel.prototype.hide=function(){this.container.classList.remove("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{panel:this,visible:!1})};netgis.Panel.prototype.toggle=function(){this.container.classList.toggle("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{panel:this,visible:this.container.classList.contains("netgis-show")})};netgis.Panel.prototype.visible=function(){return this.container.classList.contains("netgis-show")};
netgis.Panel.prototype.width=function(){return this.container.getBoundingClientRect().width};netgis.Panel.prototype.onHeaderClick=function(a){this.hide()};netgis.Panel.prototype.onResize=function(a){this.container.classList.contains("netgis-show")&&(a=this.container.getBoundingClientRect(),netgis.util.invoke(this.container,netgis.Events.PANEL_RESIZE,{width:a.width}))};netgis=netgis||{};netgis.SearchParcel=function(a){this.config=a;this.initElements();this.initEvents()};netgis.SearchParcel.Events=Object.freeze({TOGGLE:"search-parcel-toggle"}); netgis.Panel.prototype.width=function(){return this.container.getBoundingClientRect().width};netgis.Panel.prototype.onHeaderClick=function(a){this.hide()};netgis.Panel.prototype.onResize=function(a){this.container.classList.contains("netgis-show")&&(a=this.container.getBoundingClientRect(),netgis.util.invoke(this.container,netgis.Events.PANEL_RESIZE,{width:a.width}))};netgis=netgis||{};netgis.SearchParcel=function(a,b){this.client=b;this.config=a;this.initElements();this.initEvents()};netgis.SearchParcel.Events=Object.freeze({TOGGLE:"search-parcel-toggle"});
netgis.SearchParcel.prototype.initElements=function(){this.container=document.createElement("section");this.container.className="netgis-search-parcel";var a=document.createElement("section");this.top=a;this.container.appendChild(a);var b=this.createInput("Gemarkungsname:");b.style.position="relative";a.appendChild(b);this.nameInput=b.children[0];this.nameInput.setAttribute("title","ENTER: Ausw\u00e4hlen, ESCAPE: Zur\u00fccksetzen");this.nameInput.addEventListener("keyup",this.onInputNameKey.bind(this)); netgis.SearchParcel.prototype.initElements=function(){this.container=document.createElement("section");this.container.className="netgis-search-parcel";var a=document.createElement("section");this.top=a;this.container.appendChild(a);var b=this.createInput("Gemarkungsname:");b.style.position="relative";a.appendChild(b);this.nameInput=b.children[0];this.nameInput.setAttribute("title","ENTER: Ausw\u00e4hlen, ESCAPE: Zur\u00fccksetzen");this.nameInput.addEventListener("keyup",this.onInputNameKey.bind(this));
this.nameLoader=document.createElement("div");this.nameLoader.className="netgis-loader netgis-text-primary netgis-hide";this.nameLoader.innerHTML="<i class='fas fa-spinner'></i>";b.appendChild(this.nameLoader);this.nameList=document.createElement("ul");a.appendChild(this.nameList);b=this.createInput("Gemarkungsnummer:");this.districtInput=b.children[0];a.appendChild(b);b=this.createInput("Flurnummer:");this.fieldInput=b.children[0];this.fieldInput.addEventListener("keyup",this.onInputFieldKey.bind(this)); this.nameLoader=document.createElement("div");this.nameLoader.className="netgis-loader netgis-text-primary netgis-hide";this.nameLoader.innerHTML="<i class='fas fa-spinner'></i>";b.appendChild(this.nameLoader);this.nameList=document.createElement("ul");a.appendChild(this.nameList);b=this.createInput("Gemarkungsnummer:");this.districtInput=b.children[0];a.appendChild(b);b=this.createInput("Flurnummer:");this.fieldInput=b.children[0];this.fieldInput.addEventListener("keyup",this.onInputFieldKey.bind(this));
a.appendChild(b);b=this.createInput("<span>Flurst\u00fccksnummer (Z\u00e4hler/Nenner):</span>");this.parcelInputA=b.children[1];this.parcelInputA.style.width="48%";this.parcelInputB=this.parcelInputA.cloneNode(!0);this.parcelInputB.style.marginLeft="4%";b.appendChild(this.parcelInputB);a.appendChild(b);b=document.createElement("button");b.setAttribute("type","button");b.addEventListener("click",this.onParcelSearchClick.bind(this));b.className="netgis-color-a netgis-hover-c";b.innerHTML="Flurst\u00fccke suchen"; a.appendChild(b);b=this.createInput("<span>Flurst\u00fccksnummer (Z\u00e4hler/Nenner):</span>");this.parcelInputA=b.children[1];this.parcelInputA.style.width="48%";this.parcelInputB=this.parcelInputA.cloneNode(!0);this.parcelInputB.style.marginLeft="4%";b.appendChild(this.parcelInputB);a.appendChild(b);b=document.createElement("button");b.setAttribute("type","button");b.addEventListener("click",this.onParcelSearchClick.bind(this));b.className="netgis-color-a netgis-hover-c";b.innerHTML="Flurst\u00fccke suchen";
@@ -229,8 +231,8 @@ netgis.SearchParcel.prototype.attach=function(a){a.appendChild(this.container)};
netgis.SearchParcel.prototype.createNameItem=function(a){var b=document.createElement("li"),c=document.createElement("button");c.setAttribute("type","button");c.addEventListener("click",this.onNameItemClick.bind(this));c.className="netgis-color-e netgis-hover-a netgis-text-a netgis-hover-text-e";c.innerHTML=a;b.appendChild(c);return b}; netgis.SearchParcel.prototype.createNameItem=function(a){var b=document.createElement("li"),c=document.createElement("button");c.setAttribute("type","button");c.addEventListener("click",this.onNameItemClick.bind(this));c.className="netgis-color-e netgis-hover-a netgis-text-a netgis-hover-text-e";c.innerHTML=a;b.appendChild(c);return b};
netgis.SearchParcel.prototype.createTable=function(a){var b=document.createElement("div");b.className="netgis-table-wrapper";var c=document.createElement("table");b.appendChild(c);var d=document.createElement("thead");c.appendChild(d);var e=document.createElement("tr");e.className="netgis-color-d netgis-shadow";d.appendChild(e);for(d=0;d<a.length;d++){var f=document.createElement("th");f.innerHTML=a[d];e.appendChild(f)}a=document.createElement("tbody");c.appendChild(a);return b}; netgis.SearchParcel.prototype.createTable=function(a){var b=document.createElement("div");b.className="netgis-table-wrapper";var c=document.createElement("table");b.appendChild(c);var d=document.createElement("thead");c.appendChild(d);var e=document.createElement("tr");e.className="netgis-color-d netgis-shadow";d.appendChild(e);for(d=0;d<a.length;d++){var f=document.createElement("th");f.innerHTML=a[d];e.appendChild(f)}a=document.createElement("tbody");c.appendChild(a);return b};
netgis.SearchParcel.prototype.createParcelItem=function(a,b,c,d,e,f,g){var h=document.createElement("tr");h.className="netgis-hover-light netgis-hover-text-primary";h.setAttribute("title","Klicken zum zoomen");h.setAttribute("data-id",d);h.setAttribute("data-field",a);h.setAttribute("data-parcel-a",b);h.setAttribute("data-parcel-b",c);h.setAttribute("data-bbox",f);h.setAttribute("data-geom",g);h.addEventListener("pointerenter",this.onParcelEnter.bind(this));h.addEventListener("pointerleave",this.onParcelLeave.bind(this)); netgis.SearchParcel.prototype.createParcelItem=function(a,b,c,d,e,f,g){var h=document.createElement("tr");h.className="netgis-hover-light netgis-hover-text-primary";h.setAttribute("title","Klicken zum zoomen");h.setAttribute("data-id",d);h.setAttribute("data-field",a);h.setAttribute("data-parcel-a",b);h.setAttribute("data-parcel-b",c);h.setAttribute("data-bbox",f);h.setAttribute("data-geom",g);h.addEventListener("pointerenter",this.onParcelEnter.bind(this));h.addEventListener("pointerleave",this.onParcelLeave.bind(this));
h.addEventListener("click",this.onParcelClick.bind(this));f=document.createElement("td");h.appendChild(f);g=document.createElement("button");g.setAttribute("type","button");g.setAttribute("title","Geometrie \u00fcbernehmen");g.addEventListener("click",this.onParcelImportClick.bind(this));g.className="netgis-text-primary netgis-hover-primary";g.innerHTML="<i class='fas fa-paste'></i>";f.appendChild(g);f=document.createElement("td");f.innerHTML=a;h.appendChild(f);a=document.createElement("td");a.innerHTML= h.addEventListener("click",this.onParcelClick.bind(this));f=document.createElement("td");h.appendChild(f);this.client.editable&&(g=document.createElement("button"),g.setAttribute("type","button"),g.setAttribute("title","Geometrie \u00fcbernehmen"),g.addEventListener("click",this.onParcelImportClick.bind(this)),g.className="netgis-text-primary netgis-hover-primary",g.innerHTML="<i class='fas fa-paste'></i>",f.appendChild(g));f=document.createElement("td");f.innerHTML=a;h.appendChild(f);a=document.createElement("td");
b;h.appendChild(a);b=document.createElement("td");b.innerHTML=c;h.appendChild(b);c=document.createElement("td");c.innerHTML=d;h.appendChild(c);d=document.createElement("td");d.innerHTML=e;h.appendChild(d);return h}; a.innerHTML=b;h.appendChild(a);b=document.createElement("td");b.innerHTML=c;h.appendChild(b);c=document.createElement("td");c.innerHTML=d;h.appendChild(c);d=document.createElement("td");d.innerHTML=e;h.appendChild(d);return h};
netgis.SearchParcel.prototype.reset=function(){this.hideBottom();this.nameLoader.classList.add("netgis-hide");this.nameInput.value="";this.districtInput.value="";this.fieldInput.value="";this.parcelInputA.value="";this.parcelInputB.value="";this.nameList.innerHTML="";this.parcelInfo.innerHTML="";this.parcelList.innerHTML="";this.parcelTable.classList.add("netgis-hide");this.parcelReset.classList.add("netgis-hide");this.parcelCount.innerHTML="";var a=this;window.setTimeout(function(){a.top.scrollTop= netgis.SearchParcel.prototype.reset=function(){this.hideBottom();this.nameLoader.classList.add("netgis-hide");this.nameInput.value="";this.districtInput.value="";this.fieldInput.value="";this.parcelInputA.value="";this.parcelInputB.value="";this.nameList.innerHTML="";this.parcelInfo.innerHTML="";this.parcelList.innerHTML="";this.parcelTable.classList.add("netgis-hide");this.parcelReset.classList.add("netgis-hide");this.parcelCount.innerHTML="";var a=this;window.setTimeout(function(){a.top.scrollTop=
0;a.parcelTable.scrollTop=0},10);netgis.util.invoke(this.container,netgis.Events.PARCELS_RESET,null)};netgis.SearchParcel.prototype.onInputNameKey=function(a){switch(a.keyCode){case 13:this.selectFirstName();break;case 27:this.reset();break;default:this.requestName(this.nameInput.value.trim())}}; 0;a.parcelTable.scrollTop=0},10);netgis.util.invoke(this.container,netgis.Events.PARCELS_RESET,null)};netgis.SearchParcel.prototype.onInputNameKey=function(a){switch(a.keyCode){case 13:this.selectFirstName();break;case 27:this.reset();break;default:this.requestName(this.nameInput.value.trim())}};
netgis.SearchParcel.prototype.requestName=function(a){this.nameDebounce&&window.clearTimeout(this.nameDebounce);if(0!==a.length){var b=this.config.searchParcel.nameURL;b=netgis.util.replace(b,"{q}",window.encodeURIComponent(a));this.nameDebounce=window.setTimeout(this.onInputNameDebounce.bind(this,b),200);this.nameLoader.classList.remove("netgis-hide")}};netgis.SearchParcel.prototype.onInputNameDebounce=function(a){netgis.util.request(a,this.onInputNameResponse.bind(this))}; netgis.SearchParcel.prototype.requestName=function(a){this.nameDebounce&&window.clearTimeout(this.nameDebounce);if(0!==a.length){var b=this.config.searchParcel.nameURL;b=netgis.util.replace(b,"{q}",window.encodeURIComponent(a));this.nameDebounce=window.setTimeout(this.onInputNameDebounce.bind(this,b),200);this.nameLoader.classList.remove("netgis-hide")}};netgis.SearchParcel.prototype.onInputNameDebounce=function(a){netgis.util.request(a,this.onInputNameResponse.bind(this))};