Compare commits

..

72 Commits
1.9 ... 1.13.1

Author SHA1 Message Date
9a374f50de Merge pull request '# CSS bugfix' (#492) from fix_css_map_menu_bar_overlap into master
Reviewed-on: #492
2025-10-21 15:59:37 +02:00
ce63dd30bc # CSS bugfix
* fixes a rendering bug where the menu bar of the map client overlapped modal forms
2025-10-21 15:57:25 +02:00
e5db7f6b13 Merge pull request '# Small geometry processing' (#488) from 487_Small_geometry_processing into master
Reviewed-on: #488
2025-10-15 09:51:27 +02:00
442f3ceb37 # Small geometry processing
* changes SimpleGeomForm behaviour on small geometries (<1m²): These geometries will now be dismissed on processing
* adds a new info message in case of automatically removed geometries on saving
* updates tests
2025-10-15 09:50:59 +02:00
cd2949fc03 Merge pull request 'netgis_map_client_update' (#452) from netgis_map_client_update into master
Reviewed-on: #452
2025-10-12 11:31:37 +02:00
7bcd32fd7a # Netgis client update
* minor changes to configuration
2025-10-12 11:30:04 +02:00
97f1882698 Merge branch 'refs/heads/master' into netgis_map_client_update
# Conflicts:
#	konova/forms/geometry_form.py
#	templates/map/client/config.json
2025-10-12 11:22:56 +02:00
55cc8eb1f3 # Netgis client update
* updates the map client plugin to the latest and stable release
2025-10-12 11:18:11 +02:00
d6cabd5f6c Merge pull request 'sso_propagation_extension' (#483) from sso_propagation_extension into master
Reviewed-on: #483
2025-09-22 12:37:16 +02:00
63a824f9d9 # Geometry form fix
* fixes bugs in tests
* refactors and simplifies geometry merging on GeometryForm
2025-09-12 13:22:35 +02:00
a12c2fb57e # Propagation extension
* adds sso_identifier as new User model attribute
* refactors minor code snippets on user-propagation data resolving
* adds updating of username based on propagation data
* adds sso_identifier on admin backend view
2025-09-12 09:24:02 +02:00
23bc79ee3b Merge pull request '# Hotfix #480' (#481) from 480_API_error into master
Reviewed-on: #481
2025-08-18 08:46:47 +02:00
07bac26a58 # Hotfix #480
* (potentially) fixes a bug occuring on non multipolygon geometries processed in an api call
* simplifies casting into multipolygon
* simplifies casting into rlp srid (epsg:25832)
2025-08-18 08:46:21 +02:00
d01816cf71 Merge pull request '475_Wrong_uuid' (#476) from 475_Wrong_uuid into master
Reviewed-on: #476
2025-05-12 15:39:59 +02:00
f543dfc1cb # Issue 464
* updates DOP map layer to most recent DOP20
2025-05-12 15:26:47 +02:00
62fc019127 # Issue 475
* adds proper handling in case of BadRequest (error 400)
* enhances html template for error 500
* adds new html template for error 400
* adds uuid_required decorator to missing views
* updates translations
2025-05-12 15:22:43 +02:00
c01518b675 # CSS
* changes netgis map client menu background to matching color scheme for konova
2025-05-09 16:59:34 +02:00
f57306eb72 # New version
* adds the newest version of the netgis client
* updates config json to match new config syntax and make use of new features
2025-05-09 16:46:14 +02:00
c2b12649b0 Merge branch 'refs/heads/master' into netgis_map_client_update
# Conflicts:
#	templates/map/client/config.json
2025-05-09 16:03:35 +02:00
6fe67a8fbf Merge pull request '# HOTFIX' (#473) from hotfix into master
Reviewed-on: #473
2025-03-28 16:41:08 +01:00
b38a266bea # HOTFIX
* fixes bug where new wsg84 check on intersection microservice did not allow other spatial systems anymore
2025-03-28 16:40:50 +01:00
15f86e866b Merge pull request '# Map config' (#470) from map_config into master
Reviewed-on: #470
2025-02-14 15:32:47 +01:00
c85b136f0a # Map config
* adds latest map config to repository
2025-02-14 15:31:34 +01:00
faf8aed777 Merge pull request '# Drop django-simple-sso' (#468) from 467_Remove_django-simple-sso into master
Reviewed-on: #468
2025-01-24 16:12:06 +01:00
94c498866f # Drop django-simple-sso
* drops django-simple-sso package from project
* drops unused messenger.py
2025-01-24 16:11:23 +01:00
616965c890 Merge pull request 'bugfix' (#465) from bugfix into master
Reviewed-on: #465
2025-01-21 13:43:46 +01:00
e39c7eb51f # KSP Token optimization
* adds support for standardized bearer token usage instead of ksptoken/kspuser header usage (still supported)
2025-01-21 13:38:37 +01:00
19bd408fbd # Bugfix code update
* fixes bug where empty short names were not resolved properly
2025-01-21 12:52:46 +01:00
7bfe6a37f8 Merge pull request '# 456 Rework API key creation' (#462) from 456_Rework_API_key_creation into master
Reviewed-on: #462
2025-01-08 16:04:12 +01:00
9b63307f01 # 456 Rework API key creation
* removes frontend input field holding generated API key
* replaces with modal form
* reworks tests on API token form
2025-01-08 16:03:26 +01:00
123a470006 Merge pull request '# 457 User autocomplete fix' (#461) from 457_User_autocomplete_fix into master
Reviewed-on: #461
2025-01-08 14:36:01 +01:00
5a0c5285e7 # 457 User autocomplete fix
* fixes bug where empty query parameter would show users in autocomplete share view
* fixes same behaviour on autocomplete share team view
2025-01-08 14:35:35 +01:00
3a01eaff92 Merge pull request '# 450 Optimization recalculate_parcels command' (#460) from 450_Optimierung_Kommando_Nachverschneidung into master
Reviewed-on: #460
2025-01-08 14:27:55 +01:00
2af91aa178 # 450 Optimization recalculate_parcels command
* optimizes recalculate_parcels.py command so that only non-empty geometries will be processed
* drops test_identifier_generating.py command due to missing usage
2025-01-08 14:27:23 +01:00
53d0af89ac Merge pull request '# Hotfix' (#458) from oauth_fix into master
Reviewed-on: #458
2024-12-23 13:41:53 +01:00
7b5c1f0d97 # Hotfix
* fixes bug where anonymous user trying to logout would throw error
2024-12-23 13:41:25 +01:00
ef076c0b3b Merge pull request 'oauth_fix' (#453) from oauth_fix into master
Reviewed-on: #453
2024-12-23 12:09:20 +01:00
72a5075f3b # Update dependencies
* updates requirements.txt
2024-12-23 12:03:15 +01:00
d677ac6b5a # Map proxy enhancement
* adds whitelisting for map proxy hosts
2024-12-23 11:08:41 +01:00
9149e4cbd3 # Propagation improvement
* fixes documentation and variable names on oauth token revocation
* introduces private key for propagation
* changes key usage in decryption of propagated user data from oauth_client_id to private propagation key
2024-12-23 10:45:08 +01:00
1c24cbea26 # OAuth Token revocation
* adds revocation of user tokens on logout
2024-12-23 09:26:14 +01:00
mipel
bc9cc09372 # Config update
* updates config for newest netgis map client
2024-12-19 12:20:14 +01:00
24518465f3 # Improvement
* adds catch for undecodeable proxied content
2024-11-21 15:08:38 +01:00
457548da4d # Netgis client update
* integrates newest netgis map client
* generalizes map proxy response handling
2024-11-21 13:46:35 +01:00
fa89bbba99 Merge pull request '# Bugfix: Recalculate_parcels command' (#448) from bugfixing into master
Reviewed-on: #448
2024-11-13 16:09:22 +01:00
78eb711057 # Bugfix: Recalculate_parcels command
* fixes a bug on recalculate_parcels if not --force-all is used
2024-11-13 16:08:36 +01:00
6ff67d12c9 # WIP: Integration netgis client
* adds adjustments for integration of newest netgis client version (81fa3bef48)
2024-11-02 13:06:32 +01:00
3c1cbcd0bd # Netgis map update
* implements newest version of netgis map client
2024-10-30 14:09:10 +01:00
416ad8478c Merge pull request '439_Wartungskommando_Nachverschneidung' (#446) from 439_Wartungskommando_Nachverschneidung into master
Reviewed-on: #446
2024-10-26 10:24:50 +02:00
6b28c4ec15 # Drop atomic transaction
* drops atomic transaction processing on Parcel.make_unique
2024-10-26 10:24:10 +02:00
46a2a4ff46 # Parcel recalculation optimization
* enhances workflow for parcel recalculation
2024-10-26 10:17:09 +02:00
90e5cf5b36 Merge pull request '# Parcel duplicate repair' (#444) from 439_Wartungskommando_Nachverschneidung into master
Reviewed-on: #444
2024-10-26 09:48:32 +02:00
50f46e319c # Parcel duplicate repair
* adds mechanic to repair parcels in case of unwanted parcel duplicates
* optimizes filtering of geometries for parcel recalculation
2024-10-26 09:47:27 +02:00
e2ea087c4e Merge pull request '# Wartungskommando Optimization' (#442) from 439_Wartungskommando_Nachverschneidung into master
Reviewed-on: #442
2024-10-25 19:27:02 +02:00
a6e43b044b # Wartungskommando Optimization
* extends filtering for recalculatable geometries to records without started calculation at any point (parcel_update_start is null)
* catches exceptions on geometries which could not be recalculated properly, adds them to output for further analysis
* simplifies complexity factor calculation
2024-10-25 19:19:08 +02:00
be0d261e81 Merge pull request '# 439 Wartungskommando Nachverschneidung' (#440) from 439_Wartungskommando_Nachverschneidung into master
Reviewed-on: #440
2024-10-25 14:24:18 +02:00
62e1b046c3 # 439 Wartungskommando Nachverschneidung
* refactors command update_all_parcels into recalculate_parcels
* fixes bug in command generate_report
2024-10-25 14:23:21 +02:00
669a12410f Merge pull request 'missing_migrations' (#437) from missing_migrations into master
Reviewed-on: #437
2024-08-26 18:57:10 +02:00
dd77e6c16e Merge branch 'refs/heads/master' into missing_migrations 2024-08-26 18:53:11 +02:00
33774ce557 # Migrations
* adds missing migrations
* renames variables shadowing in-builts
2024-08-26 18:51:58 +02:00
dc3dc99b3d Merge pull request '# User filtering' (#435) from 433_Filter_by_user into master
Reviewed-on: #435
2024-08-19 11:42:18 +02:00
315f9de958 # User filtering
* adds query filter to search for logged users on entries
2024-08-19 11:38:09 +02:00
0726c15086 Merge pull request '432_Unreadable_payments' (#434) from 432_Unreadable_payments into master
Reviewed-on: #434
2024-08-19 10:26:40 +02:00
2492a8abe8 # Codelist migration optimization
* adds boolean to de-/activate migration logic inside of 0002_migrate_975_to_288.py
2024-08-19 10:23:05 +02:00
dbc5cba5d7 # Variable refactoring
* renames variable `has_access` into `is_entry_shared` for better understanding in various places (mostly html related)
2024-08-19 09:44:45 +02:00
c8948ddaea # Censor payments
* censor payments if entry is not shared with user
* updates translations
2024-08-19 09:39:58 +02:00
5039da28aa Merge pull request '# Hotfix' (#430) from 427_Integration_of_codelist_288 into master
Reviewed-on: #430
2024-08-07 12:07:04 +02:00
4567339570 # Hotfix
* fixes requirements dependency
2024-08-07 12:06:27 +02:00
768849e646 Merge pull request '427_Integration_of_codelist_288' (#428) from 427_Integration_of_codelist_288 into master
Reviewed-on: #428
2024-08-07 12:01:46 +02:00
ebf10645fc # Requirements update
* updates some packages in requirements.txt
2024-08-07 09:17:20 +02:00
df241747cf # Migration list 975->288
* adds migration for app codelist to migrate existing biotope type details codes from list 975 to 288 depending on their atomID
* improves rendering of action and biotope type details on frontend for KOM, OEK and EMA
* refactors KonovaCode str() rendering
2024-08-07 09:12:38 +02:00
94e9035e10 # Codelist 288
* introduces 288 to codelist/settings.py
* refactors usage from 975 to 288
* enhances rendering of codelist names depending on which name exists (short vs long)
2024-08-06 15:39:01 +02:00
116 changed files with 3815 additions and 1423 deletions

View File

@@ -24,6 +24,7 @@ DEFAULT_FROM_EMAIL=service@ksp.de
# Proxy
PROXY=CHANGE_ME
MAP_PROXY_HOST_WHITELIST=CHANGE_ME_1,CHANGE_ME_2
GEOPORTAL_RLP_USER=CHANGE_ME
GEOPORTAL_RLP_PASSWORD=CHANGE_ME
@@ -37,6 +38,7 @@ SSO_SERVER_BASE_URL=https://login.naturschutz.rlp.de
OAUTH_CODE_VERIFIER=CHANGE_ME
OAUTH_CLIENT_ID=CHANGE_ME
OAUTH_CLIENT_SECRET=CHANGE_ME
PROPAGATION_SECRET=CHANGE_ME
# RabbitMQ
## For connections to EGON

View File

@@ -51,7 +51,7 @@ class APIUserToken(models.Model):
if token_obj.valid_until is not None and token_obj.valid_until < _today:
raise PermissionError("Token validity expired")
except ObjectDoesNotExist:
raise PermissionError("Credentials invalid")
raise PermissionError("Token unknown")
return token_obj.user
@@ -155,3 +155,25 @@ class OAuthToken(UuidModel):
return user
def revoke(self) -> int:
""" Revokes the OAuth2 token of the user
(/o/revoke_token/ indeed removes the corresponding access token on provider side and invalidates the
submitted refresh token in one step)
Returns:
revocation_status_code (int): HTTP status code for revocation of refresh_token
"""
revoke_url = f"{SSO_SERVER_BASE}o/revoke_token/"
token = self.refresh_token
revocation_status_code = requests.post(
revoke_url,
data={
'token': token,
'token_type_hint': "refresh_token",
},
auth=(OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET),
).status_code
return revocation_status_code

View File

@@ -12,7 +12,7 @@ from django.contrib.gis import geos
from django.urls import reverse
from api.tests.v1.share.test_api_sharing import BaseAPIV1TestCase
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
from konova.models import Geometry
class APIV1UpdateTestCase(BaseAPIV1TestCase):
@@ -64,7 +64,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body))
put_geom.transform(DEFAULT_SRID_RLP)
put_geom = Geometry.cast_to_rlp_srid(put_geom)
self.assertEqual(put_geom, self.intervention.geometry.geom)
self.assertEqual(put_props["title"], self.intervention.title)
self.assertNotEqual(modified_on, self.intervention.modified)
@@ -94,7 +94,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body))
put_geom.transform(DEFAULT_SRID_RLP)
put_geom = Geometry.cast_to_rlp_srid(put_geom)
self.assertEqual(put_geom, self.compensation.geometry.geom)
self.assertEqual(put_props["title"], self.compensation.title)
self.assertNotEqual(modified_on, self.compensation.modified)
@@ -124,7 +124,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body))
put_geom.transform(DEFAULT_SRID_RLP)
put_geom = Geometry.cast_to_rlp_srid(put_geom)
self.assertEqual(put_geom, self.eco_account.geometry.geom)
self.assertEqual(put_props["title"], self.eco_account.title)
self.assertNotEqual(modified_on, self.eco_account.modified)
@@ -156,7 +156,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body))
put_geom.transform(DEFAULT_SRID_RLP)
put_geom = Geometry.cast_to_rlp_srid(put_geom)
self.assertEqual(put_geom, self.ema.geometry.geom)
self.assertEqual(put_props["title"], self.ema.title)
self.assertNotEqual(modified_on, self.ema.modified)

View File

@@ -13,7 +13,7 @@ from django.contrib.gis.geos import GEOSGeometry
from django.core.paginator import Paginator
from django.db.models import Q
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
from konova.models import Geometry
from konova.utils.message_templates import DATA_UNSHARED
@@ -145,8 +145,8 @@ class AbstractModelAPISerializer:
if isinstance(geojson, dict):
geojson = json.dumps(geojson)
geometry = geos.fromstr(geojson)
if geometry.srid != DEFAULT_SRID_RLP:
geometry.transform(DEFAULT_SRID_RLP)
geometry = Geometry.cast_to_rlp_srid(geometry)
geometry = Geometry.cast_to_multipolygon(geometry)
return geometry
def _get_obj_from_db(self, id, user):

View File

@@ -16,7 +16,8 @@ from api.utils.serializer.serializer import AbstractModelAPISerializer
from codelist.models import KonovaCode
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, CODELIST_PROCESS_TYPE_ID, \
CODELIST_LAW_ID, CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, \
CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, CODELIST_HANDLER_ID
CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_HANDLER_ID, \
CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID
from compensation.models import CompensationAction, UnitChoices, CompensationState
from intervention.models import Responsibility, Legal, Handler
from konova.models import Deadline, DeadlineType
@@ -347,7 +348,7 @@ class AbstractCompensationAPISerializerV1Mixin:
try:
biotope_type = entry["biotope"]
biotope_details = [
self._konova_code_from_json(e, CODELIST_BIOTOPES_EXTRA_CODES_ID) for e in entry["biotope_details"]
self._konova_code_from_json(e, CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID) for e in entry["biotope_details"]
]
surface = float(entry["surface"])
except KeyError:

View File

@@ -50,14 +50,19 @@ class AbstractAPIView(View):
def dispatch(self, request, *args, **kwargs):
try:
# Fetch the proper user from the given request header token
ksp_token = request.headers.get(KSP_TOKEN_HEADER_IDENTIFIER, None)
token = request.headers.get(KSP_TOKEN_HEADER_IDENTIFIER, None)
ksp_user = request.headers.get(KSP_USER_HEADER_IDENTIFIER, None)
token_user = APIUserToken.get_user_from_token(ksp_token)
if ksp_user != token_user.username:
if not token and not ksp_user:
bearer_token = request.headers.get("authorization", None)
if not bearer_token:
raise PermissionError("No token provided")
token = bearer_token.split(" ")[1]
token_user = APIUserToken.get_user_from_token(token)
if ksp_user and ksp_user != token_user.username:
raise PermissionError(f"Invalid token for {ksp_user}")
else:
self.user = token_user
self.user = token_user
request.user = self.user
if not self.user.is_default_user():

View File

@@ -9,7 +9,8 @@ import collections
from django.core.exceptions import ImproperlyConfigured
from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID
from codelist.settings import CODELIST_BIOTOPES_ID, \
CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID
from codelist.autocomplete.base import KonovaCodeAutocomplete
from konova.utils.message_templates import UNGROUPED
@@ -84,11 +85,11 @@ class BiotopeExtraCodeAutocomplete(KonovaCodeAutocomplete):
Due to limitations of the django dal package, we need to subclass for each code list
"""
group_by_related = "parent"
related_field_name = "long_name"
related_field_name = "short_name"
paginate_by = 200
def __init__(self, *args, **kwargs):
self.c = CODELIST_BIOTOPES_EXTRA_CODES_ID
self.c = CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID
super().__init__(*args, **kwargs)
def order_by(self, qs):
@@ -103,8 +104,11 @@ class BiotopeExtraCodeAutocomplete(KonovaCodeAutocomplete):
qs (QuerySet): The ordered queryset
"""
return qs.order_by(
"long_name",
"short_name",
)
def get_result_label(self, result):
return f"{result.long_name} ({result.short_name})"
def get_selected_result_label(self, result):
return f"{result.parent.short_name} > {result.long_name} ({result.short_name})"

View File

@@ -13,7 +13,7 @@ from codelist.settings import CODELIST_INTERVENTION_HANDLER_ID, CODELIST_CONSERV
CODELIST_REGISTRATION_OFFICE_ID, CODELIST_BIOTOPES_ID, CODELIST_LAW_ID, CODELIST_HANDLER_ID, \
CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, \
CODELIST_BASE_URL, CODELIST_PROCESS_TYPE_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, \
CODELIST_COMPENSATION_ACTION_DETAIL_ID
CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID
from konova.management.commands.setup import BaseKonovaCommand
from konova.settings import PROXIES
@@ -34,6 +34,7 @@ class Command(BaseKonovaCommand):
CODELIST_REGISTRATION_OFFICE_ID,
CODELIST_BIOTOPES_ID,
CODELIST_BIOTOPES_EXTRA_CODES_ID,
CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID,
CODELIST_LAW_ID,
CODELIST_HANDLER_ID,
CODELIST_COMPENSATION_ACTION_ID,
@@ -55,7 +56,7 @@ class Command(BaseKonovaCommand):
content = result.content.decode("utf-8")
root = etree.fromstring(content)
items = root.findall("item")
self._write_warning("Found {} codes. Process now...".format(len(items)))
self._write_warning(" Found {} codes. Process now...".format(len(items)))
code_list = KonovaCodeList.objects.get_or_create(
id=list_id,
@@ -74,15 +75,15 @@ class Command(BaseKonovaCommand):
if items is None:
return
else:
self._write_warning(" --- Found {} subcodes. Process now...".format(len(items)))
self._write_warning(" --- Found {} subcodes. Process now...".format(len(items)))
for element in items:
children = element.find("items")
_id = element.find("id").text
atom_id = element.find("atomid").text
selectable = element.find("selectable").text.lower()
selectable = bool_map.get(selectable, False)
short_name = element.find("shortname").text
long_name = element.find("longname").text
short_name = element.find("shortname").text or ""
long_name = element.find("longname").text or ""
is_archived = bool_map.get((element.find("archive").text.lower()), False)
code = KonovaCode.objects.get_or_create(

View File

@@ -0,0 +1,60 @@
# Generated by Django 5.0.7 on 2024-08-06 13:40
from django.core.exceptions import ObjectDoesNotExist
from django.db import migrations
from django.db.models import Q
from codelist.settings import CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID
def migrate_975_to_288(apps, schema_editor):
KonovaCodeList = apps.get_model('codelist', 'KonovaCodeList')
CompensationState = apps.get_model('compensation', 'CompensationState')
try:
list_288 = KonovaCodeList.objects.get(
id=CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID
).codes.all()
except ObjectDoesNotExist:
raise AssertionError("KonovaCodeList 288 does not exist. Did you run 'update_codelist' before migrating?")
states_with_extra_code = CompensationState.objects.filter(
~Q(biotope_type_details=None)
)
print(f"... Found {states_with_extra_code.count()} biotope state entries")
for state in states_with_extra_code:
extra_codes_975 = state.biotope_type_details.filter(
code_lists__in=[CODELIST_BIOTOPES_EXTRA_CODES_ID]
)
count_extra_codes_975 = extra_codes_975.count()
if count_extra_codes_975 > 0:
print(f" --> Found {count_extra_codes_975} codes from list 975 in biotope entry {state.id}")
extra_codes_288 = []
for extra_code_975 in extra_codes_975:
atom_id = extra_code_975.atom_id
codes_from_288 = list_288.filter(
atom_id=atom_id,
)
extra_codes_288 += codes_from_288
state.biotope_type_details.set(extra_codes_288)
print(" --> Migrated to list 288 for all biotope entries")
class Migration(migrations.Migration):
dependencies = [
('codelist', '0001_initial'),
('compensation', '0003_auto_20220202_0846'),
]
# If migration of codelist is not necessary, this variable can shut down the logic whilst not disturbing the
# migration history
EXECUTE_CODELIST_MIGRATION = True
operations = []
if EXECUTE_CODELIST_MIGRATION:
operations.append(migrations.RunPython(migrate_975_to_288))

View File

@@ -0,0 +1,25 @@
# Generated by Django 5.0.8 on 2024-08-26 16:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('codelist', '0002_migrate_975_to_288'),
]
operations = [
migrations.AlterField(
model_name='konovacode',
name='long_name',
field=models.CharField(blank=True, default="", max_length=1000),
preserve_default=False,
),
migrations.AlterField(
model_name='konovacode',
name='short_name',
field=models.CharField(blank=True, default="", help_text='Short version of long name', max_length=500),
preserve_default=False,
),
]

View File

@@ -25,13 +25,11 @@ class KonovaCode(models.Model):
)
short_name = models.CharField(
max_length=500,
null=True,
blank=True,
help_text="Short version of long name",
)
long_name = models.CharField(
max_length=1000,
null=True,
blank=True,
help_text="",
)
@@ -50,12 +48,28 @@ class KonovaCode(models.Model):
def __str__(self, with_parent: bool = True):
ret_val = ""
if self.parent and self.parent.long_name and with_parent:
ret_val += self.parent.long_name + " > "
ret_val += self.long_name
if self.short_name and self.short_name != self.long_name:
# Only add short name, if we won't have stupid repition like 'thing a (thing a)' due to misused long-short names
ret_val += f" ({self.short_name})"
long_name = self.long_name
short_name = self.short_name
both_names_exist = long_name is not None and short_name is not None
if both_names_exist:
if with_parent and self.parent:
parent_short_name_exists = self.parent.short_name is not None
parent_long_name_exists = self.parent.long_name is not None
if parent_long_name_exists:
ret_val += self.parent.long_name + " > "
elif parent_short_name_exists:
ret_val += self.parent.short_name + " > "
ret_val += long_name
if short_name and short_name != long_name:
ret_val += f" ({short_name})"
else:
ret_val += str(long_name or short_name)
return ret_val
@property

View File

@@ -15,7 +15,8 @@ CODELIST_CONSERVATION_OFFICE_ID = 907 # CLNaturschutzbehörden
CODELIST_REGISTRATION_OFFICE_ID = 1053 # CLZulassungsbehörden
CODELIST_BIOTOPES_ID = 654 # CL_Biotoptypen
CODELIST_AFTER_STATE_BIOTOPES_ID = 974 # CL-KSP_ZielBiotoptypen - USAGE HAS BEEN DROPPED IN 2022 IN FAVOR OF 654
CODELIST_BIOTOPES_EXTRA_CODES_ID = 975 # CLZusatzbezeichnung
CODELIST_BIOTOPES_EXTRA_CODES_ID = 975 # CLZusatzbezeichnung - Subset of 288. Migration usage 975->288 in 08/2024
CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID = 288 # CLBiotoptypZusatzcode
CODELIST_LAW_ID = 1048 # CLVerfahrensrecht
CODELIST_PROCESS_TYPE_ID = 44382 # CLVerfahrenstyp

View File

@@ -14,7 +14,8 @@ from django.shortcuts import render
from django.utils.translation import gettext_lazy as _
from codelist.models import KonovaCode
from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID
from codelist.settings import CODELIST_BIOTOPES_ID, \
CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID
from intervention.inputs import CompensationStateTreeRadioSelect
from konova.contexts import BaseContext
from konova.forms.modals import RemoveModalForm, BaseModalForm
@@ -43,7 +44,7 @@ class NewCompensationStateModalForm(BaseModalForm):
queryset=KonovaCode.objects.filter(
is_archived=False,
is_leaf=True,
code_lists__in=[CODELIST_BIOTOPES_EXTRA_CODES_ID],
code_lists__in=[CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID],
),
widget=autocomplete.ModelSelect2Multiple(
url="codelist:biotope-extra-type-autocomplete",

View File

@@ -0,0 +1,19 @@
# Generated by Django 5.0.8 on 2024-08-26 16:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('codelist', '0003_alter_konovacode_long_name_and_more'),
('compensation', '0015_alter_compensation_after_states_and_more'),
]
operations = [
migrations.AlterField(
model_name='compensationstate',
name='biotope_type_details',
field=models.ManyToManyField(blank=True, limit_choices_to={'code_lists__in': [288], 'is_archived': False, 'is_selectable': True}, related_name='+', to='codelist.konovacode'),
),
]

View File

@@ -6,10 +6,10 @@ Created on: 16.11.21
"""
from django.db import models
from django.db.models import Q
from codelist.models import KonovaCode
from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID
from codelist.settings import CODELIST_BIOTOPES_ID, \
CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID
from compensation.managers import CompensationStateManager
from konova.models import UuidModel
@@ -34,7 +34,7 @@ class CompensationState(UuidModel):
KonovaCode,
blank=True,
limit_choices_to={
"code_lists__in": [CODELIST_BIOTOPES_EXTRA_CODES_ID],
"code_lists__in": [CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID],
"is_selectable": True,
"is_archived": False,
},

View File

@@ -11,7 +11,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:new-action' obj.id %}" title="{% trans 'Add new action' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'seedling' %}
@@ -34,7 +34,7 @@
<th scope="col">
{% trans 'Comment' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -52,7 +52,7 @@
<hr>
{% endfor %}
{% for detail in action.action_type_details.all %}
<span class="badge badge-pill rlp-r" title="{{detail}}">{{detail.long_name}}</span>
<span class="badge badge-pill rlp-r" title="{{ detail.parent.long_name }} > {{detail}}">{{ detail.parent.long_name }} > {{detail.long_name}}</span>
{% empty %}
<span class="badge badge-pill rlp-r-outline" title="{% trans 'No action type details' %}">{% trans 'No action type details' %}</span>
{% endfor %}
@@ -64,7 +64,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:action-edit' obj.id action.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit action' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -11,7 +11,7 @@
{% fa5_icon 'file-alt' %}
</button>
</a>
{% if has_access %}
{% if is_entry_shared %}
<button class="btn btn-default btn-modal mr-2" title="{% trans 'Resubmission' %}" data-form-url="{% url 'compensation:resubmission-create' obj.id %}">
{% fa5_icon 'bell' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:new-deadline' obj.id %}" title="{% trans 'Add new deadline' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'calendar-check' %}
@@ -38,7 +38,7 @@
<th scope="col">
{% trans 'Comment' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -60,7 +60,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:deadline-edit' obj.id deadline.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit deadline' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:new-doc' obj.id %}" title="{% trans 'Add new document' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'file' %}
@@ -33,7 +33,7 @@
<th scope="col">
{% trans 'Comment' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -59,7 +59,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:edit-doc' obj.id doc.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit document' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:new-state' obj.id %}" title="{% trans 'Add new state after' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'layer-group' %}
@@ -35,7 +35,7 @@
<th scope="col">
{% trans 'Surface' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -51,14 +51,14 @@
<span>{{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})</span>
<br>
{% for detail in state.biotope_type_details.all %}
<span class="badge badge-pill rlp-r" title="{{detail}}">{{detail.long_name}}</span>
<span class="badge badge-pill rlp-r" title="{{ detail.parent.short_name }} > {{detail}}">{{ detail.parent.short_name }} > {{ detail.long_name }}</span>
{% empty %}
<span class="badge badge-pill rlp-r-outline" title="{% trans 'No biotope type details' %}">{% trans 'No biotope type details' %}</span>
{% endfor %}
</td>
<td>{{ state.surface|floatformat:2 }} m²</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:state-edit' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit state' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:new-state' obj.id %}?before=true" title="{% trans 'Add new state before' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'layer-group' %}
@@ -35,7 +35,7 @@
<th scope="col">
{% trans 'Surface' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -51,14 +51,14 @@
<span>{{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})</span>
<br>
{% for detail in state.biotope_type_details.all %}
<span class="badge badge-pill rlp-r" title="{{detail}}">{{detail.long_name}}</span>
<span class="badge badge-pill rlp-r" title="{{ detail.parent.short_name }} > {{detail}}">{{ detail.parent.short_name }} > {{ detail.long_name }}</span>
{% empty %}
<span class="badge badge-pill rlp-r-outline" title="{% trans 'No biotope type details' %}">{% trans 'No biotope type details' %}</span>
{% endfor %}
</td>
<td>{{ state.surface|floatformat:2 }} m²</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:state-edit' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit state' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -123,7 +123,7 @@
{% include 'user/includes/team_data_modal_button.html' %}
{% endfor %}
<hr>
{% if has_access %}
{% if is_entry_shared %}
{% for user in obj.intervention.shared_users %}
{% include 'user/includes/contact_modal_button.html' %}
{% endfor %}

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc:new-action' obj.id %}" title="{% trans 'Add new action' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'seedling' %}
@@ -33,7 +33,7 @@
<th scope="col">
{% trans 'Comment' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -51,7 +51,7 @@
<hr>
{% endfor %}
{% for detail in action.action_type_details.all %}
<span class="badge badge-pill rlp-r" title="{{detail}}">{{detail.long_name}}</span>
<span class="badge badge-pill rlp-r" title="{{ detail.parent.long_name }} > {{detail}}">{{ detail.parent.long_name }} > {{detail.long_name}}</span>
{% empty %}
<span class="badge badge-pill rlp-r-outline" title="{% trans 'No action type details' %}">{% trans 'No action type details' %}</span>
{% endfor %}
@@ -63,7 +63,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:acc:action-edit' obj.id action.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit action' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -11,7 +11,7 @@
{% fa5_icon 'file-alt' %}
</button>
</a>
{% if has_access %}
{% if is_entry_shared %}
<button class="btn btn-default btn-modal mr-2" title="{% trans 'Resubmission' %}" data-form-url="{% url 'compensation:acc:resubmission-create' obj.id %}">
{% fa5_icon 'bell' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc:new-deadline' obj.id %}" title="{% trans 'Add new deadline' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'calendar-check' %}
@@ -58,7 +58,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:acc:deadline-edit' obj.id deadline.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit deadline' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -61,7 +61,7 @@
<td class="align-middle">{{ deduction.surface|floatformat:2|intcomma }} m²</td>
<td class="align-middle">{{ deduction.created.timestamp|default_if_none:""|naturalday}}</td>
<td class="align-middle float-right">
{% if is_default_member and has_access or is_default_member and user in deduction.intervention.shared_users %}
{% if is_default_member and is_entry_shared or is_default_member and user in deduction.intervention.shared_users %}
<button data-form-url="{% url 'compensation:acc:edit-deduction' deduction.account.id deduction.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit Deduction' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc:new-doc' obj.id %}" title="{% trans 'Add new document' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'file' %}
@@ -57,7 +57,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:acc:edit-doc' obj.id doc.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit document' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc:new-state' obj.id %}" title="{% trans 'Add new state after' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'layer-group' %}
@@ -35,7 +35,7 @@
<th scope="col">
{% trans 'Surface' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -51,14 +51,14 @@
<span>{{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})</span>
<br>
{% for detail in state.biotope_type_details.all %}
<span class="badge badge-pill rlp-r" title="{{detail}}">{{detail.long_name}}</span>
<span class="badge badge-pill rlp-r" title="{{ detail.parent.short_name }} > {{detail}}">{{ detail.parent.short_name }} > {{ detail.long_name }}</span>
{% empty %}
<span class="badge badge-pill rlp-r-outline" title="{% trans 'No biotope type details' %}">{% trans 'No biotope type details' %}</span>
{% endfor %}
</td>
<td>{{ state.surface|floatformat:2 }} m²</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:acc:state-edit' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit state' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc:new-state' obj.id %}?before=true" title="{% trans 'Add new state before' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'layer-group' %}
@@ -35,7 +35,7 @@
<th scope="col">
{% trans 'Surface' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -51,14 +51,14 @@
<span>{{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})</span>
<br>
{% for detail in state.biotope_type_details.all %}
<span class="badge badge-pill rlp-r" title="{{detail}}">{{detail.long_name}}</span>
<span class="badge badge-pill rlp-r" title="{{ detail.parent.short_name }} > {{detail}}">{{ detail.parent.short_name }} > {{ detail.long_name }}</span>
{% empty %}
<span class="badge badge-pill rlp-r-outline" title="{% trans 'No biotope type details' %}">{% trans 'No biotope type details' %}</span>
{% endfor %}
</td>
<td>{{ state.surface|floatformat:2 }} m²</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:acc:state-edit' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit state' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -101,7 +101,7 @@
{% include 'user/includes/team_data_modal_button.html' %}
{% endfor %}
<hr>
{% if has_access %}
{% if is_entry_shared %}
{% for user in obj.users.all %}
{% include 'user/includes/contact_modal_button.html' %}
{% endfor %}

View File

@@ -54,7 +54,7 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
post_data = {
"identifier": test_id,
"title": test_title,
"geom": geom_json,
"output": geom_json,
"intervention": self.intervention.id,
}
pre_creation_intervention_log_count = self.intervention.log.count()
@@ -94,7 +94,7 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
post_data = {
"identifier": test_id,
"title": test_title,
"geom": geom_json,
"output": geom_json,
}
pre_creation_intervention_log_count = self.intervention.log.count()
@@ -150,7 +150,7 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
"title": new_title,
"intervention": self.intervention.id, # just keep the intervention as it is
"comment": new_comment,
"geom": geojson,
"output": geojson,
}
self.client_user.post(url, post_data)
self.compensation.refresh_from_db()

View File

@@ -46,7 +46,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
post_data = {
"identifier": test_id,
"title": test_title,
"geom": geom_json,
"output": geom_json,
"surface": test_deductable_surface,
"conservation_office": test_conservation_office.id
}
@@ -86,7 +86,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
new_title = self.create_dummy_string()
new_identifier = self.create_dummy_string()
new_comment = self.create_dummy_string()
new_geometry = MultiPolygon(srid=4326) # Create an empty geometry
new_geometry = self.create_dummy_geometry()
test_conservation_office = self.get_conservation_office_code()
test_deductable_surface = self.eco_account.deductable_surface + 100
@@ -103,7 +103,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
"identifier": new_identifier,
"title": new_title,
"comment": new_comment,
"geom": new_geometry.geojson,
"output": self.create_geojson(new_geometry),
"surface": test_deductable_surface,
"conservation_office": test_conservation_office.id
}

View File

@@ -27,7 +27,7 @@ from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE, DATA_CHECKED_PREVIOUSLY_TEMPLATE, \
RECORDED_BLOCKS_EDIT, CHECK_STATE_RESET, FORM_INVALID, PARAMS_INVALID, IDENTIFIER_REPLACED, \
COMPENSATION_ADDED_TEMPLATE, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED
COMPENSATION_ADDED_TEMPLATE, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE
@login_required
@@ -103,11 +103,19 @@ def new_view(request: HttpRequest, intervention_id: str = None):
)
)
messages.success(request, COMPENSATION_ADDED_TEMPLATE.format(comp.identifier))
if geom_form.geometry_simplified:
if geom_form.has_geometry_simplified():
messages.info(
request,
GEOMETRY_SIMPLIFIED
)
num_ignored_geometries = geom_form.get_num_geometries_ignored()
if num_ignored_geometries > 0:
messages.info(
request,
GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
)
return redirect("compensation:detail", id=comp.id)
else:
messages.error(request, FORM_INVALID, extra_tags="danger",)
@@ -179,11 +187,19 @@ def edit_view(request: HttpRequest, id: str):
if intervention_is_checked:
messages.info(request, CHECK_STATE_RESET)
messages.success(request, _("Compensation {} edited").format(comp.identifier))
if geom_form.geometry_simplified:
if geom_form.has_geometry_simplified():
messages.info(
request,
GEOMETRY_SIMPLIFIED
)
num_ignored_geometries = geom_form.get_num_geometries_ignored()
if num_ignored_geometries > 0:
messages.info(
request,
GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
)
return redirect("compensation:detail", id=comp.id)
else:
messages.error(request, FORM_INVALID, extra_tags="danger",)
@@ -259,7 +275,7 @@ def detail_view(request: HttpRequest, id: str):
"last_checked_tooltip": last_checked_tooltip,
"geom_form": geom_form,
"parcels": parcels,
"has_access": is_data_shared,
"is_entry_shared": is_data_shared,
"actions": actions,
"before_states": before_states,
"after_states": after_states,

View File

@@ -12,11 +12,12 @@ from django.utils.translation import gettext_lazy as _
from compensation.models import Compensation
from konova.contexts import BaseContext
from konova.decorators import uuid_required
from konova.forms import SimpleGeomForm
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.generators import generate_qr_code
@uuid_required
def report_view(request: HttpRequest, id: str):
""" Renders the public report view
@@ -67,7 +68,7 @@ def report_view(request: HttpRequest, id: str):
"img": qrcode_img_lanis,
"url": qrcode_lanis_url,
},
"has_access": False, # disables action buttons during rendering
"is_entry_shared": False, # disables action buttons during rendering
"before_states": before_states,
"after_states": after_states,
"geom_form": geom_form,

View File

@@ -23,7 +23,7 @@ from konova.forms import SimpleGeomForm
from konova.settings import ETS_GROUP, DEFAULT_GROUP, ZB_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import CANCEL_ACC_RECORDED_OR_DEDUCTED, RECORDED_BLOCKS_EDIT, FORM_INVALID, \
IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED
IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE
@login_required
@@ -84,11 +84,19 @@ def new_view(request: HttpRequest):
)
)
messages.success(request, _("Eco-Account {} added").format(acc.identifier))
if geom_form.geometry_simplified:
if geom_form.has_geometry_simplified():
messages.info(
request,
GEOMETRY_SIMPLIFIED
)
num_ignored_geometries = geom_form.get_num_geometries_ignored()
if num_ignored_geometries > 0:
messages.info(
request,
GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
)
return redirect("compensation:acc:detail", id=acc.id)
else:
messages.error(request, FORM_INVALID, extra_tags="danger",)
@@ -156,11 +164,19 @@ def edit_view(request: HttpRequest, id: str):
# The data form takes the geom form for processing, as well as the performing user
acc = data_form.save(request.user, geom_form)
messages.success(request, _("Eco-Account {} edited").format(acc.identifier))
if geom_form.geometry_simplified:
if geom_form.has_geometry_simplified():
messages.info(
request,
GEOMETRY_SIMPLIFIED
)
num_ignored_geometries = geom_form.get_num_geometries_ignored()
if num_ignored_geometries > 0:
messages.info(
request,
GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
)
return redirect("compensation:acc:detail", id=acc.id)
else:
messages.error(request, FORM_INVALID, extra_tags="danger",)
@@ -237,7 +253,7 @@ def detail_view(request: HttpRequest, id: str):
"obj": acc,
"geom_form": geom_form,
"parcels": parcels,
"has_access": is_data_shared,
"is_entry_shared": is_data_shared,
"before_states": before_states,
"after_states": after_states,
"sum_before_states": sum_before_states,

View File

@@ -12,11 +12,13 @@ from django.utils.translation import gettext_lazy as _
from compensation.models import EcoAccount
from konova.contexts import BaseContext
from konova.decorators import uuid_required
from konova.forms import SimpleGeomForm
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.generators import generate_qr_code
@uuid_required
def report_view(request: HttpRequest, id: str):
""" Renders the public report view
@@ -73,7 +75,7 @@ def report_view(request: HttpRequest, id: str):
"img": qrcode_img_lanis,
"url": qrcode_lanis_url,
},
"has_access": False, # disables action buttons during rendering
"is_entry_shared": False, # disables action buttons during rendering
"before_states": before_states,
"after_states": after_states,
"geom_form": geom_form,

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'ema:new-action' obj.id %}" title="{% trans 'Add new action' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'seedling' %}
@@ -49,7 +49,7 @@
<hr>
{% endfor %}
{% for detail in action.action_type_details.all %}
<span class="badge badge-pill rlp-r" title="{{detail}}">{{detail.long_name}}</span>
<span class="badge badge-pill rlp-r" title="{{ detail.parent.long_name }} > {{detail}}">{{ detail.parent.long_name }} > {{detail.long_name}}</span>
{% empty %}
<span class="badge badge-pill rlp-r-outline" title="{% trans 'No action type details' %}">{% trans 'No action type details' %}</span>
{% endfor %}
@@ -61,7 +61,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'ema:action-edit' obj.id action.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit action' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -11,7 +11,7 @@
{% fa5_icon 'file-alt' %}
</button>
</a>
{% if has_access %}
{% if is_entry_shared %}
<button class="btn btn-default btn-modal mr-2" title="{% trans 'Resubmission' %}" data-form-url="{% url 'ema:resubmission-create' obj.id %}">
{% fa5_icon 'bell' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'ema:new-deadline' obj.id %}" title="{% trans 'Add new deadline' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'calendar-check' %}
@@ -58,7 +58,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'ema:deadline-edit' obj.id deadline.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit deadline' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'ema:new-doc' obj.id %}" title="{% trans 'Add new document' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'file' %}
@@ -57,7 +57,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'ema:edit-doc' obj.id doc.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit document' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'ema:new-state' obj.id %}" title="{% trans 'Add new state after' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'layer-group' %}
@@ -49,14 +49,14 @@
<span>{{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})</span>
<br>
{% for detail in state.biotope_type_details.all %}
<span class="badge badge-pill rlp-r" title="{{detail}}">{{detail.long_name}}</span>
<span class="badge badge-pill rlp-r" title="{{ detail.parent.short_name }} > {{detail}}">{{ detail.parent.short_name }} > {{ detail.long_name }}</span>
{% empty %}
<span class="badge badge-pill rlp-r-outline" title="{% trans 'No biotope type details' %}">{% trans 'No biotope type details' %}</span>
{% endfor %}
</td>
<td>{{ state.surface|floatformat:2 }} m²</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'ema:state-edit' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit state' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'ema:new-state' obj.id %}?before=true" title="{% trans 'Add new state before' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'layer-group' %}
@@ -49,14 +49,14 @@
<span>{{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})</span>
<br>
{% for detail in state.biotope_type_details.all %}
<span class="badge badge-pill rlp-r" title="{{detail}}">{{detail.long_name}}</span>
<span class="badge badge-pill rlp-r" title="{{ detail.parent.short_name }} > {{detail}}">{{ detail.parent.short_name }} > {{ detail.long_name }}</span>
{% empty %}
<span class="badge badge-pill rlp-r-outline" title="{% trans 'No biotope type details' %}">{% trans 'No biotope type details' %}</span>
{% endfor %}
</td>
<td>{{ state.surface|floatformat:2 }} m²</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'ema:state-edit' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit state' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -87,7 +87,7 @@
{% include 'user/includes/team_data_modal_button.html' %}
{% endfor %}
<hr>
{% if has_access %}
{% if is_entry_shared %}
{% for user in obj.users.all %}
{% include 'user/includes/contact_modal_button.html' %}
{% endfor %}

View File

@@ -46,7 +46,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
post_data = {
"identifier": test_id,
"title": test_title,
"geom": geom_json,
"output": geom_json,
"conservation_office": test_conservation_office.id
}
self.client_user.post(new_url, post_data)
@@ -84,7 +84,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
new_title = self.create_dummy_string()
new_identifier = self.create_dummy_string()
new_comment = self.create_dummy_string()
new_geometry = MultiPolygon(srid=4326) # Create an empty geometry
new_geometry = self.create_dummy_geometry() # Create an empty geometry
test_conservation_office = self.get_conservation_office_code()
check_on_elements = {
@@ -99,7 +99,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
"identifier": new_identifier,
"title": new_title,
"comment": new_comment,
"geom": new_geometry.geojson,
"output": self.create_geojson(new_geometry),
"conservation_office": test_conservation_office.id
}
self.client_user.post(url, post_data)

View File

@@ -48,7 +48,7 @@ class NewEmaFormTestCase(BaseTestCase):
)
geom_form_data = json.loads(geom_form_data)
geom_form_data = {
"geom": json.dumps(geom_form_data)
"output": json.dumps(geom_form_data)
}
geom_form = SimpleGeomForm(geom_form_data)
@@ -116,7 +116,7 @@ class EditEmaFormTestCase(BaseTestCase):
)
geom_form_data = json.loads(geom_form_data)
geom_form_data = {
"geom": json.dumps(geom_form_data)
"output": json.dumps(geom_form_data)
}
geom_form = SimpleGeomForm(geom_form_data)

View File

@@ -24,7 +24,7 @@ from konova.forms.modals import RemoveModalForm
from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import RECORDED_BLOCKS_EDIT, IDENTIFIER_REPLACED, FORM_INVALID, \
DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED
DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE
@login_required
@@ -84,11 +84,17 @@ def new_view(request: HttpRequest):
)
)
messages.success(request, _("EMA {} added").format(ema.identifier))
if geom_form.geometry_simplified:
if geom_form.has_geometry_simplified():
messages.info(
request,
GEOMETRY_SIMPLIFIED
)
num_ignored_geometries = geom_form.get_num_geometries_ignored()
if num_ignored_geometries > 0:
messages.info(
request,
GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
)
return redirect("ema:detail", id=ema.id)
else:
@@ -142,7 +148,7 @@ def detail_view(request: HttpRequest, id: str):
geom_form = SimpleGeomForm(instance=ema)
parcels = ema.get_underlying_parcels()
_user = request.user
is_data_shared = ema.is_shared_with(_user)
is_entry_shared = ema.is_shared_with(_user)
# Order states according to surface
before_states = ema.before_states.all().order_by("-surface")
@@ -167,7 +173,7 @@ def detail_view(request: HttpRequest, id: str):
"obj": ema,
"geom_form": geom_form,
"parcels": parcels,
"has_access": is_data_shared,
"is_entry_shared": is_entry_shared,
"before_states": before_states,
"after_states": after_states,
"sum_before_states": sum_before_states,
@@ -215,11 +221,19 @@ def edit_view(request: HttpRequest, id: str):
# The data form takes the geom form for processing, as well as the performing user
ema = data_form.save(request.user, geom_form)
messages.success(request, _("EMA {} edited").format(ema.identifier))
if geom_form.geometry_simplified:
if geom_form.has_geometry_simplified():
messages.info(
request,
GEOMETRY_SIMPLIFIED
)
num_ignored_geometries = geom_form.get_num_geometries_ignored()
if num_ignored_geometries > 0:
messages.info(
request,
GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
)
return redirect("ema:detail", id=ema.id)
else:
messages.error(request, FORM_INVALID, extra_tags="danger",)

View File

@@ -12,11 +12,12 @@ from django.utils.translation import gettext_lazy as _
from ema.models import Ema
from konova.contexts import BaseContext
from konova.decorators import uuid_required
from konova.forms import SimpleGeomForm
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.generators import generate_qr_code
@uuid_required
def report_view(request:HttpRequest, id: str):
""" Renders the public report view
@@ -67,7 +68,7 @@ def report_view(request:HttpRequest, id: str):
"img": qrcode_img_lanis,
"url": qrcode_lanis_url
},
"has_access": False, # disables action buttons during rendering
"is_entry_shared": False, # disables action buttons during rendering
"before_states": before_states,
"after_states": after_states,
"geom_form": geom_form,

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<a href="{% url 'compensation:new' obj.id %}" title="{% trans 'Add new compensation' %}">
<button class="btn btn-outline-default">
{% fa5_icon 'plus' %}
@@ -32,7 +32,7 @@
<th scope="col">
{% trans 'Title' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -51,7 +51,7 @@
</td>
<td class="align-middle">{{ comp.title }}</td>
<td>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'intervention:remove-compensation' obj.id comp.id %}" class="btn btn-default btn-modal float-right" title="{% trans 'Remove compensation' %}">
{% fa5_icon 'trash' %}
</button>

View File

@@ -11,7 +11,7 @@
{% fa5_icon 'file-alt' %}
</button>
</a>
{% if has_access %}
{% if is_entry_shared %}
<button class="btn btn-default btn-modal mr-2" title="{% trans 'Resubmission' %}" data-form-url="{% url 'intervention:resubmission-create' obj.id %}">
{% fa5_icon 'bell' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'intervention:new-deduction' obj.id %}" title="{% trans 'Add new deduction' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'tree' %}
@@ -33,7 +33,7 @@
<th scope="col">
{% trans 'Created' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -56,7 +56,7 @@
<td class="align-middle">{{ deduction.surface|floatformat:2|intcomma }} m²</td>
<td class="align-middle">{{ deduction.created.timestamp|default_if_none:""|naturalday}}</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'intervention:edit-deduction' obj.id deduction.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit Deduction' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'intervention:new-doc' obj.id %}" title="{% trans 'Add new document' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'file' %}
@@ -38,7 +38,7 @@
<th scope="col">
{% trans 'Comment' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -66,7 +66,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'intervention:edit-doc' obj.id doc.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit document' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -10,7 +10,7 @@
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:pay:new' obj.id %}" title="{% trans 'Add new payment' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'money-bill-wave' %}
@@ -33,7 +33,7 @@
<th class="w-50" scope="col">
{% trans 'Comment' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -46,16 +46,24 @@
{% for pay in obj.payments.all %}
<tr>
<td class="align-middle">
{{ pay.amount|floatformat:2 }} €
{% if is_entry_shared %}
{{ pay.amount|floatformat:2 }} €
{% else %}
***
{% endif %}
</td>
<td class="align-middle">{{ pay.due_on|default_if_none:"---" }}</td>
<td class="align-middle">
<div class="scroll-150">
{{ pay.comment }}
{% if is_entry_shared %}
{{ pay.comment }}
{% else %}
{% trans 'This data is not shared with you' %}
{% endif %}
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'compensation:pay:edit' obj.id pay.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit payment' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -13,7 +13,7 @@
{% comment %}
Only show add-button if no revocation exists, yet.
{% endcomment %}
{% if is_default_member and has_access and not obj.legal.revocation %}
{% if is_default_member and is_entry_shared and not obj.legal.revocation %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'intervention:new-revocation' obj.id %}" title="{% trans 'Add revocation' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'ban' %}
@@ -36,7 +36,7 @@
<th scope="col">
{% trans 'Comment' %}
</th>
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<th class="w-10" scope="col">
<span class="float-right">
{% trans 'Action' %}
@@ -64,7 +64,7 @@
</div>
</td>
<td class="align-middle float-right">
{% if is_default_member and has_access %}
{% if is_default_member and is_entry_shared %}
<button data-form-url="{% url 'intervention:edit-revocation' obj.id rev.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit revocation' %}">
{% fa5_icon 'edit' %}
</button>

View File

@@ -129,7 +129,7 @@
{% include 'user/includes/team_data_modal_button.html' %}
{% endfor %}
<hr>
{% if has_access %}
{% if is_entry_shared %}
{% for user in obj.users.all %}
{% include 'user/includes/contact_modal_button.html' %}
{% endfor %}

View File

@@ -60,7 +60,7 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
post_data = {
"identifier": test_id,
"title": test_title,
"geom": geom_json,
"output": geom_json,
}
response = self.client_user.post(
new_url,

View File

@@ -62,7 +62,7 @@ class NewInterventionFormTestCase(BaseTestCase):
)
geom_form_data = json.loads(geom_form_data)
geom_form_data = {
"geom": json.dumps(geom_form_data)
"output": json.dumps(geom_form_data)
}
geom_form = SimpleGeomForm(geom_form_data)
@@ -104,7 +104,7 @@ class EditInterventionFormTestCase(NewInterventionFormTestCase):
)
geom_form_data = json.loads(geom_form_data)
geom_form_data = {
"geom": json.dumps(geom_form_data)
"output": json.dumps(geom_form_data)
}
geom_form = SimpleGeomForm(geom_form_data)
@@ -124,7 +124,7 @@ class EditInterventionFormTestCase(NewInterventionFormTestCase):
self.assertIsNotNone(obj.responsible.handler)
self.assertEqual(obj.title, data["title"])
self.assertEqual(obj.comment, data["comment"])
self.assertTrue(test_geom.equals_exact(obj.geometry.geom, 0.000001))
self.assert_equal_geometries(test_geom, obj.geometry.geom)
self.assertEqual(obj.legal.binding_date, today)
self.assertEqual(obj.legal.registration_date, today)

View File

@@ -23,7 +23,8 @@ from konova.forms.modals import RemoveModalForm
from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import DATA_CHECKED_PREVIOUSLY_TEMPLATE, RECORDED_BLOCKS_EDIT, \
CHECK_STATE_RESET, FORM_INVALID, IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED
CHECK_STATE_RESET, FORM_INVALID, IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, \
GEOMETRIES_IGNORED_TEMPLATE
@login_required
@@ -88,11 +89,19 @@ def new_view(request: HttpRequest):
)
)
messages.success(request, _("Intervention {} added").format(intervention.identifier))
if geom_form.geometry_simplified:
if geom_form.has_geometry_simplified():
messages.info(
request,
GEOMETRY_SIMPLIFIED
)
num_ignored_geometries = geom_form.get_num_geometries_ignored()
if num_ignored_geometries > 0:
messages.info(
request,
GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
)
return redirect("intervention:detail", id=intervention.id)
else:
messages.error(request, FORM_INVALID, extra_tags="danger",)
@@ -185,7 +194,7 @@ def detail_view(request: HttpRequest, id: str):
"last_checked": last_checked,
"last_checked_tooltip": last_checked_tooltip,
"compensations": compensations,
"has_access": is_data_shared,
"is_entry_shared": is_data_shared,
"geom_form": geom_form,
"is_default_member": _user.in_group(DEFAULT_GROUP),
"is_zb_member": _user.in_group(ZB_GROUP),
@@ -236,11 +245,19 @@ def edit_view(request: HttpRequest, id: str):
messages.success(request, _("Intervention {} edited").format(intervention.identifier))
if intervention_is_checked:
messages.info(request, CHECK_STATE_RESET)
if geom_form.geometry_simplified:
if geom_form.has_geometry_simplified():
messages.info(
request,
GEOMETRY_SIMPLIFIED
)
num_ignored_geometries = geom_form.get_num_geometries_ignored()
if num_ignored_geometries > 0:
messages.info(
request,
GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
)
return redirect("intervention:detail", id=intervention.id)
else:
messages.error(request, FORM_INVALID, extra_tags="danger",)

View File

@@ -11,7 +11,7 @@ from uuid import UUID
from bootstrap_modal_forms.mixins import is_ajax
from django.contrib import messages
from django.http import Http404
from django.core.exceptions import BadRequest
from django.shortcuts import redirect, get_object_or_404, render
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
@@ -185,7 +185,7 @@ def uuid_required(function):
try:
uuid = UUID(uuid)
except ValueError:
raise Http404(
raise BadRequest(
"Invalid UUID"
)
return function(request, *args, **kwargs)

View File

@@ -0,0 +1,55 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 19.08.24
"""
import django_filters
from django import forms
from django.db.models import QuerySet, Q
from django.utils.translation import gettext_lazy as _
class UserLoggedTableFilterMixin(django_filters.FilterSet):
ul = django_filters.CharFilter(
method="filter_user_log",
label=_(""),
label_suffix=_(""),
widget=forms.TextInput(
attrs={
"placeholder": _("Logged user"),
"title": _("Search for entries where this person has been participated according to log history"),
"class": "form-control",
}
),
)
class Meta:
abstract = True
def filter_user_log(self, queryset, name, value) -> QuerySet:
""" Filters queryset depending on value of input
Args:
queryset (QuerySet): Incoming (prefiltered) queryset
name (str): Name of input field
value (str): Value of input field
Returns:
"""
value = value.replace(",", " ")
value = value.strip()
values = value.split(" ")
q = Q()
for val in values:
q &= (
Q(log__user__username__icontains=val) |
Q(log__user__first_name__icontains=val) |
Q(log__user__last_name__icontains=val)
)
queryset = queryset.filter(q)
return queryset

View File

@@ -14,6 +14,7 @@ from konova.filters.mixins.office import ConservationOfficeTableFilterMixin, Reg
from konova.filters.mixins.record import RecordableTableFilterMixin
from konova.filters.mixins.self_created import SelfCreatedTableFilterMixin
from konova.filters.mixins.share import ShareableTableFilterMixin
from konova.filters.mixins.user_log import UserLoggedTableFilterMixin
class AbstractTableFilter(django_filters.FilterSet):
@@ -40,7 +41,8 @@ class SelectionTableFilter(RegistrationOfficeTableFilterMixin,
class QueryTableFilter(KeywordTableFilterMixin,
FileNumberTableFilterMixin,
GeoReferencedTableFilterMixin):
GeoReferencedTableFilterMixin,
UserLoggedTableFilterMixin):
""" TableFilter holding different filter options for query related filtering
"""

View File

@@ -25,15 +25,16 @@ class SimpleGeomForm(BaseForm):
""" A geometry form for rendering geometry read-only using a widget
"""
read_only = True
geometry_simplified = False
geom = JSONField(
read_only: bool = True
_geometry_simplified: bool = False
output = JSONField(
label=_("Geometry"),
help_text=_(""),
label_suffix="",
required=False,
disabled=False,
)
_num_geometries_ignored: int = 0
def __init__(self, *args, **kwargs):
self.read_only = kwargs.pop("read_only", True)
@@ -48,33 +49,33 @@ class SimpleGeomForm(BaseForm):
raise AttributeError
geojson = self.instance.geometry.as_feature_collection(srid=DEFAULT_SRID_RLP)
self._set_geojson_properties(geojson, title=self.instance.identifier or None)
geom = json.dumps(geojson)
except AttributeError:
# If no geometry exists for this form, we simply set the value to None and zoom to the maximum level
geom = ""
self.empty = True
self.initialize_form_field("geom", geom)
self.initialize_form_field("output", geom)
def is_valid(self):
super().is_valid()
is_valid = True
# Get geojson from form
geom = self.data["geom"]
geom = self.data.get("output", None)
if geom is None or len(geom) == 0:
# empty geometry is a valid geometry
self.cleaned_data["geom"] = MultiPolygon(srid=DEFAULT_SRID_RLP).ewkt
self.cleaned_data["output"] = MultiPolygon(srid=DEFAULT_SRID_RLP).ewkt
return is_valid
geom = json.loads(geom)
# Write submitted data back into form field to make sure invalid geometry
# will be rendered again on failed submit
self.initialize_form_field("geom", self.data["geom"])
self.initialize_form_field("output", self.data["output"])
# Read geojson into gdal geometry
# HINT: This can be simplified if the geojson format holds data in epsg:4326 (GDAL provides direct creation for
# this case)
# Initialize features list with empty MultiPolygon, so that an empty input will result in a
# proper empty MultiPolygon object
features = []
features_json = geom.get("features", [])
accepted_ogr_types = [
@@ -97,33 +98,41 @@ class SimpleGeomForm(BaseForm):
g = self.__flatten_geom_to_2D(g)
if g.geom_type not in accepted_ogr_types:
self.add_error("geom", _("Only surfaces allowed. Points or lines must be buffered."))
self.add_error("output", _("Only surfaces allowed. Points or lines must be buffered."))
is_valid &= False
return is_valid
is_valid &= self.__is_area_valid(g)
is_area_valid = self.__is_area_valid(g)
if not is_area_valid:
# Geometries with an invalid size will not be saved to the db
# We assume these are malicious snippets which are not supposed to be in the geometry in the first place
self._num_geometries_ignored += 1
continue
polygon = Polygon.from_ewkt(g.ewkt)
is_valid &= polygon.valid
if not polygon.valid:
self.add_error("geom", polygon.valid_reason)
g = Polygon.from_ewkt(g.ewkt)
is_valid &= g.valid
if not g.valid:
self.add_error("output", g.valid_reason)
return is_valid
features.append(polygon)
if isinstance(g, Polygon):
features.append(g)
elif isinstance(g, MultiPolygon):
features.extend(list(g))
# Unionize all geometry features into one new MultiPolygon
form_geom = MultiPolygon(srid=DEFAULT_SRID_RLP)
for feature in features:
form_geom = form_geom.union(feature)
if features:
form_geom = MultiPolygon(*features, srid=DEFAULT_SRID_RLP).unary_union
else:
form_geom = MultiPolygon(srid=DEFAULT_SRID_RLP)
# Make sure to convert into a MultiPolygon. Relevant if a single Polygon is provided.
if form_geom.geom_type != "MultiPolygon":
form_geom = MultiPolygon(form_geom, srid=DEFAULT_SRID_RLP)
form_geom = Geometry.cast_to_multipolygon(form_geom)
# Write unioned Multipolygon into cleaned data
if self.cleaned_data is None:
self.cleaned_data = {}
self.cleaned_data["geom"] = form_geom.ewkt
self.cleaned_data["output"] = form_geom.ewkt
return is_valid
@@ -133,7 +142,7 @@ class SimpleGeomForm(BaseForm):
Returns:
"""
geom = self.cleaned_data.get("geom")
geom = self.cleaned_data.get("output")
g = gdal.OGRGeometry(geom, srs=DEFAULT_SRID_RLP)
num_vertices = g.num_coords
@@ -146,15 +155,6 @@ class SimpleGeomForm(BaseForm):
"""
is_area_valid = geom.area > 1 # > 1m² (SRID:25832)
if not is_area_valid:
self.add_error(
"geom",
_("Geometry must be greater than 1m². Currently is {}").format(
float(geom.area)
)
)
return is_area_valid
def __simplify_geometry(self, geom, max_vert: int):
@@ -192,14 +192,14 @@ class SimpleGeomForm(BaseForm):
if self.instance is None or self.instance.geometry is None:
raise LookupError
geometry = self.instance.geometry
geometry.geom = self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID_RLP))
geometry.geom = self.cleaned_data.get("output", MultiPolygon(srid=DEFAULT_SRID_RLP))
geometry.modified = action
geometry.save()
except LookupError:
# No geometry or linked instance holding a geometry exist --> create a new one!
geometry = Geometry.objects.create(
geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID_RLP)),
geom=self.cleaned_data.get("output", MultiPolygon(srid=DEFAULT_SRID_RLP)),
created=action,
)
@@ -207,13 +207,29 @@ class SimpleGeomForm(BaseForm):
if not is_vertices_num_valid:
geometry.geom = self.__simplify_geometry(geometry.geom, max_vert=GEOM_MAX_VERTICES)
geometry.save()
self.geometry_simplified = True
self._geometry_simplified = True
# Start parcel update and geometry conflict checking procedure in a background process
celery_update_parcels.delay(geometry.id)
celery_check_for_geometry_conflicts.delay(geometry.id)
return geometry
def get_num_geometries_ignored(self):
""" Returns the number of geometries which had to be ignored for various reasons
Returns:
"""
return self._num_geometries_ignored
def has_geometry_simplified(self):
""" Returns whether the geometry has been simplified or not.
Returns:
"""
return self._geometry_simplified
def __flatten_geom_to_2D(self, geom):
"""
Enforces a given OGRGeometry from higher dimensions into 2D
@@ -223,3 +239,20 @@ class SimpleGeomForm(BaseForm):
g_wkt = wkt_w.write(geom.geos).decode("utf-8")
geom = gdal.OGRGeometry(g_wkt)
return geom
def _set_geojson_properties(self, geojson: dict, title: str = None):
""" Toggles the editable property of the geojson for proper handling in map client
Args:
geojson (dict): The GeoJson
title (str): An alternative title for the geometry
Returns:
geojson (dict): The altered GeoJson
"""
features = geojson.get("features", [])
for feature in features:
feature["properties"]["editable"] = not self.read_only
if title:
feature["properties"]["title"] = title
return geojson

View File

@@ -6,11 +6,11 @@ Created on: 26.10.22
"""
import zipfile
from datetime import datetime
from io import BytesIO
from django.core.mail import EmailMessage
from django.utils import timezone
from django.utils.datetime_safe import datetime
from analysis.utils.excel.excel import TempExcelFile
from analysis.utils.report import TimespanReport

View File

@@ -0,0 +1,88 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 04.01.22
"""
import datetime
from django.contrib.gis.db.models.functions import Area
from konova.management.commands.setup import BaseKonovaCommand
from konova.models import Geometry, ParcelIntersection
class Command(BaseKonovaCommand):
help = "Recalculates parcels for entries with geometry but missing parcel information"
def add_arguments(self, parser):
parser.add_argument(
"--force-all",
action="store_true",
default=False,
help="If Attribute set, all entries parcels will be recalculated"
)
def handle(self, *args, **options):
try:
self.recalculate_parcels(options)
except KeyboardInterrupt:
self._break_line()
exit(-1)
def recalculate_parcels(self, options: dict):
force_all = options.get("force_all", False)
geometry_objects = Geometry.objects.filter(
geom__isempty=False,
).exclude(
geom=None
)
if not force_all:
# Fetch all intersections
intersection_objs = ParcelIntersection.objects.filter(
geometry__in=geometry_objects
)
# Just take the geometry ids, which seem to have intersections
geom_with_intersection_ids = intersection_objs.values_list(
"geometry__id",
flat=True
)
# ... and resolve into Geometry objects again ...
intersected_geom_objs = Geometry.objects.filter(
id__in=geom_with_intersection_ids
)
# ... to be able to use the way more efficient difference() function ...
geometry_objects_ids = geometry_objects.difference(intersected_geom_objs).values_list("id", flat=True)
# ... so we can resolve these into proper Geometry objects again for further annotation usage
geometry_objects = Geometry.objects.filter(id__in=geometry_objects_ids)
self._write_warning("=== Update parcels and districts ===")
# Order geometries by size to process smaller once at first
geometries = geometry_objects.annotate(
area=Area("geom")
).order_by(
'area'
)
self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...")
i = 0
num_geoms = geometries.count()
geoms_with_errors = {}
for geometry in geometries:
self._write_warning(f"--- {datetime.datetime.now()} Process {geometry.id} now ...")
try:
geometry.update_parcels()
self._write_warning(f"--- Processed {geometry.get_underlying_parcels().count()} underlying parcels")
except Exception as e:
geoms_with_errors[geometry.id] = str(e)
i += 1
self._write_warning(f"--- {i}/{num_geoms} processed")
self._write_success("Updating parcels done!")
for key, val in geoms_with_errors.items():
self._write_error(f" Error on {key}: {val}")
self._write_success(f"{num_geoms - len(geoms_with_errors)} geometries successfuly recalculated!")
self._break_line()

View File

@@ -1,51 +0,0 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 19.08.21
"""
from django.core.management import BaseCommand
from intervention.models import Intervention
class Command(BaseCommand):
help = "Performs test on collisions using the identifier generation"
def handle(self, *args, **options):
identifiers = {}
max_iterations = 100000
try:
collisions = 0
len_ids = len(identifiers)
while len_ids < max_iterations:
tmp_intervention = Intervention()
_id = tmp_intervention.generate_new_identifier()
len_ids = len(identifiers)
if _id not in identifiers:
if len_ids % (max_iterations/5) == 0:
print(len_ids)
identifiers[_id] = None
else:
collisions += 1
print("+++ Collision after {} identifiers +++".format(len_ids))
except KeyboardInterrupt:
self._break_line()
exit(-1)
print(
"\n{} collisions in {} identifiers; Collision rate {}%".format(
collisions,
len_ids,
(collisions / len_ids)*100,
)
)
def _break_line(self):
""" Simply prints a line break
Returns:
"""
self.stdout.write("\n")

View File

@@ -1,54 +0,0 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 04.01.22
"""
import datetime
from django.contrib.gis.db.models.functions import Area
from konova.management.commands.setup import BaseKonovaCommand
from konova.models import Geometry, Parcel, District
class Command(BaseKonovaCommand):
help = "Checks the database' sanity and removes unused entries"
def handle(self, *args, **options):
try:
self.update_all_parcels()
except KeyboardInterrupt:
self._break_line()
exit(-1)
def update_all_parcels(self):
num_parcels_before = Parcel.objects.count()
num_districts_before = District.objects.count()
self._write_warning("=== Update parcels and districts ===")
# Order geometries by size to process smaller once at first
geometries = Geometry.objects.all().exclude(
geom=None
).annotate(area=Area("geom")).order_by(
'area'
)
self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...")
i = 0
num_geoms = geometries.count()
for geometry in geometries:
self._write_warning(f"--- {datetime.datetime.now()} Process {geometry.id} now ...")
geometry.update_parcels()
self._write_warning(f"--- Processed {geometry.get_underlying_parcels().count()} underlying parcels")
i += 1
self._write_warning(f"--- {i}/{num_geoms} processed")
num_parcels_after = Parcel.objects.count()
num_districts_after = District.objects.count()
if num_parcels_after != num_parcels_before:
self._write_error(f"Parcels have changed: {num_parcels_before} to {num_parcels_after} entries. You should run the sanitize command.")
if num_districts_after != num_districts_before:
self._write_error(f"Districts have changed: {num_districts_before} to {num_districts_after} entries. You should run the sanitize command.")
self._write_success("Updating parcels done!")
self._break_line()

View File

@@ -8,9 +8,10 @@ Created on: 15.11.21
import json
from django.contrib.gis.db.models import MultiPolygonField
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.db import models, transaction
from django.utils import timezone
from django.contrib.gis.geos import MultiPolygon
from konova.models import BaseResource, UuidModel
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
@@ -223,6 +224,17 @@ class Geometry(BaseResource):
)
parcel_obj.updated_on = _now
parcels_to_update.append(parcel_obj)
except MultipleObjectsReturned:
parcel_obj = Parcel.make_unique(
district=district,
municipal=municipal,
parcel_group=parcel_group,
flr=flr_val,
flrstck_nnr=flrstck_nnr,
flrstck_zhlr=flrstck_zhlr,
)
parcel_obj.updated_on = _now
parcels_to_update.append(parcel_obj)
except ObjectDoesNotExist:
# If not existing, create object but do not commit, yet
parcel_obj = Parcel(
@@ -331,6 +343,7 @@ class Geometry(BaseResource):
{
"type": "Feature",
"geometry": json.loads(p.json),
"properties": {},
}
for p in polygons
]
@@ -366,13 +379,42 @@ class Geometry(BaseResource):
diff = geom_envelope - self.geom
if diff.area == 0:
ratio = 1
complexity_factor = 1
else:
ratio = self.geom.area / diff.area
complexity_factor = self.geom.area / diff.area
complexity_factor = 1 - ratio
return complexity_factor
@staticmethod
def cast_to_multipolygon(input_geom):
""" If input_geom is not a MultiPolygon, cast to MultiPolygon
Args:
input_geom ():
Returns:
output_geom
"""
output_geom = input_geom
if not isinstance(input_geom, MultiPolygon):
output_geom = MultiPolygon(input_geom, srid=DEFAULT_SRID_RLP)
return output_geom
@staticmethod
def cast_to_rlp_srid(input_geom):
""" If input_geom is not of RLP SRID (25832), cast to RLP SRID
Args:
input_geom ():
Returns:
output_geom
"""
output_geom = input_geom
if output_geom.srid != DEFAULT_SRID_RLP:
output_geom.transform(DEFAULT_SRID_RLP)
return output_geom
class GeometryConflict(UuidModel):
"""

View File

@@ -5,7 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 16.12.21
"""
from django.db import models
from django.db import models, transaction
from konova.models import UuidModel
@@ -158,6 +158,46 @@ class Parcel(UuidModel):
def __str__(self):
return f"{self.parcel_group} | {self.flr} | {self.flrstck_zhlr} | {self.flrstck_nnr}"
@classmethod
def make_unique(cls, **kwargs):
""" Checks for duplicates of a Parcel, choose a (now) unique one,
repairs relations for ParcelIntersection and removes duplicates.
Args:
**kwargs ():
Returns:
unique_true (Parcel): The new unique 'true one'
"""
parcel_objs = Parcel.objects.filter(**kwargs)
if not parcel_objs.exists():
return None
# Get one of the found parcels and use it as new 'true one'
unique_parcel = parcel_objs.first()
# separate it from the rest
parcel_objs = parcel_objs.exclude(id=unique_parcel.id)
if not parcel_objs.exists():
# There are no duplicates - all good, just return
return unique_parcel
# Fetch existing intersections, which still point on the duplicated parcels
intersection_objs = ParcelIntersection.objects.filter(
parcel__in=parcel_objs
)
# Change each intersection, so they point on the 'true one' parcel from now on
for intersection in intersection_objs:
intersection.parcel = unique_parcel
intersection.save()
# Remove the duplicated parcels
parcel_objs.delete()
return unique_parcel
class ParcelIntersection(UuidModel):
"""

View File

@@ -278,4 +278,18 @@ Similar to bootstraps 'shadow-lg'
}
.alert{
margin-bottom: 0 !important;
}
/*
Overwrites netgis.css attributes
*/
.netgis-gradient-a{
/*
Overwrites gradient used on default css of netgis map client
*/
background: var(--rlp-red) !important;
}
.netgis-menu{
z-index: 1 !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -66,7 +66,6 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'django.contrib.gis',
'django.contrib.humanize',
'simple_sso.sso_server',
'django_tables2',
'bootstrap_modal_forms',
'fontawesome_5',
@@ -189,7 +188,6 @@ STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'konova/static'),
os.path.join(BASE_DIR, 'templates/map/client'), # NETGIS map client files
os.path.join(BASE_DIR, 'templates/map/client/libs'), # NETGIS map client files
]
# EMAIL (see https://docs.djangoproject.com/en/dev/topics/email/)

View File

@@ -5,6 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 31.01.22
"""
from konova.sub_settings.django_settings import env
# MAPS
DEFAULT_LAT = 50.00
@@ -28,3 +29,6 @@ LANIS_ZOOM_LUT = {
1000: 30,
500: 31,
}
MAP_PROXY_HOST_WHITELIST = env.list("MAP_PROXY_HOST_WHITELIST")
i = 0

View File

@@ -16,3 +16,5 @@ OAUTH_CODE_VERIFIER = env("OAUTH_CODE_VERIFIER")
OAUTH_CLIENT_ID = env("OAUTH_CLIENT_ID")
OAUTH_CLIENT_SECRET = env("OAUTH_CLIENT_SECRET")
PROPAGATION_SECRET = env("PROPAGATION_SECRET")

View File

@@ -124,6 +124,7 @@ class GeometryTestCase(BaseTestCase):
{
"type": "Feature",
"geometry": json.loads(p.json),
"properties": {}
}
for p in polygons
]

View File

@@ -469,7 +469,7 @@ class BaseTestCase(TestCase):
eco_account.save()
return eco_account
def assert_equal_geometries(self, geom1: MultiPolygon, geom2: MultiPolygon, tolerance = 0.001):
def assert_equal_geometries(self, geom1: MultiPolygon, geom2: MultiPolygon, tolerance=0.001):
""" Assert for geometries to be equal
Transforms the geometries to matching srids before checking
@@ -491,7 +491,10 @@ class BaseTestCase(TestCase):
# transformation from one coordinate system into the other, which is valid
geom1.transform(geom2.srid)
geom2.transform(geom1.srid)
self.assertTrue(geom1.equals_exact(geom2, tolerance) or geom2.equals_exact(geom1, tolerance))
self.assertTrue(
geom1.equals_exact(geom2, tolerance=tolerance),
msg=f"Difference is {abs(geom1.area - geom2.area)} with {geom1.area} and {geom2.area} in a tolerance of {tolerance}"
)
class BaseViewTestCase(BaseTestCase):

View File

@@ -42,5 +42,6 @@ urlpatterns = [
path('client/proxy/wfs', ClientProxyParcelWFS.as_view(), name="client-proxy-wfs"),
]
handler400 = "konova.views.error.get_400_view"
handler404 = "konova.views.error.get_404_view"
handler500 = "konova.views.error.get_500_view"

View File

@@ -83,6 +83,7 @@ EDITED_GENERAL_DATA = _("Edited general data")
# Geometry
GEOMETRY_CONFLICT_WITH_TEMPLATE = _("Geometry conflict detected with {}")
GEOMETRY_SIMPLIFIED = _("The geometry contained more than {} vertices. It had to be simplified to match the allowed limit of {} vertices.").format(GEOM_MAX_VERTICES, GEOM_MAX_VERTICES)
GEOMETRIES_IGNORED_TEMPLATE = _("The geometry contained {} parts which have been detected as invalid (e.g. too small to be valid). These parts have been removed. Please check the stored geometry.")
# INTERVENTION
INTERVENTION_HAS_REVOCATIONS_TEMPLATE = _("This intervention has {} revocations")
@@ -91,3 +92,6 @@ INTERVENTION_HAS_REVOCATIONS_TEMPLATE = _("This intervention has {} revocations"
DATA_CHECKED_ON_TEMPLATE = _("Checked on {} by {}")
DATA_CHECKED_PREVIOUSLY_TEMPLATE = _("Data has changed since last check on {} by {}")
DATA_IS_UNCHECKED = _("Current data not checked yet")
# API TOKEN SETTINGS
NEW_API_TOKEN_GENERATED = _("New token generated. Administrators need to validate.")

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 collections import Iterable
import requests
from user.models import User
from django.utils.translation import gettext_lazy as _
from konova.settings import SSO_SERVER_BASE, SSO_PUBLIC_KEY, PROXIES
from konova.sub_settings.context_settings import BASE_TITLE_SHORT
class Messenger:
""" Used to send messages to the SSO server.
Messages can be seen by the user the next time they login on their SSO dashboard.
Documentation for SSO Server-Client communication can be found here:
https://git.naturschutz.rlp.de/SGD-Nord/arnova/wiki/Messages
"""
server_url = "{}communication/message/".format(SSO_SERVER_BASE)
def __init__(self, users: Iterable, subject: str = None, body: str = None, type: str = None):
self.users = users
self.msg_subject = subject
self.msg_body = body
self.msg_type = type
def send(self):
""" Sends a message
"""
if self.msg_body is None or len(self.msg_body) == 0:
raise AttributeError("No message body set")
headers = {
"x-services-public-key": SSO_PUBLIC_KEY
}
for user in self.users:
data = {
"type": self.msg_type,
"sender": BASE_TITLE_SHORT,
"receiver": user.username,
"subject": self.msg_subject,
"body": self.msg_body,
}
requests.post(
self.server_url,
data=data,
headers=headers,
proxies=PROXIES
)
def send_object_checked(self, obj_identifier: str, performing_user: User, detail_view_url: str = ""):
""" Wraps sending of a message related to the checking of an object, like an intervention
Args:
obj_identifier (str): The object's identifier (e.g. 'EIV-123'
performing_user (User): The user who performed the checking
detail_view_url (str): If a direct link to the object shall be added to the message, it can be provided here
Returns:
"""
self.msg_subject = _("{} checked").format(obj_identifier)
if len(detail_view_url) > 0:
detail_view_url = _('<a href="{}">Check it out</a>').format(detail_view_url)
self.msg_body = _("{} has been checked successfully by user {}! {}").format(
obj_identifier,
performing_user.username,
detail_view_url
)
self.send()

View File

@@ -11,6 +11,7 @@ from json import JSONDecodeError
import requests
from konova.sub_settings import schneider_settings
from konova.sub_settings.lanis_settings import DEFAULT_SRID
from konova.sub_settings.proxy_settings import PROXIES
@@ -34,6 +35,7 @@ class ParcelFetcher:
if geom.area < buffer_threshold:
# Fallback for malicious geometries which are way too small and would disappear on negative buffering
geom = geometry.geom
geom.transform(DEFAULT_SRID)
self.geojson = geom.ewkt
self.results = []
@@ -55,11 +57,11 @@ class ParcelFetcher:
content = json.loads(response.content.decode("utf-8"))
except JSONDecodeError:
content = {}
next = content.get("next", None)
_next = content.get("next", None)
fetched_parcels = content.get("results", [])
self.results += fetched_parcels
if next:
self.get_parcels(next)
if _next:
self.get_parcels(_next)
return self.results

View File

@@ -216,11 +216,11 @@ class TableRenderMixin:
"""
html = ""
has_access = record.is_shared_with(self.user)
is_entry_shared = record.is_shared_with(self.user)
html += self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
tooltip=_("Full access granted") if is_entry_shared else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if is_entry_shared else "far fa-edit",
)
return format_html(html)

View File

@@ -25,6 +25,20 @@ def get_404_view(request: HttpRequest, exception=None):
return render(request, "404.html", context, status=404)
def get_400_view(request: HttpRequest, exception=None):
""" Returns a 400 handling view
Args:
request ():
exception ():
Returns:
"""
context = BaseContext.context
return render(request, "400.html", context, status=400)
def get_500_view(request: HttpRequest):
""" Returns a 404 handling view

View File

@@ -5,7 +5,6 @@ Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 19.08.22
"""
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.gis.geos import MultiPolygon
from django.http import HttpResponse, HttpRequest
from django.shortcuts import get_object_or_404

View File

@@ -24,5 +24,13 @@ class LogoutView(View):
Returns:
A redirect
"""
user = request.user
try:
oauth_token = user.oauth_token
if oauth_token:
oauth_token.revoke()
except AttributeError:
pass
logout(request)
return redirect(SSO_SERVER_BASE)

View File

@@ -9,15 +9,16 @@ import json
from json import JSONDecodeError
import requests
import urllib3.util
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse, HttpRequest
from django.http import JsonResponse, HttpRequest, HttpResponse
from django.utils.decorators import method_decorator
from django.utils.http import urlencode
from django.views import View
from django.utils.translation import gettext_lazy as _
from requests.auth import HTTPDigestAuth
from konova.sub_settings.lanis_settings import MAP_PROXY_HOST_WHITELIST
from konova.sub_settings.proxy_settings import PROXIES, GEOPORTAL_RLP_USER, GEOPORTAL_RLP_PASSWORD
@@ -32,6 +33,13 @@ class BaseClientProxyView(View):
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def _check_with_whitelist(self, url):
parsed_url = urllib3.util.parse_url(url)
parsed_url_host = parsed_url.host
whitelist = set(MAP_PROXY_HOST_WHITELIST)
is_allowed = parsed_url_host in whitelist
return is_allowed
def perform_url_call(self, url, headers={}, auth=None):
""" Generic proxied call
@@ -51,7 +59,10 @@ class BaseClientProxyView(View):
)
content = response.content
if isinstance(content, bytes):
content = content.decode("utf-8")
try:
content = content.decode("utf-8")
except UnicodeDecodeError:
content = f"Can not decode content of {url}"
return content, response.status_code
@@ -59,25 +70,13 @@ class ClientProxyParcelSearch(BaseClientProxyView):
def get(self, request: HttpRequest):
url = request.META.get("QUERY_STRING")
content, response_code = self.perform_url_call(url)
try:
body = json.loads(content)
except JSONDecodeError as e:
body = {
"totalResultsCount": -1,
"geonames": [
{
"title": _("The external service is currently unavailable.<br>Please try again in a few moments...")
}
]
}
if response_code != 200:
return JsonResponse({
"status_code": response_code,
"content": body,
})
return JsonResponse(body)
is_url_allowed = self._check_with_whitelist(url)
if not is_url_allowed:
raise PermissionError(f"Proxied url '{url}' is not allowed!")
content, response_code = self.perform_url_call(url)
return HttpResponse(content)
class ClientProxyParcelWFS(BaseClientProxyView):

View File

@@ -115,10 +115,10 @@ class OAuthCallbackView(View):
if status_code_invalid:
raise RuntimeError(f"OAuth access token could not be fetched: {access_code_response.text}")
oauth_access_token = OAuthToken.from_access_token_response(access_code_response_body, received_on)
oauth_access_token.save()
user = oauth_access_token.update_and_get_user()
user.oauth_replace_token(oauth_access_token)
oauth_token = OAuthToken.from_access_token_response(access_code_response_body, received_on)
oauth_token.save()
user = oauth_token.update_and_get_user()
user.oauth_replace_token(oauth_token)
login(request, user)
return redirect("home")

Binary file not shown.

View File

@@ -29,6 +29,7 @@
#: konova/filters/mixins/office.py:25 konova/filters/mixins/office.py:56
#: konova/filters/mixins/office.py:57 konova/filters/mixins/record.py:23
#: konova/filters/mixins/self_created.py:24 konova/filters/mixins/share.py:23
#: konova/filters/mixins/user_log.py:17 konova/filters/mixins/user_log.py:18
#: konova/forms/geometry_form.py:32 konova/forms/modals/document_form.py:26
#: konova/forms/modals/document_form.py:36
#: konova/forms/modals/document_form.py:50
@@ -37,13 +38,14 @@
#: konova/forms/modals/remove_form.py:23
#: konova/forms/modals/resubmission_form.py:22
#: konova/forms/modals/resubmission_form.py:38 konova/forms/remove_form.py:25
#: konova/tests/unit/test_forms.py:59 user/forms/user.py:39
#: konova/tests/unit/test_forms.py:59 user/forms/modals/api_token.py:17
#: user/forms/user.py:39
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-02-16 09:49+0100\n"
"POT-Creation-Date: 2025-10-15 09:11+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -259,7 +261,7 @@ msgstr ""
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:14
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:16
#: compensation/forms/modals/state.py:58
#: compensation/forms/modals/state.py:59
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:36
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:36
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36
@@ -372,7 +374,6 @@ msgid "Identifier"
msgstr "Kennung"
#: compensation/forms/compensation.py:33 intervention/forms/intervention.py:33
#: user/forms/user.py:77
msgid "Generated automatically - not editable"
msgstr "Automatisch generiert - nicht bearbeitbar"
@@ -447,7 +448,7 @@ msgid "Select the intervention for which this compensation compensates"
msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist"
#: compensation/forms/compensation.py:114
#: compensation/views/compensation/compensation.py:119
#: compensation/views/compensation/compensation.py:120
msgid "New compensation"
msgstr "Neue Kompensation"
@@ -474,7 +475,7 @@ msgid "When did the parties agree on this?"
msgstr "Wann wurde dieses Ökokonto offiziell vereinbart?"
#: compensation/forms/eco_account.py:72
#: compensation/views/eco_account/eco_account.py:100
#: compensation/views/eco_account/eco_account.py:101
msgid "New Eco-Account"
msgstr "Neues Ökokonto"
@@ -696,46 +697,46 @@ msgid "If there is no date you can enter, please explain why."
msgstr "Falls Sie kein Datum angeben können, erklären Sie bitte weshalb."
#: compensation/forms/modals/payment.py:108
#: intervention/templates/intervention/detail/includes/payments.html:59
#: intervention/templates/intervention/detail/includes/payments.html:67
msgid "Edit payment"
msgstr "Zahlung bearbeiten"
#: compensation/forms/modals/state.py:32
#: compensation/forms/modals/state.py:33
msgid "Biotope Type"
msgstr "Biotoptyp"
#: compensation/forms/modals/state.py:35
#: compensation/forms/modals/state.py:36
msgid "Select the biotope type"
msgstr "Biotoptyp wählen"
#: compensation/forms/modals/state.py:39 compensation/forms/modals/state.py:51
#: compensation/forms/modals/state.py:40 compensation/forms/modals/state.py:52
msgid "Biotope additional type"
msgstr "Zusatzbezeichnung"
#: compensation/forms/modals/state.py:42
#: compensation/forms/modals/state.py:43
msgid "Select an additional biotope type"
msgstr "Zusatzbezeichnung wählen"
#: compensation/forms/modals/state.py:61
#: compensation/forms/modals/state.py:62
#: intervention/forms/modals/deduction.py:49
msgid "in m²"
msgstr ""
#: compensation/forms/modals/state.py:72
#: compensation/forms/modals/state.py:73
#: compensation/tests/compensation/unit/test_forms.py:175
msgid "New state"
msgstr "Neuer Zustand"
#: compensation/forms/modals/state.py:73
#: compensation/forms/modals/state.py:74
#: compensation/tests/compensation/unit/test_forms.py:176
msgid "Insert data for the new state"
msgstr "Geben Sie die Daten des neuen Zustandes ein"
#: compensation/forms/modals/state.py:90 konova/forms/modals/base_form.py:32
#: compensation/forms/modals/state.py:91 konova/forms/modals/base_form.py:32
msgid "Object removed"
msgstr "Objekt entfernt"
#: compensation/forms/modals/state.py:145
#: compensation/forms/modals/state.py:146
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:62
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:62
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:62
@@ -1287,44 +1288,44 @@ msgstr ""
msgid "Responsible data"
msgstr "Daten zu den verantwortlichen Stellen"
#: compensation/views/compensation/compensation.py:57
#: compensation/views/compensation/compensation.py:58
msgid "Compensations - Overview"
msgstr "Kompensationen - Übersicht"
#: compensation/views/compensation/compensation.py:180
#: compensation/views/compensation/compensation.py:181
#: konova/utils/message_templates.py:40
msgid "Compensation {} edited"
msgstr "Kompensation {} bearbeitet"
#: compensation/views/compensation/compensation.py:195
#: compensation/views/eco_account/eco_account.py:172 ema/views/ema.py:230
#: intervention/views/intervention.py:251
#: compensation/views/compensation/compensation.py:196
#: compensation/views/eco_account/eco_account.py:173 ema/views/ema.py:238
#: intervention/views/intervention.py:253
msgid "Edit {}"
msgstr "Bearbeite {}"
#: compensation/views/compensation/report.py:34
#: compensation/views/eco_account/report.py:34 ema/views/report.py:34
#: intervention/views/report.py:37
#: compensation/views/compensation/report.py:35
#: compensation/views/eco_account/report.py:36 ema/views/report.py:35
#: intervention/views/report.py:35
msgid "Report {}"
msgstr "Bericht {}"
#: compensation/views/eco_account/eco_account.py:52
#: compensation/views/eco_account/eco_account.py:53
msgid "Eco-account - Overview"
msgstr "Ökokonten - Übersicht"
#: compensation/views/eco_account/eco_account.py:85
#: compensation/views/eco_account/eco_account.py:86
msgid "Eco-Account {} added"
msgstr "Ökokonto {} hinzugefügt"
#: compensation/views/eco_account/eco_account.py:157
#: compensation/views/eco_account/eco_account.py:158
msgid "Eco-Account {} edited"
msgstr "Ökokonto {} bearbeitet"
#: compensation/views/eco_account/eco_account.py:286
#: compensation/views/eco_account/eco_account.py:288
msgid "Eco-account removed"
msgstr "Ökokonto entfernt"
#: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:101
#: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:108
msgid "New EMA"
msgstr "Neue EMA hinzufügen"
@@ -1352,19 +1353,19 @@ msgstr ""
msgid "Payment funded compensation"
msgstr "Ersatzzahlungsmaßnahme"
#: ema/views/ema.py:52
#: ema/views/ema.py:53
msgid "EMAs - Overview"
msgstr "EMAs - Übersicht"
#: ema/views/ema.py:85
#: ema/views/ema.py:86
msgid "EMA {} added"
msgstr "EMA {} hinzugefügt"
#: ema/views/ema.py:215
#: ema/views/ema.py:223
msgid "EMA {} edited"
msgstr "EMA {} bearbeitet"
#: ema/views/ema.py:254
#: ema/views/ema.py:262
msgid "EMA removed"
msgstr "EMA entfernt"
@@ -1428,7 +1429,7 @@ msgstr "Datum Bestandskraft bzw. Rechtskraft"
#: intervention/forms/intervention.py:216
#: intervention/tests/unit/test_forms.py:36
#: intervention/views/intervention.py:104
#: intervention/views/intervention.py:105
msgid "New intervention"
msgstr "Neuer Eingriff"
@@ -1597,7 +1598,12 @@ msgctxt "money"
msgid "Amount"
msgstr "Betrag"
#: intervention/templates/intervention/detail/includes/payments.html:62
#: intervention/templates/intervention/detail/includes/payments.html:61
#: konova/utils/message_templates.py:25
msgid "This data is not shared with you"
msgstr "Diese Daten sind für Sie nicht freigegeben"
#: intervention/templates/intervention/detail/includes/payments.html:70
msgid "Remove payment"
msgstr "Zahlung entfernen"
@@ -1659,19 +1665,19 @@ msgstr ""
msgid "Check performed"
msgstr "Prüfung durchgeführt"
#: intervention/views/intervention.py:56
#: intervention/views/intervention.py:57
msgid "Interventions - Overview"
msgstr "Eingriffe - Übersicht"
#: intervention/views/intervention.py:89
#: intervention/views/intervention.py:90
msgid "Intervention {} added"
msgstr "Eingriff {} hinzugefügt"
#: intervention/views/intervention.py:234
#: intervention/views/intervention.py:236
msgid "Intervention {} edited"
msgstr "Eingriff {} bearbeitet"
#: intervention/views/intervention.py:276
#: intervention/views/intervention.py:278
msgid "{} removed"
msgstr "{} entfernt"
@@ -1781,6 +1787,16 @@ msgstr ""
"Wenn aktiviert werden auch Einträge angezeigt, die nicht für Sie freigegeben "
"sind"
#: konova/filters/mixins/user_log.py:21
msgid "Logged user"
msgstr "Bearbeitender Nutzer"
#: konova/filters/mixins/user_log.py:22
msgid ""
"Search for entries where this person has been participated according to log "
"history"
msgstr "Sucht nach Einträgen, an denen diese Person gearbeitet hat"
#: konova/forms/base_form.py:23 templates/form/collapsable/form.html:62
msgid "Save"
msgstr "Speichern"
@@ -1799,10 +1815,6 @@ msgid "Only surfaces allowed. Points or lines must be buffered."
msgstr ""
"Nur Flächen erlaubt. Punkte oder Linien müssen zu Flächen gepuffert werden."
#: konova/forms/geometry_form.py:153
msgid "Geometry must be greater than 1m². Currently is {}m²"
msgstr "Geometrie muss größer als 1m² sein. Aktueller Flächeninhalt: {}m²"
#: konova/forms/modals/document_form.py:37
msgid "When has this file been created? Important for photos."
msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?"
@@ -1841,6 +1853,7 @@ msgstr ""
"Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen."
#: konova/forms/modals/remove_form.py:22 konova/forms/remove_form.py:24
#: user/forms/modals/api_token.py:16
msgid "Confirm"
msgstr "Bestätige"
@@ -1911,11 +1924,11 @@ msgstr "Kontrolle am"
msgid "Other"
msgstr "Sonstige"
#: konova/sub_settings/django_settings.py:166
#: konova/sub_settings/django_settings.py:156
msgid "German"
msgstr ""
#: konova/sub_settings/django_settings.py:167
#: konova/sub_settings/django_settings.py:157
msgid "English"
msgstr ""
@@ -2091,10 +2104,6 @@ msgstr ""
"Eintrag ist verzeichnet. Um Daten zu bearbeiten, muss der Eintrag erst "
"entzeichnet werden."
#: konova/utils/message_templates.py:25
msgid "This data is not shared with you"
msgstr "Diese Daten sind für Sie nicht freigegeben"
#: konova/utils/message_templates.py:26
msgid ""
"Remember: This data has not been shared with you, yet. This means you can "
@@ -2253,34 +2262,35 @@ msgstr ""
"Die Geometrie enthielt mehr als {} Eckpunkte. Sie musste vereinfacht werden "
"um die Obergrenze von {} erlaubten Eckpunkten einzuhalten."
#: konova/utils/message_templates.py:88
#: konova/utils/message_templates.py:86
msgid ""
"The geometry contained {} parts which have been detected as invalid (e.g. "
"too small to be valid). These parts have been removed. Please check the "
"stored geometry."
msgstr ""
"Die Geometrie enthielt {} invalide Bestandteile (z.B. unaussagekräftige Kleinstflächen)."
"Diese Bestandteile wurden automatisch entfernt. Bitte überprüfen Sie die angepasste Geometrie."
#: konova/utils/message_templates.py:89
msgid "This intervention has {} revocations"
msgstr "Dem Eingriff liegen {} Widersprüche vor"
#: konova/utils/message_templates.py:91
#: konova/utils/message_templates.py:92
msgid "Checked on {} by {}"
msgstr "Am {} von {} geprüft worden"
#: konova/utils/message_templates.py:92
#: konova/utils/message_templates.py:93
msgid "Data has changed since last check on {} by {}"
msgstr ""
"Daten wurden nach der letzten Prüfung geändert. Letzte Prüfung am {} durch {}"
#: konova/utils/message_templates.py:93
#: konova/utils/message_templates.py:94
msgid "Current data not checked yet"
msgstr "Momentane Daten noch nicht geprüft"
#: konova/utils/messenger.py:70
msgid "{} checked"
msgstr "{} geprüft"
#: konova/utils/messenger.py:72
msgid "<a href=\"{}\">Check it out</a>"
msgstr "<a href=\"{}\">Schauen Sie rein</a>"
#: konova/utils/messenger.py:73
msgid "{} has been checked successfully by user {}! {}"
msgstr "{} wurde erfolgreich vom Nutzer {} geprüft! {}"
#: konova/utils/message_templates.py:97
msgid "New token generated. Administrators need to validate."
msgstr "Neuer Token generiert. Administratoren sind informiert."
#: konova/utils/quality.py:32
msgid "missing"
@@ -2308,14 +2318,6 @@ msgstr "Home"
msgid "Log"
msgstr "Log"
#: konova/views/map_proxy.py:70
msgid ""
"The external service is currently unavailable.<br>Please try again in a few "
"moments..."
msgstr ""
"Der externe Dienst ist zur Zeit nicht erreichbar.<br>Versuchen Sie es in ein "
"paar Sekunden nochmal."
#: konova/views/record.py:30
msgid "{} unrecorded"
msgstr "{} entzeichnet"
@@ -2372,6 +2374,20 @@ msgstr "Alle"
msgid "News"
msgstr "Neuigkeiten"
#: templates/400.html:12
msgid "Request was invalid"
msgstr "Anfrage fehlerhaft"
#: templates/400.html:17
msgid "There seems to be a problem with the link you opened."
msgstr "Es scheint ein Problem mit dem Link zu geben, den Sie geöffnet haben."
#: templates/400.html:18
msgid "Make sure the URL is valid (no whitespaces, properly copied, ...)."
msgstr ""
"Stellen Sie sicher, dass die URL gültig ist (keine Leerzeichen, fehlerfrei "
"kopiert, ...)."
#: templates/404.html:7
msgid "Not found"
msgstr "Nicht gefunden"
@@ -2384,11 +2400,11 @@ msgstr "Die angeforderten Daten existieren nicht."
msgid "Make sure the URL is valid (no whitespaces, ...)."
msgstr "Stellen Sie sicher, dass die URL gültig ist (keine Leerzeichen, ...)."
#: templates/500.html:7
#: templates/500.html:12
msgid "Server Error"
msgstr ""
#: templates/500.html:10
#: templates/500.html:17
msgid "Something happened. Admins have been informed. We are working on it!"
msgstr ""
"Irgendetwas ist passiert. Die Administratoren wurden informiert. Wir "
@@ -2817,11 +2833,15 @@ msgstr "Mehr"
msgid "Reports"
msgstr "Berichte"
#: templates/navbars/navbar.html:56 user/templates/user/index.html:31
#: templates/navbars/navbar.html:57
msgid "Admin"
msgstr ""
#: templates/navbars/navbar.html:59 user/templates/user/index.html:31
msgid "Settings"
msgstr "Einstellungen"
#: templates/navbars/navbar.html:57
#: templates/navbars/navbar.html:60
msgid "Logout"
msgstr "Abmelden"
@@ -2854,6 +2874,22 @@ msgstr ""
"Falls die Geometrie nicht leer ist, werden die Flurstücke aktuell berechnet. "
"Bitte laden Sie diese Seite in ein paar Augenblicken erneut..."
#: user/forms/modals/api_token.py:25
msgid "Generate API Token"
msgstr "API Token generieren"
#: user/forms/modals/api_token.py:29
msgid ""
"You are about to create a new API token. The existing one will not be usable "
"afterwards."
msgstr ""
"Wenn Sie fortfahren, generieren Sie einen neuen API Token. Ihren "
"existierenden werden Sie dann nicht länger nutzen können."
#: user/forms/modals/api_token.py:31
msgid "A new token needs to be validated by an administrator!"
msgstr "Neue Tokens müssen durch Administratoren freigeschaltet werden!"
#: user/forms/modals/team.py:20 user/forms/modals/team.py:24
#: user/forms/team.py:17 user/forms/team.py:22
msgid "Team name"
@@ -2876,11 +2912,11 @@ msgstr ""
"Mehrfachauswahl möglich - Sie können nur Nutzer wählen, die noch nicht "
"Mitglieder dieses Teams sind. Geben Sie den ganzen Nutzernamen an."
#: user/forms/modals/team.py:56 user/tests/unit/test_forms.py:31
#: user/forms/modals/team.py:56 user/tests/unit/test_forms.py:30
msgid "Create new team"
msgstr "Neues Team anlegen"
#: user/forms/modals/team.py:57 user/tests/unit/test_forms.py:32
#: user/forms/modals/team.py:57 user/tests/unit/test_forms.py:31
msgid ""
"You will become the administrator for this group by default. You do not need "
"to add yourself to the list of members."
@@ -2909,11 +2945,11 @@ msgid "There must be at least one admin on this team."
msgstr "Es muss mindestens einen Administrator für das Team geben."
#: user/forms/modals/team.py:160 user/templates/user/team/index.html:60
#: user/tests/unit/test_forms.py:88
#: user/tests/unit/test_forms.py:87
msgid "Edit team"
msgstr "Team bearbeiten"
#: user/forms/modals/team.py:187 user/tests/unit/test_forms.py:165
#: user/forms/modals/team.py:187 user/tests/unit/test_forms.py:164
msgid ""
"ATTENTION!\n"
"\n"
@@ -2930,7 +2966,7 @@ msgstr ""
"Sind Sie sicher, dass Sie dieses Team löschen möchten?"
#: user/forms/modals/team.py:197 user/templates/user/team/index.html:56
#: user/tests/unit/test_forms.py:198
#: user/tests/unit/test_forms.py:197
msgid "Leave team"
msgstr "Team verlassen"
@@ -2962,22 +2998,10 @@ msgstr "Benachrichtigungen"
msgid "Select the situations when you want to receive a notification"
msgstr "Wann wollen Sie per E-Mail benachrichtigt werden?"
#: user/forms/user.py:38 user/tests/unit/test_forms.py:234
#: user/forms/user.py:38 user/tests/unit/test_forms.py:233
msgid "Edit notifications"
msgstr "Benachrichtigungen bearbeiten"
#: user/forms/user.py:73
msgid "Token"
msgstr ""
#: user/forms/user.py:88 user/tests/unit/test_forms.py:260
msgid "Create new token"
msgstr "Neuen Token generieren"
#: user/forms/user.py:89 user/tests/unit/test_forms.py:261
msgid "A new token needs to be validated by an administrator!"
msgstr "Neue Tokens müssen durch Administratoren freigeschaltet werden!"
#: user/models/user_action.py:23
msgid "Unrecorded"
msgstr "Entzeichnet"
@@ -3032,7 +3056,7 @@ msgid "Manage teams"
msgstr ""
#: user/templates/user/index.html:53 user/templates/user/team/index.html:19
#: user/views.py:171
#: user/views/views.py:135
msgid "Teams"
msgstr ""
@@ -3068,270 +3092,58 @@ msgstr "API Einstellungen"
msgid "Current token"
msgstr "Aktueller Token"
#: user/templates/user/token.html:14
#: user/templates/user/token.html:15
msgid "Create new token"
msgstr "Neuen Token generieren"
#: user/templates/user/token.html:23
msgid "Authenticated by admins"
msgstr "Von Admin freigeschaltet"
#: user/templates/user/token.html:18
#: user/templates/user/token.html:27
msgid "Token has been verified and can be used"
msgstr "Token wurde freigeschaltet und kann verwendet werden"
#: user/templates/user/token.html:20
#: user/templates/user/token.html:29
msgid "Token waiting for verification"
msgstr "Token noch nicht freigeschaltet"
#: user/templates/user/token.html:24
#: user/templates/user/token.html:33
msgid "Valid until"
msgstr "Läuft ab am"
#: user/views.py:35
msgid "User settings"
msgstr "Einstellungen"
#: user/views.py:61
msgid "Notifications edited"
msgstr "Benachrichtigungen bearbeitet"
#: user/views.py:73
msgid "User notifications"
msgstr "Benachrichtigungen"
#: user/views.py:96
msgid "New token generated. Administrators need to validate."
msgstr "Neuer Token generiert. Administratoren sind informiert."
#: user/views.py:107
#: user/views/api_token.py:34
msgid "User API token"
msgstr "API Nutzer Token"
#: user/views.py:183
#: user/views/views.py:33
msgid "User settings"
msgstr "Einstellungen"
#: user/views/views.py:59
msgid "Notifications edited"
msgstr "Benachrichtigungen bearbeitet"
#: user/views/views.py:71
msgid "User notifications"
msgstr "Benachrichtigungen"
#: user/views/views.py:147
msgid "New team added"
msgstr "Neues Team hinzugefügt"
#: user/views.py:198
#: user/views/views.py:162
msgid "Team edited"
msgstr "Team bearbeitet"
#: user/views.py:213
#: user/views/views.py:177
msgid "Team removed"
msgstr "Team gelöscht"
#: user/views.py:228
#: user/views/views.py:192
msgid "You are not a member of this team"
msgstr "Sie sind kein Mitglied dieses Teams"
#: user/views.py:235
#: user/views/views.py:199
msgid "Left Team"
msgstr "Team verlassen"
#~ msgid "close"
#~ msgstr "Schließen"
#~ msgid "Options"
#~ msgstr "Optionen"
#~ msgid "Commands"
#~ msgstr "Befehle"
#~ msgid "Missing command."
#~ msgstr "Befehl fehlt"
#~ msgid "Missing argument"
#~ msgstr "Argument fehlt"
#~ msgid "Missing option"
#~ msgstr "Option fehlt"
#~ msgid "Missing parameter"
#~ msgstr "Parameter fehlt"
#~ msgid "Messages"
#~ msgstr "Nachrichten"
#~ msgid "This field is required."
#~ msgstr "Pflichtfeld"
#~ msgid "Monday"
#~ msgstr "Montag"
#~ msgid "Tuesday"
#~ msgstr "Dienstag"
#~ msgid "Wednesday"
#~ msgstr "Mittwoch"
#~ msgid "Thursday"
#~ msgstr "Donnerstag"
#~ msgid "Friday"
#~ msgstr "Freitag"
#~ msgid "Saturday"
#~ msgstr "Samstag"
#~ msgid "Sunday"
#~ msgstr "Sonntag"
#~ msgid "Mon"
#~ msgstr "Mo"
#~ msgid "Tue"
#~ msgstr "Di"
#~ msgid "Wed"
#~ msgstr "Mi"
#~ msgid "Thu"
#~ msgstr "Do"
#~ msgid "Fri"
#~ msgstr "Fr"
#~ msgid "Sat"
#~ msgstr "Sa"
#~ msgid "Sun"
#~ msgstr "So"
#~ msgid "January"
#~ msgstr "Januar"
#~ msgid "February"
#~ msgstr "Februar"
#~ msgid "March"
#~ msgstr "März"
#~ msgid "May"
#~ msgstr "Mai"
#~ msgid "June"
#~ msgstr "Juni"
#~ msgid "July"
#~ msgstr "Juli"
#~ msgid "October"
#~ msgstr "Oktober"
#~ msgid "December"
#~ msgstr "Dezember"
#~ msgid "mar"
#~ msgstr "mär"
#~ msgid "may"
#~ msgstr "mai"
#~ msgid "oct"
#~ msgstr "okt"
#~ msgid "dec"
#~ msgstr "dez"
#~ msgctxt "abbrev. month"
#~ msgid "March"
#~ msgstr "Mär"
#~ msgctxt "abbrev. month"
#~ msgid "May"
#~ msgstr "Mai"
#~ msgctxt "abbrev. month"
#~ msgid "June"
#~ msgstr "Juni"
#~ msgctxt "abbrev. month"
#~ msgid "July"
#~ msgstr "Juli"
#~ msgctxt "abbrev. month"
#~ msgid "Oct."
#~ msgstr "Okt."
#~ msgctxt "abbrev. month"
#~ msgid "Dec."
#~ msgstr "Dez."
#~ msgctxt "alt. month"
#~ msgid "January"
#~ msgstr "Januar"
#~ msgctxt "alt. month"
#~ msgid "February"
#~ msgstr "Februar"
#~ msgctxt "alt. month"
#~ msgid "March"
#~ msgstr "März"
#~ msgctxt "alt. month"
#~ msgid "May"
#~ msgstr "Mai"
#~ msgctxt "alt. month"
#~ msgid "June"
#~ msgstr "Juni"
#~ msgctxt "alt. month"
#~ msgid "July"
#~ msgstr "Juli"
#~ msgctxt "alt. month"
#~ msgid "October"
#~ msgstr "Oktober"
#~ msgctxt "alt. month"
#~ msgid "December"
#~ msgstr "Dezember"
#~ msgid "or"
#~ msgstr "oder"
#~ msgid ""
#~ "Deductable surface can not be larger than existing surfaces in after "
#~ "states"
#~ msgstr ""
#~ "Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht "
#~ "überschreiten"
#~ msgid ""
#~ "Deductable surface can not be smaller than the sum of already existing "
#~ "deductions. Please contact the responsible users for the deductions!"
#~ msgstr ""
#~ "Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar "
#~ "einstellen wollen. Kontaktieren Sie die für die Abbuchungen "
#~ "verantwortlichen Nutzer!"
#~ msgid "Added deadline"
#~ msgstr "Frist/Termin hinzugefügt"
#~ msgid "Change default configuration for your KSP map"
#~ msgstr "Karteneinstellungen ändern"
#~ msgid "Map settings"
#~ msgstr "Karte"
#~ msgid "There are errors on this intervention:"
#~ msgstr "Es liegen Fehler in diesem Eingriff vor:"
#~ msgid "Before"
#~ msgstr "Vor"
#~ msgid "Groups"
#~ msgstr "Gruppen"
#~ msgid "Show more..."
#~ msgstr "Mehr anzeigen..."
#~ msgid "Kreis"
#~ msgstr "Kreis"
#~ msgid "Gemarkung"
#~ msgstr "Gemarkung"
#~ msgid "Loading..."
#~ msgstr "Lade..."
#~ msgid "Who handles the eco-account"
#~ msgstr "Wer für die Herrichtung des Ökokontos verantwortlich ist"

View File

@@ -1,65 +1,63 @@
amqp==5.2.0
amqp==5.3.1
asgiref==3.8.1
async-timeout==4.0.3
async-timeout==5.0.1
beautifulsoup4==4.13.0b2
billiard==4.2.0
cached-property==1.5.2
billiard==4.2.1
cached-property==2.0.1
celery==5.4.0
certifi==2024.7.4
cffi==1.17.0rc1
certifi==2024.12.14
cffi==1.17.1
chardet==5.2.0
charset-normalizer==3.3.2
click==8.1.7
charset-normalizer==3.4.0
click==8.1.8
click-didyoumean==0.3.1
click-plugins==1.1.1
click-repl==0.3.0
coverage==7.5.4
cryptography==42.0.8
Deprecated==1.2.14
Django==5.0.7
coverage==7.6.9
cryptography==44.0.0
Deprecated==1.2.15
Django==5.1.4
django-autocomplete-light==3.11.0
django-bootstrap-modal-forms==3.0.4
django-bootstrap4==24.3
django-bootstrap-modal-forms==3.0.5
django-bootstrap4==24.4
django-environ==0.11.2
django-filter==24.2
django-filter==24.3
django-fontawesome-5==1.0.18
django-oauth-toolkit==2.4.0
django-simple-sso==1.2.0
django-tables2==2.7.0
et-xmlfile==1.1.0
gunicorn==22.0.0
idna==3.7
importlib_metadata==8.0.0
itsdangerous==0.24
django-oauth-toolkit==3.0.1
django-tables2==2.7.1
et_xmlfile==2.0.0
gunicorn==23.0.0
idna==3.10
importlib_metadata==8.5.0
jwcrypto==1.5.6
kombu==5.4.0rc1
oauthlib==3.2.2
openpyxl==3.2.0b1
packaging==24.1
packaging==24.2
pika==1.3.2
pillow==10.4.0
prompt_toolkit==3.0.47
psycopg==3.2.1
psycopg-binary==3.2.1
pillow==11.0.0
prompt_toolkit==3.0.48
psycopg==3.2.3
psycopg-binary==3.2.3
pycparser==2.22
pyparsing==3.1.2
pyparsing==3.2.0
pypng==0.20220715.0
pyproj==3.6.1
pyproj==3.7.0
python-dateutil==2.9.0.post0
pytz==2024.1
PyYAML==6.0.2rc1
pytz==2024.2
PyYAML==6.0.2
qrcode==7.3.1
redis==5.1.0b6
requests<2.32.0
requests==2.32.3
six==1.16.0
soupsieve==2.5
sqlparse==0.5.0
sqlparse==0.5.1
typing_extensions==4.12.2
tzdata==2024.1
urllib3==2.2.2
tzdata==2024.2
urllib3==2.3.0
vine==5.1.0
wcwidth==0.2.13
webservices==0.7
wrapt==1.16.0
xmltodict==0.13.0
zipp==3.19.2
xmltodict==0.14.2
zipp==3.21.0

21
templates/400.html Normal file
View File

@@ -0,0 +1,21 @@
{% extends 'public_base.html' %}
{% load i18n fontawesome_5 static %}
{% block body %}
<div class="jumbotron">
<div class="row">
<div class="col-auto">
<img src="{% static 'images/error_imgs/croc_technician_400.png' %}" style="max-width: 150px">
</div>
<div class="col-sm-12 col-md-9 col-lg-9 col-xl-10">
<h1 class="display-4">{% fa5_icon 'question-circle' %}400</h1>
<h1 class="display-4">{% trans 'Request was invalid' %}</h1>
</div>
</div>
<hr>
<p class="lead">
{% trans 'There seems to be a problem with the link you opened.' %}
{% trans 'Make sure the URL is valid (no whitespaces, properly copied, ...).' %}
</p>
</div>
{% endblock %}

View File

@@ -1,10 +1,17 @@
{% extends 'public_base.html' %}
{% load i18n fontawesome_5 %}
{% load i18n fontawesome_5 static %}
{% block body %}
<div class="jumbotron">
<h1 class="display-4">{% fa5_icon 'fire-extinguisher' %} {% fa5_icon 'fire-alt' %} 500</h1>
<h1 class="display-4">{% trans 'Server Error' %}</h1>
<div class="row">
<div class="col-auto">
<img src="{% static 'images/error_imgs/croc_technician_500.png' %}" style="max-width: 150px">
</div>
<div class="col-sm-12 col-md-9 col-lg-9 col-xl-10">
<h1 class="display-4">{% fa5_icon 'fire-alt' %} 500</h1>
<h1 class="display-4">{% trans 'Server Error' %}</h1>
</div>
</div>
<hr>
<p class="lead">
{% trans 'Something happened. Admins have been informed. We are working on it!' %}

View File

@@ -1,170 +1,304 @@
{
"layers":
[
{ "folder": 5, "type": "WMS", "title": "KOM Flächen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=kom_f&", "name": "kom_f" },
{ "folder": 5, "type": "WMS", "title": "KOM Linien", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=kom_l&", "name": "kom_l" },
{ "folder": 5, "type": "WMS", "title": "KOM Punkte", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=komon&", "name": "kom_p" },
{ "folder": 6, "type": "WMS", "title": "EIV Flächen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=eiv_f&", "name": "eiv_f" },
{ "folder": 6, "type": "WMS", "title": "EIV Linien", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=eiv_l&", "name": "eiv_l" },
{ "folder": 6, "type": "WMS", "title": "EIV Punkte", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=eiv_p&", "name": "eiv_p" },
{ "folder": 7, "type": "WMS", "title": "OEK Flächen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=oek_f&", "name": "oek_f" },
{ "folder": 8, "type": "WMS", "title": "EMA Flächen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=ema_f&", "name": "ema_f" },
{ "folder": 9, "type": "WMS", "title": "MAE Flächen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=mae&", "name": "mae" },
{ "folder": 10, "type": "WMS", "title": "Naturschutzgebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=naturschutzgebiet&", "name": "naturschutzgebiet" },
{ "folder": 10, "type": "WMS", "title": "Naturparkzonen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=naturparkzonen&", "name": "naturparkzonen" },
{ "folder": 10, "type": "WMS", "title": "Landschaftsschutzgebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=landschaftsschutzgebiet&", "name": "landschaftsschutzgebiet" },
{ "folder": 10, "type": "WMS", "title": "Vogelschutzgebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=vogelschutzgebiet&", "name": "vogelschutzgebiet" },
{ "folder": 10, "type": "WMS", "title": "FFH Gebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=ffh&", "name": "ffh" },
{ "folder": 11, "type": "WMS", "title": "Nationalpark Zonen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=nationalpark_zonen&", "name": "nationalpark_zonen" },
{ "folder": 11, "type": "WMS", "title": "Nationalpark Grenzen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=nationalpark_grenze&", "name": "nationalpark_grenze" },
{ "folder": 12, "type": "WMS", "title": "Naturräume Grenzen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=natraum_lkompvo_grenzen&", "name": "natraum_lkompvo_grenzen" },
{ "folder": 12, "type": "WMS", "title": "Naturräume Flächen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=natraum_lkompvo&", "name": "natraum_lkompvo" },
{ "folder": 1, "type": "WMS", "title": "Lagebezeichnungen", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "Lagebezeichnungen" },
{ "folder": 1, "type": "WMS", "title": "Flurstücke (WMS)", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "Flurstueck", "active": true},
{ "folder": 1, "type": "WFS", "title": "Flurstücke (WFS; ab hoher Zoomstufe)", "url": "/client/proxy/wfs?", "name": "ave:Flurstueck", "minZoom": 17},
{ "folder": 1, "type": "WMS", "title": "Gebäude / Bauwerke", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "GebaeudeBauwerke" },
{ "folder": 1, "type": "WMS", "title": "Nutzung", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "Nutzung" },
{ "folder": 2, "type": "WMS", "title": "Landkreise", "url": "http://geo5.service24.rlp.de/wms/verwaltungsgrenzen_rp.fcgi?", "name": "Landkreise" },
{ "folder": 2, "type": "WMS", "title": "Verbandsgemeinden", "url": "http://geo5.service24.rlp.de/wms/verwaltungsgrenzen_rp.fcgi?", "name": "Verbandsgemeinden" },
{ "folder": 2, "type": "WMS", "title": "Gemeinden", "url": "http://geo5.service24.rlp.de/wms/verwaltungsgrenzen_rp.fcgi?", "name": "Gemeinden" },
{ "folder": 15, "type": "WMS", "order": -1, "title": "farbig", "attribution": "LVermGeo", "url": "https://maps.service24.rlp.de/gisserver/services/RP/RP_WebAtlasRP/MapServer/WmsServer?", "name": "RP_WebAtlasRP", "active": true},
{ "folder": 15, "type": "WMS", "title": "grau", "attribution": "LVermGeo", "url": "https://maps.service24.rlp.de/gisserver/services/RP/RP_ETRS_Gt/MapServer/WmsServer?", "name": "0", "active": false },
{ "folder": 0, "type": "WMS", "title": "Luftbilder", "attribution": "LVermGeo", "url": "http://geo4.service24.rlp.de/wms/dop_basis.fcgi?", "name": "rp_dop", "active": false },
{ "folder": 14, "type": "WMS", "title": "farbig", "attribution": "BKG", "url": "https://sgx.geodatenzentrum.de/wms_basemapde?", "name": "de_basemapde_web_raster_farbe", "active": false },
{ "folder": 14, "type": "WMS", "title": "grau", "attribution": "BKG", "url": "https://sgx.geodatenzentrum.de/wms_basemapde?", "name": "de_basemapde_web_raster_grau", "active": false },
{ "folder": 13, "type": "WMS", "title": "farbig", "attribution": "LVermGeo", "url": "https://geo4.service24.rlp.de/wms/dtk5_rp.fcgi?", "name": "rp_dtk5", "active": false },
{ "folder": 13, "type": "WMS", "title": "grau", "attribution": "LVermGeo", "url": "https://geo4.service24.rlp.de/wms/dtk5_rp.fcgi?", "name": "rp_dtk5_grau", "active": false }
],
"folders":
[
{ "title": "Hintergrund", "parent": -1 },
{ "title": "ALKIS Liegenschaften", "parent": -1 },
{ "title": "Verwaltungsgrenzen", "parent": -1 },
{ "title": "Geofachdaten", "parent": -1 },
{ "title": "Kompensationsverzeichnis", "parent": 3 },
{ "title": "Kompensationen", "parent": 4 },
{ "title": "Eingriffe", "parent": 4 },
{ "title": "Ökokonten", "parent": 4 },
{ "title": "EMA", "parent": 4 },
{ "title": "MAE", "parent": 4 },
{ "title": "Schutzgebiete", "parent": 3 },
{ "title": "Nationalparke", "parent": 10 },
{ "title": "Naturräume", "parent": 10 },
{ "title": "Topographisch (DTK5)", "parent": 0 },
{ "title": "BaseMap", "parent": 0 },
{ "title": "Webatlas", "parent": 0 }
],
"modules":
{
"menu": true,
"layertree": true,
"map": true,
"controls": true,
"attribution": true,
"info": true,
"searchplace": true,
"searchparcel": true,
"toolbox": true,
"import": true,
"export": true
},
"menu":
{
"header": "",
"items":
[
{ "id": "searchplace", "title": "<i class='fas fa-search'></i><span>Suche</span>" },
{ "id": "searchparcel", "title": "<i class='fas fa-vector-square'></i><span>Flurstücke</span>" },
{ "id": "toolbox", "title": "<i class='fas fa-tools'></i><span>Werkzeuge</span>" },
{ "id": "layertree", "title": "<i class='fas fa-layer-group'></i><span>Inhalte</span>" }
]
},
"projections":
[
[ "EPSG:25832", "+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs" ]
],
"map":
{
"projection": "EPSG:25832",
"center": [ 385000, 5543000 ],
"minZoom": 5,
"maxZoom": 22,
"center_lonlat": [ 7.0, 50.0 ],
"zoom": 9,
"attribution": "LANIS RLP",
"scalebar": true
},
"output":
{
"id": "netgis-storage"
},
"search":
{
"url": "/client/proxy?https://www.geoportal.rlp.de/mapbender/geoportal/gaz_geom_mobile.php?outputFormat=json&resultTarget=web&searchEPSG={epsg}&maxResults=5&maxRows=5&featureClass=P&style=full&searchText={q}&name_startsWith={q}"
"min_zoom": 5,
"max_zoom": 24,
"scalebar": true,
"move_tolerance": 5
},
"folders":
[
{ "id": "bg", "title": "Hintergrund", "parent": null , "radio": true},
{ "id": "alkis", "parent": null, "title": "ALKIS Liegenschaften" },
{ "id": "verwaltung", "parent": null, "title": "Verwaltungsgrenzen" },
{ "id": "fachdaten", "parent": null, "title": "Geofachdaten" },
{ "id": "ksp", "parent": "fachdaten", "title": "Kompensationsverzeichnis"},
{ "id": "schutzgebiet", "parent": "fachdaten", "title": "Schutzgebiete"},
{ "id": "nationalpark", "parent": "schutzgebiet", "title": "Nationalparke"},
{ "id": "naturraum", "parent": "schutzgebiet", "title": "Naturräume" },
{ "id": "kom", "parent": "ksp", "title": "Kompensationen" },
{ "id": "eiv", "parent": "ksp", "title": "Eingriffe" },
{ "id": "oek", "parent": "ksp", "title": "Ökokonten" },
{ "id": "ema", "parent": "ksp", "title": "EMA" },
{ "id": "mae", "parent": "ksp", "title": "MAE" }
],
"layers":
[
{ "id": "webatlas_farbe", "folder": "bg", "type": "WMS", "order": -1, "title": "WebatlasRP farbig", "attribution": "LVermGeo", "url": "https://maps.service24.rlp.de/gisserver/services/RP/RP_WebAtlasRP/MapServer/WmsServer?", "name": "RP_WebAtlasRP", "active": true},
{ "id": "webatlas_grau", "folder": "bg", "type": "WMS", "order": -1, "title": "WebatlasRP grau", "attribution": "LVermGeo", "url": "https://maps.service24.rlp.de/gisserver/services/RP/RP_ETRS_Gt/MapServer/WmsServer?", "name": "0", "active": false },
{ "id": "luftbilder", "folder": "bg", "type": "WMS", "order": -1, "title": "Luftbilder", "attribution": "LVermGeo", "url": "https://geo4.service24.rlp.de/wms/dop_basis.fcgi?", "name": "rp_dop", "active": false },
{ "id": "basemap_farbe", "folder": "bg", "type": "WMS", "order": -1, "title": "BasemapDE farbig", "attribution": "BKG", "url": "https://sgx.geodatenzentrum.de/wms_basemapde?", "name": "de_basemapde_web_raster_farbe", "active": false },
{ "id": "basemap_grau", "folder": "bg", "type": "WMS", "order": -1, "title": "BasemapDE grau", "attribution": "BKG", "url": "https://sgx.geodatenzentrum.de/wms_basemapde?", "name": "de_basemapde_web_raster_grau", "active": false },
{ "id": "dtk_farbe", "folder": "bg", "type": "WMS", "order": -1, "title": "DTK5 farbig", "attribution": "LVermGeo", "url": "https://geo4.service24.rlp.de/wms/dtk5_rp.fcgi?", "name": "rp_dtk5", "active": false },
{ "id": "dtk_grau", "folder": "bg", "type": "WMS", "order": -1, "title": "DTK5 grau", "attribution": "LVermGeo", "url": "https://geo4.service24.rlp.de/wms/dtk5_rp.fcgi?", "name": "rp_dtk5_grau", "active": false },
"searchParcel":
{ "id": "kom", "folder": "kom", "type": "WMS", "title": "KOM", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=kom_recorded&", "name": "kom_recorded" },
{ "id": "kom_rec", "folder": "kom", "type": "WMS", "title": "KOM - In Bearbeitung", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=kom_unrecorded&", "name": "kom_unrecorded" },
{ "id": "kom_rec_unfinished", "folder": "kom", "type": "WMS", "title": "KOM - Unvollständige Altfälle", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=kom_unrecorded_old_entries&", "name": "kom_unrecorded_old_entries" },
{ "id": "eiv", "folder": "eiv", "type": "WMS", "title": "EIV", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=eiv_recorded&", "name": "eiv_recorded" },
{ "id": "eiv_rec", "folder": "eiv", "type": "WMS", "title": "EIV - In Bearbeitung", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=eiv_unrecorded&", "name": "eiv_unrecorded" },
{ "id": "eiv_rec_unfinished", "folder": "eiv", "type": "WMS", "title": "EIV - Unvollständige Altfälle", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=eiv_unrecorded_old_entries&", "name": "eiv_unrecorded_old_entries" },
{ "id": "oek", "folder": "oek", "type": "WMS", "title": "OEK", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=oek_recorded&", "name": "oek_recorded" },
{ "id": "oek_rec", "folder": "oek", "type": "WMS", "title": "OEK - In Bearbeitung", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=oek_unrecorded&", "name": "oek_unrecorded" },
{ "id": "ema", "folder": "ema", "type": "WMS", "title": "EMA", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=ema_recorded&", "name": "ema_recorded" },
{ "id": "ema_rec", "folder": "ema", "type": "WMS", "title": "EMA - In Bearbeitung", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=ema_unrecorded&", "name": "ema_unrecorded" },
{ "id": "mae", "folder": "mae", "type": "WMS", "title": "MAE", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=mae&", "name": "mae" },
{ "id": "nsg", "folder": "schutzgebiet", "type": "WMS", "title": "Naturschutzgebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=naturschutzgebiet&", "name": "naturschutzgebiet" },
{ "id": "npz", "folder": "schutzgebiet", "type": "WMS", "title": "Naturparkzonen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=naturparkzonen&", "name": "naturparkzonen" },
{ "id": "lsg", "folder": "schutzgebiet", "type": "WMS", "title": "Landschaftsschutzgebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=landschaftsschutzgebiet&", "name": "landschaftsschutzgebiet" },
{ "id": "vsg", "folder": "schutzgebiet", "type": "WMS", "title": "Vogelschutzgebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=vogelschutzgebiet&", "name": "vogelschutzgebiet" },
{ "id": "ffh", "folder": "schutzgebiet", "type": "WMS", "title": "FFH Gebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=ffh&", "name": "ffh" },
{"id": "ntpz", "folder": "nationalpark", "type": "WMS", "title": "Nationalpark Zonen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=nationalpark_zonen&", "name": "nationalpark_zonen" },
{"id": "ntpg", "folder": "nationalpark", "type": "WMS", "title": "Nationalpark Grenzen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=nationalpark_grenze&", "name": "nationalpark_grenze" },
{ "id": "natraum_g", "folder": "naturraum", "type": "WMS", "title": "Naturräume Grenzen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=natraum_lkompvo_grenzen&", "name": "natraum_lkompvo_grenzen" },
{ "id": "natraum_f", "folder": "naturraum", "type": "WMS", "title": "Naturräume Flächen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=natraum_lkompvo&", "name": "natraum_lkompvo" },
{ "id": "lagebezeichnung", "folder": "alkis", "type": "WMS", "title": "Lagebezeichnungen", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "Lagebezeichnungen" },
{ "id": "flurstueck_wms", "folder": "alkis", "type": "WMS", "title": "Flurstücke (WMS)", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "Flurstueck", "active": true},
{ "id": "flurstueck_wfs", "folder": "alkis", "type": "WFS", "title": "Flurstücke (WFS; ab hoher Zoomstufe)", "url": "/client/proxy/wfs?", "name": "ave:Flurstueck", "minZoom": 17},
{ "id": "gebaeude", "folder": "alkis", "type": "WMS", "title": "Gebäude / Bauwerke", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "GebaeudeBauwerke" },
{ "id": "nutzung", "folder": "alkis", "type": "WMS", "title": "Nutzung", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "Nutzung" },
{ "id": "lk", "folder": "verwaltung", "type": "WMS", "title": "Landkreise", "url": "https://geo5.service24.rlp.de/wms/verwaltungsgrenzen_rp.fcgi?", "name": "Landkreise" },
{ "id": "vg", "folder": "verwaltung", "type": "WMS", "title": "Verbandsgemeinden", "url": "https://geo5.service24.rlp.de/wms/verwaltungsgrenzen_rp.fcgi?", "name": "Verbandsgemeinden" },
{ "id": "gmd", "folder": "verwaltung", "type": "WMS", "title": "Gemeinden", "url": "https://geo5.service24.rlp.de/wms/verwaltungsgrenzen_rp.fcgi?", "name": "Gemeinden" }
],
"layertree":
{
"nameURL": "/client/proxy?https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_alkis/gem_search.php?placename={q}",
"parcelURL": "/client/proxy?https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_alkis/flur_search.php?gmk_gmn={district}&fln={field}&fsn_zae={parcelA}&fsn_nen={parcelB}&export=json",
"open": false,
"title": "Inhalte",
"buttons":
[
{ "id": "import_layer", "title": "<i class='netgis-icon fas fa-plus' style='font-size: 1em;'></i><span>Hinzufügen...</span>" }
]
},
"controls":
{
"buttons":
[
{ "id": "zoom_in", "icon": "<i class='fas fa-plus'></i>", "title": "Zoom +" },
{ "id": "zoom_out", "icon": "<i class='fas fa-minus'></i>", "title": "Zoom -" },
{ "id": "zoom_home", "icon": "<i class='fas fa-home'></i>", "title": "Anfangsausdehung" }
]
},
"searchplace":
{
"title": "Adresse...",
"url": "/client/proxy?https://www.geoportal.rlp.de/mapbender/geoportal/gaz_geom_mobile.php?outputFormat=json&resultTarget=web&searchEPSG={epsg}&maxResults=5&maxRows=5&featureClass=P&style=full&searchText={query}&name_startsWith={query}",
"zoom": 17,
"marker_color": "darkgray",
"marker_title": "Such-Ergebnis"
},
"searchparcel":
{
"open": false,
"name_url": "/client/proxy?https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_alkis/gem_search.php?placename={q}",
"parcel_url": "/client/proxy?https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_alkis/flur_search.php?gmk_gmn={district}&fln={field}&fsn_zae={parcelA}&fsn_nen={parcelB}&export=json",
"districts_service":
{
"type": "WFS",
"url": "http://geo5.service24.rlp.de/wfs/verwaltungsgrenzen_rp.fcgi?",
"url": "https://geo5.service24.rlp.de/wfs/verwaltungsgrenzen_rp.fcgi?",
"name": "vermkv:gemarkungen_rlp",
"order": 10,
"minZoom": 11,
"maxZoom": 17
"format": "application/json; subtype=geojson",
"min_zoom": 12
},
"fields_service":
{
"url": "http://geo5.service24.rlp.de/wfs/verwaltungsgrenzen_rp.fcgi?",
"url": "https://geo5.service24.rlp.de/wfs/verwaltungsgrenzen_rp.fcgi?",
"name": "vermkv:fluren_rlp",
"filter_property": "gmkgnr"
}
},
"toolbox":
{
"open": false,
"items":
[
{ "id": "view", "title": "<i class='netgis-icon netgis-text-a fas fa-hand-paper'></i><span>Betrachten</span>" },
{ "id": "zoom_box", "title": "<i class='netgis-icon netgis-text-a fas fa-expand'></i><span>Zoom-Rechteck</span>" },
{ "id": "view_prev", "title": "<i class='netgis-icon netgis-text-a fas fa-step-backward'></i><span>Vorherige Ansicht</span>" },
{ "id": "view_next", "title": "<i class='netgis-icon netgis-text-a fas fa-step-forward'></i><span>Nächste Ansicht</span>" },
{ "id": "measure_line", "title": "<i class='netgis-icon netgis-text-a fas fa-ruler'></i><span>Strecke messen</span>" },
{ "id": "measure_area", "title": "<i class='netgis-icon netgis-text-a fas fa-ruler-combined'></i><span>Fläche messen</span>" },
{ "id": "measure_clear", "title": "<i class='netgis-icon netgis-text-a fas fa-trash-alt'></i><span>Messung löschen</span>" },
{ "id": "draw_points", "title": "<i class='netgis-icon netgis-text-a fas fa-map-marker-alt'></i><span>Punkte zeichnen</span>" },
{ "id": "draw_lines", "title": "<i class='netgis-icon netgis-text-a fas fa-minus'></i><span>Linien zeichnen</span>" },
{ "id": "draw_polygons", "title": "<i class='netgis-icon netgis-text-a fas fa-vector-square'></i><span>Polygone zeichnen</span>" },
{ "id": "modify_features", "title": "<i class='netgis-icon netgis-text-a fas fa-arrows-alt'></i><span>Verschieben</span>" },
{ "id": "delete_features", "title": "<i class='netgis-icon netgis-text-a fas fa-eraser'></i><span>Löschen</span>" },
{ "id": "buffer_features", "title": "<i class='netgis-icon netgis-text-a far fa-dot-circle'></i><span>Puffern</span>" },
{ "id": "cut_features", "title": "<i class='netgis-icon netgis-text-a fas fa-cut'></i><span>Ausschneiden</span>" },
{ "id": "import_layer", "title": "<i class='netgis-icon netgis-text-a fas fa-upload'></i><span>Importieren</span>" },
{ "id": "export", "title": "<i class='netgis-icon netgis-text-a fas fa-save'></i><span>Exportieren</span>" }
],
"options":
{
"buffer_features":
{
"title": "Puffern",
"items":
[
{ "id": "buffer_radius", "type": "integer", "title": "Radius (Meter)" },
{ "id": "buffer_segments", "type": "integer", "title": "Segmente" },
{ "id": "buffer_submit", "type": "button", "title": "<i class='netgis-icon netgis-text-a fas fa-arrow-circle-right'></i><span>Akzeptieren</span>" }
]
}
}
},
"import":
{
"geopackageLibURL": "/static/libs/geopackage/4.2.3/"
"title": "Ebene hinzufügen",
"preview": true,
"wms_options": [ "https://sgx.geodatenzentrum.de/wms_topplus_open" ],
"wfs_options": [ "http://213.139.159.34:80/geoserver/uesg/wfs" ],
"wfs_proxy": "/client/proxy?",
"geopackage_lib": "/static/libs/geopackage/4.2.3/"
},
"export":
{
"title": "Exportieren",
"logo": "/static/assets/logo.png",
"gifWebWorker": "/static/libs/gifjs/0.2.0/gif.worker.js",
"defaultFilename": "Export",
"defaultMargin": 10
"gif_worker": "/static/libs/gifjs/0.2.0/gif.worker.js",
"default_filename": "Export",
"default_margin": 10
},
"measure":
{
"line_color": "rgba( 255, 0, 0, 1.0 )",
"line_width": 3.0,
"line_dash": [ 5, 10 ],
"area_fill": "rgba( 255, 0, 0, 0.3 )",
"point_radius": 4.0,
"point_fill": "rgba( 255, 255, 255, 1.0 )",
"point_stroke": "rgba( 0, 0, 0, 1.0 )",
"text_color": "#871d33",
"text_back": "rgba( 255, 255, 255, 0.7 )"
},
"tools":
{
"editable": true,
"interactive_render": true,
"buffer":
{
"defaultRadius": 5,
"defaultSegments": 2
}
"default_radius": 5,
"default_segments": 3
},
"snapping":
{
"show": true,
"active": true,
"tolerance": 35
},
"bounds_message": "Ausserhalb des erlaubten Bereichs!",
"show_bounds": true
},
"output":
{
"id": "netgis-storage"
},
"attribution":
{
"prefix": "LANIS"
},
"styles":
{
"editLayer":
"draw":
{
"fill": "rgba( 255, 0, 0, 0.2 )",
"stroke": "#ff0000",
"strokeWidth": 3,
"pointRadius": 6
"fill": "rgba( 135, 29, 51, 0.5 )",
"stroke": "#871d33",
"width": 3,
"radius": 6,
"viewport_labels": true
},
"non_edit":
{
"fill": "rgba( 135, 29, 51, 0.5 )",
"stroke": "#871d33",
"width": 3,
"radius": 6,
"viewport_labels": true
},
"select":
{
"fill": "rgba( 0, 127, 255, 0.5 )",
"stroke": "#007fff",
"strokeWidth": 3,
"pointRadius": 6
"width": 3,
"radius": 6
},
"sketch":
{
"fill": "rgba( 0, 127, 255, 0.2 )",
"stroke": "#0080ff",
"strokeWidth": 3,
"pointRadius": 6
"fill": "rgba( 29, 135, 113, 0.5 )",
"stroke": "#1D8771",
"width": 3,
"radius": 6
},
"error":
{
"fill": "rgba( 255, 0, 0, 0.5 )",
"stroke": "#ff0000",
"width": 3,
"radius": 6
},
"bounds":
{
"fill": "rgba( 0, 0, 0, 0.0 )",
"stroke": "#000000",
"width": 3,
"radius": 6
},
"modify":
{
"fill": "rgba( 0, 127, 255, 0.5 )",
"stroke": "#0080ff",
"strokeWidth": 3,
"pointRadius": 6
"fill": "rgba( 29, 135, 113, 0.5 )",
"stroke": "#1D8771",
"width": 3,
"radius": 6
},
"parcel":
{
"fill": "rgba( 127, 255, 255, 0.5 )",
"stroke": "#7fffff",
"strokeWidth": 3
"fill": "rgba( 127, 0, 0, 0.2 )",
"stroke": "rgba( 127, 0, 0, 1.0 )",
"width": 2.5
},
"import":
{
"fill": "rgba( 0, 127, 255, 0.2 )",
@@ -172,4 +306,4 @@
"width": 1.5
}
}
}
}

File diff suppressed because one or more lines are too long

559
templates/map/client/dist/netgis.min.js vendored Normal file
View File

@@ -0,0 +1,559 @@
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.polyfill=function(a,b,c,d){if(b){c=$jscomp.global;a=a.split(".");for(d=0;d<a.length-1;d++){var e=a[d];e in c||(c[e]={});c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:b})}};$jscomp.polyfill("Number.parseFloat",function(a){return a||parseFloat},"es6","es3");$jscomp.polyfill("Number.parseInt",function(a){return a||parseInt},"es6","es3");
$jscomp.arrayIteratorImpl=function(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}};$jscomp.arrayIterator=function(a){return{next:$jscomp.arrayIteratorImpl(a)}};$jscomp.SYMBOL_PREFIX="jscomp_symbol_";$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.SymbolClass=function(a,b){this.$jscomp$symbol$id_=a;$jscomp.defineProperty(this,"description",{configurable:!0,writable:!0,value:b})};
$jscomp.SymbolClass.prototype.toString=function(){return this.$jscomp$symbol$id_};$jscomp.Symbol=function(){function a(c){if(this instanceof a)throw new TypeError("Symbol is not a constructor");return new $jscomp.SymbolClass($jscomp.SYMBOL_PREFIX+(c||"")+"_"+b++,c)}var b=0;return a}();
$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var a=$jscomp.global.Symbol.iterator;a||(a=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("Symbol.iterator"));"function"!=typeof Array.prototype[a]&&$jscomp.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return $jscomp.iteratorPrototype($jscomp.arrayIteratorImpl(this))}});$jscomp.initSymbolIterator=function(){}};
$jscomp.initSymbolAsyncIterator=function(){$jscomp.initSymbol();var a=$jscomp.global.Symbol.asyncIterator;a||(a=$jscomp.global.Symbol.asyncIterator=$jscomp.global.Symbol("Symbol.asyncIterator"));$jscomp.initSymbolAsyncIterator=function(){}};$jscomp.iteratorPrototype=function(a){$jscomp.initSymbolIterator();a={next:a};a[$jscomp.global.Symbol.iterator]=function(){return this};return a};
$jscomp.iteratorFromArray=function(a,b){$jscomp.initSymbolIterator();a instanceof String&&(a+="");var c=0,d={next:function(){if(c<a.length){var e=c++;return{value:b(e,a[e]),done:!1}}d.next=function(){return{done:!0,value:void 0}};return d.next()}};d[Symbol.iterator]=function(){return d};return d};$jscomp.polyfill("Array.prototype.values",function(a){return a?a:function(){return $jscomp.iteratorFromArray(this,function(a,c){return c})}},"es8","es3");
$jscomp.polyfill("Number.isNaN",function(a){return a?a:function(a){return"number"===typeof a&&isNaN(a)}},"es6","es3");$jscomp.owns=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};$jscomp.assign="function"==typeof Object.assign?Object.assign:function(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c];if(d)for(var e in d)$jscomp.owns(d,e)&&(a[e]=d[e])}return a};$jscomp.polyfill("Object.assign",function(a){return a||$jscomp.assign},"es6","es3");var netgis=netgis||{};
netgis.Attribution=function(a){this.config=a;this.layers=this.client=null;this.items=[];this.initElements(a);this.initConfig(a)};netgis.Attribution.Config={prefix:"NetGIS"};netgis.Attribution.prototype.initElements=function(a){this.container=document.createElement("section");this.container.className="netgis-attribution netgis-text-a";var b=this;window.setTimeout(function(){b.update()},100)};
netgis.Attribution.prototype.initConfig=function(a){if(a&&(a.attribution&&a.attribution.prefix&&this.items.push(a.attribution.prefix),a=a.layers))for(var b=0;b<a.length;b++){var c=a[b],d=c.attribution;d&&0!==d.length&&c.active&&this.items.push(d)}};
netgis.Attribution.prototype.attachTo=function(a){a.appendChild(this.container);a.addEventListener(netgis.Events.CLIENT_CONTEXT_RESPONSE,this.onContextUpdate.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_TOGGLE,this.onMapLayerToggle.bind(this));a.addEventListener(netgis.Events.MAP_EDIT_LAYER_CHANGE,this.onEditLayerChange.bind(this))};netgis.Attribution.prototype.update=function(){var a="&copy; "+this.items.join(", ");this.appendix&&(a+=", "+this.appendix);this.container.innerHTML=a};
netgis.Attribution.prototype.add=function(a){for(var b=0;b<this.items.length;b++)if(this.items[b]===a)return;this.items.push(a);this.update()};netgis.Attribution.prototype.remove=function(a){for(var b=0;b<this.items.length;b++)if(this.items[b]===a){this.items.splice(b,1);break}this.update()};netgis.Attribution.prototype.onMapLayerToggle=function(a){a=a.detail;for(var b=this.config.layers,c=null,d=0;d<b.length;d++){var e=b[d];e.id===a.id&&(c=e.attribution)}c&&(a.on?this.add(c):this.remove(c))};
netgis.Attribution.prototype.onContextUpdate=function(a){this.initConfig(a.detail.context.config);this.update()};netgis.Attribution.prototype.onContextUpdate_01=function(a){config.attribution&&config.attribution.prefix&&this.items.push(config.attribution.prefix);this.layers=[];for(var b=0;b<a.layers.length;b++){var c=a.layers[b];c.attribution&&0<c.attribution.length&&(this.layers[c.id]=c.attribution)}for(b=0;b<a.layers.length;b++)if(c=a.layers[b],c.active)this.onLayerShow({id:c.id})};
netgis.Attribution.prototype.onLayerShow=function(a){if(a=this.layers[a.id]){for(var b=0;b<this.items.length;b++)if(this.items[b]===a)return;this.items.push(a);this.update()}};netgis.Attribution.prototype.onLayerHide=function(a){if(a=this.layers[a.id]){for(var b=0;b<this.items.length;b++)if(this.items[b]===a){this.items.splice(b,1);break}this.update()}};
netgis.Attribution.prototype.onEditLayerChange=function(a){a=a.detail.geojson.area;for(var b=0;b<this.items.length;b++)if(-1<this.items[b].search("Zeichnungsfl\u00e4che: ")){this.items.splice(b,1);break}this.appendix=a&&0<a?"<b>Zeichnungsfl\u00e4che: "+netgis.util.formatArea(a,!0)+"</b>":null;this.update()};netgis=netgis||{};netgis.Client=function(a,b){b||(b={});a=this.initLegacyConfig(b,a);this.container=this.initContainer(a);this.debug=!1;netgis.util.isString(b)?netgis.util.isJSON(b,!1)?(b=JSON.parse(b),this.init(this.container,b)):(this.showLoader(!0),netgis.util.request(b,this.onConfigResponse.bind(this))):this.init(this.container,b)};netgis.Client.Config={loading_text:"Geoportal Client wird geladen..."};netgis.Client.Output={id:"netgis-storage"};
netgis.Client.prototype.init=function(a,b){this.config=b;this.initParams(b);this.initConfig(b);this.initElements(a);this.initEvents();this.initModules(b);this.initOutput(b);a=new netgis.ContextMenu;a.attachTo(this.container);this.modules.contextmenu=a;this.popup=new netgis.Popup;this.popup.attachTo(this.container)};
netgis.Client.prototype.initLegacyConfig=function(a,b){var c=netgis.config;if(!c)return b;c.MAP_CONTAINER_ID&&(b=c.MAP_CONTAINER_ID);a.modules||(a.modules={menu:!0,map:!0,controls:!0,attribution:!0,legend:!0,layertree:!0,info:!0,searchplace:!0,geolocation:!0});a.map||(a.map={});!c.INITIAL_CENTER_X&&0!==c.INITIAL_CENTER_X||!c.INITIAL_CENTER_Y&&0!==c.INITIAL_CENTER_Y||(a.map.center=[c.INITIAL_CENTER_X,c.INITIAL_CENTER_Y]);a.map.scalebar=!0;c.INITIAL_SCALE&&(a.map.scale=c.INITIAL_SCALE);c.MAP_SCALES&&
(a.map.scales=c.MAP_SCALES);c.MAP_EXTENT&&(a.map.extent=c.MAP_EXTENT);c.MAX_HISTORY&&(a.map.max_view_history=c.MAX_HISTORY);a.attribution={prefix:"GeoPortal"};c.MAP_PROJECTIONS&&(a.projections=c.MAP_PROJECTIONS);c.MAP_PROJECTION&&(a.map.projection=c.MAP_PROJECTION);a.controls={buttons:[{id:"zoom_in",icon:"<i class='fas fa-plus'></i>",title:"Zoom +"},{id:"zoom_out",icon:"<i class='fas fa-minus'></i>",title:"Zoom -"},{id:"geolocation",icon:"<i class='fas fa-crosshairs'></i>",title:"Ger\u00e4testandort"},
{id:"zoom_home",icon:"<i class='fas fa-home'></i>",title:"Anfangsausdehung"},{id:"legend",icon:"<i class='fas fa-bars'></i>",title:"Legende"}]};a.folders||(a.folders=[{id:"bg",title:"Hintergrund",parent:null,radio:!0}]);a.layers||(a.layers=[]);if(c.URL_BACKGROUND_HYBRID){var d=c.URL_BACKGROUND_HYBRID;-1!==d.indexOf("{x}")||-1!==d.indexOf("{y}")&&-1!==d.indexOf("{-y}")||-1!==d.indexOf("{z}")||(d+="/{z}/{x}/{-y}.jpeg");d={id:"bg_hybrid",active:!0,folder:"bg",order:1,title:"Hybrid",type:"TMS",url:d,
projection:"EPSG:25832",extent:"map",scales:"map",transparency:0};a.layers.push(d)}c.URL_BACKGROUND_AERIAL&&(d=c.URL_BACKGROUND_AERIAL,d={id:"bg_aerial",folder:"bg",order:1,title:"Luftbild",type:"WMS",url:d,query:!1,transparency:0},a.layers.push(d));c.URL_HEIGHT_REQUEST&&(d=c.URL_HEIGHT_REQUEST,-1===d.indexOf("{x}")&&-1===d.indexOf("{y}")&&(d+="&coord={x},{y}"),d={id:"dem_hidden",title:"Digitales H\u00f6henmodell",hidden:!0,active:!0,query:!0,type:"HIDDEN",query_url:d},a.layers.push(d));a.layertree||
(a.layertree={});a.layertree.title="Ebenen";a.info||(a.info={});a.info.default_format="text/html";c.URL_FEATURE_INFO_PROXY&&0<c.URL_FEATURE_INFO_PROXY.length&&(a.info.proxy=c.URL_FEATURE_INFO_PROXY);a.menu||(a.menu={header:"GeoPortal",compact:!0,items:[{title:"<i class='fas fa-tools'></i><span>Tools</span>",items:[{id:"view",title:"<i class='netgis-icon fas fa-hand-paper'></i><span>Betrachten</span>"},{id:"zoom_box",title:"<i class='netgis-icon fas fa-expand'></i><span>Zoom-Rechteck</span>"},{id:"measure_line",
title:"<i class='netgis-icon fas fa-ruler'></i><span>Strecke messen</span>"},{id:"measure_area",title:"<i class='netgis-icon fas fa-ruler-combined'></i><span>Fl\u00e4che messen</span>"},{id:"measure_clear",title:"<i class='netgis-icon fas fa-trash-alt'></i><span>Messung l\u00f6schen</span>"}]},{id:"layertree",title:"<i class='fas fa-layer-group'></i><span>Ebenen</span>"}]},c.MAP_SCALES&&0<c.MAP_SCALES.length&&a.menu.items.unshift({title:"<i class='far fa-eye'></i><span>Ansicht</span>",items:[{id:"view_prev",
title:"<i class='fas fa-step-backward'></i><span>Vorherige</span>"},{id:"view_next",title:"<i class='fas fa-step-forward'></i><span>N\u00e4chste</span>"},{id:"scales",title:"<i class='fas fa-ruler-horizontal'></i><span>Ma\u00dfstab</span><i class='fas fa-caret-right'></i>",items:[]}]}),c.URL_USAGE_TERMS&&0<c.URL_USAGE_TERMS.length&&a.menu.items.unshift({title:"<i class='fas fa-info-circle'></i><span>Info</span>",items:[{url:c.URL_USAGE_TERMS,title:"<i class='fas fa-external-link-alt'></i><span>Nutzungsbedingungen</span>"}]}));
c.URL_SEARCH_REQUEST&&(d=c.URL_SEARCH_REQUEST,-1===d.indexOf("{query}")&&(d+="?outputFormat=json&resultTarget=web&searchEPSG=4326&maxResults=5&maxRows=5&featureClass=P&style=full&searchText={query}&name_startsWith={query}"),c.URL_SEARCH_PROXY&&0<c.URL_SEARCH_PROXY.length&&(d=c.URL_SEARCH_PROXY+"?"+d),a.menu.items.unshift({id:"searchplace",title:"<i class='fas fa-search'></i><span>Suche</span>"}),a.searchplace={title:"Suche...",url:d});a.wmc||(a.wmc={});if(c.URL_WMC_REQUEST){d=c.URL_WMC_REQUEST;if(-1===
d.indexOf("{id}")){var e="mobilemap2";c.CONF_FILE_NAME&&0<c.CONF_FILE_NAME.length&&(e=c.CONF_FILE_NAME);d+="?confFileName="+e+"&epsg=25832&withHierarchy=1&wmc_id={id}"}c.URL_WMC_PROXY&&0<c.URL_WMC_PROXY.length&&(d=c.URL_WMC_PROXY+"?"+d);a.wmc.url=d}c.URL_LAYERS_REQUEST&&(d=c.URL_LAYERS_REQUEST,-1===d.indexOf("{ids}")&&(d+="?languageCode=de&resultTarget=web&maxResults=40&resourceIds={ids}"),c.URL_LAYERS_PROXY&&0<c.URL_LAYERS_PROXY.length&&(d=c.URL_LAYERS_PROXY+"?"+d),a.wmc.layers_url=d);return b};
netgis.Client.prototype.initContainer=function(a){netgis.util.isString(a)&&(a=document.getElementById(a));a.classList.add("netgis-client","netgis-font");return a};
netgis.Client.prototype.initParams=function(a){var b=window.location.search.substr(1);b=b.split("&");this.params={};for(var c=0;c<b.length;c++){var d=b[c].split("="),e=d[0].toLowerCase();d=d[1];e&&""!==e&&(this.params[e]=d)}for(e in this.params)switch(d=this.params[e],e){case "wmc_id":a.wmc&&(a.wmc.id=d);break;case "layerid":a&&a.wmc&&a.wmc.layers_url&&(b=a.wmc.layers_url,b=netgis.util.replace(b,"{ids}",d),netgis.util.request(b,this.onContextResponseLayer.bind(this)))}};
netgis.Client.prototype.initConfig=function(a){a&&a.wmc&&a.wmc.url&&this.requestContextWMC(a.wmc.url,a.wmc.id);a&&a.ows&&a.ows.url&&this.requestContextOWS(a.ows.url)};
netgis.Client.prototype.initElements=function(a){if(a.hasAttribute("data-lon")){var b=Number.parseFloat(a.getAttribute("data-lon"));this.config.map.center_lonlat||(this.config.map.center_lonlat=[]);this.config.map.center_lonlat[0]=b}a.hasAttribute("data-lat")&&(b=Number.parseFloat(a.getAttribute("data-lat")),this.config.map.center_lonlat||(this.config.map.center_lonlat=[]),this.config.map.center_lonlat[1]=b);a.hasAttribute("data-zoom")&&(b=Number.parseFloat(a.getAttribute("data-zoom")),this.config.map.zoom=
b);a.hasAttribute("data-bounds")&&(b=a.getAttribute("data-bounds"),this.config.tools.bounds=b);a.hasAttribute("data-editable")&&(a="true"===a.getAttribute("data-editable"),this.config.tools||(this.config.tools={}),this.config.tools.editable=a)};
netgis.Client.prototype.initOutput=function(a){var b;if(a.output&&a.output.id){var c=a.output.id;console.warn('config[ "output" ][ "id" ] is deprecated, use config[ "tools" ][ "output_id" ] instead')}a.tools&&(a.tools.output_id&&(c=a.tools.output_id),a.tools.output_name&&(b=a.tools.output_name));if(c){if((a=document.getElementById(c))&&a.value&&0<a.value.length){var d=JSON.parse(a.value);netgis.util.invoke(this.container,netgis.Events.MAP_EDIT_LAYER_LOADED,{geojson:d})}this.output=a}this.output||
(this.output=document.createElement("input"),this.output.className="netgis-storage",this.output.setAttribute("type","hidden"),c&&this.output.setAttribute("id",c),b&&this.output.setAttribute("name",b),this.container.appendChild(this.output))};
netgis.Client.prototype.initModules=function(a){this.modules={};if(a=a.modules)a.map&&this.addModule("map",netgis.Map),a.controls&&this.addModule("controls",netgis.Controls),a.attribution&&this.addModule("attribution",netgis.Attribution),a.legend&&this.addModule("legend",netgis.Legend),a.geolocation&&this.addModule("geolocation",netgis.Geolocation),a.info&&this.addModule("info",netgis.Info),a.menu&&this.addModule("menu",netgis.Menu),a.layertree&&this.addModule("layertree",netgis.LayerTree),a.searchplace&&
this.addModule("searchplace",netgis.SearchPlace),a.searchparcel&&this.addModule("searchparcel",netgis.SearchParcel),a.toolbox&&this.addModule("toolbox",netgis.Toolbox),a["import"]&&this.addModule("import",netgis.Import),a["export"]&&this.addModule("export",netgis.Export),a.timeslider&&this.addModule("timeslider",netgis.TimeSlider),a.plugins&&this.addModule("plugins",netgis.Plugins)};
netgis.Client.prototype.initEvents=function(){this.container.addEventListener(void 0,function(a){console.error("undefined event invoked",a)});for(var a in netgis.Events)this.container.addEventListener(netgis.Events[a],this.handleEvent.bind(this));this.container.addEventListener(netgis.Events.MAP_EDIT_LAYER_CHANGE,this.onMapEditLayerChange.bind(this))};
netgis.Client.prototype.showLoader=function(a){this.loader||(this.loader=document.createElement("div"),this.loader.className="netgis-loader netgis-color-e netgis-text-a",this.loader.innerHTML="<i class='fas fa-cog'></i>",this.config&&this.config.client&&this.config.client.loading_text&&(this.loader.innerHTML+="<h2>"+this.config.client.loading_text+"</h2>"),this.container.appendChild(this.loader));!1===a?(this.loader.classList.add("netgis-fade"),this.loaderTimeout=window.setTimeout(function(){this.loader.classList.add("netgis-hide");
this.loaderTimeout=null}.bind(this),600)):(this.loader.classList.remove("netgis-hide"),this.loader.classList.remove("netgis-fade"),this.loaderTimeout&&(window.clearTimeout(this.loaderTimeout),this.loaderTimeout=null))};netgis.Client.prototype.handleEvent=function(a){var b=a.type;a=a.detail;!0===this.debug&&console.info("EVENT:",b,a)};netgis.Client.prototype.addModule=function(a,b){b=new b(this.config);b.attachTo&&b.attachTo(this.container);return this.modules[a]=b};
netgis.Client.prototype.isMobile=function(){return netgis.util.isMobile(this.container)};netgis.Client.prototype.onConfigResponse=function(a){a=JSON.parse(a);this.init(this.container,a);this.showLoader(!1)};netgis.Client.prototype.requestContextWMC=function(a,b){if(-1<a.indexOf("{id}"))if(b)a=netgis.util.replace(a,"{id}",b);else{console.warn("No WMC id set in config for url",a);return}(new netgis.WMC(this.config)).requestContext(a,this.onContextResponseWMC.bind(this));this.showLoader(!0)};
netgis.Client.prototype.onContextResponseWMC=function(a){console.info("WMC Response:",a);for(var b=0;b<a.config.layers.length;b++)this.config.layers.push(a.config.layers[b]);a.config.map.bbox&&(this.config.map.bbox=a.config.map.bbox);netgis.util.invoke(this.container,netgis.Events.CLIENT_CONTEXT_RESPONSE,{context:a});this.showLoader(!1)};
netgis.Client.prototype.onContextResponseLayer=function(a){var b=JSON.parse(a);console.info("Layer Response:",b);a=new netgis.WMC;b=b.wms.srv[0];a=a.parseServiceLayer(b.id.toString(),b,null,b.layer[0],null);this.config.layers.push(a);netgis.util.invoke(this.container,netgis.Events.MAP_LAYER_CREATE,a)};netgis.Client.prototype.requestContextOWS=function(a){console.info("Request OWS:",a);netgis.util.request(a,this.onContextResponseOWS.bind(this))};
netgis.Client.prototype.onContextResponseOWS=function(a){a=JSON.parse(a);console.info("OWS Response:",a);a=netgis.OWS.read(a,this);console.info("OWS Config:",a)};netgis.Client.prototype.onIconbarIconClick=function(a){switch(a.detail.id){case "home":a=this.config.layers;for(var b=0;b<a.length;b++){var c=a[b],d=c.id;!0===c.active?(this.modules.map.addLayer(d,c),this.modules.layertree.tree.setItemChecked(d,!0)):(this.modules.map.removeLayer(d),this.modules.layertree.tree.setItemChecked(d,!1))}}};
netgis.Client.prototype.onIconbarItemClick=function(a){a=a.detail;for(var b=this.config.layers,c=0;c<b.length;c++){var d=b[c],e=d.id;"background"!==d.folder&&(e===a.id?(this.modules.map.addLayer(e,d),this.modules.layertree.tree.setItemChecked(e,!0)):(this.modules.map.removeLayer(e),this.modules.layertree.tree.setItemChecked(e,!1)))}};
netgis.Client.prototype.onSwitcherButtonClick=function(a){a=a.detail;for(var b=this.config.switcher.buttons,c=this.config.layers,d=0;d<b.length;d++){var e=b[d].id;if(e===a.id)for(var f=0;f<c.length;f++){var g=c[f];g.id===e&&(this.modules.map.addLayer(e,g),this.modules.layertree.tree.setItemChecked(e,!0))}else this.modules.map.removeLayer(e),this.modules.layertree.tree.setItemChecked(e,!1)}0===this.modules.switcher.getIndex(a.id)&&this.modules.switcher.shift(1,0)};
netgis.Client.prototype.onGeolocationToggle=function(a){this.modules.map.setGeolocMarkerVisible(a.detail.on)};netgis.Client.prototype.onGeolocationChange=function(a){a=a.detail;this.modules.map.zoomLonLat(a.lon,a.lat,this.config.geolocation.zoom);this.modules.map.setGeolocMarkerLonLat(a.lon,a.lat)};netgis.Client.prototype.onMapEditLayerChange=function(a){a=JSON.stringify(a.detail.geojson);this.output.value=a};
netgis.Client.handleCommand=function(a,b){var c=b.split(":");b=c[0];switch(b.toUpperCase()){case netgis.Commands.PLUGIN:b=c[1];if(!b){console.error("missing second command parameter id",c);break}netgis.util.invoke(a,netgis.Events.PLUGIN_TOGGLE,{id:b});break;case netgis.Commands.LAYERTREE:netgis.util.isMobile()?netgis.util.invoke(a,netgis.Events.LAYERTREE_TOGGLE,{on:!0}):netgis.util.invoke(a,netgis.Events.LAYERTREE_TOGGLE,null);break;case netgis.Commands.SEARCHPLACE:netgis.util.isMobile()?netgis.util.invoke(a,
netgis.Events.SEARCHPLACE_TOGGLE,{on:!0}):netgis.util.invoke(a,netgis.Events.SEARCHPLACE_TOGGLE,null);break;case netgis.Commands.SEARCHPARCEL:netgis.util.isMobile()?netgis.util.invoke(a,netgis.Events.SEARCHPARCEL_TOGGLE,{on:!0}):netgis.util.invoke(a,netgis.Events.SEARCHPARCEL_TOGGLE,null);break;case netgis.Commands.TOOLBOX:netgis.util.isMobile()?netgis.util.invoke(a,netgis.Events.TOOLBOX_TOGGLE,{on:!0}):netgis.util.invoke(a,netgis.Events.TOOLBOX_TOGGLE,null);break;case netgis.Commands.LEGEND:netgis.util.isMobile()?
netgis.util.invoke(a,netgis.Events.LEGEND_TOGGLE,{on:!0}):netgis.util.invoke(a,netgis.Events.LEGEND_TOGGLE,null);break;case netgis.Commands.VIEW_PREV:netgis.util.invoke(a,netgis.Events.MAP_VIEW_PREV,null);break;case netgis.Commands.VIEW_NEXT:netgis.util.invoke(a,netgis.Events.MAP_VIEW_NEXT,null);break;case netgis.Commands.VIEW:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.VIEW});break;case netgis.Commands.ZOOM_BOX:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.ZOOM_BOX});
break;case netgis.Commands.ZOOM_SCALE:c=Number.parseInt(a.innerText.split(":")[1]);netgis.util.invoke(a,netgis.Events.MAP_ZOOM_SCALE,{scale:c,anim:!0});break;case netgis.Commands.MEASURE_LINE:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.MEASURE_LINE});break;case netgis.Commands.MEASURE_AREA:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.MEASURE_AREA});break;case netgis.Commands.MEASURE_CLEAR:netgis.util.invoke(a,netgis.Events.MEASURE_CLEAR,null);break;
case netgis.Commands.DRAW_POINTS:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.DRAW_POINTS});break;case netgis.Commands.DRAW_LINES:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.DRAW_LINES});break;case netgis.Commands.DRAW_POLYGONS:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.DRAW_POLYGONS});break;case netgis.Commands.MODIFY_FEATURES:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.MODIFY_FEATURES});break;
case netgis.Commands.DELETE_FEATURES:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.DELETE_FEATURES});break;case netgis.Commands.BUFFER_FEATURES:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.BUFFER_FEATURES_DYNAMIC});break;case netgis.Commands.CUT_FEATURES:netgis.util.invoke(a,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.CUT_FEATURES});break;case netgis.Commands.IMPORT_LAYER:netgis.util.invoke(a,netgis.Events.IMPORT_LAYER_SHOW,null);break;case netgis.Commands.EXPORT:netgis.util.invoke(a,
netgis.Events.EXPORT_SHOW,null);break;case netgis.Commands.GEOLOCATION:netgis.util.invoke(a,netgis.Events.GEOLOCATION_SHOW_OPTIONS,null);break;default:console.error("unhandled command id",b)}};netgis=netgis||{};
netgis.Commands={PLUGIN:"PLUGIN",LAYERTREE:"LAYERTREE",SEARCHPLACE:"SEARCHPLACE",SEARCHPARCEL:"SEARCHPARCEL",TOOLBOX:"TOOLBOX",LEGEND:"LEGEND",VIEW_PREV:"VIEW_PREV",VIEW_NEXT:"VIEW_NEXT",VIEW:"VIEW",ZOOM_BOX:"ZOOM_BOX",ZOOM_SCALE:"ZOOM_SCALE",MEASURE_LINE:"MEASURE_LINE",MEASURE_AREA:"MEASURE_AREA",MEASURE_CLEAR:"MEASURE_CLEAR",DRAW_POINTS:"DRAW_POINTS",DRAW_LINES:"DRAW_LINES",DRAW_POLYGONS:"DRAW_POLYGONS",MODIFY_FEATURES:"MODIFY_FEATURES",DELETE_FEATURES:"DELETE_FEATURES",BUFFER_FEATURES:"BUFFER_FEATURES",CUT_FEATURES:"CUT_FEATURES",
SNAP_TOGGLE:"SNAP_TOGGLE",IMPORT_LAYER:"IMPORT_LAYER",EXPORT:"EXPORT",GEOLOCATION:"GEOLOCATION"};netgis=netgis||{};netgis.ContextMenu=function(){this.initElements()};netgis.ContextMenu.prototype.initElements=function(){this.container=document.createElement("div");this.container.className="netgis-contextmenu netgis-shadow-large netgis-color-e netgis-hide"};
netgis.ContextMenu.prototype.attachTo=function(a){a.appendChild(this.container);a.addEventListener(netgis.Events.CONTEXTMENU_SHOW,this.onContextMenuShow.bind(this));a.addEventListener("click",this.onParentClick.bind(this));a.addEventListener("pointerup",this.onParentClick.bind(this));a.addEventListener("scroll",this.onParentScroll.bind(this),!0);a.addEventListener("keydown",this.onParentKeyDown.bind(this))};netgis.ContextMenu.prototype.clear=function(){this.container.innerHTML=""};
netgis.ContextMenu.prototype.addButton=function(a,b){var c=document.createElement("button");c.className="netgis-button netgis-clip-text netgis-hover-d";c.innerHTML=b;c.setAttribute("type","button");c.setAttribute("data-id",a);c.addEventListener("click",this.onButtonClick.bind(this));this.container.appendChild(c);return c};
netgis.ContextMenu.prototype.addCheckbox=function(a,b,c){var d=document.createElement("label");d.className="netgis-noselect netgis-hover-d";var e=document.createElement("input");e.setAttribute("type","checkbox");e.setAttribute("title",b);e.setAttribute("data-id",a);e.checked=c;e.addEventListener("change",this.onCheckboxChange.bind(this));d.appendChild(e);a=document.createElement("span");a.className="netgis-clip-text";a.innerHTML=b;d.appendChild(a);this.container.appendChild(d);return e};
netgis.ContextMenu.prototype.addSlider=function(a,b,c,d,e,f){var g=document.createElement("label");g.className="netgis-noselect netgis-hover-d";var h=document.createElement("span");h.className="netgis-clip-text";h.innerHTML=b;g.appendChild(h);h=document.createElement("span");g.appendChild(h);c||0===c||(c=50);d||0===d||(d=0);e||0===e||(e=100);f||(f=1);var k=document.createElement("input");k.setAttribute("type","range");k.setAttribute("min",d);k.setAttribute("max",e);k.setAttribute("step",f);k.setAttribute("value",
c);k.setAttribute("data-id",a);k.setAttribute("data-title",b);k.setAttribute("title",b+" "+c);k.addEventListener("change",this.onSliderChange.bind(this));k.addEventListener("input",this.onSliderChange.bind(this));h.appendChild(k);this.container.appendChild(g);return k};netgis.ContextMenu.prototype.setVisible=function(a){a?this.container.classList.remove("netgis-hide"):this.container.classList.add("netgis-hide")};
netgis.ContextMenu.prototype.setPosition=function(a,b){var c=this.container.parentNode.getBoundingClientRect(),d=this.container.getBoundingClientRect();a+d.width>c.width&&(a-=d.width);b+d.height>c.height&&(b-=d.height);this.container.style.left=a+"px";this.container.style.top=b+"px"};
netgis.ContextMenu.prototype.onContextMenuShow=function(a){a=a.detail;this.clear();for(var b=0;b<a.items.length;b++){var c=a.items[b];switch(c.type){case "slider":this.addSlider(c.id,c.title,c.val,c.min,c.max)}}this.setVisible(!0);this.setPosition(a.x,a.y)};netgis.ContextMenu.prototype.onContextMenu=function(a){a.preventDefault();var b=a.clientX;a=a.clientY;this.setVisible(!0);this.setPosition(b,a);return!1};
netgis.ContextMenu.prototype.onParentClick=function(a){this.container.contains(a.target)||this.setVisible(!1)};netgis.ContextMenu.prototype.onParentScroll=function(a){this.setVisible(!1)};netgis.ContextMenu.prototype.onParentKeyDown=function(a){27===(a.keyCode||a.which)&&this.setVisible(!1)};
netgis.ContextMenu.prototype.onButtonClick=function(a){a=a.currentTarget;var b=a.getAttribute("data-id");this.setVisible(!1);netgis.util.invoke(a,netgis.Events.CONTEXTMENU_BUTTON_CLICK,{id:b});netgis.Client.handleCommand(a,b)};netgis.ContextMenu.prototype.onCheckboxChange=function(a){a=a.currentTarget;var b=a.getAttribute("data-id");netgis.util.invoke(a,netgis.Events.CONTEXTMENU_CHECKBOX_CHANGE,{id:b,checked:a.checked})};
netgis.ContextMenu.prototype.onSliderChange=function(a){a=a.currentTarget;var b=a.getAttribute("data-id"),c=Number.parseFloat(a.value),d=a.getAttribute("data-title");a.setAttribute("title",d+" "+c);netgis.util.invoke(a,netgis.Events.CONTEXTMENU_SLIDER_CHANGE,{id:b,val:c})};netgis=netgis||{};netgis.Controls=function(a){this.config=a;this.initElements(a);this.initConfig(a)};netgis.Controls.Config={buttons:[]};
netgis.Controls.prototype.initElements=function(a){this.container=document.createElement("section");this.container.className="netgis-controls netgis-color-e netgis-text-a netgis-shadow netgis-round";if(a&&a.modules&&!0===a.modules.geolocation){this.popupGeoloc=new netgis.Popup({direction:"right"});this.popupGeoloc.container.style.width="60mm";this.popupGeoloc.setHeader("Ger\u00e4te-Standort");a=document.createElement("label");a.className="netgis-hover-d netgis-clip-text netgis-clickable netgis-noselect";
var b=document.createElement("input");b.setAttribute("type","checkbox");b.addEventListener("change",this.onInputGeolocActiveChange.bind(this));a.appendChild(b);this.inputGeolocActive=b;b=document.createElement("span");b.innerHTML="Aktiviert";a.appendChild(b);this.popupGeoloc.wrapper.appendChild(a);a=document.createElement("label");a.className="netgis-hover-d netgis-clip-text netgis-clickable netgis-noselect";b=document.createElement("input");b.setAttribute("type","checkbox");b.addEventListener("change",
this.onInputGeolocCenterChange.bind(this));a.appendChild(b);this.inputGeolocCenter=b;b=document.createElement("span");b.innerHTML="Zentriert";a.appendChild(b);this.popupGeoloc.wrapper.appendChild(a)}};netgis.Controls.prototype.initConfig=function(a){if(a=a.controls)if(a=a.buttons)for(var b=0;b<a.length;b++){var c=a[b];this.addButton(c.id,c.icon,c.title)}};
netgis.Controls.prototype.attachTo=function(a){a.appendChild(this.container);this.popupGeoloc&&this.popupGeoloc.attachTo(a);a.addEventListener(netgis.Events.GEOLOCATION_SHOW_OPTIONS,this.onGeolocShowOptions.bind(this));a.addEventListener(netgis.Events.GEOLOCATION_TOGGLE_ACTIVE,this.onGeolocToggleActive.bind(this));a.addEventListener(netgis.Events.GEOLOCATION_TOGGLE_CENTER,this.onGeolocToggleCenter.bind(this));a.addEventListener("pointerdown",this.onParentPointerDown.bind(this))};
netgis.Controls.prototype.addButton=function(a,b,c){var d=document.createElement("button");d.setAttribute("type","button");d.setAttribute("data-id",a);d.className="netgis-hover-a";d.innerHTML=b;d.title=c;d.addEventListener("pointerdown",this.onButtonClick.bind(this));this.container.appendChild(d);return d};
netgis.Controls.prototype.onButtonClick=function(a){a=a.currentTarget;var b=a.getAttribute("data-id");switch(b){case "zoom_in":netgis.util.invoke(a,netgis.Events.MAP_ZOOM,{delta:1});break;case "zoom_out":netgis.util.invoke(a,netgis.Events.MAP_ZOOM,{delta:-1});break;case "zoom_home":netgis.util.invoke(a,netgis.Events.MAP_ZOOM_HOME,null);break;default:netgis.Client.handleCommand(a,b)}};
netgis.Controls.prototype.onGeolocShowOptions=function(a){a=this.container.getElementsByTagName("button");for(var b=null,c=0;c<a.length;c++){var d=a[c].getAttribute("data-id");if(d&&d.toUpperCase()===netgis.Commands.GEOLOCATION){b=a[c];break}}b&&(this.popupGeoloc.isVisible()?this.popupGeoloc.hide():(this.popupGeoloc.show(),a=b.getBoundingClientRect(),this.popupGeoloc.setPosition(a.x+4,a.y+.3*a.height)))};
netgis.Controls.prototype.onParentPointerDown=function(a){netgis.util.insideElement(this.container,a.clientX,a.clientY)||this.popupGeoloc&&this.popupGeoloc.hide()};netgis.Controls.prototype.onInputGeolocActiveChange=function(a){a=a.currentTarget;netgis.util.invoke(a,netgis.Events.GEOLOCATION_TOGGLE_ACTIVE,{on:a.checked})};netgis.Controls.prototype.onInputGeolocCenterChange=function(a){a=a.currentTarget;netgis.util.invoke(a,netgis.Events.GEOLOCATION_TOGGLE_CENTER,{on:a.checked})};
netgis.Controls.prototype.onGeolocToggleActive=function(a){a.target!==this.inputGeolocActive&&(this.inputGeolocActive.checked=a.detail.on)};netgis.Controls.prototype.onGeolocToggleCenter=function(a){a.target!==this.inputGeolocCenter&&(this.inputGeolocCenter.checked=a.detail.on)};netgis=netgis||{};
netgis.Events={CLIENT_CONTEXT_RESPONSE:"client-context-response",CLIENT_SET_MODE:"client-set-mode",PLUGIN_TOGGLE:"plugin-toggle",CONTROLS_BUTTON_CLICK:"controls-button-click",MAP_ZOOM:"map-zoom",MAP_ZOOM_HOME:"map-zoom-home",MAP_ZOOM_LONLAT:"map-zoom-lonlat",MAP_ZOOM_SCALE:"map-zoom-scale",MAP_ZOOM_LAYER:"map-zoom-layer",MAP_ZOOM_LEVEL:"map-zoom-level",MAP_LAYER_CREATE:"map-layer-create",MAP_LAYER_TOGGLE:"map-layer-toggle",MAP_LAYER_TRANSPARENCY:"map-layer-transparency",MAP_LAYER_ORDER:"map-layer-order",MAP_LAYER_DELETE:"map-layer-delete",
MAP_VIEW_CHANGE:"map-view-change",MAP_VIEW_NEXT:"map-view-next",MAP_VIEW_PREV:"map-view-prev",MAP_CLICK:"map-click",MAP_FEATURE_ENTER:"map-feature-enter",MAP_FEATURE_CLICK:"map-feature-click",MAP_FEATURE_LEAVE:"map-feature-leave",MAP_SNAP_TOGGLE:"map-snap-toggle",MAP_EDIT_LAYER_CHANGE:"map-edit-layer-change",MAP_EDIT_LAYER_LOADED:"map-edit-layer-loaded",MAP_COPY_FEATURE_TO_EDIT:"map-copy-feature-to-edit",PANEL_TOGGLE:"panel-toggle",PANEL_RESIZE:"panel-resize",WINDOW_TOGGLE:"window-toggle",WINDOW_RESIZE:"window-resize",
TREE_ITEM_CHANGE:"tree-item-change",TREE_ITEM_SLIDER_CHANGE:"tree-item-slider-change",TREE_ITEM_ORDER_CHANGE:"tree-item-order-change",TREE_BUTTON_CLICK:"tree-button-click",LAYERTREE_TOGGLE:"layertree-toggle",LEGEND_TOGGLE:"legend-toggle",GEOLOCATION_SHOW_OPTIONS:"geolocation-show-options",GEOLOCATION_TOGGLE_ACTIVE:"geolocation-toggle-active",GEOLOCATION_TOGGLE_CENTER:"geolocation-toggle-center",GEOLOCATION_CHANGE:"geolocation-change",TOOLBOX_TOGGLE:"toolbox-toggle",TOOLBOX_BUTTON_CLICK:"toolbox-button-click",
MENU_BUTTON_CLICK:"menu-button-click",MENU_CHECKBOX_CHANGE:"menu-checkbox-change",MENU_SELECT_CHANGE:"menu-select-change",CONTEXTMENU_SHOW:"contextmenu-show",CONTEXTMENU_BUTTON_CLICK:"contextmenu-button-click",CONTEXTMENU_CHECKBOX_CHANGE:"contextmenu-checkbox-change",CONTEXTMENU_SLIDER_CHANGE:"contextmenu-slider-change",SEARCH_CHANGE:"search-change",SEARCH_SELECT:"search-select",SEARCH_CLEAR:"search-clear",SEARCHPLACE_TOGGLE:"searchplace-toggle",SEARCHPARCEL_TOGGLE:"searchparcel-toggle",SEARCHPARCEL_RESET:"searchparcel-reset",
SEARCHPARCEL_PARCELS_RESPONSE:"searchparcel-parcels-response",SEARCHPARCEL_ITEM_ENTER:"searchparcel-item-enter",SEARCHPARCEL_ITEM_LEAVE:"searchparcel-item-leave",SEARCHPARCEL_ITEM_CLICK:"searchparcel-item-click",SEARCHPARCEL_ITEM_IMPORT:"searchparcel-item-import",MEASURE_CLEAR:"measure-clear",SELECT_MULTI_TOGGLE:"select-multi-toggle",DRAW_BUFFER_TOGGLE:"draw-buffer-toggle",DRAW_BUFFER_CHANGE:"draw-buffer-change",BUFFER_CHANGE:"buffer-change",BUFFER_ACCEPT:"buffer-accept",IMPORT_LAYER_SHOW:"import-layer-show",
IMPORT_LAYER_ACCEPT:"import-layer-accept",IMPORT_LAYER_PREVIEW:"import-layer-preview",IMPORT_LAYER_PREVIEW_FEATURES:"import-layer-preview-features",IMPORT_GEOPORTAL_SUBMIT:"import-geoportal-submit",EXPORT_SHOW:"export-show",EXPORT_BEGIN:"export-begin",EXPORT_END:"export-end",TIMESLIDER_SHOW:"timeslider-show",TIMESLIDER_HIDE:"timeslider-hide",TIMESLIDER_SELECT:"timeslider-select"};netgis=netgis||{};netgis.Export=function(a){this.config=a;this.initElements(a);this.initSections()};netgis.Export.Config={title:"Export",logo:"",gif_worker:"/libs/gifjs/0.2.0/gif.worker.js",default_filename:"Export",default_margin:10};
netgis.Export.prototype.initElements=function(a){a=a["export"];this.modal=new netgis.Modal(a.title?a.title:"Export");this.modal.container.classList.add("netgis-export");this.tabs=new netgis.Tabs(["PDF","JPEG","PNG","GIF","GeoJSON"]);this.tabs.container.style.position="absolute";this.tabs.container.style.left="0mm";this.tabs.container.style.right="0mm";this.tabs.container.style.top="12mm";this.tabs.container.style.bottom="0mm";this.tabs.attachTo(this.modal.content)};
netgis.Export.prototype.initSections=function(){this.sections={};var a=0;this.sections.pdf=this.tabs.getContentSection(a);a+=1;this.addInputNumber(this.sections.pdf,"Breite (Pixel):",1600,0);this.addInputNumber(this.sections.pdf,"H\u00f6he (Pixel):",900,0);this.addInputNumber(this.sections.pdf,"Seitenr\u00e4nder (Millimeter):",10,0);this.addCheckbox(this.sections.pdf,"Querformat",!0);this.addButton(this.sections.pdf,"<i class='netgis-icon fas fa-save'></i><span>Exportieren</span>",this.onExportClickPDF.bind(this));
this.sections.jpeg=this.tabs.getContentSection(a);a+=1;this.addInputNumber(this.sections.jpeg,"Breite (Pixel):",1600,0);this.addInputNumber(this.sections.jpeg,"H\u00f6he (Pixel):",900,0);this.addCheckbox(this.sections.jpeg,"Querformat",!0);this.addButton(this.sections.jpeg,"<i class='netgis-icon fas fa-save'></i><span>Exportieren</span>",this.onExportClickJPEG.bind(this));this.sections.png=this.tabs.getContentSection(a);a+=1;this.addInputNumber(this.sections.png,"Breite (Pixel):",1600,0);this.addInputNumber(this.sections.png,
"H\u00f6he (Pixel):",900,0);this.addCheckbox(this.sections.png,"Querformat",!0);this.addButton(this.sections.png,"<i class='netgis-icon fas fa-save'></i><span>Exportieren</span>",this.onExportClickPNG.bind(this));this.sections.gif=this.tabs.getContentSection(a);a+=1;this.addInputNumber(this.sections.gif,"Breite (Pixel):",1600,0);this.addInputNumber(this.sections.gif,"H\u00f6he (Pixel):",900,0);this.addCheckbox(this.sections.gif,"Querformat",!0);this.addButton(this.sections.gif,"<i class='netgis-icon fas fa-save'></i><span>Exportieren</span>",
this.onExportClickGIF.bind(this));this.sections.geojson=this.tabs.getContentSection(a);this.addCheckbox(this.sections.geojson,"Nicht-Editierbare Geometrien einbeziehen",!1);this.addButton(this.sections.geojson,"<i class='netgis-icon fas fa-save'></i><span>Exportieren</span>",this.onExportClickGeoJSON.bind(this))};
netgis.Export.prototype.attachTo=function(a){a.appendChild(this.modal.container);a.addEventListener(netgis.Events.EXPORT_SHOW,this.onExportShow.bind(this));a.addEventListener(netgis.Events.EXPORT_END,this.onExportEnd.bind(this))};netgis.Export.prototype.addText=function(a,b){var c=document.createElement("div");c.innerHTML=b;a.appendChild(c);return c};
netgis.Export.prototype.addButton=function(a,b,c){var d=document.createElement("button");d.className="netgis-button netgis-center netgis-color-a netgis-hover-c netgis-shadow";d.setAttribute("type","button");d.innerHTML=b;c&&(d.onclick=c);a.appendChild(d);return d};
netgis.Export.prototype.addInputText=function(a,b,c){var d=document.createElement("label");d.innerHTML=b;var e=document.createElement("input");e.setAttribute("type","text");d.appendChild(e);if(c){b="list-"+netgis.util.stringToID(b);var f=document.createElement("datalist");f.setAttribute("id",b);for(var g=0;g<c.length;g++){var h=document.createElement("option");h.setAttribute("value",c[g]);f.appendChild(h)}a.appendChild(f);e.setAttribute("list",b)}a.appendChild(d);return e};
netgis.Export.prototype.addInputNumber=function(a,b,c,d,e){var f=document.createElement("label");f.innerHTML=b;b=document.createElement("input");b.setAttribute("type","number");(d||0===d)&&b.setAttribute("min",d);e&&b.setAttribute("max",e);b.setAttribute("value",c);f.appendChild(b);a.appendChild(f);return b};
netgis.Export.prototype.addCheckbox=function(a,b,c){var d=document.createElement("label"),e=document.createElement("input");e.setAttribute("type","checkbox");e.checked=c;d.appendChild(e);c=document.createElement("span");c.innerHTML=b;d.appendChild(c);a.appendChild(d);return e};netgis.Export.prototype.onExportShow=function(a){this.modal.show()};
netgis.Export.prototype.onExportClickPDF=function(a){var b=this.sections.pdf.getElementsByTagName("input");b={format:"pdf",width:Number.parseInt(b[0].value),height:Number.parseInt(b[1].value),padding:Number.parseInt(b[2].value),landscape:b[3].checked};netgis.util.invoke(a.target,netgis.Events.EXPORT_BEGIN,b)};
netgis.Export.prototype.onExportClickJPEG=function(a){var b=this.sections.pdf.getElementsByTagName("input");b={format:"jpeg",width:Number.parseInt(b[0].value),height:Number.parseInt(b[1].value),landscape:b[3].checked};netgis.util.invoke(a.target,netgis.Events.EXPORT_BEGIN,b)};
netgis.Export.prototype.onExportClickPNG=function(a){var b=this.sections.pdf.getElementsByTagName("input");b={format:"png",width:Number.parseInt(b[0].value),height:Number.parseInt(b[1].value),landscape:b[3].checked};netgis.util.invoke(a.target,netgis.Events.EXPORT_BEGIN,b)};
netgis.Export.prototype.onExportClickGIF=function(a){var b=this.sections.pdf.getElementsByTagName("input");b={format:"gif",width:Number.parseInt(b[0].value),height:Number.parseInt(b[1].value),landscape:b[3].checked};netgis.util.invoke(a.target,netgis.Events.EXPORT_BEGIN,b)};netgis.Export.prototype.onExportClickGeoJSON=function(a){var b={format:"geojson",nonEdits:this.sections.geojson.getElementsByTagName("input")[0].checked};netgis.util.invoke(a.target,netgis.Events.EXPORT_BEGIN,b)};
netgis.Export.prototype.onExportEnd=function(a){this.modal.hide()};netgis=netgis||{};netgis.Geolocation=function(a){this.config=a;this.center=this.active=!1};netgis.Geolocation.Config={marker_color:"#3480eb",marker_title:"Geolocation",timeout:1E4};netgis.Geolocation.prototype.initConfig=function(a){};netgis.Geolocation.prototype.attachTo=function(a){this.container=a;a.addEventListener(netgis.Events.GEOLOCATION_TOGGLE_ACTIVE,this.onGeolocToggleActive.bind(this));a.addEventListener(netgis.Events.GEOLOCATION_TOGGLE_CENTER,this.onGeolocToggleCenter.bind(this))};
netgis.Geolocation.prototype.setActive=function(a,b){var c=this.config.geolocation;a?navigator.geolocation?(this.watch=navigator.geolocation.watchPosition(this.onPositionChange.bind(this),this.onPositionError.bind(this),{timeout:c&&c.timeout?1E3*c.timeout:1E4,maximumAge:0,enableHighAccuracy:!0}),b||netgis.util.invoke(this.container,netgis.Events.GEOLOCATION_TOGGLE_ACTIVE,{on:!0})):this.error("Geolocation not supported by this device!"):(this.watch&&(navigator.geolocation.clearWatch(this.watch),this.watch=
null),b||netgis.util.invoke(this.container,netgis.Events.GEOLOCATION_TOGGLE_ACTIVE,{on:!1}));this.active=a};netgis.Geolocation.prototype.isActive=function(){return this.active};netgis.Geolocation.prototype.error=function(a){console.error(a);this.watch&&(navigator.geolocation.clearWatch(this.watch),this.watch=null);netgis.util.invoke(this.container,netgis.Events.GEOLOCATION_TOGGLE_ACTIVE,{on:!1})};netgis.Geolocation.prototype.onActiveChange=function(a){this.setActive(a.currentTarget.checked)};
netgis.Geolocation.prototype.onCenterChange=function(a){};netgis.Geolocation.prototype.onPositionChange=function(a){netgis.util.invoke(this.container,netgis.Events.GEOLOCATION_CHANGE,{lon:a.coords.longitude,lat:a.coords.latitude,center:this.center})};netgis.Geolocation.prototype.onPositionError=function(a){this.error("Geolocation: "+a.message+" ("+a.code+")")};netgis.Geolocation.prototype.onGeolocToggleActive=function(a){a.target!==this.container&&this.setActive(a.detail.on)};
netgis.Geolocation.prototype.onGeolocToggleCenter=function(a){a.target!==this.container&&(this.center=a.detail.on)};netgis=netgis||{};netgis.Import=function(a){this.config=a;this.initElements(a);this.initSections(a);this.initPreview()};netgis.Import.Config={title:"Import Layer",preview:!0,wms_options:[],wfs_options:[],wfs_proxy:"",geopackage_lib:"/libs/geopackage/4.2.3/",geoportal_tab:!0,geoportal_search_url:"",geoportal_autocomplete:!0};
netgis.Import.prototype.initElements=function(a){a=a["import"];this.modal=new netgis.Modal(a.title?a.title:"Import");this.modal.container.classList.add("netgis-import");var b="WMS WFS GeoJSON GML GeoPackage Spatialite Shapefile".split(" ");a.geoportal_tab&&b.unshift("Geoportal");this.tabs=new netgis.Tabs(b);this.tabs.container.style.position="absolute";this.tabs.container.style.left="0mm";this.tabs.container.style.right="0mm";this.tabs.container.style.top="12mm";this.tabs.container.style.bottom="0mm";
this.tabs.attachTo(this.modal.content)};
netgis.Import.prototype.initSections=function(a){this.sections={};var b=0;a["import"]&&!0===a["import"].geoportal_tab&&(this.sections.geoportal=this.tabs.getContentSection(b),b+=1,this.sections.geoportal.classList.add("netgis-geoportal"),this.geoportalSearch=new netgis.Search("Thema, Schlagwort..."),this.geoportalSearch.container.addEventListener(netgis.Events.SEARCH_CHANGE,this.onGeoportalSearchChange.bind(this)),this.geoportalSearch.container.addEventListener(netgis.Events.SEARCH_CLEAR,this.onGeoportalSearchClear.bind(this)),
this.geoportalSearch.attachTo(this.sections.geoportal),a=document.createElement("span"),a.innerHTML="Suche im Datenkatalog:",this.geoportalSearch.label.insertBefore(a,this.geoportalSearch.label.firstChild),this.geoportalLoader=document.createElement("div"),this.geoportalLoader.className="netgis-loader netgis-text-a netgis-hide",this.geoportalLoader.innerHTML="<i class='fas fa-cog'></i>",this.sections.geoportal.appendChild(this.geoportalLoader),this.geoportalResults=new netgis.Tree,this.geoportalResults.container.addEventListener(netgis.Events.TREE_ITEM_CHANGE,
this.onGeoportalTreeItemChange.bind(this)),this.geoportalResults.attachTo(this.sections.geoportal),this.geoportalSubmit=this.addButton(this.sections.geoportal,"<i class='netgis-icon fas fa-check'></i><span>Hinzuf\u00fcgen<span class='netgis-count'></span></span>",this.onGeoportalSubmit.bind(this)));this.sections.wms=this.tabs.getContentSection(b);b+=1;this.addInputText(this.sections.wms,"WMS-URL:",this.config["import"].wms_options);this.addButton(this.sections.wms,"<i class='netgis-icon fas fa-cloud-download-alt'></i><span>Dienst laden</span>",
this.onWMSLoadClick.bind(this));this.addInputText(this.sections.wms,"Bezeichnung:");this.addInputSelect(this.sections.wms,"Ebene:");this.addInputSelect(this.sections.wms,"Format:");this.addButton(this.sections.wms,"<i class='netgis-icon fas fa-check'></i><span>Hinzuf\u00fcgen</span>",this.onWMSAcceptClick.bind(this));this.showDetailsWMS(!1);this.sections.wfs=this.tabs.getContentSection(b);b+=1;this.addInputText(this.sections.wfs,"WFS-URL:",this.config["import"].wfs_options);this.addButton(this.sections.wfs,
"<i class='netgis-icon fas fa-cloud-download-alt'></i><span>Dienst laden</span>",this.onWFSLoadClick.bind(this));this.addInputText(this.sections.wfs,"Bezeichnung:");this.addInputSelect(this.sections.wfs,"Ebene:");this.addInputSelect(this.sections.wfs,"Format:");this.addButton(this.sections.wfs,"<i class='netgis-icon fas fa-check'></i><span>Hinzuf\u00fcgen</span>",this.onWFSAcceptClick.bind(this));this.showDetailsWFS(!1);this.sections.geojson=this.tabs.getContentSection(b);b+=1;this.addInputFile(this.sections.geojson,
"GeoJSON-Datei:",".geojson,.json");this.addText(this.sections.geojson,"<h3>Unterst\u00fctzte Koordinatensysteme:</h3><ul><li>Web Mercator (EPSG:3857)</li><li>WGS84 / Lon-Lat (EPSG:4326)</li><li>ETRS89 / UTM Zone 32N (EPSG:25832)</li></ul>");this.addButton(this.sections.geojson,"<i class='netgis-icon fas fa-check'></i><span>Datei laden</span>",this.onGeoJSONAcceptClick.bind(this));this.sections.gml=this.tabs.getContentSection(b);b+=1;this.addInputFile(this.sections.gml,"GML-Datei:",".gml,.xml");this.addText(this.sections.gml,
"<h3>Unterst\u00fctzte Koordinatensysteme:</h3><ul><li>Web Mercator (EPSG:3857)</li><li>WGS84 / Lon-Lat (EPSG:4326)</li><li>ETRS89 / UTM Zone 32N (EPSG:25832)</li></ul>");this.addButton(this.sections.gml,"<i class='netgis-icon fas fa-check'></i><span>Datei laden</span>",this.onGMLAcceptClick.bind(this));this.sections.geopackage=this.tabs.getContentSection(b);b+=1;this.addInputFile(this.sections.geopackage,"GeoPackage-Datei:",".gpkg");this.addText(this.sections.geopackage,"<h3>Unterst\u00fctzte Koordinatensysteme:</h3><ul><li>Web Mercator (EPSG:3857)</li><li>WGS84 / Lon-Lat (EPSG:4326)</li><li>ETRS89 / UTM Zone 32N (EPSG:25832)</li></ul>");
this.addButton(this.sections.geopackage,"<i class='netgis-icon fas fa-check'></i><span>Datei laden</span>",this.onGeoPackageAcceptClick.bind(this));this.sections.spatialite=this.tabs.getContentSection(b);b+=1;this.addInputFile(this.sections.spatialite,"Spatialite-Datei:",".sqlite");this.addText(this.sections.spatialite,"<h3>Unterst\u00fctzte Koordinatensysteme:</h3><ul><li>Web Mercator (EPSG:3857)</li><li>WGS84 / Lon-Lat (EPSG:4326)</li><li>ETRS89 / UTM Zone 32N (EPSG:25832)</li></ul>");this.addButton(this.sections.spatialite,
"<i class='netgis-icon fas fa-check'></i><span>Datei laden</span>",this.onSpatialiteAcceptClick.bind(this));this.sections.shapefile=this.tabs.getContentSection(b);this.addInputFile(this.sections.shapefile,"Shapefile-Zip-Datei:",".zip");this.addText(this.sections.shapefile,"<h3>Unterst\u00fctzte Koordinatensysteme:</h3><ul><li>Web Mercator (EPSG:3857)</li><li>WGS84 / Lon-Lat (EPSG:4326)</li><li>ETRS89 / UTM Zone 32N (EPSG:25832)</li></ul>");this.addButton(this.sections.shapefile,"<i class='netgis-icon fas fa-check'></i><span>Datei laden</span>",
this.onShapefileAcceptClick.bind(this))};
netgis.Import.prototype.initPreview=function(){this.preview=new netgis.Modal("Vorschau");this.preview.attachTo(this.modal.content);this.previewMapContainer=document.createElement("div");this.previewMapContainer.className="netgis-preview-map";this.preview.content.appendChild(this.previewMapContainer);if(ol){var a=this.config.map;a={projection:a.projection,center:a.centerLonLat?ol.proj.fromLonLat(a.centerLonLat):a.center,zoom:a.zoom};this.previewMap=new ol.Map({target:this.previewMapContainer,view:new ol.View(a),
pixelRatio:1,moveTolerance:3,controls:[]});this.previewMap.getView().padding=[10,10,10,10];this.previewMap.addLayer(new ol.layer.Tile({source:new ol.source.OSM}))}this.previewTree=new netgis.Tree;this.previewTree.container.classList.add("netgis-preview-tree");this.previewTree.attachTo(this.preview.content);this.previewTree.container.addEventListener(netgis.Events.TREE_ITEM_CHANGE,this.onPreviewTreeItemChange.bind(this));this.previewSubmit=document.createElement("button");this.previewSubmit.setAttribute("type",
"button");this.previewSubmit.className="netgis-import-submit netgis-button netgis-center netgis-color-a netgis-hover-c netgis-shadow";this.previewSubmit.innerHTML="<i class='netgis-icon fas fa-check'></i><span>Hinzuf\u00fcgen</span>";this.previewSubmit.addEventListener("click",this.onPreviewSubmitClick.bind(this));this.preview.content.appendChild(this.previewSubmit)};
netgis.Import.prototype.attachTo=function(a){a.appendChild(this.modal.container);a.addEventListener(netgis.Events.IMPORT_LAYER_SHOW,this.onImportShow.bind(this));a.addEventListener(netgis.Events.IMPORT_LAYER_PREVIEW_FEATURES,this.onImportPreviewFeatures.bind(this))};netgis.Import.prototype.addText=function(a,b){var c=document.createElement("div");c.innerHTML=b;a.appendChild(c);return c};
netgis.Import.prototype.addButton=function(a,b,c){var d=document.createElement("button");d.className="netgis-button netgis-center netgis-color-a netgis-hover-c netgis-shadow";d.setAttribute("type","button");d.innerHTML=b;c&&(d.onclick=c);a.appendChild(d);return d};
netgis.Import.prototype.addInputText=function(a,b,c){var d=document.createElement("label");d.innerHTML=b;var e=document.createElement("input");e.setAttribute("type","text");d.appendChild(e);if(c){b="list-"+netgis.util.stringToID(b);var f=document.createElement("datalist");f.setAttribute("id",b);for(var g=0;g<c.length;g++){var h=document.createElement("option");h.setAttribute("value",c[g]);f.appendChild(h)}a.appendChild(f);e.setAttribute("list",b)}a.appendChild(d);return e};
netgis.Import.prototype.addInputSelect=function(a,b,c){c=document.createElement("label");c.innerHTML=b;b=document.createElement("select");c.appendChild(b);a.appendChild(c);return b};netgis.Import.prototype.addInputFile=function(a,b,c){var d=document.createElement("label");d.innerHTML=b;b=document.createElement("input");b.setAttribute("type","file");b.setAttribute("accept",c);d.appendChild(b);a.appendChild(d);return b};netgis.Import.prototype.getLayerOrder=function(){return 1E4};
netgis.Import.prototype.showDetailsWMS=function(a){var b=this.sections.wms,c=b.getElementsByTagName("label");b=b.getElementsByTagName("button");a?(c[1].classList.remove("netgis-hide"),c[2].classList.remove("netgis-hide"),c[3].classList.remove("netgis-hide"),b[1].classList.remove("netgis-hide")):(c[1].classList.add("netgis-hide"),c[2].classList.add("netgis-hide"),c[3].classList.add("netgis-hide"),b[1].classList.add("netgis-hide"))};
netgis.Import.prototype.showDetailsWFS=function(a){var b=this.sections.wfs,c=b.getElementsByTagName("label");b=b.getElementsByTagName("button");a?(c[1].classList.remove("netgis-hide"),c[2].classList.remove("netgis-hide"),c[3].classList.remove("netgis-hide"),b[1].classList.remove("netgis-hide")):(c[1].classList.add("netgis-hide"),c[2].classList.add("netgis-hide"),c[3].classList.add("netgis-hide"),b[1].classList.add("netgis-hide"))};
netgis.Import.prototype.submitImportLayer=function(a){!0===this.config["import"].preview?netgis.util.invoke(this.modal.container,netgis.Events.IMPORT_LAYER_PREVIEW,a):(this.config.layers.push(a),netgis.util.invoke(this.modal.container,netgis.Events.IMPORT_LAYER_ACCEPT,a),this.modal.hide())};netgis.Import.prototype.onImportShow=function(a){this.modal.show();this.tabs.updateHeaderScroll()};
netgis.Import.prototype.onWMSLoadClick=function(a){this.showDetailsWMS(!1);a=this.sections.wms.getElementsByTagName("input")[0].value;a=a.trim();if(!(1>a.length)){var b=netgis.util.parseURL(a);a=b.base;b=b.parameters;b.push("request=GetCapabilities");b=b.join("&");-1===b.search("service=")&&(b+="&service=WMS");netgis.util.request(a+"?"+b,this.onWMSCapsResponse.bind(this))}};
netgis.Import.prototype.onWMSCapsResponse=function(a){var b=(new DOMParser).parseFromString(a,"text/xml"),c=b.documentElement;b=b.getElementsByTagName("parsererror");for(var d=0;d<b.length;d++)console.error("WMS caps parser error:",b[d].textContent);0<b.length&&alert(0<a.length?a:b[0].textContent);a=this.sections.wms;var e=a.getElementsByTagName("input");a=a.getElementsByTagName("select");b=a[0];a=a[1];for(d=b.options.length-1;0<=d;d--)b.options.remove(d);for(d=a.options.length-1;0<=d;d--)a.options.remove(d);
switch(c.nodeName){default:case "HTML":console.warn("could not detect WMS service",c);break;case "WMS_Capabilities":case "WMT_MS_Capabilities":c.getAttribute("version");d=c.getElementsByTagName("Service")[0].getElementsByTagName("Title")[0].textContent;e[1].value=d;d=c.getElementsByTagName("Layer");for(var f=[],g=0;g<d.length;g++){e=d[g];var h=e.getElementsByTagName("Name")[0].textContent,k=e.getElementsByTagName("Title")[0].textContent;f.push({name:h,title:k});e=document.createElement("option");
e.text=k;e.value=h;b.options.add(e)}c=c.getElementsByTagName("GetMap")[0].getElementsByTagName("Format");b=[];for(d=0;d<c.length;d++)e=c[d],f=e.textContent,-1!==f.search("image")&&(b.push(f),e=document.createElement("option"),e.text=f,e.value=f,a.options.add(e))}this.showDetailsWMS(!0)};
netgis.Import.prototype.onWMSAcceptClick=function(a){a=this.sections.wms;var b=a.getElementsByTagName("input"),c=a.getElementsByTagName("select"),d="import_"+netgis.util.getTimeStamp(!0),e=b[0].value;b=c[0].selectedOptions[0].innerText;var f=c[0].value;c=c[1].value;e=netgis.util.replace(e,"request=","oldrequest=");e=netgis.util.replace(e,"Request=","oldrequest=");var g=netgis.util.parseURL(e);e=g.base;g=g.parameters;g=g.join("&");-1===g.search("service=")&&(g+="&service=WMS");e=e+"?"+g;g={id:d,folder:null,
active:!0,query:!0,order:this.getLayerOrder(),type:netgis.LayerTypes.WMS,url:e,title:b,name:f,format:c,tiled:!0};this.config.layers.push(g);netgis.util.invoke(a,netgis.Events.IMPORT_LAYER_ACCEPT,g);this.modal.hide()};
netgis.Import.prototype.onWFSLoadClick=function(a){this.showDetailsWFS(!1);var b=this.sections.wfs.getElementsByTagName("input")[0].value;b=b.trim();if(!(1>b.length)){var c=b.indexOf("?");a=-1<c?b.substr(0,c):b;var d=["request=GetCapabilities"];if(-1<c)for(b=b.substr(c+1),b=b.split("&"),c=0;c<b.length;c++){var e=b[c];e=e.toLowerCase();-1<e.search("service")?d.push(e):-1<e.search("version")?d.push(e):-1<e.search("request")||d.push(e)}d=d.join("&");-1===d.search("service=")&&(d+="&service=WFS");a=a+
"?"+d;this.config["import"].wfs_proxy&&(a=this.config["import"].wfs_proxy+a);netgis.util.request(a,this.onWFSCapsResponse.bind(this))}};
netgis.Import.prototype.onWFSCapsResponse=function(a){var b=(new DOMParser).parseFromString(a,"text/xml"),c=b.documentElement;b=b.getElementsByTagName("parsererror");for(var d=0;d<b.length;d++)console.error("WFS caps parser error:",b[d].textContent);0<b.length&&alert(0<a.length?a:b[0].textContent);a=this.sections.wfs;var e=a.getElementsByTagName("input");a=a.getElementsByTagName("select");b=a[0];a=a[1];for(d=b.options.length-1;0<=d;d--)b.options.remove(d);for(d=a.options.length-1;0<=d;d--)a.options.remove(d);
switch(c.nodeName){default:case "HTML":console.error("could not detect WFS service",c);break;case "WFS_Capabilities":case "wfs:WFS_Capabilities":c.getAttribute("version");d=c.getElementsByTagName("ows:ServiceIdentification")[0].getElementsByTagName("ows:Title")[0].textContent;e[1].value=d;d=c.getElementsByTagName("FeatureType");for(var f=[],g=0;g<d.length;g++){e=d[g];var h=e.getElementsByTagName("Name")[0].textContent,k=e.getElementsByTagName("Title")[0].textContent;f.push({name:h,title:k});e=document.createElement("option");
e.text=k;e.value=h;b.options.add(e)}c=c.getElementsByTagName("ows:Operation");b=null;for(e=0;e<c.length;e++)if("GetFeature"===c[e].getAttribute("name")){b=c[e];break}c=null;if(b)for(b=b.getElementsByTagName("ows:Parameter"),e=0;e<b.length;e++)if(d=b[e],"outputFormat"===d.getAttribute("name")){b=d.getElementsByTagName("ows:Value");for(d=0;d<b.length;d++)e=b[d],f=e.textContent,e=document.createElement("option"),e.text=f,e.value=f,a.options.add(e),-1<f.search("json")&&(c=f);break}c&&(a.value=c)}this.showDetailsWFS(!0)};
netgis.Import.prototype.onWFSAcceptClick=function(a){a=this.sections.wfs;var b=a.getElementsByTagName("input"),c=a.getElementsByTagName("select"),d="import_"+netgis.util.getTimeStamp(!0);b=b[0].value;var e=c[0].selectedOptions[0].innerText,f=c[0].value;c=c[1].value;b=netgis.util.replace(b,"request=","oldrequest=");b=netgis.util.replace(b,"Request=","oldrequest=");this.config["import"].wfs_proxy&&(b=this.config["import"].wfs_proxy+b);d={id:d,folder:null,active:!0,order:this.getLayerOrder(),style:this.config.styles["import"],
title:e,type:netgis.LayerTypes.WFS,url:b,name:f,format:c};this.config.layers.push(d);netgis.util.invoke(a,netgis.Events.IMPORT_LAYER_ACCEPT,d);this.modal.hide()};netgis.Import.prototype.onGeoJSONAcceptClick=function(a){if(a=this.sections.geojson.getElementsByTagName("input")[0].files[0]){var b=new FileReader;b.title=a.name;b.onload=this.onGeoJSONLoad.bind(this);b.readAsText(a)}else alert("No file selected!")};
netgis.Import.prototype.onGeoJSONLoad=function(a){var b=a.target;a=b.title;b=b.result;a={id:"import_"+netgis.util.getTimeStamp(!0),folder:null,active:!0,order:this.getLayerOrder(),style:this.config.styles["import"],title:a,type:netgis.LayerTypes.GEOJSON,data:b};this.submitImportLayer(a)};netgis.Import.prototype.onGMLAcceptClick=function(a){if(a=this.sections.gml.getElementsByTagName("input")[0].files[0]){var b=new FileReader;b.title=a.name;b.onload=this.onGMLLoad.bind(this);b.readAsText(a)}else alert("No file selected!")};
netgis.Import.prototype.onGMLLoad=function(a){var b=a.target;a=b.result;var c="import_"+netgis.util.getTimeStamp(!0);b=b.title;a={id:c,folder:null,active:!0,order:this.getLayerOrder(),style:this.config.styles["import"],title:b,type:netgis.LayerTypes.GML,data:a};this.submitImportLayer(a)};netgis.Import.prototype.onGeoPackageAcceptClick=function(a){if(a=this.sections.geopackage.getElementsByTagName("input")[0].files[0]){var b=new FileReader;b.title=a.name;b.onload=this.onGeoPackageLoad.bind(this);b.readAsArrayBuffer(a)}else alert("No file selected!")};
netgis.Import.prototype.onGeoPackageLoad=function(a){var b=a.target;a=b.result;var c="import_"+netgis.util.getTimeStamp(!0);b=b.title;a={id:c,folder:null,active:!0,order:this.getLayerOrder(),style:this.config.styles["import"],title:b,type:netgis.LayerTypes.GEOPACKAGE,data:a};this.submitImportLayer(a)};
netgis.Import.prototype.onSpatialiteAcceptClick=function(a){if(a=this.sections.spatialite.getElementsByTagName("input")[0].files[0]){var b=new FileReader;b.title=a.name;b.onload=this.onSpatialiteLoad.bind(this);b.readAsArrayBuffer(a)}else alert("No file selected!")};
netgis.Import.prototype.onSpatialiteLoad=function(a){var b=a.target;a=b.result;var c="import_"+netgis.util.getTimeStamp(!0);b=b.title;a={id:c,folder:null,active:!0,order:this.getLayerOrder(),style:this.config.styles["import"],title:b,type:netgis.LayerTypes.SPATIALITE,data:a};this.submitImportLayer(a)};
netgis.Import.prototype.onShapefileAcceptClick=function(a){if(a=this.sections.shapefile.getElementsByTagName("input")[0].files[0]){var b=new FileReader;b.title=a.name;b.onload=this.onShapefileLoad.bind(this);b.readAsArrayBuffer(a)}else alert("No file selected!")};
netgis.Import.prototype.onShapefileLoad=function(a){var b=a.target;a=b.result;var c="import_"+netgis.util.getTimeStamp(!0);b=b.title;a={id:c,folder:null,active:!0,order:this.getLayerOrder(),style:this.config.styles["import"],title:b,type:netgis.LayerTypes.SHAPEFILE,data:a};this.submitImportLayer(a)};
netgis.Import.prototype.onImportPreviewFeatures=function(a){var b=a.detail,c=b.layer;this.previewTree.clear();a=this.previewMap.getLayers().getArray();for(var d=1;d<a.length;d++)this.previewMap.removeLayer(a[d]);if(ol){a=config.styles["import"];a=new ol.style.Style({fill:new ol.style.Fill({color:a.fill}),stroke:new ol.style.Stroke({color:a.stroke,width:a.width})});c.setStyle(a);this.previewMap.addLayer(c);var e=this.previewTree.addFolder(null,b.id,b.title);a=c.getSource().getFeatures();if(0===a.length){var f=
this;c.getSource().on("addfeature",function(a){f.featureLoadTimeout&&window.clearTimeout(f.featureLoadTimeout);f.featureLoadTimeout=window.setTimeout(function(){var a=c.getSource().getFeatures();f.updatePreviewFeatures(a,e,c,b);f.featureLoadTimeout=null},100)})}else this.updatePreviewFeatures(a,e,c,b)}else console.error("import preview only supported with OL map renderer",c)};
netgis.Import.prototype.updatePreviewFeatures=function(a,b,c,d){for(var e=0;e<a.length;e++){var f=a[e],g=f.getId(),h=f.getProperties();g||(g=e+1,f.setId(g));var k=null,l;for(l in h)switch(l.toLowerCase()){case "name":k=h[l];break;case "title":k=h[l];break;case "id":k=h[l];break;case "gid":k=h[l];break;case "oid":k=h[l];break;case "objectid":k=h[l]}k||(k=g);h=f.getGeometry();if(h instanceof ol.geom.Polygon||h instanceof ol.geom.MultiPolygon)k+=" ("+netgis.util.formatArea(h.getArea())+")";else if(h instanceof
ol.geom.LineString)k+=" ("+netgis.util.formatArea(h.getLength())+")";else if(h instanceof ol.geom.MultiLineString){f=0;h=h.getLineStrings();for(var m=0;m<h.length;m++)f+=h[m].getLength();k+=" ("+netgis.util.formatArea(f)+")"}this.previewTree.addCheckbox(b,g,"Feature "+k,!0)}this.previewTree.setFolderOpen(d.id,!0);this.previewTree.updateFolderChecks();this.preview.show();this.previewMap.updateSize();this.previewMap.getView().fit(c.getSource().getExtent())};
netgis.Import.prototype.onPreviewSubmitClick=function(a){var b=this.previewTree.container.getElementsByClassName("netgis-folder")[0];a=b.getAttribute("data-id");b=b.getElementsByTagName("span")[0].innerText;for(var c=this.previewTree.container.getElementsByTagName("input"),d=this.previewMap.getLayers().getArray()[1].getSource(),e=[],f=1;f<c.length;f++){var g=c[f];g.checked&&(g=g.getAttribute("data-id"),g=d.getFeatureById(g),e.push(g))}c=(new ol.format.GeoJSON).writeFeaturesObject(e);d=this.previewMap.getView().getProjection().getCode();
c.crs={type:"name",properties:{name:"urn:ogc:def:crs:"+d.replace(":","::")}};a={id:a,folder:null,active:!0,order:this.getLayerOrder(),style:this.config.styles["import"],title:b,type:netgis.LayerTypes.GEOJSON,data:c};this.config.layers.push(a);netgis.util.invoke(this.preview.container,netgis.Events.IMPORT_LAYER_ACCEPT,a);this.preview.hide();this.modal.hide()};
netgis.Import.prototype.onPreviewTreeItemChange=function(a){a=a.detail;var b=this.previewMap.getLayers().getArray()[1].getSource().getFeatureById(a.id);a.checked?b.setStyle(null):b.setStyle(new ol.style.Style({}))};netgis.Import.prototype.onGeoportalSearchKeyUp=function(a){switch(a.keyCode){case 13:break;case 27:break;default:this.onGeoportalSearchChange()}};
netgis.Import.prototype.onGeoportalSearchChange=function(a){a=a.detail.query;if(0<a.length){this.geoportalLoader.classList.remove("netgis-hide");a=netgis.util.replace(a," ",",");var b=this.config["import"].geoportal_search_url;b=netgis.util.replace(b,"{query}",window.encodeURIComponent(a));netgis.util.request(b,this.onGeoportalSearchResponse.bind(this));this.geoportalSearch.showClearButton(!0)}};netgis.Import.prototype.onGeoportalSearchClear=function(a){this.geoportalResults.clear()};
netgis.Import.prototype.onGeoportalSearchResponse=function(a){function b(a){if(a&&a.layer)for(var c=0;c<a.layer.length;c++)b(a.layer[c]);else a&&e.push(a);return e.length}a=JSON.parse(a);this.geoportalResults.clear();this.geoportalDataRaw=a=a.wms.srv;this.geoportalData=[];for(var c=0;c<a.length;c++){var d=a[c];var e=[];var f=b(d);f=this.geoportalResults.addFolder(null,c,d.title+" ("+f+")");f.setAttribute("title",d["abstract"]);for(var g=0;g<e.length;g++)this.geoportalResults.addCheckbox(f,g,e[g].title);
d.children=e;this.geoportalData.push(d)}this.geoportalLoader.classList.add("netgis-hide")};netgis.Import.prototype.onGeoportalTreeItemChange=function(a){a=this.geoportalResults.container.getElementsByClassName("netgis-item");for(var b=0,c=0;c<a.length;c++)a[c].getElementsByTagName("input")[0].checked&&(b+=1);this.geoportalSubmit.getElementsByClassName("netgis-count")[0].innerHTML=0===b?"":" ("+b+")"};
netgis.Import.prototype.onGeoportalSubmit=function(a){a=this.geoportalResults.container.getElementsByClassName("netgis-item");for(var b=0,c=0;c<a.length;c++){var d=a[c],e=d.getElementsByTagName("input")[0];if(e.checked){b+=1;e=e.getAttribute("data-id");d=d.parentNode.parentNode.parentNode.getAttribute("data-id");var f=this.geoportalData[d],g=f.children[e],h=f.title;f=f.getMapUrl;var k=g.name;g=g.title;d="geoportal_"+d;e=d+"_"+e;netgis.util.invoke(this.sections.geoportal,netgis.Events.IMPORT_GEOPORTAL_SUBMIT,
{folder:{id:d,title:h},layer:{id:e,url:f,name:k,title:g}})}}0<b&&this.modal.hide()};netgis=netgis||{};netgis.Info=function(a){this.config=a;this.queryLayers={};this.popup=new netgis.Popup;this.popup.setHeader("Abfrage");this.initConfig(a)};netgis.Info.Config={default_format:"text/plain",proxy:""};netgis.Info.prototype.initConfig=function(a){a=a.layers;for(var b=a.length-1;0<=b;b--){var c=a[b];!0===c.active&&this.isLayerQueryable(c)?this.queryLayers[c.id]=c:this.queryLayers[c.id]&&delete this.queryLayers[c.id]}};
netgis.Info.prototype.attachTo=function(a){this.popup.attachTo(a);a.addEventListener(netgis.Events.CLIENT_CONTEXT_RESPONSE,this.onClientContextResponse.bind(this));a.addEventListener(netgis.Events.CLIENT_SET_MODE,this.onClientSetMode.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_TOGGLE,this.onMapLayerToggle.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_CREATE,this.onMapLayerCreate.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_DELETE,this.onMapLayerDelete.bind(this));a.addEventListener(netgis.Events.IMPORT_LAYER_ACCEPT,
this.onImportLayerAccept.bind(this));a.addEventListener(netgis.Events.IMPORT_GEOPORTAL_SUBMIT,this.onImportGeoportalSubmit.bind(this));a.addEventListener(netgis.Events.MAP_CLICK,this.onMapClick.bind(this));a.addEventListener(netgis.Events.MAP_FEATURE_CLICK,this.onMapFeatureClick.bind(this))};netgis.Info.prototype.isLayerQueryable=function(a){var b=!1;if(!0===a.query)b=!0;else if(!1!==a.query)switch(a.type){case netgis.LayerTypes.WMS:case netgis.LayerTypes.WMST:b=!0}return b};
netgis.Info.prototype.addSection=function(a,b,c){this.popup.addContent([!0===c?"<details open='open'>":"<details>","<summary class='netgis-button netgis-noselect netgis-clip-text netgis-color-d netgis-hover-text-a netgis-hover-d'>",a,"</summary><div class='netgis-border-d'>",b,"</div></details>"].join(""))};netgis.Info.prototype.onClientContextResponse=function(a){this.initConfig(a.detail.context.config)};netgis.Info.prototype.onClientSetMode=function(a){this.popup.hide()};
netgis.Info.prototype.onMapLayerToggle=function(a){var b=a.detail;a=b.id;if(b.on){b=this.config.layers;for(var c=null,d=0;d<b.length;d++)if(b[d].id===a){c=b[d];break}c&&this.isLayerQueryable(c)&&(this.queryLayers[a]=c)}else delete this.queryLayers[a]};netgis.Info.prototype.onMapLayerCreate=function(a){a=a.detail;this.isLayerQueryable(a)&&(this.queryLayers[a.id]=a)};netgis.Info.prototype.onMapLayerDelete=function(a){delete this.queryLayers[a.detail.id]};
netgis.Info.prototype.onImportLayerAccept=function(a){a=a.detail;this.isLayerQueryable(a)&&(this.queryLayers[a.id]=a)};netgis.Info.prototype.onImportGeoportalSubmit=function(a){};
netgis.Info.prototype.onMapClick=function(a){a=a.detail;if(a.mode===netgis.Modes.SEARCH_PARCEL)this.popup.clearContent(),this.popup.hide();else if(a.mode===netgis.Modes.VIEW){var b=this.config.info;this.popup.container!==a.overlay&&this.popup.attachTo(a.overlay);this.popup.clearContent();var c=0,d;for(d in this.queryLayers){var e=this.queryLayers[d];if(a.info&&a.info[d]){var f=a.info[d];b.proxy&&0<b.proxy.length&&(f=b.proxy+f);netgis.util.request(f,this.onLayerResponseWMS.bind(this),{title:e.title});
c+=1}else{if(!e.query_url||""===e.query_url)switch(e.type){case netgis.LayerTypes.WMS:case netgis.LayerTypes.WMST:f=e.url;var g=["SERVICE=WMS","VERSION=1.1.1","REQUEST=GetFeatureInfo","STYLES=","LAYERS="+window.encodeURIComponent(e.name),"QUERY_LAYERS="+window.encodeURIComponent(e.name),"BBOX="+a.view.bbox.join(","),"SRS="+a.view.projection,"WIDTH="+a.view.width,"HEIGHT="+a.view.height,"X="+Math.round(a.pixel[0]),"Y="+Math.round(a.pixel[1]),"INFO_FORMAT="+(b&&b.default_format?b.default_format:"text/plain")];
f=f+(-1===f.indexOf("?")?"?":"")+g.join("&");b.proxy&&0<b.proxy.length&&(f=b.proxy+f);netgis.util.request(f,this.onLayerResponseWMS.bind(this),{title:e.title});c+=1}(f=e.query_url)&&""!==f&&(f=netgis.util.replace(f,"{bbox}",a.view.bbox.join(",")),f=netgis.util.replace(f,"{proj}",a.view.projection),f=netgis.util.replace(f,"{width}",a.view.width),f=netgis.util.replace(f,"{height}",a.view.height),f=netgis.util.replace(f,"{x}",a.coords[0]),f=netgis.util.replace(f,"{y}",a.coords[1]),f=netgis.util.replace(f,
"{px}",a.pixel[0]),f=netgis.util.replace(f,"{py}",a.pixel[1]),f=netgis.util.replace(f,"{lon}",a.lon),f=netgis.util.replace(f,"{lat}",a.lat),b.proxy&&0<b.proxy.length&&(f=b.proxy+f),netgis.util.request(f,this.onLayerResponseWMS.bind(this),{title:e.title}),c+=1)}}0<c?(this.popup.showLoader(),this.popup.show()):this.popup.hide()}};
netgis.Info.prototype.onMapFeatureClick=function(a){var b=a.detail,c=b.properties;if(b.mode===netgis.Modes.SEARCH_PARCEL)this.popup.clearContent(),this.popup.hide();else{a=null;var d=[],e="geometry fill fill-opacity stroke stroke-opacity stroke-width styleUrl".split(" ");for(g in c)if(!(-1<e.indexOf(g))){var f=c[g];d.push([g,f]);a||("name"===g&&""!==f?a=f:"title"===g&&""!==f?a=f:"id"===g&&f&&(a=f))}!a&&b.id&&(a=b.id);a=a?'Feature "'+a+'"':"Feature";"geolocation"===b.id&&((a=this.config.geolocation.marker_title)&&
""!==a||(a="Geolocation"),d.push(["L\u00e4ngengrad (Lon.)",b.lon]),d.push(["Breitengrad (Lat.)",b.lat]));b=[];if(0<d.length){b.push("<table>");for(c=0;c<d.length;c++){f=d[c];var g=f[0];f=f[1];b.push("<tr class='netgis-hover-d'>");b.push("<th>"+g+"</th>");b.push("<td>"+f+"</td>");b.push("</tr>")}b.push("</table>")}else b.push("<i>Keine Eigenschaften vorhanden...</i>");b=b.join("");this.addSection(a,b,!1);!this.popup.isVisible()&&this.popup.show()}};
netgis.Info.prototype.onLayerResponseWMS=function(a,b,c){b=b.title;if(c=c.getResponseHeader("Content-Type"))switch(c.split(";")[0]){case "text/plain":a="<pre>"+a+"</pre>"}this.popup.hideLoader();this.addSection(b,a,!1)};netgis=netgis||{};netgis.LayerID={EDITABLE:"editable-layer",NON_EDITABLE:"non-editable-layer"};netgis=netgis||{};netgis.LayerTree=function(a){this.config=a;this.importFolder=null;this.initElements(a);this.initFolders();this.initConfig(a)};netgis.LayerTree.Config={open:!1,title:"Layers",buttons:[]};netgis.LayerTree.Folders=[];
netgis.LayerTree.prototype.initElements=function(a){a=a.layertree;this.panel=new netgis.Panel("Layers");this.tree=new netgis.Tree(a.draggable);this.tree.attachTo(this.panel.content);this.tree.container.addEventListener(netgis.Events.TREE_ITEM_CHANGE,this.onTreeItemChange.bind(this));this.tree.container.addEventListener(netgis.Events.TREE_ITEM_SLIDER_CHANGE,this.onTreeItemSliderChange.bind(this));this.tree.container.addEventListener(netgis.Events.TREE_ITEM_ORDER_CHANGE,this.onTreeItemOrderChange.bind(this));
!0===a.draggable&&(this.panel.content.addEventListener("dragover",this.onDragOver.bind(this)),this.panel.content.addEventListener("drop",this.onDragDrop.bind(this)))};
netgis.LayerTree.prototype.initFolders=function(){this.editFolder=this.tree.addFolder(null,"edit-folder","Zeichnung",!0,!0);this.tree.addCheckbox(this.editFolder,netgis.LayerID.EDITABLE,"Editierbar");this.tree.setItemChecked(netgis.LayerID.EDITABLE,!0);this.tree.addCheckbox(this.editFolder,netgis.LayerID.NON_EDITABLE,"Nicht-Editierbar");this.tree.setItemChecked(netgis.LayerID.NON_EDITABLE,!0);this.editFolder.classList.add("netgis-hide")};
netgis.LayerTree.prototype.initConfig=function(a,b){var c=a.layertree;c&&c.title&&this.panel.setTitle(c.title);var d=a.folders,e={};if(d){for(var f=0;f<d.length;f++){var g=d[f],h=this.tree.addFolder(null,g.id,g.title,b,!1,g.draggable);e[g.id]=h;!0===g.open&&this.tree.setFolderOpen(g.id,!0)}for(f=0;f<d.length;f++)g=d[f],h=g.id,g=g.parent,-1===g&&(g=null),""===g&&(g=null),g&&this.tree.setFolderParent(e[h],e[g])}if(b=a.layers)for(f=0;f<b.length;f++){var k=b[f];g=e[k.folder]?e[k.folder]:null;h=k.id?k.id:
f.toString();var l=!1;if(g)for(var m=0;m<d.length;m++){var n=d[m];n.id===k.folder&&(l=n.radio)}m=k.title;n='<i class="fas fa-mouse-pointer" title="Ebene ist abfragbar"></i>';a.layertree&&a.layertree.query_icon&&(n=a.layertree.query_icon);(!0===k.query||k.query_url&&""!==k.query_url)&&n&&""!==n&&(m+='<span class="netgis-right">'+n+"</span>");h=!0===l?this.tree.addRadioButton(g,h,m,k.active,this.createDefaultDetails(k,!0,!1)):this.tree.addCheckbox(g,h,m,k.active,!1,this.createDefaultDetails(k,!0,!0));
h.addEventListener("contextmenu",this.onTreeItemMenu.bind(this));!0===k.hidden&&h.classList.add("netgis-hide")}this.tree.updateFolderChecks();if(c&&c.buttons)for(a=a.layertree.buttons,f=0;f<a.length;f++)d=a[f],this.tree.addButton(null,d.id,d.title,this.onTreeButtonClick.bind(this));c&&!0===c.open&&this.panel.show()};
netgis.LayerTree.prototype.attachTo=function(a){this.panel.attachTo(a);a.addEventListener(netgis.Events.CLIENT_CONTEXT_RESPONSE,this.onClientContextResponse.bind(this));a.addEventListener(netgis.Events.LAYERTREE_TOGGLE,this.onLayerTreeToggle.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_CREATE,this.onMapLayerCreate.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_TOGGLE,this.onMapLayerToggle.bind(this));a.addEventListener(netgis.Events.IMPORT_LAYER_ACCEPT,this.onImportLayerAccept.bind(this));
a.addEventListener(netgis.Events.IMPORT_GEOPORTAL_SUBMIT,this.onImportGeoportalSubmit.bind(this));a.addEventListener(netgis.Events.CONTEXTMENU_SLIDER_CHANGE,this.onContextMenuSliderChange.bind(this));a.addEventListener(netgis.Events.MAP_EDIT_LAYER_LOADED,this.onMapEditLayerChange.bind(this));a.addEventListener(netgis.Events.MAP_EDIT_LAYER_CHANGE,this.onMapEditLayerChange.bind(this))};
netgis.LayerTree.prototype.createDefaultDetails=function(a,b,c){var d=[];!0===b&&d.push({title:"<i class='netgis-icon fas fa-eye-slash'></i> Transparenz:",type:"slider",val:a.transparency?Math.round(100*a.transparency):0});!0===c&&d.push({title:"<i class='netgis-icon fas fa-times'></i> Entfernen",type:"button",callback:this.onTreeItemDeleteClick.bind(this)});return d};
netgis.LayerTree.prototype.onTreeItemChange=function(a){var b=a.detail;netgis.util.invoke(a.target,netgis.Events.MAP_LAYER_TOGGLE,{id:b.id,on:b.checked})};netgis.LayerTree.prototype.onClientContextResponse=function(a){this.initConfig(a.detail.context.config,!0)};netgis.LayerTree.prototype.onLayerTreeToggle=function(a){this.panel.toggle()};netgis.LayerTree.prototype.onTreeButtonClick=function(a){a=a.currentTarget;var b=a.getAttribute("data-id");netgis.Client.handleCommand(a,b)};
netgis.LayerTree.prototype.onMapLayerCreate=function(a){this.addLayerItem(a.detail,null)};netgis.LayerTree.prototype.onMapLayerToggle=function(a){a=a.detail;this.tree.setItemChecked(a.id,a.on,!0);this.tree.updateFolderChecks()};netgis.LayerTree.prototype.onImportLayerAccept=function(a){a=a.detail;this.importFolder||(this.importFolder=this.tree.addFolder(null,"_import","Import",!0,!1));this.addLayerItem(a,this.importFolder);this.tree.updateFolderChecks()};
netgis.LayerTree.prototype.addLayerItem=function(a,b){var c=a.title,d='<i class="fas fa-mouse-pointer" title="Ebene ist abfragbar"></i>';config.layertree&&config.layertree.query_icon&&(d=config.layertree.query_icon);(!0===a.query||a.query_url&&""!==a.query_url)&&d&&""!==d&&(c+='<span class="netgis-right">'+d+"</span>");this.tree.addCheckbox(b,a.id,c,!0,!0,this.createDefaultDetails(a,!0,!0)).addEventListener("contextmenu",this.onTreeItemMenu.bind(this))};
netgis.LayerTree.prototype.onImportGeoportalSubmit=function(a){a=a.detail;var b=a.folder.id,c=this.tree.getFolder(b);c||(c=this.tree.addFolder(null,b,a.folder.title,!0,!1));var d=a.layer.id;b={id:d,folder:b,title:a.layer.title,active:!0,type:netgis.LayerTypes.WMS,url:a.layer.url,name:a.layer.name,order:1E4,transparency:0};this.config.layers.push(b);this.tree.addCheckbox(c,d,a.layer.title,!1,!1,this.createDefaultDetails(b,!0,!0));this.tree.setItemChecked(d,!0,!1)};
netgis.LayerTree.prototype.onTreeItemMenu=function(a){a.preventDefault();return!1};netgis.LayerTree.prototype.onContextMenuSliderChange=function(a){var b=a.detail;a=.01*b.val;var c=null;0===b.id.indexOf("layer_trans_")&&(c=b.id.split("layer_trans_")[1]);b=this.config.layers;for(var d=0;d<b.length;d++){var e=b[d];if(e.id===c){e.transparency=a;break}}netgis.util.invoke(this.tree.container,netgis.Events.MAP_LAYER_TRANSPARENCY,{id:c,transparency:a})};
netgis.LayerTree.prototype.onTreeItemSliderChange=function(a){var b=a.detail;a=b.id;b=.01*b.val;for(var c=this.config.layers,d=0;d<c.length;d++){var e=c[d];if(e.id===a){e.transparency=b;break}}netgis.util.invoke(this.tree.container,netgis.Events.MAP_LAYER_TRANSPARENCY,{id:a,transparency:b})};
netgis.LayerTree.prototype.onTreeItemOrderChange=function(a){a=a.detail.items;for(var b=this.config.layers,c=a.length,d=0;d<a.length;d++){for(var e=a[d].getElementsByTagName("input")[0].getAttribute("data-id"),f=0;f<b.length;f++){var g=b[f];g.id===e&&(g.order=c,netgis.util.invoke(this.tree.container,netgis.Events.MAP_LAYER_ORDER,{id:e,order:c}))}c--}};
netgis.LayerTree.prototype.onTreeItemDeleteClick=function(a){a=a.currentTarget.parentNode.parentNode.parentNode.parentNode.getElementsByTagName("input")[0].getAttribute("data-id");netgis.util.invoke(this.tree.container,netgis.Events.MAP_LAYER_DELETE,{id:a});this.tree.removeItem(a)};netgis.LayerTree.prototype.onMapEditLayerChange=function(a){this.editFolder.classList.remove("netgis-hide")};netgis.LayerTree.prototype.onDragOver=function(a){a.preventDefault()};
netgis.LayerTree.prototype.onDragDrop=function(a){a=this.tree.dragElement;"summary"===a.nodeName.toLowerCase()&&(a=a.parentNode.parentNode);a.parentNode.removeChild(a);0<this.tree.container.childNodes.length?this.tree.container.insertBefore(a,this.tree.container.childNodes[0]):this.tree.container.appendChild(a);netgis.util.invoke(this.tree.container,netgis.Events.TREE_ITEM_ORDER_CHANGE,{items:this.tree.container.getElementsByClassName("netgis-item")})};netgis=netgis||{};netgis.LayerTypes={TMS:"TMS",XYZ:"XYZ",OSM:"OSM",WMTS:"WMTS",WMS:"WMS",WMST:"WMST",GEOJSON:"GEOJSON",VTILES:"VTILES",WFS:"WFS",GML:"GML",KML:"KML",GEOPACKAGE:"GEOPACKAGE",SPATIALITE:"SPATIALITE",SHAPEFILE:"SHAPEFILE",WKT:"WKT",HIDDEN:"HIDDEN"};netgis=netgis||{};netgis.Legend=function(a){this.config=a;this.initElements();this.initConfig(a)};netgis.Legend.Config={open:!1};netgis.Legend.prototype.initElements=function(){this.panel=new netgis.Panel("<i class='netgis-icon fas fa-bars'></i><span>Legende</span>");this.panel.content.classList.add("netgis-legend")};netgis.Legend.prototype.initConfig=function(a){var b=a.legend;b&&!0===b.open&&this.show();a=a.layers;for(b=0;b<a.length;b++){var c=a[b];!0===c.active?this.addLayerLegend(c.id):this.removeLayerLegend(c.id)}};
netgis.Legend.prototype.attachTo=function(a){this.panel.attachTo(a);a.addEventListener(netgis.Events.CLIENT_CONTEXT_RESPONSE,this.onClientContextResponse.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_TOGGLE,this.onMapLayerToggle.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_CREATE,this.onMapLayerCreate.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_DELETE,this.onMapLayerDelete.bind(this));a.addEventListener(netgis.Events.LEGEND_TOGGLE,this.onLegendToggle.bind(this))};
netgis.Legend.prototype.show=function(){this.panel.show()};netgis.Legend.prototype.hide=function(){this.panel.hide()};netgis.Legend.prototype.addSection=function(a,b,c,d){this.panel.content.innerHTML=[!0===d?"<details data-id='"+a+"' open='open'>":"<details data-id='"+a+"'>","<summary class='netgis-button netgis-noselect netgis-clip-text netgis-color-d netgis-hover-text-a netgis-hover-d'>",b,"</summary><div class='netgis-border-d'>",c,"</div></details>"].join("")+this.panel.content.innerHTML};
netgis.Legend.prototype.addLayerLegend=function(a){for(var b=null,c=this.config.layers,d=0;d<c.length;d++){var e=c[d];if(e.id===a){b=e;break}}if(b){c=b.legend;if(!c||""===c)switch(b.type){case netgis.LayerTypes.WMS:case netgis.LayerTypes.WMST:(c=b.url)&&-1===c.indexOf("?")&&(c+="?"),c+=["service=WMS&version=1.1.0&request=GetLegendGraphic&format=image/png","layer="+b.name].join("&")}c&&""!==c&&this.addSection(a,b.title,"<img src='"+c+"'/>",!0)}};
netgis.Legend.prototype.removeLayerLegend=function(a){for(var b=this.panel.content.getElementsByTagName("details"),c=0;c<b.length;c++){var d=b[c];d.getAttribute("data-id")===a&&d.parentNode.removeChild(d)}};netgis.Legend.prototype.onClientContextResponse=function(a){this.initConfig(a.detail.context.config)};netgis.Legend.prototype.onMapLayerToggle=function(a){a=a.detail;a.on?this.addLayerLegend(a.id):this.removeLayerLegend(a.id)};netgis.Legend.prototype.onMapLayerCreate=function(a){this.addLayerLegend(a.detail.id)};
netgis.Legend.prototype.onMapLayerDelete=function(a){this.removeLayerLegend(a.detail.id)};netgis.Legend.prototype.onLegendToggle=function(a){this.panel.toggle()};netgis=netgis||{};
netgis.Map=function(a){this.config=a;this.mode=null;this.interactions={};this.layers={};this.viewHistory=[];this.viewIndex=-1;this.viewFromHistory=!1;this.viewHistoryMax=20;this.paddingBuffer=40;this.hoverBounds=this.hoverFeature=null;this.selectedFeatures=[];this.sketchFeatures=[];this.snap=null;this.snapFeatures=new ol.Collection;this.drawError=this.selectReset=this.selectMultiple=this.editEventsSilent=!1;this.initElements();a.map&&(this.initMap(a),this.initLayers(),this.initOverlays(),this.initInteractions(),
this.initConfig(a),this.setPadding(0,0,0,0),this.setMode(netgis.Modes.VIEW))};netgis.Map.Config={projection:"EPSG:25832",center:[329766.1782104631,5513621.076679279],center_lonlat:[7,50],zoom:14,min_zoom:5,max_zoom:19,extent:[293315.97,5423948.96,464350.97,5644103.06],bbox:[293315.97,5423948.96,464350.97,5644103.06],scales:[500,1E3,3E3,5E3,8E3,1E4,15E3,25E3,5E4,1E5,15E4,25E4,5E5,1E6,15E5,2E6],scale:1E5,scalebar:!0,max_view_history:20};netgis.Map.Projections=[["EPSG:25832","+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs"]];
netgis.Map.Layers=[];netgis.Map.Measure={line_color:"rgba( 255, 0, 0, 1.0 )",line_width:3,line_dash:[5,10],area_fill:"rgba( 255, 0, 0, 0.3 )",point_radius:4,point_fill:"rgba( 255, 255, 255, 1.0 )",point_stroke:"rgba( 0, 0, 0, 1.0 )",text_color:"#871d33",text_back:"rgba( 255, 255, 255, 0.7 )"};
netgis.Map.Tools={editable:!0,output_id:"",interactive_render:!0,select_multi_reset:!0,buffer:{default_radius:300,default_segments:3},snapping:{show:!0,active:!0,tolerance:10},bounds:void 0,bounds_message:"Out of bounds!",show_bounds:!0};
netgis.Map.Styles={draw:{fill:"rgba( 255, 0, 0, 0.5 )",stroke:"#ff0000",width:3,radius:6,viewport_labels:!0},non_edit:{fill:"rgba( 80, 80, 80, 0.5 )",stroke:"#666666",width:3,radius:6,viewport_labels:!0},select:{fill:"rgba( 0, 127, 255, 0.5 )",stroke:"#007fff",width:3,radius:6},sketch:{fill:"rgba( 0, 127, 0, 0.5 )",stroke:"#007f00",width:3,radius:6},error:{fill:"rgba( 255, 0, 0, 0.5 )",stroke:"#ff0000",width:3,radius:6},bounds:{fill:"rgba( 0, 0, 0, 0.0 )",stroke:"#000000",width:3,radius:6},modify:{fill:"rgba( 255, 127, 0, 0.5 )",
stroke:"#ff7f00",width:3,radius:6},parcel:{fill:"rgba( 127, 0, 0, 0.0 )",stroke:"rgba( 127, 0, 0, 1.0 )",width:1.5},"import":{fill:"rgba( 0, 127, 255, 0.2 )",stroke:"rgba( 0, 127, 255, 1.0 )",width:1.5}};
netgis.Map.prototype.initElements=function(){this.container=document.createElement("div");this.container.setAttribute("tabindex",-1);this.container.className="netgis-map";this.container.addEventListener("pointerleave",this.onPointerLeave.bind(this));this.container.addEventListener("click",this.onContainerClick.bind(this));this.container.addEventListener("contextmenu",this.onRightClick.bind(this));this.container.addEventListener("keydown",this.onKeyDown.bind(this));this.container.addEventListener("keyup",
this.onKeyUp.bind(this))};
netgis.Map.prototype.initMap=function(a){var b=a.map;"undefined"!==typeof proj4?(a.projections&&0<a.projections.length&&proj4.defs(a.projections),proj4.defs("urn:ogc:def:crs:OGC:1.3:CRS84",proj4.defs("EPSG:4326")),ol.proj.proj4.register(proj4)):(a.projections&&0<a.projections.length||b.projection)&&console.error("map projections configured but no proj4 js library found",a.projections,b.projection);a=void 0;b.center_lonlat&&(a=ol.proj.fromLonLat(b.center_lonlat,b.projection));!a&&b.center&&(a=b.center);
var c=void 0;if(b.zoom||0===b.zoom)c=b.zoom;void 0===c&&void 0!==b.min_zoom&&(c=b.min_zoom);void 0===c&&(c=0);this.view=new ol.View({projection:b.projection,center:a,minZoom:b.min_zoom,maxZoom:b.max_zoom,zoom:c});b.default_scale&&console.error("config[ 'map' ][ 'default_scale' ] is deprecated, use config[ 'map' ][ 'scale' ] instead");b.scale&&this.view.setResolution(this.getResolutionFromScale(b.scale));this.map=new ol.Map({target:this.container,view:this.view,pixelRatio:1,moveTolerance:b.move_tolerance||
0===b.move_tolerance?b.move_tolerance:7,controls:[]});if(b.scalebar&&(this.scalebar=new ol.control.ScaleLine({bar:!0}),this.map.addControl(this.scalebar),(a=b.scales)&&0<a.length))for(this.scalebarSelect=document.createElement("select"),this.scalebarSelect.addEventListener("change",this.onScalebarSelectChange.bind(this)),this.scalebar.element.appendChild(this.scalebarSelect),c=0;c<a.length;c++){var d=a[c],e=document.createElement("option");e.innerHTML="1:"+d;e.setAttribute("value",d);this.scalebarSelect.appendChild(e)}this.map.on("moveend",
this.onMapMoveEnd.bind(this));this.map.on("pointermove",this.onPointerMove.bind(this));this.map.on("click",this.onPointerClick.bind(this));if(b){var f=b.extent;b.bbox&&(f=b.bbox);if(f){var g=this;window.setTimeout(function(){g.map.updateSize();g.view.fit(f)},10)}}};
netgis.Map.prototype.initLayers=function(){this.measureLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),zIndex:6E4,style:this.styleMeasure.bind(this)});this.map.addLayer(this.measureLayer);var a=this.config.tools;if(a&&(this.nonEditLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),zIndex:5E4,style:this.styleNonEdit.bind(this),updateWhileAnimating:a&&a.interactive_render?a.interactive_render:!1,updateWhileInteracting:a&&a.interactive_render?a.interactive_render:
!1}),this.map.addLayer(this.nonEditLayer),this.editLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),zIndex:5E4,style:this.styleEdit.bind(this),updateWhileAnimating:a&&a.interactive_render?a.interactive_render:!1,updateWhileInteracting:a&&a.interactive_render?a.interactive_render:!1}),this.map.addLayer(this.editLayer),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)),this.previewLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),zIndex:55E3,style:this.styleSketch.bind(this)}),this.map.addLayer(this.previewLayer),this.boundsLayer=null,a=a.bounds)){a=netgis.util.replace(a,"'",'"');var b=(new ol.format.GeoJSON).readFeatures(a);a=null;this.config.tools.show_bounds&&this.config.styles.bounds&&(a=this.createStyle(this.config.styles.bounds));this.boundsLayer=new ol.layer.Vector({source:new ol.source.Vector({features:b}),
style:a,zIndex:6E4});this.map.addLayer(this.boundsLayer)}this.geolocLayer=null;this.config.modules&&!0===this.config.modules.geolocation&&(a=this.config.geolocation,a||(a=netgis.Geolocation.Config),a=[new ol.style.Style({image:new ol.style.Circle({fill:new ol.style.Fill({color:"#ffffff"}),radius:8})}),new ol.style.Style({image:new ol.style.Circle({fill:new ol.style.Fill({color:a.marker_color?a.marker_color:"#ff0000"}),radius:5})})],b=new ol.Feature({geometry:new ol.geom.Point(ol.proj.fromLonLat([7,
50],this.view.getProjection()))}),b.setId("geolocation"),this.geolocLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[b]}),style:a,zIndex:66E3}),this.map.addLayer(this.geolocLayer),this.geolocLayer.setVisible(!1))};netgis.Map.prototype.initOverlays=function(){var a=document.createElement("div");a.className="netgis-map-overlay";this.popupOverlay=new ol.Overlay({id:"popup",element:a,positioning:"center-center"});this.map.addOverlay(this.popupOverlay)};
netgis.Map.prototype.initInteractions=function(){this.interactions[netgis.Modes.VIEW]=[new ol.interaction.DragPan,new ol.interaction.DragPan({condition:function(a){return 1===a.originalEvent.button}}),new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.ZOOM_BOX]=[new ol.interaction.DragZoom({condition:function(a){return 0===a.originalEvent.button},out:!1,className:"netgis-zoom-box"}),new ol.interaction.DragPan({condition:function(a){return 1===a.originalEvent.button}}),new ol.interaction.MouseWheelZoom];
this.interactions[netgis.Modes.MEASURE_LINE]=[new ol.interaction.DragPan,new ol.interaction.Modify({source:this.measureLayer.getSource(),deleteCondition:ol.events.condition.doubleClick,style:this.styleMeasure.bind(this)}),new ol.interaction.Draw({type:"LineString",source:this.measureLayer.getSource(),style:this.styleMeasure.bind(this)}),new ol.interaction.DragPan({condition:function(a){return 1===a.originalEvent.button}}),new ol.interaction.PinchZoom,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.MEASURE_AREA]=
[new ol.interaction.DragPan,new ol.interaction.Modify({source:this.measureLayer.getSource(),deleteCondition:ol.events.condition.doubleClick,style:this.styleMeasure.bind(this)}),new ol.interaction.Draw({type:"Polygon",source:this.measureLayer.getSource(),style:this.styleMeasure.bind(this)}),new ol.interaction.DragPan({condition:function(a){return 1===a.originalEvent.button}}),new ol.interaction.PinchZoom,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.MEASURE_LINE][2].on("drawstart",
this.onMeasureLineBegin.bind(this));this.interactions[netgis.Modes.MEASURE_AREA][2].on("drawstart",this.onMeasureAreaBegin.bind(this));if(this.config.tools&&!0===this.config.tools.editable){var a=this.config.tools.bounds?!0:!1;this.interactions[netgis.Modes.DRAW_POINTS]=[new ol.interaction.Draw({type:"Point",source:this.editLayer.getSource(),style:this.styleSketch.bind(this),geometryFunction:a?this.onDrawPointsUpdateGeom.bind(this):void 0}),new ol.interaction.DragPan,new ol.interaction.DragPan({condition:function(a){return 1===
a.originalEvent.button}}),new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.DRAW_POINTS][0].on("drawend",this.onDrawBufferEnd.bind(this));if(a)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),geometryFunction:a?this.onDrawLinesUpdateGeom.bind(this):void 0}),new ol.interaction.DragPan,new ol.interaction.DragPan({condition:function(a){return 1===
a.originalEvent.button}}),new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.DRAW_LINES][0].on("drawend",this.onDrawBufferEnd.bind(this));if(a)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),geometryFunction:a?this.onDrawPolygonsUpdateGeom.bind(this):void 0}),new ol.interaction.DragPan,new ol.interaction.DragPan({condition:function(a){return 1===
a.originalEvent.button}}),new ol.interaction.MouseWheelZoom];if(a)this.interactions[netgis.Modes.DRAW_POLYGONS][0].on("drawend",this.onDrawPolygonsEnd.bind(this));this.interactions[netgis.Modes.MODIFY_FEATURES]=[new ol.interaction.DragPan,new ol.interaction.Modify({source:this.editLayer.getSource(),deleteCondition:ol.events.condition.doubleClick,style:this.styleModify.bind(this)}),new ol.interaction.DragPan({condition:function(a){return 1===a.originalEvent.button}}),new ol.interaction.MouseWheelZoom];
this.interactions[netgis.Modes.DELETE_FEATURES]=[new ol.interaction.DragPan,new ol.interaction.DragPan({condition:function(a){return 1===a.originalEvent.button}}),new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.CUT_FEATURES_DRAW]=[new ol.interaction.Draw({type:"Polygon",style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.DragPan({condition:function(a){return 1===a.originalEvent.button}}),new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.CUT_FEATURES_DRAW][0].on("drawend",
this.onCutFeaturesDrawEnd.bind(this))}};netgis.Map.prototype.initConfig=function(a){var b=a.map;b&&(b.bbox&&this.zoomBBox(a.map.bbox),!b.zoom||b.extent||b.scale||this.view.setZoom(a.map.zoom),b.max_view_history&&(this.viewHistoryMax=b.max_view_history));if(a=a.layers)for(b=a.length-1;0<=b;b--){var c=a[b];!0===c.active&&this.addLayer(c.id,c)}};
netgis.Map.prototype.attachTo=function(a){a.appendChild(this.container);a.addEventListener(netgis.Events.CLIENT_CONTEXT_RESPONSE,this.onClientContextResponse.bind(this));a.addEventListener(netgis.Events.CLIENT_SET_MODE,this.onClientSetMode.bind(this));a.addEventListener(netgis.Events.PANEL_TOGGLE,this.onPanelToggle.bind(this));a.addEventListener(netgis.Events.PANEL_RESIZE,this.onPanelResize.bind(this));a.addEventListener(netgis.Events.MAP_EDIT_LAYER_LOADED,this.onEditLayerLoaded.bind(this));a.addEventListener(netgis.Events.MAP_ZOOM,
this.onMapZoom.bind(this));a.addEventListener(netgis.Events.MAP_ZOOM_HOME,this.onMapZoomHome.bind(this));a.addEventListener(netgis.Events.MAP_ZOOM_LONLAT,this.onMapZoomLonLat.bind(this));a.addEventListener(netgis.Events.MAP_ZOOM_SCALE,this.onMapZoomScale.bind(this));a.addEventListener(netgis.Events.MAP_ZOOM_LAYER,this.onMapZoomLayer.bind(this));a.addEventListener(netgis.Events.MAP_ZOOM_LEVEL,this.onMapZoomLevel.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_CREATE,this.onMapLayerCreate.bind(this));
a.addEventListener(netgis.Events.MAP_LAYER_TOGGLE,this.onMapLayerToggle.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_TRANSPARENCY,this.onMapLayerTransparency.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_ORDER,this.onMapLayerOrder.bind(this));a.addEventListener(netgis.Events.MAP_LAYER_DELETE,this.onMapLayerDelete.bind(this));a.addEventListener(netgis.Events.MAP_SNAP_TOGGLE,this.onMapSnapToggle.bind(this));a.addEventListener(netgis.Events.MAP_VIEW_PREV,this.onMapViewPrev.bind(this));
a.addEventListener(netgis.Events.MAP_VIEW_NEXT,this.onMapViewNext.bind(this));a.addEventListener(netgis.Events.GEOLOCATION_TOGGLE_ACTIVE,this.onGeolocToggleActive.bind(this));a.addEventListener(netgis.Events.GEOLOCATION_CHANGE,this.onGeolocChange.bind(this));a.addEventListener(netgis.Events.MEASURE_CLEAR,this.onMeasureClear.bind(this));a.addEventListener(netgis.Events.SELECT_MULTI_TOGGLE,this.onSelectMultiToggle.bind(this));a.addEventListener(netgis.Events.DRAW_BUFFER_TOGGLE,this.onDrawBufferToggle.bind(this));
a.addEventListener(netgis.Events.DRAW_BUFFER_CHANGE,this.onDrawBufferChange.bind(this));a.addEventListener(netgis.Events.BUFFER_CHANGE,this.onBufferChange.bind(this));a.addEventListener(netgis.Events.BUFFER_ACCEPT,this.onBufferAccept.bind(this));a.addEventListener(netgis.Events.IMPORT_LAYER_ACCEPT,this.onImportLayerAccept.bind(this));a.addEventListener(netgis.Events.IMPORT_LAYER_PREVIEW,this.onImportLayerPreview.bind(this));a.addEventListener(netgis.Events.IMPORT_GEOPORTAL_SUBMIT,this.onImportGeoportalSubmit.bind(this));
a.addEventListener(netgis.Events.MAP_COPY_FEATURE_TO_EDIT,this.onCopyFeatureToEdit.bind(this));a.addEventListener(netgis.Events.SEARCHPARCEL_ITEM_ENTER,this.onSearchParcelItemEnter.bind(this));a.addEventListener(netgis.Events.SEARCHPARCEL_ITEM_LEAVE,this.onSearchParcelItemLeave.bind(this));a.addEventListener(netgis.Events.SEARCHPARCEL_ITEM_CLICK,this.onSearchParcelItemClick.bind(this));a.addEventListener(netgis.Events.SEARCHPARCEL_ITEM_IMPORT,this.onSearchParcelItemImport.bind(this));a.addEventListener(netgis.Events.EXPORT_BEGIN,
this.onExportBegin.bind(this));a.addEventListener(netgis.Events.TIMESLIDER_SHOW,this.onTimeSliderShow.bind(this));a.addEventListener(netgis.Events.TIMESLIDER_HIDE,this.onTimeSliderHide.bind(this));a.addEventListener(netgis.Events.TIMESLIDER_SELECT,this.onTimeSliderSelect.bind(this))};
netgis.Map.prototype.setMode=function(a){switch(this.mode){case netgis.Modes.VIEW:this.container.classList.remove("netgis-clickable");break;case netgis.Modes.MODIFY_FEATURES:this.editLayer.setStyle(this.styleEdit.bind(this));break;case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:this.previewLayer.getSource().clear();this.container.classList.remove("netgis-not-allowed");this.container.removeAttribute("title");break;case netgis.Modes.DRAW_POLYGONS:this.container.classList.remove("netgis-not-allowed");
this.container.removeAttribute("title");break;case netgis.Modes.BUFFER_FEATURES:this.clearSketchFeatures();break;case netgis.Modes.BUFFER_FEATURES_EDIT:this.clearSketchFeatures();this.selectedFeatures=[];this.redrawVectorLayers();break;case netgis.Modes.BUFFER_FEATURES_DYNAMIC:this.clearSketchFeatures();this.selectedFeatures=[];this.redrawVectorLayers();break;case netgis.Modes.CUT_FEATURES:a!==netgis.Modes.CUT_FEATURES_DRAW&&(this.selectedFeatures=[],this.redrawVectorLayers());break;case netgis.Modes.CUT_FEATURES_DRAW:this.selectedFeatures=
[],this.redrawVectorLayers()}this.map.getInteractions().clear();this.mode&&this.container.classList.remove("netgis-mode-"+this.mode);var b=this.interactions[a];b||(console.warn("no interactions found for mode",a),b=this.interactions[netgis.Modes.VIEW]);for(var c=0;c<b.length;c++)this.map.addInteraction(b[c]);b=this.config.tools&&this.config.tools.editable;switch(a){case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:b&&(this.setSnapping(this.drawSnapOn),this.onDrawBufferToggle({detail:{on:this.drawBufferOn,
radius:this.drawBufferRadius,segments:this.drawBufferSegments}}));break;case netgis.Modes.DRAW_POLYGONS:b&&this.setSnapping(this.drawSnapOn);break;case netgis.Modes.MODIFY_FEATURES:b&&(this.setSnapping(this.drawSnapOn),this.editLayer.setStyle(this.styleModify.bind(this)))}this.container.classList.add("netgis-mode-"+a);this.mode=a};
netgis.Map.prototype.addLayer=function(a,b){var c=this.createLayer(b);c&&(c.set("id",a),this.map.addLayer(c),this.layers[a]=c,b.order&&c.setZIndex(b.order),b.transparency&&c.setOpacity(1-b.transparency),b.style&&c.setStyle(this.createStyle(b.style)),b.min_zoom&&c.setMinZoom(b.min_zoom-1E-4),b.max_zoom&&c.setMaxZoom(b.max_zoom),c instanceof ol.layer.Vector&&this.addSnapLayer(c),b.type===netgis.LayerTypes.WMST&&netgis.util.invoke(this.container,netgis.Events.TIMESLIDER_SHOW,{layer:a,title:b.title,url:b.url,
name:b.name}));return c};netgis.Map.prototype.isLayerQueryable=function(a){var b=!1;if(!0===a.query)b=!0;else if(!1!==a.query)switch(a.type){case netgis.LayerTypes.WMS:case netgis.LayerTypes.WMST:b=!0}return b};netgis.Map.prototype.getQueryableLayers=function(a){var b=[],c=this.config.layers;if(c)for(var d=0;d<c.length;d++){var e=c[d],f=this.layers[e.id];f&&(a&&f instanceof ol.layer.Vector||this.isLayerQueryable(e)&&b.push(e))}return b};
netgis.Map.prototype.createLayer=function(a){switch(a.type){case netgis.LayerTypes.HIDDEN:break;case netgis.LayerTypes.TMS:case netgis.LayerTypes.XYZ:var b=this.createLayerTMS(a.url,a.projection,a.extent,a.scales,a.resolutions);break;case netgis.LayerTypes.OSM:b=this.createLayerTMS("https://{a-c}.tile.openstreetmap.de/{z}/{x}/{y}.png");break;case netgis.LayerTypes.WMTS:b=this.createLayerWMTS(a.url,a.name);break;case netgis.LayerTypes.WMS:b=this.createLayerWMS(a.url,a.name,a.format,a.tiled,a.username,
a.password);break;case netgis.LayerTypes.WMST:b=this.createLayerWMST(a.url,a.name,a.format,a.tiled,a.username,a.password);break;case netgis.LayerTypes.GEOJSON:(b=a.data)&&netgis.util.isString(b)&&(b=JSON.parse(b));b=this.createLayerGeoJSON(b?b:a.url);break;case netgis.LayerTypes.WFS:b=this.createLayerWFS(a.url,a.name,this.view.getProjection().getCode(),a.format,a.username,a.password);break;case netgis.LayerTypes.VTILES:b=this.createLayerVectorTiles(a.url,a.extent,a.min_zoom,a.max_zoom);break;case netgis.LayerTypes.GML:b=
this.createLayerGML(a.data);break;case netgis.LayerTypes.KML:b=this.createLayerKML(a.url);break;case netgis.LayerTypes.GEOPACKAGE:b=this.createLayerGeoPackage(a.data);break;case netgis.LayerTypes.SPATIALITE:b=this.createLayerSpatialite(a.data);break;case netgis.LayerTypes.SHAPEFILE:b=this.createLayerShapefile(a.data);break;case netgis.LayerTypes.WKT:b=this.createLayerWKT(a.data);break;default:console.error("unknown layer type",a.type)}return b};
netgis.Map.prototype.removeLayer=function(a){var b=this.layers[a];b instanceof ol.layer.Vector&&this.removeSnapLayer(b);for(var c=0;c<this.config.layers.length;c++){var d=this.config.layers[c];d.id===a&&d.type===netgis.LayerTypes.WMST&&netgis.util.invoke(this.container,netgis.Events.TIMESLIDER_HIDE,null)}this.map.removeLayer(b);delete this.layers[a]};netgis.Map.prototype.setLayerOrder=function(a,b){this.layers[a].setZIndex(b)};
netgis.Map.prototype.createStyle=function(a){var b=a.radius?a.radius:3,c=a.width?a.width:1,d=a.fill?a.fill:"gray",e=a.stroke?a.stroke:"black";return function(a){return new ol.style.Style({image:new ol.style.Circle({radius:b-c,fill:new ol.style.Fill({color:d})}),fill:new ol.style.Fill({color:d}),stroke:new ol.style.Stroke({color:e,width:c})})}};
netgis.Map.prototype.styleMeasure=function(a){var b=a.getGeometry(),c=this.config.measure;c||(c=netgis.Map.Measure);var d=new ol.style.Style({fill:new ol.style.Fill({color:c.area_fill}),stroke:new ol.style.Stroke({color:c.line_color,width:c.line_width,lineDash:c.line_dash})});b instanceof ol.geom.Polygon?(b=b.getArea(),d.setText(new ol.style.Text({text:[netgis.util.formatArea(b,!0),"4mm sans-serif"],font:"Arial",fill:new ol.style.Fill({color:c.text_color}),backgroundFill:new ol.style.Fill({color:c.text_back}),
padding:[2,4,2,4],overflow:!0}))):b instanceof ol.geom.LineString&&(this.mode===netgis.Modes.MEASURE_LINE||this.mode===netgis.Modes.VIEW)&&(b=b.getLength(),d.setText(new ol.style.Text({text:[netgis.util.formatDistance(b),"4mm sans-serif"],font:"Arial",fill:new ol.style.Fill({color:c.text_color}),backgroundFill:new ol.style.Fill({color:c.text_back}),padding:[2,4,2,4],overflow:!0})));return c.point_radius&&0<c.point_radius?(b=this.getGeometryPoints(a),a=new ol.style.Style({image:new ol.style.Circle({radius:1.25*
c.point_radius,fill:new ol.style.Fill({color:c.point_stroke})}),geometry:b}),c=new ol.style.Style({image:new ol.style.Circle({radius:c.point_radius,fill:new ol.style.Fill({color:c.point_fill})}),geometry:b}),[d,a,c]):d};
netgis.Map.prototype.styleEdit=function(a){var b,c;this.config&&this.config.styles&&(this.config.styles.draw&&(b=this.config.styles.draw),this.config.styles.select&&(c=this.config.styles.select));b||(b=netgis.Map.Styles.draw);c||(c=netgis.Map.Styles.select);var d=a.getGeometry(),e=this.hoverFeature===a;-1<this.selectedFeatures.indexOf(a)&&(e=!0);var f=e?c.fill:b.fill,g=e?c.stroke:b.stroke;c=new ol.style.Style({image:new ol.style.Circle({radius:e?c.radius:b.radius,fill:new ol.style.Fill({color:g})}),
fill:new ol.style.Fill({color:f}),stroke:new ol.style.Stroke({color:g,width:b.width})});e&&c.setZIndex(1);if(d instanceof ol.geom.Polygon||d instanceof ol.geom.MultiPolygon){e=d.getArea();if(!e||0>=e)return c;!0===b.viewport_labels&&(b=this.view.calculateExtent(this.map.getSize()),f=ol.geom.Polygon.fromExtent(b),b=new jsts.io.OL3Parser,d=b.read(d),f=b.read(f),d=d.intersection(f),d=b.write(d),c.setGeometry(d));e=netgis.util.formatArea(e,!0);(a=a.getProperties().title)&&(e=a+"\n"+e);c.setText(new ol.style.Text({text:e,
font:"4mm Arial, sans-serif",fill:new ol.style.Fill({color:g}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]}))}return c};
netgis.Map.prototype.styleNonEdit=function(a){var b,c;this.config&&this.config.styles&&(this.config.styles.non_edit&&(b=this.config.styles.non_edit),this.config.styles.select&&(c=this.config.styles.select));b||(b=netgis.Map.Styles.non_edit);c||(c=netgis.Map.Styles.select);var d=a.getGeometry(),e=this.hoverFeature===a;-1<this.selectedFeatures.indexOf(a)&&(e=!0);var f=e?c.fill:b.fill,g=e?c.stroke:b.stroke;c=new ol.style.Style({image:new ol.style.Circle({radius:e?c.radius:b.radius,fill:new ol.style.Fill({color:g})}),
fill:new ol.style.Fill({color:f}),stroke:new ol.style.Stroke({color:g,width:b.width})});e&&c.setZIndex(1);if(d instanceof ol.geom.Polygon){e=d.getArea();if(!e||0>=e)return c;!0===b.viewport_labels&&(b=this.map.getView().calculateExtent(this.map.getSize()),f=ol.geom.Polygon.fromExtent(b),b=new jsts.io.OL3Parser,d=b.read(d),f=b.read(f),d=d.intersection(f),d=b.write(d),c.setGeometry(d));e=netgis.util.formatArea(e,!0);(a=a.getProperties().title)&&(e=a+"\n"+e);c.setText(new ol.style.Text({text:e,font:"4mm Arial, sans-serif",
fill:new ol.style.Fill({color:g}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]}))}return c};
netgis.Map.prototype.styleSketch=function(a){var b,c;this.config&&this.config.styles&&(this.config.styles.sketch&&(b=this.config.styles.sketch),this.config.styles.error&&(c=this.config.styles.error));b||(b=netgis.Map.Styles.sketch);c||(c=netgis.Map.Styles.error);this.drawError&&c&&(b=c);var d=a.getGeometry();c=new ol.style.Style({image:new ol.style.Circle({radius:b.radius,fill:new ol.style.Fill({color:b.fill})}),fill:new ol.style.Fill({color:b.fill}),stroke:new ol.style.Stroke({color:b.stroke,width:b.width})});
d instanceof ol.geom.Polygon&&(d=d.getArea(),c.setText(new ol.style.Text({text:[netgis.util.formatArea(d,!0),"4mm sans-serif"],font:"Arial",fill:new ol.style.Fill({color:b.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:b.radius,fill:new ol.style.Fill({color:b.stroke})}),geometry:this.getGeometryPoints(a)});return[c,a]};
netgis.Map.prototype.styleModify=function(a){var b;this.config&&this.config.styles&&this.config.styles.modify&&(b=this.config.styles.modify);b||(b=netgis.Map.Styles.modify);var c=new ol.style.Style({image:new ol.style.Circle({radius:b.radius,fill:new ol.style.Fill({color:b.stroke})}),fill:new ol.style.Fill({color:b.fill}),stroke:new ol.style.Stroke({color:b.stroke,width:b.width})}),d=new ol.style.Style({image:new ol.style.Circle({radius:b.radius,fill:new ol.style.Fill({color:b.stroke})}),geometry:this.getGeometryPoints(a)});
a=a.getGeometry();a instanceof ol.geom.Polygon&&(a=a.getArea(),c.setText(new ol.style.Text({text:[netgis.util.formatArea(a,!0),"4mm sans-serif"],font:"Arial",fill:new ol.style.Fill({color:b.stroke}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]})));return[c,d]};
netgis.Map.prototype.styleHover=function(a){var b;this.config&&this.config.styles&&this.config.styles.select&&(b=this.config.styles.select);b||(b=netgis.Map.Styles.select);return new ol.style.Style({image:new ol.style.Circle({radius:b.radius,fill:new ol.style.Fill({color:b.stroke})}),fill:new ol.style.Fill({color:b.fill}),stroke:new ol.style.Stroke({color:b.stroke,width:b.width}),zIndex:1})};
netgis.Map.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.Map.prototype.redrawVectorLayers=function(){this.map.getLayers().forEach(function(a,b,c){(a instanceof ol.layer.Vector||a instanceof ol.layer.VectorTile)&&a.setStyle(a.getStyle())})};
netgis.Map.prototype.setSnapping=function(a){var b=this.config.tools.snapping;a?(this.snap=new ol.interaction.Snap({features:this.snapFeatures,pixelTolerance:b.tolerance?b.tolerance:10}),this.map.addInteraction(this.snap),this.snapFeatures.changed()):this.snap&&(this.map.removeInteraction(this.snap),this.snap=null);this.drawSnapOn=a};netgis.Map.prototype.setDrawTrace=function(a){};netgis.Map.prototype.addSnapLayer=function(a){a=a.getSource().getFeatures();for(var b=0;b<a.length;b++)this.snapFeatures.push(a[b])};
netgis.Map.prototype.removeSnapLayer=function(a){a=a.getSource().getFeatures();for(var b=0;b<a.length;b++)this.snapFeatures.remove(a[b])};netgis.Map.prototype.setDrawBuffer=function(a,b,c){if(a){var d=this.createBufferFeature(new ol.geom.Point(this.view.getCenter()),b,c);this.previewLayer.getSource().addFeature(d);this.drawBufferRadius=b;this.drawBufferSegments=c}else this.previewLayer.getSource().clear();this.drawBufferOn=a};
netgis.Map.prototype.createLayerTMS=function(a,b,c,d,e){"map"===d&&(this.config.map&&this.config.map.scales?d=this.config.map.scales:(console.error("TMS layer references map scales, but none given in config,",a),d=void 0));"map"===c&&(this.config.map&&this.config.map.extent?c=this.config.map.extent:(console.error("TMS layer references map 'extent', but none given in config 'map',",a),c=void 0));if(b&&c&&(d||e)){if(d)for(e=[],b=0;b<d.length;b++)e.unshift(this.getResolutionFromScale(d[b]));c=new ol.source.TileImage({crossOrigin:null,
projection:this.view.getProjection(),tileGrid:new ol.tilegrid.TileGrid({extent:c,origin:c?[c[0],c[1]]:[0,0],resolutions:e}),tileUrlFunction:function(b){if(null!==b){var c=a;c=netgis.util.replace(c,"{z}",b[0]);c=netgis.util.replace(c,"{x}",b[1]);c=netgis.util.replace(c,"{y}",b[2]);return c=netgis.util.replace(c,"{-y}",-b[2]-1)}}});c=new ol.layer.Tile({source:c})}else c=new ol.layer.Tile({source:new ol.source.XYZ({url:a,crossOrigin:"anonymous"})});return c};
netgis.Map.prototype.createLayerWMS=function(a,b,c,d,e,f){"image/tiff"===c&&(console.error("WMS layer format 'image/tiff' detected but not supported in OL, reverting to 'image/png' for '"+a+"'"),c="image/png");a={url:a,params:{LAYERS:b,FORMAT:c?c:"image/png",TRANSPARENT:"true"},hidpi:!1};e&&f&&(a.imageLoadFunction=function(a,b){var c=new XMLHttpRequest;c.open("GET",b);c.setRequestHeader("Authorization","Basic "+window.btoa(e+":"+f));c.onload=function(){a.getImage().src=b};c.send()});d?(d=new ol.source.TileWMS(a),
d=new ol.layer.Tile({source:d})):(d=new ol.source.ImageWMS(a),d=new ol.layer.Image({source:d}));return d};
netgis.Map.prototype.createLayerWMST=function(a,b,c,d,e,f){"image/tiff"===c&&(console.error("WMST layer format 'image/tiff' detected but not supported in OL, reverting to 'image/png' for '"+a+"'"),c="image/png");a={url:a,params:{LAYERS:b,FORMAT:c?c:"image/png",TRANSPARENT:"true",VERSION:"1.1.1"},hidpi:!1};e&&f&&(a.imageLoadFunction=function(a,b){var c=new XMLHttpRequest;c.open("GET",b);c.setRequestHeader("Authorization","Basic "+window.btoa(e+":"+f));c.onload=function(){a.getImage().src=b};c.send()});
d?(d=new ol.source.TileWMS(a),d=new ol.layer.Tile({source:d})):(d=new ol.source.ImageWMS(a),d=new ol.layer.Image({source:d}));return d};
netgis.Map.prototype.createLayerWMTS=function(a){for(var b=[],c=this.client.config.map.scales,d=this.client.config.map.extent,e=0;e<c.length;e++)b.unshift(this.getResolutionFromScale(c[e]));b=new ol.source.TileImage({crossOrigin:null,projection:this.view.getProjection(),tileGrid:new ol.tilegrid.TileGrid({extent:d,origin:[d[0],d[1]],resolutions:b}),tileUrlFunction:function(b){if(null!==b){var c=a;c=netgis.util.replace(c,"{z}",b[0]);c=netgis.util.replace(c,"{x}",b[1]);c=netgis.util.replace(c,"{y}",
b[2]);return c=netgis.util.replace(c,"{-y}",-b[2])}}});return new ol.layer.Tile({source:b})};
netgis.Map.prototype.createLayerWMTS_01=function(a,b){for(var c=this.view.getProjection().getExtent(),d=ol.extent.getWidth(c)/256,e=Array(14),f=Array(14),g=0;14>g;++g)e[g]=d/Math.pow(2,g),f[g]=g;source=new ol.source.WMTS({url:a,params:{LAYER:b,FORMAT:"image/png",TRANSPARENT:"true",VERSION:"1.1.1"},layer:b,format:"image/jpeg",matrixSet:"UTM32",tileGrid:new ol.tilegrid.WMTS({origin:ol.extent.getTopLeft(c),resolutions:e,matrixIds:f})})};
netgis.Map.prototype.createLayerGeoJSON=function(a){if(netgis.util.isObject(a)){var b=new ol.format.GeoJSON,c=b.readProjection(a);a=b.readFeatures(a,{featureProjection:this.view.getProjection()});c=c.getCode();switch(c){case "EPSG:3857":case "EPSG:4326":case this.view.getProjection().getCode():break;default:console.warn("unsupported import projection '"+c+"'")}var d=new ol.layer.Vector({source:new ol.source.Vector({features:a})});return d}if(netgis.util.isString(a)){d=new ol.layer.Vector({source:new ol.source.Vector({features:[]})});
var e=this;netgis.util.request(a,function(a){a=JSON.parse(a);a=e.createLayerGeoJSON(a);d.getSource().addFeatures(a.getSource().getFeatures())});return d}};
netgis.Map.prototype.createLayerGML=function(a){console.warn("GML support is experimental!");var b=[];a=(new DOMParser).parseFromString(a,"text/xml").getElementsByTagName("gml:featureMember");for(var c=0;c<a.length;c++){for(var d={},e=a[c].children[0],f=0;f<e.attributes.length;f++){var g=e.attributes[f];d[g.nodeName]=g.nodeValue}for(f=0;f<e.children.length;f++)if(g=e.children[f],"ogr:geometryProperty"!==g.nodeName){var h=g.nodeName.split(":");d[h[h.length-1]]=g.innerHTML}e=e.getElementsByTagName("ogr:geometryProperty")[0].children[0];
(f=e.getAttribute("srsName"))&&"EPSG:4326"!==f&&f!==this.projection&&console.warn("unsupported import projection:",f);switch(e.nodeName){case "gml:Polygon":d.geometry=this.gmlParsePolygon(e,f);break;case "gml:MultiPolygon":d.geometry=this.gmlParseMultiPolygon(e,f)}d=new ol.Feature(d);b.push(d)}return new ol.layer.Vector({source:new ol.source.Vector({features:b})})};
netgis.Map.prototype.gmlParsePolygon=function(a,b){var c=[];a=a.getElementsByTagName("gml:LinearRing");for(var d=0;d<a.length;d++){var e=a[d].getElementsByTagName("gml:coordinates")[0].innerHTML;c.push(this.gmlParseCoordinates(e,b))}return new ol.geom.Polygon(c)};netgis.Map.prototype.gmlParseMultiPolygon=function(a,b){var c=[];a=a.getElementsByTagName("gml:polygonMember");for(var d=0;d<a.length;d++){var e=a[d].getElementsByTagName("gml:Polygon")[0];c.push(this.gmlParsePolygon(e,b))}return new ol.geom.MultiPolygon(c)};
netgis.Map.prototype.gmlParseCoordinates=function(a,b){a=a.split(" ");for(var c=0;c<a.length;c++){a[c]=a[c].split(",");for(var d=0;d<a[c].length;d++)a[c][d]=Number.parseFloat(a[c][d]);b&&(a[c]=ol.proj.transform(a[c],b,this.view.getProjection()))}return a};
netgis.Map.prototype.createLayerGeoPackage=function(a){var b=new ol.layer.Vector({source:new ol.source.Vector({features:[]})}),c=this;a=new Uint8Array(a);window.GeoPackage.setSqljsWasmLocateFile(function(a){return c.config["import"].geopackage_lib+a});window.GeoPackage.GeoPackageAPI.open(a).then(function(a){for(var d=[],f=new ol.format.GeoJSON,g=a.getFeatureTables(),h=0;h<g.length;h++)for(var k=a.queryForGeoJSONFeaturesInTable(g[h]),l=0;l<k.length;l++){var m=f.readGeometry(k[l].geometry,{featureProjection:c.view.getProjection()});
m=new ol.Feature({geometry:m});d.push(m)}b.getSource().addFeatures(d)});return b};
netgis.Map.prototype.createLayerSpatialite=function(a){var b=new ol.layer.Vector({source:new ol.source.Vector({features:[]})}),c=this;window.initSqlJs().then(function(d){var e=[],f=new Uint8Array(a);d=new d.Database(f);var g=d.exec("SELECT name FROM sqlite_schema WHERE type = 'table' \n\t\t\t\t\tAND name NOT LIKE 'sqlite_%' \n\t\t\t\t\tAND name NOT LIKE 'sql_%' \n\t\t\t\t\tAND name NOT LIKE 'idx_%' \n\t\t\t\t\tAND name NOT LIKE 'spatial_ref_sys%' \n\t\t\t\t\tAND name NOT LIKE 'spatialite_%' \n\t\t\t\t\tAND name NOT LIKE 'geometry_columns%' \n\t\t\t\t\tAND name NOT LIKE 'views_%' \n\t\t\t\t\tAND name NOT LIKE 'virts_%' \n\t\t\t\t\tAND name NOT LIKE 'SpatialIndex' \n\t\t\t\t\tAND name NOT LIKE 'KNN%' \n\t\t\t\t\tAND name NOT LIKE 'ElementaryGeometries' \n\t\t\t\t;");f=
g[0].values;for(var h=0;h<f.length;h++){g=d.exec("SELECT * FROM "+f[h][0]);var k=g[0];g=null;for(var l=0;l<k.columns.length;l++){if("geometry"===k.columns[l].toLowerCase()){g=l;break}if("geom"===k.columns[l].toLowerCase()){g=l;break}}if(null!==g)for(k=k.values,l=0;l<k.length;l++){var m=k[l][g],n=new Uint8Array(m.length-43-1+5);n[0]=m[1];n[1]=m[39];n[2]=m[40];n[3]=m[41];n[4]=m[42];for(var p=m.length-43-1,q=0;q<p;q++)n[5+q]=m[43+q];m=(new ol.format.WKB).readGeometry(n,{featureProjection:c.view.getProjection()});
e.push(new ol.Feature({geometry:m}))}}b.getSource().addFeatures(e)});return b};netgis.Map.prototype.createLayerShapefile=function(a){var b=new ol.layer.Vector({source:new ol.source.Vector({features:[]})}),c=this;shp(a).then(function(a){var d=new ol.format.GeoJSON;d.readProjection(a);a=d.readFeatures(a,{featureProjection:c.view.getProjection()});b.getSource().addFeatures(a)});return b};
netgis.Map.prototype.createLayerWKT=function(a){for(var b=new ol.format.WKT,c=[],d=0;d<a.length;d++){var e=a[d],f=b.readGeometry(e.geometry),g=e.properties;g.geometry=f;g.wkt=e.geometry;f=new ol.Feature(g);f.setId(e.id);c.push(f)}return new ol.layer.Vector({source:new ol.source.Vector({features:c})})};
netgis.Map.prototype.createLayerWFS=function(a,b,c,d,e,f){"?"!==a[a.length-1]&&(a+="?");a+="service=WFS&version=1.1.0&request=GetFeature";c||(c=this.view.getProjection().getCode());d=d?netgis.util.replace(d," ","+"):"application/json";var g=new ol.source.Vector({format:new ol.format.GeoJSON,strategy:ol.loadingstrategy.bbox,loader:function(h,k,n,p,q){h=a+"&typename="+b+"&srsname="+c+"&bbox="+h.join(",")+","+c+"&outputFormat="+d;var l=new XMLHttpRequest;l.open("GET",h);e&&f&&l.setRequestHeader("Authorization",
"Basic "+window.btoa(e+":"+f));l.onerror=function(){console.error("WFS request error");q()};l.onload=function(){if(200===l.status){g.clear();var a=g.getFormat().readFeatures(l.responseText);g.addFeatures(a);p(a)}else console.error("WFS request status",l.status),q()};l.send()}}),h=new ol.layer.Vector({source:g}),k=this;g.on("featuresloadstart",function(a){k.removeSnapLayer(h)});g.on("featuresloadend",function(a){window.setTimeout(function(){k.addSnapLayer(h)},10)});return h};
netgis.Map.prototype.createLayerVectorTiles=function(a,b,c,d){return new ol.layer.VectorTile({extent:b,source:new ol.source.VectorTile({format:new ol.format.MVT,overlaps:!0,url:a,minZoom:c,maxZoom:d})})};
netgis.Map.prototype.createLayerKML=function(a){var b=new ol.layer.Vector({source:new ol.source.Vector({features:[]})}),c=this;netgis.util.request(a,function(a){a=(new ol.format.KML).readFeatures(a,{featureProjection:c.view.getProjection()});for(var d=0;d<a.length;d++){var f=a[d],g=f.getProperties(),h={fill:"rgba( 127, 127, 127, 0.5 )",stroke:"rgba( 127, 127, 127, 1.0 )",radius:5,width:3},k;for(k in g){var l=g[k];switch(k){case "fill":h.fill=l;break;case "fill-opacity":h["fill-opacity"]=l;break;case "stroke":h.stroke=
l;break;case "stroke-opacity":h["stroke-opacity"]=l;break;case "stroke-width":h.width=l}}h["fill-opacity"]&&(g=netgis.util.hexToRGB(h.fill),g="rgba("+g.join(",")+","+h["fill-opacity"]+")",h.fill=g);h["stroke-opacity"]&&(g=netgis.util.hexToRGB(h.stroke),g="rgba("+g.join(",")+","+h["stroke-opacity"]+")",h.stroke=g);h=new ol.style.Style({image:new ol.style.Circle({radius:h.radius,fill:new ol.style.Fill({color:h.stroke})}),fill:new ol.style.Fill({color:h.fill}),stroke:new ol.style.Stroke({color:h.stroke,
width:h.width})});f.setStyle(h)}b.getSource().addFeatures(a)});return b};netgis.Map.prototype.createBufferFeature=function(a,b,c){a=this.createBufferGeometry(a,b,c);return new ol.Feature({geometry:a})};netgis.Map.prototype.createBufferGeometry=function(a,b,c){var d=new jsts.io.OL3Parser;a=d.read(a).buffer(b,c);if(this.boundsLayer)for(b=this.boundsLayer.getSource().getFeatures(),c=0;c<b.length;c++){var e=d.read(b[c].getGeometry());a.intersects(e)&&(a=a.intersection(e))}return d.write(a)};
netgis.Map.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.Map.prototype.clearSketchFeatures=function(){for(var a=this.editLayer.getSource(),b=0;b<this.sketchFeatures.length;b++)a.removeFeature(this.sketchFeatures[b]);this.sketchFeatures=[]};
netgis.Map.prototype.updateDrawBufferPreview=function(){if(!1!==this.config.tools.editable){var a=this.interactions[this.mode][0].getOverlay().getSource().getFeatures();if(!(1>a.length)){var b=this.previewLayer.getSource().getFeatures()[0];b&&(a=a[0].getGeometry(),a=this.createBufferGeometry(a,this.drawBufferRadius,this.drawBufferSegments),b.setGeometry(a))}}};
netgis.Map.prototype.isPointInsideLayer=function(a,b){a=a.getSource().getFeatures();for(var c=0;c<a.length;c++)if(a[c].getGeometry().intersectsCoordinate(b))return!0;return!1};
netgis.Map.prototype.isGeomInsideLayer=function(a,b){var c=b.getCoordinates();if(b instanceof ol.geom.LineString){if(2>c.length)return!1}else if(b instanceof ol.geom.Polygon&&(c=c[0],4>c.length||0>=b.getArea()))return!1;c=new jsts.io.OL3Parser;b=c.read(b);a=a.getSource().getFeatures();for(var d=0;d<a.length;d++){var e=a[d].getGeometry();if(c.read(e).contains(b))return!0}return!1};netgis.Map.prototype.getScaleFromResolution=function(a){return Math.round(2834.6472*a)};
netgis.Map.prototype.getResolutionFromScale=function(a){var b=39.3701*ol.proj.Units.METERS_PER_UNIT[this.view.getProjection().getUnits()];return 1/(this.normalizeScale(a)*b*72)};netgis.Map.prototype.normalizeScale=function(a){return 1<a?1/a:a};
netgis.Map.prototype.updateEditOutput=function(){var a=this.editLayer.getSource().getFeatures(),b=this.view.getProjection().getCode(),c=(new ol.format.GeoJSON).writeFeaturesObject(a,{dataProjection:b,featureProjection:b});c.crs={type:"name",properties:{name:"urn:ogc:def:crs:"+b.replace(":","::")}};for(var d=b=0;d<a.length;d++){var e=a[d].getGeometry();e instanceof ol.geom.Polygon&&(b+=e.getArea())}c.area=b;netgis.util.invoke(this.container,netgis.Events.MAP_EDIT_LAYER_CHANGE,{geojson:c})};
netgis.Map.prototype.updateSnapFeatures=function(){this.snapFeatures.clear();var a=this;this.map.getLayers().forEach(function(b,c,d){c=b.get("id");c!==netgis.Client.Layers.PARCEL_DISTRICTS&&c!==netgis.Client.Layers.PARCEL_FIELDS&&c!==netgis.Client.Layers.PARCEL_FEATURES&&b instanceof ol.layer.Vector&&a.addSnapLayer(b)})};netgis.Map.prototype.zoom=function(a){this.view.animate({zoom:this.view.getZoom()+a,duration:200})};
netgis.Map.prototype.zoomLevel=function(a){this.view.animate({zoom:a,center:this.view.getCenter(),duration:300})};netgis.Map.prototype.zoomCoords=function(a,b,c){this.view.animate({zoom:c,center:[a,b],duration:500})};netgis.Map.prototype.zoomLonLat=function(a,b,c){this.view.animate({zoom:c,center:ol.proj.fromLonLat([a,b],this.view.getProjection()),duration:500})};
netgis.Map.prototype.zoomExtentLonLat=function(a,b,c,d){a=ol.proj.fromLonLat([a,b],this.view.getProjection());c=ol.proj.fromLonLat([c,d],this.view.getProjection());this.view.fit([a[0],a[1],c[0],c[1]])};netgis.Map.prototype.zoomExtent=function(a,b,c,d){this.view.fit([a,b,c,d])};netgis.Map.prototype.zoomBBox=function(a,b){this.view.fit(a,{duration:b})};netgis.Map.prototype.zoomScale=function(a,b){b?this.view.animate({resolution:this.getResolutionFromScale(a),duration:500}):this.view.setResolution(this.getResolutionFromScale(a))};
netgis.Map.prototype.zoomFeature=function(a,b){a=this.layers[a].getSource().getFeatureById(b);this.view.fit(a.getGeometry().getExtent(),{duration:500})};netgis.Map.prototype.zoomFeatures=function(a){if(a&&!(1>a.length)){for(var b=a[0].getGeometry().getExtent(),c=1;c<a.length;c++)b=ol.extent.extend(b,a[c].getGeometry().getExtent());this.view.fit(b,{duration:0,padding:this.view.padding})}};
netgis.Map.prototype.addViewHistory=function(a,b){if(0<this.viewHistory.length){var c=this.viewHistory[this.viewHistory.length-1],d=!0;10<Math.abs(a[0]-c.center[0])&&(d=!1);10<Math.abs(a[1]-c.center[1])&&(d=!1);.1<Math.abs(b-c.zoom)&&(d=!1);if(!0===d)return}this.viewHistory.push({center:a,zoom:b});this.viewHistory.length>this.viewHistoryMax&&this.viewHistory.shift();this.viewIndex=this.viewHistory.length-1};
netgis.Map.prototype.gotoViewHistory=function(a){if(!(1>this.viewHistory.length)){var b=this.viewHistory.length-1;0>a&&(a=b);a>b&&(a=0);a!==this.viewIndex&&(b=this.viewHistory[a],this.viewIndex=a,this.viewFromHistory=!0,this.view.setCenter(b.center),this.view.setZoom(b.zoom))}};netgis.Map.prototype.setPadding=function(a,b,c,d){var e=this.paddingBuffer;this.view.padding=[a+e,b+e,c+e,d+e]};
netgis.Map.prototype.exportImage=function(a,b,c,d,e){var f=this,g=this.container,h=this.map,k=this.config["export"],l=new Image;l.onload=function(){var m=document.createElement("div");m.style.position="fixed";m.style.top="0px";m.style.left="0px";m.style.width=b+"px";m.style.height=c+"px";m.style.background="white";m.style.zIndex=-1;m.style.opacity=0;m.style.pointerEvents="none";g.appendChild(m);h.setTarget(m);h.once("rendercomplete",function(){var n=document.createElement("canvas");n.width=b;n.height=
c;var p=n.getContext("2d");p.webkitImageSmoothingEnabled=!1;p.mozImageSmoothingEnabled=!1;p.imageSmoothingEnabled=!1;Array.prototype.forEach.call(document.querySelectorAll(".ol-layer canvas"),function(a){if(0<a.width){var b=a.parentNode.style.opacity;p.globalAlpha=""===b?1:Number(b);b=a.style.transform.match(/^matrix\(([^\(]*)\)$/)[1].split(",").map(Number);CanvasRenderingContext2D.prototype.setTransform.apply(p,b);p.drawImage(a,0,0)}});p.drawImage(l,0,0);p.fillStyle="#fff";p.fillRect(0,n.height-
30,140,30);p.fillStyle="#000";p.font="4mm sans-serif";p.fillText(netgis.util.getTimeStamp(),10,n.height-10);var q=document.createElement("a");switch(a){case "pdf":e=e?e:0;var r=297-e-e,t=210-e-e,u=n.width/n.height;if(!d){var v=r;r=t;t=v}if(n.height>n.width){var w=t;v=w*u;v>r&&(v=r,w=v/u)}else v=r,w=v/u,w>t&&(w=t,v=w*u);u=new jsPDF(d?"l":"p");var x=e;x+=(r-v)/2;r=e;r+=(t-w)/2;u.addImage(n.toDataURL("image/png,1.0",1),"PNG",x,r,v,w);u.setFillColor(255,255,255);u.rect(x,r+w-11,80,11,"F");u.setFontSize(8);
u.text("Datum: "+netgis.util.getTimeStamp(),x+2,r+w-2-4);u.text("Quelle: "+window.location.href,x+2,r+w-2);n=u.output("bloburl",{filename:k.default_filename+".pdf"});window.open(n,"_blank");break;case "jpeg":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),k.default_filename+".jpg"):(q.setAttribute("download",k.default_filename+".jpg"),q.setAttribute("href",n.toDataURL("image/jpeg",1)),q.click());break;case "png":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),
k.default_filename+".png"):(q.setAttribute("download",k.default_filename+".png"),q.setAttribute("href",n.toDataURL("image/png",1)),q.click());break;case "gif":q.setAttribute("download",k.default_filename+".gif"),t=new GIF({workerScript:k.gif_worker,quality:1}),t.addFrame(n),t.on("finished",function(a){q.setAttribute("href",window.URL.createObjectURL(a));q.click()}),t.render()}h.setTarget(g);g.removeChild(m);netgis.util.invoke(f.container,netgis.Events.EXPORT_END,null)});h.renderSync()};l.src=k.logo};
netgis.Map.prototype.exportFeatures=function(a){var b=this.editLayer.getSource().getFeatures();!0===a&&(a=this.nonEditLayer.getSource().getFeatures(),b=b.concat(a));b=(new ol.format.GeoJSON).writeFeaturesObject(b,{featureProjection:this.view.getProjection(),dataProjection:"EPSG:4326"});a=this.config["export"].default_filename+".geojson";b.name=a;netgis.util.downloadJSON(b,a);netgis.util.invoke(this.container,netgis.Events.EXPORT_END,null)};netgis.Map.prototype.onClientContextResponse=function(a){this.initConfig(a.detail.context.config)};
netgis.Map.prototype.onEditLayerLoaded=function(a){a=a.detail.geojson;var b=new ol.format.GeoJSON;b.readProjection(a);a=b.readFeatures(a,{featureProjection:this.view.getProjection().getCode()});var c=this,d=a.slice();window.setTimeout(function(){c.zoomFeatures(d)},10);b=[];for(var e=0;e<a.length;e++){var f=a[e];!0===f.getProperties().editable&&b.push(f)}for(e=0;e<b.length;e++)a.splice(a.indexOf(b[e]),1);this.editEventsSilent=!0;this.editLayer.getSource().addFeatures(b);this.nonEditLayer.getSource().addFeatures(a);
this.editEventsSilent=!1};netgis.Map.prototype.onClientSetMode=function(a){this.setMode(a.detail.mode)};netgis.Map.prototype.onPanelResize=function(a){this.setPadding(0,0,0,a.detail.width);this.redrawVectorLayers()};
netgis.Map.prototype.onPanelToggle=function(a){a=!1;for(var b=0,c=this.container.parentNode.getElementsByClassName("netgis-panel"),d=0;d<c.length;d++)if(c[d].classList.contains("netgis-show")){a=!0;b=c[d].getBoundingClientRect().width;break}a?this.setPadding(0,0,0,b):this.setPadding(0,0,0,0);this.redrawVectorLayers()};netgis.Map.prototype.onMapZoom=function(a){this.zoom(a.detail.delta)};
netgis.Map.prototype.onMapZoomHome=function(a){a=this.config;if(a.map.bbox)this.zoomBBox(a.map.bbox,500);else if(a.map.center){var b=a.map.center;this.zoomCoords(b[0],b[1],a.map.zoom)}else a.map.center_lonlat&&(b=a.map.center_lonlat,this.zoomLonLat(b[0],b[1],a.map.zoom))};netgis.Map.prototype.onMapZoomLonLat=function(a){a=a.detail;this.zoomLonLat(a.lon,a.lat,a.zoom)};netgis.Map.prototype.onMapZoomScale=function(a){a=a.detail;this.zoomScale(a.scale,a.anim)};
netgis.Map.prototype.onMapZoomLayer=function(a){a=a.detail;var b=this.layers[a.id];b?this.view.fit(b.getSource().getExtent(),{duration:600}):console.warning("trying to zoom non existing layer",a.id)};netgis.Map.prototype.onMapZoomLevel=function(a){this.view.setZoom(a.detail.z)};netgis.Map.prototype.onMapViewPrev=function(a){this.gotoViewHistory(this.viewIndex-1)};netgis.Map.prototype.onMapViewNext=function(a){this.gotoViewHistory(this.viewIndex+1)};
netgis.Map.prototype.onMapLayerToggle=function(a){a=a.detail;switch(a.id){case netgis.LayerID.EDITABLE:a.on?this.map.addLayer(this.editLayer):this.map.removeLayer(this.editLayer);break;case netgis.LayerID.NON_EDITABLE:a.on?this.map.addLayer(this.nonEditLayer):this.map.removeLayer(this.nonEditLayer);break;default:if(a.on)for(var b=this.config.layers,c=0;c<b.length;c++){var d=b[c];d.id===a.id&&this.addLayer(a.id,d)}else this.removeLayer(a.id)}};
netgis.Map.prototype.onMapLayerTransparency=function(a){a=a.detail;var b=this.layers[a.id];b||(netgis.util.invoke(this.container,netgis.Events.MAP_LAYER_TOGGLE,{id:a.id,on:!0}),b=this.layers[a.id]);b.setOpacity(1-a.transparency)};netgis.Map.prototype.onMapLayerOrder=function(a){a=a.detail;var b=this.layers[a.id];b&&b.setZIndex(a.order)};netgis.Map.prototype.onMapLayerCreate=function(a){a=a.detail;this.addLayer(a.id,a)};netgis.Map.prototype.onMapLayerDelete=function(a){this.removeLayer(a.detail.id)};
netgis.Map.prototype.onMapSnapToggle=function(a){this.setSnapping(a.detail.on)};netgis.Map.prototype.onMapMoveEnd=function(a){a=this.view.getCenter();var b=this.view.getZoom(),c=this.getScaleFromResolution(this.view.getResolution());!1===this.viewFromHistory&&this.addViewHistory(a,b);netgis.util.invoke(this.container,netgis.Events.MAP_VIEW_CHANGE,{center:a,zoom:b,scale:c});this.viewFromHistory=!1};
netgis.Map.prototype.onPointerMove=function(a){var b=a.pixel;a=a.coordinate;var c=null,d=null,e=void 0,f=this;this.map.forEachFeatureAtPixel(b,function(a,b){if(b&&b!==f.measureLayer&&b!==f.nonEditLayer)if(b===f.boundsLayer)e=a;else if(b!==f.previewLayer)return c=a,d=b,!0});switch(this.mode){case netgis.Modes.VIEW:0===this.getQueryableLayers(!0).length?c?this.container.classList.add("netgis-clickable"):this.container.classList.remove("netgis-clickable"):this.container.classList.add("netgis-clickable");
break;case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:this.updateDrawBufferPreview()}if(this.boundsLayer&&(this.mode===netgis.Modes.DRAW_POINTS||this.mode===netgis.Modes.DRAW_LINES||this.mode===netgis.Modes.DRAW_POLYGONS)){if(e)this.container.classList.remove("netgis-not-allowed"),this.container.removeAttribute("title");else{this.container.classList.add("netgis-not-allowed");var g=this.config.tools.bounds_message;g&&0<g.length&&this.container.setAttribute("title",g)}this.hoverBounds=e}g=
!0;this.mode===netgis.Modes.MEASURE_LINE&&(g=!1);this.mode===netgis.Modes.MEASURE_AREA&&(g=!1);this.mode===netgis.Modes.DRAW_POINTS&&(g=!1);this.mode===netgis.Modes.DRAW_LINES&&(g=!1);this.mode===netgis.Modes.DRAW_POLYGONS&&(g=!1);this.mode===netgis.Modes.CUT_FEATURES_DRAW&&(g=!1);if(c!==this.hoverFeature&&g){if(this.hoverFeature)this.onFeatureLeave(this.hoverFeature,this.hoverLayer,b,a);if(c)this.onFeatureEnter(c,d,b,a);this.redrawVectorLayers();this.hoverFeature=c;this.hoverLayer=d}if(c)this.onFeatureHover(c,
d,b,a)};netgis.Map.prototype.onPointerLeave=function(a){this.hoverFeature&&(this.onFeatureLeave(this.hoverFeature,this.hoverLayer,[a.offsetX,a.offsetY],null),this.hoverLayer=this.hoverFeature=null)};
netgis.Map.prototype.onPointerClick=function(a){var b=a.pixel;a=a.coordinate;this.popupOverlay.setPosition(a);var c={resolution:this.view.getResolution(),projection:this.view.getProjection().getCode(),bbox:this.view.calculateExtent(this.map.getSize()),width:this.map.getSize()[0],height:this.map.getSize()[1]},d=ol.proj.toLonLat(a,this.view.getProjection()),e={};for(g in this.layers){var f=this.layers[g].getSource();f.getFeatureInfoUrl&&(e[g]=f.getFeatureInfoUrl(a,c.resolution,c.projection,{INFO_FORMAT:"text/html"}))}var g=
{mode:this.mode,pixel:b,coords:a,lon:d[0],lat:d[1],overlay:this.popupOverlay.getElement(),view:c,info:e};this.mode===netgis.Modes.VIEW&&netgis.util.invoke(this.container,netgis.Events.MAP_CLICK,g);var h=[],k=this;this.map.forEachFeatureAtPixel(b,function(a,b){b&&b!==k.nonEditLayer&&b!==k.boundsLayer&&b!==k.measureLayer&&b!==k.previewLayer&&(-1<k.sketchFeatures.indexOf(a)||h.push({feature:a,layer:b}))});g=!0;this.mode===netgis.Modes.VIEW&&(g=!1);this.mode===netgis.Modes.MEASURE_LINE&&(g=!1);this.mode===
netgis.Modes.MEASURE_AREA&&(g=!1);this.mode===netgis.Modes.DRAW_POINTS&&(g=!1);this.mode===netgis.Modes.DRAW_LINES&&(g=!1);this.mode===netgis.Modes.DRAW_POLYGONS&&(g=!1);this.mode===netgis.Modes.CUT_FEATURES_DRAW&&(g=!1);g&&(0<h.length&&!1===this.selectMultiple&&(this.selectedFeatures=[]),0===h.length&&!1===this.selectMultiple&&(this.selectedFeatures=[]),!0===this.selectReset&&(this.selectedFeatures=[],this.selectReset=!1),this.mode===netgis.Modes.BUFFER_FEATURES_DYNAMIC&&this.updateBufferFeaturesSketch(this.bufferFeaturesRadius,
this.bufferFeaturesSegments));for(c=0;c<h.length;c++)d=h[c],g&&(e=this.selectedFeatures.indexOf(d.feature),-1<e?this.selectedFeatures.splice(e,1):this.selectedFeatures.push(d.feature)),this.onFeatureClick(d.feature,d.layer,b,a);this.redrawVectorLayers()};netgis.Map.prototype.onContainerClick=function(a){if(2===a.detail)this.onDoubleClick(a)};
netgis.Map.prototype.onDoubleClick=function(a){switch(this.mode){case netgis.Modes.MEASURE_LINE:this.interactions[netgis.Modes.MEASURE_LINE]&&this.interactions[netgis.Modes.MEASURE_LINE][2].finishDrawing();break;case netgis.Modes.MEASURE_AREA:this.interactions[netgis.Modes.MEASURE_AREA]&&this.interactions[netgis.Modes.MEASURE_AREA][2].finishDrawing();break;case netgis.Modes.DRAW_LINES:this.interactions[netgis.Modes.DRAW_LINES]&&this.interactions[netgis.Modes.DRAW_LINES][0].finishDrawing();break;case netgis.Modes.DRAW_POLYGONS:this.interactions[netgis.Modes.DRAW_POLYGONS]&&
this.interactions[netgis.Modes.DRAW_POLYGONS][0].finishDrawing();break;case netgis.Modes.CUT_FEATURES_DRAW:this.interactions[netgis.Modes.CUT_FEATURES_DRAW]&&this.interactions[netgis.Modes.CUT_FEATURES_DRAW][0].finishDrawing()}};
netgis.Map.prototype.onRightClick=function(a){switch(this.mode){case netgis.Modes.MEASURE_LINE:this.interactions[netgis.Modes.MEASURE_LINE]&&this.interactions[netgis.Modes.MEASURE_LINE][2].finishDrawing();break;case netgis.Modes.MEASURE_AREA:this.interactions[netgis.Modes.MEASURE_AREA]&&this.interactions[netgis.Modes.MEASURE_AREA][2].finishDrawing();break;case netgis.Modes.DRAW_LINES:this.interactions[netgis.Modes.DRAW_LINES]&&this.interactions[netgis.Modes.DRAW_LINES][0].finishDrawing();break;case netgis.Modes.DRAW_POLYGONS:this.interactions[netgis.Modes.DRAW_POLYGONS]&&
this.interactions[netgis.Modes.DRAW_POLYGONS][0].finishDrawing();break;case netgis.Modes.CUT_FEATURES_DRAW:this.interactions[netgis.Modes.CUT_FEATURES_DRAW]&&this.interactions[netgis.Modes.CUT_FEATURES_DRAW][0].finishDrawing()}a.preventDefault();return!1};
netgis.Map.prototype.onKeyDown=function(a){a=a.keyCode||a.which;switch(this.mode){case netgis.Modes.MEASURE_LINE:13===a&&this.interactions[netgis.Modes.MEASURE_LINE][2].finishDrawing();27===a&&this.interactions[netgis.Modes.MEASURE_LINE][2].abortDrawing();break;case netgis.Modes.MEASURE_AREA:13===a&&this.interactions[netgis.Modes.MEASURE_AREA][2].finishDrawing();27===a&&this.interactions[netgis.Modes.MEASURE_AREA][2].abortDrawing();break;case netgis.Modes.DRAW_LINES:var b=this.interactions[netgis.Modes.DRAW_LINES][0];
13===a&&b.finishDrawing();27===a&&b.abortDrawing();8===a&&b.removeLastPoint();46===a&&b.abortDrawing();break;case netgis.Modes.DRAW_POLYGONS:b=this.interactions[netgis.Modes.DRAW_POLYGONS][0];13===a&&b.finishDrawing();27===a&&b.abortDrawing();8===a&&b.removeLastPoint();46===a&&b.abortDrawing();break;case netgis.Modes.CUT_FEATURES_DRAW:b=this.interactions[netgis.Modes.CUT_FEATURES_DRAW][0],13===a&&b.finishDrawing(),27===a&&b.abortDrawing(),8===a&&b.removeLastPoint(),46===a&&b.abortDrawing(),16===a&&
netgis.util.invoke(this.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.CUT_FEATURES})}16===a&&!1===this.selectMultiple&&netgis.util.invoke(this.container,netgis.Events.SELECT_MULTI_TOGGLE,{on:!0})};
netgis.Map.prototype.onKeyUp=function(a){a=a.keyCode||a.which;switch(this.mode){case netgis.Modes.BUFFER_FEATURES:this.selectMultiple&&netgis.util.invoke(this.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.BUFFER_FEATURES_EDIT});break;case netgis.Modes.CUT_FEATURES:this.selectMultiple&&netgis.util.invoke(this.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.CUT_FEATURES_DRAW})}16===a&&(netgis.util.invoke(this.container,netgis.Events.SELECT_MULTI_TOGGLE,{on:!1}),this.selectReset=
!1,!0===this.config.tools.select_multi_reset&&(this.selectReset=!0))};
netgis.Map.prototype.onFeatureEnter=function(a,b,c,d){if(b){switch(this.mode){case netgis.Modes.VIEW:this.container.classList.add("netgis-clickable");break;case netgis.Modes.DELETE_FEATURES:case netgis.Modes.BUFFER_FEATURES:case netgis.Modes.BUFFER_FEATURES_DYNAMIC:case netgis.Modes.CUT_FEATURES:this.container.classList.add("netgis-clickable");a.setStyle(this.styleHover.bind(this));break;case netgis.Modes.SEARCH_PARCEL:this.container.classList.add("netgis-clickable"),a.setStyle(this.styleHover.bind(this))}netgis.util.invoke(this.container,
netgis.Events.MAP_FEATURE_ENTER,{pixel:c,coords:d,layer:b.get("id"),properties:a.getProperties()})}};netgis.Map.prototype.onFeatureHover=function(a,b,c,d){};
netgis.Map.prototype.onFeatureClick=function(a,b,c,d){var e=ol.proj.toLonLat(d,this.view.getProjection());c={pixel:c,coords:d,lon:e[0],lat:e[1],overlay:this.popupOverlay.getElement(),layer:b.get("id"),id:a.getId(),properties:a.getProperties(),mode:this.mode};netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_CLICK,c);switch(this.mode){case netgis.Modes.DELETE_FEATURES:b.getSource().removeFeature(a);this.onFeatureLeave(a,b);netgis.util.invoke(this.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.VIEW});
break;case netgis.Modes.BUFFER_FEATURES:case netgis.Modes.BUFFER_FEATURES_EDIT:this.onFeatureLeave(a,b);this.selectMultiple?netgis.util.invoke(this.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.BUFFER_FEATURES}):netgis.util.invoke(this.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.BUFFER_FEATURES_EDIT});break;case netgis.Modes.BUFFER_FEATURES_DYNAMIC:this.updateBufferFeaturesSketch(this.bufferFeaturesRadius,this.bufferFeaturesSegments);break;case netgis.Modes.CUT_FEATURES:if(a.getGeometry()instanceof
ol.geom.Point)this.onFeatureLeave(a,b);else this.selectMultiple||netgis.util.invoke(this.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.CUT_FEATURES_DRAW})}};
netgis.Map.prototype.onFeatureLeave=function(a,b,c,d){netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_LEAVE,{pixel:c,coords:d,layer:b?b.get("id"):null,properties:a.getProperties()});switch(this.mode){case netgis.Modes.DELETE_FEATURES:case netgis.Modes.BUFFER_FEATURES:case netgis.Modes.BUFFER_FEATURES_DYNAMIC:case netgis.Modes.CUT_FEATURES:case netgis.Modes.CUT_FEATURES_DRAW:this.container.classList.remove("netgis-clickable");a.setStyle(null);break;case netgis.Modes.SEARCH_PARCEL:this.container.classList.remove("netgis-clickable"),
a.setStyle(null)}};netgis.Map.prototype.onEditLayerAdd=function(a){this.editEventsSilent||this.updateEditOutput();this.snapFeatures.push(a.feature)};netgis.Map.prototype.onEditLayerRemove=function(a){this.editEventsSilent||this.updateEditOutput();this.snapFeatures.remove(a.feature)};netgis.Map.prototype.onEditLayerChange=function(a){this.editEventsSilent||this.updateEditOutput()};
netgis.Map.prototype.onCopyFeatureToEdit=function(a){a=a.detail;var b=this.layers[a.source].getSource().getFeatureById(a.id);b?this.editLayer.getSource().getFeatureById(a.id)||(b.setStyle(void 0),this.selectedFeatures=[],this.editLayer.getSource().addFeature(b)):console.error("feature to copy not found",a)};netgis.Map.prototype.onGeolocToggleActive=function(a){a.detail.on?this.geolocLayer.setVisible(!0):this.geolocLayer.setVisible(!1)};
netgis.Map.prototype.onGeolocChange=function(a){a=a.detail;this.geolocLayer.getSource().getFeatures()[0].getGeometry().setCoordinates(ol.proj.fromLonLat([a.lon,a.lat],this.view.getProjection()));!0===a.center&&this.zoomLonLat(a.lon,a.lat,this.view.getZoom())};netgis.Map.prototype.onMeasureLineBegin=function(a){this.measureLayer.getSource().clear()};netgis.Map.prototype.onMeasureAreaBegin=function(a){this.measureLayer.getSource().clear()};netgis.Map.prototype.onMeasureClear=function(a){this.measureLayer.getSource().clear()};
netgis.Map.prototype.onDrawBufferEnd=function(a){var b=a.feature;a=this.previewLayer.getSource().getFeatures();if(0!==a.length){a=a[0];if(this.boundsLayer){var c=!0;c=b.getGeometry()instanceof ol.geom.Point?this.isPointInsideLayer(this.boundsLayer,b.getGeometry().getCoordinates()):this.isGeomInsideLayer(this.boundsLayer,b.getGeometry());if(!c)return;c=new jsts.io.OL3Parser;for(var d=c.read(a.getGeometry()),e=this.boundsLayer.getSource().getFeatures(),f=0;f<e.length;f++){var g=c.read(e[f].getGeometry());
d.intersects(g)&&(d=d.intersection(g))}c=c.write(d);a.setGeometry(c)}var h=this.editLayer.getSource();h.addFeature(a.clone());window.setTimeout(function(){h.removeFeature(b)},10)}};netgis.Map.prototype.onSelectMultiToggle=function(a){this.selectMultiple=a.detail.on};netgis.Map.prototype.onDrawBufferToggle=function(a){a=a.detail;this.setDrawBuffer(a.on,a.radius,a.segments)};
netgis.Map.prototype.onDrawBufferChange=function(a){a=a.detail;this.drawBufferRadius=a.radius;this.drawBufferSegments=a.segments;this.updateDrawBufferPreview()};netgis.Map.prototype.onBufferChange=function(a){a=a.detail;this.updateBufferFeaturesSketch(a.radius,a.segments);this.bufferFeaturesRadius=a.radius;this.bufferFeaturesSegments=a.segments};
netgis.Map.prototype.updateBufferFeaturesSketch=function(a,b){var c=this.selectedFeatures,d=this.editLayer.getSource();this.clearSketchFeatures();for(var e=0;e<c.length;e++){var f=this.createBufferFeature(this.selectedFeatures[e].getGeometry(),a,b);d.addFeature(f);this.sketchFeatures.push(f)}};netgis.Map.prototype.onBufferAccept=function(a){a=this.selectedFeatures;for(var b=this.editLayer.getSource(),c=0;c<a.length;c++)b.removeFeature(a[c]);this.sketchFeatures=[];this.selectedFeatures=[]};
netgis.Map.prototype.onCutFeaturesDrawEnd=function(a){a=a.feature;for(var b=0;b<this.selectedFeatures.length;b++){var c=this.selectedFeatures[b];if(c)if(this.onFeatureLeave(c,null),c.getGeometry()instanceof ol.geom.Point)console.error("trying to cut a point feature",c);else{var d=new jsts.io.OL3Parser,e=d.read(c.getGeometry()),f=d.read(a.getGeometry());e=e.difference(f);d=d.write(e);d=new ol.Feature({geometry:d});e=this.editLayer.getSource();e.removeFeature(c);e.addFeature(d)}}this.selectedFeatures=
[];this.editEventsSilent=!0;this.splitMultiPolygons(this.editLayer);this.editEventsSilent=!1;this.updateEditOutput();netgis.util.invoke(this.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.VIEW})};netgis.Map.prototype.onImportLayerAccept=function(a){a=a.detail;a=this.addLayer(a.id,a);var b=a.getSource();b instanceof ol.source.Vector&&0<b.getFeatures().length&&this.view.fit(a.getSource().getExtent(),{duration:600})};netgis.Map.prototype.onImportGeoportalSubmit=function(a){};
netgis.Map.prototype.onImportLayerPreview=function(a){a=a.detail;var b=this.createLayer(a),c=this.view.getProjection().getCode();netgis.util.invoke(this.container,netgis.Events.IMPORT_LAYER_PREVIEW_FEATURES,{id:a.id,title:a.title,layer:b,proj:c})};netgis.Map.prototype.onSearchParcelReset=function(a){(a=this.config.searchparcel.districts_service.min_zoom)&&this.view.setZoom(a)};netgis.Map.prototype.onSearchParcelItemEnter=function(a){a=a.detail.id;this.layers.searchparcel_parcels.getSource().getFeatureById(a).setStyle(this.styleHover.bind(this))};
netgis.Map.prototype.onSearchParcelItemLeave=function(a){a=a.detail.id;this.layers.searchparcel_parcels.getSource().getFeatureById(a).setStyle(null)};netgis.Map.prototype.onSearchParcelItemClick=function(a){this.zoomFeature("searchparcel_parcels",a.detail.id)};netgis.Map.prototype.onSearchParcelItemImport=function(a){};netgis.Map.prototype.onDrawPointsUpdateGeom=function(a,b,c){b?b.setCoordinates(a):b=new ol.geom.Point(a);return b};
netgis.Map.prototype.onDrawLinesUpdateGeom=function(a,b,c){b?b.setCoordinates(a):b=new ol.geom.LineString(a);this.drawError=!this.isGeomInsideLayer(this.boundsLayer,b);return b};
netgis.Map.prototype.onDrawPolygonsUpdateGeom=function(a,b,c){b?(a=[a[0].concat([a[0][0]])],b.setCoordinates(a)):b=new ol.geom.Polygon(a);c=!0;if(4>a[0].length)for(var d=0;d<a[0].length;d++){if(!this.isPointInsideLayer(this.boundsLayer,a[0][d])){c=!1;break}}else c=this.isGeomInsideLayer(this.boundsLayer,b);this.drawError=!c;return b};
netgis.Map.prototype.onDrawPointsEnd=function(a){if(this.boundsLayer){var b=a.feature,c=this.editLayer;this.isPointInsideLayer(this.boundsLayer,b.getGeometry().getCoordinates())||window.setTimeout(function(){c.getSource().removeFeature(b)},10)}};netgis.Map.prototype.onDrawLinesEnd=function(a){if(this.boundsLayer){var b=a.feature,c=this.editLayer;this.isGeomInsideLayer(this.boundsLayer,b.getGeometry())||window.setTimeout(function(){c.getSource().removeFeature(b)},10)}};
netgis.Map.prototype.onDrawPolygonsEnd=function(a){if(this.boundsLayer){var b=a.feature,c=this.editLayer;this.isGeomInsideLayer(this.boundsLayer,b.getGeometry())||window.setTimeout(function(){c.getSource().removeFeature(b)},10)}};netgis.Map.prototype.onExportBegin=function(a){a=a.detail;switch(a.format){case "geojson":this.exportFeatures(a.nonEdits);break;default:this.exportImage(a.format,a.width,a.height,a.landscape,a.padding)}};
netgis.Map.prototype.onScalebarSelectChange=function(a){netgis.util.invoke(this.scalebarSelect,netgis.Events.MAP_ZOOM_SCALE,{scale:this.scalebarSelect.value,anim:!0})};netgis.Map.prototype.onTimeSliderShow=function(a){};netgis.Map.prototype.onTimeSliderHide=function(a){};netgis.Map.prototype.onTimeSliderSelect=function(a){a=a.detail;console.info("Time Slider Select:",a);this.layers[a.layer].getSource().updateParams({TIME:a.time})};netgis=netgis||{};netgis.Menu=function(a){this.config=a;this.initElements();this.initConfig(a)};netgis.Menu.Config={header:"<a href='.' target='_self'>NetGIS Client</a>",items:[],compact:!0};
netgis.Menu.prototype.initElements=function(){this.container=document.createElement("nav");this.container.className="netgis-menu netgis-noselect netgis-color-a netgis-gradient-a netgis-shadow-large";this.toggle=document.createElement("button");this.toggle.setAttribute("type","button");this.toggle.addEventListener("click",this.onToggleClick.bind(this));this.toggle.className="netgis-menu-toggle netgis-hover-c";this.toggle.innerHTML="<i class='fas fa-bars'></i>";this.container.appendChild(this.toggle)};
netgis.Menu.prototype.initConfig=function(a){var b=a.menu;if(b&&(b.header&&this.addHeader(b.header),!0===b.compact&&this.container.classList.add("netgis-compact"),b.items)){b=b.items;for(var c=0;c<b.length;c++){var d=b[c];if(d.items){var e=d.items;if("scales"===d.id)for(var f=this.getScaleItems(),g=0;g<f.length;g++)e.push(f[g]);this.addDropdown(d.title,e)}else if(d.url&&0<d.url.length)this.addLink(d.url,d.title);else if(d.options)if("scales"===d.options){e={0:"1:X"};for(g=0;g<a.map.scales.length;g++)e[a.map.scales[g]]=
"1:"+a.map.scales[g];var h=a.map.default_scale;this.addSelect(d.id,d.title,e,h).options[0].classList.add("netgis-hide")}else{e=d.options;if(d.value)h=d.value;else for(var k in e){h=k;break}this.addSelect(d.id,d.title,e,h)}else this.addButton(d.id,d.title)}}};netgis.Menu.prototype.attachTo=function(a){a.appendChild(this.container);a.addEventListener(netgis.Events.MAP_VIEW_CHANGE,this.onMapViewChange.bind(this))};
netgis.Menu.prototype.addHeader=function(a){var b=document.createElement("h1");b.className="netgis-hover-c";b.innerHTML=a;this.container.appendChild(b);return b};netgis.Menu.prototype.addButton=function(a,b){a=this.createButton(a,b);this.container.appendChild(a);return a};netgis.Menu.prototype.addLink=function(a,b){a=this.createLink(a,b);this.container.appendChild(a);return a};
netgis.Menu.prototype.addSelect=function(a,b,c,d){var e=document.createElement("span");e.className="netgis-wrapper netgis-hover-c";var f=document.createElement("select");f.setAttribute("data-id",a);for(var g in c){a=c[g];var h=document.createElement("option");h.setAttribute("value",g);h.innerHTML=a;f.appendChild(h)}f.value=d;f.addEventListener("change",this.onSelectChange.bind(this));e.appendChild(f);b&&(c=document.createElement("span"),c.className="netgis-icon",c.innerHTML=b,e.appendChild(c));this.container.appendChild(e);
return f};netgis.Menu.prototype.addDropdown=function(a,b){var c=document.createElement("div");c.className="netgis-dropdown netgis-hover-c";var d=document.createElement("button");d.setAttribute("type","button");d.addEventListener("click",this.onDropdownClick.bind(this));d.innerHTML=a;c.appendChild(d);a=document.createElement("ul");a.className="netgis-color-e netgis-shadow";c.appendChild(a);for(d=0;d<b.length;d++)a.appendChild(this.createMenuItem(b[d]));this.container.appendChild(c);return c};
netgis.Menu.prototype.getScaleItems=function(){var a=[];if(!this.config||!this.config.map||!this.config.map.scales)return a;for(var b=this.config.map.scales,c=0;c<b.length;c++)a.push({id:netgis.Commands.ZOOM_SCALE,title:"1:"+b[c]});return a};
netgis.Menu.prototype.createMenuItem=function(a){var b=document.createElement("li");b.className="netgis-hover-c";var c=a.items;if("scales"===a.id)for(var d=this.getScaleItems(),e=0;e<d.length;e++)c.push(d[e]);if(c&&0<c.length)a=this.createMenu(a.title,c),b.appendChild(a.button),b.appendChild(a.list);else if(a.type)switch(a.type){case "checkbox":a=this.createCheckbox(a.id,a.title,a.value);b.appendChild(a);break;default:console.error("unhandled menu item type",a.type,"for",a.id)}else a.url?(a=this.createLink(a.url,
a.title),b.appendChild(a)):(a=this.createButton(a.id,a.title),b.appendChild(a));return b};netgis.Menu.prototype.createMenu=function(a,b){var c=document.createElement("button");c.setAttribute("type","button");c.addEventListener("pointerdown",this.onButtonClick.bind(this));c.innerHTML=a;a=document.createElement("ul");a.className="netgis-color-e netgis-shadow";for(var d=0;d<b.length;d++)a.appendChild(this.createMenuItem(b[d]));return{button:c,list:a}};
netgis.Menu.prototype.createLink=function(a,b){var c=document.createElement("a");c.setAttribute("href",a);c.setAttribute("target","_blank");c.className="netgis-button netgis-text-e netgis-hover-c";c.innerHTML=b;return c};netgis.Menu.prototype.createButton=function(a,b){var c=document.createElement("button");c.className="netgis-text-e netgis-hover-c";c.setAttribute("type","button");c.setAttribute("data-id",a);c.addEventListener("pointerdown",this.onButtonClick.bind(this));c.innerHTML=b;return c};
netgis.Menu.prototype.createCheckbox=function(a,b,c){var d=document.createElement("label");d.className="netgis-button";var e=document.createElement("input");e.setAttribute("type","checkbox");e.setAttribute("data-id",a);e.addEventListener("change",this.onCheckboxChange.bind(this));e.checked=c;d.appendChild(e);a=document.createElement("span");a.innerHTML=b;d.appendChild(a);return d};netgis.Menu.prototype.onToggleClick=function(a){this.container.classList.toggle("netgis-menu-large")};
netgis.Menu.prototype.onButtonClick=function(a){a=a.currentTarget;var b=a.getAttribute("data-id");this.container.classList.remove("netgis-menu-large");this.container.scrollTop=0;netgis.util.invoke(a,netgis.Events.MENU_BUTTON_CLICK,{id:b});netgis.Client.handleCommand(a,b)};
netgis.Menu.prototype.onCheckboxChange=function(a){a=a.currentTarget;var b=a.getAttribute("data-id"),c=a.checked;netgis.util.invoke(a,netgis.Events.MENU_CHECKBOX_CHANGE,{id:b,checked:c});switch(b){case netgis.Menu.ItemID.SNAP_TOGGLE:netgis.util.invoke(a,netgis.Events.MAP_SNAP_TOGGLE,{on:c});break;default:console.error("unhandled menu item id",b)}};
netgis.Menu.prototype.onSelectChange=function(a){a=a.currentTarget;var b=a.getAttribute("data-id"),c=a.value;netgis.util.invoke(a,netgis.Events.MENU_SELECT_CHANGE,{id:b,value:c});switch(b){case "scales":netgis.util.invoke(a,netgis.Events.MAP_ZOOM_SCALE,{scale:Number.parseInt(c)})}};
netgis.Menu.prototype.onMapViewChange=function(a){a=a.detail;for(var b=a.scale,c=this.container.getElementsByTagName("button"),d=0;d<c.length;d++){var e=c[d];"zoom_scale"===e.getAttribute("data-id")&&(Number.parseInt(e.innerText.split(":")[1])===b?e.classList.add("netgis-bold"):e.classList.remove("netgis-bold"))}c=this.container.getElementsByTagName("select");for(d=0;d<c.length;d++){e=c[d];if("scales"===!e.getAttribute("data-id"))break;for(var f=!1,g=this.config.map.scales,h=0;h<g.length;h++)if(g[h]===
b){f=!0;break}f?e.options[0].classList.add("netgis-hide"):(e.options[0].setAttribute("value",a.scale),e.options[0].innerHTML="1:"+a.scale,e.options[0].classList.remove("netgis-hide"));e.value=b}};netgis.Menu.prototype.onDropdownClick=function(a){a.currentTarget.parentNode.classList.toggle("netgis-active")};netgis=netgis||{};netgis.Modal=function(a){this.initElements(a);this.initEvents()};netgis.Modal.prototype.initElements=function(a){this.container=document.createElement("div");this.container.className="netgis-modal";this.container.addEventListener("click",this.onContainerClick.bind(this));this.content=document.createElement("div");this.content.className="netgis-color-e netgis-shadow";this.container.appendChild(this.content);this.header=this.addHeader(this.content,a,this.onHeaderClick.bind(this))};
netgis.Modal.prototype.initEvents=function(){};netgis.Modal.prototype.attachTo=function(a){a.appendChild(this.container)};netgis.Modal.prototype.show=function(){this.container.classList.add("netgis-show")};netgis.Modal.prototype.hide=function(){this.container.classList.remove("netgis-show")};
netgis.Modal.prototype.addHeader=function(a,b,c){var d=document.createElement("button");d.className="netgis-button netgis-clip-text netgis-color-c netgis-gradient-a";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.Modal.prototype.onHeaderClick=function(a){this.hide()};netgis.Modal.prototype.onContainerClick=function(a){a.target===this.container&&this.hide()};netgis=netgis||{};
netgis.Modes=Object.freeze({VIEW:"view",ZOOM_BOX:"zoom-box",MEASURE_LINE:"measure-line",MEASURE_AREA:"measure-area",DRAW_POINTS:"draw-points",DRAW_LINES:"draw-lines",DRAW_POLYGONS:"draw-polygons",MODIFY_FEATURES:"modify-features",DELETE_FEATURES:"delete-features",BUFFER_FEATURES:"buffer-features",BUFFER_FEATURES_EDIT:"buffer-features-edit",BUFFER_FEATURES_DYNAMIC:"buffer-features-dynamic",CUT_FEATURES:"cut-features",CUT_FEATURES_DRAW:"cut-features-draw",CUT_FEATURES_DYNAMIC:"cut-features-dynamic",SEARCH_PARCEL:"search-parcel"});netgis=netgis||{};netgis.Modules={menu:!0,layertree:!0,map:!0,controls:!0,attribution:!0,legend:!0,geolocation:!0,info:!0,searchplace:!0,searchparcel:!0,toolbox:!0,"import":!0,"export":!0,timeslider:!0};netgis=netgis||{};
netgis.OWS=function(){return{read:function(a,b){console.info("OWS READ:",a);console.info("OWS PROPS:",a.properties);a=a.features;for(b=0;b<a.length;b++){var c=a[b];console.info("OWS FEATURE:",b,c);var d=c;c=d.properties;switch(d.type){case "Feature":d=c.minScaleDenominator;var e=c.maxScaleDenominator;console.info("TITLE:",c.title,"FOLDER:",c.folder);console.info("MIN/MAX SCALE:",d,e);c=c.offerings;for(d=0;d<c.length;d++){e=c[d];console.info("OFFERING:",d,e);var f=e,g=f.code;e=f.content;switch(g){case "http://www.opengis.net/spec/owc-atom/1.0/req/kml":for(f=
0;f<e.length;f++)switch(g=e[f],g.type){case "application/vnd.google-earth.kml+xml":break;default:console.error("OWS: unknown offering content type '"+g.type+"'",g)}break;default:console.error("OWS: unknown offering code '"+g+"'",f)}}break;default:console.error("OWS: unknown feature type '"+d.type+"'",d)}}}}}();netgis=netgis||{};
netgis.OWS=function(){return{read:function(a,b){b={layers:[],folders:[]};netgis.util.isDefined(a.properties)&&(b.bbox=a.properties.bbox);a=a.features;for(var c=0;c<a.length;c++){var d=a[c];if("Feature"===d.type){var e=d.properties;e=e.folder;var f=!1;for(d=0;d<b.folders.length;d++)if(b.folders[d].id===e){f=!0;break}if(!f){d=e.split("/");e=[];for(f=0;f<d.length;f++){var g=d[f];0<g.length&&e.push(g)}var h=-1;for(f=0;f<e.length;f++){g=e[f];var k="/"+e.slice(0,f+1).join("/"),l=!1;for(d=0;d<b.folders.length;d++)if(b.folders[d].path===
k){h=d;l=!0;break}l||(d=b.folders.length,b.folders.push({title:g,parent:h,path:k}),h=d)}}}}for(c=0;c<a.length;c++)if(d=a[c],"Feature"===d.type){e=d.properties;f=-1;for(d=0;d<b.folders.length;d++)if(b.folders[d].path===e.folder){f=d;break}d=e.offerings;for(g=0;g<d.length;g++)switch(h=d[g],k=h.operations,h.code){case "http://www.opengis.net/spec/owc-geojson/1.0/req/wms":b.layers.push({folder:f,type:netgis.LayerTypes.WMS,url:k[0].href,title:e.title,attribution:e.rights,active:e.active});break;case "http://www.opengis.net/spec/owc-geojson/1.0/req/xyz":h=
k[0];b.layers.push({folder:f,type:netgis.LayerTypes.XYZ,url:h.href,title:e.title,attribution:e.rights,active:e.active});break;case "http://www.opengis.net/spec/owc-geojson/1.0/req/osm":h=k[0],b.layers.push({folder:f,type:netgis.LayerTypes.XYZ,url:h.href,title:e.title,attribution:e.rights,active:e.active})}}return b}}}();netgis.OWS.Config={url:""};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.content=document.createElement("div");b.appendChild(this.content);this.header=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.attachTo=function(a){a.appendChild(this.container);a.addEventListener(netgis.Events.PANEL_TOGGLE,this.onPanelToggle.bind(this))};netgis.Panel.prototype.addHeader=function(a,b,c){var d=document.createElement("button");d.className="netgis-button netgis-clip-text netgis-color-c netgis-gradient-a netgis-shadow";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.contains("netgis-show")||(this.container.classList.add("netgis-show"),netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{container:this.container,visible:!0,width:this.container.getBoundingClientRect().width}))};
netgis.Panel.prototype.hide=function(){this.container.classList.contains("netgis-show")&&(this.container.classList.remove("netgis-show"),netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{container:this.container,visible:!1}))};
netgis.Panel.prototype.toggle=function(){this.container.classList.toggle("netgis-show");var a=this.container.classList.contains("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{container:this.container,visible:a,width:a?this.container.getBoundingClientRect().width:void 0})};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.setTitle=function(a){this.header.getElementsByTagName("span")[0].innerHTML=a};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.Panel.prototype.onPanelToggle=function(a){a=a.detail;a.visible&&a.container!==this.container&&this.hide()};netgis=netgis||{};netgis.Plugins=function(a){this.config=a;this.plugins={};this.initConfig(a)};netgis.Plugins.Config={};
netgis.Plugins.prototype.initConfig=function(a){if(a=a.plugins)for(var b=0;b<a.length;b++){var c=a[b],d={};switch(c.type){case "panel":var e=new netgis.Panel(c.title);e.container.classList.add("netgis-plugin");c.active&&e.show();d.panel=e;break;case "window":e=new netgis.Window(c.title),e.container.classList.add("netgis-plugin"),c.active&&e.show(),d.window=e}if(e&&(e.container.setAttribute("data-id",c.id),c.url&&0<c.url.length)){var f=document.createElement("iframe");f.setAttribute("name",c.id);f.setAttribute("title",
c.title);f.setAttribute("src",c.url);f.setAttribute("data-id",c.id);f.onload=this.onIFrameLoad.bind(this);d.iframe=f;e.content.appendChild(f)}this.plugins[c.id]=d}};
netgis.Plugins.prototype.attachTo=function(a){for(var b in this.plugins){var c=this.plugins[b];c.panel&&c.panel.attachTo(a);c.window&&c.window.attachTo(a)}a.addEventListener(netgis.Events.PLUGIN_TOGGLE,this.onPluginToggle.bind(this));a.addEventListener(netgis.Events.PANEL_TOGGLE,this.onPanelToggle.bind(this));for(var d in netgis.Events)a.addEventListener(netgis.Events[d],this.onClientEvent.bind(this))};
netgis.Plugins.prototype.onPluginToggle=function(a){a=this.plugins[a.detail.id];a.panel&&a.panel.toggle();a.window&&a.window.toggle()};netgis.Plugins.prototype.onIFrameLoad=function(a){var b=a.target,c;for(c in netgis.Events)b.contentDocument.addEventListener(netgis.Events[c],function(a){this.onIFrameEvent(a,b.getAttribute("data-id"))}.bind(this))};netgis.Plugins.prototype.onIFrameMessage=function(a){console.info("IFrame Message:",a)};
netgis.Plugins.prototype.onIFrameEvent=function(a,b){var c=a.explicitOriginalTarget,d=a.detail;b=this.plugins[b];b.panel&&!b.panel.container.parentNode.contains(c)&&netgis.util.invoke(b.panel.container,a.type,d);b.window&&!b.window.container.parentNode.contains(c)&&netgis.util.invoke(b.window.container,a.type,d)};
netgis.Plugins.prototype.onClientEvent=function(a){var b=a.srcElement,c=a.type;a=a.detail;if(!b.classList.contains("netgis-plugin"))for(var d in this.plugins){var e=this.plugins[d];e.panel&&e.panel.container===b||e.window&&e.window.container===b||netgis.util.invoke(e.iframe.contentDocument,c,a)}};netgis.Plugins.prototype.onPanelToggle=function(a){a=a.detail;if(a.visible)for(var b in this.plugins){var c=this.plugins[b];c.panel&&a.container!==c.panel.container&&c.panel.hide()}};netgis=netgis||{};netgis.Popup=function(a){a||(a={direction:"down"});this.options=a;this.initElements()};
netgis.Popup.prototype.initElements=function(){document.body.addEventListener("pointerdown",this.onDocumentPointerDown.bind(this));this.container=document.createElement("div");this.container.className="netgis-popup";this.container.addEventListener("pointerdown",this.onPointerDown.bind(this));this.content=document.createElement("div");this.content.className="netgis-content netgis-color-e netgis-round";this.container.appendChild(this.content);this.content.addEventListener("pointermove",function(a){a.stopPropagation()});
switch(this.options.direction){default:case "down":this.container.classList.add("netgis-dir-down");break;case "right":this.container.classList.add("netgis-dir-right")}this.arrow=document.createElement("div");this.arrow.className="netgis-arrow";this.container.appendChild(this.arrow);this.closer=document.createElement("button");this.closer.setAttribute("type","button");this.closer.className="netgis-closer netgis-color-e netgis-text-a";this.closer.innerHTML="<span></span><i class='fas fa-times'></i>";
this.closer.onclick=this.onCloserClick.bind(this);this.content.appendChild(this.closer);this.loader=document.createElement("div");this.loader.className="netgis-loader netgis-color-e netgis-text-a";this.loader.innerHTML="<i class='netgis-icon netgis-anim-spin fas fa-sync-alt'></i>";this.wrapper=document.createElement("div");this.wrapper.className="netgis-wrapper";this.content.appendChild(this.wrapper)};netgis.Popup.prototype.attachTo=function(a){a.appendChild(this.container)};
netgis.Popup.prototype.show=function(){this.container.classList.add("netgis-show");netgis.util.isMobile()&&(this.container.style.width=document.body.getBoundingClientRect().width-10+"px")};netgis.Popup.prototype.hide=function(){this.container.classList.remove("netgis-show")};netgis.Popup.prototype.isVisible=function(){return this.container.classList.contains("netgis-show")};netgis.Popup.prototype.showLoader=function(){this.content.appendChild(this.loader)};
netgis.Popup.prototype.hideLoader=function(){this.loader.parentNode===this.content&&this.content.removeChild(this.loader)};
netgis.Popup.prototype.setPosition=function(a,b){var c=this.container.parentNode.getBoundingClientRect(),d=this.arrow.getBoundingClientRect();a>c.width-d.width&&(a=c.width-d.width);a<d.width&&(a=d.width);switch(this.options.direction){default:case "down":this.container.style.left=a+"px";this.container.style.top=b+"px";break;case "right":this.container.style.right=c.width-a+"px",this.container.style.top=b+"px"}this.content.style.left="";a=this.content.getBoundingClientRect();0>a.x?this.content.style.left=
-a.x+"px":a.x+a.width>c.width&&(this.content.style.left=-(a.x+a.width-c.width)+"px")};netgis.Popup.prototype.setHeader=function(a){this.closer.getElementsByTagName("span")[0].innerHTML=a};netgis.Popup.prototype.setContent=function(a){this.wrapper.innerHTML=a};netgis.Popup.prototype.clearContent=function(){this.wrapper.innerHTML=""};netgis.Popup.prototype.addContent=function(a){this.wrapper.innerHTML+=a};netgis.Popup.prototype.onDocumentPointerDown=function(a){};
netgis.Popup.prototype.onPointerDown=function(a){a.stopPropagation()};netgis.Popup.prototype.onCloserClick=function(a){this.hide()};netgis=netgis||{};netgis.Search=function(a){this.debounce=400;this.initElements(a);this.initEvents()};
netgis.Search.prototype.initElements=function(a){var b=document.createElement("div");b.className="netgis-search";this.container=b;var c=document.createElement("label");b.appendChild(c);this.label=c;var d=document.createElement("input");d.className="netgis-round netgis-shadow";d.setAttribute("type","text");d.setAttribute("placeholder",a);c.appendChild(d);this.input=d;a=document.createElement("button");a.setAttribute("type","button");a.innerHTML="<i class='fas fa-search'></i>";c.appendChild(a);this.button=
a;a=document.createElement("button");a.setAttribute("type","button");a.className="netgis-hide";a.innerHTML="<i class='fas fa-times'></i>";c.appendChild(a);this.closer=a;c=document.createElement("ul");b.appendChild(c);this.results=c};
netgis.Search.prototype.initEvents=function(){this.input.addEventListener("change",this.onInputChange.bind(this));this.input.addEventListener("keydown",this.onInputKeyDown.bind(this));this.input.addEventListener("keyup",this.onInputKeyUp.bind(this));this.button.addEventListener("click",this.onButtonClick.bind(this));this.closer.addEventListener("click",this.onCloserClick.bind(this))};netgis.Search.prototype.attachTo=function(a){a.appendChild(this.container)};netgis.Search.prototype.show=function(){this.container.classList.remove("netgis-hide")};
netgis.Search.prototype.hide=function(){this.container.classList.add("netgis-hide")};netgis.Search.prototype.toggle=function(){this.container.classList.toggle("netgis-hide")};netgis.Search.prototype.isVisible=function(){return!this.container.classList.contains("netgis-hide")};netgis.Search.prototype.minimize=function(){this.container.classList.remove("netgis-color-e","netgis-shadow");this.input.classList.add("netgis-shadow")};
netgis.Search.prototype.maximize=function(){this.container.classList.add("netgis-color-e","netgis-shadow");this.input.classList.remove("netgis-shadow")};netgis.Search.prototype.focus=function(){this.input.focus()};netgis.Search.prototype.setTitle=function(a){this.input.setAttribute("placeholder",a)};
netgis.Search.prototype.addResult=function(a,b){var c=document.createElement("li"),d=document.createElement("button");d.className="netgis-button netgis-clip-text netgis-color-e netgis-hover-a";d.innerHTML=a;d.setAttribute("type","button");d.setAttribute("title",d.innerText);d.setAttribute("data-result",b);d.addEventListener("click",this.onResultClick.bind(this));c.appendChild(d);0===this.results.childNodes.length&&this.showClearButton(!0);this.results.appendChild(c);this.maximize();return c};
netgis.Search.prototype.clearResults=function(){this.results.innerHTML="";this.minimize();netgis.util.invoke(this.container,netgis.Events.SEARCH_CLEAR,null)};netgis.Search.prototype.clearAll=function(){this.clearResults();this.lastQuery=null;this.input.value="";this.showClearButton(!1)};netgis.Search.prototype.requestSearch=function(a){this.lastQuery&&this.lastQuery===a||(this.lastQuery=a,netgis.util.invoke(this.container,netgis.Events.SEARCH_CHANGE,{query:a}))};
netgis.Search.prototype.showClearButton=function(a){!1===a?(this.button.classList.remove("netgis-hide"),this.closer.classList.add("netgis-hide")):(this.button.classList.add("netgis-hide"),this.closer.classList.remove("netgis-hide"))};netgis.Search.prototype.onInputKeyDown=function(a){if(13===a.keyCode)return a.preventDefault(),!1};
netgis.Search.prototype.onInputKeyUp=function(a){switch(a.keyCode){case 13:a=this.results.getElementsByTagName("button");0<a.length&&a[0].click();break;case 27:this.clearAll();break;default:this.onInputChange()}};netgis.Search.prototype.onInputChange=function(a){this.timeout&&window.clearTimeout(this.timeout);this.timeout=window.setTimeout(this.onInputTimeout.bind(this),this.debounce)};
netgis.Search.prototype.onInputTimeout=function(){var a=this.input.value;a=a.trim();0<a.length?this.requestSearch(a):this.clearAll()};netgis.Search.prototype.onButtonClick=function(a){this.input.focus()};netgis.Search.prototype.onCloserClick=function(a){this.clearAll();this.input.focus()};netgis.Search.prototype.onResultClick=function(a){a=a.currentTarget;var b=a.getAttribute("data-result");netgis.util.invoke(a,netgis.Events.SEARCH_SELECT,{item:a,data:b})};netgis=netgis||{};netgis.SearchParcel=function(a){this.config=a;this.districtsLayerID="searchparcel_districts";this.fieldsLayerID="searchparcel_fields";this.parcelsLayerID="searchparcel_parcels";this.selected={};this.initElements();this.initEvents();this.initConfig(a)};
netgis.SearchParcel.Config={open:!1,name_url:"./proxy.php?https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_alkis/gem_search.php?placename={q}",parcel_url:"./proxy.php?https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_alkis/flur_search.php?gmk_gmn={district}&fln={field}&fsn_zae={parcelA}&fsn_nen={parcelB}&export=json",districts_service:{type:"WFS",url:"http://geo5.service24.rlp.de/wfs/verwaltungsgrenzen_rp.fcgi?",name:"vermkv:gemarkungen_rlp",format:"application/json; subtype=geojson",
min_zoom:12},fields_service:{url:"http://geo5.service24.rlp.de/wfs/verwaltungsgrenzen_rp.fcgi?",name:"vermkv:fluren_rlp",filter_property:"gmkgnr"}};
netgis.SearchParcel.prototype.initElements=function(){this.panel=new netgis.Panel("Flurst\u00fccks-Suche");this.panel.container.style.minWidth="92mm";this.panel.container.addEventListener(netgis.Events.PANEL_TOGGLE,this.onPanelToggle.bind(this));this.container=document.createElement("section");this.container.className="netgis-search-parcel";this.panel.content.appendChild(this.container);this.popup=new netgis.Popup;this.popup.setHeader("Flurst\u00fcck");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));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";b.style.marginTop="4mm";a.appendChild(b);b=document.createElement("section");b.className="netgis-hide";this.bottom=b;this.container.appendChild(b);var c=document.createElement("button");c.className="netgis-button netgis-clip-text netgis-color-c netgis-gradient-a";
c.innerHTML="<span>Flurst\u00fccke</span> <span></span><i class='netgis-icon fas fa-times'></i>";c.setAttribute("type","button");c.addEventListener("click",this.onBottomHeaderClick.bind(this));b.appendChild(c);this.parcelCount=c.getElementsByTagName("span")[1];this.parcelInfo=document.createElement("p");this.parcelTable=this.createTable(["Flur","Z\u00e4hler","Nenner","FKZ","Fl\u00e4che (qm)"]);this.parcelTable.classList.add("netgis-hide");this.parcelTable.style.position="absolute";this.parcelTable.style.width=
"100%";this.parcelTable.style.top="12mm";this.parcelTable.style.bottom="0mm";this.parcelTable.style.margin="0mm";this.parcelTable.style.overflow="auto";b.appendChild(this.parcelTable);this.parcelList=this.parcelTable.getElementsByTagName("tbody")[0];this.parcelReset=document.createElement("button");this.parcelReset.setAttribute("type","button");this.parcelReset.addEventListener("click",this.onResetClick.bind(this));this.parcelReset.className="netgis-color-a netgis-hover-c";this.parcelReset.innerHTML=
"Zur\u00fccksetzen";this.parcelReset.style.marginTop="4mm";a.appendChild(this.parcelReset)};netgis.SearchParcel.prototype.initEvents=function(){this.resizeObserver=(new ResizeObserver(this.onTopResize.bind(this))).observe(this.top)};
netgis.SearchParcel.prototype.initConfig=function(a){this.districtsLayer=a.searchparcel.districts_service;this.districtsLayer.id=this.districtsLayerID;this.districtsLayer.style=a.styles.parcel;this.districtsLayer.order=99999;a.layers.push(this.districtsLayer);this.fieldsLayer={id:this.fieldsLayerID,type:netgis.LayerTypes.GEOJSON,style:a.styles.parcel,order:99999,data:null};a.layers.push(this.fieldsLayer);this.parcelsLayer={id:this.parcelsLayerID,type:netgis.LayerTypes.WKT,style:a.styles.parcel,order:99999,
data:null};a.layers.push(this.parcelsLayer);if(!0===a.searchparcel.open){var b=this;window.setTimeout(function(){b.panel.show()},100)}};
netgis.SearchParcel.prototype.attachTo=function(a){this.panel.attachTo(a);this.popup.attachTo(a);a.addEventListener(netgis.Events.CLIENT_SET_MODE,this.onClientSetMode.bind(this));a.addEventListener(netgis.Events.SEARCHPARCEL_TOGGLE,this.onSearchParcelToggle.bind(this));a.addEventListener(netgis.Events.MAP_FEATURE_ENTER,this.onMapFeatureEnter.bind(this));a.addEventListener(netgis.Events.MAP_FEATURE_CLICK,this.onMapFeatureClick.bind(this));a.addEventListener(netgis.Events.MAP_FEATURE_LEAVE,this.onMapFeatureLeave.bind(this));
a.addEventListener(netgis.Events.MAP_COPY_FEATURE_TO_EDIT,this.onMapCopyFeatureToEdit.bind(this))};netgis.SearchParcel.prototype.createInput=function(a){var b=document.createElement("label");b.className="netgis-hover-text-primary";b.innerHTML=a;a=document.createElement("input");a.setAttribute("type","text");b.appendChild(a);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);d=document.createElement("th");e.appendChild(d);var f=document.createElement("input");f.setAttribute("type","checkbox");f.addEventListener("change",this.onTableFilterChange.bind(this));
f.setAttribute("title","Nur markierte Parzellen anzeigen");d.appendChild(f);this.tableFilter=f;for(f=0;f<a.length;f++)d=document.createElement("th"),d.innerHTML=a[f],e.appendChild(d);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-d";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-hover-a";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=b;h.appendChild(a);b=document.createElement("td");
b.innerHTML=c;h.appendChild(b);c=document.createElement("td");c.innerHTML=netgis.util.trim(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.tableFilter.checked=!1;this.parcelList.classList.remove("netgis-filter-active");this.selected={};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.SEARCHPARCEL_RESET,null);this.panel.visible()&&this.showDistricts(!0);this.showFields(!1);this.showParcels(!1)};
netgis.SearchParcel.prototype.showDistricts=function(a){a?(netgis.util.invoke(this.container,netgis.Events.MAP_LAYER_TOGGLE,{id:this.districtsLayerID,on:!0}),netgis.util.invoke(this.container,netgis.Events.MAP_ZOOM_LEVEL,{z:this.config.searchparcel.districts_service.min_zoom})):netgis.util.invoke(this.container,netgis.Events.MAP_LAYER_TOGGLE,{id:this.districtsLayerID,on:!1})};
netgis.SearchParcel.prototype.showFields=function(a,b){a?(b.crs={type:"name",properties:{name:"urn:ogc:def:crs:EPSG::25832"}},this.fieldsLayer.data=b,netgis.util.invoke(this.container,netgis.Events.MAP_LAYER_TOGGLE,{id:this.fieldsLayerID,on:!0}),netgis.util.invoke(this.container,netgis.Events.MAP_ZOOM_LAYER,{id:this.fieldsLayerID})):(netgis.util.invoke(this.container,netgis.Events.MAP_LAYER_TOGGLE,{id:this.fieldsLayerID,on:!1}),this.fieldsLayer.data=null)};
netgis.SearchParcel.prototype.showParcels=function(a,b){if(a){a=[];for(var c=0;c<b.length;c++){var d=b[c];a.push({id:d.fsk,geometry:d.geometry,properties:{flaeche:d.flaeche,fln:d.fln,fsk:d.fsk,fsn_nen:d.fsn_nen,fsn_zae:d.fsn_zae}})}this.parcelsLayer.data=a;netgis.util.invoke(this.container,netgis.Events.MAP_LAYER_TOGGLE,{id:this.parcelsLayerID,on:!0});netgis.util.invoke(this.container,netgis.Events.MAP_ZOOM_LAYER,{id:this.parcelsLayerID})}else netgis.util.invoke(this.container,netgis.Events.MAP_LAYER_TOGGLE,
{id:this.parcelsLayerID,on:!1})};netgis.SearchParcel.prototype.onSearchParcelToggle=function(a){this.panel.toggle()};netgis.SearchParcel.prototype.onClientSetMode=function(a){a=a.detail;this.popup.clearContent();this.popup.hide();a.mode===netgis.Modes.SEARCH_PARCEL?this.reset():(this.showDistricts(!1),this.showFields(!1),this.showParcels(!1))};
netgis.SearchParcel.prototype.onPanelToggle=function(a){!1===a.detail.visible?netgis.util.invoke(this.panel.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.VIEW}):netgis.util.invoke(this.panel.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.SEARCH_PARCEL})};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.name_url;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.onInputNameResponse=function(a){this.nameLoader.classList.add("netgis-hide");this.parcelReset.classList.remove("netgis-hide");this.nameList.innerHTML="";if("{"===a.charAt(0)||"["===a.charAt(0)){a=JSON.parse(a);for(var b=0;b<a.data.length;b++){var c=a.data[b],d=this.createNameItem(c.gmk_name);d.getElementsByTagName("button")[0].setAttribute("data-id",c.gmk_gmn);this.nameList.appendChild(d)}}};
netgis.SearchParcel.prototype.onNameItemClick=function(a){a=a.target;var b=a.getAttribute("data-id");this.nameInput.value=a.innerHTML;this.nameList.innerHTML="";this.districtInput.value=b;this.requestFields(b)};
netgis.SearchParcel.prototype.requestFields=function(a){var b=this.config.searchparcel.fields_service,c=b.url;c=c+"service=WFS&version=1.0.0&request=GetFeature&outputFormat=application/json; subtype=geojson&typename="+b.name;c=c+"&filter=<Filter><PropertyIsEqualTo><PropertyName>"+(b.filter_property+"</PropertyName>");netgis.util.request(c+("<Literal>"+a+"</Literal></PropertyIsEqualTo></Filter>"),this.onFieldsResponse.bind(this))};
netgis.SearchParcel.prototype.onFieldsResponse=function(a){a=JSON.parse(a);this.showDistricts(!1);this.showFields(!0,a);this.showParcels(!1)};netgis.SearchParcel.prototype.selectFirstName=function(){var a=this.nameList.getElementsByTagName("button");0<a.length&&a[0].click()};netgis.SearchParcel.prototype.setDistrict=function(a,b){this.nameInput.value=a;this.districtInput.value=b;this.requestFields(b)};netgis.SearchParcel.prototype.setFieldNumber=function(a){this.fieldInput.value=a;this.onParcelSearchClick()};
netgis.SearchParcel.prototype.setParcelNumber=function(a,b){this.parcelInputA.value=a;this.parcelInputB.value=b;this.onParcelSearchClick()};netgis.SearchParcel.prototype.showBottom=function(){this.top.classList.add("netgis-resize-bottom");this.top.style.height="50%";this.top.style.bottom="auto";this.bottom.classList.remove("netgis-hide")};netgis.SearchParcel.prototype.hideBottom=function(){this.top.classList.remove("netgis-resize-bottom");this.top.style.height="auto";this.top.style.bottom="0mm";this.bottom.classList.add("netgis-hide")};
netgis.SearchParcel.prototype.onInputFieldKey=function(a){switch(a.keyCode){case 13:this.onParcelSearchClick()}};netgis.SearchParcel.prototype.onParcelSearchClick=function(a){this.requestParcels(this.districtInput.value.trim(),this.fieldInput.value.trim(),this.parcelInputA.value.trim(),this.parcelInputB.value.trim())};
netgis.SearchParcel.prototype.requestParcels=function(a,b,c,d){var e=this.config.searchparcel.parcel_url;e=netgis.util.replace(e,"{district}",a?a:"");e=netgis.util.replace(e,"{field}",b?b:"");e=netgis.util.replace(e,"{parcelA}",c?c:"");e=netgis.util.replace(e,"{parcelB}",d?d:"");this.parcelTable.classList.add("netgis-hide");this.parcelList.innerHTML="";this.parcelList.classList.remove("netgis-filter-active");this.tableFilter.checked=!1;this.selected={};this.parcelInfo.innerHTML="Suche Flurst\u00fccke...";
netgis.util.request(e,this.onParcelsResponse.bind(this))};
netgis.SearchParcel.prototype.updateTableRows=function(){for(var a=this.parcelList.getElementsByTagName("tr"),b=0;b<a.length;b++){var c=a[b],d=c.getAttribute("data-id"),e=c.getElementsByTagName("button")[0];!0===this.selected[d]?(c.classList.add("netgis-active","netgis-text-a","netgis-hover-text-a"),e.setAttribute("disabled","disabled"),e.setAttribute("title","Geometrie bereits \u00fcbernommen"),e.classList.remove("netgis-hover-a")):(c.classList.remove("netgis-active","netgis-text-a","netgis-hover-text-a"),
e.removeAttribute("disabled"),e.setAttribute("title","Geometrie \u00fcbernehmen"),e.classList.add("netgis-hover-a"))}};
netgis.SearchParcel.prototype.onParcelsResponse=function(a){a=JSON.parse(a);this.parcelCount.innerHTML="("+a.count+")";if(0===a.count)this.parcelInfo.innerHTML=a.Info;else{for(var b=0;b<a.data.length;b++){var c=a.data[b];c=this.createParcelItem(c.fln,c.fsn_zae,c.fsn_nen,c.fsk,c.flaeche,c.bbox,c.geometry);this.parcelList.appendChild(c)}this.parcelTable.classList.remove("netgis-hide");this.showBottom();this.showDistricts(!1);this.showFields(!1);this.showParcels(!0,a.data)}this.container.classList.contains("netgis-hide")||
this.parcelTable.scrollIntoView()};netgis.SearchParcel.prototype.onParcelEnter=function(a){a=a.target;var b=a.getAttribute("data-geom");a={id:a.getAttribute("data-id"),field:a.getAttribute("data-field"),parcelA:a.getAttribute("data-parcel-a"),parcelB:a.getAttribute("data-parcel-b"),geom:b};netgis.util.invoke(this.container,netgis.Events.SEARCHPARCEL_ITEM_ENTER,a)};netgis.SearchParcel.prototype.onParcelLeave=function(a){netgis.util.invoke(this.container,netgis.Events.SEARCHPARCEL_ITEM_LEAVE,{id:a.target.getAttribute("data-id")})};
netgis.SearchParcel.prototype.onParcelClick=function(a){netgis.util.invoke(this.container,netgis.Events.SEARCHPARCEL_ITEM_CLICK,{id:a.currentTarget.getAttribute("data-id")})};netgis.SearchParcel.prototype.onParcelImportClick=function(a){a.stopPropagation();a=a.currentTarget.parentElement.parentElement;var b=a.getAttribute("data-id");a.getAttribute("data-geom");netgis.util.invoke(this.container,netgis.Events.MAP_COPY_FEATURE_TO_EDIT,{source:this.parcelsLayerID,id:b})};
netgis.SearchParcel.prototype.onResetClick=function(a){this.reset()};netgis.SearchParcel.prototype.onTopResize=function(a){if(!this.bottom.classList.contains("netgis-hide")){a=this.top.getBoundingClientRect();var b=this.top.parentNode.getBoundingClientRect();this.bottom.style.top=a.bottom-b.top+"px"}};netgis.SearchParcel.prototype.onBottomHeaderClick=function(a){this.reset()};
netgis.SearchParcel.prototype.onMapFeatureEnter=function(a){var b=a.target;a=a.detail;switch(a.layer){case this.districtsLayerID:a=a.properties.gemarkung;b.setAttribute("title",a);break;case this.fieldsLayerID:a=a.properties.flurname;b.setAttribute("title",a);break;case this.parcelsLayerID:a="Flur: "+a.properties.fln+" / Z\u00e4hler: "+a.properties.fsn_zae+" / Nenner: "+a.properties.fsn_nen,b.setAttribute("title",a)}};
netgis.SearchParcel.prototype.onMapFeatureClick=function(a){var b=a.detail;this.popup.hide();switch(b.layer){case this.districtsLayerID:this.setDistrict(b.properties.gemarkung+" ("+b.properties.ldkreis+")",b.properties.gmkgnr);break;case this.fieldsLayerID:this.setFieldNumber(b.properties.flur);break;case this.parcelsLayerID:if(a=b.properties.fsk,!this.selected[a]){this.popup.container!==b.overlay&&this.popup.attachTo(b.overlay);var c="<table style='margin: 1mm;'><tr><th>Flur:</th><td>"+(b.properties.fln+
"</td>");c+="<tr><th>Z\u00e4hler:</th><td>"+b.properties.fsn_zae+"</td>";c+="<tr><th>Nenner:</th><td>"+b.properties.fsn_nen+"</td>";c+="<tr><th>Fl\u00e4che:</th><td>"+b.properties.flaeche+" qm</td>";this.popup.setContent(c+"</table><button type='button' class='netgis-hover-a'><i class='netgis-icon fas fa-paste' style='margin-right: 3mm;'></i><span>Geometrie \u00fcbernehmen</span></button>");b=this.popup.content.getElementsByTagName("button")[1];b.setAttribute("data-id",a);b.addEventListener("click",
this.onParcelPopupButtonClick.bind(this));this.popup.show()}}};netgis.SearchParcel.prototype.onParcelPopupButtonClick=function(a){a=a.currentTarget.getAttribute("data-id");netgis.util.invoke(this.container,netgis.Events.MAP_COPY_FEATURE_TO_EDIT,{source:this.parcelsLayerID,id:a});this.popup.hide()};
netgis.SearchParcel.prototype.onMapFeatureLeave=function(a){var b=a.target;switch(a.detail.layer){case this.districtsLayerID:case this.fieldsLayerID:b.setAttribute("title","");break;case this.parcelsLayerID:b.setAttribute("title","")}};netgis.SearchParcel.prototype.onMapCopyFeatureToEdit=function(a){a=a.detail;var b=a.id;a.source===this.parcelsLayerID&&(this.selected[b]||(this.selected[b]=!0),this.updateTableRows())};
netgis.SearchParcel.prototype.onTableFilterChange=function(a){this.parcelList.classList.toggle("netgis-filter-active",a.currentTarget.checked)};netgis=netgis||{};netgis.SearchPlace=function(a){this.config=a;this.initElements();this.initEvents();this.initConfig(a)};netgis.SearchPlace.Config={title:"Search...",url:"",zoom:17,marker_color:"darkgray",marker_title:"Search-Result"};
netgis.SearchPlace.prototype.initElements=function(){this.search=new netgis.Search("");this.container=this.search.container;this.container.classList.add("netgis-search-place","netgis-responsive");this.search.container.addEventListener(netgis.Events.SEARCH_CHANGE,this.onSearchChange.bind(this));this.search.container.addEventListener(netgis.Events.SEARCH_SELECT,this.onSearchSelect.bind(this));this.search.container.addEventListener(netgis.Events.SEARCH_CLEAR,this.onSearchClear.bind(this))};
netgis.SearchPlace.prototype.initEvents=function(){};netgis.SearchPlace.prototype.initConfig=function(a){(a=a.searchplace)&&a.title&&this.search.setTitle(a.title)};netgis.SearchPlace.prototype.attachTo=function(a){this.search.attachTo(a);a.addEventListener(netgis.Events.SEARCHPLACE_TOGGLE,this.onSearchPlaceToggle.bind(this))};
netgis.SearchPlace.prototype.onSearchPlaceToggle=function(a){(a=a.detail)&&a.on?this.search.show():this.search.toggle();if(this.search.isVisible()){var b=this.search;window.setTimeout(function(){b.focus()},200)}};netgis.SearchPlace.prototype.onSearchChange=function(a){var b=this.config.searchplace;b&&b.url&&(b=b.url,b=netgis.util.replace(b,"{query}",window.encodeURIComponent(a.detail.query)),b=netgis.util.replace(b,"{epsg}",4326),netgis.util.request(b,this.onSearchResponse.bind(this)))};
netgis.SearchPlace.prototype.onSearchResponse=function(a){a=JSON.parse(a);this.search.clearResults();if(a.geonames){a=a.geonames;for(var b=0;b<a.length;b++){var c=a[b],d=c.title,e=.5*(Number.parseFloat(c.minx)+Number.parseFloat(c.maxx)),f=.5*(Number.parseFloat(c.miny)+Number.parseFloat(c.maxy));c={type:c.category,id:b,lon:e,lat:f};this.search.addResult(d,JSON.stringify(c))}}else if(a.data)for(a=a.data,b=0;b<a.length;b++)c=a[b],d=c.name,c={type:"street",id:c.strid,lon:Number.parseFloat(c.wgs_x),lat:Number.parseFloat(c.wgs_y)},
this.search.addResult(d,JSON.stringify(c))};netgis.SearchPlace.prototype.onSearchSelect=function(a){a=JSON.parse(a.detail.data);netgis.util.invoke(this.container,netgis.Events.MAP_ZOOM_LONLAT,{lon:a.lon,lat:a.lat,zoom:this.config.searchplace.zoom});if("street"===a.type){var b=this.config.searchplace.url_detail;b&&(b=netgis.util.replace(b,"{id}",a.id),netgis.util.request(b,this.onSearchDetailResponse.bind(this)))}};
netgis.SearchPlace.prototype.onSearchDetailResponse=function(a){a=JSON.parse(a);var b=a.hsnrarr;if(0!==b.length){this.search.clearResults();for(var c=0;c<b.length;c++){var d=b[c],e=a.strname+" "+d.hsnr;d={type:"address",lon:Number.parseFloat(d.wgs_x),lat:Number.parseFloat(d.wgs_y)};this.search.addResult(e,JSON.stringify(d))}}};netgis.SearchPlace.prototype.onSearchClear=function(a){};netgis=netgis||{};
netgis.SLD=function(){return{read:function(a,b){var c={};a=(new DOMParser).parseFromString(a,"text/xml").getElementsByTagName("NamedLayer");for(var d=0;d<a.length;d++){var e=a[d],f=e.getElementsByTagName("se:Name")[0].innerHTML;console.info("Layer:",f);e=e.getElementsByTagName("se:FeatureTypeStyle");for(f=0;f<e.length;f++)for(var g=e[f].getElementsByTagName("se:Rule"),h=0;h<g.length;h++){var k=g[h],l=k.getElementsByTagName("se:Name")[0].innerHTML;console.info("Rule:",l);l=k.getElementsByTagName("se:PolygonSymbolizer")[0];k=
l.getElementsByTagName("se:Fill")[0];l=l.getElementsByTagName("se:Stroke")[0];c.polygon={fill:k.querySelector("[name='fill']").innerHTML,stroke:l.querySelector("[name='stroke']").innerHTML,strokeWidth:Number.parseFloat(l.querySelector("[name='stroke-width']").innerHTML)}}}console.info("SLD:",c);b.invoke(netgis.Events.MAP_UPDATE_STYLE,c);return c}}}();netgis=netgis||{};netgis.Tabs=function(a){this.initElements(a);this.setActiveTab(0)};
netgis.Tabs.prototype.initElements=function(a){this.container=document.createElement("div");this.container.className="netgis-tabs";this.header=document.createElement("div");this.header.className="netgis-header netgis-color-d";this.container.appendChild(this.header);this.content=document.createElement("div");this.content.className="netgis-content netgis-color-e";this.container.appendChild(this.content);for(var b=0;b<a.length;b++){var c=document.createElement("button");c.setAttribute("type","button");
c.addEventListener("click",this.onHeaderButtonClick.bind(this));c.className="netgis-button netgis-color-d";c.innerHTML=a[b];this.header.appendChild(c);c=document.createElement("section");c.className="netgis-color-e netgis-form";this.content.appendChild(c)}};netgis.Tabs.prototype.attachTo=function(a){a.appendChild(this.container)};
netgis.Tabs.prototype.setActiveTab=function(a){for(var b=this.header.getElementsByClassName("netgis-button"),c=this.content.getElementsByTagName("section"),d=0;d<b.length;d++){var e=b[d],f=c[d];d===a?(e.classList.add("netgis-color-e"),e.classList.add("netgis-text-a"),e.classList.add("netgis-bar-a"),e.classList.add("netgis-active"),e.scrollIntoView({behavior:"smooth"}),f.classList.remove("netgis-hide"),f.scrollTop=0):(e.classList.remove("netgis-color-e"),e.classList.remove("netgis-text-a"),e.classList.remove("netgis-bar-a"),
e.classList.remove("netgis-active"),f.classList.add("netgis-hide"))}};netgis.Tabs.prototype.getContentSection=function(a){return this.content.getElementsByTagName("section")[a]};netgis.Tabs.prototype.appendContent=function(a,b){this.content.getElementsByTagName("section")[a].appendChild(b)};
netgis.Tabs.prototype.updateHeaderScroll=function(){for(var a=0,b=this.header.getElementsByTagName("button"),c=0;c<b.length;c++){var d=b[c];a+=d.getBoundingClientRect().width;d.classList.contains("netgis-active")&&d.scrollIntoView()}b=this.header.getBoundingClientRect().width;a>b?this.container.classList.add("netgis-scroll"):this.container.classList.remove("netgis-scroll")};
netgis.Tabs.prototype.onHeaderButtonClick=function(a){a=a.currentTarget;for(var b=this.header.getElementsByClassName("netgis-button"),c=0,d=0;d<b.length;d++)if(b[d]===a){c=d;break}this.setActiveTab(c)};netgis=netgis||{};netgis.TimeSlider=function(a){this.config=a;this.insertTop=!0;this.initElements();for(a=1900;2E3>=a;a++);var b=this;window.setTimeout(function(){b.container.scrollLeft=0},1)};netgis.TimeSlider.Config={};
netgis.TimeSlider.prototype.initElements=function(){this.container=document.createElement("section");this.container.className="netgis-timeslider netgis-footer netgis-noselect netgis-color-e netgis-hide";document.addEventListener("pointermove",this.onPointerMove.bind(this));document.addEventListener("pointerup",this.onPointerUp.bind(this));this.header=document.createElement("button");this.header.className="netgis-header netgis-button netgis-clip-text netgis-color-a netgis-hover-c netgis-shadow";this.header.innerHTML=
"<i class='netgis-icon fas fa-clock'></i><span>TimeSlider</span><i class='netgis-icon fas fa-times'></i>";this.header.setAttribute("type","button");this.header.addEventListener("click",this.onHeaderClick.bind(this));this.container.appendChild(this.header);this.wrapper=document.createElement("div");this.wrapper.className="netgis-wrapper";this.wrapper.addEventListener("pointerdown",this.onPointerDown.bind(this));this.container.appendChild(this.wrapper);this.table=document.createElement("table");this.wrapper.appendChild(this.table);
this.top=document.createElement("tr");this.table.appendChild(this.top);this.bottom=document.createElement("tr")};netgis.TimeSlider.prototype.attachTo=function(a){a.appendChild(this.container);a.addEventListener(netgis.Events.TIMESLIDER_SHOW,this.onTimeSliderShow.bind(this));a.addEventListener(netgis.Events.TIMESLIDER_HIDE,this.onTimeSliderHide.bind(this))};
netgis.TimeSlider.prototype.setVisible=function(a){a?(this.container.classList.remove("netgis-hide"),this.container.parentNode.classList.add("netgis-footer")):(this.container.classList.add("netgis-hide"),this.container.parentNode.classList.remove("netgis-footer"))};netgis.TimeSlider.prototype.setTitle=function(a){this.header.getElementsByTagName("span")[0].innerHTML=a};netgis.TimeSlider.prototype.clearTimeSteps=function(){this.top.innerHTML=""};
netgis.TimeSlider.prototype.addTimeStep=function(a,b){var c=document.createElement("td");c.setAttribute("data-id",a);a=document.createElement("button");a.className="netgis-button netgis-color-e netgis-hover-d";a.innerHTML="<i class='netgis-icon netgis-text-a far fa-calendar'></i><span>"+b+"</span>";a.setAttribute("type","button");a.addEventListener("click",this.onTimeStepClick.bind(this));c.appendChild(a);this.top.appendChild(c)};
netgis.TimeSlider.prototype.addTimeStep_01=function(a,b){a=document.createElement("td");var c=document.createElement("td");this.insertTop?a.innerHTML=b:c.innerHTML=b;this.top.appendChild(a);this.bottom.appendChild(c);this.insertTop=!this.insertTop};
netgis.TimeSlider.prototype.setActiveTimeStep=function(a){var b=this.top.getElementsByTagName("td"),c=b[a],d=c.getAttribute("data-id");console.info("Set Active Step:",a,d);for(var e=0;e<b.length;e++){var f=b[e],g=f.getElementsByClassName("netgis-icon")[0];e===a?(f.classList.add("netgis-active"),g.classList.remove("fa-calendar"),g.classList.add("fa-calendar-check")):(f.classList.remove("netgis-active"),g.classList.add("fa-calendar"),g.classList.remove("fa-calendar-check"))}c.scrollIntoView();netgis.util.invoke(c,
netgis.Events.TIMESLIDER_SELECT,{layer:this.layerID,time:d})};netgis.TimeSlider.prototype.requestServiceWMST=function(a,b){a=a.trim();1>a.length||(-1===a.indexOf("GetCapabilities")&&(a+="&REQUEST=GetCapabilities"),netgis.util.request(a,this.onServiceResponseWMST.bind(this),{id:b}))};
netgis.TimeSlider.prototype.onServiceResponseWMST=function(a,b){for(var c=(new DOMParser).parseFromString(a,"text/xml").documentElement.getElementsByTagName("Layer"),d,e=0;e<c.length;e++){a=c[e];var f=a.getElementsByTagName("Name")[0].textContent;if(f===b.id){d={name:f,title:a.getElementsByTagName("Title")[0].textContent,abstract:a.getElementsByTagName("Abstract")[0].textContent,queryable:"1"===a.getAttribute("queryable"),opaque:"1"===a.getAttribute("opaque")};e=a.getElementsByTagName("SRS");0<e.length&&
(d.projection=e[0].textContent);e=a.getElementsByTagName("CRS");0<e.length&&(d.projection=e[0].textContent);e=a.getElementsByTagName("BoundingBox")[0];d.bbox=[Number.parseFloat(e.getAttribute("minx")),Number.parseFloat(e.getAttribute("miny")),Number.parseFloat(e.getAttribute("maxx")),Number.parseFloat(e.getAttribute("maxy"))];b=a.getElementsByTagName("Dimension");for(e=0;e<b.length;e++)if(c=b[e],"time"===c.getAttribute("name")){var g={defaultTime:c.getAttribute("default"),extent:c.textContent.split("/")};
break}a=a.getElementsByTagName("Extent");for(e=0;e<a.length;e++)if(b=a[e],"time"===b.getAttribute("name")){g.defaultTime=b.getAttribute("default");g.extent=b.textContent.split("/");break}d.time=g;break}}console.info("WMST Layer:",d);this.setTitle(d.title);if(d.time.extent){g=new Date(d.time.extent[0]);a=new Date(d.time.extent[1]);b=d.time.extent[2];d=[];switch(b){case "P1D":for(;g<=a;)d.push(new Date(g)),g.setDate(g.getDate()+1);break;default:console.error("unsupported WMST date range",b,g,a)}for(e=
0;e<d.length;e++)b=d[e],a=g=b.toISOString(),a=a.replace("T",", "),a=a.replace("Z",""),this.addTimeStep(g,a);this.setActiveTimeStep(d.length-1)}};netgis.TimeSlider.prototype.onTimeSliderShow=function(a){a=a.detail;console.info("TimeSlider Show:",a);this.layerID=a.layer;this.setTitle(a.title);this.clearTimeSteps();this.requestServiceWMST(a.url,a.name);this.setVisible(!0)};netgis.TimeSlider.prototype.onTimeSliderHide=function(a){this.setVisible(!1)};netgis.TimeSlider.prototype.onHeaderClick=function(a){this.setVisible(!1)};
netgis.TimeSlider.prototype.onPointerDown=function(a){a=a.pageX-this.wrapper.offsetLeft;this.down=!0;this.downX=a;this.downScroll=this.wrapper.scrollLeft;this.container.classList.add("netgis-active")};netgis.TimeSlider.prototype.onPointerMove=function(a){this.down&&(a.preventDefault(),this.wrapper.scrollLeft=this.downScroll-(a.pageX-this.wrapper.offsetLeft-this.downX))};netgis.TimeSlider.prototype.onPointerUp=function(a){this.down&&a.preventDefault();this.down=!1;this.container.classList.remove("netgis-active")};
netgis.TimeSlider.prototype.onTimeStepClick=function(a){a=a.currentTarget.parentNode;a.getAttribute("data-id");if(!(5<Math.abs(this.wrapper.scrollLeft-this.downScroll))){for(var b=this.top.getElementsByTagName("td"),c=-1,d=0;d<b.length;d++)if(b[d]===a){c=d;break}this.setActiveTimeStep(c)}};netgis=netgis||{};netgis.Toolbox=function(a){this.config=a;this.bottomPanels={};this.initElements(a);this.initOptions(a);this.initEvents();this.setActiveButton(netgis.Commands.VIEW)};netgis.Toolbox.Config={open:!1,items:[],options:{buffer_features:{title:"Buffer",items:[{id:"buffer_radius",type:"integer",title:"Radius (Meter)"},{id:"buffer_segments",type:"integer",title:"Segments"},{id:"buffer_submit",type:"button",title:"<i class='netgis-icon netgis-text-a fas fa-arrow-circle-right'></i><span>Akzeptieren</span>"}]}}};
netgis.Toolbox.prototype.initElements=function(a){this.panel=new netgis.Panel("Toolbox");this.panel.content.classList.add("netgis-toolbox");this.top=document.createElement("section");this.panel.content.appendChild(this.top);for(var b=a.toolbox.items,c=0;c<b.length;c++){var d=b[c];if(this.config.tools&&!1===this.config.tools.editable)switch(d.id){case "draw_points":continue;case "draw_lines":continue;case "draw_polygons":continue;case "modify_features":continue;case "delete_features":continue;case "buffer_features":continue;
case "cut_features":continue}this.addButton(this.top,d.id,d.title)}this.bottom=document.createElement("section");this.bottom.className="netgis-color-e netgis-hide";this.panel.content.appendChild(this.bottom);b=document.createElement("button");b.className="netgis-button netgis-clip-text netgis-color-c netgis-gradient-a";b.innerHTML="<span>Einstellungen</span><i class='netgis-icon fas fa-times'></i>";b.setAttribute("type","button");b.addEventListener("click",this.onBottomHeaderClick.bind(this));this.bottom.appendChild(b);
this.bottomTitle=b.getElementsByTagName("span")[0];a.toolbox&&!0===a.toolbox.open&&this.panel.show()};
netgis.Toolbox.prototype.initOptions=function(a){var b=a.toolbox.options;if(b)for(var c in b);a=a.tools;b=[];a&&(a.buffer||(a.buffer={}),this.bottomPanels.drawPoints=document.createElement("div"),b.push(this.addCheckbox(this.bottomPanels.drawPoints,"Einrasten",this.onDrawSnapToggle.bind(this))),this.addCheckbox(this.bottomPanels.drawPoints,"Puffern",this.onDrawBufferToggle.bind(this)),this.addInputNumber(this.bottomPanels.drawPoints,"Radius (Meter):",a.buffer.default_radius,this.onDrawBufferChange.bind(this)),
this.addInputNumber(this.bottomPanels.drawPoints,"Segmente:",a.buffer.default_segments,this.onDrawBufferChange.bind(this)),this.bottom.appendChild(this.bottomPanels.drawPoints),this.bottomPanels.drawLines=document.createElement("div"),b.push(this.addCheckbox(this.bottomPanels.drawLines,"Einrasten",this.onDrawSnapToggle.bind(this))),this.addCheckbox(this.bottomPanels.drawLines,"Puffern",this.onDrawBufferToggle.bind(this)),this.addInputNumber(this.bottomPanels.drawLines,"Radius (Meter):",a.buffer.default_radius,
this.onDrawBufferChange.bind(this)),this.addInputNumber(this.bottomPanels.drawLines,"Segmente:",a.buffer.default_segments,this.onDrawBufferChange.bind(this)),this.bottom.appendChild(this.bottomPanels.drawLines),this.showDrawBufferOptions(!1),this.bottomPanels.drawPolygons=document.createElement("div"),b.push(this.addCheckbox(this.bottomPanels.drawPolygons,"Einrasten",this.onDrawSnapToggle.bind(this))),this.bottom.appendChild(this.bottomPanels.drawPolygons),this.bottomPanels.bufferFeatures=document.createElement("div"),
this.addInputNumber(this.bottomPanels.bufferFeatures,"Radius (Meter):",a.buffer.default_radius,this.onBufferFeaturesChange.bind(this)),this.addInputNumber(this.bottomPanels.bufferFeatures,"Segmente:",a.buffer.default_segments,this.onBufferFeaturesChange.bind(this)),this.addCheckbox(this.bottomPanels.bufferFeatures,"Mehrfach-Auswahl",this.onSelectMultipleChange.bind(this)),this.addButton(this.bottomPanels.bufferFeatures,null,"<i class='netgis-icon netgis-text-a fas fa-arrow-circle-right'></i><span>Akzeptieren</span>",
this.onBufferFeaturesAccept.bind(this)),this.bottom.appendChild(this.bottomPanels.bufferFeatures),this.bottomPanels.cutFeatures=document.createElement("div"),this.addCheckbox(this.bottomPanels.cutFeatures,"Mehrfach-Auswahl",this.onSelectMultipleChange.bind(this)),this.bottom.appendChild(this.bottomPanels.cutFeatures),this.bottomPanels.modifyFeatures=document.createElement("div"),b.push(this.addCheckbox(this.bottomPanels.modifyFeatures,"Einrasten",this.onDrawSnapToggle.bind(this))),this.bottom.appendChild(this.bottomPanels.modifyFeatures));
if(a&&a.snapping){if(!1===a.snapping.show)for(c=0;c<b.length;c++)b[c].parentNode.classList.add("netgis-hide");if(!0===a.snapping.active){for(c=0;c<b.length;c++)b[c].checked=!0;var d=this;window.setTimeout(function(){netgis.util.invoke(d.panel.container,netgis.Events.MAP_SNAP_TOGGLE,{on:!0})},100)}}};netgis.Toolbox.prototype.initEvents=function(){this.resizeObserver=(new ResizeObserver(this.onTopResize.bind(this))).observe(this.top)};
netgis.Toolbox.prototype.attachTo=function(a){this.panel.attachTo(a);a.addEventListener(netgis.Events.CLIENT_SET_MODE,this.onClientSetMode.bind(this));a.addEventListener(netgis.Events.TOOLBOX_TOGGLE,this.onToolboxToggle.bind(this));a.addEventListener(netgis.Events.SELECT_MULTI_TOGGLE,this.onSelectMultiToggle.bind(this))};
netgis.Toolbox.prototype.addButton=function(a,b,c,d){var e=document.createElement("button");e.className="netgis-button netgis-clip-text netgis-color-e netgis-hover-d";e.innerHTML=c;e.setAttribute("type","button");e.setAttribute("data-id",b);d?e.onclick=d:e.addEventListener("click",this.onButtonClick.bind(this));a&&a.appendChild(e);return e};
netgis.Toolbox.prototype.addCheckbox=function(a,b,c){var d=document.createElement("label");d.className="netgis-noselect netgis-color-e netgis-hover-d";var e=document.createElement("input");e.setAttribute("type","checkbox");d.appendChild(e);var f=document.createElement("span");f.innerHTML=b;d.appendChild(f);c&&(e.onchange=c);a&&a.appendChild(d);return e};
netgis.Toolbox.prototype.addInputNumber=function(a,b,c,d){var e=document.createElement("label");e.className="netgis-noselect netgis-color-e netgis-hover-d";var f=document.createElement("span");f.innerHTML=b;e.appendChild(f);b=document.createElement("input");b.setAttribute("type","number");b.setAttribute("min",0);b.value=c;e.appendChild(b);d&&(b.onchange=d,b.onkeyup=d);a&&a.appendChild(e);return b};
netgis.Toolbox.prototype.showBottom=function(a,b){this.top.classList.add("netgis-resize-bottom");this.top.style.height="50%";this.top.style.bottom="auto";this.bottom.classList.remove("netgis-hide");this.bottomTitle.innerHTML=b;if(a)for(var c in this.bottomPanels)b=this.bottomPanels[c],b===a?b.classList.remove("netgis-hide"):b.classList.add("netgis-hide")};
netgis.Toolbox.prototype.hideBottom=function(){this.top.classList.remove("netgis-resize-bottom");this.top.style.height="auto";this.top.style.bottom="0mm";this.bottom.classList.add("netgis-hide")};
netgis.Toolbox.prototype.showDrawBufferOptions=function(a){var b=this.bottomPanels.drawPoints.getElementsByTagName("label"),c=this.bottomPanels.drawLines.getElementsByTagName("label");b[1].getElementsByTagName("input")[0].checked=a;(c[1].getElementsByTagName("input")[0].checked=a)?(b[2].classList.remove("netgis-hide"),b[3].classList.remove("netgis-hide"),c[2].classList.remove("netgis-hide"),c[3].classList.remove("netgis-hide")):(b[2].classList.add("netgis-hide"),b[3].classList.add("netgis-hide"),
c[2].classList.add("netgis-hide"),c[3].classList.add("netgis-hide"))};
netgis.Toolbox.prototype.setActiveButton=function(a){for(var b=this.top.getElementsByTagName("button"),c=null,d=0;d<b.length;d++){var e=b[d];a&&e.getAttribute("data-id")===a.toLowerCase()?(c=e,e.classList.remove("netgis-color-e"),e.classList.add("netgis-active","netgis-color-d")):(e.classList.remove("netgis-active","netgis-color-d"),e.classList.add("netgis-color-e"))}if(c){var f=this;window.setTimeout(function(){f.top.scrollTo({top:c.offsetTop,behavior:"smooth"})},10)}};
netgis.Toolbox.prototype.onToolboxToggle=function(a){this.panel.toggle()};
netgis.Toolbox.prototype.onClientSetMode=function(a){a=a.detail;this.hideBottom();switch(a.mode){default:this.setActiveButton(null);break;case netgis.Modes.VIEW:this.setActiveButton(netgis.Commands.VIEW);break;case netgis.Modes.ZOOM_BOX:this.setActiveButton(netgis.Commands.ZOOM_BOX);break;case netgis.Modes.MEASURE_LINE:this.setActiveButton(netgis.Commands.MEASURE_LINE);break;case netgis.Modes.MEASURE_AREA:this.setActiveButton(netgis.Commands.MEASURE_AREA);break;case netgis.Modes.DRAW_POINTS:this.setActiveButton(netgis.Commands.DRAW_POINTS);
this.showBottom(this.bottomPanels.drawPoints,"Punkte zeichnen");break;case netgis.Modes.DRAW_LINES:this.setActiveButton(netgis.Commands.DRAW_LINES);this.showBottom(this.bottomPanels.drawLines,"Linien zeichnen");break;case netgis.Modes.DRAW_POLYGONS:this.setActiveButton(netgis.Commands.DRAW_POLYGONS);this.showBottom(this.bottomPanels.drawPolygons,"Polygone zeichnen");break;case netgis.Modes.MODIFY_FEATURES:this.setActiveButton(netgis.Commands.MODIFY_FEATURES);this.showBottom(this.bottomPanels.modifyFeatures,
"Verschieben");break;case netgis.Modes.DELETE_FEATURES:this.setActiveButton(netgis.Commands.DELETE_FEATURES);break;case netgis.Modes.BUFFER_FEATURES:this.setActiveButton(netgis.Commands.BUFFER_FEATURES);this.showBottom(this.bottomPanels.bufferFeatures,"Puffern");this.onBufferFeaturesChange();break;case netgis.Modes.BUFFER_FEATURES_EDIT:this.setActiveButton(netgis.Commands.BUFFER_FEATURES);this.showBottom(this.bottomPanels.bufferFeatures,"Puffern");this.onBufferFeaturesChange();break;case netgis.Modes.BUFFER_FEATURES_DYNAMIC:this.setActiveButton(netgis.Commands.BUFFER_FEATURES);
this.showBottom(this.bottomPanels.bufferFeatures,"Puffern");this.onBufferFeaturesChange();break;case netgis.Modes.CUT_FEATURES:netgis.util.invoke(this.panel.container,netgis.Events.SELECT_MULTI_TOGGLE,{on:!1});this.setActiveButton(netgis.Commands.CUT_FEATURES);break;case netgis.Modes.CUT_FEATURES_DRAW:this.setActiveButton(netgis.Commands.CUT_FEATURES)}};
netgis.Toolbox.prototype.onTopResize=function(a){if(!this.bottom.classList.contains("netgis-hide")){a=this.top.getBoundingClientRect();var b=this.top.parentNode.getBoundingClientRect();this.bottom.style.top=a.bottom-b.top+"px"}};netgis.Toolbox.prototype.onBottomHeaderClick=function(a){netgis.util.invoke(this.panel.container,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.VIEW})};
netgis.Toolbox.prototype.onButtonClick=function(a){a=a.currentTarget;var b=a.getAttribute("data-id");netgis.util.invoke(a,netgis.Events.TOOLBOX_BUTTON_CLICK,{id:b});netgis.Client.handleCommand(a,b)};
netgis.Toolbox.prototype.onDrawSnapToggle=function(a){var b=a.currentTarget,c=b.parentNode.parentNode;a=b.checked;netgis.util.invoke(b,netgis.Events.MAP_SNAP_TOGGLE,{on:a});b=[];c===this.bottomPanels.drawPoints&&(b.push(this.bottomPanels.drawLines),b.push(this.bottomPanels.drawPolygons),b.push(this.bottomPanels.modifyFeatures));c===this.bottomPanels.drawLines&&(b.push(this.bottomPanels.drawPoints),b.push(this.bottomPanels.drawPolygons),b.push(this.bottomPanels.modifyFeatures));c===this.bottomPanels.drawPolygons&&
(b.push(this.bottomPanels.drawPoints),b.push(this.bottomPanels.drawLines),b.push(this.bottomPanels.modifyFeatures));c===this.bottomPanels.modifyFeatures&&(b.push(this.bottomPanels.drawPoints),b.push(this.bottomPanels.drawLines),b.push(this.bottomPanels.drawPolygons));for(c=0;c<b.length;c++)b[c].getElementsByTagName("input")[0].checked=a};
netgis.Toolbox.prototype.onDrawBufferToggle=function(a){a=a.currentTarget;var b=a.checked;this.showDrawBufferOptions(b);var c=this.bottomPanels.drawPoints.getElementsByTagName("input"),d=Number.parseFloat(c[2].value);c=Number.parseInt(c[3].value);netgis.util.invoke(a,netgis.Events.DRAW_BUFFER_TOGGLE,{on:b,radius:d,segments:c})};
netgis.Toolbox.prototype.onDrawBufferChange=function(a){a=a.currentTarget.parentNode.parentNode;var b=a.getElementsByTagName("input"),c=b[1].checked,d=Number.parseFloat(b[2].value),e=Number.parseInt(b[3].value);netgis.util.invoke(this.bottomPanels.drawPoints,netgis.Events.DRAW_BUFFER_CHANGE,{on:c,radius:d,segments:e});if(a===this.bottomPanels.drawPoints)var f=this.bottomPanels.drawLines;a===this.bottomPanels.drawLines&&(f=this.bottomPanels.drawPoints);f&&(b=f.getElementsByTagName("input"),b[1].checked=
c,b[2].value=d,b[3].value=e)};netgis.Toolbox.prototype.onBufferFeaturesChange=function(a){var b=this.bottomPanels.bufferFeatures.getElementsByTagName("input");a=Number.parseFloat(b[0].value);b=Number.parseInt(b[1].value);netgis.util.invoke(this.bottomPanels.bufferFeatures,netgis.Events.BUFFER_CHANGE,{radius:a,segments:b})};netgis.Toolbox.prototype.onSelectMultipleChange=function(a){netgis.util.invoke(this.bottomPanels.bufferFeatures,netgis.Events.SELECT_MULTI_TOGGLE,{on:a.currentTarget.checked})};
netgis.Toolbox.prototype.onSelectMultiToggle=function(a){a=a.detail;this.bottomPanels.bufferFeatures.getElementsByTagName("input")[2].checked=a.on};
netgis.Toolbox.prototype.onBufferFeaturesAccept=function(a){var b=this.bottomPanels.bufferFeatures.getElementsByTagName("input");a=Number.parseFloat(b[0].value);b=Number.parseInt(b[1].value);netgis.util.invoke(this.bottomPanels.bufferFeatures,netgis.Events.BUFFER_ACCEPT,{radius:a,segments:b});netgis.util.invoke(this.bottomPanels.bufferFeatures,netgis.Events.CLIENT_SET_MODE,{mode:netgis.Modes.VIEW})};netgis=netgis||{};netgis.Tree=function(a){this.draggable=a?a:!1;this.dragElement=null;this.initElements()};netgis.Tree.prototype.initElements=function(){var a=document.createElement("ul");a.className="netgis-tree";this.container=a};netgis.Tree.prototype.attachTo=function(a){a.appendChild(this.container)};netgis.Tree.prototype.clear=function(){this.container.innerHTML=""};
netgis.Tree.prototype.addFolder=function(a,b,c,d,e,f){var g=document.createElement("li");g.className="netgis-folder";g.setAttribute("data-id",b);b=document.createElement("details");g.appendChild(b);var h=document.createElement("summary");h.className="netgis-button netgis-noselect netgis-clip-text netgis-color-e netgis-hover-d";h.innerHTML="<i class='netgis-icon netgis-hide-open fas fa-folder'></i><i class='netgis-icon netgis-show-open fas fa-folder-open'></i><span>"+c+"</span>";b.appendChild(h);!0===
this.draggable&&(netgis.util.isDefined(f)&&!0!==f||this.setItemDraggable(h));c=document.createElement("label");h.appendChild(c);f=document.createElement("input");f.setAttribute("type","checkbox");f.onchange=this.onFolderChange.bind(this);c.appendChild(f);!0===e&&g.classList.add("netgis-nocheck");e=document.createElement("ul");b.appendChild(e);a=a?a.getElementsByTagName("ul")[0]:this.container;d?a.insertBefore(g,a.firstChild):a.appendChild(g);return g};
netgis.Tree.prototype.addCheckbox=function(a,b,c,d,e,f){var g=document.createElement("li");g.className="netgis-item";!0===this.draggable&&this.setItemDraggable(g);var h=document.createElement("label");h.className="netgis-button netgis-noselect netgis-clip-text netgis-color-e netgis-hover-d";h.innerHTML="<span>"+c+"</span>";g.appendChild(h);c=document.createElement("span");c.className="netgis-wrapper";h.insertBefore(c,h.firstChild);h=document.createElement("input");h.setAttribute("type","checkbox");
h.setAttribute("data-id",b);d&&(h.checked=d);h.onchange=this.onItemChange.bind(this);c.appendChild(h);f&&this.addItemDetails(g,b,f);a=a?a.getElementsByTagName("ul")[0]:this.container;e?a.insertBefore(g,a.firstChild):a.appendChild(g);return g};
netgis.Tree.prototype.addRadioButton=function(a,b,c,d,e){var f=document.createElement("li");f.className="netgis-item";var g=document.createElement("label");g.className="netgis-button netgis-noselect netgis-clip-text netgis-color-e netgis-hover-d";g.innerHTML="<span>"+c+"</span>";f.appendChild(g);c=document.createElement("span");c.className="netgis-wrapper";g.insertBefore(c,g.firstChild);g=a?"radio-"+a.getAttribute("data-id"):"radio-noname";var h=document.createElement("input");h.setAttribute("type",
"radio");h.setAttribute("name",g);h.setAttribute("value","radio-"+b);h.setAttribute("data-id",b);d&&(h.checked=d);h.onchange=this.onItemChange.bind(this);c.appendChild(h);e&&this.addItemDetails(f,b,e);a?a.getElementsByTagName("ul")[0].appendChild(f):this.container.appendChild(f);return f};
netgis.Tree.prototype.addButton=function(a,b,c,d){var e=document.createElement("li"),f=document.createElement("button");f.innerHTML=c;f.className="netgis-button netgis-color-e netgis-hover-d netgis-clip-text";f.setAttribute("type","button");e.appendChild(f);b&&f.setAttribute("data-id",b);d&&(f.onclick=d);f.addEventListener("click",this.onButtonClick.bind(this));a?a.getElementsByTagName("ul")[0].appendChild(e):this.container.appendChild(e);return e};
netgis.Tree.prototype.addSpace=function(a){var b=document.createElement("li");b.className="netgis-space";a?a.getElementsByTagName("ul")[0].appendChild(b):this.container.appendChild(b);return b};
netgis.Tree.prototype.addItemDetails=function(a,b,c){var d=document.createElement("details");d.className="netgis-noselect";var e=document.createElement("summary");e.className="netgis-clickable netgis-hover-d";e.innerHTML="<i class='fas fa-angle-down'></i>";d.appendChild(e);e=document.createElement("div");d.appendChild(e);for(var f=0;f<c.length;f++){var g=c[f],h=document.createElement("label");h.className="netgis-hover-d";switch(g.type){case "button":var k=document.createElement("button");k.setAttribute("type",
"button");k.addEventListener("click",g.callback);k.className="netgis-button netgis-color-e netgis-hover-d";k.innerHTML=g.title;h.appendChild(k);break;case "slider":k=document.createElement("span");k.className="netgis-clip-text";k.innerHTML=g.title;h.appendChild(k);k=document.createElement("span");h.appendChild(k);var l=document.createElement("input");l.setAttribute("type","range");l.setAttribute("min",0);l.setAttribute("max",100);l.setAttribute("step",1);l.setAttribute("value",g.val);l.setAttribute("data-id",
b);l.addEventListener("change",this.onItemSliderChange.bind(this));l.addEventListener("input",this.onItemSliderChange.bind(this));this.draggable&&(l.setAttribute("draggable","true"),l.addEventListener("dragstart",function(a){a.preventDefault();a.stopImmediatePropagation()}));k.appendChild(l)}e.appendChild(h)}a.appendChild(d)};
netgis.Tree.prototype.setItemDraggable=function(a){a.setAttribute("draggable","true");a.addEventListener("dragstart",this.onDragStart.bind(this));a.addEventListener("dragenter",this.onDragEnter.bind(this));a.addEventListener("dragover",this.onDragOver.bind(this));a.addEventListener("dragleave",this.onDragLeave.bind(this));a.addEventListener("drop",this.onDragDrop.bind(this));a.addEventListener("dragend",this.onDragEnd.bind(this))};
netgis.Tree.prototype.getFolder=function(a){for(var b=this.container.getElementsByClassName("netgis-folder"),c=0;c<b.length;c++){var d=b[c];if(d.getAttribute("data-id")===a)return d}return null};netgis.Tree.prototype.getItem=function(a){for(var b=this.container.getElementsByTagName("input"),c=0;c<b.length;c++){var d=b[c];if(d.getAttribute("data-id")===a)return d}return null};
netgis.Tree.prototype.removeItem=function(a){if(a=this.getItem(a))a=a.parentNode.parentNode.parentNode,a.parentNode.removeChild(a),this.removeEmptyFolders(),this.updateFolderChecks()};netgis.Tree.prototype.removeEmptyFolders=function(){for(var a=this.container.getElementsByClassName("netgis-folder"),b=0;b<a.length;b++)a[b].getElementsByTagName("ul")[0].getElementsByTagName("li")};
netgis.Tree.prototype.setFolderOpen=function(a,b){var c=this.container.getElementsByClassName("netgis-folder");a=a.toString();for(var d=0;d<c.length;d++){var e=c[d],f=e.getElementsByTagName("details")[0];e.getAttribute("data-id")===a&&(!0===b?f.setAttribute("open",""):f.removeAttribute("open"))}};
netgis.Tree.prototype.setItemChecked=function(a,b,c){var d=this.container.getElementsByClassName("netgis-item");a=a.toString();for(var e=0;e<d.length;e++){var f=d[e],g=f.getElementsByTagName("input")[0];if(g.getAttribute("data-id")===a){if("radio"===g.getAttribute("type")){f=f.parentNode.getElementsByTagName("input");for(var h=0;h<f.length;h++){var k=f[h];k!==g&&"radio"===k.getAttribute("type")&&!1!==k.checked&&(k.checked=!1,netgis.util.invoke(g,netgis.Events.TREE_ITEM_CHANGE,{id:k.getAttribute("data-id"),
checked:!1}))}}c?g.checked=b:g.checked!==b&&g.click()}}};netgis.Tree.prototype.setFolderParent=function(a,b){var c=a.parentNode;c&&c.removeChild(a);null!==b?b.getElementsByTagName("ul")[0].appendChild(a):this.container.appendChild(a)};netgis.Tree.prototype.updateFolderChecks=function(){for(var a=this.container.getElementsByClassName("netgis-folder"),b=0;b<a.length;b++)this.updateFolderCheck(a[b])};
netgis.Tree.prototype.updateFolderCheck=function(a){a||(a=this.container);for(var b=a.getElementsByClassName("netgis-item"),c=0,d=0;d<b.length;d++){var e=b[d].getElementsByTagName("input")[0];e.checked&&c++}e=a.getElementsByTagName("input")[0];d=0;0<c&&(d=1);0<c&&c===b.length&&(d=2);switch(d){case 0:e.checked=!1;e.classList.remove("netgis-partial");break;case 1:e.checked=!0;e.classList.add("netgis-partial");break;case 2:e.checked=!0,e.classList.remove("netgis-partial")}(a=a.parentElement)&&a!==this.container&&
(a=a.parentElement.parentElement)&&-1!==a.className.search("netgis-folder")&&this.updateFolderCheck(a)};netgis.Tree.prototype.onFolderChange=function(a){var b=a.currentTarget;a=b.checked;b=b.parentElement.parentElement.parentElement.parentElement;for(var c=b.getElementsByTagName("input"),d=1;d<c.length;d++){var e=c[d];e.checked!==a&&e.click()}this.updateFolderCheck(b);a=b.parentElement.parentElement.parentElement;-1!==a.className.search("netgis-folder")&&this.updateFolderCheck(a)};
netgis.Tree.prototype.onItemChange=function(a){a=a.currentTarget;var b=a.checked,c=a.getAttribute("data-id"),d=a.parentElement.parentElement.parentElement.parentElement.parentElement;if("radio"===a.getAttribute("type"))for(var e=a.parentNode.parentNode.parentNode.parentNode.getElementsByTagName("input"),f=0;f<e.length;f++){var g=e[f].getAttribute("data-id");g&&g!==c&&netgis.util.invoke(a,netgis.Events.TREE_ITEM_CHANGE,{id:g,checked:!1})}netgis.util.invoke(a,netgis.Events.TREE_ITEM_CHANGE,{id:c,checked:b});
-1!==d.className.search("netgis-folder")&&this.updateFolderCheck(d)};netgis.Tree.prototype.onRadioChange=function(a){a=a.currentTarget;var b=a.checked,c=a.getAttribute("data-id"),d=Number.parseInt(c);Number.isNaN(d)||(c=d);d=a.parentElement.parentElement.parentElement.parentElement.parentElement;netgis.util.invoke(a,netgis.Events.TREE_ITEM_CHANGE,{id:c,checked:b});-1!==d.className.search("netgis-folder")&&this.updateFolderCheck(d)};
netgis.Tree.prototype.onButtonClick=function(a){a=a.currentTarget;var b=a.getAttribute("data-id");netgis.util.invoke(a,netgis.Events.TREE_BUTTON_CLICK,{id:b})};netgis.Tree.prototype.onItemSliderChange=function(a){a=a.currentTarget;var b=a.getAttribute("data-id");netgis.util.invoke(a,netgis.Events.TREE_ITEM_SLIDER_CHANGE,{id:b,val:Number.parseFloat(a.value)})};
netgis.Tree.prototype.onDragStart=function(a){a.stopPropagation();var b=a.currentTarget,c=b.getElementsByTagName("input")[0].getAttribute("data-id");b.classList.add("netgis-dragging");a.dataTransfer.setData("text/plain",c);a.dataTransfer.dropEffect="move";this.dragElement=b};netgis.Tree.prototype.onDragEnter=function(a){a=a.currentTarget;a!==this.dragElement&&a.classList.add("netgis-dragover")};
netgis.Tree.prototype.onDragOver=function(a){a.preventDefault();a=a.currentTarget;a!==this.dragElement&&a.classList.add("netgis-dragover")};netgis.Tree.prototype.onDragLeave=function(a){a.currentTarget.classList.remove("netgis-dragover")};
netgis.Tree.prototype.onDragDrop=function(a){a.preventDefault();a.stopPropagation();var b=a.currentTarget;a.dataTransfer.getData("text/plain");if(b!==this.dragElement){b.classList.remove("netgis-dragover");"summary"===b.nodeName.toLowerCase()?(a=b.parentNode.getElementsByTagName("ul")[0],b=0<a.childNodes.length?a.childNodes[0]:null):a=b.parentNode;var c="summary"===this.dragElement.nodeName.toLowerCase()?this.dragElement.parentNode.parentNode:this.dragElement;c.parentNode!==a||1<a.childNodes.length||
(b=null);c.contains(a)||(c.parentNode.removeChild(c),b?a.insertBefore(c,b):a.appendChild(c),netgis.util.invoke(this.container,netgis.Events.TREE_ITEM_ORDER_CHANGE,{items:this.container.getElementsByClassName("netgis-item")}))}};netgis.Tree.prototype.onDragEnd=function(a){a.currentTarget.classList.remove("netgis-dragging");this.dragElement=null};netgis=netgis||{};
netgis.util=function(){var a=function(a,b){for(var c in a)a.hasOwnProperty(c)&&b(c,a[c])},b=function(){return navigator.language||"de-DE"};return{isDefined:function(a){return"undefined"!==typeof a},isObject:function(a){return"object"!==typeof a||Array.isArray(a)||null===a?!1:!0},isString:function(a){return"string"===typeof a||a instanceof String},isJSON:function(a,b){if(!0===b){a="string"!==typeof a?JSON.stringify(a):a;try{a=JSON.parse(a)}catch(e){return!1}return"object"===typeof a&&null!==a}b=a.trim();
a=b.charAt(0);b=b.charAt(b.length-1);return"{"===a&&"}"===b||"["===a&&"]"===b?!0:!1},isMobile:function(a){return a?600>a.getBoundingClientRect().width:600>document.body.getBoundingClientRect().width},clone:function(a){return JSON.parse(JSON.stringify(a))},stringToID:function(a,b){b||(b="-");a=a.trim();a=a.toLowerCase();a=this.replace(a," ",b);a=this.replace(a,"\n",b);a=this.replace(a,"\t",b);a=this.replace(a,"\\.",b);a=this.replace(a,"\\,",b);a=this.replace(a,"\\!",b);a=this.replace(a,"\\?",b);a=
this.replace(a,":",b);a=this.replace(a,";",b);a=this.replace(a,'"',b);a=this.replace(a,"'",b);a=this.replace(a,"\\\u00a7",b);a=this.replace(a,"\\$",b);a=this.replace(a,"\\%",b);a=this.replace(a,"\\&",b);a=this.replace(a,"\\/",b);a=this.replace(a,"\\\\",b);a=this.replace(a,"\\(",b);a=this.replace(a,"\\)",b);a=this.replace(a,"\\{",b);a=this.replace(a,"\\}",b);a=this.replace(a,"\\[",b);a=this.replace(a,"\\]",b);a=this.replace(a,"=",b);a=this.replace(a,"\\+",b);a=this.replace(a,"\\*",b);a=this.replace(a,
"\\~",b);a=this.replace(a,"\\^",b);a=this.replace(a,"\\\u00b0",b);a=this.replace(a,"\u00b2",b);a=this.replace(a,"\u00b3",b);a=this.replace(a,"\\#",b);a=this.replace(a,"\\<",b);a=this.replace(a,"\\>",b);a=this.replace(a,"\\|",b);a=this.replace(a,"\\@",b);a=this.replace(a,"\u20ac",b);a=this.replace(a,"\u00b5",b);a=this.trim(a,b);a=this.replace(a,"\u00e4","ae");a=this.replace(a,"\u00f6","oe");a=this.replace(a,"\u00fc","ue");a=this.replace(a,"\u00df","ss");a=this.replace(a,"\u00e1","a");a=this.replace(a,
"\u00e0","a");a=this.replace(a,"\u00e2","a");a=this.replace(a,"\u00e9","e");a=this.replace(a,"\u00e8","e");a=this.replace(a,"\u00ea","e");a=this.replace(a,"\u00ed","i");a=this.replace(a,"\u00ec","i");a=this.replace(a,"\u00ee","i");a=this.replace(a,"\u00f3","o");a=this.replace(a,"\u00f2","o");a=this.replace(a,"\u00f4","o");a=this.replace(a,"\u00fa","u");a=this.replace(a,"\u00f9","u");return a=this.replace(a,"\u00fb","u")},replace:function(a,b,e){return a.replace(new RegExp(b,"g"),e)},trim:function(a,
b){a=a.replace(new RegExp("^"+b+"+"),"");return a=a.replace(new RegExp(b+"+$"),"")},foreach:a,template:function(b,d){a(d,function(a,c){b=b.replace(new RegExp("{"+a+"}","g"),c)});return b},newlines:function(a){return a.replace(/\n/g,"<br />")},create:function(a){var b=document.createElement("tbody");b.innerHTML=a;return b.children[0]},insideElement:function(a,b,e){a=a.getBoundingClientRect();return b<a.left||e<a.top||b>a.right||e>a.bottom?!1:!0},size:function(a){a=(new TextEncoder).encode(JSON.stringify(a)).length;
var b=a/1024;return{bytes:a,kilobytes:b,megabytes:b/1024}},request:function(a,b,e,f){f=new XMLHttpRequest;e&&(f._requestData=e);f.onload=function(){b(this.responseText,this._requestData,this)};f.withCredentials=!1;f.open("GET",a,!0);f.send();return f},downloadJSON:function(a,b){a="data:text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(a));var c=document.createElement("a");c.setAttribute("href",a);c.setAttribute("download",b);document.body.appendChild(c);c.click();c.remove()},padstr:function(a,
b){for(a=a.toString();a.length<b;)a="0"+a;return a},merge:function(a,b){return Object.assign(a,b)},getTimeStamp:function(a){var b=new Date;if(!0===a){a=b.getFullYear();var c=b.getMonth()+1,f=b.getDate(),g=b.getHours(),h=b.getMinutes();b=b.getSeconds();10>c&&(c="0"+c);10>f&&(f="0"+f);10>g&&(g="0"+g);10>h&&(h="0"+h);10>b&&(b="0"+b);a=[a,c,f,"_",g,h,b].join("")}else a=b.getDate()+"."+(b.getMonth()+1)+"."+b.getFullYear(),a+=" "+b.getHours()+":"+b.getMinutes();return a},getUserLanguage:b,getFileExtension:function(a){a=
a.split(".");return 1>=a.length?"":a[a.length-1]},parseURL:function(a){var b=a.indexOf("?"),c=-1<b?a.substr(0,b):a,f=[];if(-1<b)for(a=a.substr(b+1),a=a.split("&"),b=0;b<a.length;b++){var g=a[b];g=g.toLowerCase();-1<g.search("request")||f.push(g)}return{base:c,parameters:f}},formatDistance:function(a){return 100<a?Math.round(a/1E3*100)/100+" km":Math.round(100*a)/100+" m"},formatLength:function(a,b){var c=1E3<a;a=c?b?Math.round(a/1E3*1E3)/1E3:Math.round(a/1E3):b?Math.round(100*a)/100:Math.round(a);
0===a&&(c=!1);return a+(c?" km":" m")},formatArea:function(a,d,e,f){a=(e=a>(e||1E5))?d?Math.round(a/1E6*1E3)/1E3:Math.round(a/1E6):d?Math.round(100*a)/100:Math.round(a);0===a&&(e=!1);a=a.toLocaleString(b());return a+(e?" km\u00b2":" m\u00b2")},hexToRGB:function(a){"#"===a.charAt(0)&&(a=a.substr(1));a=Number.parseInt(a,16);return[a>>16&255,a>>8&255,a&255]},invoke:function(a,b,e){a.dispatchEvent(new CustomEvent(b,{bubbles:!0,detail:e}))},handler:function(a,b){return function(c){b||(b=c);netgis.util.invoke(this,
a,b)}}}}();netgis=netgis||{};netgis.Window=function(a){this.resizing=this.dragging=!1;this.py=this.px=0;this.initElements(a);this.initEvents();var b=this;window.setTimeout(function(){var a=b.container.getBoundingClientRect();b.container.style.right="auto";b.container.style.bottom="auto";b.container.style.left=a.left+"px";b.container.style.top=a.top+"px"},100)};
netgis.Window.prototype.initElements=function(a){this.container=document.createElement("section");this.container.className="netgis-window netgis-shadow";this.header=document.createElement("button");this.header.setAttribute("type","button");this.header.className="netgis-mover netgis-button netgis-clip-text netgis-color-c netgis-gradient-a netgis-shadow";this.header.innerHTML=a;this.container.appendChild(this.header);this.closer=document.createElement("button");this.closer.className="netgis-closer netgis-button netgis-text-e";
this.closer.innerHTML='<i class="netgis-icon fas fa-times"></i>';this.closer.setAttribute("type","button");this.container.appendChild(this.closer);this.content=document.createElement("div");this.content.className="netgis-content";this.container.appendChild(this.content)};
netgis.Window.prototype.initEvents=function(){this.closer.addEventListener("click",this.onCloserClick.bind(this));this.header.addEventListener("pointerdown",this.onPointerDown.bind(this));document.addEventListener("pointermove",this.onDocPointerMove.bind(this));document.addEventListener("pointerup",this.onDocPointerUp.bind(this));this.observer=new ResizeObserver(this.onResizeObserve.bind(this));this.observer.observe(this.container,{attributes:!0})};netgis.Window.prototype.attachTo=function(a){a.appendChild(this.container)};
netgis.Window.prototype.show=function(){this.container.classList.remove("netgis-hide")};netgis.Window.prototype.hide=function(){this.container.classList.add("netgis-hide")};netgis.Window.prototype.toggle=function(){this.container.classList.toggle("netgis-hide")};netgis.Window.prototype.isVisible=function(){return!this.container.classList.contains("netgis-hide")};netgis.Window.prototype.onCloserClick=function(a){this.hide()};
netgis.Window.prototype.onPointerDown=function(a){var b=this.container.getBoundingClientRect();this.dragging=!0;this.px=a.clientX-b.left;this.py=a.clientY-b.top;this.container.classList.add("netgis-dragging")};
netgis.Window.prototype.onDocPointerMove=function(a){var b=a.clientX,c=a.clientY,d=this.container.getBoundingClientRect();if(!this.resizing&&this.dragging){b-=this.px;c-=this.py;var e=this.container.parentNode.getBoundingClientRect();0>b&&(b=0,this.px=a.clientX-d.left);40>c&&(c=40,this.py=a.clientY-d.top);b+d.width>e.right&&(b=e.width-d.width,this.px=a.clientX-d.left);c+d.height>e.bottom&&(c=e.height-d.height,this.py=a.clientY-d.top);this.container.style.left=b+"px";this.container.style.top=c+"px";
this.container.style.right="auto";this.container.style.bottom="auto"}};netgis.Window.prototype.onDocPointerUp=function(a){this.resizing=this.dragging=!1;this.container.classList.remove("netgis-dragging")};netgis.Window.prototype.onResizeObserve=function(a){this.dragging&&(this.dragging=!1,this.resizing=!0);a=this.container.getBoundingClientRect();netgis.util.invoke(this.container,netgis.Events.WINDOW_RESIZE,{x:a.x,y:a.y,w:a.width,h:a.height})};netgis=netgis||{};netgis.WMC=function(a){this.config=a};netgis.WMC.Config={url:"",layers_url:""};netgis.WMC.prototype.requestContext=function(a,b){this.callback=b;netgis.util.request(a,this.onContextResponse.bind(this))};netgis.WMC.prototype.onContextResponse=function(a){var b=JSON.parse(a);this.data=b;a=[];b=b.layerList;for(var c=0;c<b.length;c++)a.push(b[c].layerId);this.requestLayers(a)};
netgis.WMC.prototype.requestLayers=function(a){var b=this.config.wmc;b?(b=b.layers_url,b=netgis.util.replace(b,"{ids}",a.join(",")),netgis.util.request(b,this.onLayersResponse.bind(this))):console.error("no config[ 'wmc' ] found, skipping WMC layer loading")};netgis.WMC.prototype.onLayersResponse=function(a){this.layers=a=JSON.parse(a);console.info("WMC Layers Response:",a);this.callback&&this.callback({config:this.toConfig()})};
netgis.WMC.prototype.toConfig=function(){var a=this.data.wmc,b=this.data.layerList,c=this.layers.wms.srv,d={},e=a.bbox;e=e.split(",");for(var f=0;f<e.length;f++)e[f]=Number.parseFloat(e[f]);d.map={projection:a.crs,bbox:e};d.attribution||(d.attribution={});d.attribution.prefix=d.attribution.prefix?a.title+", "+d.attribution.prefix:a.title;a=d.folders=[];e=d.layers=[];this.parseServiceLayers(c,b,a,e);b=1E3;for(c=0;c<a.length;c++){f=a[c];for(var g=e.length-1;0<=g;g--){var h=e[g];h.folder===f.id&&(h.order=
b,b+=1)}}return d};
netgis.WMC.prototype.parseServiceLayers=function(a,b,c,d){c||(c=[]);d||(d=[]);for(var e=0;e<a.length;e++)for(var f=a[e],g=0;g<f.layer.length;g++){var h=f.layer[g];h.isRoot&&c.push({id:h.id,title:h.title,open:"1"===f.isopen});var k=h.layer;if(k){b&&k.sort(function(a,c){a=a.id;var d=c.id,e=null;c=null;for(var f=0;f<b.length;f++){var g=b[f];g.layerId.toString()===a&&(e=g);g.layerId.toString()===d&&(c=g)}a=e.layerPos;c=c.layerPos;return a<c?-1:a>c?1:0});for(var l=k.length-1;0<=l;l--){var m=k[l],n=m.id,
p=null;if(b)for(var q=0;q<b.length;q++)if(b[q].layerId.toString()===n){p=b[q];break}m=this.parseServiceLayer(n,f,h.id,m,p);d.push(m)}}}return{folders:c,layers:d}};netgis.WMC.prototype.parseServiceLayer=function(a,b,c,d,e){return{id:a,folder:c,title:d.title,active:e?e.active:!0,query:1===d.queryable,transparency:e?1-.01*e.opacity:0,order:1E3,type:netgis.LayerTypes.WMS,url:b.getMapUrl,name:d.name,format:e?e.currentFormat:"image/png"}};
netgis.WMC.prototype.toConfig_02=function(){var a=this.data.wmc,b=this.layers.wms.srv,c=this.data.layerList,d={},e=a.bbox;e=e.split(",");for(var f=0;f<e.length;f++)e[f]=Number.parseFloat(e[f]);d.map={projection:a.crs,bbox:e};d.attribution||(d.attribution={});d.attribution.prefix=d.attribution.prefix?a.title+", "+d.attribution.prefix:a.title;a=d.folders=[];e=d.layers=[];var g=[];for(f=0;f<c.length;f++){var h=c[f],k={id:Number.parseInt(h.layerId),type:"layer",order:h.layerPos,active:h.active,opacity:h.opacity};
g.push(k)}for(f=0;f<b.length;f++){c=b[f];k={id:Number.parseInt(c.id),type:"service",title:c.title,url:c.getMapUrl,open:"1"===c.isopen};g.push(k);for(var l=0;l<c.layer.length;l++){h=c.layer[l];var m=this.parseLayer(h,k.id,g);if(h.layer)for(var n=0;n<h.layer.length;n++){var p=h.layer[n],q=this.parseLayer(p,m.id,g);if(p.layer)for(var r=0;r<p.layer.length;r++){var t=p.layer[r],u=this.parseLayer(t,q.id,g);if(t.layer)for(var v=0;v<t.layer.length;v++)this.parseLayer(t.layer[v],u.id,g)}}}}console.info("WMC ITEMS:",
g);for(f=0;f<g.length;f++)switch(k=g[f],k.type){case "service":a.push({id:k.id,title:k.title,open:k.open});break;case "layer":h={},e.push(h)}return d};
netgis.WMC.prototype.parseLayer=function(a,b,c){for(var d=null,e=0;e<c.length;e++)if(c[e].id===Number.parseInt(a.id)){d=c[e];break}d||(d={id:Number.parseInt(a.id),type:"layer"},c.push(d));d.title=a.title;d.name=a.name;d.parent=b;a.getLegendGraphicUrl&&a.getLegendGraphicUrlFormat&&(d.legendURL=a.getLegendGraphicUrl,d.legendFormat=a.getLegendGraphicUrlFormat);a.legendUrl&&(d.legendURL=window.decodeURIComponent(a.legendUrl),d.legendFormat=a.getLegendGraphicUrlFormat);d.queryable=1===a.layerQueryable||
1===a.queryable?!0:!1;if(a.bbox){a=a.bbox.split(",");for(b=0;b<a.length;b++)a[b]=parseFloat(a[b]);d.bbox=[a[0],a[1],a[2],a[3]]}return d};
netgis.WMC.prototype.toConfig_01=function(){var a=this.data.wmc,b=this.layers.wms.srv,c=this.data.layerList,d={},e=a.bbox;e=e.split(",");for(var f=0;f<e.length;f++)e[f]=Number.parseFloat(e[f]);d.map={attribution:a.title+", GeoPortal RLP",projection:a.crs,bbox:e};e=[];var g={};for(f=0;f<b.length;f++){var h=b[f],k={id:h.id,title:h.title,open:"1"===h.isopen};e.push(k);for(k=0;k<h.layer.length;k++){var l=h.layer[k];l.getMapUrl||(l.getMapUrl=h.getMapUrl);g[l.id.toString()]=l;if(l.layer)for(var m=0;m<l.layer.length;m++){var n=
l.layer[m];n.getMapUrl||(n.getMapUrl=l.getMapUrl);g[n.id.toString()]=n}}}console.info("WMC FOLDERS:",b,"---\x3e",e);b=[];h=9999;(this.kmloverlay=a.kmloverlay)&&""!==this.kmloverlay&&(k={id:"kmloverlay",title:"Meine Geodaten",parent:null},e.push(k),l={id:"kmloverlay",folder:"kmloverlay",title:"KML Overlay",active:!0,order:h,type:netgis.LayerTypes.KML,url:this.kmloverlay,query:!0},b.push(l),--h);for(f=c.length-1;0<=f;f--)a=c[f],m=a.layerId.toString(),(l=g[m])&&!l.isRoot&&(k=null!==a.layerParent?e[a.layerParent].id:
null,l={id:m,folder:k,title:l.title,active:a.active,query:1===a.layerQueryable,transparency:1-.01*a.opacity,order:h,type:netgis.LayerTypes.WMS,url:l.getMapUrl,name:l.name,format:a.currentFormat},"image/tiff"===l.format&&(l.format="image/png"),b.push(l),--h);d.folders=e;d.layers=b;return d};
netgis.build="20251010";

View File

@@ -1,15 +1,13 @@
{% load static %}
<!-- Library Styles -->
<link rel="stylesheet" type="text/css" href="{% static 'libs/fontawesome/5.12.0/css/all.min.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'libs/openlayers/7.2.2/ol.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'libs/openlayers/10.0.0/ol.css' %}" />
<!-- Client Styles -->
<link rel="stylesheet" type="text/css" href="{% static 'netgis.min.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'dist/netgis.min.css' %}" />
<!-- Library Scripts-->
<script type="text/javascript" src="{% static 'libs/openlayers/7.2.2/ol.js' %}"></script>
<script type="text/javascript" src="{% static 'libs/openlayers/10.0.0/ol.js' %}"></script>
<script type="text/javascript" src="{% static 'libs/proj4js/2.6.0/proj4.js' %}"></script>
<script type="text/javascript" src="{% static 'libs/jsts/1.6.1/jsts.min.js' %}"></script>
<script type="text/javascript" src="{% static 'libs/shapefilejs/4.0.2/shp.js' %}"></script>
@@ -19,13 +17,14 @@
<script type="text/javascript" src="{% static 'libs/geopackage/4.2.3/geopackage.min.js' %}"></script>
<!-- Client Scripts -->
<script type="text/javascript" src="{% static 'netgis.min.js' %}"></script>
<script type="text/javascript" src="{% static 'dist/netgis.min.js' %}"></script>
<main id="container" {% if geom_form.read_only %}data-editable="false"{% else %}data-editable="true"{% endif %} style="position: relative; width: 100%; height: 100%;">
<main id="container"
{% if geom_form.read_only %}data-editable="false"{% else %}data-editable="true"{% endif %}
style="position: relative; width: 100%; height: 100%;">
</main>
<input type="hidden" id="netgis-storage" name="geom" value="{{geom_form.fields.geom.initial}}"/>
<input type="hidden" id="netgis-storage" name="output" value="{{geom_form.fields.output.initial}}"/>
<script type="text/javascript">

View File

@@ -109,6 +109,11 @@
.ol-viewport canvas {
all: unset;
overflow: hidden;
}
.ol-viewport {
touch-action: pan-x pan-y;
}
.ol-selectable {
@@ -343,3 +348,7 @@
.ol-overviewmap .ol-overviewmap-box:hover {
cursor: move;
}
.ol-overviewmap .ol-viewport:hover {
cursor: pointer;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,25 +0,0 @@
BSD 2-Clause License
Copyright 2005-present, OpenLayers Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

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