// Copyright (C) 1999-2017 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include #include "fdstream.hpp" #include #include "context.h" #include "framebase.h" #include "fitsimage.h" static int xmlRead (void * context, char * buffer, int len) { istream* str=(istream*)context; str->read(buffer,len); return str->gcount(); } static int xmlClose (void * context) { return 1; } void Base::xmlParse(istream& str) { xmlTextReaderPtr reader = xmlReaderForIO(xmlRead, xmlClose, (void*)(&str), "", NULL, 0); if (reader) { char** cols=NULL; int colcnt=0; int id[128]; char* unit[128]; char* ref[128]; char* axis[128]; char* dir[128]; for (int ii=0; ii<128; ii++) { id[ii]=0; unit[ii]=NULL; ref[ii]=NULL; dir[ii]=NULL; } int cnt=0; int state=0; int ret = xmlTextReaderRead(reader); while (ret == 1) { int nodeType = xmlTextReaderNodeType(reader); char* key = (char*)xmlTextReaderConstName(reader); if (!strncmp(key,"VOTABLE",7) && (nodeType==1)) { } else if (!strncmp(key,"VOTABLE",7) && (nodeType==15)) { } else if (!strncmp(key,"DEFINITIONS",11) && (nodeType==1)) { } else if (!strncmp(key,"DEFINITIONS",11) && (nodeType==15)) { } else if (!strncmp(key,"COOSYS",6) && (nodeType==1)) { } else if (!strncmp(key,"COOSYS",6) && (nodeType==15)) { } else if (!strncmp(key,"RESOURCE",8) && (nodeType==1)) { } else if (!strncmp(key,"RESOURCE",8) && (nodeType==15)) { } else if (!strncmp(key,"TABLE",5) && (nodeType==1)) { } else if (!strncmp(key,"TABLE",5) && (nodeType==15)) { } else if (!strncmp(key,"FIELD",5) && (nodeType==1)) { xmlParseFIELD(reader,id,unit,ref,axis,dir,colcnt); state = 2; colcnt++; } else if (!strncmp(key,"FIELD",5) && (nodeType==15)) { state = 0; } else if (!strncmp(key,"DATA",4) && (nodeType==1)) { state = 0; } else if (!strncmp(key,"DATA",4) && (nodeType==15)) { } else if (!strncmp(key,"TABLEDATA",9) && (nodeType==1)) { state = 0; } else if (!strncmp(key,"TABLEDATA",9) && (nodeType==15)) { } else if (!strncmp(key,"TR",2) && (nodeType==1)) { if (cols) { for (int ii=0; ii taglist; // params char* param =NULL; char* param2 =NULL; char* param3 =NULL; char* param4 =NULL; char* param5 =NULL; // comment char* comment=NULL; List cblist; // build it for (int ii=0; iimapLenToRef(atof(r), rsys, rdist), fill, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "ellipse", 7)) { int fill =0; if (param) fill = atoi(param); createEllipseCmd(xmlPoint(ptr, x, y, sys, sky, format), ptr->mapLenToRef(Vector(atof(r),atof(r2)), rsys, rdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), fill, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "box", 3) || STRCMP(shape, "rotbox", 6)) { int fill =0; if (param) fill = atoi(param); createBoxCmd(xmlPoint(ptr, x, y, sys, sky, format), ptr->mapLenToRef(Vector(atof(r),atof(r2)), rsys, rdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), fill, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "rectang", 6) || STRCMP(shape, "rotrec", 6)) { int fill =0; if (param) fill = atoi(param); Vector v1 = xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 0); Vector v2 = xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 1); Vector d = v2-v1; Vector c = d/2 + v1; createBoxCmd(c,d, xmlAngle(ang, angsign, angoffset, angformat, sys, sky), fill, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "polygon", 7)) { int fill =0; if (param) fill = atoi(param); List* list = xmlVertex(ptr, xv, yv, vsys, vsky, vformat); createPolygonCmd(*list, fill, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "line", 4)) { int arrow1 =1; int arrow2 =1; if (param) arrow1 = atoi(param); if (param2) arrow2 = atoi(param2); createLineCmd(xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 0), xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 1), arrow1, arrow2, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "vector", 6)) { int arrow =1; if (param) arrow = atoi(param); createVectCmd(xmlPoint(ptr, x, y, sys, sky, format), ptr->mapLenToRef(atof(r), rsys, rdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), arrow, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "projection", 10)) { createProjectionCmd(xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 0), xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 1), ptr->mapLenToRef(atof(r), rsys, rdist), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "segment", 7)) { List* list = xmlVertex(ptr, xv, yv, vsys, vsky, vformat); createSegmentCmd(*list, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "text", 4)) { int rotate = 1; if (param) rotate = atoi(param); createTextCmd(xmlPoint(ptr, x, y, sys, sky, format), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), rotate, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "point", 5)) { const char* def = "circle"; Point::PointShape shape = Point::CIRCLE; if (!param) param = (char*)def; int size = 11; if (param2) size = atoi(param2); if (STRCMP(param, "circle", 6)) shape = Point::CIRCLE; else if (STRCMP(param, "box", 3)) shape = Point::BOX; else if (STRCMP(param, "diamond", 7)) shape = Point::DIAMOND; else if (STRCMP(param, "cross", 5)) shape = Point::CROSS; else if (STRCMP(param, "x", 1)) shape = Point::EX; else if (STRCMP(param, "arrow", 5)) shape = Point::ARROW; else if (STRCMP(param,"boxcircle",9)) shape = Point::BOXCIRCLE; createPointCmd(xmlPoint(ptr, x, y, sys, sky, format), shape, size, color, dash, width, font, text, props, comment, taglist, cblist); } // Measurement Regions else if (STRCMP(shape, "ruler", 5)) { Coord::CoordSystem rsys; Coord::SkyFrame rsky; coord.strToCoordSystem(param, wcsSystem_, &rsys, &rsky); Coord::CoordSystem dsys; Coord::DistFormat ddist; coord.strToDistSystem(param2, wcsSystem_, &dsys, &ddist); createRulerCmd(xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 0), xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 1), rsys, rsky, dsys, ddist, "", color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "compass", 7)) { Coord::CoordSystem csys; Coord::SkyFrame csky; coord.strToCoordSystem(param, wcsSystem_, &csys, &csky); const char* param2def = "N"; if (!param2) param2 = (char*)param2def; const char* param3def = "E"; if (!param3) param3 = (char*)param3def; int arrow1 =1; if (param4) arrow1 = atoi(param4); int arrow2 =1; if (param5) arrow2 = atoi(param5); createCompassCmd(xmlPoint(ptr, x, y, sys, sky, format), ptr->mapLenToRef(atof(r), rsys, rdist), param2, param3, arrow1, arrow2, csys, csky, color, dash, width, font, text, props, comment, taglist, cblist); } // Annulus Regions else if (STRCMP(shape, "annulus", 7)) { int num = xmlCount(rv); createAnnulusCmd(xmlPoint(ptr, x, y, sys, sky, format), num, xmlDistance(ptr, rv, num, rvsys, rvdist), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "ellipseannulus", 14)) { int num = xmlCount(rv); createEllipseAnnulusCmd(xmlPoint(ptr, x, y, sys, sky, format), num, xmlDistance(ptr, rv, rv2, num, rvsys, rvdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "boxannulus", 10)) { int num = xmlCount(rv); createBoxAnnulusCmd(xmlPoint(ptr, x, y, sys, sky, format), num, xmlDistance(ptr, rv, rv2, num, rvsys, rvdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } // Panda Regions else if (STRCMP(shape, "panda", 5) || STRCMP(shape, "pie", 3)) { int anum = xmlCount(angv); int rnum = xmlCount(rv); createCpandaCmd(xmlPoint(ptr, x, y, sys, sky, format), anum, xmlAngles(angv, angvsign, angvoffset, anum, angvformat, sys, sky), rnum, xmlDistance(ptr, rv, rnum, rvsys, rvdist), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "epanda", 6)) { int anum = xmlCount(angv); int rnum = xmlCount(rv); createEpandaCmd(xmlPoint(ptr, x, y, sys, sky, format), anum, xmlAngles(angv, angvsign, angoffset, anum, angvformat, sys, sky), rnum, xmlDistance(ptr, rv, rv2, rnum, rvsys, rvdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "bpanda", 6)) { int anum = xmlCount(angv); int rnum = xmlCount(rv); createBpandaCmd(xmlPoint(ptr, x, y, sys, sky, format), anum, xmlAngles(angv, angvsign, angvoffset, anum, angvformat, sys, sky), rnum, xmlDistance(ptr, rv, rv2, rnum, rvsys, rvdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } } void Base::xmlSetProps(unsigned short* props, unsigned short prop, char* str) { if (atoi(str)) *props |= prop; else *props &= ~prop; } int Base::xmlCount(const char* col) { int cnt=0; char* cc = dupstr(col); char* tok = strtok(cc, " "); while (tok) { cnt++; tok = strtok(NULL, " "); } delete [] cc; return cnt; } Vector Base::xmlPoint(FitsImage* ptr, const char* xstr, const char* ystr, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int which) { if (!xstr || !ystr) return Vector(); char* x =NULL; char* y =NULL; char* xcc =NULL; char* ycc =NULL; if (which>0) { xcc = dupstr(xstr); x = strtok(xcc, " "); for (int ii=0; iimapToRef(Vector(atof(x),atof(y)), sys); break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: rr = ptr->mapToRef(Vector(atof(x),atof(y)), sys, sky); break; case Coord::SEXAGESIMAL: { double xx=parseSEXStr(x); double yy=parseSEXStr(y); switch (sky) { case Coord::FK4: case Coord::FK4_NO_E: case Coord::FK5: case Coord::ICRS: xx = xx/24.*360.; break; case Coord::GALACTIC: case Coord::SUPERGALACTIC: case Coord::ECLIPTIC: case Coord::HELIOECLIPTIC: break; } rr = ptr->mapToRef(Vector(xx,yy), sys, sky); } } } else rr = ptr->mapToRef(Vector(atof(x),atof(y)), sys); } if (which>0) { if (xcc) delete [] xcc; if (ycc) delete [] ycc; } return rr; } List* Base::xmlVertex(FitsImage* ptr, const char* x, const char* y, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { List* list = new List; int cnt= xmlCount(x); for (int ii=0; iiappend(n); } return list; } double* Base::xmlDistance(FitsImage* ptr, const char* r, int cnt, Coord::CoordSystem sys, Coord::DistFormat dist) { double* rr = new double[cnt]; char* cc = dupstr(r); char* tok = strtok(cc, " "); for (int ii=0; iimapLenToRef(rr[ii], sys, dist); return rr; } Vector* Base::xmlDistance(FitsImage* ptr, const char* r, const char* r2, int cnt, Coord::CoordSystem sys, Coord::DistFormat dist) { Vector* vv = new Vector[cnt]; { char* cc = dupstr(r); char* tok = strtok(cc, " "); for (int ii=0; iimapLenToRef(vv[ii], sys, dist); return vv; } double Base::xmlAngle(const char* angle, int sign, double offset, Coord::AngleFormat format, Coord::CoordSystem sys, Coord::SkyFrame sky) { switch (format) { case Coord::DEG: return mapAngleToRef(sign*degToRad(atof(angle))+offset, sys, sky); case Coord::RAD: return mapAngleToRef(sign*atof(angle)+offset, sys, sky); } } double* Base::xmlAngles(const char* angle, int sign, double offset, int cnt, Coord::AngleFormat format, Coord::CoordSystem sys, Coord::SkyFrame sky) { double* ang = new double[cnt]; char* cc = dupstr(angle); char* tok = strtok(cc, " "); for (int ii=0; ii" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "DS9 version 4.1" << endl; str << "" << endl; switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; break; default: if (keyContext->fits->hasWCS(sys)) { if (keyContext->fits->hasWCSCel(sys)) { // determine ucd char* xucd=NULL; char* yucd=NULL; switch (sky) { case Coord::FK4: case Coord::FK4_NO_E: case Coord::FK5: case Coord::ICRS: xucd = dupstr("pos.eq.ra;meta.main"); yucd = dupstr("pos.eq.dec;meta.main"); break; case Coord::GALACTIC: case Coord::SUPERGALACTIC: xucd = dupstr("pos.galactic.lon;meta.main"); yucd = dupstr("pos.galactic.lat;meta.main"); break; case Coord::ECLIPTIC: case Coord::HELIOECLIPTIC: xucd = dupstr("pos.ecliptic.lon;meta.main"); yucd = dupstr("pos.ecliptic.lat;meta.main"); break; } switch (format) { case Coord::DEGREES: str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; break; case Coord::SEXAGESIMAL: str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; break; } str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; } else { str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; } } } str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl; str << "" << endl << "" << endl; } void Base::markerListXMLFooter(ostream& str) { str << "" << endl << "" << endl << "
" << endl << "
" << endl << "
" << endl; }