Я пишу небольшой служебный класс, который преобразует координаты широты и долготы в локальную систему UTM. Для этой задачи я использую этот источник . Я создал struct
, чтобы помочь мне управлять большинством данных, но что-то не так, если я передаю данные определенным образом. Это работает, если я четко переформулирую ценности. Смотрите ниже пример:
zoneconverter.h
#ifndef ZONE_CONVERTER_H
#define ZONE_CONVERTER_H
#include <string>
#include <math.h>
#include <cmath>
#include <ctgmath>
#include <stdlib.h>
#include <stdio.h>
#include <stdexcept>
#define PI 3.14159265358979323846 /* pi */
#define SMaxA 6378137.0 /* semi major axis */
#define SMinA 6356752.314245 /* sdmi minor axis */
#define grid_size 100000.0 /* 100 km grid*/
struct Deg2Rad {
double D2R = PI/180.0;
};
struct Rad2Deg {
double R2D = PI*180.0;
};
// definition of the World Geodetic System 84
struct WGS84_DATA
{
double semi_major_axis_a = 6378137.0; // by definition
double semi_minor_axis_b = 6356752.314245; // by definition
const double flattening = (SMaxA-SMinA)/SMaxA; // by definition
const double first_eccentricity = 0.081891909; // by calculation
double second_eccentricity = 0.0820944377; // by calculation
double angular_velocity_earth = 72.92115e-6; // rad/s
double gravitational_constant = 3986004.418e8; // by definition
};
struct UTM_DATA
{
double point_scale_factor = 0.9996; // by convention
double equatorial_radius = 6378137.0; // meters also semi_major_axis_a
double inverse_flattening = 1/((SMaxA-SMinA)/SMaxA); // by convention
double northen_emisphere = 0.0; // meter
double southern_hemisphere = 10000000.0; // meter
double false_esting = 500000.0; // meter by convention
double first_eccentricity_power2 = 0.081891909*0.081891909;
double first_eccentricity_power4 = 0.081891909*0.081891909*0.081891909*0.081891909;
double first_eccentricity_power6 = 0.081891909*0.081891909*0.081891909*0.081891909*0.081891909*0.081891909;
};
enum UTMidentifierLeter {
X, W, V, U, T, S, R, Q, P, N,
M, L, K, J, H, G, F, E, D, C, Z
};
struct UTM_LETTER_ZONE { UTMidentifierLeter utmLetterZone; };
enum UTMIdentifierZone { NORWAY, SVALBARD };
struct UTM_ZONE { UTMIdentifierZone utmZone; };
class ZONE_converter
{
public:
ZONE_converter();
WGS84_DATA wgs84_data;
UTM_DATA utm_data;
Deg2Rad degreeToRad_reader;
Rad2Deg radToDeg_reader;
void UTM(double lat, double lon, double eastingUtmzone, double northingUtmzone);
char adjustForNorway(double lat);
char adjustForSvalbard(double lat, double lon);
char allOtherZones(double lat);
private:
UTM_LETTER_ZONE letter;
UTM_ZONE zone;
double latitude;
double longitude;
int current_zone;
};
#endif // ZONE_CONVERTER_H
zoneconverter.cpp выглядит следующим образом
#include "zone_converter.h"
ZONE_converter::ZONE_converter(){}
void ZONE_converter::UTM(double lat, double lon, double eastingUtmzone, double northingUtmzone)
{
double m0_a11 = (std::pow(wgs84_data.first_eccentricity, 4)/4);
double m0_a12 = (std::pow(wgs84_data.first_eccentricity, 4)/64);
double m0_a13 = (std::pow(wgs84_data.first_eccentricity, 6))/256;
double m0 = 1 - m0_a11 - 3*m0_a12 - 5*m0_a13;
double m1_a11 = (std::pow(wgs84_data.first_eccentricity, 2))/8;
double m1_a12 = (std::pow(wgs84_data.first_eccentricity, 4))/32;
double m1_a13 = (std::pow(wgs84_data.first_eccentricity, 6))/1024;
double m1 = -(3*m1_a11 + 3*m1_a12 + 45*m1_a13);
double m2_a11 = (std::pow(wgs84_data.first_eccentricity, 4))/256;
double m2_a12 = (std::pow(wgs84_data.first_eccentricity, 6))/1024;
double m2 = 15*m2_a11 + 45*m2_a12;
double m3_a11 = (std::pow(wgs84_data.first_eccentricity, 6))/3072;
double m3 = -35*m3_a11;
// calculation of the central meridian
int centralMeridian = ((lon >= 0.0)
? (static_cast<int>(lon) - (static_cast<int>(lon)) % 6 + 3)
: (static_cast<int>(lon) - (static_cast<int>(lon)) % 6 - 3));
double rlat = degreeToRad_reader.D2R;
double rlon = degreeToRad_reader.D2R;
double rlon0 = centralMeridian*degreeToRad_reader.D2R;
double slat = std::sin(rlat);
double clat = std::cos(rlat);
double tlat = std::tan(rlat);
double fn = (lat > 0) ? utm_data.northen_emisphere : utm_data.southern_hemisphere;
double T = tlat*tlat;
double C = (wgs84_data.first_eccentricity*wgs84_data.first_eccentricity)*clat*clat;
double A = (rlon - rlon0)*clat;
double M = (wgs84_data.semi_major_axis_a)*(m0*rlat + m1*std::sin(2*rlat) + m2*std::sin(4*rlat) + m3*std::sin(6*rlat));
// radius of curvature on the plane of the prime vertical
double Rn = wgs84_data.semi_major_axis_a/(std::sqrt(1 - std::pow((wgs84_data.first_eccentricity), 2)*slat*slat));
// radius of Curvature in the plane os the meridian
double Rc = ((wgs84_data.semi_major_axis_a)*(1 - ((wgs84_data.first_eccentricity)*(wgs84_data.first_eccentricity))))/(1 - ((wgs84_data.first_eccentricity)*(wgs84_data.first_eccentricity))*std::pow(std::sin(rlat), 2));
// computation of the easting-northing coordinate
eastingUtmzone = utm_data.point_scale_factor*Rn*(A + ((1-T+C)*(std::pow(A, 3)/6))+(5-18*T + std::pow(T,2) + 72*C - 58*(std::pow(wgs84_data.second_eccentricity, 2)))*(std::pow(A, 5))/120);
northingUtmzone = utm_data.point_scale_factor*((M - 0.0)+Rn*tlat*(((A*A)/2) + (((std::pow(A, 4))/24)*(5-T+9*C+4*C*C)) + (61 - 58*T + T*T + 600*C - 330*(std::pow(wgs84_data.second_eccentricity, 2))*((std::pow(A, 6))/720))));
(void) Rc;
(void) fn;
return;
}
main.cpp
#include <iostream>
#include "zone_converter.h"
using namespace std;
int main()
{
ZONE_converter convert;
double lat = 26.281742;
double lon = 92.142683;
double eastingUtmzone;
double northingUtmzone;
convert.UTM(lat, lon, eastingUtmzone, northingUtmzone);
std::cout<< lat << lon<< northingUtmzone<< eastingUtmzone<< std::endl;
return 0;
}
Но я пытаюсь понять, почему, если я пишу функцию следующим образом, обращаясь к struct
, который я создал в заголовочном файле, я получаю SIGSEV
ошибку сегментации:
void ZONE_converter::UTM(double lat, double lon, double eastingUtmzone, double northingUtmzone)
{
double m0_a11 = (std::pow(wgs84_data.first_eccentricity, 2)/4);
double m0_a12 = (std::pow(wgs84_data.first_eccentricity, 4)/64);
double m0_a13 = (std::pow(wgs84_data.first_eccentricity, 6))/256;
double m0 = 1 - m0_a11 - 3*m0_a12 - 5*m0_a13;
// ... additional operation
}
Может кто-нибудь пролить свет на этот вопрос?