Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Elevation measure widget #1881

Closed
wants to merge 6 commits into from
Closed

Elevation measure widget #1881

wants to merge 6 commits into from

Conversation

jailln
Copy link
Contributor

@jailln jailln commented Aug 9, 2022

Description

Add a widget to measure elevation anywhere in the 3D scene. Also contains a few modifications of the API (Picking and View).

I will write tests and squash commits once we agree on the implementation :) (i.e. after a first review)

Note that I opened a PR on itowns2-sample-data for the assets related to this widget (sprite, logo and dataset for the example).

Motivation and Context

Implementation of the first tool described in #1868

Screenshots (if appropriate)

Mesure elevation on the terrain:

image

Mesure elevation on any 3D object:
image

@mgermerie
Copy link
Contributor

There is an issue with the Elevation widget : if you use it while zoomed out, the elevation is not red on the most detailed tile (since it is not necessarily loaded yet). The value will therefore differ on the same point, whether you use the widget while zoomed out or zoomed in at maximum.

@jailln jailln force-pushed the feat/elevation-measure branch from 03be1e9 to 6d1178d Compare October 24, 2022 12:54
@jailln jailln added wip 🚧 Still being worked on feature 🍏 Adds a new feature widget labels Oct 26, 2022
*/
pickCoordinates(mouse, target = new Coordinates(this.tileLayer.extent.crs)) {
pickTerrainCoordinates(mouse, target = new Coordinates(this.referenceCrs)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renaming this method introduces a breaking change. Could you still define pickCoordinates with a deprecation warning and a calling to the new method ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep and I will also add a breaking change in the commit message.

src/Core/View.js Outdated
coordinates.crs = this.referenceCrs;
coordinates.setFromVector3(positionVector);
coordinates.as(target.crs, target);
target.setFromVector3(positionVector);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to leave the transformation here, since use should be able to call the method with any target coordinate. We can't assume the CRS of target. For example if I type :

const coordinates = new itowns.Coordinates('EPSG:4326');
view.pickTerrainCoordinates({ /* some mouse position */ }, coordinates);

it will return some coordinates with an EPSG:4326 CRS but whose x, y and z values are intended as EPSG:4978, so most probably not the coordinates under the mouse position.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep you're right, I got mixed up :)

*/
pickCoordinates(mouse, target = new Coordinates(this.tileLayer.extent.crs)) {
pickTerrainCoordinates(mouse, target = new Coordinates(this.referenceCrs)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can indeed change the default target CRS with the view's reference CRS, as it seems more logical.
However we should keep these two following points in mind :

  • this introduces a breaking change for some users (who for example feed the default output of this method to other processes without transforming it).
  • In a PlanarView context, I believe that view.referenceCrs and view.tileLayer.extent.crs are always the same. Having the default output CRS to view.tileLayer.extent.crs allows to output coordinates in longitude, latitude and altitude, whose representation is more easy to understand than coordinates in EPSG:4978.

Therefore, do you still think we should change it ? In any case, could you please add the previously missing documentation on the default output CRS ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think yes because it is clearer for users since in my opinion users don't really know the crs of the extent of the tileLayer which is quite internal to itowns, they should expect to get coordinates in the view CRS which they actually know of. You're right that it is a breaking change, I will add one.

* @param {number|Array<number>|Coordinates|THREE.Vector3} [v0=0] -
* x or longitude value, or a more complex one: it can be an array of three
* numbers, being x/lon, x/lat, z/alt, or it can be `THREE.Vector3`. It can
* also simply be a Coordinates.
* @param {number} [v1=0] - y or latitude value.
* @param {number} [v2=0] - z or altitude value.
*/
constructor(crs, v0 = 0, v1 = 0, v2 = 0) {
constructor(crs = 'EPSG:4978', v0 = 0, v1 = 0, v2 = 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation is a good addition, thanks !
On another hand, I don't think we should assume a default CRS for coordinates. No coordinates make sense without a CRS and in my opinion, user should always have to specify the CRS associated with the coordinates values he is dealing with.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I agree with you, I will remove the default CRS.

* Sets the Coordinate Reference System.
* @param {String} crs Coordinate Reference System (e.g. 'EPSG:4978')
*/
setCrs(crs) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea to add this check of parameter validity !

@@ -187,9 +188,16 @@ export default {
// if baseId matches objId, the clicked point belongs to `o`
for (let i = 0; i < candidates.length; i++) {
if (candidates[i].objId == o.baseId) {
// Compute distance to the camera
const pointCoordinate = new Coordinates(view.referenceCrs, o.position.x, o.position.y, o.position.z);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this method for computing distance could cause issues : the position property for threejs Object3D is expressed in the object's parent coordinates system.
Here, the point could be centered within a Group, and the Group could be positioned at the correct world coordinates. the position of the point would therefore be (0, 0, 0). Using world position for the point, as you did for the camera would prevent this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, do you know of an usage of this picking method other than with PointCloudLayer ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right, I added the world transformation and updated a bit this part to fix a bug that I had not seen for point cloud picking.

@jailln jailln force-pushed the feat/elevation-measure branch 4 times, most recently from d79c41b to 86ac17f Compare January 19, 2023 14:50
@jailln
Copy link
Contributor Author

jailln commented Jan 19, 2023

@mgermerie I made the modifications you recommended, squashed and rebased.

@jailln jailln force-pushed the feat/elevation-measure branch from 3cf694e to 86ac17f Compare January 20, 2023 08:59
@jailln
Copy link
Contributor Author

jailln commented Jan 20, 2023

Some functional tests don't pass (timeout), while they pass locally. I tried to update a few things but it didn't change anything. Any ideas @mgermerie @gchoqueux ?

@jailln jailln force-pushed the feat/elevation-measure branch from 86ac17f to 8543d2a Compare February 2, 2023 14:12
BREAKING CHANGE: View.pickCoordinates has been renamed to View.pickTerrainCoordinates and returns the coordinates in the referenceCrs of the view instead of in the crs of the tiledLayer extent.
@jailln jailln force-pushed the feat/elevation-measure branch from 8543d2a to 11cdf5f Compare February 2, 2023 14:42
@jailln jailln mentioned this pull request Feb 2, 2023
@jailln jailln force-pushed the feat/elevation-measure branch from 11cdf5f to 5595e57 Compare February 3, 2023 10:15
@jailln jailln force-pushed the feat/elevation-measure branch from 5595e57 to 2dada14 Compare February 7, 2023 17:41
@jailln jailln marked this pull request as draft February 13, 2023 09:25
@jailln
Copy link
Contributor Author

jailln commented Oct 4, 2024

I won't have time to finish this feature in the short term, closing for now.

@jailln jailln closed this Oct 4, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
feature 🍏 Adds a new feature widget wip 🚧 Still being worked on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants