-
Notifications
You must be signed in to change notification settings - Fork 148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refresh of map after map style change #35
Comments
Hi @ShaneTex, do you have a repro of this issue? I am working on v.2.0.5. adding an example on change style and it works perfectly |
@jscastro76 This is what I have: If I select one of my change style buttons up in the upper right corner, and I use the normal on style.load, I get 2 versions of the same models, if I add a check to see if it was loaded, then the original don't render. Here is one that doesn't work: Here is one that works by adding a small 3d graphic and then render, but I don't thing it is good practice: |
Hi @ShaneTex , Just copy and paste this full HTML+js on your threebox /examples cloned folder. This code is using Threebox v.2.0.4. <!doctype html>
<html>
<head>
<title>Change style map for Eiffel Tower</title>
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet" />
<script src="../dist/threebox.js" type="text/javascript"></script>
<link href="./css/threebox.css" rel="stylesheet" />
<script src="config.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
html, body, #map {
height: 100%;
}
#menu {
position: absolute;
background: #fff;
padding: 10px;
font-family: 'Open Sans', sans-serif;
}
</style>
</head>
<body>
<div id='map' class='map'></div>
<div id="menu">
<input id="streets-v11" type="radio" name="rtoggle" value="streets" checked="checked" />
<label for="streets-v11">streets</label>
<input id="light-v10" type="radio" name="rtoggle" value="light" />
<label for="light-v10">light</label>
<input id="dark-v10" type="radio" name="rtoggle" value="dark" />
<label for="dark-v10">dark</label>
<input id="outdoors-v11" type="radio" name="rtoggle" value="outdoors" />
<label for="outdoors-v11">outdoors</label>
<input id="satellite-v9" type="radio" name="rtoggle" value="outdoors" />
<label for="satellite-v9">satellite</label>
</div>
<script>
// This example downloads a tower model from an external OBJ/MTL file, adds it to the map, and drives it around via paths fetched from the Mapbox Directions API
if (!config) console.error("Config not set! Make a copy of 'config_template.js', add in your access token, and save the file as 'config.js'.");
mapboxgl.accessToken = config.accessToken;
let mapConfig = {
PAR: { origin: [2.294514, 48.857475, 0], center: [2.294625, 48.861085, 0], zoom: 15.95, pitch: 60, bearing: 0, scale: 0.01029, timezone: 'Europe/Paris' },
names: {
customLayer: "custom-layer"
}
}
let map = window.map = new mapboxgl.Map({
container: 'map',
zoom: mapConfig.PAR.zoom,
pitch: mapConfig.PAR.pitch,
bearing: mapConfig.PAR.bearing,
center: mapConfig.PAR.center,
style: 'mapbox://styles/mapbox/streets-v11',
hash: true
});
window.tb = new Threebox(
map,
map.getCanvas().getContext('webgl'),
{
defaultLights: true
}
);
let layerId = "streets-v11";
function switchLayer(layer) {
if (layerId != layer.target.id) {
layerId = layer.target.id;
map.setStyle('mapbox://styles/mapbox/' + layerId);
}
}
let styleList = document.getElementById('menu');
let inputs = styleList.getElementsByTagName('input');
for (let i = 0; i < inputs.length; i++) {
inputs[i].onclick = switchLayer;
}
map.on('style.load', () => {
map.addLayer({
id: mapConfig.names.customLayer,
type: 'custom',
renderingMode: '3d',
onAdd: function (map, mbxContext) {
options = {
obj: './models/eiffel.glb',
type: 'gltf',
scale: mapConfig.PAR.scale,
units: 'meters',
//adjustment: { x: -0.5, y: -0.5, z: 0 } // model center is displaced
}
tb.loadObj(options, function (model) {
model.setCoords(mapConfig.PAR.origin);
model.setRotation({ x: 0, y: 0, z: 45.7 });
model.addTooltip("Eiffel Tower", true);
model.castShadow = true;
tb.add(model);
})
},
render: function (gl, matrix) {
tb.update();
}
});
});
</script>
</body>
</html>
|
@ShaneTex the mistake is in your code with the variable |
@jscastro76 Yes, I added that styleLoaded because it was duplicating all the models, if you look at those green drone coins, you see now that they are duplicated, or double what they were to start with. |
@jscastro76 Ok, I just added this to your example: enableSelectingFeatures: true, //change this to false to disable fill-extrusion features selection Then after I switch style, then drag the eiffel tower, I have 2 now. |
Let me check that out! |
sounds good |
@ShaneTex, good news, I got it! As said, once So there are not too many changes needed, and I have already implemented this bug for v.2.0.5 within a new method function clear () {
tb.world.traverse(function (obj) {
tb.remove(obj);
});
} You have to call it after the |
@jscastro76 Ok, I try that and it tells me this: mckinneyevents.html:633 Uncaught TypeError: Cannot read property 'traverse' of undefined, i tried chaning this to tb. as well and get the same errir. |
Sorry, there was a mistake in my answer it’s |
Here is the full test page, comment or uncomment line with the <!doctype html>
<html>
<head>
<title>Change style map for Eiffel Tower</title>
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet" />
<script src="../dist/threebox.js" type="text/javascript"></script>
<link href="./css/threebox.css" rel="stylesheet" />
<script src="config.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
html, body, #map {
height: 100%;
}
#menu {
position: absolute;
background: #fff;
padding: 10px;
font-family: 'Open Sans', sans-serif;
}
</style>
</head>
<body>
<div id='map' class='map'></div>
<div id="menu">
<input id="streets-v11" type="radio" name="rtoggle" value="streets" checked="checked" />
<label for="streets-v11">streets</label>
<input id="light-v10" type="radio" name="rtoggle" value="light" />
<label for="light-v10">light</label>
<input id="dark-v10" type="radio" name="rtoggle" value="dark" />
<label for="dark-v10">dark</label>
<input id="outdoors-v11" type="radio" name="rtoggle" value="outdoors" />
<label for="outdoors-v11">outdoors</label>
<input id="satellite-v9" type="radio" name="rtoggle" value="outdoors" />
<label for="satellite-v9">satellite</label>
</div>
<script>
// This example downloads a tower model from an external OBJ/MTL file, adds it to the map, and drives it around via paths fetched from the Mapbox Directions API
if (!config) console.error("Config not set! Make a copy of 'config_template.js', add in your access token, and save the file as 'config.js'.");
mapboxgl.accessToken = config.accessToken;
let mapConfig = {
PAR: { origin: [2.294514, 48.857475, 0], center: [2.294625, 48.861085, 0], zoom: 15.95, pitch: 60, bearing: 0, scale: 0.01029, timezone: 'Europe/Paris' },
names: {
customLayer: "custom-layer"
}
}
let map = window.map = new mapboxgl.Map({
container: 'map',
zoom: mapConfig.PAR.zoom,
pitch: mapConfig.PAR.pitch,
bearing: mapConfig.PAR.bearing,
center: mapConfig.PAR.center,
style: 'mapbox://styles/mapbox/streets-v11',
hash: true
});
window.tb = new Threebox(
map,
map.getCanvas().getContext('webgl'),
{
defaultLights: true,
enableSelectingObjects: true,
enableDraggingObjects: true
}
);
let layerId = "streets-v11";
function switchLayer(layer) {
if (layerId != layer.target.id) {
layerId = layer.target.id;
map.setStyle('mapbox://styles/mapbox/' + layerId);
clear(); // comment this so see the effect
}
}
function clear () {
tb.world.traverse(function (obj) {
tb.remove(obj);
});
}
let styleList = document.getElementById('menu');
let inputs = styleList.getElementsByTagName('input');
for (let i = 0; i < inputs.length; i++) {
inputs[i].onclick = switchLayer;
}
map.on('style.load', () => {
map.addLayer({
id: mapConfig.names.customLayer,
type: 'custom',
renderingMode: '3d',
onAdd: function (map, mbxContext) {
options = {
obj: './models/eiffel.glb',
type: 'gltf',
scale: mapConfig.PAR.scale,
units: 'meters',
//adjustment: { x: -0.5, y: -0.5, z: 0 } // model center is displaced
}
tb.loadObj(options, function (model) {
model.setCoords(mapConfig.PAR.origin);
model.setRotation({ x: 0, y: 0, z: 45.7 });
model.addTooltip("Eiffel Tower", true);
model.castShadow = true;
tb.add(model);
})
},
render: function (gl, matrix) {
tb.update();
}
});
});
</script>
</body>
</html> |
@jscastro76 It is interesting, I made those changes, and it still does that or I get the same error. |
Ok, let me try to finish the rest of the release changes and I'll try to push the commit asap |
If I change the map.setStyle using standard mapbox tools, I loose all objects that have been added to the map. Is there a way to refresh via tb.update(); on a reload of the page after a setStyle. The only way I could get it to work was add a simple feature within style.load and then do the tb.update() within the render property. Then I get all my previous custom objects back on the map.
Is there a way to use the tb.update() outside of render on the style.load by it self.
The text was updated successfully, but these errors were encountered: