Пример #1
0
bool CSpatialReference::IsGeographic() const
{
	if(!m_Handle)
	{
		return false;
	}
    OGRSpatialReference* psr = (OGRSpatialReference*)m_Handle;

	return psr->IsGeographic();
}
Пример #2
0
GDALDataset *AAIGDataset::CommonOpen( GDALOpenInfo *poOpenInfo,
                                      GridFormat eFormat )
{
    if( poOpenInfo->fpL == nullptr )
        return nullptr;

    // Create a corresponding GDALDataset.
    AAIGDataset *poDS = nullptr;

    if (eFormat == FORMAT_AAIG)
        poDS = new AAIGDataset();
    else
        poDS = new GRASSASCIIDataset();

    const char *pszDataTypeOption =
        eFormat == FORMAT_AAIG ?
        "AAIGRID_DATATYPE" : "GRASSASCIIGRID_DATATYPE";

    const char *pszDataType = CPLGetConfigOption(pszDataTypeOption, nullptr);
    if( pszDataType == nullptr )
        pszDataType =
            CSLFetchNameValue(poOpenInfo->papszOpenOptions, "DATATYPE");
    if (pszDataType != nullptr)
    {
        poDS->eDataType = GDALGetDataTypeByName(pszDataType);
        if (!(poDS->eDataType == GDT_Int32 || poDS->eDataType == GDT_Float32 ||
              poDS->eDataType == GDT_Float64))
        {
            CPLError(CE_Warning, CPLE_NotSupported,
                     "Unsupported value for %s : %s",
                     pszDataTypeOption, pszDataType);
            poDS->eDataType = GDT_Int32;
            pszDataType = nullptr;
        }
    }

    // Parse the header.
    if (!poDS->ParseHeader((const char *)poOpenInfo->pabyHeader, pszDataType))
    {
        delete poDS;
        return nullptr;
    }

    poDS->fp = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;

    // Find the start of real data.
    int nStartOfData = 0;

    for( int i = 2; true; i++ )
    {
        if( poOpenInfo->pabyHeader[i] == '\0' )
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Couldn't find data values in ASCII Grid file.");
            delete poDS;
            return nullptr;
        }

        if( poOpenInfo->pabyHeader[i - 1] == '\n' ||
            poOpenInfo->pabyHeader[i - 2] == '\n' ||
            poOpenInfo->pabyHeader[i - 1] == '\r' ||
            poOpenInfo->pabyHeader[i - 2] == '\r' )
        {
            if( !isalpha(poOpenInfo->pabyHeader[i]) &&
                poOpenInfo->pabyHeader[i] != '\n' &&
                poOpenInfo->pabyHeader[i] != '\r')
            {
                nStartOfData = i;

                // Beginning of real data found.
                break;
            }
        }
    }

    // Recognize the type of data.
    CPLAssert(nullptr != poDS->fp);

    if( pszDataType == nullptr &&
        poDS->eDataType != GDT_Float32 && poDS->eDataType != GDT_Float64)
    {
        // Allocate 100K chunk + 1 extra byte for NULL character.
        constexpr size_t nChunkSize = 1024 * 100;
        GByte *pabyChunk = static_cast<GByte *>(
            VSI_CALLOC_VERBOSE(nChunkSize + 1, sizeof(GByte)));
        if (pabyChunk == nullptr)
        {
            delete poDS;
            return nullptr;
        }
        pabyChunk[nChunkSize] = '\0';

        if( VSIFSeekL(poDS->fp, nStartOfData, SEEK_SET) < 0 )
        {
            delete poDS;
            VSIFree(pabyChunk);
            return nullptr;
        }

        // Scan for dot in subsequent chunks of data.
        while( !VSIFEofL(poDS->fp) )
        {
            CPL_IGNORE_RET_VAL(VSIFReadL(pabyChunk, nChunkSize, 1, poDS->fp));

            for( int i = 0; i < static_cast<int>(nChunkSize); i++)
            {
                GByte ch = pabyChunk[i];
                if (ch == '.' || ch == ',' || ch == 'e' || ch == 'E')
                {
                    poDS->eDataType = GDT_Float32;
                    break;
                }
            }
        }

        // Deallocate chunk.
        VSIFree(pabyChunk);
    }

    // Create band information objects.
    AAIGRasterBand *band = new AAIGRasterBand(poDS, nStartOfData);
    poDS->SetBand(1, band);
    if (band->panLineOffset == nullptr)
    {
        delete poDS;
        return nullptr;
    }

    // Try to read projection file.
    char *const pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename));
    char *const pszBasename =
        CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename));

    poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "prj");
    int nRet = 0;
    {
        VSIStatBufL sStatBuf;
        nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf);
    }
    if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename) )
    {
        poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "PRJ");

        VSIStatBufL sStatBuf;
        nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf);
    }

    if( nRet == 0 )
    {
        poDS->papszPrj = CSLLoad(poDS->osPrjFilename);

        CPLDebug("AAIGrid", "Loaded SRS from %s", poDS->osPrjFilename.c_str());

        OGRSpatialReference oSRS;
        if( oSRS.importFromESRI(poDS->papszPrj) == OGRERR_NONE )
        {
            // If geographic values are in seconds, we must transform.
            // Is there a code for minutes too?
            if( oSRS.IsGeographic() &&
                EQUAL(OSR_GDS(poDS->papszPrj, "Units", ""), "DS") )
            {
                poDS->adfGeoTransform[0] /= 3600.0;
                poDS->adfGeoTransform[1] /= 3600.0;
                poDS->adfGeoTransform[2] /= 3600.0;
                poDS->adfGeoTransform[3] /= 3600.0;
                poDS->adfGeoTransform[4] /= 3600.0;
                poDS->adfGeoTransform[5] /= 3600.0;
            }

            CPLFree(poDS->pszProjection);
            oSRS.exportToWkt(&(poDS->pszProjection));
        }
    }

    CPLFree(pszDirname);
    CPLFree(pszBasename);

    // Initialize any PAM information.
    poDS->SetDescription(poOpenInfo->pszFilename);
    poDS->TryLoadXML();

    // Check for external overviews.
    poDS->oOvManager.Initialize(
        poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles());

    return poDS;
}
Пример #3
0
bool ShpReader::SetupVectorProjection(OGRDataSource* OGRDataset, StudyControllerPtr studyController, OGRLayer* poLayer, VectorMapControllerPtr vectorMapController)
{
	//If there exists a map layer, the vector file will be projected based on the projection of the map layer
	if ( App::Inst().GetLayerTreeController()->GetNumMapLayers() > 0 )
	{
		ProjectionToolPtr projTool = studyController->GetProjectionTool();
		OGRSpatialReference* currentShpSR = poLayer->GetSpatialRef();
		if (!studyController->IsProjectData() && !studyController->IsGeographic())
		{
			needProjection=false;			
			Log::Inst().Write("The projection information for this study is being ignored.");
		}
		else
		{
	
			if(currentShpSR != NULL) 
			{
				if(currentShpSR->IsGeographic())
				{
					Log::Inst().Write("Loading vector map with geographic coordinates.");
					studyController->SetProjectData(true);
					studyController->SetGeographic(true);
					needProjection=true;
					poTransform = studyController->GetProjectionTool();
				}
				else if(currentShpSR->IsProjected())
				{
					studyController->SetProjectData(true);
					studyController->SetGeographic(false);
					needProjection=true;
					Log::Inst().Write("Loading vector map with projected coordinates.");
					ProjectionToolPtr projTool = studyController->GetProjectionTool();
					//OGRSpatialReference* currentLatLong = currentShpSR->CloneGeogCS();
					OGRSpatialReference *targetCS= projTool->GetTargetCS ();
					if(targetCS != NULL && !currentShpSR->IsSame(targetCS)) 
						poTransform.reset(OGRCreateCoordinateTransformation(currentShpSR, targetCS));
					
					else
						needProjection=false;

				}
				else
				{
				// The user should probably be made aware of this warning.
					Log::Inst().Warning("(Warning) Unknown type of coordinate system.");
					return false;
				}
			}		
	

			else 
			{
				//studyController->SetProjectData(false);
				//studyController->SetGeographic(false);
				needProjection=false;		
				
				Log::Inst().Write("Coordinate system information is not available for this map.");
				Log::Inst().Write("As a result, the projection information for this study is being ignored.");
				Log::Inst().Write("");
			
			}

		return true;
		}
	}
	// App::Inst().GetLayerTreeController()->GetNumMapLayers() ==0
	else
	{
		OGRSpatialReference* currentShpSR = poLayer->GetSpatialRef();
	//OGRSpatialReference oSource;
		if(currentShpSR != NULL) 
		{
			if(currentShpSR->IsGeographic())
			{
			// lat/lon coordinates are using the geographic projection (aka, plate carrée) 
				Log::Inst().Write("Loading vector map with lat/long coordinates.");
				studyController->SetProjectData(true);
				studyController->SetGeographic(true);
				needProjection=true;

			// determine centre of map
				VectorMapModelPtr vectorMapModel = vectorMapController->GetVectorMapModel();
				float vectorMinX= vectorMapModel->GetVectorBoundary_MinX();
				float vectorMinY = vectorMapModel->GetVectorBoundary_MinY();
				float vectorMaxX = vectorMapModel->GetVectorBoundary_MaxX();
				float vectorMaxY = vectorMapModel->GetVectorBoundary_MaxY();
			
				studyController->SetCentreLongitude(float(vectorMinX + fabs(vectorMinX - vectorMaxX) / 2.0));			
				studyController->SetCentreLatitude(float(vectorMinY + fabs(vectorMinY - vectorMaxY) / 2.0));

				studyController->SetFirstStandardParallel(vectorMinY);
				studyController->SetSecondStandardParallel(vectorMaxY);

				studyController->CalculateProjectionTool(currentShpSR);
				poTransform = studyController->GetProjectionTool();

			}
			else if(currentShpSR->IsProjected())
			{
				studyController->SetProjectData(true);
				studyController->SetGeographic(false);
				Log::Inst().Write("Loading vector map with projected coordinates.");
				studyController->CalculateProjectionTool(currentShpSR);
				poTransform = studyController->GetProjectionTool();
				needProjection=false;
			}
			else
			{
				// The user should probably be made aware of this warning.
				Log::Inst().Warning("(Warning) Unknown type of coordinate system.");
				return false;
				}
		}
		else 
		{
			studyController->SetProjectData(false);
			studyController->SetGeographic(false);
			needProjection=false;
		
			
			Log::Inst().Write("Coordinate system information is not available for this map.");
			Log::Inst().Write("As a result, the projection information for this study is being ignored.");
			Log::Inst().Write("To overlaid a Vector map on top of this map, the vector map must be specified in the same coordinate system as this map");
			Log::Inst().Write("");
		
		}
		}

	return true;
}
Пример #4
0
bool GdalAdapter::loadImage(const QString& fn)
{
    if (alreadyLoaded(fn))
        return true;

    QFileInfo fi(fn);
    GdalImage img;
    QRectF bbox;

    poDataset = (GDALDataset *) GDALOpen( QDir::toNativeSeparators(fi.absoluteFilePath()).toUtf8().constData(), GA_ReadOnly );
    if( poDataset == NULL )
    {
        qDebug() <<  "GDAL Open failed: " << fn;
        return false;
    }

    bool hasGeo = false;
    QDir dir(fi.absoluteDir());
    QString f = fi.baseName();
    QStringList wldFilter;
    wldFilter <<  f+".tfw" << f+".tifw" << f+".tiffw" << f+".wld";
    QFileInfoList fil = dir.entryInfoList(wldFilter);
    if (fil.count()) {
        QFile wld(fil[0].absoluteFilePath());
        if (wld.open(QIODevice::ReadOnly)) {
            int i;
            for (i=0; i<6; ++i) {
                if (wld.atEnd())
                    break;
                QString l = wld.readLine();
                bool ok;
                double d = l.toDouble(&ok);
                if (!ok)
                    break;
                switch (i) {
                case 0:
                    img.adfGeoTransform[1] = d;
                    break;
                case 1:
                    img.adfGeoTransform[4] = d;
                    break;
                case 2:
                    img.adfGeoTransform[2] = d;
                    break;
                case 3:
                    img.adfGeoTransform[5] = d;
                    break;
                case 4:
                    img.adfGeoTransform[0] = d;
                    break;
                case 5:
                    img.adfGeoTransform[3] = d;
                    break;
                }

            }
            if (i == 6)
                hasGeo = true;
        }
    }
    if(!hasGeo)
        if ( poDataset->GetGeoTransform( img.adfGeoTransform ) != CE_None ) {
            GDALClose((GDALDatasetH)poDataset);
            return false;
        }

    qDebug( "Origin = (%.6f,%.6f)\n",
            img.adfGeoTransform[0], img.adfGeoTransform[3] );

    qDebug( "Pixel Size = (%.6f,%.6f)\n",
            img.adfGeoTransform[1], img.adfGeoTransform[5] );

    bbox.setTopLeft(QPointF(img.adfGeoTransform[0], img.adfGeoTransform[3]));
    bbox.setWidth(img.adfGeoTransform[1]*poDataset->GetRasterXSize());
    bbox.setHeight(img.adfGeoTransform[5]*poDataset->GetRasterYSize());

    isLatLon = false;
    if( strlen(poDataset->GetProjectionRef()) != 0 ) {
        qDebug( "Projection is `%s'\n", poDataset->GetProjectionRef() );
        OGRSpatialReference* theSrs = new OGRSpatialReference(poDataset->GetProjectionRef());
        if (theSrs && theSrs->Validate() == OGRERR_NONE) {
            theSrs->morphFromESRI();
            char* theProj4;
            if (theSrs->exportToProj4(&theProj4) == OGRERR_NONE) {
                qDebug() << "GDAL: to proj4 : " << theProj4;
            } else {
                qDebug() << "GDAL: to proj4 error: " << CPLGetLastErrorMsg();
                GDALClose((GDALDatasetH)poDataset);
                return false;
            }
            QString srsProj = QString(theProj4);
            if (!srsProj.isEmpty() && theProjection != srsProj) {
                cleanup();
                theProjection = srsProj;
            }
            isLatLon = (theSrs->IsGeographic() == TRUE);
        }
    }
    if (theProjection.isEmpty()) {
        theProjection = ProjectionChooser::getProjection(QCoreApplication::translate("ImportExportGdal", "Unable to set projection; please specify one"));
        if (theProjection.isEmpty()) {
            GDALClose((GDALDatasetH)poDataset);
            return false;
        }
    }

    qDebug( "Driver: %s/%s\n",
            poDataset->GetDriver()->GetDescription(),
            poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) );

    qDebug( "Size is %dx%dx%d\n",
            poDataset->GetRasterXSize(), poDataset->GetRasterYSize(),
            poDataset->GetRasterCount() );

    GdalAdapter::ImgType theType = GdalAdapter::Unknown;
    int bandCount = poDataset->GetRasterCount();
    int ixA = -1;
    int ixR, ixG, ixB;
    int ixH, ixS, ixL;
    int ixC, ixM, ixY, ixK;
    int ixYuvY, ixYuvU, ixYuvV;
    double adfMinMax[2];
    double UnknownUnit;
    GDALColorTable* colTable = NULL;
    for (int i=0; i<bandCount; ++i) {
        GDALRasterBand  *poBand = poDataset->GetRasterBand( i+1 );
        GDALColorInterp bandtype = poBand->GetColorInterpretation();
        qDebug() << "Band " << i+1 << " Color: " <<  GDALGetColorInterpretationName(poBand->GetColorInterpretation());

        switch (bandtype)
        {
        case GCI_Undefined:
            theType = GdalAdapter::Unknown;
            int             bGotMin, bGotMax;
            adfMinMax[0] = poBand->GetMinimum( &bGotMin );
            adfMinMax[1] = poBand->GetMaximum( &bGotMax );
            if( ! (bGotMin && bGotMax) )
                GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
            UnknownUnit = (adfMinMax[1] - adfMinMax[0]) / 256;
            break;
        case GCI_GrayIndex:
            theType = GdalAdapter::GrayScale;
            break;
        case GCI_RedBand:
            theType = GdalAdapter::Rgb;
            ixR = i;
            break;
        case GCI_GreenBand:
            theType = GdalAdapter::Rgb;
            ixG = i;
            break;
        case GCI_BlueBand :
            theType = GdalAdapter::Rgb;
            ixB = i;
            break;
        case GCI_HueBand:
            theType = GdalAdapter::Hsl;
            ixH = i;
            break;
        case GCI_SaturationBand:
            theType = GdalAdapter::Hsl;
            ixS = i;
            break;
        case GCI_LightnessBand:
            theType = GdalAdapter::Hsl;
            ixL = i;
            break;
        case GCI_CyanBand:
            theType = GdalAdapter::Cmyk;
            ixC = i;
            break;
        case GCI_MagentaBand:
            theType = GdalAdapter::Cmyk;
            ixM = i;
            break;
        case GCI_YellowBand:
            theType = GdalAdapter::Cmyk;
            ixY = i;
            break;
        case GCI_BlackBand:
            theType = GdalAdapter::Cmyk;
            ixK = i;
            break;
        case GCI_YCbCr_YBand:
            theType = GdalAdapter::YUV;
            ixYuvY = i;
            break;
        case GCI_YCbCr_CbBand:
            theType = GdalAdapter::YUV;
            ixYuvU = i;
            break;
        case GCI_YCbCr_CrBand:
            theType = GdalAdapter::YUV;
            ixYuvV = i;
            break;
        case GCI_AlphaBand:
            ixA = i;
            break;
        case GCI_PaletteIndex:
            colTable = poBand->GetColorTable();
            switch (colTable->GetPaletteInterpretation())
            {
            case GPI_Gray :
                theType = GdalAdapter::Palette_Gray;
                break;
            case GPI_RGB :
                theType = GdalAdapter::Palette_RGBA;
                break;
            case GPI_CMYK :
                theType = GdalAdapter::Palette_CMYK;
                break;
            case GPI_HLS :
                theType = GdalAdapter::Palette_HLS;
                break;
            }
            break;
        }
    }

    QSize theImgSize(poDataset->GetRasterXSize(), poDataset->GetRasterYSize());
    QImage theImg = QImage(theImgSize, QImage::Format_ARGB32);

    // Make sure that lineBuf holds one whole line of data.
    float *lineBuf;
    lineBuf = (float *) CPLMalloc(theImgSize.width() * bandCount * sizeof(float));

    int px, py;
    //every row loop
    for (int row = 0; row < theImgSize.height(); row++) {
        py = row;
        poDataset->RasterIO( GF_Read, 0, row, theImgSize.width(), 1, lineBuf, theImgSize.width(), 1, GDT_Float32,
                            bandCount, NULL, sizeof(float) * bandCount, 0, sizeof(float) );
        // every pixel in row.
        for (int col = 0; col < theImgSize.width(); col++){
            px = col;
            switch (theType)
            {
            case GdalAdapter::Unknown:
            {
                float* v = lineBuf + (col*bandCount);
                float val = (*v - adfMinMax[0]) / UnknownUnit;
                theImg.setPixel(px, py, qRgb(val, val, val));
                break;
            }
            case GdalAdapter::GrayScale:
            {
                float* v = lineBuf + (col*bandCount);
                theImg.setPixel(px, py, qRgb(*v, *v, *v));
                break;
            }
            case GdalAdapter::Rgb:
            {
                float* r = lineBuf + (col*bandCount) + ixR;
                float* g = lineBuf + (col*bandCount) + ixG;
                float* b = lineBuf + (col*bandCount) + ixB;
                int a = 255;
                if (ixA != -1) {
                    float* fa = lineBuf + (col*bandCount) + ixA;
                    a = *fa;
                }
                theImg.setPixel(px, py, qRgba(*r, *g, *b, a));
                break;
            }
#if QT_VERSION >= 0x040600
            case GdalAdapter::Hsl:
            {
                float* h = lineBuf + (col*bandCount) + ixH;
                float* s = lineBuf + (col*bandCount) + ixS;
                float* l = lineBuf + (col*bandCount) + ixL;
                int a = 255;
                if (ixA != -1) {
                    float* fa = lineBuf + (col*bandCount) + ixA;
                    a = *fa;
                }
                QColor C = QColor::fromHsl(*h, *s, *l, a);
                theImg.setPixel(px, py, C.rgba());
                break;
            }
#endif
            case GdalAdapter::Cmyk:
            {
                float* c = lineBuf + (col*bandCount) + ixC;
                float* m = lineBuf + (col*bandCount) + ixM;
                float* y = lineBuf + (col*bandCount) + ixY;
                float* k = lineBuf + (col*bandCount) + ixK;
                int a = 255;
                if (ixA != -1) {
                    float* fa = lineBuf + (col*bandCount) + ixA;
                    a = *fa;
                }
                QColor C = QColor::fromCmyk(*c, *m, *y, *k, a);
                theImg.setPixel(px, py, C.rgba());
                break;
            }
            case GdalAdapter::YUV:
            {
                // From http://www.fourcc.org/fccyvrgb.php
                float* y = lineBuf + (col*bandCount) + ixYuvY;
                float* u = lineBuf + (col*bandCount) + ixYuvU;
                float* v = lineBuf + (col*bandCount) + ixYuvV;
                int a = 255;
                if (ixA != -1) {
                    float* fa = lineBuf + (col*bandCount) + ixA;
                    a = *fa;
                }
                float R = 1.164*(*y - 16) + 1.596*(*v - 128);
                float G = 1.164*(*y - 16) - 0.813*(*v - 128) - 0.391*(*u - 128);
                float B = 1.164*(*y - 16) + 2.018*(*u - 128);

                theImg.setPixel(px, py, qRgba(R, G, B, a));
                break;
            }
            case GdalAdapter::Palette_Gray:
            {
                float* ix = (lineBuf + (col*bandCount));
                const GDALColorEntry* color = colTable->GetColorEntry(*ix);
                theImg.setPixel(px, py, qRgb(color->c1, color->c1, color->c1));
                break;
            }
            case GdalAdapter::Palette_RGBA:
            {
                float* ix = (lineBuf + (col*bandCount));
                const GDALColorEntry* color = colTable->GetColorEntry(*ix);
                theImg.setPixel(px, py, qRgba(color->c1, color->c2, color->c3, color->c4));
                break;
            }
#if QT_VERSION >= 0x040600
            case GdalAdapter::Palette_HLS:
            {
                float* ix = (lineBuf + (col*bandCount));
                const GDALColorEntry* color = colTable->GetColorEntry(*ix);
                QColor C = QColor::fromHsl(color->c1, color->c2, color->c3, color->c4);
                theImg.setPixel(px, py, C.rgba());
                break;
            }
#endif
            case GdalAdapter::Palette_CMYK:
            {
                float* ix = (lineBuf + (col*bandCount));
                const GDALColorEntry* color = colTable->GetColorEntry(*ix);
                QColor C = QColor::fromCmyk(color->c1, color->c2, color->c3, color->c4);
                theImg.setPixel(px, py, C.rgba());
                break;
            }
            }
        }
        QCoreApplication::processEvents();
    }

    img.theFilename = fn;
    img.theImg = QPixmap::fromImage(theImg);
    theImages.push_back(img);
    theBbox = theBbox.united(bbox);

    GDALClose((GDALDatasetH)poDataset);
    return true;
}
Пример #5
0
GDALDataset* HF2Dataset::CreateCopy( const char * pszFilename,
                                     GDALDataset *poSrcDS, 
                                     int bStrict, char ** papszOptions, 
                                     GDALProgressFunc pfnProgress,
                                     void * pProgressData )
{
/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "HF2 driver does not support source dataset with zero band.\n");
        return NULL;
    }

    if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
                  "HF2 driver only uses the first band of the dataset.\n");
        if (bStrict)
            return NULL;
    }

    if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Get source dataset info                                         */
