googlemaps / js-samples

Samples for the Google Maps JavaScript v3 API
https://developers.google.com/maps/documentation/javascript/
Other
743 stars 823 forks source link

feat: update 'samples/overlay-hideshow' to account for tilt (v=beta) #929

Open dudiw opened 2 years ago

dudiw commented 2 years ago

I noticed that the google.maps.OverlayView in 'overlay-hideshow' sample gets distorted when the map is tilted (beta feature).

See example (hold shift and drag with the mouse to tilt and rotate the map) https://jsfiddle.net/jq5f0zsk/1/

The issue becomes apparent when the tilt > 0 image

Is there a way to configure the OverlayView to remain "flat"? Alternatively, perhaps the 'div' can be transformed (3d rotation) to compensate for the tilt and rotation of the camera?

Thank you!

jpoehnelt commented 2 years ago

Alternatively, perhaps the 'div' can be transformed (3d rotation) to compensate for the tilt and rotation of the camera?

This is probably the fix. I'll see about updating the sample to account for this.

https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d()

dudiw commented 2 years ago

@jpoehnelt Awesome! It's a bit tricky since the tilt and heading of google.maps.Map are in the camera's reference frame, whereas the div rotation(3d) is in the image's reference frame.

Thank you for looking into this!

jpoehnelt commented 2 years ago

No guarantees. It's been way too long since I took linear algebra and graphics courses!

jpoehnelt commented 2 years ago

Some of the utils in deckgl might be useful?? https://github.com/visgl/deck.gl/blob/master/modules/google-maps/src/utils.js

dudiw commented 2 years ago

Thank you @jpoehnelt for the effort!

I also found this old overlay-tiler repo that demonstrates how to transform an overlay (including planar rotation). From overlay.js line 156:

var proj = this.getProjection(); // google.maps.Map.getProjection()

/* properties topLeft, topRight, bottomRight initialized in setInitialGCP_() line 110 */
var tl = proj.fromLatLngToDivPixel(this.get('topLeft'));
var tr = proj.fromLatLngToDivPixel(this.get('topRight'));
var br = proj.fromLatLngToDivPixel(this.get('bottomRight'));
img.style.transform =  'matrix(' + [tr.x - tl.x, tr.y - tl.y, br.x - tr.x, br.y - tr.y, tl.x, tl.y] + ')';

Regarding deckgl utils.js, the method getViewPropsFromCoordinateTransformer (line 174) might contain some hints on GoogleMaps projection matrix.

Not sure if this helps - I'll keep searching

regeter commented 2 years ago

This can be served well by using Deck.gl with Bitmap Layer: https://jsfiddle.net/regeter/j0fuqzpc/90/

dudiw commented 2 years ago

This can be served well by using Deck.gl with Bitmap Layer: https://jsfiddle.net/regeter/j0fuqzpc/90/

Excellent @regeter ! Thank you so much!