fromLatLngToDivPixel在不同的viewBox比例尺上没有给出相同的坐标

时间:2018-10-12 15:10:13

标签: google-maps svg polygon

我在谷歌地图的OverlayView类中使用了具有定义和恒定边界的SVG,并且我的目的是在单击地图上的某个位置时(如果单击的位置在此边界内)绘制相应的区域边界。我决定不使用google的默认路径选项来绘制多边形,而是决定使用SVG路径元素。为了避免使用多个SVG元素,我想在一个SVG上使用多个路径元素(用于区域的多边形)。 为此,考虑到用户将更改缩放级别以适应任何缩放级别,我采用了viewBox属性以根据地图的缩放级别进行缩放。因此,主要思想是,当更改地图的缩放级别时,单个SVG标签内的所有路径元素也会根据需要分别对齐。 尽管一切似乎都正常,但单击不同的缩放级别时,相同的边界之间仍存在细微差异。我无法解决问题所在。

我的代码如下:

如果能帮助我指出此代码中的错误之处,我将不胜感激。

谢谢。

注意:要了解该问题并查看实际存在的问题,可以查看我的网站。由于尚未定义所有地标,因此在屏幕中间某处,某处建筑物和绿地中间都可以单击并查看问题,方法是在平移和缩放后单击同一区域,然后看到边界不重叠。但首先,您必须先单击底部的“获取信息”菜单栏,该菜单栏将模式设置为地图上的区域选择。 网址:https://www.mikkins.com/landplot/11.php

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<div class="menu">
    <div class="title">MENU</div>
    <div class="wrapper"><div class="button">Get Info</div></div>
    <ul class="nav">
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Work</a></li>
      <li><a href="#">Resources</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
