Merge pull request #3106 from boundlessgeo/wfs-t-tests-2

Wfs t tests
This commit is contained in:
Alessandro Pasotti 2016-05-25 17:46:47 +02:00
commit 0469ffc13e
20 changed files with 886 additions and 0 deletions

View File

@ -271,6 +271,7 @@ void QgsWFSProviderSQLColumnRefValidator::visit( const QgsSQLStatement::NodeColu
bool QgsWFSProvider::processSQL( const QString& sqlString, QString& errorMsg )
{
QgsDebugMsg( QString( "Processing SQL: %1" ).arg( sqlString ) );
errorMsg.clear();
QgsSQLStatement sql( sqlString );
if ( sql.hasParserError() )

View File

@ -124,4 +124,5 @@ ENDIF (WITH_APIDOC)
IF (WITH_SERVER)
ADD_PYTHON_TEST(PyQgsServer test_qgsserver.py)
ADD_PYTHON_TEST(PyQgsServerAccessControl test_qgsserver_accesscontrol.py)
ADD_PYTHON_TEST(PyQgsServerWFST test_qgsserver_wfst.py)
ENDIF (WITH_SERVER)

View File

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
"""
QGIS Server HTTP wrapper
This script launches a QGIS Server listening on port 8081 or on the port
specified on the environment variable QGIS_SERVER_DEFAULT_PORT
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Alessandro Pasotti'
__date__ = '05/15/2016'
__copyright__ = 'Copyright 2016, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
import urlparse
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from qgis.server import QgsServer
try:
QGIS_SERVER_DEFAULT_PORT = os.environ('QGIS_SERVER_DEFAULT_PORT')
except:
QGIS_SERVER_DEFAULT_PORT = 8081
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
parsed_path = urlparse.urlparse(self.path)
s = QgsServer()
headers, body = s.handleRequest(parsed_path.query)
self.send_response(200)
for k, v in [h.split(':') for h in headers.split('\n') if h]:
self.send_header(k, v)
self.end_headers()
self.wfile.write(body)
return
def do_POST(self):
content_len = int(self.headers.getheader('content-length', 0))
post_body = self.rfile.read(content_len)
request = post_body[1:post_body.find(' ')]
self.path = self.path + '&REQUEST_BODY=' + \
post_body.replace('&', '') + '&REQUEST=' + request
return self.do_GET()
if __name__ == '__main__':
server = HTTPServer(('localhost', QGIS_SERVER_DEFAULT_PORT), Handler)
print 'Starting server on localhost:%s, use <Ctrl-C> to stop' % \
QGIS_SERVER_DEFAULT_PORT
server.serve_forever()

View File

@ -0,0 +1,289 @@
# -*- coding: utf-8 -*-
"""
Tests for WFS-T provider using QGIS Server through qgis_wrapped_server.py.
This is an integration test for QGIS Desktop WFS-T provider and QGIS Server
WFS-T that check if QGIS can talk to and uderstand itself.
The test uses testdata/wfs_transactional/wfs_transactional.qgs and three
initially empty shapefiles layrs with points, lines and polygons.
All WFS-T calls are executed through the QGIS WFS data provider.
The three layers are
1. populated with WFS-T
2. checked for geometry and attributes
3. modified with WFS-T
4. checked for geometry and attributes
5. emptied with WFS-T calls to delete
From build dir, run: ctest -R PyQgsServerWFST -V
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Alessandro Pasotti'
__date__ = '05/15/2016'
__copyright__ = 'Copyright 2016, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
import subprocess
from shutil import copytree, rmtree
import tempfile
from time import sleep
from utilities import unitTestDataPath
from qgis.core import (
QgsVectorLayer,
QgsFeature,
QgsGeometry,
QgsPoint,
QgsRectangle,
QgsFeatureRequest,
QgsExpression,
)
from qgis.testing import (
start_app,
unittest,
)
try:
QGIS_SERVER_WFST_DEFAULT_PORT = os.environ['QGIS_SERVER_WFST_DEFAULT_PORT']
except:
QGIS_SERVER_WFST_DEFAULT_PORT = 8081
qgis_app = start_app()
class TestWFST(unittest.TestCase):
@classmethod
def setUpClass(cls):
"""Run before all tests"""
cls.port = QGIS_SERVER_WFST_DEFAULT_PORT
cls.testdata_path = unitTestDataPath('wfs_transactional') + '/'
# Create tmp folder
cls.temp_path = tempfile.mkdtemp()
cls.testdata_path = cls.temp_path + '/' + 'wfs_transactional' + '/'
copytree(unitTestDataPath('wfs_transactional') + '/',
cls.temp_path + '/' + 'wfs_transactional')
cls.project_path = cls.temp_path + '/' + 'wfs_transactional' + '/' + \
'wfs_transactional.qgs'
assert os.path.exists(cls.project_path), "Project not found: %s" % \
cls.project_path
# Clean env just to be sure
env_vars = ['QUERY_STRING', 'QGIS_PROJECT_FILE']
for ev in env_vars:
try:
del os.environ[ev]
except KeyError:
pass
# Clear all test layers
for ln in ['test_point', 'test_polygon', 'test_linestring']:
cls._clearLayer(ln)
os.environ['QGIS_SERVER_DEFAULT_PORT'] = str(cls.port)
server_path = os.path.dirname(os.path.realpath(__file__)) + \
'/qgis_wrapped_server.py'
cls.server = subprocess.Popen(['python', server_path],
env=os.environ)
sleep(2)
@classmethod
def tearDownClass(cls):
"""Run after all tests"""
cls.server.terminate()
del cls.server
# Clear all test layers
for ln in ['test_point', 'test_polygon', 'test_linestring']:
layer = cls._getLayer(ln)
cls._clearLayer(ln)
rmtree(cls.temp_path)
def setUp(self):
"""Run before each test."""
pass
def tearDown(self):
"""Run after each test."""
pass
@classmethod
def _clearLayer(cls, layer_name):
"""
Delete all features from a vector layer
"""
layer = cls._getLayer(layer_name)
layer.startEditing()
layer.deleteFeatures([f.id() for f in layer.getFeatures()])
layer.commitChanges()
assert layer.featureCount() == 0
@classmethod
def _getLayer(cls, layer_name):
"""
OGR Layer factory
"""
path = cls.testdata_path + layer_name + '.shp'
layer = QgsVectorLayer(path, layer_name, "ogr")
assert layer.isValid()
return layer
@classmethod
def _getWFSLayer(cls, type_name, layer_name=None):
"""
WFS layer factory
"""
if layer_name is None:
layer_name = 'wfs_' + type_name
parms = {
'srsname': 'EPSG:4326',
'typename': type_name,
'url': 'http://127.0.0.1:%s/?map=%s' % (cls.port,
cls.project_path),
'version': 'auto',
'table': '',
#'sql': '',
}
uri = ' '.join([("%s='%s'" % (k, v)) for k, v in parms.iteritems()])
wfs_layer = QgsVectorLayer(uri, layer_name, 'WFS')
assert wfs_layer.isValid()
return wfs_layer
@classmethod
def _getFeatureByAttribute(cls, layer, attr_name, attr_value):
"""
Find the feature and return it, raise exception if not found
"""
request = QgsFeatureRequest(QgsExpression("%s=%s" % (attr_name,
attr_value)))
try:
return layer.dataProvider().getFeatures(request).next()
except StopIteration:
raise Exception("Wrong attributes in WFS layer %s" %
layer.name())
def _checkAddFeatures(self, wfs_layer, layer, features):
"""
Check features were added
"""
wfs_layer.dataProvider().addFeatures(features)
layer = self._getLayer(layer.name())
self.assertTrue(layer.isValid())
self.assertEqual(layer.featureCount(), len(features))
def _checkUpdateFeatures(self, wfs_layer, old_features, new_features):
"""
Check features can be updated
"""
for i in range(len(old_features)):
f = self._getFeatureByAttribute(wfs_layer, 'id', old_features[i]['id'])
self.assertTrue(wfs_layer.dataProvider().changeGeometryValues({f.id(): new_features[i].geometry()}))
self.assertTrue(wfs_layer.dataProvider().changeAttributeValues({f.id(): {0: new_features[i]['id']}}))
def _checkMatchFeatures(self, wfs_layer, features):
"""
Check feature attributes and geometry match
"""
for f in features:
wf = self._getFeatureByAttribute(wfs_layer, 'id', f['id'])
self.assertEqual(wf.geometry().exportToWkt(),
f.geometry().exportToWkt())
def _checkDeleteFeatures(self, layer, features):
"""
Delete features
"""
ids = []
for f in features:
wf = self._getFeatureByAttribute(layer, 'id', f['id'])
ids.append(wf.id())
self.assertTrue(layer.dataProvider().deleteFeatures(ids))
def _testLayer(self, wfs_layer, layer, old_features, new_features):
"""
Perform all test steps on the layer.
"""
self.assertEqual(wfs_layer.featureCount(), 0)
self._checkAddFeatures(wfs_layer, layer, old_features)
self._checkMatchFeatures(wfs_layer, old_features)
self.assertEqual(wfs_layer.dataProvider().featureCount(),
len(old_features))
self._checkUpdateFeatures(wfs_layer, old_features, new_features)
self._checkMatchFeatures(wfs_layer, new_features)
self._checkDeleteFeatures(wfs_layer, new_features)
self.assertEqual(wfs_layer.dataProvider().featureCount(), 0)
def testWFSPoints(self):
"""
Adds some points, then check and clear all
"""
layer_name = 'test_point'
layer = self._getLayer(layer_name)
wfs_layer = self._getWFSLayer(layer_name)
feat1 = QgsFeature(wfs_layer.pendingFields())
feat1['id'] = 11
feat1.setGeometry(QgsGeometry.fromPoint(QgsPoint(9, 45)))
feat2 = QgsFeature(wfs_layer.pendingFields())
feat2.setGeometry(QgsGeometry.fromPoint(QgsPoint(9.5, 45.5)))
feat2['id'] = 12
old_features = [feat1, feat2]
# Change feat1
new_feat1 = QgsFeature(wfs_layer.pendingFields())
new_feat1['id'] = 121
new_feat1.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 46)))
new_features = [new_feat1, feat2]
self._testLayer(wfs_layer, layer, old_features, new_features)
def testWFSPolygons(self):
"""
Adds some polygons, then check and clear all
"""
layer_name = 'test_polygon'
layer = self._getLayer(layer_name)
wfs_layer = self._getWFSLayer(layer_name)
feat1 = QgsFeature(wfs_layer.pendingFields())
feat1['id'] = 11
feat1.setGeometry(QgsGeometry.fromRect(QgsRectangle(QgsPoint(9, 45), QgsPoint(10, 46))))
feat2 = QgsFeature(wfs_layer.pendingFields())
feat2.setGeometry(QgsGeometry.fromRect(QgsRectangle(QgsPoint(9.5, 45.5), QgsPoint(10.5, 46.5))))
feat2['id'] = 12
old_features = [feat1, feat2]
# Change feat1
new_feat1 = QgsFeature(wfs_layer.pendingFields())
new_feat1['id'] = 121
new_feat1.setGeometry(QgsGeometry.fromRect(QgsRectangle(QgsPoint(10, 46), QgsPoint(11.5, 47.5))))
new_features = [new_feat1, feat2]
self._testLayer(wfs_layer, layer, old_features, new_features)
def testWFSLineStrings(self):
"""
Adds some lines, then check and clear all
"""
layer_name = 'test_linestring'
layer = self._getLayer(layer_name)
wfs_layer = self._getWFSLayer(layer_name)
feat1 = QgsFeature(wfs_layer.pendingFields())
feat1['id'] = 11
feat1.setGeometry(QgsGeometry.fromPolyline([QgsPoint(9, 45), QgsPoint(10, 46)]))
feat2 = QgsFeature(wfs_layer.pendingFields())
feat2.setGeometry(QgsGeometry.fromPolyline([QgsPoint(9.5, 45.5), QgsPoint(10.5, 46.5)]))
feat2['id'] = 12
old_features = [feat1, feat2]
# Change feat1
new_feat1 = QgsFeature(wfs_layer.pendingFields())
new_feat1['id'] = 121
new_feat1.setGeometry(QgsGeometry.fromPolyline([QgsPoint(9.8, 45.8), QgsPoint(10.8, 46.8)]))
new_features = [new_feat1, feat2]
self._testLayer(wfs_layer, layer, old_features, new_features)
if __name__ == '__main__':
unittest.main()

