gpt4 book ai didi

数据可视化【原创】vue+arcgis+threejs实现海量建筑物房屋渲染,性能优化

转载 作者:我是一只小鸟 更新时间:2023-08-31 07:38:50 33 4
gpt4 key购买 nike

本文适合对vue,arcgis4.x,threejs,ES6较熟悉的人群食用.

先报备一下版本号 。

 "vue": "^2.6.11" 。

"@arcgis/core": "^4.21.2" 。

"three": "^0.149.0" 。

语法:vue,ES6 。

  。

其实现在主流很多海量建筑渲染的方案是加载3DTiles服务图层,可是奈何我们这里没有这个配套。只能全部依靠前端来渲染,目前数据量在6万级别的不规则建筑物房屋.

试过很多方案,当然,还有一个很重要的因素,就是你的机器显卡厉不厉害,反正我的很垃圾,GTX1050,笔记本,我把chrome的强制使用显卡渲染开启了,避免集成显卡出来搞笑。以下方案中的代码是基于项目接口的,不能直接跑起来,但是关键的策略逻辑已经完全体现.

  。

先说结论,我选的方案3.

1 :首先根据视口内切圆的范围来查询,把构建了的要素缓存,在地图漫游的时候在缓存中查找,避免重复构建,移出视口内切圆范围的要素移除(缓存不清除),其实就和瓦片加载机制(行列号级别缓存)类似。还要限制级别,如果当级别很小的时候,视口内切圆中的数据量太多,会卡顿,所以这种方案最好是做达到一定级别,房屋图层渐变显示,反之渐变消失,代码中有。再用arcgis的graphicslayer,计算faces,构建Mesh对象,这个构建Mesh的过程需要根据3D知识自己写(getFaces,getTopFaces,getSideFaces),代码中有。这个方案性能很一般,大概只能大几千的数据量,顶多1万,并且在数据量支持不了的时候我开启了延迟队列加载的策略。样式控制相对于featurelayer灵活一点,效果也可控制,比如使用gsap动画库做伸展效果.

                  
                      1
                  
                  
                    import
                  
                   GraphicsLayer from "@arcgis/core/layers/GraphicsLayer"
                  
                    ;

                  
                  
                      2
                  
                  
                    import
                  
                   Graphic from "@arcgis/core/Graphic"
                  
                    ;

                  
                  
                      3
                  
                  
                    import
                  
                   Mesh from "@arcgis/core/geometry/Mesh"
                  
                    ;

                  
                  
                      4
                  
                  
                    import
                  
                   Polygon from "@arcgis/core/geometry/Polygon"
                  
                    ;

                  
                  
                      5
                  
                  
                    import
                  
                   Polyline from "@arcgis/core/geometry/Polyline"
                  
                    ;

                  
                  
                      6
                  
                  
                    import
                  
                   Circle from "@arcgis/core/geometry/Circle"
                  
                    ;

                  
                  
                      7
                  
                  
                    import
                  
                   * as watchUtils from "@arcgis/core/core/watchUtils"
                  
                    ;

                  
                  
                      8
                  
                  
                    import
                  
                   * as geometryEngine from "@arcgis/core/geometry/geometryEngine"
                  
                    ;

                  
                  
                      9
                  
                  
                    import
                  
                   mapx from '@/utils/mapUtils.js'
                  
                    ;

                  
                  
                     10
                  
                  
                     11
                  
                   export 
                  
                    default
                  
                  
                    class
                  
                  
                     BMLayer {

                  
                  
                     12
                  
                  
                        constructor(ops) {

                  
                  
                     13
                  
                  
                    this
                  
                  .$url =
                  
                     ops.url;

                  
                  
                     14
                  
                  
                    this
                  
                  .$view =
                  
                     ops.view;

                  
                  
                     15
                  
                  
                    //
                  
                  
                     this.$zoom = ops.zoom;
                  
                  
                     16
                  
                  
                    this
                  
                  .$ofomatter =
                  
                     ops.ofomatter;

                  
                  
                     17
                  
                  
                    this
                  
                  .$idkey =
                  
                     ops.idkey;

                  
                  
                     18
                  
                  
                    this
                  
                  .$click =
                  
                     ops.click;

                  
                  
                     19
                  
                  
                    this
                  
                  .$zfomatter =
                  
                     ops.zfomatter;

                  
                  
                     20
                  
                  
                    this
                  
                  .$wfomatter =
                  
                     ops.wfomatter;

                  
                  
                     21
                  
                  
                    this
                  
                  .$sfomatter =
                  
                     ops.sfomatter;

                  
                  
                     22
                  
                  
                     23
                  
                  
                    this
                  
                  
                    .setup()

                  
                  
                     24
                  
                  
                        }

                  
                  
                     25
                  
                  
                     26
                  
                  
                        setup() {

                  
                  
                     27
                  
                  
                    this
                  
                  .layer = 
                  
                    null
                  
                  
                    ;

                  
                  
                     28
                  
                  
                    this
                  
                  .highlightSelect = 
                  
                    null
                  
                  
                    ;

                  
                  
                     29
                  
                  
                    this
                  
                  .preModels =
                  
                     {};

                  
                  
                     30
                  
                  
                    this
                  
                  .ef = 1.2
                  
                    ;

                  
                  
                     31
                  
                  
                    this
                  
                  .currentCircle = 
                  
                    null
                  
                  
                    ;

                  
                  
                     32
                  
                  
                    this
                  
                  .autoLoad = 
                  
                    false
                  
                  
                    ;

                  
                  
                     33
                  
                  
                     34
                  
                  
                    this
                  
                  .rendering = 
                  
                    false
                  
                  
                    ;

                  
                  
                     35
                  
                  
                     36
                  
                  
                    this
                  
                  .layer = 
                  
                    new
                  
                  
                     GraphicsLayer();

                  
                  
                     37
                  
                  
                    this
                  
                  .$view.map.add(
                  
                    this
                  
                  
                    .layer);

                  
                  
                     38
                  
                  
                     39
                  
                  
                    this
                  
                  
                    .extentChanged();

                  
                  
                     40
                  
                  
                        }

                  
                  
                     41
                  
                  
                     42
                  
                  
                        addModel(fs) {

                  
                  
                     43
                  
                  
                    for
                  
                   (let key in 
                  
                    this
                  
                  
                    .preModels) {

                  
                  
                     44
                  
                               var m = 
                  
                    this
                  
                  
                    .preModels[key];

                  
                  
                     45
                  
                  
                    if
                  
                   (!
                  
                    this
                  
                  
                    .$view.extent.intersects(m.geometry)) {

                  
                  
                     46
                  
                  
                    this
                  
                  
                    .layer.remove(m);

                  
                  
                     47
                  
                                   delete 
                  
                    this
                  
                  
                    .preModels[key];

                  
                  
                     48
                  
                  
                                }

                  
                  
                     49
                  
                  
                            }

                  
                  
                     50
                  
                           var per = 100
                  
                    ;

                  
                  
                     51
                  
                  
                    if
                  
                   (fs.length <
                  
                     per) {

                  
                  
                     52
                  
                               per =
                  
                     fs.length;

                  
                  
                     53
                  
                  
                            }

                  
                  
                     54
                  
                           var sid = setInterval(() =>
                  
                     {

                  
                  
                     55
                  
                               var i = 0
                  
                    ;

                  
                  
                     56
                  
                  
                    for
                  
                   (; i < per; i++
                  
                    ) {

                  
                  
                     57
                  
                                   var f =
                  
                     fs.pop();

                  
                  
                     58
                  
                  
                    if
                  
                  
                     (f) {

                  
                  
                     59
                  
                                       var att =
                  
                     f.attributes;

                  
                  
                     60
                  
                                       var uid = att[
                  
                    this
                  
                  
                    .$idkey];

                  
                  
                     61
                  
                  
                     62
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .preModels.hasOwnProperty(uid)) {

                  
                  
                     63
                  
                  
                     64
                  
                                       } 
                  
                    else
                  
                  
                     {

                  
                  
                     65
                  
                                           var z = 
                  
                    this
                  
                  
                    .$zfomatter(att);

                  
                  
                     66
                  
                                           var model = 
                  
                    this
                  
                  .createModel(f, z, 
                  
                    this
                  
                  
                    .getBaseSymbol());

                  
                  
                     67
                  
                  
                    this
                  
                  
                    .layer.add(model);

                  
                  
                     68
                  
                  
                     69
                  
                  
                    this
                  
                  .preModels[uid] =
                  
                     model;

                  
                  
                     70
                  
                  
                                        }

                  
                  
                     71
                  
                                   } 
                  
                    else
                  
                  
                     {

                  
                  
                     72
                  
                  
                    this
                  
                  .rendering = 
                  
                    false
                  
                  
                    ;

                  
                  
                     73
                  
                  
                                        clearInterval(sid);

                  
                  
                     74
                  
                  
                    break
                  
                  
                    ;

                  
                  
                     75
                  
                  
                                    }

                  
                  
                     76
                  
                  
                                }

                  
                  
                     77
                  
                           }, 25
                  
                    );

                  
                  
                     78
                  
                  
                        }

                  
                  
                     79
                  
                  
                     80
                  
                  
                        click(results, mapPoint) {

                  
                  
                     81
                  
                  
                    if
                  
                   (results && results.length > 0
                  
                    ) {

                  
                  
                     82
                  
                               var grah = results[0
                  
                    ].graphic;

                  
                  
                     83
                  
                  
                    if
                  
                   (grah.layer === 
                  
                    this
                  
                  
                    .layer) {

                  
                  
                     84
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .highlightSelect) {

                  
                  
                     85
                  
                  
                    this
                  
                  
                    .highlightSelect.remove();

                  
                  
                     86
                  
                  
                                    }

                  
                  
                     87
                  
                  
                     88
                  
                  
                    this
                  
                  
                    .$view.whenLayerView(grah.layer).then(

                  
                  
                     89
                  
                                       layerView =>
                  
                     {

                  
                  
                     90
                  
                  
                    this
                  
                  .highlightSelect =
                  
                     layerView.highlight(grah);

                  
                  
                     91
                  
                  
                                        });

                  
                  
                     92
                  
                  
                    this
                  
                  .$click(grah, mapPoint, 
                  
                    this
                  
                  
                    .$view);

                  
                  
                     93
                  
                               } 
                  
                    else
                  
                  
                     {

                  
                  
                     94
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .highlightSelect) {

                  
                  
                     95
                  
                  
                    this
                  
                  
                    .highlightSelect.remove();

                  
                  
                     96
                  
                  
                                    }

                  
                  
                     97
                  
                  
                    //
                  
                  
                     this.$view.popup.close()
                  
                  
                     98
                  
                  
                                }

                  
                  
                     99
                  
                           } 
                  
                    else
                  
                  
                     {

                  
                  
                    100
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .highlightSelect) {

                  
                  
                    101
                  
                  
                    this
                  
                  
                    .highlightSelect.remove();

                  
                  
                    102
                  
                  
                                }

                  
                  
                    103
                  
                  
                    //
                  
                  
                     this.$view.popup.close()
                  
                  
                    104
                  
                  
                            }

                  
                  
                    105
                  
                  
                        }

                  
                  
                    106
                  
                  
                    107
                  
                  
                        clearHighlight() {

                  
                  
                    108
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .highlightSelect) {

                  
                  
                    109
                  
                  
                    this
                  
                  
                    .highlightSelect.remove();

                  
                  
                    110
                  
                  
                            }

                  
                  
                    111
                  
                  
                        }

                  
                  
                    112
                  
                  
                    113
                  
                  
                        setAutoLoad(v) {

                  
                  
                    114
                  
                  
                    this
                  
                  .autoLoad =
                  
                     v

                  
                  
                    115
                  
                  
                        }

                  
                  
                    116
                  
                  
                    117
                  
                  
                        extentChanged() {

                  
                  
                    118
                  
                  
                    return
                  
                   watchUtils.whenTrue(
                  
                    this
                  
                  .$view, "stationary", () =>
                  
                     {

                  
                  
                    119
                  
                  
                    //
                  
                  
                     console.log(this.$view.zoom)
                  
                  
                    120
                  
                  
                    const
                  
                   flag = 
                  
                    this
                  
                  .$ofomatter(
                  
                    this
                  
                  
                    .$view);

                  
                  
                    121
                  
                  
                    if
                  
                  
                     (flag) {

                  
                  
                    122
                  
                  
                    if
                  
                   (!
                  
                    this
                  
                  
                    .rendering) {

                  
                  
                    123
                  
                  
                    this
                  
                  .rendering = 
                  
                    true
                  
                  
                    ;

                  
                  
                    124
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .autoLoad) {

                  
                  
                    125
                  
                  
                    this
                  
                  
                    .loadData();

                  
                  
                    126
                  
                  
                                        }

                  
                  
                    127
                  
                  
                                    }

                  
                  
                    128
                  
                  
                    //
                  
                  
                     this.layer.visible = true;
                  
                  
                    129
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  .layer.opacity === 0
                  
                    ) {

                  
                  
                    130
                  
                  
                    this
                  
                  .fadeVisibilityOn(
                  
                    this
                  
                  .$view, 
                  
                    this
                  
                  .layer, 
                  
                    true
                  
                  
                    )

                  
                  
                    131
                  
                  
                                    }

                  
                  
                    132
                  
                               } 
                  
                    else
                  
                  
                     {

                  
                  
                    133
                  
                  
                    //
                  
                  
                     this.clearLayer();
                  
                  
                    134
                  
                  
                    this
                  
                  .rendering = 
                  
                    false
                  
                  
                    ;

                  
                  
                    135
                  
                  
                    //
                  
                  
                     this.layer.visible = false;
                  
                  
                    136
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  .layer.opacity === 1
                  
                    ) {

                  
                  
                    137
                  
                  
                    this
                  
                  .fadeVisibilityOn(
                  
                    this
                  
                  .$view, 
                  
                    this
                  
                  .layer, 
                  
                    false
                  
                  
                    )

                  
                  
                    138
                  
                  
                                    }

                  
                  
                    139
                  
                  
                                }

                  
                  
                    140
                  
                  
                            });

                  
                  
                    141
                  
                  
                        }

                  
                  
                    142
                  
                  
                    143
                  
                  
                        loadData() {

                  
                  
                    144
                  
                  
                    //
                  
                  
                     var r = this.getRadius(1.5);

                  
                  
                    145
                  
                  
                    //
                  
                  
                     var p = this.$view.center.clone();

                  
                  
                    146
                  
                  
                    //
                  
                  
                     p.z = 1;

                  
                  
                    147
                  
                  
                    //
                  
                  
                     this.currentCircle = new Circle(p, {

                  
                  
                    148
                  
                  
                    //
                  
                  
                         radius: r

                  
                  
                    149
                  
                  
                    //
                  
                  
                     });
                  
                  
                    150
                  
                           let where = ''

                  
                    151
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .$wfomatter) {

                  
                  
                    152
                  
                               where = 
                  
                    this
                  
                  
                    .$wfomatter();

                  
                  
                    153
                  
                  
                    //
                  
                  
                     console.log(where)
                  
                  
                    154
                  
                  
                            }

                  
                  
                    155
                  
                           mapx.queryTask(
                  
                    this
                  
                  
                    .$url, {

                  
                  
                    156
                  
                  
                                where: where,

                  
                  
                    157
                  
                               outSpatialReference: '4326'
                  
                    ,

                  
                  
                    158
                  
                               geometry: 
                  
                    this
                  
                  
                    .$view.extent,

                  
                  
                    159
                  
                               returnGeometry: 
                  
                    true
                  
                  
                    160
                  
                           }).then(featureSet =>
                  
                     {

                  
                  
                    161
                  
                  
                    this
                  
                  
                    .addModel(featureSet);

                  
                  
                    162
                  
                           }).
                  
                    catch
                  
                  (error =>
                  
                     {})

                  
                  
                    163
                  
                  
                        }

                  
                  
                    164
                  
                  
                    165
                  
                  
                        clearLayer() {

                  
                  
                    166
                  
                  
                    this
                  
                  
                    .layer.removeAll();

                  
                  
                    167
                  
                  
                    this
                  
                  .preModels =
                  
                     {};

                  
                  
                    168
                  
                  
                        }

                  
                  
                    169
                  
                  
                    170
                  
                  
                        createModel(f, h, sym) {

                  
                  
                    171
                  
                           var geo =
                  
                     f.geometry;

                  
                  
                    172
                  
                           var ris = geo.rings[0
                  
                    ];

                  
                  
                    173
                  
                  
                            ris.pop();

                  
                  
                    174
                  
                           var len =
                  
                     ris.length;

                  
                  
                    175
                  
                           var pos = 
                  
                    new
                  
                   Array((len - 1) * 2 * 3
                  
                    );

                  
                  
                    176
                  
                           var ii = 0
                  
                    ;

                  
                  
                    177
                  
                  
                    for
                  
                   (; ii < len; ii++
                  
                    ) {

                  
                  
                    178
                  
                               var ary =
                  
                     ris[ii];

                  
                  
                    179
                  
                               pos[ii * 3] = ary[0
                  
                    ];

                  
                  
                    180
                  
                               pos[ii * 3 + 1] = ary[1
                  
                    ];

                  
                  
                    181
                  
                               pos[ii * 3 + 2] = 0
                  
                    ;

                  
                  
                    182
                  
                               pos[ii * 3 + len * 3] = ary[0
                  
                    ];

                  
                  
                    183
                  
                               pos[ii * 3 + len * 3 + 1] = ary[1
                  
                    ];

                  
                  
                    184
                  
                               pos[ii * 3 + len * 3 + 2] =
                  
                     h;

                  
                  
                    185
                  
                  
                            }

                  
                  
                    186
                  
                  
                    187
                  
                           var polygon = 
                  
                    new
                  
                  
                     Polygon({

                  
                  
                    188
                  
                               type: "polygon"
                  
                    ,

                  
                  
                    189
                  
                  
                                rings: [ris]

                  
                  
                    190
                  
                  
                            });

                  
                  
                    191
                  
                  
                    192
                  
                           var ll = pos.length / 2 / 3
                  
                    ;

                  
                  
                    193
                  
                           var faces = 
                  
                    this
                  
                  
                    .getFaces(polygon, ll);

                  
                  
                    194
                  
                           var mesh = 
                  
                    new
                  
                  
                     Mesh({

                  
                  
                    195
                  
                  
                                vertexAttributes: {

                  
                  
                    196
                  
                  
                                    position: pos

                  
                  
                    197
                  
                  
                                },

                  
                  
                    198
                  
                  
                                components: [{

                  
                  
                    199
                  
                  
                                    faces: faces

                  
                  
                    200
                  
                  
                                }],

                  
                  
                    201
                  
                  
                            });

                  
                  
                    202
                  
                  
                    203
                  
                  
                            let symbol

                  
                  
                    204
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .$sfomatter) {

                  
                  
                    205
                  
                               symbol = 
                  
                    this
                  
                  .getBaseSymbol(
                  
                    this
                  
                  
                    .$sfomatter(f))

                  
                  
                    206
                  
                           } 
                  
                    else
                  
                  
                     {

                  
                  
                    207
                  
                               symbol =
                  
                     sym

                  
                  
                    208
                  
                  
                            }

                  
                  
                    209
                  
                           var graphic = 
                  
                    new
                  
                  
                     Graphic({

                  
                  
                    210
                  
                  
                                attributes: f.attributes,

                  
                  
                    211
                  
                  
                                geometry: mesh,

                  
                  
                    212
                  
                  
                                symbol: symbol

                  
                  
                    213
                  
                  
                            });

                  
                  
                    214
                  
                  
                    215
                  
                  
                    return
                  
                  
                     graphic;

                  
                  
                    216
                  
                  
                        }

                  
                  
                    217
                  
                  
                    218
                  
                  
                        getFaces(polygon, len) {

                  
                  
                    219
                  
                           var topfaces = 
                  
                    this
                  
                  
                    .getTopFaces(polygon);

                  
                  
                    220
                  
                           var sidefaces = 
                  
                    this
                  
                  
                    .getSideFaces(len);

                  
                  
                    221
                  
                  
                    //
                  
                  
                                    var i = 0;

                  
                  
                    222
                  
                  
                    //
                  
                  
                                    for(; i < topfaces.length; i++) {

                  
                  
                    223
                  
                  
                    //
                  
                  
                                        var t = topfaces[i];

                  
                  
                    224
                  
                  
                    //
                  
                  
                                        sidefaces.push(t);

                  
                  
                    225
                  
                  
                    //
                  
                  
                                    }
                  
                  
                    226
                  
                           var i = 0
                  
                    ;

                  
                  
                    227
                  
                  
                    for
                  
                   (; i < topfaces.length; i++
                  
                    ) {

                  
                  
                    228
                  
                               var t =
                  
                     topfaces[i];

                  
                  
                    229
                  
                               sidefaces.push(t +
                  
                     len);

                  
                  
                    230
                  
                  
                            }

                  
                  
                    231
                  
                  
                    return
                  
                  
                     sidefaces;

                  
                  
                    232
                  
                  
                        }

                  
                  
                    233
                  
                  
                    234
                  
                  
                        getTopFaces(polygon) {

                  
                  
                    235
                  
                           var temp =
                  
                     Mesh.createFromPolygon(polygon, {});

                  
                  
                    236
                  
                           var faces = temp.components[0
                  
                    ].faces;

                  
                  
                    237
                  
                  
                    return
                  
                  
                     faces;

                  
                  
                    238
                  
                  
                        }

                  
                  
                    239
                  
                  
                    240
                  
                  
                        getSideFaces(l) {

                  
                  
                    241
                  
                           var fas =
                  
                     [];

                  
                  
                    242
                  
                           var a =
                  
                     [];

                  
                  
                    243
                  
                           var i = 0
                  
                    ;

                  
                  
                    244
                  
                  
                    for
                  
                   (; i < l; i++
                  
                    ) {

                  
                  
                    245
                  
                               var n0 = 0
                  
                    ;

                  
                  
                    246
                  
                               var n1 = 0
                  
                    ;

                  
                  
                    247
                  
                               var n2 = 0
                  
                    ;

                  
                  
                    248
                  
                               var n3 = 0
                  
                    ;

                  
                  
                    249
                  
                  
                    if
                  
                   (i + 1 ==
                  
                     l) {

                  
                  
                    250
                  
                                   n0 =
                  
                     i;

                  
                  
                    251
                  
                                   n1 = 0
                  
                    ;

                  
                  
                    252
                  
                                   n2 = i +
                  
                     l;

                  
                  
                    253
                  
                                   n3 = i + 1
                  
                    ;

                  
                  
                    254
                  
                               } 
                  
                    else
                  
                  
                     {

                  
                  
                    255
                  
                                   n0 =
                  
                     i;

                  
                  
                    256
                  
                                   n1 = i + 1
                  
                    ;

                  
                  
                    257
                  
                                   n2 = i +
                  
                     l;

                  
                  
                    258
                  
                                   n3 = i + l + 1
                  
                    ;

                  
                  
                    259
                  
                  
                                }

                  
                  
                    260
                  
                  
                                fas.push(n0, n1, n2, n1, n2, n3);

                  
                  
                    261
                  
                           } 
                  
                    //
                  
                  
                    console.log(fas);
                  
                  
                    262
                  
                  
                    return
                  
                  
                     fas;

                  
                  
                    263
                  
                  
                        }

                  
                  
                    264
                  
                  
                    265
                  
                  
                        getRadius() {

                  
                  
                    266
                  
                           var extent = 
                  
                    this
                  
                  
                    .$view.extent;

                  
                  
                    267
                  
                           var paths =
                  
                     [

                  
                  
                    268
                  
                  
                                [

                  
                  
                    269
                  
                  
                                    [extent.xmin, extent.ymin],

                  
                  
                    270
                  
                  
                                    [extent.xmax, extent.ymax]

                  
                  
                    271
                  
                  
                                ]

                  
                  
                    272
                  
                  
                            ];

                  
                  
                    273
                  
                           var line = 
                  
                    new
                  
                  
                     Polyline({

                  
                  
                    274
                  
                  
                                paths: paths,

                  
                  
                    275
                  
                               spatialReference: 
                  
                    this
                  
                  
                    .$view.spatialReference

                  
                  
                    276
                  
                  
                            });

                  
                  
                    277
                  
                           var d = geometryEngine.geodesicLength(line, 9001
                  
                    );

                  
                  
                    278
                  
                  
                    return
                  
                   d * 0.5 * 
                  
                    this
                  
                  
                    .ef;

                  
                  
                    279
                  
                  
                        }

                  
                  
                    280
                  
                  
                    281
                  
                       getBaseSymbol(color = [224, 224, 224, 0.8
                  
                    ]) {

                  
                  
                    282
                  
                  
                    return
                  
                  
                     {

                  
                  
                    283
                  
                               type: "mesh-3d"
                  
                    ,

                  
                  
                    284
                  
                  
                                symbolLayers: [{

                  
                  
                    285
                  
                                   type: "fill"
                  
                    ,

                  
                  
                    286
                  
                  
                                    material: {

                  
                  
                    287
                  
                  
                                        color: color,

                  
                  
                    288
                  
                                       colorMixMode: "tint"

                  
                    289
                  
                  
                                    }

                  
                  
                    290
                  
                  
                                }]

                  
                  
                    291
                  
                  
                            }

                  
                  
                    292
                  
                  
                        }

                  
                  
                    293
                  
                  
                    294
                  
                  
                        fadeVisibilityOn(view, layer, flag) {

                  
                  
                    295
                  
                           let animating = 
                  
                    true
                  
                  
                    ;

                  
                  
                    296
                  
                           let opacity = flag ? 0 : 1
                  
                    ;

                  
                  
                    297
                  
                  
                    //
                  
                  
                     fade layer's opacity from 0 to

                  
                  
                    298
                  
                  
                    //
                  
                  
                     whichever value the user has configured
                  
                  
                    299
                  
                  
                    const
                  
                   finalOpacity = flag ? 1 : 0
                  
                    ;

                  
                  
                    300
                  
                           layer.opacity =
                  
                     opacity;

                  
                  
                    301
                  
                  
                    302
                  
                           view.whenLayerView(layer).then((layerView) =>
                  
                     {

                  
                  
                    303
                  
                  
                                function incrementOpacityByFrame() {

                  
                  
                    304
                  
                  
                    if
                  
                   (opacity >= finalOpacity &&
                  
                     animating) {

                  
                  
                    305
                  
                                       layer.opacity =
                  
                     finalOpacity;

                  
                  
                    306
                  
                                       animating = 
                  
                    false
                  
                  
                    ;

                  
                  
                    307
                  
                  
                    return
                  
                  
                    ;

                  
                  
                    308
                  
                  
                                    }

                  
                  
                    309
                  
                  
                    310
                  
                                   layer.opacity =
                  
                     opacity;

                  
                  
                    311
                  
                                   opacity += 0.07
                  
                    ;

                  
                  
                    312
                  
                  
                    313
                  
                  
                                    requestAnimationFrame(incrementOpacityByFrame);

                  
                  
                    314
                  
                  
                                }

                  
                  
                    315
                  
                  
                    316
                  
                  
                                function decrementOpacityByFrame() {

                  
                  
                    317
                  
                  
                    if
                  
                   (opacity <= finalOpacity &&
                  
                     animating) {

                  
                  
                    318
                  
                                       layer.opacity =
                  
                     finalOpacity;

                  
                  
                    319
                  
                                       animating = 
                  
                    false
                  
                  
                    ;

                  
                  
                    320
                  
                  
                    return
                  
                  
                    ;

                  
                  
                    321
                  
                  
                                    }

                  
                  
                    322
                  
                  
                    323
                  
                                   layer.opacity =
                  
                     opacity;

                  
                  
                    324
                  
                                   opacity -= 0.07
                  
                    ;

                  
                  
                    325
                  
                  
                    326
                  
                  
                                    requestAnimationFrame(decrementOpacityByFrame);

                  
                  
                    327
                  
                  
                                }

                  
                  
                    328
                  
                  
                    329
                  
                  
                    //
                  
                  
                     Wait for tiles to finish loading before beginning the fade
                  
                  
                    330
                  
                  
                                watchUtils.whenFalseOnce(

                  
                  
                    331
                  
                  
                                    layerView,

                  
                  
                    332
                  
                                   "updating"
                  
                    ,

                  
                  
                    333
                  
                  
                                    function(updating) {

                  
                  
                    334
                  
                  
                    if
                  
                  
                     (flag) {

                  
                  
                    335
                  
                  
                                            requestAnimationFrame(incrementOpacityByFrame);

                  
                  
                    336
                  
                                       } 
                  
                    else
                  
                  
                     {

                  
                  
                    337
                  
                  
                                            requestAnimationFrame(decrementOpacityByFrame);

                  
                  
                    338
                  
                  
                                        }

                  
                  
                    339
                  
                  
                                    }

                  
                  
                    340
                  
                  
                                );

                  
                  
                    341
                  
                  
                            });

                  
                  
                    342
                  
                  
                        }

                  
                  
                    343
                  
                  
                    344
                  
                   }
                
View Code

  。

2 :首先根据视口内切圆的范围来查询,把构建了的要素缓存,在地图漫游的时候在缓存中查找,避免重复构建,移出视口内切圆范围的要素移除(缓存不清除),其实就和瓦片加载机制(行列号级别缓存)类似。还要限制级别,如果当级别很小的时候,视口内切圆中的数据量太多,会卡顿,所以这种方案最好是做达到一定级别,房屋图层渐变显示,反之渐变消失,代码中有。再用arcgis的featurelayer,symbol的polygon-3d、extrude来构建加载,其实featurelayer应该是开了work异步加载的,但是数据量也就能保证在2万左右,并且初始化的时候加载策略和3dTiles是类似的,看不全!是在用户漫游地图,放大平移的时候分批加载的。性能一般,样式控制不灵活,效果也不行.

                  
                      1
                  
                  
                    import
                  
                   GraphicsLayer from "@arcgis/core/layers/GraphicsLayer"
                  
                    ;

                  
                  
                      2
                  
                  
                    import
                  
                   FeatureLayer from "@arcgis/core/layers/FeatureLayer"
                  
                    ;

                  
                  
                      3
                  
                  
                    import
                  
                   Graphic from "@arcgis/core/Graphic"
                  
                    ;

                  
                  
                      4
                  
                  
                    import
                  
                   Mesh from "@arcgis/core/geometry/Mesh"
                  
                    ;

                  
                  
                      5
                  
                  
                    import
                  
                   Polygon from "@arcgis/core/geometry/Polygon"
                  
                    ;

                  
                  
                      6
                  
                  
                    import
                  
                   Polyline from "@arcgis/core/geometry/Polyline"
                  
                    ;

                  
                  
                      7
                  
                  
                    import
                  
                   Circle from "@arcgis/core/geometry/Circle"
                  
                    ;

                  
                  
                      8
                  
                  
                    import
                  
                   * as watchUtils from "@arcgis/core/core/watchUtils"
                  
                    ;

                  
                  
                      9
                  
                  
                    import
                  
                   * as geometryEngine from "@arcgis/core/geometry/geometryEngine"
                  
                    ;

                  
                  
                     10
                  
                  
                    import
                  
                   * as webMercatorUtils from "@arcgis/core/geometry/support/webMercatorUtils"
                  
                    ;

                  
                  
                     11
                  
                  
                    import
                  
                   mapx from '@/utils/mapUtils.js'
                  
                    ;

                  
                  
                     12
                  
                  
                     13
                  
                   export 
                  
                    default
                  
                  
                    class
                  
                  
                     BMLayer {

                  
                  
                     14
                  
                  
                        constructor(ops) {

                  
                  
                     15
                  
                  
                    this
                  
                  .$url =
                  
                     ops.url;

                  
                  
                     16
                  
                  
                    this
                  
                  .$view =
                  
                     ops.view;

                  
                  
                     17
                  
                  
                    //
                  
                  
                     this.$zoom = ops.zoom;
                  
                  
                     18
                  
                  
                    this
                  
                  .$ofomatter =
                  
                     ops.ofomatter;

                  
                  
                     19
                  
                  
                    this
                  
                  .$idkey =
                  
                     ops.idkey;

                  
                  
                     20
                  
                  
                    this
                  
                  .$click =
                  
                     ops.click;

                  
                  
                     21
                  
                  
                    this
                  
                  .$zfomatter =
                  
                     ops.zfomatter;

                  
                  
                     22
                  
                  
                    this
                  
                  .$wfomatter =
                  
                     ops.wfomatter;

                  
                  
                     23
                  
                  
                    this
                  
                  .$sfomatter =
                  
                     ops.sfomatter;

                  
                  
                     24
                  
                  
                     25
                  
                  
                    this
                  
                  
                    .setup()

                  
                  
                     26
                  
                  
                        }

                  
                  
                     27
                  
                  
                     28
                  
                  
                        setup() {

                  
                  
                     29
                  
                  
                    this
                  
                  .layer = 
                  
                    null
                  
                  
                    ;

                  
                  
                     30
                  
                  
                    this
                  
                  .highlightSelect = 
                  
                    null
                  
                  
                    ;

                  
                  
                     31
                  
                  
                    this
                  
                  .preModels =
                  
                     {};

                  
                  
                     32
                  
                  
                    this
                  
                  .ef = 1.2
                  
                    ;

                  
                  
                     33
                  
                  
                    this
                  
                  .autoLoad = 
                  
                    false
                  
                  
                    ;

                  
                  
                     34
                  
                  
                    this
                  
                  .circle = 
                  
                    null
                  
                  
                    ;

                  
                  
                     35
                  
                  
                    this
                  
                  .circleGraphic = 
                  
                    null
                  
                  
                    ;

                  
                  
                     36
                  
                  
                    this
                  
                  .rendering = 
                  
                    false
                  
                  
                    ;

                  
                  
                     37
                  
                  
                    this
                  
                  .maxZoom = 20
                  
                    ;

                  
                  
                     38
                  
                  
                    this
                  
                  .baseRadius = 700
                  
                    ;

                  
                  
                     39
                  
                  
                    this
                  
                  .factor = 0.66
                  
                    ;

                  
                  
                     40
                  
                  
                     41
                  
                  
                    this
                  
                  .layer = 
                  
                    new
                  
                  
                     GraphicsLayer();

                  
                  
                     42
                  
                  
                    this
                  
                  .$view.map.add(
                  
                    this
                  
                  
                    .layer);

                  
                  
                     43
                  
                  
                     44
                  
                  
                    this
                  
                  .baselayer = 
                  
                    new
                  
                  
                     FeatureLayer({

                  
                  
                     45
                  
                  
                                source: [],

                  
                  
                     46
                  
                               objectIdField: "ObjectID"
                  
                    ,

                  
                  
                     47
                  
                               geometryType: 'polygon'
                  
                    ,

                  
                  
                     48
                  
                  
                                render: {

                  
                  
                     49
                  
                                   type: "simple"
                  
                    ,

                  
                  
                     50
                  
                                   symbol: 
                  
                    this
                  
                  
                    .getBaseSymbol()

                  
                  
                     51
                  
                  
                                }

                  
                  
                     52
                  
                  
                            });

                  
                  
                     53
                  
                  
                    this
                  
                  .$view.map.add(
                  
                    this
                  
                  
                    .baselayer);

                  
                  
                     54
                  
                  
                     55
                  
                  
                    this
                  
                  
                    .addEvents();

                  
                  
                     56
                  
                  
                        }

                  
                  
                     57
                  
                  
                     58
                  
                  
                        addModel(fs) {

                  
                  
                     59
                  
                  
                    for
                  
                   (let key in 
                  
                    this
                  
                  
                    .preModels) {

                  
                  
                     60
                  
                  
                    const
                  
                   m = 
                  
                    this
                  
                  
                    .preModels[key];

                  
                  
                     61
                  
                  
                    //
                  
                  
                     if (!this.$view.extent.intersects(m.geometry)) {
                  
                  
                     62
                  
                  
                    const
                  
                   flag = geometryEngine.intersects(
                  
                    this
                  
                  
                    .circle, m.geometry)

                  
                  
                     63
                  
                  
                    if
                  
                   (!
                  
                    flag) {

                  
                  
                     64
                  
                  
                    this
                  
                  
                    .layer.remove(m);

                  
                  
                     65
                  
                                   delete 
                  
                    this
                  
                  
                    .preModels[key]

                  
                  
                     66
                  
                  
                                }

                  
                  
                     67
                  
                  
                            }

                  
                  
                     68
                  
                  
                    const
                  
                   per = 300
                  
                    ;

                  
                  
                     69
                  
                  
                    //
                  
                  
                     console.log(fs.length)
                  
                  
                     70
                  
                  
                    if
                  
                   (fs.length >
                  
                     per) {

                  
                  
                     71
                  
                               fs.length =
                  
                     per

                  
                  
                     72
                  
                  
                            }

                  
                  
                     73
                  
                           let sid = setInterval(() =>
                  
                     {

                  
                  
                     74
                  
                  
                    if
                  
                   (fs.length === 0
                  
                    ) {

                  
                  
                     75
                  
                  
                    this
                  
                  .rendering = 
                  
                    false
                  
                  
                    ;

                  
                  
                     76
                  
                  
                                    clearInterval(sid);

                  
                  
                     77
                  
                  
                                }

                  
                  
                     78
                  
                               let i = 0
                  
                    ;

                  
                  
                     79
                  
                  
                    for
                  
                   (; i < fs.length; i++
                  
                    ) {

                  
                  
                     80
                  
                  
                    const
                  
                   f =
                  
                     fs.pop()

                  
                  
                     81
                  
                  
                    if
                  
                  
                     (f) {

                  
                  
                     82
                  
                  
                    const
                  
                   att =
                  
                     f.attributes;

                  
                  
                     83
                  
                  
                    const
                  
                   uid = att[
                  
                    this
                  
                  
                    .$idkey];

                  
                  
                     84
                  
                  
                     85
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .preModels.hasOwnProperty(uid)) {

                  
                  
                     86
                  
                  
                     87
                  
                                       } 
                  
                    else
                  
                  
                     {

                  
                  
                     88
                  
                  
                    const
                  
                   z = 
                  
                    this
                  
                  
                    .$zfomatter(att)

                  
                  
                     89
                  
                  
                                            let symbol;

                  
                  
                     90
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .$sfomatter) {

                  
                  
                     91
                  
                                               symbol = 
                  
                    this
                  
                  .getBaseSymbol(z, 
                  
                    this
                  
                  
                    .$sfomatter(f));

                  
                  
                     92
                  
                                           } 
                  
                    else
                  
                  
                     {

                  
                  
                     93
                  
                                               symbol = 
                  
                    this
                  
                  
                    .getBaseSymbol(z);

                  
                  
                     94
                  
                  
                                            }

                  
                  
                     95
                  
                  
                    const
                  
                   model =
                  
                     f;

                  
                  
                     96
                  
                                           model.symbol =
                  
                     symbol;

                  
                  
                     97
                  
                  
                    //
                  
                  
                     this.layer.add(model);
                  
                  
                     98
                  
                  
                    this
                  
                  
                    .baselayer.applyEdits({addFeatures: [model]})

                  
                  
                     99
                  
                  
                    100
                  
                  
                    this
                  
                  .preModels[uid] =
                  
                     model;

                  
                  
                    101
                  
                  
                                        }

                  
                  
                    102
                  
                  
                                    }

                  
                  
                    103
                  
                  
                                }

                  
                  
                    104
                  
                           }, 25
                  
                    );

                  
                  
                    105
                  
                  
                        }

                  
                  
                    106
                  
                  
                    107
                  
                  
                        click(results, mapPoint) {

                  
                  
                    108
                  
                  
                    if
                  
                   (results && results.length > 0
                  
                    ) {

                  
                  
                    109
                  
                               var grah = results[0
                  
                    ].graphic;

                  
                  
                    110
                  
                  
                    if
                  
                   (grah.layer === 
                  
                    this
                  
                  
                    .layer) {

                  
                  
                    111
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .highlightSelect) {

                  
                  
                    112
                  
                  
                    this
                  
                  
                    .highlightSelect.remove();

                  
                  
                    113
                  
                  
                                    }

                  
                  
                    114
                  
                  
                    115
                  
                  
                    this
                  
                  
                    .$view.whenLayerView(grah.layer).then(

                  
                  
                    116
                  
                                       layerView =>
                  
                     {

                  
                  
                    117
                  
                  
                    this
                  
                  .highlightSelect =
                  
                     layerView.highlight(grah);

                  
                  
                    118
                  
                  
                                        });

                  
                  
                    119
                  
                  
                    this
                  
                  .$click(grah, mapPoint, 
                  
                    this
                  
                  
                    .$view);

                  
                  
                    120
                  
                               } 
                  
                    else
                  
                  
                     {

                  
                  
                    121
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .highlightSelect) {

                  
                  
                    122
                  
                  
                    this
                  
                  
                    .highlightSelect.remove();

                  
                  
                    123
                  
                  
                                    }

                  
                  
                    124
                  
                  
                    //
                  
                  
                     this.$view.popup.close()
                  
                  
                    125
                  
                  
                                }

                  
                  
                    126
                  
                           } 
                  
                    else
                  
                  
                     {

                  
                  
                    127
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .highlightSelect) {

                  
                  
                    128
                  
                  
                    this
                  
                  
                    .highlightSelect.remove();

                  
                  
                    129
                  
                  
                                }

                  
                  
                    130
                  
                  
                    //
                  
                  
                     this.$view.popup.close()
                  
                  
                    131
                  
                  
                            }

                  
                  
                    132
                  
                  
                        }

                  
                  
                    133
                  
                  
                    134
                  
                  
                        clearHighlight() {

                  
                  
                    135
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .highlightSelect) {

                  
                  
                    136
                  
                  
                    this
                  
                  
                    .highlightSelect.remove();

                  
                  
                    137
                  
                  
                            }

                  
                  
                    138
                  
                  
                        }

                  
                  
                    139
                  
                  
                    140
                  
                  
                        setAutoLoad(v) {

                  
                  
                    141
                  
                  
                    this
                  
                  .autoLoad =
                  
                     v

                  
                  
                    142
                  
                  
                        }

                  
                  
                    143
                  
                  
                    144
                  
                  
                        addEvents() {

                  
                  
                    145
                  
                           watchUtils.watch(
                  
                    this
                  
                  .$view, 'zoom', () =>
                  
                     {

                  
                  
                    146
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  .$view.zoom > 
                  
                    this
                  
                  
                    .maxZoom) {

                  
                  
                    147
                  
                  
                    this
                  
                  .$view.zoom = 
                  
                    this
                  
                  
                    .maxZoom;

                  
                  
                    148
                  
                  
                                }

                  
                  
                    149
                  
                  
                            });

                  
                  
                    150
                  
                  
                    151
                  
                           watchUtils.whenTrue(
                  
                    this
                  
                  .$view, "stationary", () =>
                  
                     {

                  
                  
                    152
                  
                  
                    //
                  
                  
                     console.log(this.$view.zoom)
                  
                  
                    153
                  
                  
                    const
                  
                   flag = 
                  
                    this
                  
                  .$ofomatter(
                  
                    this
                  
                  
                    .$view);

                  
                  
                    154
                  
                  
                    if
                  
                  
                     (flag) {

                  
                  
                    155
                  
                  
                    if
                  
                   (!
                  
                    this
                  
                  
                    .rendering) {

                  
                  
                    156
                  
                  
                    this
                  
                  .rendering = 
                  
                    true
                  
                  
                    ;

                  
                  
                    157
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .autoLoad) {

                  
                  
                    158
                  
                  
                    this
                  
                  
                    .loadData();

                  
                  
                    159
                  
                  
                                        }

                  
                  
                    160
                  
                  
                                    }

                  
                  
                    161
                  
                  
                    //
                  
                  
                     this.layer.visible = true;
                  
                  
                    162
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  .layer.opacity === 0
                  
                    ) {

                  
                  
                    163
                  
                  
                    this
                  
                  .fadeVisibilityOn(
                  
                    this
                  
                  .$view, 
                  
                    this
                  
                  .layer, 
                  
                    true
                  
                  
                    )

                  
                  
                    164
                  
                  
                                    }

                  
                  
                    165
                  
                               } 
                  
                    else
                  
                  
                     {

                  
                  
                    166
                  
                  
                    //
                  
                  
                     this.clearLayer();
                  
                  
                    167
                  
                  
                    this
                  
                  .rendering = 
                  
                    false
                  
                  
                    ;

                  
                  
                    168
                  
                  
                    //
                  
                  
                     this.layer.visible = false;
                  
                  
                    169
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  .layer.opacity === 1
                  
                    ) {

                  
                  
                    170
                  
                  
                    this
                  
                  .fadeVisibilityOn(
                  
                    this
                  
                  .$view, 
                  
                    this
                  
                  .layer, 
                  
                    false
                  
                  
                    )

                  
                  
                    171
                  
                  
                                    }

                  
                  
                    172
                  
                  
                                }

                  
                  
                    173
                  
                  
                            });

                  
                  
                    174
                  
                  
                        }

                  
                  
                    175
                  
                  
                    176
                  
                  
                        loadData() {

                  
                  
                    177
                  
                           var r = 
                  
                    this
                  
                  
                    .getRadius();

                  
                  
                    178
                  
                           var center = 
                  
                    this
                  
                  
                    .$view.center;

                  
                  
                    179
                  
                  
                    const
                  
                   p =
                  
                     webMercatorUtils.xyToLngLat(center.x, center.y);

                  
                  
                    180
                  
                           p.z = 10
                  
                    ;

                  
                  
                    181
                  
                  
                    this
                  
                  .circle = 
                  
                    new
                  
                  
                     Circle({

                  
                  
                    182
                  
                  
                                center: p,

                  
                  
                    183
                  
                               geodesic: 
                  
                    true
                  
                  
                    ,

                  
                  
                    184
                  
                               numberOfPoints: 10
                  
                    ,

                  
                  
                    185
                  
                  
                                radius: r,

                  
                  
                    186
                  
                               radiusUnit: "meters"

                  
                    187
                  
                  
                            })

                  
                  
                    188
                  
                  
                    //
                  
                  
                     if(this.circleGraphic) {

                  
                  
                    189
                  
                  
                    //
                  
                  
                         this.layer.remove(this.circleGraphic);

                  
                  
                    190
                  
                  
                    //
                  
                  
                     }

                  
                  
                    191
                  
                  
                    //
                  
                  
                     this.circleGraphic = new Graphic({

                  
                  
                    192
                  
                  
                    //
                  
                  
                         geometry: this.circle,

                  
                  
                    193
                  
                  
                    //
                  
                  
                         symbol: {

                  
                  
                    194
                  
                  
                    //
                  
                  
                             type: "simple-fill",

                  
                  
                    195
                  
                  
                    //
                  
                  
                             color: [51, 51, 204, 0.7],

                  
                  
                    196
                  
                  
                    //
                  
                  
                             style: "solid",

                  
                  
                    197
                  
                  
                    //
                  
                  
                             outline: {

                  
                  
                    198
                  
                  
                    //
                  
                  
                                 color: "white",

                  
                  
                    199
                  
                  
                    //
                  
                  
                                 width: 1

                  
                  
                    200
                  
                  
                    //
                  
                  
                             }

                  
                  
                    201
                  
                  
                    //
                  
                  
                         }

                  
                  
                    202
                  
                  
                    //
                  
                  
                     })

                  
                  
                    203
                  
                  
                    //
                  
                  
                     this.layer.add(this.circleGraphic);
                  
                  
                    204
                  
                  
                    205
                  
                           let where = ''

                  
                    206
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .$wfomatter) {

                  
                  
                    207
                  
                               where = 
                  
                    this
                  
                  
                    .$wfomatter();

                  
                  
                    208
                  
                  
                            }

                  
                  
                    209
                  
                           mapx.queryTask(
                  
                    this
                  
                  
                    .$url, {

                  
                  
                    210
                  
                  
                                where: where,

                  
                  
                    211
                  
                               outSpatialReference: '4326'
                  
                    ,

                  
                  
                    212
                  
                  
                    //
                  
                  
                     geometry: this.$view.extent,
                  
                  
                    213
                  
                               geometry: 
                  
                    this
                  
                  
                    .circle,

                  
                  
                    214
                  
                               returnGeometry: 
                  
                    true
                  
                  
                    215
                  
                           }).then(featureSet =>
                  
                     {

                  
                  
                    216
                  
                  
                    this
                  
                  
                    .addModel(featureSet);

                  
                  
                    217
                  
                           }).
                  
                    catch
                  
                  (error =>
                  
                     {})

                  
                  
                    218
                  
                  
                        }

                  
                  
                    219
                  
                  
                    220
                  
                  
                        clearLayer() {

                  
                  
                    221
                  
                  
                    this
                  
                  
                    .layer.removeAll();

                  
                  
                    222
                  
                  
                    this
                  
                  .preModels =
                  
                     {};

                  
                  
                    223
                  
                  
                        }

                  
                  
                    224
                  
                  
                    225
                  
                  
                        getRadius() {

                  
                  
                    226
                  
                  
                    const
                  
                   zoomMap =
                  
                     {

                  
                  
                    227
                  
                               '15': 
                  
                    this
                  
                  .baseRadius / 
                  
                    this
                  
                  .factor / 
                  
                    this
                  
                  
                    .factor,

                  
                  
                    228
                  
                               '16': 
                  
                    this
                  
                  .baseRadius / 
                  
                    this
                  
                  
                    .factor,

                  
                  
                    229
                  
                               '17': 
                  
                    this
                  
                  
                    .baseRadius,

                  
                  
                    230
                  
                               '18': 
                  
                    this
                  
                  .baseRadius * 
                  
                    this
                  
                  
                    .factor,

                  
                  
                    231
                  
                               '19': 
                  
                    this
                  
                  .baseRadius * 
                  
                    this
                  
                  .factor * 
                  
                    this
                  
                  
                    .factor,

                  
                  
                    232
                  
                               '20': 
                  
                    this
                  
                  .baseRadius * 
                  
                    this
                  
                  .factor * 
                  
                    this
                  
                  .factor * 
                  
                    this
                  
                  
                    .factor,

                  
                  
                    233
                  
                               '21': 
                  
                    this
                  
                  .baseRadius * 
                  
                    this
                  
                  .factor * 
                  
                    this
                  
                  .factor * 
                  
                    this
                  
                  .factor * 
                  
                    this
                  
                  
                    .factor

                  
                  
                    234
                  
                  
                            }

                  
                  
                    235
                  
                  
                    const
                  
                   zoom = Math.round(
                  
                    this
                  
                  
                    .$view.zoom)

                  
                  
                    236
                  
                  
                    return
                  
                   zoomMap[zoom + ''
                  
                    ]

                  
                  
                    237
                  
                  
                    //
                  
                  
                     var extent = this.$view.extent;

                  
                  
                    238
                  
                  
                    //
                  
                  
                     var paths = [

                  
                  
                    239
                  
                  
                    //
                  
                  
                         [

                  
                  
                    240
                  
                  
                    //
                  
                  
                             [extent.xmin, extent.ymin],

                  
                  
                    241
                  
                  
                    //
                  
                  
                             [extent.xmax, extent.ymax]

                  
                  
                    242
                  
                  
                    //
                  
                  
                         ]

                  
                  
                    243
                  
                  
                    //
                  
                  
                     ];

                  
                  
                    244
                  
                  
                    //
                  
                  
                     var line = new Polyline({

                  
                  
                    245
                  
                  
                    //
                  
                  
                         paths: paths,

                  
                  
                    246
                  
                  
                    //
                  
                  
                         spatialReference: this.$view.spatialReference

                  
                  
                    247
                  
                  
                    //
                  
                  
                     });

                  
                  
                    248
                  
                  
                    //
                  
                  
                     var d = geometryEngine.geodesicLength(line, 'meters');

                  
                  
                    249
                  
                  
                    //
                  
                  
                    //
                  
                  
                     var d = geometryEngine.planarLength(line, 'meters');

                  
                  
                    250
                  
                  
                    //
                  
                  
                     return d * 0.5 * this.ef;
                  
                  
                    251
                  
                  
                        }

                  
                  
                    252
                  
                  
                    253
                  
                       getBaseSymbol(z, color = [224, 224, 224, 0.8
                  
                    ]) {

                  
                  
                    254
                  
                  
                    return
                  
                  
                     {

                  
                  
                    255
                  
                               type: "polygon-3d"
                  
                    ,

                  
                  
                    256
                  
                  
                                symbolLayers: [{

                  
                  
                    257
                  
                                   type: "extrude"
                  
                    ,

                  
                  
                    258
                  
                  
                                    size: z,

                  
                  
                    259
                  
                  
                                    material: {

                  
                  
                    260
                  
                  
                                        color: color

                  
                  
                    261
                  
                  
                                    },

                  
                  
                    262
                  
                  
                                    edges: {

                  
                  
                    263
                  
                                       type: "solid"
                  
                    ,

                  
                  
                    264
                  
                                       size: 1.5
                  
                    ,

                  
                  
                    265
                  
                                       color: [50, 50, 50, 0.5
                  
                    ]

                  
                  
                    266
                  
                  
                    //
                  
                  
                     type: "sketch",

                  
                  
                    267
                  
                  
                    //
                  
                  
                     color: [50, 50, 50, 0.5],

                  
                  
                    268
                  
                  
                    //
                  
                  
                     size: 1.5,

                  
                  
                    269
                  
                  
                    //
                  
                  
                     extensionLength: 2
                  
                  
                    270
                  
                  
                                    }

                  
                  
                    271
                  
                  
                                }]

                  
                  
                    272
                  
                  
                            }

                  
                  
                    273
                  
                  
                        }

                  
                  
                    274
                  
                  
                    275
                  
                  
                        fadeVisibilityOn(view, layer, flag) {

                  
                  
                    276
                  
                           let animating = 
                  
                    true
                  
                  
                    ;

                  
                  
                    277
                  
                           let opacity = flag ? 0 : 1
                  
                    ;

                  
                  
                    278
                  
                  
                    //
                  
                  
                     fade layer's opacity from 0 to

                  
                  
                    279
                  
                  
                    //
                  
                  
                     whichever value the user has configured
                  
                  
                    280
                  
                  
                    const
                  
                   finalOpacity = flag ? 1 : 0
                  
                    ;

                  
                  
                    281
                  
                           layer.opacity =
                  
                     opacity;

                  
                  
                    282
                  
                  
                    283
                  
                           view.whenLayerView(layer).then((layerView) =>
                  
                     {

                  
                  
                    284
                  
                  
                                function incrementOpacityByFrame() {

                  
                  
                    285
                  
                  
                    if
                  
                   (opacity >= finalOpacity &&
                  
                     animating) {

                  
                  
                    286
                  
                                       layer.opacity =
                  
                     finalOpacity;

                  
                  
                    287
                  
                                       animating = 
                  
                    false
                  
                  
                    ;

                  
                  
                    288
                  
                  
                    return
                  
                  
                    ;

                  
                  
                    289
                  
                  
                                    }

                  
                  
                    290
                  
                  
                    291
                  
                                   layer.opacity =
                  
                     opacity;

                  
                  
                    292
                  
                                   opacity += 0.07
                  
                    ;

                  
                  
                    293
                  
                  
                    294
                  
                  
                                    requestAnimationFrame(incrementOpacityByFrame);

                  
                  
                    295
                  
                  
                                }

                  
                  
                    296
                  
                  
                    297
                  
                  
                                function decrementOpacityByFrame() {

                  
                  
                    298
                  
                  
                    if
                  
                   (opacity <= finalOpacity &&
                  
                     animating) {

                  
                  
                    299
                  
                                       layer.opacity =
                  
                     finalOpacity;

                  
                  
                    300
                  
                                       animating = 
                  
                    false
                  
                  
                    ;

                  
                  
                    301
                  
                  
                    return
                  
                  
                    ;

                  
                  
                    302
                  
                  
                                    }

                  
                  
                    303
                  
                  
                    304
                  
                                   layer.opacity =
                  
                     opacity;

                  
                  
                    305
                  
                                   opacity -= 0.07
                  
                    ;

                  
                  
                    306
                  
                  
                    307
                  
                  
                                    requestAnimationFrame(decrementOpacityByFrame);

                  
                  
                    308
                  
                  
                                }

                  
                  
                    309
                  
                  
                    310
                  
                  
                    //
                  
                  
                     Wait for tiles to finish loading before beginning the fade
                  
                  
                    311
                  
                  
                                watchUtils.whenFalseOnce(

                  
                  
                    312
                  
                  
                                    layerView,

                  
                  
                    313
                  
                                   "updating"
                  
                    ,

                  
                  
                    314
                  
                  
                                    function(updating) {

                  
                  
                    315
                  
                  
                    if
                  
                  
                     (flag) {

                  
                  
                    316
                  
                  
                                            requestAnimationFrame(incrementOpacityByFrame);

                  
                  
                    317
                  
                                       } 
                  
                    else
                  
                  
                     {

                  
                  
                    318
                  
                  
                                            requestAnimationFrame(decrementOpacityByFrame);

                  
                  
                    319
                  
                  
                                        }

                  
                  
                    320
                  
                  
                                    }

                  
                  
                    321
                  
                  
                                );

                  
                  
                    322
                  
                  
                            });

                  
                  
                    323
                  
                  
                        }

                  
                  
                    324
                  
                  
                    325
                  
                   }
                
