openlayer的凸包算法实现
最近在要实现一个openlayer的凸多边形,也遇到了不小的坑,就记录一下
1.具体的需求:
通过在界面点击,获取点击是的坐标点,来绘制一个凸多边形。
2.思考过程:
1)首先,我们得先获取点击事件发生时,触发的点的坐标
map.events.register('click', map, function (e) {
var pixel = new OpenLayers.Pixel(e.xy.x,e.xy.y);
var lonlat = map.getLonLatFromPixel(pixel);
/* lonlat.transform(new OpenLayers.Projection("EPSG:4326")); //由900913坐标系转为4326 */
var newPoint = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
})
2)将获得的点做成一个凸多边形(ps:中间遇到点小坑)
(1)将获得的点坐标设置为map的点对象,点对象一步步转化为一个map的多边形对象
/**
* 绘画凸多边形图层
* @param {Object} pointList
*/
function drawConvex(pointList){
var linearRing = new OpenLayers.Geometry.LinearRing(pointList);
var LinearArr = linearRing.components;
var polygonFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([linearRing]));
map.addLayer(vectorLayer);
vectorLayer.addFeatures([polygonFeature]);
}
接下来,重要的来了,如何将获取的无序的坐标集合转化为凸多边形的点呢?(这里也是血泪史的开始)
原本的思路:1.首先得到点,前两个点不做判断,
· 2.将第三个开始的坐标做一个判断,判断是否在凸多边形内
//判断点是否在多边形内
function PointInPoly(pt, poly) {
for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
&& (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
&& (c = !c);
return c;
}
3将不在凸多边形内的点(也就是新点)与多边形的其他坐标做判断,通过距离排序来找出距离最近的点,然后将新点插入点的数组中,本以为这样就可以得到一个有 序的点数组,结果代码写出来了,发现这个和预想不一样,未获得预想的效果。具体代码如下,有大牛懂的话可以指点下。
//确定插入点在多边形的位置
function idIndex(p, points){
var arr = [];
for(var i =0;i<points.length;i++){
var obj ={"id":"","distance":"","name":""};
obj.distance = getFlatternDistance(points[i],p);
obj.id=i;
obj.name = points[i].id;
arr.push(obj);
}
arr.sort(by("distance"));
console.log("arr距离:",arr);
if(arr.length<2)
return 0; return arr[1].id;
} /**
* by函数接受一个成员名字符串做为参数
并返回一个可以用来对包含该成员的对象数组进行排序的比较函数
* @param {Object} name
*/
function by(name){
return function(o,p){
var a, b;
if(typeof o === "object" && typeof p === "object" && o && p) {
a= o[name];
b= p[name];
if(a === b) {
return 0;
}
if(typeof a === typeof b) {
return a < b ? -1 : 1;
}
return typeof a < typeof b ? -1 : 1;
}else{
throw("error");
}
}
} //俩点之间的距离
function getFlatternDistance(pointa,pointb){
var f = getRad((pointa.x + pointb.x)/2);
var g = getRad((pointa.x - pointb.x)/2);
var l = getRad((pointa.y - pointb.y)/2); var sg = Math.sin(g);
var sl = Math.sin(l);
var sf = Math.sin(f); var s,c,w,r,d,h1,h2;
var a = EARTH_RADIUS;
var fl = 1/298.257; sg = sg*sg;
sl = sl*sl;
sf = sf*sf; s = sg*(1-sl) + (1-sf)*sl;
c = (1-sg)*(1-sl) + sf*sl; w = Math.atan(Math.sqrt(s/c));
r = Math.sqrt(s*c)/w;
d = 2*w*a;
h1 = (3*r -1)/2/c;
h2 = (3*r +1)/2/s; return d*(1 + fl*(h1*sf*(1-sg) - h2*(1-sf)*sg));
} var EARTH_RADIUS = 6378137.0; //单位M
var PI = Math.PI;
function getRad(d){
return d*PI/180.0;
}
最后,是实现凸包算法的代码(下面的代码是git上找到的,可以实现给一个无序数组,将其中的点排序,过滤生成一个凸多边形,可以省略掉我上面判断点是否在多边形内)
function convexHull(points) {
points.sort(function (a, b) {
return a.x != b.x ? a.x - b.x : a.y - b.y;
});
var n = points.length;
var hull = [];
for (var i = 0; i < 2 * n; i++) {
var j = i < n ? i : 2 * n - 1 - i;
while (hull.length >= 2 && removeMiddle(hull[hull.length - 2], hull[hull.length - 1], points[j]))
hull.pop();
hull.push(points[j]);
}
hull.pop();
return hull;
}
function removeMiddle(a, b, c) {
var cross = (a.x - b.x) * (c.y - b.y) - (a.y - b.y) * (c.x - b.x);
var dot = (a.x - b.x) * (c.x - b.x) + (a.y - b.y) * (c.y - b.y);
return cross < 0 || cross == 0 && dot <= 0;
}
最后,出一张效果图

openlayer的凸包算法实现的更多相关文章
- 圈水池 nyoj 78 凸包算法
圈水池 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水, ...
- Graham Scan凸包算法
获得凸包的算法可以算是计算几何中最基础的算法之一了.寻找凸包的算法有很多种,Graham Scan算法是一种十分简单高效的二维凸包算法,能够在O(nlogn)的时间内找到凸包. 首先介绍一下二维向量的 ...
- 计算几何-凸包算法 Python实现与Matlab动画演示
凸包算法是计算几何中的最经典问题之一了.给定一个点集,计算其凸包.凸包是什么就不罗嗦了 本文给出了<计算几何——算法与应用>中一书所列凸包算法的Python实现和Matlab实现,并给出了 ...
- Beauty Contest(graham求凸包算法)
Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 25256 Accepted: 7756 Description Bess ...
- Graham凸包算法简介
凸包真是一个神奇的算法.. 概念 凸包,我理解为凸多边形 叉积 对于向量AB和向量BC,记向量AB*向量BC = AB * BC * sin ∠ABC,而叉积的绝对值其实就是S△ABC/2 对于平面上 ...
- 587. Erect the Fence(凸包算法)
问题 给定一群树的坐标点,画个围栏把所有树围起来(凸包). 至少有一棵树,输入和输出没有顺序. Input: [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]] Output: ...
- 向量积&&凸包算法
参考:Thanks 百度百科 http://blog.csdn.net/keng_s/article/details/52131034 https://www.cnblogs.com/aiguona/ ...
- POJ1113:Wall (凸包算法学习)
题意: 给你一个由n个点构成的多边形城堡(看成二维),按顺序给你n个点,相邻两个点相连. 让你围着这个多边形城堡建一个围墙,城堡任意一点到围墙的距离要求大于等于L,让你求这个围墙的最小周长(看成二维平 ...
- 凸包算法(Graham扫描法)详解
先说下基础知识,不然不好理解后面的东西 两向量的X乘p1(x1,y1),p2(x2,y2) p1Xp2如果小于零则说明 p1在p2的逆时针方向 如果大于零则说明 p1在p2的顺时针方向 struct ...
随机推荐
- jquery的2.0.3版本源码系列(6):2880-3042行,回调对象,对函数的统一管理
目录 1 . 回调对象callbacks的演示 回调的使用有一点像事件绑定,先绑定好,等到有点击事件或者其他时就触发. <script src="js/jquery-2.0.3.js& ...
- Markdown最佳实践
Markdown 最佳实践 结合目前看到的信息,总结使用Markdown的最方便的方式. 我的需求是: 能够配合各种笔记软件使用,目前主要使用的是为知笔记和有道笔记.笔记的内容需要记录代码及数学公式, ...
- python程序之profile分析
操作系统 : CentOS7.3.1611_x64 python版本:2.7.5 问题描述 1.Python开发的程序在使用过程中很慢,想确定下是哪段代码比较慢: 2.Python开发的程序在使用过程 ...
- JS中的事件以及DOM 操作
[DOM树节点] DOM节点分为三大节点:元素节点,文本节点,属性节点. 文本节点,属性节点为元素节点的两个子节点通过getElment系列方法,可以去到元素节点 [查看节点] 1 document. ...
- ADO.NET中SQL Server数据库连接池
连接到数据库服务器通常由几个需要很长时间的步骤组成. 必须建立物理通道(例如套接字或命名管道),必须与服务器进行初次握手,必须分析连接字符串信息,必须由服务器对连接进行身份验证,必须运行检查以便在当前 ...
- 比较两个date返回日期相差天数
public static int daydiff(Date fDate, Date oDate) { Calendar aCalendar = Calendar.getInstance(); aCa ...
- JVM和java应用服务器调优
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt413 对于调优这个事情来说,一般就是三个过程: 性能监控:问题没有发生,你并 ...
- [js高手之路]Vue2.0基于vue-cli+webpack父子组件通信教程
在git命令行下,执行以下命令完成环境的搭建: 1,npm install --global vue-cli 安装vue命令行工具 2,vue init webpack vue-demo 使用v ...
- grunt之concat、cssmin、uglify
周末有点懒,跑去看了<智取威虎山>,手撕鬼子的神剧情节被徐老怪一条回忆线就解释过去了,牛到极致尽是这种四两拨千斤的处理方式,手撕加分,四星推荐. --------------------- ...
- C# 文件的操作
C#对文件的操作相当方便,主要涉及到四个类:File.FileInfo.Directory.DirectoryInfo,前两个提供了针对文件的操作,后两个提供了针对目录的操作,类图关系如上图所示; 下 ...