/* -------------------------------------------------------------------- */

    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    double adfGeoTransform[6];
    poSrcDS->GetGeoTransform(adfGeoTransform);
    int bHasGeoTransform = !(adfGeoTransform[0] == 0 &&
                             adfGeoTransform[1] == 1 &&
                             adfGeoTransform[2] == 0 &&
                             adfGeoTransform[3] == 0 &&
                             adfGeoTransform[4] == 0 &&
                             adfGeoTransform[5] == 1);
    if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "HF2 driver does not support CreateCopy() from skewed or rotated dataset.\n");
        return NULL;
    }

    GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    GDALDataType eReqDT;
    float fVertPres = (float) 0.01;
    if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16)
    {
        fVertPres = 1;
        eReqDT = GDT_Int16;
    }
    else
        eReqDT = GDT_Float32;

/* -------------------------------------------------------------------- */
/*      Read creation options                                           */
/* -------------------------------------------------------------------- */
    const char* pszCompressed = CSLFetchNameValue(papszOptions, "COMPRESS");
    int bCompress = FALSE;
    if (pszCompressed)
        bCompress = CSLTestBoolean(pszCompressed);
    
    const char* pszVerticalPrecision = CSLFetchNameValue(papszOptions, "VERTICAL_PRECISION");
    if (pszVerticalPrecision)
    {
        fVertPres = (float) CPLAtofM(pszVerticalPrecision);
        if (fVertPres <= 0)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Unsupported value for VERTICAL_PRECISION. Defaulting to 0.01");
            fVertPres = (float) 0.01;
        }
        if (eReqDT == GDT_Int16 && fVertPres > 1)
            eReqDT = GDT_Float32;
    }

    const char* pszBlockSize = CSLFetchNameValue(papszOptions, "BLOCKSIZE");
    int nTileSize = 256;
    if (pszBlockSize)
    {
        nTileSize = atoi(pszBlockSize);
        if (nTileSize < 8 || nTileSize > 4096)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Unsupported value for BLOCKSIZE. Defaulting to 256");
            nTileSize = 256;
        }
    }

