Skip to content
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

How to create a marker with altitude #84

Closed
John2397 opened this issue Nov 12, 2020 · 11 comments
Closed

How to create a marker with altitude #84

John2397 opened this issue Nov 12, 2020 · 11 comments
Assignees
Labels
❓ question Further information is requested 🥇 good first issue Good for newcomers
Milestone

Comments

@John2397
Copy link

Hello @jscastro76

As we know, mapbox gl js doesn't allow to add altitude on our markers.
I would like to be able to place a marker in 3d space, but not attached to any 3d object. Just the marker.

I've seen your post here that explains how to add a tooltip with altitude and also found the part on your code that creates the tooltip.

However, I'm having difficulty to understand how I can create my own marker with altitude (which is similar with tooltip).

This is my attempt (based on your code)

let divToolTip;
let divContent = document.createElement('div');
divContent.className = 'mapboxgl-popup-content';
divContent.style.width = "fit-content";
let strong = document.createElement('strong');
strong.innerHTML = "TEST TOOLTIP";
divContent.appendChild(strong);
let tip = document.createElement('div');
tip.className = 'mapboxgl-popup-tip';
let div = document.createElement('div');
div.className = 'marker mapboxgl-popup-anchor-bottom';
div.appendChild(tip);
div.appendChild(divContent);
divToolTip = document.createElement('div');
divToolTip.className += 'label3D';
divToolTip.appendChild(div);

let test_tooltip = new THREE.CSS2DObject(divToolTip);

Even if the above is correct, how do I set the location for test_tooltip? On your code you use setPosition to set a xyz position
but I guess this is about the relevant position in reference to the object.

Thank you.

@jscastro76 jscastro76 added the ❓ question Further information is requested label Nov 12, 2020
@jscastro76
Copy link
Owner

Hi @John2397
When I posted that in Mapbox github, it's because I had created here my own object to manage them, tb.label. You can create an always visible label as simple as this...

var origin = [-122.47920912, 37.716351775, 30]; //30 meters altitude
...
...

label = tb.label(obj = {
	position: origin,
	htmlElement: createLabel(), //here you create the div element
	cssClass: " label3D",
	alwaysVisible: true,
	bottomMargin: 0,
	feature: null
});
label.setCoords(origin); //here you set position including altitude
tb.add(label);

It should look like this
image

Here is the full code:

<!doctype html>
<head>
	<title>Label using altitude</title>
	<script src="config.js"></script>
	<script src="/Scripts/mapbox-gl.js"></script>
	<link href="/Scripts/mapbox-gl.css" rel="stylesheet" />
	<script src="/Scripts/threebox.js"></script>
	<link href="/Styles/threebox.css" rel="stylesheet" />

	<style>
		body, html {
			width: 100%;
			height: 100%;
			margin: 0;
			background: black;
		}

		#map {
			width: 100%;
			height: 100%;
		}

	</style>
</head>
<body>
	<div id='map' class='map' />

	<script>
		var config = {
			accessToken: 'your token here'
		};

		// This example downloads a soldier 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;

		var origin = [-122.47920912, 37.716351775, 30];
		var label;

		var map = new mapboxgl.Map({
			container: 'map',
			style: 'mapbox://styles/mapbox/outdoors-v11',
			center: origin,
			zoom: 18,
			pitch: 60,
			bearing: 0
		});
		map.on('style.load', function () {

			map
				.addLayer({
					id: 'custom_layer',
					type: 'custom',
					renderingMode: '3d',
					onAdd: function (map, mbxContext) {

						window.tb = new Threebox(
							map,
							mbxContext,
							{ defaultLights: true }
						);

						label = tb.label(obj = {
							position: origin,
							htmlElement: createLabel(),
							cssClass: " label3D",
							alwaysVisible: true,
							bottomMargin: 0,
							feature: null
						});

						label.setCoords(origin);
						tb.add(label);

					},

					render: function (gl, matrix) {
						tb.update();
					}
				});
		});

		function createLabel() {
			let divToolTip;
			let divContent = document.createElement('div');
			divContent.className = 'mapboxgl-popup-content';
			divContent.style.width = "fit-content";
			let strong = document.createElement('strong');
			strong.innerHTML = "TEST TOOLTIP";
			divContent.appendChild(strong);
			let tip = document.createElement('div');
			tip.className = 'mapboxgl-popup-tip';
			let div = document.createElement('div');
			div.className = 'marker mapboxgl-popup-anchor-bottom';
			div.appendChild(tip);
			div.appendChild(divContent);
			divToolTip = document.createElement('div');
			divToolTip.className += 'label3D';
			divToolTip.appendChild(div);
			return divToolTip;
		}

	</script>
</body>

@John2397
Copy link
Author

Thank you a lot, I appreciate it.

Basically my goal is to let the user place a marker on 3d space.

So ideally, the way I think of it is to let the user click somewhere on the map to set the position on xy plane at first (like it is now), and then let them know they have to set the altitude of the marker by dragging it up or down.

Would that kind of thing be possible? I noticed that the drag/select/unselect features are not available for the 3d label.

@jscastro76
Copy link
Owner

So far, dragging is only avaliable for lng lat movements (mouse + SHIFT) and rotate over anchor (mouse + ALT), not for altitude, but it would be possible using another key (CTRL would be the best but it's used by mapbox), but it wouldn't be very hard to implement it now. I can open an new feature request with this to implement it whenever I have time enough. It all depends if you need it immediately or not, if so, I would you recommend to fork and try it by yourself.

@jscastro76
Copy link
Owner

@John2397 The marker itself is an HTML object positioned in a concrete coords set, but it's not captured by the mapbox or threejs raycast, so it won't respond to drag actions through Threebox. What I'm already implementing is indeed the option to drag 3D objects on altitude, but as said, it won't affect to labels.

@John2397
Copy link
Author

Then I guess I will try to create a marker-shaped 3d object ( a custom mesh maybe?) to get the drag actions working.

Thank you a lot for your help!

@jscastro76
Copy link
Owner

@John2397 I´m about to deliver #89 in the next coming days, so yes, I think the best option is to create a 3D marker object that you´ll be able to drag freely instead of a label which HTML and not selectable by the raycast

@John2397
Copy link
Author

Nice! Thank you, I'll wait for it

@jscastro76 jscastro76 self-assigned this Nov 18, 2020
@jscastro76 jscastro76 added this to the v2.0.9. milestone Nov 18, 2020
@jscastro76
Copy link
Owner

jscastro76 commented Nov 18, 2020

Hi @John2397
Check this out...
dragging

I have also added something I was thinking about while ago, a tooltip that shows the different actions coords, angles and altitude in real time when you drag the object. I think it´s now much better, thanks for the question that drove me to develop this feature.

@jscastro76 jscastro76 added the 🥇 good first issue Good for newcomers label Nov 18, 2020
@John2397
Copy link
Author

This is great! And the tooltip is pretty useful, indeed. Thank you for your work :)

@jscastro76
Copy link
Owner

I´m preparing the upload, in about an hour, it´ll be ready

@jscastro76
Copy link
Owner

Hi @John2397
This is updated in v2.0.9. and also in npm package

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
❓ question Further information is requested 🥇 good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants