如何在JavaScript中围绕多段线绘制多边形? [英] How to draw a polygon around a polyline in JavaScript?

查看:111
本文介绍了如何在JavaScript中围绕多段线绘制多边形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想围绕多段线绘制多边形。在我的情况下,多段线是一个Google Maps的方向,我需要在Google Maps画布中显示一个多边形。

第一:



为了抵消,我使用JavaScript Clipper Library。我有以下折线(路线):我使用Clipper在下面制作偏移多边形:



我有一个工作

代码是:




pre> < HTML>
< head>
< title> Javascript Clipper Library / Offset polyline< / title>
< script src =clipper.js>< / script>
< script>
函数draw(){
var polygons = [[{X:72,Y:59.45},{X:136,Y:66},{X :170, Y:99},{ X:171, Y:114},{ X:183, Y:125},{ X:218, Y:144 },{ X:218, Y:165},{ X:226, Y:193},{ X:254, Y:195},{ X:283 , Y:195},{ X:292, Y:202},{ X:325, Y:213},{ X:341, Y:234}, { X:397, Y:245},{ X:417, Y:248}]];
var scale = 100;
reverse_copy(polygons);
多边形=放大(多边形,比例);
var cpr = new ClipperLib.Clipper();
var delta = 25;
var joinType = ClipperLib.JoinType.jtRound;
var miterLimit = 2;
var AutoFix = true;
var svg,offsetted_polygon,
cont = document.getElementById('svgcontainer');
offsetted_polygon = cpr.OffsetPolygons(polygons,delta * scale,joinType,miterLimit,AutoFix);
//console.log(JSON.stringify(offsetted_polygon));

//绘制红色偏移多边形
svg ='< svg style =margin-top:10px; margin-right:10px; margin-bottom:10px; background-color:# ddddddwidth =540height =340>';
svg + ='< path stroke =redfill =redstroke-width =2stroke-opacity =0.6fill-opacity =0.2d ='+ polys2path(offsetted_polygon ,scale)+'/>';

//绘制蓝色折线
svg + ='<路径描边=蓝色描边宽度=3d ='+ polys2path(多边形,比例)+'' />';
svg + ='< / svg>';

cont.innerHTML + = svg;
}

//辅助函数来放大多边形坐标
函数放大(poly,scale){
var i,j;

if(!scale)
scale = 1; (j = 0; j< poly [i] .length; j ++){$ b $($ i = 0; i

) b poly [i] [j] .X * = scale;
poly [i] [j] .Y * =比例;
}
}

return poly;
}

//将多边形转换为SVG路径字符串
函数polys2path(poly,scale){
var path =,i,j;

if(!scale)
scale = 1; (j = 0; j< poly [i] .length; j ++){$ b $($ i = 0; i

) b if(!j)
path + =M;
else
path + =L;
path + =(poly [i] [j] .X / scale)+,+(poly [i] [j] .Y / scale);
}
path + =Z;
}

返回路径;


函数reverse_copy(poly){
//创建多边形的反向副本=将折线转换为'平面'多边形...
var k,klen = poly.length,len,j; (k = 0; k len = poly [k] .length;


$ b;
poly [k] .length = len * 2 - 2;对于(j = 1; j <= len-2; j ++){
poly [k] [len-1 + j] = {
X:poly [ k] [len - 1 - j] .X,
Y:poly [k] [len - 1 - j] .Y
}
}
}
}
< / script>
< / head>
< body onload =draw()>
< h2> Javascript Clipper Library / Offset polyline< / h2>
此页面显示偏移多段线并使用SVG绘制它的示例。
< div id =svgcontainer>< / div>
< / body>
< / html>