View Code

  。

3 :首先把漫游策略改了,方案1、2是漫游中加载并缓存,现在直接在初始化的时候给出进度条,加载所有数据(6万+),肯定是不能一口气去查询加载的,我还是启动一个延迟加载的策略,在地图上分区域分布队列加载,尽量在每一帧里面分摊开销。然后完全舍弃arcgis的要素渲染,改用 threejs 来绘制,arcgis给出了一个接口 externalRenderers ,这个很重要,可以集成第三方3D引擎。threejs这边使用Shape,ExtrudeGeometry,Mesh来构建要素,但是如果仅仅是这样去渲染,当6万+个建筑物在地图上是会卡顿的,因为对象太多了,那么我们是否可以做一个合并操作呢,把6万+个要素按区域合并,也就是合并geometry咯,一开始在网上找了一个mergeBufferGeometries算法,后来发现threejs API里面有BufferGeometryUtils.mergeBufferGeometries,感觉threejs计算速度快一点。合并之后在加载到图层上,那么事实上,比如全市是15个区,那就只有15个Mesh,当然不卡了,满帧跑。不过相比大家也会发现一个问题,就是当要和建筑物交互的时候,就获取不到点击的Mesh了,这个问题我会继续区研究一下怎么改进。最后,效果和样式就不用担心了,threejs自带的Material就很丰富,不行还有Shader着色器,动效也方便,在updateModels里面随便操作(threejs的render事件,我封装了),归根结底,剩下的就是threejs的能力展现了.

