1、纬度圈、赤道圈、平行圈
2、经度圈、子午圈
3、法线
4、卯酋圈
5、曲率、曲率半径
6、半轴长:
地球的长半轴上:a = 6378137m
地球的短半轴上:b = 6356755m
7、扁率
8、椭圆的第一偏心率
9、椭圆的第二偏心率
10、大地纬度
B:单位,rad, -pi/2~pi/2
知道了南北向的子午圈曲率半径,东西向的平行圈曲率半径,地球表面的经纬度为lat、lon(弧度),则转为平面坐标为:
map_project.h
#ifndef __MAP_PROJECT__
#define __MAP_PROJECT__
#define M_PI_F 3.1415926f
#define R2D(v) (v/M_PI_F*180.0f)
#define D2R(v) (v/180.0f*M_PI_F)
typedef struct{
unsigned char inited;
double h_lat;
double h_lon;
double dx_mue;
double dy_lambda;
}coordinate_map_t;
int coordinate_map_ref_init(coordinate_map_t *pref, double lon, double lat, double h);
int coordinate_map_project(const coordinate_map_t *pref, double lon, double lat, float *x, float *y);
int coordinate_map_reproject(const coordinate_map_t *pref, float x, float y, double *lon, double *lat);
int coordinate_map_ref_distance(const coordinate_map_t *pref, double lon, double lat, float *d_x, float *d_y);
#endif
map_project.cpp
/*======================================================================*
* *
* map project, *
* *
* Author: niu hongfang *
* Date: 2019.07.29 *
* Addr: Shen Zhen, Guangdong *
* *
*=======================================================================*/
#include "map_project.h"
#include "math.h"
#define E_a 6378137.0f /* 地球纬度圈半径 m */
#define E_b 6356755.0f /* 地球经度圈半径 m */
/*
* note: coordinate ref init.
*
* @param1 ref
* @param2 latitude, rad, -pi/2~pi/2
* @param3 longitude, rad, -pi~pi
* @param4 h, m,
* @return init success/failure
*/
int coordinate_map_ref_init(coordinate_map_t *pref, double lon, double lat, double h)
{
double e, e_2;
double f;
double sin_2_lat;
double R_lat_circle;
double R_lon_circle;
double den_prime_vertical, R_prime_vertical, omiga_2;
if (lat > M_PI_F / 2 || lat < -M_PI_F / 2){
return -1;
}
f = (E_a - E_b) / E_a;
e_2 = f * (2.0 - f);
sin_2_lat = sin(lat);
omiga_2 = 1 - e_2 * sin_2_lat;
den_prime_vertical = sqrtf(omiga_2);
R_prime_vertical = E_a / den_prime_vertical;
R_lat_circle = (R_prime_vertical + h) * cosf(lat);
R_lon_circle = R_prime_vertical * (1 - e_2) / omiga_2 + h;
pref->h_lat = lat;
pref->h_lon = lon;
pref->dx_mue = R_lon_circle;
pref->dy_lambda = R_lat_circle;
pref->inited = 1;
return 0;
}
int coordinate_map_project(const coordinate_map_t *pref, double lon, double lat, float *x, float *y)
{
if (!pref->inited){
return -1;
}
*x = pref->dx_mue * lon;
*y = pref->dy_lambda * lat;
return 0;
}
int coordinate_map_reproject(const coordinate_map_t *pref, float x, float y, double *lon, double *lat)
{
if (!pref->inited){
return -1;
}
*lon = (double)x / pref->dx_mue;
*lat = (double)y / pref->dy_lambda;
return 0;
}
int coordinate_map_ref_distance(const coordinate_map_t *pref, double lon, double lat, float *d_x, float *d_y)
{
if (!pref->inited){
return -1;
}
double d_lon, d_lat;
d_lon = lon - pref->h_lon;
d_lat = lat - pref->h_lat;
*d_x = d_lon*pref->dx_mue;
*d_y = d_lat*pref->dy_lambda;
return 0;
}
main.c
#include "stdio.h"
#include "iostream"
#include "map_project.h"
/* 经纬度转为平面坐标xy ----------------------------------- */
coordinate_map_t coordinate_ref = { 0 };
int main()
{
/* 深圳 */
double lat = 22.55329;
double lon = 113.88308;
/* 广州 */
double lat_g = 23.15792;
double lon_g = 113.27324;
float x_g, y_g, x_s, y_s;
coordinate_map_ref_init(&coordinate_ref, D2R(lon), D2R(lat), 10);
printf("R-lat:%.3f, \r\nR-lon:%.3f\n", coordinate_ref.dy_lambda, coordinate_ref.dx_mue);
coordinate_map_project(&coordinate_ref, D2R(lon_g), D2R(lat_g), &x_g, &y_g);
printf("g x:%f, y:%f\r\n", x_g, y_g);
coordinate_map_project(&coordinate_ref, D2R(lon), D2R(lat), &x_s, &y_s);
printf("g-->s x:%f, y:%f\r\n", x_g - x_s, y_g - y_s);
float d1,d2;
coordinate_map_ref_distance(&coordinate_ref, D2R(lon_g), D2R(lat_g), &d1, &d2);
printf("g-->s x:%f, y:%f\r\n", d1, d2);
}
可直接下载使用:https://download.csdn.net/download/niu_88/11449955
参考文献: