So I looked into this some and I think the main problem is the way Unicode works in JavaScript. Here’s a fairly extensive article on the subject: https://mathiasbynens.be/notes/javascript-unicode
The problem is specifically the way JavaScript deals with surrogate pairs (two characters that actually form one glyph). For example, alert(‘ตึก’.length) reports 3, even though visually there are clearly 2 characters. In order to support a large amount of strings, the LabelCollection renders each glyph as a separate image, so when we iterate the string, we actually create two separate characters for one glyph (because JavaScript itself treats a surrogate pair as two characters).
I’m not sure there’s an easy solution for this problem using our current label rendering techniques. The good news is it’s incredibly easy to work around by just using Billboards instead. (which is how labels are implemented anyway) Below is an example of doing that in Cesium. Basically rename LabelCollection to BillboardCollection and instead of assigning a text property, use writeTextToCanvas to create an image from the text and assign it to the image property.
The only downside to this approach is that it will use more texture memory and if you have dynamic textures, you could run out. Give it a try and let me know how it works out. I also opened a GitHub issue so that we look at this in the future: https://github.com/AnalyticalGraphicsInc/cesium/issues/2521
var viewer = new Cesium.Viewer(‘cesiumContainer’);
var scene = viewer.scene;
var camera = viewer.scene.camera;
camera.lookAt(Cesium.Cartesian3.fromDegrees(100.5382368,13.8, 50000),
Cesium.Cartesian3.fromDegrees(100.5382368,13.7242002, 0), Cesium.Cartesian3.UNIT_Z);
var labels = scene.primitives.add(new Cesium.BillboardCollection());
labels.add({
position : Cesium.Cartesian3.fromDegrees(100.545624,13.743179),
image : Cesium.writeTextToCanvas(‘ตึก’, { font: ‘24px san-serif’ })
});
Let me know how it works out.
Thanks,
Matt