ExternalRendererLayer:

                  
                      1
                  
                  
                    import
                  
                   * as THREE from 'three'

                  
                      2
                  
                  
                    import
                  
                   Stats from 'three/examples/jsm/libs/stats.module.js'

                  
                      3
                  
                  
                    import
                  
                   * as webMercatorUtils from "@arcgis/core/geometry/support/webMercatorUtils"

                  
                      4
                  
                  
                    import
                  
                   * as externalRenderers from "@arcgis/core/views/3d/externalRenderers"

                  
                      5
                  
                  
                      6
                  
                   export 
                  
                    default
                  
                  
                    class
                  
                  
                     ExternalRendererLayer {

                  
                  
                      7
                  
                  
                        constructor({

                  
                  
                      8
                  
                  
                            view,

                  
                  
                      9
                  
                  
                            options

                  
                  
                     10
                  
                  
                        }) {

                  
                  
                     11
                  
                  
                    this
                  
                  .view =
                  
                     view

                  
                  
                     12
                  
                  
                    this
                  
                  .options =
                  
                     options

                  
                  
                     13
                  
                  
                     14
                  
                  
                    this
                  
                  .objects =
                  
                     []

                  
                  
                     15
                  
                  
                    this
                  
                  .scene = 
                  
                    null
                  
                  
                     16
                  
                  
                    this
                  
                  .camera = 
                  
                    null
                  
                  
                     17
                  
                  
                    this
                  
                  .renderer = 
                  
                    null
                  
                  
                     18
                  
                  
                     19
                  
                  
                    this
                  
                  
                    .setup();

                  
                  
                     20
                  
                  
                        }

                  
                  
                     21
                  
                  
                     22
                  
                  
                        setup() {

                  
                  
                     23
                  
                  
                    if
                  
                   (process.env.NODE_ENV !== "production"
                  
                    ) {

                  
                  
                     24
                  
                  
                    const
                  
                   sid = setTimeout(() =>
                  
                     {

                  
                  
                     25
                  
                  
                                    clearTimeout(sid)

                  
                  
                     26
                  
                  
                    //
                  
                  
                    构建帧率查看器
                  
                  
                     27
                  
                                   let stats = 
                  
                    new
                  
                  
                     Stats()

                  
                  
                     28
                  
                                   stats.setMode(0
                  
                    )

                  
                  
                     29
                  
                                   stats.domElement.style.position = 'absolute'

                  
                     30
                  
                                   stats.domElement.style.left = '0px'

                  
                     31
                  
                                   stats.domElement.style.top = '0px'

                  
                     32
                  
                  
                                    document.body.appendChild(stats.domElement)

                  
                  
                     33
                  
                  
                                    function render() {

                  
                  
                     34
                  
                  
                                      stats.update()

                  
                  
                     35
                  
                  
                                      requestAnimationFrame(render)

                  
                  
                     36
                  
                  
                                    }

                  
                  
                     37
                  
                  
                                    render()

                  
                  
                     38
                  
                               }, 5000
                  
                    )

                  
                  
                     39
                  
                  
                            }

                  
                  
                     40
                  
                  
                        }

                  
                  
                     41
                  
                  
                     42
                  
                  
                        apply() {

                  
                  
                     43
                  
                           let myExternalRenderer =
                  
                     {

                  
                  
                     44
                  
                               setup: context =>
                  
                     {

                  
                  
                     45
                  
                  
                    this
                  
                  
                    .createSetup(context)

                  
                  
                     46
                  
                  
                                },

                  
                  
                     47
                  
                               render: context =>
                  
                     {

                  
                  
                     48
                  
                  
                    this
                  
                  
                    .createRender(context)

                  
                  
                     49
                  
                  
                                }

                  
                  
                     50
                  
                  
                            }

                  
                  
                     51
                  
                  
                     52
                  
                           externalRenderers.add(
                  
                    this
                  
                  
                    .view, myExternalRenderer);

                  
                  
                     53
                  
                  
                        }

                  
                  
                     54
                  
                  
                     55
                  
                  
                        createSetup(context) {

                  
                  
                     56
                  
                  
                    this
                  
                  .scene = 
                  
                    new
                  
                   THREE.Scene(); 
                  
                    //
                  
                  
                     场景
                  
                  
                     57
                  
                  
                    this
                  
                  .camera = 
                  
                    new
                  
                   THREE.PerspectiveCamera(); 
                  
                    //
                  
                  
                     相机
                  
                  
                     58
                  
                  
                     59
                  
                  
                    this
                  
                  
                    .setLight();

                  
                  
                     60
                  
                  
                     61
                  
                  
                    //
                  
                  
                     添加坐标轴辅助工具
                  
                  
                     62
                  
                  
                    const
                  
                   axesHelper = 
                  
                    new
                  
                   THREE.AxesHelper(10000000
                  
                    );

                  
                  
                     63
                  
                  
                    this
                  
                  .scene.Helpers =
                  
                     axesHelper;

                  
                  
                     64
                  
                  
                    this
                  
                  
                    .scene.add(axesHelper);

                  
                  
                     65
                  
                  
                     66
                  
                  
                    this
                  
                  .renderer = 
                  
                    new
                  
                  
                     THREE.WebGLRenderer({

                  
                  
                     67
                  
                               context: context.gl, 
                  
                    //
                  
                  
                     可用于将渲染器附加到已有的渲染环境(RenderingContext)中
                  
                  
                     68
                  
                               premultipliedAlpha: 
                  
                    false
                  
                  , 
                  
                    //
                  
                  
                     renderer是否假设颜色有 premultiplied alpha. 默认为true

                  
                  
                     69
                  
                  
                    //
                  
                  
                     antialias: true

                  
                  
                     70
                  
                  
                    //
                  
                  
                     logarithmicDepthBuffer: false
                  
                  
                     71
                  
                  
                            });

                  
                  
                     72
                  
                  
                    this
                  
                  .renderer.setPixelRatio(window.devicePixelRatio); 
                  
                    //
                  
                  
                     设置设备像素比。通常用于避免HiDPI设备上绘图模糊
                  
                  
                     73
                  
                  
                    this
                  
                  .renderer.setViewport(0, 0, 
                  
                    this
                  
                  .view.width, 
                  
                    this
                  
                  .view.height); 
                  
                    //
                  
                  
                     视口大小设置

                  
                  
                     74
                  
                  
                     75
                  
                  
                    //
                  
                  
                     防止Three.js清除ArcGIS JS API提供的缓冲区。
                  
                  
                     76
                  
                  
                    this
                  
                  .renderer.autoClearDepth = 
                  
                    false
                  
                  ; 
                  
                    //
                  
                  
                     定义renderer是否清除深度缓存
                  
                  
                     77
                  
                  
                    this
                  
                  .renderer.autoClearStencil = 
                  
                    false
                  
                  ; 
                  
                    //
                  
                  
                     定义renderer是否清除模板缓存
                  
                  
                     78
                  
                  
                    this
                  
                  .renderer.autoClearColor = 
                  
                    false
                  
                  ; 
                  
                    //
                  
                  
                     定义renderer是否清除颜色缓存

                  
                  
                     79
                  
                  
                    //
                  
                  
                     this.renderer.autoClear = false;

                  
                  
                     80
                  
                  
                     81
                  
                  
                    //
                  
                  
                     ArcGIS JS API渲染自定义离屏缓冲区,而不是默认的帧缓冲区。

                  
                  
                     82
                  
                  
                    //
                  
                  
                     我们必须将这段代码注入到three.js运行时中,以便绑定这些缓冲区而不是默认的缓冲区。
                  
                  
                     83
                  
                  
                    const
                  
                   originalSetRenderTarget = 
                  
                    this
                  
                  
                    .renderer.setRenderTarget.bind(

                  
                  
                     84
                  
                  
                    this
                  
                  
                    .renderer

                  
                  
                     85
                  
                  
                            );

                  
                  
                     86
                  
                  
                    this
                  
                  .renderer.setRenderTarget = target =>
                  
                     {

                  
                  
                     87
                  
                  
                                originalSetRenderTarget(target);

                  
                  
                     88
                  
                  
                    if
                  
                   (target == 
                  
                    null
                  
                  
                    ) {

                  
                  
                     89
                  
                  
                    //
                  
                  
                     绑定外部渲染器应该渲染到的颜色和深度缓冲区
                  
                  
                     90
                  
                  
                                    context.bindRenderTarget();

                  
                  
                     91
                  
                  
                                }

                  
                  
                     92
                  
                  
                            };

                  
                  
                     93
                  
                  
                     94
                  
                  
                    this
                  
                  
                    .addModels(context);

                  
                  
                     95
                  
                  
                     96
                  
                  
                            context.resetWebGLState();

                  
                  
                     97
                  
                  
                        }

                  
                  
                     98
                  
                  
                     99
                  
                  
                        createRender(context) {

                  
                  
                    100
                  
                  
                    const
                  
                   cam =
                  
                     context.camera;

                  
                  
                    101
                  
                  
                    this
                  
                  .camera.position.set(cam.eye[0], cam.eye[1], cam.eye[2
                  
                    ]);

                  
                  
                    102
                  
                  
                    this
                  
                  .camera.up.set(cam.up[0], cam.up[1], cam.up[2
                  
                    ]);

                  
                  
                    103
                  
                  
                    this
                  
                  
                    .camera.lookAt(

                  
                  
                    104
                  
                  
                    new
                  
                   THREE.Vector3(cam.center[0], cam.center[1], cam.center[2
                  
                    ])

                  
                  
                    105
                  
                  
                            );

                  
                  
                    106
                  
                  
                    this
                  
                  .camera.near = 1
                  
                    ;

                  
                  
                    107
                  
                  
                    this
                  
                  .camera.far = 100
                  
                    ;

                  
                  
                    108
                  
                  
                    109
                  
                  
                    //
                  
                  
                     投影矩阵可以直接复制
                  
                  
                    110
                  
                  
                    this
                  
                  
                    .camera.projectionMatrix.fromArray(cam.projectionMatrix);

                  
                  
                    111
                  
                  
                    112
                  
                  
                    this
                  
                  
                    .updateModels(context);

                  
                  
                    113
                  
                  
                    114
                  
                  
                    this
                  
                  
                    .renderer.state.reset();

                  
                  
                    115
                  
                  
                    116
                  
                  
                            context.bindRenderTarget();

                  
                  
                    117
                  
                  
                    118
                  
                  
                    this
                  
                  .renderer.render(
                  
                    this
                  
                  .scene, 
                  
                    this
                  
                  
                    .camera);

                  
                  
                    119
                  
                  
                    120
                  
                  
                    //
                  
                  
                     请求重绘视图。
                  
                  
                    121
                  
                           externalRenderers.requestRender(
                  
                    this
                  
                  
                    .view);

                  
                  
                    122
                  
                  
                    123
                  
                  
                    //
                  
                  
                     cleanup
                  
                  
                    124
                  
                  
                            context.resetWebGLState();

                  
                  
                    125
                  
                  
                        }

                  
                  
                    126
                  
                  
                    127
                  
                  
                    //
                  
                  
                    经纬度坐标转成三维空间坐标
                  
                  
                    128
                  
                  
                        lngLatToXY(view, points) {

                  
                  
                    129
                  
                  
                    130
                  
                           let vector3List; 
                  
                    //
                  
                  
                     顶点数组
                  
                  
                    131
                  
                  
                    132
                  
                  
                            let pointXYs;

                  
                  
                    133
                  
                  
                    134
                  
                  
                    135
                  
                  
                    //
                  
                  
                     计算顶点
                  
                  
                    136
                  
                           let transform = 
                  
                    new
                  
                   THREE.Matrix4(); 
                  
                    //
                  
                  
                     变换矩阵
                  
                  
                    137
                  
                           let transformation = 
                  
                    new
                  
                   Array(16
                  
                    );

                  
                  
                    138
                  
                  
                    139
                  
                  
                    //
                  
                  
                     将经纬度坐标转换为xy值\
                  
                  
                    140
                  
                           let pointXY = webMercatorUtils.lngLatToXY(points[0], points[1
                  
                    ]);

                  
                  
                    141
                  
                  
                    142
                  
                  
                    //
                  
                  
                     先转换高度为0的点
                  
                  
                    143
                  
                  
                            transform.fromArray(

                  
                  
                    144
                  
                  
                                externalRenderers.renderCoordinateTransformAt(

                  
                  
                    145
                  
                  
                                    view,

                  
                  
                    146
                  
                                   [pointXY[0], pointXY[1
                  
                    ], points[

                  
                  
                    147
                  
                                       2]], 
                  
                    //
                  
                  
                     坐标在地面上的点[x值, y值, 高度值]
                  
                  
                    148
                  
                  
                                    view.spatialReference,

                  
                  
                    149
                  
                  
                                    transformation

                  
                  
                    150
                  
                  
                                )

                  
                  
                    151
                  
                  
                            );

                  
                  
                    152
                  
                  
                    153
                  
                           pointXYs =
                  
                     pointXY;

                  
                  
                    154
                  
                  
                    155
                  
                           vector3List =

                  
                    156
                  
                  
                    new
                  
                  
                     THREE.Vector3(

                  
                  
                    157
                  
                                   transform.elements[12
                  
                    ],

                  
                  
                    158
                  
                                   transform.elements[13
                  
                    ],

                  
                  
                    159
                  
                                   transform.elements[14
                  
                    ]

                  
                  
                    160
                  
                  
                                )

                  
                  
                    161
                  
                  
                    162
                  
                  
                    return
                  
                  
                     {

                  
                  
                    163
                  
                  
                                vector3List: vector3List,

                  
                  
                    164
                  
                  
                                pointXYs: pointXYs

                  
                  
                    165
                  
                  
                            };

                  
                  
                    166
                  
                  
                        }

                  
                  
                    167
                  
                  
                    168
                  
                  
                        setLight() {

                  
                  
                    169
                  
                           console.log('setLight'
                  
                    )

                  
                  
                    170
                  
                           let ambient = 
                  
                    new
                  
                   THREE.AmbientLight(0xffffff, 0.7
                  
                    );

                  
                  
                    171
                  
                  
                    this
                  
                  
                    .scene.add(ambient);

                  
                  
                    172
                  
                           let directionalLight = 
                  
                    new
                  
                   THREE.DirectionalLight(0xffffff, 0.7
                  
                    );

                  
                  
                    173
                  
                           directionalLight.position.set(100, 300, 200
                  
                    );

                  
                  
                    174
                  
                  
                    this
                  
                  
                    .scene.add(directionalLight);

                  
                  
                    175
                  
                  
                        }

                  
                  
                    176
                  
                  
                    177
                  
                  
                        addModels(context) {

                  
                  
                    178
                  
                           console.log('addModels'
                  
                    )

                  
                  
                    179
                  
                  
                        }

                  
                  
                    180
                  
                  
                    181
                  
                  
                        updateModels(context) {

                  
                  
                    182
                  
                  
                    //
                  
                  
                     console.log('updateModels')
                  
                  
                    183
                  
                  
                        }

                  
                  
                    184
                  
                  
                    185
                  
                   }
                
