最近在要实现一个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;
}

最后,出一张效果图

 

最新文章

  1. UML图
  2. Hadoop内功修炼
  3. Ceph剖析:数据分布之CRUSH算法与一致性Hash
  4. unbuntu apahce 2 设置 多域名
  5. Java多线程基础知识(二)
  6. JQ获取当前是第几个元素,以及直接选取第几个元素的方法
  7. Win7 64 安装Visual Studio 2010和SQL Server 2008 R2
  8. 基于动态库的C++插件开发模型
  9. CF192div2-330B - Road Construction
  10. php错误捕捉
  11. git bash【初级入门篇】
  12. Android:Service的非绑定式的创建和生命周期
  13. commons-beanutils使用
  14. IDEA关掉重复代码波浪线
  15. jq获取页面url后边带的参数
  16. ubuntu 出错 /etc/sudoers is world writable
  17. UML标准建模语言与应用实例
  18. IIS8.5 Error Code 0x8007007e HTTP 错误 500.19的解决方法
  19. 人人网(cookie登录)
  20. 开源 免费 java CMS - FreeCMS1.9 移动APP管理 网站配置

热门文章

  1. Properties类随笔
  2. lnmp架构(第一篇)
  3. Gvim安装nerd_tree插件
  4. 比较三个 CSS 预处理器:Sass、LESS 和 Stylus(上)
  5. 【笔记】shellcode相关整理
  6. Apache配置网站根目录
  7. 转:【Java并发编程】之二:线程中断(含代码)
  8. JQuery中的表单验证及相关的内容
  9. 结对实验---基于GUI的四则运算
  10. LaTeX排版指南