/* -------------------------------------------------------------------- */
/*      Parse source dataset georeferencing info                        */
/* -------------------------------------------------------------------- */

    int nExtendedHeaderLen = 0;
    if (bHasGeoTransform)
        nExtendedHeaderLen += 58;
    const char* pszProjectionRef = poSrcDS->GetProjectionRef();
    int nDatumCode = -2;
    int nUTMZone = 0;
    int bNorth = FALSE;
    int nEPSGCode = 0;
    int nExtentUnits = 1;
    if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0')
    {
        OGRSpatialReference oSRS;
        char* pszTemp = (char*) pszProjectionRef;
        if (oSRS.importFromWkt(&pszTemp) == OGRERR_NONE)
        {
            const char* pszValue = NULL;
            if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL
                && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") )
                nDatumCode = atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" ));
            else if ((pszValue = oSRS.GetAttrValue("GEOGCS|DATUM")) != NULL)
            {
                if (strstr(pszValue, "WGS") && strstr(pszValue, "84"))
                    nDatumCode = 6326;
            }

            nUTMZone = oSRS.GetUTMZone(&bNorth);
        }
        if( oSRS.GetAuthorityName( "PROJCS" ) != NULL
            && EQUAL(oSRS.GetAuthorityName( "PROJCS" ),"EPSG") )
            nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" ));

        if( oSRS.IsGeographic() )
        {
            nExtentUnits = 0;
        }
        else
        {
            double dfLinear = oSRS.GetLinearUnits();

            if( ABS(dfLinear - 0.3048) < 0.0000001 )
                nExtentUnits = 2;
            else if( ABS(dfLinear - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
                nExtentUnits = 3;
            else
                nExtentUnits = 1;
        }
    }
    if (nDatumCode != -2)
        nExtendedHeaderLen += 26;
    if (nUTMZone != 0)
        nExtendedHeaderLen += 26;
    if (nEPSGCode)
        nExtendedHeaderLen += 26;

/* -------------------------------------------------------------------- */
/*      Create target file                                              */
/* -------------------------------------------------------------------- */

    CPLString osFilename;
    if (bCompress)
    {
        osFilename = "/vsigzip/";
        osFilename += pszFilename;
    }
    else
        osFilename = pszFilename;
    VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "wb");
    if (fp == NULL)
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Cannot create %s", pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Write header                                                    */
/* -------------------------------------------------------------------- */

    VSIFWriteL("HF2\0", 4, 1, fp);
    WriteShort(fp, 0);
    WriteInt(fp, nXSize);
    WriteInt(fp, nYSize);
    WriteShort(fp, (GInt16) nTileSize);
    WriteFloat(fp, fVertPres);
    float fHorizScale = (float) ((fabs(adfGeoTransform[1]) + fabs(adfGeoTransform[5])) / 2);
    WriteFloat(fp, fHorizScale);
    WriteInt(fp, nExtendedHeaderLen);

/* -------------------------------------------------------------------- */
/*      Write extended header                                           */
/* -------------------------------------------------------------------- */

    char szBlockName[16 + 1];
    if (bHasGeoTransform)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-extents");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 34);
        WriteShort(fp, (GInt16) nExtentUnits);
        WriteDouble(fp, adfGeoTransform[0]);
        WriteDouble(fp, adfGeoTransform[0] + nXSize * adfGeoTransform[1]);
        WriteDouble(fp, adfGeoTransform[3] + nYSize * adfGeoTransform[5]);
        WriteDouble(fp, adfGeoTransform[3]);
    }
    if (nUTMZone != 0)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-utm");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) ((bNorth) ? nUTMZone : -nUTMZone));
    }
    if (nDatumCode != -2)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-datum");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) nDatumCode);
    }
    if (nEPSGCode != 0)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-epsg-prj");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) nEPSGCode);
    }

/* -------------------------------------------------------------------- */
/*      Copy imagery                                                    */
/* -------------------------------------------------------------------- */
    int nXBlocks = (nXSize + nTileSize - 1) / nTileSize;
    int nYBlocks = (nYSize + nTileSize - 1) / nTileSize;

    void* pTileBuffer = (void*) VSIMalloc(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8));
    if (pTileBuffer == NULL)
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory");
        VSIFCloseL(fp);
        return NULL;
    }

    int i, j, k, l;
    CPLErr eErr = CE_None;
    for(j=0;j<nYBlocks && eErr == CE_None;j++)
    {
        for(i=0;i<nXBlocks && eErr == CE_None;i++)
        {
            int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize);
            int nReqYSize = MIN(nTileSize, nYSize - j * nTileSize);
            eErr = poSrcDS->GetRasterBand(1)->RasterIO(GF_Read,
                                                i * nTileSize, MAX(0, nYSize - (j + 1) * nTileSize),
                                                nReqXSize, nReqYSize,
                                                pTileBuffer, nReqXSize, nReqYSize,
                                                eReqDT, 0, 0, NULL);
            if (eErr != CE_None)
                break;

            if (eReqDT == GDT_Int16)
            {
                WriteFloat(fp, 1); /* scale */
                WriteFloat(fp, 0); /* offset */
                for(k=0;k<nReqYSize;k++)
                {
                    int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    GByte nWordSize = 1;
                    for(l=1;l<nReqXSize;l++)
                    {
                        int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        int nDiff = nVal - nLastVal;
                        if (nDiff < -32768 || nDiff > 32767)
                        {
                            nWordSize = 4;
                            break;
                        }
                        if (nDiff < -128 || nDiff > 127)
                            nWordSize = 2;
                        nLastVal = nVal;
                    }

                    VSIFWriteL(&nWordSize, 1, 1, fp);
                    nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    WriteInt(fp, nLastVal);
                    for(l=1;l<nReqXSize;l++)
                    {
                        int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        int nDiff = nVal - nLastVal;
                        if (nWordSize == 1)
                        {
                            CPLAssert(nDiff >= -128 && nDiff <= 127);
                            signed char chDiff = (signed char)nDiff;
                            VSIFWriteL(&chDiff, 1, 1, fp);
                        }
                        else if (nWordSize == 2)
                        {
                            CPLAssert(nDiff >= -32768 && nDiff <= 32767);
                            WriteShort(fp, (short)nDiff);
                        }
                        else
                        {
                            WriteInt(fp, nDiff);
                        }
                        nLastVal = nVal;
                    }
                }
            }
            else
            {
                float fMinVal = ((float*)pTileBuffer)[0];
                float fMaxVal = fMinVal;
                for(k=1;k<nReqYSize*nReqXSize;k++)
                {
                    float fVal = ((float*)pTileBuffer)[k];
                    if (fVal < fMinVal) fMinVal = fVal;
                    if (fVal > fMaxVal) fMaxVal = fVal;
                }

                float fIntRange = (fMaxVal - fMinVal) / fVertPres;
                float fScale = (fMinVal == fMaxVal) ? 1 : (fMaxVal - fMinVal) / fIntRange;
                float fOffset = fMinVal;
                WriteFloat(fp, fScale); /* scale */
                WriteFloat(fp, fOffset); /* offset */
                for(k=0;k<nReqYSize;k++)
                {
                    float fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    float fIntLastVal = (fLastVal - fOffset) / fScale;
                    CPLAssert(fIntLastVal >= -2147483648.0f && fIntLastVal <= 2147483647.0f);
                    int nLastVal = (int)fIntLastVal;
                    GByte nWordSize = 1;
                    for(l=1;l<nReqXSize;l++)
                    {
                        float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        float fIntVal = (fVal - fOffset) / fScale;
                        CPLAssert(fIntVal >= -2147483648.0f && fIntVal <= 2147483647.0f);
                        int nVal = (int)fIntVal;
                        int nDiff = nVal - nLastVal;
                        CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff);
                        if (nDiff < -32768 || nDiff > 32767)
                        {
                            nWordSize = 4;
                            break;
                        }
                        if (nDiff < -128 || nDiff > 127)
                            nWordSize = 2;
                        nLastVal = nVal;
                    }

                    VSIFWriteL(&nWordSize, 1, 1, fp);
                    fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    fIntLastVal = (fLastVal - fOffset) / fScale;
                    nLastVal = (int)fIntLastVal;
                    WriteInt(fp, nLastVal);
                    for(l=1;l<nReqXSize;l++)
                    {
                        float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        float fIntVal = (fVal - fOffset) / fScale;
                        int nVal = (int)fIntVal;
                        int nDiff = nVal - nLastVal;
                        CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff);
                        if (nWordSize == 1)
                        {
                            CPLAssert(nDiff >= -128 && nDiff <= 127);
                            signed char chDiff = (signed char)nDiff;
                            VSIFWriteL(&chDiff, 1, 1, fp);
                        }
                        else if (nWordSize == 2)
                        {
                            CPLAssert(nDiff >= -32768 && nDiff <= 32767);
                            WriteShort(fp, (short)nDiff);
                        }
                        else
                        {
                            WriteInt(fp, nDiff);
                        }
                        nLastVal = nVal;
                    }
                }
            }

            if( pfnProgress && !pfnProgress( (j * nXBlocks + i + 1) * 1.0 / (nXBlocks * nYBlocks), NULL, pProgressData ) )
            {
                eErr = CE_Failure;
                break;
            }
        }
    }

    CPLFree(pTileBuffer);

    VSIFCloseL(fp);

    if (eErr != CE_None)
        return NULL;

    return (GDALDataset*) GDALOpen(osFilename.c_str(), GA_ReadOnly);
}
Пример #6
0
bool LevellerDataset::compute_elev_scaling
(
	const OGRSpatialReference& sr
)
{
	const char* pszGroundUnits;

	if(!sr.IsGeographic())
	{
		// For projected or local CS, the elev scale is
		// the average ground scale.
		m_dElevScale = average(m_adfTransform[1], m_adfTransform[5]);

		const double dfLinear = sr.GetLinearUnits();
		const measurement_unit* pu = this->get_uom(dfLinear);
		if(pu == NULL)
			return false;

		pszGroundUnits = pu->pszID;
	}
	else
	{
		pszGroundUnits = "m";

		const double kdEarthCircumPolar = 40007849;
		const double kdEarthCircumEquat = 40075004;

		double xr, yr;
		xr = 0.5 * this->nRasterXSize;
		yr = 0.5 * this->nRasterYSize;

		double xg[2], yg[2];
		this->raw_to_proj(xr, yr, xg[0], yg[0]);
		this->raw_to_proj(xr+1, yr+1, xg[1], yg[1]);
		
		// The earths' circumference shrinks using a sin()
		// curve as we go up in latitude.
		const double dLatCircum = kdEarthCircumEquat 
			* sin(degrees_to_radians(90.0 - yg[0]));

		// Derive meter distance between geolongitudes
		// in xg[0] and xg[1].
		double dx = fabs(xg[1] - xg[0]) / 360.0 * dLatCircum;
		double dy = fabs(yg[1] - yg[0]) / 360.0 * kdEarthCircumPolar;

		m_dElevScale = average(dx, dy);
	}

	m_dElevBase = m_dLogSpan[0];

	// Convert from ground units to elev units.
	const measurement_unit* puG = this->get_uom(pszGroundUnits);
	const measurement_unit* puE = this->get_uom(m_szElevUnits);

	if(puG == NULL || puE == NULL)
		return false;

	const double g_to_e = puG->dScale / puE->dScale;

	m_dElevScale *= g_to_e;
	return true;
}
Пример #7
0
int OGRProj4CT::InitializeNoLock( OGRSpatialReference * poSourceIn, 
                                  OGRSpatialReference * poTargetIn )

