需求

2016年5月,客户要求在地图上显示路灯及数据,分析数据生成报表,以便查看分析路灯情况。

选型

国外项目就不考虑国内的地图了,开始想使用google的web地图,考虑到地图上标记物过多影响性能及使用体验,对gmap测试后,选用gmap.net。

开发

功能:

1.导入路灯及数据,在地图上添加、编辑、删除路灯,路灯数据软件修正、移除错误数据

2.地图上线时路灯及数据,数据以标记、曲线、表格方式显示

3.导出整个系统数据,下次可以将系统导出的文件导入进行查看;导出生成excel报表

4.多点测距;多边形方式进行选择查看,选择多边形内路灯情况

代码

计算2个坐标点距离

    private static double EARTH_RADIUS = 6378137;//赤道半径(单位m)
/**
* 转化为弧度(rad)
* */
private static double rad(double d)
{
return d * Math.PI / 180.0;
} /**
* 基于余弦定理求两经纬度距离
* @param lon1 第一点的精度
* @param lat1 第一点的纬度
* @param lon2 第二点的精度
* @param lat3 第二点的纬度
* @return 返回的距离,单位m
* */
public static double GetDistance(double lng1, double lat1, double lng2, double lat2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2); double radLng1 = rad(lng1);
double radLng2 = rad(lng2); if (radLat1 < 0)
radLat1 = Math.PI / 2 + Math.Abs(radLat1);// south
if (radLat1 > 0)
radLat1 = Math.PI / 2 - Math.Abs(radLat1);// north
if (radLng1 < 0)
radLng1 = Math.PI * 2 - Math.Abs(radLng1);// west
if (radLat2 < 0)
radLat2 = Math.PI / 2 + Math.Abs(radLat2);// south
if (radLat2 > 0)
radLat2 = Math.PI / 2 - Math.Abs(radLat2);// north
if (radLng2 < 0)
radLng2 = Math.PI * 2 - Math.Abs(radLng2);// west
double x1 = EARTH_RADIUS * Math.Cos(radLng1) * Math.Sin(radLat1);
double y1 = EARTH_RADIUS * Math.Sin(radLng1) * Math.Sin(radLat1);
double z1 = EARTH_RADIUS * Math.Cos(radLat1); double x2 = EARTH_RADIUS * Math.Cos(radLng2) * Math.Sin(radLat2);
double y2 = EARTH_RADIUS * Math.Sin(radLng2) * Math.Sin(radLat2);
double z2 = EARTH_RADIUS * Math.Cos(radLat2); double d = Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
//余弦定理求夹角
double theta = Math.Acos((EARTH_RADIUS * EARTH_RADIUS + EARTH_RADIUS * EARTH_RADIUS - d * d) / (2 * EARTH_RADIUS * EARTH_RADIUS));
double dist = theta * EARTH_RADIUS;
return dist;
}

获取方向角度

    /// <summary>
/// 获取方向角度
/// </summary>
/// <param name="lon1"></param>
/// <param name="lat1"></param>
/// <param name="lon2"></param>
/// <param name="lat2"></param>
/// <returns></returns>
public static double GetDirection(double lon1, double lat1, double lon2, double lat2)
{
double x1 = lon1;
double y1 = lat1;
double x2 = lon2;
double y2 = lat2;
double pi = Math.PI;
double w1 = y1 / 180 * pi;
double j1 = x1 / 180 * pi;
double w2 = y2 / 180 * pi;
double j2 = x2 / 180 * pi;
double ret;
if (j1 == j2)
{
if (w1 > w2) ret = 270; //北半球的情况,南半球忽略
else if (w1 < w2) ret = 90;
else ret =-1;//位置完全相同
}
ret = 4 * Math.Pow(Math.Sin((w1 - w2) / 2), 2) - Math.Pow(Math.Sin((j1 - j2) / 2) * (Math.Cos(w1) - Math.Cos(w2)), 2);
ret = Math.Sqrt(ret);
double temp = (Math.Sin(Math.Abs(j1 - j2) / 2) * (Math.Cos(w1) + Math.Cos(w2)));
ret = ret / temp;
ret = Math.Atan(ret) / pi * 180;
if (j1 > j2) // 1为参考点坐标
{
if (w1 > w2) ret += 180;
else ret = 180 - ret;
}
else if (w1 > w2) ret = 360 - ret; return ret;
//result.Text = Convert.ToString(ret); //if ((ret <= 10) || (ret > 350)) angle.Text = "东";
//if ((ret > 10) && (ret <= 80)) angle.Text = "东北";
//if ((ret > 80) && (ret <= 100)) angle.Text = "北";
//if ((ret > 100) && (ret <= 170)) angle.Text = "西北";
//if ((ret > 170) && (ret <= 190)) angle.Text = "西";
//if ((ret > 190) && (ret <= 260)) angle.Text = "西南";
//if ((ret > 260) && (ret <= 280)) angle.Text = "南";
//if ((ret > 280) && (ret <= 350)) angle.Text = "东南";
}

判断坐标是否在多边形内

    /// <summary>
/// 判断点是否在多边形内.
/// </summary>
/// <param name="checkPoint">要判断的点</param>
/// <param name="polygonPoints">多边形的顶点</param>
/// <returns></returns>
public static bool IsInPolygon(PointLatLng checkPoint, List<PointLatLng> polygonPoints)
{
int counter = 0;
int i;
double xinters;
PointLatLng p1, p2;
int pointCount = polygonPoints.Count;
p1 = polygonPoints[0];
for (i = 1; i <= pointCount; i++)
{
p2 = polygonPoints[i % pointCount];
if (checkPoint.Lat > Math.Min(p1.Lat, p2.Lat)//校验点的Y大于线段端点的最小Y
&& checkPoint.Lat <= Math.Max(p1.Lat, p2.Lat))//校验点的Y小于线段端点的最大Y
{
if (checkPoint.Lng <= Math.Max(p1.Lng, p2.Lng))//校验点的X小于等线段端点的最大X(使用校验点的左射线判断).
{
if (p1.Lat != p2.Lat)//线段不平行于X轴
{
xinters = (checkPoint.Lat - p1.Lat) * (p2.Lng - p1.Lng) / (p2.Lat - p1.Lat) + p1.Lng;
if (p1.Lng == p2.Lng || checkPoint.Lng <= xinters)
{
counter++;
}
}
} }
p1 = p2;
} if (counter % 2 == 0)
{
return false;
}
else
{
return true;
}
}

多点测距



多边形选择

关于测距

测距尝试过使用gmap提供的根据道路测距,发现还是不太准,所以还是选择了手动选择坐标点连线测距。

后记

该项目2018年初还增加了一些功能,开发过程中有不少次沟通和修改,主要就是一些gps和数据拆分、补全上的处理和报表算法上有些繁琐,项目目前暂时告一段落。

【项目记录】-路灯监测 gmap.net的更多相关文章

  1. IOS客户端Coding项目记录导航

    IOS客户端Coding项目记录(一) a:UITextField设置出现清除按键 b:绘画一条下划线  表格一些设置 c:可以定义表头跟底部视图(代码接上面) d:隐藏本页的导航栏 e:UIEdge ...

  2. Unity Project Wizard (最近打开的项目记录)

    最近打开工程列表 当用Unity打开过的项目越来越多之后,在最近打开项目记录框中就会变的很长,那么如何才能删除最近打开的记录呢? Unity4.x最近打开的工程记录 Unity5.x最近打开的工程记录 ...

  3. jenkins构建项目记录2(tag)

    与jenkins构建项目记录1不同的是通过tag拉去对应版本代码 1.先安装创建(git parameter) 2.general设置 name可任意命名,下面源码管理设置时变量会引用到. 3.源码管 ...

  4. 【项目记录】-液化气配送app android版

    15年底参与过甲方呼叫中心平台开发.液化气配送app android版要求1个月开发完成.开发此项目以前我只有过一周android的开发经验.(与甲方签署过保密协议,遵循职业道德有些敏感信息不能写.) ...

  5. 用spring+hibernate+struts 项目记录以及常用的用法进等

    一.hibernate1. -----BaseDao------ // 容器注入 private SessionFactory sessionFactory; public void setSessi ...

  6. [项目记录] 用c语言完成的一个学生成绩管理系统

    一.要求: 学生成绩管理系统 某班有最多不超过30人(具体人数由键盘输入)参加期末考试,最多不超过6门(具体门数由键盘输入).使用链表编程实现如下菜单驱动的学生成绩管理系统. 从文件读入每个学生个人信 ...

  7. [项目记录]一个.net下使用HAP实现的吉大校园通知网爬虫工具:OAWebScraping

    第一章 简介 本文主要介绍了在.NET下利用优秀的HTML解析组件HtmlAgilityPack开发的一个吉林大学校内通知oa.jlu.edu.cn的爬取器.尽管.Net下解析HTML文件有很多种选择 ...

  8. vue 项目记录.路飞学城(一)

    前情提要: 通过vue 搭建路飞学城记录  一:项目分析 二:项目搭建 1:创建项目 vue init webpack luffy 2:初始化项目 清除默认的HelloWorld.vue组件和APP. ...

  9. wc项目记录

    1.Github项目地址:https://github.com/3116004700/ruanjiangongcheng 2.预估时间见PSP表格. 3.解题思路描述: 在看到这个项目的时候我就想到了 ...

随机推荐

  1. Android之MaterialDesign应用技术

    PS:纵观现在大大小小软件的界面都变的比较漂亮,还有一些系统了,比如小米的MIUI,华为的EMUI等,虽然底层都是安卓,但他们的界面多多少少都会不同,谷歌对这个UI也是非常重视的,MaterialDe ...

  2. Codeforces 900 E. Maximum Questions (DP,技巧)

    题目链接:900 E. Maximum Questions 题意: 给出一个长度为n只含有a和b还有'?'的串s,且'?'可以被任意替换为a或b.再给出一个字符串t (奇数位上为a,偶数位上为b,所以 ...

  3. Java数据持久层框架 MyBatis之API学习二(入门)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  4. 自动化测试框架Selenium工作原理

    本文所讲的Selenium是指Selenium Webdriver Selenium WebDriver与RC的功能相同,并且包含原始的1.x绑定.它涉及语言绑定和单个浏览器控制代码的实现.这通常被称 ...

  5. 用Express、MySQL搭建项目(接口以及静态文件获取、文件上传等)

    一.简介 本文将主要基于node.js使用express框架搭建一个后台环境,包括如何自定义项目目录.所用依赖以及中间件.路由以及模板引擎.接口数据获取以及文件上传等内容. 二.后台环境搭建 1.新建 ...

  6. set&enum小结(database)

    今天发现mysql中有set这种数据类型,工作的业务中也使用到了.网上查阅资料后,小结一下 先总结一下两者的分别 set和enum类似表单中的多选和单选,set和enum在数据库内部是用整数表示的,显 ...

  7. pandas读取excel中指定数据的行数

    shuju = pd.read_excel(filename) loandata = pd.DataFrame(shuju) ncol = (len(loandata.keys())) data = ...

  8. JavaScript高级编程小结

    Undefined 对未初始化的变量执行typeof操作符会返回undefined值,而对未声明的变量执行typeof操作符同样也会返回undefined var message; console.l ...

  9. lambda高级进阶--返回函数

    在函数式编程语言中,函数是一级公民.如同你可以将数字传递给方法,也可以让方法产生数字一样,函数不仅可以作为参数,也可以作为返回值.这听起来好像有点抽象,在JAVA编码中,我们好像也很少这样子写到,但是 ...

  10. Maven 常用配置

    pom.xml基础配置: <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEn ...