OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimEsriShapeFileFilter.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: See LICENSE.txt file in the top level directory.
5 //
6 // Author: Garrett Potts
7 //
8 //*************************************************************************
9 // $Id: ossimEsriShapeFileFilter.cpp 19669 2011-05-27 13:27:29Z gpotts $
10 
11 #include <cstdio>
12 #include <cstdlib>
13 #include <sstream>
14 using namespace std;
15 
17 #include <ossimShapeFile.h>
23 #include <ossim/base/ossimTrace.h>
24 #include <ossim/base/ossimCommon.h>
27 #include <ossim/base/ossimTrace.h>
36 
38  "ossimEsriShapeFileFilter",
41 
42 static const ossimTrace traceDebug("ossimEsriShapeFileFilter:debug");
43 
45  :ossimAnnotationSource(inputSource),
47  theCoordinateSystem(OSSIM_GEOGRAPHIC_SPACE),
48  theUnitType(OSSIM_METERS),
49  theTree((SHPTree*)0),
50  theMaxQuadTreeLevels(10),
51  thePenColor(255,255,255),
52  theBrushColor(255,255,255),
53  theFillFlag(false),
54  theThickness(1),
55  thePointWidthHeight(1, 1),
56  theBorderSize(0.0),
57  theBorderSizeUnits(OSSIM_DEGREES)
58 {
64 }
65 
67 {
69 
70  if(theTree)
71  {
72  SHPDestroyTree(theTree);
73  }
74 
75  deleteCache();
76 }
77 
79 {
80  ossimProjection* proj = PTR_CAST(ossimProjection, baseObject);
81  if(proj)
82  {
84  {
86  }
87  else
88  {
89  theImageGeometry = new ossimImageGeometry(0, proj);
90  }
91  return true;
92  }
93  else
94  {
95  ossimImageGeometry* geom = dynamic_cast<ossimImageGeometry*> (baseObject);
96  if(geom)
97  {
98  theImageGeometry = geom;
99  return true;
100  }
101  }
102 
103  return false;
104 }
105 
107 {
108  return theImageGeometry.get();
109 }
110 
112 {
113  return theImageGeometry.get();
114 }
115 
117 {
119  << "ossimEsriShapeFileFilter::addObject\n"
120  << "Can't add objects to layer, must go through Esri loadShapeFile"
121  <<endl;
122 
123  return false;
124 }
125 
127 {
128 // ossimAnnotationSource::computeBoundingRect();
129 
130  std::multimap<int, ossimAnnotationObject*>::iterator iter = theShapeCache.begin();
131 
133  while(iter != theShapeCache.end())
134  {
135  ossimDrect rect = (*iter).second->getBoundingRect();
137  {
138  theBoundingRect = rect;
139  }
140  else
141  {
142  if(!rect.hasNans())
143  {
145  }
146  }
147 
148  ++iter;
149  }
150 }
151 
153 {
154  if(!isSourceEnabled()||
155  getInput())
156  {
157  if(getInput())
158  {
160  if(input)
161  {
162  return input->getBoundingRect(resLevel);
163  }
164  }
165  }
166  return theBoundingRect;
167 }
168 
170 {
172 
173  if (!theTree||!theShapeFile.isOpen()) return;
174  if(theImageGeometry.valid())
175  {
176  ossimIrect rect = tile->getImageRectangle();
177 
178  rect = ossimIrect(rect.ul().x,
179  rect.ul().y,
180  rect.lr().x,
181  rect.lr().y);
182  double boundsMin[2];
183  double boundsMax[2];
184 
185  ossimGpt gp1;
186  ossimGpt gp2;
187  ossimGpt gp3;
188  ossimGpt gp4;
189 
191  gp1);
193  gp2);
195  gp3);
197  gp4);
198 
199  ossimDrect boundsRect( ossimDpt(gp1.lond(),
200  gp1.latd()),
201  ossimDpt(gp2.lond(),
202  gp2.latd()),
203  ossimDpt(gp3.lond(),
204  gp3.latd()),
205  ossimDpt(gp4.lond(),
206  gp4.latd()),
208 
209  boundsMin[0] = boundsRect.ul().x;
210  boundsMin[1] = boundsRect.lr().y;
211 
212  boundsMax[0] = boundsRect.lr().x;
213  boundsMax[1] = boundsRect.ul().y;
214 
215  int n;
216  int *array=(int*)0;
217 
219  boundsMin,
220  boundsMax,
221  &n);
222 
224  if(n&&array)
225  {
226  for(int i = 0; i < n; ++i)
227  {
228  std::multimap<int, ossimAnnotationObject*>::iterator iter = theShapeCache.find(array[i]);
229  while( ((*iter).first == array[i]) && (iter != theShapeCache.end()) )
230  {
231  (*iter).second->draw(*theImage);
232  ++iter;
233  }
234  }
235 
236  free(array);
237  }
238  }
239 }
240 
242 {
243  std::multimap<int, ossimAnnotationObject*>::iterator iter = theShapeCache.begin();
244 
245 
247  if(geom)
248  {
249  tempGeom = geom;
250  }
251 
252  if(!tempGeom) return;
253 
254  while(iter != theShapeCache.end())
255  {
257  (*iter).second);
258  if(obj)
259  {
260  obj->transform(tempGeom);
261  }
262  ++iter;
263  }
264 
266 }
267 
269 {
270  theImageGeometry = geom;
272 }
273 
274 //**************************************************************************************************
277 //**************************************************************************************************
279 {
280  if( !theImageGeometry )
281  {
283  }
284  return theImageGeometry;
285 }
286 
288 {
289  theImageGeometry = 0;
290 }
291 
293 {
294  std::multimap<int, ossimAnnotationObject*>::iterator iter = theShapeCache.begin();
295 
296 
297  while(iter != theShapeCache.end())
298  {
299  if ((*iter).second)
300  {
301  (*iter).second->unref();
302  }
303  ++iter;
304  }
305 
306  theShapeCache.clear();
307 }
308 
310 {
311  if(!theImageGeometry.valid())
312  {
314  if(theImageGeometry.valid())
315  {
317  }
318  }
319 }
320 
322 {
323  if(theTree)
324  {
325  SHPDestroyTree(theTree);
326  theTree = (SHPTree*)0;
327  }
328  theShapeFile.open(shapeFile);
329  deleteCache();
330  deleteAll();
331 
332  if(theShapeFile.isOpen())
333  {
336 
338  2,
340  theMinArray,
341  theMaxArray);
342 
343  ossimShapeObject obj;
344  for(int index = 0 ; index < theShapeFile.getNumberOfShapes(); ++index)
345  {
347  index);
348 
349  if(obj.isLoaded())
350  {
351  switch(obj.getType())
352  {
353  case SHPT_POLYGON:
354  case SHPT_POLYGONZ:
355  {
356  loadPolygon(obj);
357  break;
358  }
359  case SHPT_POINT:
360  case SHPT_POINTZ:
361  {
362  loadPoint(obj);
363  break;
364  }
365  case SHPT_ARC:
366  case SHPT_ARCZ:
367  {
368  loadArc(obj);
369  break;
370  }
371  case SHPT_NULL:
372  {
373  break;
374  }
375  default:
376  {
378  << "ossimEsriShapeFileFilter::loadShapeFile\n"
379  << "SHAPE " << obj.getTypeByName()
380  << " Not supported" << endl;
381  break;
382  }
383  }
384  }
385  }
386 
387  theCurrentObject = theShapeCache .begin();
388  if(theImageGeometry.valid())
389  {
391  }
392  else
393  {
395  }
396  }
397 
398  return true;
399 }
400 
402 {
403  int starti = 0;
404  int endi = 0;
405  if(obj.getNumberOfParts() > 1)
406  {
407  starti = obj.getShapeObject()->panPartStart[0];
408  endi = obj.getShapeObject()->panPartStart[1];
409  }
410  else
411  {
412  starti = 0;
413  endi = obj.getShapeObject()->nVertices;
414  }
415 
416  vector<ossimGpt> groundPolygon;
417  for(ossim_uint32 part = 0; part < obj.getNumberOfParts(); ++part)
418  {
419  if(obj.getPartType(part) != SHPP_RING)
420  {
422  << "ossimEsriShapeFileFilter::loadPolygon\n"
423  << "Part = " << obj.getPartByName(part)
424  << " not supported for shape = "
425  << obj.getTypeByName() << endl;
426  break;
427  }
428  groundPolygon.clear();
429  for(ossim_int32 vertexNumber = starti; vertexNumber < endi; ++vertexNumber)
430  {
431  groundPolygon.push_back(ossimGpt(obj.getShapeObject()->padfY[vertexNumber],
432  obj.getShapeObject()->padfX[vertexNumber]));
433 
434  }
435  starti = endi;
436  if((part + 2) < obj.getNumberOfParts())
437  {
438  endi = obj.getShapeObject()->panPartStart[part+2];
439  }
440  else
441  {
442  endi = obj.getShapeObject()->nVertices;
443  }
444 
445  ossimRgbVector color;
446 
447  if(theFillFlag)
448  {
449  color = theBrushColor;
450  }
451  else
452  {
453  color = thePenColor;
454  }
455 
456  if(theBorderSize != 0.0)
457  {
458  ossimGeoPolygon tempPoly(groundPolygon);
459  ossimGeoPolygon tempPoly2;
460 
461  tempPoly.stretchOut(tempPoly2,
462  theBorderSize);
463  groundPolygon = tempPoly2.getVertexList();
464 
465  }
466 
467  ossimGeoAnnotationObject *newGeoObj = new ossimGeoAnnotationPolyObject(groundPolygon,
468  theFillFlag,
469  color.getR(),
470  color.getG(),
471  color.getB(),
472  theThickness);
473  newGeoObj->setName(theFeatureName);
474  theShapeCache.insert(make_pair(obj.getId(),
475  newGeoObj));
476  }
477 }
478 
480 {
481  int n = obj.getNumberOfVertices();
482 
483  if(n)
484  {
485  ossimGpt gpt(obj.getShapeObject()->padfY[0],
486  obj.getShapeObject()->padfX[0]);
487 
488  ossimRgbVector color;
489 
490  if(theFillFlag)
491  {
492  color = theBrushColor;
493  }
494  else
495  {
496  color = thePenColor;
497  }
501  theFillFlag,
502  color.getR(),
503  color.getG(),
504  color.getB(),
505  theThickness);
507  newGeoObj->setName(theFeatureName);
508  theShapeCache.insert(make_pair(obj.getId(),
509  newGeoObj));
510 
511  }
512 }
513 
515 {
516  int starti = 0;
517  int endi = 0;
518  if(obj.getNumberOfParts() > 1)
519  {
520  starti = obj.getShapeObject()->panPartStart[0];
521  endi = obj.getShapeObject()->panPartStart[1];
522  }
523  else
524  {
525  starti = 0;
526  endi = obj.getShapeObject()->nVertices;
527  }
528 
529  vector<ossimGpt> groundPolygon;
530  for(ossim_uint32 part = 0; part < obj.getNumberOfParts(); ++part)
531  {
532  if(obj.getPartType(part) != SHPP_RING)
533  {
535  << "ossimEsriShapeFileFilter::loadArc\n"
536  << "Part = " << obj.getPartByName(part)
537  << " not supported for shape = "
538  << obj.getTypeByName() << endl;
539  break;
540  }
541  groundPolygon.clear();
542  for(ossim_int32 vertexNumber = starti; vertexNumber < endi; ++vertexNumber)
543  {
544  groundPolygon.push_back(ossimGpt(obj.getShapeObject()->padfY[vertexNumber],
545  obj.getShapeObject()->padfX[vertexNumber]));
546 
547  }
548  starti = endi;
549  if((part + 2) < obj.getNumberOfParts())
550  {
551  endi = obj.getShapeObject()->panPartStart[part+2];
552  }
553  else
554  {
555  endi = obj.getShapeObject()->nVertices;
556  }
557 
558  ossimRgbVector color;
559 
560  if(theFillFlag)
561  {
562  color = theBrushColor;
563  }
564  else
565  {
566  color = thePenColor;
567  }
568 
569  ossimGeoAnnotationObject *newGeoObj = new ossimGeoAnnotationPolyLineObject(groundPolygon,
570  color.getR(),
571  color.getG(),
572  color.getB(),
573  theThickness);
574  newGeoObj->setName(theFeatureName);
575  theShapeCache.insert(make_pair(obj.getId(),
576  newGeoObj));
577  }
578 }
579 
581  const char* prefix)const
582 {
583  ossimString s;
584 
585  kwl.add(prefix,
588  true);
589 
590  kwl.add(prefix,
593  true);
594 
595  s = ossimString::toString((int)thePenColor.getR()) + " " +
596  ossimString::toString((int)thePenColor.getG()) + " " +
598 
599  kwl.add(prefix,
601  s.c_str(),
602  true);
603 
604  s = ossimString::toString((int)theBrushColor.getR()) + " " +
607 
608  kwl.add(prefix,
610  s.c_str(),
611  true);
612 
613  kwl.add(prefix,
615  (int)theFillFlag,
616  true);
617 
618  kwl.add(prefix,
621  true);
622 
623  kwl.add(prefix,
625  theThickness,
626  true);
627 
628  ossimString border;
630  border += " degrees";
631  kwl.add(prefix,
633  border,
634  true);
635 
638 
639  kwl.add(prefix,
641  s.c_str(),
642  true);
643 
644  if(theImageGeometry.valid())
645  {
646  ossimString newPrefix = prefix;
647  newPrefix += "view_proj.";
648  theImageGeometry->saveState(kwl, newPrefix.c_str());
649  }
650 
651  return ossimAnnotationSource::saveState(kwl, prefix);
652 }
653 
655  const char* prefix)
656 {
657 
658  const char* quadLevels = kwl.find(prefix, ossimKeywordNames::MAX_QUADTREE_LEVELS_KW);
659  const char* filename = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
660  const char* penColor = kwl.find(prefix, ossimKeywordNames::PEN_COLOR_KW);
661  const char* brushColor = kwl.find(prefix, ossimKeywordNames::BRUSH_COLOR_KW);
662  const char* featureName = kwl.find(prefix, ossimKeywordNames::FEATURE_NAME_KW);
663  const char* fillFlag = kwl.find(prefix, ossimKeywordNames::FILL_FLAG_KW);
664  const char* thickness = kwl.find(prefix, ossimKeywordNames::THICKNESS_KW);
665  const char* pointWh = kwl.find(prefix, ossimKeywordNames::POINT_WIDTH_HEIGHT_KW);
666  const char* border_size = kwl.find(prefix, ossimKeywordNames::BORDER_SIZE_KW);
667 
668  deleteCache();
669 
670  if(thickness)
671  {
672  theThickness = ossimString(thickness).toLong();
673  }
674  if(quadLevels)
675  {
676  theMaxQuadTreeLevels = ossimString(quadLevels).toLong();
677  }
678 
679  if(penColor)
680  {
681  int r, g, b;
682  istringstream s(penColor);
683  s>>r>>g>>b;
685  }
686 
687  if(brushColor)
688  {
689  int r, g, b;
690  istringstream s(brushColor);
691  s>>r>>g>>b;
693  }
694  if(pointWh)
695  {
696  double w, h;
697  istringstream s(pointWh);
698  s>>w>>h;
700  }
701 
702  if(fillFlag)
703  {
704  theFillFlag = ossimString(fillFlag).toBool();
705  }
706 
707  if(border_size)
708  {
709  istringstream input(border_size);
710 
711  ossimString s;
712  input >> s;
713 
714  theBorderSize = s.toDouble();
715 
716  ossimString s2;
717 
718  input >> s2;
719 
720  s2 = s2.upcase();
721 
722  if(s2 == "US")
723  {
725  }
726  else if(s2 == "METERS")
727  {
729  }
730  else if(s2 == "FEET")
731  {
733  }
734  else
735  {
737  }
740 
741  theBorderSize = unitConvert.getValue(OSSIM_DEGREES);
743  }
744  else
745  {
746  theBorderSize = 0.0;
748  }
749 
750  theFeatureName = featureName;
751 
752  ossimString newPrefix = prefix;
753  newPrefix += "view_proj.";
754 
756  if(!theImageGeometry->loadState(kwl, newPrefix.c_str()))
757  {
758  theImageGeometry = 0;
759  }
760 
761  if(filename)
762  {
763  loadShapeFile(ossimFilename(filename));
764  }
765 
767 
768  return ossimAnnotationSource::loadState(kwl, prefix);
769 }
virtual void loadPoint(ossimShapeObject &obj)
void clear()
Erases the entire container.
Definition: ossimString.h:432
void makeNan()
Definition: ossimDrect.h:388
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
virtual bool isSourceEnabled() const
Definition: ossimSource.cpp:79
ossimObject * theObject
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
This will return the bounding rect of the source.
#define SHPT_ARC
Definition: shapefil.h:247
virtual void setName(const ossimString &name)
int getPartType(ossim_uint32 partIndex) const
double getValue(ossimUnitType unitType=OSSIM_METERS) const
static const char * BRUSH_COLOR_KW
void setProjection(ossimProjection *projection)
Sets the projection to be used for local-to-world coordinate transformation.
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
ossimString getTypeByName() const
unsigned char getR() const
ossim_uint32 getNumberOfParts() const
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
virtual void setEllipseWidthHeightUnitType(ossimUnitType type)
void stretchOut(ossimGeoPolygon &newPolygon, double displacement)
virtual SHPHandle getHandle()
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Attempts to initialize a transform and a projection given the KWL.
const char * find(const char *key) const
long getId() const
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
const ossimDpt & ul() const
Definition: ossimDrect.h:339
double y
Definition: ossimDpt.h:165
#define SHPT_ARCZ
Definition: shapefil.h:251
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if non defined...
static ossimString toString(bool aValue)
Numeric to string methods.
RTTI_DEF2(ossimEsriShapeFileFilter, "ossimEsriShapeFileFilter", ossimAnnotationSource, ossimViewInterface)
virtual void setImageGeometry(ossimImageGeometry *projection)
virtual void transform(ossimImageGeometry *projection)=0
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual bool open(const ossimFilename &file, const ossimString &flags=ossimString("rb"))
ossimDrect combine(const ossimDrect &rect) const
Definition: ossimDrect.h:826
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
const ossimIpt & ll() const
Definition: ossimIrect.h:277
virtual void setNumberOfBands(ossim_uint32 bands)
ossimEsriShapeFileFilter(ossimImageSource *inputSource=NULL)
static const char * MAX_QUADTREE_LEVELS_KW
ossimConnectableObject * getInput(ossim_uint32 index=0)
returns the object at the specified index.
static const char * FEATURE_NAME_KW
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
double * padfY
Definition: shapefil.h:289
int SHPAPI_CALL1 * SHPTreeFindLikelyShapes(SHPTree *hTree, double *padfBoundsMin, double *padfBoundsMax, int *);int SHPAPI_CALL SHPCheckBoundsOverlap(double *, double *, double *, double *, int
int nVertices
Definition: shapefil.h:287
SHPTree SHPAPI_CALL1 * SHPCreateTree(SHPHandle hSHP, int nDimension, int nMaxDepth, double *padfBoundsMin, double *padfBoundsMax);void SHPAPI_CALL SHPDestroyTree(SHPTree *hTree
virtual bool loadShapeFile(const ossimFilename &shapeFile)
bool loadShape(const ossimShapeFile &shapeFile, long shapeRecord)
bool localToWorld(const ossimDpt &local_pt, ossimGpt &world_pt) const
Exposes the 3D projection from image to world coordinates.
ossim_uint32 getNumberOfVertices() const
os2<< "> n<< " > nendobj n
virtual void drawAnnotations(ossimRefPtr< ossimImageData > tile)
bool toBool() const
String to numeric methods.
unsigned int ossim_uint32
static const char * FILL_FLAG_KW
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
static const char * BORDER_SIZE_KW
std::multimap< int, ossimAnnotationObject * > theShapeCache
virtual ossimIrect getImageRectangle() const
#define SHPP_RING
Definition: shapefil.h:271
const std::vector< ossimGpt > & getVertexList() const
unsigned char getB() const
const ossimIpt & lr() const
Definition: ossimIrect.h:276
ossimString getPartByName(ossim_uint32 partIndex) const
virtual void loadPolygon(ossimShapeObject &obj)
ossimRefPtr< ossimImageGeometry > theImageGeometry
#define SHPT_POINTZ
Definition: shapefil.h:250
bool hasNans() const
Definition: ossimDrect.h:396
int * panPartStart
Definition: shapefil.h:284
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
const ossimIpt & ur() const
Definition: ossimIrect.h:275
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
std::multimap< int, ossimAnnotationObject * >::iterator theCurrentObject
unsigned char getG() const
long toLong() const
toLong&#39;s deprecated, please use the toInts...
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=NULL)
void getBounds(double &minX, double &minY, double &minZ, double &minM, double &maxX, double &maxY, double &maxZ, double &maxM) const
ossim_int32 y
Definition: ossimIpt.h:142
#define SHPT_POINT
Definition: shapefil.h:246
double * padfX
Definition: shapefil.h:288
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
ossimRefPtr< ossimRgbImage > theImage
virtual bool setView(ossimObject *baseObject)
virtual bool addObject(ossimAnnotationObject *anObject)
virtual long getNumberOfShapes() const
double x
Definition: ossimDpt.h:164
#define SHPT_NULL
Definition: shapefil.h:245
#define SHPT_POLYGON
Definition: shapefil.h:248
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
static const char * PEN_COLOR_KW
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Saves the transform (if any) and projection (if any) states to the KWL.
ossim_int32 x
Definition: ossimIpt.h:141
SHPObject * getShapeObject()
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
static const char * POINT_WIDTH_HEIGHT_KW
void setCurrentImageData(ossimRefPtr< ossimImageData > &imageData)
Allows you to change the image data that this RgbImage object operates on.
const ossimDpt & lr() const
Definition: ossimDrect.h:341
static const char * FILENAME_KW
static const char * THICKNESS_KW
bool isOpen() const
const ossimFilename & getFilename() const
virtual void loadArc(ossimShapeObject &obj)
unsigned char ossim_uint8
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
virtual void drawAnnotations(ossimRefPtr< ossimImageData > tile)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=NULL) const
virtual void transformObjects(ossimImageGeometry *geom=0)
int ossim_int32
#define SHPT_POLYGONZ
Definition: shapefil.h:252