GDAL: la image de deformación en el sistema de coorderadas del eje y invertido (Apple MapKit) da la image al revés

Tengo una image de un map que quiero referencer y superponer en el map incorporado en iOS. Estoy usando GDAL mediante progtwigción.

Paso 1 (Aceptar) – Referencia geográfica (funciona bien)

Actualmente estoy calculando un GeoTransform (los 6 coeficientes) de tres puntos de control de tierra para hacer una reference geográfica de la image y me da los 6 coeficientes correctos.

Paso 2 (PROBLEMA) – Imagen de distorsión + obtenga GeoTransform para una nueva image transformada

¡La image se vuelve al revés! Esto se debe a que el sistema de coorderadas del objective (el sistema de coorderadas propio de Apple en MapKit) ha invertido el eje y que aumenta a medida que avanza hacia el sur.

Pregunta

¿Cómo puedo hacer que GDAL deforme la image correctamente (y al mismo time me dé una GeoTransform correcta para ir con ella)?

Lo que he probado

Cambié el valor 5/6 en el GeoTransform original antes de deformar. Esto da una urdimbre correcta de la image, pero el nuevo GeoTransform está mal.

CÓDIGO ACTUAL

- (WarpResultC*)warpImageWithGeoTransform:(NSArray<NSNumber*>*)geoTransformArray sourceFile:(NSString*)inFilepath destinationFile:(NSString*)outFilepath { GDALAllRegister(); GDALDriverH hDriver; GDALDataType eDT; GDALDatasetH hDstDS; GDALDatasetH hSrcDS; // Open the source file. hSrcDS = GDALOpen( inFilepath.UTF8String, GA_ReadOnly ); CPLAssert( hSrcDS != NULL ); // Set the GeoTransform on the source image // HERE IS WHERE I NEED NEGATIVE VALUES OF 4 & 5 TO GET A PROPER IMAGE double geoTransform[] = { geoTransformArray[0].doubleValue, geoTransformArray[1].doubleValue, geoTransformArray[2].doubleValue, geoTransformArray[3].doubleValue, -geoTransformArray[4].doubleValue, -geoTransformArray[5].doubleValue }; GDALSetGeoTransform(hSrcDS, geoTransform); // Create output with same datatype as first input band. eDT = GDALGetRasterDataType(GDALGetRasterBand(hSrcDS, 1)); // Get output driver (GeoTIFF format) hDriver = GDALGetDriverByName( "GTiff" ); CPLAssert( hDriver != NULL ); // Create a transformer that maps from source pixel/line coordinates // to destination georeferenced coordinates (not destination // pixel line). We do that by omitting the destination dataset // handle (setting it to NULL). void *hTransformArg = GDALCreateGenImgProjTransformer( hSrcDS, NULL, NULL, NULL, FALSE, 0, 1 ); CPLAssert( hTransformArg != NULL ); // Get approximate output georeferenced bounds and resolution for file. double adfDstGeoTransform[6]; int nPixels=0, nLines=0; CPLErr eErr = GDALSuggestedWarpOutput( hSrcDS, GDALGenImgProjTransform, hTransformArg, adfDstGeoTransform, &nPixels, &nLines ); CPLAssert( eErr == CE_None ); GDALDestroyGenImgProjTransformer( hTransformArg ); // Create the output file. hDstDS = GDALCreate( hDriver, outFilepath.UTF8String, nPixels, nLines, 4, eDT, NULL ); CPLAssert( hDstDS != NULL ); // Write out the projection definition. GDALSetGeoTransform( hDstDS, adfDstGeoTransform ); // Copy the color table, if requinetworking. GDALColorTableH hCT = GDALGetRasterColorTable( GDALGetRasterBand(hSrcDS, 1) ); if( hCT != NULL ) GDALSetRasterColorTable( GDALGetRasterBand(hDstDS, 1), hCT ); // Setup warp options. GDALWarpOptions *psWarpOptions = GDALCreateWarpOptions(); psWarpOptions->hSrcDS = hSrcDS; psWarpOptions->hDstDS = hDstDS; /* -------------------------------------------------------------------- */ /* Do we have a source alpha band? */ /* -------------------------------------------------------------------- */ bool enableSrcAlpha = GDALGetRasterColorInterpretation( GDALGetRasterBand(hSrcDS, GDALGetRasterCount(hSrcDS) )) == GCI_AlphaBand; if(enableSrcAlpha) { printf( "Using band %d of source image as alpha.\n", GDALGetRasterCount(hSrcDS) ); } /* -------------------------------------------------------------------- */ /* Setup band mapping. */ /* -------------------------------------------------------------------- */ if(enableSrcAlpha) psWarpOptions->nBandCount = GDALGetRasterCount(hSrcDS) - 1; else psWarpOptions->nBandCount = GDALGetRasterCount(hSrcDS); psWarpOptions->panSrcBands = (int *) CPLMalloc(psWarpOptions->nBandCount*sizeof(int)); psWarpOptions->panDstBands = (int *) CPLMalloc(psWarpOptions->nBandCount*sizeof(int)); for( int i = 0; i < psWarpOptions->nBandCount; i++ ) { psWarpOptions->panSrcBands[i] = i+1; psWarpOptions->panDstBands[i] = i+1; } /* -------------------------------------------------------------------- */ /* Setup alpha bands used if any. */ /* -------------------------------------------------------------------- */ if( enableSrcAlpha ) psWarpOptions->nSrcAlphaBand = GDALGetRasterCount(hSrcDS); psWarpOptions->nDstAlphaBand = GDALGetRasterCount(hDstDS); psWarpOptions->pfnProgress = GDALTermProgress; // Establish reprojection transformer. psWarpOptions->pTransformerArg = GDALCreateGenImgProjTransformer( hSrcDS, NULL, hDstDS, NULL, FALSE, 0.0, 1 ); psWarpOptions->pfnTransformer = GDALGenImgProjTransform; // Initialize and execute the warp operation. GDALWarpOperation oOperation; oOperation.Initialize( psWarpOptions ); CPLErr warpError = oOperation.ChunkAndWarpImage( 0, 0, GDALGetRasterXSize( hDstDS ), GDALGetRasterYSize( hDstDS ) ); CPLAssert( warpError == CE_None ); GDALDestroyGenImgProjTransformer( psWarpOptions->pTransformerArg ); GDALDestroyWarpOptions( psWarpOptions ); GDALClose( hDstDS ); GDALClose( hSrcDS ); WarpResultC* warpResultC = [WarpResultC new]; warpResultC.geoTransformValues = @[@(adfDstGeoTransform[0]), @(adfDstGeoTransform[1]), @(adfDstGeoTransform[2]), @(adfDstGeoTransform[3]), @(adfDstGeoTransform[4]), @(adfDstGeoTransform[5])]; warpResultC.newX = nPixels; warpResultC.newY = nLines; return warpResultC; } 

Para ello, usa GDALCreateGenImgProjTransformer . De la documentation: cree un transformador que se asigne desde las coorderadas de píxel / línea de origen a las coorderadas georeferencedas de destino (no la línea de píxel de destino). Hacemos eso omitiendo el identificador de set de datos de destino (configurándolo a NULL).

Otra información relacionada para su tarea de gdal_alg.h : Crear image a transformador de image.

Esta function crea un object de transformación que se asigna desde coorderadas de píxel / línea en una image a coorderadas de píxel / línea en otra image. Las imágenes pueden georeferencerse potencialmente en diferentes sistemas de coorderadas, y pueden usar GCP para mapear entre sus coorderadas de píxel / línea y coorderadas georeferencedas (en contraposition a la suposition por defecto de que se debe usar su geotransformación).

Este transformador potencialmente realiza tres transformaciones concatenadas.

La primera etapa es desde coorderadas de línea / píxel de image de origen hasta coorderadas georeferencedas de image de origen, y puede hacerse utilizando la geotransformación, o si no se define utilizando un model polinómico derivado de GCP. Si se utilizan GCP, esta etapa se logra usando GDALGCPTransform ().

La segunda etapa es cambiar las proyecciones desde el sistema de coorderadas de origen al sistema de coorderadas de destino, suponiendo que difieren. Esto se logra internamente usando GDALReprojectionTransform ().

La tercera etapa está convirtiendo las coorderadas georeferencedas de la image de destino en coorderadas de la image de destino. Esto se hace usando la geotransformación de la image de destino, o si no está disponible, utilizando un model polinómico derivado de GCP. Si se utilizan GCP, esta etapa se logra usando GDALGCPTransform (). Esta etapa se omite si hDstDS es NULL cuando se crea la transformación.

    Intereting Posts