1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkGeoFileTerrainSource.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /*-------------------------------------------------------------------------
16   Copyright 2008 Sandia Corporation.
17   Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
18   the U.S. Government retains certain rights in this software.
19 -------------------------------------------------------------------------*/
20 
21 #include "vtkGeoFileTerrainSource.h"
22 
23 #include "vtkGeoTerrainNode.h"
24 #include "vtkObjectFactory.h"
25 #include "vtkPointData.h"
26 #include "vtkPolyData.h"
27 #include "vtkSmartPointer.h"
28 #include "vtkStdString.h"
29 #include "vtkXMLPolyDataReader.h"
30 
31 #include <fstream>
32 #include <sstream>
33 #include <utility>
34 
35 vtkStandardNewMacro(vtkGeoFileTerrainSource);
36 //----------------------------------------------------------------------------
vtkGeoFileTerrainSource()37 vtkGeoFileTerrainSource::vtkGeoFileTerrainSource()
38 {
39   VTK_LEGACY_BODY(vtkGeoFileTerrainSource::vtkGeoFileTerrainSource, "VTK 8.2");
40   this->Path = nullptr;
41 }
42 
43 //----------------------------------------------------------------------------
~vtkGeoFileTerrainSource()44 vtkGeoFileTerrainSource::~vtkGeoFileTerrainSource()
45 {
46   this->SetPath(nullptr);
47 }
48 
49 //----------------------------------------------------------------------------
FetchRoot(vtkGeoTreeNode * r)50 bool vtkGeoFileTerrainSource::FetchRoot(vtkGeoTreeNode* r)
51 {
52   vtkGeoTerrainNode* root = nullptr;
53   if (!(root = vtkGeoTerrainNode::SafeDownCast(r)))
54   {
55     vtkErrorMacro(<< "Can only fetch terrain nodes from this source.");
56     return false;
57   }
58 
59   this->ReadModel(0, 0, root);
60   return true;
61 }
62 
63 //----------------------------------------------------------------------------
FetchChild(vtkGeoTreeNode * p,int index,vtkGeoTreeNode * c)64 bool vtkGeoFileTerrainSource::FetchChild(vtkGeoTreeNode* p, int index, vtkGeoTreeNode* c)
65 {
66   vtkGeoTerrainNode* parent = nullptr;
67   if (!(parent = vtkGeoTerrainNode::SafeDownCast(p)))
68   {
69     vtkErrorMacro(<< "Can only fetch terrain nodes from this source.");
70     return false;
71   }
72   vtkGeoTerrainNode* child = nullptr;
73   if (!(child = vtkGeoTerrainNode::SafeDownCast(c)))
74   {
75     vtkErrorMacro(<< "Can only fetch terrain nodes from this source.");
76     return false;
77   }
78 
79   int level = parent->GetLevel() + 1;
80   int id = parent->GetId() | (index << (2*level-2));
81   return this->ReadModel(level, id, child);
82 }
83 
84 //----------------------------------------------------------------------------
ReadModel(int level,int id,vtkGeoTerrainNode * node)85 bool vtkGeoFileTerrainSource::ReadModel(int level, int id, vtkGeoTerrainNode* node)
86 {
87   // Load the image
88   node->SetId(id);
89   node->SetLevel(level);
90   vtkSmartPointer<vtkXMLPolyDataReader> reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();
91   std::stringstream ss;
92   ss.str("");
93   ss << this->Path << "/tile_" << level << "_" << id << ".vtp";
94 
95   // Check if the file exists
96   std::ifstream in;
97   in.open(ss.str().c_str(), std::ifstream::in);
98   if (in.fail())
99   {
100     // Make a dummy polydata
101     in.close();
102     vtkSmartPointer<vtkPolyData> dummy = vtkSmartPointer<vtkPolyData>::New();
103     node->SetModel(dummy);
104     return false;
105   }
106   in.close();
107 
108   // Read the file
109   reader->SetFileName(ss.str().c_str());
110   reader->Update();
111   vtkPolyData* model = reader->GetOutput();
112   node->SetModel(model);
113 
114   double lonRange[2] = {0.0, 0.0};
115   double latRange[2] = {0.0, 0.0};
116   double xRange[2] = {0.0, 0.0};
117   double yRange[2] = {0.0, 0.0};
118   if (model->GetNumberOfPoints() > 0)
119   {
120     model->GetPointData()->GetArray("LatLong")->GetRange(latRange, 0);
121     model->GetPointData()->GetArray("LatLong")->GetRange(lonRange, 1);
122     model->GetPoints()->GetData()->GetRange(xRange, 0);
123     model->GetPoints()->GetData()->GetRange(yRange, 1);
124   }
125   node->SetLatitudeRange(latRange);
126   node->SetLongitudeRange(lonRange);
127   node->SetProjectionBounds(xRange[0], xRange[1], yRange[0], yRange[1]);
128   node->UpdateBoundingSphere();
129 
130   return true;
131 }
132 
133 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)134 void vtkGeoFileTerrainSource::PrintSelf(ostream& os, vtkIndent indent)
135 {
136   this->Superclass::PrintSelf(os, indent);
137   os << indent << "Path: " << (this->Path ? this->Path : "(none)") << endl;
138 }
139