我在谷歌地图的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>

  ask by cenk translate from so

本文未有回复,本站智能推荐:

1回复

PHP生成的图表。CSS错误。比例尺错误。SVG多边形

我编写了一个使用SVG-Poligons显示图表的脚本。 情况。 我有一个具有最高价格和最低价格的产品。 我每个星期一(称为周期)收集该信息。 我的系统会计算出底价和产品的获胜百分比,并设置自己的价格。 例 现在,我用值来绘制Poligons。 为了做到这一点,由于poli
2回复

SVG多边形形状的坐标数组

我正在用Python创建一个随机地图生成器。 我正在建立随机的政治领土。 我有一种算法,可以为一个地区列表生成一个X,Y坐标列表。 这些区域不必是连续的,因此点列表可以产生多个多边形。 目前,我正在将点列表转换为Path字符串,该字符串本质上是一条很长的线,可以绕起来形成一个形状。
1回复

如果沿线的y坐标已知,则沿2条线求x值

[多边形的所有坐标都是已知的] 这里对于特定的 Y 值,我需要计算多边形填充中的 x 范围,但现在我正在为 y 搜索 x 的每个点并检查它是否在填充与否,任何人都可以为此提出更好的解决方案。 //////////////////////////更新////////////////// 在这里
1回复

SVG多边形,点坐标为百分比[重复]

这个问题在这里已有答案: 具有百分比单位的SVG多边形点支持 2个答案 我可以在svg中使用矩形坐标中的百分比值,但不能在多边形中使用百分比值。 有解决方法吗? 我的意思是,这没关系: svg { background: #ADF; width: 300px; h
1回复

SVG多边形比例和相应设置点

嗨堆栈溢出:) 我正在与svg多边形对象作斗争,我需要能够调整大小(按比例),并保存/设置新的点值。 目前,我可以通过将CSS转换应用于SVG对象来实现此目的,但这不会更改points属性值。 这有可能吗? 我的SVG多边形如下所示: <svg viewBox="0 0
1回复

将SVG路径转换为多边形坐标

我需要一个函数或插​​件来将SVG路径的路径命令转换为多边形点。 我发现了一个: https : //github.com/Phrogz/svg-path-to-polygons 这里的问题是它不支持A和C之类的弧和曲线。 let pathData = 'M5,15 c5.5,0
1回复

Google地图-获取英国县的坐标

我想知道是否有人可以建议我如何获取英国县的坐标,以便能够使用Google Maps API向Google地图添加多边形? 我看过使用https://nominatim.openstreetmap.org/details.php?place_id=198164455来检索OSM关系以便能够使用
1回复

检索Google多边形LatLng坐标

当您在 Google 地图(例如伦敦)上搜索某个区域时,它会向您显示一个突出显示的伦敦多边形。 我需要做的是检索这个多边形的 LatLng 坐标。 查看 Google 的 API 文档,我没有找到任何符合需求的内容。 是否有可能以另一种方式/解决方法来做到这一点?