Compare commits

...

75 Commits

Author SHA1 Message Date
ee2c859a9e Merge pull request '# Improve exception reporting for API' (#515) from improve_exception_reporting into master
Reviewed-on: #515
2025-12-19 14:17:37 +01:00
328f672ec0 # Improve exception reporting for API
* fixes typo in exception_reporter.py
* properly catches error on geometry cast into multipolygon if input are no valid polygons
* extends error response on malicious api calls
* specifies different exceptions on try-catch while initializing api data
2025-12-19 14:17:15 +01:00
047c9489fe Merge pull request '# ExceptionReporter adjustment' (#513) from improve_exception_reporting into master
Reviewed-on: #513
2025-12-17 14:03:23 +01:00
38b81996ed # ExceptionReporter adjustment
* extends the KonovaExceptionReporter to hold POST body content (practical for debugging broken content on API)
2025-12-17 14:02:08 +01:00
4c4d64cc3d Merge pull request '# HOTFIX: empty geometry save' (#510) from hotfix_empty_geometry_save into master
Reviewed-on: #510
2025-12-03 13:49:55 +01:00
fbde03caec # Optimization
* optimizes logic in case of empty geometry by dropping redundant pre-check on emptiness
2025-12-03 13:48:58 +01:00
43eb598d3f # HOTFIX: empty geometry save
* fixes a bug where the saving of an empty geometry could lead into a json decode error
2025-12-03 13:38:13 +01:00
b7fac0ae03 Merge pull request '# Fix fpr #507' (#508) from 507_Improper_deduction-recording_rendering_on_unrecorded_eco_account into master
Reviewed-on: #508
2025-11-30 12:33:39 +01:00
447ba942b5 # Fix fpr #507
* fixes incorrect rendering of recording-info for deductions on unrecorded eco accounts
2025-11-30 12:32:05 +01:00
6df47f1615 Merge pull request '504_Geometry_read-only_on_editing' (#505) from 504_Geometry_read-only_on_editing into master
Reviewed-on: #505
2025-11-28 11:45:30 +01:00
e25d549a97 # 497 Impressum link update
* updates impressum link
2025-11-28 11:44:18 +01:00
5e65b8f4dc # Geometry error message fix
* fixes bug where errors on geometry form were not rendered properly
* fixes bug where invalid geometry was written as read-only back into form (could not be corrected by user)
* adds explanatory comments to SimpleGeomForm is_valid() checks
* reorders code snippets for better understanding
* adds correcting logic to _set_geojson_properties() in case of missing properties element
2025-11-28 11:43:17 +01:00
22cddb9902 Merge pull request '# Fix for #500' (#501) from 500_Geometry_conflicts_still_visible into master
Reviewed-on: #501
2025-11-19 13:16:30 +01:00
c986bd0b92 # Fix for #500
* fixes bug where de-facto deleted compensations (because of deleted intervention) would still show up as geometry conflicts on other entries
2025-11-19 13:16:09 +01:00
2c60d86177 Merge pull request '# Update netgis map client' (#498) from netgis_map_client into master
Reviewed-on: #498
2025-11-07 14:11:57 +01:00
b7792ececc # Update netgis map client
* updates netgis map client (bugfix for https://github.com/sebastianpauli/netgis-client/issues/43#issuecomment-3446898016)
2025-11-07 14:11:15 +01:00
210f3fcafa Merge pull request '# HOTFIX' (#495) from update_map_config into master
Reviewed-on: #495
2025-10-23 16:12:45 +02:00
e7d67560f2 # HOTFIX
* fixes bug on netgis map client where importing a geometry would result in an error message
* THIS IS JUST A WORKAROUND AND HAS TO BE REPLACED BY A PROPER FIX FROM THE DEVS ASAP
2025-10-23 16:12:05 +02:00
b5e991fb95 Merge pull request '# Map layer update' (#494) from update_map_config into master
Reviewed-on: #494
2025-10-22 16:02:02 +02:00
d3a555d406 # Map layer update
* updates rp_dop layer from deprecated to newest
2025-10-22 16:00:35 +02:00
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
80 changed files with 3484 additions and 1267 deletions

View File

@@ -24,6 +24,7 @@ DEFAULT_FROM_EMAIL=service@ksp.de
# Proxy # Proxy
PROXY=CHANGE_ME PROXY=CHANGE_ME
MAP_PROXY_HOST_WHITELIST=CHANGE_ME_1,CHANGE_ME_2
GEOPORTAL_RLP_USER=CHANGE_ME GEOPORTAL_RLP_USER=CHANGE_ME
GEOPORTAL_RLP_PASSWORD=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_CODE_VERIFIER=CHANGE_ME
OAUTH_CLIENT_ID=CHANGE_ME OAUTH_CLIENT_ID=CHANGE_ME
OAUTH_CLIENT_SECRET=CHANGE_ME OAUTH_CLIENT_SECRET=CHANGE_ME
PROPAGATION_SECRET=CHANGE_ME
# RabbitMQ # RabbitMQ
## For connections to EGON ## 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: if token_obj.valid_until is not None and token_obj.valid_until < _today:
raise PermissionError("Token validity expired") raise PermissionError("Token validity expired")
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise PermissionError("Credentials invalid") raise PermissionError("Token unknown")
return token_obj.user return token_obj.user
@@ -155,3 +155,25 @@ class OAuthToken(UuidModel):
return user 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

@@ -71,7 +71,7 @@ class APIV1CreateTestCase(BaseAPIV1TestCase):
# Expect this first request to fail, since user has no shared access on the intervention, we want to create # Expect this first request to fail, since user has no shared access on the intervention, we want to create
# a compensation for # a compensation for
response = self._run_create_request(url, post_body) response = self._run_create_request(url, post_body)
self.assertEqual(response.status_code, 500, msg=response.content) self.assertEqual(response.status_code, 400, msg=response.content)
content = json.loads(response.content) content = json.loads(response.content)
self.assertGreater(len(content.get("errors", [])), 0, msg=response.content) self.assertGreater(len(content.get("errors", [])), 0, msg=response.content)

View File

@@ -12,7 +12,7 @@ from django.contrib.gis import geos
from django.urls import reverse from django.urls import reverse
from api.tests.v1.share.test_api_sharing import BaseAPIV1TestCase 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): class APIV1UpdateTestCase(BaseAPIV1TestCase):
@@ -64,7 +64,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"] put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body)) 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_geom, self.intervention.geometry.geom)
self.assertEqual(put_props["title"], self.intervention.title) self.assertEqual(put_props["title"], self.intervention.title)
self.assertNotEqual(modified_on, self.intervention.modified) self.assertNotEqual(modified_on, self.intervention.modified)
@@ -94,7 +94,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"] put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body)) 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_geom, self.compensation.geometry.geom)
self.assertEqual(put_props["title"], self.compensation.title) self.assertEqual(put_props["title"], self.compensation.title)
self.assertNotEqual(modified_on, self.compensation.modified) self.assertNotEqual(modified_on, self.compensation.modified)
@@ -124,7 +124,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"] put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body)) 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_geom, self.eco_account.geometry.geom)
self.assertEqual(put_props["title"], self.eco_account.title) self.assertEqual(put_props["title"], self.eco_account.title)
self.assertNotEqual(modified_on, self.eco_account.modified) self.assertNotEqual(modified_on, self.eco_account.modified)
@@ -156,7 +156,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"] put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body)) 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_geom, self.ema.geometry.geom)
self.assertEqual(put_props["title"], self.ema.title) self.assertEqual(put_props["title"], self.ema.title)
self.assertNotEqual(modified_on, self.ema.modified) 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.core.paginator import Paginator
from django.db.models import Q 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 from konova.utils.message_templates import DATA_UNSHARED
@@ -145,8 +145,8 @@ class AbstractModelAPISerializer:
if isinstance(geojson, dict): if isinstance(geojson, dict):
geojson = json.dumps(geojson) geojson = json.dumps(geojson)
geometry = geos.fromstr(geojson) geometry = geos.fromstr(geojson)
if geometry.srid != DEFAULT_SRID_RLP: geometry = Geometry.cast_to_rlp_srid(geometry)
geometry.transform(DEFAULT_SRID_RLP) geometry = Geometry.cast_to_multipolygon(geometry)
return geometry return geometry
def _get_obj_from_db(self, id, user): def _get_obj_from_db(self, id, user):

View File

@@ -6,7 +6,9 @@ Created on: 21.01.22
""" """
import json import json
from json import JSONDecodeError
from django.core.exceptions import ObjectDoesNotExist
from django.http import JsonResponse, HttpRequest from django.http import JsonResponse, HttpRequest
from api.utils.serializer.v1.compensation import CompensationAPISerializerV1 from api.utils.serializer.v1.compensation import CompensationAPISerializerV1
@@ -66,8 +68,12 @@ class AbstractAPIViewV1(AbstractAPIView):
body = request.body.decode("utf-8") body = request.body.decode("utf-8")
body = json.loads(body) body = json.loads(body)
created_id = self.serializer.create_model_from_json(body, self.user) created_id = self.serializer.create_model_from_json(body, self.user)
except Exception as e: except (JSONDecodeError,
return self._return_error_response(e, 500) AssertionError,
ValueError,
PermissionError,
ObjectDoesNotExist) as e:
return self._return_error_response(e, 400)
return JsonResponse({"id": created_id}) return JsonResponse({"id": created_id})
def put(self, request: HttpRequest, id=None): def put(self, request: HttpRequest, id=None):

View File

@@ -50,14 +50,19 @@ class AbstractAPIView(View):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
try: try:
# Fetch the proper user from the given request header token # 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) 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}") raise PermissionError(f"Invalid token for {ksp_user}")
else: self.user = token_user
self.user = token_user
request.user = self.user request.user = self.user
if not self.user.is_default_user(): if not self.user.is_default_user():
@@ -76,9 +81,7 @@ class AbstractAPIView(View):
Returns: Returns:
""" """
content = [error.__str__()] content = [f"{error.__class__.__name__}: {str(error)}"]
if hasattr(error, "messages"):
content = error.messages
return JsonResponse( return JsonResponse(
{ {
"errors": content "errors": content

View File

@@ -82,8 +82,8 @@ class Command(BaseKonovaCommand):
atom_id = element.find("atomid").text atom_id = element.find("atomid").text
selectable = element.find("selectable").text.lower() selectable = element.find("selectable").text.lower()
selectable = bool_map.get(selectable, False) selectable = bool_map.get(selectable, False)
short_name = element.find("shortname").text short_name = element.find("shortname").text or ""
long_name = element.find("longname").text long_name = element.find("longname").text or ""
is_archived = bool_map.get((element.find("archive").text.lower()), False) is_archived = bool_map.get((element.find("archive").text.lower()), False)
code = KonovaCode.objects.get_or_create( code = KonovaCode.objects.get_or_create(

View File

@@ -53,7 +53,7 @@
</td> </td>
<td class="align-middle"> <td class="align-middle">
{% if deduction.intervention.recorded %} {% if deduction.intervention.recorded %}
<em title="{% trans 'Recorded on' %} {{obj.recorded.timestamp}} {% trans 'by' %} {{obj.recorded.user}}" class='fas fa-bookmark registered-bookmark'></em> <em title="{% trans 'Recorded on' %} {{deduction.intervention.recorded.timestamp}} {% trans 'by' %} {{deduction.intervention.recorded.user}}" class='fas fa-bookmark registered-bookmark'></em>
{% else %} {% else %}
<em title="{% trans 'Not recorded yet' %}" class='far fa-bookmark'></em> <em title="{% trans 'Not recorded yet' %}" class='far fa-bookmark'></em>
{% endif %} {% endif %}

View File

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

View File

@@ -46,7 +46,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
post_data = { post_data = {
"identifier": test_id, "identifier": test_id,
"title": test_title, "title": test_title,
"geom": geom_json, "output": geom_json,
"surface": test_deductable_surface, "surface": test_deductable_surface,
"conservation_office": test_conservation_office.id "conservation_office": test_conservation_office.id
} }
@@ -86,7 +86,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
new_title = self.create_dummy_string() new_title = self.create_dummy_string()
new_identifier = self.create_dummy_string() new_identifier = self.create_dummy_string()
new_comment = 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_conservation_office = self.get_conservation_office_code()
test_deductable_surface = self.eco_account.deductable_surface + 100 test_deductable_surface = self.eco_account.deductable_surface + 100
@@ -103,7 +103,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
"identifier": new_identifier, "identifier": new_identifier,
"title": new_title, "title": new_title,
"comment": new_comment, "comment": new_comment,
"geom": new_geometry.geojson, "output": self.create_geojson(new_geometry),
"surface": test_deductable_surface, "surface": test_deductable_surface,
"conservation_office": test_conservation_office.id "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.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE, DATA_CHECKED_PREVIOUSLY_TEMPLATE, \ 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, \ 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 @login_required
@@ -103,11 +103,19 @@ def new_view(request: HttpRequest, intervention_id: str = None):
) )
) )
messages.success(request, COMPENSATION_ADDED_TEMPLATE.format(comp.identifier)) messages.success(request, COMPENSATION_ADDED_TEMPLATE.format(comp.identifier))
if geom_form.geometry_simplified: if geom_form.has_geometry_simplified():
messages.info( messages.info(
request, request,
GEOMETRY_SIMPLIFIED 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) return redirect("compensation:detail", id=comp.id)
else: else:
messages.error(request, FORM_INVALID, extra_tags="danger",) messages.error(request, FORM_INVALID, extra_tags="danger",)
@@ -179,11 +187,19 @@ def edit_view(request: HttpRequest, id: str):
if intervention_is_checked: if intervention_is_checked:
messages.info(request, CHECK_STATE_RESET) messages.info(request, CHECK_STATE_RESET)
messages.success(request, _("Compensation {} edited").format(comp.identifier)) messages.success(request, _("Compensation {} edited").format(comp.identifier))
if geom_form.geometry_simplified: if geom_form.has_geometry_simplified():
messages.info( messages.info(
request, request,
GEOMETRY_SIMPLIFIED 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) return redirect("compensation:detail", id=comp.id)
else: else:
messages.error(request, FORM_INVALID, extra_tags="danger",) messages.error(request, FORM_INVALID, extra_tags="danger",)

View File

@@ -12,11 +12,12 @@ from django.utils.translation import gettext_lazy as _
from compensation.models import Compensation from compensation.models import Compensation
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.decorators import uuid_required
from konova.forms import SimpleGeomForm from konova.forms import SimpleGeomForm
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.generators import generate_qr_code from konova.utils.generators import generate_qr_code
@uuid_required
def report_view(request: HttpRequest, id: str): def report_view(request: HttpRequest, id: str):
""" Renders the public report view """ Renders the public report view

View File

@@ -23,7 +23,7 @@ from konova.forms import SimpleGeomForm
from konova.settings import ETS_GROUP, DEFAULT_GROUP, ZB_GROUP from konova.settings import ETS_GROUP, DEFAULT_GROUP, ZB_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER 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, \ 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 @login_required
@@ -84,11 +84,19 @@ def new_view(request: HttpRequest):
) )
) )
messages.success(request, _("Eco-Account {} added").format(acc.identifier)) messages.success(request, _("Eco-Account {} added").format(acc.identifier))
if geom_form.geometry_simplified: if geom_form.has_geometry_simplified():
messages.info( messages.info(
request, request,
GEOMETRY_SIMPLIFIED 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) return redirect("compensation:acc:detail", id=acc.id)
else: else:
messages.error(request, FORM_INVALID, extra_tags="danger",) 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 # The data form takes the geom form for processing, as well as the performing user
acc = data_form.save(request.user, geom_form) acc = data_form.save(request.user, geom_form)
messages.success(request, _("Eco-Account {} edited").format(acc.identifier)) messages.success(request, _("Eco-Account {} edited").format(acc.identifier))
if geom_form.geometry_simplified: if geom_form.has_geometry_simplified():
messages.info( messages.info(
request, request,
GEOMETRY_SIMPLIFIED 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) return redirect("compensation:acc:detail", id=acc.id)
else: else:
messages.error(request, FORM_INVALID, extra_tags="danger",) messages.error(request, FORM_INVALID, extra_tags="danger",)

View File

@@ -12,11 +12,13 @@ from django.utils.translation import gettext_lazy as _
from compensation.models import EcoAccount from compensation.models import EcoAccount
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.decorators import uuid_required
from konova.forms import SimpleGeomForm from konova.forms import SimpleGeomForm
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.generators import generate_qr_code from konova.utils.generators import generate_qr_code
@uuid_required
def report_view(request: HttpRequest, id: str): def report_view(request: HttpRequest, id: str):
""" Renders the public report view """ Renders the public report view

View File

@@ -46,7 +46,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
post_data = { post_data = {
"identifier": test_id, "identifier": test_id,
"title": test_title, "title": test_title,
"geom": geom_json, "output": geom_json,
"conservation_office": test_conservation_office.id "conservation_office": test_conservation_office.id
} }
self.client_user.post(new_url, post_data) self.client_user.post(new_url, post_data)
@@ -84,7 +84,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
new_title = self.create_dummy_string() new_title = self.create_dummy_string()
new_identifier = self.create_dummy_string() new_identifier = self.create_dummy_string()
new_comment = 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() test_conservation_office = self.get_conservation_office_code()
check_on_elements = { check_on_elements = {
@@ -99,7 +99,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
"identifier": new_identifier, "identifier": new_identifier,
"title": new_title, "title": new_title,
"comment": new_comment, "comment": new_comment,
"geom": new_geometry.geojson, "output": self.create_geojson(new_geometry),
"conservation_office": test_conservation_office.id "conservation_office": test_conservation_office.id
} }
self.client_user.post(url, post_data) 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 = json.loads(geom_form_data)
geom_form_data = { geom_form_data = {
"geom": json.dumps(geom_form_data) "output": json.dumps(geom_form_data)
} }
geom_form = SimpleGeomForm(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 = json.loads(geom_form_data)
geom_form_data = { geom_form_data = {
"geom": json.dumps(geom_form_data) "output": json.dumps(geom_form_data)
} }
geom_form = SimpleGeomForm(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.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import RECORDED_BLOCKS_EDIT, IDENTIFIER_REPLACED, FORM_INVALID, \ 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 @login_required
@@ -84,11 +84,17 @@ def new_view(request: HttpRequest):
) )
) )
messages.success(request, _("EMA {} added").format(ema.identifier)) messages.success(request, _("EMA {} added").format(ema.identifier))
if geom_form.geometry_simplified: if geom_form.has_geometry_simplified():
messages.info( messages.info(
request, request,
GEOMETRY_SIMPLIFIED 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) return redirect("ema:detail", id=ema.id)
else: else:
@@ -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 # The data form takes the geom form for processing, as well as the performing user
ema = data_form.save(request.user, geom_form) ema = data_form.save(request.user, geom_form)
messages.success(request, _("EMA {} edited").format(ema.identifier)) messages.success(request, _("EMA {} edited").format(ema.identifier))
if geom_form.geometry_simplified: if geom_form.has_geometry_simplified():
messages.info( messages.info(
request, request,
GEOMETRY_SIMPLIFIED 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) return redirect("ema:detail", id=ema.id)
else: else:
messages.error(request, FORM_INVALID, extra_tags="danger",) 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 ema.models import Ema
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.decorators import uuid_required
from konova.forms import SimpleGeomForm from konova.forms import SimpleGeomForm
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.generators import generate_qr_code from konova.utils.generators import generate_qr_code
@uuid_required
def report_view(request:HttpRequest, id: str): def report_view(request:HttpRequest, id: str):
""" Renders the public report view """ Renders the public report view

View File

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

View File

@@ -62,7 +62,7 @@ class NewInterventionFormTestCase(BaseTestCase):
) )
geom_form_data = json.loads(geom_form_data) geom_form_data = json.loads(geom_form_data)
geom_form_data = { geom_form_data = {
"geom": json.dumps(geom_form_data) "output": json.dumps(geom_form_data)
} }
geom_form = SimpleGeomForm(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 = json.loads(geom_form_data)
geom_form_data = { geom_form_data = {
"geom": json.dumps(geom_form_data) "output": json.dumps(geom_form_data)
} }
geom_form = SimpleGeomForm(geom_form_data) geom_form = SimpleGeomForm(geom_form_data)
@@ -124,7 +124,7 @@ class EditInterventionFormTestCase(NewInterventionFormTestCase):
self.assertIsNotNone(obj.responsible.handler) self.assertIsNotNone(obj.responsible.handler)
self.assertEqual(obj.title, data["title"]) self.assertEqual(obj.title, data["title"])
self.assertEqual(obj.comment, data["comment"]) 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.binding_date, today)
self.assertEqual(obj.legal.registration_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.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import DATA_CHECKED_PREVIOUSLY_TEMPLATE, RECORDED_BLOCKS_EDIT, \ 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 @login_required
@@ -88,11 +89,19 @@ def new_view(request: HttpRequest):
) )
) )
messages.success(request, _("Intervention {} added").format(intervention.identifier)) messages.success(request, _("Intervention {} added").format(intervention.identifier))
if geom_form.geometry_simplified: if geom_form.has_geometry_simplified():
messages.info( messages.info(
request, request,
GEOMETRY_SIMPLIFIED 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) return redirect("intervention:detail", id=intervention.id)
else: else:
messages.error(request, FORM_INVALID, extra_tags="danger",) messages.error(request, FORM_INVALID, extra_tags="danger",)
@@ -236,11 +245,19 @@ def edit_view(request: HttpRequest, id: str):
messages.success(request, _("Intervention {} edited").format(intervention.identifier)) messages.success(request, _("Intervention {} edited").format(intervention.identifier))
if intervention_is_checked: if intervention_is_checked:
messages.info(request, CHECK_STATE_RESET) messages.info(request, CHECK_STATE_RESET)
if geom_form.geometry_simplified: if geom_form.has_geometry_simplified():
messages.info( messages.info(
request, request,
GEOMETRY_SIMPLIFIED 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) return redirect("intervention:detail", id=intervention.id)
else: else:
messages.error(request, FORM_INVALID, extra_tags="danger",) 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 bootstrap_modal_forms.mixins import is_ajax
from django.contrib import messages 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.shortcuts import redirect, get_object_or_404, render
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@@ -185,7 +185,7 @@ def uuid_required(function):
try: try:
uuid = UUID(uuid) uuid = UUID(uuid)
except ValueError: except ValueError:
raise Http404( raise BadRequest(
"Invalid UUID" "Invalid UUID"
) )
return function(request, *args, **kwargs) return function(request, *args, **kwargs)

View File

@@ -25,15 +25,17 @@ class SimpleGeomForm(BaseForm):
""" A geometry form for rendering geometry read-only using a widget """ A geometry form for rendering geometry read-only using a widget
""" """
read_only = True read_only: bool = True
geometry_simplified = False _geometry_simplified: bool = False
geom = JSONField( output = JSONField(
label=_("Geometry"), label=_("Geometry"),
help_text=_(""), help_text=_(""),
label_suffix="", label_suffix="",
required=False, required=False,
disabled=False, disabled=False,
) )
_num_geometries_ignored: int = 0
empty = False
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.read_only = kwargs.pop("read_only", True) self.read_only = kwargs.pop("read_only", True)
@@ -48,33 +50,33 @@ class SimpleGeomForm(BaseForm):
raise AttributeError raise AttributeError
geojson = self.instance.geometry.as_feature_collection(srid=DEFAULT_SRID_RLP) geojson = self.instance.geometry.as_feature_collection(srid=DEFAULT_SRID_RLP)
geojson = self._set_geojson_properties(geojson, title=self.instance.identifier or None)
geom = json.dumps(geojson) geom = json.dumps(geojson)
except AttributeError: except AttributeError:
# If no geometry exists for this form, we simply set the value to None and zoom to the maximum level # If no geometry exists for this form, we simply set the value to None and zoom to the maximum level
geom = "" geom = json.dumps({})
self.empty = True self.empty = True
self.initialize_form_field("geom", geom) self.initialize_form_field("output", geom)
def is_valid(self): def is_valid(self):
super().is_valid() super().is_valid()
is_valid = True is_valid = True
# Get geojson from form # Make sure invalid geometry is properly rendered again to the user
geom = self.data["geom"] # Therefore: write submitted data back into form field
if geom is None or len(geom) == 0: # (does not matter whether we know if it is valid or invalid)
# empty geometry is a valid geometry submitted_data = self.data["output"]
self.cleaned_data["geom"] = MultiPolygon(srid=DEFAULT_SRID_RLP).ewkt submitted_data = json.loads(submitted_data)
return is_valid submitted_data = self._set_geojson_properties(submitted_data)
self.initialize_form_field("output", json.dumps(submitted_data))
# Get geojson from form for validity checking
geom = self.data.get("output", json.dumps({}))
geom = json.loads(geom) geom = json.loads(geom)
# Write submitted data back into form field to make sure invalid geometry # Initialize features list with empty MultiPolygon, so that an empty input will result in a
# will be rendered again on failed submit # proper empty MultiPolygon object
self.initialize_form_field("geom", self.data["geom"])
# 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)
features = [] features = []
features_json = geom.get("features", []) features_json = geom.get("features", [])
accepted_ogr_types = [ accepted_ogr_types = [
@@ -83,47 +85,64 @@ class SimpleGeomForm(BaseForm):
"MultiPolygon", "MultiPolygon",
"MultiPolygon25D", "MultiPolygon25D",
] ]
# Check validity for each feature of the geometry
for feature in features_json: for feature in features_json:
feature_geom = feature.get("geometry", feature) feature_geom = feature.get("geometry", feature)
if feature_geom is None: if feature_geom is None:
# Fallback for rare cases where a feature does not contain any geometry # Fallback for rare cases where a feature does not contain any geometry
continue continue
# Try to create a geometry object from the single feature
feature_geom = json.dumps(feature_geom) feature_geom = json.dumps(feature_geom)
g = gdal.OGRGeometry(feature_geom, srs=DEFAULT_SRID_RLP) g = gdal.OGRGeometry(feature_geom, srs=DEFAULT_SRID_RLP)
flatten_geometry = g.coord_dim > 2 geometry_has_unwanted_dimensions = g.coord_dim > 2
if flatten_geometry: if geometry_has_unwanted_dimensions:
g = self.__flatten_geom_to_2D(g) g = self.__flatten_geom_to_2D(g)
if g.geom_type not in accepted_ogr_types: geometry_type_is_accepted = g.geom_type not in accepted_ogr_types
self.add_error("geom", _("Only surfaces allowed. Points or lines must be buffered.")) if geometry_type_is_accepted:
self.add_error("output", _("Only surfaces allowed. Points or lines must be buffered."))
is_valid &= False is_valid &= False
return is_valid 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) # Whatever this geometry object is -> try to create a Polygon from it
is_valid &= polygon.valid # The resulting polygon object automatically detects whether a valid polygon has been created or not
if not polygon.valid: g = Polygon.from_ewkt(g.ewkt)
self.add_error("geom", polygon.valid_reason) is_valid &= g.valid
if not g.valid:
self.add_error("output", g.valid_reason)
return is_valid return is_valid
features.append(polygon) # If the resulting polygon is just a single polygon, we add it to the list of properly casted features
if isinstance(g, Polygon):
features.append(g)
elif isinstance(g, MultiPolygon):
# The resulting polygon could be of type MultiPolygon (due to multiple surfaces)
# If so, we extract all polygons from the MultiPolygon and extend the casted features list
features.extend(list(g))
# Unionize all geometry features into one new MultiPolygon # Unionize all polygon features into one new MultiPolygon
form_geom = MultiPolygon(srid=DEFAULT_SRID_RLP) if features:
for feature in features: form_geom = MultiPolygon(*features, srid=DEFAULT_SRID_RLP).unary_union
form_geom = form_geom.union(feature) else:
# If no features have been processed, this indicates an empty geometry - so we store an empty geometry
form_geom = MultiPolygon(srid=DEFAULT_SRID_RLP)
# Make sure to convert into a MultiPolygon. Relevant if a single Polygon is provided. # Make sure to convert into a MultiPolygon. Relevant if a single Polygon is provided.
if form_geom.geom_type != "MultiPolygon": form_geom = Geometry.cast_to_multipolygon(form_geom)
form_geom = MultiPolygon(form_geom, srid=DEFAULT_SRID_RLP)
# Write unioned Multipolygon into cleaned data # Write unionized Multipolygon back into cleaned data
if self.cleaned_data is None: if self.cleaned_data is None:
self.cleaned_data = {} self.cleaned_data = {}
self.cleaned_data["geom"] = form_geom.ewkt self.cleaned_data["output"] = form_geom.ewkt
return is_valid return is_valid
@@ -133,7 +152,7 @@ class SimpleGeomForm(BaseForm):
Returns: Returns:
""" """
geom = self.cleaned_data.get("geom") geom = self.cleaned_data.get("output")
g = gdal.OGRGeometry(geom, srs=DEFAULT_SRID_RLP) g = gdal.OGRGeometry(geom, srs=DEFAULT_SRID_RLP)
num_vertices = g.num_coords num_vertices = g.num_coords
@@ -146,15 +165,6 @@ class SimpleGeomForm(BaseForm):
""" """
is_area_valid = geom.area > 1 # > 1m² (SRID:25832) 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 return is_area_valid
def __simplify_geometry(self, geom, max_vert: int): def __simplify_geometry(self, geom, max_vert: int):
@@ -192,14 +202,14 @@ class SimpleGeomForm(BaseForm):
if self.instance is None or self.instance.geometry is None: if self.instance is None or self.instance.geometry is None:
raise LookupError raise LookupError
geometry = self.instance.geometry 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.modified = action
geometry.save() geometry.save()
except LookupError: except LookupError:
# No geometry or linked instance holding a geometry exist --> create a new one! # No geometry or linked instance holding a geometry exist --> create a new one!
geometry = Geometry.objects.create( 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, created=action,
) )
@@ -207,13 +217,29 @@ class SimpleGeomForm(BaseForm):
if not is_vertices_num_valid: if not is_vertices_num_valid:
geometry.geom = self.__simplify_geometry(geometry.geom, max_vert=GEOM_MAX_VERTICES) geometry.geom = self.__simplify_geometry(geometry.geom, max_vert=GEOM_MAX_VERTICES)
geometry.save() geometry.save()
self.geometry_simplified = True self._geometry_simplified = True
# Start parcel update and geometry conflict checking procedure in a background process # Start parcel update and geometry conflict checking procedure in a background process
celery_update_parcels.delay(geometry.id) celery_update_parcels.delay(geometry.id)
celery_check_for_geometry_conflicts.delay(geometry.id) celery_check_for_geometry_conflicts.delay(geometry.id)
return geometry 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): def __flatten_geom_to_2D(self, geom):
""" """
Enforces a given OGRGeometry from higher dimensions into 2D Enforces a given OGRGeometry from higher dimensions into 2D
@@ -223,3 +249,22 @@ class SimpleGeomForm(BaseForm):
g_wkt = wkt_w.write(geom.geos).decode("utf-8") g_wkt = wkt_w.write(geom.geos).decode("utf-8")
geom = gdal.OGRGeometry(g_wkt) geom = gdal.OGRGeometry(g_wkt)
return geom 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:
if not feature.get("properties", None):
feature["properties"] = {}
feature["properties"]["editable"] = not self.read_only
if title:
feature["properties"]["title"] = title
return geojson

View File

@@ -8,10 +8,9 @@ Created on: 04.01.22
import datetime import datetime
from django.contrib.gis.db.models.functions import Area from django.contrib.gis.db.models.functions import Area
from django.utils.timezone import now
from konova.management.commands.setup import BaseKonovaCommand from konova.management.commands.setup import BaseKonovaCommand
from konova.models import Geometry, Parcel, District from konova.models import Geometry, ParcelIntersection
class Command(BaseKonovaCommand): class Command(BaseKonovaCommand):
@@ -35,32 +34,55 @@ class Command(BaseKonovaCommand):
def recalculate_parcels(self, options: dict): def recalculate_parcels(self, options: dict):
force_all = options.get("force_all", False) force_all = options.get("force_all", False)
if force_all: geometry_objects = Geometry.objects.filter(
geometry_objects = Geometry.objects.all() geom__isempty=False,
else: ).exclude(
_today = now().date() geom=None
_date_threshold = _today - datetime.timedelta(days=1) )
geometry_objects = Geometry.objects.filter(
parcel_update_start__date__lte=_date_threshold, if not force_all:
parcel_update_end__isnull=True # 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 ===") self._write_warning("=== Update parcels and districts ===")
# Order geometries by size to process smaller once at first # Order geometries by size to process smaller once at first
geometries = geometry_objects.exclude( geometries = geometry_objects.annotate(
geom=None area=Area("geom")
).annotate(area=Area("geom")).order_by( ).order_by(
'area' 'area'
) )
self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...") self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...")
i = 0 i = 0
num_geoms = geometries.count() num_geoms = geometries.count()
geoms_with_errors = {}
for geometry in geometries: for geometry in geometries:
self._write_warning(f"--- {datetime.datetime.now()} Process {geometry.id} now ...") self._write_warning(f"--- {datetime.datetime.now()} Process {geometry.id} now ...")
geometry.update_parcels() try:
self._write_warning(f"--- Processed {geometry.get_underlying_parcels().count()} underlying parcels") 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 i += 1
self._write_warning(f"--- {i}/{num_geoms} processed") self._write_warning(f"--- {i}/{num_geoms} processed")
self._write_success("Updating parcels done!") 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() 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

@@ -8,9 +8,11 @@ Created on: 15.11.21
import json import json
from django.contrib.gis.db.models import MultiPolygonField 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.db import models, transaction
from django.db.models import Q
from django.utils import timezone from django.utils import timezone
from django.contrib.gis.geos import MultiPolygon
from konova.models import BaseResource, UuidModel from konova.models import BaseResource, UuidModel
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
@@ -108,17 +110,26 @@ class Geometry(BaseResource):
objs (list): The list of objects objs (list): The list of objects
""" """
objs = [] objs = []
sets = [
# Some related data sets can be processed rather easily
regular_sets = [
self.intervention_set, self.intervention_set,
self.compensation_set,
self.ema_set, self.ema_set,
self.ecoaccount_set, self.ecoaccount_set,
] ]
for _set in sets: for _set in regular_sets:
set_objs = _set.filter( set_objs = _set.filter(
deleted=None deleted=None
) )
objs += set_objs objs += set_objs
# ... but we need a special treatment for compensations, since they can be deleted directly OR inherit their
# de-facto-deleted status from their deleted parent intervention
comp_objs = self.compensation_set.filter(
Q(deleted=None) & Q(intervention__deleted=None)
)
objs += comp_objs
return objs return objs
def get_data_object(self): def get_data_object(self):
@@ -223,6 +234,17 @@ class Geometry(BaseResource):
) )
parcel_obj.updated_on = _now parcel_obj.updated_on = _now
parcels_to_update.append(parcel_obj) 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: except ObjectDoesNotExist:
# If not existing, create object but do not commit, yet # If not existing, create object but do not commit, yet
parcel_obj = Parcel( parcel_obj = Parcel(
@@ -331,6 +353,7 @@ class Geometry(BaseResource):
{ {
"type": "Feature", "type": "Feature",
"geometry": json.loads(p.json), "geometry": json.loads(p.json),
"properties": {},
} }
for p in polygons for p in polygons
] ]
@@ -366,13 +389,45 @@ class Geometry(BaseResource):
diff = geom_envelope - self.geom diff = geom_envelope - self.geom
if diff.area == 0: if diff.area == 0:
ratio = 1 complexity_factor = 1
else: else:
ratio = self.geom.area / diff.area complexity_factor = self.geom.area / diff.area
complexity_factor = 1 - ratio
return complexity_factor 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):
try:
output_geom = MultiPolygon(input_geom, srid=DEFAULT_SRID_RLP)
except TypeError as e:
raise AssertionError(f"Only (Multi)Polygon allowed! Could not convert {input_geom.geom_type} to MultiPolygon")
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): class GeometryConflict(UuidModel):
""" """

View File

@@ -677,12 +677,12 @@ class GeoReferencedMixin(models.Model):
return request return request
instance_objs = [] instance_objs = []
conflicts = self.geometry.conflicts_geometries.all() conflicts = self.geometry.conflicts_geometries.iterator()
for conflict in conflicts: for conflict in conflicts:
instance_objs += conflict.affected_geometry.get_data_objects() instance_objs += conflict.affected_geometry.get_data_objects()
conflicts = self.geometry.conflicted_by_geometries.all() conflicts = self.geometry.conflicted_by_geometries.iterator()
for conflict in conflicts: for conflict in conflicts:
instance_objs += conflict.conflicting_geometry.get_data_objects() instance_objs += conflict.conflicting_geometry.get_data_objects()

View File

@@ -5,7 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 16.12.21 Created on: 16.12.21
""" """
from django.db import models from django.db import models, transaction
from konova.models import UuidModel from konova.models import UuidModel
@@ -158,6 +158,46 @@ class Parcel(UuidModel):
def __str__(self): def __str__(self):
return f"{self.parcel_group} | {self.flr} | {self.flrstck_zhlr} | {self.flrstck_nnr}" 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): class ParcelIntersection(UuidModel):
""" """

View File

@@ -278,4 +278,18 @@ Similar to bootstraps 'shadow-lg'
} }
.alert{ .alert{
margin-bottom: 0 !important; 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

@@ -11,4 +11,4 @@ BASE_TITLE = "KSP - Kompensationsverzeichnis Service Portal"
BASE_FRONTEND_TITLE = "Kompensationsverzeichnis Service Portal" BASE_FRONTEND_TITLE = "Kompensationsverzeichnis Service Portal"
TAB_TITLE_IDENTIFIER = "tab_title" TAB_TITLE_IDENTIFIER = "tab_title"
HELP_LINK = "https://dienste.naturschutz.rlp.de/doku/doku.php?id=ksp2:start" HELP_LINK = "https://dienste.naturschutz.rlp.de/doku/doku.php?id=ksp2:start"
IMPRESSUM_LINK = "https://naturschutz.rlp.de/index.php?q=impressum" IMPRESSUM_LINK = "https://naturschutz.rlp.de/ueber-uns/impressum"

View File

@@ -66,7 +66,6 @@ INSTALLED_APPS = [
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.gis', 'django.contrib.gis',
'django.contrib.humanize', 'django.contrib.humanize',
'simple_sso.sso_server',
'django_tables2', 'django_tables2',
'bootstrap_modal_forms', 'bootstrap_modal_forms',
'fontawesome_5', 'fontawesome_5',
@@ -189,7 +188,6 @@ STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_DIRS = [ STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'konova/static'), 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'), # 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/) # 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 Created on: 31.01.22
""" """
from konova.sub_settings.django_settings import env
# MAPS # MAPS
DEFAULT_LAT = 50.00 DEFAULT_LAT = 50.00
@@ -28,3 +29,6 @@ LANIS_ZOOM_LUT = {
1000: 30, 1000: 30,
500: 31, 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_ID = env("OAUTH_CLIENT_ID")
OAUTH_CLIENT_SECRET = env("OAUTH_CLIENT_SECRET") OAUTH_CLIENT_SECRET = env("OAUTH_CLIENT_SECRET")
PROPAGATION_SECRET = env("PROPAGATION_SECRET")

View File

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

View File

@@ -469,7 +469,7 @@ class BaseTestCase(TestCase):
eco_account.save() eco_account.save()
return eco_account 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 """ Assert for geometries to be equal
Transforms the geometries to matching srids before checking 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 # transformation from one coordinate system into the other, which is valid
geom1.transform(geom2.srid) geom1.transform(geom2.srid)
geom2.transform(geom1.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): class BaseViewTestCase(BaseTestCase):

View File

@@ -42,5 +42,6 @@ urlpatterns = [
path('client/proxy/wfs', ClientProxyParcelWFS.as_view(), name="client-proxy-wfs"), 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" handler404 = "konova.views.error.get_404_view"
handler500 = "konova.views.error.get_500_view" handler500 = "konova.views.error.get_500_view"

View File

@@ -5,6 +5,9 @@ Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 11.12.23 Created on: 11.12.23
""" """
import json
from json import JSONDecodeError
from django.views.debug import ExceptionReporter from django.views.debug import ExceptionReporter
@@ -30,7 +33,7 @@ class KonovaExceptionReporter(ExceptionReporter):
""" """
whitelist = [ whitelist = [
"is_email", "is_email",
"unicdoe_hint", "unicode_hint",
"frames", "frames",
"request", "request",
"user_str", "user_str",
@@ -39,6 +42,8 @@ class KonovaExceptionReporter(ExceptionReporter):
"raising_view_name", "raising_view_name",
"exception_type", "exception_type",
"exception_value", "exception_value",
"filtered_GET_items",
"filtered_POST_items",
] ]
clean_data = dict() clean_data = dict()
for entry in whitelist: for entry in whitelist:
@@ -56,7 +61,28 @@ class KonovaExceptionReporter(ExceptionReporter):
""" """
tb_data = super().get_traceback_data() tb_data = super().get_traceback_data()
return_data = tb_data
if self.is_email: if self.is_email:
tb_data = self._filter_traceback_data(tb_data) filtered_data = dict()
filtered_data.update(self._filter_traceback_data(tb_data))
filtered_data.update(self._filter_POST_body(tb_data))
return_data = filtered_data
return return_data
return tb_data def _filter_POST_body(self, tb_data: dict):
""" Filters POST body from traceback data
"""
post_data = tb_data.get("request", None)
if post_data:
post_data = post_data.body
try:
post_data = json.loads(post_data)
except JSONDecodeError:
pass
post_data = {
"filtered_POST_items": [
("body", post_data),
]
}
return post_data

View File

@@ -83,6 +83,7 @@ EDITED_GENERAL_DATA = _("Edited general data")
# Geometry # Geometry
GEOMETRY_CONFLICT_WITH_TEMPLATE = _("Geometry conflict detected with {}") 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) 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
INTERVENTION_HAS_REVOCATIONS_TEMPLATE = _("This intervention has {} revocations") 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_ON_TEMPLATE = _("Checked on {} by {}")
DATA_CHECKED_PREVIOUSLY_TEMPLATE = _("Data has changed since last check on {} by {}") DATA_CHECKED_PREVIOUSLY_TEMPLATE = _("Data has changed since last check on {} by {}")
DATA_IS_UNCHECKED = _("Current data not checked yet") 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 import requests
from konova.sub_settings import schneider_settings from konova.sub_settings import schneider_settings
from konova.sub_settings.lanis_settings import DEFAULT_SRID
from konova.sub_settings.proxy_settings import PROXIES from konova.sub_settings.proxy_settings import PROXIES
@@ -34,6 +35,7 @@ class ParcelFetcher:
if geom.area < buffer_threshold: if geom.area < buffer_threshold:
# Fallback for malicious geometries which are way too small and would disappear on negative buffering # Fallback for malicious geometries which are way too small and would disappear on negative buffering
geom = geometry.geom geom = geometry.geom
geom.transform(DEFAULT_SRID)
self.geojson = geom.ewkt self.geojson = geom.ewkt
self.results = [] self.results = []

View File

@@ -25,6 +25,20 @@ def get_404_view(request: HttpRequest, exception=None):
return render(request, "404.html", context, status=404) 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): def get_500_view(request: HttpRequest):
""" Returns a 404 handling view """ Returns a 404 handling view

View File

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

View File

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

View File

@@ -9,15 +9,16 @@ import json
from json import JSONDecodeError from json import JSONDecodeError
import requests import requests
import urllib3.util
from django.contrib.auth.decorators import login_required 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.decorators import method_decorator
from django.utils.http import urlencode from django.utils.http import urlencode
from django.views import View from django.views import View
from django.utils.translation import gettext_lazy as _
from requests.auth import HTTPDigestAuth 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 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): def dispatch(self, request, *args, **kwargs):
return super().dispatch(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): def perform_url_call(self, url, headers={}, auth=None):
""" Generic proxied call """ Generic proxied call
@@ -51,7 +59,10 @@ class BaseClientProxyView(View):
) )
content = response.content content = response.content
if isinstance(content, bytes): 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 return content, response.status_code
@@ -59,25 +70,13 @@ class ClientProxyParcelSearch(BaseClientProxyView):
def get(self, request: HttpRequest): def get(self, request: HttpRequest):
url = request.META.get("QUERY_STRING") 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: is_url_allowed = self._check_with_whitelist(url)
return JsonResponse({ if not is_url_allowed:
"status_code": response_code, raise PermissionError(f"Proxied url '{url}' is not allowed!")
"content": body,
}) content, response_code = self.perform_url_call(url)
return JsonResponse(body) return HttpResponse(content)
class ClientProxyParcelWFS(BaseClientProxyView): class ClientProxyParcelWFS(BaseClientProxyView):

View File

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

Binary file not shown.

View File

@@ -38,13 +38,14 @@
#: konova/forms/modals/remove_form.py:23 #: konova/forms/modals/remove_form.py:23
#: konova/forms/modals/resubmission_form.py:22 #: konova/forms/modals/resubmission_form.py:22
#: konova/forms/modals/resubmission_form.py:38 konova/forms/remove_form.py:25 #: 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 #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-19 10:32+0200\n" "POT-Creation-Date: 2025-10-15 09:11+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -373,7 +374,6 @@ msgid "Identifier"
msgstr "Kennung" msgstr "Kennung"
#: compensation/forms/compensation.py:33 intervention/forms/intervention.py:33 #: compensation/forms/compensation.py:33 intervention/forms/intervention.py:33
#: user/forms/user.py:77
msgid "Generated automatically - not editable" msgid "Generated automatically - not editable"
msgstr "Automatisch generiert - nicht bearbeitbar" msgstr "Automatisch generiert - nicht bearbeitbar"
@@ -1298,13 +1298,13 @@ msgid "Compensation {} edited"
msgstr "Kompensation {} bearbeitet" msgstr "Kompensation {} bearbeitet"
#: compensation/views/compensation/compensation.py:196 #: compensation/views/compensation/compensation.py:196
#: compensation/views/eco_account/eco_account.py:173 ema/views/ema.py:232 #: compensation/views/eco_account/eco_account.py:173 ema/views/ema.py:238
#: intervention/views/intervention.py:253 #: intervention/views/intervention.py:253
msgid "Edit {}" msgid "Edit {}"
msgstr "Bearbeite {}" msgstr "Bearbeite {}"
#: compensation/views/compensation/report.py:34 #: compensation/views/compensation/report.py:35
#: compensation/views/eco_account/report.py:34 ema/views/report.py:34 #: compensation/views/eco_account/report.py:36 ema/views/report.py:35
#: intervention/views/report.py:35 #: intervention/views/report.py:35
msgid "Report {}" msgid "Report {}"
msgstr "Bericht {}" msgstr "Bericht {}"
@@ -1325,7 +1325,7 @@ msgstr "Ökokonto {} bearbeitet"
msgid "Eco-account removed" msgid "Eco-account removed"
msgstr "Ökokonto entfernt" msgstr "Ökokonto entfernt"
#: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:102 #: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:108
msgid "New EMA" msgid "New EMA"
msgstr "Neue EMA hinzufügen" msgstr "Neue EMA hinzufügen"
@@ -1361,11 +1361,11 @@ msgstr "EMAs - Übersicht"
msgid "EMA {} added" msgid "EMA {} added"
msgstr "EMA {} hinzugefügt" msgstr "EMA {} hinzugefügt"
#: ema/views/ema.py:217 #: ema/views/ema.py:223
msgid "EMA {} edited" msgid "EMA {} edited"
msgstr "EMA {} bearbeitet" msgstr "EMA {} bearbeitet"
#: ema/views/ema.py:256 #: ema/views/ema.py:262
msgid "EMA removed" msgid "EMA removed"
msgstr "EMA entfernt" msgstr "EMA entfernt"
@@ -1795,8 +1795,7 @@ msgstr "Bearbeitender Nutzer"
msgid "" msgid ""
"Search for entries where this person has been participated according to log " "Search for entries where this person has been participated according to log "
"history" "history"
msgstr "" msgstr "Sucht nach Einträgen, an denen diese Person gearbeitet hat"
"Sucht nach Einträgen, an denen diese Person gearbeitet hat"
#: konova/forms/base_form.py:23 templates/form/collapsable/form.html:62 #: konova/forms/base_form.py:23 templates/form/collapsable/form.html:62
msgid "Save" msgid "Save"
@@ -1816,10 +1815,6 @@ msgid "Only surfaces allowed. Points or lines must be buffered."
msgstr "" msgstr ""
"Nur Flächen erlaubt. Punkte oder Linien müssen zu Flächen gepuffert werden." "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 #: konova/forms/modals/document_form.py:37
msgid "When has this file been created? Important for photos." msgid "When has this file been created? Important for photos."
msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?"
@@ -1858,6 +1853,7 @@ msgstr ""
"Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen."
#: konova/forms/modals/remove_form.py:22 konova/forms/remove_form.py:24 #: konova/forms/modals/remove_form.py:22 konova/forms/remove_form.py:24
#: user/forms/modals/api_token.py:16
msgid "Confirm" msgid "Confirm"
msgstr "Bestätige" msgstr "Bestätige"
@@ -1928,11 +1924,11 @@ msgstr "Kontrolle am"
msgid "Other" msgid "Other"
msgstr "Sonstige" msgstr "Sonstige"
#: konova/sub_settings/django_settings.py:157 #: konova/sub_settings/django_settings.py:156
msgid "German" msgid "German"
msgstr "" msgstr ""
#: konova/sub_settings/django_settings.py:158 #: konova/sub_settings/django_settings.py:157
msgid "English" msgid "English"
msgstr "" msgstr ""
@@ -2266,34 +2262,35 @@ msgstr ""
"Die Geometrie enthielt mehr als {} Eckpunkte. Sie musste vereinfacht werden " "Die Geometrie enthielt mehr als {} Eckpunkte. Sie musste vereinfacht werden "
"um die Obergrenze von {} erlaubten Eckpunkten einzuhalten." "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" msgid "This intervention has {} revocations"
msgstr "Dem Eingriff liegen {} Widersprüche vor" msgstr "Dem Eingriff liegen {} Widersprüche vor"
#: konova/utils/message_templates.py:91 #: konova/utils/message_templates.py:92
msgid "Checked on {} by {}" msgid "Checked on {} by {}"
msgstr "Am {} von {} geprüft worden" 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 {}" msgid "Data has changed since last check on {} by {}"
msgstr "" msgstr ""
"Daten wurden nach der letzten Prüfung geändert. Letzte Prüfung am {} durch {}" "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" msgid "Current data not checked yet"
msgstr "Momentane Daten noch nicht geprüft" msgstr "Momentane Daten noch nicht geprüft"
#: konova/utils/messenger.py:70 #: konova/utils/message_templates.py:97
msgid "{} checked" msgid "New token generated. Administrators need to validate."
msgstr "{} geprüft" msgstr "Neuer Token generiert. Administratoren sind informiert."
#: 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/quality.py:32 #: konova/utils/quality.py:32
msgid "missing" msgid "missing"
@@ -2321,14 +2318,6 @@ msgstr "Home"
msgid "Log" msgid "Log"
msgstr "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 #: konova/views/record.py:30
msgid "{} unrecorded" msgid "{} unrecorded"
msgstr "{} entzeichnet" msgstr "{} entzeichnet"
@@ -2385,6 +2374,20 @@ msgstr "Alle"
msgid "News" msgid "News"
msgstr "Neuigkeiten" 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 #: templates/404.html:7
msgid "Not found" msgid "Not found"
msgstr "Nicht gefunden" msgstr "Nicht gefunden"
@@ -2397,11 +2400,11 @@ msgstr "Die angeforderten Daten existieren nicht."
msgid "Make sure the URL is valid (no whitespaces, ...)." msgid "Make sure the URL is valid (no whitespaces, ...)."
msgstr "Stellen Sie sicher, dass die URL gültig ist (keine Leerzeichen, ...)." msgstr "Stellen Sie sicher, dass die URL gültig ist (keine Leerzeichen, ...)."
#: templates/500.html:7 #: templates/500.html:12
msgid "Server Error" msgid "Server Error"
msgstr "" msgstr ""
#: templates/500.html:10 #: templates/500.html:17
msgid "Something happened. Admins have been informed. We are working on it!" msgid "Something happened. Admins have been informed. We are working on it!"
msgstr "" msgstr ""
"Irgendetwas ist passiert. Die Administratoren wurden informiert. Wir " "Irgendetwas ist passiert. Die Administratoren wurden informiert. Wir "
@@ -2831,10 +2834,8 @@ msgid "Reports"
msgstr "Berichte" msgstr "Berichte"
#: templates/navbars/navbar.html:57 #: templates/navbars/navbar.html:57
#, fuzzy
#| msgid "Admins"
msgid "Admin" msgid "Admin"
msgstr "Administratoren" msgstr ""
#: templates/navbars/navbar.html:59 user/templates/user/index.html:31 #: templates/navbars/navbar.html:59 user/templates/user/index.html:31
msgid "Settings" msgid "Settings"
@@ -2873,6 +2874,22 @@ msgstr ""
"Falls die Geometrie nicht leer ist, werden die Flurstücke aktuell berechnet. " "Falls die Geometrie nicht leer ist, werden die Flurstücke aktuell berechnet. "
"Bitte laden Sie diese Seite in ein paar Augenblicken erneut..." "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/modals/team.py:20 user/forms/modals/team.py:24
#: user/forms/team.py:17 user/forms/team.py:22 #: user/forms/team.py:17 user/forms/team.py:22
msgid "Team name" msgid "Team name"
@@ -2895,11 +2912,11 @@ msgstr ""
"Mehrfachauswahl möglich - Sie können nur Nutzer wählen, die noch nicht " "Mehrfachauswahl möglich - Sie können nur Nutzer wählen, die noch nicht "
"Mitglieder dieses Teams sind. Geben Sie den ganzen Nutzernamen an." "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" msgid "Create new team"
msgstr "Neues Team anlegen" 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 "" msgid ""
"You will become the administrator for this group by default. You do not need " "You will become the administrator for this group by default. You do not need "
"to add yourself to the list of members." "to add yourself to the list of members."
@@ -2928,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." 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/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" msgid "Edit team"
msgstr "Team bearbeiten" 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 "" msgid ""
"ATTENTION!\n" "ATTENTION!\n"
"\n" "\n"
@@ -2949,7 +2966,7 @@ msgstr ""
"Sind Sie sicher, dass Sie dieses Team löschen möchten?" "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/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" msgid "Leave team"
msgstr "Team verlassen" msgstr "Team verlassen"
@@ -2981,22 +2998,10 @@ msgstr "Benachrichtigungen"
msgid "Select the situations when you want to receive a notification" msgid "Select the situations when you want to receive a notification"
msgstr "Wann wollen Sie per E-Mail benachrichtigt werden?" 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" msgid "Edit notifications"
msgstr "Benachrichtigungen bearbeiten" 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 #: user/models/user_action.py:23
msgid "Unrecorded" msgid "Unrecorded"
msgstr "Entzeichnet" msgstr "Entzeichnet"
@@ -3051,7 +3056,7 @@ msgid "Manage teams"
msgstr "" msgstr ""
#: user/templates/user/index.html:53 user/templates/user/team/index.html:19 #: user/templates/user/index.html:53 user/templates/user/team/index.html:19
#: user/views/views.py:171 #: user/views/views.py:135
msgid "Teams" msgid "Teams"
msgstr "" msgstr ""
@@ -3087,270 +3092,58 @@ msgstr "API Einstellungen"
msgid "Current token" msgid "Current token"
msgstr "Aktueller 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" msgid "Authenticated by admins"
msgstr "Von Admin freigeschaltet" 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" msgid "Token has been verified and can be used"
msgstr "Token wurde freigeschaltet und kann verwendet werden" 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" msgid "Token waiting for verification"
msgstr "Token noch nicht freigeschaltet" msgstr "Token noch nicht freigeschaltet"
#: user/templates/user/token.html:24 #: user/templates/user/token.html:33
msgid "Valid until" msgid "Valid until"
msgstr "Läuft ab am" msgstr "Läuft ab am"
#: user/views/views.py:35 #: user/views/api_token.py:34
msgid "User settings"
msgstr "Einstellungen"
#: user/views/views.py:61
msgid "Notifications edited"
msgstr "Benachrichtigungen bearbeitet"
#: user/views/views.py:73
msgid "User notifications"
msgstr "Benachrichtigungen"
#: user/views/views.py:96
msgid "New token generated. Administrators need to validate."
msgstr "Neuer Token generiert. Administratoren sind informiert."
#: user/views/views.py:107
msgid "User API token" msgid "User API token"
msgstr "API Nutzer Token" msgstr "API Nutzer Token"
#: user/views/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" msgid "New team added"
msgstr "Neues Team hinzugefügt" msgstr "Neues Team hinzugefügt"
#: user/views/views.py:198 #: user/views/views.py:162
msgid "Team edited" msgid "Team edited"
msgstr "Team bearbeitet" msgstr "Team bearbeitet"
#: user/views/views.py:213 #: user/views/views.py:177
msgid "Team removed" msgid "Team removed"
msgstr "Team gelöscht" msgstr "Team gelöscht"
#: user/views/views.py:228 #: user/views/views.py:192
msgid "You are not a member of this team" msgid "You are not a member of this team"
msgstr "Sie sind kein Mitglied dieses Teams" msgstr "Sie sind kein Mitglied dieses Teams"
#: user/views/views.py:235 #: user/views/views.py:199
msgid "Left Team" msgid "Left Team"
msgstr "Team verlassen" 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 asgiref==3.8.1
async-timeout==4.0.3 async-timeout==5.0.1
beautifulsoup4==4.13.0b2 beautifulsoup4==4.13.0b2
billiard==4.2.0 billiard==4.2.1
cached-property==1.5.2 cached-property==2.0.1
celery==5.4.0 celery==5.4.0
certifi==2024.7.4 certifi==2024.12.14
cffi==1.17.0 cffi==1.17.1
chardet==5.2.0 chardet==5.2.0
charset-normalizer==3.3.2 charset-normalizer==3.4.0
click==8.1.7 click==8.1.8
click-didyoumean==0.3.1 click-didyoumean==0.3.1
click-plugins==1.1.1 click-plugins==1.1.1
click-repl==0.3.0 click-repl==0.3.0
coverage==7.5.4 coverage==7.6.9
cryptography==43.0.0 cryptography==44.0.0
Deprecated==1.2.14 Deprecated==1.2.15
Django==5.0.8 Django==5.1.4
django-autocomplete-light==3.11.0 django-autocomplete-light==3.11.0
django-bootstrap-modal-forms==3.0.4 django-bootstrap-modal-forms==3.0.5
django-bootstrap4==24.3 django-bootstrap4==24.4
django-environ==0.11.2 django-environ==0.11.2
django-filter==24.3 django-filter==24.3
django-fontawesome-5==1.0.18 django-fontawesome-5==1.0.18
django-oauth-toolkit==2.4.0 django-oauth-toolkit==3.0.1
django-simple-sso==1.2.0 django-tables2==2.7.1
django-tables2==2.7.0 et_xmlfile==2.0.0
et-xmlfile==1.1.0 gunicorn==23.0.0
gunicorn==22.0.0 idna==3.10
idna==3.7 importlib_metadata==8.5.0
importlib_metadata==8.2.0
itsdangerous==0.24
jwcrypto==1.5.6 jwcrypto==1.5.6
kombu==5.4.0rc1 kombu==5.4.0rc1
oauthlib==3.2.2 oauthlib==3.2.2
openpyxl==3.2.0b1 openpyxl==3.2.0b1
packaging==24.1 packaging==24.2
pika==1.3.2 pika==1.3.2
pillow==10.4.0 pillow==11.0.0
prompt_toolkit==3.0.47 prompt_toolkit==3.0.48
psycopg==3.2.1 psycopg==3.2.3
psycopg-binary==3.2.1 psycopg-binary==3.2.3
pycparser==2.22 pycparser==2.22
pyparsing==3.1.2 pyparsing==3.2.0
pypng==0.20220715.0 pypng==0.20220715.0
pyproj==3.6.1 pyproj==3.7.0
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
pytz==2024.1 pytz==2024.2
PyYAML==6.0.2 PyYAML==6.0.2
qrcode==7.3.1 qrcode==7.3.1
redis==5.1.0b6 redis==5.1.0b6
requests<2.32.0 # kombu 5.4.0rc1 depends on requests<2.32.0 requests==2.32.3
six==1.16.0 six==1.16.0
soupsieve==2.5 soupsieve==2.5
sqlparse==0.5.1 sqlparse==0.5.1
typing_extensions==4.12.2 typing_extensions==4.12.2
tzdata==2024.1 tzdata==2024.2
urllib3==2.2.2 urllib3==2.3.0
vine==5.1.0 vine==5.1.0
wcwidth==0.2.13 wcwidth==0.2.13
webservices==0.7 webservices==0.7
wrapt==1.16.0 wrapt==1.16.0
xmltodict==0.13.0 xmltodict==0.14.2
zipp==3.19.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' %} {% extends 'public_base.html' %}
{% load i18n fontawesome_5 %} {% load i18n fontawesome_5 static %}
{% block body %} {% block body %}
<div class="jumbotron"> <div class="jumbotron">
<h1 class="display-4">{% fa5_icon 'fire-extinguisher' %} {% fa5_icon 'fire-alt' %} 500</h1> <div class="row">
<h1 class="display-4">{% trans 'Server Error' %}</h1> <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> <hr>
<p class="lead"> <p class="lead">
{% trans 'Something happened. Admins have been informed. We are working on it!' %} {% trans 'Something happened. Admins have been informed. We are working on it!' %}

View File

@@ -1,170 +1,305 @@
{ {
"layers": "modules":
[ {
{ "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" }, "menu": true,
{ "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" }, "layertree": true,
{ "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" }, "map": true,
"controls": true,
{ "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" }, "attribution": true,
{ "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" }, "info": true,
{ "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" }, "searchplace": true,
"searchparcel": true,
{ "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" }, "toolbox": true,
"import": true,
{ "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" }, "export": true
},
{ "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" }, "menu":
{
{ "folder": 10, "type": "WMS", "title": "Naturschutzgebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=naturschutzgebiet&", "name": "naturschutzgebiet" }, "header": "",
{ "folder": 10, "type": "WMS", "title": "Naturparkzonen", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=naturparkzonen&", "name": "naturparkzonen" }, "items":
{ "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" }, { "id": "searchplace", "title": "<i class='fas fa-search'></i><span>Suche</span>" },
{ "folder": 10, "type": "WMS", "title": "FFH Gebiete", "url": "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/mod_ogc/wms_getmap.php?mapfile=ffh&", "name": "ffh" }, { "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>" },
{ "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" }, { "id": "layertree", "title": "<i class='fas fa-layer-group'></i><span>Inhalte</span>" }
{ "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 }
],
"projections": "projections":
[ [
[ "EPSG:25832", "+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs" ] [ "EPSG:25832", "+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs" ]
], ],
"map": "map":
{ {
"projection": "EPSG:25832", "projection": "EPSG:25832",
"center": [ 385000, 5543000 ], "center_lonlat": [ 7.0, 50.0 ],
"minZoom": 5,
"maxZoom": 22,
"zoom": 9, "zoom": 9,
"attribution": "LANIS RLP", "min_zoom": 5,
"scalebar": true "max_zoom": 24,
}, "scalebar": true,
"move_tolerance": 5
"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}"
}, },
"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/rp_dop20.fcgi?", "name": "rp_dop20", "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}", "open": false,
"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", "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": "districts_service":
{ {
"type": "WFS", "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", "name": "vermkv:gemarkungen_rlp",
"order": 10, "format": "application/json; subtype=geojson",
"minZoom": 11, "min_zoom": 12
"maxZoom": 17
}, },
"fields_service": "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", "name": "vermkv:fluren_rlp",
"filter_property": "gmkgnr" "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": "import":
{ {
"geopackageLibURL": "/static/libs/geopackage/4.2.3/" "title": "Ebene hinzufügen",
"preview": true,
"editable": 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": "export":
{ {
"title": "Exportieren",
"logo": "/static/assets/logo.png", "logo": "/static/assets/logo.png",
"gifWebWorker": "/static/libs/gifjs/0.2.0/gif.worker.js", "gif_worker": "/static/libs/gifjs/0.2.0/gif.worker.js",
"defaultFilename": "Export", "default_filename": "Export",
"defaultMargin": 10 "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": "tools":
{ {
"editable": true,
"interactive_render": true,
"buffer": "buffer":
{ {
"defaultRadius": 5, "default_radius": 5,
"defaultSegments": 2 "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": "styles":
{ {
"editLayer": "draw":
{ {
"fill": "rgba( 255, 0, 0, 0.2 )", "fill": "rgba( 135, 29, 51, 0.5 )",
"stroke": "#ff0000", "stroke": "#871d33",
"strokeWidth": 3, "width": 3,
"pointRadius": 6 "radius": 6,
"viewport_labels": true
},
"non_edit":
{
"fill": "rgba( 135, 29, 51, 0.5 )",
"stroke": "#871d33",
"width": 3,
"radius": 6,
"viewport_labels": true
}, },
"select": "select":
{ {
"fill": "rgba( 0, 127, 255, 0.5 )", "fill": "rgba( 0, 127, 255, 0.5 )",
"stroke": "#007fff", "stroke": "#007fff",
"strokeWidth": 3, "width": 3,
"pointRadius": 6 "radius": 6
}, },
"sketch": "sketch":
{ {
"fill": "rgba( 0, 127, 255, 0.2 )", "fill": "rgba( 29, 135, 113, 0.5 )",
"stroke": "#0080ff", "stroke": "#1D8771",
"strokeWidth": 3, "width": 3,
"pointRadius": 6 "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": "modify":
{ {
"fill": "rgba( 0, 127, 255, 0.5 )", "fill": "rgba( 29, 135, 113, 0.5 )",
"stroke": "#0080ff", "stroke": "#1D8771",
"strokeWidth": 3, "width": 3,
"pointRadius": 6 "radius": 6
}, },
"parcel": "parcel":
{ {
"fill": "rgba( 127, 255, 255, 0.5 )", "fill": "rgba( 127, 0, 0, 0.2 )",
"stroke": "#7fffff", "stroke": "rgba( 127, 0, 0, 1.0 )",
"strokeWidth": 3 "width": 2.5
}, },
"import": "import":
{ {
"fill": "rgba( 0, 127, 255, 0.2 )", "fill": "rgba( 0, 127, 255, 0.2 )",
@@ -172,4 +307,4 @@
"width": 1.5 "width": 1.5
} }
} }
} }

File diff suppressed because one or more lines are too long

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

@@ -0,0 +1,550 @@
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)};
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.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,editable:!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.autocomplete=a["import"].geoportal_autocomplete,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),a=document.createElement("button"),a.innerHTML="Suchen",a.className="netgis-color-a netgis-hover-c netgis-round netgis-shadow",a.setAttribute("type","button"),a.addEventListener("click",this.onGeoportalSearchButtonClick.bind(this)),this.geoportalSearch.label.appendChild(a),
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=this.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,editable:this.config["import"]&&!0===this.config["import"].editable,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.onGeoportalSearchButtonClick=function(a){this.geoportalSearch.onInputTimeout()};
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&&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&&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&&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",draggable:!1,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>");n=k.removable;h=!0===l?this.tree.addRadioButton(g,h,m,k.active,this.createDefaultDetails(k,!0,n)):this.tree.addCheckbox(g,h,m,k.active,!1,this.createDefaultDetails(k,
!0,n));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;!0!==a.editable&&(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 q=m.length-43-1,p=0;p<q;p++)n[5+p]=m[43+p];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,q,p){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");p()};l.onload=function(){if(200===l.status){g.clear();var a=g.getFormat().readFeatures(l.responseText);g.addFeatures(a);q(a)}else console.error("WFS request status",l.status),p()};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 q=n.getContext("2d");q.webkitImageSmoothingEnabled=!1;q.mozImageSmoothingEnabled=!1;q.imageSmoothingEnabled=!1;Array.prototype.forEach.call(document.querySelectorAll(".ol-layer canvas"),function(a){if(0<a.width){var b=a.parentNode.style.opacity;q.globalAlpha=""===b?1:Number(b);b=a.style.transform.match(/^matrix\(([^\(]*)\)$/)[1].split(",").map(Number);CanvasRenderingContext2D.prototype.setTransform.apply(q,b);q.drawImage(a,0,0)}});q.drawImage(l,0,0);q.fillStyle="#fff";q.fillRect(0,n.height-
30,140,30);q.fillStyle="#000";q.font="4mm sans-serif";q.fillText(netgis.util.getTimeStamp(),10,n.height-10);var p=document.createElement("a");switch(a){case "pdf":e=e?e:0;var r=297-e-e,v=210-e-e,t=n.width/n.height;if(!d){var w=r;r=v;v=w}if(n.height>n.width){var u=v;w=u*t;w>r&&(w=r,u=w/t)}else w=r,u=w/t,u>v&&(u=v,w=u*t);t=new jsPDF(d?"l":"p");var x=e;x+=(r-w)/2;r=e;r+=(v-u)/2;t.addImage(n.toDataURL("image/png,1.0",1),"PNG",x,r,w,u);t.setFillColor(255,255,255);t.rect(x,r+u-11,80,11,"F");t.setFontSize(8);
t.text("Datum: "+netgis.util.getTimeStamp(),x+2,r+u-2-4);t.text("Quelle: "+window.location.href,x+2,r+u-2);n=t.output("bloburl",{filename:k.default_filename+".pdf"});window.open(n,"_blank");break;case "jpeg":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),k.default_filename+".jpg"):(p.setAttribute("download",k.default_filename+".jpg"),p.setAttribute("href",n.toDataURL("image/jpeg",1)),p.click());break;case "png":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),
k.default_filename+".png"):(p.setAttribute("download",k.default_filename+".png"),p.setAttribute("href",n.toDataURL("image/png",1)),p.click());break;case "gif":p.setAttribute("download",k.default_filename+".gif"),v=new GIF({workerScript:k.gif_worker,quality:1}),v.addFrame(n),v.on("finished",function(a){p.setAttribute("href",window.URL.createObjectURL(a));p.click()}),v.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++)if(d=h[c],g&&(e=this.selectedFeatures.indexOf(d.feature),-1<e?this.selectedFeatures.splice(e,1):this.selectedFeatures.push(d.feature)),e=!1,this.mode===netgis.Modes.VIEW&&(e=!0),this.mode===netgis.Modes.DELETE_FEATURES&&(e=!0),this.mode===netgis.Modes.BUFFER_FEATURES_DYNAMIC&&(e=!0),this.mode===netgis.Modes.CUT_FEATURES&&(e=!0),this.mode===netgis.Modes.SEARCH_PARCEL&&(e=!0),e)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){if(this.mode!==netgis.Modes.SEARCH_PARCEL||"searchparcel_districts"===b.get("id")||"searchparcel_fields"===b.get("id")||"searchparcel_parcels"===b.get("id")){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.editable?(a=this.createLayerGeoJSON(a.data),a=a.getSource(),this.editLayer.getSource().addFeatures(a.getFeatures())):(a=this.addLayer(a.id,a),a=a.getSource());a instanceof ol.source.Vector&&0<a.getFeatures().length&&this.view.fit(a.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;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.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.autocomplete=!0;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>";a.className="netgis-no-background";
c.appendChild(a);this.button=a;a=document.createElement("button");a.setAttribute("type","button");a.className="netgis-hide netgis-no-background";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:if(this.autocomplete)a=this.results.getElementsByTagName("button"),0<a.length&&a[0].click();else this.onInputTimeout();break;case 27:this.clearAll();break;default:if(this.autocomplete)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();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){for(var b=this.top.getElementsByTagName("td"),c=b[a],d=c.getAttribute("data-id"),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}}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;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.getElementsByTagName("input");for(var c=1;c<b.length;c++){var d=b[c];d.checked!==a&&d.click()}this.updateFolderChecks()};
netgis.Tree.prototype.onItemChange=function(a){a=a.currentTarget;var b=a.checked,c=a.getAttribute("data-id");if("radio"===a.getAttribute("type"))for(var d=a.parentNode.parentNode.parentNode.parentNode.getElementsByTagName("input"),e=0;e<d.length;e++){var f=d[e].getAttribute("data-id");f&&f!==c&&netgis.util.invoke(a,netgis.Events.TREE_ITEM_CHANGE,{id:f,checked:!1})}netgis.util.invoke(a,netgis.Events.TREE_ITEM_CHANGE,{id:c,checked:b});this.updateFolderChecks()};
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,
q=null;if(b)for(var p=0;p<b.length;p++)if(b[p].layerId.toString()===n){q=b[p];break}m=this.parseServiceLayer(n,f,h.id,m,q);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.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.build="20251027";

View File

@@ -1,15 +1,13 @@
{% load static %} {% load static %}
<!-- Library Styles --> <!-- 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/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 --> <!-- 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--> <!-- 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/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/jsts/1.6.1/jsts.min.js' %}"></script>
<script type="text/javascript" src="{% static 'libs/shapefilejs/4.0.2/shp.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> <script type="text/javascript" src="{% static 'libs/geopackage/4.2.3/geopackage.min.js' %}"></script>
<!-- Client Scripts --> <!-- 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"
<main id="container" {% if geom_form.read_only %}data-editable="false"{% else %}data-editable="true"{% endif %} style="position: relative; width: 100%; height: 100%;"> {% if geom_form.read_only %}data-editable="false"{% else %}data-editable="true"{% endif %}
style="position: relative; width: 100%; height: 100%;">
</main> </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"> <script type="text/javascript">

View File

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

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,336 +0,0 @@
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.polyfill("Array.prototype.fill",function(a){return a?a:function(a,c,d){var b=this.length||0;0>c&&(c=Math.max(0,b+c));if(null==d||d>b)d=b;d=Number(d);0>d&&(d=Math.max(0,b+d));for(c=Number(c||0);c<d;c++)this[c]=a;return this}},"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.isFinite",function(a){return a?a:function(a){return"number"!==typeof a?!1:!isNaN(a)&&Infinity!==a&&-Infinity!==a}},"es6","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(){this.layers=this.client=null;this.items=[]};
netgis.Attribution.prototype.load=function(){this.root=document.createElement("section");this.root.className="netgis-attribution netgis-text-primary";netgis.util.isDefined(this.client.config.map)&&netgis.util.isDefined(this.client.config.map.attribution)&&this.items.push(this.client.config.map.attribution);this.update();this.client.root.appendChild(this.root);this.client.on(netgis.Events.CONTEXT_UPDATE,this.onContextUpdate.bind(this));this.client.on(netgis.Events.LAYER_SHOW,this.onLayerShow.bind(this));
this.client.on(netgis.Events.LAYER_HIDE,this.onLayerHide.bind(this));this.client.on(netgis.Events.EDIT_FEATURES_CHANGE,this.onEditFeaturesChange.bind(this))};netgis.Attribution.prototype.update=function(){var a="&copy; "+this.items.join(", ");this.appendix&&(a+=", "+this.appendix);this.root.innerHTML=a};
netgis.Attribution.prototype.onContextUpdate=function(a){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.onEditFeaturesChange=function(a){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.area&&0<a.area?"<b>Zeichnungsfl\u00e4che: "+netgis.util.formatArea(a.area,!0)+"</b>":null;this.update()};netgis=netgis||{};
netgis.Client=function(a,b){this.build="20220826";this.debug=!1;netgis.util.isString(a)&&(a=document.getElementById(a));this.container=a;this.editable=!0;this.root=null;this.modules=[];this.callbacks={};this.config=this.createDefaultConfig();this.create();if(netgis.util.isDefined(b))if(netgis.util.isString(b)){var c=this;netgis.util.request(b,function(a){a=JSON.parse(a);netgis.util.merge(c.config,a);c.applyConfig(c.config)})}else netgis.util.merge(this.config,b),this.applyConfig(this.config);else this.applyConfig(this.config);
this.hideLoader()};netgis.Client.Layers=Object.freeze({PARCEL_DISTRICTS:"parcel-districts",PARCEL_FIELDS:"parcel-fields",PARCEL_FEATURES:"parcel-features",EDIT_LAYER:"edit-layer",PREVIEW_LAYER:"preview-layer"});netgis.Client.prototype.applyConfig=function(a){this.createModules();this.load();this.invoke(netgis.Events.CONTEXT_UPDATE,a);this.initModules(a);this.initConfig(a);this.initOutput(a);this.initEvents();this.importLayers={};this.setMode(netgis.Modes.VIEW)};
netgis.Client.prototype.initElements=function(){};
netgis.Client.prototype.initModules=function(a){this.map=new netgis.MapOpenLayers(a);this.map.attach(this.root);this.controls=new netgis.Controls;this.controls.attach(this.root);this.layerPanel=new netgis.Panel("Inhalte");this.layerPanel.attach(this.root);this.layerTree=new netgis.Tree;this.layerTree.container.style.position="absolute";this.layerTree.container.style.width="100%";this.layerTree.container.style.top="12mm";this.layerTree.container.style.bottom="6mm";this.layerTree.container.style.overflow=
"auto";this.layerTree.attach(this.layerPanel.container);this.toolboxPanel=new netgis.Panel("Werkzeuge");this.toolboxPanel.attach(this.root);this.toolbox=new netgis.Toolbox(a);this.toolbox.attach(this.toolboxPanel.container);this.searchPlace=new netgis.SearchPlace(a);this.searchPlace.attach(this.root);this.parcelPanel=new netgis.Panel("Flurst\u00fccks-Suche");this.parcelPanel.container.style.minWidth="92mm";this.parcelPanel.attach(this.root);this.searchParcel=new netgis.SearchParcel(a,this);this.searchParcel.attach(this.parcelPanel.container);
this.importModal=new netgis.Modal("Ebene hinzuf\u00fcgen");this.importModal.container.classList.add("netgis-import");this.importModal.attach(this.root);a=document.createElement("div");a.className="netgis-content netgis-form netgis-noselect";this.importModal.content.appendChild(a);var b=document.createElement("label");b.innerHTML="Dateiformat:";a.appendChild(b);var c=document.createElement("select");c.innerHTML="<option value='geojson'>GeoJSON</option><option value='gml'>GML</option><option value='gpkg'>GeoPackage</option><option value='shp'>Shapefile (Zip)</option><option value='spatialite'>Spatialite</option>";
b.addEventListener("change",this.onImportFileTypeChange.bind(this));b.appendChild(c);this.importFileSelect=c;b=document.createElement("div");b.innerHTML="<h3>Unterst\u00fctzte Koordinatensysteme:</h3><ul><li>World Geodetic System 1984 (EPSG:4326)</li><li>ETRS89 / UTM zone 32N (EPSG:25832)</li></ul>";a.appendChild(b);b=document.createElement("label");b.innerHTML="Datei ausw\u00e4hlen/ablegen:";a.appendChild(b);c=document.createElement("input");c.className="netgis-color-d";c.setAttribute("type","file");
c.setAttribute("accept",".geojson,.json");b.appendChild(c);this.importFileInput=c;b=document.createElement("button");b.setAttribute("type","button");b.className="netgis-button netgis-center netgis-color-a netgis-hover-c netgis-shadow";b.innerHTML="<i class='netgis-icon fas fa-check'></i><span>Hinzuf\u00fcgen</span>";b.addEventListener("click",this.onImportFileClick.bind(this));a.appendChild(b);this.importServiceModal=new netgis.Modal("Dienst hinzuf\u00fcgen");this.importServiceModal.container.classList.add("netgis-import");
this.importServiceModal.attach(this.root);b=document.createElement("div");b.className="netgis-content netgis-form netgis-noselect";this.importServiceModal.content.appendChild(b);a=document.createElement("label");a.innerHTML="WMS/WFS URL:";b.appendChild(a);c=document.createElement("input");c.setAttribute("type","text");a.appendChild(c);this.importServiceInput=c;a=document.createElement("button");a.setAttribute("type","button");a.className="netgis-button netgis-center netgis-color-a netgis-hover-c netgis-shadow";
a.innerHTML="<i class='netgis-icon fas fa-cloud-download-alt'></i><span>Dienst laden</span>";a.style.marginBottom="6mm";a.addEventListener("click",this.onImportServiceClick.bind(this));b.appendChild(a);a=document.createElement("div");a.className="netgis-hide";b.appendChild(a);this.importServiceDetails=a;b=document.createElement("label");b.innerHTML="Bezeichnung:";a.appendChild(b);c=document.createElement("input");c.setAttribute("type","text");b.appendChild(c);this.importServiceNameInput=c;b=document.createElement("label");
b.innerHTML="Kartenebene:";a.appendChild(b);c=document.createElement("select");b.appendChild(c);this.importServiceLayerSelect=c;b=document.createElement("label");b.innerHTML="Format:";a.appendChild(b);c=document.createElement("select");b.appendChild(c);this.importServiceFormatSelect=c;b=document.createElement("button");b.setAttribute("type","button");b.className="netgis-button netgis-center netgis-color-a netgis-hover-c netgis-shadow";b.innerHTML="<i class='netgis-icon fas fa-check'></i><span>Hinzuf\u00fcgen</span>";
b.addEventListener("click",this.onImportServiceAccept.bind(this));a.appendChild(b);this.exportModal=new netgis.Modal("Exportieren");this.exportModal.container.classList.add("netgis-export");this.exportModal.attach(this.root);a=document.createElement("div");a.className="netgis-form netgis-noselect";a.style.position="absolute";a.style.width="100%";a.style.top="12mm";a.style.bottom="0mm";a.style.overflow="auto";a.style.padding="12mm";this.exportModal.content.appendChild(a);b=document.createElement("label");
b.innerHTML="Format:";a.appendChild(b);c=document.createElement("select");c.innerHTML="<option value='pdf'>PDF</option><option value='jpeg'>JPEG</option><option value='png'>PNG</option><option value='gif'>GIF</option>";c.addEventListener("change",this.onExportFormatChange.bind(this));b.appendChild(c);this.exportFormatSelect=c;b=document.createElement("label");b.innerHTML="Breite (Pixel):";a.appendChild(b);c=document.createElement("input");c.setAttribute("type","number");c.setAttribute("min",0);b.appendChild(c);
this.exportWidthInput=c;b=document.createElement("label");b.innerHTML="H\u00f6he (Pixel):";a.appendChild(b);c=document.createElement("input");c.setAttribute("type","number");c.setAttribute("min",0);b.appendChild(c);this.exportHeightInput=c;b=document.createElement("label");b.innerHTML="Seitenr\u00e4nder (Millimeter):";a.appendChild(b);c=document.createElement("input");c.setAttribute("type","number");c.setAttribute("min",0);c.value=10;b.appendChild(c);this.exportPaddingInput=c;b=document.createElement("label");
b.innerHTML="Querformat:";a.appendChild(b);c=document.createElement("input");c.setAttribute("type","checkbox");b.appendChild(c);this.exportLandscapeInput=c;b=document.createElement("button");b.setAttribute("type","button");b.className="netgis-button netgis-center netgis-color-a netgis-hover-c netgis-shadow";b.innerHTML="<i class='netgis-icon fas fa-check'></i><span>Exportieren</span>";b.addEventListener("click",this.onExportButtonClick.bind(this));a.appendChild(b)};
netgis.Client.prototype.initConfig=function(a){var b=[],c=a.folders;if(c){for(var d=0;d<c.length;d++){var e=1E3+d,f=this.layerTree.addFolder(null,e,c[d].title);b.push(f)}for(d=0;d<c.length;d++)e=c[d].parent,-1<e&&this.layerTree.setFolderParent(b[d],b[e])}if(c=a.layers)for(d=0;d<c.length;d++){var g=c[d];f=-1<g.folder?b[g.folder]:null;e=g.id;e||(e=1E3+d,g.id=e);this.layerTree.addCheckbox(f,e,g.title);g.active&&(this.map.addLayer(e,this.map.createLayer(g)),this.layerTree.setItemChecked(e,!0))}this.importFolder=
this.layerTree.addFolder(null,"import","Importierte Ebenen",!0);this.importFolder.classList.add("netgis-hide");this.editFolder=this.layerTree.addFolder(null,"edit-folder","Zeichnung",!0);this.editFolder.classList.add("netgis-hide");this.layerTree.addCheckbox(this.editFolder,"edit-layer","Zeichnung");this.layerTree.setItemChecked("edit-layer",!0);this.importButton=this.layerTree.addButton(null,"<i class='netgis-icon fas fa-plus' style='font-size: 1em;'></i><span>Dienst hinzuf\u00fcgen...</span>",this.onLayerTreeImportClick.bind(this));
this.attribution.onContextUpdate(a)};
netgis.Client.prototype.initOutput=function(a){if(a.output&&a.output.id){if((a=document.getElementById(a.output.id))&&a.value&&0<a.value.length){var b=JSON.parse(a.value);this.map.addEditFeaturesGeoJSON(b,!1);var c=this;window.setTimeout(function(){c.map.map.updateSize();c.map.zoomGeoJSON(b)},50);this.editFolder.classList.remove("netgis-hide")}this.output=a}this.output||(this.output=document.createElement("input"),this.output.setAttribute("type","hidden"),this.output.className="netgis-storage",this.root.appendChild(this.output))};
netgis.Client.prototype.initEvents=function(){this.container.addEventListener(netgis.Events.SET_MODE,this.onSetMode.bind(this));this.container.addEventListener(netgis.Events.PANEL_TOGGLE,this.onPanelToggle.bind(this));this.container.addEventListener(netgis.Events.PANEL_RESIZE,this.onPanelResize.bind(this));this.container.addEventListener(netgis.Events.LAYERS_TOGGLE,this.onLayersToggle.bind(this));this.container.addEventListener(netgis.SearchPlace.Events.TOGGLE,this.onSearchPlaceToggle.bind(this));
this.container.addEventListener(netgis.SearchParcel.Events.TOGGLE,this.onSearchParcelToggle.bind(this));this.container.addEventListener(netgis.Events.CONTROLS_ZOOM,this.onControlsZoom.bind(this));this.container.addEventListener(netgis.Events.CONTROLS_ZOOM_ALL,this.onControlsZoomAll.bind(this));this.container.addEventListener(netgis.Events.TOOLBOX_TOGGLE,this.onToolboxToggle.bind(this));this.parcelPanel.container.addEventListener(netgis.Events.PANEL_TOGGLE,this.onParcelsPanelToggle.bind(this));this.container.addEventListener(netgis.Events.PARCELS_RESET,
this.onParcelsReset.bind(this));this.container.addEventListener(netgis.Events.PARCELS_FIELDS_RESPONSE,this.onParcelsFieldsResponse.bind(this));this.container.addEventListener(netgis.Events.PARCELS_RESPONSE,this.onParcelsResponse.bind(this));this.container.addEventListener(netgis.Events.PARCELS_ITEM_ENTER,this.onParcelsItemEnter.bind(this));this.container.addEventListener(netgis.Events.PARCELS_ITEM_LEAVE,this.onParcelsItemLeave.bind(this));this.container.addEventListener(netgis.Events.PARCELS_ITEM_CLICK,
this.onParcelsItemClick.bind(this));this.container.addEventListener(netgis.Events.PARCELS_ITEM_IMPORT_CLICK,this.onParcelsImportClick.bind(this));this.container.addEventListener(netgis.Events.MAP_FEATURE_ENTER,this.onMapFeatureEnter.bind(this));this.container.addEventListener(netgis.Events.MAP_FEATURE_CLICK,this.onMapFeatureClick.bind(this));this.container.addEventListener(netgis.Events.MAP_FEATURE_LEAVE,this.onMapFeatureLeave.bind(this));this.container.addEventListener(netgis.Events.LAYER_CREATED,
this.onLayerCreated.bind(this));this.layerTree.container.addEventListener(netgis.Tree.Events.ITEM_CHANGE,this.onLayerTreeItemChange.bind(this));this.searchPlace.container.addEventListener(netgis.SearchPlace.Events.SELECT,this.onSearchPlaceSelect.bind(this));this.container.addEventListener(netgis.Events.SNAP_TOGGLE,this.onSnapToggle.bind(this));this.container.addEventListener(netgis.Events.TRACING_TOGGLE,this.onTracingToggle.bind(this));this.container.addEventListener(netgis.Events.BUFFER_TOGGLE,this.onBufferToggle.bind(this));
this.container.addEventListener(netgis.Events.DRAW_BUFFER_RADIUS_CHANGE,this.onBufferRadiusChange.bind(this));this.container.addEventListener(netgis.Events.DRAW_BUFFER_SEGMENTS_CHANGE,this.onBufferSegmentsChange.bind(this));this.container.addEventListener(netgis.Events.BUFFER_CHANGE,this.onBufferFeatureChange.bind(this));this.container.addEventListener(netgis.Events.BUFFER_ACCEPT,this.onBufferFeatureAccept.bind(this));this.container.addEventListener(netgis.Events.IMPORT_SHAPEFILE_SHOW,this.onImportShapefileShow.bind(this));
this.container.addEventListener(netgis.Events.IMPORT_GEOJSON_SHOW,this.onImportGeoJSONShow.bind(this));this.container.addEventListener(netgis.Events.IMPORT_GML_SHOW,this.onImportGMLShow.bind(this));this.container.addEventListener(netgis.Events.IMPORT_SPATIALITE_SHOW,this.onImportSpatialiteShow.bind(this));this.container.addEventListener(netgis.Events.IMPORT_GEOPACKAGE_SHOW,this.onImportGeopackageShow.bind(this));this.container.addEventListener(netgis.Events.EXPORT_PDF_SHOW,this.onExportPDFShow.bind(this));
this.container.addEventListener(netgis.Events.EXPORT_PNG_SHOW,this.onExportPNGShow.bind(this));this.container.addEventListener(netgis.Events.EXPORT_JPEG_SHOW,this.onExportJPEGShow.bind(this));this.container.addEventListener(netgis.Events.EXPORT_GIF_SHOW,this.onExportGIFShow.bind(this));this.container.addEventListener(netgis.Events.EXPORT_PDF,this.onExportPDF.bind(this));this.container.addEventListener(netgis.Events.EXPORT_PNG,this.onExportPNG.bind(this));this.container.addEventListener(netgis.Events.EXPORT_JPEG,
this.onExportJPEG.bind(this));this.container.addEventListener(netgis.Events.EXPORT_GIF,this.onExportGIF.bind(this));this.container.addEventListener(netgis.Events.EDIT_FEATURES_CHANGE,this.onEditFeaturesChange.bind(this));this.container.addEventListener(netgis.Events.IMPORT_SHOW,this.onImportShow.bind(this));this.container.addEventListener(netgis.Events.EXPORT_SHOW,this.onExportShow.bind(this))};
netgis.Client.prototype.createDefaultConfig=function(){return{map:{projection:"EPSG:3857",center:[1113194,6621293],minZoom:0,maxZoom:20,zoom:6,attribution:"NetGIS"},projections:[],layers:[{folder:0,type:netgis.LayerTypes.OSM,title:"Open Street Map",attribution:"OSM Contributors",active:!0}],folders:[{title:"Hintergrund",parent:-1}],styles:{editLayer:{fill:"rgba( 255, 0, 0, 0.5 )",stroke:"#ff0000",strokeWidth:3,pointRadius:6},select:{fill:"rgba( 0, 127, 255, 0.5 )",stroke:"#007fff",strokeWidth:3,pointRadius:6},
sketch:{fill:"rgba( 0, 127, 0, 0.5 )",stroke:"#007f00",strokeWidth:3,pointRadius:6},modify:{fill:"rgba( 0, 127, 0, 0.5 )",stroke:"#007f00",strokeWidth:3,pointRadius:6},parcel:{fill:"rgba( 127, 255, 255, 0.5 )",stroke:"#7fffff",strokeWidth:3}}}};
netgis.Client.prototype.create=function(){this.root=document.createElement("section");this.root.className="netgis-client";this.loader=document.createElement("div");this.loader.className="netgis-loader netgis-dialog netgis-text-primary";this.loader.innerHTML="<i class='fas fa-spinner'></i>";this.root.appendChild(this.loader);this.container.appendChild(this.root)};
netgis.Client.prototype.createModules=function(){this.editable=!0;this.container.hasAttribute("contenteditable")&&"false"===this.container.getAttribute("contenteditable")&&(this.editable=!1);this.container.hasAttribute("data-editable")&&(this.editable="true"===this.container.getAttribute("data-editable")?!0:!1);this.add(this.attribution=new netgis.Attribution);this.add(new netgis.Toolbar);this.add(new netgis.Menu)};
netgis.Client.prototype.load=function(){for(var a=0;a<this.modules.length;a++)this.modules[a].load();this.invoke(netgis.Events.SET_MODE,netgis.Modes.VIEW);this.on(netgis.Events.EXPORT_BEGIN,this.onMapExportBegin.bind(this));this.on(netgis.Events.EXPORT_END,this.onMapExportEnd.bind(this));this.on(netgis.Events.EDIT_FEATURES_CHANGE,this.onEditFeaturesChange.bind(this))};netgis.Client.prototype.add=function(a){a.client=this;this.modules.push(a)};
netgis.Client.prototype.on=function(a,b){netgis.util.isDefined(this.callbacks[a])||(this.callbacks[a]=[]);this.callbacks[a].push(b)};netgis.Client.prototype.off=function(a,b){if(netgis.util.isDefined(this.callbacks[a]))if(netgis.util.isDefined(b)){for(var c=0;c<this.callbacks[a].length;c++)if(this.callbacks[a][c]===b){this.callbacks[a].splice(c,1);break}1>this.callbacks[a].length&&delete this.callbacks[a]}else delete this.callbacks[a]};
netgis.Client.prototype.invoke=function(a,b){this.debug&&console.info("EVENT:",a,b);if(netgis.util.isDefined(this.callbacks[a]))for(var c=0;c<this.callbacks[a].length;c++)this.callbacks[a][c](b)};netgis.Client.prototype.showLoader=function(){this.loader.classList.remove("netgis-hide")};netgis.Client.prototype.hideLoader=function(){this.loader.classList.add("netgis-hide")};netgis.Client.prototype.onHtmlResponse=function(a){this.root=netgis.util.create(a);this.container.appendChild(this.root)};
netgis.Client.prototype.onEditFeaturesChange=function(a){var b=JSON.stringify(a.detail);this.output.value=b;this.attribution.onEditFeaturesChange(a.detail)};netgis.Client.prototype.onMapExportBegin=function(a){this.showLoader()};netgis.Client.prototype.onMapExportEnd=function(a){this.hideLoader()};netgis.Client.prototype.setMode=function(a){this.map.setMode(a);this.toolbox.setMode(a)};
netgis.Client.prototype.onPanelToggle=function(a){a=a.detail;a.visible?this.map.setPadding(0,0,0,a.panel.width()):(a=!1,this.layerPanel.visible()&&(a=!0),this.toolboxPanel.visible()&&(a=!0),this.parcelPanel.visible()&&(a=!0),a||this.map.setPadding(0,0,0,0))};netgis.Client.prototype.onPanelResize=function(a){this.map.setPadding(0,0,0,a.detail.width)};netgis.Client.prototype.onLayerCreated=function(a){a.detail.id===this.map.editLayerID&&this.editFolder.classList.remove("netgis-hide")};
netgis.Client.prototype.onLayersToggle=function(a){this.layerPanel.toggle();this.layerPanel.visible()&&(this.toolboxPanel.hide(),this.parcelPanel.hide())};
netgis.Client.prototype.onLayerTreeItemChange=function(a){var b=a.detail.id;a=a.detail.checked;switch(b){default:for(var c=this.config.layers,d=!1,e=null,f=0;f<c.length;f++){var g=c[f],h=g.id;if(h===b){e=this.map.createLayer(g);d=!0;break}}if(!d)for(h in this.importLayers)if(h===b){e=this.importLayers[b];d=!0;break}d&&(a?(this.map.addLayer(b,e),this.attribution.onLayerShow({id:b})):(this.map.removeLayer(b),this.attribution.onLayerHide({id:b})));break;case "edit-layer":a?this.map.addLayer(netgis.Client.Layers.EDIT_LAYER,
this.map.editLayer):this.map.removeLayer(netgis.Client.Layers.EDIT_LAYER)}};netgis.Client.prototype.onToolboxToggle=function(a){this.toolboxPanel.toggle();this.toolboxPanel.visible()&&(this.layerPanel.hide(),this.parcelPanel.hide())};netgis.Client.prototype.onSearchPlaceToggle=function(a){this.searchPlace.toggle()};netgis.Client.prototype.onSearchPlaceSelect=function(a){a=a.detail;this.map.zoomExtent(a.minx,a.miny,a.maxx,a.maxy)};
netgis.Client.prototype.onSearchParcelToggle=function(a){this.parcelPanel.toggle();this.parcelPanel.visible()&&(this.layerPanel.hide(),this.toolboxPanel.hide())};netgis.Client.prototype.onControlsZoom=function(a){this.map.zoom(a.detail)};netgis.Client.prototype.onControlsZoomAll=function(a){this.map.zoomAll()};netgis.Client.prototype.onParcelsPanelToggle=function(a){this.searchParcel.reset()};
netgis.Client.prototype.onParcelsReset=function(a){this.map.removeLayer(netgis.Client.Layers.PARCEL_DISTRICTS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FIELDS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FEATURES);if(this.parcelPanel.visible()){this.parcelsAdded=[];var b=this.config.searchParcel.districts_service;a=this.map.createLayer(b);var c=this.config.styles.parcel;this.map.setLayerStyleSimple(a,c.fill,c.stroke,c.width);this.map.setLayerOrder(a,99999);this.map.addLayer(netgis.Client.Layers.PARCEL_DISTRICTS,
a);if(b.minZoom){var d=this;window.setTimeout(function(){d.map.zoomLevel(b.minZoom+1)},50)}this.setMode(netgis.Modes.PARCEL_SELECT)}else this.setMode(netgis.Modes.VIEW)};
netgis.Client.prototype.onParcelsFieldsResponse=function(a){var b=a.detail;this.map.zoomGeoJSON(b.geojson);this.map.removeLayer(netgis.Client.Layers.PARCEL_DISTRICTS);a=this.config.styles.parcel;b=this.map.createLayerGeoJSON(b.geojson,!1);this.map.setLayerStyleSimple(b,a.fill,a.stroke,a.width);this.map.setLayerOrder(b,99999);this.map.addLayer(netgis.Client.Layers.PARCEL_FIELDS,b)};
netgis.Client.prototype.onParcelsResponse=function(a){a=this.map.createLayerWKT(a.detail.parcels);var b=this.config.styles.parcel;this.map.removeLayer(netgis.Client.Layers.PARCEL_DISTRICTS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FIELDS);this.map.removeLayer(netgis.Client.Layers.PARCEL_FEATURES);this.map.setLayerStyleSimple(a,b.fill,b.stroke,b.width);this.map.setLayerOrder(a,99999);this.map.addLayer(netgis.Client.Layers.PARCEL_FEATURES,a);this.map.zoomLayer(netgis.Client.Layers.PARCEL_FEATURES)};
netgis.Client.prototype.onMapFeatureEnter=function(a){a=a.detail;switch(a.layer){case netgis.Client.Layers.PARCEL_DISTRICTS:a=a.properties.gemarkung;this.map.container.setAttribute("title",a);break;case netgis.Client.Layers.PARCEL_FIELDS:a=a.properties.flurname;this.map.container.setAttribute("title",a);break;case netgis.Client.Layers.PARCEL_FEATURES:a="Flur: "+a.properties.fln+" / Z\u00e4hler: "+a.properties.fsn_zae+" / Nenner: "+a.properties.fsn_nen,this.editable&&(a+=" (Klicken zum \u00dcbernehmen der Geometrie)"),
this.map.container.setAttribute("title",a)}};
netgis.Client.prototype.onMapFeatureClick=function(a){a=a.detail;switch(a.layer){default:console.info("Feature Click:",a);break;case netgis.Client.Layers.PARCEL_DISTRICTS:this.searchParcel.setDistrict(a.properties.gemarkung+" ("+a.properties.ldkreis+")",a.properties.gmkgnr);break;case netgis.Client.Layers.PARCEL_FIELDS:this.searchParcel.setFieldNumber(a.properties.flur);break;case netgis.Client.Layers.PARCEL_FEATURES:if(!0===this.editable){var b=a.properties.fsk;-1===this.parcelsAdded.indexOf(b)&&
(this.map.addEditFeature(this.map.createFeatureJSON(a.properties)),this.map.updateSnapFeatures(),this.parcelsAdded.push(b))}}};netgis.Client.prototype.onMapFeatureLeave=function(a){this.map.container.setAttribute("title","")};netgis.Client.prototype.onParcelsItemEnter=function(a){this.map.setFeatureHover(this.map.findFeature(netgis.Client.Layers.PARCEL_FEATURES,"fsk",a.detail.id),!0)};
netgis.Client.prototype.onParcelsItemLeave=function(a){this.map.setFeatureHover(this.map.findFeature(netgis.Client.Layers.PARCEL_FEATURES,"fsk",a.detail.id),!1)};netgis.Client.prototype.onParcelsItemClick=function(a){this.map.zoomFeature(this.map.findFeature(netgis.Client.Layers.PARCEL_FEATURES,"fsk",a.detail.id))};netgis.Client.prototype.onParcelsImportClick=function(a){a=a.detail;!1!==this.editable&&(this.map.addEditFeature(this.map.createFeatureWKT(a.geom,{id:a.id})),this.map.updateSnapFeatures())};
netgis.Client.prototype.onSetMode=function(a){this.setMode(a.detail)};netgis.Client.prototype.onSnapToggle=function(a){(a=a.detail.target.checked)?(this.map.updateSnapFeatures(),this.map.setSnapOn()):this.map.setSnapOff();this.toolbox.setSnap(a)};netgis.Client.prototype.onTracingToggle=function(a){a.detail.target.checked?(this.map.updateSnapFeatures(),this.map.setSnapOn(),this.map.setTracingOn(),this.toolbox.setSnap(!0)):this.map.setTracingOff()};
netgis.Client.prototype.onBufferToggle=function(a){if(a=a.detail.target.checked)this.map.onDrawBufferOn();else this.map.onDrawBufferOff();this.toolbox.setBuffer(a)};netgis.Client.prototype.onBufferRadiusChange=function(a){a=Number.parseFloat(a.detail.target.value);this.map.onDrawBufferRadiusChange(a);this.toolbox.setBufferRadius(a)};netgis.Client.prototype.onBufferSegmentsChange=function(a){a=Number.parseInt(a.detail.target.value);this.map.onDrawBufferSegmentsChange(a);this.toolbox.setBufferSegments(a)};
netgis.Client.prototype.onBufferFeatureChange=function(a){this.map.onBufferChange(a.detail)};netgis.Client.prototype.onBufferFeatureAccept=function(a){this.map.onBufferAccept()};netgis.Client.prototype.onImportShapefileShow=function(a){this.modal.onImportShapefileShow(a)};netgis.Client.prototype.onImportGeoJSONShow=function(a){this.modal.onImportGeoJSONShow(a)};netgis.Client.prototype.onImportGMLShow=function(a){this.modal.onImportGMLShow(a)};netgis.Client.prototype.onImportSpatialiteShow=function(a){this.modal.onImportSpatialiteShow(a)};
netgis.Client.prototype.onImportGeopackageShow=function(a){this.modal.onImportGeopackageShow(a)};netgis.Client.prototype.onExportPDFShow=function(a){this.modal.onExportPDFShow(a)};netgis.Client.prototype.onExportPNGShow=function(a){this.modal.onExportPNGShow(a)};netgis.Client.prototype.onExportJPEGShow=function(a){this.modal.onExportJPEGShow(a)};netgis.Client.prototype.onExportGIFShow=function(a){this.modal.onExportGIFShow(a)};netgis.Client.prototype.onExportPDF=function(a){this.map.onExportPDF(a)};
netgis.Client.prototype.onExportPNG=function(a){this.map.onExportPNG(a)};netgis.Client.prototype.onExportJPEG=function(a){this.map.onExportJPEG(a)};netgis.Client.prototype.onExportGIF=function(a){this.map.onExportGIF(a)};netgis.Client.prototype.onLayerTreeImportClick=function(a){this.importServiceModal.show()};
netgis.Client.prototype.onImportFileTypeChange=function(a){a=this.importFileSelect.value;var b="*.*";console.info("File Type:",a);switch(a){case "geojson":b=".geojson,.json";break;case "gml":b=".gml,.xml";break;case "gpkg":b=".gpkg";break;case "shp":b="application/zip";break;case "spatialite":b=".sqlite"}this.importFileInput.setAttribute("accept",b)};
netgis.Client.prototype.onImportFileClick=function(a){if(a=this.importFileInput.files[0]){var b=this;switch(netgis.util.getFileExtension(a.name).toLowerCase()){case "geojson":console.info("GeoJSON detected:",a.name);var c=new FileReader;c.onload=function(a){a=JSON.parse(a.target.result);b.map.addEditFeaturesGeoJSON(a,!0);b.map.zoomGeoJSON(a);b.editFolder.classList.remove("netgis-hide")};c.readAsText(a);break;case "zip":console.info("Shapefile Zip detected:",a.name);c=new FileReader;c.onload=function(a){b.map.addEditFeaturesShapefile(a.target.result);
b.editFolder.classList.remove("netgis-hide")};c.readAsArrayBuffer(a);break;case "gml":console.info("GML detected:",a.name);c=new FileReader;c.onload=function(a){a=b.map.createLayerGML(a.target.result);b.map.addEditFeaturesFromLayer(a);b.editFolder.classList.remove("netgis-hide")};c.readAsText(a);break;case "sqlite":console.info("Spatialite detected:",a.name);c=new FileReader;c.onload=function(a){b.map.addEditFeaturesSpatialite(a.target.result);b.editFolder.classList.remove("netgis-hide")};c.readAsArrayBuffer(a);
break;case "gpkg":console.info("GeoPackage detected:",a.name),c=new FileReader,c.onload=function(a){b.map.addEditFeaturesGeopackage(a.target.result);b.editFolder.classList.remove("netgis-hide")},c.readAsArrayBuffer(a)}this.importModal.hide()}else alert("No file selected!")};
netgis.Client.prototype.addImportLayer=function(a,b){this.importCounter||(this.importCounter=0);var c=this.importCounter+1;c="import-"+c;this.importCounter+=1;this.layerTree.addCheckbox(this.importFolder,c,a);this.importFolder.classList.remove("netgis-hide");this.importLayers[c]=b;this.map.setLayerOrder(b,this.map.importLayerID);a=this.config.styles["import"];this.map.setLayerStyleSimple(b,a.fill,a.stroke,a.width);this.map.addLayer(c,b);this.layerTree.setItemChecked(c,!0);this.map.zoomLayer(c);this.importModal.hide()};
netgis.Client.prototype.onImportServiceClick=function(a){this.importServiceDetails.classList.add("netgis-hide");var b=this.importServiceInput.value;b=b.trim();if(!(1>b.length)){var c=b.indexOf("?");this.importServiceBaseURL=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)}a=a+"?"+d.join("&");-1===a.search("service=")?(netgis.util.request(a+
"&service=WMS",this.onImportServiceCapsResponse.bind(this)),netgis.util.request(a+"&service=WFS",this.onImportServiceCapsResponse.bind(this))):netgis.util.request(a,this.onImportServiceCapsResponse.bind(this))}};
netgis.Client.prototype.onImportServiceCapsResponse=function(a){var b=(new DOMParser).parseFromString(a,"text/xml").documentElement,c=this.importServiceLayerSelect;a=this.importServiceFormatSelect;for(var d=c.options.length-1;0<=d;d--)c.options.remove(d);for(d=a.options.length-1;0<=d;d--)a.options.remove(d);switch(b.nodeName){default:case "HTML":this.importServiceType=null;console.warn("could not detect wms or wfs service",b);break;case "WMS_Capabilities":case "WMT_MS_Capabilities":this.importServiceType=
"wms";b.getAttribute("version");d=b.getElementsByTagName("Service")[0];d=d.getElementsByTagName("Title")[0].textContent;this.importServiceNameInput.value=d;for(var e=b.getElementsByTagName("Layer"),f=[],g=0;g<e.length;g++){d=e[g];var h=d.getElementsByTagName("Name")[0].textContent,k=d.getElementsByTagName("Title")[0].textContent;f.push({name:h,title:k});d=document.createElement("option");d.text=k;d.value=h;c.options.add(d)}c=b.getElementsByTagName("GetMap")[0].getElementsByTagName("Format");b=[];
for(g=0;g<c.length;g++)d=c[g],e=d.textContent,b.push(e),d=document.createElement("option"),d.text=e,d.value=e,a.options.add(d);break;case "WFS_Capabilities":case "wfs:WFS_Capabilities":this.importServiceType="wfs";b.getAttribute("version");d=b.getElementsByTagName("ows:ServiceIdentification")[0];d=d.getElementsByTagName("ows:Title")[0].textContent;this.importServiceNameInput.value=d;e=b.getElementsByTagName("FeatureType");f=[];for(g=0;g<e.length;g++)d=e[g],h=d.getElementsByTagName("Name")[0].textContent,
k=d.getElementsByTagName("Title")[0].textContent,f.push({name:h,title:k}),d=document.createElement("option"),d.text=k,d.value=h,c.options.add(d);b=b.getElementsByTagName("ows:Operation");d=null;for(c=0;c<b.length;c++)if("GetFeature"===b[c].getAttribute("name")){d=b[c];break}b=null;if(d)for(d=d.getElementsByTagName("ows:Parameter"),c=0;c<d.length;c++)if(g=d[c],"outputFormat"===g.getAttribute("name")){c=g.getElementsByTagName("ows:Value");for(g=0;g<c.length;g++)d=c[g],e=d.textContent,d=document.createElement("option"),
d.text=e,d.value=e,a.options.add(d),-1<e.search("json")&&(b=e);break}b&&(a.value=b)}this.importServiceDetails.classList.remove("netgis-hide")};
netgis.Client.prototype.onImportServiceAccept=function(a){a=this.importServiceBaseURL;var b=this.importServiceNameInput.value,c=this.importServiceLayerSelect.value,d=this.importServiceFormatSelect.value;switch(this.importServiceType){case "wms":this.addImportLayer(b,this.map.createLayerWMS(a,c,d,!1));break;case "wfs":this.addImportLayer(b,this.map.createLayerWFS(a+"?",c,null,d))}};netgis.Client.prototype.onImportShow=function(a){this.importModal.show()};
netgis.Client.prototype.onExportShow=function(a){this.exportWidthInput.value=this.map.getWidth();this.exportHeightInput.value=this.map.getHeight();this.exportLandscapeInput.checked=this.exportWidthInput.value>this.exportHeightInput.value;this.toolboxPanel.hide();this.exportModal.show()};
netgis.Client.prototype.onExportFormatChange=function(a){"pdf"===this.exportFormatSelect.value?(this.exportPaddingInput.parentNode.classList.remove("netgis-hide"),this.exportLandscapeInput.parentNode.classList.remove("netgis-hide")):(this.exportPaddingInput.parentNode.classList.add("netgis-hide"),this.exportLandscapeInput.parentNode.classList.add("netgis-hide"))};
netgis.Client.prototype.onExportButtonClick=function(a){a=this.exportFormatSelect.value;var b=Number.parseInt(this.exportWidthInput.value),c=Number.parseInt(this.exportHeightInput.value),d=Number.parseInt(this.exportPaddingInput.value);this.map.exportImage(a,b,c,this.exportLandscapeInput.checked,d)};netgis=netgis||{};netgis.Controls=function(){this.initElements()};
netgis.Controls.prototype.initElements=function(){this.container=document.createElement("section");this.container.className="netgis-controls netgis-color-e netgis-text-a netgis-shadow netgis-round";this.zoomIn=this.createButton("<i class='fas fa-plus'></i>","Zoom +");this.zoomIn.addEventListener("click",this.onZoomInClick.bind(this));this.container.appendChild(this.zoomIn);this.zoomOut=this.createButton("<i class='fas fa-minus'></i>","Zoom -");this.zoomOut.addEventListener("click",this.onZoomOutClick.bind(this));
this.container.appendChild(this.zoomOut);this.zoomAll=this.createButton("<i class='fas fa-home'></i>","Zoom auf Anfangsausdehung");this.zoomAll.addEventListener("click",this.onZoomAllClick.bind(this));this.container.appendChild(this.zoomAll)};netgis.Controls.prototype.attach=function(a){a.appendChild(this.container)};netgis.Controls.prototype.createButton=function(a,b){var c=document.createElement("button");c.setAttribute("type","button");c.innerHTML=a;c.title=b;c.className="netgis-hover-a";return c};
netgis.Controls.prototype.load=function(){this.root=document.createElement("section");this.root.className="netgis-controls netgis-color-e netgis-text-a netgis-hover-a netgis-shadow netgis-round";var a=document.createElement("button");a.setAttribute("type","button");a.innerHTML="<i class='fas fa-search-plus'></i>";a.title="Hineinzoomen";a.addEventListener("click",this.onZoomInClick.bind(this));this.root.appendChild(a);a=document.createElement("button");a.setAttribute("type","button");a.innerHTML="<i class='fas fa-search-minus'></i>";
a.title="Herauszoomen";a.addEventListener("click",this.onZoomOutClick.bind(this));this.root.appendChild(a);this.client.root.appendChild(this.root)};netgis.Controls.prototype.onZoomInClick=function(a){netgis.util.invoke(this.container,netgis.Events.CONTROLS_ZOOM,1)};netgis.Controls.prototype.onZoomOutClick=function(a){netgis.util.invoke(this.container,netgis.Events.CONTROLS_ZOOM,-1)};
netgis.Controls.prototype.onZoomAllClick=function(a){netgis.util.invoke(this.container,netgis.Events.CONTROLS_ZOOM_ALL,null)};netgis.Controls.prototype.onSettings=function(a){alert("TODO: settings dialog")};netgis=netgis||{};
netgis.Events=Object.freeze({PANEL_RESIZE:"panel-resize",PANEL_TOGGLE:"panel-toggle",LAYERS_TOGGLE:"layers-toggle",TOOLBOX_TOGGLE:"toolbox-toggle",CONTROLS_ZOOM:"controls-zoom",CONTROLS_ZOOM_ALL:"controls-zoom-all",MAP_FEATURE_ENTER:"map-feature-enter",MAP_FEATURE_HOVER:"map-feature-hover",MAP_FEATURE_CLICK:"map-feature-click",MAP_FEATURE_LEAVE:"map-feature-leave",PARCELS_RESET:"parcels-reset",PARCELS_FIELDS_RESPONSE:"parcels-fields-response",PARCELS_RESPONSE:"parcels-response",PARCELS_ITEM_ENTER:"parcels-item-enter",
PARCELS_ITEM_LEAVE:"parcels-item-leave",PARCELS_ITEM_CLICK:"parcels-item-click",PARCELS_ITEM_IMPORT_CLICK:"parcels-item-import-click",SNAP_TOGGLE:"snap-toggle",BUFFER_TOGGLE:"buffer-toggle",TRACING_TOGGLE:"tracing-toggle",IMPORT_SHOW:"import-show",EXPORT_SHOW:"export-show",CONTEXT_UPDATE:"CONTEXT_UPDATE",SET_MODE:"SET_MODE",LAYER_LIST_TOGGLE:"LAYER_LIST_TOGGLE",PANEL_SHOW:"PANEL_SHOW",PANEL_HIDE:"PANEL_HIDE",LAYER_SHOW:"LAYER_SHOW",LAYER_HIDE:"LAYER_HIDE",LAYER_CREATED:"LAYER_CREATED",MAP_ZOOM_WKT:"MAP_ZOOM_WKT",
MAP_SET_EXTENT:"MAP_SET_EXTENT",MAP_CHANGE_ZOOM:"MAP_CHANGE_ZOOM",MAP_UPDATE_STYLE:"MAP_UPDATE_STYLE",MAP_MODE_POINTS:"MAP_MODE_POINTS",MAP_MODE_LINES:"MAP_MODE_LINES",MAP_MODE_POLYGONS:"MAP_MODE_POLYGONS",EDIT_FEATURES_LOADED:"EDIT_FEATURES_LOADED",EDIT_FEATURES_CHANGE:"EDIT_FEATURES_CHANGE",SEARCH_PLACE_REQUEST:"SEARCH_PLACE_REQUEST",SEARCH_PLACE_RESPONSE:"SEARCH_PLACE_RESPONSE",PARCEL_SHOW_PREVIEW:"PARCEL_SHOW_PREVIEW",PARCEL_HIDE_PREVIEW:"PARCEL_HIDE_PREVIEW",BUFFER_CHANGE:"BUFFER_CHANGE",BUFFER_ACCEPT:"BUFFER_ACCEPT",
BUFFER_CANCEL:"BUFFER_CANCEL",DRAW_BUFFER_ON:"DRAW_BUFFER_ON",DRAW_BUFFER_OFF:"DRAW_BUFFER_OFF",DRAW_BUFFER_RADIUS_CHANGE:"DRAW_BUFFER_RADIUS_CHANGE",DRAW_BUFFER_SEGMENTS_CHANGE:"DRAW_BUFFER_SEGMENTS_CHANGE",SNAP_ON:"SNAP_ON",SNAP_OFF:"SNAP_OFF",TRACING_ON:"TRACING_ON",TRACING_OFF:"TRACING_OFF",IMPORT_SHAPEFILE_SHOW:"IMPORT_SHAPEFILE_SHOW",IMPORT_GEOJSON_SHOW:"IMPORT_GEOJSON_SHOW",IMPORT_GML_SHOW:"IMPORT_GML_SHOW",IMPORT_SPATIALITE_SHOW:"IMPORT_SPATIALITE_SHOW",IMPORT_GEOPACKAGE_SHOW:"IMPORT_GEOPACKAGE_SHOW",
IMPORT_SHAPEFILE:"IMPORT_SHAPEFILE",IMPORT_GEOJSON:"IMPORT_GEOJSON",IMPORT_GML:"IMPORT_GML",IMPORT_WKT:"IMPORT_WKT",IMPORT_SPATIALITE:"IMPORT_SPATIALITE",IMPORT_GEOPACKAGE:"IMPORT_GEOPACKAGE",EXPORT_PDF_SHOW:"EXPORT_PDF_SHOW",EXPORT_JPEG_SHOW:"EXPORT_JPEG_SHOW",EXPORT_PNG_SHOW:"EXPORT_PNG_SHOW",EXPORT_GIF_SHOW:"EXPORT_GIF_SHOW",EXPORT_PDF:"EXPORT_PDF",EXPORT_JPEG:"EXPORT_JPEG",EXPORT_PNG:"EXPORT_PNG",EXPORT_GIF:"EXPORT_GIF",EXPORT_BEGIN:"EXPORT_BEGIN",EXPORT_END:"EXPORT_END",ADD_SERVICE_SHOW:"ADD_SERVICE_SHOW",
ADD_SERVICE_WMS:"ADD_SERVICE_WMS",ADD_SERVICE_WFS:"ADD_SERVICE_WFS"});netgis=netgis||{};netgis.LayerTypes=Object.freeze({XYZ:"XYZ",OSM:"OSM",WMS:"WMS",WFS:"WFS",KML:"KML"});netgis=netgis||{};netgis.Map=function(){this.attribution=this.root=this.client=null};netgis.Map.prototype.load=function(){this.root=document.createElement("section");this.root.className="netgis-map";this.client.root.appendChild(this.root)};netgis=netgis||{};
netgis.MapOpenLayers=function(a){this.activeLayers={};this.projection=a.map.projection;this.config=a;this.mode=null;this.toolbars={};this.map=this.view=null;this.layers=[];this.interactions={};this.sketch=this.selected=this.hoverLayer=this.hoverFeature=this.parcelLayer=this.editLayer=this.snapFeatures=this.snap=null;this.editEventsSilent=!1;this.importLayerID=2E4;this.editLayerID=3E4;this.labelFont="4mm Verdana, sans-serif";this.drawBufferRadius=100;this.drawBufferSegments=3;this.initElements();this.initMap(a);
this.initStyles(a);this.initDefaultLayers();this.initInteractions();this.initEvents()};netgis.MapOpenLayers.prototype.initElements=function(){this.container=document.createElement("section");this.container.className="netgis-map"};netgis.MapOpenLayers.prototype.attach=function(a){a.appendChild(this.container)};netgis.MapOpenLayers.prototype.initEvents=function(){this.container.addEventListener("pointerleave",this.onPointerLeave.bind(this))};
netgis.MapOpenLayers.prototype.load=function(){netgis.Map.prototype.load.call(this);this.dropTarget=document.createElement("div");this.dropTarget.className="netgis-drop-target netgis-hide";this.dropTarget.innerHTML="Datei hier ablegen!";this.container.appendChild(this.dropTarget);this.container.addEventListener("dragenter",this.onDragEnter.bind(this));this.container.addEventListener("dragover",this.onDragEnter.bind(this));this.container.addEventListener("dragend",this.onDragLeave.bind(this));this.container.addEventListener("dragleave",
this.onDragLeave.bind(this));this.container.addEventListener("drop",this.onDragDrop.bind(this));this.initMap();this.initDefaultLayers();this.initInteractions();this.client.on(netgis.Events.CONTEXT_UPDATE,this.onContextUpdate.bind(this));this.client.on(netgis.Events.MAP_UPDATE_STYLE,this.onUpdateStyle.bind(this));this.client.on(netgis.Events.EDIT_FEATURES_LOADED,this.onEditFeaturesLoaded.bind(this));this.client.on(netgis.Events.SET_MODE,this.onSetMode.bind(this));this.client.on(netgis.Events.SNAP_ON,
this.onSnapOn.bind(this));this.client.on(netgis.Events.SNAP_OFF,this.onSnapOff.bind(this));this.client.on(netgis.Events.TRACING_ON,this.onTracingOn.bind(this));this.client.on(netgis.Events.TRACING_OFF,this.onTracingOff.bind(this));this.client.on(netgis.Events.LAYER_SHOW,this.onLayerShow.bind(this));this.client.on(netgis.Events.LAYER_HIDE,this.onLayerHide.bind(this));this.client.on(netgis.Events.MAP_ZOOM_WKT,this.onZoomWKT.bind(this));this.client.on(netgis.Events.MAP_SET_EXTENT,this.onSetExtent.bind(this));
this.client.on(netgis.Events.MAP_CHANGE_ZOOM,this.onChangeZoom.bind(this));this.client.on(netgis.Events.BUFFER_CHANGE,this.onBufferChange.bind(this));this.client.on(netgis.Events.BUFFER_ACCEPT,this.onBufferAccept.bind(this));this.client.on(netgis.Events.BUFFER_CANCEL,this.onBufferCancel.bind(this));this.client.on(netgis.Events.IMPORT_GEOJSON,this.onImportGeoJSON.bind(this));this.client.on(netgis.Events.IMPORT_GML,this.onImportGML.bind(this));this.client.on(netgis.Events.IMPORT_SHAPEFILE,this.onImportShapefile.bind(this));
this.client.on(netgis.Events.IMPORT_WKT,this.onImportWKT.bind(this));this.client.on(netgis.Events.IMPORT_SPATIALITE,this.onImportSpatialite.bind(this));this.client.on(netgis.Events.IMPORT_GEOPACKAGE,this.onImportGeopackage.bind(this));this.client.on(netgis.Events.EXPORT_PDF,this.onExportPDF.bind(this));this.client.on(netgis.Events.EXPORT_JPEG,this.onExportJPEG.bind(this));this.client.on(netgis.Events.EXPORT_PNG,this.onExportPNG.bind(this));this.client.on(netgis.Events.EXPORT_GIF,this.onExportGIF.bind(this));
this.client.on(netgis.Events.PARCEL_SHOW_PREVIEW,this.onParcelShowPreview.bind(this));this.client.on(netgis.Events.PARCEL_HIDE_PREVIEW,this.onParcelHidePreview.bind(this));this.client.on(netgis.Events.ADD_SERVICE_WMS,this.onAddServiceWMS.bind(this));this.client.on(netgis.Events.ADD_SERVICE_WFS,this.onAddServiceWFS.bind(this));this.client.on(netgis.Events.DRAW_BUFFER_ON,this.onDrawBufferOn.bind(this));this.client.on(netgis.Events.DRAW_BUFFER_OFF,this.onDrawBufferOff.bind(this));this.client.on(netgis.Events.DRAW_BUFFER_RADIUS_CHANGE,
this.onDrawBufferRadiusChange.bind(this));this.client.on(netgis.Events.DRAW_BUFFER_SEGMENTS_CHANGE,this.onDrawBufferSegmentsChange.bind(this))};
netgis.MapOpenLayers.prototype.initMap=function(a){"undefined"!==typeof proj4&&(proj4.defs(a.projections),proj4.defs("urn:ogc:def:crs:OGC:1.3:CRS84",proj4.defs("EPSG:4326")),ol.proj.proj4.register(proj4));this.view=new ol.View({projection:a.map.projection,center:a.map.center,minZoom:a.map.minZoom,maxZoom:a.map.maxZoom,zoom:a.map.zoom});this.setPadding(0,0,0,0);this.map=new ol.Map({target:this.container,view:this.view,pixelRatio:1,moveTolerance:5,controls:[]});a.map.scalebar&&(this.scalebar=new ol.control.ScaleLine({bar:!0}),
this.map.addControl(this.scalebar));this.map.on("pointermove",this.onPointerMove.bind(this));this.map.on("click",this.onSingleClick.bind(this));this.map.on("movestart",this.onMoveStart.bind(this));this.map.on("moveend",this.onMoveEnd.bind(this));this.view.on("change:resolution",this.onChangeResolution.bind(this))};netgis.MapOpenLayers.prototype.initStyles=function(a){a=a.styles.select;this.hoverStyle=this.createStyle(a.fill,a.stroke,a.width);this.hoverStyle.setZIndex(1)};
netgis.MapOpenLayers.prototype.initDefaultLayers=function(){this.editLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),style:this.styleEdit.bind(this),zIndex:this.editLayerID});this.addLayer(netgis.Client.Layers.EDIT_LAYER,this.editLayer);this.previewLayer=new ol.layer.Vector({source:new ol.source.Vector({features:[]}),style:this.styleSketch.bind(this),zIndex:this.editLayerID+1E3});this.addLayer(netgis.Client.Layers.PREVIEW_LAYER,this.previewLayer);this.editEventsOn()};
netgis.MapOpenLayers.prototype.editEventsOn=function(){this.editLayer.getSource().on("addfeature",this.onEditLayerAdd.bind(this));this.editLayer.getSource().on("changefeature",this.onEditLayerChange.bind(this));this.editLayer.getSource().on("removefeature",this.onEditLayerRemove.bind(this))};netgis.MapOpenLayers.prototype.editEventsOff=function(){};
netgis.MapOpenLayers.prototype.initInteractions=function(){this.interactions[netgis.Modes.VIEW]=[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.PANNING]=this.interactions[netgis.Modes.VIEW];this.interactions[netgis.Modes.ZOOMING_IN]=this.interactions[netgis.Modes.VIEW];this.interactions[netgis.Modes.ZOOMING_OUT]=this.interactions[netgis.Modes.VIEW];this.interactions[netgis.Modes.DRAW_POINTS]=[new ol.interaction.Draw({type:"Point",source:this.editLayer.getSource(),
style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.DRAW_POINTS][0].on("drawend",this.onDrawPointsEnd.bind(this));this.interactions[netgis.Modes.DRAW_LINES]=[new ol.interaction.Draw({type:"LineString",source:this.editLayer.getSource(),style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.DRAW_LINES][0].on("drawend",this.onDrawLinesEnd.bind(this));
this.interactions[netgis.Modes.DRAW_POLYGONS]=[new ol.interaction.Draw({type:"Polygon",source:this.editLayer.getSource(),style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.CUT_FEATURE_BEGIN]=[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.CUT_FEATURE_DRAW]=[new ol.interaction.Draw({type:"Polygon",style:this.styleSketch.bind(this)}),new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];
this.interactions[netgis.Modes.CUT_FEATURE_DRAW][0].on("drawend",this.onCutFeatureDrawEnd.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.MouseWheelZoom];this.interactions[netgis.Modes.MODIFY_FEATURES][0].on("modifyend",this.onModifyFeaturesEnd.bind(this));this.interactions[netgis.Modes.DELETE_FEATURES]=
[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.BUFFER_FEATURE_BEGIN]=[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.BUFFER_FEATURE_EDIT]=[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.snapFeatures=new ol.Collection;this.interactions[netgis.Modes.SEARCH_PLACE]=[new ol.interaction.DragPan,new ol.interaction.MouseWheelZoom];this.interactions[netgis.Modes.SEARCH_PARCEL]=this.interactions[netgis.Modes.VIEW]};
netgis.MapOpenLayers.prototype.addLayer=function(a,b){b&&(b.set("id",a),this.map.addLayer(b),this.activeLayers[a]=b)};netgis.MapOpenLayers.prototype.removeLayer=function(a){var b=this.activeLayers[a];b&&(this.map.removeLayer(b),delete this.activeLayers[a])};netgis.MapOpenLayers.prototype.createStyle=function(a,b,c){var d={};a&&(d.fill=new ol.style.Fill({color:a}));b&&(d.stroke=new ol.style.Stroke({color:b,width:c?c:3}));return new ol.style.Style(d)};
netgis.MapOpenLayers.prototype.setLayerStyle=function(a,b){a.setStyle?a.setStyle(b):console.warn("setting style on a non-vector layer",a,b)};netgis.MapOpenLayers.prototype.setLayerStyleSimple=function(a,b,c,d){this.setLayerStyle(a,this.createStyle(b,c,d))};netgis.MapOpenLayers.prototype.setLayerStyleEdit=function(a){a.setStyle(this.styleEdit.bind(this))};netgis.MapOpenLayers.prototype.setLayerOrder=function(a,b){a.setZIndex(Number.parseInt(b))};
netgis.MapOpenLayers.prototype.createLayer=function(a){var b=null;switch(a.type){case netgis.LayerTypes.XYZ:b=this.createLayerXYZ(a.url);break;case netgis.LayerTypes.OSM:b=this.createLayerOSM();break;case netgis.LayerTypes.WMS:b=this.createLayerWMS(a.url,a.name,a.format,a.tiled,a.username,a.password);break;case netgis.LayerTypes.WFS:b=this.createLayerWFS(a.url,a.name,this.projection,a.format,a.username,a.password),(a.fill||a.stroke||a.width)&&b.setStyle(this.createStyle(a.fill,a.stroke,a.width))}b&&
(a.minZoom&&b.setMinZoom(Number.parseFloat(a.minZoom)),a.maxZoom&&b.setMaxZoom(Number.parseFloat(a.maxZoom)),a.order&&b.setZIndex(Number.parseInt(a.order)));return b};netgis.MapOpenLayers.prototype.createLayerXYZ=function(a){return new ol.layer.Tile({source:new ol.source.XYZ({url:a,crossOrigin:"anonymous"})})};netgis.MapOpenLayers.prototype.createLayerOSM=function(){return new ol.layer.Tile({source:new ol.source.OSM})};
netgis.MapOpenLayers.prototype.createLayerWMS=function(a,b,c,d,e,f){a={url:a,params:{LAYERS:b,FORMAT:c?c:"image/png",TRANSPARENT:"true",VERSION:"1.1.1"},serverType:"mapserver",crossOrigin:"anonymous",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.MapOpenLayers.prototype.createLayerWFS=function(a,b,c,d,e,f){a+="service=WFS&version=1.1.0&request=GetFeature";c||(c=this.projection);d=d?netgis.util.replace(d," ","+"):"application/json; subtype=geojson";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){var a=g.getFormat().readFeatures(l.responseText);g.clear();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.MapOpenLayers.prototype.clearAll=function(){for(var a=0;a<this.layers.length;a++)this.map.removeLayer(this.layers[a]);this.layers=[];this.snapFeatures.clear()};netgis.MapOpenLayers.prototype.addFeature=function(a,b){a.getSource().addFeature(b)};netgis.MapOpenLayers.prototype.addEditFeature=function(a){this.editLayer.getSource().addFeature(a)};netgis.MapOpenLayers.prototype.addEditFeaturesFromLayer=function(a){a=a.getSource().getFeatures();this.addImportedFeatures(a)};
netgis.MapOpenLayers.prototype.addEditFeaturesGeoJSON=function(a,b){var c=new ol.format.GeoJSON;c.readProjection(a);a=b?c.readFeatures(a,{featureProjection:this.projection}):c.readFeatures(a);this.addImportedFeatures(a)};netgis.MapOpenLayers.prototype.addEditFeaturesShapefile=function(a){var b=this;shp(a).then(function(a){var c=new ol.format.GeoJSON;c.readProjection(a);a=c.readFeatures(a,{featureProjection:b.projection});b.addImportedFeatures(a)})};
netgis.MapOpenLayers.prototype.addEditFeaturesGeopackage=function(a){var b=this;a=new Uint8Array(a);window.GeoPackage.setSqljsWasmLocateFile(function(a){return b.config["import"].geopackageLibURL+a});window.GeoPackage.GeoPackageAPI.open(a).then(function(a){for(var c=[],e=new ol.format.GeoJSON,f=a.getFeatureTables(),g=0;g<f.length;g++)for(var h=a.queryForGeoJSONFeaturesInTable(f[g]),k=0;k<h.length;k++){var l=e.readGeometry(h[k].geometry,{featureProjection:b.projection});l=new ol.Feature({geometry:l});
c.push(l)}b.addImportedFeatures(c)})};
netgis.MapOpenLayers.prototype.addEditFeaturesSpatialite=function(a){var b=this;window.initSqlJs().then(function(c){var d=[],e=new Uint8Array(a);c=new c.Database(e);var f=c.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 'ElementaryGeometries' \n\t\t\t\t;");e=
f[0].values;for(var g=0;g<e.length;g++){f=c.exec("SELECT * FROM "+e[g][0]);var h=f[0];f=null;for(var k=0;k<h.columns.length;k++){if("geometry"===h.columns[k].toLowerCase()){f=k;break}if("geom"===h.columns[k].toLowerCase()){f=k;break}}h=h.values;for(k=0;k<h.length;k++){var l=h[k][f],m=new Uint8Array(l.length-43-1+5);m[0]=l[1];m[1]=l[39];m[2]=l[40];m[3]=l[41];m[4]=l[42];for(var n=l.length-43-1,p=0;p<n;p++)m[5+p]=l[43+p];l=(new ol.format.WKB).readGeometry(m,{featureProjection:b.projection});d.push(new ol.Feature({geometry:l}))}}b.addImportedFeatures(d)})};
netgis.MapOpenLayers.prototype.createFeatureWKT=function(a,b){a=(new ol.format.WKT).readGeometry(a);b.geometry=a;return new ol.Feature(b)};netgis.MapOpenLayers.prototype.createFeatureJSON=function(a){return new ol.Feature(a)};netgis.MapOpenLayers.prototype.onUpdateStyle=function(a){a=new ol.style.Style({fill:new ol.style.Fill({color:a.polygon.fill}),stroke:new ol.style.Stroke({color:a.polygon.stroke,width:a.polygon.strokeWidth})});this.editLayer.setStyle(a)};
netgis.MapOpenLayers.prototype.styleEdit=function(a){var b=a.getGeometry(),c=this.hoverFeature===a,d=c?this.config.styles.select.fill:this.config.styles.editLayer.fill;a=c?this.config.styles.select.stroke:this.config.styles.editLayer.stroke;d=new ol.style.Style({image:new ol.style.Circle({radius:c?this.config.styles.select.pointRadius:this.config.styles.editLayer.pointRadius,fill:new ol.style.Fill({color:a})}),fill:new ol.style.Fill({color:d}),stroke:new ol.style.Stroke({color:a,width:this.config.styles.editLayer.strokeWidth})});
c&&d.setZIndex(1);b instanceof ol.geom.Polygon&&(b=b.getArea(),d.setText(new ol.style.Text({text:[netgis.util.formatArea(b,!0),"4mm sans-serif"],font:this.labelFont,fill:new ol.style.Fill({color:a}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]})));return d};
netgis.MapOpenLayers.prototype.styleSelect=function(a){var b=a.getGeometry();a=new ol.style.Style({image:new ol.style.Circle({radius:this.client.config.styles.select.pointRadius,fill:new ol.style.Fill({color:this.client.config.styles.select.stroke})}),fill:new ol.style.Fill({color:this.client.config.styles.select.fill}),stroke:new ol.style.Stroke({color:this.client.config.styles.select.stroke,width:this.client.config.styles.select.strokeWidth})});b instanceof ol.geom.Polygon&&(b=b.getArea(),a.setText(new ol.style.Text({text:[netgis.util.formatArea(b,
!0),"4mm sans-serif"],font:this.labelFont,fill:new ol.style.Fill({color:this.client.config.styles.select.stroke}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]})));return a};
netgis.MapOpenLayers.prototype.styleModify=function(a){var b=new ol.style.Style({image:new ol.style.Circle({radius:this.config.styles.modify.pointRadius,fill:new ol.style.Fill({color:this.config.styles.modify.stroke})}),fill:new ol.style.Fill({color:this.config.styles.modify.fill}),stroke:new ol.style.Stroke({color:this.config.styles.modify.stroke,width:this.config.styles.modify.strokeWidth})}),c=new ol.style.Style({image:new ol.style.Circle({radius:this.config.styles.modify.pointRadius,fill:new ol.style.Fill({color:this.config.styles.modify.stroke})}),
geometry:this.getGeometryPoints(a)});a=a.getGeometry();a instanceof ol.geom.Polygon&&(a=a.getArea(),b.setText(new ol.style.Text({text:[netgis.util.formatArea(a,!0),"4mm sans-serif"],font:this.labelFont,fill:new ol.style.Fill({color:this.config.styles.modify.stroke}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]})));return[b,c]};
netgis.MapOpenLayers.prototype.styleSketch=function(a){var b=a.getGeometry(),c=new ol.style.Style({image:new ol.style.Circle({radius:this.config.styles.sketch.pointRadius,fill:new ol.style.Fill({color:this.config.styles.sketch.stroke})}),fill:new ol.style.Fill({color:this.config.styles.sketch.fill}),stroke:new ol.style.Stroke({color:this.config.styles.sketch.stroke,width:this.config.styles.sketch.strokeWidth})});b instanceof ol.geom.Polygon&&(b=b.getArea(),c.setText(new ol.style.Text({text:[netgis.util.formatArea(b,
!0),"4mm sans-serif"],font:this.labelFont,fill:new ol.style.Fill({color:this.config.styles.sketch.stroke}),backgroundFill:new ol.style.Fill({color:"rgba( 255, 255, 255, 0.5 )"}),padding:[2,4,2,4]})));a=new ol.style.Style({image:new ol.style.Circle({radius:this.config.styles.sketch.pointRadius,fill:new ol.style.Fill({color:this.config.styles.sketch.stroke})}),geometry:this.getGeometryPoints(a)});return[c,a]};
netgis.MapOpenLayers.prototype.styleParcel=function(){return new ol.style.Style({fill:new ol.style.Fill({color:this.client.config.styles.parcel.fill}),stroke:new ol.style.Stroke({color:this.client.config.styles.parcel.stroke,width:this.client.config.styles.parcel.strokeWidth}),zIndex:99999})};netgis.MapOpenLayers.prototype.redrawVectorLayers=function(){this.map.getLayers().forEach(function(a,b,c){a instanceof ol.layer.Vector&&a.setStyle(a.getStyle())})};
netgis.MapOpenLayers.prototype.getGeometryPoints=function(a){var b=a.getGeometry();if(b instanceof ol.geom.LineString)return new ol.geom.MultiPoint(b.getCoordinates());if(b instanceof ol.geom.Polygon){a=[];b=b.getCoordinates();for(var c=0;c<b.length;c++)for(var d=b[c],e=0;e<d.length;e++)a.push(d[e]);return new ol.geom.MultiPoint(a)}if(b instanceof ol.geom.MultiPolygon){a=[];for(var f=b.getPolygons(),g=0;g<f.length;g++)for(b=f[g].getCoordinates(),c=0;c<b.length;c++)for(d=b[c],e=0;e<d.length;e++)a.push(d[e]);
return new ol.geom.MultiPoint(a)}if(b instanceof ol.geom.MultiLineString){a=[];f=b.getPolygons();for(g=0;g<f.length;g++)for(b=f[g].getCoordinates(),c=0;c<b.length;c++)for(d=b[c],e=0;e<d.length;e++)a.push(d[e]);return new ol.geom.MultiPoint(a)}return b};netgis.MapOpenLayers.prototype.getActiveVectorLayers=function(){for(var a=[],b=this.map.getLayers().getArray(),c=this.layers,d=0;d<c.length;d++){var e=c[d];e instanceof ol.layer.Vector&&-1<b.indexOf(e)&&a.push(e)}return a};
netgis.MapOpenLayers.prototype.setMode=function(a){switch(this.mode){case netgis.Modes.BUFFER_FEATURE_EDIT:this.onBufferCancel(null);break;case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:var b=this.drawBufferOn;this.onDrawBufferOff(null);this.drawBufferOn=b;break;case netgis.Modes.MODIFY_FEATURES:this.editLayer.setStyle(this.styleEdit.bind(this))}this.container.classList.remove("netgis-cursor-draw");this.container.classList.remove("netgis-clickable");switch(a){case netgis.Modes.DRAW_POINTS:this.container.classList.add("netgis-cursor-draw");
this.updateSnapFeatures();if(this.drawBufferOn)this.onDrawBufferOn();break;case netgis.Modes.DRAW_LINES:this.container.classList.add("netgis-cursor-draw");this.updateSnapFeatures();if(this.drawBufferOn)this.onDrawBufferOn();break;case netgis.Modes.DRAW_POLYGONS:this.container.classList.add("netgis-cursor-draw");this.updateSnapFeatures();break;case netgis.Modes.MODIFY_FEATURES:this.editLayer.setStyle(this.styleModify.bind(this))}this.map.getInteractions().clear();(b=this.interactions[a])||(b=this.interactions[netgis.Modes.VIEW]);
for(var c=0;c<b.length;c++)this.map.addInteraction(b[c]);this.snap&&(a===netgis.Modes.DRAW_POINTS||a===netgis.Modes.DRAW_LINES||a===netgis.Modes.DRAW_POLYGONS)&&this.map.addInteraction(this.snap);this.mode=a};netgis.MapOpenLayers.prototype.getModeClassName=function(a){a=a.toLowerCase();a=netgis.util.replace(a,"_","-");return"netgis-mode-"+a};netgis.MapOpenLayers.prototype.setSnapOn=function(){this.snap=new ol.interaction.Snap({features:this.snapFeatures});this.map.addInteraction(this.snap);this.snapFeatures.changed()};
netgis.MapOpenLayers.prototype.setSnapOff=function(){this.snap&&(this.map.removeInteraction(this.snap),this.snap=null)};netgis.MapOpenLayers.prototype.setTracingOn=function(){var a=new ol.source.Vector({features:this.snapFeatures});this.tracing=new ol.interaction.Draw({type:"Polygon",source:this.editLayer.getSource(),style:this.styleSketch.bind(this),trace:!0,traceSource:a});a=this.interactions[netgis.Modes.DRAW_POLYGONS];a[0].setActive(!1);a.push(this.tracing);this.setMode(this.mode)};
netgis.MapOpenLayers.prototype.setTracingOff=function(){var a=this.interactions[netgis.Modes.DRAW_POLYGONS];a[0].setActive(!0);a.splice(a.indexOf(this.tracing),1);this.setMode(this.mode)};netgis.MapOpenLayers.prototype.addSnapLayer=function(a){a=a.getSource().getFeatures();for(var b=0;b<a.length;b++)this.snapFeatures.push(a[b])};netgis.MapOpenLayers.prototype.removeSnapLayer=function(a){a=a.getSource().getFeatures();for(var b=0;b<a.length;b++)this.snapFeatures.remove(a[b])};
netgis.MapOpenLayers.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.MapOpenLayers.prototype.zoomExtent=function(a,b,c,d){a=ol.proj.fromLonLat([a,b],this.projection);c=ol.proj.fromLonLat([c,d],this.projection);this.view.fit([a[0],a[1],c[0],c[1]])};netgis.MapOpenLayers.prototype.zoomWKT=function(a){a=(new ol.format.WKT).readGeometry(a);this.view.fit(a,{duration:300})};
netgis.MapOpenLayers.prototype.zoomGeoJSON=function(a){a=(new ol.format.GeoJSON).readFeatures(a,{});for(var b=a[0].getGeometry().getExtent(),c=1;c<a.length;c++)ol.extent.extend(b,a[c].getGeometry().getExtent());this.view.fit(b,{duration:300})};netgis.MapOpenLayers.prototype.zoomLayer=function(a){var b=this.activeLayers[a];b||(b=a);b.getSource&&b.getSource().getExtent&&(a=b.getSource().getExtent())&&Number.isFinite(a[0])&&this.view.fit(a,{duration:300})};
netgis.MapOpenLayers.prototype.zoomFeature=function(a){this.view.fit(a.getGeometry(),{duration:300})};netgis.MapOpenLayers.prototype.zoom=function(a){this.view.animate({zoom:this.view.getZoom()+a,duration:200})};netgis.MapOpenLayers.prototype.zoomLevel=function(a){this.view.animate({zoom:a,center:this.view.getCenter(),duration:300})};netgis.MapOpenLayers.prototype.zoomAll=function(){var a=this.config.map;this.view.animate({zoom:a.zoom,center:a.center,duration:500})};
netgis.MapOpenLayers.prototype.setPadding=function(a,b,c,d){this.view.padding=[a+40,b+40,c+40,d+40]};netgis.MapOpenLayers.prototype.onSnapOn=function(a){this.setSnapOn()};netgis.MapOpenLayers.prototype.onSnapOff=function(a){this.setSnapOff()};netgis.MapOpenLayers.prototype.onTracingOn=function(a){this.setTracingOn()};netgis.MapOpenLayers.prototype.onTracingOff=function(a){this.setTracingOff()};
netgis.MapOpenLayers.prototype.onLayerShow=function(a){if(a=this.layers[a.id])this.map.addLayer(a),a instanceof ol.layer.Vector&&this.addSnapLayer(a)};netgis.MapOpenLayers.prototype.onLayerHide=function(a){if(a=this.layers[a.id])this.map.removeLayer(a),a instanceof ol.layer.Vector&&this.removeSnapLayer(a)};
netgis.MapOpenLayers.prototype.onContextUpdate=function(a){this.clearAll();if(a=a.bbox){if(netgis.util.isDefined(this.client.config.map)&&netgis.util.isDefined(this.client.config.map.projection)){var b=ol.proj.fromLonLat([a[0],a[1]],this.client.config.map.projection);var c=ol.proj.fromLonLat([a[2],a[3]],this.client.config.map.projection)}else b=ol.proj.fromLonLat([a[0],a[1]]),c=ol.proj.fromLonLat([a[2],a[3]]);a[0]=b[0];a[1]=b[1];a[2]=c[0];a[3]=c[1];this.view.fit(a)}};
netgis.MapOpenLayers.prototype.onAddServiceWMS=function(a){var b=this.createLayerWMS(a.url,a.name,a.format);b.setZIndex(a.id);this.layers[a.id]=b};netgis.MapOpenLayers.prototype.onAddServiceWFS=function(a){var b=this.createLayerWFS(a.url,a.name,this.client.config.map.projection,a.format);b.setZIndex(a.id);this.layers[a.id]=b};netgis.MapOpenLayers.prototype.onSetMode=function(a){this.setMode(a)};
netgis.MapOpenLayers.prototype.onSetExtent=function(a){var b=ol.proj.fromLonLat([a.minx,a.miny],this.client.config.map.projection);a=ol.proj.fromLonLat([a.maxx,a.maxy],this.client.config.map.projection);this.view.fit([b[0],b[1],a[0],a[1]])};netgis.MapOpenLayers.prototype.onChangeZoom=function(a){this.view.animate({zoom:this.view.getZoom()+a,duration:200})};netgis.MapOpenLayers.prototype.onZoomWKT=function(a){a=(new ol.format.WKT).readGeometry(a);this.view.fit(a,{duration:300,padding:[40,40,40,40]})};
netgis.MapOpenLayers.prototype.onPointerMove=function(a){var b=a.pixel;a=a.coordinate;var c=null,d=null;this.map.forEachFeatureAtPixel(b,function(a,b){if(b){if(b.get("id")&&netgis.util.isString(b.get("id"))&&-1!==b.get("id").search("import-"))return!1;c=a;d=b;return!0}});switch(this.mode){default:return!0;case netgis.Modes.PARCEL_SELECT:case netgis.Modes.DELETE_FEATURES:case netgis.Modes.CUT_FEATURE_BEGIN:case netgis.Modes.BUFFER_FEATURE_BEGIN:break;case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:return this.updateDrawBufferPreview(),
!0}c!==this.hoverFeature&&(this.hoverFeature&&this.featureLeave(this.hoverFeature,this.hoverLayer,b,a),c&&this.featureEnter(c,d,b,a),this.redrawVectorLayers(),this.hoverFeature=c,this.hoverLayer=d);c&&this.featureHover(c,d,b,a)};netgis.MapOpenLayers.prototype.onPointerLeave=function(a){this.hoverFeature&&(this.featureLeave(this.hoverFeature,this.hoverLayer,[a.offsetX,a.offsetY],null),this.hoverLayer=this.hoverFeature=null)};
netgis.MapOpenLayers.prototype.featureEnter=function(a,b,c,d){if(b){this.container.classList.add("netgis-clickable");var e=!1;b.get("id")===netgis.Client.Layers.EDIT_LAYER&&(e=!0);b.get("id")===netgis.Client.Layers.PARCEL_DISTRICTS&&(e=!0);b.get("id")===netgis.Client.Layers.PARCEL_FIELDS&&(e=!0);b.get("id")===netgis.Client.Layers.PARCEL_FEATURES&&(e=!0);e&&a.setStyle(this.hoverStyle);netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_ENTER,{pixel:c,coords:d,layer:b.get("id"),properties:a.getProperties()})}};
netgis.MapOpenLayers.prototype.featureHover=function(a,b,c,d){};netgis.MapOpenLayers.prototype.featureLeave=function(a,b,c,d){b&&(this.container.classList.remove("netgis-clickable"),b.get("id")!==netgis.Client.Layers.EDIT_LAYER&&a.setStyle(null),netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_LEAVE,{pixel:c,coords:d,layer:b.get("id"),properties:a.getProperties()}))};
netgis.MapOpenLayers.prototype.findFeature=function(a,b,c){if(a=this.activeLayers[a]){a=a.getSource().getFeatures();for(var d=null,e=0;e<a.length;e++){var f=a[e];if(f.get(b)===c){d=f;break}}return d}};netgis.MapOpenLayers.prototype.setFeatureHover=function(a,b){a.setStyle(b?this.hoverStyle:null)};
netgis.MapOpenLayers.prototype.onPointerMove_01=function(a){a=a.pixel;var b=this.hoverFeature,c=this;switch(this.mode){case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:this.updateDrawBufferPreview()}b=null;this.map.forEachFeatureAtPixel(a,function(a,e){e===c.editLayer&&(b=a);return!0});b!==this.hoverFeature&&this.redrawVectorLayers();this.hoverFeature=b};
netgis.MapOpenLayers.prototype.onSingleClick=function(a){switch(this.mode){default:this.hoverFeature&&this.hoverLayer&&(a={pixel:a.pixel,coords:a.coordinate,layer:this.hoverLayer.get("id"),id:this.hoverFeature.getId(),properties:this.hoverFeature.getProperties()},netgis.util.invoke(this.container,netgis.Events.MAP_FEATURE_CLICK,a));break;case netgis.Modes.DELETE_FEATURES:this.hoverFeature&&(this.editLayer.getSource().removeFeature(this.hoverFeature),this.featureLeave(this.hoverFeature,this.editLayer),
this.hoverFeature=null,netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.VIEW));break;case netgis.Modes.CUT_FEATURE_BEGIN:this.hoverFeature&&(this.selected=this.hoverFeature,netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.CUT_FEATURE_DRAW));break;case netgis.Modes.BUFFER_FEATURE_BEGIN:this.hoverFeature&&(this.selected=this.hoverFeature,netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.BUFFER_FEATURE_EDIT))}};
netgis.MapOpenLayers.prototype.onMoveStart=function(a){};netgis.MapOpenLayers.prototype.onMoveEnd=function(a){};netgis.MapOpenLayers.prototype.onChangeResolution=function(a){};
netgis.MapOpenLayers.prototype.onCutFeatureDrawEnd=function(a){var b=a.feature;if(a=this.selected){var c=new jsts.io.OL3Parser,d=c.read(a.getGeometry());b=c.read(b.getGeometry());d=d.difference(b);c=c.write(d);c=new ol.Feature({geometry:c});d=this.editLayer.getSource();d.removeFeature(a);d.addFeature(c);this.selected=c}this.editEventsSilent=!0;this.splitMultiPolygons(this.editLayer);this.editEventsSilent=!1;this.updateEditOutput();netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.VIEW)};
netgis.MapOpenLayers.prototype.onModifyFeaturesEnd=function(a){this.updateEditOutput();this.updateEditArea()};netgis.MapOpenLayers.prototype.createBufferFeature=function(a,b,c){a=this.createBufferGeometry(a,b,c);return new ol.Feature({geometry:a})};netgis.MapOpenLayers.prototype.createBufferGeometry=function(a,b,c){var d=new jsts.io.OL3Parser;a=d.read(a).buffer(b,c);return d.write(a)};
netgis.MapOpenLayers.prototype.onBufferChange=function(a){var b=this.editLayer.getSource(),c=this.selected;this.sketch&&b.removeFeature(this.sketch);c&&(a=this.createBufferFeature(c.getGeometry(),a.radius,a.segments),b.addFeature(a),this.sketch=a)};netgis.MapOpenLayers.prototype.onBufferAccept=function(a){this.selected&&this.sketch&&this.editLayer.getSource().removeFeature(this.selected);this.selected=this.sketch=null};
netgis.MapOpenLayers.prototype.onBufferCancel=function(a){this.sketch&&(this.editLayer.getSource().removeFeature(this.sketch),this.sketch=null);this.selected=null};netgis.MapOpenLayers.prototype.onDrawPointsEnd=function(a){var b=this.previewLayer.getSource().getFeatures()[0];if(b){var c=this.editLayer.getSource();c.addFeature(b.clone());window.setTimeout(function(){c.removeFeature(a.feature)},10)}};
netgis.MapOpenLayers.prototype.onDrawLinesEnd=function(a){var b=this.previewLayer.getSource().getFeatures()[0];if(b){var c=this.editLayer.getSource();c.addFeature(b.clone());window.setTimeout(function(){c.removeFeature(a.feature)},10)}};netgis.MapOpenLayers.prototype.onDrawBufferOn=function(a){a=this.createBufferFeature(new ol.geom.Point(this.config.map.center),this.drawBufferRadius,this.drawBufferSegments);this.previewLayer.getSource().addFeature(a);this.drawBufferOn=!0};
netgis.MapOpenLayers.prototype.onDrawBufferOff=function(a){this.previewLayer.getSource().clear();this.drawBufferOn=!1};netgis.MapOpenLayers.prototype.onDrawBufferRadiusChange=function(a){this.drawBufferRadius=a;this.updateDrawBufferPreview()};netgis.MapOpenLayers.prototype.onDrawBufferSegmentsChange=function(a){this.drawBufferSegments=a;this.updateDrawBufferPreview()};
netgis.MapOpenLayers.prototype.updateDrawBufferPreview=function(){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.MapOpenLayers.prototype.onEditLayerAdd=function(a){this.updateEditLayerItem();this.updateEditOutput();this.snapFeatures.push(a.feature)};
netgis.MapOpenLayers.prototype.onEditLayerRemove=function(a){this.updateEditOutput();this.snapFeatures.remove(a.feature)};netgis.MapOpenLayers.prototype.onEditLayerChange=function(a){this.updateEditOutput()};
netgis.MapOpenLayers.prototype.updateEditOutput=function(){var a=this.editLayer.getSource().getFeatures(),b=this.projection,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;this.editEventsSilent||netgis.util.invoke(this.container,netgis.Events.EDIT_FEATURES_CHANGE,c)};
netgis.MapOpenLayers.prototype.updateEditLayerItem=function(){var a=this.editLayerID;this.activeLayers[a]||(this.activeLayers[a]=this.editLayer,netgis.util.invoke(this.container,netgis.Events.LAYER_CREATED,{id:a,title:"Zeichnung",checked:!0,folder:"draw"}))};netgis.MapOpenLayers.prototype.updateEditArea=function(){};
netgis.MapOpenLayers.prototype.onEditFeaturesLoaded=function(a){var b=this;console.info("Edit Features Loaded:",a);window.setTimeout(function(){b.addLayer("import",b.createLayerGeoJSON(a,!0))},10)};netgis.MapOpenLayers.prototype.onDragEnter=function(a){a.preventDefault();this.dropTarget.classList.remove("netgis-hide");return!1};netgis.MapOpenLayers.prototype.onDragLeave=function(a){this.dropTarget.classList.add("netgis-hide");return!1};
netgis.MapOpenLayers.prototype.onDragDrop=function(a){console.info("Drag Drop");this.dropTarget.classList.add("netgis-hide");a.preventDefault();a=a.dataTransfer.files[0];var b=new FileReader;b.onload=this.onDragLoad.bind(this);console.log("File:",a);b.readAsArrayBuffer(a);return!1};netgis.MapOpenLayers.prototype.onDragLoad=function(a){console.log("On Load:",a.target);this.loadShape(a.target.result)};netgis.MapOpenLayers.prototype.loadShape=function(a){var b=this;shp(a).then(function(a){b.onShapeLoad(a)})};
netgis.MapOpenLayers.prototype.onShapeLoad=function(a){console.info("Shapefile To Geojson:",a);a=(new ol.format.GeoJSON({dataProjection:"EPSG:4326",featureProjection:"EPSG:3857"})).readFeatures(a);this.importLayer.getSource().addFeatures(a);this.view.fit(this.importLayer.getSource().getExtent(),{})};netgis.MapOpenLayers.prototype.onImportGeoJSON=function(a){var b=a.name,c=this,d=new FileReader;d.onload=function(a){c.createLayerGeoJSON(b,a.target.result)};d.readAsText(a)};
netgis.MapOpenLayers.prototype.onImportGML=function(a){var b=a.name,c=this,d=new FileReader;d.onload=function(a){c.createLayerGML(b,a.target.result)};d.readAsText(a)};netgis.MapOpenLayers.prototype.onImportShapefile=function(a){var b=a.name,c=this,d=new FileReader;d.onload=function(a){c.createLayerShapefile(b,a.target.result)};d.readAsArrayBuffer(a)};
netgis.MapOpenLayers.prototype.onImportSpatialite=function(a){var b=a.name,c=this,d=new FileReader;d.onload=function(a){c.createLayerSpatialite(b,a.target.result)};d.readAsArrayBuffer(a)};netgis.MapOpenLayers.prototype.onImportGeopackage=function(a){var b=a.name,c=this,d=new FileReader;d.onload=function(a){c.createLayerGeopackage(b,a.target.result)};d.readAsArrayBuffer(a)};
netgis.MapOpenLayers.prototype.createLayerGeoJSON=function(a,b){var c=new ol.format.GeoJSON,d=c.readProjection(a);a=b?c.readFeatures(a,{featureProjection:this.projection}):c.readFeatures(a);d=d.getCode();switch(d){case "EPSG:3857":case "EPSG:4326":case this.projection:break;default:console.warn("Unsupported Import Projection:",d)}return new ol.layer.Vector({source:new ol.source.Vector({features:a})})};
netgis.MapOpenLayers.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);e.geometry=f;f=new ol.Feature(e);c.push(f)}return new ol.layer.Vector({source:new ol.source.Vector({features:c})})};netgis.MapOpenLayers.prototype.createLayerVector=function(a){var b=new ol.layer.Vector({source:new ol.source.Vector({features:[]})});a&&b.setZIndex(a);return b};
netgis.MapOpenLayers.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.MapOpenLayers.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.MapOpenLayers.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.MapOpenLayers.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.projection))}return a};
netgis.MapOpenLayers.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.projection});b.getSource().addFeatures(a)});return b};
netgis.MapOpenLayers.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 '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}}k=k.values;for(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.projection});e.push(new ol.Feature({geometry:m}))}}b.getSource().addFeatures(e)});
return b};
netgis.MapOpenLayers.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"].geopackageLibURL+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.projection});
m=new ol.Feature({geometry:m});d.push(m)}b.getSource().addFeatures(d)});return b};netgis.MapOpenLayers.prototype.addImportedFeatures=function(a){this.editLayer.getSource().addFeatures(a);this.updateSnapFeatures();if(0<a.length){for(var b=a[0].getGeometry().getExtent(),c=1;c<a.length;c++)ol.extent.extend(b,a[c].getGeometry().getExtent());this.view.fit(b,{duration:300})}};netgis.MapOpenLayers.prototype.onImportWKT=function(a){a=(new ol.format.WKT).readGeometry(a);a=new ol.Feature({geometry:a});this.addImportedFeatures([a])};
netgis.MapOpenLayers.prototype.onExportPDF=function(a){this.exportImage("pdf",a.resx,a.resy,a.mode,a.margin)};netgis.MapOpenLayers.prototype.onExportJPEG=function(a){this.exportImage("jpeg",a.resx,a.resy)};netgis.MapOpenLayers.prototype.onExportPNG=function(a){this.exportImage("png",a.resx,a.resy)};netgis.MapOpenLayers.prototype.onExportGIF=function(a){this.exportImage("gif",a.resx,a.resy)};
netgis.MapOpenLayers.prototype.onParcelShowPreview=function(a){a=(new ol.format.WKT).readGeometry(a.geom);a=new ol.Feature({geometry:a});this.parcelLayer.getSource().clear();this.parcelLayer.getSource().addFeature(a)};netgis.MapOpenLayers.prototype.onParcelHidePreview=function(a){this.parcelLayer.getSource().clear()};netgis.MapOpenLayers.prototype.getWidth=function(){return this.map.getSize()[0]};netgis.MapOpenLayers.prototype.getHeight=function(){return this.map.getSize()[1]};
netgis.MapOpenLayers.prototype.exportImage=function(a,b,c,d,e){netgis.util.invoke(this.container,netgis.Events.EXPORT_BEGIN,null);var f=this,g=this.container,h=this.map,k=this.config,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,v=210-e-e,t=n.width/n.height;if(!d){var w=r;r=v;v=w}if(n.height>n.width){var u=v;w=u*t;w>r&&(w=r,u=w/t)}else w=r,u=w/t,u>v&&(u=v,w=u*t);t=new jsPDF(d?"l":"p");var x=e;x+=(r-w)/2;r=e;r+=(v-u)/2;t.addImage(n.toDataURL("image/png,1.0",1),"PNG",x,r,w,u);
t.setFillColor(255,255,255);t.rect(x,r+u-11,80,11,"F");t.setFontSize(8);t.text("Datum: "+netgis.util.getTimeStamp(),x+2,r+u-2-4);t.text("Quelle: "+window.location.href,x+2,r+u-2);n=t.output("bloburl",{filename:k.export.defaultFilename+".pdf"});window.open(n,"_blank");break;case "jpeg":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),k.export.defaultFilename+".jpg"):(q.setAttribute("download",k.export.defaultFilename+".jpg"),q.setAttribute("href",n.toDataURL("image/jpeg",1)),q.click());
break;case "png":window.navigator.msSaveBlob?window.navigator.msSaveBlob(n.msToBlob(),k.export.defaultFilename+".png"):(q.setAttribute("download",k.export.defaultFilename+".png"),q.setAttribute("href",n.toDataURL("image/png",1)),q.click());break;case "gif":q.setAttribute("download",k.export.defaultFilename+".gif"),v=new GIF({workerScript:k.export.gifWebWorker,quality:1}),v.addFrame(n),v.on("finished",function(a){q.setAttribute("href",window.URL.createObjectURL(a));q.click()}),v.render()}h.setTarget(g);
g.removeChild(m);netgis.util.invoke(f.container,netgis.Events.EXPORT_END,null)});h.renderSync()};l.src=k.export.logo};netgis.MapOpenLayers.prototype.splitMultiPolygons=function(a){a=a.getSource();for(var b=a.getFeatures(),c=[],d=[],e=0;e<b.length;e++){var f=b[e],g=f.getGeometry();if(g instanceof ol.geom.MultiPolygon){g=g.getPolygons();for(var h=0;h<g.length;h++){var k=new ol.Feature({geometry:g[h]});d.push(k)}c.push(f)}}for(e=0;e<c.length;e++)a.removeFeature(c[e]);a.addFeatures(d)};netgis=netgis||{};netgis.Menu=function(){this.root=this.client=null;this.sections=[]};
netgis.Menu.prototype.load=function(){this.root=document.createElement("header");this.root.className="netgis-menu netgis-color-a netgis-shadow";var a=document.createElement("div");this.root.appendChild(a);var b=this.createButton('<i class="fab fa-buffer"></i><span>Inhalte</span>',!0);b.addEventListener("click",this.onToggleClick.bind(this));a.appendChild(b);!0===this.client.editable&&(b=this.createButton('<i class="fas fa-tools"></i><span>Werkzeuge</span>',!0),b.addEventListener("click",this.onToolboxClick.bind(this)),
a.appendChild(b));b=this.createButton('<i class="fas fa-vector-square"></i><span>Flurst\u00fccke</span>',!0);b.addEventListener("click",this.onSearchParcelClick.bind(this));a.appendChild(b);b=this.createButton('<i class="fas fa-search"></i><span>Suche</span>',!0);b.addEventListener("click",this.onSearchPlaceClick.bind(this));a.appendChild(b);this.client.editable&&(a=this.createMenu('<i class="fas fa-caret-down"></i>Zeichnen').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-map-marker-alt"></i>Punkte',
this.onDrawPointClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-minus"></i>Linien',this.onDrawLineClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-vector-square"></i>Polygone',this.onDrawPolygonClick.bind(this))),a=this.createMenu('<i class="fas fa-caret-down"></i>Bearbeiten').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-cut"></i>Ausschneiden',this.onCutFeatureClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-arrows-alt"></i>Verschieben',
this.onModifyFeaturesClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-eraser"></i>L\u00f6schen',this.onDeleteFeaturesClick.bind(this))),a.appendChild(this.createMenuItem('<i class="far fa-dot-circle"></i>Puffern',this.onBufferFeatureClick.bind(this))),a=this.createMenu('<i class="fas fa-caret-down"></i>Import').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GeoJSON',this.onImportGeoJSONClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GML',
this.onImportGMLClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>Shapefile',this.onImportShapefileClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>Spatialite',this.onImportSpatialiteClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GeoPackage',this.onImportGeopackageClick.bind(this))),a=this.createMenu('<i class="fas fa-caret-down"></i>Export').getElementsByTagName("ul")[0],a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>PDF',
this.onExportPDFClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>JPEG',this.onExportJPEGClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>PNG',this.onExportPNGClick.bind(this))),a.appendChild(this.createMenuItem('<i class="fas fa-file"></i>GIF',this.onExportGIFClick.bind(this))));this.client.root.appendChild(this.root)};
netgis.Menu.prototype.createButton=function(a,b){var c=document.createElement("button");c.setAttribute("type","button");c.className="netgis-color-a netgis-hover-c";b&&(c.className+=" netgis-right");c.innerHTML=a;return c};
netgis.Menu.prototype.createMenu=function(a){var b=document.createElement("div");b.className="netgis-dropdown";var c=document.createElement("button");c.setAttribute("type","button");c.className="netgis-primary netgis-hover-primary";c.innerHTML=a;b.appendChild(c);a=document.createElement("ul");a.className="netgis-dropdown-content netgis-dialog netgis-shadow";b.appendChild(a);return b};
netgis.Menu.prototype.createMenuItem=function(a,b){var c=document.createElement("li");c.className="netgis-hover-light";var d=document.createElement("button");d.setAttribute("type","button");d.innerHTML=a;d.addEventListener("click",b);c.appendChild(d);return c};netgis.Menu.prototype.onToggleClick=function(a){netgis.util.invoke(this.root,netgis.Events.LAYERS_TOGGLE)};netgis.Menu.prototype.onDrawPointClick=function(a){this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.DRAW_POINTS)};
netgis.Menu.prototype.onDrawLineClick=function(a){this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.DRAW_LINES)};netgis.Menu.prototype.onDrawPolygonClick=function(a){this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.DRAW_POLYGONS)};netgis.Menu.prototype.onCutFeatureClick=function(a){this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.CUT_FEATURE_BEGIN)};netgis.Menu.prototype.onModifyFeaturesClick=function(a){this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.MODIFY_FEATURES)};
netgis.Menu.prototype.onDeleteFeaturesClick=function(a){this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.DELETE_FEATURES)};netgis.Menu.prototype.onBufferFeatureClick=function(a){this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.BUFFER_FEATURE_BEGIN)};netgis.Menu.prototype.onSearchPlaceClick=function(a){netgis.util.invoke(this.root,netgis.SearchPlace.Events.TOGGLE)};netgis.Menu.prototype.onSearchParcelClick=function(a){netgis.util.invoke(this.root,netgis.SearchParcel.Events.TOGGLE)};
netgis.Menu.prototype.onToolboxClick=function(a){netgis.util.invoke(this.root,netgis.Events.TOOLBOX_TOGGLE)};netgis.Menu.prototype.onSearchDataClick=function(a){alert("TODO: data search interface")};netgis.Menu.prototype.onImportOWSClick=function(a){alert("TODO: ows import interface, try setting url parameter '?ows=<url>'")};netgis.Menu.prototype.onImportShapefileClick=function(a){this.client.invoke(netgis.Events.IMPORT_SHAPEFILE_SHOW,null)};
netgis.Menu.prototype.onImportGeoJSONClick=function(a){this.client.invoke(netgis.Events.IMPORT_GEOJSON_SHOW,null)};netgis.Menu.prototype.onImportKMLClick=function(a){alert("TODO: kml import interface")};netgis.Menu.prototype.onImportGMLClick=function(a){this.client.invoke(netgis.Events.IMPORT_GML_SHOW,null)};netgis.Menu.prototype.onImportSpatialiteClick=function(a){this.client.invoke(netgis.Events.IMPORT_SPATIALITE_SHOW,null)};
netgis.Menu.prototype.onImportGeopackageClick=function(a){this.client.invoke(netgis.Events.IMPORT_GEOPACKAGE_SHOW,null)};netgis.Menu.prototype.onExportPDFClick=function(a){this.client.invoke(netgis.Events.EXPORT_PDF_SHOW,null)};netgis.Menu.prototype.onExportJPEGClick=function(a){this.client.invoke(netgis.Events.EXPORT_JPEG_SHOW,null)};netgis.Menu.prototype.onExportPNGClick=function(a){this.client.invoke(netgis.Events.EXPORT_PNG_SHOW,null)};
netgis.Menu.prototype.onExportGIFClick=function(a){this.client.invoke(netgis.Events.EXPORT_GIF_SHOW,null)};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.attach=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";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",PANNING:"PANNING",ZOOMING_IN:"ZOOMING_IN",ZOOMING_OUT:"ZOOMING_OUT",DRAW_POINTS:"DRAW_POINTS",DRAW_LINES:"DRAW_LINES",DRAW_POLYGONS:"DRAW_POLYGONS",CUT_FEATURE_BEGIN:"CUT_FEATURE_BEGIN",CUT_FEATURE_DRAW:"CUT_FEATURE_DRAW",MODIFY_FEATURES:"MODIFY_FEATURES",DELETE_FEATURES:"DELETE_FEATURES",BUFFER_FEATURE_BEGIN:"BUFFER_FEATURE_BEGIN",BUFFER_FEATURE_EDIT:"BUFFER_FEATURE_EDIT",SEARCH_PLACE:"SEARCH_PLACE",SEARCH_PARCEL:"SEARCH_PARCEL",PARCEL_SELECT:"PARCEL_SELECT",IMPORT:"IMPORT",
EXPORT:"EXPORT"});netgis=netgis||{};
netgis.OWS=function(){return{read:function(a,b){var c={layers:[],folders:[]};netgis.util.isDefined(a.properties)&&(c.bbox=a.properties.bbox);a=a.features;for(var d=0;d<a.length;d++){var e=a[d];if("Feature"===e.type){var f=e.properties;f=f.folder;var g=!1;for(e=0;e<c.folders.length;e++)if(c.folders[e].id===f){g=!0;break}if(!g){e=f.split("/");f=[];for(g=0;g<e.length;g++){var h=e[g];0<h.length&&f.push(h)}var k=-1;for(g=0;g<f.length;g++){h=f[g];var l="/"+f.slice(0,g+1).join("/"),m=!1;for(e=0;e<c.folders.length;e++)if(c.folders[e].path===
l){k=e;m=!0;break}m||(e=c.folders.length,c.folders.push({title:h,parent:k,path:l}),k=e)}}}}for(d=0;d<a.length;d++)if(e=a[d],"Feature"===e.type){f=e.properties;g=-1;for(e=0;e<c.folders.length;e++)if(c.folders[e].path===f.folder){g=e;break}e=f.offerings;for(h=0;h<e.length;h++)switch(k=e[h],l=k.operations,k.code){case "http://www.opengis.net/spec/owc-geojson/1.0/req/wms":c.layers.push({folder:g,type:netgis.LayerTypes.WMS,url:l[0].href,title:f.title,attribution:f.rights,active:f.active});break;case "http://www.opengis.net/spec/owc-geojson/1.0/req/xyz":k=
l[0];c.layers.push({folder:g,type:netgis.LayerTypes.XYZ,url:k.href,title:f.title,attribution:f.rights,active:f.active});break;case "http://www.opengis.net/spec/owc-geojson/1.0/req/osm":k=l[0],c.layers.push({folder:g,type:netgis.LayerTypes.XYZ,url:k.href,title:f.title,attribution:f.rights,active:f.active})}}b.invoke(netgis.Events.CONTEXT_UPDATE,c)}}}();netgis=netgis||{};netgis.Panel=function(a){this.initElements(a);this.initEvents()};netgis.Panel.prototype.initElements=function(a){var b=document.createElement("section");b.className="netgis-panel netgis-resize-right netgis-color-e netgis-shadow";this.addHeader(b,a,this.onHeaderClick.bind(this));this.container=b};netgis.Panel.prototype.initEvents=function(){this.resizeObserver=(new ResizeObserver(this.onResize.bind(this))).observe(this.container)};netgis.Panel.prototype.attach=function(a){a.appendChild(this.container)};
netgis.Panel.prototype.addHeader=function(a,b,c){var d=document.createElement("button");d.className="netgis-button netgis-clip-text netgis-color-c";d.innerHTML="<span>"+b+"</span><i class='netgis-icon fas fa-times'></i>";d.setAttribute("type","button");c&&(d.onclick=c);a&&a.appendChild(d);return d};netgis.Panel.prototype.show=function(){this.container.classList.add("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{panel:this,visible:!0})};
netgis.Panel.prototype.hide=function(){this.container.classList.remove("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{panel:this,visible:!1})};netgis.Panel.prototype.toggle=function(){this.container.classList.toggle("netgis-show");netgis.util.invoke(this.container,netgis.Events.PANEL_TOGGLE,{panel:this,visible:this.container.classList.contains("netgis-show")})};netgis.Panel.prototype.visible=function(){return this.container.classList.contains("netgis-show")};
netgis.Panel.prototype.width=function(){return this.container.getBoundingClientRect().width};netgis.Panel.prototype.onHeaderClick=function(a){this.hide()};netgis.Panel.prototype.onResize=function(a){this.container.classList.contains("netgis-show")&&(a=this.container.getBoundingClientRect(),netgis.util.invoke(this.container,netgis.Events.PANEL_RESIZE,{width:a.width}))};netgis=netgis||{};netgis.SearchParcel=function(a,b){this.client=b;this.config=a;this.initElements();this.initEvents()};netgis.SearchParcel.Events=Object.freeze({TOGGLE:"search-parcel-toggle"});
netgis.SearchParcel.prototype.initElements=function(){this.container=document.createElement("section");this.container.className="netgis-search-parcel";var a=document.createElement("section");this.top=a;this.container.appendChild(a);var b=this.createInput("Gemarkungsname:");b.style.position="relative";a.appendChild(b);this.nameInput=b.children[0];this.nameInput.setAttribute("title","ENTER: Ausw\u00e4hlen, ESCAPE: Zur\u00fccksetzen");this.nameInput.addEventListener("keyup",this.onInputNameKey.bind(this));
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";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)".split(";"));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.onParcelResetClick.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);var d=this;window.setTimeout(function(){d.reset()},50)};netgis.SearchParcel.prototype.initEvents=function(){this.resizeObserver=(new ResizeObserver(this.onTopResize.bind(this))).observe(this.top)};
netgis.SearchParcel.prototype.attach=function(a){a.appendChild(this.container)};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);for(d=0;d<a.length;d++){var f=document.createElement("th");f.innerHTML=a[d];e.appendChild(f)}a=document.createElement("tbody");c.appendChild(a);return b};
netgis.SearchParcel.prototype.createParcelItem=function(a,b,c,d,e,f,g){var h=document.createElement("tr");h.className="netgis-hover-light netgis-hover-text-primary";h.setAttribute("title","Klicken zum zoomen");h.setAttribute("data-id",d);h.setAttribute("data-field",a);h.setAttribute("data-parcel-a",b);h.setAttribute("data-parcel-b",c);h.setAttribute("data-bbox",f);h.setAttribute("data-geom",g);h.addEventListener("pointerenter",this.onParcelEnter.bind(this));h.addEventListener("pointerleave",this.onParcelLeave.bind(this));
h.addEventListener("click",this.onParcelClick.bind(this));f=document.createElement("td");h.appendChild(f);this.client.editable&&(g=document.createElement("button"),g.setAttribute("type","button"),g.setAttribute("title","Geometrie \u00fcbernehmen"),g.addEventListener("click",this.onParcelImportClick.bind(this)),g.className="netgis-text-primary netgis-hover-primary",g.innerHTML="<i class='fas fa-paste'></i>",f.appendChild(g));f=document.createElement("td");f.innerHTML=a;h.appendChild(f);a=document.createElement("td");
a.innerHTML=b;h.appendChild(a);b=document.createElement("td");b.innerHTML=c;h.appendChild(b);c=document.createElement("td");c.innerHTML=d;h.appendChild(c);d=document.createElement("td");d.innerHTML=e;h.appendChild(d);return h};
netgis.SearchParcel.prototype.reset=function(){this.hideBottom();this.nameLoader.classList.add("netgis-hide");this.nameInput.value="";this.districtInput.value="";this.fieldInput.value="";this.parcelInputA.value="";this.parcelInputB.value="";this.nameList.innerHTML="";this.parcelInfo.innerHTML="";this.parcelList.innerHTML="";this.parcelTable.classList.add("netgis-hide");this.parcelReset.classList.add("netgis-hide");this.parcelCount.innerHTML="";var a=this;window.setTimeout(function(){a.top.scrollTop=
0;a.parcelTable.scrollTop=0},10);netgis.util.invoke(this.container,netgis.Events.PARCELS_RESET,null)};netgis.SearchParcel.prototype.onInputNameKey=function(a){switch(a.keyCode){case 13:this.selectFirstName();break;case 27:this.reset();break;default:this.requestName(this.nameInput.value.trim())}};
netgis.SearchParcel.prototype.requestName=function(a){this.nameDebounce&&window.clearTimeout(this.nameDebounce);if(0!==a.length){var b=this.config.searchParcel.nameURL;b=netgis.util.replace(b,"{q}",window.encodeURIComponent(a));this.nameDebounce=window.setTimeout(this.onInputNameDebounce.bind(this,b),200);this.nameLoader.classList.remove("netgis-hide")}};netgis.SearchParcel.prototype.onInputNameDebounce=function(a){netgis.util.request(a,this.onInputNameResponse.bind(this))};
netgis.SearchParcel.prototype.onInputNameResponse=function(a){this.nameLoader.classList.add("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.requestFieldsGeom(b)};
netgis.SearchParcel.prototype.requestFieldsGeom=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.onFieldsGeomResponse.bind(this))};
netgis.SearchParcel.prototype.onFieldsGeomResponse=function(a){a=JSON.parse(a);netgis.util.invoke(this.container,netgis.Events.PARCELS_FIELDS_RESPONSE,{geojson:a})};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.requestFieldsGeom(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.requestParcel(this.districtInput.value.trim(),this.fieldInput.value.trim(),this.parcelInputA.value.trim(),this.parcelInputB.value.trim())};
netgis.SearchParcel.prototype.requestParcel=function(a,b,c,d){var e=this.config.searchParcel.parcelURL;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.parcelInfo.innerHTML="Suche Flurst\u00fccke...";netgis.util.request(e,this.onParcelResponse.bind(this))};
netgis.SearchParcel.prototype.onParcelResponse=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();netgis.util.invoke(this.container,netgis.Events.PARCELS_RESPONSE,{parcels:a.data})}this.parcelReset.classList.remove("netgis-hide");
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.PARCELS_ITEM_ENTER,a)};
netgis.SearchParcel.prototype.onParcelLeave=function(a){netgis.util.invoke(this.container,netgis.Events.PARCELS_ITEM_LEAVE,{id:a.target.getAttribute("data-id")})};netgis.SearchParcel.prototype.onParcelClick=function(a){netgis.util.invoke(this.container,netgis.Events.PARCELS_ITEM_CLICK,{id:a.currentTarget.getAttribute("data-id")})};
netgis.SearchParcel.prototype.onParcelImportClick=function(a){a.stopPropagation();var b=a.currentTarget.parentElement.parentElement;a=b.getAttribute("data-id");b=b.getAttribute("data-geom");netgis.util.invoke(this.container,netgis.Events.PARCELS_ITEM_IMPORT_CLICK,{id:a,geom:b})};netgis.SearchParcel.prototype.onParcelResetClick=function(a){this.reset()};
netgis.SearchParcel.prototype.onSetMode=function(a){a===netgis.Modes.SEARCH_PARCEL&&this.container.classList.contains("netgis-hide")?this.container.classList.remove("netgis-hide"):this.container.classList.add("netgis-hide")};netgis.SearchParcel.prototype.onLayerListToggle=function(a){this.container.classList.add("netgis-hide")};
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=netgis||{};"use strict";netgis=netgis||{};netgis.SearchPlace=function(a){this.config=a;this.debounce=400;this.initElements();this.initEvents()};netgis.SearchPlace.Events=Object.freeze({TOGGLE:"toggle",SELECT:"select"});
netgis.SearchPlace.prototype.initElements=function(){var a=document.createElement("div");a.className="netgis-search-place netgis-color-e netgis-shadow";this.input=document.createElement("input");this.input.setAttribute("type","text");this.input.setAttribute("placeholder","Suche...");a.appendChild(this.input);this.list=document.createElement("ul");a.appendChild(this.list);this.closer=document.createElement("button");this.closer.setAttribute("type","button");this.closer.className="netgis-button";this.closer.innerHTML=
"<i class='fas fa-times'></i>";this.closer.addEventListener("click",this.onCloserClick.bind(this));a.appendChild(this.closer);this.container=a};
netgis.SearchPlace.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.input.addEventListener("click",this.onInputClick.bind(this));this.container.addEventListener("focusout",this.onFocusOut.bind(this))};netgis.SearchPlace.prototype.attach=function(a){a.appendChild(this.container)};
netgis.SearchPlace.prototype.toggle=function(){this.container.classList.toggle("netgis-show");this.container.classList.contains("netgis-show")?this.input.focus():this.list.classList.add("netgis-hide")};
netgis.SearchPlace.prototype.requestSearch=function(a){if(!this.lastQuery||this.lastQuery!==a){this.lastQuery=a;var b=this.config.search.url;b=netgis.util.replace(b,"{q}",window.encodeURIComponent(a));b=netgis.util.replace(b,"{epsg}",4326);b=window.encodeURI(b);this.lastRequest=netgis.util.request(b,this.onSearchResponse.bind(this))}};
netgis.SearchPlace.prototype.createResult=function(a,b,c,d,e){var f=document.createElement("li"),g=document.createElement("button");g.className="netgis-button netgis-clip-text netgis-color-e netgis-hover-a";g.innerHTML=a;g.setAttribute("type","button");g.setAttribute("title",a);g.setAttribute("data-minx",b);g.setAttribute("data-miny",c);g.setAttribute("data-maxx",d);g.setAttribute("data-maxy",e);g.addEventListener("click",this.onResultClick.bind(this));f.appendChild(g);return f};
netgis.SearchPlace.prototype.onSearchResponse=function(a){a=JSON.parse(a);console.info("Search Response:",a);this.list.innerHTML="";this.list.classList.remove("netgis-hide");if(a.geonames){a=a.geonames;for(var b=0;b<a.length;b++){var c=a[b],d=this.createResult(c.title,Number.parseFloat(c.minx),Number.parseFloat(c.miny),Number.parseFloat(c.maxx),Number.parseFloat(c.maxy));d.children[0].setAttribute("data-title",c.title);this.list.appendChild(d)}}};
netgis.SearchPlace.prototype.onInputKeyDown=function(a){if(13===a.keyCode)return this.list.classList.remove("netgis-hide"),a.preventDefault(),!1};netgis.SearchPlace.prototype.onInputKeyUp=function(a){switch(a.keyCode){case 13:break;case 27:this.toggle();break;default:this.onInputChange()}};netgis.SearchPlace.prototype.onInputChange=function(a){this.timeout&&window.clearTimeout(this.timeout);this.timeout=window.setTimeout(this.onInputTimeout.bind(this),this.debounce)};
netgis.SearchPlace.prototype.onInputTimeout=function(){var a=this.input.value;a=a.trim();0<a.length&&this.requestSearch(a)};netgis.SearchPlace.prototype.onInputClick=function(a){this.list.classList.toggle("netgis-hide")};netgis.SearchPlace.prototype.onFocusOut=function(a){a=a.relatedTarget;a!==this.input&&a!==this.list&&(a&&a.parentNode===this.list||a&&a.parentNode.parentNode===this.list||this.list.classList.add("netgis-hide"))};
netgis.SearchPlace.prototype.onResultClick=function(a){a=a.currentTarget;var b=Number.parseFloat(a.getAttribute("data-minx")),c=Number.parseFloat(a.getAttribute("data-miny")),d=Number.parseFloat(a.getAttribute("data-maxx")),e=Number.parseFloat(a.getAttribute("data-maxy")),f=a.getAttribute("data-title");netgis.util.invoke(a,netgis.SearchPlace.Events.SELECT,{minx:b,miny:c,maxx:d,maxy:e,title:f})};
netgis.SearchPlace.prototype.onCloserClick=function(a){this.toggle();this.list.innerHTML="";this.input.value=""};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.initEvents();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";this.header.style.background="orange";this.container.appendChild(this.header);this.content=document.createElement("div");this.content.className="netgis-content";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.initEvents=function(){};netgis.Tabs.prototype.attach=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"),f.classList.remove("netgis-hide")):(e.classList.remove("netgis-color-e"),e.classList.remove("netgis-text-a"),e.classList.remove("netgis-bar-a"),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.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.Toolbar=function(){this.client=null;this.toolbars={};this.searchValue=""};
netgis.Toolbar.prototype.load=function(){var a=this.client.config;this.root=document.createElement("section");this.root.className="netgis-toolbars";if(this.client.editable){var b=1E3,c=3;netgis.util.isDefined(a.tools)&&(netgis.util.isDefined(a.tools.buffer.defaultRadius)&&(b=a.tools.buffer.defaultRadius),netgis.util.isDefined(a.tools.buffer.defaultSegments)&&(c=a.tools.buffer.defaultSegments));this.toolbars[netgis.Modes.DRAW_POINTS]=this.createToolbar();this.append(this.toolbars[netgis.Modes.DRAW_POINTS],
this.createToolbarButton('<i class="fas fa-times"></i><span>Punkte zeichnen:</span>',this.onToolbarClose.bind(this)));this.append(this.toolbars[netgis.Modes.DRAW_POINTS],this.createToolbarCheckbox("Einrasten",this.onSnapChange.bind(this)));this.append(this.toolbars[netgis.Modes.DRAW_POINTS],this.createToolbarCheckbox("Puffern",this.onDrawBufferChange.bind(this)));this.append(this.toolbars[netgis.Modes.DRAW_POINTS],this.createToolbarInput("Radius (Meter):",b,this.onDrawBufferRadiusChange.bind(this)));
this.append(this.toolbars[netgis.Modes.DRAW_POINTS],this.createToolbarInput("Segmente:",c,this.onDrawBufferSegmentsChange.bind(this)));this.root.appendChild(this.toolbars[netgis.Modes.DRAW_POINTS]);this.toolbars[netgis.Modes.DRAW_LINES]=this.createToolbar();this.append(this.toolbars[netgis.Modes.DRAW_LINES],this.createToolbarButton('<i class="fas fa-times"></i><span>Linien zeichnen:</span>',this.onToolbarClose.bind(this)));this.append(this.toolbars[netgis.Modes.DRAW_LINES],this.createToolbarCheckbox("Einrasten",
this.onSnapChange.bind(this)));this.append(this.toolbars[netgis.Modes.DRAW_LINES],this.createToolbarCheckbox("Puffern",this.onDrawBufferChange.bind(this)));this.append(this.toolbars[netgis.Modes.DRAW_LINES],this.createToolbarInput("Radius (Meter):",b,this.onDrawBufferRadiusChange.bind(this)));this.append(this.toolbars[netgis.Modes.DRAW_LINES],this.createToolbarInput("Segmente:",c,this.onDrawBufferSegmentsChange.bind(this)));this.root.appendChild(this.toolbars[netgis.Modes.DRAW_LINES]);this.showDrawBufferOptions(!1);
this.toolbars[netgis.Modes.DRAW_POLYGONS]=this.createToolbar();this.append(this.toolbars[netgis.Modes.DRAW_POLYGONS],this.createToolbarButton('<i class="fas fa-times"></i><span>Polygone zeichnen:</span>',this.onToolbarClose.bind(this)));this.append(this.toolbars[netgis.Modes.DRAW_POLYGONS],this.createToolbarCheckbox("Einrasten",this.onSnapChange.bind(this)));this.append(this.toolbars[netgis.Modes.DRAW_POLYGONS],this.createToolbarCheckbox("Tracing",this.onTracingChange.bind(this)));this.root.appendChild(this.toolbars[netgis.Modes.DRAW_POLYGONS]);
this.toolbars[netgis.Modes.CUT_FEATURE_BEGIN]=this.createToolbar();this.append(this.toolbars[netgis.Modes.CUT_FEATURE_BEGIN],this.createToolbarButton('<i class="fas fa-times"></i><span>Feature zum Ausschneiden w\u00e4hlen:</span>',this.onToolbarClose.bind(this)));this.root.appendChild(this.toolbars[netgis.Modes.CUT_FEATURE_BEGIN]);this.toolbars[netgis.Modes.CUT_FEATURE_DRAW]=this.createToolbar();this.append(this.toolbars[netgis.Modes.CUT_FEATURE_DRAW],this.createToolbarButton('<i class="fas fa-times"></i><span>Fl\u00e4che zum Ausschneiden zeichnen:</span>',
this.onToolbarClose.bind(this)));this.root.appendChild(this.toolbars[netgis.Modes.CUT_FEATURE_DRAW]);this.toolbars[netgis.Modes.MODIFY_FEATURES]=this.createToolbar();this.append(this.toolbars[netgis.Modes.MODIFY_FEATURES],this.createToolbarButton('<i class="fas fa-times"></i><span>Feature-Eckpunkte verschieben:</span>',this.onToolbarClose.bind(this)));this.root.appendChild(this.toolbars[netgis.Modes.MODIFY_FEATURES]);this.toolbars[netgis.Modes.DELETE_FEATURES]=this.createToolbar();this.append(this.toolbars[netgis.Modes.DELETE_FEATURES],
this.createToolbarButton('<i class="fas fa-times"></i><span>Features l\u00f6schen:</span>',this.onToolbarClose.bind(this)));this.root.appendChild(this.toolbars[netgis.Modes.DELETE_FEATURES]);this.toolbars[netgis.Modes.BUFFER_FEATURE_BEGIN]=this.createToolbar();this.append(this.toolbars[netgis.Modes.BUFFER_FEATURE_BEGIN],this.createToolbarButton('<i class="fas fa-times"></i><span>Feature zum Puffern w\u00e4hlen:</span>',this.onToolbarClose.bind(this)));this.root.appendChild(this.toolbars[netgis.Modes.BUFFER_FEATURE_BEGIN]);
this.toolbars[netgis.Modes.BUFFER_FEATURE_EDIT]=this.createToolbar();this.append(this.toolbars[netgis.Modes.BUFFER_FEATURE_EDIT],this.createToolbarButton('<i class="fas fa-times"></i><span>Feature puffern:</span>',this.onBufferCancel.bind(this)));this.append(this.toolbars[netgis.Modes.BUFFER_FEATURE_EDIT],this.createToolbarInput("Radius (Meter):",b,this.onBufferChange.bind(this)));this.append(this.toolbars[netgis.Modes.BUFFER_FEATURE_EDIT],this.createToolbarInput("Segmente:",c,this.onBufferChange.bind(this)));
this.append(this.toolbars[netgis.Modes.BUFFER_FEATURE_EDIT],this.createToolbarButton('<i class="fas fa-check"></i><span>OK</span>',this.onBufferAccept.bind(this)));a=this.toolbars[netgis.Modes.BUFFER_FEATURE_EDIT].getElementsByTagName("input");a[0].addEventListener("keyup",this.onBufferKeyUp.bind(this));a[1].addEventListener("keyup",this.onBufferKeyUp.bind(this));a[1].setAttribute("min",1);this.root.appendChild(this.toolbars[netgis.Modes.BUFFER_FEATURE_EDIT])}this.toolbars[netgis.Modes.SEARCH_PLACE]=
this.createToolbar();this.append(this.toolbars[netgis.Modes.SEARCH_PLACE],this.createToolbarButton('<i class="fas fa-times"></i><span>Suche:</span>',this.onToolbarClose.bind(this)));a=this.createToolbarInputText("Adresse...","",null);a.style.position="relative";this.searchInput=a.getElementsByTagName("input")[0];this.searchInput.addEventListener("keyup",this.onSearchKeyUp.bind(this));this.searchInput.addEventListener("focus",this.onSearchFocus.bind(this));this.searchInput.addEventListener("blur",
this.onSearchBlur.bind(this));this.append(this.toolbars[netgis.Modes.SEARCH_PLACE],a);this.searchList=document.createElement("ul");this.searchList.className="netgis-dropdown-content netgis-search-list netgis-dialog netgis-shadow netgis-hide";a.appendChild(this.searchList);this.append(this.toolbars[netgis.Modes.SEARCH_PLACE],this.createToolbarButton('<i class="fas fa-undo"></i>',this.onSearchClear.bind(this)));this.root.appendChild(this.toolbars[netgis.Modes.SEARCH_PLACE]);this.client.root.appendChild(this.root);
this.client.on(netgis.Events.SET_MODE,this.onSetMode.bind(this));this.client.on(netgis.Events.SEARCH_PLACE_RESPONSE,this.onSearchPlaceResponse.bind(this))};netgis.Toolbar.prototype.createToolbar=function(){var a=document.createElement("div");a.className="netgis-toolbar netgis-dialog netgis-shadow netgis-hide";var b=document.createElement("div");a.appendChild(b);return a};netgis.Toolbar.prototype.append=function(a,b){a.getElementsByTagName("div")[0].appendChild(b)};
netgis.Toolbar.prototype.createToolbarButton=function(a,b){var c=document.createElement("button");c.setAttribute("type","button");c.className="netgis-hover-light";c.innerHTML=a;c.addEventListener("click",b);return c};
netgis.Toolbar.prototype.createToolbarCheckbox=function(a,b){var c=document.createElement("label");c.className="netgis-hover-light";var d=document.createElement("input");d.setAttribute("type","checkbox");d.addEventListener("change",b);c.appendChild(d);a=document.createTextNode(a);c.appendChild(a);return c};
netgis.Toolbar.prototype.createToolbarInput=function(a,b,c){var d=document.createElement("label");d.className="netgis-hover-light";a=document.createTextNode(a);d.appendChild(a);a=document.createElement("input");a.setAttribute("type","number");a.setAttribute("min",0);a.value=b;a.addEventListener("change",c);a.addEventListener("keyup",c);d.appendChild(a);return d};
netgis.Toolbar.prototype.createToolbarInputText=function(a,b,c){var d=document.createElement("label");d.className="netgis-hover-light";var e=document.createElement("input");e.setAttribute("type","text");e.setAttribute("placeholder",a);e.value=b;c&&e.addEventListener("change",c);d.appendChild(e);return d};
netgis.Toolbar.prototype.onSetMode=function(a){var b=!this.toolbars[netgis.Modes.SEARCH_PLACE].classList.contains("netgis-hide");netgis.util.foreach(this.toolbars,function(b,d){b===a?d.classList.remove("netgis-hide"):d.classList.add("netgis-hide")});switch(a){case netgis.Modes.SEARCH_PLACE:b?this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.VIEW):this.searchInput.focus();break;case netgis.Modes.BUFFER_FEATURE_EDIT:this.updateBuffer();break;case netgis.Modes.DRAW_POINTS:case netgis.Modes.DRAW_LINES:this.toolbars[netgis.Modes.DRAW_POINTS].getElementsByTagName("input")[1].checked&&
this.client.invoke(netgis.Events.DRAW_BUFFER_ON,null)}};netgis.Toolbar.prototype.onToolbarClose=function(a){this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.VIEW)};netgis.Toolbar.prototype.searchRequest=function(a){a=a.trim();a!==this.searchValue&&(this.searchValue=a,0<a.length&&this.client.invoke(netgis.Events.SEARCH_PLACE_REQUEST,{query:a}))};netgis.Toolbar.prototype.searchClear=function(){this.searchInput.value="";this.searchList.innerHTML=""};
netgis.Toolbar.prototype.searchSelectFirst=function(){var a=this.searchList.getElementsByTagName("button");if(0<a.length)this.onSearchItemClick({target:a[0]})};netgis.Toolbar.prototype.onSearchKeyUp=function(a){var b=a.target;switch(a.keyCode){case 13:this.searchSelectFirst();this.searchList.classList.add("netgis-hide");break;case 27:this.searchClear();break;default:this.searchRequest(b.value)}};netgis.Toolbar.prototype.onSearchChange=function(a){this.searchRequest(a.target.value)};
netgis.Toolbar.prototype.onSearchClear=function(a){this.searchClear();this.searchInput.focus()};netgis.Toolbar.prototype.onSearchFocus=function(a){this.searchList.classList.remove("netgis-hide")};netgis.Toolbar.prototype.onSearchBlur=function(a){this.searchList.classList.add("netgis-hide")};
netgis.Toolbar.prototype.onSearchPlaceResponse=function(a){this.searchList.innerHTML="";a=a.geonames;for(var b=0;b<a.length;b++){var c=a[b],d=document.createElement("li");d.className="netgis-hover-light";var e=document.createElement("button");e.setAttribute("type","button");e.innerHTML=c.title;e.dataset.title=c.title;e.dataset.minx=c.minx;e.dataset.miny=c.miny;e.dataset.maxx=c.maxx;e.dataset.maxy=c.maxy;e.addEventListener("mousedown",this.onSearchItemClick.bind(this));d.appendChild(e);this.searchList.appendChild(d)}};
netgis.Toolbar.prototype.onSearchItemClick=function(a){var b=a.target;a=b.dataset.title;var c=Number.parseFloat(b.dataset.minx),d=Number.parseFloat(b.dataset.miny),e=Number.parseFloat(b.dataset.maxx);b=Number.parseFloat(b.dataset.maxy);this.client.invoke(netgis.Events.MAP_SET_EXTENT,{minx:c,miny:d,maxx:e,maxy:b});this.searchValue=a};
netgis.Toolbar.prototype.updateBuffer=function(){var a=this.toolbars[netgis.Modes.BUFFER_FEATURE_EDIT].getElementsByTagName("input"),b=Number.parseFloat(a[0].value);a=Number.parseInt(a[1].value);this.client.invoke(netgis.Events.BUFFER_CHANGE,{radius:b,segments:a})};netgis.Toolbar.prototype.onBufferChange=function(a){this.updateBuffer()};netgis.Toolbar.prototype.onBufferKeyUp=function(a){this.updateBuffer()};
netgis.Toolbar.prototype.onBufferAccept=function(a){this.client.invoke(netgis.Events.BUFFER_ACCEPT,null);this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.VIEW)};netgis.Toolbar.prototype.onBufferCancel=function(a){this.client.invoke(netgis.Events.BUFFER_CANCEL,null);this.client.invoke(netgis.Events.SET_MODE,netgis.Modes.VIEW)};
netgis.Toolbar.prototype.onSnapChange=function(a){a=a.target.checked;this.toolbars[netgis.Modes.DRAW_POINTS].getElementsByTagName("input")[0].checked=a;this.toolbars[netgis.Modes.DRAW_LINES].getElementsByTagName("input")[0].checked=a;this.toolbars[netgis.Modes.DRAW_POLYGONS].getElementsByTagName("input")[0].checked=a;this.client.invoke(a?netgis.Events.SNAP_ON:netgis.Events.SNAP_OFF,null)};
netgis.Toolbar.prototype.onTracingChange=function(a){a=a.target.checked;var b=this.toolbars[netgis.Modes.DRAW_POLYGONS].getElementsByTagName("input")[0],c=b.checked;a&&!c&&(b.checked=a,this.client.invoke(netgis.Events.SNAP_ON,null));this.client.invoke(a?netgis.Events.TRACING_ON:netgis.Events.TRACING_OFF,null)};
netgis.Toolbar.prototype.onDrawBufferChange=function(a){a=a.target.checked;this.toolbars[netgis.Modes.DRAW_POINTS].getElementsByTagName("input")[1].checked=a;this.toolbars[netgis.Modes.DRAW_LINES].getElementsByTagName("input")[1].checked=a;this.client.invoke(a?netgis.Events.DRAW_BUFFER_ON:netgis.Events.DRAW_BUFFER_OFF,null);this.showDrawBufferOptions(a);if(a){a=!0;this.toolbars[netgis.Modes.DRAW_LINES].classList.contains("netgis-hide")||(a=!1);var b=this.toolbars[a?netgis.Modes.DRAW_POINTS:netgis.Modes.DRAW_LINES].getElementsByTagName("input");
a=Number.parseInt(b[2].value);b=Number.parseInt(b[3].value);this.client.invoke(netgis.Events.DRAW_BUFFER_RADIUS_CHANGE,a);this.client.invoke(netgis.Events.DRAW_BUFFER_SEGMENTS_CHANGE,b)}};
netgis.Toolbar.prototype.onDrawBufferRadiusChange=function(a){a=a.target;var b=Number.parseFloat(a.value);this.client.invoke(netgis.Events.DRAW_BUFFER_RADIUS_CHANGE,b);var c=this.toolbars[netgis.Modes.DRAW_POINTS].getElementsByTagName("input")[2];a!==c&&(c.value=b);c=this.toolbars[netgis.Modes.DRAW_LINES].getElementsByTagName("input")[2];a!==c&&(c.value=b)};
netgis.Toolbar.prototype.onDrawBufferSegmentsChange=function(a){a=a.target;var b=Number.parseInt(a.value);this.client.invoke(netgis.Events.DRAW_BUFFER_SEGMENTS_CHANGE,b);var c=this.toolbars[netgis.Modes.DRAW_POINTS].getElementsByTagName("input")[3];a!==c&&(c.value=b);c=this.toolbars[netgis.Modes.DRAW_LINES].getElementsByTagName("input")[3];a!==c&&(c.value=b)};
netgis.Toolbar.prototype.showDrawBufferOptions=function(a){var b=this.toolbars[netgis.Modes.DRAW_POINTS].children[0].children,c=this.toolbars[netgis.Modes.DRAW_LINES].children[0].children;a?(b[3].classList.remove("netgis-hide"),b[4].classList.remove("netgis-hide"),c[3].classList.remove("netgis-hide"),c[4].classList.remove("netgis-hide")):(b[3].classList.add("netgis-hide"),b[4].classList.add("netgis-hide"),c[3].classList.add("netgis-hide"),c[4].classList.add("netgis-hide"))};netgis=netgis||{};netgis.Toolbox=function(a){this.initElements(a);this.initEvents()};
netgis.Toolbox.prototype.initElements=function(a){this.container=document.createElement("section");this.container.className="netgis-toolbox";var b=document.createElement("section");this.container.appendChild(b);this.top=b;this.addButton(this.top,"<i class='netgis-icon netgis-text-a fas fa-hand-paper'></i><span>Betrachten</span>",netgis.util.handler(netgis.Events.SET_MODE,netgis.Modes.VIEW));this.addButton(this.top,"<i class='netgis-icon netgis-text-a fas fa-map-marker-alt'></i><span>Punkte</span>",
netgis.util.handler(netgis.Events.SET_MODE,netgis.Modes.DRAW_POINTS));this.addButton(this.top,"<i class='netgis-icon netgis-text-a fas fa-minus'></i><span>Linien</span>",netgis.util.handler(netgis.Events.SET_MODE,netgis.Modes.DRAW_LINES));this.addButton(this.top,"<i class='netgis-icon netgis-text-a fas fa-vector-square'></i><span>Polygone</span>",netgis.util.handler(netgis.Events.SET_MODE,netgis.Modes.DRAW_POLYGONS));this.addButton(this.top,"<i class='netgis-icon netgis-text-a fas fa-arrows-alt'></i><span>Verschieben</span>",
netgis.util.handler(netgis.Events.SET_MODE,netgis.Modes.MODIFY_FEATURES));this.addButton(this.top,"<i class='netgis-icon netgis-text-a fas fa-eraser'></i><span>L\u00f6schen</span>",netgis.util.handler(netgis.Events.SET_MODE,netgis.Modes.DELETE_FEATURES));this.addButton(this.top,"<i class='netgis-icon netgis-text-a far fa-dot-circle'></i><span>Puffern</span>",netgis.util.handler(netgis.Events.SET_MODE,netgis.Modes.BUFFER_FEATURE_BEGIN));this.addButton(this.top,"<i class='netgis-icon netgis-text-a fas fa-cut'></i><span>Ausschneiden</span>",
netgis.util.handler(netgis.Events.SET_MODE,netgis.Modes.CUT_FEATURE_BEGIN));this.addButton(this.top,"<i class='netgis-icon netgis-text-a fas fa-file-upload'></i><span>Importieren</span>",netgis.util.handler(netgis.Events.IMPORT_SHOW));this.addButton(this.top,"<i class='netgis-icon netgis-text-a fas fa-file-download'></i><span>Exportieren</span>",netgis.util.handler(netgis.Events.EXPORT_SHOW));b=document.createElement("section");b.className="netgis-hide";this.container.appendChild(b);this.bottom=b;
var c=document.createElement("button");c.className="netgis-button netgis-clip-text netgis-color-c";c.innerHTML="<span>Einstellungen</span><i class='netgis-icon fas fa-times'></i>";c.setAttribute("type","button");c.addEventListener("click",this.onBottomHeaderClick.bind(this));b.appendChild(c);this.bottomTitle=c.getElementsByTagName("span")[0];this.bottomPanels={};b=a.tools.buffer.defaultRadius;a=a.tools.buffer.defaultSegments;c=document.createElement("div");this.addCheckbox(c,"Einrasten",netgis.util.handler(netgis.Events.SNAP_TOGGLE));
this.addCheckbox(c,"Puffern",netgis.util.handler(netgis.Events.BUFFER_TOGGLE));this.addInputNumber(c,"Radius (Meter):",b,netgis.util.handler(netgis.Events.DRAW_BUFFER_RADIUS_CHANGE));this.addInputNumber(c,"Segmente:",a,netgis.util.handler(netgis.Events.DRAW_BUFFER_SEGMENTS_CHANGE));this.bottomPanels[netgis.Modes.DRAW_POINTS]=c;c=document.createElement("div");this.addCheckbox(c,"Einrasten",netgis.util.handler(netgis.Events.SNAP_TOGGLE));this.addCheckbox(c,"Puffern",netgis.util.handler(netgis.Events.BUFFER_TOGGLE));
this.addInputNumber(c,"Radius (Meter):",b,netgis.util.handler(netgis.Events.DRAW_BUFFER_RADIUS_CHANGE));this.addInputNumber(c,"Segmente:",a,netgis.util.handler(netgis.Events.DRAW_BUFFER_SEGMENTS_CHANGE));this.bottomPanels[netgis.Modes.DRAW_LINES]=c;c=document.createElement("div");this.addCheckbox(c,"Einrasten",netgis.util.handler(netgis.Events.SNAP_TOGGLE));this.addCheckbox(c,"Tracing",netgis.util.handler(netgis.Events.TRACING_TOGGLE));this.bottomPanels[netgis.Modes.DRAW_POLYGONS]=c;c=document.createElement("div");
this.addInputNumber(c,"Radius (Meter):",b,this.onBufferFeatureChange.bind(this));this.addInputNumber(c,"Segmente:",a,this.onBufferFeatureChange.bind(this));this.addButton(c,"<i class='netgis-icon netgis-text-a fas fa-arrow-circle-right'></i><span>Akzeptieren</span>",this.onBufferFeatureAccept.bind(this));this.bottomPanels[netgis.Modes.BUFFER_FEATURE_EDIT]=c;b=document.createElement("div");this.addButton(b,"<i class='netgis-icon netgis-text-a fas fa-file-upload'></i><span>Shapefile</span>",netgis.util.handler(netgis.Events.IMPORT_SHAPEFILE_SHOW));
this.addButton(b,"<i class='netgis-icon netgis-text-a fas fa-file-upload'></i><span>GeoJSON</span>",netgis.util.handler(netgis.Events.IMPORT_GEOJSON_SHOW));this.addButton(b,"<i class='netgis-icon netgis-text-a fas fa-file-upload'></i><span>GML</span>",netgis.util.handler(netgis.Events.IMPORT_GML_SHOW));this.addButton(b,"<i class='netgis-icon netgis-text-a fas fa-file-upload'></i><span>Spatialite</span>",netgis.util.handler(netgis.Events.IMPORT_SPATIALITE_SHOW));this.addButton(b,"<i class='netgis-icon netgis-text-a fas fa-file-upload'></i><span>Geopackage</span>",
netgis.util.handler(netgis.Events.IMPORT_GEOPACKAGE_SHOW));this.bottomPanels[netgis.Modes.IMPORT]=b;b=document.createElement("div");this.addButton(b,"<i class='netgis-icon netgis-text-a fas fa-file-download'></i><span>PDF</span>",netgis.util.handler(netgis.Events.EXPORT_PDF_SHOW));this.addButton(b,"<i class='netgis-icon netgis-text-a fas fa-file-download'></i><span>JPEG</span>",netgis.util.handler(netgis.Events.EXPORT_JPEG_SHOW));this.addButton(b,"<i class='netgis-icon netgis-text-a fas fa-file-download'></i><span>PNG</span>",
netgis.util.handler(netgis.Events.EXPORT_PNG_SHOW));this.addButton(b,"<i class='netgis-icon netgis-text-a fas fa-file-download'></i><span>GIF</span>",netgis.util.handler(netgis.Events.EXPORT_GIF_SHOW));this.bottomPanels[netgis.Modes.EXPORT]=b;this.setBuffer(!1)};netgis.Toolbox.prototype.initEvents=function(){this.resizeObserver=(new ResizeObserver(this.onTopResize.bind(this))).observe(this.top)};netgis.Toolbox.prototype.attach=function(a){a.appendChild(this.container)};
netgis.Toolbox.prototype.addButton=function(a,b,c){var d=document.createElement("button");d.className="netgis-button netgis-clip-text netgis-color-e netgis-hover-a";d.innerHTML=b;d.setAttribute("type","button");c&&(d.onclick=c);a&&a.appendChild(d);return d};
netgis.Toolbox.prototype.addCheckbox=function(a,b,c){var d=document.createElement("label");d.className="netgis-noselect netgis-hover-a";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-hover-a";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.setMode=function(a){for(var b=this.top.getElementsByTagName("button"),c=0;c<b.length;c++)b[c].classList.remove("netgis-bold");for(var d in this.bottomPanels)c=this.bottomPanels[d],c.parentNode===this.bottom&&this.bottom.removeChild(c);switch(a){case netgis.Modes.VIEW:b[0].classList.add("netgis-bold");this.bottomTitle.innerHTML="";break;case netgis.Modes.DRAW_POINTS:b[1].classList.add("netgis-bold");this.bottomTitle.innerHTML="Punkte";break;case netgis.Modes.DRAW_LINES:b[2].classList.add("netgis-bold");
this.bottomTitle.innerHTML="Linien";break;case netgis.Modes.DRAW_POLYGONS:b[3].classList.add("netgis-bold");this.bottomTitle.innerHTML="Polygone";break;case netgis.Modes.MODIFY_FEATURES:b[4].classList.add("netgis-bold");this.bottomTitle.innerHTML="Verschieben";break;case netgis.Modes.DELETE_FEATURES:b[5].classList.add("netgis-bold");this.bottomTitle.innerHTML="L\u00f6schen";break;case netgis.Modes.BUFFER_FEATURE_BEGIN:case netgis.Modes.BUFFER_FEATURE_EDIT:b[6].classList.add("netgis-bold");this.bottomTitle.innerHTML=
"Puffern";break;case netgis.Modes.CUT_FEATURE_BEGIN:case netgis.Modes.CUT_FEATURE_DRAW:b[7].classList.add("netgis-bold");this.bottomTitle.innerHTML="Ausschneiden";break;case netgis.Modes.IMPORT:b[8].classList.add("netgis-bold");this.bottomTitle.innerHTML="Importieren";break;case netgis.Modes.EXPORT:b[9].classList.add("netgis-bold"),this.bottomTitle.innerHTML="Exportieren"}(c=this.bottomPanels[a])?(this.bottom.appendChild(c),this.showBottom()):this.hideBottom()};
netgis.Toolbox.prototype.setSnap=function(a){this.bottomPanels[netgis.Modes.DRAW_POINTS].getElementsByTagName("input")[0].checked=a;this.bottomPanels[netgis.Modes.DRAW_LINES].getElementsByTagName("input")[0].checked=a;this.bottomPanels[netgis.Modes.DRAW_POLYGONS].getElementsByTagName("input")[0].checked=a};
netgis.Toolbox.prototype.setBuffer=function(a){var b=this.bottomPanels[netgis.Modes.DRAW_POINTS].getElementsByTagName("label"),c=this.bottomPanels[netgis.Modes.DRAW_LINES].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.setBufferRadius=function(a){var b=this.bottomPanels[netgis.Modes.DRAW_POINTS].getElementsByTagName("input"),c=this.bottomPanels[netgis.Modes.DRAW_LINES].getElementsByTagName("input");b[2].value=a;c[2].value=a};
netgis.Toolbox.prototype.setBufferSegments=function(a){var b=this.bottomPanels[netgis.Modes.DRAW_POINTS].getElementsByTagName("input"),c=this.bottomPanels[netgis.Modes.DRAW_LINES].getElementsByTagName("input");b[3].value=a;c[3].value=a};netgis.Toolbox.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.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.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.container,netgis.Events.SET_MODE,netgis.Modes.VIEW)};netgis.Toolbox.prototype.onBufferFeatureChange=function(a){var b=this.bottomPanels[netgis.Modes.BUFFER_FEATURE_EDIT].getElementsByTagName("input");a=Number.parseFloat(b[0].value);b=Number.parseInt(b[1].value);netgis.util.invoke(this.container,netgis.Events.BUFFER_CHANGE,{radius:a,segments:b})};
netgis.Toolbox.prototype.onBufferFeatureAccept=function(a){netgis.util.invoke(this.container,netgis.Events.BUFFER_ACCEPT,null);netgis.util.invoke(this.container,netgis.Events.SET_MODE,netgis.Modes.VIEW)};netgis=netgis||{};netgis.Tree=function(){this.initElements()};netgis.Tree.Events=Object.freeze({ITEM_CHANGE:"item-change"});netgis.Tree.prototype.initElements=function(){var a=document.createElement("ul");a.className="netgis-tree";this.container=a};netgis.Tree.prototype.attach=function(a){a.appendChild(this.container)};
netgis.Tree.prototype.addFolder=function(a,b,c,d){var e=document.createElement("li");e.className="netgis-folder";e.setAttribute("data-id",b);b=document.createElement("details");e.appendChild(b);var f=document.createElement("summary");f.className="netgis-button netgis-noselect netgis-clip-text netgis-color-e netgis-hover-a";f.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(f);c=document.createElement("label");
f.appendChild(c);f=document.createElement("input");f.setAttribute("type","checkbox");f.onchange=this.onFolderChange.bind(this);c.appendChild(f);c=document.createElement("ul");b.appendChild(c);a=a?a.getElementsByTagName("ul")[0]:this.container;d?a.insertBefore(e,a.firstChild):a.appendChild(e);return e};
netgis.Tree.prototype.addCheckbox=function(a,b,c){var d=document.createElement("li");d.className="netgis-item";var e=document.createElement("label");e.className="netgis-button netgis-noselect netgis-clip-text netgis-color-e netgis-hover-a";e.innerHTML="<span>"+c+"</span>";d.appendChild(e);c=document.createElement("input");c.setAttribute("type","checkbox");c.setAttribute("data-id",b);c.onchange=this.onItemChange.bind(this);e.insertBefore(c,e.firstChild);a?a.getElementsByTagName("ul")[0].appendChild(d):
this.container.appendChild(d);return d};netgis.Tree.prototype.addButton=function(a,b,c){var d=document.createElement("li"),e=document.createElement("button");e.innerHTML=b;e.className="netgis-button netgis-color-e netgis-text-a netgis-hover-a netgis-clip-text";e.setAttribute("type","button");d.appendChild(e);c&&(e.onclick=c);a?a.getElementsByTagName("ul")[0].appendChild(d):this.container.appendChild(d);return d};
netgis.Tree.prototype.setItemChecked=function(a,b){var c=this.container.getElementsByClassName("netgis-item");a=a.toString();for(var d=0;d<c.length;d++){var e=c[d].getElementsByTagName("input")[0];e.getAttribute("data-id")===a&&e.checked!==b&&e.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.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);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=Number.parseInt(c);Number.isNaN(d)||(c=d);d=a.parentElement.parentElement.parentElement.parentElement.parentElement;netgis.util.invoke(a,netgis.Tree.Events.ITEM_CHANGE,{id:c,checked:b});-1!==d.className.search("netgis-folder")&&this.updateFolderCheck(d)};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},isString:function(a){return"string"===typeof a||a instanceof String},replace:function(a,b,e){return a.replace(new RegExp(b,"g"),e)},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]},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){var c=new XMLHttpRequest;c.onload=function(){b(this.responseText)};c.open("GET",a,!0);c.send()},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]},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")},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)}}}}();

View File

@@ -13,9 +13,9 @@
</div> </div>
{% endif %} {% endif %}
{% if geom_form.geom.errors %} {% if geom_form.output.errors %}
<div class="alert-danger p-2"> <div class="alert-danger p-2">
{% for error in geom_form.geom.errors %} {% for error in geom_form.output.errors %}
<strong class="invalid">{{ error }}</strong> <strong class="invalid">{{ error }}</strong>
<br> <br>
{% endfor %} {% endfor %}

View File

@@ -15,6 +15,7 @@ class UserNotificationAdmin(admin.ModelAdmin):
class UserAdmin(admin.ModelAdmin): class UserAdmin(admin.ModelAdmin):
list_display = [ list_display = [
"id", "id",
"sso_identifier",
"username", "username",
"first_name", "first_name",
"last_name", "last_name",

View File

@@ -17,10 +17,11 @@ class ShareUserAutocomplete(Select2QuerySetView):
""" """
def get_queryset(self): def get_queryset(self):
qs = User.objects.none()
if self.request.user.is_anonymous: if self.request.user.is_anonymous:
return User.objects.none() return qs
qs = User.objects.all()
if self.q: if self.q:
qs = User.objects.all()
# Due to privacy concerns only a full username match will return the proper user entry # Due to privacy concerns only a full username match will return the proper user entry
qs = qs.filter( qs = qs.filter(
Q(username=self.q) | Q(username=self.q) |
@@ -41,13 +42,13 @@ class ShareTeamAutocomplete(Select2QuerySetView):
""" """
def get_queryset(self): def get_queryset(self):
qs = Team.objects.none()
if self.request.user.is_anonymous: if self.request.user.is_anonymous:
return Team.objects.none() return qs
qs = Team.objects.filter(
deleted__isnull=True
)
if self.q: if self.q:
# Due to privacy concerns only a full username match will return the proper user entry qs = Team.objects.filter(
deleted__isnull=True
)
q_parts = self.q.split(" ") q_parts = self.q.split(" ")
q = Q() q = Q()
for part in q_parts: for part in q_parts:

View File

@@ -0,0 +1,49 @@
"""
Author: Michel Peltriaux
Created on: 08.01.25
"""
from django import forms
from django.utils.translation import gettext_lazy as _
from api.models import APIUserToken
from konova.forms.modals import BaseModalForm
from konova.utils.mailer import Mailer
class NewAPITokenModalForm(BaseModalForm):
confirm = forms.BooleanField(
label=_("Confirm"),
label_suffix=_(""),
widget=forms.CheckboxInput(),
required=True,
)
def __init__(self, *args, **kwargs):
self.template = "modal/modal_form.html"
super().__init__(*args, **kwargs)
self.form_title = _("Generate API Token")
self.form_caption = ""
if self.__user_has_api_token():
self.form_caption = _("You are about to create a new API token. The existing one will not be usable afterwards.")
self.form_caption += "\n"
self.form_caption += _("A new token needs to be validated by an administrator!")
# Disable automatic w-100 setting for this type of modal form. Looks kinda strange
self.fields["confirm"].widget.attrs["class"] = ""
def __user_has_api_token(self):
return self.instance.api_token is not None
def save(self):
user = self.instance
if user.api_token is not None:
user.api_token.delete()
user.api_token = APIUserToken.objects.create()
user.save()
mailer = Mailer()
mailer.send_mail_verify_api_token(user)
return user.api_token

View File

@@ -66,48 +66,3 @@ class UserNotificationForm(BaseForm):
id__in=selected_notification_ids, id__in=selected_notification_ids,
) )
self.user.notifications.set(notifications) self.user.notifications.set(notifications)
class UserAPITokenForm(BaseForm):
token = forms.CharField(
label=_("Token"),
label_suffix="",
max_length=255,
required=True,
help_text=_("Generated automatically - not editable"),
widget=GenerateInput(
attrs={
"class": "form-control",
"url": reverse_lazy("api:generate-new-token"),
}
)
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form_title = _("Create new token")
self.form_caption = _("A new token needs to be validated by an administrator!")
self.action_url = reverse("user:api-token")
self.cancel_redirect = reverse("user:index")
# Make direct token editing by user impossible. Instead set the proper url for generating a new token
self.initialize_form_field("token", None)
self.fields["token"].widget.attrs["readonly"] = True
def save(self):
""" Saves the form data
Returns:
api_token (APIUserToken)
"""
user = self.instance
new_token = self.cleaned_data["token"]
if user.api_token is not None:
user.api_token.delete()
new_token = APIUserToken.objects.create(
token=new_token
)
user.api_token = new_token
user.save()
return new_token

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.1.6 on 2025-09-12 06:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user', '0009_user_oauth_token'),
]
operations = [
migrations.AddField(
model_name='user',
name='sso_identifier',
field=models.CharField(blank=True, db_comment='Identifies the account based on an unique identifier from the SSO system', max_length=255, null=True),
),
]

View File

@@ -6,6 +6,7 @@ Created on: 15.11.21
""" """
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.core.exceptions import ObjectDoesNotExist
from django.db import models from django.db import models
@@ -32,6 +33,12 @@ class User(AbstractUser):
db_comment="OAuth token for the user", db_comment="OAuth token for the user",
related_name="+" related_name="+"
) )
sso_identifier = models.CharField(
blank=True,
null=True,
db_comment="Identifies the account based on an unique identifier from the SSO system",
max_length=255,
)
def is_notification_setting_set(self, notification_enum: UserNotificationEnum): def is_notification_setting_set(self, notification_enum: UserNotificationEnum):
return self.notifications.filter( return self.notifications.filter(
@@ -264,4 +271,48 @@ class User(AbstractUser):
self.oauth_token.delete() self.oauth_token.delete()
self.oauth_token = token self.oauth_token = token
self.save() self.save()
return self return self
@staticmethod
def resolve_user_using_propagation_data(data: dict):
""" Fetches user from db by the given data from propagation process
Args:
data (dict): json containing user information from the sso system
Returns:
user (User): The resolved user
"""
username = data.get("username", None)
sso_identifier = data.get("sso_identifier", None)
if not username and not sso_identifier:
raise AssertionError("No username or sso identifier provided")
try:
user = User.objects.get(username=username)
except ObjectDoesNotExist:
try:
user = User.objects.get(sso_identifier=sso_identifier)
except ObjectDoesNotExist:
raise ObjectDoesNotExist("No user with this username or sso identifier was found")
return user
def update_user_using_propagation_data(self, data: dict):
""" Update user data based on propagation data from sso system
Args:
data (dict): json containing user information from the sso system
Returns:
user (User): The updated user
"""
skipable_attrs = {
"is_staff",
"is_superuser",
}
for _attr, _val in data.items():
if _attr in skipable_attrs:
continue
setattr(self, _attr, _val)
return self

View File

@@ -8,7 +8,16 @@
<table class="table table-hover"> <table class="table table-hover">
<tr> <tr>
<th scope="row">{% trans 'Current token' %}</th> <th scope="row">{% trans 'Current token' %}</th>
<td>{{ user.api_token.token }}</td> <td>
<div class="row">
<div class="col-10">{{ user.api_token.token }}</div>
<div class="col-2">
<button class="btn btn-default btn-modal" data-form-url="{% url 'user:api-token-new' %}" title="{% trans 'Create new token' %}">
{% fa5_icon 'dice' %}
</button>
</div>
</div>
</td>
</tr> </tr>
<tr> <tr>
<th scope="row">{% trans 'Authenticated by admins' %}</th> <th scope="row">{% trans 'Authenticated by admins' %}</th>
@@ -27,7 +36,9 @@
</table> </table>
</div> </div>
</div> </div>
<hr>
{% include 'form/table/generic_table_form.html' %} {% with 'btn-modal' as btn_class %}
{% include 'modal/modal_form_script.html' %}
{% endwith %}
{% endblock %} {% endblock %}

View File

@@ -5,15 +5,14 @@ Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 12.09.23 Created on: 12.09.23
""" """
from django.core.exceptions import ObjectDoesNotExist
from django.test import RequestFactory from django.test import RequestFactory
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from api.models import APIUserToken
from konova.tests.test_views import BaseTestCase from konova.tests.test_views import BaseTestCase
from user.forms.modals.api_token import NewAPITokenModalForm
from user.forms.modals.team import NewTeamModalForm, EditTeamModalForm, RemoveTeamModalForm, LeaveTeamModalForm from user.forms.modals.team import NewTeamModalForm, EditTeamModalForm, RemoveTeamModalForm, LeaveTeamModalForm
from user.forms.user import UserNotificationForm, UserAPITokenForm from user.forms.user import UserNotificationForm
from user.models import Team, UserAction, UserNotification from user.models import Team, UserAction, UserNotification
@@ -252,35 +251,28 @@ class UserNotificationFormTestCase(BaseTestCase):
self.assertIn(selected_notification, self.user.notifications.all()) self.assertIn(selected_notification, self.user.notifications.all())
class UserAPITokenFormTestCase(BaseTestCase): class ApiTokenFormTestCase(BaseTestCase):
def test_init(self): def test_new_token_and_recreating_token(self):
form = UserAPITokenForm( request = RequestFactory().request()
instance=self.user request.user = self.user
) request.POST = {
self.assertEqual(form.form_title, str(_("Create new token"))) "confirm": True
self.assertEqual(form.form_caption, str(_("A new token needs to be validated by an administrator!")))
self.assertEqual(form.action_url, reverse("user:api-token"))
self.assertEqual(form.cancel_redirect, reverse("user:index"))
self.assertIsNone(form.fields["token"].initial)
self.assertTrue(form.fields["token"].widget.attrs["readonly"])
def test_save(self):
data = {
"token": APIUserToken().token
} }
form = UserAPITokenForm(
data,
instance=self.user
)
self.assertTrue(form.is_valid(), msg=form.errors)
self.assertIsNone(self.user.api_token) self.assertIsNone(self.user.api_token)
token = form.save() form = NewAPITokenModalForm(request.POST, instance=self.user)
self.assertEqual(self.user.api_token, token) form.save()
new_token = form.save() self.user.refresh_from_db()
self.assertEqual(self.user.api_token, new_token) token = self.user.api_token
try: self.assertFalse(token.is_active)
token.refresh_from_db() self.assertIsNone(token.valid_until)
self.fail("Token should be deleted and not be fetchable anymore") self.assertIsNotNone(token.token)
except ObjectDoesNotExist:
pass old_token = token.token
form.save()
self.user.refresh_from_db()
new_token = self.user.api_token
self.assertNotEqual(new_token.token, old_token)
self.assertFalse(new_token.is_active)
self.assertIsNone(new_token.valid_until)

View File

@@ -9,6 +9,7 @@ from django.urls import path
from user.autocomplete.share import ShareUserAutocomplete, ShareTeamAutocomplete from user.autocomplete.share import ShareUserAutocomplete, ShareTeamAutocomplete
from user.autocomplete.team import TeamAdminAutocomplete from user.autocomplete.team import TeamAdminAutocomplete
from user.views.api_token import APITokenView, new_api_token_view
from user.views.propagate import PropagateUserView from user.views.propagate import PropagateUserView
from user.views.views import * from user.views.views import *
@@ -17,7 +18,8 @@ urlpatterns = [
path("", index_view, name="index"), path("", index_view, name="index"),
path("propagate/", PropagateUserView.as_view(), name="propagate"), path("propagate/", PropagateUserView.as_view(), name="propagate"),
path("notifications/", notifications_view, name="notifications"), path("notifications/", notifications_view, name="notifications"),
path("token/api", api_token_view, name="api-token"), path("token/api", APITokenView.as_view(), name="api-token"),
path("token/api/new", new_api_token_view, name="api-token-new"),
path("contact/<id>", contact_view, name="contact"), path("contact/<id>", contact_view, name="contact"),
path("team/", index_team_view, name="team-index"), path("team/", index_team_view, name="team-index"),
path("team/new", new_team_view, name="team-new"), path("team/new", new_team_view, name="team-new"),
@@ -30,4 +32,4 @@ urlpatterns = [
path("atcmplt/share/u", ShareUserAutocomplete.as_view(), name="share-user-autocomplete"), path("atcmplt/share/u", ShareUserAutocomplete.as_view(), name="share-user-autocomplete"),
path("atcmplt/share/t", ShareTeamAutocomplete.as_view(), name="share-team-autocomplete"), path("atcmplt/share/t", ShareTeamAutocomplete.as_view(), name="share-team-autocomplete"),
path("atcmplt/team/admin", TeamAdminAutocomplete.as_view(), name="team-admin-autocomplete"), path("atcmplt/team/admin", TeamAdminAutocomplete.as_view(), name="team-admin-autocomplete"),
] ]

57
user/views/api_token.py Normal file
View File

@@ -0,0 +1,57 @@
"""
Author: Michel Peltriaux
Created on: 08.01.25
"""
from django.contrib.auth.decorators import login_required
from django.http import HttpRequest
from django.shortcuts import render
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views import View
from django.utils.translation import gettext_lazy as _
from konova.contexts import BaseContext
from konova.decorators import default_group_required
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import NEW_API_TOKEN_GENERATED
from user.forms.modals.api_token import NewAPITokenModalForm
class APITokenView(View):
@method_decorator(login_required)
@method_decorator(default_group_required)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def get(self, request: HttpRequest):
template = "user/token.html"
user = request.user
context = {
"user": user,
TAB_TITLE_IDENTIFIER: _("User API token"),
}
context = BaseContext(request, context).context
return render(request, template, context)
def new_api_token_view(request: HttpRequest):
""" Function based view for processing ModalForm
(Currently ModalForms only work properly with function based views)
Args:
request ():
Returns:
"""
user = request.user
form = NewAPITokenModalForm(request.POST or None, instance=user, request=request)
return form.process_request(
request=request,
msg_success=NEW_API_TOKEN_GENERATED,
redirect_url=reverse("user:api-token"),
)

View File

@@ -16,7 +16,7 @@ from django.utils.decorators import method_decorator
from django.views import View from django.views import View
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from konova.sub_settings.sso_settings import OAUTH_CLIENT_ID from konova.sub_settings.sso_settings import PROPAGATION_SECRET
from user.models import User from user.models import User
@@ -36,7 +36,7 @@ class PropagateUserView(View):
# Decrypt # Decrypt
encrypted_body = request.body encrypted_body = request.body
_hash = hashlib.md5() _hash = hashlib.md5()
_hash.update(OAUTH_CLIENT_ID.encode("utf-8")) _hash.update(PROPAGATION_SECRET.encode("utf-8"))
key = base64.urlsafe_b64encode(_hash.hexdigest().encode("utf-8")) key = base64.urlsafe_b64encode(_hash.hexdigest().encode("utf-8"))
fernet = Fernet(key) fernet = Fernet(key)
body = fernet.decrypt(encrypted_body).decode("utf-8") body = fernet.decrypt(encrypted_body).decode("utf-8")
@@ -44,17 +44,8 @@ class PropagateUserView(View):
try: try:
status = "updated" status = "updated"
user = User.objects.get(username=body.get('username')) user = User.resolve_user_using_propagation_data(body)
# Update user data, excluding some changes user = user.update_user_using_propagation_data(body)
skipable_attrs = {
"username",
"is_staff",
"is_superuser",
}
for _attr, _val in body.items():
if _attr in skipable_attrs:
continue
setattr(user, _attr, _val)
except ObjectDoesNotExist: except ObjectDoesNotExist:
user = User(**body) user = User(**body)
status = "created" status = "created"

View File

@@ -3,19 +3,17 @@ from django.contrib.auth.decorators import login_required
from django.urls import reverse from django.urls import reverse
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.mailer import Mailer
from konova.utils.message_templates import FORM_INVALID
from user.forms.modals.team import NewTeamModalForm, EditTeamModalForm, RemoveTeamModalForm, LeaveTeamModalForm from user.forms.modals.team import NewTeamModalForm, EditTeamModalForm, RemoveTeamModalForm, LeaveTeamModalForm
from user.forms.modals.user import UserContactForm from user.forms.modals.user import UserContactForm
from user.forms.team import TeamDataForm from user.forms.team import TeamDataForm
from user.forms.user import UserNotificationForm, UserAPITokenForm from user.forms.user import UserNotificationForm
from user.models import User, Team from user.models import User, Team
from django.http import HttpRequest, Http404 from django.http import HttpRequest, Http404
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.decorators import any_group_check, default_group_required, login_required_modal from konova.decorators import any_group_check, login_required_modal
@login_required @login_required
@@ -76,40 +74,6 @@ def notifications_view(request: HttpRequest):
return render(request, template, context) return render(request, template, context)
@login_required
@default_group_required
def api_token_view(request: HttpRequest):
""" Handles the request for user api frontend settings
Args:
request (HttpRequest): The incoming request
Returns:
"""
template = "user/token.html"
user = request.user
form = UserAPITokenForm(request.POST or None, instance=user)
if request.method == "POST":
if form.is_valid():
token = form.save()
messages.info(request, _("New token generated. Administrators need to validate."))
mailer = Mailer()
mailer.send_mail_verify_api_token(user)
return redirect("user:api-token")
else:
messages.error(request, FORM_INVALID, extra_tags="danger")
elif request.method != "GET":
raise NotImplementedError
context = {
"user": user,
"form": form,
TAB_TITLE_IDENTIFIER: _("User API token"),
}
context = BaseContext(request, context).context
return render(request, template, context)
@login_required_modal @login_required_modal
@login_required @login_required
def contact_view(request: HttpRequest, id: str): def contact_view(request: HttpRequest, id: str):