1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: RP
6 //
7 // Description:
8 //
9 //
10 //*******************************************************************
11 // $Id$
12 #include <ossim/imaging/ossimElevRemapper.h>
13 #include <ossim/imaging/ossimImageGeometry.h>
14 #include <ossim/base/ossimGeoidManager.h>
15 #include <ossim/base/ossimTrace.h>
16
17 RTTI_DEF1(ossimElevRemapper, "ossimElevRemapper", ossimImageSourceFilter);
18 static ossimTrace traceDebug("ossimElevRemapper::debug");
19
20 const char ossimElevRemapper::REMAP_MODE_KW[] = "remap_mode";
21
22 using namespace std;
23
ossimElevRemapper()24 ossimElevRemapper::ossimElevRemapper()
25 :m_replacementType(ReplacementType_ELLIPSOID)
26 {
27 }
28
~ossimElevRemapper()29 ossimElevRemapper::~ossimElevRemapper()
30 {
31 m_imageGeometry = 0;
32 }
33
initialize()34 void ossimElevRemapper::initialize()
35 {
36 if (theInputConnection && (!m_imageGeometry.valid() || !m_imageGeometry->getProjection()))
37 {
38 m_imageGeometry = theInputConnection->getImageGeometry();
39 }
40 }
41
getTile(const ossimIrect & tile_rect,ossim_uint32 resLevel)42 ossimRefPtr<ossimImageData> ossimElevRemapper::getTile(const ossimIrect& tile_rect,
43 ossim_uint32 resLevel)
44 {
45 if (traceDebug())
46 {
47 ossimNotify(ossimNotifyLevel_DEBUG)
48 << "ossimElevRemapper::getTile entered..." << endl;
49 }
50
51 ossimRefPtr<ossimImageData> result = ossimImageSourceFilter::getTile(tile_rect, resLevel);
52 if(!isSourceEnabled()||!result.valid())
53 {
54 return result.get();
55 }
56 ossimDataObjectStatus status = result->getDataObjectStatus();
57
58 if(status == OSSIM_NULL)
59 {
60 return result.get();
61 }
62 // Call the appropriate load method.
63 switch (result->getScalarType())
64 {
65 case OSSIM_UCHAR:
66 {
67 elevRemap(ossim_uint8(0), result.get(), resLevel);
68 break;
69 }
70
71 case OSSIM_UINT16:
72 case OSSIM_USHORT11:
73 case OSSIM_USHORT12:
74 case OSSIM_USHORT13:
75 case OSSIM_USHORT14:
76 case OSSIM_USHORT15:
77 {
78 elevRemap(ossim_uint16(0), result.get(), resLevel);
79 break;
80 }
81
82 case OSSIM_SSHORT16:
83 {
84 elevRemap(ossim_sint16(0), result.get(), resLevel);
85 break;
86 }
87 case OSSIM_UINT32:
88 {
89 elevRemap(ossim_uint32(0), result.get(), resLevel);
90 break;
91 }
92 case OSSIM_SINT32:
93 {
94 elevRemap(ossim_sint32(0), result.get(), resLevel);
95 break;
96 }
97 case OSSIM_FLOAT32:
98 case OSSIM_NORMALIZED_FLOAT:
99 {
100 elevRemap(ossim_float32(0), result.get(), resLevel);
101 break; } case OSSIM_NORMALIZED_DOUBLE: case OSSIM_FLOAT64:
102 {
103 elevRemap(ossim_float64(0), result.get(), resLevel);
104 break;
105 }
106
107 case OSSIM_SCALAR_UNKNOWN:
108 default:
109 {
110 ossimNotify(ossimNotifyLevel_WARN)
111 << "ossimElevRemapper::getTile Unsupported scalar type!" << endl;
112 break;
113 }
114 }
115 if (traceDebug())
116 {
117 ossimNotify(ossimNotifyLevel_DEBUG)
118 << "ossimElevRemapper::getTile leaving..." << endl;
119 }
120
121 return result;
122 }
123
124 template <class T>
elevRemap(T,ossimImageData * inputTile,ossim_uint32 resLevel)125 void ossimElevRemapper::elevRemap(T /* dummy */,
126 ossimImageData* inputTile,
127 ossim_uint32 resLevel)
128 {
129 if (!inputTile) return;
130 ossimIrect rect = inputTile->getImageRectangle();
131 ossimIrect imageBounds = getBoundingRect(resLevel);
132 ossimIrect clipRect;
133 if(!rect.intersects(imageBounds))
134 {
135 return;
136 }
137 clipRect = rect.clipToRect(imageBounds);
138
139 if (m_imageGeometry.valid() && m_imageGeometry->getProjection())
140 {
141 ossimGpt ul, ll, lr, ur;
142 ossim_float32 hul, hll, hlr, hur;
143 ossim_float32 height = 0.0, xpercent, ypercent, uppery, lowery;
144
145 m_imageGeometry->rnToWorld(clipRect.ul(), resLevel, ul);
146 m_imageGeometry->rnToWorld(clipRect.ur(), resLevel, ur);
147 m_imageGeometry->rnToWorld(clipRect.ll(), resLevel, ll);
148 m_imageGeometry->rnToWorld(clipRect.lr(), resLevel, lr);
149
150 //std::cout << "UL: " << clipRect.ul() << " RES: " << ossimString::toString(resLevel) << " ULGROUND: " << ul << "\n";
151
152 hul = ossimGeoidManager::instance()->offsetFromEllipsoid(ul);
153 hll = ossimGeoidManager::instance()->offsetFromEllipsoid(ll);
154 hlr = ossimGeoidManager::instance()->offsetFromEllipsoid(lr);
155 hur = ossimGeoidManager::instance()->offsetFromEllipsoid(ur);
156
157 // std::cout << "HUL: " << ossimString::toString(hul) << " HUR: " << ossimString::toString(hur) << " HLR: " << ossimString::toString(hlr) << " HUR: " << ossimString::toString(hur) << "\n";
158
159 if(!rect.completely_within(imageBounds))
160 {
161 ossim_uint32 bands = inputTile->getNumberOfBands();
162 ossimIpt origin = clipRect.ul() - rect.ul();
163 ossim_uint32 bandIdx = 0;
164 ossim_uint32 inputW = inputTile->getWidth();
165 ossim_uint32 originOffset = origin.y*inputW + origin.x;
166 ossim_uint32 w = clipRect.width();
167 ossim_uint32 h = clipRect.height();
168 ossim_uint32 x = 0;
169 ossim_uint32 y = 0;
170 ossim_float32 height = 0.0, xpercent, ypercent, uppery, lowery;
171 for(bandIdx = 0; bandIdx < bands; ++bandIdx)
172 {
173 T* bandPtr = static_cast<T*>(inputTile->getBuf(bandIdx)) + originOffset;
174 for(y = 0; y < h; ++y)
175 {
176 for(x = 0; x < w; ++x)
177 {
178 xpercent = x / clipRect.width();
179 ypercent = y / clipRect.height();
180 uppery = hul + xpercent * ( hur - hul);
181 lowery = hll + xpercent * ( hlr - hll);
182 height = uppery + ypercent * ( lowery - uppery );
183 if (m_replacementType==ReplacementType_GEOID) height*=-1.0;
184
185 bandPtr[x] += height;
186 }
187 bandPtr += inputW;
188 }
189 }
190 }
191 else
192 {
193 ossim_uint32 bands = inputTile->getNumberOfBands();
194 ossim_uint32 bandIdx = 0;
195 ossim_uint32 size = inputTile->getWidth()*inputTile->getHeight();
196 ossim_float32 height = 0.0;
197 for(bandIdx = 0; bandIdx < bands; ++bandIdx)
198 {
199 T* bandPtr = static_cast<T*>(inputTile->getBuf(bandIdx));
200
201 ossim_uint32 idx = 0;
202 for(idx = 0; idx < size;++idx)
203 {
204 ossim_uint32 y = idx / rect.width();
205 ossim_uint32 x = idx % rect.width();
206 xpercent = x / clipRect.width();
207 ypercent = y / clipRect.height();
208 uppery = hul + xpercent * ( hur - hul);
209 lowery = hll + xpercent * ( hlr - hll);
210 height = uppery + ypercent * ( lowery - uppery );
211 if (m_replacementType==ReplacementType_GEOID) height*=-1.0;
212
213 (*bandPtr) += height;
214 ++bandPtr;
215 }
216 }
217 }
218 }
219 }
220
saveState(ossimKeywordlist & kwl,const char * prefix) const221 bool ossimElevRemapper::saveState(ossimKeywordlist& kwl,
222 const char* prefix)const
223 {
224 bool result = ossimImageSourceFilter::saveState(kwl, prefix);
225 ossimString remapMode = "";
226 switch(m_replacementType)
227 {
228 case ReplacementType_ELLIPSOID:
229 remapMode = "ellipsoid";
230 break;
231 case ReplacementType_GEOID:
232 remapMode = "geoid";
233 break;
234 default:
235 remapMode = "ellipsoid";
236 break;
237 }
238 kwl.add(prefix, REMAP_MODE_KW, remapMode.c_str());
239
240 ossimString imagePrefix = ossimString(prefix)+"image_geometry.";
241
242 if(m_imageGeometry.valid())
243 {
244 m_imageGeometry->saveState(kwl, imagePrefix.c_str());
245 }
246 //std::cout << kwl << " SAVESTATE\n";
247 return result;
248 }
249
loadState(const ossimKeywordlist & kwl,const char * prefix)250 bool ossimElevRemapper::loadState(const ossimKeywordlist& kwl,
251 const char* prefix)
252 {
253 //std::cout << kwl << " LOADSTATE\n";
254 if (traceDebug())
255 {
256 ossimNotify(ossimNotifyLevel_DEBUG)
257 << "ossimElevRemapper::loadState entered..." << endl;
258 }
259 bool result = ossimImageSourceFilter::loadState(kwl, prefix);
260
261 const char* lookup;
262 lookup = kwl.find(prefix, REMAP_MODE_KW);
263 if(lookup)
264 {
265 ossimString mode = lookup;
266 mode.upcase();
267 if (mode == "ELLIPSOID")
268 {
269 m_replacementType = ReplacementType_ELLIPSOID;
270 }
271 else if (mode == "GEOID")
272 {
273 m_replacementType = ReplacementType_GEOID;
274 }
275 }
276
277 ossimString imagePrefix = ossimString(prefix)+"image_geometry.";
278 if(kwl.numberOf(imagePrefix.c_str())>0)
279 {
280 m_imageGeometry = new ossimImageGeometry();
281 m_imageGeometry->loadState(kwl, imagePrefix.c_str());
282 //setImageGeometry(m_igeometry.get());
283 }
284
285 return result;
286 }
287