OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
TiePoint.cpp
Go to the documentation of this file.
1 //**************************************************************************************************
2 //
3 // OSSIM Open Source Geospatial Data Processing Library
4 // See top level LICENSE.txt file for license information
5 //
6 //**************************************************************************************************
7 
8 #include <ossim/reg/TiePoint.h>
10 #include <ctime>
11 
12 using namespace std;
13 
14 namespace ossim
15 {
16 int TiePoint::s_runningId = 1;
17 
18 TiePoint::TiePoint()
19 : m_type (UNASSIGNED),
20  m_gsd (0.0)
21 {
22 
23 }
24 
26 : m_type (copy.m_type),
27  m_gsd (copy.m_gsd),
28  m_gcpId (copy.m_gcpId)
29 {
30  for (size_t i=0; i<copy.m_images.size(); ++i)
31  m_images.push_back(copy.m_images[i]);
32 
33  for (size_t i=0; i<copy.m_imagePoints.size(); ++i)
34  m_imagePoints.push_back(copy.m_imagePoints[i]);
35 
36  for (size_t i=0; i<copy.m_covariances.size(); ++i)
37  m_covariances.push_back(copy.m_covariances[i]);
38 }
39 
40 TiePoint::TiePoint(const Json::Value& json_node)
41 : m_type (UNASSIGNED),
42  m_gsd (0.0)
43 {
44  loadJSON(json_node);
45 }
46 
48 {
49  m_images.clear();
50  m_imagePoints.clear();
51  m_covariances.clear();
52 }
53 
54 void TiePoint::setTiePointId(const string& id)
55 {
56  if (id.empty())
57  {
58  // Generate ID based on date/time:
59  ostringstream tp1;
60  tp1<<"TP"<<s_runningId++;
61  m_tiePointId = tp1.str();
62  }
63  else
64  {
65  // Only accept if there is no ID existing:
66  m_tiePointId = id;
67  }
68 }
69 
70 void TiePoint::getImagePoint(unsigned int index,
71  std::string& imageId,
72  ossimDpt& imagePoint,
73  NEWMAT::SymmetricMatrix& cov) const
74 {
75  // Search the PB index list for entry:
76  imagePoint.makeNan();
77  imageId.clear();
78 
79  if (index >= m_images.size())
80  return;
81 
82  imageId = m_images[index]->getImageId();
83  imagePoint = m_imagePoints[index];
84  if (m_covariances.size() > index)
85  cov = m_covariances[index];
86 }
87 
88 void TiePoint::setImagePoint(std::shared_ptr<Image> image,
89  const ossimDpt& imagePoint,
90  const NEWMAT::SymmetricMatrix& cov)
91 {
92  bool found = false;
93 
94  // Possible edit of existing point?
95  for (size_t i=0; i<m_images.size(); ++i)
96  {
97  if (m_images[i]->getImageId().compare(image->getImageId()) == 0)
98  {
99  found = true;
100  if (i >= m_imagePoints.size())
101  {
102  // This shouldn't happen, but go ahead and resize for this image:
103  m_imagePoints.resize(i+1);
104  m_covariances.resize(i+1);
105  }
106  m_imagePoints[i] = imagePoint;
107  m_covariances[i] = cov;
108  break;
109  }
110  }
111 
112  if (!found)
113  {
114  m_images.push_back(image);
115  m_imagePoints.push_back(imagePoint);
116  m_covariances.push_back(cov);
117  }
118 }
119 
120 void TiePoint::setGcpId(const std::string& id)
121 {
122  m_gcpId = id;
123  m_type = GCP;
124 }
125 
126 void TiePoint::loadJSON(const Json::Value& json_node)
127 {
128  ostringstream xmsg;
129  xmsg<<__FILE__<<": TiePoint(JSON) --";
130 
131  // ID
132  setTiePointId(json_node["id"].asString());
133 
134  // Type
135  string tpType = json_node["type"].asString();
136  switch (tpType[0])
137  {
138  case 'M':
140  break;
141  case 'A':
143  break;
144  case 'G':
146  break;
147  default:
148  xmsg<<"Tiepoint JSON field \"type\" must be specified as 'M', 'A', or 'G'.";
149  throw ossimException(xmsg.str());
150  }
151 
152  // Read the GCP ID if present:
153  if (m_type == TiePoint::GCP)
154  m_gcpId = json_node["gcpId"].asString();
155 
156  // Image points
157  const Json::Value& imagePoints = json_node["imagePoints"];
158  if (!imagePoints || (imagePoints.size() < 1))
159  {
160  xmsg<<"Tiepoint JSON field \"imagePoints\" not found or is empty!";
161  throw ossimException(xmsg.str());
162  }
163 
164  // Loop over points on each image:
165  for (int i=0; i<imagePoints.size(); ++i)
166  {
167  const Json::Value& p = imagePoints[i];
168  if (!p || !(p["imageId"].isString()) || !(p["x"]) || !(p["y"]))
169  {
170  xmsg<<"Tiepoint JSON field \"imagePoints\" entry is ill-formed or not complete:\n"
171  <<p.toStyledString()<<endl;
172  throw ossimException(xmsg.str());
173  }
174 
175  string imageId = p["imageId"].asString();
176  string filename = p["filename"].asString();
177  shared_ptr<Image> image (new Image(imageId, filename));
178  m_images.push_back(image);
179 
180  ossimDpt xy(p["x"].asDouble(), p["y"].asDouble());
181  m_imagePoints.push_back(xy);
182 
183  const Json::Value& covariance = p["covariance"];
184  if (covariance.size() == 3)
185  {
186  NEWMAT::SymmetricMatrix c(2);
187  c(1, 1) = covariance[0].asDouble();
188  c(2, 2) = covariance[1].asDouble();
189  c(1, 2) = covariance[2].asDouble();
190  m_covariances.push_back(c);
191  }
192  }
193 }
194 
195 void TiePoint::saveJSON(Json::Value& json_node) const
196 {
197  // ID
198  json_node["id"] = m_tiePointId;
199 
200  // Type
201  string tpType = json_node["type"].asString();
202  switch (m_type)
203  {
204  case TiePoint::MANUAL:
205  json_node["type"] = "M";
206  break;
207  case TiePoint::AUTO:
208  json_node["type"] = "A";
209  break;
210  case TiePoint::GCP:
211  json_node["type"] = "G";
212  break;
213  default:
214  json_node["type"] = "UNNASSIGNED";
215  }
216 
217  // Image points
218  Json::Value jsonList (Json::arrayValue);
219  // Loop over points on each image:
220  for (int i=0; i<m_imagePoints.size(); ++i)
221  {
222  jsonList[i]["filename"] = m_images[i]->getFilename();
223  jsonList[i]["imageId"] = m_images[i]->getImageId();
224  jsonList[i]["x"] = m_imagePoints[i].x;
225  jsonList[i]["y"] = m_imagePoints[i].y;
226 
227  if (i<m_covariances.size())
228  {
229  Json::Value covJson (Json::arrayValue);
230  covJson[0] = m_covariances[i](1,1);
231  covJson[1] = m_covariances[i](2,2);
232  covJson[2] = m_covariances[i](1,2);
233  jsonList[i]["covariance"] = covJson;
234  }
235  }
236  json_node["imagePoints"] = jsonList;
237 }
238 
240 {
241  Json::Value node;
242  saveJSON(node);
243  out << node.toStyledString();
244  return out;
245 }
246 
247 } // end namespace ISA
virtual void saveJSON(Json::Value &json) const
Definition: TiePoint.cpp:195
std::vector< NEWMAT::SymmetricMatrix > m_covariances
Definition: TiePoint.h:117
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
This code was derived from https://gist.github.com/mshockwave.
Definition: Barrier.h:8
void getImagePoint(unsigned int index, std::string &imageId, ossimDpt &imagePoint, NEWMAT::SymmetricMatrix &cov) const
Fetches the image point coordinates along with image ID and GCP ID if available.
Definition: TiePoint.cpp:70
std::vector< ossimDpt > m_imagePoints
Definition: TiePoint.h:116
void setTiePointId(const std::string &id)
Definition: TiePoint.cpp:54
static int s_runningId
Definition: TiePoint.h:120
std::string m_tiePointId
Definition: TiePoint.h:114
Class representing an Image as used by ossim-msp services.
Definition: Image.h:27
void setGcpId(const std::string &id)
Definition: TiePoint.cpp:120
std::vector< std::shared_ptr< Image > > m_images
Definition: TiePoint.h:115
virtual void loadJSON(const Json::Value &json)
Definition: TiePoint.cpp:126
Class for representing a single tiepoint on two or more images.
Definition: TiePoint.h:28
virtual std::ostream & print(std::ostream &out) const
Definition: TiePoint.cpp:239
void setImagePoint(std::shared_ptr< Image > image, const ossimDpt &imagePoint, const NEWMAT::SymmetricMatrix &cov)
Sets image point value and associated measurement covariance for specified image ID.
Definition: TiePoint.cpp:88
void makeNan()
Definition: ossimDpt.h:65
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
std::string m_gcpId
Definition: TiePoint.h:119
virtual ~TiePoint()
Definition: TiePoint.cpp:47