/* Polyconic forward equations--mapping lat,long to x,y ---------------------------------------------------*/ long polyfor ( double lon, /* (I) Longitude */ double lat, /* (I) Latitude */ double *x, /* (O) X projection coordinate */ double *y /* (O) Y projection coordinate */ ) { double sinphi, cosphi; /* sin and cos value */ double con, ml; /* cone constant, small m */ double ms; /* small m */ /* Forward equations -----------------*/ con = adjust_lon(lon - lon_center); if (fabs(lat) <= .0000001) { *x = false_easting + r_major * con; *y = false_northing - r_major * ml0; } else { gctp_sincos(lat,&sinphi,&cosphi); ml = mlfn(e0, e1, e2, e3, lat); ms = msfnz(e,sinphi,cosphi); con *= sinphi; *x = false_easting + r_major * ms * sin(con)/sinphi; *y = false_northing + r_major * (ml - ml0 + ms * (1.0 - cos(con))/sinphi); } return(GCTP_OK); }
/* Universal Transverse Mercator forward equations--mapping lat,long to x,y Note: The algorithm for UTM is exactly the same as TM and therefore if a change is implemented, also make the change to TMFOR.c -----------------------------------------------------------------------*/ long utmfor ( double lon, /* (I) Longitude */ double lat, /* (I) Latitude */ double *x, /* (O) X projection coordinate */ double *y /* (O) Y projection coordinate */ ) { double delta_lon; /* Delta longitude (Given longitude - center */ double sin_phi, cos_phi;/* sin and cos value */ double al, als; /* temporary values */ double b; /* temporary values */ double c, t, tq; /* temporary values */ double con, n, ml; /* cone constant, small m */ /* Forward equations -----------------*/ delta_lon = adjust_lon(lon - lon_center); gctp_sincos(lat, &sin_phi, &cos_phi); /* This part was in the fortran code and is for the spherical form ----------------------------------------------------------------*/ if (ind != 0) { b = cos_phi * sin(delta_lon); if ((fabs(fabs(b) - 1.0)) < .0000000001) { p_error("Point projects into infinity","utm-for"); return(93); } else { *x = .5 * r_major * scale_factor * log((1.0 + b)/(1.0 - b)); con = acos(cos_phi * cos(delta_lon)/sqrt(1.0 - b*b)); if (lat < 0) con = - con; *y = r_major * scale_factor * (con - lat_origin); return(GCTP_OK); } } al = cos_phi * delta_lon; als = SQUARE(al); c = esp * SQUARE(cos_phi); tq = tan(lat); t = SQUARE(tq); con = 1.0 - es * SQUARE(sin_phi); n = r_major / sqrt(con); ml = r_major * mlfn(e0, e1, e2, e3, lat); *x = scale_factor * n * al * (1.0 + als / 6.0 * (1.0 - t + c + als / 20.0 * (5.0 - 18.0 * t + SQUARE(t) + 72.0 * c - 58.0 * esp))) + false_easting; *y = scale_factor * (ml - ml0 + n * tq * (als * (0.5 + als / 24.0 * (5.0 - t + 9.0 * c + 4.0 * SQUARE(c) + als / 30.0 * (61.0 - 58.0 * t + SQUARE(t) + 600.0 * c - 330.0 * esp))))) + false_northing; return(GCTP_OK); }
// Initialize the Universal Transverse Mercator (UTM) projection long Projectoid::utmforint( double r_maj, // major axis double r_min, // minor axis double scale_fact, // scale factor long zone) // zone number { double temp; // temporary variable if ((abs(zone) < 1) || (abs(zone) > 60)) { p_error("Illegal zone number", "utm-forint"); return(11); } r_major = r_maj; r_minor = r_min; scale_factor = scale_fact; lat_origin = 0.0; lon_center = ((6 * abs(zone)) - 183) * D2R; false_easting = 500000.0; false_northing = (zone < 0) ? 10000000.0 : 0.0; temp = r_minor / r_major; es = 1.0 - SQUARE(temp); e = sqrt(es); e0 = e0fn(es); e1 = e1fn(es); e2 = e2fn(es); e3 = e3fn(es); ml0 = r_major * mlfn(e0, e1, e2, e3, lat_origin); esp = es / (1.0 - es); if (es < .00001) ind = 1; // Report parameters to the user ptitle("UNIVERSAL TRANSVERSE MERCATOR (UTM)"); genrpt_long(zone, "Zone: "); radius2(r_major, r_minor); genrpt(scale_factor, "Scale Factor at C. Meridian: "); cenlonmer(lon_center); ForwardOK[WCS_PROJECTIONCODE_UTM] = 1; ForwardTransform = &Projectoid::utmfor; return(OK); }
/* Initialize the Universal Transverse Mercator (UTM) projection -------------------------------------------------------------*/ long utmforint ( double r_maj, /* major axis */ double r_min, /* minor axis */ double scale_fact, /* scale factor */ long zone /* zone number */ ) { double temp; /* temporary variable */ if ((abs(zone) < 1) || (abs(zone) > 60)) { p_error("Illegal zone number","utm-forint"); return(11); } r_major = r_maj; r_minor = r_min; scale_factor = scale_fact; lat_origin = 0.0; lon_center = ((6 * abs(zone)) - 183) * D2R; false_easting = 500000.0; false_northing = (zone < 0) ? 10000000.0 : 0.0; temp = r_minor / r_major; es = 1.0 - SQUARE(temp); e0 = e0fn(es); e1 = e1fn(es); e2 = e2fn(es); e3 = e3fn(es); ml0 = r_major * mlfn(e0, e1, e2, e3, lat_origin); esp = es / (1.0 - es); if (es < .00001) ind = 1; /* Report parameters to the user -----------------------------*/ ptitle("UNIVERSAL TRANSVERSE MERCATOR (UTM)"); genrpt_long(zone, "Zone: "); radius2(r_major, r_minor); genrpt(scale_factor,"Scale Factor at C. Meridian: "); cenlonmer(lon_center); return(GCTP_OK); }
pair<double, double> WGS84Coordinate::project(double lat, double lon) const { pair<double, double> result; if (abs(lat) < 1e-10 ) { result.first = lon; result.second = -m_ml0; } else { double ms; if (abs(sin(lat)) > 1e-10) { ms = msfn(sin(lat), cos(lat), SQUARED_ECCENTRICITY) / sin(lat); } else { ms = 0.0; } result.first = ms * sin(lon *= sin(lat)); result.second = (mlfn(lat) - m_ml0) + ms * (1.0 - cos(lon)); } return result; }
// Initialize the POLYCONIC projection long Projectoid::polyinvint( double r_maj, // major axis double r_min, // minor axis double center_lon_init, // center longitude double center_lat_init, // center latitude double false_east, // x offset in meters double false_north) // y offset in meters { double temp; // temporary variable // Place parameters in static storage for common use r_major = r_maj; r_minor = r_min; lon_center = center_lon_init; lat_origin = center_lat_init; false_northing = false_north; false_easting = false_east; temp = r_minor / r_major; es = 1.0 - SQUARE(temp); e = sqrt(es); e0 = e0fn(es); e1 = e1fn(es); e2 = e2fn(es); e3 = e3fn(es); ml0 = mlfn(e0, e1, e2, e3, lat_origin); // Report parameters to the user ptitle("POLYCONIC"); radius2(r_major, r_minor); cenlonmer(lon_center); origin(lat_origin); offsetp(false_easting, false_northing); InverseOK[WCS_PROJECTIONCODE_POLYC] = 1; InverseTransform = &Projectoid::polyinv; return(OK); }
/* Initialize the POLYCONIC projection ----------------------------------*/ long polyforint ( double r_maj, /* major axis */ double r_min, /* minor axis */ double center_lon, /* center longitude */ double center_lat, /* center latitude */ double false_east, /* x offset in meters */ double false_north /* y offset in meters */ ) { double temp; /* temporary variable */ /* Place parameters in static storage for common use -------------------------------------------------*/ r_major = r_maj; r_minor = r_min; lon_center = center_lon; lat_origin = center_lat; false_northing = false_north; false_easting = false_east; temp = r_minor / r_major; es = 1.0 - SQUARE(temp); e = sqrt(es); e0 = e0fn(es); e1 = e1fn(es); e2 = e2fn(es); e3 = e3fn(es); ml0 = mlfn(e0, e1, e2, e3, lat_origin); /* Report parameters to the user -----------------------------*/ ptitle("POLYCONIC"); radius2(r_major, r_minor); cenlonmer(lon_center); origin(lat_origin); offsetp(false_easting,false_northing); return(GCTP_OK); }
/* Initialize the Equidistant Conic projection ------------------------------------------*/ int eqconinvint( double r_maj, /* major axis */ double r_min, /* minor axis */ double lat1, /* latitude of standard parallel*/ double lat2, /* latitude of standard parallel*/ double center_lon, /* center longitude */ double center_lat, /* center latitude */ double false_east, /* x offset in meters */ double false_north, /* y offset in meters */ long mode) /* which format is present A B */ { double temp; /* temporary variable */ double sinphi,cosphi; /* sin and cos values */ double ms1,ms2; double ml1,ml2; /* Place parameters in static storage for common use -------------------------------------------------*/ r_major = r_maj; r_minor = r_min; lon_center = center_lon; false_northing = false_north; false_easting = false_east; temp = r_minor / r_major; es = 1.0 - SQUARE(temp); e = sqrt(es); e0 = e0fn(es); e1 = e1fn(es); e2 = e2fn(es); e3 = e3fn(es); tsincos(lat1,&sinphi,&cosphi); ms1 = msfnz(e,sinphi,cosphi); ml1 = mlfn(e0, e1, e2, e3, lat1); /* format B ---------*/ if (mode != 0) { if (fabs(lat1 + lat2) < EPSLN) { p_error("Standard Parallels on opposite sides of equator","eqcon-for"); return(81); } tsincos(lat2,&sinphi,&cosphi); ms2 = msfnz(e,sinphi,cosphi); ml2 = mlfn(e0, e1, e2, e3, lat2); if (fabs(lat1 - lat2) >= EPSLN) ns = (ms1 - ms2) / (ml2 - ml1); else ns = sinphi; } else ns = sinphi; g = ml1 + ms1/ns; ml0 = mlfn(e0, e1, e2, e3, center_lat); rh = r_major * (g - ml0); /* Report parameters to the user -----------------------------*/ if (mode != 0) { ptitle("EQUIDISTANT CONIC"); radius2(r_major, r_minor); stanparl(lat1,lat2); cenlonmer(lon_center); origin(center_lat); offsetp(false_easting,false_northing); } else { ptitle("EQUIDISTANT CONIC"); radius2(r_major, r_minor); stparl1(lat1); cenlonmer(lon_center); origin(center_lat); offsetp(false_easting,false_northing); } return(OK); }