Cesium issue positioning labels for GeoJSON markers - label

I'm displaying some GeoJSON as markers in Cesium; they do not have altitude, so I'm using clampToGround: true. This all works.
When I try to label the markers, the labels only display when I'm zoomed far out. When I zoom in the labels disappear "underground", which is under the Terrain "layer".
How to solve this? I've looked at this, but it didn't help in my case. This neither.
The code:
const viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider: Cesium.createWorldTerrain(),
timeline: false, // Hide clock thing
animation: false, // ditto
});
// Add Cesium OSM Buildings, a global 3D buildings layer.
const buildingTileset = viewer.scene.primitives.add(Cesium.createOsmBuildings());
// Fly the camera to the given longitude, latitude, and height.
viewer.camera.flyTo({
destination : Cesium.Cartesian3.fromDegrees(11.952996, 57.671910, 400),
orientation : {
heading : Cesium.Math.toRadians(0.0),
pitch : Cesium.Math.toRadians(-15.0),
}
});
var promise = Cesium.GeoJsonDataSource.load('data/botaniska_play.geojson', {
clampToGround: true,
markerColor: Cesium.Color.DARKGREEN,
});
promise.then (function (dataSource) {
viewer.dataSources.add (dataSource);
var entities = dataSource["_entityCollection"]["_entities"]["_array"];
entities.forEach (entity => {
// Add (and poistion?) label
entity.label = new Cesium.LabelGraphics ({
text: entity['_properties']['art']._value,
//eyeOffset: new Cesium.Cartesian3 (0, 10, 0),
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0.0, -40.0), // Show above ground?
});
});
});
Snippet of the geojson:
{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[11.9531552705143,57.6814657645123]},"properties":{"ogc_fid":6,"geom":"{\"type\":\"Point\",\"coordinates\":[11.9531552705143,57.6814657645123]}","plats":"Test Plats","besikt_datum":"2013-06-07","trad_id":"6","art":"Magnolia stellata","status":null,"aldersfas":"Gammalt","hojd":9,"krondiameter":9,"stamdiameter":56,"skador":"Lindriga","vitalitet":"God","anmarkningar":"Vackert","rekommendationer":null,"risk":"Låg","resterande_risk":"-","atgards_datum":null,"atgard_gjort":null,"nasta_besiktning":"2014-06-07","stabiliserings_datum":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[11.9500765558289,57.6815427053798]},"properties":{"ogc_fid":21,"geom":"{\"type\":\"Point\",\"coordinates\":[11.9500765558289,57.6815427053798]}","plats":null,"besikt_datum":"2017-06-09","trad_id":null,"art":"Acer griseum","status":null,"aldersfas":"Vuxet","hojd":9,"krondiameter":8,"stamdiameter":50,"skador":null,"vitalitet":"God","anmarkningar":"Alléträd högt naturvärde\n","rekommendationer":null,"risk":"Låg","resterande_risk":null,"atgards_datum":null,"atgard_gjort":null,"nasta_besiktning":null,"stabiliserings_datum":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[11.9514171990732,57.6828566964894]},"properties":{"ogc_fid":3,"geom":"{\"type\":\"Point\",\"coordinates\":[11.9514171990732,57.6828566964894]}","plats":"Test Plats","besikt_datum":"2013-06-07","trad_id":"3","art":"Populus siemonii","status":null,"aldersfas":"Gammalt","hojd":15,"krondiameter":14,"stamdiameter":60,"skador":"Inga","vitalitet":"God","anmarkningar":"Fin","rekommendationer":null,"risk":"Låg","resterande_risk":"-","atgards_datum":null,"atgard_gjort":null,"nasta_besiktning":"2014-06-07","stabiliserings_datum":null}} ...

Try add disableDepthTestDistance: Number.POSITIVE_INFINITY to LabelGraphics options

Related

A-Frame & Three.js: Color map makes object white

I'm trying to assign a new material to an object, but when I assign a new (color) map, the object renders as white, and the AO and shadows no longer show up. It's as if the emissive attribute is 100%. I can change the color attribute (e.g. 'red' or 'blue'), ao, normal, etc. without issues. The glb loaded in already has a working material with a color map and ao, but I want to be able to replace it.
I'm using 8th Wall with A-Frame, but I've registered the following as a custom Three.js component.
const customMat = {
schema: {}, // will pass textures via aframe later
init() {
this.el.addEventListener('model-loaded', (e) => {
const material = new THREE.MeshStandardMaterial()
const texLoader = new THREE.TextureLoader()
texLoader.crossOrigin = ''
const mapColor = texLoader.load('assets/cover_color.jpg')
const mapAO = texLoader.load('assets/cover_ao.jpg')
material.map = mapColor // makes everything 100% white likes it's emissive
// material.color = new THREE.Color('red') // works fine no problem
material.aoMap = mapAO
material.aoMapIntensity = 1
e.detail.model.traverse((mesh) => {
if (mesh.isMesh) {
mesh.material = material
mesh.material.needsUpdate = true // not sure if needed
}
})
})
},
}
export {customMat}
Any suggestions would be much appreciated. I've tried this with primitive geometry too, but the same issue occurs. I don't seem to be able to modify the existing material's attributes either, so maybe my approach is fundamentally wrong.

Tooltip disappears when moving leaflet map

I add markers to the map and place them in the markercluster. For markers that are not clustered, I want to show the tooltip that I attach to the marker when I create it.
var geoMarkers = L.markerClusterGroup({ removeOutsideVisibleBounds:true, chunkedLoading: true, chunkProgress: this._updateProgress });
//start loop create markers
var marker = new L.marker(latlng, { icon: icon } );
marker.bindPopup(L._("Loading.."));
marker.bindTooltip(' text ');
geoMarkers.addLayer(marker);
//end loop
map.addLayer(geoMarkers);
map.on('layeradd', function(event) {
var layer = event.layer;
if (layer instanceof L.Marker && !(layer instanceof L.MarkerCluster)) {
layer.openTooltip();
}
});
To do this, I followed advice and listen for the layeradd event. When loading the map and moving to new markers, everything works. However, at any movement of the map, on those markers where the tooltip is already open, it is closed, since the layeradd event does not affect them. There is only one way to see the hint on them again - to zoom out so that the marker "hides" in the cluster and then again increasing the scale, I see the hint again. It is desirable that it be always present when the marker is not hidden in the cluster.
I ask for help or hints.
You can use the permanent tooltip option in order to maintain the visibility of your marker. Check here for official docs.
...
var geoMarkers = L.markerClusterGroup({ removeOutsideVisibleBounds:true, chunkedLoading: true, chunkProgress: this._updateProgress });
//start loop create markers
var marker = new L.marker(latlng, { icon: icon } );
marker.bindPopup(L._("Loading.."));
marker.bindTooltip(' text ', { permanent: true} ); // here define it
geoMarkers.addLayer(marker);
//end loop

how to Combe three.js page into A-frame page

Here is a Three.js Example from stemkoski, now I want to use this Texture-Animation plane or box in A-frame page, how can I Combine it.
A-frame Version: 0.9.0
I couldn't find any examples.
When integrating three.js pieces into aframe, it's recommended to use custom components. Here's a simple example:
js
AFRAME.registerComponent('foo', {
// this is called upon initialization
init: function() {
// we'll need this later on for updating the animation
this.animator = null
// wait until the component is loaded
this.el.addEventListener('loaded', e => {
// copied straight from stemkoski's code:
var runnerTexture = new THREE.ImageUtils.loadTexture( 'images/run.png' );
this.animator = new TextureAnimator( runnerTexture, 10, 1, 10, 75 );
// apply the texture to our element
let mesh = this.el.getObject3D('mesh')
mesh.material.map = runnerTexture
mesh.material.needsUpdate = true
})
},
// this is called before each render loop
tick: function(time, delta) {
// update only if animator was created
if (!this.animator) return
this.animator.update(1000 * delta);
}
})
HTML:
<a-plane foo></a-plane>
glitch here. To make it work with a glitch i had to preload the image with a-assets due to cors issues.

Cesium’s Tileset are laying behind pointcloud of Potree

