Google map API image overlay in vector map with tilt and heading

417 Views Asked by At

I place the image on the map using custom overlay example in https://developers.google.com/maps/documentation/javascript/customoverlays

but when i rotate the map, overlay deforms. Is it possible to fix it?

enter image description here

I understand that this is happening because in the draw method processing is carried out at two points - SouthWest and NorthEast.

draw() {
  // We use the south-west and north-east
  // coordinates of the overlay to peg it to the correct position and size.
  // To do this, we need to retrieve the projection from the overlay.
  const overlayProjection = this.getProjection();
  // Retrieve the south-west and north-east coordinates of this overlay
  // in LatLngs and convert them to pixel coordinates.
  // We'll use these coordinates to resize the div.

  const sw = overlayProjection.fromLatLngToDivPixel(
    this.bounds.getSouthWest()
  );
  const ne = overlayProjection.fromLatLngToDivPixel(
    this.bounds.getNorthEast()
  );

  // Resize the image's div to fit the indicated dimensions.
  if (this.div) {
    this.div.style.left = sw.x + "px";
    this.div.style.top = ne.y + "px";
    this.div.style.width = ne.x - sw.x + "px";
    this.div.style.height = sw.y - ne.y + "px";
    this.div.style.transform = 'rotate(' + this.angle + 'deg)';
  }

Because of this, the image is deformed. But I don't know how to set four vertices for an image.

1

There are 1 best solutions below

0
On

i solved it using WebGLOverlayView https://developers.google.com/maps/documentation/javascript/webgl/webgl-overlay-view

    const webGLOverlayView = new google.maps.WebGLOverlayView();

    webGLOverlayView.onAdd = () => {

        scene = new THREE.Scene();

        const fov = 180;
        const aspect = 2;  // the canvas default
        const near = 1;
        const far = 1;

        camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

        const width = 800;
        const height = 400;
        const widthSegments = 800;
        const heightSegments = 400;

        const geometry = new THREE.PlaneBufferGeometry(width, height, widthSegments, heightSegments)
        const loader = new THREE.TextureLoader();
        const texture = loader.load('img920C.jpg');

        texture.magFilter = THREE.NearestFilter
        texture.minFilter = THREE.NearestMipMapNearestFilter
        texture.anisotropy = 16

        var material = new THREE.MeshBasicMaterial( { map: texture, } );
        var cube = new THREE.Mesh( geometry, material );
        cube.name = 'cube';

        scene.add( cube );

    }
    webGLOverlayView.onContextRestored = ({gl}) => {

        renderer = new THREE.WebGLRenderer({
          canvas: gl.canvas,
          context: gl,
          antialias: false,
          ...gl.getContextAttributes(),
        });

        renderer.autoClear = false;
        renderer.antialias = false;
        const controls = new THREE.OrbitControls(camera, renderer.domElement);

    };

    webGLOverlayView.onDraw = ({gl, transformer}) => {
        const latLngAltitudeLiteral = {
        lat: marker.getPosition().lat,
        lng: marker.getPosition().lng,
        altitude: 0
        }

        const matrix = transformer.fromLatLngAltitude(latLngAltitudeLiteral);
        camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);

        webGLOverlayView.requestRedraw();

        renderer.render(scene, camera);
        renderer.resetState();
    }
    webGLOverlayView.setMap(map)

}

It looks like this is the correct approach. But what about mouse events, I don't know. I would like to receive a mousedown click event? for webGLOverlayView. Something similar to:

webGLOverlayView.addListener('click', function(){console.log("ok")});