好几天没更博了,yogurt最近忙得飞起啊,没办法,相信付出总是会有收获的!每次更博的时候都是yogurt最开心的时候,啦啦啦~~~好了,废话不多说,赶紧更完写作业 去了~~~~(>_<)~~~~

今天yogurt要给大家分享的是我前几周刚学会的地图投影!就是把.gen的矢量形式的地图文件读入,并通过数学运算,实现墨卡托投影和兰伯特投影的效果~~(可以利用ArcGIS的DtaInteroperability的快速导入工具进行查看投影后效果哦~~开心到飞起,感觉自己完成了什么了不起的大事情呢,哈哈哈)

=================================yogurt小课堂开课了=============================

首先yogurt给大家简单普及一下坐标系这个概念!要知道我们有三种坐标!三维的地心坐标系(XYZ)、三维椭球体的地理坐标系(经纬度)以及二维平面上的投影坐标系。它们之间的关系就如图:所以我们不能直接将一张地图(经过投影了)直接转换到另一种坐标系下的地图,而是需要复杂的变化操作。先从投影坐标系变回地理坐标系,再由地理坐标系变到大地坐标系,最后通过三参数法或者七参数法进行坐标变换,然后换算到另一种椭球体对应的地理坐标系中,最后进行投影得到另一个坐标系下的地图。

因此,不同的投影坐标系的投影方法对应的数学运算是不一样的。然而yogurt这个小程序实现了从经纬度利用墨卡托投影(正轴等角圆柱投影)和兰伯特投影(等角圆锥投影)投影到二维平面单位转化为米或者千米。

=================================下课了================================

好了,话不多说,Yogur上代码了。注意:我用来存储.gen数据的二维数组我简单解释一下:第一维存放线号(第0号位置存放总的线数目,第i号位置存放i),第二维存放点号(第0号位置存放该线对应的总的点数目,第j号存放该线上第j个点的坐标),如:a[7][0].x:代表第7条线对应的点的数目;a[3][4]:代表第3条线的第4个点的坐标。

  1   1 // 投影.cpp : 定义控制台应用程序的入口点。
  2   2 //
  3   3
  4   4 #include "stdafx.h"
  5   5 #include<stdlib.h>
  6   6 #include<string.h>
  7   7 #include<math.h>
  8   8 #define PI 3.1415926535898
  9   9
 10  10 typedef struct POINT
 11  11 {
 12  12     double x, y;
 13  13 }point;
 14  14
 15  15 point ** read(char * InFILEname)
 16  16 {
 17  17     int lines_p[500];//用于记录每条线有的点数
 18  18     FILE * fp = fopen(InFILEname, "r");
 19  19     if (fp == NULL)
 20  20     {
 21  21         printf("Can not open it.");
 22  22         return 0;
 23  23     }
 24  24     char s[100] = { 0 };
 25  25     int i = 0;//记录线数
 26  26     int j = 0;//记录点数
 27  27     fscanf(fp, "%s", s);  //s不是线编号就是文件读取结束的标志“END”
 28  28     while (s[0] != 'E')
 29  29     {
 30  30         i++;
 31  31         j = 0;
 32  32         fscanf(fp, "%s", s);  //s不是点对就是线读取结束的标志“END”
 33  33         while (s[0] != 'E')
 34  34         {
 35  35             j++;
 36  36             fscanf(fp, "%s", s);
 37  37         }
 38  38         lines_p[i] = j;
 39  39         fscanf(fp, "%s", s);
 40  40     }
 41  41     lines_p[0] = i; //记录线的数目
 42  42     rewind(fp);
 43  43
 44  44     //分配空间
 45  45     point **a = (point **)malloc(sizeof(point *)*(lines_p[0] + 1));
 46  46     a[0] = (point *)malloc(sizeof(point));
 47  47
 48  48     for (int i = 1; i <= lines_p[0]; i++)   //为每条线开辟足够的点空间
 49  49     {
 50  50
 51  51         a[i] = (point *)malloc((lines_p[i] + 1)* sizeof(point));
 52  52
 53  53     }
 54  54
 55  55     //0位置赋值(线数和点数)
 56  56     for (int i = 0; i <= lines_p[0]; i++)
 57  57     {
 58  58         a[i][0].x = a[i][0].y = lines_p[i];//第一个位置存放线数或者点数
 59  59     }
 60  60
 61  61     for (int i = 1; i <= a[0][0].x; i++)//第i条线
 62  62     {
 63  63         fscanf(fp, "%s", s);//过滤掉线号
 64  64         for (int j = 1; j <= a[i][0].x; j++)//第j个点
 65  65             fscanf(fp, "%lf,%lf", &a[i][j].x, &a[i][j].y);
 66  66         fscanf(fp, "%s", s);//过滤掉END标志
 67  67     }
 68  68
 69  69     return a;
 70  70 }
 71  71
 72  72 void LambertPro(point ** p, char * OutFILEname)
 73  73 {
 74  74     FILE *fp = fopen(OutFILEname, "w");
 75  75     if (fp == NULL)
 76  76         printf("Can not open it.");
 77  77     for (int i = 1; i <= p[0][0].x; i++)       //第i条线
 78  78     {
 79  79         fprintf(fp, "%d\n", i);
 80  80         for (int j = 1; j<=p[i][0].x; j++)     //第j个点
 81  81         {
 82  82             double lon = p[i][j].x*PI / 180;
 83  83             double lat = p[i][j].y*PI / 180;                         //被投影的点的经纬度
 84  84
 85  85             double a = 6378245;                    //长半轴
 86  86             double b = 6356863.0188;               //短半轴
 87  87             double e = sqrt(a*a - b*b) / a;        //第一偏心率
 88  88             double originLon = 105 * PI / 180;
 89  89             double originLat = 0;                  //原始经纬度
 90  90             double SP1 = 20 * PI / 180;
 91  91             double SP2 = 40 * PI / 180;            //第一、二标准纬线
 92  92             double Ef = 609600;
 93  93             double Nf = 0;                          //假东和假北
 94  94
 95  95             double t = tan(PI / 4 - lat / 2) / pow(((1 - e*sin(lat)) / (1 + e*sin(lat))), e / 2);
 96  96             double t1 = tan(PI / 4 - SP1 / 2) / pow(((1 - e*sin(SP1)) / (1 + e*sin(SP1))), e / 2);
 97  97             double t2 = tan(PI / 4 - SP2 / 2) / pow(((1 - e*sin(SP2)) / (1 + e*sin(SP2))), e / 2);
 98  98             double tF = tan(PI / 4 - originLat / 2) / pow(((1 - e*sin(originLat)) / (1 + e*sin(originLat))), e / 2);
 99  99             double m1 = cos(SP1) / pow((1 - e*e*sin(SP1)*sin(SP1)), 0.5);
100 100             double m2 = cos(SP2) / pow((1 - e*e*sin(SP2)*sin(SP2)), 0.5);
101 101             double n = (log(m1) - log(m2)) / (log(t1) - log(t2));
102 102             double F = m1 / (n*pow(t1, n));
103 103             double A = n*(lon - originLon);
104 104             double r = a*F*pow(t, n);
105 105             double rF = a*F*pow(tF, n);
106 106
107 107             double E = Ef + r*sin(A);
108 108             double N = Nf + rF - r*cos(A);
109 109             fprintf(fp, "%lf,%lf\n", E, N);
110 110         }
111 111         fprintf(fp, "END\n");
112 112     }
113 113     fprintf(fp, "END\n");
114 114     fclose(fp);
115 115     return;
116 116 }
117 117
118 118 void MercatoPro(point ** p, char * OutFILEname)
119 119 {
120 120     FILE *fp = fopen(OutFILEname, "w");
121 121     if (fp == NULL)
122 122         printf("Can not open it.");
123 123     for (int i = 1; i <= p[0][0].x; i++)       //第i条线
124 124     {
125 125         fprintf(fp, "%d\n", i);
126 126         for (int j = 1; j <= p[i][0].x; j++)     //第j个点
127 127         {
128 128             double lon = p[i][j].x*PI / 180;
129 129             double lat = p[i][j].y*PI / 180;                         //被投影的点的经纬度
130 130
131 131             double a = 6378245;                    //长半轴
132 132             double b = 6356863.0188;               //短半轴
133 133             double e = sqrt(a*a - b*b) / a;        //第一偏心率
134 134             double e2 = sqrt(a*a - b*b) / b;       //第二偏心率
135 135             double L0 = 0;                         //原始经度
136 136             double B0 = 42 * PI / 180;             //标准纬度
137 137
138 138             double K = (a*a / b) / sqrt(1 + e2*e2*cos(B0)*cos(B0)) * cos(B0);
139 139
140 140             double N = K*log(tan(PI / 4 + lat / 2))*(pow((1 - e*sin(lat)) / (1 + e*sin(lat)), e / 2));
141 141             double E = K*(lon - L0);
142 142             fprintf(fp, "%lf,%lf\n", E, N);
143 143         }
144 144         fprintf(fp, "END\n");
145 145     }
146 146     fprintf(fp, "END\n");
147 147     fclose(fp);
148 148     return;
149 149 }
150 150
151 151 int _tmain(int argc, _TCHAR* argv[])
152 152 {
153 153     point ** a = read("CHINA_Arc.gen");
154 154     char outL[15] = "LambertPro.gen";
155 155     char outM[15] = "MercatoPro.gen";
156 156     LambertPro(a, outL);
157 157     MercatoPro(a, outM);
158 158     return 0;
159 159 }
160 View Code

View Code

这样就大功告成啦!我把结构的导入ArcGIS里面试一试哈,见证奇迹的时候到了~~

原文件:

投影后:

转载于:https://www.cnblogs.com/to-sunshine/p/6048438.html

.gen地图文件的投影编程实现(以墨卡托投影和兰伯特投影为例)相关推荐

  1. 分享proj4js中经纬度和兰伯特投影的转换代码

    兰伯特投影简介参见百科搜索: 兰伯特投影在气象数据的处理中,是比较常用的投影坐标系,根据不同区域.范围进行投影. proj4是专业的坐标转换类库,有各种语言版本的,C++,java,js,python ...

  2. Python-cartopy兰伯特投影绘制场图

    在学习画图的过程中,看了许多大佬的绘图代码收益匪浅.在巨人的肩膀上继续前进,分享这一次的画图.多数没有注释,原理可能需要额外找别的帖子进行查阅. 再次之前,anaconda安装cartopy包也遇到了 ...

  3. 计算兰伯特投影数据到其他空间参考的地理范围

    问题:  在实现动态投影得时候未考虑兰伯特这种投影, 导致投影得数据过少, 数据有缺失 分析: 常用投影计算是将一个投影得box范围计算到另外一个投影得box上, 直接使用box得四个点计算, 但是兰 ...

  4. lambert(兰伯特)投影 应用工具_全息投影技术,在哪些场地可以用到

    全息投影技术,也称为虚拟成像技术,应该是大家都熟悉的.它不仅能产生立体的空中视觉,还能使视觉与人互动,产生震撼的效果.它有广泛的应用场景,可以根据不同的应用环境灵活改变,新起典给你介绍全息投影技术在哪 ...

  5. arcgis 散瓦片发布服务_利用已有的缓存地图文件发布ArcGIS Server瓦片服务

    1.拷贝缓存地图文件夹至ArcGIS Server缓存目录. 2.确认缓存文件夹目录结构,如果不是如下文件目录结构,可手动调整. 注意,Layers的上一级目录,建议直接以服务名来命名. 3.ArcM ...

  6. 内存映射文件——Windows核心编程学习手札之十七

    内存映射文件 --Windows核心编程学习手札之十七 与虚拟内存一样,内存映射文件保留地址空间,并将物理存储器提交给该区域,差别在于所提交的物理存储器是磁盘上有文件存在的空间,而非系统的页文件,一旦 ...

  7. Linux文件I/O编程(二)lseek函数

    文件I/O编程处理open.read.write.close,等必要函数对文件进行读写操作外,lseek.fcntl也是I/O编程很重要的函数. lseek函数 lseek函数主要用来移动当前读写位置 ...

  8. arcengine 将地图文件保存为图片(包括各种图片格式)

    1,最近做了个地图文件输出图片的功能,思想主要就是利用MapControl的ActiveView中的out方法: 2代码如下:欢迎交流指正 1 SaveFileDialog m_save = new ...

  9. w10自动删除文件怎么关了_绝地求生怎么删除新地图_删新沙漠地图文件办法

    绝地求生怎么删除新地图?对于这张沙漠地图来说,很多玩家都不喜欢,大家都觉得掩体太少了,很容易死不好玩,还是比较喜欢老地图,怎么才能删除这张沙漠地图,从而不会匹配到呢?下面安卓市场小编就为各位玩家带来绝 ...

  10. 读取gps观测数据o文件的matlab编程,读取GPS观测数据O文件的matlab编程.doc

    读取GPS观测数据O文件的matlab编程 读取GPS观测数据O文件的matlab编程 function HeadO=ReadObsHead [fname,fpath]=uigetfile('*.*O ...

最新文章

  1. 直击面试现场:程序员阿里应聘,2轮4小时成功搞定16Koffer!
  2. 1090 Highest Price in Supply Chain (25 分)【难度: 一般 / 知识点: 树的遍历】
  3. Angular学习资料
  4. 空间滤波_第三章 灰度变换与空间滤波-(六)锐化空间滤波器之非锐化掩蔽
  5. mysql 子字符串函数_MySQL 内置字符串函数
  6. 离开载具_迷你世界 自制火箭试飞成功 飞行载具不负众望
  7. 【Flink】flink Kafka报错 : Failed to send data to Kafka: This server is not the leader for that topic-pa
  8. css3和jquery实现的可折叠导航菜单(适合手机网页)
  9. 3分钟了解LCD1602液晶显示屏的使用
  10. 计算机二级幻灯片母版奇数页,计算机二级office考试中PPT母版知识考察点有哪些...
  11. x86 x64 x86_64 AMD64 区别
  12. 油罐清洗抽吸系统设计
  13. 将Spring Boot应用程序迁移到Java 9-模块
  14. 快递查询—API接口
  15. Stata-交乘项专题: 主效应项可以忽略吗?
  16. Confession:关于本博客以及实习
  17. 轻量级网络:ResNeXt
  18. MATLAB制作扇形图及颜色调配
  19. 轻量级虚拟桌面基础架构(VDI) 解决方案降低 IT 成本并保护知识产权
  20. C语言小游戏:文字冒险游戏

热门文章

  1. RepairImages\superboot-6410.bin
  2. go 导出 html 报告(使用 hero 预编译 html 模板引擎)
  3. vb中查询mysql_vb数据库查询语句-vb中使用sql语句-vb读取sql语句的字段
  4. Android淘宝客链接自动跳转淘宝APP问题
  5. android刷机工具 原理,Android 设备刷机教程
  6. 数学建模 —— 预测模型
  7. matlab实验十ask,matlab实验十ASK调制与解调实验
  8. linux台式机双屏幕怎么连接,台式机Linux/Unix多系统安装详细教程
  9. html给图片加文字,如何给图片加上字
  10. 1、SVPWM空间矢量脉宽调制和基本原理