Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a4f50d6eb5 | |||
| ce4a7c51c4 | |||
| dad11bd249 | |||
| 477e4f6f5c | |||
| 04ab4867f9 | |||
| 303f296af1 | |||
| 488d4bd125 | |||
| 02557d0fdf | |||
| 16d6474bb9 | |||
| 10615b31f4 | |||
| ab51838db5 | |||
| e3e858233d | |||
| cc2d5c6200 | |||
| b2ee167132 | |||
| 600a3c7aff | |||
| 8f9cf4c9fb | |||
| 18573cb3be | |||
| 6b0d94c54e | |||
| a9f65893f0 | |||
| dcaca4c883 | |||
| dbd5fca40b | |||
| ecb1e49d8d | |||
| ad6c7ea3e1 | |||
| 1bb425e419 | |||
| b8f36bab7a | |||
| aacba1e5eb | |||
| 9efeff5aff |
@@ -1,12 +1,12 @@
|
||||
[general]
|
||||
version=26.3.1-testing
|
||||
version=
|
||||
name=LNO Sachsen | Plan41
|
||||
description=Plugin zum Erzeugen der Pläne nach §38 und §41
|
||||
author=Daniel Helbig, Michael Otto
|
||||
homepage=https://entwicklung.flurneuordnung-sachsen.de/AG_QGIS/Plugin_SN_Plan41
|
||||
tracker=https://entwicklung.flurneuordnung-sachsen.de/AG_QGIS/Plugin_SN_Plan41/issues
|
||||
repository=https://entwicklung.flurneuordnung-sachsen.de/AG_QGIS/Plugin_Test_Action/src/branch/testing/
|
||||
|
||||
repository=https://entwicklung.flurneuordnung-sachsen.de/AG_QGIS/Plugin_Test_Action/src/branch/unstable/
|
||||
QGISMaximumVersion=4.99
|
||||
qgisMinimumVersion=3.40
|
||||
experimental=true
|
||||
deprecated=false
|
||||
+14
@@ -1,3 +1,17 @@
|
||||
"""sn_plan41 – QGIS-Plugin für thematische Linklisten und Datenquellen.
|
||||
Verwaltet Excel-basierte Link-Listen und Fachdatenabruf.
|
||||
"""
|
||||
|
||||
|
||||
def classFactory(iface):
|
||||
"""Factory-Funktion für QGIS.
|
||||
Wird von QGIS aufgerufen, um die Plugin-Instanz zu erstellen.
|
||||
|
||||
Args:
|
||||
iface: QGIS-Schnittstellenobjekt
|
||||
|
||||
Returns:
|
||||
Plan41: Instanziiertes Plugin
|
||||
"""
|
||||
from .main import Plan41
|
||||
return Plan41(iface)
|
||||
|
||||
@@ -0,0 +1,866 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis maxScale="0" simplifyDrawingHints="1" simplifyMaxScale="1" simplifyLocal="1" styleCategories="AllStyleCategories" labelsEnabled="0" simplifyAlgorithm="0" minScale="100000000" version="3.40.7-Bratislava" symbologyReferenceScale="-1" hasScaleBasedVisibilityFlag="0" autoRefreshMode="Disabled" readOnly="0" autoRefreshTime="0" simplifyDrawingTol="1">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal endExpression="" durationField="OBJECTID" enabled="0" mode="0" fixedDuration="0" startField="" accumulate="0" limitMode="0" endField="" durationUnit="min" startExpression="">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation respectLayerSymbol="1" zscale="1" extrusionEnabled="0" extrusion="0" type="IndividualFeatures" clamping="Terrain" symbology="Line" binding="Centroid" showMarkerSymbolInSurfacePlots="0" zoffset="0">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="line" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleLine" locked="0" id="{6c29bf72-f401-4d8a-b41c-3b305bb5a1cb}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="align_dash_pattern" type="QString" value="0"/>
|
||||
<Option name="capstyle" type="QString" value="square"/>
|
||||
<Option name="customdash" type="QString" value="5;2"/>
|
||||
<Option name="customdash_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="customdash_unit" type="QString" value="MM"/>
|
||||
<Option name="dash_pattern_offset" type="QString" value="0"/>
|
||||
<Option name="dash_pattern_offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="dash_pattern_offset_unit" type="QString" value="MM"/>
|
||||
<Option name="draw_inside_polygon" type="QString" value="0"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="line_color" type="QString" value="152,125,183,255,rgb:0.59607843137254901,0.49019607843137253,0.71764705882352942,1"/>
|
||||
<Option name="line_style" type="QString" value="solid"/>
|
||||
<Option name="line_width" type="QString" value="0.6"/>
|
||||
<Option name="line_width_unit" type="QString" value="MM"/>
|
||||
<Option name="offset" type="QString" value="0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="ring_filter" type="QString" value="0"/>
|
||||
<Option name="trim_distance_end" type="QString" value="0"/>
|
||||
<Option name="trim_distance_end_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="trim_distance_end_unit" type="QString" value="MM"/>
|
||||
<Option name="trim_distance_start" type="QString" value="0"/>
|
||||
<Option name="trim_distance_start_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="trim_distance_start_unit" type="QString" value="MM"/>
|
||||
<Option name="tweak_dash_pattern_on_corners" type="QString" value="0"/>
|
||||
<Option name="use_custom_dash" type="QString" value="0"/>
|
||||
<Option name="width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{e2680116-f813-4429-9fa9-d867acb612b6}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="152,125,183,255,rgb:0.59607843137254901,0.49019607843137253,0.71764705882352942,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="109,89,131,255,rgb:0.42575722896162355,0.35013351644159607,0.51259632257572285,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.2"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
<profileMarkerSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="marker" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleMarker" locked="0" id="{138fd242-c263-4b78-9e45-35a46c014c45}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="0"/>
|
||||
<Option name="cap_style" type="QString" value="square"/>
|
||||
<Option name="color" type="QString" value="152,125,183,255,rgb:0.59607843137254901,0.49019607843137253,0.71764705882352942,1"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="name" type="QString" value="diamond"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="109,89,131,255,rgb:0.42575722896162355,0.35013351644159607,0.51259632257572285,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.2"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="scale_method" type="QString" value="diameter"/>
|
||||
<Option name="size" type="QString" value="3"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileMarkerSymbol>
|
||||
</elevation>
|
||||
<renderer-v2 forceraster="0" type="singleSymbol" enableorderby="0" referencescale="-1" symbollevels="0">
|
||||
<symbols>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="0" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="CentroidFill" locked="0" id="{13b6615d-1ea0-4ab5-a22e-ff53199febfd}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="clip_on_current_part_only" type="QString" value="1"/>
|
||||
<Option name="clip_points" type="QString" value="1"/>
|
||||
<Option name="point_on_all_parts" type="QString" value="1"/>
|
||||
<Option name="point_on_surface" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="@0@0" force_rhr="0" type="marker" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleMarker" locked="0" id="{22dff15d-7192-4a3b-b746-ebaa619293f8}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="0"/>
|
||||
<Option name="cap_style" type="QString" value="square"/>
|
||||
<Option name="color" type="QString" value="255,0,0,0,rgb:1,0,0,0"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="name" type="QString" value="circle"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.5"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="scale_method" type="QString" value="diameter"/>
|
||||
<Option name="size" type="QString" value="15"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
<layer enabled="1" class="FontMarker" locked="0" id="{be8c7958-eff9-4238-ab27-fad83324e55d}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="0"/>
|
||||
<Option name="chr" type="QString" value="N"/>
|
||||
<Option name="color" type="QString" value="0,0,0,255,rgb:0,0,0,1"/>
|
||||
<Option name="font" type="QString" value="Arial"/>
|
||||
<Option name="font_style" type="QString" value="Standard"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_width" type="QString" value="0"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="size" type="QString" value="5"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</layer>
|
||||
<layer enabled="1" class="MarkerLine" locked="0" id="{3fbb33b2-51ae-4fdb-87ff-a779155198ad}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="average_angle_length" type="QString" value="4"/>
|
||||
<Option name="average_angle_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="average_angle_unit" type="QString" value="MM"/>
|
||||
<Option name="interval" type="QString" value="5"/>
|
||||
<Option name="interval_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="interval_unit" type="QString" value="MM"/>
|
||||
<Option name="offset" type="QString" value="5.55112e-17"/>
|
||||
<Option name="offset_along_line" type="QString" value="0"/>
|
||||
<Option name="offset_along_line_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_along_line_unit" type="QString" value="MM"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="Pixel"/>
|
||||
<Option name="place_on_every_part" type="bool" value="true"/>
|
||||
<Option name="placements" type="QString" value="Interval"/>
|
||||
<Option name="ring_filter" type="QString" value="1"/>
|
||||
<Option name="rotate" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="@0@1" force_rhr="0" type="marker" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleMarker" locked="0" id="{9e34c4c6-1165-4598-a42c-90fa8fc5ceb1}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="90"/>
|
||||
<Option name="cap_style" type="QString" value="square"/>
|
||||
<Option name="color" type="QString" value="255,0,0,255,rgb:1,0,0,1"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="name" type="QString" value="line"/>
|
||||
<Option name="offset" type="QString" value="2,-1.5"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.5"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="scale_method" type="QString" value="diameter"/>
|
||||
<Option name="size" type="QString" value="3"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
<layer enabled="1" class="SimpleMarker" locked="0" id="{740b060e-faa9-40ad-9cea-81c949fa1213}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="0"/>
|
||||
<Option name="cap_style" type="QString" value="square"/>
|
||||
<Option name="color" type="QString" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="name" type="QString" value="line"/>
|
||||
<Option name="offset" type="QString" value="3,1"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.5"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="scale_method" type="QString" value="diameter"/>
|
||||
<Option name="size" type="QString" value="2"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
<layer enabled="1" class="SimpleMarker" locked="0" id="{ad3c4f89-aa14-4614-bf6a-1ce121763a53}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="0"/>
|
||||
<Option name="cap_style" type="QString" value="square"/>
|
||||
<Option name="color" type="QString" value="255,0,0,255,rgb:1,0,0,1"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="name" type="QString" value="line"/>
|
||||
<Option name="offset" type="QString" value="2,1"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.5"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="scale_method" type="QString" value="diameter"/>
|
||||
<Option name="size" type="QString" value="2"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
<layer enabled="1" class="SimpleMarker" locked="0" id="{19fe76ca-22b3-40fd-9177-9ac25a80499b}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="0"/>
|
||||
<Option name="cap_style" type="QString" value="square"/>
|
||||
<Option name="color" type="QString" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="name" type="QString" value="line"/>
|
||||
<Option name="offset" type="QString" value="1,1"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.5"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="scale_method" type="QString" value="diameter"/>
|
||||
<Option name="size" type="QString" value="2"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
<layer enabled="1" class="SimpleMarker" locked="0" id="{cdfe941b-0a2d-450b-bcca-0901823247e1}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="0"/>
|
||||
<Option name="cap_style" type="QString" value="square"/>
|
||||
<Option name="color" type="QString" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="name" type="QString" value="line"/>
|
||||
<Option name="offset" type="QString" value="0,1"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.5"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="scale_method" type="QString" value="diameter"/>
|
||||
<Option name="size" type="QString" value="2"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</layer>
|
||||
<layer enabled="1" class="SimpleLine" locked="0" id="{7ad934f6-f1ca-462a-8e99-2f3c035e1df4}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="align_dash_pattern" type="QString" value="0"/>
|
||||
<Option name="capstyle" type="QString" value="square"/>
|
||||
<Option name="customdash" type="QString" value="5;2"/>
|
||||
<Option name="customdash_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="customdash_unit" type="QString" value="MM"/>
|
||||
<Option name="dash_pattern_offset" type="QString" value="0"/>
|
||||
<Option name="dash_pattern_offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="dash_pattern_offset_unit" type="QString" value="MM"/>
|
||||
<Option name="draw_inside_polygon" type="QString" value="0"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="line_color" type="QString" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option name="line_style" type="QString" value="solid"/>
|
||||
<Option name="line_width" type="QString" value="0.5"/>
|
||||
<Option name="line_width_unit" type="QString" value="MM"/>
|
||||
<Option name="offset" type="QString" value="0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="ring_filter" type="QString" value="0"/>
|
||||
<Option name="trim_distance_end" type="QString" value="0"/>
|
||||
<Option name="trim_distance_end_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="trim_distance_end_unit" type="QString" value="MM"/>
|
||||
<Option name="trim_distance_start" type="QString" value="0"/>
|
||||
<Option name="trim_distance_start_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="trim_distance_start_unit" type="QString" value="MM"/>
|
||||
<Option name="tweak_dash_pattern_on_corners" type="QString" value="0"/>
|
||||
<Option name="use_custom_dash" type="QString" value="0"/>
|
||||
<Option name="width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</symbols>
|
||||
<rotation/>
|
||||
<sizescale/>
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
</renderer-v2>
|
||||
<selection mode="Default">
|
||||
<selectionColor invalid="1"/>
|
||||
<selectionSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{9e97a033-5092-4073-b71d-2367914e7397}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="0,0,255,255,rgb:0,0,1,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</selectionSymbol>
|
||||
</selection>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option name="embeddedWidgets/count" type="int" value="0"/>
|
||||
<Option name="variableNames"/>
|
||||
<Option name="variableValues"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<blendMode>0</blendMode>
|
||||
<featureBlendMode>0</featureBlendMode>
|
||||
<layerOpacity>1</layerOpacity>
|
||||
<geometryOptions geometryPrecision="0" removeDuplicateNodes="0">
|
||||
<activeChecks/>
|
||||
<checkConfiguration type="Map">
|
||||
<Option name="QgsGeometryGapCheck" type="Map">
|
||||
<Option name="allowedGapsBuffer" type="double" value="0"/>
|
||||
<Option name="allowedGapsEnabled" type="bool" value="false"/>
|
||||
<Option name="allowedGapsLayer" type="QString" value=""/>
|
||||
</Option>
|
||||
</checkConfiguration>
|
||||
</geometryOptions>
|
||||
<legend showLabelLegend="0" type="default-vector"/>
|
||||
<referencedLayers/>
|
||||
<fieldConfiguration>
|
||||
<field name="OBJECTID" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="KATEGORIE" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="STATUS" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="SG_NR" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="NAME" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="FLAECHE" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="UMFANG" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="RVO_DATUM" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="RVO_1" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="RVO_2" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="PRAEZI" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="ERFDAT" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="UEBDAT" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Shape__Area" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Shape__Length" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="SE_ANNO_CAD_DATA" configurationFlags="NoFlag">
|
||||
<editWidget type="Binary">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
</fieldConfiguration>
|
||||
<aliases>
|
||||
<alias index="0" name="" field="OBJECTID"/>
|
||||
<alias index="1" name="" field="KATEGORIE"/>
|
||||
<alias index="2" name="" field="STATUS"/>
|
||||
<alias index="3" name="" field="SG_NR"/>
|
||||
<alias index="4" name="" field="NAME"/>
|
||||
<alias index="5" name="" field="FLAECHE"/>
|
||||
<alias index="6" name="" field="UMFANG"/>
|
||||
<alias index="7" name="" field="RVO_DATUM"/>
|
||||
<alias index="8" name="" field="RVO_1"/>
|
||||
<alias index="9" name="" field="RVO_2"/>
|
||||
<alias index="10" name="" field="PRAEZI"/>
|
||||
<alias index="11" name="" field="ERFDAT"/>
|
||||
<alias index="12" name="" field="UEBDAT"/>
|
||||
<alias index="13" name="SHAPE.AREA" field="Shape__Area"/>
|
||||
<alias index="14" name="SHAPE.LEN" field="Shape__Length"/>
|
||||
<alias index="15" name="" field="SE_ANNO_CAD_DATA"/>
|
||||
</aliases>
|
||||
<splitPolicies>
|
||||
<policy policy="Duplicate" field="OBJECTID"/>
|
||||
<policy policy="Duplicate" field="KATEGORIE"/>
|
||||
<policy policy="Duplicate" field="STATUS"/>
|
||||
<policy policy="Duplicate" field="SG_NR"/>
|
||||
<policy policy="Duplicate" field="NAME"/>
|
||||
<policy policy="Duplicate" field="FLAECHE"/>
|
||||
<policy policy="Duplicate" field="UMFANG"/>
|
||||
<policy policy="Duplicate" field="RVO_DATUM"/>
|
||||
<policy policy="Duplicate" field="RVO_1"/>
|
||||
<policy policy="Duplicate" field="RVO_2"/>
|
||||
<policy policy="Duplicate" field="PRAEZI"/>
|
||||
<policy policy="Duplicate" field="ERFDAT"/>
|
||||
<policy policy="Duplicate" field="UEBDAT"/>
|
||||
<policy policy="Duplicate" field="Shape__Area"/>
|
||||
<policy policy="Duplicate" field="Shape__Length"/>
|
||||
<policy policy="Duplicate" field="SE_ANNO_CAD_DATA"/>
|
||||
</splitPolicies>
|
||||
<duplicatePolicies>
|
||||
<policy policy="Duplicate" field="OBJECTID"/>
|
||||
<policy policy="Duplicate" field="KATEGORIE"/>
|
||||
<policy policy="Duplicate" field="STATUS"/>
|
||||
<policy policy="Duplicate" field="SG_NR"/>
|
||||
<policy policy="Duplicate" field="NAME"/>
|
||||
<policy policy="Duplicate" field="FLAECHE"/>
|
||||
<policy policy="Duplicate" field="UMFANG"/>
|
||||
<policy policy="Duplicate" field="RVO_DATUM"/>
|
||||
<policy policy="Duplicate" field="RVO_1"/>
|
||||
<policy policy="Duplicate" field="RVO_2"/>
|
||||
<policy policy="Duplicate" field="PRAEZI"/>
|
||||
<policy policy="Duplicate" field="ERFDAT"/>
|
||||
<policy policy="Duplicate" field="UEBDAT"/>
|
||||
<policy policy="Duplicate" field="Shape__Area"/>
|
||||
<policy policy="Duplicate" field="Shape__Length"/>
|
||||
<policy policy="Duplicate" field="SE_ANNO_CAD_DATA"/>
|
||||
</duplicatePolicies>
|
||||
<defaults>
|
||||
<default field="OBJECTID" expression="" applyOnUpdate="0"/>
|
||||
<default field="KATEGORIE" expression="" applyOnUpdate="0"/>
|
||||
<default field="STATUS" expression="" applyOnUpdate="0"/>
|
||||
<default field="SG_NR" expression="" applyOnUpdate="0"/>
|
||||
<default field="NAME" expression="" applyOnUpdate="0"/>
|
||||
<default field="FLAECHE" expression="" applyOnUpdate="0"/>
|
||||
<default field="UMFANG" expression="" applyOnUpdate="0"/>
|
||||
<default field="RVO_DATUM" expression="" applyOnUpdate="0"/>
|
||||
<default field="RVO_1" expression="" applyOnUpdate="0"/>
|
||||
<default field="RVO_2" expression="" applyOnUpdate="0"/>
|
||||
<default field="PRAEZI" expression="" applyOnUpdate="0"/>
|
||||
<default field="ERFDAT" expression="" applyOnUpdate="0"/>
|
||||
<default field="UEBDAT" expression="" applyOnUpdate="0"/>
|
||||
<default field="Shape__Area" expression="" applyOnUpdate="0"/>
|
||||
<default field="Shape__Length" expression="" applyOnUpdate="0"/>
|
||||
<default field="SE_ANNO_CAD_DATA" expression="" applyOnUpdate="0"/>
|
||||
</defaults>
|
||||
<constraints>
|
||||
<constraint constraints="3" unique_strength="1" exp_strength="0" notnull_strength="1" field="OBJECTID"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="KATEGORIE"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="STATUS"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="SG_NR"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="NAME"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="FLAECHE"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="UMFANG"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="RVO_DATUM"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="RVO_1"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="RVO_2"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="PRAEZI"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="ERFDAT"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="UEBDAT"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="Shape__Area"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="Shape__Length"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="SE_ANNO_CAD_DATA"/>
|
||||
</constraints>
|
||||
<constraintExpressions>
|
||||
<constraint desc="" exp="" field="OBJECTID"/>
|
||||
<constraint desc="" exp="" field="KATEGORIE"/>
|
||||
<constraint desc="" exp="" field="STATUS"/>
|
||||
<constraint desc="" exp="" field="SG_NR"/>
|
||||
<constraint desc="" exp="" field="NAME"/>
|
||||
<constraint desc="" exp="" field="FLAECHE"/>
|
||||
<constraint desc="" exp="" field="UMFANG"/>
|
||||
<constraint desc="" exp="" field="RVO_DATUM"/>
|
||||
<constraint desc="" exp="" field="RVO_1"/>
|
||||
<constraint desc="" exp="" field="RVO_2"/>
|
||||
<constraint desc="" exp="" field="PRAEZI"/>
|
||||
<constraint desc="" exp="" field="ERFDAT"/>
|
||||
<constraint desc="" exp="" field="UEBDAT"/>
|
||||
<constraint desc="" exp="" field="Shape__Area"/>
|
||||
<constraint desc="" exp="" field="Shape__Length"/>
|
||||
<constraint desc="" exp="" field="SE_ANNO_CAD_DATA"/>
|
||||
</constraintExpressions>
|
||||
<expressionfields/>
|
||||
<attributeactions>
|
||||
<defaultAction value="{00000000-0000-0000-0000-000000000000}" key="Canvas"/>
|
||||
</attributeactions>
|
||||
<attributetableconfig sortOrder="0" actionWidgetStyle="dropDown" sortExpression="">
|
||||
<columns>
|
||||
<column name="OBJECTID" width="-1" type="field" hidden="0"/>
|
||||
<column name="KATEGORIE" width="-1" type="field" hidden="0"/>
|
||||
<column name="STATUS" width="-1" type="field" hidden="0"/>
|
||||
<column name="SG_NR" width="-1" type="field" hidden="0"/>
|
||||
<column name="NAME" width="-1" type="field" hidden="0"/>
|
||||
<column name="FLAECHE" width="-1" type="field" hidden="0"/>
|
||||
<column name="UMFANG" width="-1" type="field" hidden="0"/>
|
||||
<column name="RVO_DATUM" width="-1" type="field" hidden="0"/>
|
||||
<column name="RVO_1" width="-1" type="field" hidden="0"/>
|
||||
<column name="RVO_2" width="-1" type="field" hidden="0"/>
|
||||
<column name="PRAEZI" width="-1" type="field" hidden="0"/>
|
||||
<column name="ERFDAT" width="-1" type="field" hidden="0"/>
|
||||
<column name="UEBDAT" width="-1" type="field" hidden="0"/>
|
||||
<column name="Shape__Area" width="-1" type="field" hidden="0"/>
|
||||
<column name="Shape__Length" width="-1" type="field" hidden="0"/>
|
||||
<column name="SE_ANNO_CAD_DATA" width="-1" type="field" hidden="0"/>
|
||||
<column width="-1" type="actions" hidden="1"/>
|
||||
</columns>
|
||||
</attributetableconfig>
|
||||
<conditionalstyles>
|
||||
<rowstyles/>
|
||||
<fieldstyles/>
|
||||
</conditionalstyles>
|
||||
<storedexpressions/>
|
||||
<editform tolerant="1"></editform>
|
||||
<editforminit/>
|
||||
<editforminitcodesource>0</editforminitcodesource>
|
||||
<editforminitfilepath></editforminitfilepath>
|
||||
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||
"""
|
||||
QGIS-Formulare können eine Python-Funktion haben,, die aufgerufen wird, wenn sich das Formular öffnet
|
||||
|
||||
Diese Funktion kann verwendet werden um dem Formular Extralogik hinzuzufügen.
|
||||
|
||||
Der Name der Funktion wird im Feld "Python Init-Function" angegeben
|
||||
Ein Beispiel folgt:
|
||||
"""
|
||||
from qgis.PyQt.QtWidgets import QWidget
|
||||
|
||||
def my_form_open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||
]]></editforminitcode>
|
||||
<featformsuppress>0</featformsuppress>
|
||||
<editorlayout>generatedlayout</editorlayout>
|
||||
<editable>
|
||||
<field name="ERFDAT" editable="1"/>
|
||||
<field name="FLAECHE" editable="1"/>
|
||||
<field name="KATEGORIE" editable="1"/>
|
||||
<field name="NAME" editable="1"/>
|
||||
<field name="OBJECTID" editable="0"/>
|
||||
<field name="PRAEZI" editable="1"/>
|
||||
<field name="RVO_1" editable="1"/>
|
||||
<field name="RVO_2" editable="1"/>
|
||||
<field name="RVO_DATUM" editable="1"/>
|
||||
<field name="SE_ANNO_CAD_DATA" editable="1"/>
|
||||
<field name="SG_NR" editable="1"/>
|
||||
<field name="STATUS" editable="1"/>
|
||||
<field name="Shape__Area" editable="0"/>
|
||||
<field name="Shape__Length" editable="0"/>
|
||||
<field name="UEBDAT" editable="1"/>
|
||||
<field name="UMFANG" editable="1"/>
|
||||
</editable>
|
||||
<labelOnTop>
|
||||
<field name="ERFDAT" labelOnTop="0"/>
|
||||
<field name="FLAECHE" labelOnTop="0"/>
|
||||
<field name="KATEGORIE" labelOnTop="0"/>
|
||||
<field name="NAME" labelOnTop="0"/>
|
||||
<field name="OBJECTID" labelOnTop="0"/>
|
||||
<field name="PRAEZI" labelOnTop="0"/>
|
||||
<field name="RVO_1" labelOnTop="0"/>
|
||||
<field name="RVO_2" labelOnTop="0"/>
|
||||
<field name="RVO_DATUM" labelOnTop="0"/>
|
||||
<field name="SE_ANNO_CAD_DATA" labelOnTop="0"/>
|
||||
<field name="SG_NR" labelOnTop="0"/>
|
||||
<field name="STATUS" labelOnTop="0"/>
|
||||
<field name="Shape__Area" labelOnTop="0"/>
|
||||
<field name="Shape__Length" labelOnTop="0"/>
|
||||
<field name="UEBDAT" labelOnTop="0"/>
|
||||
<field name="UMFANG" labelOnTop="0"/>
|
||||
</labelOnTop>
|
||||
<reuseLastValue>
|
||||
<field name="ERFDAT" reuseLastValue="0"/>
|
||||
<field name="FLAECHE" reuseLastValue="0"/>
|
||||
<field name="KATEGORIE" reuseLastValue="0"/>
|
||||
<field name="NAME" reuseLastValue="0"/>
|
||||
<field name="OBJECTID" reuseLastValue="0"/>
|
||||
<field name="PRAEZI" reuseLastValue="0"/>
|
||||
<field name="RVO_1" reuseLastValue="0"/>
|
||||
<field name="RVO_2" reuseLastValue="0"/>
|
||||
<field name="RVO_DATUM" reuseLastValue="0"/>
|
||||
<field name="SE_ANNO_CAD_DATA" reuseLastValue="0"/>
|
||||
<field name="SG_NR" reuseLastValue="0"/>
|
||||
<field name="STATUS" reuseLastValue="0"/>
|
||||
<field name="Shape__Area" reuseLastValue="0"/>
|
||||
<field name="Shape__Length" reuseLastValue="0"/>
|
||||
<field name="UEBDAT" reuseLastValue="0"/>
|
||||
<field name="UMFANG" reuseLastValue="0"/>
|
||||
</reuseLastValue>
|
||||
<dataDefinedFieldProperties/>
|
||||
<widgets/>
|
||||
<previewExpression>"NAME"</previewExpression>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<layerGeometryType>2</layerGeometryType>
|
||||
</qgis>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,871 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis maxScale="0" simplifyDrawingHints="1" simplifyMaxScale="1" simplifyLocal="1" styleCategories="AllStyleCategories" labelsEnabled="0" simplifyAlgorithm="0" minScale="100000000" version="3.40.7-Bratislava" symbologyReferenceScale="-1" hasScaleBasedVisibilityFlag="0" autoRefreshMode="Disabled" readOnly="0" autoRefreshTime="0" simplifyDrawingTol="1">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal endExpression="" durationField="HFV_FLAECHE_RES" enabled="0" mode="0" fixedDuration="0" startField="HFV_DAT_ERF" accumulate="0" limitMode="0" endField="" durationUnit="min" startExpression="">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation respectLayerSymbol="1" zscale="1" extrusionEnabled="0" extrusion="0" type="IndividualFeatures" clamping="Terrain" symbology="Line" binding="Centroid" showMarkerSymbolInSurfacePlots="0" zoffset="0">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="line" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleLine" locked="0" id="{e5f07881-cf7e-4b94-83db-53938f3f7ae2}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="align_dash_pattern" type="QString" value="0"/>
|
||||
<Option name="capstyle" type="QString" value="square"/>
|
||||
<Option name="customdash" type="QString" value="5;2"/>
|
||||
<Option name="customdash_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="customdash_unit" type="QString" value="MM"/>
|
||||
<Option name="dash_pattern_offset" type="QString" value="0"/>
|
||||
<Option name="dash_pattern_offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="dash_pattern_offset_unit" type="QString" value="MM"/>
|
||||
<Option name="draw_inside_polygon" type="QString" value="0"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="line_color" type="QString" value="114,155,111,255,rgb:0.44705882352941179,0.60784313725490191,0.43529411764705883,1"/>
|
||||
<Option name="line_style" type="QString" value="solid"/>
|
||||
<Option name="line_width" type="QString" value="0.6"/>
|
||||
<Option name="line_width_unit" type="QString" value="MM"/>
|
||||
<Option name="offset" type="QString" value="0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="ring_filter" type="QString" value="0"/>
|
||||
<Option name="trim_distance_end" type="QString" value="0"/>
|
||||
<Option name="trim_distance_end_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="trim_distance_end_unit" type="QString" value="MM"/>
|
||||
<Option name="trim_distance_start" type="QString" value="0"/>
|
||||
<Option name="trim_distance_start_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="trim_distance_start_unit" type="QString" value="MM"/>
|
||||
<Option name="tweak_dash_pattern_on_corners" type="QString" value="0"/>
|
||||
<Option name="use_custom_dash" type="QString" value="0"/>
|
||||
<Option name="width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{67b96080-159c-481a-beb8-fd549559befd}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="114,155,111,255,rgb:0.44705882352941179,0.60784313725490191,0.43529411764705883,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="81,111,79,255,rgb:0.31932555123216599,0.4341649500267033,0.3109178301670863,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.2"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
<profileMarkerSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="marker" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleMarker" locked="0" id="{73b16b15-abe7-4a92-802d-ee527e2ef844}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="0"/>
|
||||
<Option name="cap_style" type="QString" value="square"/>
|
||||
<Option name="color" type="QString" value="114,155,111,255,rgb:0.44705882352941179,0.60784313725490191,0.43529411764705883,1"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="name" type="QString" value="diamond"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="81,111,79,255,rgb:0.31932555123216599,0.4341649500267033,0.3109178301670863,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.2"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="scale_method" type="QString" value="diameter"/>
|
||||
<Option name="size" type="QString" value="3"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileMarkerSymbol>
|
||||
</elevation>
|
||||
<renderer-v2 forceraster="0" type="categorizedSymbol" enableorderby="0" referencescale="-1" attr="HBTP_BEZ" symbollevels="0">
|
||||
<categories>
|
||||
<category render="true" uuid="{6f28b785-1b9e-4468-b474-2f1743c40d73}" type="string" label="Brutbaum (Brutbaumkomplex)" value="Brutbaum (Brutbaumkomplex)" symbol="0"/>
|
||||
<category render="true" uuid="{fd48cc7e-3a90-4576-8e5a-8262bbb27cd2}" type="string" label="Reproduktionshabitat" value="Reproduktionshabitat" symbol="1"/>
|
||||
<category render="true" uuid="{53a85327-7622-4312-84f5-36f881aced7e}" type="NULL" label="" value="NULL" symbol="2"/>
|
||||
</categories>
|
||||
<symbols>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="0" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{68961825-6501-4e47-9f29-94d9091d2f36}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="0,170,0,255,rgb:0,0.66666666666666663,0,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="1" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{a4195645-1010-4615-affb-26157b7fb07b}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="230,70,214,255,rgb:0.90196078431372551,0.27450980392156865,0.83921568627450982,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="2" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{b701f552-5171-4e40-a689-ab881a88384b}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="110,144,217,255,hsv:0.61388888888888893,0.49411764705882355,0.85098039215686272,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</symbols>
|
||||
<source-symbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="0" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{08ef956c-cfc8-4429-be33-2c2aac3938c6}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="243,166,178,255,rgb:0.95294117647058818,0.65098039215686276,0.69803921568627447,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</source-symbol>
|
||||
<colorramp name="[source]" type="randomcolors">
|
||||
<Option/>
|
||||
</colorramp>
|
||||
<rotation/>
|
||||
<sizescale/>
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
</renderer-v2>
|
||||
<selection mode="Default">
|
||||
<selectionColor invalid="1"/>
|
||||
<selectionSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{54461271-fa73-4ec5-8323-72cc78b26ced}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="0,0,255,255,rgb:0,0,1,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</selectionSymbol>
|
||||
</selection>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option name="embeddedWidgets/count" type="int" value="0"/>
|
||||
<Option name="variableNames"/>
|
||||
<Option name="variableValues"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<blendMode>0</blendMode>
|
||||
<featureBlendMode>0</featureBlendMode>
|
||||
<layerOpacity>1</layerOpacity>
|
||||
<geometryOptions geometryPrecision="0" removeDuplicateNodes="0">
|
||||
<activeChecks/>
|
||||
<checkConfiguration type="Map">
|
||||
<Option name="QgsGeometryGapCheck" type="Map">
|
||||
<Option name="allowedGapsBuffer" type="double" value="0"/>
|
||||
<Option name="allowedGapsEnabled" type="bool" value="false"/>
|
||||
<Option name="allowedGapsLayer" type="QString" value=""/>
|
||||
</Option>
|
||||
</checkConfiguration>
|
||||
</geometryOptions>
|
||||
<legend showLabelLegend="0" type="default-vector"/>
|
||||
<referencedLayers/>
|
||||
<fieldConfiguration>
|
||||
<field name="ART_DEUTSCH" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="ART_WISSENSCHAFTL" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HBTP_BEZ" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFV_DAT_ERF" configurationFlags="NoFlag">
|
||||
<editWidget type="DateTime">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFV_FLAECHE_RES" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFF_HABF_ID" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFF_FLTYP" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="GDF_NR_LAND" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="GID_BEZ" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="GTF_NR" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFV_BEW_POP" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFV_BEW_HAB" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFV_BEW_BTR" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFV_ZUS_ERH" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFV_ABW_GA" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFV_BEM_ZUS_ERH" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="LEGENDE" configurationFlags="NoFlag">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="REPORT" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="GDF_ID" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HFF_ID" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HTFF_ID" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="HTFF_HABF_ID" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="OBJECTID" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Shape__Area" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Shape__Length" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="LEGENDE_2" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="SE_ANNO_CAD_DATA" configurationFlags="NoFlag">
|
||||
<editWidget type="Binary">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
</fieldConfiguration>
|
||||
<aliases>
|
||||
<alias index="0" name="Art dt" field="ART_DEUTSCH"/>
|
||||
<alias index="1" name="Art wiss" field="ART_WISSENSCHAFTL"/>
|
||||
<alias index="2" name="Habit_Typ" field="HBTP_BEZ"/>
|
||||
<alias index="3" name="Datum Erf" field="HFV_DAT_ERF"/>
|
||||
<alias index="4" name="Flaeche" field="HFV_FLAECHE_RES"/>
|
||||
<alias index="5" name="Habit ID" field="HFF_HABF_ID"/>
|
||||
<alias index="6" name="Flaechentyp" field="HFF_FLTYP"/>
|
||||
<alias index="7" name="SN Nr Gebiet" field="GDF_NR_LAND"/>
|
||||
<alias index="8" name="Name_Gebiet" field="GID_BEZ"/>
|
||||
<alias index="9" name="Nr_Teilfl" field="GTF_NR"/>
|
||||
<alias index="10" name="Bew Popula" field="HFV_BEW_POP"/>
|
||||
<alias index="11" name="Bew Habitat" field="HFV_BEW_HAB"/>
|
||||
<alias index="12" name="Bew Beeintr" field="HFV_BEW_BTR"/>
|
||||
<alias index="13" name="EHZ" field="HFV_ZUS_ERH"/>
|
||||
<alias index="14" name="Abw_EHZ" field="HFV_ABW_GA"/>
|
||||
<alias index="15" name="Grund Abw" field="HFV_BEM_ZUS_ERH"/>
|
||||
<alias index="16" name="Legende" field="LEGENDE"/>
|
||||
<alias index="17" name="Report" field="REPORT"/>
|
||||
<alias index="18" name="" field="GDF_ID"/>
|
||||
<alias index="19" name="" field="HFF_ID"/>
|
||||
<alias index="20" name="" field="HTFF_ID"/>
|
||||
<alias index="21" name="Habit Tf ID" field="HTFF_HABF_ID"/>
|
||||
<alias index="22" name="" field="OBJECTID"/>
|
||||
<alias index="23" name="SHAPE.AREA" field="Shape__Area"/>
|
||||
<alias index="24" name="SHAPE.LEN" field="Shape__Length"/>
|
||||
<alias index="25" name="" field="LEGENDE_2"/>
|
||||
<alias index="26" name="" field="SE_ANNO_CAD_DATA"/>
|
||||
</aliases>
|
||||
<splitPolicies>
|
||||
<policy policy="Duplicate" field="ART_DEUTSCH"/>
|
||||
<policy policy="Duplicate" field="ART_WISSENSCHAFTL"/>
|
||||
<policy policy="Duplicate" field="HBTP_BEZ"/>
|
||||
<policy policy="Duplicate" field="HFV_DAT_ERF"/>
|
||||
<policy policy="Duplicate" field="HFV_FLAECHE_RES"/>
|
||||
<policy policy="Duplicate" field="HFF_HABF_ID"/>
|
||||
<policy policy="Duplicate" field="HFF_FLTYP"/>
|
||||
<policy policy="Duplicate" field="GDF_NR_LAND"/>
|
||||
<policy policy="Duplicate" field="GID_BEZ"/>
|
||||
<policy policy="Duplicate" field="GTF_NR"/>
|
||||
<policy policy="Duplicate" field="HFV_BEW_POP"/>
|
||||
<policy policy="Duplicate" field="HFV_BEW_HAB"/>
|
||||
<policy policy="Duplicate" field="HFV_BEW_BTR"/>
|
||||
<policy policy="Duplicate" field="HFV_ZUS_ERH"/>
|
||||
<policy policy="Duplicate" field="HFV_ABW_GA"/>
|
||||
<policy policy="Duplicate" field="HFV_BEM_ZUS_ERH"/>
|
||||
<policy policy="Duplicate" field="LEGENDE"/>
|
||||
<policy policy="Duplicate" field="REPORT"/>
|
||||
<policy policy="Duplicate" field="GDF_ID"/>
|
||||
<policy policy="Duplicate" field="HFF_ID"/>
|
||||
<policy policy="Duplicate" field="HTFF_ID"/>
|
||||
<policy policy="Duplicate" field="HTFF_HABF_ID"/>
|
||||
<policy policy="Duplicate" field="OBJECTID"/>
|
||||
<policy policy="Duplicate" field="Shape__Area"/>
|
||||
<policy policy="Duplicate" field="Shape__Length"/>
|
||||
<policy policy="Duplicate" field="LEGENDE_2"/>
|
||||
<policy policy="Duplicate" field="SE_ANNO_CAD_DATA"/>
|
||||
</splitPolicies>
|
||||
<duplicatePolicies>
|
||||
<policy policy="Duplicate" field="ART_DEUTSCH"/>
|
||||
<policy policy="Duplicate" field="ART_WISSENSCHAFTL"/>
|
||||
<policy policy="Duplicate" field="HBTP_BEZ"/>
|
||||
<policy policy="Duplicate" field="HFV_DAT_ERF"/>
|
||||
<policy policy="Duplicate" field="HFV_FLAECHE_RES"/>
|
||||
<policy policy="Duplicate" field="HFF_HABF_ID"/>
|
||||
<policy policy="Duplicate" field="HFF_FLTYP"/>
|
||||
<policy policy="Duplicate" field="GDF_NR_LAND"/>
|
||||
<policy policy="Duplicate" field="GID_BEZ"/>
|
||||
<policy policy="Duplicate" field="GTF_NR"/>
|
||||
<policy policy="Duplicate" field="HFV_BEW_POP"/>
|
||||
<policy policy="Duplicate" field="HFV_BEW_HAB"/>
|
||||
<policy policy="Duplicate" field="HFV_BEW_BTR"/>
|
||||
<policy policy="Duplicate" field="HFV_ZUS_ERH"/>
|
||||
<policy policy="Duplicate" field="HFV_ABW_GA"/>
|
||||
<policy policy="Duplicate" field="HFV_BEM_ZUS_ERH"/>
|
||||
<policy policy="Duplicate" field="LEGENDE"/>
|
||||
<policy policy="Duplicate" field="REPORT"/>
|
||||
<policy policy="Duplicate" field="GDF_ID"/>
|
||||
<policy policy="Duplicate" field="HFF_ID"/>
|
||||
<policy policy="Duplicate" field="HTFF_ID"/>
|
||||
<policy policy="Duplicate" field="HTFF_HABF_ID"/>
|
||||
<policy policy="Duplicate" field="OBJECTID"/>
|
||||
<policy policy="Duplicate" field="Shape__Area"/>
|
||||
<policy policy="Duplicate" field="Shape__Length"/>
|
||||
<policy policy="Duplicate" field="LEGENDE_2"/>
|
||||
<policy policy="Duplicate" field="SE_ANNO_CAD_DATA"/>
|
||||
</duplicatePolicies>
|
||||
<defaults>
|
||||
<default field="ART_DEUTSCH" expression="" applyOnUpdate="0"/>
|
||||
<default field="ART_WISSENSCHAFTL" expression="" applyOnUpdate="0"/>
|
||||
<default field="HBTP_BEZ" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFV_DAT_ERF" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFV_FLAECHE_RES" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFF_HABF_ID" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFF_FLTYP" expression="" applyOnUpdate="0"/>
|
||||
<default field="GDF_NR_LAND" expression="" applyOnUpdate="0"/>
|
||||
<default field="GID_BEZ" expression="" applyOnUpdate="0"/>
|
||||
<default field="GTF_NR" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFV_BEW_POP" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFV_BEW_HAB" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFV_BEW_BTR" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFV_ZUS_ERH" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFV_ABW_GA" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFV_BEM_ZUS_ERH" expression="" applyOnUpdate="0"/>
|
||||
<default field="LEGENDE" expression="" applyOnUpdate="0"/>
|
||||
<default field="REPORT" expression="" applyOnUpdate="0"/>
|
||||
<default field="GDF_ID" expression="" applyOnUpdate="0"/>
|
||||
<default field="HFF_ID" expression="" applyOnUpdate="0"/>
|
||||
<default field="HTFF_ID" expression="" applyOnUpdate="0"/>
|
||||
<default field="HTFF_HABF_ID" expression="" applyOnUpdate="0"/>
|
||||
<default field="OBJECTID" expression="" applyOnUpdate="0"/>
|
||||
<default field="Shape__Area" expression="" applyOnUpdate="0"/>
|
||||
<default field="Shape__Length" expression="" applyOnUpdate="0"/>
|
||||
<default field="LEGENDE_2" expression="" applyOnUpdate="0"/>
|
||||
<default field="SE_ANNO_CAD_DATA" expression="" applyOnUpdate="0"/>
|
||||
</defaults>
|
||||
<constraints>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="ART_DEUTSCH"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="ART_WISSENSCHAFTL"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HBTP_BEZ"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFV_DAT_ERF"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFV_FLAECHE_RES"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFF_HABF_ID"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFF_FLTYP"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="GDF_NR_LAND"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="GID_BEZ"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="GTF_NR"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFV_BEW_POP"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFV_BEW_HAB"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFV_BEW_BTR"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFV_ZUS_ERH"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFV_ABW_GA"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFV_BEM_ZUS_ERH"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="LEGENDE"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="REPORT"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="GDF_ID"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HFF_ID"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HTFF_ID"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="HTFF_HABF_ID"/>
|
||||
<constraint constraints="3" unique_strength="1" exp_strength="0" notnull_strength="1" field="OBJECTID"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="Shape__Area"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="Shape__Length"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="LEGENDE_2"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="SE_ANNO_CAD_DATA"/>
|
||||
</constraints>
|
||||
<constraintExpressions>
|
||||
<constraint desc="" exp="" field="ART_DEUTSCH"/>
|
||||
<constraint desc="" exp="" field="ART_WISSENSCHAFTL"/>
|
||||
<constraint desc="" exp="" field="HBTP_BEZ"/>
|
||||
<constraint desc="" exp="" field="HFV_DAT_ERF"/>
|
||||
<constraint desc="" exp="" field="HFV_FLAECHE_RES"/>
|
||||
<constraint desc="" exp="" field="HFF_HABF_ID"/>
|
||||
<constraint desc="" exp="" field="HFF_FLTYP"/>
|
||||
<constraint desc="" exp="" field="GDF_NR_LAND"/>
|
||||
<constraint desc="" exp="" field="GID_BEZ"/>
|
||||
<constraint desc="" exp="" field="GTF_NR"/>
|
||||
<constraint desc="" exp="" field="HFV_BEW_POP"/>
|
||||
<constraint desc="" exp="" field="HFV_BEW_HAB"/>
|
||||
<constraint desc="" exp="" field="HFV_BEW_BTR"/>
|
||||
<constraint desc="" exp="" field="HFV_ZUS_ERH"/>
|
||||
<constraint desc="" exp="" field="HFV_ABW_GA"/>
|
||||
<constraint desc="" exp="" field="HFV_BEM_ZUS_ERH"/>
|
||||
<constraint desc="" exp="" field="LEGENDE"/>
|
||||
<constraint desc="" exp="" field="REPORT"/>
|
||||
<constraint desc="" exp="" field="GDF_ID"/>
|
||||
<constraint desc="" exp="" field="HFF_ID"/>
|
||||
<constraint desc="" exp="" field="HTFF_ID"/>
|
||||
<constraint desc="" exp="" field="HTFF_HABF_ID"/>
|
||||
<constraint desc="" exp="" field="OBJECTID"/>
|
||||
<constraint desc="" exp="" field="Shape__Area"/>
|
||||
<constraint desc="" exp="" field="Shape__Length"/>
|
||||
<constraint desc="" exp="" field="LEGENDE_2"/>
|
||||
<constraint desc="" exp="" field="SE_ANNO_CAD_DATA"/>
|
||||
</constraintExpressions>
|
||||
<expressionfields/>
|
||||
<attributeactions>
|
||||
<defaultAction value="{00000000-0000-0000-0000-000000000000}" key="Canvas"/>
|
||||
</attributeactions>
|
||||
<attributetableconfig sortOrder="0" actionWidgetStyle="dropDown" sortExpression="">
|
||||
<columns>
|
||||
<column name="ART_DEUTSCH" width="-1" type="field" hidden="0"/>
|
||||
<column name="ART_WISSENSCHAFTL" width="-1" type="field" hidden="0"/>
|
||||
<column name="HBTP_BEZ" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFV_DAT_ERF" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFV_FLAECHE_RES" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFF_HABF_ID" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFF_FLTYP" width="-1" type="field" hidden="0"/>
|
||||
<column name="GDF_NR_LAND" width="-1" type="field" hidden="0"/>
|
||||
<column name="GID_BEZ" width="-1" type="field" hidden="0"/>
|
||||
<column name="GTF_NR" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFV_BEW_POP" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFV_BEW_HAB" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFV_BEW_BTR" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFV_ZUS_ERH" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFV_ABW_GA" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFV_BEM_ZUS_ERH" width="-1" type="field" hidden="0"/>
|
||||
<column name="LEGENDE" width="-1" type="field" hidden="0"/>
|
||||
<column name="REPORT" width="-1" type="field" hidden="0"/>
|
||||
<column name="GDF_ID" width="-1" type="field" hidden="0"/>
|
||||
<column name="HFF_ID" width="-1" type="field" hidden="0"/>
|
||||
<column name="HTFF_ID" width="-1" type="field" hidden="0"/>
|
||||
<column name="HTFF_HABF_ID" width="-1" type="field" hidden="0"/>
|
||||
<column name="OBJECTID" width="-1" type="field" hidden="0"/>
|
||||
<column name="Shape__Area" width="-1" type="field" hidden="0"/>
|
||||
<column name="Shape__Length" width="-1" type="field" hidden="0"/>
|
||||
<column name="LEGENDE_2" width="-1" type="field" hidden="0"/>
|
||||
<column name="SE_ANNO_CAD_DATA" width="-1" type="field" hidden="0"/>
|
||||
<column width="-1" type="actions" hidden="1"/>
|
||||
</columns>
|
||||
</attributetableconfig>
|
||||
<conditionalstyles>
|
||||
<rowstyles/>
|
||||
<fieldstyles/>
|
||||
</conditionalstyles>
|
||||
<storedexpressions/>
|
||||
<editform tolerant="1"></editform>
|
||||
<editforminit/>
|
||||
<editforminitcodesource>0</editforminitcodesource>
|
||||
<editforminitfilepath></editforminitfilepath>
|
||||
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||
"""
|
||||
QGIS-Formulare können eine Python-Funktion haben,, die aufgerufen wird, wenn sich das Formular öffnet
|
||||
|
||||
Diese Funktion kann verwendet werden um dem Formular Extralogik hinzuzufügen.
|
||||
|
||||
Der Name der Funktion wird im Feld "Python Init-Function" angegeben
|
||||
Ein Beispiel folgt:
|
||||
"""
|
||||
from qgis.PyQt.QtWidgets import QWidget
|
||||
|
||||
def my_form_open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||
]]></editforminitcode>
|
||||
<featformsuppress>0</featformsuppress>
|
||||
<editorlayout>generatedlayout</editorlayout>
|
||||
<editable>
|
||||
<field name="ART_DEUTSCH" editable="1"/>
|
||||
<field name="ART_WISSENSCHAFTL" editable="1"/>
|
||||
<field name="GDF_ID" editable="1"/>
|
||||
<field name="GDF_NR_LAND" editable="1"/>
|
||||
<field name="GID_BEZ" editable="1"/>
|
||||
<field name="GTF_NR" editable="1"/>
|
||||
<field name="HBTP_BEZ" editable="1"/>
|
||||
<field name="HFF_FLTYP" editable="1"/>
|
||||
<field name="HFF_HABF_ID" editable="1"/>
|
||||
<field name="HFF_ID" editable="1"/>
|
||||
<field name="HFV_ABW_GA" editable="1"/>
|
||||
<field name="HFV_BEM_ZUS_ERH" editable="1"/>
|
||||
<field name="HFV_BEW_BTR" editable="1"/>
|
||||
<field name="HFV_BEW_HAB" editable="1"/>
|
||||
<field name="HFV_BEW_POP" editable="1"/>
|
||||
<field name="HFV_DAT_ERF" editable="1"/>
|
||||
<field name="HFV_FLAECHE_RES" editable="1"/>
|
||||
<field name="HFV_ZUS_ERH" editable="1"/>
|
||||
<field name="HTFF_HABF_ID" editable="1"/>
|
||||
<field name="HTFF_ID" editable="1"/>
|
||||
<field name="LEGENDE" editable="1"/>
|
||||
<field name="LEGENDE_2" editable="1"/>
|
||||
<field name="OBJECTID" editable="0"/>
|
||||
<field name="REPORT" editable="1"/>
|
||||
<field name="SE_ANNO_CAD_DATA" editable="1"/>
|
||||
<field name="Shape__Area" editable="0"/>
|
||||
<field name="Shape__Length" editable="0"/>
|
||||
</editable>
|
||||
<labelOnTop>
|
||||
<field name="ART_DEUTSCH" labelOnTop="0"/>
|
||||
<field name="ART_WISSENSCHAFTL" labelOnTop="0"/>
|
||||
<field name="GDF_ID" labelOnTop="0"/>
|
||||
<field name="GDF_NR_LAND" labelOnTop="0"/>
|
||||
<field name="GID_BEZ" labelOnTop="0"/>
|
||||
<field name="GTF_NR" labelOnTop="0"/>
|
||||
<field name="HBTP_BEZ" labelOnTop="0"/>
|
||||
<field name="HFF_FLTYP" labelOnTop="0"/>
|
||||
<field name="HFF_HABF_ID" labelOnTop="0"/>
|
||||
<field name="HFF_ID" labelOnTop="0"/>
|
||||
<field name="HFV_ABW_GA" labelOnTop="0"/>
|
||||
<field name="HFV_BEM_ZUS_ERH" labelOnTop="0"/>
|
||||
<field name="HFV_BEW_BTR" labelOnTop="0"/>
|
||||
<field name="HFV_BEW_HAB" labelOnTop="0"/>
|
||||
<field name="HFV_BEW_POP" labelOnTop="0"/>
|
||||
<field name="HFV_DAT_ERF" labelOnTop="0"/>
|
||||
<field name="HFV_FLAECHE_RES" labelOnTop="0"/>
|
||||
<field name="HFV_ZUS_ERH" labelOnTop="0"/>
|
||||
<field name="HTFF_HABF_ID" labelOnTop="0"/>
|
||||
<field name="HTFF_ID" labelOnTop="0"/>
|
||||
<field name="LEGENDE" labelOnTop="0"/>
|
||||
<field name="LEGENDE_2" labelOnTop="0"/>
|
||||
<field name="OBJECTID" labelOnTop="0"/>
|
||||
<field name="REPORT" labelOnTop="0"/>
|
||||
<field name="SE_ANNO_CAD_DATA" labelOnTop="0"/>
|
||||
<field name="Shape__Area" labelOnTop="0"/>
|
||||
<field name="Shape__Length" labelOnTop="0"/>
|
||||
</labelOnTop>
|
||||
<reuseLastValue>
|
||||
<field name="ART_DEUTSCH" reuseLastValue="0"/>
|
||||
<field name="ART_WISSENSCHAFTL" reuseLastValue="0"/>
|
||||
<field name="GDF_ID" reuseLastValue="0"/>
|
||||
<field name="GDF_NR_LAND" reuseLastValue="0"/>
|
||||
<field name="GID_BEZ" reuseLastValue="0"/>
|
||||
<field name="GTF_NR" reuseLastValue="0"/>
|
||||
<field name="HBTP_BEZ" reuseLastValue="0"/>
|
||||
<field name="HFF_FLTYP" reuseLastValue="0"/>
|
||||
<field name="HFF_HABF_ID" reuseLastValue="0"/>
|
||||
<field name="HFF_ID" reuseLastValue="0"/>
|
||||
<field name="HFV_ABW_GA" reuseLastValue="0"/>
|
||||
<field name="HFV_BEM_ZUS_ERH" reuseLastValue="0"/>
|
||||
<field name="HFV_BEW_BTR" reuseLastValue="0"/>
|
||||
<field name="HFV_BEW_HAB" reuseLastValue="0"/>
|
||||
<field name="HFV_BEW_POP" reuseLastValue="0"/>
|
||||
<field name="HFV_DAT_ERF" reuseLastValue="0"/>
|
||||
<field name="HFV_FLAECHE_RES" reuseLastValue="0"/>
|
||||
<field name="HFV_ZUS_ERH" reuseLastValue="0"/>
|
||||
<field name="HTFF_HABF_ID" reuseLastValue="0"/>
|
||||
<field name="HTFF_ID" reuseLastValue="0"/>
|
||||
<field name="LEGENDE" reuseLastValue="0"/>
|
||||
<field name="LEGENDE_2" reuseLastValue="0"/>
|
||||
<field name="OBJECTID" reuseLastValue="0"/>
|
||||
<field name="REPORT" reuseLastValue="0"/>
|
||||
<field name="SE_ANNO_CAD_DATA" reuseLastValue="0"/>
|
||||
<field name="Shape__Area" reuseLastValue="0"/>
|
||||
<field name="Shape__Length" reuseLastValue="0"/>
|
||||
</reuseLastValue>
|
||||
<dataDefinedFieldProperties/>
|
||||
<widgets/>
|
||||
<previewExpression>"ART_DEUTSCH"</previewExpression>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<layerGeometryType>2</layerGeometryType>
|
||||
</qgis>
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,597 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis autoRefreshMode="Disabled" autoRefreshTime="0" readOnly="0" styleCategories="AllStyleCategories" simplifyLocal="1" symbologyReferenceScale="-1" minScale="100000000" maxScale="0" labelsEnabled="1" simplifyDrawingHints="1" version="3.40.7-Bratislava" simplifyAlgorithm="0" hasScaleBasedVisibilityFlag="0" simplifyMaxScale="1" simplifyDrawingTol="1">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal enabled="0" limitMode="0" startField="" mode="0" durationField="Anzahl" endField="" endExpression="" durationUnit="min" fixedDuration="0" accumulate="0" startExpression="">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation zscale="1" type="IndividualFeatures" symbology="Line" respectLayerSymbol="1" extrusionEnabled="0" clamping="Terrain" showMarkerSymbolInSurfacePlots="0" extrusion="0" zoffset="0" binding="Centroid">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol alpha="1" type="line" name="" force_rhr="0" clip_to_extent="1" is_animated="0" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" id="{806bb2f8-e515-41c5-931f-aa961a636da4}" locked="0" class="SimpleLine" pass="0">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="align_dash_pattern" value="0"/>
|
||||
<Option type="QString" name="capstyle" value="square"/>
|
||||
<Option type="QString" name="customdash" value="5;2"/>
|
||||
<Option type="QString" name="customdash_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="customdash_unit" value="MM"/>
|
||||
<Option type="QString" name="dash_pattern_offset" value="0"/>
|
||||
<Option type="QString" name="dash_pattern_offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="dash_pattern_offset_unit" value="MM"/>
|
||||
<Option type="QString" name="draw_inside_polygon" value="0"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="line_color" value="231,113,72,255,rgb:0.90588235294117647,0.44313725490196076,0.28235294117647058,1"/>
|
||||
<Option type="QString" name="line_style" value="solid"/>
|
||||
<Option type="QString" name="line_width" value="0.6"/>
|
||||
<Option type="QString" name="line_width_unit" value="MM"/>
|
||||
<Option type="QString" name="offset" value="0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="ring_filter" value="0"/>
|
||||
<Option type="QString" name="trim_distance_end" value="0"/>
|
||||
<Option type="QString" name="trim_distance_end_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="trim_distance_end_unit" value="MM"/>
|
||||
<Option type="QString" name="trim_distance_start" value="0"/>
|
||||
<Option type="QString" name="trim_distance_start_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="trim_distance_start_unit" value="MM"/>
|
||||
<Option type="QString" name="tweak_dash_pattern_on_corners" value="0"/>
|
||||
<Option type="QString" name="use_custom_dash" value="0"/>
|
||||
<Option type="QString" name="width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol alpha="1" type="fill" name="" force_rhr="0" clip_to_extent="1" is_animated="0" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" id="{5fceef15-676f-4c5c-bb67-84e236dc3eab}" locked="0" class="SimpleFill" pass="0">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="color" value="231,113,72,255,rgb:0.90588235294117647,0.44313725490196076,0.28235294117647058,1"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="offset" value="0,0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="outline_color" value="165,81,51,255,rgb:0.6470588235294118,0.31651789120317386,0.20167849240863661,1"/>
|
||||
<Option type="QString" name="outline_style" value="solid"/>
|
||||
<Option type="QString" name="outline_width" value="0.2"/>
|
||||
<Option type="QString" name="outline_width_unit" value="MM"/>
|
||||
<Option type="QString" name="style" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
<profileMarkerSymbol>
|
||||
<symbol alpha="1" type="marker" name="" force_rhr="0" clip_to_extent="1" is_animated="0" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" id="{6c4ff12c-7cf1-4ddc-a6e1-b7f01dda66ad}" locked="0" class="SimpleMarker" pass="0">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="angle" value="0"/>
|
||||
<Option type="QString" name="cap_style" value="square"/>
|
||||
<Option type="QString" name="color" value="231,113,72,255,rgb:0.90588235294117647,0.44313725490196076,0.28235294117647058,1"/>
|
||||
<Option type="QString" name="horizontal_anchor_point" value="1"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="name" value="diamond"/>
|
||||
<Option type="QString" name="offset" value="0,0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="outline_color" value="165,81,51,255,rgb:0.6470588235294118,0.31651789120317386,0.20167849240863661,1"/>
|
||||
<Option type="QString" name="outline_style" value="solid"/>
|
||||
<Option type="QString" name="outline_width" value="0.2"/>
|
||||
<Option type="QString" name="outline_width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="outline_width_unit" value="MM"/>
|
||||
<Option type="QString" name="scale_method" value="diameter"/>
|
||||
<Option type="QString" name="size" value="3"/>
|
||||
<Option type="QString" name="size_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="size_unit" value="MM"/>
|
||||
<Option type="QString" name="vertical_anchor_point" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileMarkerSymbol>
|
||||
</elevation>
|
||||
<renderer-v2 referencescale="-1" type="singleSymbol" forceraster="0" enableorderby="0" symbollevels="0">
|
||||
<symbols>
|
||||
<symbol alpha="1" type="fill" name="0" force_rhr="0" clip_to_extent="1" is_animated="0" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" id="{37953f01-68d9-43be-b9d8-546ca454487e}" locked="0" class="SimpleFill" pass="0">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="color" value="0,85,255,255,rgb:0,0.33333333333333331,1,1"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="offset" value="0,0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="outline_color" value="0,85,255,255,rgb:0,0.33333333333333331,1,1"/>
|
||||
<Option type="QString" name="outline_style" value="solid"/>
|
||||
<Option type="QString" name="outline_width" value="1.06"/>
|
||||
<Option type="QString" name="outline_width_unit" value="MM"/>
|
||||
<Option type="QString" name="style" value="no"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</symbols>
|
||||
<rotation/>
|
||||
<sizescale/>
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
</renderer-v2>
|
||||
<selection mode="Default">
|
||||
<selectionColor invalid="1"/>
|
||||
<selectionSymbol>
|
||||
<symbol alpha="1" type="fill" name="" force_rhr="0" clip_to_extent="1" is_animated="0" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" id="{37c84ab2-1f8e-4d9f-90bb-400976543063}" locked="0" class="SimpleFill" pass="0">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="color" value="0,0,255,255,rgb:0,0,1,1"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="offset" value="0,0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="outline_color" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option type="QString" name="outline_style" value="solid"/>
|
||||
<Option type="QString" name="outline_width" value="0.26"/>
|
||||
<Option type="QString" name="outline_width_unit" value="MM"/>
|
||||
<Option type="QString" name="style" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</selectionSymbol>
|
||||
</selection>
|
||||
<labeling type="rule-based">
|
||||
<rules key="{31adca09-e30f-437a-bc70-ef63b20670ed}">
|
||||
<rule filter="left("MKZ",3)='222'" key="{79a5bb52-55b4-45ee-89fe-d90e0fe95f62}" description="Wege,geplant">
|
||||
<settings calloutType="simple">
|
||||
<text-style fontKerning="0" useSubstitutions="0" namedStyle="Bold" previewBkgrdColor="255,255,255,255,rgb:1,1,1,1" fontWeight="75" tabStopDistanceMapUnitScale="3x:0,0,0,0,0,0" fontUnderline="0" tabStopDistance="80" fieldName="left("MKZ",3)|| '\n' || '―'|| '\n' || right("MKZ",4)" textColor="5,125,180,255,rgb:0.0196078431372549,0.49019607843137253,0.70588235294117652,1" fontStrikeout="0" forcedBold="0" forcedItalic="0" allowHtml="0" multilineHeight="0.59999999999999998" fontSize="10" fontWordSpacing="-0.6875" stretchFactor="100" blendMode="0" fontSizeMapUnitScale="3x:0,0,0,0,0,0" textOrientation="horizontal" fontItalic="0" fontLetterSpacing="-0.5625" tabStopDistanceUnit="Point" multilineHeightUnit="Percentage" fontFamily="Arial" fontSizeUnit="Point" capitalization="0" isExpression="1" legendString="Aa" textOpacity="1">
|
||||
<families/>
|
||||
<text-buffer bufferColor="255,0,0,255,hsv:0,1,1,1" bufferNoFill="1" bufferSize="1" bufferSizeMapUnitScale="3x:0,0,0,0,0,0" bufferSizeUnits="MM" bufferDraw="0" bufferJoinStyle="128" bufferOpacity="1" bufferBlendMode="0"/>
|
||||
<text-mask maskedSymbolLayers="" maskJoinStyle="128" maskEnabled="0" maskType="0" maskSize2="1.5" maskSizeUnits="MM" maskSizeMapUnitScale="3x:0,0,0,0,0,0" maskSize="1.5" maskOpacity="1"/>
|
||||
<background shapeJoinStyle="64" shapeBlendMode="0" shapeRotationType="0" shapeRadiiX="0" shapeRadiiY="0" shapeSVGFile="" shapeSizeType="0" shapeBorderWidthMapUnitScale="3x:0,0,0,0,0,0" shapeSizeUnit="Point" shapeRadiiMapUnitScale="3x:0,0,0,0,0,0" shapeFillColor="255,255,255,255,rgb:1,1,1,1" shapeOffsetMapUnitScale="3x:0,0,0,0,0,0" shapeDraw="1" shapeRotation="0" shapeType="5" shapeSizeMapUnitScale="3x:0,0,0,0,0,0" shapeOffsetUnit="Point" shapeRadiiUnit="Point" shapeSizeX="3" shapeOpacity="1" shapeBorderWidth="0" shapeOffsetY="0" shapeBorderColor="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1" shapeBorderWidthUnit="Point" shapeSizeY="0" shapeOffsetX="0">
|
||||
<symbol alpha="1" type="marker" name="markerSymbol" force_rhr="0" clip_to_extent="1" is_animated="0" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" id="" locked="0" class="SimpleMarker" pass="0">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="angle" value="0"/>
|
||||
<Option type="QString" name="cap_style" value="square"/>
|
||||
<Option type="QString" name="color" value="255,255,255,255,rgb:1,1,1,1"/>
|
||||
<Option type="QString" name="horizontal_anchor_point" value="1"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="name" value="circle"/>
|
||||
<Option type="QString" name="offset" value="0,0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="outline_color" value="8,135,203,255,rgb:0.03137254901960784,0.52941176470588236,0.79607843137254897,1"/>
|
||||
<Option type="QString" name="outline_style" value="solid"/>
|
||||
<Option type="QString" name="outline_width" value="0.6"/>
|
||||
<Option type="QString" name="outline_width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="outline_width_unit" value="MM"/>
|
||||
<Option type="QString" name="scale_method" value="diameter"/>
|
||||
<Option type="QString" name="size" value="2"/>
|
||||
<Option type="QString" name="size_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="size_unit" value="MM"/>
|
||||
<Option type="QString" name="vertical_anchor_point" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
<symbol alpha="1" type="fill" name="fillSymbol" force_rhr="0" clip_to_extent="1" is_animated="0" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" id="" locked="0" class="SimpleFill" pass="0">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="color" value="255,255,255,255,rgb:1,1,1,1"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="offset" value="0,0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="outline_color" value="128,128,128,255,rgb:0.50196078431372548,0.50196078431372548,0.50196078431372548,1"/>
|
||||
<Option type="QString" name="outline_style" value="no"/>
|
||||
<Option type="QString" name="outline_width" value="0"/>
|
||||
<Option type="QString" name="outline_width_unit" value="Point"/>
|
||||
<Option type="QString" name="style" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</background>
|
||||
<shadow shadowOffsetAngle="135" shadowRadiusAlphaOnly="0" shadowUnder="0" shadowOffsetMapUnitScale="3x:0,0,0,0,0,0" shadowRadius="1.5" shadowOffsetDist="1" shadowScale="100" shadowColor="0,0,0,255,rgb:0,0,0,1" shadowOffsetUnit="MM" shadowRadiusUnit="MM" shadowBlendMode="6" shadowOpacity="0.69999999999999996" shadowDraw="0" shadowRadiusMapUnitScale="3x:0,0,0,0,0,0" shadowOffsetGlobal="1"/>
|
||||
<dd_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</dd_properties>
|
||||
<substitutions/>
|
||||
</text-style>
|
||||
<text-format useMaxLineLengthForAutoWrap="1" formatNumbers="0" leftDirectionSymbol="<" rightDirectionSymbol=">" reverseDirectionSymbol="0" decimals="3" wrapChar="" autoWrapLength="0" placeDirectionSymbol="0" plussign="0" multilineAlign="1" addDirectionSymbol="0"/>
|
||||
<placement placementFlags="14" placement="4" distUnits="MM" maximumDistance="0" fitInPolygonOnly="0" offsetUnits="MM" repeatDistance="0" geometryGeneratorEnabled="0" rotationUnit="AngleDegrees" lineAnchorTextPoint="CenterOfText" lineAnchorClipping="1" centroidWhole="0" priority="6" geometryGeneratorType="PointGeometry" prioritization="PreferCloser" repeatDistanceMapUnitScale="3x:0,0,0,0,0,0" overrunDistance="0" rotationAngle="0" quadOffset="4" dist="5" overlapHandling="PreventOverlap" offsetType="0" layerType="PolygonGeometry" repeatDistanceUnits="MM" predefinedPositionOrder="TR,TL,BR,BL,R,L,TSR,BSR" overrunDistanceMapUnitScale="3x:0,0,0,0,0,0" centroidInside="0" maximumDistanceUnit="MM" allowDegraded="0" maxCurvedCharAngleOut="-25" polygonPlacementFlags="3" labelOffsetMapUnitScale="3x:0,0,0,0,0,0" geometryGenerator="" lineAnchorType="0" lineAnchorPercent="0.5" xOffset="0" preserveRotation="0" maxCurvedCharAngleIn="25" overrunDistanceUnit="MM" yOffset="0" maximumDistanceMapUnitScale="3x:0,0,0,0,0,0" distMapUnitScale="3x:0,0,0,0,0,0"/>
|
||||
<rendering obstacle="1" scaleVisibility="0" maxNumLabels="2000" drawLabels="1" labelPerPart="0" obstacleFactor="1.2" fontMinPixelSize="3" scaleMin="0" unplacedVisibility="0" zIndex="0" upsidedownLabels="0" fontLimitPixelSize="0" limitNumLabels="0" minFeatureSize="0" fontMaxPixelSize="10000" scaleMax="0" obstacleType="1" mergeLines="0"/>
|
||||
<dd_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</dd_properties>
|
||||
<callout type="simple">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="anchorPoint" value="pole_of_inaccessibility"/>
|
||||
<Option type="int" name="blendMode" value="0"/>
|
||||
<Option type="Map" name="ddProperties">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
<Option type="bool" name="drawToAllParts" value="false"/>
|
||||
<Option type="QString" name="enabled" value="0"/>
|
||||
<Option type="QString" name="labelAnchorPoint" value="point_on_exterior"/>
|
||||
<Option type="QString" name="lineSymbol" value="<symbol alpha="1" type="line" name="symbol" force_rhr="0" clip_to_extent="1" is_animated="0" frame_rate="10"><data_defined_properties><Option type="Map"><Option type="QString" name="name" value=""/><Option name="properties"/><Option type="QString" name="type" value="collection"/></Option></data_defined_properties><layer enabled="1" id="{03dc8a93-2fef-4767-9787-e3607853696d}" locked="0" class="SimpleLine" pass="0"><Option type="Map"><Option type="QString" name="align_dash_pattern" value="0"/><Option type="QString" name="capstyle" value="square"/><Option type="QString" name="customdash" value="5;2"/><Option type="QString" name="customdash_map_unit_scale" value="3x:0,0,0,0,0,0"/><Option type="QString" name="customdash_unit" value="MM"/><Option type="QString" name="dash_pattern_offset" value="0"/><Option type="QString" name="dash_pattern_offset_map_unit_scale" value="3x:0,0,0,0,0,0"/><Option type="QString" name="dash_pattern_offset_unit" value="MM"/><Option type="QString" name="draw_inside_polygon" value="0"/><Option type="QString" name="joinstyle" value="bevel"/><Option type="QString" name="line_color" value="60,60,60,255,rgb:0.23529411764705882,0.23529411764705882,0.23529411764705882,1"/><Option type="QString" name="line_style" value="solid"/><Option type="QString" name="line_width" value="0.3"/><Option type="QString" name="line_width_unit" value="MM"/><Option type="QString" name="offset" value="0"/><Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/><Option type="QString" name="offset_unit" value="MM"/><Option type="QString" name="ring_filter" value="0"/><Option type="QString" name="trim_distance_end" value="0"/><Option type="QString" name="trim_distance_end_map_unit_scale" value="3x:0,0,0,0,0,0"/><Option type="QString" name="trim_distance_end_unit" value="MM"/><Option type="QString" name="trim_distance_start" value="0"/><Option type="QString" name="trim_distance_start_map_unit_scale" value="3x:0,0,0,0,0,0"/><Option type="QString" name="trim_distance_start_unit" value="MM"/><Option type="QString" name="tweak_dash_pattern_on_corners" value="0"/><Option type="QString" name="use_custom_dash" value="0"/><Option type="QString" name="width_map_unit_scale" value="3x:0,0,0,0,0,0"/></Option><data_defined_properties><Option type="Map"><Option type="QString" name="name" value=""/><Option name="properties"/><Option type="QString" name="type" value="collection"/></Option></data_defined_properties></layer></symbol>"/>
|
||||
<Option type="double" name="minLength" value="0"/>
|
||||
<Option type="QString" name="minLengthMapUnitScale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="minLengthUnit" value="MM"/>
|
||||
<Option type="double" name="offsetFromAnchor" value="0"/>
|
||||
<Option type="QString" name="offsetFromAnchorMapUnitScale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offsetFromAnchorUnit" value="MM"/>
|
||||
<Option type="double" name="offsetFromLabel" value="0"/>
|
||||
<Option type="QString" name="offsetFromLabelMapUnitScale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offsetFromLabelUnit" value="MM"/>
|
||||
</Option>
|
||||
</callout>
|
||||
</settings>
|
||||
</rule>
|
||||
</rules>
|
||||
</labeling>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option type="List" name="dualview/previewExpressions">
|
||||
<Option type="QString" value=""NAME""/>
|
||||
</Option>
|
||||
<Option type="int" name="embeddedWidgets/count" value="0"/>
|
||||
<Option type="QString" name="geopdf/groupName" value="Verfahren"/>
|
||||
<Option name="variableNames"/>
|
||||
<Option name="variableValues"/>
|
||||
<Option type="QString" name="vln_karten/api_path" value="/maps/p41/27027"/>
|
||||
<Option type="QString" name="vln_karten/dataset" value="p41"/>
|
||||
<Option type="QString" name="vln_karten/verfahren" value="27027"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<blendMode>0</blendMode>
|
||||
<featureBlendMode>0</featureBlendMode>
|
||||
<layerOpacity>1</layerOpacity>
|
||||
<geometryOptions removeDuplicateNodes="0" geometryPrecision="0">
|
||||
<activeChecks/>
|
||||
<checkConfiguration type="Map">
|
||||
<Option type="Map" name="QgsGeometryGapCheck">
|
||||
<Option type="double" name="allowedGapsBuffer" value="0"/>
|
||||
<Option type="bool" name="allowedGapsEnabled" value="false"/>
|
||||
<Option type="QString" name="allowedGapsLayer" value=""/>
|
||||
</Option>
|
||||
</checkConfiguration>
|
||||
</geometryOptions>
|
||||
<legend type="default-vector" showLabelLegend="0"/>
|
||||
<referencedLayers/>
|
||||
<fieldConfiguration>
|
||||
<field name="Anzahl" configurationFlags="NoFlag">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Baumart" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Belag" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Fahrbahn" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Krone" configurationFlags="NoFlag">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="MKZ" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="NAME" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="VKZ" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="qm" configurationFlags="NoFlag">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
</fieldConfiguration>
|
||||
<aliases>
|
||||
<alias name="" index="0" field="Anzahl"/>
|
||||
<alias name="" index="1" field="Baumart"/>
|
||||
<alias name="" index="2" field="Belag"/>
|
||||
<alias name="" index="3" field="Fahrbahn"/>
|
||||
<alias name="" index="4" field="Krone"/>
|
||||
<alias name="" index="5" field="MKZ"/>
|
||||
<alias name="" index="6" field="NAME"/>
|
||||
<alias name="" index="7" field="VKZ"/>
|
||||
<alias name="" index="8" field="qm"/>
|
||||
</aliases>
|
||||
<splitPolicies>
|
||||
<policy policy="Duplicate" field="Anzahl"/>
|
||||
<policy policy="Duplicate" field="Baumart"/>
|
||||
<policy policy="Duplicate" field="Belag"/>
|
||||
<policy policy="Duplicate" field="Fahrbahn"/>
|
||||
<policy policy="Duplicate" field="Krone"/>
|
||||
<policy policy="Duplicate" field="MKZ"/>
|
||||
<policy policy="Duplicate" field="NAME"/>
|
||||
<policy policy="Duplicate" field="VKZ"/>
|
||||
<policy policy="Duplicate" field="qm"/>
|
||||
</splitPolicies>
|
||||
<duplicatePolicies>
|
||||
<policy policy="Duplicate" field="Anzahl"/>
|
||||
<policy policy="Duplicate" field="Baumart"/>
|
||||
<policy policy="Duplicate" field="Belag"/>
|
||||
<policy policy="Duplicate" field="Fahrbahn"/>
|
||||
<policy policy="Duplicate" field="Krone"/>
|
||||
<policy policy="Duplicate" field="MKZ"/>
|
||||
<policy policy="Duplicate" field="NAME"/>
|
||||
<policy policy="Duplicate" field="VKZ"/>
|
||||
<policy policy="Duplicate" field="qm"/>
|
||||
</duplicatePolicies>
|
||||
<defaults>
|
||||
<default expression="" applyOnUpdate="0" field="Anzahl"/>
|
||||
<default expression="" applyOnUpdate="0" field="Baumart"/>
|
||||
<default expression="" applyOnUpdate="0" field="Belag"/>
|
||||
<default expression="" applyOnUpdate="0" field="Fahrbahn"/>
|
||||
<default expression="" applyOnUpdate="0" field="Krone"/>
|
||||
<default expression="" applyOnUpdate="0" field="MKZ"/>
|
||||
<default expression="" applyOnUpdate="0" field="NAME"/>
|
||||
<default expression="" applyOnUpdate="0" field="VKZ"/>
|
||||
<default expression="" applyOnUpdate="0" field="qm"/>
|
||||
</defaults>
|
||||
<constraints>
|
||||
<constraint exp_strength="0" notnull_strength="0" constraints="0" unique_strength="0" field="Anzahl"/>
|
||||
<constraint exp_strength="0" notnull_strength="0" constraints="0" unique_strength="0" field="Baumart"/>
|
||||
<constraint exp_strength="0" notnull_strength="0" constraints="0" unique_strength="0" field="Belag"/>
|
||||
<constraint exp_strength="0" notnull_strength="0" constraints="0" unique_strength="0" field="Fahrbahn"/>
|
||||
<constraint exp_strength="0" notnull_strength="0" constraints="0" unique_strength="0" field="Krone"/>
|
||||
<constraint exp_strength="0" notnull_strength="0" constraints="0" unique_strength="0" field="MKZ"/>
|
||||
<constraint exp_strength="0" notnull_strength="0" constraints="0" unique_strength="0" field="NAME"/>
|
||||
<constraint exp_strength="0" notnull_strength="0" constraints="0" unique_strength="0" field="VKZ"/>
|
||||
<constraint exp_strength="0" notnull_strength="0" constraints="0" unique_strength="0" field="qm"/>
|
||||
</constraints>
|
||||
<constraintExpressions>
|
||||
<constraint exp="" desc="" field="Anzahl"/>
|
||||
<constraint exp="" desc="" field="Baumart"/>
|
||||
<constraint exp="" desc="" field="Belag"/>
|
||||
<constraint exp="" desc="" field="Fahrbahn"/>
|
||||
<constraint exp="" desc="" field="Krone"/>
|
||||
<constraint exp="" desc="" field="MKZ"/>
|
||||
<constraint exp="" desc="" field="NAME"/>
|
||||
<constraint exp="" desc="" field="VKZ"/>
|
||||
<constraint exp="" desc="" field="qm"/>
|
||||
</constraintExpressions>
|
||||
<expressionfields/>
|
||||
<attributeactions>
|
||||
<defaultAction value="{00000000-0000-0000-0000-000000000000}" key="Canvas"/>
|
||||
</attributeactions>
|
||||
<attributetableconfig sortExpression="" actionWidgetStyle="dropDown" sortOrder="0">
|
||||
<columns>
|
||||
<column type="field" name="Anzahl" width="-1" hidden="0"/>
|
||||
<column type="field" name="Baumart" width="-1" hidden="0"/>
|
||||
<column type="field" name="Belag" width="-1" hidden="0"/>
|
||||
<column type="field" name="Fahrbahn" width="-1" hidden="0"/>
|
||||
<column type="field" name="Krone" width="-1" hidden="0"/>
|
||||
<column type="field" name="MKZ" width="-1" hidden="0"/>
|
||||
<column type="field" name="NAME" width="-1" hidden="0"/>
|
||||
<column type="field" name="VKZ" width="-1" hidden="0"/>
|
||||
<column type="field" name="qm" width="-1" hidden="0"/>
|
||||
<column type="actions" width="-1" hidden="1"/>
|
||||
</columns>
|
||||
</attributetableconfig>
|
||||
<conditionalstyles>
|
||||
<rowstyles/>
|
||||
<fieldstyles/>
|
||||
</conditionalstyles>
|
||||
<storedexpressions/>
|
||||
<editform tolerant="1"></editform>
|
||||
<editforminit/>
|
||||
<editforminitcodesource>0</editforminitcodesource>
|
||||
<editforminitfilepath></editforminitfilepath>
|
||||
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||
"""
|
||||
QGIS-Formulare können eine Python-Funktion haben,, die aufgerufen wird, wenn sich das Formular öffnet
|
||||
|
||||
Diese Funktion kann verwendet werden um dem Formular Extralogik hinzuzufügen.
|
||||
|
||||
Der Name der Funktion wird im Feld "Python Init-Function" angegeben
|
||||
Ein Beispiel folgt:
|
||||
"""
|
||||
from qgis.PyQt.QtWidgets import QWidget
|
||||
|
||||
def my_form_open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||
]]></editforminitcode>
|
||||
<featformsuppress>0</featformsuppress>
|
||||
<editorlayout>generatedlayout</editorlayout>
|
||||
<editable>
|
||||
<field name="Anzahl" editable="1"/>
|
||||
<field name="Baumart" editable="1"/>
|
||||
<field name="Belag" editable="1"/>
|
||||
<field name="Fahrbahn" editable="1"/>
|
||||
<field name="Krone" editable="1"/>
|
||||
<field name="MKZ" editable="1"/>
|
||||
<field name="NAME" editable="1"/>
|
||||
<field name="VKZ" editable="1"/>
|
||||
<field name="qm" editable="1"/>
|
||||
</editable>
|
||||
<labelOnTop>
|
||||
<field name="Anzahl" labelOnTop="0"/>
|
||||
<field name="Baumart" labelOnTop="0"/>
|
||||
<field name="Belag" labelOnTop="0"/>
|
||||
<field name="Fahrbahn" labelOnTop="0"/>
|
||||
<field name="Krone" labelOnTop="0"/>
|
||||
<field name="MKZ" labelOnTop="0"/>
|
||||
<field name="NAME" labelOnTop="0"/>
|
||||
<field name="VKZ" labelOnTop="0"/>
|
||||
<field name="qm" labelOnTop="0"/>
|
||||
</labelOnTop>
|
||||
<reuseLastValue>
|
||||
<field reuseLastValue="0" name="Anzahl"/>
|
||||
<field reuseLastValue="0" name="Baumart"/>
|
||||
<field reuseLastValue="0" name="Belag"/>
|
||||
<field reuseLastValue="0" name="Fahrbahn"/>
|
||||
<field reuseLastValue="0" name="Krone"/>
|
||||
<field reuseLastValue="0" name="MKZ"/>
|
||||
<field reuseLastValue="0" name="NAME"/>
|
||||
<field reuseLastValue="0" name="VKZ"/>
|
||||
<field reuseLastValue="0" name="qm"/>
|
||||
</reuseLastValue>
|
||||
<dataDefinedFieldProperties/>
|
||||
<widgets/>
|
||||
<previewExpression>"NAME"</previewExpression>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<layerGeometryType>2</layerGeometryType>
|
||||
</qgis>
|
||||
@@ -0,0 +1,516 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis maxScale="0" simplifyDrawingHints="1" simplifyMaxScale="1" simplifyLocal="1" styleCategories="AllStyleCategories" labelsEnabled="0" simplifyAlgorithm="0" minScale="100000000" version="3.40.7-Bratislava" symbologyReferenceScale="-1" hasScaleBasedVisibilityFlag="0" autoRefreshMode="Disabled" readOnly="0" autoRefreshTime="0" simplifyDrawingTol="1">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal endExpression="" durationField="OBJECTID" enabled="0" mode="0" fixedDuration="0" startField="" accumulate="0" limitMode="0" endField="" durationUnit="min" startExpression="">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation respectLayerSymbol="1" zscale="1" extrusionEnabled="0" extrusion="0" type="IndividualFeatures" clamping="Terrain" symbology="Line" binding="Centroid" showMarkerSymbolInSurfacePlots="0" zoffset="0">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="line" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleLine" locked="0" id="{322ac269-5ed9-4529-82eb-f6d50258e9d7}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="align_dash_pattern" type="QString" value="0"/>
|
||||
<Option name="capstyle" type="QString" value="square"/>
|
||||
<Option name="customdash" type="QString" value="5;2"/>
|
||||
<Option name="customdash_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="customdash_unit" type="QString" value="MM"/>
|
||||
<Option name="dash_pattern_offset" type="QString" value="0"/>
|
||||
<Option name="dash_pattern_offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="dash_pattern_offset_unit" type="QString" value="MM"/>
|
||||
<Option name="draw_inside_polygon" type="QString" value="0"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="line_color" type="QString" value="145,82,45,255,rgb:0.56862745098039214,0.32156862745098042,0.17647058823529413,1"/>
|
||||
<Option name="line_style" type="QString" value="solid"/>
|
||||
<Option name="line_width" type="QString" value="0.6"/>
|
||||
<Option name="line_width_unit" type="QString" value="MM"/>
|
||||
<Option name="offset" type="QString" value="0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="ring_filter" type="QString" value="0"/>
|
||||
<Option name="trim_distance_end" type="QString" value="0"/>
|
||||
<Option name="trim_distance_end_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="trim_distance_end_unit" type="QString" value="MM"/>
|
||||
<Option name="trim_distance_start" type="QString" value="0"/>
|
||||
<Option name="trim_distance_start_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="trim_distance_start_unit" type="QString" value="MM"/>
|
||||
<Option name="tweak_dash_pattern_on_corners" type="QString" value="0"/>
|
||||
<Option name="use_custom_dash" type="QString" value="0"/>
|
||||
<Option name="width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{8a672c34-07cc-4c89-b9a6-b505a5d0e87f}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="145,82,45,255,rgb:0.56862745098039214,0.32156862745098042,0.17647058823529413,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="104,59,32,255,rgb:0.40614938582436866,0.22967879758907453,0.12603952086671244,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.2"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
<profileMarkerSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="marker" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleMarker" locked="0" id="{203784dc-59ab-4b43-bd5b-cc85a7fcf2f5}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="angle" type="QString" value="0"/>
|
||||
<Option name="cap_style" type="QString" value="square"/>
|
||||
<Option name="color" type="QString" value="145,82,45,255,rgb:0.56862745098039214,0.32156862745098042,0.17647058823529413,1"/>
|
||||
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="name" type="QString" value="diamond"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="104,59,32,255,rgb:0.40614938582436866,0.22967879758907453,0.12603952086671244,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.2"/>
|
||||
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="scale_method" type="QString" value="diameter"/>
|
||||
<Option name="size" type="QString" value="3"/>
|
||||
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="size_unit" type="QString" value="MM"/>
|
||||
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileMarkerSymbol>
|
||||
</elevation>
|
||||
<renderer-v2 forceraster="0" type="categorizedSymbol" enableorderby="0" referencescale="-1" attr="FB_BN_KAT" symbollevels="0">
|
||||
<categories>
|
||||
<category render="true" uuid="{fe3d6ff3-2b79-4775-8ee7-3d1ccfd1cd77}" type="string" label="AL" value="AL" symbol="0"/>
|
||||
<category render="true" uuid="{4bea0187-6bcf-418a-bbd9-39f7b5334b19}" type="NULL" label="" value="NULL" symbol="1"/>
|
||||
</categories>
|
||||
<symbols>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="0" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{6725bd87-d1ed-46a2-a500-d22c83510ab8}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="203,203,101,255,rgb:0.79607843137254897,0.79607843137254897,0.396078431372549,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="1" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{e0ad06d8-97eb-4592-a841-0b06fa4c1fe0}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="100,222,94,255,hsv:0.32500000000000001,0.57647058823529407,0.87058823529411766,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</symbols>
|
||||
<source-symbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="0" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{d5672f9f-8595-4ee2-bce8-db0978ea6f57}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="125,139,143,255,rgb:0.49019607843137253,0.54509803921568623,0.5607843137254902,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</source-symbol>
|
||||
<colorramp name="[source]" type="randomcolors">
|
||||
<Option/>
|
||||
</colorramp>
|
||||
<rotation/>
|
||||
<sizescale/>
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
</renderer-v2>
|
||||
<selection mode="Default">
|
||||
<selectionColor invalid="1"/>
|
||||
<selectionSymbol>
|
||||
<symbol frame_rate="10" clip_to_extent="1" is_animated="0" name="" force_rhr="0" type="fill" alpha="1">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" id="{9ffb125e-e358-4390-8adb-d8c9c14a882f}" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="0,0,255,255,rgb:0,0,1,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.13725490196078433,0.13725490196078433,0.13725490196078433,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</selectionSymbol>
|
||||
</selection>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option name="embeddedWidgets/count" type="int" value="0"/>
|
||||
<Option name="variableNames"/>
|
||||
<Option name="variableValues"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<blendMode>0</blendMode>
|
||||
<featureBlendMode>0</featureBlendMode>
|
||||
<layerOpacity>1</layerOpacity>
|
||||
<geometryOptions geometryPrecision="0" removeDuplicateNodes="0">
|
||||
<activeChecks/>
|
||||
<checkConfiguration type="Map">
|
||||
<Option name="QgsGeometryGapCheck" type="Map">
|
||||
<Option name="allowedGapsBuffer" type="double" value="0"/>
|
||||
<Option name="allowedGapsEnabled" type="bool" value="false"/>
|
||||
<Option name="allowedGapsLayer" type="QString" value=""/>
|
||||
</Option>
|
||||
</checkConfiguration>
|
||||
</geometryOptions>
|
||||
<legend showLabelLegend="0" type="default-vector"/>
|
||||
<referencedLayers/>
|
||||
<fieldConfiguration>
|
||||
<field name="OBJECTID" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="FL" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="FB_BN_KAT" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="FB_BEZEICH" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="REG_SAAT" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="SE_ANNO_CAD_DATA" configurationFlags="NoFlag">
|
||||
<editWidget type="Binary">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Shape__Area" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="Shape__Length" configurationFlags="NoFlag">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
</fieldConfiguration>
|
||||
<aliases>
|
||||
<alias index="0" name="" field="OBJECTID"/>
|
||||
<alias index="1" name="Flaeche_des_Feldblocks_in_ha" field="FL"/>
|
||||
<alias index="2" name="Kategorie_des_Feldblocks" field="FB_BN_KAT"/>
|
||||
<alias index="3" name="Bezeichnung_des_Feldblocks" field="FB_BEZEICH"/>
|
||||
<alias index="4" name="Ursprungsgebiet_UG_Herkunft_des_Regiosaatguts" field="REG_SAAT"/>
|
||||
<alias index="5" name="" field="SE_ANNO_CAD_DATA"/>
|
||||
<alias index="6" name="SHAPE.AREA" field="Shape__Area"/>
|
||||
<alias index="7" name="SHAPE.LEN" field="Shape__Length"/>
|
||||
</aliases>
|
||||
<splitPolicies>
|
||||
<policy policy="Duplicate" field="OBJECTID"/>
|
||||
<policy policy="Duplicate" field="FL"/>
|
||||
<policy policy="Duplicate" field="FB_BN_KAT"/>
|
||||
<policy policy="Duplicate" field="FB_BEZEICH"/>
|
||||
<policy policy="Duplicate" field="REG_SAAT"/>
|
||||
<policy policy="Duplicate" field="SE_ANNO_CAD_DATA"/>
|
||||
<policy policy="Duplicate" field="Shape__Area"/>
|
||||
<policy policy="Duplicate" field="Shape__Length"/>
|
||||
</splitPolicies>
|
||||
<duplicatePolicies>
|
||||
<policy policy="Duplicate" field="OBJECTID"/>
|
||||
<policy policy="Duplicate" field="FL"/>
|
||||
<policy policy="Duplicate" field="FB_BN_KAT"/>
|
||||
<policy policy="Duplicate" field="FB_BEZEICH"/>
|
||||
<policy policy="Duplicate" field="REG_SAAT"/>
|
||||
<policy policy="Duplicate" field="SE_ANNO_CAD_DATA"/>
|
||||
<policy policy="Duplicate" field="Shape__Area"/>
|
||||
<policy policy="Duplicate" field="Shape__Length"/>
|
||||
</duplicatePolicies>
|
||||
<defaults>
|
||||
<default field="OBJECTID" expression="" applyOnUpdate="0"/>
|
||||
<default field="FL" expression="" applyOnUpdate="0"/>
|
||||
<default field="FB_BN_KAT" expression="" applyOnUpdate="0"/>
|
||||
<default field="FB_BEZEICH" expression="" applyOnUpdate="0"/>
|
||||
<default field="REG_SAAT" expression="" applyOnUpdate="0"/>
|
||||
<default field="SE_ANNO_CAD_DATA" expression="" applyOnUpdate="0"/>
|
||||
<default field="Shape__Area" expression="" applyOnUpdate="0"/>
|
||||
<default field="Shape__Length" expression="" applyOnUpdate="0"/>
|
||||
</defaults>
|
||||
<constraints>
|
||||
<constraint constraints="3" unique_strength="1" exp_strength="0" notnull_strength="1" field="OBJECTID"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="FL"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="FB_BN_KAT"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="FB_BEZEICH"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="REG_SAAT"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="SE_ANNO_CAD_DATA"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="Shape__Area"/>
|
||||
<constraint constraints="0" unique_strength="0" exp_strength="0" notnull_strength="0" field="Shape__Length"/>
|
||||
</constraints>
|
||||
<constraintExpressions>
|
||||
<constraint desc="" exp="" field="OBJECTID"/>
|
||||
<constraint desc="" exp="" field="FL"/>
|
||||
<constraint desc="" exp="" field="FB_BN_KAT"/>
|
||||
<constraint desc="" exp="" field="FB_BEZEICH"/>
|
||||
<constraint desc="" exp="" field="REG_SAAT"/>
|
||||
<constraint desc="" exp="" field="SE_ANNO_CAD_DATA"/>
|
||||
<constraint desc="" exp="" field="Shape__Area"/>
|
||||
<constraint desc="" exp="" field="Shape__Length"/>
|
||||
</constraintExpressions>
|
||||
<expressionfields/>
|
||||
<attributeactions>
|
||||
<defaultAction value="{00000000-0000-0000-0000-000000000000}" key="Canvas"/>
|
||||
</attributeactions>
|
||||
<attributetableconfig sortOrder="0" actionWidgetStyle="dropDown" sortExpression="">
|
||||
<columns>
|
||||
<column name="OBJECTID" width="-1" type="field" hidden="0"/>
|
||||
<column name="FL" width="-1" type="field" hidden="0"/>
|
||||
<column name="FB_BN_KAT" width="-1" type="field" hidden="0"/>
|
||||
<column name="FB_BEZEICH" width="-1" type="field" hidden="0"/>
|
||||
<column name="REG_SAAT" width="-1" type="field" hidden="0"/>
|
||||
<column name="SE_ANNO_CAD_DATA" width="-1" type="field" hidden="0"/>
|
||||
<column name="Shape__Area" width="-1" type="field" hidden="0"/>
|
||||
<column name="Shape__Length" width="-1" type="field" hidden="0"/>
|
||||
<column width="-1" type="actions" hidden="1"/>
|
||||
</columns>
|
||||
</attributetableconfig>
|
||||
<conditionalstyles>
|
||||
<rowstyles/>
|
||||
<fieldstyles/>
|
||||
</conditionalstyles>
|
||||
<storedexpressions/>
|
||||
<editform tolerant="1"></editform>
|
||||
<editforminit/>
|
||||
<editforminitcodesource>0</editforminitcodesource>
|
||||
<editforminitfilepath></editforminitfilepath>
|
||||
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||
"""
|
||||
QGIS-Formulare können eine Python-Funktion haben,, die aufgerufen wird, wenn sich das Formular öffnet
|
||||
|
||||
Diese Funktion kann verwendet werden um dem Formular Extralogik hinzuzufügen.
|
||||
|
||||
Der Name der Funktion wird im Feld "Python Init-Function" angegeben
|
||||
Ein Beispiel folgt:
|
||||
"""
|
||||
from qgis.PyQt.QtWidgets import QWidget
|
||||
|
||||
def my_form_open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||
]]></editforminitcode>
|
||||
<featformsuppress>0</featformsuppress>
|
||||
<editorlayout>generatedlayout</editorlayout>
|
||||
<editable>
|
||||
<field name="FB_BEZEICH" editable="1"/>
|
||||
<field name="FB_BN_KAT" editable="1"/>
|
||||
<field name="FL" editable="1"/>
|
||||
<field name="OBJECTID" editable="0"/>
|
||||
<field name="REG_SAAT" editable="1"/>
|
||||
<field name="SE_ANNO_CAD_DATA" editable="1"/>
|
||||
<field name="Shape__Area" editable="0"/>
|
||||
<field name="Shape__Length" editable="0"/>
|
||||
</editable>
|
||||
<labelOnTop>
|
||||
<field name="FB_BEZEICH" labelOnTop="0"/>
|
||||
<field name="FB_BN_KAT" labelOnTop="0"/>
|
||||
<field name="FL" labelOnTop="0"/>
|
||||
<field name="OBJECTID" labelOnTop="0"/>
|
||||
<field name="REG_SAAT" labelOnTop="0"/>
|
||||
<field name="SE_ANNO_CAD_DATA" labelOnTop="0"/>
|
||||
<field name="Shape__Area" labelOnTop="0"/>
|
||||
<field name="Shape__Length" labelOnTop="0"/>
|
||||
</labelOnTop>
|
||||
<reuseLastValue>
|
||||
<field name="FB_BEZEICH" reuseLastValue="0"/>
|
||||
<field name="FB_BN_KAT" reuseLastValue="0"/>
|
||||
<field name="FL" reuseLastValue="0"/>
|
||||
<field name="OBJECTID" reuseLastValue="0"/>
|
||||
<field name="REG_SAAT" reuseLastValue="0"/>
|
||||
<field name="SE_ANNO_CAD_DATA" reuseLastValue="0"/>
|
||||
<field name="Shape__Area" reuseLastValue="0"/>
|
||||
<field name="Shape__Length" reuseLastValue="0"/>
|
||||
</reuseLastValue>
|
||||
<dataDefinedFieldProperties/>
|
||||
<widgets/>
|
||||
<previewExpression>"FB_BN_KAT"</previewExpression>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<layerGeometryType>2</layerGeometryType>
|
||||
</qgis>
|
||||
@@ -1,4 +1,17 @@
|
||||
---
|
||||
Version 26.6.1-unstable:
|
||||
- VLN-API zum Laden der Plan41-Maßnahmen integriert
|
||||
---
|
||||
Version 26.4.3-unstable:
|
||||
---
|
||||
Version 26.4.2-testing:
|
||||
---
|
||||
Version 26.04.1-unstable:
|
||||
---
|
||||
Version 26.3.3-unstable:
|
||||
---
|
||||
Version 26.3.2-unstable:
|
||||
---
|
||||
Version 26.3.1-testing:
|
||||
- unstable als testing veröffentlicht
|
||||
---
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# sn_plan41/main.py
|
||||
"""sn_plan41/main.py – Einstiegspunkt des sn_plan41 Plugins.
|
||||
Orchestriert die UI und den Datenabruf für Thematische Linklisten.
|
||||
"""
|
||||
|
||||
from qgis.utils import plugins
|
||||
from sn_basis.ui.dockmanager import DockManager
|
||||
@@ -8,6 +10,9 @@ from sn_basis.modules.Pruefmanager import Pruefmanager
|
||||
|
||||
|
||||
class Plan41:
|
||||
"""Einstiegspunkt des sn_plan41-Plugins.
|
||||
Verwaltet die DockWidget-Initialisierung und den Datenflusss.
|
||||
"""
|
||||
def __init__(self, iface):
|
||||
self.iface = iface
|
||||
self.pruefmanager=Pruefmanager(ui_modus="qgis")
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#sn_plan41/modules/listenauswerter.py
|
||||
"""sn_plan41/modules/listenauswerter.py – Validierung von Linklisten.
|
||||
Prüft Zeilen aus DataDict auf Vollständigkeit und Konsistenz.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Mapping, Optional, Tuple
|
||||
from collections.abc import Mapping as _Mapping
|
||||
# Prüfer-Typen (werden als Instanzen erwartet)
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
"""HTTP-Client für die VLN-Manager-API.
|
||||
|
||||
API-Vertrag (Stand 2026-06-08):
|
||||
|
||||
Basis-URL: https://api.flurneuordnung-sachsen.de/v2
|
||||
|
||||
POST /person/login
|
||||
Body: {"mail": "...", "password": "..."}
|
||||
Antwort: {"data": {"userauth": "<url_token>", "id": ...}}
|
||||
Das userauth-Token ist der API-Key (= PERSON.url_token).
|
||||
|
||||
GET /tgen -> Teilnehmergemeinschaften (Verfahren)
|
||||
|
||||
GET /maps/<layer>/{vkz} -> GeoJSON FeatureCollection (EPSG:25833)
|
||||
PUT /maps/<layer>/{vkz} <- GeoJSON (ersetzt den Layer dieser VKZ)
|
||||
Antwort: {"data": {"vkz", "layer", "art", "speicher_id"}, "status": "ok"}
|
||||
|
||||
Layer: umringe, p41, st, kas, we
|
||||
Auth nach Login über den Header "X-API-Key".
|
||||
Fehlerformat: RFC 7807 (application/problem+json).
|
||||
|
||||
Es wird QgsBlockingNetworkRequest verwendet, damit Proxy- und
|
||||
Zertifikatseinstellungen aus QGIS automatisch greifen.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from sn_basis.functions.qt_wrapper import QUrl, QNetworkRequest
|
||||
from sn_basis.functions.qgiscore_wrapper import QgsBlockingNetworkRequest
|
||||
|
||||
# Fest verdrahtete Produktiv-API des VLN Managers.
|
||||
DEFAULT_BASE_URL = "https://api.flurneuordnung-sachsen.de/v2"
|
||||
|
||||
|
||||
class ApiError(Exception):
|
||||
"""Fehler bei der Kommunikation mit der Karten-API."""
|
||||
|
||||
|
||||
class AuthError(ApiError):
|
||||
"""API-Key fehlt, ist abgelaufen oder hat keine Berechtigung (401/403)."""
|
||||
|
||||
|
||||
class KartenApiClient:
|
||||
def __init__(self, base_url=DEFAULT_BASE_URL, api_key=None, mail=None):
|
||||
self.base_url = base_url.rstrip("/")
|
||||
self.api_key = api_key
|
||||
self.mail = mail
|
||||
|
||||
@property
|
||||
def is_authenticated(self):
|
||||
return bool(self.api_key)
|
||||
|
||||
def login(self, mail, password):
|
||||
"""Meldet den Benutzer an. Die API liefert das userauth-Token
|
||||
(= API-Key), das für alle weiteren Requests verwendet wird."""
|
||||
data = self._request(
|
||||
"POST",
|
||||
"/person/login",
|
||||
payload={"mail": mail, "password": password},
|
||||
with_auth=False,
|
||||
)
|
||||
payload = data.get("data") if isinstance(data, dict) else None
|
||||
if not isinstance(payload, dict):
|
||||
payload = data if isinstance(data, dict) else {}
|
||||
api_key = payload.get("userauth")
|
||||
if not api_key:
|
||||
raise ApiError(
|
||||
"Login-Antwort enthielt kein userauth-Token. "
|
||||
"Erhaltene Antwort: %s" % json.dumps(data)[:300]
|
||||
)
|
||||
self.api_key = api_key
|
||||
self.mail = mail
|
||||
return api_key
|
||||
|
||||
def logout(self):
|
||||
self.api_key = None
|
||||
self.mail = None
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Verfahren (Teilnehmergemeinschaften)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def get_verfahren(self):
|
||||
"""Liste der Verfahren (TGs) als [{"vkz": ..., "name": ...}, ...],
|
||||
sortiert nach VKZ. Quelle: GET /tgen."""
|
||||
data = self._request("GET", "/tgen")
|
||||
|
||||
rows = None
|
||||
if isinstance(data, list):
|
||||
rows = data
|
||||
elif isinstance(data, dict):
|
||||
for key in ("data", "rows"):
|
||||
value = data.get(key)
|
||||
if isinstance(value, list):
|
||||
rows = value
|
||||
break
|
||||
if isinstance(value, dict) and isinstance(value.get("rows"), list):
|
||||
rows = value["rows"]
|
||||
break
|
||||
if rows is None:
|
||||
raise ApiError(
|
||||
"Antwort von /tgen hat ein unerwartetes Format: %s"
|
||||
% json.dumps(data)[:200]
|
||||
)
|
||||
|
||||
verfahren = []
|
||||
for row in rows:
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
vkz = row.get("vkz") or row.get("VKZ")
|
||||
name = (
|
||||
row.get("kurzname")
|
||||
or row.get("Kurzname")
|
||||
or row.get("name")
|
||||
or row.get("Name")
|
||||
or ""
|
||||
)
|
||||
if vkz:
|
||||
verfahren.append({"vkz": str(vkz), "name": str(name)})
|
||||
verfahren.sort(key=lambda v: v["vkz"])
|
||||
return verfahren
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Karten-Layer
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def load_layer_complete(self, layer_key, vkz, page_size=2000):
|
||||
"""Lädt ALLE Objekte eines Layers für eine VKZ aus KARTE_OBJEKT.
|
||||
|
||||
Nutzt den Listen-Endpunkt /maps/<layer>?vkz=… mit limit/offset-Paging,
|
||||
bis keine weitere Seite mehr kommt."""
|
||||
from urllib.parse import quote
|
||||
|
||||
features = []
|
||||
offset = 0
|
||||
while True:
|
||||
data = self._request(
|
||||
"GET",
|
||||
"/maps/%s?vkz=%s&limit=%d&offset=%d"
|
||||
% (quote(str(layer_key)), quote(str(vkz)), page_size, offset),
|
||||
)
|
||||
if not isinstance(data, dict) or data.get("type") != "FeatureCollection":
|
||||
raise ApiError(
|
||||
"Antwort von /maps/%s ist keine GeoJSON FeatureCollection."
|
||||
% layer_key
|
||||
)
|
||||
page = data.get("features", [])
|
||||
features.extend(page)
|
||||
if len(page) < page_size:
|
||||
break
|
||||
offset += page_size
|
||||
return {"type": "FeatureCollection", "features": features}
|
||||
|
||||
def load_feature_collection(self, path):
|
||||
"""Lädt einen Layer als GeoJSON FeatureCollection (dict)."""
|
||||
data = self._request("GET", path)
|
||||
if isinstance(data, dict):
|
||||
if data.get("type") == "FeatureCollection":
|
||||
return data
|
||||
inner = data.get("data")
|
||||
if isinstance(inner, dict) and inner.get("type") == "FeatureCollection":
|
||||
return inner
|
||||
raise ApiError(
|
||||
"Antwort von %s ist keine GeoJSON FeatureCollection." % path
|
||||
)
|
||||
|
||||
def save_feature_collection(self, path, feature_collection):
|
||||
"""Schreibt eine GeoJSON FeatureCollection zurück an die API
|
||||
(PUT ersetzt den kompletten Layer der jeweiligen VKZ)."""
|
||||
return self._request("PUT", path, payload=feature_collection)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Intern
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _request(self, method, path, payload=None, with_auth=True):
|
||||
if with_auth and not self.is_authenticated:
|
||||
raise AuthError("Nicht angemeldet — bitte zuerst einloggen.")
|
||||
|
||||
request = QNetworkRequest(QUrl(self.base_url + path))
|
||||
request.setHeader(
|
||||
QNetworkRequest.KnownHeaders.ContentTypeHeader, "application/json"
|
||||
)
|
||||
request.setRawHeader(b"Accept", b"application/json")
|
||||
if with_auth:
|
||||
request.setRawHeader(b"X-API-Key", self.api_key.encode("utf-8"))
|
||||
|
||||
body = b""
|
||||
if payload is not None:
|
||||
body = json.dumps(payload).encode("utf-8")
|
||||
|
||||
blocking = QgsBlockingNetworkRequest()
|
||||
if method == "GET":
|
||||
error = blocking.get(request)
|
||||
elif method == "POST":
|
||||
error = blocking.post(request, body)
|
||||
elif method == "PUT":
|
||||
error = blocking.put(request, body)
|
||||
else:
|
||||
raise ApiError("Nicht unterstützte HTTP-Methode: %s" % method)
|
||||
|
||||
reply = blocking.reply()
|
||||
content = bytes(reply.content())
|
||||
status = reply.attribute(
|
||||
QNetworkRequest.Attribute.HttpStatusCodeAttribute
|
||||
)
|
||||
status = int(status) if status is not None else None
|
||||
|
||||
if status in (401, 403):
|
||||
raise AuthError(
|
||||
"Keine Berechtigung für %s %s (HTTP %s)%s"
|
||||
% (method, path, status, self._error_detail(content))
|
||||
)
|
||||
if error != QgsBlockingNetworkRequest.NoError:
|
||||
raise ApiError(
|
||||
"%s %s fehlgeschlagen: %s%s"
|
||||
% (method, path, blocking.errorMessage(), self._error_detail(content))
|
||||
)
|
||||
if status is not None and status >= 400:
|
||||
raise ApiError(
|
||||
"%s %s lieferte HTTP %s%s"
|
||||
% (method, path, status, self._error_detail(content))
|
||||
)
|
||||
|
||||
if not content:
|
||||
return None
|
||||
try:
|
||||
return json.loads(content.decode("utf-8"))
|
||||
except ValueError:
|
||||
raise ApiError(
|
||||
"Antwort von %s ist kein gültiges JSON." % path
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _error_detail(content):
|
||||
"""Liest title/detail aus einer RFC-7807-Fehlerantwort."""
|
||||
if not content:
|
||||
return ""
|
||||
try:
|
||||
problem = json.loads(content.decode("utf-8"))
|
||||
parts = [
|
||||
str(problem[k]) for k in ("title", "detail") if problem.get(k)
|
||||
]
|
||||
if parts:
|
||||
return " — " + ": ".join(parts)
|
||||
except (ValueError, AttributeError):
|
||||
pass
|
||||
return " — " + content[:300].decode("utf-8", "replace")
|
||||
@@ -0,0 +1,378 @@
|
||||
"""
|
||||
sn_plan41/modules/vln_api_logic.py – Fachlogik für die VLN-API-Integration in Tab A.
|
||||
|
||||
Kapselt:
|
||||
- Anmeldung / Abmeldung (KartenApiClient aus vln_karten)
|
||||
- Persistierung des API-Keys in QSettings
|
||||
- Verfahrensliste laden (GET /tgen)
|
||||
- Persistierung der VKZ-Auswahl in der Projektdatei
|
||||
- Plan 41 laden (2 Layer + Stile aus sn_plan41/assets/)
|
||||
- Aktiven Layer hochladen
|
||||
|
||||
Voraussetzung: Das Plugin `vln_karten` muss installiert sein.
|
||||
Wenn nicht vorhanden, liefert :attr:`is_available` False; die UI
|
||||
kann dann einen entsprechenden Hinweis anzeigen.
|
||||
|
||||
Sitzungsablauf bei AuthError:
|
||||
- :meth:`handle_session_expired` aufrufen → API-Key löschen + logout
|
||||
- In der UI danach :meth:`_update_vln_ui_state` aufrufen und
|
||||
QMessageBox.warning anzeigen. Kein automatischer Login-Dialog.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from sn_basis.functions.qt_wrapper import QSettings
|
||||
from sn_basis.functions.qgiscore_wrapper import QgsProject
|
||||
from sn_basis.functions.sys_wrapper import get_plugin_root, join_path
|
||||
from sn_basis.functions.ly_style_wrapper import apply_style_from_path
|
||||
|
||||
# Lokale API-Module — fallenübrig, sobald QGIS verfügbar ist.
|
||||
# In der reinen Python-Testumgebung (kein qgis-Paket) schlagen die
|
||||
# qgis-Imports in den Untermodulen fehl; daher der try/except-Guard.
|
||||
try:
|
||||
from sn_plan41.modules.vln_api_client import KartenApiClient, ApiError, AuthError
|
||||
from sn_plan41.modules.vln_layer_manager import (
|
||||
feature_collection_to_layers,
|
||||
plugin_layers,
|
||||
layers_to_feature_collection,
|
||||
layer_api_path,
|
||||
PROP_DATASET,
|
||||
PROP_VERFAHREN,
|
||||
)
|
||||
VLN_KARTEN_AVAILABLE = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
KartenApiClient = None # type: ignore[assignment,misc]
|
||||
ApiError = Exception # type: ignore[assignment,misc]
|
||||
AuthError = Exception # type: ignore[assignment,misc]
|
||||
VLN_KARTEN_AVAILABLE = False
|
||||
|
||||
# Geometrietyp-Konstanten (QGIS intern: 1 = Linie, 2 = Fläche)
|
||||
try:
|
||||
from qgis.core import Qgis as _Qgis
|
||||
_GEOM_LINE = _Qgis.GeometryType.Line
|
||||
_GEOM_POLYGON = _Qgis.GeometryType.Polygon
|
||||
except (ImportError, AttributeError):
|
||||
try:
|
||||
from qgis.core import QgsWkbTypes as _QgsWkbTypes
|
||||
_GEOM_LINE = _QgsWkbTypes.LineGeometry
|
||||
_GEOM_POLYGON = _QgsWkbTypes.PolygonGeometry
|
||||
except (ImportError, AttributeError):
|
||||
_GEOM_LINE = 1
|
||||
_GEOM_POLYGON = 2
|
||||
|
||||
# Konstanten
|
||||
SETTINGS_GROUP = "vln_karten"
|
||||
PROJECT_SCOPE = "vln_karten"
|
||||
PROJECT_KEY_VKZ = "/vkz"
|
||||
|
||||
P41_DATASET_KEY = "p41"
|
||||
P41_LABEL = "Plan 41 (Wege- und Gewässerplan)"
|
||||
P41_PATH_TEMPLATE = "/maps/p41/{vkz}"
|
||||
P41_GEOMETRY = "MultiPolygon"
|
||||
|
||||
STYLE_FLAECHE = "QGIS_P41_API_Layer_flaeche.qml"
|
||||
STYLE_LINIE = "QGIS_P41_API_Layer_Linie.qml"
|
||||
|
||||
|
||||
class VlnApiLogic:
|
||||
"""
|
||||
Kapselt die VLN-API-Fachlogik für den Plan41-Tab.
|
||||
|
||||
Alle Methoden, die Netzwerkkommunikation erfordern, können
|
||||
``ApiError`` oder ``AuthError`` werfen – die UI ist für die
|
||||
Fehlerdarstellung zuständig.
|
||||
"""
|
||||
|
||||
def __init__(self, pruefmanager=None) -> None:
|
||||
self.pruefmanager = pruefmanager
|
||||
self._client: Optional[object] = None # KartenApiClient | None
|
||||
|
||||
# API-Client aus gespeicherten Credentials initialisieren
|
||||
if VLN_KARTEN_AVAILABLE:
|
||||
api_key, mail = self.load_stored_credentials()
|
||||
if api_key:
|
||||
self._client = KartenApiClient(api_key=api_key, mail=mail)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Verfügbarkeit
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@staticmethod
|
||||
def is_available() -> bool:
|
||||
"""True, wenn die lokalen API-Module geladen werden konnten
|
||||
(erfordert eine QGIS-Laufzeitumgebung)."""
|
||||
return VLN_KARTEN_AVAILABLE
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Authentifizierungsstatus
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@property
|
||||
def is_authenticated(self) -> bool:
|
||||
"""True, wenn ein gültiger API-Key vorhanden ist."""
|
||||
if self._client is None:
|
||||
return False
|
||||
return bool(getattr(self._client, "is_authenticated", False))
|
||||
|
||||
@property
|
||||
def mail(self) -> Optional[str]:
|
||||
"""E-Mail-Adresse des angemeldeten Benutzers oder None."""
|
||||
if self._client is None:
|
||||
return None
|
||||
return getattr(self._client, "mail", None)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# QSettings: API-Key persistieren
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def load_stored_credentials(self) -> tuple:
|
||||
"""Liest API-Key und Mail aus QSettings.
|
||||
Gibt ``(api_key, mail)`` zurück – leere Strings wenn nicht vorhanden.
|
||||
"""
|
||||
settings = QSettings()
|
||||
settings.beginGroup(SETTINGS_GROUP)
|
||||
api_key = settings.value("api_key", "")
|
||||
mail = settings.value("mail", "")
|
||||
settings.endGroup()
|
||||
return api_key or None, mail or None
|
||||
|
||||
def save_api_key(self, api_key: str, mail: str) -> None:
|
||||
"""Speichert API-Key und Mail in QSettings."""
|
||||
settings = QSettings()
|
||||
settings.beginGroup(SETTINGS_GROUP)
|
||||
settings.setValue("api_key", api_key)
|
||||
settings.setValue("mail", mail or "")
|
||||
settings.endGroup()
|
||||
|
||||
def clear_api_key(self) -> None:
|
||||
"""Entfernt API-Key aus QSettings."""
|
||||
settings = QSettings()
|
||||
settings.beginGroup(SETTINGS_GROUP)
|
||||
settings.remove("api_key")
|
||||
settings.endGroup()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Login / Logout
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def login(self, mail: str, password: str) -> None:
|
||||
"""
|
||||
Meldet den Benutzer an und speichert den API-Key.
|
||||
|
||||
:raises ApiError: Bei ungültigen Zugangsdaten oder Netzwerkproblem.
|
||||
:raises RuntimeError: Wenn QGIS nicht verfügbar ist (kein qgis-Paket).
|
||||
"""
|
||||
if not VLN_KARTEN_AVAILABLE:
|
||||
raise RuntimeError(
|
||||
"VLN-API-Module nicht verfügbar (QGIS-Laufzeitumgebung benötigt)."
|
||||
)
|
||||
client = KartenApiClient()
|
||||
client.login(mail, password) # wirft ApiError bei Fehler
|
||||
self._client = client
|
||||
self.save_api_key(client.api_key, mail)
|
||||
|
||||
def logout(self) -> None:
|
||||
"""Meldet den Benutzer ab (lokal, kein API-Aufruf)."""
|
||||
if self._client is not None:
|
||||
getattr(self._client, "logout", lambda: None)()
|
||||
self._client = None
|
||||
|
||||
def handle_session_expired(self) -> None:
|
||||
"""
|
||||
Behandelt einen abgelaufenen API-Key:
|
||||
entfernt ihn aus QSettings und setzt den Client zurück.
|
||||
"""
|
||||
self.clear_api_key()
|
||||
self.logout()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Verfahrensliste
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def get_verfahren(self) -> list:
|
||||
"""
|
||||
Lädt alle Verfahren (TGs) vom Server.
|
||||
|
||||
:returns: Sortierte Liste von ``{"vkz": ..., "name": ...}``-Dicts.
|
||||
:raises AuthError: Wenn nicht angemeldet oder Session abgelaufen.
|
||||
:raises ApiError: Bei sonstigem Netzwerkfehler.
|
||||
"""
|
||||
if self._client is None:
|
||||
raise AuthError("Nicht angemeldet.")
|
||||
return self._client.get_verfahren()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# VKZ-Persistenz in Projektdatei
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def load_stored_vkz(self) -> Optional[str]:
|
||||
"""Liest die zuletzt gewählte VKZ aus der Projektdatei."""
|
||||
try:
|
||||
vkz, _ok = QgsProject.instance().readEntry(
|
||||
PROJECT_SCOPE, PROJECT_KEY_VKZ, ""
|
||||
)
|
||||
return vkz if vkz else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def save_vkz(self, vkz: Optional[str]) -> None:
|
||||
"""Schreibt die gewählte VKZ in die Projektdatei."""
|
||||
if not vkz:
|
||||
return
|
||||
try:
|
||||
QgsProject.instance().writeEntry(PROJECT_SCOPE, PROJECT_KEY_VKZ, vkz)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Plan 41 laden
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def get_p41_layers(self, vkz: str) -> list:
|
||||
"""Gibt alle bereits geladenen P41-Layer für diese VKZ zurück."""
|
||||
return plugin_layers(P41_DATASET_KEY, vkz)
|
||||
|
||||
def remove_p41_layers(self, vkz: str) -> None:
|
||||
"""Entfernt alle P41-Layer dieser VKZ aus dem Projekt."""
|
||||
existing = plugin_layers(P41_DATASET_KEY, vkz)
|
||||
if existing:
|
||||
QgsProject.instance().removeMapLayers([l.id() for l in existing])
|
||||
|
||||
def load_p41(self, vkz: str) -> list:
|
||||
"""
|
||||
Lädt den Plan-41-Datensatz für eine VKZ vom Server und legt
|
||||
Memory-Layer im Projekt an. Auf die entstandenen Layer werden
|
||||
die passenden QML-Stile aus ``sn_plan41/assets/`` angewendet.
|
||||
|
||||
:returns: Liste der erzeugten ``QgsVectorLayer``.
|
||||
:raises AuthError: Wenn nicht angemeldet oder Session abgelaufen.
|
||||
:raises ApiError: Bei sonstigem Netzwerkfehler.
|
||||
:raises RuntimeError: Wenn QGIS nicht verfügbar ist.
|
||||
"""
|
||||
if not VLN_KARTEN_AVAILABLE:
|
||||
raise RuntimeError(
|
||||
"VLN-API-Module nicht verfügbar (QGIS-Laufzeitumgebung benötigt)."
|
||||
)
|
||||
if self._client is None:
|
||||
raise AuthError("Nicht angemeldet.")
|
||||
|
||||
path = P41_PATH_TEMPLATE.format(vkz=vkz)
|
||||
feature_collection = self._client.load_layer_complete(
|
||||
P41_DATASET_KEY, vkz
|
||||
)
|
||||
base_name = "%s %s" % (P41_LABEL, vkz)
|
||||
layers = feature_collection_to_layers(
|
||||
feature_collection,
|
||||
base_name,
|
||||
P41_GEOMETRY,
|
||||
P41_DATASET_KEY,
|
||||
vkz,
|
||||
path,
|
||||
)
|
||||
self._apply_p41_styles(layers)
|
||||
return layers
|
||||
|
||||
def _apply_p41_styles(self, layers: list) -> None:
|
||||
"""Wendet den passenden QML-Stil auf jeden Layer an."""
|
||||
assets_dir = join_path(get_plugin_root(), "sn_plan41", "assets")
|
||||
for layer in layers:
|
||||
try:
|
||||
gtype = layer.geometryType()
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if gtype == _GEOM_POLYGON:
|
||||
style_file = STYLE_FLAECHE
|
||||
elif gtype == _GEOM_LINE:
|
||||
style_file = STYLE_LINIE
|
||||
else:
|
||||
continue # Punkt- und None-Layer erhalten keinen Stil
|
||||
|
||||
style_path = join_path(assets_dir, style_file)
|
||||
apply_style_from_path(layer, style_path)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Upload
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def upload_active_layer(self, active_layer) -> tuple:
|
||||
"""
|
||||
Lädt alle Teil-Layer des aktiven Layers zum Server hoch.
|
||||
|
||||
:param active_layer: Aktiver ``QgsVectorLayer`` (aus ``iface.activeLayer()``).
|
||||
:returns: ``(success: bool, message: str)``
|
||||
:raises AuthError: Wenn Session abgelaufen.
|
||||
:raises ApiError: Bei Netzwerkfehler.
|
||||
"""
|
||||
if not VLN_KARTEN_AVAILABLE:
|
||||
return False, (
|
||||
"VLN-API-Module nicht verfügbar (QGIS-Laufzeitumgebung benötigt)."
|
||||
)
|
||||
|
||||
if self._client is None:
|
||||
raise AuthError("Nicht angemeldet.")
|
||||
|
||||
path = layer_api_path(active_layer) if active_layer else None
|
||||
if not path:
|
||||
return (
|
||||
False,
|
||||
"Der aktive Layer wurde nicht über 'vln_karten' geladen. "
|
||||
"Bitte einen Plan41-Layer aus dem Projekt auswählen.",
|
||||
)
|
||||
|
||||
dataset_key = active_layer.customProperty(PROP_DATASET)
|
||||
vkz = active_layer.customProperty(PROP_VERFAHREN)
|
||||
siblings = plugin_layers(dataset_key, vkz)
|
||||
|
||||
for layer in siblings:
|
||||
if layer.isEditable() and not layer.commitChanges():
|
||||
return (
|
||||
False,
|
||||
"Die Bearbeitungssitzung von '%s' konnte nicht "
|
||||
"gespeichert werden." % layer.name(),
|
||||
)
|
||||
|
||||
feature_collection = layers_to_feature_collection(siblings)
|
||||
self._client.save_feature_collection(path, feature_collection)
|
||||
|
||||
total = sum(layer.featureCount() for layer in siblings)
|
||||
return (
|
||||
True,
|
||||
"%d Objekte aus %d Layer(n) erfolgreich hochgeladen."
|
||||
% (total, len(siblings)),
|
||||
)
|
||||
|
||||
def upload_summary(self, active_layer) -> Optional[dict]:
|
||||
"""
|
||||
Gibt eine Zusammenfassung der zu hochladenden Layer zurück
|
||||
(für den Bestätigungs-Dialog in der UI), ohne den Upload
|
||||
tatsächlich auszuführen.
|
||||
|
||||
:returns: Dict mit ``dataset_label``, ``vkz``, ``siblings``
|
||||
(Layer-Liste), ``total`` (Objektanzahl), ``listing`` (str)
|
||||
oder ``None`` wenn kein gültiger Layer.
|
||||
"""
|
||||
if not VLN_KARTEN_AVAILABLE or active_layer is None:
|
||||
return None
|
||||
path = layer_api_path(active_layer)
|
||||
if not path:
|
||||
return None
|
||||
|
||||
dataset_key = active_layer.customProperty(PROP_DATASET)
|
||||
vkz = active_layer.customProperty(PROP_VERFAHREN)
|
||||
siblings = plugin_layers(dataset_key, vkz)
|
||||
|
||||
total = sum(l.featureCount() for l in siblings)
|
||||
listing = "\n".join(
|
||||
"• %s (%d Objekte)" % (l.name(), l.featureCount())
|
||||
for l in siblings
|
||||
)
|
||||
return {
|
||||
"dataset_label": P41_LABEL if dataset_key == P41_DATASET_KEY else dataset_key,
|
||||
"vkz": vkz,
|
||||
"siblings": siblings,
|
||||
"total": total,
|
||||
"listing": listing,
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
"""Konvertierung GeoJSON <-> QGIS-Layer für die VLN-API.
|
||||
|
||||
Lokale Kopie des Layer-Managers aus dem vln_karten-Plugin — sn_plan41
|
||||
benötigt kein separat installiertes vln_karten-Plugin mehr.
|
||||
|
||||
Die API liefert je Layer (z.B. Plan 41) gemischte Geometrietypen in einer
|
||||
FeatureCollection: Punkte, Linien, Polygone sowie deren Multi-Varianten.
|
||||
QGIS-Memory-Layer können nur einen Geometrietyp halten — beim Laden wird
|
||||
deshalb nach Geometrie-Familie (Punkte/Linien/Flächen) in bis zu drei
|
||||
Layer gesplittet; Single-Geometrien werden zu Multi befördert.
|
||||
|
||||
Beim Hochladen müssen alle Teil-Layer desselben Datensatzes wieder zu
|
||||
EINER FeatureCollection vereint werden, weil der PUT der API den
|
||||
kompletten Layer-Bestand der VKZ ersetzt.
|
||||
|
||||
Custom-Properties an Layern (kompatibel mit vln_karten, falls beide
|
||||
Plugins gleichzeitig installiert sind):
|
||||
vln_karten/dataset — z.B. "p41"
|
||||
vln_karten/verfahren — VKZ-Nummer
|
||||
vln_karten/api_path — API-Pfad für Upload
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from sn_basis.functions.qgiscore_wrapper import (
|
||||
QgsJsonExporter,
|
||||
QgsJsonUtils,
|
||||
QgsProject,
|
||||
QgsVectorLayer,
|
||||
GEOM_POINT,
|
||||
GEOM_LINE,
|
||||
GEOM_POLYGON,
|
||||
)
|
||||
|
||||
_GEOM_POINT = GEOM_POINT
|
||||
_GEOM_LINE = GEOM_LINE
|
||||
_GEOM_POLYGON = GEOM_POLYGON
|
||||
|
||||
# Die VLN-API liefert Koordinaten in ETRS89 / UTM Zone 33 (EPSG:25833).
|
||||
GEOJSON_CRS = "EPSG:25833"
|
||||
|
||||
# Custom-Property-Schlüssel — identisch mit vln_karten für Kompatibilität.
|
||||
PROP_DATASET = "vln_karten/dataset"
|
||||
PROP_VERFAHREN = "vln_karten/verfahren"
|
||||
PROP_PATH = "vln_karten/api_path"
|
||||
|
||||
# Geometrie-Familie → (Memory-Provider-Typ, Namenszusatz).
|
||||
# Reihenfolge = Lade-Reihenfolge: Flächen zuerst, damit Punkte im
|
||||
# Layerbaum oben landen und nicht verdeckt werden.
|
||||
_FAMILIES = (
|
||||
("polygon", "MultiPolygon", "Flächen"),
|
||||
("line", "MultiLineString", "Linien"),
|
||||
("point", "MultiPoint", "Punkte"),
|
||||
("none", "None", "ohne Geometrie"),
|
||||
)
|
||||
|
||||
|
||||
def _family(feature):
|
||||
"""Geometrie-Familie eines Features. Unbekannte Typen (z.B.
|
||||
GeometryCollection) landen bei 'none'."""
|
||||
if not feature.hasGeometry() or feature.geometry().isNull():
|
||||
return "none"
|
||||
gtype = feature.geometry().type()
|
||||
if gtype == _GEOM_POINT:
|
||||
return "point"
|
||||
if gtype == _GEOM_LINE:
|
||||
return "line"
|
||||
if gtype == _GEOM_POLYGON:
|
||||
return "polygon"
|
||||
return "none"
|
||||
|
||||
|
||||
def memory_layer_from_features(
|
||||
uri_type, name, fields, features, dataset_key, verfahren_nr, api_path, promote=True
|
||||
):
|
||||
"""Baut einen Memory-Layer aus fertigen QgsFeatures, setzt die
|
||||
Plugin-Custom-Properties und hängt ihn ins Projekt."""
|
||||
uri = uri_type if uri_type == "None" else "%s?crs=%s" % (uri_type, GEOJSON_CRS)
|
||||
layer = QgsVectorLayer(uri, name, "memory")
|
||||
if not layer.isValid():
|
||||
raise RuntimeError("Memory-Layer '%s' konnte nicht erzeugt werden." % name)
|
||||
provider = layer.dataProvider()
|
||||
provider.addAttributes(fields.toList())
|
||||
layer.updateFields()
|
||||
prepared = []
|
||||
for feature in features:
|
||||
geometry = feature.geometry()
|
||||
if promote and not geometry.isNull() and not geometry.isMultipart():
|
||||
geometry.convertToMultiType()
|
||||
feature.setGeometry(geometry)
|
||||
prepared.append(feature)
|
||||
provider.addFeatures(prepared)
|
||||
layer.updateExtents()
|
||||
layer.setCustomProperty(PROP_DATASET, dataset_key)
|
||||
layer.setCustomProperty(PROP_VERFAHREN, verfahren_nr)
|
||||
layer.setCustomProperty(PROP_PATH, api_path)
|
||||
return layer
|
||||
|
||||
|
||||
def feature_collection_to_layers(
|
||||
feature_collection, base_name, default_geometry, dataset_key, verfahren_nr, api_path
|
||||
):
|
||||
"""Erzeugt aus einer GeoJSON FeatureCollection je vorkommender
|
||||
Geometrie-Familie einen Memory-Layer und hängt sie ins Projekt.
|
||||
Liefert die Liste der erzeugten Layer."""
|
||||
text = json.dumps(feature_collection)
|
||||
fields = QgsJsonUtils.stringToFields(text)
|
||||
features = QgsJsonUtils.stringToFeatureList(text, fields)
|
||||
|
||||
groups = {}
|
||||
for feature in features:
|
||||
groups.setdefault(_family(feature), []).append(feature)
|
||||
|
||||
layers = []
|
||||
multiple = len(groups) > 1
|
||||
|
||||
def make_layer(uri_type, name, group_features, promote):
|
||||
layers.append(
|
||||
memory_layer_from_features(
|
||||
uri_type, name, fields, group_features,
|
||||
dataset_key, verfahren_nr, api_path, promote=promote,
|
||||
)
|
||||
)
|
||||
|
||||
if not groups:
|
||||
# Leerer Datensatz: ein leerer Layer im Default-Typ, damit der
|
||||
# Nutzer digitalisieren und hochladen kann.
|
||||
make_layer(default_geometry, base_name, [], promote=False)
|
||||
else:
|
||||
for family, uri_type, suffix in _FAMILIES:
|
||||
if family not in groups:
|
||||
continue
|
||||
name = "%s — %s" % (base_name, suffix) if multiple else base_name
|
||||
make_layer(uri_type, name, groups[family], promote=(family != "none"))
|
||||
|
||||
QgsProject.instance().addMapLayers(layers)
|
||||
return layers
|
||||
|
||||
|
||||
def plugin_layers(dataset_key, verfahren_nr):
|
||||
"""Alle Layer im Projekt, die zu diesem Datensatz und dieser VKZ
|
||||
gehören (z.B. die Punkte-/Linien-/Flächen-Teil-Layer von Plan 41)."""
|
||||
result = []
|
||||
for layer in QgsProject.instance().mapLayers().values():
|
||||
if (
|
||||
isinstance(layer, QgsVectorLayer)
|
||||
and layer.customProperty(PROP_DATASET) == dataset_key
|
||||
and str(layer.customProperty(PROP_VERFAHREN)) == str(verfahren_nr)
|
||||
):
|
||||
result.append(layer)
|
||||
return result
|
||||
|
||||
|
||||
def layers_to_feature_collection(layers):
|
||||
"""Vereint die Features mehrerer Layer zu EINER GeoJSON
|
||||
FeatureCollection (für den PUT, der den Serverbestand ersetzt).
|
||||
|
||||
Keine Transformation nach WGS84: Die API erwartet die Koordinaten im
|
||||
selben CRS, in dem sie sie liefert (EPSG:25833)."""
|
||||
merged = []
|
||||
for layer in layers:
|
||||
exporter = QgsJsonExporter(layer)
|
||||
exporter.setSourceCrs(layer.crs())
|
||||
exporter.setTransformGeometries(False)
|
||||
collection = json.loads(
|
||||
exporter.exportFeatures(list(layer.getFeatures()))
|
||||
)
|
||||
merged.extend(collection.get("features", []))
|
||||
return {"type": "FeatureCollection", "features": merged}
|
||||
|
||||
|
||||
def layer_api_path(layer):
|
||||
"""API-Pfad, unter dem dieser Layer geladen wurde — oder None,
|
||||
wenn der Layer nicht von diesem Plugin stammt."""
|
||||
if not isinstance(layer, QgsVectorLayer):
|
||||
return None
|
||||
return layer.customProperty(PROP_PATH) or None
|
||||
+3
-1
@@ -1 +1,3 @@
|
||||
#Testordner
|
||||
"""sn_plan41/tests – Test-Suite für das sn_plan41 Plugin.
|
||||
Enthält Unit-Tests und Integrationstests für Tab-Logik und Datengrabber.
|
||||
"""
|
||||
|
||||
@@ -5,6 +5,7 @@ Zentraler Test-Runner für sn_plan41.
|
||||
Wrapper-konform, QGIS-unabhängig, CI- und IDE-fähig.
|
||||
"""
|
||||
|
||||
import io
|
||||
import unittest
|
||||
import datetime
|
||||
import inspect
|
||||
@@ -12,6 +13,19 @@ import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Stdout auf UTF-8 umstellen, damit Emoji-Print-Statements in
|
||||
# qt_wrapper.py (Mock-Modus) auf Windows-Konsolen (CP1252) nicht zu
|
||||
# UnicodeEncodeError führen.
|
||||
if hasattr(sys.stdout, "reconfigure"):
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
||||
except Exception:
|
||||
pass
|
||||
elif hasattr(sys.stdout, "buffer"):
|
||||
sys.stdout = io.TextIOWrapper(
|
||||
sys.stdout.buffer, encoding="utf-8", errors="replace"
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Plugin-Roots bestimmen
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import unittest
|
||||
from typing import Any
|
||||
|
||||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis
|
||||
from sn_plan41.modules.listenauswerter import Listenauswerter
|
||||
|
||||
|
||||
class _DummyPruefmanager:
|
||||
def __init__(self) -> None:
|
||||
self.seen = []
|
||||
|
||||
def verarbeite(self, ergebnis: Any):
|
||||
self.seen.append(ergebnis)
|
||||
return ergebnis
|
||||
|
||||
|
||||
class _DummyStilPruefer:
|
||||
def __init__(self, ok: bool = True) -> None:
|
||||
self.ok = ok
|
||||
|
||||
def pruefe(self, _path: str) -> pruef_ergebnis:
|
||||
if self.ok:
|
||||
return pruef_ergebnis(ok=True, meldung="ok", aktion="ok", kontext=None)
|
||||
return pruef_ergebnis(ok=False, meldung="stil fehler", aktion="falsche_endung", kontext=None)
|
||||
|
||||
|
||||
class TestListenauswerter(unittest.TestCase):
|
||||
|
||||
def test_validate_rows_accepts_valid_row_and_normalizes_provider(self):
|
||||
manager = _DummyPruefmanager()
|
||||
validator = Listenauswerter(manager, _DummyStilPruefer(ok=True))
|
||||
|
||||
data = {"rows": [{"ident": "A1", "Inhalt": "Test", "Link": "http://x", "Provider": "wfs"}]}
|
||||
validated, processed = validator.validate_rows(data)
|
||||
|
||||
self.assertEqual(len(validated["rows"]), 1)
|
||||
self.assertEqual(validated["rows"][0]["Provider"], "WFS")
|
||||
self.assertEqual(processed, [])
|
||||
|
||||
def test_validate_rows_rejects_missing_required_fields(self):
|
||||
manager = _DummyPruefmanager()
|
||||
validator = Listenauswerter(manager, _DummyStilPruefer(ok=True))
|
||||
|
||||
data = {"rows": [{"ident": "", "Link": "", "Provider": ""}]}
|
||||
validated, processed = validator.validate_rows(data)
|
||||
|
||||
self.assertEqual(validated["rows"], [])
|
||||
self.assertEqual(len(processed), 1)
|
||||
self.assertEqual(processed[0].aktion, "pflichtfelder_fehlen")
|
||||
|
||||
def test_validate_rows_sets_stildatei_none_on_style_failure(self):
|
||||
manager = _DummyPruefmanager()
|
||||
validator = Listenauswerter(manager, _DummyStilPruefer(ok=False))
|
||||
|
||||
data = {
|
||||
"rows": [
|
||||
{
|
||||
"ident": "A1",
|
||||
"Inhalt": "Thema",
|
||||
"Link": "http://x",
|
||||
"Provider": "WMS",
|
||||
"Stildatei": "broken.qml",
|
||||
}
|
||||
]
|
||||
}
|
||||
validated, processed = validator.validate_rows(data)
|
||||
|
||||
self.assertEqual(len(validated["rows"]), 1)
|
||||
self.assertIsNone(validated["rows"][0]["stildatei"])
|
||||
self.assertEqual(len(processed), 1)
|
||||
self.assertEqual(processed[0].aktion, "falsche_endung")
|
||||
|
||||
def test_validate_rows_handles_non_mapping_rows_edge_case(self):
|
||||
manager = _DummyPruefmanager()
|
||||
validator = Listenauswerter(manager, _DummyStilPruefer(ok=True))
|
||||
|
||||
validated, processed = validator.validate_rows({"rows": ["invalid", 123, None]})
|
||||
|
||||
self.assertEqual(validated, {"rows": []})
|
||||
self.assertEqual(processed, [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+78
-121
@@ -1,152 +1,109 @@
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import Any, cast
|
||||
from unittest.mock import patch
|
||||
|
||||
from sn_plan41.ui.tab_a_logic import TabALogic # type: ignore
|
||||
from sn_basis.functions.variable_wrapper import get_variable # type: ignore
|
||||
from sn_basis.functions.sys_wrapper import file_exists # type: ignore
|
||||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis
|
||||
from sn_basis.functions.variable_wrapper import get_variable
|
||||
from sn_plan41.ui.tab_a_logic import TabALogic
|
||||
|
||||
|
||||
class _DummyPruefmanager:
|
||||
def verarbeite(self, ergebnis):
|
||||
return ergebnis
|
||||
|
||||
|
||||
class TestTabALogic(unittest.TestCase):
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 1. Verfahrens-DB setzen und laden
|
||||
# -----------------------------------------------------
|
||||
def test_verfahrens_db_set_and_load(self):
|
||||
logic = TabALogic()
|
||||
def _make_logic(self) -> TabALogic:
|
||||
return TabALogic(
|
||||
pruefmanager=cast(Any, _DummyPruefmanager()),
|
||||
link_pruefer=cast(Any, object()),
|
||||
stil_pruefer=cast(Any, object()),
|
||||
)
|
||||
|
||||
with TemporaryDirectory() as tmp:
|
||||
db_path = Path(tmp) / "test.gpkg"
|
||||
db_path.write_text("")
|
||||
def test_verfahrens_db_set_and_load_roundtrip(self):
|
||||
logic = self._make_logic()
|
||||
logic.set_verfahrens_db("C:/tmp/v_db.gpkg")
|
||||
self.assertEqual(logic.load_verfahrens_db(), "C:/tmp/v_db.gpkg")
|
||||
|
||||
logic.set_verfahrens_db(str(db_path))
|
||||
|
||||
stored = get_variable("verfahrens_db", scope="project")
|
||||
self.assertEqual(stored, str(db_path))
|
||||
|
||||
loaded = logic.load_verfahrens_db()
|
||||
self.assertEqual(loaded, str(db_path))
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 2. Verfahrens-DB löschen
|
||||
# -----------------------------------------------------
|
||||
def test_verfahrens_db_clear(self):
|
||||
logic = TabALogic()
|
||||
|
||||
logic = self._make_logic()
|
||||
logic.set_verfahrens_db(None)
|
||||
self.assertEqual(get_variable("verfahrens_db", scope="project"), "")
|
||||
|
||||
stored = get_variable("verfahrens_db", scope="project")
|
||||
self.assertEqual(stored, "")
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 3. Neue Verfahrens-DB anlegen
|
||||
# -----------------------------------------------------
|
||||
def test_create_new_verfahrens_db(self):
|
||||
logic = TabALogic()
|
||||
|
||||
with TemporaryDirectory() as tmp:
|
||||
db_path = Path(tmp) / "neu.gpkg"
|
||||
|
||||
result = logic.create_new_verfahrens_db(str(db_path))
|
||||
|
||||
self.assertTrue(result)
|
||||
self.assertTrue(file_exists(db_path))
|
||||
|
||||
stored = get_variable("verfahrens_db", scope="project")
|
||||
self.assertEqual(stored, str(db_path))
|
||||
|
||||
def test_create_new_verfahrens_db_with_none_path(self):
|
||||
logic = TabALogic()
|
||||
result = logic.create_new_verfahrens_db(None)
|
||||
self.assertFalse(result)
|
||||
|
||||
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 4. Linkliste setzen und laden
|
||||
# -----------------------------------------------------
|
||||
def test_linkliste_set_and_load(self):
|
||||
logic = TabALogic()
|
||||
|
||||
def test_linkliste_set_and_load_existing_path(self):
|
||||
logic = self._make_logic()
|
||||
with TemporaryDirectory() as tmp:
|
||||
link_path = Path(tmp) / "links.xlsx"
|
||||
link_path.write_text("dummy")
|
||||
link_path.write_text("x", encoding="utf-8")
|
||||
|
||||
logic.set_linkliste(str(link_path))
|
||||
self.assertEqual(logic.load_linkliste(), str(link_path))
|
||||
|
||||
stored = get_variable("linkliste", scope="project")
|
||||
self.assertEqual(stored, str(link_path))
|
||||
def test_linkliste_load_returns_none_when_file_missing(self):
|
||||
logic = self._make_logic()
|
||||
logic.set_linkliste("C:/tmp/missing.xlsx")
|
||||
self.assertIsNone(logic.load_linkliste())
|
||||
|
||||
loaded = logic.load_linkliste()
|
||||
self.assertEqual(loaded, str(link_path))
|
||||
@patch("sn_plan41.ui.tab_a_logic.get_plugin_root", return_value="C:/plugins")
|
||||
@patch("sn_plan41.ui.tab_a_logic.join_path", return_value="C:/plugins/sn_plan41/assets/Linkliste.xlsx")
|
||||
def test_resolve_linkliste_empty_uses_standard_and_persists(self, _mock_join_path, _mock_root):
|
||||
logic = self._make_logic()
|
||||
resolved = logic._resolve_linkliste(None)
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 5. Linkliste löschen
|
||||
# -----------------------------------------------------
|
||||
def test_linkliste_clear(self):
|
||||
logic = TabALogic()
|
||||
self.assertEqual(resolved, "C:/plugins/sn_plan41/assets/Linkliste.xlsx")
|
||||
self.assertEqual(get_variable("linkliste", scope="project"), "C:/plugins/sn_plan41/assets/Linkliste.xlsx")
|
||||
|
||||
logic.set_linkliste(None)
|
||||
@patch("sn_plan41.ui.tab_a_logic.Dateipruefer")
|
||||
def test_resolve_linkliste_returns_none_when_pruefmanager_rejects(self, mock_dateipruefer):
|
||||
logic = self._make_logic()
|
||||
mock_dateipruefer.return_value.pruefe.return_value = pruef_ergebnis(
|
||||
ok=False,
|
||||
meldung="Ungültig",
|
||||
aktion="datei_nicht_gefunden",
|
||||
kontext=None,
|
||||
)
|
||||
|
||||
stored = get_variable("linkliste", scope="project")
|
||||
self.assertEqual(stored, "")
|
||||
resolved = logic._resolve_linkliste("C:/tmp/missing.xlsx")
|
||||
self.assertIsNone(resolved)
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 6. Layer-ID speichern
|
||||
# -----------------------------------------------------
|
||||
def test_verfahrensgebiet_layer_id_storage(self):
|
||||
logic = TabALogic()
|
||||
def test_resolve_raumfilter_without_filter_returns_none(self):
|
||||
logic = self._make_logic()
|
||||
result = logic._resolve_raumfilter("ohne", "C:/tmp/v_db.gpkg")
|
||||
self.assertIsNone(result)
|
||||
|
||||
class MockLayer:
|
||||
def id(self):
|
||||
return "layer-123"
|
||||
@patch.object(TabALogic, "_get_verfahrensgebiet_layer", return_value="layer_obj")
|
||||
def test_resolve_raumfilter_verfahrensgebiet_uses_layer_lookup(self, mock_get_layer):
|
||||
logic = self._make_logic()
|
||||
result = logic._resolve_raumfilter("Verfahrensgebiet", "C:/tmp/v_db.gpkg")
|
||||
|
||||
logic.save_verfahrensgebiet_layer(MockLayer())
|
||||
self.assertEqual(result, "layer_obj")
|
||||
mock_get_layer.assert_called_once()
|
||||
|
||||
stored = get_variable("verfahrensgebiet_layer", scope="project")
|
||||
self.assertEqual(stored, "layer-123")
|
||||
def test_extract_datenabruf_error_maps_merges_reason_maps(self):
|
||||
logic = self._make_logic()
|
||||
results = [
|
||||
pruef_ergebnis(
|
||||
ok=False,
|
||||
meldung="Head failed",
|
||||
aktion="url_nicht_erreichbar",
|
||||
kontext={"ident": "A1", "thema": "Dienst A", "error": "Timeout"},
|
||||
),
|
||||
pruef_ergebnis(
|
||||
ok=False,
|
||||
meldung="Fetch failed",
|
||||
aktion="datenabruf",
|
||||
kontext={"fehler": {"Dienst B": "HTTP 500", "Dienst A": "ignored"}},
|
||||
),
|
||||
]
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 7. Ungültiger Layer wird ignoriert
|
||||
# -----------------------------------------------------
|
||||
def test_invalid_layer_is_rejected(self):
|
||||
logic = TabALogic()
|
||||
merged = logic._extract_datenabruf_error_maps(results)
|
||||
|
||||
class InvalidLayer:
|
||||
pass
|
||||
|
||||
logic.save_verfahrensgebiet_layer(InvalidLayer())
|
||||
|
||||
stored = get_variable("verfahrensgebiet_layer", scope="project")
|
||||
self.assertEqual(stored, "")
|
||||
#-----------------------------------------------------
|
||||
# 8. Layer-ID wirft Exception
|
||||
#----------------------------------------------------
|
||||
def test_layer_id_raises_exception(self):
|
||||
logic = TabALogic()
|
||||
|
||||
class BadLayer:
|
||||
def id(self):
|
||||
raise RuntimeError("boom")
|
||||
|
||||
logic.save_verfahrensgebiet_layer(BadLayer())
|
||||
|
||||
stored = get_variable("verfahrensgebiet_layer", scope="project")
|
||||
self.assertEqual(stored, "")
|
||||
# -----------------------------------------------------
|
||||
# 11. Layer ID wird leer zurückgegeben
|
||||
# -----------------------------------------------------
|
||||
def test_layer_id_returns_empty(self):
|
||||
logic = TabALogic()
|
||||
|
||||
class EmptyLayer:
|
||||
def id(self):
|
||||
return ""
|
||||
|
||||
logic.save_verfahrensgebiet_layer(EmptyLayer())
|
||||
|
||||
stored = get_variable("verfahrensgebiet_layer", scope="project")
|
||||
self.assertEqual(stored, "")
|
||||
self.assertEqual(merged["by_ident"]["A1"], "Timeout")
|
||||
self.assertEqual(merged["by_thema"]["Dienst A"], "Timeout")
|
||||
self.assertEqual(merged["by_thema"]["Dienst B"], "HTTP 500")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from typing import Any, cast
|
||||
|
||||
from sn_plan41.ui.tab_a_logic import TabALogic
|
||||
|
||||
|
||||
class _DummyPruefmanager:
|
||||
def __init__(self) -> None:
|
||||
self.hinweise: list[tuple[str, str]] = []
|
||||
|
||||
def verarbeite(self, ergebnis):
|
||||
return ergebnis
|
||||
|
||||
def zeige_hinweis(self, titel: str, meldung: str) -> None:
|
||||
self.hinweise.append((titel, meldung))
|
||||
|
||||
|
||||
class _DummyDateiErgebnis:
|
||||
def __init__(self, ok: bool = True, kontext: str = "C:/tmp/v_db.gpkg") -> None:
|
||||
self.ok = ok
|
||||
self.kontext = kontext
|
||||
|
||||
|
||||
class _DummyProgress:
|
||||
def __init__(self) -> None:
|
||||
self.closed = False
|
||||
|
||||
def set_total(self, _value: int) -> None:
|
||||
pass
|
||||
|
||||
def set_value(self, _value: int) -> None:
|
||||
pass
|
||||
|
||||
def set_label(self, _value: str) -> None:
|
||||
pass
|
||||
|
||||
def close(self) -> None:
|
||||
self.closed = True
|
||||
|
||||
|
||||
class _DummyProject:
|
||||
def mapLayer(self, _layer_id: str):
|
||||
return None
|
||||
|
||||
|
||||
class _DummyGrabber:
|
||||
pass
|
||||
|
||||
|
||||
class TestTabAPreconditions(unittest.TestCase):
|
||||
|
||||
def _make_logic(self) -> tuple[TabALogic, _DummyPruefmanager]:
|
||||
pruefmanager = _DummyPruefmanager()
|
||||
logic = TabALogic(
|
||||
pruefmanager=cast(Any, pruefmanager),
|
||||
link_pruefer=cast(Any, object()),
|
||||
stil_pruefer=cast(Any, object()),
|
||||
)
|
||||
return logic, pruefmanager
|
||||
|
||||
def test_get_verfahrensgebiet_layer_shows_hint_when_layer_id_missing(self):
|
||||
logic, pruefmanager = self._make_logic()
|
||||
|
||||
with patch.object(logic, "load_verfahrensgebiet_layer_id", return_value=None):
|
||||
layer = logic._get_verfahrensgebiet_layer()
|
||||
|
||||
self.assertIsNone(layer)
|
||||
self.assertEqual(len(pruefmanager.hinweise), 1)
|
||||
self.assertIn("Verfahrensgebiet", pruefmanager.hinweise[0][0])
|
||||
|
||||
@patch("sn_plan41.ui.tab_a_logic.QgsProject.instance", return_value=_DummyProject())
|
||||
def test_get_verfahrensgebiet_layer_shows_hint_when_layer_not_in_project(self, _mock_project_instance):
|
||||
logic, pruefmanager = self._make_logic()
|
||||
|
||||
with patch.object(logic, "load_verfahrensgebiet_layer_id", return_value="layer_404"):
|
||||
layer = logic._get_verfahrensgebiet_layer()
|
||||
|
||||
self.assertIsNone(layer)
|
||||
self.assertEqual(len(pruefmanager.hinweise), 1)
|
||||
self.assertIn("Verfahrensgebiet", pruefmanager.hinweise[0][0])
|
||||
|
||||
@patch("sn_plan41.ui.tab_a_logic.Dateipruefer")
|
||||
def test_pipeline_aborts_and_shows_hint_when_verfahrensgebiet_missing(
|
||||
self,
|
||||
mock_dateipruefer,
|
||||
):
|
||||
logic, pruefmanager = self._make_logic()
|
||||
logic.data_grabber = cast(Any, _DummyGrabber())
|
||||
|
||||
mock_dateipruefer.return_value.pruefe.return_value = _DummyDateiErgebnis(ok=True, kontext="C:/tmp/v_db.gpkg")
|
||||
|
||||
progress = _DummyProgress()
|
||||
|
||||
with patch("sn_plan41.ui.tab_a_logic.create_progress_dialog", return_value=progress):
|
||||
with patch.object(logic, "_resolve_linkliste", return_value="C:/tmp/linkliste.xlsx"):
|
||||
with patch.object(logic, "load_verfahrensgebiet_layer_id", return_value=None):
|
||||
result = logic._on_run_pipeline(
|
||||
source="C:/tmp/v_db.gpkg",
|
||||
linkliste=None,
|
||||
raumfilter="Verfahrensgebiet",
|
||||
)
|
||||
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual(len(pruefmanager.hinweise), 1)
|
||||
self.assertIn("Verfahrensgebiet", pruefmanager.hinweise[0][0])
|
||||
self.assertTrue(progress.closed)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+94
-37
@@ -1,56 +1,113 @@
|
||||
"""
|
||||
Smoke-Tests für TabA UI (sn_plan41/ui/tab_a_ui.py)
|
||||
|
||||
Ziel:
|
||||
- UI kann erstellt werden
|
||||
- Callbacks crashen nicht
|
||||
- Keine Qt-Verhaltensprüfung
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from sn_plan41.ui.tab_a_ui import TabA #type:ignore
|
||||
from sn_basis.functions.variable_wrapper import get_variable
|
||||
from sn_plan41.ui.tab_a_ui import TabA
|
||||
|
||||
|
||||
class _DummySignal:
|
||||
def connect(self, _callback):
|
||||
return None
|
||||
|
||||
|
||||
class _DummyToggleButton:
|
||||
def __init__(self):
|
||||
self.arrow = None
|
||||
self.style = ""
|
||||
|
||||
def setArrowType(self, arrow):
|
||||
self.arrow = arrow
|
||||
|
||||
def setStyleSheet(self, style):
|
||||
self.style = style
|
||||
|
||||
|
||||
class _DummyWidget:
|
||||
def __init__(self):
|
||||
self.visible = None
|
||||
|
||||
def setVisible(self, visible):
|
||||
self.visible = visible
|
||||
|
||||
|
||||
class _DummyFileWidget:
|
||||
def __init__(self):
|
||||
self._path = ""
|
||||
|
||||
def setFilePath(self, path):
|
||||
self._path = path
|
||||
|
||||
def filePath(self):
|
||||
return self._path
|
||||
|
||||
|
||||
class _DummyCombo:
|
||||
def __init__(self, value="Pufferlayer"):
|
||||
self._value = value
|
||||
|
||||
def currentText(self):
|
||||
return self._value
|
||||
|
||||
|
||||
class _DummyPruefmanager:
|
||||
pass
|
||||
|
||||
|
||||
class _DummyDataGrabber:
|
||||
pass
|
||||
|
||||
|
||||
class TestTabAUI(unittest.TestCase):
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 1. UI kann erstellt werden
|
||||
# -----------------------------------------------------
|
||||
def test_tab_a_ui_can_be_created(self):
|
||||
tab = TabA(parent=None,build_ui=False)
|
||||
def _make_tab_without_qt(self):
|
||||
tab = TabA.__new__(TabA)
|
||||
tab.group_button = _DummyToggleButton()
|
||||
tab.group_content = _DummyWidget()
|
||||
tab.optional_button = _DummyToggleButton()
|
||||
tab.optional_content = _DummyWidget()
|
||||
tab.file_widget = _DummyFileWidget()
|
||||
tab.linkliste_widget = _DummyFileWidget()
|
||||
tab._raumfilter_combo = _DummyCombo("ohne")
|
||||
tab.verfahrens_db = None
|
||||
tab.lokale_linkliste = None
|
||||
tab.logic = None
|
||||
tab.pruefmanager = None
|
||||
tab.data_grabber = None
|
||||
return tab
|
||||
|
||||
self.assertIsNotNone(tab)
|
||||
self.assertEqual(tab.tab_title, "Daten")
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 2. Toggle-Callbacks crashen nicht
|
||||
# -----------------------------------------------------
|
||||
def test_tab_a_toggle_callbacks_do_not_crash(self):
|
||||
tab = TabA(parent=None,build_ui=False)
|
||||
def test_tab_a_callbacks_can_be_called_without_crash(self):
|
||||
tab = self._make_tab_without_qt()
|
||||
|
||||
tab._toggle_group(True)
|
||||
tab._toggle_group(False)
|
||||
|
||||
tab._toggle_optional(True)
|
||||
tab._toggle_optional(False)
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 3. Datei-Callbacks akzeptieren leere Eingaben
|
||||
# -----------------------------------------------------
|
||||
def test_tab_a_file_callbacks_accept_empty_input(self):
|
||||
tab = TabA(parent=None,build_ui=False)
|
||||
|
||||
tab._on_verfahrens_db_changed("")
|
||||
tab._on_linkliste_changed("")
|
||||
|
||||
# -----------------------------------------------------
|
||||
# 4. Layer-Callback akzeptiert None
|
||||
# -----------------------------------------------------
|
||||
def test_tab_a_layer_callback_accepts_none(self):
|
||||
tab = TabA(parent=None,build_ui=False)
|
||||
self.assertEqual(tab.group_content.visible, False)
|
||||
self.assertEqual(tab.optional_content.visible, False)
|
||||
|
||||
tab._on_layer_changed(None)
|
||||
def test_tab_a_raumfilter_callback_persists_value(self):
|
||||
tab = self._make_tab_without_qt()
|
||||
|
||||
tab._on_raumfilter_changed("ohne")
|
||||
self.assertEqual(get_variable("Raumfilter", scope="project"), "ohne")
|
||||
|
||||
@patch("sn_plan41.ui.tab_a_ui.TabALogic")
|
||||
def test_set_services_initializes_logic_and_injects_data_grabber(self, mock_logic_cls):
|
||||
tab = self._make_tab_without_qt()
|
||||
mock_logic = mock_logic_cls.return_value
|
||||
|
||||
pm = _DummyPruefmanager()
|
||||
dg = _DummyDataGrabber()
|
||||
|
||||
tab.set_services(pruefmanager=pm, data_grabber=dg)
|
||||
|
||||
self.assertIs(tab.pruefmanager, pm)
|
||||
self.assertIs(tab.data_grabber, dg)
|
||||
self.assertIs(tab.logic, mock_logic)
|
||||
self.assertIs(tab.logic.data_grabber, dg)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,473 @@
|
||||
"""
|
||||
Tests für sn_plan41/modules/vln_api_logic.py
|
||||
|
||||
Alle externen Abhängigkeiten (vln_karten, QSettings, QgsProject, Netzwerk)
|
||||
werden mit unittest.mock gemockt, sodass keine QGIS-Laufzeitumgebung nötig ist.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from typing import Any, Optional
|
||||
from unittest.mock import MagicMock, patch, call
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _make_logic(api_key: Optional[str] = None, mail: Optional[str] = None):
|
||||
"""Erzeugt eine VlnApiLogic-Instanz mit gemockten QSettings."""
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings") as mock_qs_cls:
|
||||
mock_qs = MagicMock()
|
||||
mock_qs.value.side_effect = lambda key, default="": (
|
||||
api_key if key == "api_key" else (mail if key == "mail" else default)
|
||||
)
|
||||
mock_qs_cls.return_value = mock_qs
|
||||
|
||||
if api_key and VlnApiLogic.is_available():
|
||||
with patch(
|
||||
"sn_plan41.modules.vln_api_logic.KartenApiClient"
|
||||
) as mock_client_cls:
|
||||
mock_client = MagicMock()
|
||||
mock_client.is_authenticated = True
|
||||
mock_client.api_key = api_key
|
||||
mock_client.mail = mail
|
||||
mock_client_cls.return_value = mock_client
|
||||
logic = VlnApiLogic()
|
||||
else:
|
||||
logic = VlnApiLogic()
|
||||
|
||||
return logic
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Verfügbarkeit
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestVlnApiLogicAvailability(unittest.TestCase):
|
||||
|
||||
def test_is_available_reflects_import_state(self):
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
result = VlnApiLogic.is_available()
|
||||
# Ergebnis hängt davon ab, ob vln_karten installiert ist —
|
||||
# wir prüfen nur, dass ein bool zurückkommt
|
||||
self.assertIsInstance(result, bool)
|
||||
|
||||
def test_is_available_false_when_vln_karten_missing(self):
|
||||
"""Wenn VLN_KARTEN_AVAILABLE=False, liefert is_available() False."""
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
original = module.VLN_KARTEN_AVAILABLE
|
||||
try:
|
||||
module.VLN_KARTEN_AVAILABLE = False
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
with patch.object(module, "VLN_KARTEN_AVAILABLE", False):
|
||||
self.assertFalse(VlnApiLogic.is_available())
|
||||
finally:
|
||||
module.VLN_KARTEN_AVAILABLE = original
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Credentials-Persistenz
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestVlnApiLogicCredentials(unittest.TestCase):
|
||||
|
||||
def _make(self):
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings"):
|
||||
with patch("sn_plan41.modules.vln_api_logic.KartenApiClient"):
|
||||
return VlnApiLogic()
|
||||
|
||||
def test_save_api_key_calls_qsettings(self):
|
||||
logic = self._make()
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings") as mock_qs_cls:
|
||||
mock_qs = MagicMock()
|
||||
mock_qs_cls.return_value = mock_qs
|
||||
logic.save_api_key("token123", "user@test.de")
|
||||
|
||||
mock_qs.setValue.assert_any_call("api_key", "token123")
|
||||
mock_qs.setValue.assert_any_call("mail", "user@test.de")
|
||||
mock_qs.beginGroup.assert_called_with("vln_karten")
|
||||
|
||||
def test_clear_api_key_calls_remove(self):
|
||||
logic = self._make()
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings") as mock_qs_cls:
|
||||
mock_qs = MagicMock()
|
||||
mock_qs_cls.return_value = mock_qs
|
||||
logic.clear_api_key()
|
||||
|
||||
mock_qs.remove.assert_called_with("api_key")
|
||||
|
||||
def test_load_stored_credentials_returns_api_key_and_mail(self):
|
||||
logic = self._make()
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings") as mock_qs_cls:
|
||||
mock_qs = MagicMock()
|
||||
mock_qs.value.side_effect = lambda key, default="": {
|
||||
"api_key": "mykey",
|
||||
"mail": "user@test.de",
|
||||
}.get(key, default)
|
||||
mock_qs_cls.return_value = mock_qs
|
||||
|
||||
api_key, mail = logic.load_stored_credentials()
|
||||
|
||||
self.assertEqual(api_key, "mykey")
|
||||
self.assertEqual(mail, "user@test.de")
|
||||
|
||||
def test_load_stored_credentials_returns_none_for_empty(self):
|
||||
logic = self._make()
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings") as mock_qs_cls:
|
||||
mock_qs = MagicMock()
|
||||
mock_qs.value.return_value = ""
|
||||
mock_qs_cls.return_value = mock_qs
|
||||
|
||||
api_key, mail = logic.load_stored_credentials()
|
||||
|
||||
self.assertIsNone(api_key)
|
||||
self.assertIsNone(mail)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Login / Logout
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestVlnApiLogicLogin(unittest.TestCase):
|
||||
|
||||
def _make(self):
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings"):
|
||||
with patch("sn_plan41.modules.vln_api_logic.KartenApiClient"):
|
||||
return VlnApiLogic()
|
||||
|
||||
def test_login_sets_client_and_saves_key(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
if not module.VLN_KARTEN_AVAILABLE:
|
||||
self.skipTest("vln_karten nicht verfügbar")
|
||||
|
||||
logic = self._make()
|
||||
|
||||
mock_client = MagicMock()
|
||||
mock_client.api_key = "newtoken"
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.KartenApiClient", return_value=mock_client):
|
||||
with patch.object(logic, "save_api_key") as mock_save:
|
||||
logic.login("user@test.de", "secret")
|
||||
|
||||
mock_client.login.assert_called_once_with("user@test.de", "secret")
|
||||
mock_save.assert_called_once_with("newtoken", "user@test.de")
|
||||
|
||||
def test_login_raises_runtime_error_without_qgis_modules(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
logic = self._make()
|
||||
with patch.object(module, "VLN_KARTEN_AVAILABLE", False):
|
||||
with self.assertRaises(RuntimeError):
|
||||
logic.login("user@test.de", "secret")
|
||||
|
||||
def test_login_propagates_api_error(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
if not module.VLN_KARTEN_AVAILABLE:
|
||||
self.skipTest("vln_karten nicht verfügbar")
|
||||
|
||||
logic = self._make()
|
||||
mock_client = MagicMock()
|
||||
mock_client.login.side_effect = module.ApiError("Ungültige Zugangsdaten")
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.KartenApiClient", return_value=mock_client):
|
||||
with self.assertRaises(Exception):
|
||||
logic.login("user@test.de", "wrong")
|
||||
|
||||
def test_logout_clears_client(self):
|
||||
logic = self._make()
|
||||
logic._client = MagicMock()
|
||||
logic.logout()
|
||||
self.assertIsNone(logic._client)
|
||||
|
||||
def test_is_authenticated_false_after_logout(self):
|
||||
logic = self._make()
|
||||
logic._client = None
|
||||
self.assertFalse(logic.is_authenticated)
|
||||
|
||||
def test_handle_session_expired_clears_key_and_client(self):
|
||||
logic = self._make()
|
||||
with patch.object(logic, "clear_api_key") as mock_clear:
|
||||
with patch.object(logic, "logout") as mock_logout:
|
||||
logic.handle_session_expired()
|
||||
|
||||
mock_clear.assert_called_once()
|
||||
mock_logout.assert_called_once()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Verfahrensliste
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestVlnApiLogicVerfahren(unittest.TestCase):
|
||||
|
||||
def _make_authenticated(self):
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings"):
|
||||
with patch("sn_plan41.modules.vln_api_logic.KartenApiClient"):
|
||||
logic = VlnApiLogic()
|
||||
|
||||
mock_client = MagicMock()
|
||||
mock_client.is_authenticated = True
|
||||
logic._client = mock_client
|
||||
return logic, mock_client
|
||||
|
||||
def test_get_verfahren_raises_when_not_authenticated(self):
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings"):
|
||||
with patch("sn_plan41.modules.vln_api_logic.KartenApiClient"):
|
||||
logic = VlnApiLogic()
|
||||
logic._client = None
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
logic.get_verfahren()
|
||||
|
||||
def test_get_verfahren_delegates_to_client(self):
|
||||
logic, mock_client = self._make_authenticated()
|
||||
mock_client.get_verfahren.return_value = [
|
||||
{"vkz": "27010", "name": "Alpha"},
|
||||
{"vkz": "27001", "name": "Beta"},
|
||||
]
|
||||
result = logic.get_verfahren()
|
||||
mock_client.get_verfahren.assert_called_once()
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: VKZ-Persistenz
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestVlnApiLogicVkz(unittest.TestCase):
|
||||
|
||||
def _make(self):
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings"):
|
||||
with patch("sn_plan41.modules.vln_api_logic.KartenApiClient"):
|
||||
return VlnApiLogic()
|
||||
|
||||
def test_load_stored_vkz_reads_from_project(self):
|
||||
logic = self._make()
|
||||
mock_project = MagicMock()
|
||||
mock_project.readEntry.return_value = ("27010", True)
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QgsProject") as mock_qgsproj_cls:
|
||||
mock_qgsproj_cls.instance.return_value = mock_project
|
||||
vkz = logic.load_stored_vkz()
|
||||
|
||||
self.assertEqual(vkz, "27010")
|
||||
mock_project.readEntry.assert_called_once_with("vln_karten", "/vkz", "")
|
||||
|
||||
def test_load_stored_vkz_returns_none_for_empty(self):
|
||||
logic = self._make()
|
||||
mock_project = MagicMock()
|
||||
mock_project.readEntry.return_value = ("", True)
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QgsProject") as mock_qgsproj_cls:
|
||||
mock_qgsproj_cls.instance.return_value = mock_project
|
||||
vkz = logic.load_stored_vkz()
|
||||
|
||||
self.assertIsNone(vkz)
|
||||
|
||||
def test_save_vkz_writes_to_project(self):
|
||||
logic = self._make()
|
||||
mock_project = MagicMock()
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QgsProject") as mock_qgsproj_cls:
|
||||
mock_qgsproj_cls.instance.return_value = mock_project
|
||||
logic.save_vkz("27010")
|
||||
|
||||
mock_project.writeEntry.assert_called_once_with("vln_karten", "/vkz", "27010")
|
||||
|
||||
def test_save_vkz_does_nothing_for_none(self):
|
||||
logic = self._make()
|
||||
mock_project = MagicMock()
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QgsProject") as mock_qgsproj_cls:
|
||||
mock_qgsproj_cls.instance.return_value = mock_project
|
||||
logic.save_vkz(None)
|
||||
|
||||
mock_project.writeEntry.assert_not_called()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Plan 41 laden (Stil-Anwendung)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestVlnApiLogicLoadP41(unittest.TestCase):
|
||||
|
||||
def _make(self):
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings"):
|
||||
with patch("sn_plan41.modules.vln_api_logic.KartenApiClient"):
|
||||
logic = VlnApiLogic()
|
||||
|
||||
mock_client = MagicMock()
|
||||
mock_client.is_authenticated = True
|
||||
mock_client.load_layer_complete.return_value = {
|
||||
"type": "FeatureCollection",
|
||||
"features": [],
|
||||
}
|
||||
logic._client = mock_client
|
||||
return logic
|
||||
|
||||
def test_load_p41_raises_without_vln_karten(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
logic = self._make()
|
||||
with patch.object(module, "VLN_KARTEN_AVAILABLE", False):
|
||||
with self.assertRaises(RuntimeError):
|
||||
logic.load_p41("27010")
|
||||
|
||||
def test_load_p41_applies_styles_to_polygon_and_line_layers(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
if not module.VLN_KARTEN_AVAILABLE:
|
||||
self.skipTest("vln_karten nicht verfügbar")
|
||||
|
||||
logic = self._make()
|
||||
|
||||
# Zwei Mock-Layer: einer Polygon (2), einer Linie (1)
|
||||
mock_layer_polygon = MagicMock()
|
||||
mock_layer_polygon.geometryType.return_value = module._GEOM_POLYGON
|
||||
|
||||
mock_layer_line = MagicMock()
|
||||
mock_layer_line.geometryType.return_value = module._GEOM_LINE
|
||||
|
||||
with patch(
|
||||
"sn_plan41.modules.vln_api_logic.feature_collection_to_layers",
|
||||
return_value=[mock_layer_polygon, mock_layer_line],
|
||||
):
|
||||
with patch(
|
||||
"sn_plan41.modules.vln_api_logic.apply_style_from_path"
|
||||
) as mock_style:
|
||||
with patch("sn_plan41.modules.vln_api_logic.join_path", side_effect=lambda *p: "/".join(p)):
|
||||
with patch("sn_plan41.modules.vln_api_logic.get_plugin_root", return_value="/plugins"):
|
||||
logic.load_p41("27010")
|
||||
|
||||
# Prüfen, dass der richtige Stil für jeden Geometrietyp verwendet wurde
|
||||
style_calls = [str(c) for c in mock_style.call_args_list]
|
||||
polygon_style_used = any(
|
||||
module.STYLE_FLAECHE in c for c in style_calls
|
||||
)
|
||||
line_style_used = any(
|
||||
module.STYLE_LINIE in c for c in style_calls
|
||||
)
|
||||
self.assertTrue(polygon_style_used, "Flächen-Stil wurde nicht angewendet")
|
||||
self.assertTrue(line_style_used, "Linien-Stil wurde nicht angewendet")
|
||||
|
||||
def test_load_p41_no_style_for_point_layer(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
if not module.VLN_KARTEN_AVAILABLE:
|
||||
self.skipTest("vln_karten nicht verfügbar")
|
||||
|
||||
logic = self._make()
|
||||
|
||||
mock_layer_point = MagicMock()
|
||||
mock_layer_point.geometryType.return_value = 0 # Point
|
||||
|
||||
with patch(
|
||||
"sn_plan41.modules.vln_api_logic.feature_collection_to_layers",
|
||||
return_value=[mock_layer_point],
|
||||
):
|
||||
with patch(
|
||||
"sn_plan41.modules.vln_api_logic.apply_style_from_path"
|
||||
) as mock_style:
|
||||
with patch("sn_plan41.modules.vln_api_logic.join_path", side_effect=lambda *p: "/".join(p)):
|
||||
with patch("sn_plan41.modules.vln_api_logic.get_plugin_root", return_value="/plugins"):
|
||||
logic.load_p41("27010")
|
||||
|
||||
mock_style.assert_not_called()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Upload
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestVlnApiLogicUpload(unittest.TestCase):
|
||||
|
||||
def _make(self):
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.QSettings"):
|
||||
with patch("sn_plan41.modules.vln_api_logic.KartenApiClient"):
|
||||
logic = VlnApiLogic()
|
||||
|
||||
mock_client = MagicMock()
|
||||
mock_client.is_authenticated = True
|
||||
logic._client = mock_client
|
||||
return logic
|
||||
|
||||
def test_upload_returns_error_for_layer_without_api_path(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
if not module.VLN_KARTEN_AVAILABLE:
|
||||
self.skipTest("vln_karten nicht verfügbar")
|
||||
|
||||
logic = self._make()
|
||||
mock_layer = MagicMock()
|
||||
|
||||
with patch(
|
||||
"sn_plan41.modules.vln_api_logic.layer_api_path", return_value=None
|
||||
):
|
||||
success, message = logic.upload_active_layer(mock_layer)
|
||||
|
||||
self.assertFalse(success)
|
||||
self.assertIn("nicht", message.lower())
|
||||
|
||||
def test_upload_returns_error_for_none_layer(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
if not module.VLN_KARTEN_AVAILABLE:
|
||||
self.skipTest("vln_karten nicht verfügbar")
|
||||
|
||||
logic = self._make()
|
||||
with patch(
|
||||
"sn_plan41.modules.vln_api_logic.layer_api_path", return_value=None
|
||||
):
|
||||
success, message = logic.upload_active_layer(None)
|
||||
|
||||
self.assertFalse(success)
|
||||
|
||||
def test_upload_returns_false_without_qgis_modules(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
logic = self._make()
|
||||
with patch.object(module, "VLN_KARTEN_AVAILABLE", False):
|
||||
success, message = logic.upload_active_layer(MagicMock())
|
||||
|
||||
self.assertFalse(success)
|
||||
|
||||
def test_upload_calls_save_feature_collection(self):
|
||||
import sn_plan41.modules.vln_api_logic as module
|
||||
if not module.VLN_KARTEN_AVAILABLE:
|
||||
self.skipTest("vln_karten nicht verfügbar")
|
||||
|
||||
logic = self._make()
|
||||
|
||||
mock_layer = MagicMock()
|
||||
mock_layer.isEditable.return_value = False
|
||||
mock_layer.featureCount.return_value = 5
|
||||
|
||||
fc = {"type": "FeatureCollection", "features": []}
|
||||
|
||||
with patch("sn_plan41.modules.vln_api_logic.layer_api_path", return_value="/maps/p41/27010"):
|
||||
with patch("sn_plan41.modules.vln_api_logic.plugin_layers", return_value=[mock_layer]):
|
||||
with patch("sn_plan41.modules.vln_api_logic.layers_to_feature_collection", return_value=fc):
|
||||
success, message = logic.upload_active_layer(mock_layer)
|
||||
|
||||
logic._client.save_feature_collection.assert_called_once_with("/maps/p41/27010", fc)
|
||||
self.assertTrue(success)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+20
-1
@@ -1,4 +1,7 @@
|
||||
#sn_plan41/ui/dockwidget.py
|
||||
"""sn_plan41/ui/dockwidget.py – Haupt-DockWidget für sn_plan41.
|
||||
Verwaltet die Tabs für Linkvalidierung, Druck und Einstellungen.
|
||||
"""
|
||||
|
||||
from sn_basis.ui.tabs.settings_tab import SettingsTab
|
||||
from sn_plan41.ui.tab_a_ui import TabA
|
||||
from sn_basis.ui.tabs.print_tab import PrintTab
|
||||
@@ -8,9 +11,25 @@ from sn_basis.functions.message_wrapper import error
|
||||
|
||||
|
||||
class DockWidget(BaseDockWidget):
|
||||
"""Haupt-DockWidget für sn_plan41 mit Tab-Verwaltung.
|
||||
|
||||
Attributes:
|
||||
tabs: Liste von Tab-Klassen (TabA, PrintTab, SettingsTab)
|
||||
pruefmanager: Prüfmanager-Instanz für Validierung
|
||||
data_grabber: DataGrabber-Instanz für Fachdatenabruf
|
||||
"""
|
||||
|
||||
tabs = [TabA, PrintTab, SettingsTab]
|
||||
|
||||
def __init__(self, parent=None, subtitle="", pruefmanager=None, data_grabber=None):
|
||||
"""Initialisiert das DockWidget mit Services und Tabs.
|
||||
|
||||
Args:
|
||||
parent: Übergeordnetes Widget
|
||||
subtitle: Untertitel des DockWidgets
|
||||
pruefmanager: Prüfmanager-Instanz
|
||||
data_grabber: DataGrabber-Instanz
|
||||
"""
|
||||
super().__init__(parent, subtitle)
|
||||
|
||||
# Services als Attribute speichern
|
||||
|
||||
+221
-53
@@ -12,6 +12,7 @@ import os
|
||||
import datetime
|
||||
import json
|
||||
import tempfile
|
||||
import html
|
||||
|
||||
from sn_basis.functions.qgiscore_wrapper import (
|
||||
QgsVectorFileWriter,
|
||||
@@ -63,9 +64,88 @@ class TabALogic:
|
||||
self.link_pruefer = link_pruefer
|
||||
self.stil_pruefer = stil_pruefer
|
||||
self.data_grabber: Optional[DataGrabber] = None
|
||||
|
||||
class _SilentPruefmanagerProxy:
|
||||
"""Proxy, der Prüfergebnisse ohne UI-Meldungen verarbeitet."""
|
||||
|
||||
def __init__(self, outer: "TabALogic", fallback: Optional[Any]) -> None:
|
||||
self._outer = outer
|
||||
self._fallback = fallback
|
||||
self.results: List[Any] = []
|
||||
|
||||
def verarbeite(self, ergebnis: Any) -> Any:
|
||||
self.results.append(ergebnis)
|
||||
ok = bool(getattr(ergebnis, "ok", False))
|
||||
if not ok:
|
||||
aktion = getattr(ergebnis, "aktion", "unbekannt")
|
||||
meldung = getattr(ergebnis, "meldung", "")
|
||||
self._outer._log(f"[SILENT-PRUEFMANAGER] {aktion}: {meldung}")
|
||||
return ergebnis
|
||||
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
if self._fallback is not None:
|
||||
return getattr(self._fallback, name)
|
||||
raise AttributeError(name)
|
||||
|
||||
def _log(self, msg: str) -> None:
|
||||
print(f"[TabALogic] {msg}")
|
||||
|
||||
def _create_silent_pruefmanager(self) -> "TabALogic._SilentPruefmanagerProxy":
|
||||
return TabALogic._SilentPruefmanagerProxy(self, self.pruefmanager)
|
||||
|
||||
def _extract_datenabruf_error_maps(self, datenabruf_results: List[Any]) -> Dict[str, Dict[str, str]]:
|
||||
by_ident: Dict[str, str] = {}
|
||||
by_thema: Dict[str, str] = {}
|
||||
|
||||
for result in datenabruf_results or []:
|
||||
if not result:
|
||||
continue
|
||||
context = getattr(result, "kontext", None)
|
||||
if not isinstance(context, dict):
|
||||
continue
|
||||
|
||||
if getattr(result, "aktion", None) == "url_nicht_erreichbar":
|
||||
ident = str(context.get("ident") or "").strip()
|
||||
thema = str(context.get("thema") or "").strip()
|
||||
reason = str(context.get("error") or getattr(result, "meldung", "") or "unbekannter Fehler").strip()
|
||||
if ident and reason:
|
||||
by_ident[ident] = reason
|
||||
if thema and reason:
|
||||
by_thema[thema] = reason
|
||||
|
||||
if getattr(result, "aktion", None) == "datenabruf":
|
||||
fehler_map = context.get("fehler")
|
||||
if isinstance(fehler_map, dict):
|
||||
for thema_key, value in fehler_map.items():
|
||||
thema = str(thema_key or "").strip()
|
||||
reason = str(value or "").strip()
|
||||
if thema and reason and thema not in by_thema:
|
||||
by_thema[thema] = reason
|
||||
|
||||
return {"by_ident": by_ident, "by_thema": by_thema}
|
||||
|
||||
def _zeige_verfahrensgebiet_hinweis(self) -> None:
|
||||
if not self.pruefmanager:
|
||||
return
|
||||
show_hint = getattr(self.pruefmanager, "zeige_hinweis", None)
|
||||
if callable(show_hint):
|
||||
show_hint(
|
||||
"Verfahrensgebiet fehlt",
|
||||
"Kein gueltiger Verfahrensgebiet-Layer vorhanden. "
|
||||
"Bitte zuerst in sn_verfahrensgebiet den Layer ueber 'Aus ALKIS laden' laden "
|
||||
"oder im Dropdown einen gueltigen Layer auswaehlen.",
|
||||
)
|
||||
|
||||
def _close_progress_dialog(self, progress: Optional[Any]) -> None:
|
||||
if progress is None:
|
||||
return
|
||||
close = getattr(progress, "close", None)
|
||||
if callable(close):
|
||||
try:
|
||||
close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# -------------------------------
|
||||
# Verfahrens-Datenbank (Pfad-Management)
|
||||
# -------------------------------
|
||||
@@ -155,12 +235,6 @@ class TabALogic:
|
||||
# -------------------------------
|
||||
# Verfahrensgebiet-Layer
|
||||
# -------------------------------
|
||||
|
||||
def save_verfahrensgebiet_layer(self, layer: QgsVectorLayer) -> None:
|
||||
"""Speichert die Verfahrensgebiet-Layer-ID, unter Annahme, dass der Layer prevalidiert ist."""
|
||||
layer_id = layer.id() if layer is not None else ""
|
||||
set_variable("verfahrensgebiet_layer", layer_id or "", scope="project")
|
||||
|
||||
def load_verfahrensgebiet_layer_id(self) -> Optional[str]:
|
||||
value = get_variable("verfahrensgebiet_layer", scope="project")
|
||||
return value or None
|
||||
@@ -217,6 +291,7 @@ class TabALogic:
|
||||
linkliste_final = self._resolve_linkliste(linkliste)
|
||||
if linkliste_final is None:
|
||||
self._log("Linkliste kann nicht aufgelöst werden")
|
||||
self._close_progress_dialog(progress)
|
||||
return None
|
||||
else:
|
||||
self._log(f"Linkliste final: '{linkliste_final}'")
|
||||
@@ -224,6 +299,7 @@ class TabALogic:
|
||||
raumfilter_layer = self._resolve_raumfilter(raumfilter, final_pfad)
|
||||
if raumfilter in ("Verfahrensgebiet", "Pufferlayer") and raumfilter_layer is None:
|
||||
self._log(f"Raumfilter '{raumfilter}' nicht verfügbar")
|
||||
self._close_progress_dialog(progress)
|
||||
return None
|
||||
|
||||
# 4) Lade-Status initialisieren (funktioniert ab Bestätigung überschreiben/anhängen)
|
||||
@@ -236,7 +312,16 @@ class TabALogic:
|
||||
progress.set_label("Prüfe Eingaben...")
|
||||
|
||||
# 5) Daten aus Linkliste laden und prüfen
|
||||
source_dict, grabber_summary = self.data_grabber.run(linkliste_final)
|
||||
silent_pruefmanager = self._create_silent_pruefmanager()
|
||||
local_data_grabber = DataGrabber(
|
||||
silent_pruefmanager,
|
||||
datei_pruefer_cls=self.data_grabber._datei_pruefer_cls,
|
||||
link_pruefer=self.data_grabber.link_pruefer,
|
||||
layer_pruefer=self.data_grabber.layer_pruefer,
|
||||
stil_pruefer=self.data_grabber.stil_pruefer,
|
||||
excel_importer_cls=self.data_grabber._excel_importer_cls,
|
||||
)
|
||||
source_dict, grabber_summary = local_data_grabber.run(linkliste_final)
|
||||
self._log(f"DataGrabber: {grabber_summary.meldung} [{grabber_summary.aktion}]")
|
||||
|
||||
# DEBUG: detaillierter Status
|
||||
@@ -249,6 +334,7 @@ class TabALogic:
|
||||
if not source_dict.get("rows"):
|
||||
self._log("Keine validen Linkliste-Einträge für Datenabruf")
|
||||
print("[TabALogic] ... STOP: rows:", len(source_dict.get("rows", [])))
|
||||
self._close_progress_dialog(progress)
|
||||
return None
|
||||
|
||||
total_rows = len(source_dict.get("rows", []))
|
||||
@@ -266,7 +352,8 @@ class TabALogic:
|
||||
self._log("Warnung: DataGrabber meldet fehlerhafte Zeilen, fahre mit Validierungsdaten fort")
|
||||
|
||||
# 5) Datenabruf (aus validierten Zeilen)
|
||||
datenabruf = Datenabruf(self.pruefmanager)
|
||||
silent_pruefmanager = self._create_silent_pruefmanager()
|
||||
datenabruf = Datenabruf(silent_pruefmanager)
|
||||
result_dict, datenabruf_results = datenabruf.datenabruf(
|
||||
result_dict=source_dict,
|
||||
raumfilter=raumfilter,
|
||||
@@ -296,7 +383,7 @@ class TabALogic:
|
||||
progress.set_label("Fachdaten laden abgeschlossen. Bitte OK klicken, um den Dialog zu schließen.")
|
||||
|
||||
# 7) Log-Datei schreiben
|
||||
self._write_markdown_log(final_pfad, source_dict, pipeline_context, load_summary)
|
||||
self._write_html_log(final_pfad, source_dict, pipeline_context, load_summary)
|
||||
|
||||
print("=" * 60 + "\n")
|
||||
return pipeline_context
|
||||
@@ -310,7 +397,15 @@ class TabALogic:
|
||||
aborted = False
|
||||
if not rows:
|
||||
self._log("Keine Dienste zum Laden")
|
||||
return
|
||||
return {
|
||||
"row_count": 0,
|
||||
"loaded_count": 0,
|
||||
"skipped_outside": 0,
|
||||
"aborted": False,
|
||||
"row_stats": [],
|
||||
"layer_call_status": {},
|
||||
"raumfilter_name": pipeline_context.get("raumfilter_name", "unbekannt"),
|
||||
}
|
||||
|
||||
final_pfad = pipeline_context.get("source") or ""
|
||||
use_datenschreiber = bool(final_pfad)
|
||||
@@ -340,7 +435,12 @@ class TabALogic:
|
||||
raumfilter_extent = raumfilter_layer.extent()
|
||||
|
||||
temp_layers: List[Any] = []
|
||||
layer_loader = LayerLoader(self.pruefmanager, stil_pruefer=self.stil_pruefer, layer_pruefer=self.link_pruefer)
|
||||
silent_pruefmanager = self._create_silent_pruefmanager()
|
||||
layer_loader = LayerLoader(silent_pruefmanager, stil_pruefer=self.stil_pruefer, layer_pruefer=self.link_pruefer)
|
||||
|
||||
error_maps = self._extract_datenabruf_error_maps(pipeline_context.get("datenabruf_results", []))
|
||||
error_by_ident = error_maps.get("by_ident", {})
|
||||
error_by_thema = error_maps.get("by_thema", {})
|
||||
|
||||
# Statistiken für Log: Raumfilter-Info pro Dienst
|
||||
row_stats: List[Dict[str, Any]] = []
|
||||
@@ -357,6 +457,7 @@ class TabALogic:
|
||||
daten_map = (pipeline_context.get("result_dict") or {}).get("daten", {})
|
||||
fetched_features = daten_map.get(ident, []) if isinstance(daten_map, dict) else []
|
||||
fetched_count = len(fetched_features) if isinstance(fetched_features, list) else None
|
||||
base_reason = error_by_ident.get(ident) or error_by_thema.get(thema)
|
||||
|
||||
if progress is not None:
|
||||
progress.set_label(f"Lade Dienst {idx}/{total}: {thema}")
|
||||
@@ -385,6 +486,8 @@ class TabALogic:
|
||||
if not layer:
|
||||
layer_call_status[thema] = "layer_nicht_ladbar"
|
||||
self._log(f"[DEBUG] Layeraufruf fehlgeschlagen: thema='{thema}'")
|
||||
reason = base_reason or "Layer konnte nicht geladen werden (Dienst nicht erreichbar oder Link fehlerhaft)"
|
||||
self._log(f"[DEBUG] Dienst nicht geladen: {thema} | Grund: {reason}")
|
||||
row_stats.append({
|
||||
"dienst": thema,
|
||||
"provider": provider,
|
||||
@@ -394,7 +497,7 @@ class TabALogic:
|
||||
"total_features": None,
|
||||
"filtered_features": None,
|
||||
"status": "layer_nicht_ladbar",
|
||||
"raumfilter": raumfilter_name,
|
||||
"reason": reason,
|
||||
})
|
||||
continue
|
||||
|
||||
@@ -448,6 +551,7 @@ class TabALogic:
|
||||
layer_call_status[thema] = "raumfilter_ausserhalb"
|
||||
self._log(f"Dienst {thema} ist außerhalb des Raumfilters")
|
||||
skipped_outside += 1
|
||||
reason = "Keine Objekte innerhalb des Raumfilters"
|
||||
row_stats.append({
|
||||
"dienst": thema,
|
||||
"provider": provider,
|
||||
@@ -457,7 +561,7 @@ class TabALogic:
|
||||
"total_features": total_features,
|
||||
"filtered_features": 0,
|
||||
"status": "außerhalb",
|
||||
"raumfilter": raumfilter_name,
|
||||
"reason": reason,
|
||||
})
|
||||
continue
|
||||
|
||||
@@ -473,7 +577,7 @@ class TabALogic:
|
||||
"total_features": total_features,
|
||||
"filtered_features": filtered_features,
|
||||
"status": "geladen",
|
||||
"raumfilter": raumfilter_name,
|
||||
"reason": "geladen",
|
||||
})
|
||||
layer_call_status[thema] = "geladen"
|
||||
self._log(f"[DEBUG] Dienst geladen: thema='{thema}', provider='{provider}', filtered_features={filtered_features}")
|
||||
@@ -671,75 +775,118 @@ class TabALogic:
|
||||
self._log(f"[DEBUG] Fehler beim Erzeugen lokaler Featureschicht für {thema}: {exc}")
|
||||
return None
|
||||
|
||||
def _write_markdown_log(
|
||||
def _write_html_log(
|
||||
self,
|
||||
final_pfad: str,
|
||||
source_dict: DataDict,
|
||||
pipeline_context: Dict[str, Any],
|
||||
load_summary: Dict[str, Any],
|
||||
) -> None:
|
||||
"""Schreibt den Pipeline-Log (Markdown)."""
|
||||
"""Schreibt den Pipeline-Log als HTML-Datei."""
|
||||
lines = [
|
||||
"# Plan41 Fachdaten-Ladevorgang",
|
||||
"",
|
||||
f"**Datum**: {datetime.datetime.now().isoformat()}",
|
||||
f"**Verfahrens-DB**: {final_pfad or 'temporär'}",
|
||||
f"**Linkliste**: {pipeline_context.get('linkliste')}",
|
||||
"",
|
||||
"## Zusammenfassung",
|
||||
"",
|
||||
f"- **Zeilen gesamt**: {load_summary.get('row_count', 0)}",
|
||||
f"- **Geladene Dienste**: {load_summary.get('loaded_count', 0)}",
|
||||
f"- **Außerhalb Raumfilter**: {load_summary.get('skipped_outside', 0)}",
|
||||
f"- **Abgebrochen**: {load_summary.get('aborted', False)}",
|
||||
f"- **Raumfilter**: {load_summary.get('raumfilter_name', 'unbekannt')}",
|
||||
f"- **Raumfilter-Typ**: {pipeline_context.get('raumfilter_name', 'unbekannt')}",
|
||||
"",
|
||||
"## Dienstliste",
|
||||
"",
|
||||
"| Dienst | Provider | Linkadresse | Aufrufstatus | Ergebnisstatus |",
|
||||
"|---|---|---|---|---|",
|
||||
"<!doctype html>",
|
||||
"<html lang='de'>",
|
||||
"<head>",
|
||||
" <meta charset='utf-8'>",
|
||||
" <title>Plan41 Fachdaten-Ladevorgang</title>",
|
||||
" <style>",
|
||||
" body { font-family: Arial, sans-serif; margin: 20px; color: #222; }",
|
||||
" h1, h2 { margin-bottom: 8px; }",
|
||||
" .meta p { margin: 4px 0; }",
|
||||
" table { border-collapse: collapse; width: 100%; margin: 12px 0 24px; }",
|
||||
" th, td { border: 1px solid #ccc; padding: 6px 8px; text-align: left; vertical-align: top; }",
|
||||
" th { background: #f2f2f2; }",
|
||||
" .ok { color: #1b5e20; font-weight: 600; }",
|
||||
" .warn { color: #8d6e00; font-weight: 600; }",
|
||||
" .err { color: #b71c1c; font-weight: 600; }",
|
||||
" </style>",
|
||||
"</head>",
|
||||
"<body>",
|
||||
"<h1>Plan41 Fachdaten-Ladevorgang</h1>",
|
||||
"<div class='meta'>",
|
||||
f" <p><strong>Datum:</strong> {datetime.datetime.now().isoformat()}</p>",
|
||||
f" <p><strong>Verfahrens-DB:</strong> {final_pfad or 'temporär'}</p>",
|
||||
f" <p><strong>Linkliste:</strong> {pipeline_context.get('linkliste')}</p>",
|
||||
f" <p><strong>Raumfilter:</strong> {load_summary.get('raumfilter_name', 'unbekannt')}</p>",
|
||||
"</div>",
|
||||
"<h2>Zusammenfassung</h2>",
|
||||
"<ul>",
|
||||
f" <li>Zeilen gesamt: {load_summary.get('row_count', 0)}</li>",
|
||||
f" <li>Geladene Dienste: {load_summary.get('loaded_count', 0)}</li>",
|
||||
f" <li>Außerhalb Raumfilter: {load_summary.get('skipped_outside', 0)}</li>",
|
||||
f" <li>Abgebrochen: {load_summary.get('aborted', False)}</li>",
|
||||
"</ul>",
|
||||
"<h2>Dienstliste</h2>",
|
||||
"<table>",
|
||||
"<thead><tr><th>Dienst</th><th>Provider</th><th>Linkadresse</th><th>Aufrufstatus</th></tr></thead>",
|
||||
"<tbody>",
|
||||
]
|
||||
|
||||
status_by_dienst = {
|
||||
str(stat.get("dienst", "")): str(stat.get("status", "n/a"))
|
||||
for stat in load_summary.get("row_stats", [])
|
||||
}
|
||||
aufrufstatus_by_dienst = {
|
||||
str(key): str(value)
|
||||
for key, value in (load_summary.get("layer_call_status", {}) or {}).items()
|
||||
}
|
||||
aufrufstatus_labels = {
|
||||
"layeraufruf_start": "Layer-Aufruf gestartet",
|
||||
"layeraufruf_ok": "Layer-Aufruf erfolgreich",
|
||||
"geladen": "Geladen",
|
||||
"layer_nicht_ladbar": "Nicht ladbar",
|
||||
"raumfilter_ausserhalb": "Außerhalb Raumfilter",
|
||||
"abbruch_vor_layeraufruf": "Abbruch vor Layer-Aufruf",
|
||||
"abbruch_nach_layeraufruf": "Abbruch nach Layer-Aufruf",
|
||||
"abbruch_nach_raumfilter": "Abbruch nach Raumfilter",
|
||||
"nicht_aufgerufen": "Nicht aufgerufen",
|
||||
}
|
||||
status_labels = {
|
||||
"geladen": "Geladen",
|
||||
"außerhalb": "Außerhalb Raumfilter",
|
||||
"layer_nicht_ladbar": "Nicht ladbar",
|
||||
}
|
||||
|
||||
for row in source_dict.get('rows', []):
|
||||
dienst = row.get('Inhalt') or row.get('ident') or ''
|
||||
provider = row.get('Provider') or ''
|
||||
link = row.get('Link') or ''
|
||||
aufrufstatus = aufrufstatus_by_dienst.get(str(dienst), "nicht_aufgerufen")
|
||||
ergebnisstatus = status_by_dienst.get(str(dienst), "n/a")
|
||||
lines.append(f"| {dienst} | {provider} | {link} | {aufrufstatus} | {ergebnisstatus} |")
|
||||
aufrufstatus_text = aufrufstatus_labels.get(str(aufrufstatus), str(aufrufstatus))
|
||||
lines.append(
|
||||
f"<tr><td>{html.escape(str(dienst))}</td><td>{html.escape(str(provider))}</td><td>{html.escape(str(link))}</td><td>{html.escape(str(aufrufstatus_text))}</td></tr>"
|
||||
)
|
||||
|
||||
lines.extend([
|
||||
"",
|
||||
"## Raumfilter-Statistik",
|
||||
"",
|
||||
"| Dienst | Provider | Linkadresse | Datenabruf-Objekte | Gesamt-Objekte | Gefilterte Objekte | Raumfilter | Status |",
|
||||
"|---|---|---|---|---|---|---|---|",
|
||||
"</tbody>",
|
||||
"</table>",
|
||||
"<h2>Raumfilter-Statistik</h2>",
|
||||
"<table>",
|
||||
"<thead><tr><th>Dienst</th><th>Datenabruf-Objekte</th><th>Gesamt-Objekte</th><th>Gefilterte Objekte</th><th>Status</th></tr></thead>",
|
||||
"<tbody>",
|
||||
])
|
||||
|
||||
for stat in load_summary.get('row_stats', []):
|
||||
status = str(stat.get('status', 'n/a'))
|
||||
status_label = status_labels.get(status, status)
|
||||
reason = str(stat.get('reason', '') or '')
|
||||
status_text = status_label if not reason else f"{status_label}: {reason}"
|
||||
lines.append(
|
||||
f"| {stat.get('dienst', '')} | {stat.get('provider', '')} | {stat.get('link', '')} | {stat.get('datenabruf_features', 'n/a')} | {stat.get('total_features', 'n/a')} | {stat.get('filtered_features', 'n/a')} | {stat.get('raumfilter', '')} | {stat.get('status', 'n/a')} |"
|
||||
f"<tr><td>{html.escape(str(stat.get('dienst', '')))}</td><td>{html.escape(str(stat.get('datenabruf_features', 'n/a')))}</td><td>{html.escape(str(stat.get('total_features', 'n/a')))}</td><td>{html.escape(str(stat.get('filtered_features', 'n/a')))}</td><td>{html.escape(status_text)}</td></tr>"
|
||||
)
|
||||
|
||||
markdown = "\n".join(lines)
|
||||
lines.extend([
|
||||
"</tbody>",
|
||||
"</table>",
|
||||
"</body>",
|
||||
"</html>",
|
||||
])
|
||||
|
||||
html_text = "\n".join(lines)
|
||||
|
||||
if final_pfad:
|
||||
log_dir = os.path.dirname(final_pfad)
|
||||
os.makedirs(log_dir, exist_ok=True)
|
||||
log_file = os.path.join(log_dir, "plan41_lade_log.md")
|
||||
log_file = os.path.join(log_dir, "plan41_lade_log.html")
|
||||
try:
|
||||
with open(log_file, "w", encoding="utf-8") as fh:
|
||||
fh.write(markdown)
|
||||
fh.write(html_text)
|
||||
|
||||
self.pruefmanager.verarbeite(
|
||||
pruef_ergebnis(
|
||||
@@ -754,15 +901,33 @@ class TabALogic:
|
||||
self.pruefmanager.verarbeite(
|
||||
pruef_ergebnis(
|
||||
ok=False,
|
||||
meldung=f"Fehler beim Schreiben des Logle (md): {exc}",
|
||||
meldung=f"Fehler beim Schreiben des Logs (html): {exc}",
|
||||
aktion="log_schreiben_fehlgeschlagen",
|
||||
kontext={"error": str(exc)},
|
||||
)
|
||||
)
|
||||
warning("Lade-Log", f"Konnte Datei nicht schreiben: {exc}", duration=10)
|
||||
else:
|
||||
# temporärer Modus: nur anzeigen
|
||||
info("Lade-Log (temporär)", markdown, duration=20)
|
||||
try:
|
||||
tmp_dir = os.path.join(tempfile.gettempdir(), "sn_plan41")
|
||||
os.makedirs(tmp_dir, exist_ok=True)
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
log_file = os.path.join(tmp_dir, f"plan41_lade_log_{timestamp}.html")
|
||||
|
||||
with open(log_file, "w", encoding="utf-8") as fh:
|
||||
fh.write(html_text)
|
||||
|
||||
self._log(f"Lade-Log (temporär) gespeichert: {log_file}")
|
||||
|
||||
if hasattr(os, "startfile"):
|
||||
try:
|
||||
os.startfile(log_file)
|
||||
except Exception as exc:
|
||||
self._log(f"Konnte temporäre Log-Datei nicht öffnen: {exc}")
|
||||
|
||||
info("Lade-Log (temporär)", f"Lade-Protokoll gespeichert: {log_file}", duration=20)
|
||||
except Exception as exc:
|
||||
warning("Lade-Log", f"Konnte temporäre Log-Datei nicht schreiben: {exc}", duration=10)
|
||||
|
||||
|
||||
def _clone_layer_with_extent(self, layer: QgsVectorLayer, extent, thema: str) -> QgsVectorLayer | None:
|
||||
@@ -875,15 +1040,18 @@ class TabALogic:
|
||||
|
||||
if not layer_id:
|
||||
self._log("❌ Keine Layer-ID gespeichert")
|
||||
self._zeige_verfahrensgebiet_hinweis()
|
||||
return None
|
||||
|
||||
layer = QgsProject.instance().mapLayer(layer_id)
|
||||
if not layer:
|
||||
self._log("❌ Layer-ID existiert nicht im Projekt")
|
||||
self._zeige_verfahrensgebiet_hinweis()
|
||||
return None
|
||||
|
||||
if not self.is_valid_verfahrensgebiet_layer(layer):
|
||||
self._log("❌ Layer ist kein gültiger Vektorlayer")
|
||||
self._zeige_verfahrensgebiet_hinweis()
|
||||
return None
|
||||
|
||||
self._log(f"Verfahrensgebiet-Layer OK: '{layer.name()}'")
|
||||
|
||||
+366
-51
@@ -9,7 +9,9 @@ from typing import Optional
|
||||
from sn_basis.functions.qt_wrapper import (
|
||||
QWidget,
|
||||
QVBoxLayout,
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
QLineEdit,
|
||||
QPushButton,
|
||||
QToolButton,
|
||||
QFileDialog,
|
||||
@@ -32,7 +34,8 @@ from sn_basis.modules.DataGrabber import DataGrabber
|
||||
from sn_basis.modules.Dateipruefer import Dateipruefer
|
||||
from sn_plan41.ui.tab_a_logic import TabALogic
|
||||
from sn_basis.modules.linkpruefer import Linkpruefer
|
||||
from sn_basis.modules.stilpruefer import Stilpruefer
|
||||
from sn_basis.modules.stilpruefer import Stilpruefer
|
||||
from sn_plan41.modules.vln_api_logic import VlnApiLogic
|
||||
|
||||
# Konstanten
|
||||
RAUMFILTER_VAR = "Raumfilter"
|
||||
@@ -78,7 +81,11 @@ class TabA(QWidget):
|
||||
|
||||
# UI-Referenzen
|
||||
self._raumfilter_combo: Optional[QComboBox] = None
|
||||
|
||||
|
||||
# VLN-API
|
||||
self.vln_logic: Optional[VlnApiLogic] = None
|
||||
self._vln_restoring: bool = False
|
||||
|
||||
self._build_ui()
|
||||
self._restore_state()
|
||||
|
||||
@@ -92,14 +99,17 @@ class TabA(QWidget):
|
||||
self.pruefmanager = pruefmanager
|
||||
self.data_grabber = data_grabber
|
||||
self.logic = TabALogic(
|
||||
pruefmanager=self.pruefmanager,
|
||||
link_pruefer=Linkpruefer(),
|
||||
stil_pruefer=Stilpruefer(),
|
||||
)
|
||||
|
||||
# DataGrabber in die Logik injizieren
|
||||
pruefmanager=self.pruefmanager,
|
||||
link_pruefer=Linkpruefer(),
|
||||
stil_pruefer=Stilpruefer(),
|
||||
)
|
||||
self.logic.data_grabber = self.data_grabber
|
||||
|
||||
# VLN-API-Logik initialisieren
|
||||
self.vln_logic = VlnApiLogic(self.pruefmanager)
|
||||
self._update_vln_ui_state()
|
||||
self._restore_vln_state()
|
||||
|
||||
def _build_ui(self) -> None:
|
||||
"""Erstellt die komplette UI-Hierarchie mit allen Gruppen."""
|
||||
main_layout = QVBoxLayout()
|
||||
@@ -166,16 +176,7 @@ class TabA(QWidget):
|
||||
self.optional_content.setVisible(False)
|
||||
main_layout.addWidget(self.optional_content)
|
||||
|
||||
# === LAYER-AUSWAHL + RAUMFILTER ===
|
||||
layer_label = QLabel("Verfahrensgebiet-Layer auswählen")
|
||||
layer_label.setStyleSheet("font-weight: bold; margin-top: 6px;")
|
||||
main_layout.addWidget(layer_label)
|
||||
|
||||
self.layer_combo = QgsMapLayerComboBox()
|
||||
self.layer_combo.setFilters(QgsMapLayerProxyModel.VectorLayer)
|
||||
self.layer_combo.layerChanged.connect(self._on_layer_changed)
|
||||
main_layout.addWidget(self.layer_combo)
|
||||
|
||||
# === RAUMFILTER ===
|
||||
main_layout.addWidget(QLabel("Raumfilter"))
|
||||
self._raumfilter_combo = QComboBox(self)
|
||||
self._raumfilter_combo.setToolTip("Wählt die räumliche Bezugsfläche für die Datenextraktion.")
|
||||
@@ -189,7 +190,84 @@ class TabA(QWidget):
|
||||
self.btn_pipeline.clicked.connect(self._on_load_fachdaten)
|
||||
main_layout.addWidget(self.btn_pipeline)
|
||||
|
||||
|
||||
# === VLN API / PLAN 41 ===
|
||||
self._vln_group_button = QToolButton()
|
||||
self._vln_group_button.setText("VLN API / Plan 41")
|
||||
self._vln_group_button.setCheckable(True)
|
||||
self._vln_group_button.setChecked(False)
|
||||
self._vln_group_button.setToolButtonStyle(ToolButtonTextBesideIcon)
|
||||
self._vln_group_button.setArrowType(ArrowRight)
|
||||
self._vln_group_button.setStyleSheet("font-weight: bold; margin-top: 8px;")
|
||||
self._vln_group_button.toggled.connect(self._toggle_vln_group)
|
||||
main_layout.addWidget(self._vln_group_button)
|
||||
|
||||
self._vln_group_content = QWidget()
|
||||
self._vln_group_content.setSizePolicy(SizePolicyPreferred, SizePolicyMaximum)
|
||||
vln_layout = QVBoxLayout()
|
||||
vln_layout.setSpacing(4)
|
||||
vln_layout.setContentsMargins(10, 4, 4, 8)
|
||||
|
||||
# Status
|
||||
self._vln_status_label = QLabel("Nicht angemeldet")
|
||||
self._vln_status_label.setStyleSheet("color: gray; font-style: italic;")
|
||||
vln_layout.addWidget(self._vln_status_label)
|
||||
|
||||
# E-Mail und Passwort
|
||||
vln_layout.addWidget(QLabel("E-Mail:"))
|
||||
self._vln_mail_edit = QLineEdit()
|
||||
self._vln_mail_edit.setPlaceholderText("mail@beispiel.de")
|
||||
vln_layout.addWidget(self._vln_mail_edit)
|
||||
|
||||
vln_layout.addWidget(QLabel("Passwort:"))
|
||||
self._vln_pass_edit = QLineEdit()
|
||||
try:
|
||||
self._vln_pass_edit.setEchoMode(QLineEdit.EchoMode.Password)
|
||||
except AttributeError:
|
||||
self._vln_pass_edit.setEchoMode(QLineEdit.Password)
|
||||
vln_layout.addWidget(self._vln_pass_edit)
|
||||
|
||||
# Login / Logout Buttons
|
||||
btn_row = QHBoxLayout()
|
||||
self._btn_vln_login = QPushButton("Anmelden")
|
||||
self._btn_vln_login.clicked.connect(self._on_vln_login)
|
||||
self._btn_vln_logout = QPushButton("Abmelden")
|
||||
self._btn_vln_logout.clicked.connect(self._on_vln_logout)
|
||||
btn_row.addWidget(self._btn_vln_login)
|
||||
btn_row.addWidget(self._btn_vln_logout)
|
||||
vln_layout.addLayout(btn_row)
|
||||
|
||||
# Verfahren
|
||||
vln_layout.addWidget(QLabel("Verfahren:"))
|
||||
self._vln_verfahren_combo = QComboBox()
|
||||
self._vln_verfahren_combo.setToolTip("Verfahren (Teilnehmergemeinschaft) wählen")
|
||||
self._vln_verfahren_combo.setEnabled(False)
|
||||
self._vln_verfahren_combo.currentIndexChanged.connect(
|
||||
self._on_vln_verfahren_changed
|
||||
)
|
||||
vln_layout.addWidget(self._vln_verfahren_combo)
|
||||
|
||||
# Plan 41 laden
|
||||
self._btn_p41_laden = QPushButton("Plan 41 (Wege- und Gewässerplan) laden")
|
||||
self._btn_p41_laden.setToolTip(
|
||||
"Lädt Flächen- und Linienlayer für das gewählte Verfahren vom Server"
|
||||
)
|
||||
self._btn_p41_laden.setEnabled(False)
|
||||
self._btn_p41_laden.clicked.connect(self._on_p41_laden)
|
||||
vln_layout.addWidget(self._btn_p41_laden)
|
||||
|
||||
# Upload
|
||||
self._btn_upload = QPushButton("Aktiven Layer hochladen")
|
||||
self._btn_upload.setToolTip(
|
||||
"Lädt alle Plan-41-Layer des aktiven Verfahrens zum Server hoch"
|
||||
)
|
||||
self._btn_upload.setEnabled(False)
|
||||
self._btn_upload.clicked.connect(self._on_upload_active)
|
||||
vln_layout.addWidget(self._btn_upload)
|
||||
|
||||
self._vln_group_content.setLayout(vln_layout)
|
||||
self._vln_group_content.setVisible(False)
|
||||
main_layout.addWidget(self._vln_group_content)
|
||||
|
||||
main_layout.addStretch(1)
|
||||
self.setLayout(main_layout)
|
||||
|
||||
@@ -213,21 +291,281 @@ class TabA(QWidget):
|
||||
self.lokale_linkliste = link
|
||||
except Exception:
|
||||
pass
|
||||
# Raumfilter (schon im _build_ui behandelt)
|
||||
|
||||
# Layer
|
||||
def _restore_vln_state(self) -> None:
|
||||
"""Stellt die zuletzt gewählte VKZ aus der Projektdatei wieder her."""
|
||||
if self.vln_logic is None or not self.vln_logic.is_authenticated:
|
||||
return
|
||||
try:
|
||||
layer_id = get_variable("tab_a_layer_id", scope="project")
|
||||
if layer_id:
|
||||
layer = QgsProject.instance().mapLayer(layer_id)
|
||||
if layer and self.layer_combo:
|
||||
self.layer_combo.setLayer(layer)
|
||||
self._pufferlayer = layer
|
||||
self._populate_verfahren_combo(restore_vkz=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Raumfilter (schon im _build_ui behandelt)
|
||||
|
||||
# === UI CALLBACKS ===
|
||||
|
||||
def _toggle_vln_group(self, checked: bool) -> None:
|
||||
self._vln_group_button.setArrowType(ArrowDown if checked else ArrowRight)
|
||||
self._vln_group_content.setVisible(checked)
|
||||
|
||||
def _update_vln_ui_state(self) -> None:
|
||||
"""Passt alle VLN-Controls an den aktuellen Authentifizierungsstatus an."""
|
||||
if self.vln_logic is None:
|
||||
authenticated = False
|
||||
available = False
|
||||
else:
|
||||
authenticated = self.vln_logic.is_authenticated
|
||||
available = self.vln_logic.is_available()
|
||||
|
||||
if not available:
|
||||
self._vln_status_label.setText(
|
||||
"Plugin 'vln_karten' nicht installiert"
|
||||
)
|
||||
self._vln_status_label.setStyleSheet("color: red; font-style: italic;")
|
||||
self._btn_vln_login.setEnabled(False)
|
||||
elif authenticated:
|
||||
mail = (self.vln_logic.mail or "API-Key") if self.vln_logic else ""
|
||||
self._vln_status_label.setText("Angemeldet: %s" % mail)
|
||||
self._vln_status_label.setStyleSheet(
|
||||
"color: green; font-style: italic;"
|
||||
)
|
||||
self._btn_vln_login.setEnabled(False)
|
||||
else:
|
||||
self._vln_status_label.setText("Nicht angemeldet")
|
||||
self._vln_status_label.setStyleSheet("color: gray; font-style: italic;")
|
||||
self._btn_vln_login.setEnabled(True)
|
||||
|
||||
self._btn_vln_logout.setEnabled(authenticated)
|
||||
self._vln_verfahren_combo.setEnabled(authenticated)
|
||||
vkz_chosen = (
|
||||
authenticated
|
||||
and self._vln_verfahren_combo.currentData() is not None
|
||||
)
|
||||
self._btn_p41_laden.setEnabled(vkz_chosen)
|
||||
self._btn_upload.setEnabled(authenticated)
|
||||
|
||||
def _populate_verfahren_combo(self, restore_vkz: bool = False) -> None:
|
||||
"""Füllt die Verfahren-Combo und wählt ggf. die gespeicherte VKZ."""
|
||||
if self.vln_logic is None:
|
||||
return
|
||||
verfahren = self.vln_logic.get_verfahren()
|
||||
self._vln_restoring = True
|
||||
self._vln_verfahren_combo.clear()
|
||||
self._vln_verfahren_combo.addItem("— Verfahren wählen —", None)
|
||||
for v in verfahren:
|
||||
label = (
|
||||
"%s — %s" % (v["vkz"], v["name"])
|
||||
if v["name"]
|
||||
else v["vkz"]
|
||||
)
|
||||
self._vln_verfahren_combo.addItem(label, v["vkz"])
|
||||
self._vln_restoring = False
|
||||
|
||||
if restore_vkz:
|
||||
stored_vkz = self.vln_logic.load_stored_vkz()
|
||||
if stored_vkz:
|
||||
idx = self._vln_verfahren_combo.findData(stored_vkz)
|
||||
if idx >= 0:
|
||||
self._vln_verfahren_combo.setCurrentIndex(idx)
|
||||
|
||||
self._vln_verfahren_combo.setEnabled(True)
|
||||
self._update_vln_ui_state()
|
||||
|
||||
def _on_vln_login(self) -> None:
|
||||
"""Führt den API-Login durch."""
|
||||
if self.vln_logic is None:
|
||||
return
|
||||
mail = self._vln_mail_edit.text().strip()
|
||||
password = self._vln_pass_edit.text()
|
||||
if not mail or not password:
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Anmeldung",
|
||||
"Bitte E-Mail-Adresse und Passwort eingeben.",
|
||||
)
|
||||
return
|
||||
try:
|
||||
self.vln_logic.login(mail, password)
|
||||
except Exception as exc:
|
||||
QMessageBox.warning(self, "Anmeldung fehlgeschlagen", str(exc))
|
||||
return
|
||||
|
||||
self._vln_pass_edit.clear()
|
||||
try:
|
||||
self._populate_verfahren_combo(restore_vkz=True)
|
||||
except Exception as exc:
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Verfahrensliste",
|
||||
"Anmeldung erfolgreich, aber Verfahrensliste konnte nicht "
|
||||
"geladen werden: %s" % exc,
|
||||
)
|
||||
self._update_vln_ui_state()
|
||||
|
||||
def _on_vln_logout(self) -> None:
|
||||
"""Meldet den Benutzer lokal ab."""
|
||||
if self.vln_logic is None:
|
||||
return
|
||||
self.vln_logic.logout()
|
||||
self._vln_restoring = True
|
||||
self._vln_verfahren_combo.clear()
|
||||
self._vln_verfahren_combo.setEnabled(False)
|
||||
self._vln_restoring = False
|
||||
self._update_vln_ui_state()
|
||||
|
||||
def _on_vln_verfahren_changed(self, _index: int) -> None:
|
||||
"""Persistiert die gewählte VKZ."""
|
||||
if self._vln_restoring or self.vln_logic is None:
|
||||
return
|
||||
vkz = self._vln_verfahren_combo.currentData()
|
||||
self.vln_logic.save_vkz(vkz)
|
||||
self._update_vln_ui_state()
|
||||
|
||||
def _on_p41_laden(self) -> None:
|
||||
"""Lädt den Plan-41-Datensatz für die gewählte VKZ."""
|
||||
if self.vln_logic is None:
|
||||
return
|
||||
vkz = self._vln_verfahren_combo.currentData()
|
||||
if not vkz:
|
||||
QMessageBox.warning(
|
||||
self, "Plan 41 laden", "Bitte zuerst ein Verfahren wählen."
|
||||
)
|
||||
return
|
||||
|
||||
# Bereits geladene Layer prüfen
|
||||
existing = self.vln_logic.get_p41_layers(vkz)
|
||||
if existing:
|
||||
try:
|
||||
answer = QMessageBox.question(
|
||||
self,
|
||||
"Layer ersetzen",
|
||||
"Plan 41 für VKZ %s ist bereits geladen.\n"
|
||||
"Beim Neuladen werden die bestehenden Layer ersetzt. Fortfahren?"
|
||||
% vkz,
|
||||
)
|
||||
# Qt6: StandardButton.Yes, Qt5: QMessageBox.Yes
|
||||
yes = getattr(
|
||||
getattr(QMessageBox, "StandardButton", QMessageBox),
|
||||
"Yes",
|
||||
QMessageBox.Yes if hasattr(QMessageBox, "Yes") else None,
|
||||
)
|
||||
if answer != yes:
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
self.vln_logic.remove_p41_layers(vkz)
|
||||
|
||||
try:
|
||||
layers = self.vln_logic.load_p41(vkz)
|
||||
except Exception as exc:
|
||||
# AuthError: Sitzung abgelaufen
|
||||
try:
|
||||
from sn_plan41.modules.vln_api_client import AuthError as _AuthError
|
||||
if isinstance(exc, _AuthError):
|
||||
self.vln_logic.handle_session_expired()
|
||||
self._on_vln_logout()
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Sitzung abgelaufen",
|
||||
"Der API-Key ist nicht mehr gültig — bitte neu anmelden.",
|
||||
)
|
||||
return
|
||||
except ImportError:
|
||||
pass
|
||||
QMessageBox.warning(self, "Laden fehlgeschlagen", str(exc))
|
||||
return
|
||||
|
||||
total = sum(l.featureCount() for l in layers)
|
||||
detail = ", ".join(
|
||||
"%s: %d" % (l.name(), l.featureCount()) for l in layers
|
||||
)
|
||||
if total == 0:
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Plan 41 laden",
|
||||
"Keine Objekte vorhanden — ein leerer Layer wurde angelegt.",
|
||||
)
|
||||
else:
|
||||
try:
|
||||
from sn_basis.functions.message_wrapper import info
|
||||
info(
|
||||
"Plan 41 geladen",
|
||||
"%d Layer geladen (%s)." % (len(layers), detail),
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _on_upload_active(self) -> None:
|
||||
"""Lädt den aktiven Layer (und Geschwister-Layer) zum Server hoch."""
|
||||
if self.vln_logic is None:
|
||||
return
|
||||
|
||||
# Zusammenfassung für Bestaetigungs-Dialog ermitteln
|
||||
try:
|
||||
from sn_basis.functions.qgisui_wrapper import iface as _iface
|
||||
active_layer = _iface.activeLayer() if _iface else None
|
||||
except Exception:
|
||||
active_layer = None
|
||||
|
||||
summary = self.vln_logic.upload_summary(active_layer)
|
||||
if summary is None:
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Hochladen nicht möglich",
|
||||
"Der aktive Layer wurde nicht über 'vln_karten' geladen.",
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
answer = QMessageBox.question(
|
||||
self,
|
||||
"Zum Server hochladen",
|
||||
"%s für VKZ %s übertragen?\n\n%s\n\n"
|
||||
"%d Objekte; der bisherige Bestand dieser VKZ wird ersetzt."
|
||||
% (
|
||||
summary["dataset_label"],
|
||||
summary["vkz"],
|
||||
summary["listing"],
|
||||
summary["total"],
|
||||
),
|
||||
)
|
||||
yes = getattr(
|
||||
getattr(QMessageBox, "StandardButton", QMessageBox),
|
||||
"Yes",
|
||||
QMessageBox.Yes if hasattr(QMessageBox, "Yes") else None,
|
||||
)
|
||||
if answer != yes:
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
|
||||
try:
|
||||
success, message = self.vln_logic.upload_active_layer(active_layer)
|
||||
except Exception as exc:
|
||||
try:
|
||||
from sn_plan41.modules.vln_api_client import AuthError as _AuthError
|
||||
if isinstance(exc, _AuthError):
|
||||
self.vln_logic.handle_session_expired()
|
||||
self._on_vln_logout()
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Sitzung abgelaufen",
|
||||
"Der API-Key ist nicht mehr gültig — bitte neu anmelden.",
|
||||
)
|
||||
return
|
||||
except ImportError:
|
||||
pass
|
||||
QMessageBox.warning(self, "Hochladen fehlgeschlagen", str(exc))
|
||||
return
|
||||
|
||||
if success:
|
||||
try:
|
||||
from sn_basis.functions.message_wrapper import info
|
||||
info("Upload erfolgreich", message)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
QMessageBox.warning(self, "Hochladen fehlgeschlagen", message)
|
||||
def _toggle_group(self, checked: bool) -> None:
|
||||
"""Zeigt/verbirgt Verfahrens-DB-Gruppe."""
|
||||
self.group_button.setArrowType(ArrowDown if checked else ArrowRight)
|
||||
@@ -249,20 +587,6 @@ class TabA(QWidget):
|
||||
self.lokale_linkliste = path
|
||||
set_variable("tab_a_linkliste", path, scope="project")
|
||||
|
||||
def _on_layer_changed(self, layer) -> None:
|
||||
"""Persistiert Layer-Auswahl und registriert Verfahrensgebiet."""
|
||||
self._pufferlayer = layer
|
||||
|
||||
if not layer:
|
||||
return
|
||||
|
||||
# UI-State speichern
|
||||
set_variable("tab_a_layer_id", layer.id(), scope="project")
|
||||
|
||||
# 🔹 NEU: Verfahrensgebiet explizit registrieren
|
||||
if self.logic:
|
||||
self.logic.save_verfahrensgebiet_layer(layer)
|
||||
|
||||
|
||||
def _on_raumfilter_changed(self, value: str) -> None:
|
||||
"""Persistieret Raumfilter-Auswahl."""
|
||||
@@ -296,15 +620,6 @@ class TabA(QWidget):
|
||||
source = self.file_widget.filePath()
|
||||
raumfilter = self._raumfilter_combo.currentText()
|
||||
linkliste = self.linkliste_widget.filePath()
|
||||
|
||||
if self.logic and self.layer_combo:
|
||||
layer = self.layer_combo.currentLayer()
|
||||
else:
|
||||
layer = None
|
||||
|
||||
if layer and layer.name() == "Verfahrensgebiet":
|
||||
self.logic.save_verfahrensgebiet_layer(layer)
|
||||
|
||||
if self.logic:
|
||||
try:
|
||||
self.logic._on_run_pipeline(source, linkliste, raumfilter)
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
"""sn_plan41/ui/tabs/tab_b.py – Beispiel-Tab für zusätzliche Funktionen.
|
||||
Ein Tab für zukünftige Erweiterungen.
|
||||
"""
|
||||
|
||||
from qgis.PyQt.QtWidgets import QWidget, QVBoxLayout, QLabel, QTextEdit
|
||||
|
||||
class TabB(QWidget):
|
||||
"""Beispiel-Tab für sn_plan41.
|
||||
|
||||
Attributes:
|
||||
tab_title: Anzeigetitel des Tabs ("Tab B")
|
||||
"""
|
||||
|
||||
tab_title = "Tab B"
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""Initialisiert den Tab mit Beispielinhalt.
|
||||
|
||||
Args:
|
||||
parent: Übergeordnetes Widget
|
||||
"""
|
||||
super().__init__(parent)
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(QLabel("Plugin2 – Tab B"))
|
||||
|
||||
Reference in New Issue
Block a user