前言

昨天写了好久的博文我没保存,今天在来想继续写居然没了,气死人啊这种情况你们见到过没,所以今天重新写,我还是切换到了HTML格式的书写上。废话不多说了,我们现在就进入主题,上周我仔细研究了WebGis基于openlayers的显示问题,同事也略微的实现了地图上的点击事件当然啦,这周我们将细分为点和线的点击事件,如果读者有兴趣也可以自己研究区域的点击事件,说白了就是我们初中时候学的那个三维立体的思想,或者读者也可以私下找我交流。

逻辑思想

(点)在处理这些点击事件中我突然想到一个很常见的思路,就是我通过点击来获取屏幕的坐标,然后在将屏幕的坐标转换成对应地图上的经纬度,拿到经纬度之后去和数据库里面一条一条匹配,最后从数据查到这个点了我就将这个点的信息给输出,如果我没有查到这个点就说明我没有点击到这个点上。但是值得注意的一点就是我们地图在屏幕上是很小的,是存在点击误差的,什么叫点击误差就是我们点击地图上的点我们肉眼上觉得是点击了点,但是实际上我们点击的那个点的坐标和地图上的那个点的坐标是存在一定的误差的,所以我为了实现肉眼上的点击点的事件,我在查找数据库的时候给定了一个我们肉眼默认的误差范围的,也就是说我在数据中并不是真正去查这个点,而是查询数据库中的点到我这个店的距离的,只要这个距离小于我指定的误差值,我就默认为这两个点是同一个点,这也就是我实现点的思路;那么问题来了如果我在地图上点击的时候出现了两个点都和我这个点的距离在我的误差范围之内呢,答案是肯定会的,那么有的读者会问,这个该怎么办呢。不用担心我有解决方法。在取到不止两个的情况下我们去距离最小的那一个,离的最近的我们默认选择这个点的
(线)处理完点自然就是线了,在处理线的时候我一开始的思路就是拿角度去比对,如果是统一角度的就说明我们点击的点在这条线上面,如果不是统一角度就不在这条线上,这个方法后来我实行了,当然这个也是存在误差的,我指定好了误差之后就可行的,但是在性能上不好,没有在距离的方法有效,因为如果我们用角度的话,角度会根据大小的不同误差级别,也就是说角度本身就有误差,在加上我们的肉眼的误差这样就相当于放大了误差,所以最后在项目里我放弃了角度的方法,后来我换了一种思路,我可以求点到直线的距离啊,这样我就成功的将角度的问题转换成了上面的距离的问题了,而且高中我们都会用点到直线的距离公式,而且俩个点确定直线的方程我们也都会使用最后整理了一下就是下面的代码来实现球点到直线的距离,拿到了距离了就回归了我们上面的点的处理中了,我们只要指定误差范围就可以了。
(总结)理论呢就是这么多,估计有的同学已经开始着急了,怎么还没有代码啊,个人觉得!授人以渔不如授人以渔。所以我在上面才唠叨半天,只要你们理解我的思路,下面的代码只需要有初中的水平就可以看得懂了。

/*续上*/

代码实现

