vtkGeoSampleArcs.cxx 5.88 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGeoSampleArcs.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkGeoSampleArcs.h"

#include "vtkCamera.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCoordinate.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkGeoMath.h"
#include "vtkGlobeSource.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkRenderWindow.h"
#include "vtkRendererCollection.h"
#include "vtkTimerLog.h"

vtkStandardNewMacro(vtkGeoSampleArcs);

vtkGeoSampleArcs::vtkGeoSampleArcs()
{
  this->GlobeRadius = vtkGeoMath::EarthRadiusMeters();
  this->MaximumDistanceMeters = 100000.0;
45 46
  this->InputCoordinateSystem = RECTANGULAR;
  this->OutputCoordinateSystem = RECTANGULAR;
Ken Martin's avatar
Ken Martin committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
}

vtkGeoSampleArcs::~vtkGeoSampleArcs()
{
}

int vtkGeoSampleArcs::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

62
  // get the input and output
Ken Martin's avatar
Ken Martin committed
63 64 65 66 67
  vtkPolyData *input = vtkPolyData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

68
  // Traverse input lines, adding a circle for each line segment.
Ken Martin's avatar
Ken Martin committed
69 70
  vtkCellArray* lines = input->GetLines();
  vtkPoints* points = input->GetPoints();
71
  if ( !points )
72
  {
73
    return 0;
74
  }
75
  vtkCellArray* newLines = vtkCellArray::New();
Ken Martin's avatar
Ken Martin committed
76 77 78 79
  float* pointsPtr = static_cast<float*>(points->GetVoidPointer(0));
  vtkPoints* newPoints = vtkPoints::New();
  lines->InitTraversal();
  for (vtkIdType i = 0; i < lines->GetNumberOfCells(); i++)
80
  {
81
      vtkIdType npts=0; // to remove warning
82
      vtkIdType* pts=nullptr; // to remove warning
Ken Martin's avatar
Ken Martin committed
83
    lines->GetNextCell(npts, pts);
84

Ken Martin's avatar
Ken Martin committed
85 86 87 88
    double lastPoint[3];
    double curPoint[3];
    double lastPtLL[2];
    double curPtLL[2];
89
    if (this->InputCoordinateSystem == RECTANGULAR)
90
    {
91 92 93 94 95
      curPoint[0] = pointsPtr[3*pts[0]+0];
      curPoint[1] = pointsPtr[3*pts[0]+1];
      curPoint[2] = pointsPtr[3*pts[0]+2];
      vtkGlobeSource::ComputeLatitudeLongitude(
        curPoint, curPtLL[0], curPtLL[1]);
96
    }
97
    else // SPHERICAL
98
    {
99 100 101 102
      curPtLL[0] = pointsPtr[3*pts[0]+0];
      curPtLL[1] = pointsPtr[3*pts[0]+1];
      vtkGlobeSource::ComputeGlobePoint(
        curPtLL[0], curPtLL[1], this->GlobeRadius, curPoint);
103
    }
104

Ken Martin's avatar
Ken Martin committed
105
    for (vtkIdType p = 1; p < npts; ++p)
106
    {
Ken Martin's avatar
Ken Martin committed
107 108
      // Advance point
      for (int c = 0; c < 3; ++c)
109
      {
Ken Martin's avatar
Ken Martin committed
110
        lastPoint[c] = curPoint[c];
111
      }
Ken Martin's avatar
Ken Martin committed
112 113
      lastPtLL[0] = curPtLL[0];
      lastPtLL[1] = curPtLL[1];
114
      if (this->InputCoordinateSystem == RECTANGULAR)
115
      {
116 117 118 119 120
        curPoint[0] = pointsPtr[3*pts[p]+0];
        curPoint[1] = pointsPtr[3*pts[p]+1];
        curPoint[2] = pointsPtr[3*pts[p]+2];
        vtkGlobeSource::ComputeLatitudeLongitude(
          curPoint, curPtLL[0], curPtLL[1]);
121
      }
122
      else // SPHERICAL
123
      {
124 125 126 127
        curPtLL[0] = pointsPtr[3*pts[p]+0];
        curPtLL[1] = pointsPtr[3*pts[p]+1];
        vtkGlobeSource::ComputeGlobePoint(
          curPtLL[0], curPtLL[1], this->GlobeRadius, curPoint);
128
      }
Ken Martin's avatar
Ken Martin committed
129 130 131 132 133 134

      double dist = sqrt(vtkMath::Distance2BetweenPoints(lastPoint, curPoint));

      // Calculate the number of subdivisions.
      vtkIdType numDivisions = static_cast<vtkIdType>(dist / this->MaximumDistanceMeters + 0.5) + 1;
      if (numDivisions < 2)
135
      {
Ken Martin's avatar
Ken Martin committed
136
        numDivisions = 2;
137
      }
Ken Martin's avatar
Ken Martin committed
138 139 140

      // Create the new cell
      newLines->InsertNextCell(numDivisions);
141

Ken Martin's avatar
Ken Martin committed
142
      for (vtkIdType s = 0; s < numDivisions; ++s)
143
      {
Ken Martin's avatar
Ken Martin committed
144 145 146 147
        // Interpolate in lat-long.
        double interpPtLL[2];
        double frac = static_cast<double>(s) / (numDivisions - 1);
        for (int c = 0; c < 2; ++c)
148
        {
Ken Martin's avatar
Ken Martin committed
149
          interpPtLL[c] = frac*curPtLL[c] + (1.0 - frac)*lastPtLL[c];
150
        }
151
        if (this->OutputCoordinateSystem == RECTANGULAR)
152
        {
153 154 155 156 157
          // Convert lat-long to world;
          double interpPt[3];
          vtkGlobeSource::ComputeGlobePoint(interpPtLL[0], interpPtLL[1], this->GlobeRadius, interpPt);
          vtkIdType newPt = newPoints->InsertNextPoint(interpPt);
          newLines->InsertCellPoint(newPt);
158
        }
159
        else // SPHERICAL
160
        {
161 162
          vtkIdType newPt = newPoints->InsertNextPoint(interpPtLL[0], interpPtLL[1], 0.0);
          newLines->InsertCellPoint(newPt);
Ken Martin's avatar
Ken Martin committed
163 164 165
        }
      }
    }
166
  }
Ken Martin's avatar
Ken Martin committed
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183

  // Send the data to output.
  output->SetLines(newLines);
  output->SetPoints(newPoints);

  // Clean up.
  newLines->Delete();
  newPoints->Delete();

  return 1;
}

void vtkGeoSampleArcs::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "GlobeRadius: " << this->GlobeRadius << endl;
  os << indent << "MaximumDistanceMeters: " << this->MaximumDistanceMeters << endl;
184 185
  os << indent << "InputCoordinateSystem: " << this->InputCoordinateSystem << endl;
  os << indent << "OutputCoordinateSystem: " << this->OutputCoordinateSystem << endl;
Ken Martin's avatar
Ken Martin committed
186 187
}