コード例 #1
0
ファイル: qgswfstransaction.cpp プロジェクト: wongjimsan/QGIS
  QDomDocument createTransactionDocument( QgsServerInterface* serverIface, const QString& version,
                                          const QgsServerRequest& request )
  {
    Q_UNUSED( version );

    QDomDocument doc;

    QgsWfsProjectParser* configParser = getConfigParser( serverIface );
#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl* accessControl = serverIface->accessControls();
#endif
    const QString requestBody = request.getParameter( QStringLiteral( "REQUEST_BODY" ) );

    QString errorMsg;
    if ( !doc.setContent( requestBody, true, &errorMsg ) )
    {
      throw QgsRequestNotWellFormedException( errorMsg );
    }

    QDomElement docElem = doc.documentElement();
    QDomNodeList docChildNodes = docElem.childNodes();

    // Re-organize the transaction document
    QDomDocument mDoc;
    QDomElement mDocElem = mDoc.createElement( QStringLiteral( "myTransactionDocument" ) );
    mDocElem.setAttribute( QStringLiteral( "xmlns" ), QGS_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:wfs" ), WFS_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:qgs" ), QGS_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    mDoc.appendChild( mDocElem );

    QDomElement actionElem;
    QString actionName;
    QDomElement typeNameElem;
    QString typeName;

    for ( int i = docChildNodes.count(); 0 < i; --i )
    {
      actionElem = docChildNodes.at( i - 1 ).toElement();
      actionName = actionElem.localName();

      if ( actionName == QLatin1String( "Insert" ) )
      {
        QDomElement featureElem = actionElem.firstChild().toElement();
        typeName = featureElem.localName();
      }
      else if ( actionName == QLatin1String( "Update" ) )
      {
        typeName = actionElem.attribute( QStringLiteral( "typeName" ) );
      }
      else if ( actionName == QLatin1String( "Delete" ) )
      {
        typeName = actionElem.attribute( QStringLiteral( "typeName" ) );
      }

      if ( typeName.contains( QLatin1String( ":" ) ) )
        typeName = typeName.section( QStringLiteral( ":" ), 1, 1 );

      QDomNodeList typeNameList = mDocElem.elementsByTagName( typeName );
      if ( typeNameList.count() == 0 )
      {
        typeNameElem = mDoc.createElement( typeName );
        mDocElem.appendChild( typeNameElem );
      }
      else
        typeNameElem = typeNameList.at( 0 ).toElement();

      typeNameElem.appendChild( actionElem );
    }

    // It's time to make the transaction
    // Create the response document
    QDomDocument resp;
    //wfs:WFS_TransactionRespone element
    QDomElement respElem = resp.createElement( QStringLiteral( "WFS_TransactionResponse" )/*wfs:WFS_TransactionResponse*/ );
    respElem.setAttribute( QStringLiteral( "xmlns" ), WFS_NAMESPACE );
    respElem.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    respElem.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WFS_NAMESPACE + " http://schemas.opengis.net/wfs/1.0.0/wfs.xsd" );
    respElem.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE );
    respElem.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) );
    resp.appendChild( respElem );

    // Store the created feature id for WFS
    QStringList insertResults;
    // Get the WFS layers id
    QStringList wfsLayersId = configParser->wfsLayers();;

    QList<QgsMapLayer*> layerList;
    QgsMapLayer* currentLayer = nullptr;

    // Loop through the layer transaction elements
    docChildNodes = mDocElem.childNodes();
    for ( int i = 0; i < docChildNodes.count(); ++i )
    {
      // Get the vector layer
      typeNameElem = docChildNodes.at( i ).toElement();
      typeName = typeNameElem.tagName();

      layerList = configParser->mapLayerFromTypeName( typeName );
      // Could be empty!
      if ( layerList.count() > 0 )
      {
        currentLayer = layerList.at( 0 );
      }
      else
      {
        throw QgsRequestNotWellFormedException( QStringLiteral( "Wrong TypeName: %1" ).arg( typeName ) );
      }

      QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( currentLayer );
      // it's a vectorlayer and defined by the administrator as a WFS layer
      if ( layer && wfsLayersId.contains( layer->id() ) )
      {
#ifdef HAVE_SERVER_PYTHON_PLUGINS
        if ( actionName == QLatin1String( "Insert" ) )
        {
          if ( !accessControl->layerInsertPermission( layer ) )
          {
            throw QgsSecurityAccessException( QStringLiteral( "Feature insert permission denied" ) );
          }
        }
        else if ( actionName == QLatin1String( "Update" ) )
        {
          if ( !accessControl->layerUpdatePermission( layer ) )
          {
            throw QgsSecurityAccessException( QStringLiteral( "Feature update permission denied" ) );
          }
        }
        else if ( actionName == QLatin1String( "Delete" ) )
        {
          if ( !accessControl->layerDeletePermission( layer ) )
          {
            throw QgsSecurityAccessException( QStringLiteral( "Feature delete permission denied" ) );
          }
        }
#endif

        // Get the provider and it's capabilities
        QgsVectorDataProvider* provider = layer->dataProvider();
        if ( !provider )
        {
          continue;
        }

        int cap = provider->capabilities();

        // Start the update transaction
        layer->startEditing();
        if (( cap & QgsVectorDataProvider::ChangeAttributeValues ) && ( cap & QgsVectorDataProvider::ChangeGeometries ) )
        {
          // Loop through the update elements for this layer
          QDomNodeList upNodeList = typeNameElem.elementsByTagNameNS( WFS_NAMESPACE, QStringLiteral( "Update" ) );
          for ( int j = 0; j < upNodeList.count(); ++j )
          {
            if ( !configParser->wfstUpdateLayers().contains( layer->id() ) )
            {
              //no wfs permissions to do updates
              QString errorMsg = "No permissions to do WFS updates on layer '" + layer->name() + "'";
              QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
              addTransactionResult( resp, respElem, QStringLiteral( "FAILED" ), QStringLiteral( "Update" ), errorMsg );
              return resp;
            }

            actionElem = upNodeList.at( j ).toElement();

            // Get the Feature Ids for this filter on the layer
            QDomElement filterElem = actionElem.elementsByTagName( QStringLiteral( "Filter" ) ).at( 0 ).toElement();
            QgsFeatureIds fids = getFeatureIdsFromFilter( filterElem, layer );

            // Loop through the property elements
            // Store properties and the geometry element
            QDomNodeList propertyNodeList = actionElem.elementsByTagName( QStringLiteral( "Property" ) );
            QMap<QString, QString> propertyMap;
            QDomElement propertyElem;
            QDomElement nameElem;
            QDomElement valueElem;
            QDomElement geometryElem;

            for ( int l = 0; l < propertyNodeList.count(); ++l )
            {
              propertyElem = propertyNodeList.at( l ).toElement();
              nameElem = propertyElem.elementsByTagName( QStringLiteral( "Name" ) ).at( 0 ).toElement();
              valueElem = propertyElem.elementsByTagName( QStringLiteral( "Value" ) ).at( 0 ).toElement();
              if ( nameElem.text() != QLatin1String( "geometry" ) )
              {
                propertyMap.insert( nameElem.text(), valueElem.text() );
              }
              else
              {
                geometryElem = valueElem;
              }
            }

            // Update the features
            QgsFields fields = provider->fields();
            QMap<QString, int> fieldMap = provider->fieldNameMap();
            QMap<QString, int>::const_iterator fieldMapIt;
            QString fieldName;
            bool conversionSuccess;

            QgsFeatureIds::const_iterator fidIt = fids.constBegin();
            for ( ; fidIt != fids.constEnd(); ++fidIt )
            {
#ifdef HAVE_SERVER_PYTHON_PLUGINS
              QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest( *fidIt ) );
              QgsFeature feature;
              while ( fit.nextFeature( feature ) )
              {
                if ( !accessControl->allowToEdit( layer, feature ) )
                {
                  throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) );
                }
              }
#endif

              QMap< QString, QString >::const_iterator it = propertyMap.constBegin();
              for ( ; it != propertyMap.constEnd(); ++it )
              {
                fieldName = it.key();
                fieldMapIt = fieldMap.find( fieldName );
                if ( fieldMapIt == fieldMap.constEnd() )
                {
                  continue;
                }
                QgsField field = fields.at( fieldMapIt.value() );
                if ( field.type() == 2 )
                  layer->changeAttributeValue( *fidIt, fieldMapIt.value(), it.value().toInt( &conversionSuccess ) );
                else if ( field.type() == 6 )
                  layer->changeAttributeValue( *fidIt, fieldMapIt.value(), it.value().toDouble( &conversionSuccess ) );
                else
                  layer->changeAttributeValue( *fidIt, fieldMapIt.value(), it.value() );
              }

              if ( !geometryElem.isNull() )
              {
                QgsGeometry g = QgsOgcUtils::geometryFromGML( geometryElem );
                if ( !layer->changeGeometry( *fidIt, g ) )
                {
                  throw QgsRequestNotWellFormedException( QStringLiteral( "Error in change geometry" ) );
                }
              }

#ifdef HAVE_SERVER_PYTHON_PLUGINS
              fit = layer->getFeatures( QgsFeatureRequest( *fidIt ) );
              while ( fit.nextFeature( feature ) )
              {
                if ( !accessControl->allowToEdit( layer, feature ) )
                {
                  layer->rollBack();
                  throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) );
                }
              }
#endif
            }
          }
        }
        // Commit the changes of the update elements
        if ( !layer->commitChanges() )
        {
          addTransactionResult( resp, respElem, QStringLiteral( "PARTIAL" ), QStringLiteral( "Update" ), layer->commitErrors().join( QStringLiteral( "\n  " ) ) );
          return resp;
        }
        // Start the delete transaction
        layer->startEditing();
        if (( cap & QgsVectorDataProvider::DeleteFeatures ) )
        {
          // Loop through the delete elements
          QDomNodeList delNodeList = typeNameElem.elementsByTagNameNS( WFS_NAMESPACE, QStringLiteral( "Delete" ) );
          for ( int j = 0; j < delNodeList.count(); ++j )
          {
            if ( !configParser->wfstDeleteLayers().contains( layer->id() ) )
            {
              //no wfs permissions to do updates
              QString errorMsg = "No permissions to do WFS deletes on layer '" + layer->name() + "'";
              QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
              addTransactionResult( resp, respElem, QStringLiteral( "FAILED" ), QStringLiteral( "Delete" ), errorMsg );
              return resp;
            }

            actionElem = delNodeList.at( j ).toElement();
            QDomElement filterElem = actionElem.firstChild().toElement();
            // Get Feature Ids for the Filter element
            QgsFeatureIds fids = getFeatureIdsFromFilter( filterElem, layer );

#ifdef HAVE_SERVER_PYTHON_PLUGINS
            QgsFeatureIds::const_iterator fidIt = fids.constBegin();
            for ( ; fidIt != fids.constEnd(); ++fidIt )
            {
              QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest( *fidIt ) );
              QgsFeature feature;
              while ( fit.nextFeature( feature ) )
              {
                if ( !accessControl->allowToEdit( layer, feature ) )
                {
                  throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) );
                }
              }
            }
#endif

            layer->selectByIds( fids );
            layer->deleteSelectedFeatures();
          }
        }
        // Commit the changes of the delete elements
        if ( !layer->commitChanges() )
        {
          addTransactionResult( resp, respElem, QStringLiteral( "PARTIAL" ), QStringLiteral( "Delete" ), layer->commitErrors().join( QStringLiteral( "\n  " ) ) );
          return resp;
        }

        // Store the inserted features
        QgsFeatureList inFeatList;
        if ( cap & QgsVectorDataProvider::AddFeatures )
        {
          // Get Layer Field Information
          QgsFields fields = provider->fields();
          QMap<QString, int> fieldMap = provider->fieldNameMap();
          QMap<QString, int>::const_iterator fieldMapIt;

          // Loop through the insert elements
          QDomNodeList inNodeList = typeNameElem.elementsByTagNameNS( WFS_NAMESPACE, QStringLiteral( "Insert" ) );
          for ( int j = 0; j < inNodeList.count(); ++j )
          {
            if ( !configParser->wfstInsertLayers().contains( layer->id() ) )
            {
              //no wfs permissions to do updates
              QString errorMsg = "No permissions to do WFS inserts on layer '" + layer->name() + "'";
              QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
              addTransactionResult( resp, respElem, QStringLiteral( "FAILED" ), QStringLiteral( "Insert" ), errorMsg );
              return resp;
            }

            actionElem = inNodeList.at( j ).toElement();
            // Loop through the feature element
            QDomNodeList featNodes = actionElem.childNodes();
            for ( int l = 0; l < featNodes.count(); l++ )
            {
              // Add the feature to the layer
              // and store it to put it's Feature Id in the response
              inFeatList << QgsFeature( fields );

              // Create feature for this layer
              QDomElement featureElem = featNodes.at( l ).toElement();

              QDomNode currentAttributeChild = featureElem.firstChild();

              while ( !currentAttributeChild.isNull() )
              {
                QDomElement currentAttributeElement = currentAttributeChild.toElement();
                QString attrName = currentAttributeElement.localName();

                if ( attrName != QLatin1String( "boundedBy" ) )
                {
                  if ( attrName != QLatin1String( "geometry" ) ) //a normal attribute
                  {
                    fieldMapIt = fieldMap.find( attrName );
                    if ( fieldMapIt == fieldMap.constEnd() )
                    {
                      continue;
                    }
                    QgsField field = fields.at( fieldMapIt.value() );
                    QString attrValue = currentAttributeElement.text();
                    int attrType = field.type();
                    QgsMessageLog::logMessage( QStringLiteral( "attr: name=%1 idx=%2 value=%3" ).arg( attrName ).arg( fieldMapIt.value() ).arg( attrValue ) );
                    if ( attrType == QVariant::Int )
                      inFeatList.last().setAttribute( fieldMapIt.value(), attrValue.toInt() );
                    else if ( attrType == QVariant::Double )
                      inFeatList.last().setAttribute( fieldMapIt.value(), attrValue.toDouble() );
                    else
                      inFeatList.last().setAttribute( fieldMapIt.value(), attrValue );
                  }
                  else //a geometry attribute
                  {
                    QgsGeometry g = QgsOgcUtils::geometryFromGML( currentAttributeElement );
                    inFeatList.last().setGeometry( g );
                  }
                }
                currentAttributeChild = currentAttributeChild.nextSibling();
              }
            }
          }
        }
#ifdef HAVE_SERVER_PYTHON_PLUGINS
        QgsFeatureList::iterator featureIt = inFeatList.begin();
        while ( featureIt != inFeatList.end() )
        {
          if ( !accessControl->allowToEdit( layer, *featureIt ) )
          {
            throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) );
          }
          featureIt++;
        }
#endif

        // add the features
        if ( !provider->addFeatures( inFeatList ) )
        {
          addTransactionResult( resp, respElem, QStringLiteral( "Partial" ), QStringLiteral( "Insert" ), layer->commitErrors().join( QStringLiteral( "\n  " ) ) );
          if ( provider->hasErrors() )
          {
            provider->clearErrors();
          }
          return resp;
        }
        // Get the Feature Ids of the inserted feature
        for ( int j = 0; j < inFeatList.size(); j++ )
        {
          insertResults << typeName + "." + QString::number( inFeatList[j].id() );
        }
      }
    }

    // Put the Feature Ids of the inserted feature
    if ( !insertResults.isEmpty() )
    {
      Q_FOREACH ( const QString &fidStr, insertResults )
      {
        QDomElement irElem = doc.createElement( QStringLiteral( "InsertResult" ) );
        QDomElement fiElem = doc.createElement( QStringLiteral( "ogc:FeatureId" ) );
        fiElem.setAttribute( QStringLiteral( "fid" ), fidStr );
        irElem.appendChild( fiElem );
        respElem.appendChild( irElem );
      }
コード例 #2
0
ファイル: qgswmtsutils.cpp プロジェクト: alexbruy/QGIS
  QList< tileMatrixSetDef > getTileMatrixSetList( const QgsProject *project, const QString &tms_ref )
  {
    QList< tileMatrixSetDef > tmsList;

    bool gridsDefined = false;
    QStringList wmtsGridList = project->readListEntry( QStringLiteral( "WMTSGrids" ), QStringLiteral( "CRS" ), QStringList(), &gridsDefined );
    if ( gridsDefined )
    {
      if ( !tms_ref.isEmpty() && !wmtsGridList.contains( tms_ref ) )
      {
        throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) );
      }

      QStringList wmtsGridConfigList = project->readListEntry( QStringLiteral( "WMTSGrids" ), QStringLiteral( "Config" ) );
      for ( const QString &c : wmtsGridConfigList )
      {
        QStringList config = c.split( ',' );
        QString crsStr = config[0];
        if ( !tms_ref.isEmpty() && tms_ref != crsStr )
        {
          continue;
        }

        tileMatrixInfo tmi;
        double fixedTop = 0.0;
        double fixedLeft = 0.0;
        double resolution = -1.0;
        int col = -1;
        int row = -1;
        // Does the CRS have fixed tile matrices
        if ( fixedTileMatrixInfoMap.contains( crsStr ) )
        {
          tmi = fixedTileMatrixInfoMap[crsStr];
          // Calculate resolution based on scale denominator
          resolution = tmi.resolution;
          // Get fixed corner
          QgsRectangle extent = tmi.extent;
          fixedTop = extent.yMaximum();
          fixedLeft = extent.xMinimum();
          // Get numbers of column and row for the resolution to cover the extent
          col = std::ceil( ( extent.xMaximum() - extent.xMinimum() ) / ( tileSize * resolution ) );
          row = std::ceil( ( extent.yMaximum() - extent.yMinimum() ) / ( tileSize * resolution ) );
        }
        else
        {
          tmi.ref = crsStr;

          fixedTop = QVariant( config[1] ).toDouble();
          fixedLeft = QVariant( config[2] ).toDouble();
          double minScale = QVariant( config[3] ).toDouble();

          tmi.scaleDenominator = minScale;

          QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crsStr );
          tmi.unit = crs.mapUnits();
          tmi.hasAxisInverted = crs.hasAxisInverted();

          QgsCoordinateTransform crsTransform( QgsCoordinateReferenceSystem::fromOgcWmsCrs( GEO_EPSG_CRS_AUTHID ), crs, project );
          try
          {
            // firstly transform CRS bounds expressed in WGS84 to CRS
            QgsRectangle extent = crsTransform.transformBoundingBox( crs.bounds() );
            // Calculate resolution based on scale denominator
            resolution = POINTS_TO_M * minScale / QgsUnitTypes::fromUnitToUnitFactor( tmi.unit, QgsUnitTypes::DistanceMeters );
            // Get numbers of column and row for the resolution to cover the extent
            col = std::ceil( ( extent.xMaximum() - extent.xMinimum() ) / ( tileSize * resolution ) );
            row = std::ceil( ( extent.yMaximum() - extent.yMinimum() ) / ( tileSize * resolution ) );
            // Calculate extent
            double bottom =  fixedTop - row * tileSize * resolution;
            double right =  fixedLeft + col * tileSize * resolution;
            tmi.extent = QgsRectangle( fixedLeft, bottom, right, fixedTop );
          }
          catch ( QgsCsException &cse )
          {
            Q_UNUSED( cse )
            continue;
          }
        }
        // get lastLevel
        tmi.lastLevel = QVariant( config[4] ).toInt();

        QList< tileMatrixDef > tileMatrixList;
        for ( int i = 0; i <= tmi.lastLevel; ++i )
        {
          double scale = tmi.scaleDenominator / std::pow( 2, i );
          double res = resolution / std::pow( 2, i );

          tileMatrixDef tm;
          tm.resolution = res;
          tm.scaleDenominator = scale;
          tm.col = col * std::pow( 2, i );
          tm.row = row * std::pow( 2, i );
          tm.left = fixedLeft;
          tm.top = fixedTop;
          tileMatrixList.append( tm );
        }

        tileMatrixSetDef tms;
        tms.ref = tmi.ref;
        tms.extent = tmi.extent;
        tms.unit = tmi.unit;
        tms.hasAxisInverted = tmi.hasAxisInverted;
        tms.tileMatrixList = tileMatrixList;

        tmsList.append( tms );
      }
      return tmsList;
    }

    double minScale = project->readNumEntry( QStringLiteral( "WMTSMinScale" ), QStringLiteral( "/" ), -1.0 );
    if ( minScale == -1.0 )
    {
      minScale = getProjectMinScale( project );
    }

    QStringList crsList = QgsServerProjectUtils::wmsOutputCrsList( *project );
    if ( !tms_ref.isEmpty() && !crsList.contains( tms_ref ) )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) );
    }
    for ( const QString &crsStr : crsList )
    {
      if ( !tms_ref.isEmpty() && tms_ref != crsStr )
      {
        continue;
      }
      tileMatrixInfo tmi = calculateTileMatrixInfo( crsStr, project );
      if ( tmi.scaleDenominator > 0.0 )
      {
        tmsList.append( calculateTileMatrixSet( tmi, minScale ) );
      }
    }

    return tmsList;
  }
コード例 #3
0
ファイル: qgswmtsutils.cpp プロジェクト: alexbruy/QGIS
  QUrlQuery translateWmtsParamToWmsQueryItem( const QString &request, const QgsWmtsParameters &params,
      const QgsProject *project, QgsServerInterface *serverIface )
  {
#ifndef HAVE_SERVER_PYTHON_PLUGINS
    ( void )serverIface;
#endif

    //defining Layer
    QString layer = params.layer();
    //read Layer
    if ( layer.isEmpty() )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "Layer is mandatory" ) );
    }
    //check layer value
    bool wmtsProject = project->readBoolEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Project" ) );
    QStringList wmtsGroupNameList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Group" ) );
    QStringList wmtsLayerIdList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Layer" ) );
    QStringList wmtsLayerIds;
    if ( wmtsProject )
    {
      // Root Layer name
      QString rootLayerId = QgsServerProjectUtils::wmsRootName( *project );
      if ( rootLayerId.isEmpty() )
      {
        rootLayerId = project->title();
      }
      if ( !rootLayerId.isEmpty() )
      {
        wmtsLayerIds << rootLayerId;
      }
    }
    if ( !wmtsGroupNameList.isEmpty() )
    {
      QgsLayerTreeGroup *treeRoot = project->layerTreeRoot();
      for ( const QString &gName : wmtsGroupNameList )
      {
        QgsLayerTreeGroup *treeGroup = treeRoot->findGroup( gName );
        if ( !treeGroup )
        {
          continue;
        }
        QString groupLayerId = treeGroup->customProperty( QStringLiteral( "wmsShortName" ) ).toString();
        if ( groupLayerId.isEmpty() )
        {
          groupLayerId = gName;
        }
        wmtsLayerIds << groupLayerId;
      }
    }
    if ( !wmtsLayerIdList.isEmpty() )
    {
#ifdef HAVE_SERVER_PYTHON_PLUGINS
      QgsAccessControl *accessControl = serverIface->accessControls();
#endif
      for ( const QString &lId : wmtsLayerIdList )
      {
        QgsMapLayer *l = project->mapLayer( lId );
        if ( !l )
        {
          continue;
        }
#ifdef HAVE_SERVER_PYTHON_PLUGINS
        if ( !accessControl->layerReadPermission( l ) )
        {
          continue;
        }
#endif
        QString layerLayerId = l->shortName();
        if ( layerLayerId.isEmpty() )
        {
          layerLayerId = l->name();
        }
        wmtsLayerIds << layerLayerId;
      }
    }
    if ( !wmtsLayerIds.contains( layer ) )
    {
      QString msg = QObject::tr( "Layer '%1' not found" ).arg( layer );
      throw QgsBadRequestException( QStringLiteral( "LayerNotDefined" ), msg );
    }

    //defining Format
    QString format = params.formatAsString();
    //read Format
    if ( format.isEmpty() )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "Format is mandatory" ) );
    }

    //defining TileMatrixSet ref
    QString tms_ref = params.tileMatrixSet();
    //read TileMatrixSet
    if ( tms_ref.isEmpty() )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is mandatory" ) );
    }

    // verifying TileMatrixSet value
    QList< tileMatrixSetDef > tmsList = getTileMatrixSetList( project, tms_ref );
    if ( tmsList.isEmpty() )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) );
    }
    tileMatrixSetDef tms = tmsList[0];
    if ( tms.ref != tms_ref )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) );
    }

    //defining TileMatrix idx
    int tm_idx = params.tileMatrixAsInt();
    //read TileMatrix
    if ( tm_idx < 0 || tms.tileMatrixList.count() < tm_idx )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrix is unknown" ) );
    }
    tileMatrixDef tm = tms.tileMatrixList.at( tm_idx );

    //defining TileRow
    int tr = params.tileRowAsInt();
    //read TileRow
    if ( tr < 0 || tm.row <= tr )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileRow is unknown" ) );
    }

    //defining TileCol
    int tc = params.tileColAsInt();
    //read TileCol
    if ( tc < 0 || tm.col <= tc )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileCol is unknown" ) );
    }

    double res = tm.resolution;
    double minx = tm.left + tc * ( tileSize * res );
    double miny = tm.top - ( tr + 1 ) * ( tileSize * res );
    double maxx = tm.left + ( tc + 1 ) * ( tileSize * res );
    double maxy = tm.top - tr * ( tileSize * res );
    QString bbox;
    if ( tms.hasAxisInverted )
    {
      bbox = qgsDoubleToString( miny, 6 ) + ',' +
             qgsDoubleToString( minx, 6 ) + ',' +
             qgsDoubleToString( maxy, 6 ) + ',' +
             qgsDoubleToString( maxx, 6 );
    }
    else
    {
      bbox = qgsDoubleToString( minx, 6 ) + ',' +
             qgsDoubleToString( miny, 6 ) + ',' +
             qgsDoubleToString( maxx, 6 ) + ',' +
             qgsDoubleToString( maxy, 6 );
    }

    QUrlQuery query;
    if ( !params.value( QStringLiteral( "MAP" ) ).isEmpty() )
    {
      query.addQueryItem( QgsServerParameter::name( QgsServerParameter::MAP ), params.value( QStringLiteral( "MAP" ) ) );
    }
    query.addQueryItem( QgsServerParameter::name( QgsServerParameter::SERVICE ), QStringLiteral( "WMS" ) );
    query.addQueryItem( QgsServerParameter::name( QgsServerParameter::VERSION_SERVICE ), QStringLiteral( "1.3.0" ) );
    query.addQueryItem( QgsServerParameter::name( QgsServerParameter::REQUEST ), request );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::LAYERS ), layer );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::STYLES ), QString() );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::CRS ), tms.ref );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::BBOX ), bbox );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::WIDTH ), QStringLiteral( "256" ) );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::HEIGHT ), QStringLiteral( "256" ) );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::FORMAT ), format );
    if ( params.format() == QgsWmtsParameters::Format::PNG )
    {
      query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::TRANSPARENT ), QStringLiteral( "true" ) );
    }
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::DPI ), QStringLiteral( "96" ) );

    return query;
  }
