繁体   English   中英

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

fromLatLngToDivPixel doesn't give same coordinates on different viewBox scale

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我在谷歌地图的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>
问题暂未有回复.您可以查看右边的相关问题.
1 坐标系和比例尺单位

我使用GMaps API创建了一个自定义地图,现在需要包含一个比例尺。 但是,我找不到控制缩放比例和单位的方法。 此外,由于数据集是平坦的,因此需要更改坐标系。 有人对如何开始有建议吗? 谢谢! 尽我所能,安德烈 ...

2 Python GUI比例尺

当我将刻度尺推至3,然后按一个按钮,然后发生一些特别的事情时,我该怎么做? 这样我就可以为刻度中的每个变量定义一个动作。 我用if尝试过,但是没有用。 没有错误。 标签只是不出现。 谢谢。 ...

3 TatukGIS DK比例尺

如何显示GIS Viewer的比例尺? 显然,即使我已经在“比例尺”栏上设置了GIS Viewer属性,它也不会显示。 我还检查了它是否可见并将其设置为true。 我的另一种选择是将其打印到图像上,但是只有同时打印了GIS Viewer和比例尺时,它才有效。 而且它看起来很糟糕,因为 ...

4 Android MapFragment比例尺

如何使用Android MapFragment创建显示相对距离的比例尺? 我知道如何使用带有MapView的叠加层来执行此操作,但是无法确定如何在MapFragment中执行此操作。 ...

5 iOS UIImageView比例尺

我需要制作一张必须完全适合iPad Mini 2的不同图像的表格。 因此,我有一张高度= 60且宽度= 621的图片。如果将这些尺寸放入UIImageView ,则该图片几乎适合iPad的整个屏幕。 也许有人可以告诉我为什么会这样,因为我对使用Xcode进行编程非常陌生。 ...

6 ImageView比例尺

在设备周围拖动ImageView时,我对图像比例有疑问。 我的图像是5257像素x 3423像素,因此它相当大。 我已经编码了用于拖动图像的机械模拟,效果很好(请参见下面的代码)。 但是,当我运行项目并且设备将图像显示为图像的缩小版本时,出现了我的问题。 我希望图像处于“ 100 ...

7 android imageView 比例尺

我有一个从数据库填充的 ImageView(图像来自数据库)。 在数据库中,我有纵向和横向的图像!! 我如何调整 imageView 以根据图像宽度和高度自行缩放。 我尝试了很多方法但没有结果! 任何帮助请!!!! ...

10 matplotlib 中极坐标图的比例尺

我创建了一个极坐标 plot 并且不喜欢 y 刻度标签和 plot 数据的重叠。 相反,我想创建一个比例尺来呈现 y-tick 信息。 有没有办法将 y 轴标签变成极坐标图的比例尺? 我想要 output 的一个例子: 我目前拥有的: ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM