多边型无序点排序(地图绘制多边形)

2019-11-26 11:08:02

参考地址 多边型无序点排序(地图绘制多边形)

从这些点里随便选一个(比如最左边最下面哪一个)
然后以这个点为原点按极角排序(极角相同按距离排序)

 

前言

任务需求要做一个区域高亮的功能,用到地图,想到了高德地图的多边形API,但是多边形顶点的顺序是要有序的,需求是无序,在API查找无果的情况下,只能手动实现点集合排序。

排序步骤

  1. 计算所有坐标的中心点(将x坐标相加处以数量,将y坐标相加处以数量)

  2. 计算所有点与中点的夹角(水平夹角或者垂直夹角)

  3. 按夹角大小排序

代码实现

  • 收集3个以上的坐标点放入到集合中private ArrayList<LatLng> list;

  • 计算中心点坐标

double plusX = 0, plusY = 0;for (LatLng latLng : list) {plusX += latLng.latitude;plusY += latLng.longitude;}center = new LatLng(plusX / list.size(), plusY / list.size());
  • 通过工具方法获得2个点坐标对应的在垂直方向上的角度

/**     * @param lat_a 纬度1     * @param lng_a 经度1     * @param lat_b 纬度2     * @param lng_b 经度2     * @return     */private double getAngle1(double lat_a, double lng_a, double lat_b, double lng_b) {double y = Math.sin(lng_b - lng_a) * Math.cos(lat_b);double x = Math.cos(lat_a) * Math.sin(lat_b) - Math.sin(lat_a) * Math.cos(lat_b) * Math.cos(lng_b - lng_a);double brng = Math.atan2(y, x);brng = Math.toDegrees(brng);if (brng < 0)brng = brng + 360;return brng;}
  • 将坐标数组转换为HashMap<Integer, ArrayList<Object>> 映射为下标->(角度,坐标)

HashMap<Integer, ArrayList<Object>> mapAll = new HashMap<>();for (int i = 0; i < list.size(); i++) {//第一个放经纬度 第二个放角度ArrayList<Object> objList = new ArrayList<>();objList.add(list.get(i));objList.add(getAngle1(center.latitude, center.longitude,list.get(i).latitude, list.get(i).longitude));mapAll.put(i, objList);}
  • 采用冒泡排序法对角度进行排序

ArrayList<Object> temp = new ArrayList<>();int size = mapAll.size();for (int i = 0; i < size - 1; i++) {for (int j = 0; j < size - 1 - i; j++) {if (Double.parseDouble(mapAll.get(j).get(1).toString()) >Double.parseDouble(mapAll.get(j + 1).get(1).toString()))  //交换两数位置{temp = mapAll.get(j);mapAll.put(j, mapAll.get(j + 1));mapAll.put(j + 1, temp);}}}
  • 生成新的顺时针的坐标点集合

list.clear();for (Integer integer : mapAll.keySet()) {if (mapAll.get(integer).get(0) instanceof LatLng) {list.add((LatLng) mapAll.get(integer).get(0));}}

高德功能,将多点形成的多边形显示在一个屏幕上

for (int i = 0; i < list.size(); i++) {boundsBuilder.include(list.get(i));//把所有点都include进去(LatLng类型)}aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(boundsBuilder.build(), 100));//第二个参数为四周间隔


  • 2020-01-17 08:44:57

    vue keepalive 前进刷新后退不刷新终极解决方案

    另外,我们做路由的时候要有意的根据页面等级做出路由的长度 比如 /a是一级的页面/a/b是二级的页面,下面的文章大家也可以通过判断path的长度来计算rank值,不用有意自定了 这样做的好处有两点,一个就是前进刷新,后退不刷新,还有就是,如果我们做页面进出效果的时候也能排上用场。

  • 2020-01-17 15:28:24

    深入理解vue中的slot与slot-scope

    vue中关于插槽的文档说明很短,语言又写的很凝练,再加上其和methods,data,computed等常用选项使用频率、使用先后上的差别,这就有可能造成初次接触插槽的开发者容易产生“算了吧,回头再学,反正已经可以写基础组件了”,于是就关闭了vue说明文档。

  • 2020-01-17 21:20:06

    Nuxt重要点介绍和记录

    nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染).Vue.js是开发SPA(单页应用)的,Nuxt.js这个框架,用Vue开发多页应用,并在服务端完成渲染,可以直接用命令把我们制作的vue项目生成为静态html。

  • 2020-01-17 21:21:42

    nuxtjs打包优化

    然后你再使用 npm run build 打包的时候,会弹出一个界面 当然了,它第一次出来的时候我立马关了,这啥玩意???别着急你慢慢的品,慢慢的看。 原来 这是打包后的JS,面积的大小就是体积的大小。这样我们一目了然的看到了到底那里大了

  • 2020-01-17 23:21:54

    webpack打包优化之外部扩展externals的实际应用

    使用vue-cli创建项目,使用webpack打包。其中,有一个webpack优化webpack.optimize.CommonsChunkPlugin,它会将node_modules中的必需模块提取到vendor文件中,项目开发中,增加第三方模块,比如element-ui、vue-echarts等,vendor的包都会增大。这个时候,就需要考虑减轻vendor包的大小,增加构建速度。我们可以使用webpack的外部扩展(externals)功能。

  • 2020-01-18 01:26:59

    anyProxy使用注意事项

    anyproxy-ca 运行这个命令,如果是mac电脑他会提醒你去通过证书。

  • 2020-01-18 08:54:06

    利用localStorage来处理你的Javascript脚本错误

    localStorage作为HTML5中的新特性,它的出现可以说对于前端性能体验来讲可以获得相当大的改善。存储一些用户经常用到而又不是涉及隐私和安全的东西,的确是一个非常好的选择。下面分享一下用localStorage来处理客户端代码错误的例子来了解一下它的用途吧。