#include #include #include #include #include #include "header.h" //math const const double pi = 3.1415926536, rdpdg = pi / 180.0; //setting image const double szx = 1800, szy = 1800;//size of image double szfctr = szx * 1.0;//size of the drawn map (the diameter or the width for a finite projection) const plnpos shft = plnpos(szx / 2.0, szy / 2.0);//the center of the drawn map //setting projection const int iprj = 201;//No. of projection const spcpos cnlnglat = spcpos(0.0, 0.0, 0.0) * rdpdg;//centering point(longitude, latitude, rotation) in normal earth coordinate to X-axis. (Be careful if azimuthal projection.) const spcpos dfntlat = spcpos(40.01,50.01, 0.0) * rdpdg;//parameters like as standard parallels (if needed) in coordinate after rotation by cnlnglat.(Be careful if transverse or oblique aspect.) //lines & indicatrix const double intvmeridian = 30.0 * rdpdg, intvparallel = 30.0 * rdpdg;//interval of meridians and parallels in normal earth coodinate const double indicatrixrad = 5.0 * rdpdg;//radius of indicatrices //width of cutting the sphere const double linecutrad = 0.01 * rdpdg, polecutrad = 0.01 * rdpdg, intvrad = 15.0 / 4096.0, strXcut = -0.98; //drawing style const std::string landstyle = "fill:#e0d000; stroke:#606000; strock-width:1"; const std::string linestyle = "fill:none; stroke:#204040; strock-width:1"; const std::string indicatrixstyle = "fill:#d00000; fill-opacity:0.4; stroke:#600000; strock-width:1"; const std::string seastyle = "fill:#3050f8"; int main() { projection pj = projection(iprj, cnlnglat, dfntlat, linecutrad, polecutrad, intvrad); std::list line; std::list plygon, indctr; plygnset sea = plygnset(0, 10, 2); int plymax = -1; // read data std::string linebuf1, linebuf2, word1, word2, word3, word4, word5, word6; int num1, num2, num3, num4; double num6, num7; std::ifstream ifs("mapcnv1.txt"); if (ifs) { std::getline(ifs, linebuf1); while (linebuf1 != "end") { std::istringstream iss{ linebuf1 }; std::getline(iss, word1, ','); std::getline(iss, word4, ','); std::getline(iss, word5, ','); num1 = stoi(word4); num2 = stoi(word5); std::getline(iss, word2, ','); std::getline(iss, word3, ','); std::getline(iss, word4, ','); std::getline(iss, word5, ','); std::getline(iss, word6, ','); num3 = stoi(word5); num4 = stoi(word6); if (plymax < num2) { plymax = num2; } spcpos *newsph = new spcpos[num1], *tmpsph = newsph; for (int i = 0; i < num1; ++i) { std::getline(ifs, linebuf2); std::istringstream ist{ linebuf2 }; std::getline(ist, word4, ','); std::getline(ist, word5, ','); num6 = stod(word4); num7 = stod(word5); *tmpsph = pj.mt1 * (spcpos(num6 * rdpdg, num7 * rdpdg, 1.0)).XYsphpos(); ++tmpsph; } if (word1 == "polygon") { std::list::iterator itr; for (itr = plygon.begin(); itr != plygon.end(); itr++) { if (itr->pntname == num2) { itr->plygon.push_back(plygn(1, num1, newsph, num2, num3, num4)); break; } } if (itr == plygon.end()) { plygon.push_back(plygnset(plygn(1, num1, newsph, num2, num3, num4), num2, 1)); } } else if (word1 == "lake") { std::list::iterator itr; for (itr = plygon.begin(); itr != plygon.end(); itr++) { if (itr->pntname == num4) { itr->plygon.push_back(plygn(2, num1, newsph, num2, num3, num4)); break; } } if (itr == plygon.end()) { plygon.push_back(plygnset(plygn(2, num1, newsph, num2, num3, num4), num4, 1)); } } else if (word1 == "line") { line.push_back(plygn(3, num1, newsph, num2, num3, num4)); } else { delete[] newsph; } std::getline(ifs, linebuf1); } } ifs.close(); //add lines of latitude and longitude num1 = 721; for (double i = 0.0; i < pi * 0.4999; i += intvparallel) { spcpos *newsph = new spcpos[num1], *tmpsph = newsph; for (double j = -180.0; j <= 180.0; j += 0.5) {//parallel of north side *tmpsph = pj.mt1 * spcpos(j * rdpdg, i, 1.0).XYsphpos(); ++tmpsph; } ++plymax; line.push_back(plygn(3, num1, newsph, plymax, 0, 0)); newsph = new spcpos[num1]; tmpsph = newsph; for (double j = -180.0; j <= 180.0; j += 0.5) {//parallel of south side *tmpsph = pj.mt1 * spcpos(j * rdpdg, -i, 1.0).XYsphpos(); ++tmpsph; } ++plymax; line.push_back(plygn(3, num1, newsph, plymax, 0, 0)); } num1 = 361; for (double j = 0.0; j < pi * 1.9999; j += intvmeridian) {//meridians spcpos *newsph = new spcpos[num1], *tmpsph = newsph; for (double i = -90.0; i <= 90.0; i += 0.5) { *tmpsph = pj.mt1 * spcpos(j, i * rdpdg, 1.0).XYsphpos(); ++tmpsph; } ++plymax; line.push_back(plygn(3, num1, newsph, plymax, 0, 0)); } //add indicatrice num1 = 720; double dmin, dmax, dstep = 30.0; for (double i = -90.0; i <= 90.0; i += 30.0) { if (i == -90.0 || i == 90.0) { dmin = 0.0; dmax = 0.0; } else if (abs(i) > 70.0) { dstep = 60.0; dmin = -90.0; dmax = 90.0; } else { dstep = 30.0; dmin = -180.0 + dstep; dmax = 180.0; } for (double j = dmin; j <= dmax; j += dstep) { mtrx3 mt3 = pj.mt1 * (mtrx3(spcpos(j * rdpdg, i * rdpdg, 0.0)).transpose() * mtrx3::N2X); spcpos *newsph = new spcpos[num1], *tmpsph = newsph; for (double m = -180.0; m < 180.0; m += 0.5) { *tmpsph = mt3 * (spcpos(m * rdpdg, pi / 2.0 - indicatrixrad, 1.0).XYsphpos()); ++tmpsph; } ++plymax; indctr.push_back(plygnset(plygn(4, num1, newsph, plymax, 0, 0), plymax, 4)); } } //cutting for (int i = 0; i < pj.numcut; ++i) { //cut line num1 = line.size(); int linemax = -1; for (int j = 0; j < num1; ++j) { line.begin()->linecutter(pj.mcut1[i], pj.mcut2[i], pj.dcut[i], strXcut, line, linemax); delete[] line.begin()->sph; line.pop_front(); } //cut polygon for (auto itr = plygon.begin(); itr != plygon.end(); itr++) { itr->plygncutter(pj.mcut1[i], pj.mcut2[i], -1.0, pj.dcut[i], strXcut); } //cut indicatrices for (auto itr = indctr.begin(); itr != indctr.end(); itr++) { itr->plygncutter(pj.mcut1[i], pj.mcut2[i], -1.0, pj.dcut[i], strXcut); } //make & cut sea sea.plygncutter(pj.mcut1[i], pj.mcut2[i], -1.0, pj.dcut[i], strXcut); } //output plnpos tmppl; spcpos *tmpsph; //header std::ofstream ofs("svgtest.svg"); ofs << "\n"; ofs << "\n"; ofs << "\n"; //sea ofs << "sph; for (int i = 0; i < itr->pntnum; ++i) { tmppl = ((pj.*pj.prjfnc)(*tmpsph)).dsply(szfctr, shft); if (i == 0) { ofs << "M"; } else { ofs << " L"; } ofs << std::fixed << std::setprecision(2) << tmppl.x << ","; ofs << std::fixed << std::setprecision(2) << tmppl.y << " "; if (i % 8 == 7 && i < itr->pntnum - 1) { ofs << "\n"; } ++tmpsph; } ofs << "Z"; } ofs << "\" />\n"; //coast line for (auto itr1 = plygon.begin(); itr1 != plygon.end(); itr1++) { if (itr1->plygon.size() > 0) { ofs << "plygon.begin(); itr != itr1->plygon.end(); itr++) { ofs << "\n"; tmpsph = itr->sph; for (int i = 0; i < itr->pntnum; ++i) { tmppl = ((pj.*pj.prjfnc)(*tmpsph)).dsply(szfctr, shft); if (i == 0) { ofs << "M"; } else { ofs << " L"; } ofs << std::fixed << std::setprecision(2) << tmppl.x << ","; ofs << std::fixed << std::setprecision(2) << tmppl.y << " "; if (i % 8 == 7 && i < itr->pntnum - 1) { ofs << "\n"; } ++tmpsph; } ofs << "Z"; } ofs << "\" />\n"; } } //line for (auto itr = line.begin(); itr != line.end(); itr++) { ofs << "pntnum > 6) { ofs << "\n"; } ofs << " points=\""; tmpsph = itr->sph; for (int i = 0; i < itr->pntnum; ++i) { tmppl = ((pj.*pj.prjfnc)(*tmpsph)).dsply(szfctr, shft); if (i != 0) { ofs << " "; } ofs << std::fixed << std::setprecision(2) << tmppl.x << ","; ofs << std::fixed << std::setprecision(2) << tmppl.y; if (i % 8 == 7 && i < itr->pntnum - 2) { ofs << "\n"; } ++tmpsph; } ofs << "\" />\n"; } //indicatrix for (auto itr1 = indctr.begin(); itr1 != indctr.end(); itr1++) { if (itr1->plygon.size() > 0) { ofs << "plygon.begin(); itr != itr1->plygon.end(); itr++) { ofs << "\n"; tmpsph = itr->sph; for (int i = 0; i < itr->pntnum; ++i) { tmppl = ((pj.*pj.prjfnc)(*tmpsph)).dsply(szfctr, shft); if (i == 0) { ofs << "M"; } else { ofs << " L"; } ofs << std::fixed << std::setprecision(2) << tmppl.x << ","; ofs << std::fixed << std::setprecision(2) << tmppl.y << " "; if (i % 8 == 7 && i < itr->pntnum - 1) { ofs << "\n"; } ++tmpsph; } ofs << "Z"; } ofs << "\" />\n"; } } //footer ofs << "\n"; ofs.close(); }