1. 程式人生 > 其它 >演算法 之 地理座標抽稀

演算法 之 地理座標抽稀

地理座標抽稀

問題

  • 一組點 points [point(x1,y1),point(x2,y2),point(x3,y3),……],每個點在螢幕上顯示tag
  • 隨著比例尺變化,tag會收縮到一起,顯示效果很差
  • 尋找一種方法,隨著比例尺變化,points中的點動態 隱藏與顯示
比例尺1 比例尺2

思路

  • 動態計算解析度 1(px) = ?(m) geoRES
  • 構建格網 單位:xGES = xLimit * geoRES , yGES = yLimit * geoRES
  • 遍歷點,若點所在格網單元內沒有任何點,該點顯示且新增記錄,反之則隱藏
  • 缺點: 部分點有可能相距很近
/*     xGES                               (xmax,ymax)
                +  +  +  +  +  +  +  +  +  +  +  +  +
           yGES +        +  p5    +        +  p4    +
                +        +        +        +        +
                +  +  +  +  +  +  +  +  +  +  +  +  +
                +  p9    +        + p2     +        +
                +        +        + p7(out)+        +
                +  +  +  +  +  +  +  +  +  +  +  +  +
                +        + p1     +        + p3     +
                +        +p10(out)+        +        +
                +  +  +  +  +  +  +  +  +  +  +  +  +
                +  p6    +        +  p8    +        +
                +        +        +        +        +
                +  +  +  +  +  +  +  +  +  +  +  +  +
     (xmin,ymin)
*/

js 部分程式碼

// 獲取抽稀點
let points = this.getPoints(this.viewer);

// 獲取空間螢幕解析度
let geoRES = this.calGeoRES();
if(geoRES === null) return;

//獲取點範圍
let extent = this.calExtent(points);
if(extent === null) return;

// 抽稀引數:this.x this.y 這個可以控制抽稀力度
let xGES = geoRES * this.x;
let yGES = geoRES * this.y;
const {xMin, yMin, xMax, yMax}= extent;

// 定義命中實體記錄
let hitMap = new Array<Array<Entity>>();

points.forEach(point => {
    if(point.position){
        let xy = point.position.getValue(JulianDate.now());
        let i = Math.round((xy.x - xMin)/xGES);
        let j = Math.round((xy.y - yMin)/yGES);
        
        if(hitMap[i] == undefined)
            hitMap[i] = new Array<Entity>();

        if(hitMap[i][j])
            point.show = false;
        else{
            hitMap[i][j] = point;
            point.show = true;
        }
            
    }
})


效果展示