所有这些都很好,但现在我必须用Google Maps指示中的点替换多边形变量,所以

  directionsService.route(request,function(response,status){
if(status = = google.maps.DirectionsStatus.OK){
directionsDisplay.setDirections(response);

function draw(){
var polygons = response.routes [0] .overview_path;

//代码的剩余部分
}
}
}

我有一个 JS Bin示例,使用此代码抵消折线周围的多边形。

但是有一些问题,我无法正规化,我无法在方向上找到多边形。



有什么办法可以解决这个问题吗?

解决方案

我的工作解决方案:工作示例(基于Manolis Xountasis的答案)和以下相关问题中的部分内容:


  1. 如何使用JSTS Library计算Google Maps API中的交叉区域?

  2. Google Maps多边形自相交检测






  • 包含 JSTS库

  • 添加例程以将google.maps.Polyline路径转换为JSTS对象:




 函数googleMaps2JTS(边界){
var coordinates = [];
var length = 0;
if(boundaries&& boundary.getLength)length = boundaries.getLength();
else if(boundaries&& boundaries.length)length = boundaries.length;
for(var i = 0; i< length; i ++){
if(boundaries.getLength)coordinates.push(new jsts.geom.Coordinate(
boundaries.getAt(i) .lat(),boundaries.getAt(i).lng()));
else if(boundaries.length)coordinates.push(new jsts.geom.Coordinate(
boundaries [i] .lat(),boundaries [i] .lng()));
}
返回坐标;
};






  • 并回到google.maps .LatLng数组





  var jsts2googleMaps =函数(几何) {
var coordArray = geometry.getCoordinates();
GMcoords = [];
for(var i = 0; i< coordArray.length; i ++){
GMcoords.push(new google.maps.LatLng(coordArray [i] .x,coordArray [i] .y) );
}
返回GMcoords;







  directionsService.route(request,function(response,status){
if(status == google.maps .DirectionsStatus.OK){
directionsDisplay.setDirections(response);
var overviewPath = response.routes [0] .overview_path,
overviewPathGeo = [];
for(var i = $; i< overviewPath.length; i ++){
overviewPathGeo.push(
[overviewPath [i] .lng(),overviewPath [i] .lat()]);
}

var distance = 10 / 111.12,//大概10km
geoInput = {
类型:LineString,
坐标:overviewPathGeo
};
var geoInput = googleMaps2JTS(over viewPath);
var geometryFactory = new jsts.geom.GeometryFactory();
var shell = geometryFactory.createLineString(geoInput);
var polygon = shell.buffer(distance);

var oLanLng = [];
var oCoordinates;
oCoordinates = polygon.shell.points [0];
for(i = 0; i< oCoordinates.length; i ++){
var oItem;
oItem = oCoordinates [i];
oLanLng.push(new google.maps.LatLng(oItem [1],oItem [0]));
}
if(routePolygon&& routePolygon.setMap)routePolygon.setMap(null);
routePolygon = new google.maps.Polygon({
paths:jsts2googleMaps(polygon),
map:map
});
}
});


I want to draw a polygon around a polyline. The polyline in my case is a Google Maps direction and I need to show a polygon around it within the Google Maps canvas.

First:

For offsetting I use the JavaScript Clipper Library. I have the following polyline (route): I make an offset polygon below using Clipper:

I have a working JS Bin example.

The code is:

<html>
  <head>
    <title>Javascript Clipper Library / Offset polyline</title>
    <script src="clipper.js"></script>
    <script>
    function draw() {
      var polygons = [[{"X":72,"Y":59.45},{"X":136,"Y":66},{"X":170,"Y":99},{"X":171,"Y":114},{"X":183,"Y":125},{"X":218,"Y":144},{"X":218,"Y":165},{"X":226,"Y":193},{"X":254,"Y":195},{"X":283,"Y":195},{"X":292,"Y":202},{"X":325,"Y":213},{"X":341,"Y":234},{"X":397,"Y":245},{"X":417,"Y":248}]]; 
      var scale = 100;
      reverse_copy(polygons);
      polygons = scaleup(polygons, scale);
      var cpr = new ClipperLib.Clipper();
      var delta = 25;
      var joinType = ClipperLib.JoinType.jtRound;
      var miterLimit = 2;
      var AutoFix = true;
      var svg, offsetted_polygon,
      cont = document.getElementById('svgcontainer');
      offsetted_polygon = cpr.OffsetPolygons(polygons, delta * scale, joinType, miterLimit, AutoFix);
      //console.log(JSON.stringify(offsetted_polygon));

      // Draw red offset polygon
      svg = '<svg style="margin-top:10px;margin-right:10px;margin-bottom:10px;background-color:#dddddd" width="540" height="340">';
      svg += '<path stroke="red" fill="red" stroke-width="2" stroke-opacity="0.6" fill-opacity="0.2" d="' + polys2path(offsetted_polygon, scale) + '"/>';

      //Draw blue polyline
      svg += '<path stroke="blue" stroke-width="3" d="' + polys2path(polygons, scale) + '"/>';
      svg += '</svg>';

      cont.innerHTML += svg;
    }

    // helper function to scale up polygon coordinates
    function scaleup(poly, scale) {
      var i, j;

      if (!scale)
        scale = 1;

      for(i = 0; i < poly.length; i++) {
        for(j = 0; j < poly[i].length; j++) {
          poly[i][j].X *= scale;
          poly[i][j].Y *= scale;
        }
      }

      return poly;
    }

    // converts polygons to SVG path string
    function polys2path (poly, scale) {
      var path = "", i, j;

      if (!scale)
        scale = 1;

      for(i = 0; i < poly.length; i++) {
        for(j = 0; j < poly[i].length; j++) {
          if (!j)
            path += "M";
          else
            path += "L";
          path += (poly[i][j].X / scale) + ", " + (poly[i][j].Y / scale);
        }
        path += "Z";
      }

      return path;
    }

    function reverse_copy(poly) {
      // Make reverse copy of polygons = convert polyline to a 'flat' polygon ...
      var k, klen = poly.length, len, j; 

      for (k = 0; k < klen; k++) {
        len = poly[k].length;
        poly[k].length = len * 2 - 2;

        for (j = 1; j <= len - 2; j++) {
          poly[k][len - 1 + j] = {
            X: poly[k][len - 1 - j].X,
            Y: poly[k][len - 1 - j].Y
          }
        }
      }
    }
    </script>
  </head>
  <body onload="draw()">
    <h2>Javascript Clipper Library / Offset polyline</h2>
    This page shows an example of offsetting polyline and drawing it using SVG.
    <div id="svgcontainer"></div>
  </body>
</html> 

And all this is good but now I must replace the polygon variables with points from Google Maps directions, so I do this change:

directionsService.route(request, function(response, status) {
  if (status == google.maps.DirectionsStatus.OK) {
    directionsDisplay.setDirections(response);

    function draw() {
      var polygons = response.routes[0].overview_path; 

      //REST OF CODE
    }
  }
}

I have a JS Bin example with this code for offsetting the polygon around the polyline.

But there is some problem, which I can't regonize and I can't get a polygon around directions.

Is there any way to solve this problem?

解决方案

My working solution: working example (based off of Manolis Xountasis's answer) and pieces from these related questions:

  1. How to calculate intersection area in Google Maps API with JSTS Library?
  2. Google Maps Polygons self intersecting detection

  • include the JSTS library
  • add routines to translate google.maps.Polyline paths to JSTS objects:

function googleMaps2JTS(boundaries) {
    var coordinates = [];
    var length = 0;
    if (boundaries && boundaries.getLength) length = boundaries.getLength();
    else if (boundaries && boundaries.length) length = boundaries.length;
    for (var i = 0; i < length; i++) {
        if (boundaries.getLength) coordinates.push(new jsts.geom.Coordinate(
        boundaries.getAt(i).lat(), boundaries.getAt(i).lng()));
        else if (boundaries.length) coordinates.push(new jsts.geom.Coordinate(
        boundaries[i].lat(), boundaries[i].lng()));
    }
    return coordinates;
};

  • and back to google.maps.LatLng arrays

var jsts2googleMaps = function (geometry) {
  var coordArray = geometry.getCoordinates();
  GMcoords = [];
  for (var i = 0; i < coordArray.length; i++) {
    GMcoords.push(new google.maps.LatLng(coordArray[i].x, coordArray[i].y));
  }
  return GMcoords;
}

directionsService.route(request, function (response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
        var overviewPath = response.routes[0].overview_path,
            overviewPathGeo = [];
        for (var i = 0; i < overviewPath.length; i++) {
            overviewPathGeo.push(
            [overviewPath[i].lng(), overviewPath[i].lat()]);
        }

        var distance = 10 / 111.12, // Roughly 10km
            geoInput = {
                type: "LineString",
                coordinates: overviewPathGeo
            };
        var geoInput = googleMaps2JTS(overviewPath);
        var geometryFactory = new jsts.geom.GeometryFactory();
        var shell = geometryFactory.createLineString(geoInput);
        var polygon = shell.buffer(distance);

        var oLanLng = [];
        var oCoordinates;
        oCoordinates = polygon.shell.points[0];
        for (i = 0; i < oCoordinates.length; i++) {
            var oItem;
            oItem = oCoordinates[i];
            oLanLng.push(new google.maps.LatLng(oItem[1], oItem[0]));
        }
        if (routePolygon && routePolygon.setMap) routePolygon.setMap(null);
        routePolygon = new google.maps.Polygon({
            paths: jsts2googleMaps(polygon),
            map: map
        });
    }
});

这篇关于如何在JavaScript中围绕多段线绘制多边形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