雪影工作室版权所有,转载请注明【http://blog.csdn.net/lina791211】


1、前言

这段时间一直在研究城市路网,某一天受不可告人的启发,决定把城市路网的地图做出来,然后模拟移动对象在路网上的运动,故本人开始了模拟地图生成的不归路。

  任务要求:

    (1)通过一组城市路网街道的数据(图的格式存储,demo数据下面给),把城市路网数据转换成坐标数据(其实这一步,我拿到的数据已经转换完成了,也就是说我拿到了的是平面坐标数据,而不是球面经纬度数据);

    (2)根据平面坐标数据,使用Java Swing或者Visual Studio(C# WinForm)生成城市路网;

    (3)支持点击某点,以此点放大;

    (4)支持按中心缩小

    (5)不用考虑剪枝(城市路网地图放大是存在剪枝的,那是因为附加数据太多,我的demo中只有1W多个街道,内存完全无压力)

    (6)经度不考虑(这个是因为winform坐标只能是整数,无法用浮点数表示)

    (7)根据移动对象的移动数据,模拟移动对象的运动。

 

2、数据demo

通过特殊途径拿到了一组城市路网街道的demo数据,如何拿到我就不讲了。但是可以提供另外一种获取途径。

  城市路网数据获取:来点我啊,来点我啊

  然后过几天就会拿到数据了。

  由于我这边通过其他途径得到数据的,所以还是简要介绍一下我这边数据的格式:

    (1)街道数据

0,50,8209,8769,8293,8768
1,50,8293,8768,8594,8773
2,50,8594,8773,8982,8781
3,50,8982,8781,9222,8787
4,30,8982,8781,9057,8936
5,30,9057,8936,9106,9038
6,30,9106,9038,9163,9209
7,30,9163,9209,9211,9354
8,70,9222,8787,9227,8890
9,70,9227,8890,9248,9350
10,70,9248,9350,9280,9476
11,70,9280,9476,9334,9670
12,70,9334,9670,9387,9804
13,70,9387,9804,9444,9919
14,70,9395,10233,9401,10199
15,70,9401,10199,9444,10000
16,70,9444,9919,9444,10000
17,50,8594,8773,8598,9061
18,50,8595,9495,8598,9256

  简要介绍下每行的含义

    street编号,限速,Start X,Start Y,End X,End Y。


    (2)移动对象数据

1 1   39:22.6 39:24.6 15537   3850    15537   3850    0   0
1   2   39:24.6 39:26.6 15537   3850    15541.5 3857    8.321658489 14.97898528
1   2   39:26.6 39:28.6 15541.5 3857    15550.3 3870.65 16.24076661 29.23337989
1   2   39:28.6 39:30.6 15550.3 3870.65 15559.4 3884.65 16.69760462 30.05568831
1   2   39:30.6 39:32.6 15559.4 3884.65 15565.5 3894.21 11.34035273 20.41263491
1   2   39:32.6 39:34.6 15565.5 3894.21 15574.4 3907.99 16.40421897 29.52759415
1   2   39:34.6 39:36.6 15574.4 3907.99 15583.5 3921.99 16.69760462 30.05568831
1   2   39:36.6 39:38.6 15583.5 3921.99 15592.5 3935.99 16.64331698 29.95797056
1   2   39:38.6 39:40.6 15592.5 3935.99 15601.6 3949.99 16.69760462 30.05568831
1   2   39:40.6 39:42.6 15601.6 3949.99 15610.6 3964    16.65172964 29.97311335
1   2   39:42.6 39:44.6 15610.6 3964    15619   3977.01 15.48612605 27.87502689
1   2   39:44.6 39:46.6 15619   3977.01 15625.7 3987.33 12.3041619  22.14749142
1   2   39:46.6 39:48.6 15625.7 3987.33 15634.7 4001.33 16.64331698 29.95797056
1   2   39:48.6 39:50.6 15634.7 4001.33 15643.7 4015.33 16.64331698 29.95797056
1   2   39:50.6 39:52.6 15643.7 4015.33 15652.8 4029.34 16.70598994 30.0707819
1   2   39:52.6 39:54.6 15652.8 4029.34 15661.8 4043.34 16.64331698 29.95797056
1   2   39:54.6 39:56.4 15661.8 4043.34 15670   4056    15.08362026 27.15051646
1   2   39:56.4 39:58.4 15670   4056    15663.1 4060.69 8.343027029 15.01744865
1   2   39:58.4 40:00.4 15663.1 4060.69 15649.7 4069.83 16.22034525 29.19662145

  简要介绍下每行的含义

    移动对象编号,暂无意义,开始时间,结束时间,Start X,Start Y,End X,End Y,暂无意义(其实是行驶路程),暂无意义(其实是平均速度)

3、先上demo

讲了这么久,先把路网的demo拿出来看一下。(放大两倍后的,不敢把原图搞出来,不知道是否涉密)

4、数据处理

手里拿到的路网数据,是平面坐标数据,而且起始范围特别大,用1366这样的范围根本不能忍。故要读取样本,获取X、Y的最大值、最小值,并获取区间范围,然后缩放坐标范围到1000以内就行。

  (一)获取最大值最小值

    实现机制很简单,读取文件,转换数据,比较大小,分别获取X与Y的最大值和最小值;

/// <summary>/// 测试使用/// 获取坐标集合中X 、Y的最大值和最小值/// </summary>/// <param name="strs"></param>private void getMax_Min_XY(string[] strs){int xMin = 0;int xMax = 0;int yMin = 0;int yMax = 0;string[] s = strs[0].Split(',');xMin = Convert.ToInt32(s[2]);xMax = Convert.ToInt32(s[4]);yMin = Convert.ToInt32(s[3]);yMax = Convert.ToInt32(s[5]);if (xMin < xMax){int temp = xMin; xMin = xMax; xMax = temp;}if (yMin < yMax){int temp = yMin; yMin = yMax; yMax = temp;}// Console.WriteLine("\txMax \txMin \tyMax \tyMin");for (int i = 1; i < strs.Length; i++) {Console.Write("\n"+i);string[] s1 = strs[i].Split(',');int _xMin = Convert.ToInt32(s1[2].Contains(".") ? s1[2].Substring(0, s1[2].IndexOf('.')) : s1[2]);int _xMax = Convert.ToInt32(s1[4].Contains(".") ? s1[4].Substring(0, s1[4].IndexOf('.')) : s1[4]);int _yMin = Convert.ToInt32(s1[3].Contains(".") ? s1[3].Substring(0, s1[3].IndexOf('.')) : s1[3]);int _yMax = Convert.ToInt32(s1[5].Contains(".") ? s1[5].Substring(0, s1[5].IndexOf('.')) : s1[5]);if (_xMin < xMin)  xMin = _xMin;else if (_xMin > xMax) xMax = _xMin;if (_xMax < xMin) xMin = _xMax;else if (_xMax > xMax) xMax = _xMax;if (_yMin < yMin) yMin = _yMin;else if (_yMin > yMax) yMax = _yMin;if (_yMax < yMin) yMin = _yMax;else if (_yMax > yMax) yMax = _yMax;Console.Write("\t" + xMax);Console.Write("\t" + xMin);Console.Write("\t" + yMax);Console.Write("\t" + yMin);}Console.WriteLine("xMax:" + xMax);Console.WriteLine("xMin:" + xMin);Console.WriteLine("yMax:" + yMax);Console.WriteLine("yMin:" + yMin);}

  使用 Convert.ToInt32(s1[2].Contains(".") ? s1[2].Substring(0, s1[2].IndexOf('.')) : s1[2]);的原因是:数据中有浮点数,,在粗粒度处理下,我就暴力的舍弃了。

  从而得到XY的最大和最小值:

// private int xMax =33575;// private int xMin=-10836;// private int yMax=28095;// private int yMin = -6686;

  通过计算,xMax-xMin,yMax-yMin,离他们最近的最大整数分别是 90000和70000。

  因此,我选择了form页面大小为900*700的。中心点是(450,350),xmin取-11000,ymin取-6800,坐标转换后需要的缩放倍率是50

private static int xmin = -11000;private static int ymin = -6800;private static int rate = 50;private int _Xc = 450;private int _Yc = 350;

  这些数据都作为固定值保存下来。不能每次加载地图的时候都去处理一遍啊,是不?处理数据很慢的。

  (二)转换坐标,并保存文件

  转换坐标好理解,保存文件是为了下次启动的时候可以直接读转换后的数据,而不用重新转换坐标了。其实这些都是数据的预处理。

/// <summary>/// 测试使用的,根据城市路网坐标数据,生成符合当前坐标的路网坐标/// </summary>private void ConvertStreetPoints(){string[] strs = System.IO.File.ReadAllLines("c://streets_seg.csv");FileStream fs = new FileStream("C:\\A.txt", FileMode.Append);StreamWriter sw = new StreamWriter(fs, Encoding.Default);//Graphics g = this.pictureBox1.CreateGraphics();for (int i = 1; i < strs.Length; i++){string[] s1 = strs[i].Split(',');//Console.Write("\n");// Console.WriteLine(getX(s1[2]));// Console.WriteLine(getX(s1[4]) );// Console.WriteLine(getY(s1[3]) );// Console.WriteLine(getY(s1[5]));//sw.Write(text);sw.Write(getX(s1[2]) + "\n");sw.Write(getX(s1[4]) + "\n");sw.Write(getY(s1[3]) + "\n");sw.Write(getY(s1[5]) + "\n");// Pen p = new Pen(Color.Red);// Point a = new Point(getX(s1[2]), getY(s1[3]));// Point b = new Point(getX(s1[4]), getY(s1[5]));// g.DrawLine(p, a, b);}sw.Close();fs.Close();}

  里面涉及了坐标的转换,方法如下:

/// <summary>/// 转换路网坐标/// </summary>/// <param name="x"></param>/// <returns></returns>private int getX(String x){int tmp = Convert.ToInt32(x.Contains(".") ? x.Substring(0, x.IndexOf('.')) : x);return (tmp - xmin) / rate;}/// <summary>/// 转换路网坐标/// </summary>/// <param name="y"></param>/// <returns></returns>private int getY(String y){int tmp = Convert.ToInt32(y.Contains(".") ? y.Substring(0, y.IndexOf('.')) : y);return (tmp - ymin) / rate;}

  处理后的坐标样式如下,每行一个数据,按照start X,end X,Start Y,End Y 进行保存的。当初脑子有点抽

385
391
311
311
391
399
311
311

  okay,路网的数据就这样基本处理完成了,下面开始进行地图绘制操作了。

5、地图绘制

系统启动的时候,首先要把转换后的路网坐标数据存到内存中,(不要跟我说存神马R树啊之类的,内容太少,没必要)

private int[] ax = new int[MAX];private int[] ay = new int[MAX];private int[] bx = new int[MAX];private int[] by = new int[MAX];
/// <summary>/// 初始化路网路口坐标/// </summary>private void initPoints(){string[] strs = System.IO.File.ReadAllLines("C:\\A.txt");for (int i = 0; i < strs.Length/4; i++) {//Console.WriteLine(strs[i]);ax[i] = Convert.ToInt32(strs[i * 4]);bx[i] = Convert.ToInt32(strs[i * 4 + 1]);ay[i] = Convert.ToInt32(strs[i * 4 + 2]);by[i] = Convert.ToInt32(strs[i * 4 + 3]);}}

  然后剩下的就是A-B这样进行划线啦。so easy的!(给form添加一个paint事件)

/// <summary>/// 绘制地图主方法/// </summary>private void repaint(){Graphics g = this.CreateGraphics();for (int i = 1; i < ax.Length; i++){Pen p = new Pen(Color.Red);Point a = new Point(ax[i], ay[i]);Point b = new Point(bx[i], by[i]);g.DrawLine(p, a, b);}}/// <summary>/// 绘制地图(Form的paint事件)/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Form1_Paint(object sender, PaintEventArgs e){repaint();}

  Form1_Load方法中直接调用对应的方法就行。

private void Form1_Load(object sender, EventArgs e){string[] strs = System.IO.File.ReadAllLines("c://streets_seg.csv");//Console.WriteLine(strs.Length);//ConvertStreetPoints();//ConvertTripPoint();initPoints();// initTripPoints();//getMax_Min_XY(strs);//}

6、地图出现

系统启动后会在1S左右把数据加载进来,然后绘制地图的图形,速度还是不错的。如果直接拿原始数据,先切割,再转换数据类型,然后缩放坐标点,这一套流程下来要耗费1分多的。

  下一章讲述如何放大和缩小。

  okay,本章结束!

转载于:https://my.oschina.net/teardream/blog/367867

C# 城市路网地图生成与运动模拟(一)-数据的获取相关推荐

  1. android 生成kml,Android模拟GPS数据生成kml和nmea文件

    在Android平台上开发可能没有真机的时候,我们通过DDMS中载入kml或nmea文件来模拟生产数据,使用方法参考 新版ADT插件让Android开发更人性化 一文,最终这两个文件加载到/data/ ...

  2. 经典文献阅读之--用于自动驾驶的高清地图生成技术

    0. 简介 这篇文章我们介绍一下论文"High-Definition Map Generation Technologies For Autonomous Driving: A Review ...

  3. OSM OpenStreetMap 获取城市路网数据及转为ESRI shp数据的方法

    目录 一.OSM简介 二.获取OSM数据方法 方法1:官网下载 方法2:通过ArcGIS Editor for OpenStreetMap插件下载 方法3:通过QGIS下载 三.获取OSM城市路网数据 ...

  4. arcgis 属性表中起点终点创建线_一种GIS单线路网自动生成双线路网的方法与流程...

    本发明涉及GIS路网领域,尤其是涉及一种GIS单线路网自动生成双线路网 的方法. 背景技术: GIS路网是将真实道路,通过GIS数据的形式可视化表达出来.目前主流的 道路网模型是单线双属性的节点-路段 ...

  5. 高清地图生成技术综述

    过去几年,自动驾驶一直是最受欢迎和最具挑战性的话题之一.在实现完全自动驾驶的道路上,研究人员利用了各种传感器,如激光雷达.摄像头.IMU和GPS,并开发了用于自动驾驶应用的智能算法,如目标检测.目标分 ...

  6. Open Street Map 全球城市路网数据下载并转为SHP格式(包含历史道路数据的下载方法)

    一.背景 Open street Map 是一个很好的开源数据获取源,本人正在做关于芝加哥的研究需要用到路网数据,因此需要从Open street Map 下载数据. 二.数据下载方法 1.简单粗暴法 ...

  7. 百度地图 控件——路网地图和影像地图切换

    百度地图  控件--路网地图和影像地图切换 <!DOCTYPE html> <html> <head> <meta http-equiv="Cont ...

  8. 这些坑别踩!游戏随机地图生成开发经验分享

    当时虽然简单实现了目的,但后来自己也感到世界地图的呈现并不十分完美,恐怕也就只值95分.为了精益求精且给自己找点事做,便想对大地图的呈现方式做些微调. 之前略有瑕疵的世界地图 为何选择2D? 素材好找 ...

  9. 第一章:costmap_2d代价地图生成原理

    系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录 前言 (1)[代价地图]costmap_2d功能包源码解读 (1)代价地图 ...

最新文章

  1. 推荐系统炼丹笔记:用户评论在推荐中的应用
  2. 外刊晨读 2018 年 年 5 月 月 15 日
  3. 家庭问题(信息学奥赛一本通-T1362)
  4. SQLite内部机制和新特性
  5. 差异性发展 - 浙江工商局长郑宇民“智斗”央视女主持董倩
  6. kindeditor跨域上传文件php,WebClient实现kindeditor跨域上传图片
  7. c html中让图片反色,图片反色.html
  8. 逆radon变换matlab,Radon变换及其Matlab代码实现
  9. 基于C# SQLServer开发学员管理系统
  10. hbase实战 与mysql_HBase实战系列1—压缩与编码技术
  11. cle IMP-00015: 由于对象已存在, 下列语句失败
  12. TextView自动调节字体大小
  13. 【Java基础】Debug模式操作流程及案例:不死神兔、百钱百鸡
  14. 本人以及硕士期间研究介绍
  15. 罗马字母和希腊字母读法(in math)
  16. 随谈——那些前端的事1:关于坚持1
  17. 新近手机测试工具速递
  18. 360悬浮球-小贝常规样式
  19. go语言并发之MPG模型
  20. html怎么链接ftp地址,在浏览器的地址栏中输入xxxyftp.abc.com.cn,该URL中()是要访 - 信管网...

热门文章

  1. Git 使用 stash暂存代码
  2. w5500跨网段_串口转以太网模块—W5500S2E-S1如何与计算机建立局域网
  3. 棋牌游戏开发不可缺少的四大技术支持
  4. 考勤登记管理系统(参考答案)
  5. 教你根据情况快速导入单号查询快递单号物流
  6. wampserver图标为绿色,打开localhost页面错误提示:The requested URL / was not found on this server
  7. 【技法操作】UI界面设计,用PS绘制定位app页面设计教程
  8. 6-32 表头插入法构造链表
  9. 大数据DBA:大数据数据库管理做什么
  10. 增量式编码器和绝对式编码器的介绍