<span style="font-size:24px;"><span style="font-size:18px;">1、在map地图上我们注册点击事件,唯一不同的是我们在这里自行区分点线</span>
map.events.register("click", map, function(e) {
//编写点击事件
}</span>

2、获取屏幕坐标从而转向地理坐标

var lonlat = map.getLonLatFromPixel(e.xy);

3、通过地理坐标去和已有的数据进行匹配查询,这里说的已有数据是说数据库中已经存在的点和线的数据,我现在js模拟一下数据库的写法(data就是数据里的数据)

if(data.length>1){
var min=getDis(data[0].x, data[0].y, data[1].x, data[1].y, lonlat.lon, lonlat.lat);
var index=0;
for(var i=0;i<data.length;i++){
<span style="font-family:SimHei;"> </span>if(i<data.length-1){
var fx = data[i].x;
var fy = data[i].y;
var tx = data[i+1].x;
var ty = data[i+1].y;
<span style="font-family:SimHei;"> </span>}
var dis = getDis(fx, fy, tx, ty, lonlat.lon, lonlat.lat);
if(dis<min){
min=dis;
index=i;
}
}
var wc = judgediswc(map.getZoom());
if(wc>=min){ //在误差范围内,可以认为是同一线
var lineName = data[index].site_name+">"+data[index+1].site_name;
//alert(lineName);
$("#qds").val(lineName);
}else{
searRailLine(lonlat.lon, lonlat.lat);
}
}else{
searRailLine(lonlat.lon, lonlat.lat);
}

4、这里提到的getDis 和 judgediswc  还有searRailLine这几个方法都是自己去写的,他们的作用是分别计算点到直线的距离、点到直线距离和误差的比较、去真实数据库查找线的方法。下面进行这三个方法的讲解

4-1、获得点到直线的距离,这个就是我们初高中经常用到的点到直线距离公式,自己稍加推到就可以看得懂了,这个没有什么技术含量,只有别把坐标位置放错了,就可以了,这个返回的dis就是我们需要的距离。这个算法我在数据里也封装好了,待会最后我会帖进来的。

function getDis(fx,fy,tx,ty,lon,lat){
var dis = 637800.138 * (
Math.abs(
(
(ty - fy) * lon
) + (
(fx -
tx) *
lat
) + tx * fy - ty * fx
)
) / (
Math.pow(
(ty
- fy) * (ty - fy) + (fx -
tx) * (fx -
tx),
0.5
)
);
return dis;
}

4-2、误差的大小(由于地图的缩放级别不同,我们的误差也不同,这个在前面的理论中我已经解释过了,这个就不多说了)这个就返回我们肉眼能够接受的误差最大值

function judgediswc(level){
var dis=0;
var angle=0;
if(level==15){
dis=12;
angle=42;
}else if(level==14){
dis=16;
angle=94;
}else if(level==13){
dis=52;
angle=149;
}else if(level==12){
dis=69;
angle=403;
}else if(level==11){
dis=178;
angle=479;
}else if(level==10){
dis=294;
angle=1093;
}else if(level==9){
dis=682;
angle=1449;
}else if(level==8){
dis=1488;
angle=4143;
}else if(level==7){
dis=3521;
angle=4617;
}else if(level==6){
dis=6636;
angle=5265;
}else if(level==5){
dis=7051;
angle=30217;
}else if(level==4){
dis=25763;
angle=68126;
}else if(level==3){
dis=60342;
angle=120000;
}else if(level==2){
dis=88189;
angle=220000;
}else if(level==1){
dis=110189;
angle=1000000;
}
return angle;
}

4-3、下面的方法我们就是真正去数据库查找的,上面的方法没有实际用处,只是为了掩饰给读者的快捷方法(注意我ajax的传参 很重要)

function searRailLine(lon,lat){
var sus = function(json, status) {
//alert();
var lineName = json.map[0].station_name+"站"+">"+json.map[0].next_name+"站";
$("#qds").val(lineName);
siteJson = json.map;
};
AjaxUtil.ajaxCon(path + "/echartMap/selectLineNameStr.json", {lon:lon,lat:lat,angle:judgediswc(map.getZoom())},
sus);
}

5、具体的三层架构实现我就不写了,相信能看到这里的孩子们三层架构一定都了解。我直接贴sql语句(x,y,z分别是经度、纬度、地图的显示级别)方法中返回的是点到直线的最小距离(有可能有很多个直线都是符合的我们取最小的那个)

<!-- 点在线上的方法啊 -->
<select id="selectLine" resultType="java.util.HashMap">
SELECT
line_name,
station_name,
station_x,
station_y,
next_name,
next_x,
next_y,
t
FROM
(
SELECT
line_name,
station_name,
station_x,
station_y,
next_name,
next_x,
next_y,
637800.138 * (
ABS(
(
(station_y - next_y) * #{x}
) + (
(next_x -
station_x) *
#{y}
) + station_x * next_y - station_y * next_x
)
) / (
POWER(
(station_y
- next_y) * (station_y - next_y) + (next_x -
station_x) * (next_x -
station_x),
0.5
)
) AS t
FROM
rail_line
) AS t
WHERE
t
< #{angle}
AND station_y >= #{y}
AND next_y <= #{y}
order by t asc limit 0,1
</select>

6、有的读者会问了,说好的点和线呢,你的点呢,别着急啊,我先把难的讲完简单,点呢我就把sql语句贴出来,返回了距离的值,在后台你想怎么办就怎么办,那就看你自己了。对吧

<!-- 获取站名 -->
<select id="selectPosition" resultType="String" parameterType="HashMap">
<![CDATA[
SELECT
t.name
FROM
(
SELECT
x.name,
ROUND(
6378.138 * 2 * ASIN(
SQRT(
POW(
SIN(
(#{y} * PI()
/ 180 - y * PI() / 180) / 2
),
2
) + COS(
#{y} * PI() / 180) * COS(y *
PI() / 180
) * POW(
SIN(
(
#{x} * PI() / 180 - x * PI() / 180
) / 2
),
2
)
)
) * 1000
) AS dis
FROM
(select SITE_NAME name ,fx x,fy y from TKYZ_BASE
UNION
select SITE_NAME name,fx x,fy y from THYZ_BASE
UNION
select SITE_NAME name,fx x,fy y from TKHYZ_BASE
UNION
select SITE_NAME name,fx x,fy y from TYXHR_BASE
UNION
select SITE_NAME name,fx x,fy y from TBZQD_BASE)x
) AS t
WHERE
t.dis BETWEEN 0
AND #{z}
order by t.dis asc limit 1
]]>
</select>

效果贴图

1、途中高亮显示的是模拟的js中的数据,点击高亮部分就会在脚本中查询我模拟的数据

2、点击高亮线路(北京--》北京南--》丰台)跳出相应的线路信息

3、点击非高亮地区会去查询数据库中的数据,就是真正的数据,如果点击在线上了也会弹出线的详细信息

4、如果我们点击在点上面就会 是点的相应信息,就不贴出来了,在高亮的线上我留个bug就是在线的延长线上也是认为在线上的,实际上不应该认为是线上,这点由于时间紧急我当时就没有写,读者有兴趣自己补充,提示一下判断点的位置是否在线的两端的中间就可以了,这个功能在点击非高亮线的sql语句我实现了的,可以参考一下。

总结

研究了openlayers也有两周了,这两周学到的东西很多。学东西一定要从底层学,才可以学到真正的东西。openlayers的几个基本功能我都已经实现了(地图显示+点线点击事件+定位点+定位线+居中显示墨点+手型显示),其他一些实时定位并随地理位置变动而变动的这个功能没有去实现,因为就两周时间,也就这样了,之间走了很多的弯路,所以发出博文希望对学习WebGis的新同学有点帮助

带你剖析WebGis的世界奥秘----点和线的世界的更多相关文章

  1. 带你剖析WebGis的世界奥秘----点和线的世界(转)

    带你剖析WebGis的世界奥秘----点和线的世界 转:https://zxhtom.oschina.io/zxh/20160813.html  编程  java  2016/08/13 0留言, 0 ...

  2. 带你剖析WebGis的世界奥秘----Geojson数据加载(高级)(转)

    带你剖析WebGis的世界奥秘----Geojson数据加载(高级) 转:https://zxhtom.oschina.io/zxh/20160819.html  编程  java  2016/08/ ...

  3. 带你剖析WebGis的世界奥秘----瓦片式加载地图(转)

    带你剖析WebGis的世界奥秘----瓦片式加载地图 转:https://zxhtom.oschina.io/zxh/20160805.html  编程  java  2016/08/05 0留言,  ...

  4. 带你剖析WebGis的世界奥秘----Geojson数据加载(高级)

    前言:前两周我带你们分析了WebGis中关键步骤瓦片加载+点击事件(具体的看前两篇文章),下面呢,我带大家来看看Geojson的加载及其点击事件 Geojson数据解析 GeoJSON是一种对各种地理 ...

  5. 带你剖析WebGis的世界奥秘----瓦片式加载地图

    WebGIS应用程序的页面能够通过HTML.JSP.ASP或任何任何类型的Web页文件构成,其特殊之处在于,它的请求提交的方法并不是通过常用的 "超链接"形式,而是使用鼠标与Web ...

  6. 笔者带你剖析轻量级Sharding中间件——Kratos1.x

    之所以编写Kratos其实存在一个小插曲,当笔者满山遍野寻找成熟.稳定.高性能的Sharding中间件时,确实是翻山越岭,只不过始终没有找到一款合适笔者项目场景的中间件产品.依稀记得当年第一款使用的S ...

  7. 笔者带你剖析淘宝TDDL(TAOBAO DISTRIBUTE DATA LAYER)

    注:本文部分内容引用本人博客http://gao-xianglong.iteye.com/blog/1973591   前言 在开始讲解淘宝的TDDL(Taobao Distribute Data L ...

  8. 带你剖析淘宝TDDL——Matrix层的分库分表配置与实现

    前言 在开始讲解淘宝的TDDL(Taobao Distribute Data Layer)技术之前,请允许笔者先吐槽一番.首先要开喷的是淘宝的社区支持做的无比的烂,TaoCode开源社区上面,几乎从来 ...

  9. 《笔者带你剖析Apache Commons DbUtils 1.6》(转)

    前言 关于Apache的DbUtils中间件或许了解的人并不多,大部分开发人员在生成环境中更 多的是依靠Hibernate.Ibatis.Spring JDBC.JPA等大厂提供的持久层技术解决方案, ...

随机推荐

  1. Ceph Plugin - Dashboard - By Anoyi

    ▶ 部署 Dashboard 1.安装 ceph-mgr-dashboard yum install -y ceph-mgr-dashboard 2.禁用 SSL ceph config set mg ...

  2. Django前端HTML通过JS实现表格可编辑,动态添加行,回车完成新建文件夹

    功能描述: 点击“新建文件夹”按钮,在table的末尾增加一行:单击页面的新增行,使单元格td变成可编辑状态:输入内容后,当单元格失去焦点时,保存输入的内容:回车后通过AJAX提交后台完成新建文件夹. ...

  3. 安卓学习资料推荐《深入理解Android:卷2》下载

    下载地址:百度云下载地址 编辑推荐 <深入理解Android:卷2>编辑推荐:经典畅销书<深入理解Android:卷I>姊妹篇,51CTO移动开发频道和开源中国社区一致鼎力推荐 ...

  4. Node热部署插件

    一.supervisor 首先需要使用 npm 安装 supervisor(这里需要注意一点,supervisor必须安装到全局) $ npm install -g supervisor Linux ...

  5. 【二分讲解及例题】火车站台连锁店-C++

    首先我们先来从一个小游戏理解一下二分.(摘自程序员小灰的博客) 为什么说这样效率最高呢?因为每一次选择数字,无论偏大还是偏小,都可以让剩下的选择范围缩小一半. 给定范围0到1000的整数: 第一次我们 ...

  6. go 格式化 int,位数不够0补齐

    n := 32 sInt := fmt.Sprintf("%07d", n)

  7. Spring Cloud 之 Zuul基础.

    一.概述  API 网关是一个更为智能的应用服务器,它的定义类似于面向对象设计模式中的 Facade 模式,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户端访问都需要经过它来进行调度和过滤 ...

  8. jdk安装错误1316,jdk-10.0.1

    打开注册表regedit ,定个位到 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\ 把jdk,jre下面的目录删掉.即10.0.1 ,问题解决 参考: https ...

  9. 个人永久性免费-Excel催化剂功能第90波-xml与json数据结构转换表格结构

    在网络时代,大量的数据交互以xml和json格式提供,特别是系统间的数据交互和网络WebAPI.WebService接口的数据提供,都是通过结构化的xml或json提供给其他应用调用返回数据.若能提供 ...

  10. python-if条件判断与while/for循环

    条件判断if 让计算机像人一样,能判断是非对错,根据条件做一些事情. if ''' ------ if代码结构:------- if 条件: 代码体 tips:同一缩进范围内的代码被视作同一代码体,p ...