Binary file not shown.

View File

@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]

View File

@ -0,0 +1 @@
GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]

View File

@ -0,0 +1 @@
GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]

View File

@ -0,0 +1 @@
GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,531 @@
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
<qgis projectname="QGIS Test Project" version="2.15.0-Master">
<title>QGIS Test Project</title>
<autotransaction active="0"/>
<layer-tree-group expanded="1" checked="Qt::Checked" name="">
<customproperties/>
<layer-tree-layer expanded="1" checked="Qt::Checked" id="test_polygon20160506144729957" name="test_polygon">
<customproperties/>
</layer-tree-layer>
<layer-tree-layer expanded="1" checked="Qt::Checked" id="test_point20160506204349847" name="test_point">
<customproperties/>
</layer-tree-layer>
<layer-tree-layer expanded="1" checked="Qt::Checked" id="test_linestring20160506144729962" name="test_linestring">
<customproperties/>
</layer-tree-layer>
</layer-tree-group>
<relations/>
<mapcanvas>
<units>degrees</units>
<extent>
<xmin>7.30949085639134744</xmin>
<ymin>43.54835337219116553</ymin>
<xmax>11.50948998670192047</xmax>
<ymax>47.74835250250185226</ymax>
</extent>
<rotation>0</rotation>
<projections>1</projections>
<destinationsrs>
<spatialrefsys>
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
<srsid>3452</srsid>
<srid>4326</srid>
<authid>EPSG:4326</authid>
<description>WGS 84</description>
<projectionacronym>longlat</projectionacronym>
<ellipsoidacronym>WGS84</ellipsoidacronym>
<geographicflag>true</geographicflag>
</spatialrefsys>
</destinationsrs>
<rendermaptile>0</rendermaptile>
<layer_coordinate_transform_info>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="testlayer20160505152709094"/>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="test_point20160506144313383"/>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="test_polygon20160506144443222"/>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="test_polygon20160506144729957"/>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="test_linestring20160506144729962"/>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="test_point20160506204349847"/>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="test_point20160506144729968"/>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="testlayer20150528120452665"/>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="projects20160506144157680"/>
<layer_coordinate_transform destAuthId="EPSG:4326" srcAuthId="EPSG:4326" srcDatumTransform="-1" destDatumTransform="-1" layerid="test_linestring20160506144421070"/>
</layer_coordinate_transform_info>
</mapcanvas>
<layer-tree-canvas>
<custom-order enabled="0">
<item>test_polygon20160506144729957</item>
<item>test_linestring20160506144729962</item>
<item>test_point20160506204349847</item>
</custom-order>
</layer-tree-canvas>
<legend updateDrawingOrder="true">
<legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="test_polygon" showFeatureCount="0">
<filegroup open="true" hidden="false">
<legendlayerfile isInOverview="0" layerid="test_polygon20160506144729957" visible="1"/>
</filegroup>
</legendlayer>
<legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="test_point" showFeatureCount="0">
<filegroup open="true" hidden="false">
<legendlayerfile isInOverview="0" layerid="test_point20160506204349847" visible="1"/>
</filegroup>
</legendlayer>
<legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="test_linestring" showFeatureCount="0">
<filegroup open="true" hidden="false">
<legendlayerfile isInOverview="0" layerid="test_linestring20160506144729962" visible="1"/>
</filegroup>
</legendlayer>
</legend>
<projectlayers>
<maplayer minimumScale="0" maximumScale="1e+08" simplifyDrawingHints="1" readOnly="0" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" geometry="Line" simplifyMaxScale="1" type="vector" hasScaleBasedVisibilityFlag="0" simplifyLocal="0" scaleBasedLabelVisibilityFlag="0">
<id>test_linestring20160506144729962</id>
<datasource>./test_linestring.shp</datasource>
<keywordList>
<value></value>
</keywordList>
<layername>test_linestring</layername>
<srs>
<spatialrefsys>
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
<srsid>3452</srsid>
<srid>4326</srid>
<authid>EPSG:4326</authid>
<description>WGS 84</description>
<projectionacronym>longlat</projectionacronym>
<ellipsoidacronym>WGS84</ellipsoidacronym>
<geographicflag>true</geographicflag>
</spatialrefsys>
</srs>
<provider encoding="System">ogr</provider>
<previewExpression></previewExpression>
<vectorjoins/>
<layerDependencies/>
<expressionfields/>
<map-layer-style-manager current="">
<map-layer-style name=""/>
</map-layer-style-manager>
<edittypes>
<edittype widgetv2type="TextEdit" name="id">
<widgetv2config IsMultiline="0" fieldEditable="1" UseHtml="0" labelOnTop="0"/>
</edittype>
</edittypes>
<renderer-v2 forceraster="0" symbollevels="0" type="singleSymbol" enableorderby="0">
<symbols>
<symbol alpha="1" clip_to_extent="1" type="line" name="0">
<layer pass="0" class="SimpleLine" locked="0">
<prop k="capstyle" v="square"/>
<prop k="customdash" v="5;2"/>
<prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
<prop k="customdash_unit" v="MM"/>
<prop k="draw_inside_polygon" v="0"/>
<prop k="joinstyle" v="bevel"/>
<prop k="line_color" v="132,67,147,255"/>
<prop k="line_style" v="solid"/>
<prop k="line_width" v="0.26"/>
<prop k="line_width_unit" v="MM"/>
<prop k="offset" v="0"/>
<prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
<prop k="offset_unit" v="MM"/>
<prop k="use_custom_dash" v="0"/>
<prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
</layer>
</symbol>
</symbols>
<rotation/>
<sizescale scalemethod="diameter"/>
</renderer-v2>
<labeling type="simple"/>
<customproperties/>
<blendMode>0</blendMode>
<featureBlendMode>0</featureBlendMode>
<layerTransparency>0</layerTransparency>
<displayfield>id</displayfield>
<label>0</label>
<labelattributes>
<label fieldname="" text="Etichetta"/>
<family fieldname="" name="Ubuntu"/>
<size fieldname="" units="pt" value="12"/>
<bold fieldname="" on="0"/>
<italic fieldname="" on="0"/>
<underline fieldname="" on="0"/>
<strikeout fieldname="" on="0"/>
<color fieldname="" red="0" blue="0" green="0"/>
<x fieldname=""/>
<y fieldname=""/>
<offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
<angle fieldname="" value="0" auto="0"/>
<alignment fieldname="" value="center"/>
<buffercolor fieldname="" red="255" blue="255" green="255"/>
<buffersize fieldname="" units="pt" value="1"/>
<bufferenabled fieldname="" on=""/>
<multilineenabled fieldname="" on=""/>
<selectedonly on=""/>
</labelattributes>
<annotationform>.</annotationform>
<excludeAttributesWMS/>
<excludeAttributesWFS/>
<attributeactions/>
<editform>.</editform>
<editforminit/>
<editforminitcodesource>0</editforminitcodesource>
<editforminitfilepath>.</editforminitfilepath>
<editforminitcode><![CDATA[]]></editforminitcode>
<featformsuppress>0</featformsuppress>
<editorlayout>generatedlayout</editorlayout>
<widgets/>
<attributetableconfig actionWidgetStyle="dropDown">
<columns/>
</attributetableconfig>
<conditionalstyles>
<rowstyles/>
<fieldstyles/>
</conditionalstyles>
</maplayer>
<maplayer minimumScale="0" maximumScale="1e+08" simplifyDrawingHints="1" readOnly="0" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" geometry="Point" simplifyMaxScale="1" type="vector" hasScaleBasedVisibilityFlag="0" simplifyLocal="0" scaleBasedLabelVisibilityFlag="0">
<id>test_point20160506204349847</id>
<datasource>./test_point.shp</datasource>
<keywordList>
<value></value>
</keywordList>
<layername>test_point</layername>
<srs>
<spatialrefsys>
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
<srsid>3452</srsid>
<srid>4326</srid>
<authid>EPSG:4326</authid>
<description>WGS 84</description>
<projectionacronym>longlat</projectionacronym>
<ellipsoidacronym>WGS84</ellipsoidacronym>
<geographicflag>true</geographicflag>
</spatialrefsys>
</srs>
<provider encoding="System">ogr</provider>
<previewExpression>COALESCE( "id", '&lt;NULL>' )</previewExpression>
<vectorjoins/>
<layerDependencies/>
<expressionfields/>
<map-layer-style-manager current="">
<map-layer-style name=""/>
</map-layer-style-manager>
<edittypes>
<edittype widgetv2type="TextEdit" name="id">
<widgetv2config IsMultiline="0" fieldEditable="1" UseHtml="0" labelOnTop="0"/>
</edittype>
</edittypes>
<renderer-v2 forceraster="0" symbollevels="0" type="singleSymbol" enableorderby="0">
<symbols>
<symbol alpha="1" clip_to_extent="1" type="marker" name="0">
<layer pass="0" class="SimpleMarker" locked="0">
<prop k="angle" v="0"/>
<prop k="color" v="172,87,41,255"/>
<prop k="horizontal_anchor_point" v="1"/>
<prop k="joinstyle" v="bevel"/>
<prop k="name" v="circle"/>
<prop k="offset" v="0,0"/>
<prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
<prop k="offset_unit" v="MM"/>
<prop k="outline_color" v="0,0,0,255"/>
<prop k="outline_style" v="solid"/>
<prop k="outline_width" v="0"/>
<prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
<prop k="outline_width_unit" v="MM"/>
<prop k="scale_method" v="diameter"/>
<prop k="size" v="2"/>
<prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
<prop k="size_unit" v="MM"/>
<prop k="vertical_anchor_point" v="1"/>
</layer>
</symbol>
</symbols>
<rotation/>
<sizescale scalemethod="diameter"/>
</renderer-v2>
<labeling type="simple"/>
<customproperties/>
<blendMode>0</blendMode>
<featureBlendMode>0</featureBlendMode>
<layerTransparency>0</layerTransparency>
<displayfield>id</displayfield>
<label>0</label>
<labelattributes>
<label fieldname="" text="Etichetta"/>
<family fieldname="" name="Ubuntu"/>
<size fieldname="" units="pt" value="12"/>
<bold fieldname="" on="0"/>
<italic fieldname="" on="0"/>
<underline fieldname="" on="0"/>
<strikeout fieldname="" on="0"/>
<color fieldname="" red="0" blue="0" green="0"/>
<x fieldname=""/>
<y fieldname=""/>
<offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
<angle fieldname="" value="0" auto="0"/>
<alignment fieldname="" value="center"/>
<buffercolor fieldname="" red="255" blue="255" green="255"/>
<buffersize fieldname="" units="pt" value="1"/>
<bufferenabled fieldname="" on=""/>
<multilineenabled fieldname="" on=""/>
<selectedonly on=""/>
</labelattributes>
<annotationform>.</annotationform>
<excludeAttributesWMS/>
<excludeAttributesWFS/>
<attributeactions/>
<editform>.</editform>
<editforminit/>
<editforminitcodesource>0</editforminitcodesource>
<editforminitfilepath>.</editforminitfilepath>
<editforminitcode><![CDATA[]]></editforminitcode>
<featformsuppress>0</featformsuppress>
<editorlayout>generatedlayout</editorlayout>
<widgets/>
<attributetableconfig actionWidgetStyle="dropDown">
<columns/>
</attributetableconfig>
<conditionalstyles>
<rowstyles/>
<fieldstyles/>
</conditionalstyles>
</maplayer>
<maplayer minimumScale="0" maximumScale="1e+08" simplifyDrawingHints="1" readOnly="0" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" geometry="Polygon" simplifyMaxScale="1" type="vector" hasScaleBasedVisibilityFlag="0" simplifyLocal="0" scaleBasedLabelVisibilityFlag="0">
<id>test_polygon20160506144729957</id>
<datasource>./test_polygon.shp</datasource>
<keywordList>
<value></value>
</keywordList>
<layername>test_polygon</layername>
<srs>
<spatialrefsys>
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
<srsid>3452</srsid>
<srid>4326</srid>
<authid>EPSG:4326</authid>
<description>WGS 84</description>
<projectionacronym>longlat</projectionacronym>
<ellipsoidacronym>WGS84</ellipsoidacronym>
<geographicflag>true</geographicflag>
</spatialrefsys>
</srs>
<provider encoding="System">ogr</provider>
<previewExpression></previewExpression>
<vectorjoins/>
<layerDependencies/>
<expressionfields/>
<map-layer-style-manager current="">
<map-layer-style name=""/>
</map-layer-style-manager>
<edittypes>
<edittype widgetv2type="TextEdit" name="id">
<widgetv2config IsMultiline="0" fieldEditable="1" UseHtml="0" labelOnTop="0"/>
</edittype>
</edittypes>
<renderer-v2 forceraster="0" symbollevels="0" type="singleSymbol" enableorderby="0">
<symbols>
<symbol alpha="1" clip_to_extent="1" type="fill" name="0">
<layer pass="0" class="SimpleFill" locked="0">
<prop k="border_width_map_unit_scale" v="0,0,0,0,0,0"/>
<prop k="color" v="140,193,234,255"/>
<prop k="joinstyle" v="bevel"/>
<prop k="offset" v="0,0"/>
<prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
<prop k="offset_unit" v="MM"/>
<prop k="outline_color" v="0,0,0,255"/>
<prop k="outline_style" v="solid"/>
<prop k="outline_width" v="0.26"/>
<prop k="outline_width_unit" v="MM"/>
<prop k="style" v="solid"/>
</layer>
</symbol>
</symbols>
<rotation/>
<sizescale scalemethod="diameter"/>
</renderer-v2>
<labeling type="simple"/>
<customproperties/>
<blendMode>0</blendMode>
<featureBlendMode>0</featureBlendMode>
<layerTransparency>0</layerTransparency>
<displayfield>id</displayfield>
<label>0</label>
<labelattributes>
<label fieldname="" text="Etichetta"/>
<family fieldname="" name="Ubuntu"/>
<size fieldname="" units="pt" value="12"/>
<bold fieldname="" on="0"/>
<italic fieldname="" on="0"/>
<underline fieldname="" on="0"/>
<strikeout fieldname="" on="0"/>
<color fieldname="" red="0" blue="0" green="0"/>
<x fieldname=""/>
<y fieldname=""/>
<offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
<angle fieldname="" value="0" auto="0"/>
<alignment fieldname="" value="center"/>
<buffercolor fieldname="" red="255" blue="255" green="255"/>
<buffersize fieldname="" units="pt" value="1"/>
<bufferenabled fieldname="" on=""/>
<multilineenabled fieldname="" on=""/>
<selectedonly on=""/>
</labelattributes>
<annotationform>.</annotationform>
<excludeAttributesWMS/>
<excludeAttributesWFS/>
<attributeactions/>
<editform>.</editform>
<editforminit/>
<editforminitcodesource>0</editforminitcodesource>
<editforminitfilepath>.</editforminitfilepath>
<editforminitcode><![CDATA[]]></editforminitcode>
<featformsuppress>0</featformsuppress>
<editorlayout>generatedlayout</editorlayout>
<widgets/>
<attributetableconfig actionWidgetStyle="dropDown">
<columns/>
</attributetableconfig>
<conditionalstyles>
<rowstyles/>
<fieldstyles/>
</conditionalstyles>
</maplayer>
</projectlayers>
<properties>
<WMSUrl type="QString"></WMSUrl>
<SpatialRefSys>
<ProjectCRSProj4String type="QString">+proj=longlat +datum=WGS84 +no_defs</ProjectCRSProj4String>
<ProjectCrs type="QString">EPSG:4326</ProjectCrs>
<ProjectCRSID type="int">3452</ProjectCRSID>
<ProjectionsEnabled type="int">1</ProjectionsEnabled>
</SpatialRefSys>
<Measurement>
<DistanceUnits type="QString">meters</DistanceUnits>
<AreaUnits type="QString">m2</AreaUnits>
</Measurement>
<Legend>
<filterByMap type="bool">false</filterByMap>
</Legend>
<WMSExtent type="QStringList">
<value>8.20315414376310059</value>
<value>44.901236559338642</value>
<value>8.204164917965862</value>
<value>44.90159838674664172</value>
</WMSExtent>
<DefaultStyles>
<Fill type="QString"></Fill>
<Line type="QString"></Line>
<Marker type="QString"></Marker>
<RandomColors type="bool">true</RandomColors>
<AlphaInt type="int">255</AlphaInt>
<ColorRamp type="QString"></ColorRamp>
</DefaultStyles>
<WMSAccessConstraints type="QString">None</WMSAccessConstraints>
<WMSContactMail type="QString">elpaso@itopen.it</WMSContactMail>
<WMSImageQuality type="int">90</WMSImageQuality>
<WFSLayersPrecision>
<test_linestring20160506144729962 type="int">8</test_linestring20160506144729962>
<test_point20160506204349847 type="int">8</test_point20160506204349847>
<test_polygon20160506144729957 type="int">8</test_polygon20160506144729957>
<test_point20160506144729968 type="int">8</test_point20160506144729968>
<testlayer20150528120452665 type="int">8</testlayer20150528120452665>
</WFSLayersPrecision>
<WMSRestrictedComposers type="QStringList"/>
<WMSServiceTitle type="QString">QGIS TestProject</WMSServiceTitle>
<WMSContactPhone type="QString"></WMSContactPhone>
<WFSTLayers>
<Insert type="QStringList">
<value>test_linestring20160506144729962</value>
<value>test_point20160506204349847</value>
<value>test_polygon20160506144729957</value>
</Insert>
<Update type="QStringList">
<value>test_linestring20160506144729962</value>
<value>test_point20160506204349847</value>
<value>test_polygon20160506144729957</value>
</Update>
<Delete type="QStringList">
<value>test_linestring20160506144729962</value>
<value>test_point20160506204349847</value>
<value>test_polygon20160506144729957</value>
</Delete>
</WFSTLayers>
<WCSLayers type="QStringList"/>
<WMSRestrictedLayers type="QStringList"/>
<WMSFees type="QString">conditions unknown</WMSFees>
<Macros>
<pythonCode type="QString"></pythonCode>
</Macros>
<WMSAddWktGeometry type="bool">true</WMSAddWktGeometry>
<WCSUrl type="QString"></WCSUrl>
<WMSOnlineResource type="QString"></WMSOnlineResource>
<WMSPrecision type="QString">4</WMSPrecision>
<Digitizing>
<DefaultSnapToleranceUnit type="int">2</DefaultSnapToleranceUnit>
<LayerSnappingList type="QStringList">
<value>test_linestring20160506144729962</value>
<value>test_polygon20160506144729957</value>
</LayerSnappingList>
<LayerSnappingEnabledList type="QStringList">
<value>enabled</value>
<value>enabled</value>
</LayerSnappingEnabledList>
<SnappingMode type="QString">current_layer</SnappingMode>
<AvoidIntersectionsList type="QStringList"/>
<LayerSnappingToleranceUnitList type="QStringList">
<value>1</value>
<value>1</value>
</LayerSnappingToleranceUnitList>
<LayerSnapToList type="QStringList">
<value>to_vertex_and_segment</value>
<value>to_vertex_and_segment</value>
</LayerSnapToList>
<DefaultSnapType type="QString">off</DefaultSnapType>
<DefaultSnapTolerance type="double">0</DefaultSnapTolerance>
<LayerSnappingToleranceList type="QStringList">
<value>10.000000</value>
<value>10.000000</value>
</LayerSnappingToleranceList>
</Digitizing>
<Identify>
<disabledLayers type="QStringList"/>
</Identify>
<WMSContactPerson type="QString">Alessandro Pasotti</WMSContactPerson>
<WMSContactOrganization type="QString">QGIS dev team</WMSContactOrganization>
<WMSKeywordList type="QStringList">
<value></value>
</WMSKeywordList>
<Variables>
<variableNames type="QStringList"/>
<variableValues type="QStringList"/>
</Variables>
<Paths>
<Absolute type="bool">false</Absolute>
</Paths>
<WMSContactPosition type="QString"></WMSContactPosition>
<PositionPrecision>
<DecimalPlaces type="int">2</DecimalPlaces>
<Automatic type="bool">true</Automatic>
<DegreeFormat type="QString">D</DegreeFormat>
</PositionPrecision>
<Gui>
<SelectionColorBluePart type="int">0</SelectionColorBluePart>
<CanvasColorGreenPart type="int">255</CanvasColorGreenPart>
<CanvasColorRedPart type="int">255</CanvasColorRedPart>
<SelectionColorRedPart type="int">255</SelectionColorRedPart>
<SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart>
<SelectionColorGreenPart type="int">255</SelectionColorGreenPart>
<CanvasColorBluePart type="int">255</CanvasColorBluePart>
</Gui>
<Measure>
<Ellipsoid type="QString">WGS84</Ellipsoid>
</Measure>
<WMSServiceAbstract type="QString">Some UTF8 text èòù</WMSServiceAbstract>
<WFSLayers type="QStringList">
<value>test_linestring20160506144729962</value>
<value>test_point20160506204349847</value>
<value>test_polygon20160506144729957</value>
</WFSLayers>
<WFSUrl type="QString"></WFSUrl>
<WMSServiceCapabilities type="bool">true</WMSServiceCapabilities>
<WMSUseLayerIDs type="bool">false</WMSUseLayerIDs>
</properties>
<visibility-presets/>
</qgis>