source: trunk/ossim_plugins/gdal/ossimGdalOgrVectorAnnotation.cpp

Last change on this file was 22897, checked in by dburken, 2 years ago

Removed replaced depricated OGRSFDriverRegistrar::Open with OGROpen(...) calls.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 77.7 KB
Line 
1//*******************************************************************
2// License:  See top level LICENSE.txt file.
3//
4// Author:  Garrett Potts
5//
6//*******************************************************************
7//  $Id: ossimGdalOgrVectorAnnotation.cpp 22897 2014-09-25 16:16:13Z dburken $
8
9#include <ossimGdalOgrVectorAnnotation.h>
10#include <ossimOgcWktTranslator.h>
11#include <ossimGdalType.h>
12#include <ossimOgcWktTranslator.h>
13#include <ossim/base/ossimTrace.h>
14#include <ossim/base/ossimPreferences.h>
15#include <ossim/base/ossimColorProperty.h>
16#include <ossim/base/ossimBooleanProperty.h>
17#include <ossim/base/ossimTextProperty.h>
18#include <ossim/base/ossimNumericProperty.h>
19#include <ossim/base/ossimNotify.h>
20#include <ossim/base/ossimIpt.h>
21#include <ossim/base/ossimDpt.h>
22#include <ossim/base/ossimGeoPolygon.h>
23#include <ossim/base/ossimFilename.h>
24#include <ossim/base/ossimKeywordlist.h>
25#include <ossim/base/ossimKeywordNames.h>
26#include <ossim/imaging/ossimImageData.h>
27#include <ossim/imaging/ossimAnnotationLineObject.h>
28#include <ossim/imaging/ossimAnnotationMultiLineObject.h>
29#include <ossim/imaging/ossimAnnotationPolyObject.h>
30#include <ossim/imaging/ossimGeoAnnotationPolyObject.h>
31#include <ossim/imaging/ossimGeoAnnotationPolyLineObject.h>
32#include <ossim/imaging/ossimGeoAnnotationEllipseObject.h>
33#include <ossim/imaging/ossimGeoAnnotationMultiEllipseObject.h>
34#include <ossim/imaging/ossimGeoAnnotationMultiPolyObject.h>
35#include <ossim/base/ossimPolyLine.h>
36#include <ossim/base/ossimCommon.h>
37#include <ossim/base/ossimErrorContext.h>
38#include <ossim/imaging/ossimRgbImage.h>
39#include <ossim/projection/ossimProjectionFactoryRegistry.h>
40#include <ossim/projection/ossimProjection.h>
41#include <ossim/projection/ossimEquDistCylProjection.h>
42#include <ossim/projection/ossimImageProjectionModel.h>
43#include <ossim/base/ossimUnitTypeLut.h>
44#include <ossim/base/ossimUnitConversionTool.h>
45#include <ossim/support_data/ossimFgdcXmlDoc.h>
46#include <ogr_api.h>
47#include <sstream>
48
49RTTI_DEF2(ossimGdalOgrVectorAnnotation,
50          "ossimGdalOgrVectorAnnotation",
51          ossimAnnotationSource,
52          ossimViewInterface);
53
54static ossimOgcWktTranslator wktTranslator;
55static ossimTrace traceDebug("ossimGdalOgrVectorAnnotation:debug");
56
57static const char SHAPEFILE_COLORS_AUTO_KW[] =
58   "shapefile_colors_auto";
59
60static const char NORMALIZED_RGB_BRUSH_COLOR_KW[] =
61   "shapefile_normalized_rgb_brush_color";
62
63static const char NORMALIZED_RGB_PEN_COLOR_KW[] =
64   "shapefile_normalized_rgb_pen_color";
65
66static const char POINT_SIZE_KW[] =
67   "shapefile_point_size";
68
69
70bool doubleLess(double first, double second, double epsilon, bool orequal = false) 
71{
72   if (fabs(first - second) < epsilon) 
73   {
74      return (orequal);
75   }
76   return (first < second);
77}
78
79bool doubleGreater(double first, double second, double epsilon, bool orequal = false) 
80{
81   if (fabs(first - second) < epsilon) 
82   {
83      return (orequal);
84   }
85   return (first > second);
86}
87
88/** container class for rgb value. */
89class ossimRgbColor
90{
91public:
92   /** Default constructor (green) */
93   ossimRgbColor() : r(1), g(255), b(1) {}
94
95   /** Constructor that takes an rgb. */
96   ossimRgbColor(ossim_uint8 r, ossim_uint8 g, ossim_uint8 b)
97      : r(r), g(g), b(b) {}
98   
99   ossim_uint8 r;
100   ossim_uint8 g;
101   ossim_uint8 b;
102};
103
104// The index of the current color.
105static ossim_uint32 currentAutoColorArrayIndex = 0;
106
107// Array count of colors.
108static const ossim_uint32 AUTO_COLOR_ARRAY_COUNT = 9;
109
110// Static array to index for auto colors.
111static const ossimRgbColor autoColorArray[AUTO_COLOR_ARRAY_COUNT] =
112{
113   ossimRgbColor(255,   1,   1), // red
114   ossimRgbColor(  1, 255,   1), // green
115   ossimRgbColor(  1,   1, 255), // blue
116   
117   ossimRgbColor(1,   255, 255),  // cyan
118   ossimRgbColor(255,   1, 255),  // magenta
119   ossimRgbColor(255, 255,   1),  // yellow
120
121   ossimRgbColor(255, 165,   1), // orange
122   ossimRgbColor(160,  32, 240), // purple
123   ossimRgbColor(238, 130, 238) // violet
124};
125
126class ossimOgrGdalFeatureNode
127{
128public:
129   ossimOgrGdalFeatureNode(long id,
130                           const ossimDrect& rect)
131      :theId(id),
132       theBoundingRect(rect)
133      {
134      }
135                           
136   bool intersects(const ossimDrect& rect)const
137      {
138         return theBoundingRect.intersects(rect);
139      }
140   bool intersects(double minX, double minY,
141                   double maxX, double maxY)const
142      {
143         return theBoundingRect.intersects(ossimDrect(minX, minY, maxX, maxY));
144      }
145   long theId;
146   ossimDrect theBoundingRect;
147};
148
149class ossimOgrGdalLayerNode
150{
151public:
152   ossimOgrGdalLayerNode(const ossimDrect& bounds)
153      : theBoundingRect(bounds)
154      {
155      }
156   bool intersects(const ossimDrect& rect)const
157      {
158         return theBoundingRect.intersects(rect);
159      }
160   bool intersects(double minX, double minY,
161                   double maxX, double maxY)const
162      {
163         return theBoundingRect.intersects(ossimDrect(minX, minY, maxX, maxY));
164      }
165   void getIdList(std::list<long>& idList,
166                  const ossimDrect& aoi)const;
167   std::vector<ossimOgrGdalFeatureNode> theFeatureList;
168
169   ossimDrect theBoundingRect;
170};
171void ossimOgrGdalLayerNode::getIdList(std::list<long>& idList,
172                                      const ossimDrect& aoi)const
173{
174   if(!intersects(aoi))
175   {
176      return;
177   }
178   if(theBoundingRect.completely_within(aoi))
179   {
180      for(ossim_uint32 i = 0; i < theFeatureList.size(); ++i)
181      {
182         idList.push_back(theFeatureList[i].theId);
183      }
184   }
185   else
186   {
187      for(ossim_uint32 i = 0; i < theFeatureList.size(); ++i)
188      {
189         if(theFeatureList[i].intersects(aoi))
190         {
191            idList.push_back(theFeatureList[i].theId);
192         }
193      }
194   }
195}
196
197ossimGdalOgrVectorAnnotation::ossimGdalOgrVectorAnnotation(ossimImageSource* inputSource)
198   :ossimAnnotationSource(inputSource),
199    ossimViewInterface(),
200    theDataSource(0),
201    theDriver(0),
202    theFilename(),
203    theBoundingExtent(),
204    theLayersToRenderFlagList(),
205    theLayerTable(),
206    thePenColor(255,255,255),
207    theBrushColor(255,255,255),
208    theFillFlag(false),
209    theThickness(1),
210    thePointWidthHeight(1, 1),
211    theBorderSize(0.0),
212    theBorderSizeUnits(OSSIM_DEGREES),
213    theImageBound(),
214    theIsExternalGeomFlag(false),
215    m_query(""),
216    m_needPenColor(false),
217    m_geometryDistance(0.0),
218    m_geometryDistanceType(OSSIM_UNIT_UNKNOWN),
219    m_layerName("")
220{
221   // Pick up colors from preference file if set.
222   getDefaults();
223   
224   theObject = this;
225   theImageBound.makeNan();
226   ossimAnnotationSource::setNumberOfBands(3);
227}
228
229ossimGdalOgrVectorAnnotation::~ossimGdalOgrVectorAnnotation()
230{
231   ossimViewInterface::theObject = 0;
232   close();
233}
234
235void ossimGdalOgrVectorAnnotation::close()
236{
237   deleteTables();
238   if(theDataSource)
239   {
240      delete theDataSource;
241      theDataSource = 0;
242   }
243   if (theImageGeometry.valid())
244   {
245      theImageGeometry = 0;
246   }
247}
248ossimFilename ossimGdalOgrVectorAnnotation::getFilename()const
249{
250   return theFilename;
251}
252
253void ossimGdalOgrVectorAnnotation::setQuery(const ossimString& query)
254{
255  m_query = query;
256  open(theFilename);
257}
258
259void ossimGdalOgrVectorAnnotation::setGeometryBuffer(ossim_float64 distance, ossimUnitType type)
260{
261   m_geometryDistance = distance;
262   m_geometryDistanceType = type;
263}
264
265bool ossimGdalOgrVectorAnnotation::open(const ossimFilename& file)
266{
267   const char* MODULE = "ossimGdalOgrVectorAnnotation::open";
268   if(traceDebug())
269   {
270      ossimNotify(ossimNotifyLevel_NOTICE) << MODULE << " entered...\nfile: " << file << "\n";
271   }
272   
273   if(isOpen())
274   {
275      close();
276   }
277   m_layerNames.clear();
278   if(file == "") return false;
279
280#if 0 /* Commented out but please leave until I test. drb - 15 July 2011 */
281   ossimString ext = file.ext().downcase();
282   if ( ext != "shp" )
283   {
284      //---
285      // OGRSFDriverRegistrar::Open very touchy and crashes if given a file it cannot handle.
286      // Only allow one type of extension to open file.
287      //---
288      return false;
289   }
290#endif
291   
292   // theDataSource = OGRSFDriverRegistrar::Open( file.c_str(), false, &theDriver );
293   theDataSource = (OGRDataSource*) OGROpen( file.c_str(), false, NULL );
294   if ( theDataSource )
295   {
296      theDriver  = (OGRSFDriver*) theDataSource->GetDriver();
297   }
298   
299   if ( !theDataSource || !theDriver )
300   {
301      if(traceDebug())
302      {
303         ossimNotify(ossimNotifyLevel_NOTICE) << "OGRSFDriverRegistrar::Open failed...\n";
304      }
305      return false;   
306   }
307   
308   // Capture the file.  Need here for loadExternalGeometryFile method.
309   theFilename = file;
310
311   // This will set theViewProjection if "file.geom" is present and valid.
312   loadExternalGeometryFile();
313
314   // This will load external pen, brush and point attributes.
315   loadOmdFile();
316   
317   theLayersToRenderFlagList.clear();
318   vector<ossimGpt> points;
319   if(isOpen())
320   {
321      int i = 0;
322      int layerCount = 0;
323      if (!m_query.empty())
324      {
325        layerCount = 1;
326      }
327      else if (!m_layerName.empty())
328      {
329         layerCount = 1;
330      }
331      else
332      {
333        layerCount = theDataSource->GetLayerCount();
334      }
335     
336      bool successfulTest = true;
337      if(layerCount)
338      {
339         theLayersToRenderFlagList.resize(layerCount);
340         for(i = 0; (i < layerCount)&&successfulTest; ++i)
341         {
342            OGRLayer* layer = NULL;
343            if (!m_query.empty())
344            {
345              layer = theDataSource->ExecuteSQL(m_query, NULL, NULL);
346            }
347            else if (!m_layerName.empty())
348            {
349               layer = theDataSource->GetLayerByName(m_layerName.c_str());
350            }
351            else
352            {
353              layer = theDataSource->GetLayer(i);
354            }
355           
356            if(layer)
357            {
358               OGRSpatialReference* spatialReference = layer->GetSpatialRef();
359               theLayersToRenderFlagList[i] = true;
360               m_layerNames.push_back(ossimString(layer->GetLayerDefn()->GetName()));
361               
362               if(!spatialReference)
363               {
364                  //try xml file
365                  if (!theImageGeometry.valid())
366                  {
367                     loadExternalImageGeometryFromXml();
368                  }
369
370                  if(traceDebug())
371                  {
372                     ossimNotify(ossimNotifyLevel_NOTICE)
373                     << MODULE
374                     << " No spatial reference given, assuming geographic"
375                     << endl;
376                  }
377               }
378               else if(spatialReference->IsLocal())
379               {
380                  if(traceDebug())
381                  {
382                     ossimNotify(ossimNotifyLevel_NOTICE)
383                     << MODULE
384                     << " Only geographic vectors and  projected vectors "
385                     << "are supported, layer " << i << " is local" << endl;
386                  }
387                  successfulTest = false;
388               }
389               
390            }
391            else
392            {
393
394               if(traceDebug())
395               {
396                  ossimNotify(ossimNotifyLevel_NOTICE)
397                 
398                     << MODULE
399                     << " layer " << i << " is null." << endl;
400               }
401               successfulTest = false;
402            }
403           
404            if(successfulTest&&layer)
405            {
406               if (!theImageGeometry.valid())
407               {
408                  ossimRefPtr<ossimProjection> proj = createProjFromReference(layer->GetSpatialRef());
409                  if(proj.valid())
410                  {
411                     theImageGeometry = new ossimImageGeometry(0, proj.get());
412                  }
413               }
414               ossimMapProjection* mapProj = 0;
415               if(theImageGeometry.valid())
416               {
417                 mapProj = PTR_CAST(ossimMapProjection, theImageGeometry->getProjection());
418               }
419               if (!mapProj)
420               {
421                  theImageGeometry = 0; 
422               }
423               
424               if(i == 0)
425               {
426                  layer->GetExtent(&theBoundingExtent, true);
427                  if(mapProj)
428                  {
429                     if (layer->GetSpatialRef())
430                     {
431                        double unitValue = layer->GetSpatialRef()->GetLinearUnits();
432                        theBoundingExtent.MinX = theBoundingExtent.MinX * unitValue;
433                        theBoundingExtent.MaxY = theBoundingExtent.MaxY * unitValue;
434                        theBoundingExtent.MaxX = theBoundingExtent.MaxX * unitValue;
435                        theBoundingExtent.MinY = theBoundingExtent.MinY * unitValue;
436                     }
437
438                     ossimDrect rect(theBoundingExtent.MinX,
439                                     theBoundingExtent.MaxY,
440                                     theBoundingExtent.MaxX,
441                                     theBoundingExtent.MinY,
442                                     OSSIM_RIGHT_HANDED);
443                     
444                     ossimGpt g1 = mapProj->inverse(rect.ul());
445                     ossimGpt g2 = mapProj->inverse(rect.ur());
446                     ossimGpt g3 = mapProj->inverse(rect.lr());
447                     ossimGpt g4 = mapProj->inverse(rect.ll());
448                     ossimDrect rect2 = ossimDrect(ossimDpt(g1),
449                                                   ossimDpt(g2),
450                                                   ossimDpt(g3),
451                                                   ossimDpt(g4));
452                     
453                     theBoundingExtent.MinX = rect2.ul().x;
454                     theBoundingExtent.MinY = rect2.ul().y;
455                     theBoundingExtent.MaxX = rect2.lr().x;
456                     theBoundingExtent.MaxY = rect2.lr().y;
457
458                     //insert the bounding values to points to convert to bounding rect
459                     points.push_back(g1);
460                     points.push_back(g2);
461                     points.push_back(g3);
462                     points.push_back(g4);
463                  }
464               }
465               else
466               {
467                  OGREnvelope extent;
468                  layer->GetExtent(&extent, true);
469                  if(mapProj)
470                  {
471                     ossimDrect rect(extent.MinX,
472                                     extent.MaxY,
473                                     extent.MaxX,
474                                     extent.MinY,
475                                     OSSIM_RIGHT_HANDED);
476                 
477                     ossimGpt g1 = mapProj->inverse(rect.ul());
478                     ossimGpt g2 = mapProj->inverse(rect.ur());
479                     ossimGpt g3 = mapProj->inverse(rect.lr());
480                     ossimGpt g4 = mapProj->inverse(rect.ll());
481                     ossimDrect rect2 = ossimDrect(ossimDpt(g1),
482                                                   ossimDpt(g2),
483                                                   ossimDpt(g3),
484                                                   ossimDpt(g4));
485                     extent.MinX = rect2.ul().x;
486                     extent.MinY = rect2.ul().y;
487                     extent.MaxX = rect2.lr().x;
488                     extent.MaxY = rect2.lr().y;
489
490                     //compare the current values of points with the first layer to
491                     //get the MBR of the datasource
492                     if (points.size() == 4)
493                     {
494                        if (doubleLess(g1.lon, points[0].lon, 0.0001))
495                        {
496                           points[0].lon = g1.lon;
497                        }
498                        if (doubleGreater(g1.lat, points[0].lat, 0.0001))
499                        {
500                           points[0].lat = g1.lat;
501                        }
502                        if (doubleGreater(g2.lon, points[1].lon, 0.0001))
503                        {
504                           points[1].lon = g2.lon;
505                        }
506                        if (doubleGreater(g2.lat, points[1].lat, 0.0001))
507                        {
508                           points[1].lat = g2.lat;
509                        }
510                        if (doubleGreater(g3.lon, points[2].lon, 0.0001))
511                        {
512                           points[2].lon = g3.lon;
513                        }
514                        if (doubleLess(g3.lat, points[2].lat, 0.0001))
515                        {
516                           points[2].lat = g3.lat;
517                        }
518                        if (doubleLess(g4.lon, points[3].lon, 0.0001))
519                        {
520                           points[3].lon = g4.lon;
521                        }
522                        if (doubleLess(g4.lat, points[3].lat, 0.0001))
523                        {
524                           points[3].lat = g4.lat;
525                        }
526                     }
527                  }
528                  theBoundingExtent.MinX = std::min(extent.MinX,
529                                                    theBoundingExtent.MinX);
530                  theBoundingExtent.MinY = std::min(extent.MinY,
531                                                    theBoundingExtent.MinY);
532                  theBoundingExtent.MaxX = std::max(extent.MaxX,
533                                                    theBoundingExtent.MaxX);
534                  theBoundingExtent.MaxY = std::max(extent.MaxY,
535                                                    theBoundingExtent.MaxY);
536               }
537            }
538
539            //if an OGRLayer pointer representing a results set from the query, this layer is
540            //in addition to the layers in the data store and must be destroyed with
541            //OGRDataSource::ReleaseResultSet() before the data source is closed (destroyed).
542            if (!m_query.empty() && layer != NULL)
543            {
544              theDataSource->ReleaseResultSet(layer);
545            } 
546         }
547      }
548      if(!successfulTest)
549      {
550         delete theDataSource;
551         theDataSource = NULL;
552         theLayersToRenderFlagList.clear();
553         
554         return false;
555      }
556   }
557   if(traceDebug())
558   {
559      CLOG << "Extents = "
560           << theBoundingExtent.MinX << ", "
561           << theBoundingExtent.MinY << ", "
562           << theBoundingExtent.MaxX << ", "
563           << theBoundingExtent.MaxY << endl;
564   }
565   if(!theImageGeometry.valid())
566   {
567      computeDefaultView();
568   }
569   else
570   {
571      verifyViewParams();
572   }
573
574   //initialize the bounding rect
575   initializeBoundingRec(points);
576 
577   //only initializeTables when need to draw features. This eliminate the memory allocate problem
578   //when only do ossim-info for a large shape file
579   //initializeTables();
580
581   if (traceDebug())
582   {
583      ossimNotify(ossimNotifyLevel_DEBUG)
584         << MODULE << " DEBUG:"
585         << "\ntheViewProjection:"
586         << endl;
587      if(theImageGeometry.valid())
588      {
589         theImageGeometry->print(ossimNotify(ossimNotifyLevel_DEBUG));
590      }
591      print(ossimNotify(ossimNotifyLevel_DEBUG));
592   }
593
594   return (theDataSource!=NULL);
595}
596
597void ossimGdalOgrVectorAnnotation::initializeBoundingRec(vector<ossimGpt> points)
598{
599   theImageBound.makeNan();
600
601   //if the projection is default or geographic, uses the bounding of the OGR Layer
602   if (points.size() == 0)
603   {
604      points.push_back(ossimGpt(theBoundingExtent.MaxY, theBoundingExtent.MinX));
605      points.push_back(ossimGpt(theBoundingExtent.MaxY, theBoundingExtent.MaxX));
606      points.push_back(ossimGpt(theBoundingExtent.MinY, theBoundingExtent.MaxX));
607      points.push_back(ossimGpt(theBoundingExtent.MinY, theBoundingExtent.MinX));
608   }
609
610   if(theImageGeometry.valid())
611   {
612      std::vector<ossimDpt> rectTmp;
613      rectTmp.resize(points.size());
614      for(std::vector<ossimGpt>::size_type index=0; index < points.size(); ++index)
615      {
616         theImageGeometry->worldToLocal(points[(int)index], rectTmp[(int)index]);
617      }
618
619      if (rectTmp.size() > 3)
620      {
621         ossimDrect rect2 = ossimDrect(rectTmp[0],
622            rectTmp[1],
623            rectTmp[2],
624            rectTmp[3]);
625
626         theImageBound = rect2;
627      }
628   }
629}
630
631bool ossimGdalOgrVectorAnnotation::setView(ossimObject* baseObject)
632{
633   bool result = false;
634
635   if(baseObject)
636   {
637      // Test for projection...
638      ossimProjection* p = PTR_CAST(ossimProjection, baseObject);
639      if (p)
640      {
641         if(!theImageGeometry)
642         {
643            theImageGeometry = new ossimImageGeometry(0, p);
644         }
645         else
646         {
647            theImageGeometry->setProjection(p);
648         }
649         
650         // Reproject the points to the current new projection.
651         transformObjectsFromView();
652         result = true;
653         
654      }
655      else
656      {
657         ossimImageGeometry* geom = dynamic_cast<ossimImageGeometry*> (baseObject);
658         if(geom)
659         {
660            theImageGeometry = geom;
661            // Reproject the points to the current new projection.
662            transformObjectsFromView();
663            result = true;
664         }
665      }
666   } // if (baseObject)
667
668   return result;
669}
670
671ossimObject* ossimGdalOgrVectorAnnotation::getView()
672{
673   return theImageGeometry.get();
674}
675
676//! Returns the image geometry object associated with this tile source or NULL if non defined.
677//! The geometry contains full-to-local image transform as well as projection (image-to-world)
678ossimRefPtr<ossimImageGeometry> ossimGdalOgrVectorAnnotation::getImageGeometry() const
679{
680   return theImageGeometry;
681}
682
683void ossimGdalOgrVectorAnnotation::computeDefaultView()
684{
685   if (theImageGeometry.valid())
686      return;
687
688   if(!isOpen())
689      return;
690
691   // double horizontal = fabs(theBoundingExtent.MinX - theBoundingExtent.MaxX);
692   // double vertical   = fabs(theBoundingExtent.MinY - theBoundingExtent.MaxY);
693
694   //    if((horizontal > 0.0) && (vertical > 0.0))
695   ossimEquDistCylProjection* proj = new ossimEquDistCylProjection;
696
697   ossim_float64 centerLat = (theBoundingExtent.MaxY + theBoundingExtent.MinY ) / 2.0;
698   ossim_float64 centerLon = (theBoundingExtent.MaxX + theBoundingExtent.MinX ) / 2.0;
699   ossim_float64 deltaLat  = theBoundingExtent.MaxY - theBoundingExtent.MinY;
700
701   // Scale that gives 1024 pixel in the latitude direction.
702   ossim_float64 scaleLat = deltaLat / 1024.0;
703   ossim_float64 scaleLon = scaleLat*ossim::cosd(std::fabs(centerLat)); 
704   ossimGpt origin(centerLat, centerLon, 0.0);
705   ossimDpt scale(scaleLon, scaleLat);
706
707   // Set the origin.
708   proj->setOrigin(origin);
709
710   // Set the tie point.
711   proj->setUlGpt( ossimGpt(theBoundingExtent.MaxY,
712      theBoundingExtent.MinX) );
713
714   // Set the scale.  Note this will handle computing meters per pixel.
715   proj->setDecimalDegreesPerPixel(scale);
716
717   // Capture the projection.
718   theImageGeometry = new ossimImageGeometry(0, proj);
719}
720
721ossimIrect ossimGdalOgrVectorAnnotation::getBoundingRect(ossim_uint32 /* resLevel */ )const
722{
723   return theImageBound;
724}
725
726void ossimGdalOgrVectorAnnotation::computeBoundingRect()
727{
728   std::multimap<long, ossimAnnotationObject*>::iterator iter = theFeatureCacheTable.begin();
729   
730   theImageBound.makeNan();
731   while(iter != theFeatureCacheTable.end())
732   {
733      ossimGeoAnnotationObject* obj = PTR_CAST(ossimGeoAnnotationObject,
734                                               (*iter).second);
735     
736      if(obj)
737      {
738         ossimDrect rect;
739         obj->getBoundingRect(rect);
740         
741         if(theImageBound.hasNans())
742         {
743            theImageBound = rect;
744         }
745         else
746         {
747            if(!rect.hasNans())
748            {
749               theImageBound = theImageBound.combine(rect);
750            }
751         }
752      }
753
754      ++iter;
755   }
756
757   theImageBound.stretchOut();
758}
759
760void ossimGdalOgrVectorAnnotation::drawAnnotations(
761   ossimRefPtr<ossimImageData> tile)
762{
763   if (theFeatureCacheTable.size() == 0)
764   {
765      initializeTables();
766   }
767
768   if( theImageGeometry.valid())
769   {
770      list<long> featuresToRender;
771      ossimIrect tileRect = tile->getImageRectangle();
772     
773      getFeatures(featuresToRender, tileRect);
774     
775      list<long>::iterator current = featuresToRender.begin();
776     
777      ossimRefPtr<ossimRgbImage> image = new ossimRgbImage;
778     
779      image->setCurrentImageData(tile);
780      vector<ossimAnnotationObject*> objectList;
781     
782      while(current!=featuresToRender.end())
783      {
784         getFeature(objectList, *current);
785         ++current;
786      }
787     
788      for(ossim_uint32 i = 0; i < objectList.size();++i)
789      {
790         objectList[i]->draw(*image.get());
791
792        if (theFillFlag && m_needPenColor) //need to draw both the brush and line (pen) for a polygon
793        {
794          ossimObject* objectDup = objectList[i]->dup();
795          ossimGeoAnnotationPolyObject* polyObject = PTR_CAST(ossimGeoAnnotationPolyObject, objectDup);
796          if (polyObject)//check if it is the polygon object
797          {
798            polyObject->setColor(thePenColor.getR(), thePenColor.getG(), thePenColor.getB());
799            polyObject->setThickness(theThickness);
800            polyObject->setFillFlag(false);
801            polyObject->draw(*image.get());
802          }
803          delete objectDup;
804        }
805      }
806     
807      tile->validate();
808   }
809}
810
811void ossimGdalOgrVectorAnnotation::updateAnnotationSettings()
812{
813   std::multimap<long, ossimAnnotationObject*>::iterator iter = theFeatureCacheTable.begin();
814
815   while(iter != theFeatureCacheTable.end())
816   {
817      iter->second->setThickness(theThickness);
818
819      iter->second->setColor(thePenColor.getR(),
820                             thePenColor.getG(),
821                             thePenColor.getB());
822     
823      if(PTR_CAST(ossimGeoAnnotationPolyObject, iter->second))
824      {
825         ossimGeoAnnotationPolyObject* poly =
826            (ossimGeoAnnotationPolyObject*)(iter->second);
827         poly->setFillFlag(theFillFlag);
828      }
829      else if(PTR_CAST(ossimGeoAnnotationMultiPolyObject, iter->second))
830      {
831         ossimGeoAnnotationMultiPolyObject* poly =
832            (ossimGeoAnnotationMultiPolyObject*)(iter->second);
833         poly->setFillFlag(theFillFlag);
834      }
835      else if(PTR_CAST(ossimGeoAnnotationEllipseObject, iter->second))
836      {
837         ossimGeoAnnotationEllipseObject* ell = (ossimGeoAnnotationEllipseObject*)(iter->second);
838
839         ell->setWidthHeight(thePointWidthHeight);
840         ell->setFillFlag(theFillFlag);
841         ell->transform(theImageGeometry.get());
842      }
843      if(theFillFlag)
844      {
845         iter->second->setColor(theBrushColor.getR(),
846                                theBrushColor.getG(),
847                                theBrushColor.getB());
848      }
849      ++iter;
850   }
851}
852
853void ossimGdalOgrVectorAnnotation::setProperty(ossimRefPtr<ossimProperty> property)
854{
855   if(!property.valid()) return;
856
857   ossimString name  = property->getName();
858   ossimString value = property->valueToString();
859
860   if(name == ossimKeywordNames::PEN_COLOR_KW)
861   {
862      int r; 
863      int g; 
864      int b;
865      std::istringstream in(value);
866      in >> r >> g >> b;
867      thePenColor.setR((unsigned char)r);
868      thePenColor.setG((unsigned char)g);
869      thePenColor.setB((unsigned char)b);
870      updateAnnotationSettings();
871   }
872   else if(name == ossimKeywordNames::BRUSH_COLOR_KW)
873   {
874      int r; 
875      int g; 
876      int b;
877      std::istringstream in(value);
878      in >> r >> g >> b;
879      theBrushColor.setR((unsigned char)r);
880      theBrushColor.setG((unsigned char)g);
881      theBrushColor.setB((unsigned char)b);
882      updateAnnotationSettings();
883   }
884   else if(name == ossimKeywordNames::FILL_FLAG_KW)
885   {
886      theFillFlag = value.toBool();
887      updateAnnotationSettings();
888   }
889   else if(name == ossimKeywordNames::THICKNESS_KW)
890   {
891      setThickness(value.toInt32());
892      updateAnnotationSettings();
893   }
894   else if(name == ossimKeywordNames::BORDER_SIZE_KW)
895   {
896   }
897   else if(name == ossimKeywordNames::POINT_WIDTH_HEIGHT_KW)
898   {
899      std::istringstream in(value);
900      in >> thePointWidthHeight.x;
901      in >> thePointWidthHeight.y;
902      updateAnnotationSettings();
903   }
904   else
905   {
906      ossimAnnotationSource::setProperty(property);
907   }
908}
909
910ossimRefPtr<ossimProperty> ossimGdalOgrVectorAnnotation::getProperty(const ossimString& name)const
911{
912   ossimRefPtr<ossimProperty> result;
913   if(name == ossimKeywordNames::PEN_COLOR_KW)
914   {
915      result = new ossimColorProperty(name,
916                                      thePenColor);
917      result->setCacheRefreshBit();
918   }
919   else if(name == ossimKeywordNames::BRUSH_COLOR_KW)
920   {
921      result = new ossimColorProperty(name,
922                                      theBrushColor);
923      result->setCacheRefreshBit();
924   }
925   else if(name == ossimKeywordNames::FILL_FLAG_KW)
926   {
927      result = new ossimBooleanProperty(name,
928                                        theFillFlag);
929      result->setCacheRefreshBit();
930     
931   }
932   else if(name == ossimKeywordNames::THICKNESS_KW)
933   {
934      ossimNumericProperty* prop =
935         new ossimNumericProperty(name,
936                                  ossimString::toString(getThickness()),
937                                  1.0,
938                                  255.0);
939      prop->setNumericType(ossimNumericProperty::ossimNumericPropertyType_INT);
940      result = prop;
941      result->setFullRefreshBit();
942   }
943   else if(name == ossimKeywordNames::BORDER_SIZE_KW)
944   {
945   }
946   else if(name == ossimKeywordNames::POINT_WIDTH_HEIGHT_KW)
947   {
948      result = new ossimTextProperty(name,
949                                     ossimString::toString(thePointWidthHeight.x) +
950                                     " " +
951                                     ossimString::toString(thePointWidthHeight.y));
952      result->setFullRefreshBit();
953   }
954   else
955   {
956      result = ossimAnnotationSource::getProperty(name);
957   }
958   
959   return result;
960}
961
962void ossimGdalOgrVectorAnnotation::getPropertyNames(std::vector<ossimString>& propertyNames)const
963{
964   
965   propertyNames.push_back(ossimKeywordNames::PEN_COLOR_KW);
966   propertyNames.push_back(ossimKeywordNames::BRUSH_COLOR_KW);
967   propertyNames.push_back(ossimKeywordNames::FILL_FLAG_KW);
968   propertyNames.push_back(ossimKeywordNames::THICKNESS_KW);
969   propertyNames.push_back(ossimKeywordNames::BORDER_SIZE_KW);
970   propertyNames.push_back(ossimKeywordNames::POINT_WIDTH_HEIGHT_KW);
971}
972
973
974bool ossimGdalOgrVectorAnnotation::saveState(ossimKeywordlist& kwl,
975                                             const char* prefix)const
976{
977   ossimString s;
978   
979   kwl.add(prefix,
980           ossimKeywordNames::FILENAME_KW,
981           theFilename.c_str(),
982           true);
983
984
985   s = ossimString::toString((int)thePenColor.getR()) + " " +
986       ossimString::toString((int)thePenColor.getG()) + " " +
987       ossimString::toString((int)thePenColor.getB());
988   
989   kwl.add(prefix,
990           ossimKeywordNames::PEN_COLOR_KW,
991           s.c_str(),
992           true);
993
994   s = ossimString::toString((int)theBrushColor.getR()) + " " +
995       ossimString::toString((int)theBrushColor.getG()) + " " +
996       ossimString::toString((int)theBrushColor.getB());
997   
998   kwl.add(prefix,
999           ossimKeywordNames::BRUSH_COLOR_KW,
1000           s.c_str(),
1001           true);
1002
1003   kwl.add(prefix,
1004           ossimKeywordNames::FILL_FLAG_KW,
1005           (int)theFillFlag,
1006           true);
1007
1008   kwl.add(prefix,
1009           ossimKeywordNames::THICKNESS_KW,
1010           getThickness(),
1011           true);
1012
1013   ossimString border;
1014   border = ossimString::toString(theBorderSize);
1015   border += " degrees";
1016   kwl.add(prefix,
1017           ossimKeywordNames::BORDER_SIZE_KW,
1018           border,
1019           true);
1020
1021   kwl.add(prefix,
1022           ossimString(ossimString(ossimKeywordNames::BORDER_SIZE_KW)+
1023                       "."+
1024                       ossimKeywordNames::UNITS_KW).c_str(),
1025           ossimUnitTypeLut::instance()->getEntryString(theBorderSizeUnits),
1026           true);
1027   
1028   s = ossimString::toString((int)thePointWidthHeight.x) + " " +
1029       ossimString::toString((int)thePointWidthHeight.y);
1030   
1031   kwl.add(prefix,
1032           ossimKeywordNames::POINT_WIDTH_HEIGHT_KW,
1033           s.c_str(),
1034           true);
1035
1036   if (!m_query.empty())
1037   {
1038     kwl.add(prefix,
1039       ossimKeywordNames::QUERY_KW,
1040       m_query.c_str(),
1041       true);
1042   }
1043   
1044   if(theImageGeometry.valid())
1045   {
1046      ossimString newPrefix = prefix;
1047      newPrefix += "view_proj.";
1048      theImageGeometry->saveState(kwl,
1049                                   newPrefix.c_str());
1050   }
1051   
1052   return ossimAnnotationSource::saveState(kwl, prefix);
1053}
1054
1055bool ossimGdalOgrVectorAnnotation::loadState(const ossimKeywordlist& kwl,
1056                                             const char* prefix)
1057{
1058   const char* filename    = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
1059   const char* penColor    = kwl.find(prefix, ossimKeywordNames::PEN_COLOR_KW);
1060   const char* brushColor  = kwl.find(prefix, ossimKeywordNames::BRUSH_COLOR_KW);
1061   const char* fillFlag    = kwl.find(prefix, ossimKeywordNames::FILL_FLAG_KW);
1062   const char* thickness   = kwl.find(prefix, ossimKeywordNames::THICKNESS_KW);
1063   const char* pointWh     = kwl.find(prefix, ossimKeywordNames::POINT_WIDTH_HEIGHT_KW);
1064   const char* border_size = kwl.find(prefix, ossimKeywordNames::BORDER_SIZE_KW);
1065   const char* query       = kwl.find(prefix, ossimKeywordNames::QUERY_KW);
1066   
1067   deleteTables();
1068   if(thickness)
1069   {
1070      setThickness(ossimString(thickness).toInt32());
1071   }
1072   
1073   if(penColor)
1074   {
1075      int r = 0;
1076      int g = 0;
1077      int b = 0;
1078      ossimString penColorStr = ossimString(penColor);
1079      if (penColorStr.split(",").size() == 3)
1080      {
1081         r = penColorStr.split(",")[0].toInt();
1082         g = penColorStr.split(",")[1].toInt();
1083         b = penColorStr.split(",")[2].toInt();
1084         if (r == 0 && g == 0 && b == 0)
1085         {
1086            r = 1;
1087            g = 1;
1088            b = 1;
1089         }
1090      }
1091      thePenColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
1092      m_needPenColor = true;
1093   }
1094
1095   if(brushColor)
1096   {
1097      int r = 0;
1098      int g = 0;
1099      int b = 0;
1100      ossimString brushColorStr = ossimString(brushColor);
1101      if (brushColorStr.split(",").size() == 3)
1102      {
1103         r = brushColorStr.split(",")[0].toInt();
1104         g = brushColorStr.split(",")[1].toInt();
1105         b = brushColorStr.split(",")[2].toInt();
1106         if (r == 0 && g == 0 && b == 0)
1107         {
1108            r = 1;
1109            g = 1;
1110            b = 1;
1111         }
1112      }
1113
1114      theBrushColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
1115   }
1116   if(pointWh)
1117   {
1118      double w, h;
1119      std::istringstream s(pointWh);
1120      s>>w>>h;
1121      thePointWidthHeight = ossimDpt(w, h);
1122   }
1123   
1124   if(fillFlag)
1125   {
1126      theFillFlag = ossimString(fillFlag).toBool();
1127   }
1128   theBorderSize = 0.0;
1129   if(border_size)
1130   {
1131      theBorderSize = ossimString(border_size).toDouble();
1132      ossimString unitPrefix = ossimString(prefix) +
1133                               ossimKeywordNames::BORDER_SIZE_KW +
1134                               ossimString(".");
1135     
1136      theBorderSizeUnits = (ossimUnitType)ossimUnitTypeLut::instance()->
1137         getEntryNumber(kwl,
1138                                                                                unitPrefix.c_str());
1139      if(theBorderSizeUnits != OSSIM_UNIT_UNKNOWN)
1140      {
1141         ossimUnitConversionTool unitConvert(theBorderSize,
1142                                             theBorderSizeUnits);
1143         
1144         theBorderSize      = unitConvert.getValue(OSSIM_DEGREES);
1145         theBorderSizeUnits = OSSIM_DEGREES;
1146      }
1147      else // assume degrees
1148      {
1149         theBorderSizeUnits = OSSIM_DEGREES;
1150      }
1151   }
1152   else
1153   {
1154      theBorderSize      = 0.0;
1155      theBorderSizeUnits = OSSIM_DEGREES;
1156   }
1157   
1158   if(filename)
1159   {
1160      if(!open(ossimFilename(filename)))
1161      {
1162         return false;
1163      }
1164   }
1165
1166   if (query)
1167   {
1168     setQuery(query);
1169   }
1170
1171   bool status = ossimAnnotationSource::loadState(kwl, prefix);
1172   
1173   initializeTables();
1174
1175   return status;
1176}
1177
1178std::ostream& ossimGdalOgrVectorAnnotation::print(std::ostream& out) const
1179{
1180   out << "ossimGdalOgrVectorAnnotation::print"
1181       << "\ntheLayersToRenderFlagList.size(): "
1182       << theLayersToRenderFlagList.size()
1183       << "\ntheLayerTable.size(): " << theLayerTable.size();
1184
1185   ossim_uint32 i;
1186   for(i=0; i<theLayersToRenderFlagList.size(); ++i)
1187   {
1188      out << "layer[" << i << "]:"
1189          << (theLayersToRenderFlagList[i]?"enabled":"disabled")
1190          << std::endl;
1191   }
1192   return ossimAnnotationSource::print(out);
1193}
1194
1195void ossimGdalOgrVectorAnnotation::transformObjectsFromView()
1196{
1197   if (theImageGeometry.valid())
1198   {
1199      if (theFeatureCacheTable.size() == 0)
1200      {
1201         initializeTables();
1202      }
1203      std::multimap<long, ossimAnnotationObject*>::iterator iter =
1204         theFeatureCacheTable.begin();
1205     
1206      while(iter != theFeatureCacheTable.end())
1207      {
1208         ossimGeoAnnotationObject* obj = PTR_CAST(ossimGeoAnnotationObject,
1209                                                  (*iter).second);
1210         
1211         if(obj&&theImageGeometry.valid())
1212         {
1213            obj->transform(theImageGeometry.get());
1214         }
1215         ++iter;
1216      }
1217      computeBoundingRect();
1218   }
1219}
1220
1221void ossimGdalOgrVectorAnnotation::getFeatures(std::list<long>& result,
1222                                               const ossimIrect& rect)
1223{
1224   if (isOpen())
1225   {
1226      ossimGpt gp1;
1227      ossimGpt gp2;
1228      ossimGpt gp3;
1229      ossimGpt gp4;
1230      ossimDpt dp1 = rect.ul();
1231      ossimDpt dp2 = rect.ur();
1232      ossimDpt dp3 = rect.lr();
1233      ossimDpt dp4 = rect.ll();
1234     
1235      if (theImageGeometry.valid())
1236      {
1237         theImageGeometry->localToWorld(dp1, gp1);
1238         theImageGeometry->localToWorld(dp2, gp2);
1239         theImageGeometry->localToWorld(dp3, gp3);
1240         theImageGeometry->localToWorld(dp4, gp4);
1241
1242         double maxX = std::max( gp1.lond(), std::max( gp2.lond(), std::max(gp3.lond(), gp4.lond())));
1243         double minX = std::min( gp1.lond(), std::min( gp2.lond(), std::min(gp3.lond(), gp4.lond())));
1244         double maxY = std::max( gp1.latd(), std::max( gp2.latd(), std::max(gp3.latd(), gp4.latd())));
1245         double minY = std::min( gp1.latd(), std::min( gp2.latd(), std::min(gp3.latd(), gp4.latd())));
1246         
1247         ossimDrect bounds(minX, minY, maxX, maxY);
1248         
1249         for(ossim_uint32 layerI = 0;
1250             layerI < theLayersToRenderFlagList.size();
1251             ++layerI)
1252         {
1253            if(theLayersToRenderFlagList[layerI])
1254            {
1255               if(theLayerTable[layerI])
1256               {
1257                  theLayerTable[layerI]->getIdList(result, bounds);
1258               }
1259            }
1260         }
1261      }
1262   }
1263}
1264
1265void ossimGdalOgrVectorAnnotation::initializeTables()
1266{
1267   if(traceDebug())
1268   {
1269      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimGdalOgrVectorAnnotation::initializeTables(): entered.........." << std::endl;
1270   }
1271   if(theLayerTable.size())
1272   {
1273      deleteTables();
1274   }
1275
1276   if(isOpen())
1277   {
1278      int upper = theLayersToRenderFlagList.size();
1279      theLayerTable.resize(upper);
1280
1281      for(int i = 0; i < upper; ++i)
1282      { 
1283         if(theLayersToRenderFlagList[i])
1284         {
1285            OGREnvelope extent;
1286            OGRLayer* layer = NULL;
1287            if (!m_query.empty())
1288            {
1289              layer = theDataSource->ExecuteSQL(m_query, NULL, NULL);
1290            }
1291            else if (!m_layerName.empty())
1292            {
1293               layer = theDataSource->GetLayerByName(m_layerName.c_str());
1294            }
1295            else
1296            {
1297              layer = theDataSource->GetLayer(i);
1298            }
1299
1300            ossimRefPtr<ossimProjection> proj;
1301            if (theIsExternalGeomFlag&&theImageGeometry.valid())
1302            {
1303               proj = theImageGeometry->getProjection();
1304            }
1305            else
1306            {
1307               proj = createProjFromReference(layer->GetSpatialRef());
1308            }
1309
1310            ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj.get());
1311           
1312            layer->ResetReading();
1313            layer->GetExtent(&extent, true);
1314            layer->ResetReading();
1315
1316            OGRFeature* feature = NULL;
1317            if(mapProj)
1318            {
1319               ossimDrect rect(extent.MinX,
1320                               extent.MaxY,
1321                               extent.MaxX,
1322                               extent.MinY,
1323                               OSSIM_RIGHT_HANDED);
1324               ossimGpt g1 = mapProj->inverse(rect.ul());
1325               ossimGpt g2 = mapProj->inverse(rect.ur());
1326               ossimGpt g3 = mapProj->inverse(rect.lr());
1327               ossimGpt g4 = mapProj->inverse(rect.ll());
1328
1329               ossimDrect rect2 = ossimDrect(ossimDpt(g1),
1330                                            ossimDpt(g2),
1331                                            ossimDpt(g3),
1332                                            ossimDpt(g4));
1333               theLayerTable[i] = new ossimOgrGdalLayerNode(rect2);
1334            }
1335            else
1336            {
1337               theLayerTable[i] = new ossimOgrGdalLayerNode(ossimDrect(extent.MinX,
1338                                                                       extent.MinY,
1339                                                                       extent.MaxX,
1340                                                                       extent.MaxY));
1341            }
1342           
1343            while( (feature = layer->GetNextFeature()) != NULL)
1344            {
1345                  if(feature)
1346                  {
1347                     OGRGeometry* geom = feature->GetGeometryRef();
1348                     
1349                     if(geom)
1350                     {
1351                        switch(geom->getGeometryType())
1352                        {
1353                           case wkbMultiPoint:
1354                           case wkbMultiPoint25D:
1355                           {
1356                              if(traceDebug())
1357                              {
1358                                 ossimNotify(ossimNotifyLevel_DEBUG) << "Loading multi point" << std::endl;
1359                              }
1360                              loadMultiPoint(feature->GetFID(),
1361                                             (OGRMultiPoint*)geom,
1362                                             mapProj);
1363                              break;
1364                           }
1365                           case wkbPolygon25D:
1366                           case wkbPolygon:
1367                           {
1368                              if(traceDebug())
1369                              {
1370                                 ossimNotify(ossimNotifyLevel_DEBUG) << "Loading polygon" << std::endl;
1371                              }
1372                              if (m_geometryDistance > 0.0)
1373                              {
1374                                 OGRPolygon* poly = (OGRPolygon*)geom;
1375                                 OGRLinearRing* ring = poly->getExteriorRing();
1376                                 int numPoints = ring->getNumPoints();
1377                                 OGRGeometry* bufferGeom = geom->Buffer(m_geometryDistance, numPoints);
1378                                 loadPolygon(feature->GetFID(),
1379                                    (OGRPolygon*)bufferGeom,
1380                                    mapProj);
1381                              }
1382                              else
1383                              {
1384                                 loadPolygon(feature->GetFID(),
1385                                    (OGRPolygon*)geom,
1386                                    mapProj);
1387                              }
1388
1389                              break;
1390                           }
1391                           case wkbLineString25D:
1392                           case wkbLineString:
1393                           {
1394                              if(traceDebug())
1395                              {
1396                                 ossimNotify(ossimNotifyLevel_DEBUG) << "Loading line string" << std::endl;
1397                              }
1398                              loadLineString(feature->GetFID(),
1399                                             (OGRLineString*)geom,
1400                                             mapProj);
1401                              break;
1402                           }
1403                           case wkbPoint:
1404                           case wkbPoint25D:
1405                           {
1406                              if(traceDebug())
1407                              {
1408                                 ossimNotify(ossimNotifyLevel_DEBUG) << "Loading point" << std::endl;
1409                              }
1410                              loadPoint(feature->GetFID(),
1411                                        (OGRPoint*)geom,
1412                                        mapProj);
1413                              break;
1414                           }
1415                           case wkbMultiPolygon25D:
1416                           case wkbMultiPolygon:
1417                           {
1418                              if(traceDebug())
1419                              {
1420                                 ossimNotify(ossimNotifyLevel_DEBUG) << "Loading multi polygon" << std::endl;
1421                              }
1422                              if (m_geometryDistance > 0.0)
1423                              {
1424                                 OGRGeometry* bufferGeom = geom->Buffer(m_geometryDistance);
1425                                 loadMultiPolygon(feature->GetFID(),
1426                                    (OGRMultiPolygon*)bufferGeom,
1427                                    mapProj);
1428                              }
1429                              else
1430                              {
1431                                 loadMultiPolygon(feature->GetFID(),
1432                                    (OGRMultiPolygon*)geom,
1433                                    mapProj);
1434                              }
1435                              break;
1436                                               
1437                           }
1438                           case wkbMultiLineString:
1439                           {
1440                              if(traceDebug())
1441                              {
1442                                 ossimNotify(ossimNotifyLevel_DEBUG) << "Loading line string" << std::endl;
1443                              }
1444                              loadMultiLineString(feature->GetFID(),
1445                                    (OGRMultiLineString*)geom,
1446                                    mapProj);
1447                                 break;
1448                              }
1449                           default:
1450                           {
1451                              if(traceDebug())
1452                              {
1453                                 ossimNotify(ossimNotifyLevel_WARN)
1454                                    << "ossimGdalOgrVectorAnnotation::initializeTables WARNING\n"
1455                                   
1456                                    << OGRGeometryTypeToName(geom->getGeometryType())
1457                                    <<" NOT SUPPORTED!"
1458                                    << endl;
1459                              }
1460                              break;
1461                           }
1462                        }
1463                        geom->getEnvelope(&extent);
1464                        if(mapProj)
1465                        {
1466                           ossimDrect rect(extent.MinX,
1467                                           extent.MaxY,
1468                                           extent.MaxX,
1469                                           extent.MinY,
1470                                           OSSIM_RIGHT_HANDED);
1471                           ossimGpt g1 = mapProj->inverse(rect.ul());
1472                           ossimGpt g2 = mapProj->inverse(rect.ur());
1473                           ossimGpt g3 = mapProj->inverse(rect.lr());
1474                           ossimGpt g4 = mapProj->inverse(rect.ll());
1475                           
1476                           theLayerTable[i]->theFeatureList.push_back(ossimOgrGdalFeatureNode(feature->GetFID(),
1477                                                                                              ossimDrect(ossimDpt(g1),
1478                                                                                                         ossimDpt(g2),
1479                                                                                                         ossimDpt(g3),
1480                                                                                                         ossimDpt(g4))));
1481                           
1482                        }
1483                        else
1484                        {
1485                           theLayerTable[i]->theFeatureList.push_back(ossimOgrGdalFeatureNode(feature->GetFID(),
1486                                                                                              ossimDrect(extent.MinX,
1487                                                                                                         extent.MinY,
1488                                                                                                         extent.MaxX,
1489                                                                                                         extent.MaxY)));
1490                        }
1491                     }
1492               }
1493               delete feature;
1494            }
1495
1496            //if an OGRLayer pointer representing a results set from the query, this layer is
1497            //in addition to the layers in the data store and must be destroyed with
1498            //OGRDataSource::ReleaseResultSet() before the data source is closed (destroyed).
1499            if (!m_query.empty() && layer != NULL)
1500            {
1501              theDataSource->ReleaseResultSet(layer);
1502            } 
1503         }
1504         else
1505         {
1506            theLayerTable[i] = NULL;
1507         }
1508      }
1509   }
1510   computeBoundingRect();
1511   updateAnnotationSettings();
1512   if(traceDebug())
1513   {
1514      ossimNotify(ossimNotifyLevel_DEBUG)
1515         << "ossimGdalOgrVectorAnnotation::initializeTables(): leaving..."
1516         << std::endl;
1517   }
1518}
1519
1520void ossimGdalOgrVectorAnnotation::deleteTables()
1521{
1522   for(ossim_uint32 i = 0; i < theLayerTable.size(); ++i)
1523   {
1524      if(theLayerTable[i])
1525      {
1526         delete theLayerTable[i];
1527      }
1528   }
1529
1530   theLayerTable.clear();
1531   std::multimap<long, ossimAnnotationObject*>::iterator current = theFeatureCacheTable.begin();
1532
1533   while(current != theFeatureCacheTable.end())
1534   {
1535      ((*current).second)->unref();
1536      ++current;
1537   }
1538   
1539   theFeatureCacheTable.clear();
1540}
1541
1542
1543void ossimGdalOgrVectorAnnotation::getFeature(vector<ossimAnnotationObject*>& featureList,
1544                                              long id)
1545{
1546   std::multimap<long, ossimAnnotationObject*>::iterator iter = theFeatureCacheTable.find(id);
1547   
1548   while( (iter != theFeatureCacheTable.end()) && ((*iter).first == id)  )
1549   {
1550      featureList.push_back((*iter).second);
1551      ++iter;
1552   }
1553}
1554
1555ossimProjection* ossimGdalOgrVectorAnnotation::createProjFromReference(OGRSpatialReference* reference)const
1556{
1557   if(traceDebug())
1558   {
1559      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimGdalOgrVectorAnnotation::createProjFromReference:   entered........" << std::endl;
1560   }
1561   if(!reference)
1562   {
1563      if(traceDebug())
1564      {
1565         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimGdalOgrVectorAnnotation::createProjFromReference:   leaving 1........" << std::endl;
1566      }
1567      return NULL;
1568   }
1569   if(reference->IsGeographic()||reference->IsLocal())
1570   {
1571      if(traceDebug())
1572      {
1573         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimGdalOgrVectorAnnotation::createProjFromReference:   leaving 2........" << std::endl;
1574      }
1575      return NULL;
1576   }
1577   char* wktString = NULL;
1578   ossimKeywordlist kwl;
1579   reference->exportToWkt(&wktString);
1580   wktTranslator.toOssimKwl(wktString,
1581                            kwl);
1582   if(traceDebug())
1583   {
1584      ossimNotify(ossimNotifyLevel_DEBUG) << "wktString === " << wktString << std::endl;
1585      ossimNotify(ossimNotifyLevel_DEBUG) << "KWL === " << kwl << std::endl;
1586   }
1587   OGRFree(wktString);
1588   if(traceDebug())
1589   {
1590      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimGdalOgrVectorAnnotation::createProjFromReference:   returning........" << std::endl;
1591   }
1592   return ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
1593}
1594
1595void ossimGdalOgrVectorAnnotation::loadPolygon(long id, OGRPolygon* poly, ossimMapProjection* mapProj)
1596{
1597   OGRLinearRing* ring = poly->getExteriorRing();
1598   
1599   ossimGpt origin;
1600   
1601   if(theImageGeometry.valid()&&theImageGeometry->getProjection())
1602   {
1603      origin = theImageGeometry->getProjection()->origin();
1604   }
1605   
1606   ossimRgbVector color;
1607   
1608   if(theFillFlag)
1609   {
1610      color = theBrushColor;
1611   }
1612   else
1613   {
1614      color = thePenColor;
1615   }
1616   
1617   if(ring)
1618   {
1619      int upper = ring->getNumPoints();
1620      vector<ossimGpt> points(upper);
1621      for(int i = 0; i < upper; ++i)
1622      {
1623         OGRPoint ogrPt;
1624         ring->getPoint(i, &ogrPt);
1625         if(mapProj)
1626         {
1627            points[i] = mapProj->inverse(ossimDpt(ogrPt.getX(),
1628                                                  ogrPt.getY()));
1629
1630         }
1631         else
1632         {
1633            points[i] = ossimGpt(ogrPt.getY(),
1634                                 ogrPt.getX(),
1635                                 ogrPt.getZ(),
1636                                 origin.datum());
1637         }
1638      }
1639      ossimGeoAnnotationObject* annotation =
1640         new ossimGeoAnnotationPolyObject(points,
1641                                          theFillFlag,
1642                                          color.getR(),
1643                                          color.getG(),
1644                                          color.getB(),
1645                                          theThickness);
1646      if(theImageGeometry.valid())
1647      {
1648         annotation->transform(theImageGeometry.get());
1649      }
1650     
1651      theFeatureCacheTable.insert(make_pair(id,
1652                                            annotation));
1653   }
1654   int bound = poly->getNumInteriorRings();
1655   if(bound)
1656   {
1657      for(int i = 0; i < bound; ++i)
1658       {
1659          ring = poly->getInteriorRing(i);
1660          if(ring)
1661          {
1662             int j = 0;
1663             int upper = ring->getNumPoints();
1664             vector<ossimGpt> points(upper);
1665             for(j = 0; j < upper; ++j)
1666             {
1667                OGRPoint ogrPt;
1668                ring->getPoint(j, &ogrPt);
1669                if(mapProj)
1670                {
1671                   ossimDpt eastingNorthing(ogrPt.getX(),
1672                                            ogrPt.getY());
1673                   
1674                   points[j] = mapProj->inverse(eastingNorthing);
1675                   
1676                }
1677                else
1678                {
1679                   points[j] = ossimGpt(ogrPt.getY(),
1680                                        ogrPt.getX(),
1681                                        ogrPt.getZ(),
1682                                        origin.datum());
1683                }
1684             }
1685             ossimGeoAnnotationPolyObject* annotation =
1686                new ossimGeoAnnotationPolyObject(points,
1687                                                 theFillFlag,
1688                                                 color.getR(),
1689                                                 color.getG(),
1690                                                 color.getB(),
1691                                                 theThickness);
1692             annotation->setPolyType(ossimGeoAnnotationPolyObject::OSSIM_POLY_INTERIOR_RING);
1693       
1694             if(theImageGeometry.valid())
1695             {
1696                annotation->transform(theImageGeometry.get());
1697             }
1698
1699             theFeatureCacheTable.insert(make_pair(id,
1700                                              annotation));
1701
1702          }
1703       }
1704    }
1705}
1706
1707void ossimGdalOgrVectorAnnotation::loadLineString(long id, OGRLineString* lineString,
1708                                            ossimMapProjection* mapProj)
1709{
1710    int upper = lineString->getNumPoints();
1711    ossimGpt origin;
1712    if(theImageGeometry.valid()&&theImageGeometry->getProjection())
1713    {
1714       origin = theImageGeometry->getProjection()->origin();
1715    }
1716   
1717   ossimRgbVector color;
1718   
1719   if(theFillFlag)
1720   {
1721      color = theBrushColor;
1722   }
1723   else
1724   {
1725      color = thePenColor;
1726   }
1727   vector<ossimGpt> polyLine(upper);
1728   for(int i = 0; i < upper; ++i)
1729   {
1730      OGRPoint ogrPt;
1731     
1732      lineString->getPoint(i, &ogrPt);
1733     
1734      if(mapProj)
1735      {
1736         ossimDpt eastingNorthing(ogrPt.getX(),
1737                                  ogrPt.getY());
1738         
1739         polyLine[i] = mapProj->inverse(eastingNorthing);
1740      }
1741      else
1742      {
1743         polyLine[i] = ossimGpt(ogrPt.getY(),
1744                                ogrPt.getX(),
1745                                ogrPt.getZ(),
1746                                origin.datum());
1747      }
1748   }
1749   
1750   ossimGeoAnnotationPolyLineObject* annotation =
1751      new ossimGeoAnnotationPolyLineObject(polyLine,
1752                                           color.getR(),
1753                                           color.getG(),
1754                                           color.getB(),
1755                                           theThickness);
1756   if(theImageGeometry.valid())
1757   {
1758      annotation->transform(theImageGeometry.get());
1759   }
1760
1761   theFeatureCacheTable.insert(make_pair(id,
1762                                         annotation));
1763}
1764
1765void ossimGdalOgrVectorAnnotation::loadMultiLineString(long id, OGRMultiLineString* multiLineString,
1766   ossimMapProjection* mapProj)
1767{
1768   ossimRgbVector color;
1769
1770   if(theFillFlag)
1771   {
1772      color = theBrushColor;
1773   }
1774   else
1775   {
1776      color = thePenColor;
1777   }
1778
1779   ossim_uint32 numGeometries = multiLineString->getNumGeometries();
1780   ossimGpt origin;
1781   if(theImageGeometry.valid()&&theImageGeometry->getProjection())
1782   {
1783      origin = theImageGeometry->getProjection()->origin();
1784   }
1785
1786   vector<ossimGeoPolygon> geoPoly;
1787   for(ossim_uint32 geomIdx = 0; geomIdx < numGeometries; ++geomIdx)
1788   {
1789      OGRGeometry* geomRef = multiLineString->getGeometryRef(geomIdx);
1790      OGRLineString* lineString = (OGRLineString*)geomRef;
1791      if (lineString)
1792      {
1793         int upper = lineString->getNumPoints();
1794         vector<ossimGpt> polyLine(upper);
1795         for(int i = 0; i < upper; ++i)
1796         {
1797            OGRPoint ogrPt;
1798
1799            lineString->getPoint(i, &ogrPt);
1800
1801            if(mapProj)
1802            {
1803               ossimDpt eastingNorthing(ogrPt.getX(),
1804                  ogrPt.getY());
1805
1806               polyLine[i] = mapProj->inverse(eastingNorthing);
1807            }
1808            else
1809            {
1810               polyLine[i] = ossimGpt(ogrPt.getY(),
1811                  ogrPt.getX(),
1812                  ogrPt.getZ(),
1813                  origin.datum());
1814            }
1815         }
1816
1817         ossimGeoAnnotationPolyLineObject* annotation =
1818            new ossimGeoAnnotationPolyLineObject(polyLine,
1819            color.getR(),
1820            color.getG(),
1821            color.getB(),
1822            theThickness);
1823         if(theImageGeometry.valid())
1824         {
1825            annotation->transform(theImageGeometry.get());
1826         }
1827
1828         theFeatureCacheTable.insert(make_pair(id,
1829            annotation));
1830      }
1831   }
1832}
1833
1834void ossimGdalOgrVectorAnnotation::loadPoint(long id, OGRPoint* point, ossimMapProjection* mapProj)
1835{
1836   ossimGpt origin;
1837   ossimRgbVector color;
1838   
1839   if(theFillFlag)
1840   {
1841      color = theBrushColor;
1842   }
1843   else
1844   {
1845      color = thePenColor;
1846   }
1847   if(theImageGeometry.valid()&&theImageGeometry->getProjection())
1848   {
1849      origin = theImageGeometry->getProjection()->origin();
1850   }
1851   
1852   ossimGpt gpt;
1853   if(mapProj)
1854   {
1855      ossimDpt eastingNorthing(point->getX(),
1856                               point->getY());
1857     
1858      gpt = mapProj->inverse(eastingNorthing);
1859   }
1860   else
1861   {
1862      gpt = ossimGpt(point->getY(),
1863                     point->getX(),
1864                     point->getZ(),
1865                     origin.datum());
1866   }
1867   
1868   
1869   ossimGeoAnnotationEllipseObject* annotation =
1870      new ossimGeoAnnotationEllipseObject(gpt,
1871                                          thePointWidthHeight,
1872                                          theFillFlag,
1873                                          color.getR(),
1874                                          color.getG(),
1875                                          color.getB(),
1876                                          theThickness);
1877   if(theImageGeometry.valid())
1878   {
1879      annotation->transform(theImageGeometry.get());
1880   }
1881   theFeatureCacheTable.insert(make_pair(id, annotation));
1882}
1883
1884void ossimGdalOgrVectorAnnotation::loadMultiPoint(long id,
1885                                                  OGRMultiPoint* multiPoint,
1886                                                  ossimMapProjection* mapProj)
1887{
1888   ossim_uint32 numGeometries = multiPoint->getNumGeometries();
1889   ossimRgbVector color;
1890   
1891   if(theFillFlag)
1892   {
1893      color = theBrushColor;
1894   }
1895   else
1896   {
1897      color = thePenColor;
1898   }
1899   
1900   ossimGeoAnnotationMultiEllipseObject* annotation =
1901      new ossimGeoAnnotationMultiEllipseObject(thePointWidthHeight,
1902                                               theFillFlag,
1903                                               color.getR(),
1904                                               color.getG(),
1905                                               color.getB(),
1906                                               theThickness);
1907   ossimGpt origin;
1908   if(theImageGeometry.valid()&&theImageGeometry->getProjection())
1909   {
1910      origin = theImageGeometry->getProjection()->origin();
1911   }
1912   for(ossim_uint32 i = 0; i < numGeometries; ++i)
1913   {
1914      OGRGeometry* geomRef = multiPoint->getGeometryRef(i);
1915      if( geomRef &&
1916          ( (geomRef->getGeometryType()==wkbPoint) ||
1917            (geomRef->getGeometryType()==wkbPoint25D) ) )
1918      {
1919         OGRPoint* point = (OGRPoint*)geomRef;
1920         
1921         if(mapProj)
1922         {
1923            ossimDpt eastingNorthing(point->getX(),
1924                                     point->getY());
1925           
1926            annotation->addPoint(mapProj->inverse(eastingNorthing));
1927         }
1928         annotation->addPoint(ossimGpt(point->getY(),
1929                                       point->getX(),
1930                                       point->getZ(),
1931                                       origin.datum()));
1932      }
1933   }
1934   if(theImageGeometry.valid())
1935   {
1936      annotation->transform(theImageGeometry.get());
1937   }
1938
1939   theFeatureCacheTable.insert(make_pair(id, annotation));
1940}
1941
1942
1943void ossimGdalOgrVectorAnnotation::loadMultiPolygon(
1944   long id,
1945   OGRMultiPolygon* multiPolygon,
1946   ossimMapProjection* mapProj)
1947{
1948   ossimRgbVector color;
1949   
1950   if(theFillFlag)
1951   {
1952      color = theBrushColor;
1953   }
1954   else
1955   {
1956      color = thePenColor;
1957   }
1958   ossimGpt origin;
1959   ossim_uint32 numGeometries = multiPolygon->getNumGeometries();
1960
1961   if(theImageGeometry.valid()&&theImageGeometry->getProjection())
1962   {
1963      origin = theImageGeometry->getProjection()->origin();
1964   }
1965
1966   vector<ossimGeoPolygon> geoPoly;
1967   for(ossim_uint32 geomIdx = 0; geomIdx < numGeometries; ++geomIdx)
1968   {
1969      OGRGeometry* geomRef = multiPolygon->getGeometryRef(geomIdx);
1970      if( geomRef &&
1971          ( (geomRef->getGeometryType()==wkbPolygon) ||
1972            (geomRef->getGeometryType()==wkbPolygon25D) ) )
1973      {
1974         geoPoly.push_back(ossimGeoPolygon());
1975         OGRPolygon* poly = (OGRPolygon*)geomRef;
1976         OGRLinearRing* ring = poly->getExteriorRing();
1977         ossim_uint32 currentPoly = geoPoly.size()-1;
1978
1979         if(ring)
1980         {
1981            ossim_uint32 upper = ring->getNumPoints();
1982
1983            for(ossim_uint32 ringPointIdx = 0;
1984                ringPointIdx < upper;
1985                ++ringPointIdx)
1986            {
1987               OGRPoint ogrPt;
1988               ring->getPoint(ringPointIdx, &ogrPt);
1989               if(mapProj)
1990               {
1991                  geoPoly[currentPoly].addPoint(
1992                     mapProj->inverse(ossimDpt(ogrPt.getX(), ogrPt.getY())));
1993               }
1994               else
1995               {
1996                  geoPoly[currentPoly].addPoint(ogrPt.getY(),
1997                                                ogrPt.getX(),
1998                                                ogrPt.getZ(),
1999                                                origin.datum());
2000               }
2001            }
2002         }
2003         
2004         ossim_uint32 bound = poly->getNumInteriorRings();
2005
2006         if(bound)
2007         {
2008            for(ossim_uint32 interiorRingIdx = 0;
2009                interiorRingIdx < bound;
2010                ++interiorRingIdx)
2011            {
2012               ring = poly->getInteriorRing(interiorRingIdx);
2013
2014               if(ring)
2015               {
2016                  geoPoly.push_back(ossimGeoPolygon());
2017                  currentPoly = geoPoly.size()-1;
2018
2019                  ossim_uint32 upper = ring->getNumPoints();
2020
2021                  for(ossim_uint32 interiorRingPointIdx = 0;
2022                      interiorRingPointIdx < upper;
2023                      ++interiorRingPointIdx)
2024                  {
2025                     OGRPoint ogrPt;
2026                     ring->getPoint(interiorRingPointIdx, &ogrPt);
2027                     if(mapProj)
2028                     {
2029                        geoPoly[currentPoly].addPoint(
2030                           mapProj->inverse(ossimDpt(ogrPt.getX(),
2031                                                     ogrPt.getY())));
2032                     }
2033                     else
2034                     {
2035                        geoPoly[currentPoly].addPoint(ogrPt.getY(),
2036                                                      ogrPt.getX(),
2037                                                      ogrPt.getZ(),
2038                                                      origin.datum());
2039                     }
2040                  }
2041               }
2042            }
2043         }
2044      }
2045   }
2046   
2047   if(geoPoly.size())
2048   {
2049      ossimGeoAnnotationMultiPolyObject* annotation =
2050         new ossimGeoAnnotationMultiPolyObject(geoPoly,
2051                                               theFillFlag,
2052                                               color.getR(),
2053                                               color.getG(),
2054                                               color.getB(),
2055                                               theThickness);
2056      if(theImageGeometry.valid())
2057      {
2058         annotation->transform(theImageGeometry.get());
2059      }
2060
2061      theFeatureCacheTable.insert(make_pair(id, annotation));
2062   }
2063}
2064
2065bool ossimGdalOgrVectorAnnotation::open()
2066{
2067   return open(theFilename);
2068}
2069
2070bool ossimGdalOgrVectorAnnotation::isOpen()const
2071{
2072   return (theDataSource!=NULL);
2073}
2074
2075const ossimObject* ossimGdalOgrVectorAnnotation::getView()const
2076{
2077   return theImageGeometry.get();
2078}
2079
2080void ossimGdalOgrVectorAnnotation::setBrushColor(const ossimRgbVector& brushColor)
2081{
2082   theBrushColor = brushColor;
2083}
2084   
2085void ossimGdalOgrVectorAnnotation::setPenColor(const ossimRgbVector& penColor)
2086{
2087   thePenColor = penColor;
2088}
2089
2090ossimRgbVector ossimGdalOgrVectorAnnotation::getPenColor()const
2091{
2092   return thePenColor;
2093}
2094
2095ossimRgbVector ossimGdalOgrVectorAnnotation::getBrushColor()const
2096{
2097   return theBrushColor;
2098}
2099
2100double ossimGdalOgrVectorAnnotation::getPointRadius()const
2101{
2102   return thePointWidthHeight.x/2.0;
2103}
2104
2105void ossimGdalOgrVectorAnnotation::setPointRadius(double r)
2106{
2107   thePointWidthHeight = ossimDpt(fabs(r)*2, fabs(r)*2);
2108}
2109
2110bool ossimGdalOgrVectorAnnotation::getFillFlag()const
2111{
2112   return theFillFlag;
2113}
2114
2115void ossimGdalOgrVectorAnnotation::setFillFlag(bool flag)
2116{
2117   theFillFlag=flag;
2118}
2119
2120void ossimGdalOgrVectorAnnotation::setThickness(ossim_int32 thickness)
2121{
2122   if ( (thickness > 0) && (thickness < 256) )
2123   {
2124      theThickness = static_cast<ossim_uint8>(thickness);
2125   }
2126   else
2127   {
2128      ossimNotify(ossimNotifyLevel_WARN)
2129         << "ossimGdalOgrVectorAnnotation::setThickness range error: "
2130         << thickness
2131         << "\nValid range: 1 to 255"
2132         << std::endl;
2133   }
2134}
2135
2136ossim_int32 ossimGdalOgrVectorAnnotation::getThickness()const
2137{
2138   return static_cast<ossim_int32>(theThickness);
2139}
2140
2141void ossimGdalOgrVectorAnnotation::loadExternalGeometryFile()
2142{
2143   ossimFilename filename = theFilename;
2144   filename.setExtension(".geom");
2145   if(!filename.exists())
2146   {
2147      filename.setExtension(".GEOM");
2148      if(!filename.exists())
2149      {
2150         return;
2151      }
2152   }
2153
2154   ossimKeywordlist kwl;
2155   if(kwl.addFile(filename))
2156   {
2157      ossimRefPtr<ossimImageGeometry> geom = new ossimImageGeometry;
2158      geom->loadState(kwl);
2159      if(geom->getProjection())
2160      {
2161         theImageGeometry = geom;
2162         ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, theImageGeometry->getProjection());
2163         if (mapProj)
2164         {
2165            // drb...
2166            //mapProj->setUlGpt(mapProj->origin());
2167            theIsExternalGeomFlag = true;
2168
2169            if (traceDebug())
2170            {
2171               ossimNotify(ossimNotifyLevel_DEBUG)
2172                  << "ossimGdalOgrVectorAnnotation::loadExternalGeometryFile"
2173                  << " DEBUG:"
2174                  << "\nExternal projection loaded from geometry file."
2175                  << "\nProjection dump:" << std::endl;
2176               mapProj->print(ossimNotify(ossimNotifyLevel_DEBUG));
2177            }
2178         }
2179      }
2180   }
2181}
2182
2183void ossimGdalOgrVectorAnnotation::loadExternalImageGeometryFromXml()
2184{
2185   ossimFilename filename = theFilename;
2186   ossimString fileBase = filename.noExtension();
2187   ossimFilename xmlFile = ossimString(fileBase + ".xml");
2188   if (!xmlFile.exists())//try the xml file which includes the entire source file name
2189   {
2190      xmlFile = theFilename + ".xml";
2191   }
2192   if (!xmlFile.exists())
2193   {
2194      return;
2195   }
2196   ossimFgdcXmlDoc* fgdcXmlDoc = new ossimFgdcXmlDoc;
2197   if ( fgdcXmlDoc->open(xmlFile) )
2198   {
2199      ossimRefPtr<ossimProjection> proj = fgdcXmlDoc->getProjection();
2200      if ( proj.valid() )
2201      {
2202         theImageGeometry = new ossimImageGeometry;
2203         theImageGeometry->setProjection( proj.get() );
2204         theIsExternalGeomFlag = true;
2205      }
2206   }
2207   delete fgdcXmlDoc;
2208   fgdcXmlDoc = 0;
2209}
2210
2211void ossimGdalOgrVectorAnnotation::loadOmdFile()
2212{
2213   ossimFilename filename = theFilename;
2214   filename.setExtension(".omd");
2215   if(!filename.exists())
2216   {
2217      filename.setExtension(".OMD");
2218   }
2219
2220   if( filename.exists() )
2221   {
2222      ossimKeywordlist kwl;
2223      if( kwl.addFile(filename) )
2224      {
2225         //---
2226         // Because loadState can call open() we will not call it here to
2227         // avoid a circuliar loop.  This duplicates some code but is safer.
2228         //---
2229         const char* lookup = 0;
2230
2231         // Border:
2232         lookup = kwl.find(ossimKeywordNames::BORDER_SIZE_KW);
2233         if (lookup)
2234         {
2235            theBorderSize = ossimString(lookup).toDouble();
2236            ossimString unitPrefix = ossimKeywordNames::BORDER_SIZE_KW +
2237               ossimString(".");
2238     
2239            theBorderSizeUnits = (ossimUnitType)ossimUnitTypeLut::instance()->
2240               getEntryNumber(kwl, unitPrefix.c_str());
2241            if(theBorderSizeUnits != OSSIM_UNIT_UNKNOWN)
2242            {
2243               ossimUnitConversionTool unitConvert(theBorderSize,
2244                                                   theBorderSizeUnits);
2245         
2246               theBorderSize      = unitConvert.getValue(OSSIM_DEGREES);
2247               theBorderSizeUnits = OSSIM_DEGREES;
2248            }
2249            else // assume degrees
2250            {
2251               theBorderSizeUnits = OSSIM_DEGREES;
2252            }
2253         }
2254
2255         // Brush color:
2256         lookup = kwl.find(ossimKeywordNames::BRUSH_COLOR_KW);
2257         if (lookup)
2258         {
2259            int r, g, b;
2260            std::istringstream s(lookup);
2261            s>>r>>g>>b;
2262            theBrushColor = ossimRgbVector((ossim_uint8)r,
2263                                           (ossim_uint8)g,
2264                                           (ossim_uint8)b);
2265         }
2266         else
2267         {
2268            lookup = kwl.find(NORMALIZED_RGB_BRUSH_COLOR_KW);
2269            if (lookup)
2270            {
2271               ossim_float64 r;
2272               ossim_float64 g;
2273               ossim_float64 b;
2274               
2275               std::istringstream in(lookup);
2276               in >> r >> g >> b;
2277               
2278               if ( (r >= 0.0) && (r <=1.0) )
2279               {
2280                  theBrushColor.setR(static_cast<ossim_uint8>(r*255.0+0.5));
2281               }
2282               if ( (g >= 0.0) && (g <=1.0) )
2283               {
2284                  theBrushColor.setG(static_cast<ossim_uint8>(g*255.0+0.5));
2285               }
2286               if ( (b >= 0.0) && (b <=1.0) )
2287               {
2288                  theBrushColor.setB(static_cast<ossim_uint8>(b*255.0+0.5));
2289               }
2290            }
2291         }
2292
2293         // Fill:
2294         lookup = kwl.find(ossimKeywordNames::FILL_FLAG_KW);
2295         if (lookup)
2296         {
2297            theFillFlag = ossimString(lookup).toBool();
2298         }
2299         
2300         // Pen color:
2301         lookup = kwl.find(ossimKeywordNames::PEN_COLOR_KW);
2302         if (lookup)
2303         {
2304            int r, g, b;
2305            std::istringstream s(lookup);
2306            s>>r>>g>>b;
2307            thePenColor = ossimRgbVector((ossim_uint8)r,
2308                                         (ossim_uint8)g,
2309                                         (ossim_uint8)b);
2310         }
2311         else
2312         {
2313            lookup = kwl.find(NORMALIZED_RGB_PEN_COLOR_KW);
2314            if (lookup)
2315            {
2316               ossim_float64 r;
2317               ossim_float64 g;
2318               ossim_float64 b;
2319               
2320               std::istringstream in(lookup);
2321               in >> r >> g >> b;
2322               
2323               if ( (r >= 0.0) && (r <=1.0) )
2324               {
2325                  thePenColor.setR(static_cast<ossim_uint8>(r * 255.0 + 0.5));
2326               }
2327               if ( (g >= 0.0) && (g <=1.0) )
2328               {
2329                  thePenColor.setG(static_cast<ossim_uint8>(g * 255.0 + 0.5));
2330               }
2331               if ( (b >= 0.0) && (b <=1.0) )
2332               {
2333                  thePenColor.setB(static_cast<ossim_uint8>(b * 255.0 + 0.5));
2334               }
2335            }
2336         }
2337
2338         // Point size:
2339         lookup = kwl.find(ossimKeywordNames::POINT_WIDTH_HEIGHT_KW);
2340         if (!lookup)
2341         {
2342            lookup = kwl.find(POINT_SIZE_KW);
2343         }
2344         if (lookup)
2345         {
2346            ossim_float64 x;
2347            ossim_float64 y;
2348           
2349            std::istringstream in(lookup);
2350            in >> x >> y;
2351           
2352            if ( (x > 0.0) && (y > 0.0) )
2353            {
2354               thePointWidthHeight.x = x;
2355               thePointWidthHeight.y = y;
2356            }
2357         }
2358
2359         // Thickness:
2360         lookup = kwl.find(ossimKeywordNames::THICKNESS_KW);
2361         if (lookup)
2362         {
2363            setThickness(ossimString(lookup).toInt32());
2364         }
2365
2366         // Update the feature table.
2367         updateAnnotationSettings();
2368         
2369      } // matches: if( kwl.addFile(filename) )
2370     
2371   } // matches: if(filename.exists())
2372}
2373
2374void ossimGdalOgrVectorAnnotation::getDefaults()
2375{
2376   const char* lookup;
2377
2378   // Look for auto color flag:
2379   bool autocolors = false;
2380   lookup = ossimPreferences::instance()->
2381      findPreference(SHAPEFILE_COLORS_AUTO_KW);
2382   if (lookup)
2383   {
2384      autocolors = ossimString::toBool(ossimString(lookup));
2385   }
2386   
2387   if (autocolors)
2388   {
2389      // Ensure the static index is within bounds of the array.
2390      if (currentAutoColorArrayIndex >= AUTO_COLOR_ARRAY_COUNT)
2391      {
2392         currentAutoColorArrayIndex = 0;
2393      }
2394
2395      thePenColor.setR(autoColorArray[currentAutoColorArrayIndex].r);
2396      thePenColor.setG(autoColorArray[currentAutoColorArrayIndex].g);
2397      thePenColor.setB(autoColorArray[currentAutoColorArrayIndex].b);
2398
2399      theBrushColor.setR(autoColorArray[currentAutoColorArrayIndex].r);
2400      theBrushColor.setG(autoColorArray[currentAutoColorArrayIndex].g);
2401      theBrushColor.setB(autoColorArray[currentAutoColorArrayIndex].b);
2402     
2403      ++currentAutoColorArrayIndex;
2404      if (currentAutoColorArrayIndex >= AUTO_COLOR_ARRAY_COUNT)
2405      {
2406         currentAutoColorArrayIndex = 0;
2407      }
2408     
2409   } // End of: if (autocolors)
2410   else
2411   {
2412      // Look for pen color.
2413      lookup = ossimPreferences::instance()->
2414         findPreference(NORMALIZED_RGB_PEN_COLOR_KW);
2415      if (lookup)
2416      {
2417         ossim_float64 r;
2418         ossim_float64 g;
2419         ossim_float64 b;
2420         
2421         std::istringstream in(lookup);
2422         in >> r >> g >> b;
2423         
2424         if ( (r >= 0.0) && (r <=1.0) )
2425         {
2426            thePenColor.setR(static_cast<ossim_uint8>(r * 255.0 + 0.5));
2427         }
2428         if ( (g >= 0.0) && (g <=1.0) )
2429         {
2430            thePenColor.setG(static_cast<ossim_uint8>(g * 255.0 + 0.5));
2431         }
2432         if ( (b >= 0.0) && (b <=1.0) )
2433         {
2434            thePenColor.setB(static_cast<ossim_uint8>(b * 255.0 + 0.5));
2435         }
2436      }
2437     
2438      // Look for brush color.
2439      lookup = ossimPreferences::instance()->
2440         findPreference(NORMALIZED_RGB_BRUSH_COLOR_KW);
2441      if (lookup)
2442      {
2443         ossim_float64 r;
2444         ossim_float64 g;
2445         ossim_float64 b;
2446         
2447         std::istringstream in(lookup);
2448         in >> r >> g >> b;
2449         
2450         if ( (r >= 0.0) && (r <=1.0) )
2451         {
2452            theBrushColor.setR(static_cast<ossim_uint8>(r * 255.0 + 0.5));
2453         }
2454         if ( (g >= 0.0) && (g <=1.0) )
2455         {
2456            theBrushColor.setG(static_cast<ossim_uint8>(g * 255.0 + 0.5));
2457         }
2458         if ( (b >= 0.0) && (b <=1.0) )
2459         {
2460            theBrushColor.setB(static_cast<ossim_uint8>(b * 255.0 + 0.5));
2461         }
2462      }
2463     
2464   } // End of: if (autocolors){...}else{
2465
2466   // Look for point size.
2467   lookup = ossimPreferences::instance()->
2468      findPreference(POINT_SIZE_KW);
2469   if (lookup)
2470   {
2471      ossim_float64 x;
2472      ossim_float64 y;
2473     
2474      std::istringstream in(lookup);
2475      in >> x >> y;
2476
2477      if ( (x > 0.0) && (y > 0.0) )
2478      {
2479         thePointWidthHeight.x = x;
2480         thePointWidthHeight.y = y;
2481      }
2482   }   
2483}
2484
2485void ossimGdalOgrVectorAnnotation::verifyViewParams()
2486{
2487   if (!theImageGeometry.valid())
2488   {
2489      return;
2490   }
2491   
2492   ossimMapProjection* proj = PTR_CAST(ossimMapProjection,
2493                                       theImageGeometry->getProjection());
2494   if (!proj)
2495   {
2496      return;
2497   }
2498
2499   ossimGpt ulGpt = proj->getUlGpt();
2500   if ( ulGpt.isLatNan() || ulGpt.isLonNan() )
2501   {
2502      proj->setUlGpt( ossimGpt(theBoundingExtent.MaxY,
2503                               theBoundingExtent.MinX) );
2504   }
2505   
2506   if (proj->isGeographic())
2507   {
2508      ossimDpt pt = proj->getDecimalDegreesPerPixel();
2509      if( pt.hasNans() )
2510      {
2511         // roughly... 10 meters per pixel in decimal degrees.
2512         ossim_float64 d = 1.0 / 11131.49079;
2513         proj->setDecimalDegreesPerPixel(ossimDpt(d, d));
2514      }
2515
2516   }
2517   else
2518   {
2519      ossimDpt pt = proj->getMetersPerPixel();
2520      if (pt.hasNans())
2521      {
2522         proj->setMetersPerPixel(ossimDpt(10.0, 10.0));
2523      }
2524   }
2525}
2526
2527std::multimap<long, ossimAnnotationObject*> ossimGdalOgrVectorAnnotation::getFeatureTable()
2528{
2529   if (theFeatureCacheTable.size() == 0)
2530   {
2531      initializeTables();
2532   }
2533   return theFeatureCacheTable;
2534}
2535
2536bool ossimGdalOgrVectorAnnotation::setCurrentEntry(ossim_uint32 entryIdx)
2537{
2538   if (entryIdx < m_layerNames.size())
2539   {
2540      m_layerName = m_layerNames[entryIdx];
2541      return open(theFilename);
2542   }
2543   return false;
2544}
Note: See TracBrowser for help on using the repository browser.