</div>
<div class="intro" id="GMAP"></div>
<svg id="svg1"  xmlns="http://www.w3.org/2000/svg">
</svg>
<script>
    var overlay;
    var polygonReturn=new Array();
    var polygonBounds=new Array();
    var _svgOW;

 function initGMap()
          {                                  
            var mapOptions={ center: {lat:40.88227, lng:29.251796} ,
                                        zoom: 16     ,
                                        mapTypeId:'satellite',
                                        disableDefaultUI: false,
                                        draggableCursor: 'auto',
                                        scrollwheel: false 
                                          };  
            $GMAP=new 
  google.maps.Map(document.getElementById('GMAP'),mapOptions);
            overlay=prepareOverlay($GMAP);



 document.querySelector('.button').addEventListener('click', 
 function(e) 
   {
                    //toggle between pressed and not pressed states 
 for button     
                    e.target.classList.toggle('pressed');
                    if(e.target.className.split(' 
 ').indexOf('pressed')>-1)
                    {
                        $GMAP.setOptions({draggableCursor: 
  'crosshair'});

 google.maps.event.addListener($GMAP,'click',function(evt){
                            //if button is pressed then we are in 
polygon info request mode
                            fetch("/findpolygon.php? 
lat="+evt.latLng.lat()+"&lng="+evt.latLng.lng())
                                    .then(function(response){ return 
response.text();}).
                                    then(function(strarr){

interimSlice=strarr.split('%');

polygonReturn=interimSlice[0].split(',');
                                        console.log(polygonReturn);

polygonInfo=JSON.parse(interimSlice[1]).features[0].properties;
                                        var pixelPath="";
                                        var point=new Array();


polygonReturn.forEach((polygon)=>{
                                            point=polygon.split(' ');

u=_svgOW.projection.fromLatLngToDivPixel(new 

google.maps.LatLng({lat:parseFloat(point[1]), 
lng:parseFloat(point[0])})                              
        u.x=(u.x-parseFloat(_svgOW.svg.style.left)) / 
            (1<<$GMAP.getZoom());
        u.y=(u.y-parseFloat(_svgOW.svg.style.top)) / 
            (1<<$GMAP.getZoom());

        pixelPath+=`${u.x} ${u.y}L`;                                                
            });
        pixelPath="M"+pixelPath;
        pixelPath=pixelPath.slice(0,-2);
        //Definition of new path element
 var svgPath =     
 document.createElementNS('http://www.w3.org/2000/svg', 'path');

 svgPath.setAttribute('id','path3');

 svgPath.setAttribute('fill','none');

 svgPath.setAttribute('stroke','yellow');
 svgPath.setAttribute('stroke-width','0.000008');
 svgPath.setAttribute('d',pixelPath);                                        
 overlay.addNewElement('#svg1',svgPath);
})                                  
 .catch(error=>console.error('Error: ',error));        
                            });

                    } else {
                        $GMAP.setOptions({draggableCursor: 'auto'});

 google.maps.event.clearListeners($GMAP,'click');
                        }

          });
      }


 function prepareOverlay(map){   

 class SVGOverlay extends google.maps.OverlayView {


    constructor(bounds, svg, map) {
        super();

        this.bounds = bounds;
        this.svg = svg;

        super.setMap(map);
    }

    onAdd() {
        const svg = this.svg;
        svg.style.position = 'absolute';

        //Add the SVG element to a map pane/layer that is able to 
 receive mouse events:
        const panes = super.getPanes();
        panes.overlayMouseTarget.appendChild(svg);
        const projection = super.getProjection(),
              bounds = this.bounds,
              sw = 
 projection.fromLatLngToDivPixel(bounds.getSouthWest()),
              ne = 
 projection.fromLatLngToDivPixel(bounds.getNorthEast());

        //Place the SVG element;
        var vbox=sw.x+" "+ne.y+" "+(ne.x - sw.x)+" "+(sw.y - ne.y);
        this.svg.setAttribute("viewBox",vbox);

    }

    /**
        Whenever we need to (re)draw the overlay on the map, including 
 when first added.
    */
    draw() {

        //Here, we need to find the correct on-screen position for our 
 image.
        //To achieve that, we simply ask the map's projection to 
 calculate viewport pixels from the image's lat/lng bounds:
              const projection = super.getProjection(),
              bounds = this.bounds,
              sw = 
projection.fromLatLngToDivPixel(bounds.getSouthWest()),
              ne = 
projection.fromLatLngToDivPixel(bounds.getNorthEast());

              var scale = 1 << (map.getZoom());

        //Place/resize the SVG element:
        const s = this.svg.style;
        s.left = sw.x + 'px';
        s.top  = ne.y + 'px';
        s.width  = (ne.x - sw.x) + 'px';
        s.height = (sw.y - ne.y) + 'px';

         var vbox="0 0 "+(ne.x - sw.x)/scale+" "+(sw.y - ne.y)/scale;
        this.svg.setAttribute("viewBox",vbox);


        }

    } 



   function addEvent(target, type, handler) {
    const targets = (typeof target === 'string') ? 
  Array.from(document.querySelectorAll(target))
                                                 : [target];
    targets.forEach(t => google.maps.event.addDomListener(t, type, 
 handler));
}

 function initOverlay() {
    //Say which area we want the image to occupy:
    const svgBounds = new google.maps.LatLngBounds(
        new google.maps.LatLng(35, 25),
        new google.maps.LatLng(44, 46),
    );
    _svgOW=new SVGOverlay(svgBounds, mySVG, map);

    addEvent('path', 'click', e => {
        console.log('Clicked!');
        e.currentTarget.style.fill = '#' + Math.floor(Math.random() * 
  0xfffff);
        e.stopPropagation();
    });
    addEvent('path', 'dblclick', e => {
        //Avoid zooming here:
        e.stopPropagation();
    });
   }

 addEvent(window, 'load', initOverlay);
 var TILE_SIZE=256;
 return {
    addNewElement: function (toWhere,element)
    {
        document.querySelector(toWhere).append(element)
    },

    }
 }        

 </script>
 <script async defer src="https://maps.googleapis.com/maps/api/js? 
 key=MY_APIKEY&callback=initGMap&language=&signed_in=false">
 </script>            
 </body>

</html>

0 个答案:

没有答案