Line data Source code
1 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
3 : //# License for more details.
4 : //#
5 : //# You should have received a copy of the GNU Library General Public License
6 : //# along with this library; if not, write to the Free Software Foundation,
7 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
8 : //#
9 : //# Correspondence concerning AIPS++ should be addressed as follows:
10 : //# Internet email: casa-feedback@nrao.edu.
11 : //# Postal address: AIPS++ Project Office
12 : //# National Radio Astronomy Observatory
13 : //# 520 Edgemont Road
14 : //# Charlottesville, VA 22903-2475 USA
15 : //#
16 :
17 :
18 : #include <imageanalysis/Annotations/AnnPolyline.h>
19 :
20 : #include <casacore/images/Regions/WCPolygon.h>
21 :
22 : using namespace casacore;
23 : namespace casa {
24 :
25 0 : AnnPolyline::AnnPolyline(
26 : const Vector<Quantity>& xPositions,
27 : const Vector<Quantity>& yPositions,
28 : const String& dirRefFrameString,
29 : const CoordinateSystem& csys,
30 : const IPosition& imShape,
31 : const Quantity& beginFreq,
32 : const Quantity& endFreq,
33 : const String& freqRefFrameString,
34 : const String& dopplerString,
35 : const Quantity& restfreq,
36 : const Vector<Stokes::StokesTypes> stokes,
37 : const Bool annotationOnly,
38 : const Bool requireImageRegion
39 0 : ) : AnnRegion(
40 : POLYLINE, dirRefFrameString, csys, imShape, beginFreq,
41 : endFreq, freqRefFrameString, dopplerString,
42 : restfreq, stokes, annotationOnly, requireImageRegion
43 0 : ), _origXPos(xPositions), _origYPos(yPositions) {
44 0 : _init();
45 0 : }
46 :
47 0 : AnnPolyline::AnnPolyline(
48 : const Vector<Quantity>& xPositions,
49 : const Vector<Quantity>& yPositions,
50 : const CoordinateSystem& csys,
51 : const IPosition& imShape,
52 : const Vector<Stokes::StokesTypes>& stokes,
53 : const Bool requireImageRegion
54 0 : ) : AnnRegion(POLYGON, csys, imShape, stokes, requireImageRegion),
55 0 : _origXPos(xPositions), _origYPos(yPositions) {
56 0 : _init();
57 0 : }
58 :
59 0 : AnnPolyline& AnnPolyline::operator= (
60 : const AnnPolyline& other
61 : ) {
62 0 : if (this == &other) {
63 0 : return *this;
64 : }
65 0 : AnnRegion::operator=(other);
66 0 : _origXPos.resize(other._origXPos.nelements());
67 0 : _origXPos = other._origXPos;
68 0 : _origYPos.resize(other._origYPos.nelements());
69 0 : _origYPos = other._origYPos;
70 0 : return *this;
71 : }
72 :
73 0 : Vector<MDirection> AnnPolyline::getCorners() const {
74 0 : return getConvertedDirections();
75 : }
76 :
77 0 : ostream& AnnPolyline::print(ostream &os) const {
78 0 : _printPrefix(os);
79 0 : os << "poly [";
80 0 : for (uInt i=0; i<_origXPos.size(); i++) {
81 0 : os << "[" << _printDirection(_origXPos[i], _origYPos[i]) << "]";
82 0 : if (i < _origXPos.size()-1) {
83 0 : os << ", ";
84 : }
85 : }
86 0 : os << "]";
87 0 : _printPairs(os);
88 0 : return os;
89 : }
90 :
91 0 : void AnnPolyline::worldVertices(vector<Quantity>& x, vector<Quantity>& y) const {
92 0 : const CoordinateSystem csys = getCsys();
93 0 : const IPosition dirAxes = _getDirectionAxes();
94 0 : String xUnit = csys.worldAxisUnits()[dirAxes[0]];
95 0 : String yUnit = csys.worldAxisUnits()[dirAxes[1]];
96 0 : Vector<MDirection> corners = getConvertedDirections();
97 0 : x.resize(corners.size());
98 0 : y.resize(corners.size());
99 0 : for (uInt i=0; i<corners.size(); i++) {
100 0 : x[i] = Quantity(corners[i].getAngle(xUnit).getValue(xUnit)[0], xUnit);
101 0 : y[i] = Quantity(corners[i].getAngle(yUnit).getValue(yUnit)[1], yUnit);
102 : }
103 0 : }
104 :
105 0 : void AnnPolyline::pixelVertices(vector<Double>& x, vector<Double>& y) const {
106 0 : vector<Quantity> xx, xy;
107 0 : worldVertices(xx, xy);
108 :
109 0 : const CoordinateSystem csys = getCsys();
110 0 : Vector<Double> world = csys.referenceValue();
111 0 : const IPosition dirAxes = _getDirectionAxes();
112 0 : String xUnit = csys.worldAxisUnits()[dirAxes[0]];
113 0 : String yUnit = csys.worldAxisUnits()[dirAxes[1]];
114 :
115 0 : x.resize(xx.size());
116 0 : y.resize(xx.size());
117 :
118 0 : for (uInt i=0; i<xx.size(); i++) {
119 0 : world[dirAxes[0]] = xx[i].getValue(xUnit);
120 0 : world[dirAxes[1]] = xy[i].getValue(yUnit);
121 0 : Vector<Double> pixel;
122 0 : csys.toPixel(pixel, world);
123 0 : x[i] = pixel[dirAxes[0]];
124 0 : y[i] = pixel[dirAxes[1]];
125 0 : }
126 0 : }
127 :
128 0 : void AnnPolyline::_init() {
129 0 : String preamble(String(__FUNCTION__) + ": ");
130 0 : if (_origXPos.size() != _origYPos.size()) {
131 0 : throw AipsError(
132 0 : preamble + "x and y vectors are not the same length but must be."
133 0 : );
134 : }
135 0 : AnnotationBase::Direction corners(_origXPos.size());
136 0 : for (uInt i=0; i<_origXPos.size(); i++) {
137 0 : corners[i].first = _origXPos[i];
138 0 : corners[i].second = _origYPos[i];
139 : }
140 0 : _checkAndConvertDirections(String(__FUNCTION__), corners);
141 0 : Vector<Double> xv(_origXPos.size()), yv(_origYPos.size());
142 0 : for (uInt i=0; i<xv.size(); i++) {
143 0 : Vector<Double> coords = getConvertedDirections()[i].getAngle("rad").getValue();
144 0 : xv[i] = coords[0];
145 0 : yv[i] = coords[1];
146 0 : }
147 0 : Quantum<Vector<Double> > x(xv, "rad");
148 0 : Quantum<Vector<Double> > y(yv, "rad");
149 : try {
150 : WCPolygon wpoly(
151 0 : x, y, IPosition(_getDirectionAxes()),
152 : getCsys(), RegionType::Abs
153 0 : );
154 0 : _setDirectionRegion(wpoly);
155 0 : _extend();
156 0 : } catch (const ToLCRegionConversionError& err) {
157 0 : if (_requireImageRegion) {
158 0 : throw(err);
159 : } else {
160 0 : ImageRegion defaultRegion;
161 0 : _setDirectionRegion(defaultRegion);
162 0 : _imageRegion = _directionRegion;
163 0 : }
164 0 : }
165 0 : }
166 :
167 :
168 : }
|