1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: GDAL
5 : * Purpose: Algorithm to apply a transformer to geolocation style bands.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2012, Frank Warmerdam
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "gdal_alg_priv.h"
31 : #include "gdal_priv.h"
32 : #include "cpl_conv.h"
33 :
34 : CPL_CVSID("$Id$");
35 :
36 :
37 :
38 : /************************************************************************/
39 : /* GDALTransformGeolocations() */
40 : /************************************************************************/
41 :
42 : /**
43 : * Transform locations held in bands.
44 : *
45 : * The X/Y and possibly Z values in the identified bands are transformed
46 : * using a spatial transformer. The changes values are written back to the
47 : * source bands so they need to updatable.
48 : *
49 : * @param hXBand the band containing the X locations (usually long/easting).
50 : * @param hYBand the band containing the Y locations (usually lat/northing).
51 : * @param hZBand the band containing the Z locations (may be NULL).
52 : * @param pfnTransformer the transformer function.
53 : * @param pTransformArg the callback data for the transformer function.
54 : * @param pfnProgress callback for reporting algorithm progress matching the
55 : * GDALProgressFunc() semantics. May be NULL.
56 : * @param pProgressArg callback argument passed to pfnProgress.
57 : * @param papszOptions list of name/value options - none currently supported.
58 : *
59 : * @return CE_None on success or CE_Failure if an error occurs.
60 : */
61 :
62 : CPLErr
63 1 : GDALTransformGeolocations( GDALRasterBandH hXBand,
64 : GDALRasterBandH hYBand,
65 : GDALRasterBandH hZBand,
66 : GDALTransformerFunc pfnTransformer,
67 : void *pTransformArg,
68 : GDALProgressFunc pfnProgress,
69 : void *pProgressArg,
70 : char **papszOptions )
71 :
72 : {
73 1 : VALIDATE_POINTER1( hXBand, "GDALTransformGeolocations", CE_Failure );
74 1 : VALIDATE_POINTER1( hYBand, "GDALTransformGeolocations", CE_Failure );
75 :
76 1 : if( pfnProgress == NULL )
77 1 : pfnProgress = GDALDummyProgress;
78 :
79 : /* -------------------------------------------------------------------- */
80 : /* Ensure the bands are matching in size. */
81 : /* -------------------------------------------------------------------- */
82 1 : GDALRasterBand *poXBand = (GDALRasterBand *) hXBand;
83 1 : GDALRasterBand *poYBand = (GDALRasterBand *) hYBand;
84 1 : GDALRasterBand *poZBand = (GDALRasterBand *) hZBand;
85 1 : int nXSize = poXBand->GetXSize();
86 1 : int nYSize = poXBand->GetYSize();
87 :
88 1 : if( nXSize != poYBand->GetXSize()
89 : || nYSize != poYBand->GetYSize()
90 : || (poZBand != NULL && nXSize != poZBand->GetXSize())
91 : || (poZBand != NULL && nYSize != poZBand->GetYSize()) )
92 : {
93 : CPLError( CE_Failure, CPLE_AppDefined,
94 0 : "Size of X, Y and/or Z bands do not match." );
95 0 : return CE_Failure;
96 : }
97 :
98 : /* -------------------------------------------------------------------- */
99 : /* Allocate a buffer large enough to hold one whole row. */
100 : /* -------------------------------------------------------------------- */
101 1 : double *padfX = (double*) CPLMalloc(sizeof(double) * nXSize);
102 1 : double *padfY = (double*) CPLMalloc(sizeof(double) * nXSize);
103 1 : double *padfZ = (double*) CPLMalloc(sizeof(double) * nXSize);
104 1 : int *panSuccess = (int*) CPLMalloc(sizeof(int) * nXSize);
105 : int iLine;
106 1 : CPLErr eErr = CE_None;
107 :
108 1 : pfnProgress( 0.0, "", pProgressArg );
109 3 : for( iLine = 0; eErr == CE_None && iLine < nYSize; iLine++ )
110 : {
111 : eErr = poXBand->RasterIO( GF_Read, 0, iLine, nXSize, 1,
112 2 : padfX, nXSize, 1, GDT_Float64, 0, 0 );
113 2 : if( eErr == CE_None )
114 : eErr = poYBand->RasterIO( GF_Read, 0, iLine, nXSize, 1,
115 2 : padfY, nXSize, 1, GDT_Float64, 0, 0 );
116 4 : if( eErr == CE_None && poZBand != NULL )
117 : eErr = poZBand->RasterIO( GF_Read, 0, iLine, nXSize, 1,
118 2 : padfZ, nXSize, 1, GDT_Float64, 0, 0 );
119 : else
120 0 : memset( padfZ, 0, sizeof(double) * nXSize);
121 :
122 2 : if( eErr == CE_None )
123 : {
124 : pfnTransformer( pTransformArg, FALSE, nXSize,
125 2 : padfX, padfY, padfZ, panSuccess );
126 : }
127 :
128 2 : if( eErr == CE_None )
129 : eErr = poXBand->RasterIO( GF_Write, 0, iLine, nXSize, 1,
130 2 : padfX, nXSize, 1, GDT_Float64, 0, 0 );
131 2 : if( eErr == CE_None )
132 : eErr = poYBand->RasterIO( GF_Write, 0, iLine, nXSize, 1,
133 2 : padfY, nXSize, 1, GDT_Float64, 0, 0 );
134 2 : if( eErr == CE_None && poZBand != NULL )
135 : eErr = poZBand->RasterIO( GF_Write, 0, iLine, nXSize, 1,
136 2 : padfZ, nXSize, 1, GDT_Float64, 0, 0 );
137 :
138 2 : if( eErr == CE_None )
139 2 : pfnProgress( (iLine+1) / (double) nYSize, "", pProgressArg );
140 : }
141 :
142 : /* -------------------------------------------------------------------- */
143 : /* Cleanup */
144 : /* -------------------------------------------------------------------- */
145 1 : CPLFree( padfX );
146 1 : CPLFree( padfY );
147 1 : CPLFree( padfZ );
148 1 : CPLFree( panSuccess );
149 :
150 1 : return eErr;
151 : }
|