css-scaled google maps click incorrect coordinates

前端 未结 3 1971
一生所求
一生所求 2021-01-28 11:11

I have a Google Maps map inserted in a css-scaled container. Due to project specifics this cannot be avoided. I need to track clicks coords on this map, but being scaled map set

相关标签:
3条回答
  • 2021-01-28 11:20

    Ok, figured out how to correct fix (this is when transformation center is 0,0)

    function point2LatLng(point, transformScale, map) {
        var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
        var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());
        var scale = Math.pow(2, map.getZoom());
        var worldPoint = new google.maps.Point(point.x / transformScale / scale + bottomLeft.x, point.y / transformScale / scale + topRight.y);
        return map.getProjection().fromPointToLatLng(worldPoint);
      }
    
    gmaps.event.addListener(this.map, 'click', (event)=> {
              let transformMatrix = window.getComputedStyle(this.$el.closest('.container')).transform.match(/^matrix\((.+)\)$/)[1].split(', ');
              let transformScale = parseFloat(transformMatrix[0]);
              var marker = new gmaps.Marker({
                  position: point2LatLng(event.pixel, transformScale, this.map),
                  map: this.map
              });
            });
    
    0 讨论(0)
  • 2021-01-28 11:20

    This answer works, but being scaled map works very bad, many coordinate-related functions don't wok correctly. But there is a workaround: place the map in a virtual iframe:

        const iframe = this.$el.querySelector('iframe');
        iframe.contentWindow.document.open();
        iframe.contentWindow.document.write('<div id="map" style="width: 100%; height: 100%"></div>');
        iframe.contentWindow.document.close();
    
        const mapContainer = iframe.contentWindow.document.querySelector('#map');
        const map = new gmaps.Map(mapContainer, {
                  center: {lat: 48.7, lng: 31},
                  zoom: 6
                });
    

    There are no x-origin restrictions and you can manipulate with iframe content how you want. And with it, even if parent container is scaled, everything works fine

    0 讨论(0)
  • 2021-01-28 11:32

    I also had this issue and the above solutions didn't work for me because:

    • @Terion's "point2LatLng" function didn't seem to place the marker in the correct location
    • @Terion's use of a virtual iframe meant that you can't drag the map, which severely restricted the user experience.

    However I did find a way to do it: I put the map div inside a container which I effectively un-scaled with this JS, loaded after all other JS:

    //Function: Unscale the map Container
    function unscaleMap(scale){
        var unscale = Math.round(10000/(scale * 1))/10000,
            rescale = Math.round(10000 * (100 / unscale))/10000;
        document.getElementById("fs_mapContainer").style.transform = "scale("+unscale+")";
        document.getElementById("fs_mapContainer").style.width = rescale + "%";
        document.getElementById("fs_mapContainer").style.height = 80 * scale + "vh";
    }
    

    And CSS:

    .map_container {position: relative; transform-origin: 0 0; box-sizing: border-box;}
    #map {width: 100%; height: 100%}
    
    0 讨论(0)
提交回复
热议问题