I render cesium and potree on same canvas but when I added tileset from cesium It always laying behind pointcloud.
Tell me how to fix this issue.
I initialize both cesium and potree
cviewer = new Cesium.Viewer('cesiumContainer', {
useDefaultRenderLoop: false,
animation: false,
baseLayerPicker : false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
infoBox: false,
sceneModePicker: false,
selectionIndicator: false,
timeline: false,
navigationHelpButton: false,
imageryProvider : Cesium.createOpenStreetMapImageryProvider({url : 'http://a.tile.openstreetmap.org/'}),
terrainShadows: Cesium.ShadowMode.DISABLED,
});
cviewer.snippet = new ThreeDTile();
viewer = new Potree.Viewer(document.getElementById("potree_render_area"),"");
viewer.setEDLEnabled(false);
viewer.setMaterial("RGB");
viewer.setFOV(60);
if(isMobile()==true)
viewer.setPointSize(2);
viewer.setPointSizing("Fixed");
viewer.setPointBudget(1*1000*1000); //medLow
else
viewer.setPointSize(1);
viewer.setPointSizing("Adaptive");
viewer.setPointBudget(2*1000*1000);
viewer.setQuality("Squares");
viewer.setEDLEnabled(false);
viewer.setShowSkybox(false);
viewer.setMaterialID(Potree.PointColorType.RGB);
viewer.setDescription('');
viewer.loadSettingsFromURL();
viewer.loadGUI();
let cp = new Cesium.Cartesian3(4303414.154026048, 552161.235598733, 4660771.704035539);
cviewer.camera.setView({
destination : cp,
orientation: {
heading : 10,
pitch : -Cesium.Math.PI_OVER_TWO * 0.5,
roll : 0.0
});
Call Cesium render function inside Potree render function
render(){
cviewer.render();
…..
}
I modified initThree() function remove line that add potree’s canvas in potree render area
// this.renderArea.appendChild(this.renderer.domElement);
and add cesium canvas in Three.WebGl Render
this.renderer = new THREE.WebGLRenderer({alpha : true,preserveDrawingBuffer: true , canvas : cviewer.canvas});
And also added the following lines as I see this on https://github.com/AnalyticalGraphicsInc/cesium/issues/648
var resetFunc = this.renderer.state.reset;
this.renderer.state.reset = function(){};
this.renderer.resetGLState();
this.renderer.state.reset = resetFunc;
I remove all events of Cesium except rotate because I want potree’s events only. And to stop collusion of some of the same events from both sides.
cviewer.scene.screenSpaceCameraController.enableTranslate = false;
cviewer.scene.screenSpaceCameraController.enableZoom = false;
cviewer.scene.screenSpaceCameraController.enableTilt = false;
cviewer.scene.screenSpaceCameraController.enableLook = false;
Identified pointdown event handler of Cesium from debugger and remove it. Because it stops orbit controls in potree.
function p(e, t, i, r) {
// function n(t) {
// r(e, t)
// }
i.addEventListener(t, n, !1),
e._removalFunctions.push(function() {
i.removeEventListener(t, n, !1)
})
}

How to clear out rotation of loaded model

I have a model, which is displayed in Three.js correctly. Top at the top, bottom at the bottom. However, model has a preset rotation of -1.57 on X axis. It means If I add any new object to the scene, axis of object will be not the same as the model axis. How can clear out or reset this preset rotation so the axis of model and axis of world will match and top will be still at the top? I hope I explained myself clear. Thank you.
How about to rotate yours model once by 1.57, "burn" this orientation back to the vertices of the model then saving it to new file.
// reset mesh rotation
mesh.rotation.y = 1.57;
// make current oreintation, the base of the model
applyMeshTransformation(mesh);
// export the model to new blob file (can saved from this to new file)
exportObject(mesh)
function applyMeshTransformation(mesh) {
// apply local matrix on geometry
mesh.updateMatrixWorld();
mesh.geometry.applyMatrix(mesh.matrixWorld);
// reset local matrix
mesh.position.set(0,0,0);
mesh.rotation.set(0,0,0);
mesh.scale.set(1,1,1);
mesh.updateMatrixWorld();
};
function exportObject(mesh) {
var objExporter = new THREE.ObjectExporter();
var output = JSON.stringify( objExporter.parse( mesh ), null, '\t' );
output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
var blob = new Blob( [ output ], { type: 'text/plain' } );
var objectURL = window.URL.createObjectURL( blob );
window.open( objectURL, '_blank' );
};

Resources