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

Mercator. Getting boundary values by longitude #273

Closed
dowhileforeach opened this issue Dec 28, 2022 · 2 comments
Closed

Mercator. Getting boundary values by longitude #273

dowhileforeach opened this issue Dec 28, 2022 · 2 comments

Comments

@dowhileforeach
Copy link

I use d3-geo 3.1.0

Without rotation (everything works well)

angle0

const geoToProj = geoMercator().rotate([0, 0, 0]);

console.log('[-180,0] ->', geoToProj([-180,0]));
console.log('[180,0] ->', geoToProj([180,0]));

output:

[-180,0] -> [-0.5, 250]
[180,0] -> [960.5, 250]

it seems there are no problems here, the only thing is not clear why -0.5 and 960.5, and not 0 and 960...

Rotate, lambda -10 (unexpected behavior)

angle-10

const geoToProj = geoMercator().rotate([-10, 0, 0]);

console.log('[-170,0] ->', geoToProj([-170,0]));
console.log('[190,0] ->', geoToProj([190,0]));

const roundD3Bound = (n) => n - 0.0000000000001;
console.log('[190 rounded,0] ->', geoToProj([roundD3Bound(190),0]));

output:

[-170,0] -> [-0.5, 250]
[190,0] -> [-0.49999999999994316, 250]
[190 rounded,0] -> [960.4999999999998, 250]

I rotated the projection to lambda -10 degrees.
Accordingly, I expect the longitude boundaries to be -170 and 190.
As a result, the geographic point [-170,0] on the projection [-0.5, 250]
matches the geographical point [190,0] on the projection [-0.49999999999994316, 250].

And only such a geographical point [189.9999999999999, 0] on the projection will be where it is expected [960.4999999999998, 250].

Check it. Stackblitz

Question

Is there a method to get the longitude boundary values for the projection?
That is, for example, for projection geoMercator().rotate([-10, 0, 0])
I call the method "give boundary values for longitude" and it returns to me left=-170, right=189.9999999999999?

@mbostock
Copy link
Member

You can’t rely on [190,0] being distinct from [-170, 0]; they represent the same point on the sphere. Same with [-180, 0] and [180, 0]; it’s somewhat coincidental that it works in this case due to floating point. If you want to compute the bounds of something, use path.bounds, say with {type: "Sphere"} for the entire globe.

@dowhileforeach
Copy link
Author

Mike, thank you for the hint about using path.bounds.
As a result, the boundary values of the mercator, expressed in geographical coordinates, now I get this way:

function mercatorGeoBounds(lambda: number) {
  const geoToProj = geoMercator().rotate([lambda, 0, 0]);
  const projToGeo = geoToProj.invert;
  const [leftTopBoundPointOnProj, rightBottomBoundPointOnProj] = geoPath().projection(geoToProj).bounds({type: 'Sphere'});
  const leftTopBoundPoint = projToGeo(leftTopBoundPointOnProj);
  const rightBottomBoundPoint = projToGeo(rightBottomBoundPointOnProj);

  const [lonLeft, latTop] = leftTopBoundPoint;
  return {
    lonLeft,
    lonRight: (lonLeft + 360) - 0.000000000001,
    latTop,
    latBottom: rightBottomBoundPoint[1],
  };
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants