按网上的思路一般要写双层循环,第一层循环遍历点集合,时间复杂度为O(N),第二层循环遍历结果集,逐一计算距离,距离小于阈值的不加入结果集,距离大于阈值的加入结果集,时间复杂度为O(M),双层循环总时间复杂度为O(N * M)。

新的算法思路:坐标点的经纬度经过计算得到的结果作为HashMap的Key,坐标相近的点的Key相同,利用HashMap降低时间复杂度,不需要第二层循环遍历,把时间复杂度由O(N * M)降为O(N)。

该算法的优点:1、抽稀后坐标点位置均匀,2、计算效率高(时间复杂度:O(N)),3、算法逻辑简单,4、计算结果幂等(结果集确定,多次重复计算结果集相同)。

代码:

//抽稀
if (mapZoom >= 15 && mapZoom <= 16) {
currentMarkerMap = new HashMap(); var getKey = function (lng, lat, len, ratio) { //如果计算结果数量较少,就调大ratio
var a = (10000 + lng * ratio).toString().substr(0, len);
var b = (10000 + lat * ratio).toString().substr(0, len)
return a + "," + b;
}; for (var i = 0; i < forAdd.length; i++) {
var marker = forAdd[i]; var key;
if (mapZoom == 15) key = getKey(marker.geometry.x, marker.geometry.y, 9, 1);
if (mapZoom == 16) key = getKey(marker.geometry.x, marker.geometry.y, 10, 1); if (!currentMarkerMap.containsKey(key)) {
currentMarkerMap.put(key, marker);
}
}
}

说明:代码中 forAdd 变量是抽稀前的坐标点集合,currentMarkerMap 变量是HashMap集合(HashMap是自己实现的JS类),定义代码如下:

var forClear = [];
var currentMarkerMap = new HashMap();

效果图:

缩小:

放大:

动态效果:

新算法:

说明:上面的代码用的是SuperMap iClient Classic 8C,下面用的是Leaflet

function refreshVillageMarkers(map, deviceLayer) {
//获取地图层级
let mapZoom = map.getZoom(); //点位完全显示层级
let visibleZoom = mapType == 1 ? 17 : 17; //1:使用SuperMap地图 2:使用高德地图 //获取地图可视区域
let polygon = getMapBounds(map); //获取小区点位集合
let villageMarkerArr = getVillageMarkerArr(); //筛选出可视区域内的点位
let visibleMarkerArr = [];
for (let marker of villageMarkerArr) {
if (!marker.options.rnd) {
marker.options.rnd = Math.random();
} let latLng = marker.getLatLng();
let point = turf.point([latLng.lng, latLng.lat]); if (turf.booleanPointInPolygon(point, polygon)) {
visibleMarkerArr.push(marker);
}
} //可视区域内的点位抽稀
let forAdd = [];
let visibleCount = 300;
let ratio = 1;
if (visibleMarkerArr.length > visibleCount) {
ratio = visibleCount / visibleMarkerArr.length;
}
for (let marker of visibleMarkerArr) {
if (mapZoom >= visibleZoom || marker.options.rnd < ratio) {
forAdd.push(marker);
}
} //移除可视区域外的和被抽稀掉的点位
for (let marker of currentMarkerMap.values()) {
let latLng = marker.getLatLng();
let point = turf.point([latLng.lng, latLng.lat]); if (!turf.booleanPointInPolygon(point, polygon) || (mapZoom < visibleZoom && marker.options.rnd >= ratio)) {
deviceLayer.removeLayer(marker);
currentMarkerMap.delete(marker.options.id);
}
} //可视区域内的点位添加到图层上
for (let marker of forAdd) {
deviceLayer.addLayer(marker);
if (!currentMarkerMap.has(marker.options.id)) {
currentMarkerMap.set(marker.options.id, marker);
}
} //打印
console.info('实际显示点位数/可视区点位数(' + (currentMarkerMap.size == visibleMarkerArr.length ? '相等' : '不相等') + '):' + currentMarkerMap.size + '/' + visibleMarkerArr.length)
} //获取地图可视区域
function getMapBounds(map) {
let nw = map.getBounds().getNorthWest();
let ne = map.getBounds().getNorthEast();
let se = map.getBounds().getSouthEast();
let sw = map.getBounds().getSouthWest();
let polygon = turf.polygon([[
[nw.lng, nw.lat],
[ne.lng, ne.lat],
[se.lng, se.lat],
[sw.lng, sw.lat],
[nw.lng, nw.lat]
]]);
return polygon;
}

地图区域大数据量 marker 坐标点高效抽稀算法的更多相关文章

  1. PGIS大数据量点位显示方案

    PGIS大数据量点位显示方案 问题描述 PGIS在地图上显示点位信息时,随点位数量的增加浏览器响应速度会逐渐变慢,当同时显示上千个点时浏览器会变得非常缓慢,以下是进行的测试: 测试环境: 服务器: C ...

  2. [WP8.1UI控件编程]Windows Phone大数据量网络图片列表的异步加载和内存优化

    11.2.4 大数据量网络图片列表的异步加载和内存优化 虚拟化技术可以让Windows Phone上的大数据量列表不必担心会一次性加载所有的数据,保证了UI的流程性.对于虚拟化的技术,我们不仅仅只是依 ...

  3. php 大数据量及海量数据处理算法总结

    下面的方法是我对海量数据的处理方法进行了一个一般性的总结,当然这些方法可能并不能完全覆盖所有的问题,但是这样的一些方法也基本可以处理绝大多数遇到的问题.下面的一些问题基本直接来源于公司的面试笔试题目, ...

  4. java处理大数据量任务时的可用思路--未验证版,具体实现方法有待实践

    1.Bloom filter适用范围:可以用来实现数据字典,进行数据的判重,或者集合求交集基本原理及要点:对于原理来说很简单,位数组+k个独立hash函数.将hash函数对应的值的位数组置1,查找时如 ...

  5. Export大数据量导出和打包

    项目需求 ​ 导出生成大批量数据的文件,一个Excel中最多存有五十万条数据,查询多余五十万的数据写多个Excel中.导出完成是生成的多个Excel文件打包压缩成zip,而后更新导出记录中的压缩文件路 ...

  6. 大数据量冲击下Windows网卡异常分析定位

    背景 mqtt的服务端ActiveMQ在windows上,多台PC机客户端不停地向MQ发送消息. 现象 观察MQ自己的日志data/activemq.log里显示,TCP链接皆异常断开.此时尝试从服务 ...

  7. POI3.8解决导出大数据量excel文件时内存溢出的问题

    POI3.8的SXSSF包是XSSF的一个扩展版本,支持流处理,在生成大数据量的电子表格且堆空间有限时使用.SXSSF通过限制内存中可访问的记录行数来实现其低内存利用,当达到限定值时,新一行数据的加入 ...

  8. jquery.datatable.js与CI整合 异步加载(大数据量处理)

    http://blog.csdn.net/kingsix7/article/details/38928685 1.CI 控制器添加方法 $this->show_fields_array=arra ...

  9. MySQL随机获取数据的方法,支持大数据量

    最近做项目,需要做一个从mysql数据库中随机取几条数据出来. 总所周知,order by rand 会死人的..因为本人对大数据量方面的只是了解的很少,无解,去找百度老师..搜索结果千篇一律.特发到 ...

  10. 大数据量下,分页的解决办法,bubuko.com分享,快乐人生

    大数据量,比如10万以上的数据,数据库在5G以上,单表5G以上等.大数据分页时需要考虑的问题更多. 比如信息表,单表数据100W以上. 分页如果在1秒以上,在页面上的体验将是很糟糕的. 优化思路: 1 ...

随机推荐

  1. FC 交换机基础配置

    目录 Primera600 存储服务器 FC 交换机 交换机信息查看 交换机配置管理 用户管理 以太网配置 端口配置管理 别名配置 证书管理 角色管理 Zone 管理 参考网址 Primera600 ...

  2. UNCTF-Crypto wp

    2020年 easy_rsa 题目 from Crypto.Util import number import gmpy2 from Crypto.Util.number import bytes_t ...

  3. VLOOKUP函数10种经典用法

    VLOOKUP函数是Excel中非常常用的函数之一,可以用于在一个区域或表格中查找某个值,并返回该值所在行的另一个指定列中的数值.以下是VLOOKUP函数的10种经典用法: 基本的VLOOKUP用法: ...

  4. 09 - Shell流程控制语句

    1. if-else语句 能够使用if条件语句进行条件判断 1.1 if 语法 if 条件 then 命令 fi if 条件; then 命令; fi 1.2 if-else 语法 if 条件 the ...

  5. [c/c++][考研复习笔记]内部排序篇学习笔记

    考研排序复习笔记 插入排序 #include<stdio.h> #include<stdlib.h> #define MaxSize 9 //折半插入排序 void ZBIns ...

  6. 记一次 .NET 某药厂业务系统 CPU爆高分析

    一:背景 1. 讲故事 前段时间有位朋友找到我,说他们的程序出现了CPU爆高,让我帮忙看下怎么回事?这种问题好的办法就是抓个dump丢给我,推荐的工具就是用 procdump 自动化抓捕. 二:Win ...

  7. Kernel Memory 入门系列:Kernel Memory Service

    Kernel Memory 入门系列:Kernel Memory Service 在 Kernel Memory 的 GitHub 仓库中有一个单独的项目 Service , 用于提供独立的Kerne ...

  8. 操作系统大作业:在Linux环境下模拟实现简单命令解释器(代码部分)

    好家伙   1. 题目要求 一.   课程设计(大作业)目的 熟悉Linux编程环境,加强对Linux命令的理解及函数的运用,完成一个操作系统的部分系统的设计过程.编码.调试,锻炼实际应用能力. 二. ...

  9. 算法2:Hanoi塔

    汉诺(Hanoi)塔 一.背景介绍 在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了 ...

  10. 递归产生StackOverflowError

    package com.guoba.digui; public class Demo01 { public void A(){ A();//自己调用自己,递归没用好,产生错误java.lang.Sta ...