bool QgsCoordinateReferenceSystem::equals( QString theProj4String ) { QgsCoordinateReferenceSystem r; r.setProj4String( theProj4String ); return *this == r; }
void QgsCustomProjectionDialog::on_buttonBox_accepted() { QgsDebugMsg( "Entered" ); //Update the current CRS: int i = leNameList->currentIndex().row(); if ( i != -1 ) { customCRSnames[i] = leName->text(); customCRSparameters[i] = teParameters->toPlainText(); } QgsDebugMsg( "We save the modified CRS." ); //Check if all CRS are valid: QgsCoordinateReferenceSystem CRS; for ( size_t i = 0; i < customCRSids.size(); ++i ) { CRS.createFromProj4( customCRSparameters[i] ); if ( !CRS.isValid() ) { QMessageBox::information( this, tr( "QGIS Custom Projection" ), tr( "The proj4 definition of '%1' is not valid." ).arg( customCRSnames[i] ) ); return; } } //Modify the CRS changed: bool save_success = true; for ( size_t i = 0; i < customCRSids.size(); ++i ) { CRS.createFromProj4( customCRSparameters[i] ); //Test if we just added this CRS (if it has no existing ID) if ( customCRSids[i] == "" ) { save_success = save_success && saveCRS( CRS, customCRSnames[i], "", true ); } else { if ( existingCRSnames[customCRSids[i]] != customCRSnames[i] || existingCRSparameters[customCRSids[i]] != customCRSparameters[i] ) { save_success = save_success && saveCRS( CRS, customCRSnames[i], customCRSids[i], false ); } } if ( ! save_success ) { QgsDebugMsg( QString( "Error when saving CRS '%1'" ).arg( customCRSnames[i] ) ); } } QgsDebugMsg( "We remove the deleted CRS." ); for ( size_t i = 0; i < deletedCRSs.size(); ++i ) { save_success = save_success && deleteCRS( deletedCRSs[i] ); if ( ! save_success ) { QgsDebugMsg( QString( "Problem for layer '%1'" ).arg( customCRSparameters[i] ) ); } } if ( save_success ) { accept(); } }
// ------------------------ 1.1 ---------------------------------------------- bool QgsWcsCapabilities::parseDescribeCoverageDom11( QByteArray const &xml, QgsWcsCoverageSummary *coverage ) { QgsDebugMsg( "coverage->identifier = " + coverage->identifier ); if ( ! convertToDom( xml ) ) return false; QDomElement docElem = mCapabilitiesDom.documentElement(); QgsDebugMsg( "testing tagName " + docElem.tagName() ); QString tagName = stripNS( docElem.tagName() ); if ( tagName != QLatin1String( "CoverageDescriptions" ) ) { mErrorTitle = tr( "Dom Exception" ); mErrorFormat = QStringLiteral( "text/plain" ); mError = tr( "Could not get WCS capabilities in the expected format (DTD): no %1 found.\nThis might be due to an incorrect WCS Server URL.\nTag: %3\nResponse was:\n%4" ) .arg( QStringLiteral( "CoverageDescriptions" ), docElem.tagName(), QString( xml ) ); QgsLogger::debug( "Dom Exception: " + mError ); return false; } // Get image size, we can get it from BoundingBox with crs=urn:ogc:def:crs:OGC::imageCRS // but while at least one BoundingBox is mandatory, it does not have to be urn:ogc:def:crs:OGC::imageCRS // TODO: if BoundingBox with crs=urn:ogc:def:crs:OGC::imageCRS is not found, // we could calculate image size from GridCRS.GridOffsets (if available) QList<QDomElement> boundingBoxElements = domElements( docElem, QStringLiteral( "CoverageDescription.Domain.SpatialDomain.BoundingBox" ) ); QgsDebugMsg( QStringLiteral( "%1 BoundingBox found" ).arg( boundingBoxElements.size() ) ); const auto constBoundingBoxElements = boundingBoxElements; for ( const QDomElement &el : constBoundingBoxElements ) { QString authid = crsUrnToAuthId( el.attribute( QStringLiteral( "crs" ) ) ); QList<double> low = parseDoubles( domElementText( el, QStringLiteral( "LowerCorner" ) ) ); QList<double> high = parseDoubles( domElementText( el, QStringLiteral( "UpperCorner" ) ) ); if ( low.size() != 2 && high.size() != 2 ) continue; if ( el.attribute( QStringLiteral( "crs" ) ) == QLatin1String( "urn:ogc:def:crs:OGC::imageCRS" ) ) { coverage->width = ( int )( high[0] - low[0] + 1 ); coverage->height = ( int )( high[1] - low[1] + 1 ); coverage->hasSize = true; } else { QgsRectangle box; QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( authid ); if ( crs.isValid() && crs.hasAxisInverted() ) { box = QgsRectangle( low[1], low[0], high[1], high[0] ); } else { box = QgsRectangle( low[0], low[1], high[0], high[1] ); } coverage->boundingBoxes.insert( authid, box ); QgsDebugMsg( "crs: " + crs.authid() + ' ' + crs.description() + QString( " axisInverted = %1" ).arg( crs.hasAxisInverted() ) ); QgsDebugMsg( "BoundingBox: " + authid + " : " + box.toString() ); } } QgsDebugMsg( QStringLiteral( "width = %1 height = %2" ).arg( coverage->width ).arg( coverage->height ) ); // Each georectified coverage should have GridCRS QDomElement gridCRSElement = domElement( docElem, QStringLiteral( "CoverageDescription.Domain.SpatialDomain.GridCRS" ) ); if ( !gridCRSElement.isNull() ) { QString crsUrn = firstChildText( gridCRSElement, QStringLiteral( "GridBaseCRS" ) ); coverage->nativeCrs = crsUrnToAuthId( crsUrn ); QgsDebugMsg( "nativeCrs = " + coverage->nativeCrs ); // TODO: consider getting coverage size from GridOffsets (resolution) // if urn:ogc:def:crs:OGC::imageCRS BoundingBox was not found } coverage->times = domElementsTexts( docElem, QStringLiteral( "CoverageDescription.Domain.TemporalDomain.timePosition" ) ); QList<QDomElement> timePeriodElements = domElements( docElem, QStringLiteral( "CoverageDescription.Domain.TemporalDomain.timePeriod" ) ); QgsDebugMsg( QStringLiteral( "%1 timePeriod found" ).arg( timePeriodElements.size() ) ); const auto constTimePeriodElements = timePeriodElements; for ( const QDomElement &el : constTimePeriodElements ) { QString beginPosition = domElementText( el, QStringLiteral( "beginTime" ) ); QString endPosition = domElementText( el, QStringLiteral( "endTime" ) ); QString timeResolution = domElementText( el, QStringLiteral( "timeResolution" ) ); // Format used in request QString time = beginPosition + '/' + endPosition; if ( !timeResolution.isEmpty() ) { time += '/' + timeResolution; } coverage->times << time; } // NULL / no data values // TODO: handle multiple fields / ranges (?) Q_FOREACH ( const QString &text, domElementsTexts( docElem, "CoverageDescription.Range.Field.NullValue" ) ) { bool ok; double val = text.toDouble( &ok ); if ( ok ) { coverage->nullValues.append( val ); } } QStringList formats = domElementsTexts( docElem, QStringLiteral( "CoverageDescription.SupportedFormat" ) ); // There could be formats from GetCapabilities if ( !formats.isEmpty() ) { coverage->supportedFormat = formats; } QStringList crss = domElementsTexts( docElem, QStringLiteral( "CoverageDescription.SupportedCRS" ) ); QSet<QString> authids; // Set, in case one CRS is in more formats (URN, non URN) const auto constCrss = crss; for ( const QString &crs : constCrss ) { authids.insert( crsUrnToAuthId( crs ) ); } if ( !authids.isEmpty() ) { coverage->supportedCrs = authids.toList(); } coverage->described = true; return true; }
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; }
QList< QList< int > > QgsCoordinateTransform::datumTransformations( const QgsCoordinateReferenceSystem& srcCRS, const QgsCoordinateReferenceSystem& destCRS ) { QList< QList< int > > transformations; QString srcGeoId = srcCRS.geographicCRSAuthId(); QString destGeoId = destCRS.geographicCRSAuthId(); if ( srcGeoId.isEmpty() || destGeoId.isEmpty() ) { return transformations; } QStringList srcSplit = srcGeoId.split( ":" ); QStringList destSplit = destGeoId.split( ":" ); if ( srcSplit.size() < 2 || destSplit.size() < 2 ) { return transformations; } int srcAuthCode = srcSplit.at( 1 ).toInt(); int destAuthCode = destSplit.at( 1 ).toInt(); if ( srcAuthCode == destAuthCode || srcAuthCode == 0 || destAuthCode == 0) { return transformations; //crs have the same datum or no datum } QList<int> directTransforms; searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code=%1 AND target_crs_code=%2" ).arg( srcAuthCode ).arg( destAuthCode ), directTransforms ); QList<int> reverseDirectTransforms; searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code = %1 AND target_crs_code=%2" ).arg( destAuthCode ).arg( srcAuthCode ), reverseDirectTransforms ); //concatenated tranforms QList< QList< int > > concatenatedTransforms; searchDatumTransform2( QString( "SELECT src.coord_op_code, dest.coord_op_code FROM ") + QString( "(SELECT coord_op_code, target_crs_code FROM tbl_datum_transform WHERE source_crs_code=%1) as src " ).arg( srcAuthCode ) + QString( "INNER JOIN ") + QString( "(SELECT coord_op_code, target_crs_code FROM tbl_datum_transform WHERE source_crs_code=%2) as dest " ).arg( destAuthCode ) + QString( "ON src.target_crs_code=dest.target_crs_code ;" ), concatenatedTransforms ); //add direct datum transformations QList<int>::const_iterator directIt = directTransforms.constBegin(); for ( ; directIt != directTransforms.constEnd(); ++directIt ) { transformations.push_back( QList<int>() << *directIt << -1 ); } //add direct datum transformations directIt = reverseDirectTransforms.constBegin(); for ( ; directIt != reverseDirectTransforms.constEnd(); ++directIt ) { transformations.push_back( QList<int>() << -1 << *directIt ); } //append concatenated datum transformations transformations.append( concatenatedTransforms ); return transformations; }
void QgsDistanceArea::setSourceAuthId( QString authId ) { QgsCoordinateReferenceSystem srcCRS; srcCRS.createFromOgcWmsCrs( authId ); mCoordTransform->setSourceCrs( srcCRS ); }
void QgsNewSpatialiteLayerDialog::on_pbnFindSRID_clicked() { // first get list of supported SRID from the selected Spatialite database // to build filter for projection selector sqlite3 *db = nullptr; bool status = true; int rc = sqlite3_open_v2( mDatabaseComboBox->currentText().toUtf8(), &db, SQLITE_OPEN_READONLY, nullptr ); if ( rc != SQLITE_OK ) { QMessageBox::warning( this, tr( "SpatiaLite Database" ), tr( "Unable to open the database" ) ); return; } // load up the srid table const char *pzTail; sqlite3_stmt *ppStmt; QString sql = "select auth_name || ':' || auth_srid from spatial_ref_sys order by srid asc"; QSet<QString> myCRSs; rc = sqlite3_prepare( db, sql.toUtf8(), sql.toUtf8().length(), &ppStmt, &pzTail ); // XXX Need to free memory from the error msg if one is set if ( rc == SQLITE_OK ) { // get the first row of the result set while ( sqlite3_step( ppStmt ) == SQLITE_ROW ) { myCRSs.insert( QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 0 ) ) ); } } else { // XXX query failed -- warn the user some how QMessageBox::warning( nullptr, tr( "Error" ), tr( "Failed to load SRIDS: %1" ).arg( sqlite3_errmsg( db ) ) ); status = false; } // close the statement sqlite3_finalize( ppStmt ); sqlite3_close( db ); if ( !status ) { return; } // prepare projection selector QgsGenericProjectionSelector *mySelector = new QgsGenericProjectionSelector( this ); mySelector->setMessage(); mySelector->setOgcWmsCrsFilter( myCRSs ); mySelector->setSelectedAuthId( mCrsId ); if ( mySelector->exec() ) { QgsCoordinateReferenceSystem srs; srs.createFromOgcWmsCrs( mySelector->selectedAuthId() ); QString crsId = srs.authid(); if ( crsId != mCrsId ) { mCrsId = crsId; leSRID->setText( srs.authid() + " - " + srs.description() ); } } delete mySelector; }
void QgsRasterFileWriter::createVRT( int xSize, int ySize, const QgsCoordinateReferenceSystem& crs, double* geoTransform, QGis::DataType type, const QList<bool>& destHasNoDataValueList, const QList<double>& destNoDataValueList ) { mVRTDocument.clear(); QDomElement VRTDatasetElem = mVRTDocument.createElement( "VRTDataset" ); //xsize / ysize VRTDatasetElem.setAttribute( "rasterXSize", xSize ); VRTDatasetElem.setAttribute( "rasterYSize", ySize ); mVRTDocument.appendChild( VRTDatasetElem ); //CRS QDomElement SRSElem = mVRTDocument.createElement( "SRS" ); QDomText crsText = mVRTDocument.createTextNode( crs.toWkt() ); SRSElem.appendChild( crsText ); VRTDatasetElem.appendChild( SRSElem ); //geotransform if ( geoTransform ) { QDomElement geoTransformElem = mVRTDocument.createElement( "GeoTransform" ); QString geoTransformString = QString::number( geoTransform[0] ) + ", " + QString::number( geoTransform[1] ) + ", " + QString::number( geoTransform[2] ) + ", " + QString::number( geoTransform[3] ) + ", " + QString::number( geoTransform[4] ) + ", " + QString::number( geoTransform[5] ); QDomText geoTransformText = mVRTDocument.createTextNode( geoTransformString ); geoTransformElem.appendChild( geoTransformText ); VRTDatasetElem.appendChild( geoTransformElem ); } int nBands; if ( mMode == Raw ) { nBands = mInput->bandCount(); } else { nBands = 4; } QStringList colorInterp; colorInterp << "Red" << "Green" << "Blue" << "Alpha"; QMap<QGis::DataType, QString> dataTypes; dataTypes.insert( QGis::Byte, "Byte" ); dataTypes.insert( QGis::UInt16, "UInt16" ); dataTypes.insert( QGis::Int16, "Int16" ); dataTypes.insert( QGis::UInt32, "Int32" ); dataTypes.insert( QGis::Float32, "Float32" ); dataTypes.insert( QGis::Float64, "Float64" ); dataTypes.insert( QGis::CInt16, "CInt16" ); dataTypes.insert( QGis::CInt32, "CInt32" ); dataTypes.insert( QGis::CFloat32, "CFloat32" ); dataTypes.insert( QGis::CFloat64, "CFloat64" ); for ( int i = 1; i <= nBands; i++ ) { QDomElement VRTBand = mVRTDocument.createElement( "VRTRasterBand" ); VRTBand.setAttribute( "band", QString::number( i ) ); QString dataType = dataTypes.value( type ); VRTBand.setAttribute( "dataType", dataType ); if ( mMode == Image ) { VRTBand.setAttribute( "dataType", "Byte" ); QDomElement colorInterpElement = mVRTDocument.createElement( "ColorInterp" ); QDomText interpText = mVRTDocument.createTextNode( colorInterp.value( i - 1 ) ); colorInterpElement.appendChild( interpText ); VRTBand.appendChild( colorInterpElement ); } if ( !destHasNoDataValueList.isEmpty() && destHasNoDataValueList.value( i - 1 ) ) { VRTBand.setAttribute( "NoDataValue", QString::number( destNoDataValueList.value( i - 1 ) ) ); } mVRTBands.append( VRTBand ); VRTDatasetElem.appendChild( VRTBand ); } }
bool QgsNorthArrowPlugin::calculateNorthDirection() { QgsMapCanvas& mapCanvas = *( qGisInterface->mapCanvas() ); bool goodDirn = false; if ( mapCanvas.layerCount() > 0 ) { QgsCoordinateReferenceSystem outputCRS = mapCanvas.mapRenderer()->destinationSrs(); if ( outputCRS.isValid() && !outputCRS.geographicFlag() ) { // Use a geographic CRS to get lat/long to work out direction QgsCoordinateReferenceSystem ourCRS; ourCRS.createFromProj4( "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" ); assert( ourCRS.isValid() ); QgsCoordinateTransform transform( outputCRS, ourCRS ); QgsRectangle extent = mapCanvas.extent(); QgsPoint p1( extent.center() ); // A point a bit above p1. XXX assumes that y increases up!! // May need to involve the maptopixel transform if this proves // to be a problem. QgsPoint p2( p1.x(), p1.y() + extent.height() * 0.25 ); // project p1 and p2 to geographic coords try { p1 = transform.transform( p1 ); p2 = transform.transform( p2 ); } catch ( QgsException &e ) { Q_UNUSED( e ); // just give up QgsDebugMsg( "North Arrow: Transformation error, quitting" ); return false; } // Work out the value of the initial heading one takes to go // from point p1 to point p2. The north direction is then that // many degrees anti-clockwise or vertical. // Take some care to not divide by zero, etc, and ensure that we // get sensible results for all possible values for p1 and p2. goodDirn = true; double angle = 0.0; // convert to radians for the equations below p1.multiply( PI / 180.0 ); p2.multiply( PI / 180.0 ); double y = sin( p2.x() - p1.x() ) * cos( p2.y() ); double x = cos( p1.y() ) * sin( p2.y() ) - sin( p1.y() ) * cos( p2.y() ) * cos( p2.x() - p1.x() ); if ( y > 0.0 ) { if ( x > TOL ) angle = atan( y / x ); else if ( x < -TOL ) angle = PI - atan( -y / x ); else angle = 0.5 * PI; } else if ( y < 0.0 ) { if ( x > TOL ) angle = -atan( -y / x ); else if ( x < -TOL ) angle = atan( y / x ) - PI; else angle = 1.5 * PI; } else { if ( x > TOL ) angle = 0.0; else if ( x < -TOL ) angle = PI; else { angle = 0.0; // p1 = p2 goodDirn = false; } } // And set the angle of the north arrow. Perhaps do something // different if goodDirn = false. mRotationInt = static_cast<int>( round( fmod( 360.0 - angle * 180.0 / PI, 360.0 ) ) ); } else { // For geographic CRS and for when there are no layers, set the // direction back to the default mRotationInt = 0; } } return goodDirn; }
void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& format, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect ) { QByteArray result; QString fcString; if ( format == "GeoJSON" ) { fcString = "{\"type\": \"FeatureCollection\",\n"; fcString += " \"bbox\": [ " + QString::number( rect->xMinimum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + ", " + QString::number( rect->yMinimum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + ", " + QString::number( rect->xMaximum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + ", " + QString::number( rect->yMaximum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + "],\n"; fcString += " \"features\": [\n"; result = fcString.toUtf8(); request.startGetFeatureResponse( &result, format ); } else { //Prepare url //Some client requests already have http://<SERVER_NAME> in the REQUEST_URI variable QString hrefString; QString requestUrl = getenv( "REQUEST_URI" ); QUrl mapUrl( requestUrl ); mapUrl.setHost( QString( getenv( "SERVER_NAME" ) ) ); //Add non-default ports to url QString portString = getenv( "SERVER_PORT" ); if ( !portString.isEmpty() ) { bool portOk; int portNumber = portString.toInt( &portOk ); if ( portOk ) { if ( portNumber != 80 ) { mapUrl.setPort( portNumber ); } } } if ( QString( getenv( "HTTPS" ) ).compare( "on", Qt::CaseInsensitive ) == 0 ) { mapUrl.setScheme( "https" ); } else { mapUrl.setScheme( "http" ); } QList<QPair<QString, QString> > queryItems = mapUrl.queryItems(); QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin(); for ( ; queryIt != queryItems.constEnd(); ++queryIt ) { if ( queryIt->first.compare( "REQUEST", Qt::CaseInsensitive ) == 0 ) { mapUrl.removeQueryItem( queryIt->first ); mapUrl.addQueryItem( queryIt->first, "DescribeFeatureType" ); } else if ( queryIt->first.compare( "FORMAT", Qt::CaseInsensitive ) == 0 ) { mapUrl.removeQueryItem( queryIt->first ); } else if ( queryIt->first.compare( "OUTPUTFORMAT", Qt::CaseInsensitive ) == 0 ) { mapUrl.removeQueryItem( queryIt->first ); } else if ( queryIt->first.compare( "BBOX", Qt::CaseInsensitive ) == 0 ) { mapUrl.removeQueryItem( queryIt->first ); } else if ( queryIt->first.compare( "FEATUREID", Qt::CaseInsensitive ) == 0 ) { mapUrl.removeQueryItem( queryIt->first ); } else if ( queryIt->first.compare( "FILTER", Qt::CaseInsensitive ) == 0 ) { mapUrl.removeQueryItem( queryIt->first ); } else if ( queryIt->first.compare( "MAXFEATURES", Qt::CaseInsensitive ) == 0 ) { mapUrl.removeQueryItem( queryIt->first ); } else if ( queryIt->first.compare( "PROPERTYNAME", Qt::CaseInsensitive ) == 0 ) { mapUrl.removeQueryItem( queryIt->first ); } else if ( queryIt->first.compare( "_DC", Qt::CaseInsensitive ) == 0 ) { mapUrl.removeQueryItem( queryIt->first ); } } mapUrl.addQueryItem( "OUTPUTFORMAT", "XMLSCHEMA" ); hrefString = mapUrl.toString(); //wfs:FeatureCollection fcString = "<wfs:FeatureCollection"; fcString += " xmlns:wfs=\"http://www.opengis.net/wfs\""; fcString += " xmlns:ogc=\"http://www.opengis.net/ogc\""; fcString += " xmlns:gml=\"http://www.opengis.net/gml\""; fcString += " xmlns:ows=\"http://www.opengis.net/ows\""; fcString += " xmlns:xlink=\"http://www.w3.org/1999/xlink\""; fcString += " xmlns:qgs=\"http://www.qgis.org/gml\""; fcString += " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""; fcString += " xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://www.qgis.org/gml " + hrefString.replace( "&", "&" ) + "\""; fcString += ">"; result = fcString.toUtf8(); request.startGetFeatureResponse( &result, format ); QDomDocument doc; QDomElement bbElem = doc.createElement( "gml:boundedBy" ); QDomElement boxElem = createBoxElem( rect, doc ); if ( !boxElem.isNull() ) { if ( crs.isValid() ) { boxElem.setAttribute( "srsName", crs.authid() ); } bbElem.appendChild( boxElem ); doc.appendChild( bbElem ); } result = doc.toByteArray(); request.sendGetFeatureResponse( &result ); } fcString = ""; }
bool QgsDecorationNorthArrow::calculateNorthDirection() { QgsMapCanvas* mapCanvas = QgisApp::instance()->mapCanvas(); bool goodDirn = false; // Get the shown extent... QgsRectangle canvasExtent = mapCanvas->extent(); // ... and all layers extent, ... QgsRectangle fullExtent = mapCanvas->fullExtent(); // ... and combine QgsRectangle extent = canvasExtent.intersect( & fullExtent ); // If no layers are added or shown, we can't get any direction if ( mapCanvas->layerCount() > 0 && ! extent.isEmpty() ) { QgsCoordinateReferenceSystem outputCRS = mapCanvas->mapSettings().destinationCrs(); if ( outputCRS.isValid() && !outputCRS.geographicFlag() ) { // Use a geographic CRS to get lat/long to work out direction QgsCoordinateReferenceSystem ourCRS; ourCRS.createFromOgcWmsCrs( GEO_EPSG_CRS_AUTHID ); assert( ourCRS.isValid() ); QgsCoordinateTransform transform( outputCRS, ourCRS ); QgsPoint p1( extent.center() ); // A point a bit above p1. XXX assumes that y increases up!! // May need to involve the maptopixel transform if this proves // to be a problem. QgsPoint p2( p1.x(), p1.y() + extent.height() * 0.25 ); // project p1 and p2 to geographic coords try { p1 = transform.transform( p1 ); p2 = transform.transform( p2 ); } catch ( QgsCsException &e ) { Q_UNUSED( e ); // just give up QgsDebugMsg( "North Arrow: Transformation error, quitting" ); return false; } // Work out the value of the initial heading one takes to go // from point p1 to point p2. The north direction is then that // many degrees anti-clockwise or vertical. // Take some care to not divide by zero, etc, and ensure that we // get sensible results for all possible values for p1 and p2. goodDirn = true; double angle = 0.0; // convert to radians for the equations below p1.multiply( PI / 180.0 ); p2.multiply( PI / 180.0 ); double y = sin( p2.x() - p1.x() ) * cos( p2.y() ); double x = cos( p1.y() ) * sin( p2.y() ) - sin( p1.y() ) * cos( p2.y() ) * cos( p2.x() - p1.x() ); // Use TOL to decide if the quotient is big enough. // Both x and y can be very small, if heavily zoomed // For small y/x, we set directly angle 0. Not sure // if this is needed. if ( y > 0.0 ) { if ( x > 0.0 && ( y / x ) > TOL ) angle = atan( y / x ); else if ( x < 0.0 && ( y / x ) < -TOL ) angle = PI - atan( -y / x ); else angle = 0.5 * PI; } else if ( y < 0.0 ) { if ( x > 0.0 && ( y / x ) < -TOL ) angle = -atan( -y / x ); else if ( x < 0.0 && ( y / x ) > TOL ) angle = atan( y / x ) - PI; else angle = 1.5 * PI; } else { if ( x > TOL ) angle = 0.0; else if ( x < -TOL ) angle = PI; else { angle = 0.0; // p1 = p2 goodDirn = false; } } // And set the angle of the north arrow. Perhaps do something // different if goodDirn = false. mRotationInt = qRound( fmod( 360.0 - angle * 180.0 / PI, 360.0 ) ); } else { // For geographic CRS and for when there are no layers, set the // direction back to the default mRotationInt = 0; } } mRotationInt += mapCanvas->mapSettings().rotation(); return goodDirn; }
void QgsMapToolViewshed::drawFinished() { QString layerid = QgsProject::instance()->readEntry( "Heightmap", "layer" ); QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerid ); if ( !layer || layer->type() != QgsMapLayer::RasterLayer ) { QgisApp::instance()->messageBar()->pushMessage( tr( "No heightmap is defined in the project." ), tr( "Right-click a raster layer in the layer tree and select it to be used as heightmap." ), QgsMessageBar::INFO, 10 ); reset(); return; } QgsCoordinateReferenceSystem canvasCrs = canvas()->mapSettings().destinationCrs(); double curRadius; QgsPoint center; double trash; getPart( 0, center, curRadius, trash, trash ); QGis::UnitType measureUnit = canvasCrs.mapUnits(); QgsDistanceArea().convertMeasurement( curRadius, measureUnit, QGis::Meters, false ); QgsViewshedDialog viewshedDialog( curRadius ); connect( &viewshedDialog, SIGNAL( radiusChanged( double ) ), this, SLOT( adjustRadius( double ) ) ); if ( viewshedDialog.exec() == QDialog::Rejected ) { reset(); return; } QString outputFileName = QString( "viewshed_%1,%2.tif" ).arg( center.x() ).arg( center.y() ); QString outputFile = QgsTemporaryFile::createNewFile( outputFileName ); QVector<QgsPoint> filterRegion; QgsPolygon poly = QgsGeometry( getRubberBand()->geometry()->clone() ).asPolygon(); if ( !poly.isEmpty() ) { filterRegion = poly.front(); } getPart( 0, center, curRadius, trash, trash ); if ( mCanvas->mapSettings().mapUnits() == QGis::Degrees ) { // Need to compute radius in meters QgsDistanceArea da; da.setSourceCrs( mCanvas->mapSettings().destinationCrs() ); da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); da.setEllipsoidalMode( mCanvas->mapSettings().hasCrsTransformEnabled() ); curRadius = da.measureLine( center, QgsPoint( center.x() + curRadius, center.y() ) ); QGis::UnitType measureUnits = mCanvas->mapSettings().mapUnits(); da.convertMeasurement( curRadius, measureUnits, QGis::Meters, false ); } double heightConv = QGis::fromUnitToUnitFactor( QgsCoordinateFormat::instance()->getHeightDisplayUnit(), QGis::Meters ); QProgressDialog p( tr( "Calculating viewshed..." ), tr( "Abort" ), 0, 0 ); p.setWindowTitle( tr( "Viewshed" ) ); p.setWindowModality( Qt::ApplicationModal ); bool displayVisible = viewshedDialog.getDisplayMode() == QgsViewshedDialog::DisplayVisibleArea; int accuracyFactor = viewshedDialog.getAccuracyFactor(); QApplication::setOverrideCursor( Qt::WaitCursor ); bool success = QgsViewshed::computeViewshed( layer->source(), outputFile, "GTiff", center, canvasCrs, viewshedDialog.getObserverHeight() * heightConv, viewshedDialog.getTargetHeight() * heightConv, viewshedDialog.getHeightRelativeToGround(), curRadius, QGis::Meters, filterRegion, displayVisible, accuracyFactor, &p ); QApplication::restoreOverrideCursor(); if ( success ) { QgsRasterLayer* layer = new QgsRasterLayer( outputFile, tr( "Viewshed [%1]" ).arg( center.toString() ) ); QgsColorRampShader* rampShader = new QgsColorRampShader(); if ( displayVisible ) { QList<QgsColorRampShader::ColorRampItem> colorRampItems = QList<QgsColorRampShader::ColorRampItem>() << QgsColorRampShader::ColorRampItem( 0, QColor( 0, 0, 0, 0 ), "" ) << QgsColorRampShader::ColorRampItem( 255, QColor( 0, 255, 0 ), tr( "Visible" ) ); rampShader->setColorRampItemList( colorRampItems ); } else { QList<QgsColorRampShader::ColorRampItem> colorRampItems = QList<QgsColorRampShader::ColorRampItem>() << QgsColorRampShader::ColorRampItem( 0, QColor( 0, 0, 0, 0 ), "" ) << QgsColorRampShader::ColorRampItem( 0, QColor( 255, 0, 0 ), tr( "Invisible" ) ); rampShader->setColorRampItemList( colorRampItems ); } QgsRasterShader* shader = new QgsRasterShader(); shader->setRasterShaderFunction( rampShader ); QgsSingleBandPseudoColorRenderer* renderer = new QgsSingleBandPseudoColorRenderer( 0, 1, shader ); layer->setRenderer( renderer ); QgsMapLayerRegistry::instance()->addMapLayer( layer ); QgsPinAnnotationItem* pin = new QgsPinAnnotationItem( canvas() ); pin->setMapPosition( center, canvasCrs ); pin->setItemFlags( pin->itemFlags() | QgsAnnotationItem::ItemMapPositionLocked ); QgisApp::instance()->itemCouplingManager()->addCoupling( layer, pin ); } else { QMessageBox::critical( 0, tr( "Error" ), tr( "Failed to compute viewshed." ) ); } reset(); }
void QgsArcGisServiceSourceSelect::addButtonClicked() { if ( treeView->selectionModel()->selectedRows().isEmpty() ) { return; } QgsOwsConnection connection( mServiceName, cmbConnections->currentText() ); QString pCrsString( labelCoordRefSys->text() ); QgsCoordinateReferenceSystem pCrs( pCrsString ); //prepare canvas extent info for layers with "cache features" option not set QgsRectangle extent; QgsCoordinateReferenceSystem canvasCrs; if ( mapCanvas() ) { extent = mapCanvas()->extent(); canvasCrs = mapCanvas()->mapSettings().destinationCrs(); } //does canvas have "on the fly" reprojection set? if ( pCrs.isValid() && canvasCrs.isValid() ) { try { Q_NOWARN_DEPRECATED_PUSH extent = QgsCoordinateTransform( canvasCrs, pCrs ).transform( extent ); Q_NOWARN_DEPRECATED_POP QgsDebugMsg( QStringLiteral( "canvas transform: Canvas CRS=%1, Provider CRS=%2, BBOX=%3" ) .arg( canvasCrs.authid(), pCrs.authid(), extent.asWktCoordinates() ) ); } catch ( const QgsCsException & ) { // Extent is not in range for specified CRS, leave extent empty. } } //create layers that user selected from this feature source QModelIndexList list = treeView->selectionModel()->selectedRows(); for ( int i = 0; i < list.size(); i++ ) { //add a wfs layer to the map QModelIndex idx = mModelProxy->mapToSource( list[i] ); if ( !idx.isValid() ) { continue; } int row = idx.row(); if ( !mModel->itemFromIndex( mModel->index( row, 0, idx.parent() ) )->data( IsLayerRole ).toBool() ) continue; QString layerTitle = mModel->itemFromIndex( mModel->index( row, 0, idx.parent() ) )->text(); //layer title/id QString layerName = mModel->itemFromIndex( mModel->index( row, 1, idx.parent() ) )->text(); //layer name const QString layerUri = mModel->itemFromIndex( mModel->index( row, 0, idx.parent() ) )->data( UrlRole ).toString(); QString filter = mServiceType == FeatureService ? mModel->itemFromIndex( mModel->index( row, 3, idx.parent() ) )->text() : QString(); //optional filter specified by user if ( cbxUseTitleLayerName->isChecked() && !layerTitle.isEmpty() ) { layerName = layerTitle; } QgsRectangle layerExtent; if ( mServiceType == FeatureService && ( cbxFeatureCurrentViewExtent->isChecked() ) ) { layerExtent = extent; } QString uri = getLayerURI( connection, layerUri.isEmpty() ? layerTitle : layerUri, layerName, pCrsString, filter, layerExtent ); QgsDebugMsg( "Layer " + layerName + ", uri: " + uri ); addServiceLayer( uri, layerName ); } accept(); }
void QgsWfsCapabilities::capabilitiesReplyFinished() { const QByteArray& buffer = mResponse; QgsDebugMsg( "parsing capabilities: " + buffer ); // parse XML QString capabilitiesDocError; QDomDocument capabilitiesDocument; if ( !capabilitiesDocument.setContent( buffer, true, &capabilitiesDocError ) ) { mErrorCode = QgsWfsRequest::XmlError; mErrorMessage = capabilitiesDocError; emit gotCapabilities(); return; } QDomElement doc = capabilitiesDocument.documentElement(); // handle exceptions if ( doc.tagName() == QLatin1String( "ExceptionReport" ) ) { QDomNode ex = doc.firstChild(); QString exc = ex.toElement().attribute( QStringLiteral( "exceptionCode" ), QStringLiteral( "Exception" ) ); QDomElement ext = ex.firstChild().toElement(); mErrorCode = QgsWfsRequest::ServerExceptionError; mErrorMessage = exc + ": " + ext.firstChild().nodeValue(); emit gotCapabilities(); return; } mCaps.clear(); //test wfs version mCaps.version = doc.attribute( QStringLiteral( "version" ) ); if ( !mCaps.version.startsWith( QLatin1String( "1.0" ) ) && !mCaps.version.startsWith( QLatin1String( "1.1" ) ) && !mCaps.version.startsWith( QLatin1String( "2.0" ) ) ) { mErrorCode = WFSVersionNotSupported; mErrorMessage = tr( "WFS version %1 not supported" ).arg( mCaps.version ); emit gotCapabilities(); return; } // WFS 2.0 implementation are supposed to implement resultType=hits, and some // implementations (GeoServer) might advertize it, whereas others (MapServer) do not. // WFS 1.1 implementation too I think, but in the examples of the GetCapabilities // response of the WFS 1.1 standard (and in common implementations), this is // explicitly advertized if ( mCaps.version.startsWith( QLatin1String( "2.0" ) ) ) mCaps.supportsHits = true; // Note: for conveniency, we do not use the elementsByTagNameNS() method as // the WFS and OWS namespaces URI are not the same in all versions // find <ows:OperationsMetadata> QDomElement operationsMetadataElem = doc.firstChildElement( QStringLiteral( "OperationsMetadata" ) ); if ( !operationsMetadataElem.isNull() ) { QDomNodeList contraintList = operationsMetadataElem.elementsByTagName( QStringLiteral( "Constraint" ) ); for ( int i = 0; i < contraintList.size(); ++i ) { QDomElement contraint = contraintList.at( i ).toElement(); if ( contraint.attribute( QStringLiteral( "name" ) ) == QLatin1String( "DefaultMaxFeatures" ) /* WFS 1.1 */ ) { QDomElement value = contraint.firstChildElement( QStringLiteral( "Value" ) ); if ( !value.isNull() ) { mCaps.maxFeatures = value.text().toInt(); QgsDebugMsg( QString( "maxFeatures: %1" ).arg( mCaps.maxFeatures ) ); } } else if ( contraint.attribute( QStringLiteral( "name" ) ) == QLatin1String( "CountDefault" ) /* WFS 2.0 (e.g. MapServer) */ ) { QDomElement value = contraint.firstChildElement( QStringLiteral( "DefaultValue" ) ); if ( !value.isNull() ) { mCaps.maxFeatures = value.text().toInt(); QgsDebugMsg( QString( "maxFeatures: %1" ).arg( mCaps.maxFeatures ) ); } } else if ( contraint.attribute( QStringLiteral( "name" ) ) == QLatin1String( "ImplementsResultPaging" ) /* WFS 2.0 */ ) { QDomElement value = contraint.firstChildElement( QStringLiteral( "DefaultValue" ) ); if ( !value.isNull() && value.text() == QLatin1String( "TRUE" ) ) { mCaps.supportsPaging = true; QgsDebugMsg( "Supports paging" ); } } else if ( contraint.attribute( QStringLiteral( "name" ) ) == QLatin1String( "ImplementsStandardJoins" ) || contraint.attribute( QStringLiteral( "name" ) ) == QLatin1String( "ImplementsSpatialJoins" ) /* WFS 2.0 */ ) { QDomElement value = contraint.firstChildElement( QStringLiteral( "DefaultValue" ) ); if ( !value.isNull() && value.text() == QLatin1String( "TRUE" ) ) { mCaps.supportsJoins = true; QgsDebugMsg( "Supports joins" ); } } } // In WFS 2.0, max features can also be set in Operation.GetFeature (e.g. GeoServer) // and we are also interested by resultType=hits for WFS 1.1 QDomNodeList operationList = operationsMetadataElem.elementsByTagName( QStringLiteral( "Operation" ) ); for ( int i = 0; i < operationList.size(); ++i ) { QDomElement operation = operationList.at( i ).toElement(); if ( operation.attribute( QStringLiteral( "name" ) ) == QLatin1String( "GetFeature" ) ) { QDomNodeList operationContraintList = operation.elementsByTagName( QStringLiteral( "Constraint" ) ); for ( int j = 0; j < operationContraintList.size(); ++j ) { QDomElement contraint = operationContraintList.at( j ).toElement(); if ( contraint.attribute( QStringLiteral( "name" ) ) == QLatin1String( "CountDefault" ) ) { QDomElement value = contraint.firstChildElement( QStringLiteral( "DefaultValue" ) ); if ( !value.isNull() ) { mCaps.maxFeatures = value.text().toInt(); QgsDebugMsg( QString( "maxFeatures: %1" ).arg( mCaps.maxFeatures ) ); } break; } } QDomNodeList parameterList = operation.elementsByTagName( QStringLiteral( "Parameter" ) ); for ( int j = 0; j < parameterList.size(); ++j ) { QDomElement parameter = parameterList.at( j ).toElement(); if ( parameter.attribute( QStringLiteral( "name" ) ) == QLatin1String( "resultType" ) ) { QDomNodeList valueList = parameter.elementsByTagName( QStringLiteral( "Value" ) ); for ( int k = 0; k < valueList.size(); ++k ) { QDomElement value = valueList.at( k ).toElement(); if ( value.text() == QLatin1String( "hits" ) ) { mCaps.supportsHits = true; QgsDebugMsg( "Support hits" ); break; } } } } break; } } } //go to <FeatureTypeList> QDomElement featureTypeListElem = doc.firstChildElement( QStringLiteral( "FeatureTypeList" ) ); if ( featureTypeListElem.isNull() ) { emit gotCapabilities(); return; } // Parse operations supported for all feature types bool insertCap = false; bool updateCap = false; bool deleteCap = false; // WFS < 2 if ( mCaps.version.startsWith( QLatin1String( "1" ) ) ) { parseSupportedOperations( featureTypeListElem.firstChildElement( QStringLiteral( "Operations" ) ), insertCap, updateCap, deleteCap ); } else // WFS 2.0.0 tested on GeoServer { QDomNodeList operationNodes = doc.elementsByTagName( "Operation" ); for ( int i = 0; i < operationNodes.count(); i++ ) { QDomElement operationElement = operationNodes.at( i ).toElement( ); if ( operationElement.isElement( ) && "Transaction" == operationElement.attribute( "name" ) ) { insertCap = true; updateCap = true; deleteCap = true; } } } // get the <FeatureType> elements QDomNodeList featureTypeList = featureTypeListElem.elementsByTagName( QStringLiteral( "FeatureType" ) ); for ( int i = 0; i < featureTypeList.size(); ++i ) { FeatureType featureType; QDomElement featureTypeElem = featureTypeList.at( i ).toElement(); //Name QDomNodeList nameList = featureTypeElem.elementsByTagName( QStringLiteral( "Name" ) ); if ( nameList.length() > 0 ) { featureType.name = nameList.at( 0 ).toElement().text(); } //Title QDomNodeList titleList = featureTypeElem.elementsByTagName( QStringLiteral( "Title" ) ); if ( titleList.length() > 0 ) { featureType.title = titleList.at( 0 ).toElement().text(); } //Abstract QDomNodeList abstractList = featureTypeElem.elementsByTagName( QStringLiteral( "Abstract" ) ); if ( abstractList.length() > 0 ) { featureType.abstract = abstractList.at( 0 ).toElement().text(); } //DefaultSRS is always the first entry in the feature srs list QDomNodeList defaultCRSList = featureTypeElem.elementsByTagName( QStringLiteral( "DefaultSRS" ) ); if ( defaultCRSList.length() == 0 ) // In WFS 2.0, this is spelled DefaultCRS... defaultCRSList = featureTypeElem.elementsByTagName( QStringLiteral( "DefaultCRS" ) ); if ( defaultCRSList.length() > 0 ) { QString srsname( defaultCRSList.at( 0 ).toElement().text() ); // Some servers like Geomedia advertize EPSG:XXXX even in WFS 1.1 or 2.0 if ( srsname.startsWith( QLatin1String( "EPSG:" ) ) ) mCaps.useEPSGColumnFormat = true; featureType.crslist.append( NormalizeSRSName( srsname ) ); } //OtherSRS QDomNodeList otherCRSList = featureTypeElem.elementsByTagName( QStringLiteral( "OtherSRS" ) ); if ( otherCRSList.length() == 0 ) // In WFS 2.0, this is spelled OtherCRS... otherCRSList = featureTypeElem.elementsByTagName( QStringLiteral( "OtherCRS" ) ); for ( int i = 0; i < otherCRSList.size(); ++i ) { featureType.crslist.append( NormalizeSRSName( otherCRSList.at( i ).toElement().text() ) ); } //Support <SRS> for compatibility with older versions QDomNodeList srsList = featureTypeElem.elementsByTagName( QStringLiteral( "SRS" ) ); for ( int i = 0; i < srsList.size(); ++i ) { featureType.crslist.append( NormalizeSRSName( srsList.at( i ).toElement().text() ) ); } // Get BBox WFS 1.0 way QDomElement latLongBB = featureTypeElem.firstChildElement( QStringLiteral( "LatLongBoundingBox" ) ); if ( latLongBB.hasAttributes() ) { // Despite the name LatLongBoundingBox, the coordinates are supposed to // be expressed in <SRS>. From the WFS schema; // <!-- The LatLongBoundingBox element is used to indicate the edges of // an enclosing rectangle in the SRS of the associated feature type. featureType.bbox = QgsRectangle( latLongBB.attribute( QStringLiteral( "minx" ) ).toDouble(), latLongBB.attribute( QStringLiteral( "miny" ) ).toDouble(), latLongBB.attribute( QStringLiteral( "maxx" ) ).toDouble(), latLongBB.attribute( QStringLiteral( "maxy" ) ).toDouble() ); featureType.bboxSRSIsWGS84 = false; // But some servers do not honour this and systematically reproject to WGS84 // such as GeoServer. See http://osgeo-org.1560.x6.nabble.com/WFS-LatLongBoundingBox-td3813810.html // This is also true of TinyOWS if ( !featureType.crslist.isEmpty() && featureType.bbox.xMinimum() >= -180 && featureType.bbox.yMinimum() >= -90 && featureType.bbox.xMaximum() <= 180 && featureType.bbox.yMaximum() < 90 ) { QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( featureType.crslist[0] ); if ( !crs.isGeographic() ) { // If the CRS is projected then check that projecting the corner of the bbox, assumed to be in WGS84, // into the CRS, and then back to WGS84, works (check that we are in the validity area) QgsCoordinateReferenceSystem crsWGS84 = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "CRS:84" ) ); QgsCoordinateTransform ct( crsWGS84, crs ); QgsPoint ptMin( featureType.bbox.xMinimum(), featureType.bbox.yMinimum() ); QgsPoint ptMinBack( ct.transform( ct.transform( ptMin, QgsCoordinateTransform::ForwardTransform ), QgsCoordinateTransform::ReverseTransform ) ); QgsPoint ptMax( featureType.bbox.xMaximum(), featureType.bbox.yMaximum() ); QgsPoint ptMaxBack( ct.transform( ct.transform( ptMax, QgsCoordinateTransform::ForwardTransform ), QgsCoordinateTransform::ReverseTransform ) ); QgsDebugMsg( featureType.bbox.toString() ); QgsDebugMsg( ptMinBack.toString() ); QgsDebugMsg( ptMaxBack.toString() ); if ( fabs( featureType.bbox.xMinimum() - ptMinBack.x() ) < 1e-5 && fabs( featureType.bbox.yMinimum() - ptMinBack.y() ) < 1e-5 && fabs( featureType.bbox.xMaximum() - ptMaxBack.x() ) < 1e-5 && fabs( featureType.bbox.yMaximum() - ptMaxBack.y() ) < 1e-5 ) { QgsDebugMsg( "Values of LatLongBoundingBox are consistent with WGS84 long/lat bounds, so as the CRS is projected, assume they are indeed in WGS84 and not in the CRS units" ); featureType.bboxSRSIsWGS84 = true; } } } } else { // WFS 1.1 way QDomElement WGS84BoundingBox = featureTypeElem.firstChildElement( QStringLiteral( "WGS84BoundingBox" ) ); if ( !WGS84BoundingBox.isNull() ) { QDomElement lowerCorner = WGS84BoundingBox.firstChildElement( QStringLiteral( "LowerCorner" ) ); QDomElement upperCorner = WGS84BoundingBox.firstChildElement( QStringLiteral( "UpperCorner" ) ); if ( !lowerCorner.isNull() && !upperCorner.isNull() ) { QStringList lowerCornerList = lowerCorner.text().split( QStringLiteral( " " ), QString::SkipEmptyParts ); QStringList upperCornerList = upperCorner.text().split( QStringLiteral( " " ), QString::SkipEmptyParts ); if ( lowerCornerList.size() == 2 && upperCornerList.size() == 2 ) { featureType.bbox = QgsRectangle( lowerCornerList[0].toDouble(), lowerCornerList[1].toDouble(), upperCornerList[0].toDouble(), upperCornerList[1].toDouble() ); featureType.bboxSRSIsWGS84 = true; } } } } // Parse Operations specific to the type name parseSupportedOperations( featureTypeElem.firstChildElement( QStringLiteral( "Operations" ) ), featureType.insertCap, featureType.updateCap, featureType.deleteCap ); featureType.insertCap |= insertCap; featureType.updateCap |= updateCap; featureType.deleteCap |= deleteCap; mCaps.featureTypes.push_back( featureType ); } Q_FOREACH ( const FeatureType& f, mCaps.featureTypes ) { mCaps.setAllTypenames.insert( f.name ); QString unprefixed( QgsWFSUtils::removeNamespacePrefix( f.name ) ); if ( !mCaps.setAmbiguousUnprefixedTypename.contains( unprefixed ) ) { if ( mCaps.mapUnprefixedTypenameToPrefixedTypename.contains( unprefixed ) ) { mCaps.setAmbiguousUnprefixedTypename.insert( unprefixed ); mCaps.mapUnprefixedTypenameToPrefixedTypename.remove( unprefixed ); } else { mCaps.mapUnprefixedTypenameToPrefixedTypename[unprefixed] = f.name; } } } //go to <Filter_Capabilities> QDomElement filterCapabilitiesElem = doc.firstChildElement( QStringLiteral( "Filter_Capabilities" ) ); if ( !filterCapabilitiesElem.isNull() ) parseFilterCapabilities( filterCapabilitiesElem ); // Hard-coded functions Function f_ST_GeometryFromText( QStringLiteral( "ST_GeometryFromText" ), 1, 2 ); f_ST_GeometryFromText.returnType = QStringLiteral( "gml:AbstractGeometryType" ); f_ST_GeometryFromText.argumentList << Argument( QStringLiteral( "wkt" ), QStringLiteral( "xs:string" ) ); f_ST_GeometryFromText.argumentList << Argument( QStringLiteral( "srsname" ), QStringLiteral( "xs:string" ) ); mCaps.functionList << f_ST_GeometryFromText; Function f_ST_GeomFromGML( QStringLiteral( "ST_GeomFromGML" ), 1 ); f_ST_GeomFromGML.returnType = QStringLiteral( "gml:AbstractGeometryType" ); f_ST_GeomFromGML.argumentList << Argument( QStringLiteral( "gml" ), QStringLiteral( "xs:string" ) ); mCaps.functionList << f_ST_GeomFromGML; Function f_ST_MakeEnvelope( QStringLiteral( "ST_MakeEnvelope" ), 4, 5 ); f_ST_MakeEnvelope.returnType = QStringLiteral( "gml:AbstractGeometryType" ); f_ST_MakeEnvelope.argumentList << Argument( QStringLiteral( "minx" ), QStringLiteral( "xs:double" ) ); f_ST_MakeEnvelope.argumentList << Argument( QStringLiteral( "miny" ), QStringLiteral( "xs:double" ) ); f_ST_MakeEnvelope.argumentList << Argument( QStringLiteral( "maxx" ), QStringLiteral( "xs:double" ) ); f_ST_MakeEnvelope.argumentList << Argument( QStringLiteral( "maxy" ), QStringLiteral( "xs:double" ) ); f_ST_MakeEnvelope.argumentList << Argument( QStringLiteral( "srsname" ), QStringLiteral( "xs:string" ) ); mCaps.functionList << f_ST_MakeEnvelope; emit gotCapabilities(); }
void QgsDistanceArea::setSourceCrs( long srsid ) { QgsCoordinateReferenceSystem srcCRS; srcCRS.createFromSrsId( srsid ); mCoordTransform->setSourceCrs( srcCRS ); }
QDomElement QgsXmlUtils::writeVariant( const QVariant &value, QDomDocument &doc ) { QDomElement element = doc.createElement( QStringLiteral( "Option" ) ); switch ( value.type() ) { case QVariant::Invalid: { element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "invalid" ) ); break; } case QVariant::Map: { QVariantMap map = value.toMap(); for ( auto option = map.constBegin(); option != map.constEnd(); ++option ) { QDomElement optionElement = writeVariant( option.value(), doc ); optionElement.setAttribute( QStringLiteral( "name" ), option.key() ); element.appendChild( optionElement ); element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "Map" ) ); } break; } case QVariant::List: { QVariantList list = value.toList(); const auto constList = list; for ( const QVariant &value : constList ) { QDomElement valueElement = writeVariant( value, doc ); element.appendChild( valueElement ); element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "List" ) ); } break; } case QVariant::StringList: { QStringList list = value.toStringList(); const auto constList = list; for ( const QString &value : constList ) { QDomElement valueElement = writeVariant( value, doc ); element.appendChild( valueElement ); element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "StringList" ) ); } break; } case QVariant::Int: case QVariant::UInt: case QVariant::Bool: case QVariant::Double: case QVariant::LongLong: case QVariant::ULongLong: case QVariant::String: element.setAttribute( QStringLiteral( "type" ), QVariant::typeToName( value.type() ) ); element.setAttribute( QStringLiteral( "value" ), value.toString() ); break; case QVariant::UserType: { if ( value.canConvert< QgsProperty >() ) { element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsProperty" ) ); const QDomElement propertyElem = QgsXmlUtils::writeVariant( value.value< QgsProperty >().toVariant(), doc ); element.appendChild( propertyElem ); break; } else if ( value.canConvert< QgsCoordinateReferenceSystem >() ) { element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsCoordinateReferenceSystem" ) ); const QgsCoordinateReferenceSystem crs = value.value< QgsCoordinateReferenceSystem >(); crs.writeXml( element, doc ); break; } else if ( value.canConvert< QgsGeometry >() ) { element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsGeometry" ) ); const QgsGeometry geom = value.value< QgsGeometry >(); element.setAttribute( QStringLiteral( "value" ), geom.asWkt() ); break; } FALLTHROUGH } default: Q_ASSERT_X( false, "QgsXmlUtils::writeVariant", QStringLiteral( "unsupported variant type %1" ).arg( QVariant::typeToName( value.type() ) ).toLocal8Bit() ); break; } return element; }
void QgsDistanceArea::setSourceEpsgCrsId( long epsgId ) { QgsCoordinateReferenceSystem srcCRS; srcCRS.createFromOgcWmsCrs( QString( "EPSG:%1" ).arg( epsgId ) ); mCoordTransform->setSourceCrs( srcCRS ); }
QVariant QgsXmlUtils::readVariant( const QDomElement &element ) { QString type = element.attribute( QStringLiteral( "type" ) ); if ( type == QLatin1String( "invalid" ) ) { return QVariant(); } else if ( type == QLatin1String( "int" ) ) { return element.attribute( QStringLiteral( "value" ) ).toInt(); } else if ( type == QLatin1String( "uint" ) ) { return element.attribute( QStringLiteral( "value" ) ).toUInt(); } else if ( type == QLatin1String( "qlonglong" ) ) { return element.attribute( QStringLiteral( "value" ) ).toLongLong(); } else if ( type == QLatin1String( "qulonglong" ) ) { return element.attribute( QStringLiteral( "value" ) ).toULongLong(); } else if ( type == QLatin1String( "double" ) ) { return element.attribute( QStringLiteral( "value" ) ).toDouble(); } else if ( type == QLatin1String( "QString" ) ) { return element.attribute( QStringLiteral( "value" ) ); } else if ( type == QLatin1String( "bool" ) ) { return element.attribute( QStringLiteral( "value" ) ) == QLatin1String( "true" ); } else if ( type == QLatin1String( "Map" ) ) { QVariantMap map; QDomNodeList options = element.childNodes(); for ( int i = 0; i < options.count(); ++i ) { QDomElement elem = options.at( i ).toElement(); if ( elem.tagName() == QLatin1String( "Option" ) ) map.insert( elem.attribute( QStringLiteral( "name" ) ), readVariant( elem ) ); } return map; } else if ( type == QLatin1String( "List" ) ) { QVariantList list; QDomNodeList values = element.childNodes(); for ( int i = 0; i < values.count(); ++i ) { QDomElement elem = values.at( i ).toElement(); list.append( readVariant( elem ) ); } return list; } else if ( type == QLatin1String( "StringList" ) ) { QStringList list; QDomNodeList values = element.childNodes(); for ( int i = 0; i < values.count(); ++i ) { QDomElement elem = values.at( i ).toElement(); list.append( readVariant( elem ).toString() ); } return list; } else if ( type == QLatin1String( "QgsProperty" ) ) { const QDomNodeList values = element.childNodes(); if ( values.isEmpty() ) return QVariant(); QgsProperty p; if ( p.loadVariant( QgsXmlUtils::readVariant( values.at( 0 ).toElement() ) ) ) return p; return QVariant(); } else if ( type == QLatin1String( "QgsCoordinateReferenceSystem" ) ) { QgsCoordinateReferenceSystem crs; crs.readXml( element ); return crs; } else if ( type == QLatin1String( "QgsGeometry" ) ) { return QgsGeometry::fromWkt( element.attribute( "value" ) ); } else { return QVariant(); } }
bool QgsDistanceArea::setEllipsoid( const QString& ellipsoid ) { QString radius, parameter2; // // SQLITE3 stuff - get parameters for selected ellipsoid // sqlite3 *myDatabase; const char *myTail; sqlite3_stmt *myPreparedStatement; int myResult; // Shortcut if ellipsoid is none. if ( ellipsoid == "NONE" ) { mEllipsoid = "NONE"; return true; } //check the db is available myResult = sqlite3_open_v2( QgsApplication::srsDbFilePath().toUtf8().data(), &myDatabase, SQLITE_OPEN_READONLY, NULL ); if ( myResult ) { QgsMessageLog::logMessage( QObject::tr( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) ); // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. return false; } // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list QString mySql = "select radius, parameter2 from tbl_ellipsoid where acronym='" + ellipsoid + "'"; myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW ) { radius = QString(( char * )sqlite3_column_text( myPreparedStatement, 0 ) ); parameter2 = QString(( char * )sqlite3_column_text( myPreparedStatement, 1 ) ); } } // close the sqlite3 statement sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); // row for this ellipsoid wasn't found? if ( radius.isEmpty() || parameter2.isEmpty() ) { QgsDebugMsg( QString( "setEllipsoid: no row in tbl_ellipsoid for acronym '%1'" ).arg( ellipsoid ) ); return false; } // get major semiaxis if ( radius.left( 2 ) == "a=" ) mSemiMajor = radius.mid( 2 ).toDouble(); else { QgsDebugMsg( QString( "setEllipsoid: wrong format of radius field: '%1'" ).arg( radius ) ); return false; } // get second parameter // one of values 'b' or 'f' is in field parameter2 // second one must be computed using formula: invf = a/(a-b) if ( parameter2.left( 2 ) == "b=" ) { mSemiMinor = parameter2.mid( 2 ).toDouble(); mInvFlattening = mSemiMajor / ( mSemiMajor - mSemiMinor ); } else if ( parameter2.left( 3 ) == "rf=" ) { mInvFlattening = parameter2.mid( 3 ).toDouble(); mSemiMinor = mSemiMajor - ( mSemiMajor / mInvFlattening ); } else { QgsDebugMsg( QString( "setEllipsoid: wrong format of parameter2 field: '%1'" ).arg( parameter2 ) ); return false; } QgsDebugMsg( QString( "setEllipsoid: a=%1, b=%2, 1/f=%3" ).arg( mSemiMajor ).arg( mSemiMinor ).arg( mInvFlattening ) ); // get spatial ref system for ellipsoid QString proj4 = "+proj=longlat +ellps=" + ellipsoid + " +no_defs"; QgsCoordinateReferenceSystem destCRS; destCRS.createFromProj4( proj4 ); // set transformation from project CRS to ellipsoid coordinates mCoordTransform->setDestCRS( destCRS ); // precalculate some values for area calculations computeAreaInit(); mEllipsoid = ellipsoid; return true; }
QgsAfsProvider::QgsAfsProvider( const QString &uri, const ProviderOptions &options ) : QgsVectorDataProvider( uri, options ) { mSharedData.reset( new QgsAfsSharedData() ); mSharedData->mGeometryType = QgsWkbTypes::Unknown; mSharedData->mDataSource = QgsDataSourceUri( uri ); const QString authcfg = mSharedData->mDataSource.authConfigId(); // Set CRS mSharedData->mSourceCRS.createFromString( mSharedData->mDataSource.param( QStringLiteral( "crs" ) ) ); // Get layer info QString errorTitle, errorMessage; const QString referer = mSharedData->mDataSource.param( QStringLiteral( "referer" ) ); if ( !referer.isEmpty() ) mRequestHeaders[ QStringLiteral( "Referer" )] = referer; const QVariantMap layerData = QgsArcGisRestUtils::getLayerInfo( mSharedData->mDataSource.param( QStringLiteral( "url" ) ), authcfg, errorTitle, errorMessage, mRequestHeaders ); if ( layerData.isEmpty() ) { pushError( errorTitle + ": " + errorMessage ); appendError( QgsErrorMessage( tr( "getLayerInfo failed" ), QStringLiteral( "AFSProvider" ) ) ); return; } mLayerName = layerData[QStringLiteral( "name" )].toString(); mLayerDescription = layerData[QStringLiteral( "description" )].toString(); // Set extent QStringList coords = mSharedData->mDataSource.param( QStringLiteral( "bbox" ) ).split( ',' ); bool limitBbox = false; if ( coords.size() == 4 ) { bool xminOk = false, yminOk = false, xmaxOk = false, ymaxOk = false; mSharedData->mExtent.setXMinimum( coords[0].toDouble( &xminOk ) ); mSharedData->mExtent.setYMinimum( coords[1].toDouble( &yminOk ) ); mSharedData->mExtent.setXMaximum( coords[2].toDouble( &xmaxOk ) ); mSharedData->mExtent.setYMaximum( coords[3].toDouble( &ymaxOk ) ); if ( !xminOk || !yminOk || !xmaxOk || !ymaxOk ) mSharedData->mExtent = QgsRectangle(); else { // user has set a bounding box limit on the layer - so we only EVER fetch features from this extent limitBbox = true; } } const QVariantMap layerExtentMap = layerData[QStringLiteral( "extent" )].toMap(); bool xminOk = false, yminOk = false, xmaxOk = false, ymaxOk = false; QgsRectangle originalExtent; originalExtent.setXMinimum( layerExtentMap[QStringLiteral( "xmin" )].toDouble( &xminOk ) ); originalExtent.setYMinimum( layerExtentMap[QStringLiteral( "ymin" )].toDouble( &yminOk ) ); originalExtent.setXMaximum( layerExtentMap[QStringLiteral( "xmax" )].toDouble( &xmaxOk ) ); originalExtent.setYMaximum( layerExtentMap[QStringLiteral( "ymax" )].toDouble( &ymaxOk ) ); if ( mSharedData->mExtent.isEmpty() && ( !xminOk || !yminOk || !xmaxOk || !ymaxOk ) ) { appendError( QgsErrorMessage( tr( "Could not retrieve layer extent" ), QStringLiteral( "AFSProvider" ) ) ); return; } QgsCoordinateReferenceSystem extentCrs = QgsArcGisRestUtils::parseSpatialReference( layerExtentMap[QStringLiteral( "spatialReference" )].toMap() ); if ( mSharedData->mExtent.isEmpty() && !extentCrs.isValid() ) { appendError( QgsErrorMessage( tr( "Could not parse spatial reference" ), QStringLiteral( "AFSProvider" ) ) ); return; } if ( xminOk && yminOk && xmaxOk && ymaxOk ) { QgsLayerMetadata::SpatialExtent spatialExtent; spatialExtent.bounds = QgsBox3d( originalExtent ); spatialExtent.extentCrs = extentCrs; QgsLayerMetadata::Extent metadataExtent; metadataExtent.setSpatialExtents( QList< QgsLayerMetadata::SpatialExtent >() << spatialExtent ); mLayerMetadata.setExtent( metadataExtent ); } if ( extentCrs.isValid() ) { mLayerMetadata.setCrs( extentCrs ); } if ( mSharedData->mExtent.isEmpty() ) { mSharedData->mExtent = originalExtent; Q_NOWARN_DEPRECATED_PUSH mSharedData->mExtent = QgsCoordinateTransform( extentCrs, mSharedData->mSourceCRS ).transformBoundingBox( mSharedData->mExtent ); Q_NOWARN_DEPRECATED_POP }
QgsAfsProvider::QgsAfsProvider( const QString& uri ) : QgsVectorDataProvider( uri ) , mValid( false ) , mGeometryType( QgsWKBTypes::Unknown ) , mObjectIdFieldIdx( -1 ) { mDataSource = QgsDataSourceURI( uri ); // Set CRS mSourceCRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( mDataSource.param( "crs" ) ); // Get layer info QString errorTitle, errorMessage; QVariantMap layerData = QgsArcGisRestUtils::getLayerInfo( mDataSource.param( "url" ), errorTitle, errorMessage ); if ( layerData.isEmpty() ) { pushError( errorTitle + ": " + errorMessage ); appendError( QgsErrorMessage( tr( "getLayerInfo failed" ), "AFSProvider" ) ); return; } mLayerName = layerData["name"].toString(); mLayerDescription = layerData["description"].toString(); // Set extent QStringList coords = mDataSource.param( "bbox" ).split( "," ); if ( coords.size() == 4 ) { bool xminOk = false, yminOk = false, xmaxOk = false, ymaxOk = false; mExtent.setXMinimum( coords[0].toDouble( &xminOk ) ); mExtent.setYMinimum( coords[1].toDouble( &yminOk ) ); mExtent.setXMaximum( coords[2].toDouble( &xmaxOk ) ); mExtent.setYMaximum( coords[3].toDouble( &ymaxOk ) ); if ( !xminOk || !yminOk || !xmaxOk || !ymaxOk ) mExtent = QgsRectangle(); } if ( mExtent.isEmpty() ) { QVariantMap layerExtentMap = layerData["extent"].toMap(); bool xminOk = false, yminOk = false, xmaxOk = false, ymaxOk = false; mExtent.setXMinimum( layerExtentMap["xmin"].toDouble( &xminOk ) ); mExtent.setYMinimum( layerExtentMap["ymin"].toDouble( &yminOk ) ); mExtent.setXMaximum( layerExtentMap["xmax"].toDouble( &xmaxOk ) ); mExtent.setYMaximum( layerExtentMap["ymax"].toDouble( &ymaxOk ) ); if ( !xminOk || !yminOk || !xmaxOk || !ymaxOk ) { appendError( QgsErrorMessage( tr( "Could not retrieve layer extent" ), "AFSProvider" ) ); return; } QgsCoordinateReferenceSystem extentCrs = QgsArcGisRestUtils::parseSpatialReference( layerExtentMap["spatialReference"].toMap() ); if ( !extentCrs.isValid() ) { appendError( QgsErrorMessage( tr( "Could not parse spatial reference" ), "AFSProvider" ) ); return; } mExtent = QgsCoordinateTransform( extentCrs, mSourceCRS ).transformBoundingBox( mExtent ); } // Read fields foreach ( const QVariant& fieldData, layerData["fields"].toList() ) { QVariantMap fieldDataMap = fieldData.toMap(); QString fieldName = fieldDataMap["name"].toString(); QVariant::Type type = QgsArcGisRestUtils::mapEsriFieldType( fieldDataMap["type"].toString() ); if ( fieldName == "geometry" || type == QVariant::Invalid ) { QgsDebugMsg( QString( "Skipping unsupported (or possibly geometry) field" ).arg( fieldName ) ); continue; } QgsField field( fieldName, type, fieldDataMap["type"].toString(), fieldDataMap["length"].toInt() ); mFields.append( field ); } // Determine geometry type bool hasM = layerData["hasM"].toBool(); bool hasZ = layerData["hasZ"].toBool(); mGeometryType = QgsArcGisRestUtils::mapEsriGeometryType( layerData["geometryType"].toString() ); if ( mGeometryType == QgsWKBTypes::Unknown ) { appendError( QgsErrorMessage( tr( "Failed to determine geometry type" ), "AFSProvider" ) ); return; } mGeometryType = QgsWKBTypes::zmType( mGeometryType, hasZ, hasM ); // Read OBJECTIDs of all features: these may not be a continuous sequence, // and we need to store these to iterate through the features. This query // also returns the name of the ObjectID field. QVariantMap objectIdData = QgsArcGisRestUtils::getObjectIds( mDataSource.param( "url" ), errorTitle, errorMessage ); if ( objectIdData.isEmpty() ) { appendError( QgsErrorMessage( tr( "getObjectIds failed: %1 - %2" ).arg( errorTitle ).arg( errorMessage ), "AFSProvider" ) ); return; } if ( !objectIdData["objectIdFieldName"].isValid() || !objectIdData["objectIds"].isValid() ) { appendError( QgsErrorMessage( tr( "Failed to determine objectIdFieldName and/or objectIds" ), "AFSProvider" ) ); return; } mObjectIdFieldName = objectIdData["objectIdFieldName"].toString(); for ( int idx = 0, nIdx = mFields.count(); idx < nIdx; ++idx ) { if ( mFields.at( idx ).name() == mObjectIdFieldName ) { mObjectIdFieldIdx = idx; break; } } foreach ( const QVariant& objectId, objectIdData["objectIds"].toList() ) { mObjectIds.append( objectId.toInt() ); } mValid = true; }
QgsVectorLayerExporter::ExportError QgsDb2Provider::createEmptyLayer( const QString &uri, const QgsFields &fields, QgsWkbTypes::Type wkbType, const QgsCoordinateReferenceSystem &srs, bool overwrite, QMap<int, int> *oldToNewAttrIdxMap, QString *errorMessage, const QMap<QString, QVariant> *options ) { Q_UNUSED( options ); // populate members from the uri structure QgsDataSourceUri dsUri( uri ); QString connInfo = dsUri.connectionInfo(); QString errMsg; QString srsName; QgsDebugMsg( "uri: " + uri ); // connect to database QSqlDatabase db = QgsDb2Provider::getDatabase( connInfo, errMsg ); if ( !errMsg.isEmpty() ) { if ( errorMessage ) *errorMessage = errMsg; return QgsVectorLayerExporter::ErrConnectionFailed; } // Get the SRS name using srid, needed to register the spatial column // srs->posgisSrid() seems to return the authority id which is // most often the EPSG id. Hopefully DB2 has defined an SRS using this // value as the srid / srs_id. If not, we are out of luck. QgsDebugMsg( "srs: " + srs.toWkt() ); long srid = srs.postgisSrid(); QgsDebugMsg( QString( "srid: %1" ).arg( srid ) ); if ( srid >= 0 ) { QSqlQuery query( db ); QString statement = QStringLiteral( "SELECT srs_name FROM db2gse.st_spatial_reference_systems where srs_id=%1" ) .arg( srid ); QgsDebugMsg( statement ); if ( !query.exec( statement ) || !query.isActive() ) { QgsDebugMsg( query.lastError().text() ); } if ( query.next() ) { srsName = query.value( 0 ).toString(); QgsDebugMsg( QString( "srs_name: %1" ).arg( srsName ) ); } else { QgsDebugMsg( "Couldn't get srs_name from db2gse.st_spatial_reference_systems" ); } } QString schemaName = dsUri.schema().toUpper(); QString tableName = dsUri.table().toUpper(); QString fullName; if ( schemaName.isEmpty() ) { schemaName = dsUri.username().toUpper(); // set schema to user name } fullName = schemaName + "." + tableName; QString geometryColumn = dsUri.geometryColumn().toUpper(); QString primaryKey = dsUri.keyColumn().toUpper(); QString primaryKeyType; // TODO - this is a bad hack to cope with shapefiles. // The wkbType from the shapefile header is usually a multi-type // even if all the data is a single-type. If we create the column as // a multi-type, the insert will fail if the actual data is a single-type // due to type mismatch. // We could potentially defer adding the spatial column until addFeatures is // called the first time, but QgsVectorLayerExporter doesn't pass the CRS/srid // information to the DB2 provider and we need this information to register // the spatial column. // This hack is problematic because the drag/drop will fail if the // actual data is a multi-type which is possible with a shapefile or // other data source. QgsWkbTypes::Type wkbTypeSingle; wkbTypeSingle = QgsWkbTypes::singleType( wkbType ); if ( wkbType != QgsWkbTypes::NoGeometry && geometryColumn.isEmpty() ) geometryColumn = QStringLiteral( "GEOM" ); if ( primaryKey.isEmpty() ) primaryKey = QStringLiteral( "QGS_FID" ); // get the pk's name and type // if no pk name was passed, define the new pk field name int fieldCount = fields.size(); if ( primaryKey.isEmpty() ) { int index = 0; QString pk = primaryKey = QStringLiteral( "QGS_FID" ); for ( int i = 0; i < fieldCount; ++i ) { if ( fields.at( i ).name() == primaryKey ) { // it already exists, try again with a new name primaryKey = QStringLiteral( "%1_%2" ).arg( pk ).arg( index++ ); i = 0; } } } else { // search for the passed field for ( int i = 0; i < fieldCount; ++i ) { if ( fields.at( i ).name() == primaryKey ) { // found, get the field type QgsField fld = fields.at( i ); if ( convertField( fld ) ) { primaryKeyType = fld.typeName(); } } } } QgsDebugMsg( "primaryKeyType: '" + primaryKeyType + "'" ); QString sql; QSqlQuery q = QSqlQuery( db ); q.setForwardOnly( true ); // get wkb type and dimension QString geometryType; int dim = 2; db2WkbTypeAndDimension( wkbTypeSingle, geometryType, dim ); QgsDebugMsg( QString( "wkbTypeSingle: %1; geometryType: %2" ).arg( wkbTypeSingle ).arg( geometryType ) ); if ( overwrite ) { // remove the old table with the same name sql = "DROP TABLE " + fullName; if ( !q.exec( sql ) ) { if ( q.lastError().number() != -206 ) // -206 is "not found" just ignore { QString lastError = q.lastError().text(); QgsDebugMsg( lastError ); if ( errorMessage ) { *errorMessage = lastError; } return QgsVectorLayerExporter::ErrCreateLayer; } } } // add fields to the layer if ( oldToNewAttrIdxMap ) oldToNewAttrIdxMap->clear(); QString attr2Create = QLatin1String( "" ); if ( fields.size() > 0 ) { int offset = 0; // get the list of fields QgsDebugMsg( "PrimaryKey: '" + primaryKey + "'" ); for ( int i = 0; i < fieldCount; ++i ) { QgsField fld = fields.field( i ); QgsDebugMsg( QString( "i: %1; fldIdx: %2; offset: %3" ) .arg( i ).arg( fields.lookupField( fld.name() ) ).arg( offset ) ); if ( oldToNewAttrIdxMap && fld.name() == primaryKey ) { oldToNewAttrIdxMap->insert( i, 0 ); continue; } if ( fld.name() == geometryColumn ) { // Found a field with the same name of the geometry column. Skip it! continue; } QString db2Field = qgsFieldToDb2Field( fld ); if ( db2Field.isEmpty() ) { if ( errorMessage ) { *errorMessage = QObject::tr( "Unsupported type for field %1" ).arg( fld.name() ); } return QgsVectorLayerExporter::ErrAttributeTypeUnsupported; } if ( oldToNewAttrIdxMap ) { oldToNewAttrIdxMap->insert( fields.lookupField( fld.name() ), offset++ ); } attr2Create += ',' + db2Field.toUpper(); } QgsDebugMsg( attr2Create ); if ( !geometryColumn.isEmpty() ) { sql = QString( // need to set specific geometry type "CREATE TABLE %1(%2 BIGINT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY, " "%3 DB2GSE.%4 %5) " ) .arg( fullName, primaryKey, geometryColumn, geometryType, attr2Create ); } else { //geometryless table sql = QStringLiteral( // need to set specific geometry type "CREATE TABLE %1.%2(%3 INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS %4) " ) .arg( schemaName, tableName, primaryKey, attr2Create ); } QgsDebugMsg( sql ); if ( !q.exec( sql ) ) { QString lastError = q.lastError().text(); QgsDebugMsg( lastError ); if ( errorMessage ) { *errorMessage = lastError; } return QgsVectorLayerExporter::ErrCreateLayer; } if ( !geometryColumn.isEmpty() ) { int computeExtents = 0; int msgCode = 0; int outCode; int outMsg; QVariant msgText( " " ); QSqlQuery query( db ); int db2Environment = ENV_LUW; // get the environment QgsDb2GeometryColumns gc( db ); int rc = gc.open( schemaName, tableName ); // returns SQLCODE if failure if ( rc == 0 ) { db2Environment = gc.db2Environment(); } if ( ENV_LUW == db2Environment ) { sql = QStringLiteral( "CALL DB2GSE.ST_Register_Spatial_Column(?, ?, ?, ?, ?, ?, ?)" ); outCode = 5; outMsg = 6; } else // z/OS doesn't support 'computeExtents' parameter and has different schema { sql = QStringLiteral( "CALL SYSPROC.ST_Register_Spatial_Column(?, ?, ?, ?, ?, ?)" ); outCode = 4; outMsg = 5; } query.prepare( sql ); query.bindValue( 0, schemaName ); query.bindValue( 1, tableName ); query.bindValue( 2, geometryColumn ); query.bindValue( 3, srsName ); if ( ENV_LUW == db2Environment ) { query.bindValue( 4, computeExtents ); } query.bindValue( outCode, msgCode, QSql::Out ); query.bindValue( outMsg, msgText, QSql::Out ); if ( !query.exec() ) { QgsDebugMsg( QString( "error: %1; sql: %2" ).arg( query.lastError().text(), query.lastQuery() ) ); } else { msgCode = query.boundValue( outCode ).toInt(); msgText = query.boundValue( outMsg ).toString(); // never gets a value... if ( 0 != msgCode ) { QgsDebugMsg( QString( "Register failed with code: %1; text: '%2'" ).arg( msgCode ).arg( msgText.toString() ) ); } else { QgsDebugMsg( "Register successful" ); } } QList<QVariant> list = query.boundValues().values(); for ( int i = 0; i < list.size(); ++i ) { QgsDebugMsg( QString( "i: %1; value: %2; type: %3" ) .arg( i ).arg( list.at( i ).toString().toLatin1().data(), list.at( i ).typeName() ) ); } } // clear any resources hold by the query q.clear(); q.setForwardOnly( true ); } QgsDebugMsg( "successfully created empty layer" ); return QgsVectorLayerExporter::NoError; }
bool QgsDistanceArea::setEllipsoid( const QString& ellipsoid ) { QString radius, parameter2; // // SQLITE3 stuff - get parameters for selected ellipsoid // sqlite3 *myDatabase; const char *myTail; sqlite3_stmt *myPreparedStatement; int myResult; // Shortcut if ellipsoid is none. if ( ellipsoid == GEO_NONE ) { mEllipsoid = GEO_NONE; return true; } // Check if we have a custom projection, and set from text string. // Format is "PARAMETER:<semi-major axis>:<semi minor axis> // Numbers must be with (optional) decimal point and no other separators (C locale) // Distances in meters. Flattening is calculated. if ( ellipsoid.startsWith( "PARAMETER" ) ) { QStringList paramList = ellipsoid.split( ':' ); bool semiMajorOk, semiMinorOk; double semiMajor = paramList[1].toDouble( & semiMajorOk ); double semiMinor = paramList[2].toDouble( & semiMinorOk ); if ( semiMajorOk && semiMinorOk ) { return setEllipsoid( semiMajor, semiMinor ); } else { return false; } } // Continue with PROJ.4 list of ellipsoids. //check the db is available myResult = sqlite3_open_v2( QgsApplication::srsDbFilePath().toUtf8().data(), &myDatabase, SQLITE_OPEN_READONLY, nullptr ); if ( myResult ) { QgsMessageLog::logMessage( QObject::tr( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) ); // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. return false; } // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list QString mySql = "select radius, parameter2 from tbl_ellipsoid where acronym='" + ellipsoid + '\''; myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW ) { radius = QString( reinterpret_cast< const char * >( sqlite3_column_text( myPreparedStatement, 0 ) ) ); parameter2 = QString( reinterpret_cast< const char * >( sqlite3_column_text( myPreparedStatement, 1 ) ) ); } } // close the sqlite3 statement sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); // row for this ellipsoid wasn't found? if ( radius.isEmpty() || parameter2.isEmpty() ) { QgsDebugMsg( QString( "setEllipsoid: no row in tbl_ellipsoid for acronym '%1'" ).arg( ellipsoid ) ); return false; } // get major semiaxis if ( radius.left( 2 ) == "a=" ) mSemiMajor = radius.mid( 2 ).toDouble(); else { QgsDebugMsg( QString( "setEllipsoid: wrong format of radius field: '%1'" ).arg( radius ) ); return false; } // get second parameter // one of values 'b' or 'f' is in field parameter2 // second one must be computed using formula: invf = a/(a-b) if ( parameter2.left( 2 ) == "b=" ) { mSemiMinor = parameter2.mid( 2 ).toDouble(); mInvFlattening = mSemiMajor / ( mSemiMajor - mSemiMinor ); } else if ( parameter2.left( 3 ) == "rf=" ) { mInvFlattening = parameter2.mid( 3 ).toDouble(); mSemiMinor = mSemiMajor - ( mSemiMajor / mInvFlattening ); } else { QgsDebugMsg( QString( "setEllipsoid: wrong format of parameter2 field: '%1'" ).arg( parameter2 ) ); return false; } QgsDebugMsg( QString( "setEllipsoid: a=%1, b=%2, 1/f=%3" ).arg( mSemiMajor ).arg( mSemiMinor ).arg( mInvFlattening ) ); // get spatial ref system for ellipsoid QString proj4 = "+proj=longlat +ellps=" + ellipsoid + " +no_defs"; QgsCoordinateReferenceSystem destCRS = QgsCrsCache::instance()->crsByProj4( proj4 ); //TODO: createFromProj4 used to save to the user database any new CRS // this behavior was changed in order to separate creation and saving. // Not sure if it necessary to save it here, should be checked by someone // familiar with the code (should also give a more descriptive name to the generated CRS) if ( destCRS.srsid() == 0 ) { QString myName = QString( " * %1 (%2)" ) .arg( QObject::tr( "Generated CRS", "A CRS automatically generated from layer info get this prefix for description" ), destCRS.toProj4() ); destCRS.saveAsUserCrs( myName ); } // // set transformation from project CRS to ellipsoid coordinates mCoordTransform.setDestinationCrs( destCRS ); mEllipsoid = ellipsoid; // precalculate some values for area calculations computeAreaInit(); return true; }
QgsDb2Provider::QgsDb2Provider( const QString &uri ) : QgsVectorDataProvider( uri ) , mNumberFeatures( 0 ) , mFidColIdx( -1 ) , mEnvironment( ENV_LUW ) , mWkbType( QgsWkbTypes::Unknown ) { QgsDebugMsg( "uri: " + uri ); QgsDataSourceUri anUri = QgsDataSourceUri( uri ); if ( !anUri.srid().isEmpty() ) mSRId = anUri.srid().toInt(); else mSRId = -1; if ( 0 != anUri.wkbType() ) { mWkbType = anUri.wkbType(); } QgsDebugMsg( QString( "mWkbType: %1" ).arg( mWkbType ) ); QgsDebugMsg( QString( "new mWkbType: %1" ).arg( anUri.wkbType() ) ); mValid = true; mSkipFailures = false; int dim; // Not used db2WkbTypeAndDimension( mWkbType, mGeometryColType, dim ); // Get DB2 geometry type name mFidColName = anUri.keyColumn().toUpper(); QgsDebugMsg( "mFidColName " + mFidColName ); mExtents = anUri.param( QStringLiteral( "extents" ) ); QgsDebugMsg( "mExtents " + mExtents ); mUseEstimatedMetadata = anUri.useEstimatedMetadata(); QgsDebugMsg( QString( "mUseEstimatedMetadata: '%1'" ).arg( mUseEstimatedMetadata ) ); mSqlWhereClause = anUri.sql(); QString errMsg; mDatabase = getDatabase( uri, errMsg ); mConnInfo = anUri.connectionInfo(); QgsCoordinateReferenceSystem layerCrs = crs(); QgsDebugMsg( "CRS: " + layerCrs.toWkt() ); if ( !errMsg.isEmpty() ) { setLastError( errMsg ); QgsDebugMsg( mLastError ); mValid = false; return; } // Create a query for default connection mQuery = QSqlQuery( mDatabase ); mSchemaName = anUri.schema(); mTableName = anUri.table().toUpper(); QStringList sl = mTableName.split( '.' ); if ( sl.length() == 2 ) // Never seems to be the case { mSchemaName = sl[0]; mTableName = sl[1]; } if ( mSchemaName.isEmpty() ) { mSchemaName = anUri.username().toUpper(); } QgsDebugMsg( "mSchemaName: '" + mSchemaName + "; mTableName: '" + mTableName ); if ( !anUri.geometryColumn().isEmpty() ) mGeometryColName = anUri.geometryColumn().toUpper(); loadFields(); updateStatistics(); if ( mGeometryColName.isEmpty() ) { // table contains no geometries mWkbType = QgsWkbTypes::NoGeometry; mSRId = 0; } //fill type names into sets setNativeTypes( QList< NativeType >() // integer types << QgsVectorDataProvider::NativeType( tr( "8 Bytes integer" ), QStringLiteral( "bigint" ), QVariant::Int ) << QgsVectorDataProvider::NativeType( tr( "4 Bytes integer" ), QStringLiteral( "integer" ), QVariant::Int ) << QgsVectorDataProvider::NativeType( tr( "2 Bytes integer" ), QStringLiteral( "smallint" ), QVariant::Int ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), QStringLiteral( "numeric" ), QVariant::Double, 1, 31, 0, 31 ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), QStringLiteral( "decimal" ), QVariant::Double, 1, 31, 0, 31 ) // floating point << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "real" ), QVariant::Double ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), QStringLiteral( "double" ), QVariant::Double ) // date/time types << QgsVectorDataProvider::NativeType( tr( "Date" ), QStringLiteral( "date" ), QVariant::Date, -1, -1, -1, -1 ) << QgsVectorDataProvider::NativeType( tr( "Time" ), QStringLiteral( "time" ), QVariant::Time, -1, -1, -1, -1 ) << QgsVectorDataProvider::NativeType( tr( "Date & Time" ), QStringLiteral( "datetime" ), QVariant::DateTime, -1, -1, -1, -1 ) // string types << QgsVectorDataProvider::NativeType( tr( "Text, fixed length (char)" ), QStringLiteral( "char" ), QVariant::String, 1, 254 ) << QgsVectorDataProvider::NativeType( tr( "Text, variable length (varchar)" ), QStringLiteral( "varchar" ), QVariant::String, 1, 32704 ) << QgsVectorDataProvider::NativeType( tr( "Text, variable length large object (clob)" ), QStringLiteral( "clob" ), QVariant::String, 1, 2147483647 ) //DBCLOB is for 1073741824 double-byte characters, data length should be the same as CLOB (2147483647)? << QgsVectorDataProvider::NativeType( tr( "Text, variable length large object (dbclob)" ), QStringLiteral( "dbclob" ), QVariant::String, 1, 1073741824 ) ); }
void QgsLayoutMapGridWidget::setGridItems() { if ( !mMapGrid ) { return; } mGridMarkerStyleButton->registerExpressionContextGenerator( mMapGrid ); mGridLineStyleButton->registerExpressionContextGenerator( mMapGrid ); mIntervalXSpinBox->setValue( mMapGrid->intervalX() ); mIntervalYSpinBox->setValue( mMapGrid->intervalY() ); mOffsetXSpinBox->setValue( mMapGrid->offsetX() ); mOffsetYSpinBox->setValue( mMapGrid->offsetY() ); mCrossWidthSpinBox->setValue( mMapGrid->crossLength() ); mFrameWidthSpinBox->setValue( mMapGrid->frameWidth() ); mGridFrameMarginSpinBox->setValue( mMapGrid->frameMargin() ); mGridFramePenSizeSpinBox->setValue( mMapGrid->framePenSize() ); mGridFramePenColorButton->setColor( mMapGrid->framePenColor() ); mGridFrameFill1ColorButton->setColor( mMapGrid->frameFillColor1() ); mGridFrameFill2ColorButton->setColor( mMapGrid->frameFillColor2() ); QgsLayoutItemMapGrid::GridStyle gridStyle = mMapGrid->style(); switch ( gridStyle ) { case QgsLayoutItemMapGrid::Cross: mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Cross" ) ) ); mCrossWidthSpinBox->setVisible( true ); mCrossWidthLabel->setVisible( true ); mGridLineStyleButton->setVisible( true ); mLineStyleLabel->setVisible( true ); mGridMarkerStyleButton->setVisible( false ); mMarkerStyleLabel->setVisible( false ); mGridBlendComboBox->setVisible( true ); mGridBlendLabel->setVisible( true ); break; case QgsLayoutItemMapGrid::Markers: mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Markers" ) ) ); mCrossWidthSpinBox->setVisible( false ); mCrossWidthLabel->setVisible( false ); mGridLineStyleButton->setVisible( false ); mLineStyleLabel->setVisible( false ); mGridMarkerStyleButton->setVisible( true ); mMarkerStyleLabel->setVisible( true ); mGridBlendComboBox->setVisible( true ); mGridBlendLabel->setVisible( true ); break; case QgsLayoutItemMapGrid::Solid: mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Solid" ) ) ); mCrossWidthSpinBox->setVisible( false ); mCrossWidthLabel->setVisible( false ); mGridLineStyleButton->setVisible( true ); mLineStyleLabel->setVisible( true ); mGridMarkerStyleButton->setVisible( false ); mMarkerStyleLabel->setVisible( false ); mGridBlendComboBox->setVisible( true ); mGridBlendLabel->setVisible( true ); break; case QgsLayoutItemMapGrid::FrameAnnotationsOnly: mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Frame and annotations only" ) ) ); mCrossWidthSpinBox->setVisible( false ); mCrossWidthLabel->setVisible( false ); mGridLineStyleButton->setVisible( false ); mLineStyleLabel->setVisible( false ); mGridMarkerStyleButton->setVisible( false ); mMarkerStyleLabel->setVisible( false ); mGridBlendComboBox->setVisible( false ); mGridBlendLabel->setVisible( false ); break; } //grid frame mFrameWidthSpinBox->setValue( mMapGrid->frameWidth() ); mGridFrameMarginSpinBox->setValue( mMapGrid->frameMargin() ); QgsLayoutItemMapGrid::FrameStyle gridFrameStyle = mMapGrid->frameStyle(); mFrameStyleComboBox->setCurrentIndex( mFrameStyleComboBox->findData( gridFrameStyle ) ); switch ( gridFrameStyle ) { case QgsLayoutItemMapGrid::Zebra: case QgsLayoutItemMapGrid::ZebraNautical: toggleFrameControls( true, true, true ); break; case QgsLayoutItemMapGrid::InteriorTicks: case QgsLayoutItemMapGrid::ExteriorTicks: case QgsLayoutItemMapGrid::InteriorExteriorTicks: toggleFrameControls( true, false, true ); break; case QgsLayoutItemMapGrid::LineBorder: case QgsLayoutItemMapGrid::LineBorderNautical: toggleFrameControls( true, false, false ); break; case QgsLayoutItemMapGrid::NoFrame: toggleFrameControls( false, false, false ); break; } mCheckGridLeftSide->setChecked( mMapGrid->testFrameSideFlag( QgsLayoutItemMapGrid::FrameLeft ) ); mCheckGridRightSide->setChecked( mMapGrid->testFrameSideFlag( QgsLayoutItemMapGrid::FrameRight ) ); mCheckGridTopSide->setChecked( mMapGrid->testFrameSideFlag( QgsLayoutItemMapGrid::FrameTop ) ); mCheckGridBottomSide->setChecked( mMapGrid->testFrameSideFlag( QgsLayoutItemMapGrid::FrameBottom ) ); initFrameDisplayBox( mFrameDivisionsLeftComboBox, mMapGrid->frameDivisions( QgsLayoutItemMapGrid::Left ) ); initFrameDisplayBox( mFrameDivisionsRightComboBox, mMapGrid->frameDivisions( QgsLayoutItemMapGrid::Right ) ); initFrameDisplayBox( mFrameDivisionsTopComboBox, mMapGrid->frameDivisions( QgsLayoutItemMapGrid::Top ) ); initFrameDisplayBox( mFrameDivisionsBottomComboBox, mMapGrid->frameDivisions( QgsLayoutItemMapGrid::Bottom ) ); //line style mGridLineStyleButton->setSymbol( mMapGrid->lineSymbol()->clone() ); //marker style mGridMarkerStyleButton->setSymbol( mMapGrid->markerSymbol()->clone() ); mGridBlendComboBox->setBlendMode( mMapGrid->blendMode() ); mDrawAnnotationGroupBox->setChecked( mMapGrid->annotationEnabled() ); initAnnotationDisplayBox( mAnnotationDisplayLeftComboBox, mMapGrid->annotationDisplay( QgsLayoutItemMapGrid::Left ) ); initAnnotationDisplayBox( mAnnotationDisplayRightComboBox, mMapGrid->annotationDisplay( QgsLayoutItemMapGrid::Right ) ); initAnnotationDisplayBox( mAnnotationDisplayTopComboBox, mMapGrid->annotationDisplay( QgsLayoutItemMapGrid::Top ) ); initAnnotationDisplayBox( mAnnotationDisplayBottomComboBox, mMapGrid->annotationDisplay( QgsLayoutItemMapGrid::Bottom ) ); initAnnotationPositionBox( mAnnotationPositionLeftComboBox, mMapGrid->annotationPosition( QgsLayoutItemMapGrid::Left ) ); initAnnotationPositionBox( mAnnotationPositionRightComboBox, mMapGrid->annotationPosition( QgsLayoutItemMapGrid::Right ) ); initAnnotationPositionBox( mAnnotationPositionTopComboBox, mMapGrid->annotationPosition( QgsLayoutItemMapGrid::Top ) ); initAnnotationPositionBox( mAnnotationPositionBottomComboBox, mMapGrid->annotationPosition( QgsLayoutItemMapGrid::Bottom ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxLeft, mMapGrid->annotationDirection( QgsLayoutItemMapGrid::Left ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxRight, mMapGrid->annotationDirection( QgsLayoutItemMapGrid::Right ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxTop, mMapGrid->annotationDirection( QgsLayoutItemMapGrid::Top ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxBottom, mMapGrid->annotationDirection( QgsLayoutItemMapGrid::Bottom ) ); mAnnotationFontColorButton->setColor( mMapGrid->annotationFontColor() ); mAnnotationFontButton->setCurrentFont( mMapGrid->annotationFont() ); mAnnotationFormatComboBox->setCurrentIndex( mAnnotationFormatComboBox->findData( mMapGrid->annotationFormat() ) ); mAnnotationFormatButton->setEnabled( mMapGrid->annotationFormat() == QgsLayoutItemMapGrid::CustomFormat ); mDistanceToMapFrameSpinBox->setValue( mMapGrid->annotationFrameDistance() ); mCoordinatePrecisionSpinBox->setValue( mMapGrid->annotationPrecision() ); //Unit QgsLayoutItemMapGrid::GridUnit gridUnit = mMapGrid->units(); if ( gridUnit == QgsLayoutItemMapGrid::MapUnit ) { mMapGridUnitComboBox->setCurrentIndex( mMapGridUnitComboBox->findText( tr( "Map unit" ) ) ); } else if ( gridUnit == QgsLayoutItemMapGrid::MM ) { mMapGridUnitComboBox->setCurrentIndex( mMapGridUnitComboBox->findText( tr( "Millimeter" ) ) ); } else if ( gridUnit == QgsLayoutItemMapGrid::CM ) { mMapGridUnitComboBox->setCurrentIndex( mMapGridUnitComboBox->findText( tr( "Centimeter" ) ) ); } //CRS button QgsCoordinateReferenceSystem gridCrs = mMapGrid->crs(); QString crsButtonText = gridCrs.isValid() ? gridCrs.authid() : tr( "Change…" ); mMapGridCRSButton->setText( crsButtonText ); }
bool QgsCustomProjectionDialog::saveCRS( QgsCoordinateReferenceSystem myCRS, const QString& myName, QString myId, bool newEntry ) { QString mySql; int return_id; QString myProjectionAcronym = myCRS.projectionAcronym(); QString myEllipsoidAcronym = myCRS.ellipsoidAcronym(); QgsDebugMsg( QString( "Saving a CRS:%1, %2, %3" ).arg( myName ).arg( myCRS.toProj4() ).arg( newEntry ) ); if ( newEntry ) { return_id = myCRS.saveAsUserCRS( myName ); if ( return_id == -1 ) return false; else myId = QString::number( return_id ); } else { mySql = "update tbl_srs set description=" + quotedValue( myName ) + ",projection_acronym=" + quotedValue( myProjectionAcronym ) + ",ellipsoid_acronym=" + quotedValue( myEllipsoidAcronym ) + ",parameters=" + quotedValue( myCRS.toProj4() ) + ",is_geo=0" // <--shamelessly hard coded for now + " where srs_id=" + quotedValue( myId ) ; QgsDebugMsg( mySql ); sqlite3 *myDatabase; const char *myTail; sqlite3_stmt *myPreparedStatement; int myResult; //check if the db is available myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8(), &myDatabase ); if ( myResult != SQLITE_OK ) { QgsDebugMsg( QString( "Can't open database: %1 \n please notify QGIS developers of this error \n %2 (file name) " ).arg( sqlite3_errmsg( myDatabase ) ).arg( QgsApplication::qgisUserDbFilePath() ) ); // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. Q_ASSERT( myResult == SQLITE_OK ); } myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult != SQLITE_OK || sqlite3_step( myPreparedStatement ) != SQLITE_DONE ) { QgsDebugMsg( QString( "failed to write to database in custom projection dialog: %1 [%2]" ).arg( mySql ).arg( sqlite3_errmsg( myDatabase ) ) ); } sqlite3_finalize( myPreparedStatement ); // close sqlite3 db sqlite3_close( myDatabase ); if ( myResult != SQLITE_OK ) return false; } existingCRSparameters[myId] = myCRS.toProj4(); existingCRSnames[myId] = myName; QgsCRSCache::instance()->updateCRSCache( QString( "USER:%1" ).arg( myId ) ); // If we have a projection acronym not in the user db previously, add it. // This is a must, or else we can't select it from the vw_srs table. // Actually, add it always and let the SQL PRIMARY KEY remove duplicates. insertProjection( myProjectionAcronym ); return true; }