コード例 #4
0
  QgsFeatureRequest parseFilterElement( const QString &typeName, QDomElement &filterElem, const QgsProject *project )
  {
    QgsFeatureRequest request;

    QDomNodeList fidNodes = filterElem.elementsByTagName( QStringLiteral( "FeatureId" ) );
    QDomNodeList goidNodes = filterElem.elementsByTagName( QStringLiteral( "GmlObjectId" ) );
    if ( !fidNodes.isEmpty() )
    {
      QgsFeatureIds fids;
      QDomElement fidElem;
      for ( int f = 0; f < fidNodes.size(); f++ )
      {
        fidElem = fidNodes.at( f ).toElement();
        if ( !fidElem.hasAttribute( QStringLiteral( "fid" ) ) )
        {
          throw QgsRequestNotWellFormedException( "FeatureId element without fid attribute" );
        }

        QString fid = fidElem.attribute( QStringLiteral( "fid" ) );
        if ( fid.contains( QLatin1String( "." ) ) )
        {
          if ( fid.section( QStringLiteral( "." ), 0, 0 ) != typeName )
            continue;
          fid = fid.section( QStringLiteral( "." ), 1, 1 );
        }
        fids.insert( fid.toInt() );
      }

      if ( !fids.isEmpty() )
      {
        request.setFilterFids( fids );
      }
      else
      {
        throw QgsRequestNotWellFormedException( QStringLiteral( "No FeatureId element correctly parse against typeName '%1'" ).arg( typeName ) );
      }
      request.setFlags( QgsFeatureRequest::NoFlags );
      return request;
    }
    else if ( !goidNodes.isEmpty() )
    {
      QgsFeatureIds fids;
      QDomElement goidElem;
      for ( int f = 0; f < goidNodes.size(); f++ )
      {
        goidElem = goidNodes.at( f ).toElement();
        if ( !goidElem.hasAttribute( QStringLiteral( "id" ) ) && !goidElem.hasAttribute( QStringLiteral( "gml:id" ) ) )
        {
          throw QgsRequestNotWellFormedException( "GmlObjectId element without gml:id attribute" );
        }

        QString fid = goidElem.attribute( QStringLiteral( "id" ) );
        if ( fid.isEmpty() )
          fid = goidElem.attribute( QStringLiteral( "gml:id" ) );
        if ( fid.contains( QLatin1String( "." ) ) )
        {
          if ( fid.section( QStringLiteral( "." ), 0, 0 ) != typeName )
            continue;
          fid = fid.section( QStringLiteral( "." ), 1, 1 );
        }
        fids.insert( fid.toInt() );
      }

      if ( !fids.isEmpty() )
      {
        request.setFilterFids( fids );
      }
      else
      {
        throw QgsRequestNotWellFormedException( QStringLiteral( "No GmlObjectId element correctly parse against typeName '%1'" ).arg( typeName ) );
      }
      request.setFlags( QgsFeatureRequest::NoFlags );
      return request;
    }
    else if ( filterElem.firstChildElement().tagName() == QLatin1String( "BBOX" ) )
    {
      QDomElement bboxElem = filterElem.firstChildElement();
      QDomElement childElem = bboxElem.firstChildElement();

      while ( !childElem.isNull() )
      {
        if ( childElem.tagName() == QLatin1String( "Box" ) )
        {
          request.setFilterRect( QgsOgcUtils::rectangleFromGMLBox( childElem ) );
        }
        else if ( childElem.tagName() != QLatin1String( "PropertyName" ) )
        {
          QgsGeometry geom = QgsOgcUtils::geometryFromGML( childElem );
          request.setFilterRect( geom.boundingBox() );
        }
        childElem = childElem.nextSiblingElement();
      }
      request.setFlags( QgsFeatureRequest::ExactIntersect | QgsFeatureRequest::NoFlags );
      return request;
    }
    // Apply BBOX through filterRect even inside an And to use spatial index
    else if ( filterElem.firstChildElement().tagName() == QLatin1String( "And" ) &&
              !filterElem.firstChildElement().firstChildElement( QLatin1String( "BBOX" ) ).isNull() )
    {
      QDomElement childElem = filterElem.firstChildElement().firstChildElement();
      while ( !childElem.isNull() )
      {
        QDomElement childFilterElement = filterElem.ownerDocument().createElement( QLatin1String( "Filter" ) );
        childFilterElement.appendChild( childElem.cloneNode( true ) );
        QgsFeatureRequest childRequest = parseFilterElement( typeName, childFilterElement );
        if ( childElem.tagName() == QLatin1String( "BBOX" ) )
        {
          if ( request.filterRect().isEmpty() )
          {
            request.setFilterRect( childRequest.filterRect() );
          }
          else
          {
            request.setFilterRect( request.filterRect().intersect( childRequest.filterRect() ) );
          }
        }
        else
        {
          if ( !request.filterExpression() )
          {
            request.setFilterExpression( childRequest.filterExpression()->expression() );
          }
          else
          {
            QgsExpressionNode *opLeft = request.filterExpression()->rootNode()->clone();
            QgsExpressionNode *opRight = childRequest.filterExpression()->rootNode()->clone();
            std::unique_ptr<QgsExpressionNodeBinaryOperator> node = qgis::make_unique<QgsExpressionNodeBinaryOperator>( QgsExpressionNodeBinaryOperator::boAnd, opLeft, opRight );
            QgsExpression expr( node->dump() );
            request.setFilterExpression( expr );
          }
        }
        childElem = childElem.nextSiblingElement();
      }
      request.setFlags( QgsFeatureRequest::ExactIntersect | QgsFeatureRequest::NoFlags );
      return request;
    }
    else
    {
      QgsVectorLayer *layer = nullptr;
      if ( project != nullptr )
      {
        layer = layerByTypeName( project, typeName );
      }
      std::shared_ptr<QgsExpression> filter( QgsOgcUtils::expressionFromOgcFilter( filterElem, layer ) );
      if ( filter )
      {
        if ( filter->hasParserError() )
        {
          throw QgsRequestNotWellFormedException( filter->parserErrorString() );
        }

        if ( filter->needsGeometry() )
        {
          request.setFlags( QgsFeatureRequest::NoFlags );
        }
        request.setFilterExpression( filter->expression() );
        return request;
      }
    }
    return request;
  }