{
    if( poSourceIn == NULL || poTargetIn == NULL )
        return FALSE;

    poSRSSource = poSourceIn->Clone();
    poSRSTarget = poTargetIn->Clone();

    bSourceLatLong = poSRSSource->IsGeographic();
    bTargetLatLong = poSRSTarget->IsGeographic();

/* -------------------------------------------------------------------- */
/*      Setup source and target translations to radians for lat/long    */
/*      systems.                                                        */
/* -------------------------------------------------------------------- */
    dfSourceToRadians = DEG_TO_RAD;
    bSourceWrap = FALSE;
    dfSourceWrapLong = 0.0;

    if( bSourceLatLong )
    {
        OGR_SRSNode *poUNITS = poSRSSource->GetAttrNode( "GEOGCS|UNIT" );
        if( poUNITS && poUNITS->GetChildCount() >= 2 )
        {
            dfSourceToRadians = atof(poUNITS->GetChild(1)->GetValue());
            if( dfSourceToRadians == 0.0 )
                dfSourceToRadians = DEG_TO_RAD;
        }
    }

    dfTargetFromRadians = RAD_TO_DEG;
    bTargetWrap = FALSE;
    dfTargetWrapLong = 0.0;

    if( bTargetLatLong )
    {
        OGR_SRSNode *poUNITS = poSRSTarget->GetAttrNode( "GEOGCS|UNIT" );
        if( poUNITS && poUNITS->GetChildCount() >= 2 )
        {
            double dfTargetToRadians = atof(poUNITS->GetChild(1)->GetValue());
            if( dfTargetToRadians != 0.0 )
                dfTargetFromRadians = 1 / dfTargetToRadians;
        }
    }

/* -------------------------------------------------------------------- */
/*      Preliminary logic to setup wrapping.                            */
/* -------------------------------------------------------------------- */
    const char *pszCENTER_LONG;

    if( CPLGetConfigOption( "CENTER_LONG", NULL ) != NULL )
    {
        bSourceWrap = bTargetWrap = TRUE;
        dfSourceWrapLong = dfTargetWrapLong = 
            atof(CPLGetConfigOption( "CENTER_LONG", "" ));
        CPLDebug( "OGRCT", "Wrap at %g.", dfSourceWrapLong );
    }

    pszCENTER_LONG = poSRSSource->GetExtension( "GEOGCS", "CENTER_LONG" );
    if( pszCENTER_LONG != NULL )
    {
        dfSourceWrapLong = atof(pszCENTER_LONG);
        bSourceWrap = TRUE;
        CPLDebug( "OGRCT", "Wrap source at %g.", dfSourceWrapLong );
    }

    pszCENTER_LONG = poSRSTarget->GetExtension( "GEOGCS", "CENTER_LONG" );
    if( pszCENTER_LONG != NULL )
    {
        dfTargetWrapLong = atof(pszCENTER_LONG);
        bTargetWrap = TRUE;
        CPLDebug( "OGRCT", "Wrap target at %g.", dfTargetWrapLong );
    }
    
    bCheckWithInvertProj = CSLTestBoolean(CPLGetConfigOption( "CHECK_WITH_INVERT_PROJ", "NO" ));
    
    /* The threshold is rather experimental... Works well with the cases of ticket #2305 */
    if (bSourceLatLong)
        dfThreshold = atof(CPLGetConfigOption( "THRESHOLD", ".1" ));
    else
        /* 1 works well for most projections, except for +proj=aeqd that requires */
        /* a tolerance of 10000 */
        dfThreshold = atof(CPLGetConfigOption( "THRESHOLD", "10000" ));

/* -------------------------------------------------------------------- */
/*      Establish PROJ.4 handle for source if projection.               */
/* -------------------------------------------------------------------- */
    // OGRThreadSafety: The following variable is not a thread safety issue 
    // since the only issue is incrementing while accessing which at worse 
    // means debug output could be one "increment" late. 
    static int   nDebugReportCount = 0;

    char        *pszSrcProj4Defn = NULL;

    if( poSRSSource->exportToProj4( &pszSrcProj4Defn ) != OGRERR_NONE )
    {
        CPLFree( pszSrcProj4Defn );
        return FALSE;
    }

    if( strlen(pszSrcProj4Defn) == 0 )
    {
        CPLFree( pszSrcProj4Defn );
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "No PROJ.4 translation for source SRS, coordinate\n"
                  "transformation initialization has failed." );
        return FALSE;
    }

    if (pjctx)
        psPJSource = pfn_pj_init_plus_ctx( pjctx, pszSrcProj4Defn );
    else
        psPJSource = pfn_pj_init_plus( pszSrcProj4Defn );
    
    if( psPJSource == NULL )
    {
        if( pjctx != NULL)
        {
            int pj_errno = pfn_pj_ctx_get_errno(pjctx);

            /* pfn_pj_strerrno not yet thread-safe in PROJ 4.8.0 */
            CPLMutexHolderD(&hPROJMutex);
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "Failed to initialize PROJ.4 with `%s'.\n%s", 
                      pszSrcProj4Defn, pfn_pj_strerrno(pj_errno) );
        }
        else if( pfn_pj_get_errno_ref != NULL
            && pfn_pj_strerrno != NULL )
        {
            int *p_pj_errno = pfn_pj_get_errno_ref();

            CPLError( CE_Failure, CPLE_NotSupported, 
                      "Failed to initialize PROJ.4 with `%s'.\n%s", 
                      pszSrcProj4Defn, pfn_pj_strerrno(*p_pj_errno) );
        }
        else
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "Failed to initialize PROJ.4 with `%s'.\n", 
                      pszSrcProj4Defn );
        }
    }
    
    if( nDebugReportCount < 10 )
        CPLDebug( "OGRCT", "Source: %s", pszSrcProj4Defn );

    if( psPJSource == NULL )
    {
        CPLFree( pszSrcProj4Defn );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Establish PROJ.4 handle for target if projection.               */
/* -------------------------------------------------------------------- */

    char        *pszDstProj4Defn = NULL;

    if( poSRSTarget->exportToProj4( &pszDstProj4Defn ) != OGRERR_NONE )
    {
        CPLFree( pszSrcProj4Defn );
        CPLFree( pszDstProj4Defn );
        return FALSE;
    }

    if( strlen(pszDstProj4Defn) == 0 )
    {
        CPLFree( pszSrcProj4Defn );
        CPLFree( pszDstProj4Defn );
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "No PROJ.4 translation for destination SRS, coordinate\n"
                  "transformation initialization has failed." );
        return FALSE;
    }

    if (pjctx)
        psPJTarget = pfn_pj_init_plus_ctx( pjctx, pszDstProj4Defn );
    else
        psPJTarget = pfn_pj_init_plus( pszDstProj4Defn );
    
    if( psPJTarget == NULL )
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Failed to initialize PROJ.4 with `%s'.", 
                  pszDstProj4Defn );
    
    if( nDebugReportCount < 10 )
    {
        CPLDebug( "OGRCT", "Target: %s", pszDstProj4Defn );
        nDebugReportCount++;
    }

    if( psPJTarget == NULL )
    {
        CPLFree( pszSrcProj4Defn );
        CPLFree( pszDstProj4Defn );
        return FALSE;
    }

    /* Determine if we really have a transformation to do */
    bIdentityTransform = (strcmp(pszSrcProj4Defn, pszDstProj4Defn) == 0);

    /* In case of identity transform, under the following conditions, */
    /* we can also avoid transforming from deegrees <--> radians. */
    if( bIdentityTransform && bSourceLatLong && !bSourceWrap &&
        bTargetLatLong && !bTargetWrap &&
        abs(dfSourceToRadians * dfTargetFromRadians - 1.0) < 1e-10 )
    {
        /*bSourceLatLong = FALSE;
        bTargetLatLong = FALSE;*/
    }

    CPLFree( pszSrcProj4Defn );
    CPLFree( pszDstProj4Defn );

    return TRUE;
}
Пример #8
0
GDALJP2Box *GDALJP2Metadata::CreateGMLJP2( int nXSize, int nYSize )

{
/* -------------------------------------------------------------------- */
/*      This is a backdoor to let us embed a literal gmljp2 chunk       */
/*      supplied by the user as an external file.  This is mostly       */
/*      for preparing test files with exotic contents.                  */
/* -------------------------------------------------------------------- */
    if( CPLGetConfigOption( "GMLJP2OVERRIDE", NULL ) != NULL )
    {
        VSILFILE *fp = VSIFOpenL( CPLGetConfigOption( "GMLJP2OVERRIDE",""), "r" );
        char *pszGML = NULL;

        if( fp == NULL )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "Unable to open GMLJP2OVERRIDE file." );
            return NULL;
        }
        
        VSIFSeekL( fp, 0, SEEK_END );
        int nLength = (int) VSIFTellL( fp );
        pszGML = (char *) CPLCalloc(1,nLength+1);
        VSIFSeekL( fp, 0, SEEK_SET );
        VSIFReadL( pszGML, 1, nLength, fp );
        VSIFCloseL( fp );

        GDALJP2Box *apoGMLBoxes[2];

        apoGMLBoxes[0] = GDALJP2Box::CreateLblBox( "gml.data" );
        apoGMLBoxes[1] = 
            GDALJP2Box::CreateLabelledXMLAssoc( "gml.root-instance", 
                                                pszGML );

        GDALJP2Box *poGMLData = GDALJP2Box::CreateAsocBox( 2, apoGMLBoxes);
        
        delete apoGMLBoxes[0];
        delete apoGMLBoxes[1];

        CPLFree( pszGML );
        
        return poGMLData;
    }

/* -------------------------------------------------------------------- */
/*      Try do determine a PCS or GCS code we can use.                  */
/* -------------------------------------------------------------------- */
    OGRSpatialReference oSRS;
    char *pszWKTCopy = (char *) pszProjection;
    int nEPSGCode = 0;
    char szSRSName[100];
    int  bNeedAxisFlip = FALSE;

    if( oSRS.importFromWkt( &pszWKTCopy ) != OGRERR_NONE )
        return NULL;

    if( oSRS.IsProjected() )
    {
        const char *pszAuthName = oSRS.GetAuthorityName( "PROJCS" );

        if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") )
        {
            nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" ));
        }
    }
    else if( oSRS.IsGeographic() )
    {
        const char *pszAuthName = oSRS.GetAuthorityName( "GEOGCS" );

        if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") )
        {
            nEPSGCode = atoi(oSRS.GetAuthorityCode( "GEOGCS" ));
            bNeedAxisFlip = TRUE;
        }
    }

    if( nEPSGCode != 0 )
        sprintf( szSRSName, "urn:ogc:def:crs:EPSG::%d", nEPSGCode );
    else
        strcpy( szSRSName, 
                "gmljp2://xml/CRSDictionary.gml#ogrcrs1" );

/* -------------------------------------------------------------------- */
/*      Prepare coverage origin and offset vectors.  Take axis          */
/*      order into account if needed.                                   */
/* -------------------------------------------------------------------- */
    double adfOrigin[2];
    double adfXVector[2];
    double adfYVector[2];
    
    adfOrigin[0] = adfGeoTransform[0] + adfGeoTransform[1] * 0.5
        + adfGeoTransform[4] * 0.5;
    adfOrigin[1] = adfGeoTransform[3] + adfGeoTransform[2] * 0.5
        + adfGeoTransform[5] * 0.5;
    adfXVector[0] = adfGeoTransform[1];
    adfXVector[1] = adfGeoTransform[2];
        
    adfYVector[0] = adfGeoTransform[4];
    adfYVector[1] = adfGeoTransform[5];
    
    if( bNeedAxisFlip
        && CSLTestBoolean( CPLGetConfigOption( "GDAL_IGNORE_AXIS_ORIENTATION",
                                               "FALSE" ) ) )
    {
        bNeedAxisFlip = FALSE;
        CPLDebug( "GMLJP2", "Supressed axis flipping on write based on GDAL_IGNORE_AXIS_ORIENTATION." );
    }

    if( bNeedAxisFlip )
    {
        double dfTemp;
        
        CPLDebug( "GMLJP2", "Flipping GML coverage axis order." );
        
        dfTemp = adfOrigin[0];
        adfOrigin[0] = adfOrigin[1];
        adfOrigin[1] = dfTemp;

        dfTemp = adfXVector[0];
        adfXVector[0] = adfXVector[1];
        adfXVector[1] = dfTemp;

        dfTemp = adfYVector[0];
        adfYVector[0] = adfYVector[1];
        adfYVector[1] = dfTemp;
    }

/* -------------------------------------------------------------------- */
/*      For now we hardcode for a minimal instance format.              */
/* -------------------------------------------------------------------- */
    CPLString osDoc;

    osDoc.Printf( 
"<gml:FeatureCollection\n"
"   xmlns:gml=\"http://www.opengis.net/gml\"\n"
"   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
"   xsi:schemaLocation=\"http://www.opengeospatial.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlJP2Profile/1.0.0/gmlJP2Profile.xsd\">\n"
"  <gml:boundedBy>\n"
"    <gml:Null>withheld</gml:Null>\n"
"  </gml:boundedBy>\n"
"  <gml:featureMember>\n"
"    <gml:FeatureCollection>\n"
"      <gml:featureMember>\n"
"        <gml:RectifiedGridCoverage dimension=\"2\" gml:id=\"RGC0001\">\n"
"          <gml:rectifiedGridDomain>\n"
"            <gml:RectifiedGrid dimension=\"2\">\n"
"              <gml:limits>\n"
"                <gml:GridEnvelope>\n"
"                  <gml:low>0 0</gml:low>\n"
"                  <gml:high>%d %d</gml:high>\n"
"                </gml:GridEnvelope>\n"
"              </gml:limits>\n"
"              <gml:axisName>x</gml:axisName>\n"
"              <gml:axisName>y</gml:axisName>\n"
"              <gml:origin>\n"
"                <gml:Point gml:id=\"P0001\" srsName=\"%s\">\n"
"                  <gml:pos>%.15g %.15g</gml:pos>\n"
"                </gml:Point>\n"
"              </gml:origin>\n"
"              <gml:offsetVector srsName=\"%s\">%.15g %.15g</gml:offsetVector>\n"
"              <gml:offsetVector srsName=\"%s\">%.15g %.15g</gml:offsetVector>\n"
"            </gml:RectifiedGrid>\n"
"          </gml:rectifiedGridDomain>\n"
"          <gml:rangeSet>\n"
"            <gml:File>\n"
"              <gml:fileName>gmljp2://codestream/0</gml:fileName>\n"
"              <gml:fileStructure>Record Interleaved</gml:fileStructure>\n"
"            </gml:File>\n"
"          </gml:rangeSet>\n"
"        </gml:RectifiedGridCoverage>\n"
"      </gml:featureMember>\n"
"    </gml:FeatureCollection>\n"
"  </gml:featureMember>\n"
"</gml:FeatureCollection>\n",
             nXSize-1, nYSize-1, szSRSName, adfOrigin[0], adfOrigin[1],
             szSRSName, adfXVector[0], adfXVector[1], 
             szSRSName, adfYVector[0], adfYVector[1] );

/* -------------------------------------------------------------------- */
/*      If we need a user defined CRSDictionary entry, prepare it       */
/*      here.                                                           */
/* -------------------------------------------------------------------- */
    CPLString osDictBox;

    if( nEPSGCode == 0 )
    {
        char *pszGMLDef = NULL;

        if( oSRS.exportToXML( &pszGMLDef, NULL ) == OGRERR_NONE )
        {
            osDictBox.Printf(  
"<gml:Dictionary gml:id=\"CRSU1\" \n"
"        xmlns:gml=\"http://www.opengis.net/gml\"\n"
"        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
"        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"
"  <gml:dictionaryEntry>\n"
"%s\n"
"  </gml:dictionaryEntry>\n"
"</gml:Dictionary>\n",
                     pszGMLDef );
        }
        CPLFree( pszGMLDef );
    }

/* -------------------------------------------------------------------- */
/*      Setup the gml.data label.                                       */
/* -------------------------------------------------------------------- */
    GDALJP2Box *apoGMLBoxes[5];
    int nGMLBoxes = 0;

    apoGMLBoxes[nGMLBoxes++] = GDALJP2Box::CreateLblBox( "gml.data" );

/* -------------------------------------------------------------------- */
/*      Setup gml.root-instance.                                        */
/* -------------------------------------------------------------------- */
    apoGMLBoxes[nGMLBoxes++] = 
        GDALJP2Box::CreateLabelledXMLAssoc( "gml.root-instance", osDoc );

/* -------------------------------------------------------------------- */
/*      Add optional dictionary.                                        */
/* -------------------------------------------------------------------- */
    if( strlen(osDictBox) > 0 )
        apoGMLBoxes[nGMLBoxes++] = 
            GDALJP2Box::CreateLabelledXMLAssoc( "CRSDictionary.gml",
                                                osDictBox );
        
/* -------------------------------------------------------------------- */
/*      Bundle gml.data boxes into an association.                      */
/* -------------------------------------------------------------------- */
    GDALJP2Box *poGMLData = GDALJP2Box::CreateAsocBox( nGMLBoxes, apoGMLBoxes);

/* -------------------------------------------------------------------- */
/*      Cleanup working boxes.                                          */
/* -------------------------------------------------------------------- */
    while( nGMLBoxes > 0 )
        delete apoGMLBoxes[--nGMLBoxes];

    return poGMLData;
}
Пример #9
0
void ROIPACDataset::FlushCache( void )
{
    RawDataset::FlushCache();

    GDALRasterBand *band = (GetRasterCount() > 0) ? GetRasterBand(1) : NULL;

    if ( eAccess == GA_ReadOnly || band == NULL )
        return;

    // If opening an existing file in Update mode (i.e. "r+") we need to make
    // sure any existing content is cleared, otherwise the file may contain
    // trailing content from the previous write.
    CPL_IGNORE_RET_VAL(VSIFTruncateL( fpRsc, 0 ));

    CPL_IGNORE_RET_VAL(VSIFSeekL( fpRsc, 0, SEEK_SET ));
/* -------------------------------------------------------------------- */
/*      Rewrite out the header.                                         */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/*      Raster dimensions.                                              */
/* -------------------------------------------------------------------- */
    CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %d\n", "WIDTH", nRasterXSize ));
    CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %d\n", "FILE_LENGTH", nRasterYSize ));

/* -------------------------------------------------------------------- */
/*      Georeferencing.                                                 */
/* -------------------------------------------------------------------- */
    if ( pszProjection != NULL )
    {
        char *pszProjectionTmp = pszProjection;
        OGRSpatialReference oSRS;
        if( oSRS.importFromWkt( &pszProjectionTmp ) == OGRERR_NONE )
        {
            int bNorth;
            int iUTMZone = oSRS.GetUTMZone( &bNorth );
            if ( iUTMZone != 0 )
            {
                CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s%d\n", "PROJECTION", "UTM", iUTMZone ));
            }
            else if ( oSRS.IsGeographic() )
            {
                CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "PROJECTION", "LL" ));
            }
            else
            {
                CPLError( CE_Warning, CPLE_AppDefined,
                          "ROI_PAC format only support Latitude/Longitude and "
                              "UTM projections, discarding projection.");
            }

            if ( oSRS.GetAttrValue( "DATUM" ) != NULL )
            {
                if ( strcmp( oSRS.GetAttrValue( "DATUM" ), "WGS_1984" ) == 0 )
                {
                    CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "DATUM", "WGS84" ));
                }
                else
                {
                    CPLError( CE_Warning, CPLE_AppDefined,
                              "Datum \"%s\" probably not supported in the "
                                  "ROI_PAC format, saving it anyway",
                                  oSRS.GetAttrValue( "DATUM" ) );
                    CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "DATUM", oSRS.GetAttrValue( "DATUM" ) ));
                }
            }
            if ( oSRS.GetAttrValue( "UNIT" ) != NULL )
            {
                CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "X_UNIT", oSRS.GetAttrValue( "UNIT" ) ));
                CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "Y_UNIT", oSRS.GetAttrValue( "UNIT" ) ));
            }
        }
    }
    if( bValidGeoTransform )
    {
        if ( adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0 )
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "ROI_PAC format do not support geotransform with "
                          "rotation, discarding info.");
        }
        else
        {
            CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "X_FIRST", adfGeoTransform[0] ));
            CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "X_STEP", adfGeoTransform[1] ));
            CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Y_FIRST", adfGeoTransform[3] ));
            CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Y_STEP", adfGeoTransform[5] ));
            CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Z_OFFSET", band->GetOffset(NULL) ));
            CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Z_SCALE", band->GetScale(NULL) ));
        }
    }

/* -------------------------------------------------------------------- */
/*      Metadata stored in the ROI_PAC domain.                          */
/* -------------------------------------------------------------------- */
    char** papszROIPACMetadata = GetMetadata( "ROI_PAC" );
    for (int i = 0; i < CSLCount( papszROIPACMetadata ); i++)
    {
        /* Get the tokens from the metadata item */
        char **papszTokens = CSLTokenizeString2( papszROIPACMetadata[i],
                                                 "=",
                                                 CSLT_STRIPLEADSPACES
                                                 | CSLT_STRIPENDSPACES);
        if ( CSLCount( papszTokens ) != 2 )
        {
            CPLDebug("ROI_PAC",
                     "Line of header file could not be split at = into two elements: %s",
                     papszROIPACMetadata[i]);
            CSLDestroy( papszTokens );
            continue;
        }

        /* Don't write it out if it is one of the bits of metadata that is
         * written out elsewhere in this routine */
        if ( strcmp( papszTokens[0], "WIDTH" ) == 0
              || strcmp( papszTokens[0], "FILE_LENGTH" ) == 0 )
        {
            CSLDestroy( papszTokens );
            continue;
        }
        CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", papszTokens[0], papszTokens[1] ));
        CSLDestroy( papszTokens );
    }
}
Пример #10
0
int OGRProj4CT::InitializeNoLock( OGRSpatialReference * poSourceIn,
                                  OGRSpatialReference * poTargetIn )

{
    if( poSourceIn == NULL || poTargetIn == NULL )
        return FALSE;

    poSRSSource = poSourceIn->Clone();
    poSRSTarget = poTargetIn->Clone();

    bSourceLatLong = CPL_TO_BOOL(poSRSSource->IsGeographic());
    bTargetLatLong = CPL_TO_BOOL(poSRSTarget->IsGeographic());

/* -------------------------------------------------------------------- */
/*      Setup source and target translations to radians for lat/long    */
/*      systems.                                                        */
/* -------------------------------------------------------------------- */
    dfSourceToRadians = DEG_TO_RAD;
    bSourceWrap = false;
    dfSourceWrapLong = 0.0;

    if( bSourceLatLong )
    {
        OGR_SRSNode *poUNITS = poSRSSource->GetAttrNode( "GEOGCS|UNIT" );
        if( poUNITS && poUNITS->GetChildCount() >= 2 )
        {
            dfSourceToRadians = CPLAtof(poUNITS->GetChild(1)->GetValue());
            if( dfSourceToRadians == 0.0 )
                dfSourceToRadians = DEG_TO_RAD;
        }
    }

    dfTargetFromRadians = RAD_TO_DEG;
    bTargetWrap = false;
    dfTargetWrapLong = 0.0;

    if( bTargetLatLong )
    {
        OGR_SRSNode *poUNITS = poSRSTarget->GetAttrNode( "GEOGCS|UNIT" );
        if( poUNITS && poUNITS->GetChildCount() >= 2 )
        {
            double dfTargetToRadians = CPLAtof(poUNITS->GetChild(1)->GetValue());
            if( dfTargetToRadians != 0.0 )
                dfTargetFromRadians = 1 / dfTargetToRadians;
        }
    }

/* -------------------------------------------------------------------- */
/*      Preliminary logic to setup wrapping.                            */
/* -------------------------------------------------------------------- */
    if( CPLGetConfigOption( "CENTER_LONG", NULL ) != NULL )
    {
        bSourceWrap = true;
        bTargetWrap = true;
        dfSourceWrapLong = dfTargetWrapLong =
            CPLAtof(CPLGetConfigOption( "CENTER_LONG", "" ));
        CPLDebug( "OGRCT", "Wrap at %g.", dfSourceWrapLong );
    }

    const char *pszCENTER_LONG =
        poSRSSource->GetExtension( "GEOGCS", "CENTER_LONG" );
    if( pszCENTER_LONG != NULL )
    {
        dfSourceWrapLong = CPLAtof(pszCENTER_LONG);
        bSourceWrap = true;
        CPLDebug( "OGRCT", "Wrap source at %g.", dfSourceWrapLong );
    }

    pszCENTER_LONG = poSRSTarget->GetExtension( "GEOGCS", "CENTER_LONG" );
    if( pszCENTER_LONG != NULL )
    {
        dfTargetWrapLong = CPLAtof(pszCENTER_LONG);
        bTargetWrap = true;
        CPLDebug( "OGRCT", "Wrap target at %g.", dfTargetWrapLong );
    }

    bCheckWithInvertProj =
        CPLTestBool(CPLGetConfigOption( "CHECK_WITH_INVERT_PROJ", "NO" ));

    // The threshold is experimental. Works well with the cases of ticket #2305.
    if( bSourceLatLong )
        dfThreshold = CPLAtof(CPLGetConfigOption( "THRESHOLD", ".1" ));
    else
        // 1 works well for most projections, except for +proj=aeqd that
        // requires a tolerance of 10000.
        dfThreshold = CPLAtof(CPLGetConfigOption( "THRESHOLD", "10000" ));

    // OGRThreadSafety: The following variable is not a thread safety issue
    // since the only issue is incrementing while accessing which at worse
    // means debug output could be one "increment" late.
    static int   nDebugReportCount = 0;

    char        *pszSrcProj4Defn = NULL;

    if( poSRSSource->exportToProj4( &pszSrcProj4Defn ) != OGRERR_NONE )
    {
        CPLFree( pszSrcProj4Defn );
        return FALSE;
    }

    if( strlen(pszSrcProj4Defn) == 0 )
    {
        CPLFree( pszSrcProj4Defn );
        CPLError( CE_Failure, CPLE_AppDefined,
                  "No PROJ.4 translation for source SRS, coordinate\n"
                  "transformation initialization has failed." );
        return FALSE;
    }

    char        *pszDstProj4Defn = NULL;

    if( poSRSTarget->exportToProj4( &pszDstProj4Defn ) != OGRERR_NONE )
    {
        CPLFree( pszSrcProj4Defn );
        CPLFree( pszDstProj4Defn );
        return FALSE;
    }

    if( strlen(pszDstProj4Defn) == 0 )
    {
        CPLFree( pszSrcProj4Defn );
        CPLFree( pszDstProj4Defn );
        CPLError( CE_Failure, CPLE_AppDefined,
                  "No PROJ.4 translation for destination SRS, coordinate\n"
                  "transformation initialization has failed." );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Optimization to avoid useless nadgrids evaluation.              */
/*      For example when converting between WGS84 and WebMercator       */
/* -------------------------------------------------------------------- */
    if( pszSrcProj4Defn[strlen(pszSrcProj4Defn)-1] == ' ' )
        pszSrcProj4Defn[strlen(pszSrcProj4Defn)-1] = 0;
    if( pszDstProj4Defn[strlen(pszDstProj4Defn)-1] == ' ' )
        pszDstProj4Defn[strlen(pszDstProj4Defn)-1] = 0;
    char* pszNeedle = strstr(pszSrcProj4Defn, "  ");
    if( pszNeedle )
        memmove(pszNeedle, pszNeedle + 1, strlen(pszNeedle + 1)+1);
    pszNeedle = strstr(pszDstProj4Defn, "  ");
    if( pszNeedle )
        memmove(pszNeedle, pszNeedle + 1, strlen(pszNeedle + 1)+1);

    if( (strstr(pszSrcProj4Defn, "+datum=WGS84") != NULL ||
         strstr(pszSrcProj4Defn, "+ellps=WGS84 +towgs84=0,0,0,0,0,0,0 ") != NULL) &&
        strstr(pszDstProj4Defn, "+nadgrids=@null ") != NULL &&
        strstr(pszDstProj4Defn, "+towgs84") == NULL )
    {
        char* pszDst = strstr(pszSrcProj4Defn, "+towgs84=0,0,0,0,0,0,0 ");
        if( pszDst != NULL )
        {
            char *pszSrc = pszDst + strlen("+towgs84=0,0,0,0,0,0,0 ");
            memmove(pszDst, pszSrc, strlen(pszSrc)+1);
        }
        else
        {
            memcpy(strstr(pszSrcProj4Defn, "+datum=WGS84"), "+ellps", 6);
        }

        pszDst = strstr(pszDstProj4Defn, "+nadgrids=@null ");
        char *pszSrc = pszDst + strlen("+nadgrids=@null ");
        memmove(pszDst, pszSrc, strlen(pszSrc)+1);

        pszDst = strstr(pszDstProj4Defn, "+wktext ");
        if( pszDst )
        {
            pszSrc = pszDst + strlen("+wktext ");
            memmove(pszDst, pszSrc, strlen(pszSrc)+1);
        }

        //bWGS84ToWebMercator =
        //    strcmp(pszSrcProj4Defn, "+proj=longlat +ellps=WGS84 +no_defs") == 0 &&
        //    strcmp(pszDstProj4Defn, "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +no_defs") == 0;
    }
    else
    if( (strstr(pszDstProj4Defn, "+datum=WGS84") != NULL ||
         strstr(pszDstProj4Defn, "+ellps=WGS84 +towgs84=0,0,0,0,0,0,0 ") != NULL) &&
        strstr(pszSrcProj4Defn, "+nadgrids=@null ") != NULL &&
        strstr(pszSrcProj4Defn, "+towgs84") == NULL )
    {
        char* pszDst = strstr(pszDstProj4Defn, "+towgs84=0,0,0,0,0,0,0 ");
        if( pszDst != NULL)
        {
            char* pszSrc = pszDst + strlen("+towgs84=0,0,0,0,0,0,0 ");
            memmove(pszDst, pszSrc, strlen(pszSrc)+1);
        }
        else
            memcpy(strstr(pszDstProj4Defn, "+datum=WGS84"), "+ellps", 6);

        pszDst = strstr(pszSrcProj4Defn, "+nadgrids=@null ");
        char* pszSrc = pszDst + strlen("+nadgrids=@null ");
        memmove(pszDst, pszSrc, strlen(pszSrc)+1);

        pszDst = strstr(pszSrcProj4Defn, "+wktext ");
        if( pszDst )
        {
            pszSrc = pszDst + strlen("+wktext ");
            memmove(pszDst, pszSrc, strlen(pszSrc)+1);
        }
        bWebMercatorToWGS84 =
            strcmp(pszDstProj4Defn,
                   "+proj=longlat +ellps=WGS84 +no_defs") == 0 &&
            strcmp(pszSrcProj4Defn,
                   "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 "
                   "+x_0=0.0 +y_0=0 +k=1.0 +units=m +no_defs") == 0;
    }

/* -------------------------------------------------------------------- */
/*      Establish PROJ.4 handle for source if projection.               */
/* -------------------------------------------------------------------- */
    if( !bWebMercatorToWGS84 )
    {
        if (pjctx)
            psPJSource = pfn_pj_init_plus_ctx( pjctx, pszSrcProj4Defn );
        else
            psPJSource = pfn_pj_init_plus( pszSrcProj4Defn );

        if( psPJSource == NULL )
        {
            if( pjctx != NULL)
            {
                int l_pj_errno = pfn_pj_ctx_get_errno(pjctx);

                /* pfn_pj_strerrno not yet thread-safe in PROJ 4.8.0 */
                CPLMutexHolderD(&hPROJMutex);
                CPLError( CE_Failure, CPLE_NotSupported,
                        "Failed to initialize PROJ.4 with `%s'.\n%s",
                        pszSrcProj4Defn, pfn_pj_strerrno(l_pj_errno) );
            }
            else if( pfn_pj_get_errno_ref != NULL
                && pfn_pj_strerrno != NULL )
            {
                int *p_pj_errno = pfn_pj_get_errno_ref();

                CPLError( CE_Failure, CPLE_NotSupported,
                        "Failed to initialize PROJ.4 with `%s'.\n%s",
                        pszSrcProj4Defn, pfn_pj_strerrno(*p_pj_errno) );
            }
            else
            {
                CPLError( CE_Failure, CPLE_NotSupported,
                        "Failed to initialize PROJ.4 with `%s'.\n",
                        pszSrcProj4Defn );
            }
        }
    }

    if( nDebugReportCount < 10 )
        CPLDebug( "OGRCT", "Source: %s", pszSrcProj4Defn );

    if( !bWebMercatorToWGS84 && psPJSource == NULL )
    {
        CPLFree( pszSrcProj4Defn );
        CPLFree( pszDstProj4Defn );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Establish PROJ.4 handle for target if projection.               */
/* -------------------------------------------------------------------- */
    if( !bWebMercatorToWGS84 )
    {
        if (pjctx)
            psPJTarget = pfn_pj_init_plus_ctx( pjctx, pszDstProj4Defn );
        else
            psPJTarget = pfn_pj_init_plus( pszDstProj4Defn );

        if( psPJTarget == NULL )
            CPLError( CE_Failure, CPLE_NotSupported,
                    "Failed to initialize PROJ.4 with `%s'.",
                    pszDstProj4Defn );
    }
    if( nDebugReportCount < 10 )
    {
        CPLDebug( "OGRCT", "Target: %s", pszDstProj4Defn );
        nDebugReportCount++;
    }

    if( !bWebMercatorToWGS84 && psPJTarget == NULL )
    {
        CPLFree( pszSrcProj4Defn );
        CPLFree( pszDstProj4Defn );
        return FALSE;
    }

    /* Determine if we really have a transformation to do */
    bIdentityTransform = strcmp(pszSrcProj4Defn, pszDstProj4Defn) == 0;

#if 0
    /* In case of identity transform, under the following conditions, */
    /* we can also avoid transforming from degrees <--> radians. */
    if( bIdentityTransform && bSourceLatLong && !bSourceWrap &&
        bTargetLatLong && !bTargetWrap &&
        fabs(dfSourceToRadians * dfTargetFromRadians - 1.0) < 1e-10 )
    {
        // bSourceLatLong = false;
        // bTargetLatLong = false;
    }
#endif

    CPLFree( pszSrcProj4Defn );
    CPLFree( pszDstProj4Defn );

    return TRUE;
}
Пример #11
0
CPLErr IDADataset::SetProjection( const char *pszWKTIn )

{
    OGRSpatialReference oSRS;

    oSRS.importFromWkt( (char **) &pszWKTIn );

    if( !oSRS.IsGeographic() && !oSRS.IsProjected() )
        GDALPamDataset::SetProjection( pszWKTIn );

/* -------------------------------------------------------------------- */
/*      Clear projection parameters.                                    */
/* -------------------------------------------------------------------- */
    dfParallel1 = 0.0;
    dfParallel2 = 0.0;
    dfLatCenter = 0.0;
    dfLongCenter = 0.0;

/* -------------------------------------------------------------------- */
/*      Geographic.                                                     */
/* -------------------------------------------------------------------- */
    if( oSRS.IsGeographic() )
    {
        // If no change, just return. 
        if( nProjection == 3 )
            return CE_None;

        nProjection = 3;
    }

/* -------------------------------------------------------------------- */
/*      Verify we don't have a false easting or northing as these       */
/*      will be ignored for the projections we do support.              */
/* -------------------------------------------------------------------- */
    if( oSRS.GetProjParm( SRS_PP_FALSE_EASTING ) != 0.0
        || oSRS.GetProjParm( SRS_PP_FALSE_NORTHING ) != 0.0 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Attempt to set a projection on an IDA file with a non-zero\n"
                  "false easting and/or northing.  This is not supported." );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Lambert Conformal Conic.  Note that we don't support false      */
/*      eastings or nothings.                                           */
/* -------------------------------------------------------------------- */
    const char *pszProjection = oSRS.GetAttrValue( "PROJECTION" );

    if( pszProjection == NULL )
    {
        /* do nothing - presumably geographic  */;
    }
    else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
    {
        nProjection = 4;
        dfParallel1 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
        dfParallel2 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
        dfLatCenter = oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
        dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    }
    else if( EQUAL(pszProjection,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
    {
        nProjection = 6;
        dfLatCenter = oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
        dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    }
    else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
    {
        nProjection = 8;
        dfParallel1 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
        dfParallel2 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
        dfLatCenter = oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
        dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    }
    else if( EQUAL(pszProjection,SRS_PT_GOODE_HOMOLOSINE) )
    {
        nProjection = 9;
        dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    }
    else
    {
        return GDALPamDataset::SetProjection( pszWKTIn );
    }

/* -------------------------------------------------------------------- */
/*      Update header and mark it as dirty.                             */
/* -------------------------------------------------------------------- */
    bHeaderDirty = TRUE;

    abyHeader[23] = (GByte) nProjection;
    c2tp( dfLatCenter, abyHeader + 120 );
    c2tp( dfLongCenter, abyHeader + 126 );
    c2tp( dfParallel1, abyHeader + 156 );
    c2tp( dfParallel2, abyHeader + 162 );

    return CE_None;
}
Пример #12
0
bool DemReader::SetupProjection(GDALDataset* gdalDataset, StudyControllerPtr studyController, double* adfGeoTransform, uint nCols, uint nRows, bool bElevationMap)
{
	// getting the string about projection system for this dataset.
	const char* currentWkt = gdalDataset->GetProjectionRef();

	OGRSpatialReference oSource;
	if((currentWkt != NULL && oSource.importFromWkt( (char**)&currentWkt ) != OGRERR_CORRUPT_DATA)) 
	{
		if(oSource.IsGeographic())
		{
			// lat/lon coordinates are using the geographic projection (aka, plate carrée) 
			if(!App::Inst().GetLayerTreeController()->GetIsBlankRaster())
				Log::Inst().Write("Loading map with lat/long coordinates.");

			studyController->SetProjectData(true);
			studyController->SetGeographic(true);
			studyController->SetUsingProjection(true);
			studyController->SetUsingGeographic(true);

			// determine centre of map
			double longStart = adfGeoTransform[0];
			double longEnd = adfGeoTransform[0] + nCols*adfGeoTransform[1];
			studyController->SetCentreLongitude(float(longStart + fabs(longStart - longEnd) / 2.0));

			double latStart = adfGeoTransform[3] + nRows*adfGeoTransform[5];
			double latEnd = adfGeoTransform[3];
			studyController->SetCentreLatitude(float(latStart + fabs(latStart - latEnd) / 2.0));

			studyController->SetFirstStandardParallel(latStart);
			studyController->SetSecondStandardParallel(latEnd);

			studyController->CalculateProjectionTool(&oSource);
		}
		else if(oSource.IsProjected())
		{
			studyController->SetProjectData(true);
			studyController->SetGeographic(false);
			studyController->SetUsingProjection(true);
			studyController->SetUsingGeographic(false);
			if (!App::Inst().GetLayerTreeController()->GetIsBlankRaster())
				Log::Inst().Write("Loading map with projected coordinates.");
			studyController->CalculateProjectionTool(&oSource);
		}
		else
		{
			// The user should probably be made aware of this warning.
			Log::Inst().Warning("(Warning) Unknown type of coordinate system.");
			return false;
		}
	}
	else 
	{
		studyController->SetProjectData(false);
		studyController->SetGeographic(false);
		studyController->SetUsingProjection(false);
		studyController->SetUsingGeographic(false);

		if(bElevationMap)
		{
			// The user should probably be made aware of this warning.
			Log::Inst().Warning("(Warning) Well-Known text which specified coordinate system information is missing or not recognized."); 
			Log::Inst().Warning("(Warning) The projection information for this study is being ignored.");
			Log::Inst().Warning("(Warning) Location sites and leaf nodes must be specified in the same coordinate system as this map.");
			Log::Inst().Warning("");
		}
		else
		{
			// Right now we assume that any 3-channel map (i.e., non-elevational) should be projected using the 
			// the geographic projection (aka, plate carrée)
			studyController->SetUsingProjection(false);
			studyController->SetUsingGeographic(true);
			Log::Inst().Write("Coordinate system information is not available for this map.");
			Log::Inst().Write("As a result, the projection information for this study is being ignored.");
			Log::Inst().Write("");
		}
	}

	return true;
}