|
| 1 | +float calcFirstDer( float x11, float x21, float x31, float x12, float x22, float x32, float x13, float x23, float x33, |
| 2 | + float mInputNodataValue, float mOutputNodataValue, float mZFactor, float mCellSize ) |
| 3 | +{ |
| 4 | + //the basic formula would be simple, but we need to test for nodata values... |
| 5 | + //X: return (( (x31 - x11) + 2 * (x32 - x12) + (x33 - x13) ) / (8 * mCellSizeX)); |
| 6 | + //Y: return (((x11 - x13) + 2 * (x21 - x23) + (x31 - x33)) / ( 8 * mCellSizeY)); |
| 7 | + |
| 8 | + int weight = 0; |
| 9 | + float sum = 0; |
| 10 | + |
| 11 | + |
| 12 | + //first row |
| 13 | + if ( x31 != mInputNodataValue && x11 != mInputNodataValue ) //the normal case |
| 14 | + { |
| 15 | + sum += ( x31 - x11 ); |
| 16 | + weight += 2; |
| 17 | + } |
| 18 | + else if ( x31 == mInputNodataValue && x11 != mInputNodataValue && x21 != mInputNodataValue ) //probably 3x3 window is at the border |
| 19 | + { |
| 20 | + sum += ( x21 - x11 ); |
| 21 | + weight += 1; |
| 22 | + } |
| 23 | + else if ( x11 == mInputNodataValue && x31 != mInputNodataValue && x21 != mInputNodataValue ) //probably 3x3 window is at the border |
| 24 | + { |
| 25 | + sum += ( x31 - x21 ); |
| 26 | + weight += 1; |
| 27 | + } |
| 28 | + |
| 29 | + //second row |
| 30 | + if ( x32 != mInputNodataValue && x12 != mInputNodataValue ) //the normal case |
| 31 | + { |
| 32 | + sum += 2.0f * ( x32 - x12 ); |
| 33 | + weight += 4; |
| 34 | + } |
| 35 | + else if ( x32 == mInputNodataValue && x12 != mInputNodataValue && x22 != mInputNodataValue ) |
| 36 | + { |
| 37 | + sum += 2.0f * ( x22 - x12 ); |
| 38 | + weight += 2; |
| 39 | + } |
| 40 | + else if ( x12 == mInputNodataValue && x32 != mInputNodataValue && x22 != mInputNodataValue ) |
| 41 | + { |
| 42 | + sum += 2.0f * ( x32 - x22 ); |
| 43 | + weight += 2; |
| 44 | + } |
| 45 | + |
| 46 | + //third row |
| 47 | + if ( x33 != mInputNodataValue && x13 != mInputNodataValue ) //the normal case |
| 48 | + { |
| 49 | + sum += ( x33 - x13 ); |
| 50 | + weight += 2; |
| 51 | + } |
| 52 | + else if ( x33 == mInputNodataValue && x13 != mInputNodataValue && x23 != mInputNodataValue ) |
| 53 | + { |
| 54 | + sum += ( x23 - x13 ); |
| 55 | + weight += 1; |
| 56 | + } |
| 57 | + else if ( x13 == mInputNodataValue && x33 != mInputNodataValue && x23 != mInputNodataValue ) |
| 58 | + { |
| 59 | + sum += ( x33 - x23 ); |
| 60 | + weight += 1; |
| 61 | + } |
| 62 | + |
| 63 | + if ( weight == 0 ) |
| 64 | + { |
| 65 | + return mOutputNodataValue; |
| 66 | + } |
| 67 | + |
| 68 | + return sum / ( weight * mCellSize ) * mZFactor; |
| 69 | +} |
| 70 | + |
| 71 | + |
| 72 | +__kernel void processNineCellWindow( __global float *scanLine1, |
| 73 | + __global float *scanLine2, |
| 74 | + __global float *scanLine3, |
| 75 | + __global float *resultLine, |
| 76 | + __global float *rasterParams |
| 77 | + ) { |
| 78 | + |
| 79 | + // Get the index of the current element |
| 80 | + const int i = get_global_id(0); |
| 81 | + |
| 82 | + // Do the operation |
| 83 | + //return (( (x31 - x11) + 2 * (x32 - x12) + (x33 - x13) ) / (8 * mCellSizeX)) |
| 84 | + float derX = calcFirstDer( scanLine1[i], scanLine2[i], scanLine3[i], |
| 85 | + scanLine1[i+1], scanLine2[i+1], scanLine3[i+1], |
| 86 | + scanLine1[i+2], scanLine2[i+2], scanLine3[i+2], |
| 87 | + rasterParams[0], rasterParams[1], rasterParams[2], rasterParams[3] |
| 88 | + ); |
| 89 | + //return (((x11 - x13) + 2 * (x21 - x23) + (x31 - x33)) / ( 8 * mCellSizeY)); |
| 90 | + float derY = calcFirstDer( scanLine1[i+2], scanLine1[i+1], scanLine1[i], |
| 91 | + scanLine2[i+2], scanLine2[i+1], scanLine2[i], |
| 92 | + scanLine3[i+2], scanLine3[i+1], scanLine3[i], |
| 93 | + rasterParams[0], rasterParams[1], rasterParams[2], rasterParams[4] |
| 94 | + ); |
| 95 | + |
| 96 | + |
| 97 | + if ( derX == rasterParams[1] || derY == rasterParams[1] || |
| 98 | + ( derX == 0.0f && derY == 0.0f) ) |
| 99 | + { |
| 100 | + resultLine[i] = rasterParams[1]; |
| 101 | + } |
| 102 | + else |
| 103 | + { |
| 104 | + // 180.0 / M_PI = 57.29577951308232 |
| 105 | + float aspect = atan2( derX, derY ) * 57.29577951308232; |
| 106 | + if ( aspect < 0 ) |
| 107 | + resultLine[i] = 90.0f - aspect; |
| 108 | + else if (aspect > 90.0f) |
| 109 | + // 360 + 90 = 450 |
| 110 | + resultLine[i] = 450.0f - aspect; |
| 111 | + else |
| 112 | + resultLine[i] = 90.0 - aspect; |
| 113 | + } |
| 114 | +} |
0 commit comments