Exemplo n.º 1
0
void QgsHttpRequestHandler::setGetMapResponse( const QString& service, QImage* img, int imageQuality = -1 )
{
  Q_UNUSED( service );
  QgsMessageLog::logMessage( "setting getmap response..." );
  if ( img )
  {
    bool png16Bit = ( mFormatString.compare( "image/png; mode=16bit", Qt::CaseInsensitive ) == 0 );
    bool png8Bit = ( mFormatString.compare( "image/png; mode=8bit", Qt::CaseInsensitive ) == 0 );
    bool png1Bit = ( mFormatString.compare( "image/png; mode=1bit", Qt::CaseInsensitive ) == 0 );
    bool isBase64 = mFormatString.endsWith( ";base64", Qt::CaseInsensitive );
    if ( mFormat != "PNG" && mFormat != "JPG" && !png16Bit && !png8Bit && !png1Bit )
    {
      QgsMessageLog::logMessage( "service exception - incorrect image format requested..." );
      setServiceException( QgsMapServiceException( "InvalidFormat", "Output format '" + mFormatString + "' is not supported in the GetMap request" ) );
      return;
    }

    //store the image in a QByteArray and set it directly
    QByteArray ba;
    QBuffer buffer( &ba );
    buffer.open( QIODevice::WriteOnly );

    // Do not use imageQuality for PNG images
    // For now, QImage expects quality to be a range 0-9 for PNG
    if ( mFormat == "PNG" )
    {
      imageQuality = -1;
    }

    if ( png8Bit )
    {
      QVector<QRgb> colorTable;
      medianCut( colorTable, 256, *img );
      QImage palettedImg = img->convertToFormat( QImage::Format_Indexed8, colorTable, Qt::ColorOnly | Qt::ThresholdDither |
                           Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
      palettedImg.save( &buffer, "PNG", imageQuality );
    }
    else if ( png16Bit )
    {
      QImage palettedImg = img->convertToFormat( QImage::Format_ARGB4444_Premultiplied );
      palettedImg.save( &buffer, "PNG", imageQuality );
    }
    else if ( png1Bit )
    {
      QImage palettedImg = img->convertToFormat( QImage::Format_Mono, Qt::MonoOnly | Qt::ThresholdDither |
                           Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
      palettedImg.save( &buffer, "PNG", imageQuality );
    }
    else
    {
      img->save( &buffer, mFormat.toUtf8().data(), imageQuality );
    }

    if ( isBase64 )
    {
      ba = ba.toBase64();
    }
    setHttpResponse( &ba, formatToMimeType( mFormat ) );
  }
}
Exemplo n.º 2
0
QDomDocument QgsSLDConfigParser::getStyle( const QString& styleName, const QString& layerName ) const
{
  QDomElement userLayerElement = findUserLayerElement( layerName );

  if ( userLayerElement.isNull() )
  {
    throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request is for a Layer not offered by the server." ) );
  }

  QDomElement userStyleElement = findUserStyleElement( userLayerElement, styleName );

  if ( userStyleElement.isNull() )
  {
    throw QgsMapServiceException( QStringLiteral( "StyleNotDefined" ), QStringLiteral( "Operation request references a Style not offered by the server." ) );
  }

  QDomDocument styleDoc;
  styleDoc.appendChild( styleDoc.importNode( userStyleElement, true ) );
  return styleDoc;
}
Exemplo n.º 3
0
QgsFeatureRenderer* QgsSLDConfigParser::rendererFromUserStyle( const QDomElement& userStyleElement, QgsVectorLayer* vec ) const
{
  if ( !vec || userStyleElement.isNull() )
  {
    return nullptr;
  }

  QgsDebugMsg( "Entering" );

  QString errorMessage;
  QgsFeatureRenderer* renderer = QgsFeatureRenderer::loadSld( userStyleElement.parentNode(), vec->geometryType(), errorMessage );
  if ( !renderer )
  {
    throw QgsMapServiceException( QStringLiteral( "SLD error" ), errorMessage );
  }
  return renderer;
}
Exemplo n.º 4
0
void QgsGetRequestHandler::sendGetMapResponse( const QString& service, QImage* img ) const
{
  if ( img )
  {
    if ( mFormat != "PNG" && mFormat != "JPG" )
    {
      sendServiceException( QgsMapServiceException( "InvalidFormat", "Output format '" + mFormat + "' is not supported in the GetMap request" ) );
      return;
    }

    //store the image in a QByteArray and send it directly
    QByteArray ba;
    QBuffer buffer( &ba );
    buffer.open( QIODevice::WriteOnly );
    img->save( &buffer, mFormat.toLocal8Bit().data(), -1 );

    sendHttpResponse( &ba, formatToMimeType( mFormat ) );
  }
}
Exemplo n.º 5
0
QDomDocument QgsSLDConfigParser::getStyles( QStringList& layerList ) const
{
  QDomDocument styleDoc;
  for ( int i = 0; i < layerList.size(); i++ )
  {
    QString layerName;
    layerName = layerList.at( i );
    QDomElement userLayerElement = findUserLayerElement( layerName );
    if ( userLayerElement.isNull() )
    {
      throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request is for a Layer not offered by the server." ) );
    }
    QDomNodeList userStyleList = userLayerElement.elementsByTagName( QStringLiteral( "UserStyle" ) );
    for ( int j = 0; j < userStyleList.size(); j++ )
    {
      QDomElement userStyleElement = userStyleList.item( i ).toElement();
      styleDoc.appendChild( styleDoc.importNode( userStyleElement, true ) );
    }
  }
  return styleDoc;
}
Exemplo n.º 6
0
void QgsSOAPRequestHandler::parseInput()
{
  QString inputString = readPostBody();

  //QgsDebugMsg("input string is: " + inputString)

  //inputString to QDomDocument
  QDomDocument inputXML;
  QString errorMsg;
  if ( !inputXML.setContent( inputString, true, &errorMsg ) )
  {
    QgsDebugMsg( "soap request parse error" );
    QgsDebugMsg( "error message: " + errorMsg );
    QgsDebugMsg( "the xml string was:" );
    QgsDebugMsg( inputString );
    throw QgsMapServiceException( "InvalidXML", "XML error: " + errorMsg );
  }

  // if xml reading was successfull, save the inputXML in a file
  QFile soapFile;
  QTextStream soapStream;

  //go through soap envelope->soap body, search for either GetCapabilities or GetMap
  QDomNodeList envelopeNodeList = inputXML.elementsByTagNameNS( "http://schemas.xmlsoap.org/soap/envelope/", "Envelope" );
  if ( envelopeNodeList.size() < 1 )
  {
    QgsDebugMsg( "Envelope element not found" );
    throw QgsMapServiceException( "SOAPError", "Element <Envelope> not found" );
  }

  QDomNodeList bodyNodeList = envelopeNodeList.item( 0 ).toElement().elementsByTagNameNS( "http://schemas.xmlsoap.org/soap/envelope/", "Body" );
  if ( bodyNodeList.size() < 1 )
  {
    QgsDebugMsg( "body node not found" );
    throw QgsMapServiceException( "SOAPError", "Element <Body> not found" );
  }
  QDomElement bodyElement = bodyNodeList.item( 0 ).toElement();
  QDomElement firstChildElement = bodyElement.firstChild().toElement();

  QString serviceString = firstChildElement.attribute( "service" );
  if ( serviceString == "MS" )
  {
    QgsDebugMsg( "service = MS " );
    mParameterMap.insert( "SERVICE", "MS" );
    mService = "MS";
  }
  else if ( serviceString == "WMS" )
  {
    mParameterMap.insert( "SERVICE", "WMS" );
    mService = "WMS";
  }
  else if ( serviceString == "MDS" )
  {
    mParameterMap.insert( "SERVICE", "MDS" );
    mService = "MDS";
  }
  else if ( serviceString == "MAS" )
  {
    mParameterMap.insert( "SERVICE", "MAS" );
    mService = "MAS";
  }
  else
  {
    mParameterMap.insert( "SERVICE", "DISCOVERY" );
    mService = "DISCOVERY";
  }


  //GetCapabilities request
  //if(firstChildElement.localName().compare("getCapabilities", Qt::CaseInsensitive) == 0)
  if ( firstChildElement.localName() == "GetCapabilities" || firstChildElement.localName() == "getCapabilities" )
  {
    mParameterMap.insert( "REQUEST", "GetCapabilities" );
  }
  //GetMap request
  //else if(firstChildElement.tagName().compare("getMap",Qt::CaseInsensitive) == 0)
  else if ( firstChildElement.localName() == "GetMap" || firstChildElement.localName() == "getMap" )
  {
    mParameterMap.insert( "REQUEST", "GetMap" );
    parseGetMapElement( mParameterMap, firstChildElement );
  }
  //GetDiagram request
  //else if(firstChildElement.tagName().compare("getDiagram", Qt::CaseInsensitive) == 0)
  else if ( firstChildElement.localName() == "GetDiagram" )
  {
    mParameterMap.insert( "REQUEST", "GetDiagram" );
    parseGetMapElement( mParameterMap, firstChildElement ); //reuse the method for GetMap
  }
  //GetFeatureInfo request
  else if ( firstChildElement.localName() == "GetFeatureInfo" )
  {
    mParameterMap.insert( "REQUEST", "GetFeatureInfo" );
    parseGetFeatureInfoElement( mParameterMap, firstChildElement );
  }

  //set mFormat
  QString formatString = mParameterMap.value( "FORMAT" );
  if ( !formatString.isEmpty() )
  {
    //remove the image/ in front of the format
    if ( formatString == "image/jpeg" || formatString == "JPG" || formatString == "jpg" )
    {
      formatString = "JPG";
    }
    else if ( formatString == "image/png" || formatString == "PNG" || formatString == "png" )
    {
      formatString = "PNG";
    }
    else if ( formatString == "image/gif" || formatString == "GIF" || formatString == "gif" )
    {
      formatString = "GIF";
    }
    else
    {
      throw QgsMapServiceException( "InvalidFormat", "Invalid format " + formatString + ", only jpg and png are supported" );
    }

    mFormat = formatString;
  }
}
Exemplo n.º 7
0
void QgsWCSServer::executeRequest()
{
  //request type
  QString request = mParameters.value( "REQUEST" );
  if ( request.isEmpty() )
  {
    //do some error handling
    QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
    mRequestHandler->setServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
    return;
  }

  if ( request.compare( "GetCapabilities", Qt::CaseInsensitive ) == 0 )
  {
    QDomDocument capabilitiesDocument;
    try
    {
      capabilitiesDocument = getCapabilities();
    }
    catch ( QgsMapServiceException& ex )
    {
      mRequestHandler->setServiceException( ex );
      return;
    }
    QgsDebugMsg( "seting GetCapabilities response" );
    mRequestHandler->setGetCapabilitiesResponse( capabilitiesDocument );
    return;
  }
  else if ( request.compare( "DescribeCoverage", Qt::CaseInsensitive ) == 0 )
  {
    QDomDocument describeDocument;
    try
    {
      describeDocument = describeCoverage();
    }
    catch ( QgsMapServiceException& ex )
    {
      mRequestHandler->setServiceException( ex );
      return;
    }
    QgsDebugMsg( "seting GetCapabilities response" );
    mRequestHandler->setGetCapabilitiesResponse( describeDocument );
    return;
  }
  else if ( request.compare( "GetCoverage", Qt::CaseInsensitive ) == 0 )
  {
    QByteArray* coverageOutput;
    try
    {
      coverageOutput = getCoverage();
    }
    catch ( QgsMapServiceException& ex )
    {
      mRequestHandler->setServiceException( ex );
      return;
    }
    if ( coverageOutput )
    {
      mRequestHandler->setGetCoverageResponse( coverageOutput );
    }
    return;
  }
}
Exemplo n.º 8
0
QByteArray* QgsWCSServer::getCoverage()
{
  QStringList wcsLayersId = mConfigParser->wcsLayers();

  QList<QgsMapLayer*> layerList;

  QStringList mErrors = QStringList();

  //defining coverage name
  QString coveName = "";
  //read COVERAGE
  QMap<QString, QString>::const_iterator cove_name_it = mParameters.find( "COVERAGE" );
  if ( cove_name_it != mParameters.end() )
  {
    coveName = cove_name_it.value();
  }
  if ( coveName == "" )
  {
    QMap<QString, QString>::const_iterator cove_name_it = mParameters.find( "IDENTIFIER" );
    if ( cove_name_it != mParameters.end() )
    {
      coveName = cove_name_it.value();
    }
  }

  if ( coveName == "" )
  {
    mErrors << QString( "COVERAGE is mandatory" );
  }

  layerList = mConfigParser->mapLayerFromCoverage( coveName );
  if ( layerList.size() < 1 )
  {
    mErrors << QString( "The layer for the COVERAGE '%1' is not found" ).arg( coveName );
  }

  bool conversionSuccess;
  // BBOX
  bool bboxOk = false;
  double minx = 0.0, miny = 0.0, maxx = 0.0, maxy = 0.0;
  // WIDTh and HEIGHT
  int width = 0, height = 0;
  // CRS
  QString crs = "";

  // read BBOX
  QMap<QString, QString>::const_iterator bbIt = mParameters.find( "BBOX" );
  if ( bbIt == mParameters.end() )
  {
    minx = 0; miny = 0; maxx = 0; maxy = 0;
  }
  else
  {
    bboxOk = true;
    QString bbString = bbIt.value();
    minx = bbString.section( ",", 0, 0 ).toDouble( &conversionSuccess );
    if ( !conversionSuccess ) {bboxOk = false;}
    miny = bbString.section( ",", 1, 1 ).toDouble( &conversionSuccess );
    if ( !conversionSuccess ) {bboxOk = false;}
    maxx = bbString.section( ",", 2, 2 ).toDouble( &conversionSuccess );
    if ( !conversionSuccess ) {bboxOk = false;}
    maxy = bbString.section( ",", 3, 3 ).toDouble( &conversionSuccess );
    if ( !conversionSuccess ) {bboxOk = false;}
  }
  if ( !bboxOk )
  {
    mErrors << QString( "The BBOX is mandatory and has to be xx.xxx,yy.yyy,xx.xxx,yy.yyy" );
  }

  // read WIDTH
  width = mParameters.value( "WIDTH", "0" ).toInt( &conversionSuccess );
  if ( !conversionSuccess )
    width = 0;
  // read HEIGHT
  height = mParameters.value( "HEIGHT", "0" ).toInt( &conversionSuccess );
  if ( !conversionSuccess )
  {
    height = 0;
  }

  if ( width < 0 || height < 0 )
  {
    mErrors << QString( "The WIDTH and HEIGHT are mandatory and have to be integer" );
  }

  crs = mParameters.value( "CRS", "" );
  if ( crs == "" )
  {
    mErrors << QString( "The CRS is mandatory" );
  }

  if ( mErrors.count() != 0 )
  {
    throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
  }

  QgsCoordinateReferenceSystem requestCRS = QgsCRSCache::instance()->crsByAuthId( crs );
  if ( !requestCRS.isValid() )
  {
    mErrors << QString( "Could not create request CRS" );
    throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
  }

  QgsRectangle rect( minx, miny, maxx, maxy );

  QgsMapLayer* layer = layerList.at( 0 );
  QgsRasterLayer* rLayer = dynamic_cast<QgsRasterLayer*>( layer );
  if ( rLayer && wcsLayersId.contains( rLayer->id() ) )
  {
    // RESPONSE_CRS
    QgsCoordinateReferenceSystem responseCRS = rLayer->crs();
    crs = mParameters.value( "RESPONSE_CRS", "" );
    if ( crs != "" )
    {
      responseCRS = QgsCRSCache::instance()->crsByAuthId( crs );
      if ( !responseCRS.isValid() )
      {
        responseCRS = rLayer->crs();
      }
    }

    // transform rect
    if ( requestCRS != rLayer->crs() )
    {
      QgsCoordinateTransform t( requestCRS, rLayer->crs() );
      rect = t.transformBoundingBox( rect );
    }

    QTemporaryFile tempFile;
    tempFile.open();
    QgsRasterFileWriter fileWriter( tempFile.fileName() );

    // clone pipe/provider
    QgsRasterPipe* pipe = new QgsRasterPipe();
    if ( !pipe->set( rLayer->dataProvider()->clone() ) )
    {
      mErrors << QString( "Cannot set pipe provider" );
      throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
    }

    // add projector if necessary
    if ( responseCRS != rLayer->crs() )
    {
      QgsRasterProjector * projector = new QgsRasterProjector;
      projector->setCRS( rLayer->crs(), responseCRS );
      if ( !pipe->insert( 2, projector ) )
      {
        mErrors << QString( "Cannot set pipe projector" );
        throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
      }
    }

    QgsRasterFileWriter::WriterError err = fileWriter.writeRaster( pipe, width, height, rect, responseCRS );
    if ( err != QgsRasterFileWriter::NoError )
    {
      mErrors << QString( "Cannot write raster error code: %1" ).arg( err );
      throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
    }
    delete pipe;
    QByteArray* ba = 0;
    ba = new QByteArray();
    *ba = tempFile.readAll();

    return ba;
  }
  return 0;
}
Exemplo n.º 9
0
QgsComposition* QgsProjectParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList ) const
{
  //Create composition from xml
  QDomElement composerElem = composerByName( composerTemplate );
  if ( composerElem.isNull() )
  {
    throw QgsMapServiceException( "Error", "Composer template not found" );
  }

  QDomElement compositionElem = composerElem.firstChildElement( "Composition" );
  if ( compositionElem.isNull() )
  {
    return 0;
  }

  QgsComposition* composition = new QgsComposition( mapRenderer ); //set resolution, paper size from composer element attributes
  if ( !composition->readXML( compositionElem, *mXMLDoc ) )
  {
    delete composition;
    return 0;
  }

  //go through all the item elements and add them to the composition (and to the lists)
  QDomNodeList itemNodes = composerElem.childNodes();
  for ( int i = 0; i < itemNodes.size(); ++i )
  {
    QDomElement currentElem = itemNodes.at( i ).toElement();
    QString elemName = currentElem.tagName();
    if ( elemName == "ComposerMap" )
    {
      QgsComposerMap* map = new QgsComposerMap( composition );
      map->readXML( currentElem, *mXMLDoc );
      composition->addItem( map );
      mapList.push_back( map );
    }
    else if ( elemName == "ComposerLabel" )
    {
      QgsComposerLabel* label = new QgsComposerLabel( composition );
      label->readXML( currentElem, *mXMLDoc );
      composition->addItem( label );
      labelList.push_back( label );
    }
    else if ( elemName == "ComposerLegend" )
    {
      //legend needs to be loaded indirectly to have generic content
      //and to avoid usage of x-server with pixmap icons

      //read full legend from xml
      QgsComposerLegend* legend = new QgsComposerLegend( composition );
      legend->readXML( currentElem, *mXMLDoc );

      //dynamic legend (would be interesting in case of layers dynamically defined in SLD)
      //legend->_readXML( currentElem.firstChildElement( "ComposerItem" ), *mXMLDoc );
      //legend->updateLegend();
      composition->addItem( legend );
    }
    else if ( elemName == "ComposerShape" )
    {
      QgsComposerShape* shape = new QgsComposerShape( composition );
      shape->readXML( currentElem, *mXMLDoc );
      composition->addItem( shape );
    }
    else if ( elemName == "ComposerArrow" )
    {
      QgsComposerArrow* arrow = new QgsComposerArrow( composition );
      arrow->readXML( currentElem, *mXMLDoc );
      composition->addItem( arrow );
    }
    else if ( elemName == "ComposerAttributeTable" )
    {
      QgsComposerAttributeTable* table = new QgsComposerAttributeTable( composition );
      table->readXML( currentElem, *mXMLDoc );
      composition->addItem( table );
    }
  }

  //scalebars and pictures need to be loaded after the maps to receive the correct size / rotation
  for ( int i = 0; i < itemNodes.size(); ++i )
  {
    QDomElement currentElem = itemNodes.at( i ).toElement();
    QString elemName = currentElem.tagName();
    if ( elemName == "ComposerPicture" )
    {
      QgsComposerPicture* picture = new QgsComposerPicture( composition );
      picture->readXML( currentElem, *mXMLDoc );
      //qgis mapserver needs an absolute file path
      picture->setPictureFile( convertToAbsolutePath( picture->pictureFile() ) );
      composition->addItem( picture );
    }
    else if ( elemName == "ComposerScaleBar" )
    {
      QgsComposerScaleBar* bar = new QgsComposerScaleBar( composition );
      bar->readXML( currentElem, *mXMLDoc );
      composition->addItem( bar );
    }
  }

  return composition;
}
Exemplo n.º 10
0
void QgsHttpRequestHandler::setGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat )
{
  QByteArray ba;
  QgsMessageLog::logMessage( "Info format is:" + infoFormat );

  if ( infoFormat == "text/xml" || infoFormat.startsWith( "application/vnd.ogc.gml" ) )
  {
    ba = infoDoc.toByteArray();
  }
  else if ( infoFormat == "text/plain" || infoFormat == "text/html" )
  {
    //create string
    QString featureInfoString;

    if ( infoFormat == "text/plain" )
    {
      featureInfoString.append( "GetFeatureInfo results\n" );
      featureInfoString.append( "\n" );
    }
    else if ( infoFormat == "text/html" )
    {
      featureInfoString.append( "<HEAD>\n" );
      featureInfoString.append( "<TITLE> GetFeatureInfo results </TITLE>\n" );
      featureInfoString.append( "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n" );
      featureInfoString.append( "</HEAD>\n" );
      featureInfoString.append( "<BODY>\n" );
    }

    QDomNodeList layerList = infoDoc.elementsByTagName( "Layer" );

    //layer loop
    for ( int i = 0; i < layerList.size(); ++i )
    {
      QDomElement layerElem = layerList.at( i ).toElement();
      if ( infoFormat == "text/plain" )
      {
        featureInfoString.append( "Layer '" + layerElem.attribute( "name" ) + "'\n" );
      }
      else if ( infoFormat == "text/html" )
      {
        featureInfoString.append( "<TABLE border=1 width=100%>\n" );
        featureInfoString.append( "<TR><TH width=25%>Layer</TH><TD>" + layerElem.attribute( "name" ) + "</TD></TR>\n" );
        featureInfoString.append( "</BR>" );
      }

      //feature loop (for vector layers)
      QDomNodeList featureNodeList = layerElem.elementsByTagName( "Feature" );
      QDomElement currentFeatureElement;

      if ( featureNodeList.size() < 1 ) //raster layer?
      {
        QDomNodeList attributeNodeList = layerElem.elementsByTagName( "Attribute" );
        for ( int j = 0; j < attributeNodeList.size(); ++j )
        {
          QDomElement attributeElement = attributeNodeList.at( j ).toElement();
          if ( infoFormat == "text/plain" )
          {
            featureInfoString.append( attributeElement.attribute( "name" ) + " = '" +
                                      attributeElement.attribute( "value" ) + "'\n" );
          }
          else if ( infoFormat == "text/html" )
          {
            featureInfoString.append( "<TR><TH>" + attributeElement.attribute( "name" ) + "</TH><TD>" +
                                      attributeElement.attribute( "value" ) + "</TD></TR>\n" );
          }
        }
      }
      else //vector layer
      {
        for ( int j = 0; j < featureNodeList.size(); ++j )
        {
          QDomElement featureElement = featureNodeList.at( j ).toElement();
          if ( infoFormat == "text/plain" )
          {
            featureInfoString.append( "Feature " + featureElement.attribute( "id" ) + "\n" );
          }
          else if ( infoFormat == "text/html" )
          {
            featureInfoString.append( "<TABLE border=1 width=100%>\n" );
            featureInfoString.append( "<TR><TH>Feature</TH><TD>" + featureElement.attribute( "id" ) + "</TD></TR>\n" );
          }
          //attribute loop
          QDomNodeList attributeNodeList = featureElement.elementsByTagName( "Attribute" );
          for ( int k = 0; k < attributeNodeList.size(); ++k )
          {
            QDomElement attributeElement = attributeNodeList.at( k ).toElement();
            if ( infoFormat == "text/plain" )
            {
              featureInfoString.append( attributeElement.attribute( "name" ) + " = '" +
                                        attributeElement.attribute( "value" ) + "'\n" );
            }
            else if ( infoFormat == "text/html" )
            {
              featureInfoString.append( "<TR><TH>" + attributeElement.attribute( "name" ) + "</TH><TD>" + attributeElement.attribute( "value" ) + "</TD></TR>\n" );
            }
          }

          if ( infoFormat == "text/html" )
          {
            featureInfoString.append( "</TABLE>\n</BR>\n" );
          }
        }
      }
      if ( infoFormat == "text/plain" )
      {
        featureInfoString.append( "\n" );
      }
      else if ( infoFormat == "text/html" )
      {
        featureInfoString.append( "</TABLE>\n<BR></BR>\n" );

      }
    }
    if ( infoFormat == "text/html" )
    {
      featureInfoString.append( "</BODY>\n" );
    }
    ba = featureInfoString.toUtf8();
  }
  else //unsupported format, set exception
  {
    setServiceException( QgsMapServiceException( "InvalidFormat", "Feature info format '" + mFormat + "' is not supported. Possibilities are 'text/plain', 'text/html' or 'text/xml'." ) );
    return;
  }

  setHttpResponse( &ba, infoFormat );
}
Exemplo n.º 11
0
/**
 * @brief Handles the request
 * @param queryString
 * @return response headers and body
 */
QPair<QByteArray, QByteArray> QgsServer::handleRequest( const QString& queryString )
{
  // Run init if handleRequest was called without previously initialising
  // the server
  if ( ! mInitialised )
  {
    init();
  }

  /*
   * This is mainly for python bindings, passing QUERY_STRING
   * to handleRequest without using os.environment
   */
  if ( ! queryString.isEmpty() )
    putenv( "QUERY_STRING", queryString );

  int logLevel = QgsServerLogger::instance()->logLevel();
  QTime time; //used for measuring request time if loglevel < 1
  QgsMapLayerRegistry::instance()->removeAllMapLayers();
  mQgsApplication->processEvents();
  if ( logLevel < 1 )
  {
    time.start();
    printRequestInfos();
  }

  //Request handler
  QScopedPointer<QgsRequestHandler> theRequestHandler( createRequestHandler( mCaptureOutput ) );

  try
  {
    // TODO: split parse input into plain parse and processing from specific services
    theRequestHandler->parseInput();
  }
  catch ( QgsMapServiceException& e )
  {
    QgsMessageLog::logMessage( "Parse input exception: " + e.message(), "Server", QgsMessageLog::CRITICAL );
    theRequestHandler->setServiceException( e );
  }

#ifdef HAVE_SERVER_PYTHON_PLUGINS
  // Set the request handler into the interface for plugins to manipulate it
  mServerInterface->setRequestHandler( theRequestHandler.data() );
  // Iterate filters and call their requestReady() method
  QgsServerFiltersMap::const_iterator filtersIterator;
  QgsServerFiltersMap filters = mServerInterface->filters();
  for ( filtersIterator = filters.constBegin(); filtersIterator != filters.constEnd(); ++filtersIterator )
  {
    filtersIterator.value()->requestReady();
  }

  //Pass the filters to the requestHandler, this is needed for the following reasons:
  // 1. allow core services to access plugin filters and implement thir own plugin hooks
  // 2. allow requestHandler to call sendResponse plugin hook
  theRequestHandler->setPluginFilters( mServerInterface->filters() );
#endif

  // Copy the parameters map
  QMap<QString, QString> parameterMap( theRequestHandler->parameterMap() );
#ifdef HAVE_SERVER_PYTHON_PLUGINS
  const QgsAccessControl* accessControl = nullptr;
  accessControl = mServerInterface->accessControls();
#endif

  printRequestParameters( parameterMap, logLevel );
  QMap<QString, QString>::const_iterator paramIt;
  //Config file path
  QString configFilePath = configPath( mConfigFilePath, parameterMap );
#ifdef HAVE_SERVER_PYTHON_PLUGINS
  mServerInterface->setConfigFilePath( configFilePath );
#endif
  //Service parameter
  QString serviceString = theRequestHandler->parameter( "SERVICE" );

  if ( serviceString.isEmpty() )
  {
    // SERVICE not mandatory for WMS 1.3.0 GetMap & GetFeatureInfo
    QString requestString = theRequestHandler->parameter( "REQUEST" );
    if ( requestString == "GetMap" || requestString == "GetFeatureInfo" )
    {
      serviceString = "WMS";
    }
  }

  //possibility for client to suggest a download filename
  QString outputFileName = theRequestHandler->parameter( "FILE_NAME" );
  if ( !outputFileName.isEmpty() )
  {
    theRequestHandler->setDefaultHeaders();
    theRequestHandler->setHeader( "Content-Disposition", "attachment; filename=\"" + outputFileName + "\"" );
  }

  // Enter core services main switch
  if ( !theRequestHandler->exceptionRaised() )
  {
    if ( serviceString == "WCS" )
    {
      QgsWCSProjectParser* p = QgsConfigCache::instance()->wcsConfiguration(
                                 configFilePath
#ifdef HAVE_SERVER_PYTHON_PLUGINS
                                 , accessControl
#endif
                               );
      if ( !p )
      {
        theRequestHandler->setServiceException( QgsMapServiceException( "Project file error", QString( "Error reading the project file: %1" ).arg( configFilePath ) ) );
      }
      else
      {
        QgsWCSServer wcsServer(
          configFilePath
          , parameterMap
          , p
          , theRequestHandler.data()
#ifdef HAVE_SERVER_PYTHON_PLUGINS
          , accessControl
#endif
        );
        wcsServer.executeRequest();
      }
    }
    else if ( serviceString == "WFS" )
    {
      QgsWFSProjectParser* p = QgsConfigCache::instance()->wfsConfiguration(
                                 configFilePath
#ifdef HAVE_SERVER_PYTHON_PLUGINS
                                 , accessControl
#endif
                               );
      if ( !p )
      {
        theRequestHandler->setServiceException( QgsMapServiceException( "Project file error", QString( "Error reading the project file: %1" ).arg( configFilePath ) ) );
      }
      else
      {
        QgsWFSServer wfsServer(
          configFilePath
          , parameterMap
          , p
          , theRequestHandler.data()
#ifdef HAVE_SERVER_PYTHON_PLUGINS
          , accessControl
#endif
        );
        wfsServer.executeRequest();
      }
    }
    else if ( serviceString == "WMS" )
    {
      QgsWMSConfigParser* p = QgsConfigCache::instance()->wmsConfiguration(
                                configFilePath
#ifdef HAVE_SERVER_PYTHON_PLUGINS
                                , accessControl
#endif
                              );
      if ( !p )
      {
        theRequestHandler->setServiceException( QgsMapServiceException( "WMS configuration error", "There was an error reading the project file or the SLD configuration" ) );
      }
      else
      {
        QgsWMSServer wmsServer(
          configFilePath
          , parameterMap
          , p
          , theRequestHandler.data()
          , mMapRenderer
          , mCapabilitiesCache
#ifdef HAVE_SERVER_PYTHON_PLUGINS
          , accessControl
#endif
        );
        wmsServer.executeRequest();
      }
    }
    else
    {
      theRequestHandler->setServiceException( QgsMapServiceException( "Service configuration error", "Service unknown or unsupported" ) );
    } // end switch
  } // end if not exception raised

#ifdef HAVE_SERVER_PYTHON_PLUGINS
  // Iterate filters and call their responseComplete() method
  filters = mServerInterface->filters();
  for ( filtersIterator = filters.constBegin(); filtersIterator != filters.constEnd(); ++filtersIterator )
  {
    filtersIterator.value()->responseComplete();
  }
  // We are done using theRequestHandler in plugins, make sure we don't access
  // to a deleted request handler from Python bindings
  mServerInterface->clearRequestHandler();
#endif

  theRequestHandler->sendResponse();

  if ( logLevel < 1 )
  {
    QgsMessageLog::logMessage( "Request finished in " + QString::number( time.elapsed() ) + " ms", "Server", QgsMessageLog::INFO );
  }
  // Returns the header and response bytestreams (to be used in Python bindings)
  return theRequestHandler->getResponse();
}
Exemplo n.º 12
0
int main( int argc, char * argv[] )
{
#ifndef _MSC_VER
  qInstallMsgHandler( dummyMessageHandler );
#endif

  QString optionsPath = getenv( "QGIS_OPTIONS_PATH" );
  if ( !optionsPath.isEmpty() )
  {
    QgsDebugMsg( "Options PATH: " + optionsPath );
    QSettings::setDefaultFormat( QSettings::IniFormat );
    QSettings::setPath( QSettings::IniFormat, QSettings::UserScope, optionsPath );
  }

  QgsApplication qgsapp( argc, argv, getenv( "DISPLAY" ) );

  QCoreApplication::setOrganizationName( QgsApplication::QGIS_ORGANIZATION_NAME );
  QCoreApplication::setOrganizationDomain( QgsApplication::QGIS_ORGANIZATION_DOMAIN );
  QCoreApplication::setApplicationName( QgsApplication::QGIS_APPLICATION_NAME );

  //Default prefix path may be altered by environment variable
  QgsApplication::init();
#if !defined(Q_OS_WIN)
  // init QGIS's paths - true means that all path will be inited from prefix
  QgsApplication::setPrefixPath( CMAKE_INSTALL_PREFIX, TRUE );
#endif

#if defined(SERVER_SKIP_ECW)
  QgsDebugMsg( "Skipping GDAL ECW drivers in server." );
  QgsApplication::skipGdalDriver( "ECW" );
  QgsApplication::skipGdalDriver( "JP2ECW" );
#endif

  setupNetworkAccessManager();
  QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );

  // Instantiate the plugin directory so that providers are loaded
  QgsProviderRegistry::instance( QgsApplication::pluginPath() );
  QgsDebugMsg( "Prefix  PATH: " + QgsApplication::prefixPath() );
  QgsDebugMsg( "Plugin  PATH: " + QgsApplication::pluginPath() );
  QgsDebugMsg( "PkgData PATH: " + QgsApplication::pkgDataPath() );
  QgsDebugMsg( "User DB PATH: " + QgsApplication::qgisUserDbFilePath() );
  QgsDebugMsg( "SVG PATHS: " + QgsApplication::svgPaths().join( ":" ) );

  QgsApplication::createDB(); //init qgis.db (e.g. necessary for user crs)

  QString defaultConfigFilePath;
  QFileInfo projectFileInfo = defaultProjectFile(); //try to find a .qgs file in the server directory
  if ( projectFileInfo.exists() )
  {
    defaultConfigFilePath = projectFileInfo.absoluteFilePath();
    QgsDebugMsg( "Using default project file: " + defaultConfigFilePath );
  }
  else
  {
    QFileInfo adminSLDFileInfo = defaultAdminSLD();
    if ( adminSLDFileInfo.exists() )
    {
      defaultConfigFilePath = adminSLDFileInfo.absoluteFilePath();
    }
  }

  //create cache for capabilities XML
  QgsCapabilitiesCache capabilitiesCache;

  //creating QgsMapRenderer is expensive (access to srs.db), so we do it here before the fcgi loop
  QScopedPointer< QgsMapRenderer > theMapRenderer( new QgsMapRenderer );
  theMapRenderer->setLabelingEngine( new QgsPalLabeling() );

#ifdef QGSMSDEBUG
  QgsFontUtils::loadStandardTestFonts( QStringList() << "Roman" << "Bold" );
#endif

  int logLevel = QgsServerLogger::instance()->logLevel();
  QTime time; //used for measuring request time if loglevel < 1

#ifdef HAVE_SERVER_PYTHON_PLUGINS
  // Create the interface
  QgsServerInterfaceImpl serverIface( &capabilitiesCache );
  // Init plugins
  if ( ! QgsServerPlugins::initPlugins( &serverIface ) )
  {
    QgsMessageLog::logMessage( "No server python plugins are available", "Server", QgsMessageLog::INFO );
  }
  else
  {
    QgsMessageLog::logMessage( "Server python plugins loaded", "Server", QgsMessageLog::INFO );
  }
  // Store plugin filters for faster access
  QMultiMap<int, QgsServerFilter*> pluginFilters = serverIface.filters();
#endif

  QgsEditorWidgetRegistry::initEditors();

  while ( fcgi_accept() >= 0 )
  {
    QgsMapLayerRegistry::instance()->removeAllMapLayers();
    qgsapp.processEvents();

    if ( logLevel < 1 )
    {
      time.start();
      printRequestInfos();
    }

    //Request handler
    QScopedPointer<QgsRequestHandler> theRequestHandler( createRequestHandler() );

    try
    {
      // TODO: split parse input into plain parse and processing from specific services
      theRequestHandler->parseInput();
    }
    catch ( QgsMapServiceException& e )
    {
      QgsMessageLog::logMessage( "Parse input exception: " + e.message(), "Server", QgsMessageLog::CRITICAL );
      theRequestHandler->setServiceException( e );
    }

#ifdef HAVE_SERVER_PYTHON_PLUGINS
    // Set the request handler into the interface for plugins to manipulate it
    serverIface.setRequestHandler( theRequestHandler.data() );
    // Iterate filters and call their requestReady() method
    QgsServerFiltersMap::const_iterator filtersIterator;
    for ( filtersIterator = pluginFilters.constBegin(); filtersIterator != pluginFilters.constEnd(); ++filtersIterator )
    {
      filtersIterator.value()->requestReady();
    }

    //Pass the filters to the requestHandler, this is needed for the following reasons:
    // 1. allow core services to access plugin filters and implement thir own plugin hooks
    // 2. allow requestHandler to call sendResponse plugin hook

    //TODO: implement this in the requestHandler ctor (far easier if we will get rid of
    //      HAVE_SERVER_PYTHON_PLUGINS
    theRequestHandler->setPluginFilters( pluginFilters );
#endif

    // Copy the parameters map
    QMap<QString, QString> parameterMap( theRequestHandler->parameterMap() );

    printRequestParameters( parameterMap, logLevel );
    QMap<QString, QString>::const_iterator paramIt;
    //Config file path
    QString configFilePath = configPath( defaultConfigFilePath, parameterMap );
    //Service parameter
    QString serviceString = theRequestHandler->parameter( "SERVICE" );

    if ( serviceString.isEmpty() )
    {
      // SERVICE not mandatory for WMS 1.3.0 GetMap & GetFeatureInfo
      QString requestString = theRequestHandler->parameter( "REQUEST" );
      if ( requestString == "GetMap" || requestString == "GetFeatureInfo" )
      {
        serviceString = "WMS";
      }
    }

    // Enter core services main switch
    if ( !theRequestHandler->exceptionRaised() )
    {
      if ( serviceString == "WCS" )
      {
        QgsWCSProjectParser* p = QgsConfigCache::instance()->wcsConfiguration( configFilePath );
        if ( !p )
        {
          theRequestHandler->setServiceException( QgsMapServiceException( "Project file error", "Error reading the project file" ) );
        }
        else
        {
          QgsWCSServer wcsServer( configFilePath, parameterMap, p, theRequestHandler.data() );
          wcsServer.executeRequest();
        }
      }
      else if ( serviceString == "WFS" )
      {
        QgsWFSProjectParser* p = QgsConfigCache::instance()->wfsConfiguration( configFilePath );
        if ( !p )
        {
          theRequestHandler->setServiceException( QgsMapServiceException( "Project file error", "Error reading the project file" ) );
        }
        else
        {
          QgsWFSServer wfsServer( configFilePath, parameterMap, p, theRequestHandler.data() );
          wfsServer.executeRequest();
        }
      }
      else if ( serviceString == "WMS" )
      {
        QgsWMSConfigParser* p = QgsConfigCache::instance()->wmsConfiguration( configFilePath, parameterMap );
        if ( !p )
        {
          theRequestHandler->setServiceException( QgsMapServiceException( "WMS configuration error", "There was an error reading the project file or the SLD configuration" ) );
        }
        else
        {
          QgsWMSServer wmsServer( configFilePath, parameterMap, p, theRequestHandler.data(), theMapRenderer.data(), &capabilitiesCache );
          wmsServer.executeRequest();
        }
      }
      else
      {
        theRequestHandler->setServiceException( QgsMapServiceException( "Service configuration error", "Service unknown or unsupported" ) );
      } // end switch
    } // end if not exception raised

#ifdef HAVE_SERVER_PYTHON_PLUGINS
    // Iterate filters and call their responseComplete() method
    for ( filtersIterator = pluginFilters.constBegin(); filtersIterator != pluginFilters.constEnd(); ++filtersIterator )
    {
      filtersIterator.value()->responseComplete();
    }
#endif
    theRequestHandler->sendResponse();

    if ( logLevel < 1 )
    {
      QgsMessageLog::logMessage( "Request finished in " + QString::number( time.elapsed() ) + " ms", "Server", QgsMessageLog::INFO );
    }
  }
  return 0;
}
Exemplo n.º 13
0
int main( int argc, char * argv[] )
{
#ifndef _MSC_VER
  qInstallMsgHandler( dummyMessageHandler );
#endif

  QgsApplication qgsapp( argc, argv, false );

  //Default prefix path may be altered by environment variable
  char* prefixPath = getenv( "QGIS_PREFIX_PATH" );
  if ( prefixPath )
  {
    QgsApplication::setPrefixPath( prefixPath, TRUE );
  }
#if !defined(Q_OS_WIN)
  else
  {
    // init QGIS's paths - true means that all path will be inited from prefix
    QgsApplication::setPrefixPath( CMAKE_INSTALL_PREFIX, TRUE );
  }
#endif

  // Instantiate the plugin directory so that providers are loaded
  QgsProviderRegistry::instance( QgsApplication::pluginPath() );
  QgsDebugMsg( "Prefix  PATH: " + QgsApplication::prefixPath() );
  QgsDebugMsg( "Plugin  PATH: " + QgsApplication::pluginPath() );
  QgsDebugMsg( "PkgData PATH: " + QgsApplication::pkgDataPath() );
  QgsDebugMsg( "User DB PATH: " + QgsApplication::qgisUserDbFilePath() );

  QgsDebugMsg( qgsapp.applicationDirPath() + "/qgis_wms_server.log" );

  //create config cache and search for config files in the current directory.
  //These configurations are used if no mapfile parameter is present in the request
  QString defaultConfigFilePath;
  QFileInfo projectFileInfo = defaultProjectFile(); //try to find a .qgs file in the server directory
  if ( projectFileInfo.exists() )
  {
    defaultConfigFilePath = projectFileInfo.absoluteFilePath();
  }
  else
  {
    QFileInfo adminSLDFileInfo = defaultAdminSLD();
    if ( adminSLDFileInfo.exists() )
    {
      defaultConfigFilePath = adminSLDFileInfo.absoluteFilePath();
    }
  }

  //create cache for capabilities XML
  QgsCapabilitiesCache capabilitiesCache;

  //creating QgsMapRenderer is expensive (access to srs.db), so we do it here before the fcgi loop
  QgsMapRenderer* theMapRenderer = new QgsMapRenderer();

  while ( fcgi_accept() >= 0 )
  {
    printRequestInfos(); //print request infos if in debug mode

    //use QgsGetRequestHandler in case of HTTP GET and QgsSOAPRequestHandler in case of HTTP POST
    QgsRequestHandler* theRequestHandler = 0;
    char* requestMethod = getenv( "REQUEST_METHOD" );
    if ( requestMethod != NULL )
    {
      if ( strcmp( requestMethod, "POST" ) == 0 )
      {
        //QgsDebugMsg( "Creating QgsSOAPRequestHandler" );
        //theRequestHandler = new QgsSOAPRequestHandler();
        theRequestHandler = new QgsPostRequestHandler();
      }
      else
      {
        QgsDebugMsg( "Creating QgsGetRequestHandler" );
        theRequestHandler = new QgsGetRequestHandler();
      }
    }
    else
    {
      QgsDebugMsg( "Creating QgsGetRequestHandler" );
      theRequestHandler = new QgsGetRequestHandler();
    }

    std::map<QString, QString> parameterMap;

    try
    {
      parameterMap = theRequestHandler->parseInput();
    }
    catch ( QgsMapServiceException& e )
    {
      QgsDebugMsg( "An exception was thrown during input parsing" );
      theRequestHandler->sendServiceException( e );
      continue;
    }

    //set admin config file to wms server object
    QString configFilePath = defaultConfigFilePath;
    std::map<QString, QString>::const_iterator mapFileIt = parameterMap.find( "MAP" );
    if ( mapFileIt != parameterMap.end() )
    {
      configFilePath = mapFileIt->second;
      QgsDebugMsg( QString( "Configuration file path set to: %1" ).arg( defaultConfigFilePath ) );
    }
    else
    {
      QgsDebugMsg( QString( "Using default configuration file path: %1" ).arg( defaultConfigFilePath ) );
    }

    QgsConfigParser* adminConfigParser = QgsConfigCache::instance()->searchConfiguration( configFilePath );
    if ( !adminConfigParser )
    {
      QgsDebugMsg( "parse error on config file " + configFilePath );
      theRequestHandler->sendServiceException( QgsMapServiceException( "", "Configuration file problem : perhaps you left off the .qgs extension?" ) );
      continue;
    }

    //sld parser might need information about request parameters
    adminConfigParser->setParameterMap( parameterMap );

    //request to WMS?
    QString serviceString( "WMS" );
    std::map<QString, QString>::const_iterator serviceIt = parameterMap.find( "SERVICE" );
    if ( serviceIt != parameterMap.end() )
    {
      serviceString = serviceIt->second;
    }
    /*else
    {
      QgsDebugMsg( "unable to find 'SERVICE' parameter, exiting..." );
      theRequestHandler->sendServiceException( QgsMapServiceException( "ServiceNotSpecified", "Service not specified. The SERVICE parameter is mandatory" ) );
      delete theRequestHandler;
      continue;
    }*/

    QgsWMSServer* theServer = 0;
    try
    {
      theServer = new QgsWMSServer( parameterMap, theMapRenderer );
    }
    catch ( QgsMapServiceException e ) //admin.sld may be invalid
    {
      theRequestHandler->sendServiceException( e );
      continue;
    }

    theServer->setAdminConfigParser( adminConfigParser );


    //request type
    std::map<QString, QString>::const_iterator requestIt = parameterMap.find( "REQUEST" );
    if ( requestIt == parameterMap.end() )
    {
      //do some error handling
      QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
      theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
      delete theRequestHandler;
      delete theServer;
      continue;
    }

    if ( requestIt->second == "GetCapabilities" )
    {
      const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath );
      if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one
      {
        QgsDebugMsg( "Capabilities document not found in cache" );
        QDomDocument doc;
        try
        {
          doc = theServer->getCapabilities();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        capabilitiesCache.insertCapabilitiesDocument( configFilePath, &doc );
        capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath );
      }
      else
      {
        QgsDebugMsg( "Found capabilities document in cache" );
      }

      if ( capabilitiesDocument )
      {
        theRequestHandler->sendGetCapabilitiesResponse( *capabilitiesDocument );
      }
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( requestIt->second == "GetMap" )
    {
      QImage* result = 0;
      try
      {
        result = theServer->getMap();
      }
      catch ( QgsMapServiceException& ex )
      {
        QgsDebugMsg( "Catched exception during GetMap request" );
        theRequestHandler->sendServiceException( ex );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      if ( result )
      {
        QgsDebugMsg( "Sending GetMap response" );
        theRequestHandler->sendGetMapResponse( serviceString, result );
      }
      else
      {
        //do some error handling
        QgsDebugMsg( "result image is 0" );
      }
      delete result;
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( requestIt->second == "GetFeatureInfo" )
    {
      QDomDocument featureInfoDoc;
      try
      {
        if ( theServer->getFeatureInfo( featureInfoDoc ) != 0 )
        {
          delete theRequestHandler;
          delete theServer;
          continue;
        }
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      //info format for GetFeatureInfo
      QString infoFormat;
      std::map<QString, QString>::const_iterator p_it = parameterMap.find( "INFO_FORMAT" );
      if ( p_it != parameterMap.end() )
      {
        infoFormat = p_it->second;
      }

      theRequestHandler->sendGetFeatureInfoResponse( featureInfoDoc, infoFormat );
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( requestIt->second == "GetStyle" )
    {
      try
      {
        QDomDocument doc = theServer->getStyle();
        theRequestHandler->sendGetStyleResponse( doc );
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( requestIt->second == "GetLegendGraphics" )
    {
      QImage* result = 0;
      try
      {
        result = theServer->getLegendGraphics();
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      if ( result )
      {
        QgsDebugMsg( "Sending GetLegendGraphics response" );
        //sending is the same for GetMap and GetLegendGraphics
        theRequestHandler->sendGetMapResponse( serviceString, result );
      }
      else
      {
        //do some error handling
        QgsDebugMsg( "result image is 0" );
      }
      delete result;
      delete theRequestHandler;
      delete theServer;
      continue;

    }
    else if ( requestIt->second == "GetPrint" )
    {
      QByteArray* printOutput = 0;
      try
      {
        printOutput = theServer->getPrint( theRequestHandler->format() );
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      if ( printOutput )
      {
        theRequestHandler->sendGetPrintResponse( printOutput );
      }
      delete printOutput;
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else//unknown request
    {
      QgsMapServiceException e( "OperationNotSupported", "Operation " + requestIt->second + " not supported" );
      theRequestHandler->sendServiceException( e );
      delete theRequestHandler;
      delete theServer;
    }
  }

  delete theMapRenderer;
  return 0;
}
Exemplo n.º 14
0
int main( int argc, char * argv[] )
{
#ifndef _MSC_VER
  qInstallMsgHandler( dummyMessageHandler );
#endif

  QgsApplication qgsapp( argc, argv, getenv( "DISPLAY" ) );

  //Default prefix path may be altered by environment variable
  QgsApplication::init();

#if defined(MAPSERVER_SKIP_ECW)
  QgsDebugMsg( "Skipping GDAL ECW drivers in server." );
  QgsApplication::skipGdalDriver( "ECW" );
  QgsApplication::skipGdalDriver( "JP2ECW" );
#endif

  QSettings settings;

  QgsNetworkAccessManager *nam = QgsNetworkAccessManager::instance();
  QNetworkDiskCache *cache = new QNetworkDiskCache( 0 );

  QString cacheDirectory = settings.value( "cache/directory", QgsApplication::qgisSettingsDirPath() + "cache" ).toString();
  qint64 cacheSize = settings.value( "cache/size", 50 * 1024 * 1024 ).toULongLong();
  QgsDebugMsg( QString( "setCacheDirectory: %1" ).arg( cacheDirectory ) );
  QgsDebugMsg( QString( "setMaximumCacheSize: %1" ).arg( cacheSize ) );
  cache->setCacheDirectory( cacheDirectory );
  cache->setMaximumCacheSize( cacheSize );
  QgsDebugMsg( QString( "cacheDirectory: %1" ).arg( cache->cacheDirectory() ) );
  QgsDebugMsg( QString( "maximumCacheSize: %1" ).arg( cache->maximumCacheSize() ) );

  nam->setCache( cache );

  QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );

  // Instantiate the plugin directory so that providers are loaded
  QgsProviderRegistry::instance( QgsApplication::pluginPath() );
  QgsDebugMsg( "Prefix  PATH: " + QgsApplication::prefixPath() );
  QgsDebugMsg( "Plugin  PATH: " + QgsApplication::pluginPath() );
  QgsDebugMsg( "PkgData PATH: " + QgsApplication::pkgDataPath() );
  QgsDebugMsg( "User DB PATH: " + QgsApplication::qgisUserDbFilePath() );

  QgsDebugMsg( qgsapp.applicationDirPath() + "/qgis_wms_server.log" );
  QgsApplication::createDB(); //init qgis.db (e.g. necessary for user crs)

  //create config cache and search for config files in the current directory.
  //These configurations are used if no mapfile parameter is present in the request
  QString defaultConfigFilePath;
  QFileInfo projectFileInfo = defaultProjectFile(); //try to find a .qgs file in the server directory
  if ( projectFileInfo.exists() )
  {
    defaultConfigFilePath = projectFileInfo.absoluteFilePath();
    QgsDebugMsg( "Using default project file: " + defaultConfigFilePath );
  }
  else
  {
    QFileInfo adminSLDFileInfo = defaultAdminSLD();
    if ( adminSLDFileInfo.exists() )
    {
      defaultConfigFilePath = adminSLDFileInfo.absoluteFilePath();
    }
  }

  //create cache for capabilities XML
  QgsCapabilitiesCache capabilitiesCache;

  //creating QgsMapRenderer is expensive (access to srs.db), so we do it here before the fcgi loop
  QgsMapRenderer* theMapRenderer = new QgsMapRenderer();
  theMapRenderer->setLabelingEngine( new QgsPalLabeling() );

#ifdef QGSMSDEBUG
  QgsFontUtils::loadStandardTestFonts( QStringList() << "Roman" << "Bold" );
#endif

  while ( fcgi_accept() >= 0 )
  {
    printRequestInfos(); //print request infos if in debug mode

    //use QgsGetRequestHandler in case of HTTP GET and QgsSOAPRequestHandler in case of HTTP POST
    QgsRequestHandler* theRequestHandler = 0;
    char* requestMethod = getenv( "REQUEST_METHOD" );
    if ( requestMethod != NULL )
    {
      if ( strcmp( requestMethod, "POST" ) == 0 )
      {
        //QgsDebugMsg( "Creating QgsSOAPRequestHandler" );
        //theRequestHandler = new QgsSOAPRequestHandler();
        theRequestHandler = new QgsPostRequestHandler();
      }
      else
      {
        QgsDebugMsg( "Creating QgsGetRequestHandler" );
        theRequestHandler = new QgsGetRequestHandler();
      }
    }
    else
    {
      QgsDebugMsg( "Creating QgsGetRequestHandler" );
      theRequestHandler = new QgsGetRequestHandler();
    }

    QMap<QString, QString> parameterMap;

    try
    {
      parameterMap = theRequestHandler->parseInput();
    }
    catch ( QgsMapServiceException& e )
    {
      QgsDebugMsg( "An exception was thrown during input parsing" );
      theRequestHandler->sendServiceException( e );
      continue;
    }

    QMap<QString, QString>::const_iterator paramIt;

    //set admin config file to wms server object
    QString configFilePath( defaultConfigFilePath );

    QString projectFile = getenv( "QGIS_PROJECT_FILE" );
    if ( !projectFile.isEmpty() )
    {
      configFilePath = projectFile;
    }
    else
    {
      paramIt = parameterMap.find( "MAP" );
      if ( paramIt == parameterMap.constEnd() )
      {
        QgsDebugMsg( QString( "Using default configuration file path: %1" ).arg( defaultConfigFilePath ) );
      }
      else
      {
        configFilePath = paramIt.value();
      }
    }

    QgsConfigParser* adminConfigParser = QgsConfigCache::instance()->searchConfiguration( configFilePath );
    if ( !adminConfigParser )
    {
      QgsDebugMsg( "parse error on config file " + configFilePath );
      theRequestHandler->sendServiceException( QgsMapServiceException( "", "Configuration file problem : perhaps you left off the .qgs extension?" ) );
      continue;
    }

    //sld parser might need information about request parameters
    adminConfigParser->setParameterMap( parameterMap );

    //request to WMS?
    QString serviceString;
    paramIt = parameterMap.find( "SERVICE" );
    if ( paramIt == parameterMap.constEnd() )
    {
#ifndef QGISDEBUG
      serviceString = parameterMap.value( "SERVICE", "WMS" );
#else
      QgsDebugMsg( "unable to find 'SERVICE' parameter, exiting..." );
      theRequestHandler->sendServiceException( QgsMapServiceException( "ServiceNotSpecified", "Service not specified. The SERVICE parameter is mandatory" ) );
      delete theRequestHandler;
      continue;
#endif
    }
    else
    {
      serviceString = paramIt.value();
    }

    QgsWMSServer* theServer = 0;
    if ( serviceString == "WCS" )
    {
      delete theServer;
      QgsWCSServer* theServer = 0;
      try
      {
        theServer = new QgsWCSServer( parameterMap );
      }
      catch ( const QgsMapServiceException &e ) //admin.sld may be invalid
      {
        theRequestHandler->sendServiceException( e );
        continue;
      }

      theServer->setAdminConfigParser( adminConfigParser );


      //request type
      QString request = parameterMap.value( "REQUEST" );
      if ( request.isEmpty() )
      {
        //do some error handling
        QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
        theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      if ( request.compare( "GetCapabilities", Qt::CaseInsensitive ) == 0 )
      {
        QDomDocument capabilitiesDocument;
        try
        {
          capabilitiesDocument = theServer->getCapabilities();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending GetCapabilities response" );
        theRequestHandler->sendGetCapabilitiesResponse( capabilitiesDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }
      else if ( request.compare( "DescribeCoverage", Qt::CaseInsensitive ) == 0 )
      {
        QDomDocument describeDocument;
        try
        {
          describeDocument = theServer->describeCoverage();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending GetCapabilities response" );
        theRequestHandler->sendGetCapabilitiesResponse( describeDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }
      else if ( request.compare( "GetCoverage", Qt::CaseInsensitive ) == 0 )
      {
        QByteArray* coverageOutput;
        try
        {
          coverageOutput = theServer->getCoverage();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        if ( coverageOutput )
        {
          theRequestHandler->sendGetCoverageResponse( coverageOutput );
        }
        delete theRequestHandler;
        delete theServer;
        continue;
      }
    }
    else if ( serviceString == "WFS" )
    {
      delete theServer;
      QgsWFSServer* theServer = 0;
      try
      {
        theServer = new QgsWFSServer( parameterMap );
      }
      catch ( const QgsMapServiceException &e ) //admin.sld may be invalid
      {
        theRequestHandler->sendServiceException( e );
        continue;
      }

      theServer->setAdminConfigParser( adminConfigParser );


      //request type
      QString request = parameterMap.value( "REQUEST" );
      if ( request.isEmpty() )
      {
        //do some error handling
        QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
        theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      if ( request.compare( "GetCapabilities", Qt::CaseInsensitive ) == 0 )
      {
        QDomDocument capabilitiesDocument;
        try
        {
          capabilitiesDocument = theServer->getCapabilities();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending GetCapabilities response" );
        theRequestHandler->sendGetCapabilitiesResponse( capabilitiesDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }
      else if ( request.compare( "DescribeFeatureType", Qt::CaseInsensitive ) == 0 )
      {
        QDomDocument describeDocument;
        try
        {
          describeDocument = theServer->describeFeatureType();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending GetCapabilities response" );
        theRequestHandler->sendGetCapabilitiesResponse( describeDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }
      else if ( request.compare( "GetFeature", Qt::CaseInsensitive ) == 0 )
      {
        //output format for GetFeature
        QString outputFormat = parameterMap.value( "OUTPUTFORMAT" );
        try
        {
          theServer->getFeature( *theRequestHandler, outputFormat );
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
        }

        delete theRequestHandler;
        delete theServer;
        continue;
      }
      else if ( request.compare( "Transaction", Qt::CaseInsensitive ) == 0 )
      {
        QDomDocument transactionDocument;
        try
        {
          transactionDocument = theServer->transaction( parameterMap.value( "REQUEST_BODY" ) );
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending Transaction response" );
        theRequestHandler->sendGetCapabilitiesResponse( transactionDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      return 0;
    }

    try
    {
      theServer = new QgsWMSServer( parameterMap, theMapRenderer );
    }
    catch ( const QgsMapServiceException &e ) //admin.sld may be invalid
    {
      theRequestHandler->sendServiceException( e );
      continue;
    }

    adminConfigParser->loadLabelSettings( theMapRenderer->labelingEngine() );
    theServer->setAdminConfigParser( adminConfigParser );


    //request type
    QString request = parameterMap.value( "REQUEST" );
    if ( request.isEmpty() )
    {
      //do some error handling
      QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
      theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
      delete theRequestHandler;
      delete theServer;
      continue;
    }

    QString version = parameterMap.value( "VERSION", "1.3.0" );
    bool getProjectSettings = ( request.compare( "GetProjectSettings", Qt::CaseInsensitive ) == 0 );
    if ( getProjectSettings )
    {
      version = "1.3.0"; //getProjectSettings extends WMS 1.3.0 capabilities
    }

    if ( request.compare( "GetCapabilities", Qt::CaseInsensitive ) == 0 || getProjectSettings )
    {
      const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version );
      if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one
      {
        QgsDebugMsg( "Capabilities document not found in cache" );
        QDomDocument doc;
        try
        {
          doc = theServer->getCapabilities( version, getProjectSettings );
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        capabilitiesCache.insertCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version, &doc );
        capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version );
      }
      else
      {
        QgsDebugMsg( "Found capabilities document in cache" );
      }

      if ( capabilitiesDocument )
      {
        theRequestHandler->sendGetCapabilitiesResponse( *capabilitiesDocument );
      }
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.compare( "GetMap", Qt::CaseInsensitive ) == 0 )
    {
      QImage* result = 0;
      try
      {
        result = theServer->getMap();
      }
      catch ( QgsMapServiceException& ex )
      {
        QgsDebugMsg( "Caught exception during GetMap request" );
        theRequestHandler->sendServiceException( ex );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      if ( result )
      {
        QgsDebugMsg( "Sending GetMap response" );
        theRequestHandler->sendGetMapResponse( serviceString, result );
        QgsDebugMsg( "Response sent" );
      }
      else
      {
        //do some error handling
        QgsDebugMsg( "result image is 0" );
      }
      delete result;
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.compare( "GetFeatureInfo", Qt::CaseInsensitive ) == 0 )
    {
      QDomDocument featureInfoDoc;
      try
      {
        if ( theServer->getFeatureInfo( featureInfoDoc, version ) != 0 )
        {
          delete theRequestHandler;
          delete theServer;
          continue;
        }
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      QString infoFormat = parameterMap.value( "INFO_FORMAT" );
      theRequestHandler->sendGetFeatureInfoResponse( featureInfoDoc, infoFormat );
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.compare( "GetContext", Qt::CaseInsensitive ) == 0 )
    {
      try
      {
        QDomDocument doc = theServer->getContext();
        theRequestHandler->sendGetStyleResponse( doc );
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.compare( "GetStyle", Qt::CaseInsensitive ) == 0 ) // GetStyle for compatibility with earlier QGIS versions
    {
      try
      {
        QDomDocument doc = theServer->getStyle();
        theRequestHandler->sendGetStyleResponse( doc );
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.compare( "GetStyles", Qt::CaseInsensitive ) == 0 )
    {
      // GetStyles is only defined for WMS1.1.1/SLD1.0
      if ( version != "1.1.1" )
      {
        theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "GetStyles method is only available in WMS version 1.1.1" ) );
      }
      else
      {
        try
        {
          QDomDocument doc = theServer->getStyles();
          theRequestHandler->sendGetStyleResponse( doc );
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
        }
      }

      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.compare( "GetLegendGraphic", Qt::CaseInsensitive ) == 0 ||
              request.compare( "GetLegendGraphics", Qt::CaseInsensitive ) == 0 )
      // GetLegendGraphics for compatibility with earlier QGIS versions
    {
      QImage* result = 0;
      try
      {
        result = theServer->getLegendGraphics();
      }
      catch ( QgsMapServiceException& ex )
      {
        QgsDebugMsg( "Caught exception during GetLegendGraphic request" );
        theRequestHandler->sendServiceException( ex );
      }

      if ( result )
      {
        QgsDebugMsg( "Sending GetLegendGraphic response" );
        //sending is the same for GetMap and GetLegendGraphic
        theRequestHandler->sendGetMapResponse( serviceString, result );
        QgsDebugMsg( "Response sent" );
      }
      else
      {
        //do some error handling
        QgsDebugMsg( "result image is 0" );
      }
      delete result;
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.compare( "GetPrint", Qt::CaseInsensitive ) == 0 )
    {
      QByteArray* printOutput = 0;
      try
      {
        printOutput = theServer->getPrint( theRequestHandler->format() );
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      if ( printOutput )
      {
        theRequestHandler->sendGetPrintResponse( printOutput );
      }
      delete printOutput;
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else//unknown request
    {
      QgsMapServiceException e( "OperationNotSupported", "Operation " + request + " not supported" );
      theRequestHandler->sendServiceException( e );
      delete theRequestHandler;
      delete theServer;
    }
  }

  delete theMapRenderer;
  QgsDebugMsg( "************* all done ***************" );
  return 0;
}
Exemplo n.º 15
0
QgsVectorLayer* QgsSLDConfigParser::contourLayerFromRaster( const QDomElement& userStyleElem, QgsRasterLayer* rasterLayer ) const
{
  QgsDebugMsg( "Entering." );

  if ( !rasterLayer )
  {
    return nullptr;
  }

  //get <ContourSymbolizer> element
  QDomNodeList contourNodeList = userStyleElem.elementsByTagName( QStringLiteral( "ContourSymbolizer" ) );
  if ( contourNodeList.size() < 1 )
  {
    return nullptr;
  }

  QDomElement contourSymbolizerElem = contourNodeList.item( 0 ).toElement();
  if ( contourSymbolizerElem.isNull() )
  {
    return nullptr;
  }

  double equidistance, minValue, maxValue, offset;
  QString propertyName;

  equidistance = contourSymbolizerElem.attribute( QStringLiteral( "equidistance" ) ).toDouble();
  minValue = contourSymbolizerElem.attribute( QStringLiteral( "minValue" ) ).toDouble();
  maxValue = contourSymbolizerElem.attribute( QStringLiteral( "maxValue" ) ).toDouble();
  offset = contourSymbolizerElem.attribute( QStringLiteral( "offset" ) ).toDouble();
  propertyName = contourSymbolizerElem.attribute( QStringLiteral( "propertyName" ) );

  if ( equidistance <= 0.0 )
  {
    return nullptr;
  }

  QTemporaryFile* tmpFile1 = new QTemporaryFile();
  tmpFile1->open();
  mFilesToRemove.push_back( tmpFile1 );
  QString tmpBaseName = tmpFile1->fileName();
  QString tmpFileName = tmpBaseName + ".shp";

  //hack: use gdal_contour first to write into a temporary file
  /* todo: use GDALContourGenerate( hBand, dfInterval, dfOffset,
                                nFixedLevelCount, adfFixedLevels,
                                bNoDataSet, dfNoData,
                                hLayer, 0, nElevField,
                                GDALTermProgress, nullptr );*/


  //do the stuff that is also done in the main method of gdal_contour...
  /* -------------------------------------------------------------------- */
  /*      Open source raster file.                                        */
  /* -------------------------------------------------------------------- */
  GDALRasterBandH hBand;
  GDALDatasetH hSrcDS;

  int numberOfLevels = 0;
  double currentLevel = 0.0;

  if ( maxValue > minValue )
  {
    //find first level
    currentLevel = ( int )(( minValue - offset ) / equidistance + 0.5 ) * equidistance + offset;
    while ( currentLevel <= maxValue )
    {
      ++numberOfLevels;
      currentLevel += equidistance;
    }
  }

  double *adfFixedLevels = new double[numberOfLevels];
  int    nFixedLevelCount = numberOfLevels;
  currentLevel = ( int )(( minValue - offset ) / equidistance + 0.5 ) * equidistance + offset;
  for ( int i = 0; i < numberOfLevels; ++i )
  {
    adfFixedLevels[i] = currentLevel;
    currentLevel += equidistance;
  }
  int nBandIn = 1;
  double dfInterval = equidistance, dfNoData = 0.0, dfOffset = offset;

  int /* b3D = FALSE, */ bNoDataSet = FALSE, bIgnoreNoData = FALSE;

  hSrcDS = GDALOpen( rasterLayer->source().toUtf8().constData(), GA_ReadOnly );
  if ( !hSrcDS )
  {
    delete [] adfFixedLevels;
    throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request is for a file not available on the server." ) );
  }

  hBand = GDALGetRasterBand( hSrcDS, nBandIn );
  if ( !hBand )
  {
    CPLError( CE_Failure, CPLE_AppDefined,
              "Band %d does not exist on dataset.",
              nBandIn );
  }

  if ( !bNoDataSet && !bIgnoreNoData )
    dfNoData = GDALGetRasterNoDataValue( hBand, &bNoDataSet );

  /* -------------------------------------------------------------------- */
  /*      Try to get a coordinate system from the raster.                 */
  /* -------------------------------------------------------------------- */
  OGRSpatialReferenceH hSRS = nullptr;

  const char *pszWKT = GDALGetProjectionRef( hBand );

  if ( pszWKT && strlen( pszWKT ) != 0 )
    hSRS = OSRNewSpatialReference( pszWKT );

  /* -------------------------------------------------------------------- */
  /*      Create the outputfile.                                          */
  /* -------------------------------------------------------------------- */
  OGRDataSourceH hDS;
  OGRSFDriverH hDriver = OGRGetDriverByName( "ESRI Shapefile" );
  OGRFieldDefnH hFld;
  OGRLayerH hLayer;
  int nElevField = -1;

  if ( !hDriver )
  {
    //fprintf( FCGI_stderr, "Unable to find format driver named 'ESRI Shapefile'.\n" );
    delete [] adfFixedLevels;
    throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request is for a file not available on the server." ) );
  }

  hDS = OGR_Dr_CreateDataSource( hDriver, tmpFileName.toUtf8().constData(), nullptr );
  if ( !hDS )
  {
    delete [] adfFixedLevels;
    throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request cannot create data source." ) );
  }

  hLayer = OGR_DS_CreateLayer( hDS, "contour", hSRS,
                               /* b3D ? wkbLineString25D : */ wkbLineString,
                               nullptr );
  if ( !hLayer )
  {
    delete [] adfFixedLevels;
    throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request could not create contour file." ) );
  }

  hFld = OGR_Fld_Create( "ID", OFTInteger );
  OGR_Fld_SetWidth( hFld, 8 );
  OGR_L_CreateField( hLayer, hFld, FALSE );
  OGR_Fld_Destroy( hFld );

  if ( !propertyName.isEmpty() )
  {
    hFld = OGR_Fld_Create( propertyName.toUtf8().constData(), OFTReal );
    OGR_Fld_SetWidth( hFld, 12 );
    OGR_Fld_SetPrecision( hFld, 3 );
    OGR_L_CreateField( hLayer, hFld, FALSE );
    OGR_Fld_Destroy( hFld );
    nElevField = 1;
  }

  /* -------------------------------------------------------------------- */
  /*      Invoke.                                                         */
  /* -------------------------------------------------------------------- */
  GDALContourGenerate( hBand, dfInterval, dfOffset,
                       nFixedLevelCount, adfFixedLevels,
                       bNoDataSet, dfNoData,
                       hLayer, 0, nElevField,
                       GDALTermProgress, nullptr );

  delete [] adfFixedLevels;

  OGR_DS_Destroy( hDS );
  GDALClose( hSrcDS );

  //todo: store those three files elsewhere...
  //mark shp, dbf and shx to delete after the request
  mFilePathsToRemove.push_back( tmpBaseName + ".shp" );
  mFilePathsToRemove.push_back( tmpBaseName + ".dbf" );
  mFilePathsToRemove.push_back( tmpBaseName + ".shx" );

  QgsVectorLayer* contourLayer = new QgsVectorLayer( tmpFileName, QStringLiteral( "layer" ), QStringLiteral( "ogr" ) );

  //create renderer
  QgsFeatureRenderer* theRenderer = rendererFromUserStyle( userStyleElem, contourLayer );
  contourLayer->setRenderer( theRenderer );

  //add labeling if requested
  labelSettingsFromUserStyle( userStyleElem, contourLayer );

  QgsDebugMsg( "Returning the contour layer" );
  return contourLayer;
}
Exemplo n.º 16
0
int main( int argc, char * argv[] )
{
#ifndef _MSC_VER
  qInstallMsgHandler( dummyMessageHandler );
#endif

  QgsApplication qgsapp( argc, argv, getenv( "DISPLAY" ) );

  //Default prefix path may be altered by environment variable
  char* prefixPath = getenv( "QGIS_PREFIX_PATH" );
  if ( prefixPath )
  {
    QgsApplication::setPrefixPath( prefixPath, TRUE );
  }
#if !defined(Q_OS_WIN)
  else
  {
    // init QGIS's paths - true means that all path will be inited from prefix
    QgsApplication::setPrefixPath( CMAKE_INSTALL_PREFIX, TRUE );
  }
#endif

  QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );

  // Instantiate the plugin directory so that providers are loaded
  QgsProviderRegistry::instance( QgsApplication::pluginPath() );
  QgsDebugMsg( "Prefix  PATH: " + QgsApplication::prefixPath() );
  QgsDebugMsg( "Plugin  PATH: " + QgsApplication::pluginPath() );
  QgsDebugMsg( "PkgData PATH: " + QgsApplication::pkgDataPath() );
  QgsDebugMsg( "User DB PATH: " + QgsApplication::qgisUserDbFilePath() );

  QgsDebugMsg( qgsapp.applicationDirPath() + "/qgis_wms_server.log" );

  //create config cache and search for config files in the current directory.
  //These configurations are used if no mapfile parameter is present in the request
  QString defaultConfigFilePath;
  QFileInfo projectFileInfo = defaultProjectFile(); //try to find a .qgs file in the server directory
  if ( projectFileInfo.exists() )
  {
    defaultConfigFilePath = projectFileInfo.absoluteFilePath();
  }
  else
  {
    QFileInfo adminSLDFileInfo = defaultAdminSLD();
    if ( adminSLDFileInfo.exists() )
    {
      defaultConfigFilePath = adminSLDFileInfo.absoluteFilePath();
    }
  }

  //create cache for capabilities XML
  QgsCapabilitiesCache capabilitiesCache;

  //creating QgsMapRenderer is expensive (access to srs.db), so we do it here before the fcgi loop
  QgsMapRenderer* theMapRenderer = new QgsMapRenderer();
  theMapRenderer->setLabelingEngine( new QgsPalLabeling() );

  while ( fcgi_accept() >= 0 )
  {
    printRequestInfos(); //print request infos if in debug mode

    //use QgsGetRequestHandler in case of HTTP GET and QgsSOAPRequestHandler in case of HTTP POST
    QgsRequestHandler* theRequestHandler = 0;
    char* requestMethod = getenv( "REQUEST_METHOD" );
    if ( requestMethod != NULL )
    {
      if ( strcmp( requestMethod, "POST" ) == 0 )
      {
        //QgsDebugMsg( "Creating QgsSOAPRequestHandler" );
        //theRequestHandler = new QgsSOAPRequestHandler();
        theRequestHandler = new QgsPostRequestHandler();
      }
      else
      {
        QgsDebugMsg( "Creating QgsGetRequestHandler" );
        theRequestHandler = new QgsGetRequestHandler();
      }
    }
    else
    {
      QgsDebugMsg( "Creating QgsGetRequestHandler" );
      theRequestHandler = new QgsGetRequestHandler();
    }

    QMap<QString, QString> parameterMap;

    try
    {
      parameterMap = theRequestHandler->parseInput();
    }
    catch ( QgsMapServiceException& e )
    {
      QgsDebugMsg( "An exception was thrown during input parsing" );
      theRequestHandler->sendServiceException( e );
      continue;
    }

    QMap<QString, QString>::const_iterator paramIt;

    //set admin config file to wms server object
    QString configFilePath( defaultConfigFilePath );

    paramIt = parameterMap.find( "MAP" );
    if ( paramIt == parameterMap.constEnd() )
    {
      QgsDebugMsg( QString( "Using default configuration file path: %1" ).arg( defaultConfigFilePath ) );
    }
    else
    {
      configFilePath = paramIt.value();
    }

    QgsConfigParser* adminConfigParser = QgsConfigCache::instance()->searchConfiguration( configFilePath );
    if ( !adminConfigParser )
    {
      QgsDebugMsg( "parse error on config file " + configFilePath );
      theRequestHandler->sendServiceException( QgsMapServiceException( "", "Configuration file problem : perhaps you left off the .qgs extension?" ) );
      continue;
    }

    //sld parser might need information about request parameters
    adminConfigParser->setParameterMap( parameterMap );

    //request to WMS?
    QString serviceString;
    paramIt = parameterMap.find( "SERVICE" );
    if ( paramIt == parameterMap.constEnd() )
    {
#ifndef QGISDEBUG
      serviceString = parameterMap.value( "SERVICE", "WMS" );
#else
      QgsDebugMsg( "unable to find 'SERVICE' parameter, exiting..." );
      theRequestHandler->sendServiceException( QgsMapServiceException( "ServiceNotSpecified", "Service not specified. The SERVICE parameter is mandatory" ) );
      delete theRequestHandler;
      continue;
#endif
    }
    else
    {
      serviceString = paramIt.value();
    }

    QgsWMSServer* theServer = 0;
    if ( serviceString == "WFS" )
    {
      delete theServer;
      QgsWFSServer* theServer = 0;
      try
      {
        theServer = new QgsWFSServer( parameterMap );
      }
      catch ( QgsMapServiceException e ) //admin.sld may be invalid
      {
        theRequestHandler->sendServiceException( e );
        continue;
      }

      theServer->setAdminConfigParser( adminConfigParser );


      //request type
      QString request = parameterMap.value( "REQUEST" );
      if ( request.isEmpty() )
      {
        //do some error handling
        QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
        theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      if ( request.toLower() == QString( "GetCapabilities" ).toLower() )
      {
        QDomDocument capabilitiesDocument;
        try
        {
          capabilitiesDocument = theServer->getCapabilities();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending GetCapabilities response" );
        theRequestHandler->sendGetCapabilitiesResponse( capabilitiesDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }
      else if ( request.toLower() == QString( "DescribeFeatureType" ).toLower() )
      {
        QDomDocument describeDocument;
        try
        {
          describeDocument = theServer->describeFeatureType();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending GetCapabilities response" );
        theRequestHandler->sendGetCapabilitiesResponse( describeDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }
      else if ( request.toLower() == QString( "GetFeature" ).toLower() )
      {
        //output format for GetFeature
        QString outputFormat = parameterMap.value( "OUTPUTFORMAT" );
        try
        {
          if ( theServer->getFeature( *theRequestHandler, outputFormat ) != 0 )
          {
            delete theRequestHandler;
            delete theServer;
            continue;
          }
          else
          {
            delete theRequestHandler;
            delete theServer;
            continue;
          }
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
      }
      else if ( request.toLower() == QString( "Transaction" ).toLower() )
      {
        QDomDocument transactionDocument;
        try
        {
          transactionDocument = theServer->transaction( parameterMap.value( "REQUEST_BODY" ) );
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending Transaction response" );
        theRequestHandler->sendGetCapabilitiesResponse( transactionDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      return 0;
    }

    try
    {
      theServer = new QgsWMSServer( parameterMap, theMapRenderer );
    }
    catch ( QgsMapServiceException e ) //admin.sld may be invalid
    {
      theRequestHandler->sendServiceException( e );
      continue;
    }

    theServer->setAdminConfigParser( adminConfigParser );


    //request type
    QString request = parameterMap.value( "REQUEST" );
    if ( request.isEmpty() )
    {
      //do some error handling
      QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
      theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
      delete theRequestHandler;
      delete theServer;
      continue;
    }

    QString version = parameterMap.value( "VERSION", "1.3.0" );
    bool getProjectSettings = ( request.toLower() == QString( "GetProjectSettings" ).toLower() );
    if ( getProjectSettings )
    {
      version = "1.3.0"; //getProjectSettings extends WMS 1.3.0 capabilities
    }

    if ( request.toLower() == QString( "GetCapabilities" ).toLower() || getProjectSettings )
    {
      const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version );
      if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one
      {
        QgsDebugMsg( "Capabilities document not found in cache" );
        QDomDocument doc;
        try
        {
          doc = theServer->getCapabilities( version, getProjectSettings );
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        capabilitiesCache.insertCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version, &doc );
        capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, getProjectSettings ? "projectSettings" : version );
      }
      else
      {
        QgsDebugMsg( "Found capabilities document in cache" );
      }

      if ( capabilitiesDocument )
      {
        theRequestHandler->sendGetCapabilitiesResponse( *capabilitiesDocument );
      }
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.toLower() == QString( "GetMap" ).toLower() )
    {
      QImage* result = 0;
      try
      {
        result = theServer->getMap();
      }
      catch ( QgsMapServiceException& ex )
      {
        QgsDebugMsg( "Caught exception during GetMap request" );
        theRequestHandler->sendServiceException( ex );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      if ( result )
      {
        QgsDebugMsg( "Sending GetMap response" );
        theRequestHandler->sendGetMapResponse( serviceString, result );
        QgsDebugMsg( "Response sent" );
      }
      else
      {
        //do some error handling
        QgsDebugMsg( "result image is 0" );
      }
      delete result;
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.toLower() == QString( "GetFeatureInfo" ).toLower() )
    {
      QDomDocument featureInfoDoc;
      try
      {
        if ( theServer->getFeatureInfo( featureInfoDoc, version ) != 0 )
        {
          delete theRequestHandler;
          delete theServer;
          continue;
        }
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      QString infoFormat = parameterMap.value( "INFO_FORMAT" );
      theRequestHandler->sendGetFeatureInfoResponse( featureInfoDoc, infoFormat );
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.toLower() == QString( "GetStyles" ).toLower() || request.toLower() == QString( "GetStyle" ).toLower() ) // GetStyle for compatibility with earlier QGIS versions
    {
      try
      {
        QDomDocument doc = theServer->getStyle();
        theRequestHandler->sendGetStyleResponse( doc );
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request.toLower() == QString( "GetLegendGraphic" ).toLower() || request.toLower() == QString( "GetLegendGraphics" ).toLower() ) // GetLegendGraphics for compatibility with earlier QGIS versions
    {
      QImage* result = 0;
      try
      {
        result = theServer->getLegendGraphics();
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      if ( result )
      {
        QgsDebugMsg( "Sending GetLegendGraphic response" );
        //sending is the same for GetMap and GetLegendGraphic
        theRequestHandler->sendGetMapResponse( serviceString, result );
      }
      else
      {
        //do some error handling
        QgsDebugMsg( "result image is 0" );
      }
      delete result;
      delete theRequestHandler;
      delete theServer;
      continue;

    }
    else if ( request.toLower() == QString( "GetPrint" ).toLower() )
    {
      QByteArray* printOutput = 0;
      try
      {
        printOutput = theServer->getPrint( theRequestHandler->format() );
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      if ( printOutput )
      {
        theRequestHandler->sendGetPrintResponse( printOutput );
      }
      delete printOutput;
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else//unknown request
    {
      QgsMapServiceException e( "OperationNotSupported", "Operation " + request + " not supported" );
      theRequestHandler->sendServiceException( e );
      delete theRequestHandler;
      delete theServer;
    }
  }

  delete theMapRenderer;
  QgsDebugMsg( "************* all done ***************" );
  return 0;
}
Exemplo n.º 17
0
/**
 * @brief Handles the request
 * @param queryString
 * @param returnBody
 * @param returnHeaders
 * @return response body and headers if mCaptureOutput is set and the
 * flags are set, empty QByteArray if not
 */
QByteArray QgsServer::handleRequest( const QString queryString ,
                                     bool returnHeaders,
                                     bool returnBody )
{

  // Run init if handleRequest was called without previously initialising
  // the server
  if ( ! mInitialised )
  {
    init( );
  }

  /*
   * This is mainly for python bindings, passing QUERY_STRING
   * to handleRequest without using os.environment
   */
  if ( ! queryString.isEmpty() )
  {
#ifdef _MSC_VER
    _putenv_s( "QUERY_STRING", queryString.toUtf8().data() );
#else
    setenv( "QUERY_STRING", queryString.toUtf8().data(), 1 );
#endif
  }

  int logLevel = QgsServerLogger::instance()->logLevel();
  QTime time; //used for measuring request time if loglevel < 1
  QgsMapLayerRegistry::instance()->removeAllMapLayers();
  mQgsApplication->processEvents();
  if ( logLevel < 1 )
  {
    time.start();
    printRequestInfos();
  }

  //Request handler
  QScopedPointer<QgsRequestHandler> theRequestHandler( createRequestHandler( mCaptureOutput ) );

  try
  {
    // TODO: split parse input into plain parse and processing from specific services
    theRequestHandler->parseInput();
  }
  catch ( QgsMapServiceException& e )
  {
    QgsMessageLog::logMessage( "Parse input exception: " + e.message(), "Server", QgsMessageLog::CRITICAL );
    theRequestHandler->setServiceException( e );
  }

#ifdef HAVE_SERVER_PYTHON_PLUGINS
  // Set the request handler into the interface for plugins to manipulate it
  mServerInterface->setRequestHandler( theRequestHandler.data() );
  // Iterate filters and call their requestReady() method
  QgsServerFiltersMap::const_iterator filtersIterator;
  for ( filtersIterator = mServerInterface->filters().constBegin(); filtersIterator != mServerInterface->filters().constEnd(); ++filtersIterator )
  {
    filtersIterator.value()->requestReady();
  }

  //Pass the filters to the requestHandler, this is needed for the following reasons:
  // 1. allow core services to access plugin filters and implement thir own plugin hooks
  // 2. allow requestHandler to call sendResponse plugin hook

  theRequestHandler->setPluginFilters( mServerInterface->filters() );
#endif

  // Copy the parameters map
  QMap<QString, QString> parameterMap( theRequestHandler->parameterMap() );

  printRequestParameters( parameterMap, logLevel );
  QMap<QString, QString>::const_iterator paramIt;
  //Config file path
  mConfigFilePath = configPath( mConfigFilePath, parameterMap );
#ifdef HAVE_SERVER_PYTHON_PLUGINS
  mServerInterface->setConfigFilePath( mConfigFilePath );
#endif
  //Service parameter
  QString serviceString = theRequestHandler->parameter( "SERVICE" );

  if ( serviceString.isEmpty() )
  {
    // SERVICE not mandatory for WMS 1.3.0 GetMap & GetFeatureInfo
    QString requestString = theRequestHandler->parameter( "REQUEST" );
    if ( requestString == "GetMap" || requestString == "GetFeatureInfo" )
    {
      serviceString = "WMS";
    }
  }

  // Enter core services main switch
  if ( !theRequestHandler->exceptionRaised() )
  {
    if ( serviceString == "WCS" )
    {
      QgsWCSProjectParser* p = QgsConfigCache::instance()->wcsConfiguration( mConfigFilePath );
      if ( !p )
      {
        theRequestHandler->setServiceException( QgsMapServiceException( "Project file error", "Error reading the project file" ) );
      }
      else
      {
        QgsWCSServer wcsServer( mConfigFilePath, parameterMap, p, theRequestHandler.data() );
        wcsServer.executeRequest();
      }
    }
    else if ( serviceString == "WFS" )
    {
      QgsWFSProjectParser* p = QgsConfigCache::instance()->wfsConfiguration( mConfigFilePath );
      if ( !p )
      {
        theRequestHandler->setServiceException( QgsMapServiceException( "Project file error", "Error reading the project file" ) );
      }
      else
      {
        QgsWFSServer wfsServer( mConfigFilePath, parameterMap, p, theRequestHandler.data() );
        wfsServer.executeRequest();
      }
    }
    else if ( serviceString == "WMS" )
    {
      QgsWMSConfigParser* p = QgsConfigCache::instance()->wmsConfiguration( mConfigFilePath, parameterMap );
      if ( !p )
      {
        theRequestHandler->setServiceException( QgsMapServiceException( "WMS configuration error", "There was an error reading the project file or the SLD configuration" ) );
      }
      else
      {
        QgsWMSServer wmsServer( mConfigFilePath, parameterMap, p, theRequestHandler.data(), mMapRenderer, mCapabilitiesCache );
        wmsServer.executeRequest();
      }
    }
    else
    {
      theRequestHandler->setServiceException( QgsMapServiceException( "Service configuration error", "Service unknown or unsupported" ) );
    } // end switch
  } // end if not exception raised

#ifdef HAVE_SERVER_PYTHON_PLUGINS
  // Iterate filters and call their responseComplete() method
  for ( filtersIterator = mServerInterface->filters().constBegin(); filtersIterator != mServerInterface->filters().constEnd(); ++filtersIterator )
  {
    filtersIterator.value()->responseComplete();
  }
#endif
  theRequestHandler->sendResponse();

  if ( logLevel < 1 )
  {
    QgsMessageLog::logMessage( "Request finished in " + QString::number( time.elapsed() ) + " ms", "Server", QgsMessageLog::INFO );
  }
  // TODO: if HAVE_SERVER_PYTHON
  // Returns the response bytestream
  return theRequestHandler->getResponse( returnHeaders , returnBody );
}
Exemplo n.º 18
0
int main( int argc, char * argv[] )
{
#ifndef _MSC_VER
  qInstallMsgHandler( dummyMessageHandler );
#endif

  QgsApplication qgsapp( argc, argv, getenv( "DISPLAY" ) );

  //Default prefix path may be altered by environment variable
  QgsApplication::init();
#if !defined(Q_OS_WIN)
  // init QGIS's paths - true means that all path will be inited from prefix
  QgsApplication::setPrefixPath( CMAKE_INSTALL_PREFIX, TRUE );
#endif

#if defined(MAPSERVER_SKIP_ECW)
  QgsDebugMsg( "Skipping GDAL ECW drivers in server." );
  QgsApplication::skipGdalDriver( "ECW" );
  QgsApplication::skipGdalDriver( "JP2ECW" );
#endif

  setupNetworkAccessManager();
  QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );

  // Instantiate the plugin directory so that providers are loaded
  QgsProviderRegistry::instance( QgsApplication::pluginPath() );
  QgsDebugMsg( "Prefix  PATH: " + QgsApplication::prefixPath() );
  QgsDebugMsg( "Plugin  PATH: " + QgsApplication::pluginPath() );
  QgsDebugMsg( "PkgData PATH: " + QgsApplication::pkgDataPath() );
  QgsDebugMsg( "User DB PATH: " + QgsApplication::qgisUserDbFilePath() );

  QgsDebugMsg( qgsapp.applicationDirPath() + "/qgis_wms_server.log" );
  QgsApplication::createDB(); //init qgis.db (e.g. necessary for user crs)

  QString defaultConfigFilePath;
  QFileInfo projectFileInfo = defaultProjectFile(); //try to find a .qgs file in the server directory
  if ( projectFileInfo.exists() )
  {
    defaultConfigFilePath = projectFileInfo.absoluteFilePath();
    QgsDebugMsg( "Using default project file: " + defaultConfigFilePath );
  }
  else
  {
    QFileInfo adminSLDFileInfo = defaultAdminSLD();
    if ( adminSLDFileInfo.exists() )
    {
      defaultConfigFilePath = adminSLDFileInfo.absoluteFilePath();
    }
  }

  //create cache for capabilities XML
  QgsCapabilitiesCache capabilitiesCache;

  //creating QgsMapRenderer is expensive (access to srs.db), so we do it here before the fcgi loop
  QgsMapRenderer* theMapRenderer = new QgsMapRenderer();
  theMapRenderer->setLabelingEngine( new QgsPalLabeling() );

  printRequestInfos();

#ifdef QGSMSDEBUG
  QgsFontUtils::loadStandardTestFonts( QStringList() << "Roman" << "Bold" );
#endif

  while ( fcgi_accept() >= 0 )
  {
    printRequestInfos(); //print request infos if in debug mode

    //Request handler
    QgsRequestHandler* theRequestHandler = createRequestHandler();
    QMap<QString, QString> parameterMap;
    try
    {
      parameterMap = theRequestHandler->parseInput();
    }
    catch ( QgsMapServiceException& e )
    {
      QgsDebugMsg( "An exception was thrown during input parsing" );
      theRequestHandler->sendServiceException( e );
      continue;
    }

    QMap<QString, QString>::const_iterator paramIt;

    //Config file path
    QString configFilePath = configPath( defaultConfigFilePath, parameterMap );

    //Service parameter
    QString serviceString;
    paramIt = parameterMap.find( "SERVICE" );
    if ( paramIt == parameterMap.constEnd() )
    {
      theRequestHandler->sendServiceException( QgsMapServiceException( "ServiceNotSpecified", "Service not specified. The SERVICE parameter is mandatory" ) );
      delete theRequestHandler;
      continue;
    }
    else
    {
      serviceString = paramIt.value();
    }

    if ( serviceString == "WCS" )
    {
      QgsWCSProjectParser* p = QgsConfigCache::instance()->wcsConfiguration( configFilePath );
      if ( !p )
      {
        //error handling
      }
      QgsWCSServer wcsServer( configFilePath, parameterMap, p, theRequestHandler );
      wcsServer.executeRequest();
    }
    else if ( serviceString == "WFS" )
    {
      QgsWFSProjectParser* p = QgsConfigCache::instance()->wfsConfiguration( configFilePath );
      if ( !p )
      {
        //error handling
      }
      QgsWFSServer wfsServer( configFilePath, parameterMap, p, theRequestHandler );
      wfsServer.executeRequest();
    }
    else    //WMS else
    {
      QgsWMSConfigParser* p = QgsConfigCache::instance()->wmsConfiguration( configFilePath, parameterMap );
      if ( !p )
      {
        //error handling
      }
      //adminConfigParser->loadLabelSettings( theMapRenderer->labelingEngine() );
      QgsWMSServer wmsServer( configFilePath, parameterMap, p, theRequestHandler, theMapRenderer, &capabilitiesCache );
      wmsServer.executeRequest();
    }
  }

  delete theMapRenderer;
  return 0;
}