preface

The author contacted CesiumJS because of the company’s project needs, directly learning while developing, two or three months have been quite smooth. As the volume of data grew and the number of entities on the map increased, the first screen would often lag when loading, the client’s machine would perform poorly, and sometimes the browser would be unresponsive at the same time. The test classified the problem as a BUG that had to be fixed, which made my head go crazy.

Problems with loading hundreds of entities

Let’s first look at what’s wrong with loading the Label entity?

function addBillboard(bsm, name, buildingType, position) { this.viewer.entities.add({ id: bsm, name, position: Cartesian3.fromDegrees(position[0], position[1], position[2]), label: { text: name, font: style == 1 ? '500 40px Microsoft YaHei' : '500 30px Helvetica', // 15pt monospace outlineColor: Color.WHITE, // outlineWidth: 1, // width: 0.5, style: style == 1? Labelstyle.fill_and_outline: LabelStyle.FILL, fillColor: style == 1 ? Color.BLACK : Color.WHITE, pixelOffset: New Cartesian2 (110-70), / / offset showBackground: true, backgroundColor: backColor, distanceDisplayCondition: New DistanceDisplayCondition (10.0, 8000.0), disableDepthTestDistance: 100.0, scaleByDistance: New NearFarScalar(500, 1, 1400, 0.0), translucencyByDistance: New NearFarScalar(500, 1, 1400, 0.0)}, Billboard: { image: buildingTypeImage, width: 300, height: 140, pixelOffset: New Cartesian2 (90-25), / / offset distanceDisplayCondition: New DistanceDisplayCondition (10.0, 2000.0), disableDepthTestDistance: 100.0, scaleByDistance: New NearFarScalar(500, 1, 1400, 0.0), translucencyByDistance: New NearFarScalar(500, 1, 1400, 0.0)}, properties: { poiType: 'buildingPOI', name, buildingType, bsm, position } }); }Copy the code

When I need to create more than 400 of these entities, the page always freezes for a while. So I searched the Internet for relevant information, maybe I have a problem in expression, I have not found the answer I want. So I started DevTools in the browser.

When loading the map, js executes for 4.75 seconds… , the company’s computer configuration is as follows:

Not bad performance

Moving on to Performance analysis

Why did this getImageData take more than 2 seconds to execute? I thought at that time, does Cesium need to do other processing for the picture I uploaded? So I put the physicalbillboardThe attributes are removed.

20% less time. Oh, no, I didn’t upload the picture,CesiumStill upgetImageDataI wonder if this isCesiumIn generating the image,entitieAttributes only label/position/properties/id/name, in addition to label, everything else is a pure data. Isn’t label text?

With this problem in mind, I removed the entity’s label attribute as well. Performed a Performance.

getImageDataMethod is not called.

At this point, I concludeCesiumCreate an object that contains a labelentitie, a picture of the corresponding label.name value is dynamically generated.

Solution – dynamically generate your own images

Find the problem, then it’s easy, try to construct the label yourself, don’t use the Cesium label. The actual billboard in the original project is a PNG base image.



Use Canvas to draw a picture with text, and add base64 code toentitiethebillboard

const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const image = new Image(); image.style.width = '400px'; Const name = 'max_year '; image.onload = () => { canvas.width = image.width; canvas.height = image.height; ctx.drawImage(image, 0, 0, image.width, image.height); ctx.font = 'bold 20px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'bottom'; ctx.fillStyle = '#FFF'; ctx.fillText(name, 220, 70); this.imageUrl = canvas.toDataURL('image/png'); }; image.src = Iurl;Copy the code

After the image is generated, add the generated image to billboard and perform Performance again.



Page opened in seconds, no lag!!

Annotations are displayed normally.

The new problem

Considering the client’s computer performance is not good, every time open the page to dynamically generate hundreds of pictures, also quite a waste of performance. Make storage. Storage back-end Or front-end? Since the point information is dynamically configured and managed by a dedicated page, the text and base images are subject to change. In this case, images stored in the back end can only be manually controlled to generate images.

With IndexedDB storage

IndexedDB = IndexedDB = WebSQL = IndexedDB = WebSQL = IndexedDB

/ / project FILE is created and connected with IndexedDB entrance / / FILE - > the main, js const with IndexedDB = window. With IndexedDB | | window. WebkitIndexedDB | | window.mozIndexedDB; DBOpenRequest.onupgradeneeded = (e) => { console.info('DB upgradeneeded') const db = e.target.result; if (! db.objectStoreNames.contains('buildingImage')) { db.createObjectStore('buildingImage', { keyPath: 'bsm' }); }} dbOpenRequest. onsuccess = (e) => {console.info('DB link successful ') const DB = e.target.result; Vue.prototype.$DB = db; new Vue({ router, store, beforeDestroy() { DBOpenRequest.result.close(); }, render: h => h(App) }).$mount('#app'); } DBOpenRequest.onerror = (e) => { console.ERROR('Can not open indexedDB', e); new Vue({ router, store, beforeDestroy() { DBOpenRequest.result.close(); }, render: h => h(AppWith404) }).$mount('#app'); };Copy the code

Finally: When adding entitie, first check whether the corresponding BSM exists in the database. If so, judge whether all kinds of information is consistent. If so, use the stored Base64 image as the Billboard image. If no image exists or all kinds of information are inconsistent, re-generate the image and save it in the library to be used as the Billboard image.

conclusion

At this point, Cesium loading a large number of Entitie stuck problem is basically solved, enter the page can also reach the speed of second. Domestic CesiumJS knowledge sharing is too little, sometimes encountered problems, can not find the answer online; And CesiumJS has so many apis that it is difficult to find the desired functional API in a short time. If you want to study together, please private letter!! My cognition of CesiumJS is just like learning JS in pre-school, and I feel confused. If there are any mistakes or wrong remarks in this article, please point out. Thank you (low low ◡).