View Code

  。

BuildingLayerExt:

                  
                      1
                  
                  
                    import
                  
                   mapx from '@/utils/mapUtils.js'
                  
                    ;

                  
                  
                      2
                  
                  
                      3
                  
                  
                    import
                  
                   * as THREE from 'three'

                  
                      4
                  
                  
                    import
                  
                   * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'
                  
                    ;

                  
                  
                      5
                  
                  
                    import
                  
                   ExternalRendererLayer from './ExternalRendererLayer.js'

                  
                      6
                  
                  
                      7
                  
                  
                    import
                  
                   GraphicsLayer from "@arcgis/core/layers/GraphicsLayer"
                  
                    ;

                  
                  
                      8
                  
                  
                    import
                  
                   FeatureLayer from "@arcgis/core/layers/FeatureLayer"
                  
                    ;

                  
                  
                      9
                  
                  
                    import
                  
                   Graphic from "@arcgis/core/Graphic"
                  
                    ;

                  
                  
                     10
                  
                  
                    import
                  
                   SpatialReference from '@arcgis/core/geometry/SpatialReference'

                  
                     11
                  
                  
                    import
                  
                   * as externalRenderers from "@arcgis/core/views/3d/externalRenderers"

                  
                     12
                  
                  
                    import
                  
                   Polygon from "@arcgis/core/geometry/Polygon"
                  
                    ;

                  
                  
                     13
                  
                  
                    import
                  
                   Polyline from "@arcgis/core/geometry/Polyline"
                  
                    ;

                  
                  
                     14
                  
                  
                    import
                  
                   Circle from "@arcgis/core/geometry/Circle"
                  
                    ;

                  
                  
                     15
                  
                  
                    import
                  
                   * as watchUtils from "@arcgis/core/core/watchUtils"
                  
                    ;

                  
                  
                     16
                  
                  
                    import
                  
                   * as geometryEngine from "@arcgis/core/geometry/geometryEngine"
                  
                    ;

                  
                  
                     17
                  
                  
                    import
                  
                   * as webMercatorUtils from "@arcgis/core/geometry/support/webMercatorUtils"
                  
                    ;

                  
                  
                     18
                  
                  
                     19
                  
                  
                    import
                  
                   { getBuildings } from '@/api'
                  
                    ;

                  
                  
                     20
                  
                  
                     21
                  
                  
                    const
                  
                   EF = 1
                  
                    ;

                  
                  
                     22
                  
                  
                    const
                  
                   UID = 'FID'; 
                  
                    //
                  
                  
                    OBJECTID
                  
                  
                     23
                  
                  
                    const
                  
                   R = 0.8
                  
                    ;

                  
                  
                     24
                  
                  
                    const
                  
                   LEVEL = 16
                  
                    ;

                  
                  
                     25
                  
                  
                    const
                  
                   HEIGHT = 40
                  
                    ;

                  
                  
                     26
                  
                  
                    const
                  
                   INCREASE = 30
                  
                    ;

                  
                  
                     27
                  
                  
                     28
                  
                  
                    const
                  
                   JBMS =
                  
                     [

                  
                  
                     29
                  
                       420106001
                  
                    ,

                  
                  
                     30
                  
                       420106002
                  
                    ,

                  
                  
                     31
                  
                       420106003
                  
                    ,

                  
                  
                     32
                  
                       420106005
                  
                    ,

                  
                  
                     33
                  
                       420106006
                  
                    ,

                  
                  
                     34
                  
                       420106007
                  
                    ,

                  
                  
                     35
                  
                       420106008
                  
                    ,

                  
                  
                     36
                  
                       420106009
                  
                    ,

                  
                  
                     37
                  
                       420106010
                  
                    ,

                  
                  
                     38
                  
                       420106011
                  
                    ,

                  
                  
                     39
                  
                       420106012
                  
                    ,

                  
                  
                     40
                  
                       420106013
                  
                    ,

                  
                  
                     41
                  
                       420106014
                  
                    ,

                  
                  
                     42
                  
                       420106015

                  
                     43
                  
                  
                    ];

                  
                  
                     44
                  
                  
                     45
                  
                   export 
                  
                    default
                  
                  
                    class
                  
                   BuildingLayerExt 
                  
                    extends
                  
                  
                     ExternalRendererLayer {

                  
                  
                     46
                  
                  
                        constructor({

                  
                  
                     47
                  
                  
                            view,

                  
                  
                     48
                  
                  
                            options

                  
                  
                     49
                  
                  
                        }) {

                  
                  
                     50
                  
                  
                    super
                  
                  
                    ({

                  
                  
                     51
                  
                  
                                view,

                  
                  
                     52
                  
                  
                                options

                  
                  
                     53
                  
                  
                            })

                  
                  
                     54
                  
                  
                        }

                  
                  
                     55
                  
                  
                     56
                  
                  
                        setup() {

                  
                  
                     57
                  
                  
                    //
                  
                  
                     this.circleGraphic = null;

                  
                  
                     58
                  
                  
                    //
                  
                  
                     this.layer = new GraphicsLayer();
                  
                  
                     59
                  
                  
                     60
                  
                  
                    this
                  
                  .cacheObjects =
                  
                     {};

                  
                  
                     61
                  
                  
                     62
                  
                  
                    this
                  
                  .group = 
                  
                    new
                  
                  
                     THREE.Group();

                  
                  
                     63
                  
                  
                     64
                  
                  
                    //
                  
                  
                     this.material = new THREE.MeshLambertMaterial({

                  
                  
                     65
                  
                  
                    //
                  
                  
                         transparent: true,

                  
                  
                     66
                  
                  
                    //
                  
                  
                         opacity: 0.9,

                  
                  
                     67
                  
                  
                    //
                  
                  
                         color: 0xFFFFFF

                  
                  
                     68
                  
                  
                    //
                  
                  
                     }); 
                  
                  
                    //
                  
                  
                    材质对象Material

                  
                  
                     69
                  
                  
                     70
                  
                  
                    //
                  
                  
                     顶点着色器
                  
                  
                     71
                  
                  
                    const
                  
                   vertexShader =
                  
                     `

                  
                  
                     72
                  
                  
                    //
                  
                  
                     向片元着色器传递顶点位置数据
                  
                  
                     73
                  
                  
                                         varying vec3 v_position;

                  
                  
                     74
                  
                  
                    void
                  
                  
                     main () {

                  
                  
                     75
                  
                                            v_position =
                  
                     position;

                  
                  
                     76
                  
                                            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0
                  
                    );

                  
                  
                     77
                  
                  
                                         }

                  
                  
                     78
                  
                  
                                     `;

                  
                  
                     79
                  
                  
                    //
                  
                  
                     片元着色器
                  
                  
                     80
                  
                  
                    const
                  
                   fragmentShader =
                  
                     `

                  
                  
                     81
                  
                  
                    //
                  
                  
                     接收顶点着色器传递的顶点位置数据
                  
                  
                     82
                  
                  
                                         varying vec3 v_position;

                  
                  
                     83
                  
                  
                     84
                  
                  
                    //
                  
                  
                     接收js传入的值
                  
                  
                     85
                  
                                        uniform 
                  
                    float
                  
                  
                     u_time;

                  
                  
                     86
                  
                  
                                         uniform vec3 u_size;

                  
                  
                     87
                  
                  
                                         uniform vec3 u_flow;

                  
                  
                     88
                  
                  
                                         uniform vec3 u_color;

                  
                  
                     89
                  
                  
                                         uniform vec3 u_flowColor;

                  
                  
                     90
                  
                  
                                         uniform vec3 u_topColor;

                  
                  
                     91
                  
                  
                     92
                  
                  
                    void
                  
                  
                     main () {

                  
                  
                     93
                  
                  
                    //
                  
                  
                     给建筑设置从上到下的渐变颜色
                  
                  
                     94
                  
                  
                    float
                  
                   indexPct = v_position.z /
                  
                     u_size.z;

                  
                  
                     95
                  
                                            vec3 color =
                  
                     mix(u_color, u_topColor,indexPct);

                  
                  
                     96
                  
                  
                    //
                  
                  
                    //
                  
                  
                     根据时间和速度计算出当前扫描点的位置, 以上顶点为准

                  
                  
                     97
                  
                  
                    //
                  
                  
                     float flowTop = mod(u_flow.z * u_time, u_size.z);

                  
                  
                     98
                  
                  
                    //
                  
                  
                    //
                  
                  
                     判断当前点是否在扫描范围内

                  
                  
                     99
                  
                  
                    //
                  
                  
                     if (flowTop > v_position.z && flowTop - u_flow.z < v_position.z) {

                  
                  
                    100
                  
                  
                    //
                  
                  
                    //
                  
                  
                     扫描范围内的位置设置从上到下的渐变颜色

                  
                  
                    101
                  
                  
                    //
                  
                  
                         float flowPct = (u_flow.z - ( flowTop -  v_position.z)) / u_flow.z;

                  
                  
                    102
                  
                  
                    //
                  
                  
                         color = mix(color ,u_flowColor, flowPct);

                  
                  
                    103
                  
                  
                    //
                  
                  
                     }
                  
                  
                    104
                  
                                            gl_FragColor = vec4(color, 0.8
                  
                    );

                  
                  
                    105
                  
                  
                                         }

                  
                  
                    106
                  
                  
                                     `;

                  
                  
                    107
                  
                  
                    108
                  
                  
                    const
                  
                   ratio =
                  
                     {

                  
                  
                    109
                  
                               value: 0

                  
                    110
                  
                  
                            }

                  
                  
                    111
                  
                  
                    112
                  
                  
                    //
                  
                  
                     楼宇扫描相关配置数据
                  
                  
                    113
                  
                  
                    const
                  
                   flowData =
                  
                     {

                  
                  
                    114
                  
                               boxSize: { 
                  
                    //
                  
                  
                     建筑群包围盒的尺寸
                  
                  
                    115
                  
                                   x: 0
                  
                    ,

                  
                  
                    116
                  
                                   y: 0
                  
                    ,

                  
                  
                    117
                  
                  
                                    z: HEIGHT

                  
                  
                    118
                  
                  
                                },

                  
                  
                    119
                  
                  
                                flowConf: {

                  
                  
                    120
                  
                                   x: 1, 
                  
                    //
                  
                  
                     开关 1 表示开始
                  
                  
                    121
                  
                                   y: 20, 
                  
                    //
                  
                  
                     范围
                  
                  
                    122
                  
                                   z: 100 
                  
                    //
                  
                  
                     速度
                  
                  
                    123
                  
                  
                                },

                  
                  
                    124
                  
                               color: "#000000", 
                  
                    //
                  
                  
                     建筑颜色
                  
                  
                    125
                  
                               flowColor: "#ffffff", 
                  
                    //
                  
                  
                     扫描颜色
                  
                  
                    126
                  
                               topColor: '#409eff' 
                  
                    //
                  
                  
                     顶部颜色
                  
                  
                    127
                  
                  
                            }

                  
                  
                    128
                  
                  
                    129
                  
                  
                    this
                  
                  .material = 
                  
                    new
                  
                  
                     THREE.ShaderMaterial({

                  
                  
                    130
                  
                               transparent: 
                  
                    true
                  
                  
                    ,

                  
                  
                    131
                  
                  
                                uniforms: {

                  
                  
                    132
                  
                  
                                    u_time: ratio,

                  
                  
                    133
                  
                  
                                    u_size: {

                  
                  
                    134
                  
                  
                                        value: flowData.boxSize

                  
                  
                    135
                  
                  
                                    },

                  
                  
                    136
                  
                  
                                    u_flow: {

                  
                  
                    137
                  
                  
                                        value: flowData.flowConf

                  
                  
                    138
                  
                  
                                    },

                  
                  
                    139
                  
                  
                                    u_color: {

                  
                  
                    140
                  
                                       value: 
                  
                    new
                  
                  
                     THREE.Color(flowData.color)

                  
                  
                    141
                  
                  
                                    },

                  
                  
                    142
                  
                  
                                    u_flowColor: {

                  
                  
                    143
                  
                                       value: 
                  
                    new
                  
                  
                     THREE.Color(flowData.flowColor)

                  
                  
                    144
                  
                  
                                    },

                  
                  
                    145
                  
                  
                                    u_topColor: {

                  
                  
                    146
                  
                                       value: 
                  
                    new
                  
                  
                     THREE.Color(flowData.topColor)

                  
                  
                    147
                  
                  
                                    }

                  
                  
                    148
                  
                  
                                },

                  
                  
                    149
                  
                  
                                vertexShader,

                  
                  
                    150
                  
                  
                                fragmentShader

                  
                  
                    151
                  
                  
                            });

                  
                  
                    152
                  
                  
                    153
                  
                           watchUtils.whenTrue(
                  
                    this
                  
                  .view, "stationary", () =>
                  
                     {

                  
                  
                    154
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .options.zoomChange) {

                  
                  
                    155
                  
                  
                    this
                  
                  .options.zoomChange(
                  
                    this
                  
                  
                    .view.zoom);

                  
                  
                    156
                  
                  
                                }

                  
                  
                    157
                  
                  
                    //
                  
                  
                     if (this.view.zoom >= LEVEL) {

                  
                  
                    158
                  
                  
                    //
                  
                  
                         this.group.visible = true;

                  
                  
                    159
                  
                  
                    //
                  
                  
                         this.loadData();

                  
                  
                    160
                  
                  
                    //
                  
                  
                     } else {

                  
                  
                    161
                  
                  
                    //
                  
                  
                         this.group.visible = false;

                  
                  
                    162
                  
                  
                    //
                  
                  
                     }
                  
                  
                    163
                  
                  
                            });

                  
                  
                    164
                  
                  
                        }

                  
                  
                    165
                  
                  
                    166
                  
                  
                        addModels(context) {

                  
                  
                    167
                  
                  
                    super
                  
                  
                    .addModels(context);

                  
                  
                    168
                  
                  
                    169
                  
                  
                    this
                  
                  
                    .loadData();

                  
                  
                    170
                  
                  
                        }

                  
                  
                    171
                  
                  
                    172
                  
                  
                        updateModels(context) {

                  
                  
                    173
                  
                  
                    super
                  
                  
                    .updateModels(context);

                  
                  
                    174
                  
                  
                    175
                  
                  
                    //
                  
                  
                     this.objects.forEach(obj => {

                  
                  
                    176
                  
                  
                    //
                  
                  
                         obj.material.uniforms.time.value += 0.01;

                  
                  
                    177
                  
                  
                    //
                  
                  
                     })

                  
                  
                    178
                  
                  
                    179
                  
                  
                    //
                  
                  
                     this.group.children.forEach(mesh => {

                  
                  
                    180
                  
                  
                    //
                  
                  
                         if (mesh.scale.z >= 1) {

                  
                  
                    181
                  
                  
                    //
                  
                  
                             mesh.scale.z = 1;

                  
                  
                    182
                  
                  
                    //
                  
                  
                         } else {

                  
                  
                    183
                  
                  
                    //
                  
                  
                             mesh.scale.z += 0.02;

                  
                  
                    184
                  
                  
                    //
                  
                  
                         }

                  
                  
                    185
                  
                  
                    //
                  
                  
                     })
                  
                  
                    186
                  
                  
                        }

                  
                  
                    187
                  
                  
                    188
                  
                  
                        loadData() {

                  
                  
                    189
                  
                           let count = 0
                  
                    ;

                  
                  
                    190
                  
                  
                    //
                  
                  
                     let index = 0;
                  
                  
                    191
                  
                  
                    this
                  
                  ._loadData(featureSet =>
                  
                     {

                  
                  
                    192
                  
                  
                    //
                  
                  
                     console.log(index);

                  
                  
                    193
                  
                  
                    //
                  
                  
                     index++;

                  
                  
                    194
                  
                  
                    //
                  
                  
                     console.log('fz:' + featureSet.length)

                  
                  
                    195
                  
                  
                    //
                  
                  
                     console.log(count += featureSet.length)
                  
                  
                    196
                  
                  
                    197
                  
                               let _objects =
                  
                     []

                  
                  
                    198
                  
                               featureSet.forEach(feature =>
                  
                     {

                  
                  
                    199
                  
                  
                    //
                  
                  
                     this._validateModel(feature);
                  
                  
                    200
                  
                  
                    const
                  
                   obj = 
                  
                    this
                  
                  
                    ._addModel(feature);

                  
                  
                    201
                  
                  
                                    _objects.push(obj.geometry);

                  
                  
                    202
                  
                  
                                })

                  
                  
                    203
                  
                  
                    204
                  
                  
                                console.log(_objects.length)

                  
                  
                    205
                  
                  
                    206
                  
                               console.time("render building"
                  
                    );

                  
                  
                    207
                  
                  
                    const
                  
                   mergeGeometry =
                  
                     BufferGeometryUtils.mergeBufferGeometries(_objects);

                  
                  
                    208
                  
                  
                    //
                  
                  
                     const mergeGeometry = this.mergeBufferGeometry(_objects);
                  
                  
                    209
                  
                               console.timeEnd("render building"
                  
                    );

                  
                  
                    210
                  
                  
                    const
                  
                   mergeMesh = 
                  
                    new
                  
                   THREE.Mesh(mergeGeometry, 
                  
                    this
                  
                  
                    .material);

                  
                  
                    211
                  
                  
                    //
                  
                  
                     mergeMesh.scale.z = 0;
                  
                  
                    212
                  
                  
                    213
                  
                  
                    this
                  
                  
                    .group.add(mergeMesh);

                  
                  
                    214
                  
                               console.log('this.group.children.length2:' + 
                  
                    this
                  
                  
                    .group.children.length);

                  
                  
                    215
                  
                  
                    216
                  
                  
                    this
                  
                  .scene.add(
                  
                    this
                  
                  .group); 
                  
                    //
                  
                  
                    网格模型添加到场景中
                  
                  
                    217
                  
                  
                            })

                  
                  
                    218
                  
                  
                    //
                  
                  
                    http://10.102.109.88
                  
                  
                    :9530/?type=qzx

                  
                  
                    219
                  
                  
                    220
                  
                  
                    //
                  
                  
                     const url = config.mapservice[1].base_url + config.mapservice[1].house_url;

                  
                  
                    221
                  
                  
                    //
                  
                  
                    //
                  
                  
                     const url = '
                  
                  
                    http://10.34.4.103
                  
                  
                    :8010/ServiceAdapter/Map/%E6%88%BF%E5%B1%8B/15d4b9815cf7420da111307850d2049f/0';

                  
                  
                    222
                  
                  
                    //
                  
                  
                    //
                  
                  
                     const url = '
                  
                  
                    http://10.100.0.132
                  
                  
                    :6080/arcgis/rest/services/wuchang_gim/gim_region/MapServer/0';

                  
                  
                    223
                  
                  
                    //
                  
                  
                     JBMS.forEach(jbm => {

                  
                  
                    224
                  
                  
                    //
                  
                  
                         mapx.queryTask(url, {

                  
                  
                    225
                  
                  
                    //
                  
                  
                             where: `JBM='${jbm}'`,

                  
                  
                    226
                  
                  
                    //
                  
                  
                             outSpatialReference: '4326',

                  
                  
                    227
                  
                  
                    //
                  
                  
                    //
                  
                  
                     geometry: this.view.extent,

                  
                  
                    228
                  
                  
                    //
                  
                  
                    //
                  
                  
                     geometry: this.circle,

                  
                  
                    229
                  
                  
                    //
                  
                  
                             returnGeometry: true

                  
                  
                    230
                  
                  
                    //
                  
                  
                         }).then(featureSet => {

                  
                  
                    231
                  
                  
                    //
                  
                  
                             console.log('fz:' + featureSet.length)

                  
                  
                    232
                  
                  
                    233
                  
                  
                    //
                  
                  
                             console.time("render building");

                  
                  
                    234
                  
                  
                    235
                  
                  
                    //
                  
                  
                             let _objects = []

                  
                  
                    236
                  
                  
                    //
                  
                  
                             featureSet.forEach(feature => {

                  
                  
                    237
                  
                  
                    //
                  
                  
                    //
                  
                  
                     this._validateModel(feature);

                  
                  
                    238
                  
                  
                    //
                  
                  
                                 const obj = this._addModel(feature);

                  
                  
                    239
                  
                  
                    //
                  
                  
                                 _objects.push(obj.geometry);

                  
                  
                    240
                  
                  
                    //
                  
                  
                             })

                  
                  
                    241
                  
                  
                    //
                  
                  
                             const mergeGeometry = BufferGeometryUtils.mergeBufferGeometries(_objects);

                  
                  
                    242
                  
                  
                    //
                  
                  
                    //
                  
                  
                     const mergeGeometry = this.mergeBufferGeometry(_objects);

                  
                  
                    243
                  
                  
                    //
                  
                  
                             const mergeMesh = new THREE.Mesh(mergeGeometry, this.material);

                  
                  
                    244
                  
                  
                    //
                  
                  
                             this.group.add(mergeMesh);

                  
                  
                    245
                  
                  
                    246
                  
                  
                    //
                  
                  
                             console.timeEnd("render building");

                  
                  
                    247
                  
                  
                    //
                  
                  
                             console.log('this.group.children.length2:' + this.group.children.length);

                  
                  
                    248
                  
                  
                    249
                  
                  
                    //
                  
                  
                             this.scene.add(this.group); 
                  
                  
                    //
                  
                  
                    网格模型添加到场景中

                  
                  
                    250
                  
                  
                    251
                  
                  
                    //
                  
                  
                         }).catch(error => {})

                  
                  
                    252
                  
                  
                    //
                  
                  
                     })
                  
                  
                    253
                  
                  
                        }

                  
                  
                    254
                  
                  
                    255
                  
                  
                        _loadData(callback) {

                  
                  
                    256
                  
                  
                    //
                  
                  
                    循环并联本地查询
                  
                  
                    257
                  
                           JBMS.forEach(jbm =>
                  
                     {

                  
                  
                    258
                  
                               getBuildings(jbm).then(res =>
                  
                     {

                  
                  
                    259
                  
                  
                                    callback(res.data.features)

                  
                  
                    260
                  
                  
                                    console.log(res.data.features)

                  
                  
                    261
                  
                  
                                })

                  
                  
                    262
                  
                  
                            })

                  
                  
                    263
                  
                  
                    264
                  
                  
                    return
                  
                  
                    265
                  
                  
                    266
                  
                  
                    const
                  
                   url = config.mapservice[1].base_url + config.mapservice[1
                  
                    ].house_url;

                  
                  
                    267
                  
                  
                    //
                  
                  
                     const url = '
                  
                  
                    http://10.34.4.103
                  
                  
                    :8010/ServiceAdapter/Map/%E6%88%BF%E5%B1%8B/15d4b9815cf7420da111307850d2049f/0';

                  
                  
                    268
                  
                  
                    //
                  
                  
                     const url = '
                  
                  
                    http://10.100.0.132
                  
                  
                    :6080/arcgis/rest/services/wuchang_gim/gim_region/MapServer/0';

                  
                  
                    269
                  
                  
                    270
                  
                  
                    //
                  
                  
                    循环并联分发查询
                  
                  
                    271
                  
                           JBMS.forEach(jbm =>
                  
                     {

                  
                  
                    272
                  
                  
                                mapx.queryTask(url, {

                  
                  
                    273
                  
                                   where: `JBM='${jbm}'
                  
                    `,

                  
                  
                    274
                  
                                   outSpatialReference: '4326'
                  
                    ,

                  
                  
                    275
                  
                  
                    //
                  
                  
                     geometry: this.view.extent,

                  
                  
                    276
                  
                  
                    //
                  
                  
                     geometry: this.circle,
                  
                  
                    277
                  
                                   returnGeometry: 
                  
                    true
                  
                  
                    278
                  
                               }).then(featureSet =>
                  
                     {

                  
                  
                    279
                  
                  
                                    callback(featureSet)

                  
                  
                    280
                  
                               }).
                  
                    catch
                  
                  (error =>
                  
                     {})

                  
                  
                    281
                  
                  
                            })

                  
                  
                    282
                  
                  
                    283
                  
                  
                    return
                  
                  
                    284
                  
                  
                    285
                  
                  
                    //
                  
                  
                    递归串联分发查询
                  
                  
                    286
                  
                           let index= 0
                  
                    ;

                  
                  
                    287
                  
                  
                            function query() {

                  
                  
                    288
                  
                  
                                mapx.queryTask(url, {

                  
                  
                    289
                  
                                   where: `JBM='${JBMS[index]}'
                  
                    `,

                  
                  
                    290
                  
                                   outSpatialReference: '4326'
                  
                    ,

                  
                  
                    291
                  
                  
                    //
                  
                  
                     geometry: this.view.extent,

                  
                  
                    292
                  
                  
                    //
                  
                  
                     geometry: this.circle,
                  
                  
                    293
                  
                                   returnGeometry: 
                  
                    true
                  
                  
                    294
                  
                               }).then(featureSet =>
                  
                     {

                  
                  
                    295
                  
                  
                                    callback(featureSet)

                  
                  
                    296
                  
                                   index++
                  
                    ;

                  
                  
                    297
                  
                  
                    if
                  
                  (index <
                  
                     JBMS.length) {

                  
                  
                    298
                  
                  
                    //
                  
                  
                     const sid = setTimeout(() => {

                  
                  
                    299
                  
                  
                    //
                  
                  
                     clearTimeout(sid);
                  
                  
                    300
                  
                  
                                            query();

                  
                  
                    301
                  
                  
                    //
                  
                  
                     }, 2000)
                  
                  
                    302
                  
                  
                                    }

                  
                  
                    303
                  
                               }).
                  
                    catch
                  
                  (error =>
                  
                     {})

                  
                  
                    304
                  
                  
                            }

                  
                  
                    305
                  
                  
                            query();

                  
                  
                    306
                  
                  
                        }

                  
                  
                    307
                  
                  
                    308
                  
                  
                    //
                  
                  
                     _validateModel(feature) {

                  
                  
                    309
                  
                  
                    //
                  
                  
                         for (let key in this.cacheObjects) {

                  
                  
                    310
                  
                  
                    //
                  
                  
                             const m = this.cacheObjects[key];

                  
                  
                    311
                  
                  
                    //
                  
                  
                             const flag = this.view.extent.intersects(m.geometry)

                  
                  
                    312
                  
                  
                    //
                  
                  
                    //
                  
                  
                     const flag = geometryEngine.intersects(this.circle, m.geometry)

                  
                  
                    313
                  
                  
                    //
                  
                  
                             if (!flag) {

                  
                  
                    314
                  
                  
                    //
                  
                  
                                 this.group.remove(m);

                  
                  
                    315
                  
                  
                    //
                  
                  
                                 delete this.cacheObjects[key]

                  
                  
                    316
                  
                  
                    //
                  
                  
                             }

                  
                  
                    317
                  
                  
                    //
                  
                  
                         }

                  
                  
                    318
                  
                  
                    //
                  
                  
                     }
                  
                  
                    319
                  
                  
                    320
                  
                  
                        _addModel(feature) {

                  
                  
                    321
                  
                  
                    //
                  
                  
                    处理缓存
                  
                  
                    322
                  
                  
                    const
                  
                   uid =
                  
                     feature.attributes[UID];

                  
                  
                    323
                  
                  
                    if
                  
                   (
                  
                    this
                  
                  
                    .cacheObjects.hasOwnProperty(uid)) {

                  
                  
                    324
                  
                  
                    //
                  
                  
                     this.cacheObjects[uid].visible = true;
                  
                  
                    325
                  
                           } 
                  
                    else
                  
                  
                     {

                  
                  
                    326
                  
                  
                    this
                  
                  .cacheObjects[uid] =
                  
                     feature;

                  
                  
                    327
                  
                  
                    328
                  
                               let height =
                  
                     HEIGHT;

                  
                  
                    329
                  
                  
                    const
                  
                   points = feature.geometry.rings[0
                  
                    ];

                  
                  
                    330
                  
                  
                    const
                  
                   htemp = feature.attributes['高度'
                  
                    ];

                  
                  
                    331
                  
                  
                    if
                  
                  
                     (htemp) {

                  
                  
                    332
                  
                                   height = htemp +
                  
                     INCREASE;

                  
                  
                    333
                  
                  
                                }

                  
                  
                    334
                  
                  
                    335
                  
                               let vertices =
                  
                     [];

                  
                  
                    336
                  
                  
                    for
                  
                   (let i = 0; i < points.length; i++
                  
                    ) {

                  
                  
                    337
                  
                                   let p =
                  
                     points[i];

                  
                  
                    338
                  
                                   let pointXYZ = 
                  
                    this
                  
                  .lngLatToXY(
                  
                    this
                  
                  .view, [p[0], p[1], 0
                  
                    ]);

                  
                  
                    339
                  
                  
                                    vertices.push(pointXYZ);

                  
                  
                    340
                  
                  
                                }

                  
                  
                    341
                  
                  
                    342
                  
                  
                    const
                  
                   shape = 
                  
                    new
                  
                  
                     THREE.Shape();

                  
                  
                    343
                  
                  
                    for
                  
                   (let i = 0; i < vertices.length; i++
                  
                    ) {

                  
                  
                    344
                  
                                   let v =
                  
                     vertices[i].vector3List;

                  
                  
                    345
                  
                  
                    if
                  
                   (i === 0
                  
                    ) {

                  
                  
                    346
                  
                  
                                        shape.moveTo(v.x, v.y);

                  
                  
                    347
                  
                  
                                    }

                  
                  
                    348
                  
                  
                                    shape.lineTo(v.x, v.y);

                  
                  
                    349
                  
                  
                                }

                  
                  
                    350
                  
                  
                    351
                  
                  
                    const
                  
                   extrudeSettings =
                  
                     {

                  
                  
                    352
                  
                                   steps: 2
                  
                    ,

                  
                  
                    353
                  
                  
                                    depth: height,

                  
                  
                    354
                  
                                   bevelEnabled: 
                  
                    true
                  
                  
                    ,

                  
                  
                    355
                  
                                   bevelThickness: 1
                  
                    ,

                  
                  
                    356
                  
                                   bevelSize: 1
                  
                    ,

                  
                  
                    357
                  
                                   bevelOffset: 0
                  
                    ,

                  
                  
                    358
                  
                                   bevelSegments: 1

                  
                    359
                  
                  
                                };

                  
                  
                    360
                  
                  
                    361
                  
                  
                    const
                  
                   geometry = 
                  
                    new
                  
                  
                     THREE.ExtrudeGeometry(shape, extrudeSettings);

                  
                  
                    362
                  
                  
                    const
                  
                   mesh = 
                  
                    new
                  
                   THREE.Mesh(geometry, 
                  
                    this
                  
                  .material); 
                  
                    //
                  
                  
                    网格模型对象Mesh 

                  
                  
                    363
                  
                  
                    364
                  
                  
                    //
                  
                  
                     const edges = new THREE.EdgesGeometry(geometry);

                  
                  
                    365
                  
                  
                    //
                  
                  
                     const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({

                  
                  
                    366
                  
                  
                    //
                  
                  
                         color: 0x000000,

                  
                  
                    367
                  
                  
                    //
                  
                  
                         linewidth: 1

                  
                  
                    368
                  
                  
                    //
                  
                  
                     }));

                  
                  
                    369
                  
                  
                    370
                  
                  
                    //
                  
                  
                     this.group.add(mesh);

                  
                  
                    371
                  
                  
                    //
                  
                  
                     this.group.add(line);
                  
                  
                    372
                  
                  
                    this
                  
                  
                    .objects.push(mesh);

                  
                  
                    373
                  
                  
                    374
                  
                  
                    //
                  
                  
                     mesh.scale.z = 0;
                  
                  
                    375
                  
                  
                    376
                  
                  
                    return
                  
                  
                     mesh;

                  
                  
                    377
                  
                  
                            }

                  
                  
                    378
                  
                  
                        }

                  
                  
                    379
                  
                  
                    380
                  
                  
                        getRadius() {

                  
                  
                    381
                  
                           var extent = 
                  
                    this
                  
                  
                    .view.extent;

                  
                  
                    382
                  
                           var lt =
                  
                     webMercatorUtils.xyToLngLat(extent.xmin, extent.ymin);

                  
                  
                    383
                  
                           var rb =
                  
                     webMercatorUtils.xyToLngLat(extent.xmax, extent.ymax);

                  
                  
                    384
                  
                           var paths =
                  
                     [

                  
                  
                    385
                  
                  
                                [

                  
                  
                    386
                  
                  
                                    lt,

                  
                  
                    387
                  
                  
                                    rb

                  
                  
                    388
                  
                  
                                ]

                  
                  
                    389
                  
                  
                            ];

                  
                  
                    390
                  
                           var line = 
                  
                    new
                  
                  
                     Polyline({

                  
                  
                    391
                  
                  
                                paths: paths,

                  
                  
                    392
                  
                  
                                spatialReference: {

                  
                  
                    393
                  
                                   wkid: '4326'

                  
                    394
                  
                  
                                }

                  
                  
                    395
                  
                  
                            });

                  
                  
                    396
                  
                           var d = geometryEngine.geodesicLength(line, 'meters'
                  
                    );

                  
                  
                    397
                  
                  
                    //
                  
                  
                     var d = geometryEngine.planarLength(line, 'meters');
                  
                  
                    398
                  
                  
                    return
                  
                   d * 0.5 *
                  
                     EF;

                  
                  
                    399
                  
                  
                        }

                  
                  
                    400
                  
                  
                    401
                  
                  
                        mergeBufferGeometry(objects) {

                  
                  
                    402
                  
                  
                    const
                  
                   sumPosArr = 
                  
                    new
                  
                  
                     Array();

                  
                  
                    403
                  
                  
                    const
                  
                   sumNormArr = 
                  
                    new
                  
                  
                     Array();

                  
                  
                    404
                  
                  
                    const
                  
                   sumUvArr = 
                  
                    new
                  
                  
                     Array();

                  
                  
                    405
                  
                  
                    406
                  
                  
                    const
                  
                   modelGeometry = 
                  
                    new
                  
                  
                     THREE.BufferGeometry();

                  
                  
                    407
                  
                  
                    408
                  
                           let sumPosCursor = 0
                  
                    ;

                  
                  
                    409
                  
                           let sumNormCursor = 0
                  
                    ;

                  
                  
                    410
                  
                           let sumUvCursor = 0
                  
                    ;

                  
                  
                    411
                  
                  
                    412
                  
                           let startGroupCount = 0
                  
                    ;

                  
                  
                    413
                  
                           let lastGroupCount = 0
                  
                    ;

                  
                  
                    414
                  
                  
                    415
                  
                  
                    for
                  
                   (let a = 0; a < objects.length; a++
                  
                    ) {

                  
                  
                    416
                  
                  
                    const
                  
                   posAttArr = objects[a].geometry.getAttribute('position'
                  
                    ).array;

                  
                  
                    417
                  
                  
                    418
                  
                  
                    for
                  
                   (let b = 0; b < posAttArr.length; b++
                  
                    ) {

                  
                  
                    419
                  
                                   sumPosArr[b + sumPosCursor] =
                  
                     posAttArr[b];

                  
                  
                    420
                  
                  
                                }

                  
                  
                    421
                  
                  
                    422
                  
                               sumPosCursor +=
                  
                     posAttArr.length;

                  
                  
                    423
                  
                  
                    424
                  
                  
                    425
                  
                  
                    const
                  
                   numAttArr = objects[a].geometry.getAttribute('normal'
                  
                    ).array;

                  
                  
                    426
                  
                  
                    427
                  
                  
                    for
                  
                   (let b = 0; b < numAttArr.length; b++
                  
                    ) {

                  
                  
                    428
                  
                                   sumNormArr[b + sumNormCursor] =
                  
                     numAttArr[b];

                  
                  
                    429
                  
                  
                                }

                  
                  
                    430
                  
                  
                    431
                  
                               sumNormCursor +=
                  
                     numAttArr.length;

                  
                  
                    432
                  
                  
                    433
                  
                  
                    434
                  
                  
                    const
                  
                   uvAttArr = objects[a].geometry.getAttribute('uv'
                  
                    ).array;

                  
                  
                    435
                  
                  
                    436
                  
                  
                    for
                  
                   (let b = 0; b < uvAttArr.length; b++
                  
                    ) {

                  
                  
                    437
                  
                                   sumUvArr[b + sumUvCursor] =
                  
                     uvAttArr[b];

                  
                  
                    438
                  
                  
                                }

                  
                  
                    439
                  
                  
                    440
                  
                               sumUvCursor +=
                  
                     uvAttArr.length;

                  
                  
                    441
                  
                  
                    442
                  
                  
                    const
                  
                   groupArr =
                  
                     objects[a].geometry.groups;

                  
                  
                    443
                  
                  
                    444
                  
                  
                    for
                  
                   (let b = 0; b < groupArr.length; b++
                  
                    ) {

                  
                  
                    445
                  
                                   startGroupCount =
                  
                     lastGroupCount

                  
                  
                    446
                  
                  
                                    modelGeometry.addGroup(startGroupCount, groupArr[b].count, groupArr[b].materialIndex)

                  
                  
                    447
                  
                                   lastGroupCount = startGroupCount +
                  
                     groupArr[b].count

                  
                  
                    448
                  
                  
                                }

                  
                  
                    449
                  
                  
                            }

                  
                  
                    450
                  
                  
                    451
                  
                           modelGeometry.setAttribute('position', 
                  
                    new
                  
                   THREE.Float32BufferAttribute(sumPosArr, 3
                  
                    ));

                  
                  
                    452
                  
                           sumNormArr.length && modelGeometry.setAttribute('normal', 
                  
                    new
                  
                   THREE.Float32BufferAttribute(sumNormArr, 3
                  
                    ));

                  
                  
                    453
                  
                           sumUvArr.length && modelGeometry.setAttribute('uv', 
                  
                    new
                  
                   THREE.Float32BufferAttribute(sumUvArr, 2
                  
                    ));

                  
                  
                    454
                  
                  
                    455
                  
                  
                    return
                  
                  
                     modelGeometry

                  
                  
                    456
                  
                  
                        }

                  
                  
                    457
                  
                   }
                
View Code

  。

效果图:

  。

最后此篇关于数据可视化【原创】vue+arcgis+threejs实现海量建筑物房屋渲染,性能优化的文章就讲到这里了,如果你想了解更多关于数据可视化【原创】vue+arcgis+threejs实现海量建筑物房屋渲染,性能优化的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com