Skip to content

Commit 72febb3

Browse files
committed
Allow loading QLR files with invalid sources
E.g. if the layer path has moved, we still should allow these files to be read, so that the layer path can be fixed by the user manually.
1 parent 070de69 commit 72febb3

File tree

3 files changed

+287
-4
lines changed

3 files changed

+287
-4
lines changed

src/core/qgslayerdefinition.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,10 @@ QList<QgsMapLayer *> QgsLayerDefinition::loadLayerDefinitionLayers( QDomDocument
280280
if ( !layer )
281281
continue;
282282

283-
if ( layer->readLayerXml( layerElem, context ) )
284-
{
285-
layers << layer;
286-
}
283+
// always add the layer, even if the source is invalid -- this allows users to fix the source
284+
// at a later stage and still retain all the layer properties intact
285+
layer->readLayerXml( layerElem, context );
286+
layers << layer;
287287
}
288288
return layers;
289289
}

tests/src/python/test_qgslayerdefinition.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,21 @@ def testVectorAndRaster(self):
110110
self.assertEqual(len(layers), 2)
111111
QgsProject.instance().removeAllMapLayers()
112112

113+
def testInvalidSource(self):
114+
# Load a QLR containing a vector layer with a broken path
115+
QgsProject.instance().removeAllMapLayers()
116+
layers = QgsProject.instance().mapLayers()
117+
self.assertEqual(len(layers), 0)
118+
119+
(result, errMsg) = QgsLayerDefinition.loadLayerDefinition(TEST_DATA_DIR + '/invalid_source.qlr', QgsProject.instance(), QgsProject.instance().layerTreeRoot())
120+
self.assertTrue(result)
121+
self.assertFalse(errMsg)
122+
123+
layers = QgsProject.instance().mapLayers()
124+
self.assertEqual(len(layers), 1)
125+
self.assertFalse(list(layers.values())[0].isValid())
126+
QgsProject.instance().removeAllMapLayers()
127+
113128

114129
if __name__ == '__main__':
115130
unittest.main()

tests/testdata/invalid_source.qlr

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
<!DOCTYPE qgis-layer-definition>
2+
<qlr>
3+
<layer-tree-group expanded="1" name="" checked="Qt::Checked">
4+
<customproperties/>
5+
<layer-tree-layer source="C:\temp/points.shp" expanded="1" id="points_1cff66ba_ca06_4c6d_8542_610e215f65ca" name="points" providerKey="ogr" checked="Qt::Checked">
6+
<customproperties/>
7+
</layer-tree-layer>
8+
</layer-tree-group>
9+
<maplayers>
10+
<maplayer geometry="Point" labelsEnabled="0" autoRefreshEnabled="0" styleCategories="AllStyleCategories" refreshOnNotifyEnabled="0" maxScale="0" refreshOnNotifyMessage="" simplifyLocal="1" wkbType="Point" simplifyDrawingTol="1" autoRefreshTime="0" simplifyMaxScale="1" readOnly="0" minScale="0" simplifyDrawingHints="1" simplifyAlgorithm="0" type="vector" hasScaleBasedVisibilityFlag="0">
11+
<id>points_1cff66ba_ca06_4c6d_8542_610e215f65ca</id>
12+
<datasource>C:\temp/points.shp</datasource>
13+
<keywordList>
14+
<value></value>
15+
</keywordList>
16+
<layername>points</layername>
17+
<srs>
18+
<spatialrefsys>
19+
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
20+
<srsid>3452</srsid>
21+
<srid>4326</srid>
22+
<authid>EPSG:4326</authid>
23+
<description>WGS 84</description>
24+
<projectionacronym>longlat</projectionacronym>
25+
<ellipsoidacronym>WGS84</ellipsoidacronym>
26+
<geographicflag>true</geographicflag>
27+
</spatialrefsys>
28+
</srs>
29+
<resourceMetadata>
30+
<identifier></identifier>
31+
<parentidentifier></parentidentifier>
32+
<language></language>
33+
<type></type>
34+
<title></title>
35+
<abstract></abstract>
36+
<links/>
37+
<fees></fees>
38+
<encoding></encoding>
39+
<crs>
40+
<spatialrefsys>
41+
<proj4></proj4>
42+
<srsid>0</srsid>
43+
<srid>0</srid>
44+
<authid></authid>
45+
<description></description>
46+
<projectionacronym></projectionacronym>
47+
<ellipsoidacronym></ellipsoidacronym>
48+
<geographicflag>false</geographicflag>
49+
</spatialrefsys>
50+
</crs>
51+
<extent/>
52+
</resourceMetadata>
53+
<provider encoding="UTF-8">ogr</provider>
54+
<vectorjoins/>
55+
<layerDependencies/>
56+
<dataDependencies/>
57+
<legend type="default-vector"/>
58+
<expressionfields/>
59+
<map-layer-style-manager current="default">
60+
<map-layer-style name="default"/>
61+
</map-layer-style-manager>
62+
<auxiliaryLayer/>
63+
<flags>
64+
<Identifiable>1</Identifiable>
65+
<Removable>1</Removable>
66+
<Searchable>1</Searchable>
67+
</flags>
68+
<renderer-v2 symbollevels="0" graduatedMethod="GraduatedColor" attr="Importance" enableorderby="0" type="graduatedSymbol" forceraster="0">
69+
<ranges>
70+
<range render="true" upper="1.000000000000000" symbol="0" label="1.000" lower="1.000000000000000"/>
71+
<range render="true" upper="3.000000000000000" symbol="1" label="1.001 - 3.000" lower="1.001000000000000"/>
72+
<range render="true" upper="4.000000000000000" symbol="2" label="3.001 - 4.000" lower="3.001000000000000"/>
73+
<range render="true" upper="10.000000000000000" symbol="3" label="4.001 - 10.000" lower="4.001000000000000"/>
74+
<range render="true" upper="20.000000000000000" symbol="4" label="10.001 - 20.000" lower="10.000999999999999"/>
75+
</ranges>
76+
<symbols>
77+
<symbol alpha="1" force_rhr="0" clip_to_extent="1" type="marker" name="0">
78+
<layer enabled="1" pass="0" class="SimpleMarker" locked="0">
79+
<prop k="angle" v="0"/>
80+
<prop k="color" v="255,255,127,255"/>
81+
<prop k="horizontal_anchor_point" v="1"/>
82+
<prop k="joinstyle" v="bevel"/>
83+
<prop k="name" v="circle"/>
84+
<prop k="offset" v="0,0"/>
85+
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
86+
<prop k="offset_unit" v="Point"/>
87+
<prop k="outline_color" v="0,0,0,255"/>
88+
<prop k="outline_style" v="solid"/>
89+
<prop k="outline_width" v="0.5"/>
90+
<prop k="outline_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
91+
<prop k="outline_width_unit" v="Point"/>
92+
<prop k="scale_method" v="diameter"/>
93+
<prop k="size" v="4"/>
94+
<prop k="size_map_unit_scale" v="3x:0,0,0,0,0,0"/>
95+
<prop k="size_unit" v="Point"/>
96+
<prop k="vertical_anchor_point" v="1"/>
97+
<data_defined_properties>
98+
<Option type="Map">
99+
<Option value="" type="QString" name="name"/>
100+
<Option name="properties"/>
101+
<Option value="collection" type="QString" name="type"/>
102+
</Option>
103+
</data_defined_properties>
104+
</layer>
105+
</symbol>
106+
<symbol alpha="1" force_rhr="0" clip_to_extent="1" type="marker" name="1">
107+
<layer enabled="1" pass="0" class="SimpleMarker" locked="0">
108+
<prop k="angle" v="0"/>
109+
<prop k="color" v="250,209,85,255"/>
110+
<prop k="horizontal_anchor_point" v="1"/>
111+
<prop k="joinstyle" v="bevel"/>
112+
<prop k="name" v="circle"/>
113+
<prop k="offset" v="0,0"/>
114+
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
115+
<prop k="offset_unit" v="Point"/>
116+
<prop k="outline_color" v="0,0,0,255"/>
117+
<prop k="outline_style" v="solid"/>
118+
<prop k="outline_width" v="0.5"/>
119+
<prop k="outline_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
120+
<prop k="outline_width_unit" v="Point"/>
121+
<prop k="scale_method" v="diameter"/>
122+
<prop k="size" v="4"/>
123+
<prop k="size_map_unit_scale" v="3x:0,0,0,0,0,0"/>
124+
<prop k="size_unit" v="Point"/>
125+
<prop k="vertical_anchor_point" v="1"/>
126+
<data_defined_properties>
127+
<Option type="Map">
128+
<Option value="" type="QString" name="name"/>
129+
<Option name="properties"/>
130+
<Option value="collection" type="QString" name="type"/>
131+
</Option>
132+
</data_defined_properties>
133+
</layer>
134+
</symbol>
135+
<symbol alpha="1" force_rhr="0" clip_to_extent="1" type="marker" name="2">
136+
<layer enabled="1" pass="0" class="SimpleMarker" locked="0">
137+
<prop k="angle" v="0"/>
138+
<prop k="color" v="242,167,46,255"/>
139+
<prop k="horizontal_anchor_point" v="1"/>
140+
<prop k="joinstyle" v="bevel"/>
141+
<prop k="name" v="circle"/>
142+
<prop k="offset" v="0,0"/>
143+
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
144+
<prop k="offset_unit" v="Point"/>
145+
<prop k="outline_color" v="0,0,0,255"/>
146+
<prop k="outline_style" v="solid"/>
147+
<prop k="outline_width" v="0.5"/>
148+
<prop k="outline_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
149+
<prop k="outline_width_unit" v="Point"/>
150+
<prop k="scale_method" v="diameter"/>
151+
<prop k="size" v="4"/>
152+
<prop k="size_map_unit_scale" v="3x:0,0,0,0,0,0"/>
153+
<prop k="size_unit" v="Point"/>
154+
<prop k="vertical_anchor_point" v="1"/>
155+
<data_defined_properties>
156+
<Option type="Map">
157+
<Option value="" type="QString" name="name"/>
158+
<Option name="properties"/>
159+
<Option value="collection" type="QString" name="type"/>
160+
</Option>
161+
</data_defined_properties>
162+
</layer>
163+
</symbol>
164+
<symbol alpha="1" force_rhr="0" clip_to_extent="1" type="marker" name="3">
165+
<layer enabled="1" pass="0" class="SimpleMarker" locked="0">
166+
<prop k="angle" v="0"/>
167+
<prop k="color" v="173,83,19,255"/>
168+
<prop k="horizontal_anchor_point" v="1"/>
169+
<prop k="joinstyle" v="bevel"/>
170+
<prop k="name" v="circle"/>
171+
<prop k="offset" v="0,0"/>
172+
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
173+
<prop k="offset_unit" v="Point"/>
174+
<prop k="outline_color" v="0,0,0,255"/>
175+
<prop k="outline_style" v="solid"/>
176+
<prop k="outline_width" v="0.5"/>
177+
<prop k="outline_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
178+
<prop k="outline_width_unit" v="Point"/>
179+
<prop k="scale_method" v="diameter"/>
180+
<prop k="size" v="4"/>
181+
<prop k="size_map_unit_scale" v="3x:0,0,0,0,0,0"/>
182+
<prop k="size_unit" v="Point"/>
183+
<prop k="vertical_anchor_point" v="1"/>
184+
<data_defined_properties>
185+
<Option type="Map">
186+
<Option value="" type="QString" name="name"/>
187+
<Option name="properties"/>
188+
<Option value="collection" type="QString" name="type"/>
189+
</Option>
190+
</data_defined_properties>
191+
</layer>
192+
</symbol>
193+
<symbol alpha="1" force_rhr="0" clip_to_extent="1" type="marker" name="4">
194+
<layer enabled="1" pass="0" class="SimpleMarker" locked="0">
195+
<prop k="angle" v="0"/>
196+
<prop k="color" v="107,0,0,255"/>
197+
<prop k="horizontal_anchor_point" v="1"/>
198+
<prop k="joinstyle" v="bevel"/>
199+
<prop k="name" v="circle"/>
200+
<prop k="offset" v="0,0"/>
201+
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
202+
<prop k="offset_unit" v="Point"/>
203+
<prop k="outline_color" v="0,0,0,255"/>
204+
<prop k="outline_style" v="solid"/>
205+
<prop k="outline_width" v="0.5"/>
206+
<prop k="outline_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
207+
<prop k="outline_width_unit" v="Point"/>
208+
<prop k="scale_method" v="diameter"/>
209+
<prop k="size" v="4"/>
210+
<prop k="size_map_unit_scale" v="3x:0,0,0,0,0,0"/>
211+
<prop k="size_unit" v="Point"/>
212+
<prop k="vertical_anchor_point" v="1"/>
213+
<data_defined_properties>
214+
<Option type="Map">
215+
<Option value="" type="QString" name="name"/>
216+
<Option name="properties"/>
217+
<Option value="collection" type="QString" name="type"/>
218+
</Option>
219+
</data_defined_properties>
220+
</layer>
221+
</symbol>
222+
</symbols>
223+
<symmetricMode enabled="false" symmetryPoint="0" astride="false"/>
224+
<rotation/>
225+
<sizescale/>
226+
<labelformat trimtrailingzeroes="false" decimalplaces="4" format="%1 - %2"/>
227+
</renderer-v2>
228+
<customproperties/>
229+
<blendMode>0</blendMode>
230+
<featureBlendMode>0</featureBlendMode>
231+
<layerOpacity>1</layerOpacity>
232+
<geometryOptions removeDuplicateNodes="0" geometryPrecision="0">
233+
<activeChecks type="StringList">
234+
<Option value="" type="QString"/>
235+
</activeChecks>
236+
<checkConfiguration/>
237+
</geometryOptions>
238+
<fieldConfiguration/>
239+
<aliases/>
240+
<excludeAttributesWMS/>
241+
<excludeAttributesWFS/>
242+
<defaults/>
243+
<constraints/>
244+
<constraintExpressions/>
245+
<expressionfields/>
246+
<attributeactions/>
247+
<attributetableconfig sortExpression="" actionWidgetStyle="dropDown" sortOrder="0">
248+
<columns/>
249+
</attributetableconfig>
250+
<conditionalstyles>
251+
<rowstyles/>
252+
<fieldstyles/>
253+
</conditionalstyles>
254+
<editform tolerant="1"></editform>
255+
<editforminit/>
256+
<editforminitcodesource>0</editforminitcodesource>
257+
<editforminitfilepath></editforminitfilepath>
258+
<editforminitcode><![CDATA[]]></editforminitcode>
259+
<featformsuppress>0</featformsuppress>
260+
<editorlayout>generatedlayout</editorlayout>
261+
<editable/>
262+
<labelOnTop/>
263+
<widgets/>
264+
<previewExpression></previewExpression>
265+
<mapTip></mapTip>
266+
</maplayer>
267+
</maplayers>
268+
</qlr>

0 commit comments

Comments
 (0)