如何在JavaScript中围绕多段线绘制多边形?

如何在JavaScript中围绕多段线绘制多边形?,javascript,google-maps,google-maps-api-3,geofencing,Javascript,Google Maps,Google Maps Api 3,Geofencing,我想围绕多段线绘制一个多边形。在我的例子中,多段线是Google Maps方向,我需要在Google Maps画布中显示一个围绕它的多边形 第一: 对于偏移,我使用JavaScript裁剪器库。我有以下多段线布线:我使用剪裁器在下面创建偏移多边形: 我有一份工作 代码是: <html> <head> <title>Javascript Clipper Library / Offset polyline</title> <s

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

第一:

对于偏移,我使用JavaScript裁剪器库。我有以下多段线布线:我使用剪裁器在下面创建偏移多边形:

我有一份工作

代码是:

<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> 
我有一个关于在多段线周围偏移多边形的代码

但是有一个问题,我不能重新电离,也不能得到一个围绕方向的多边形


有办法解决这个问题吗?

这是有效的解决方案。你可以找到那个

我的工作解决方案:基于Manolis Xountasis的答案和这些相关问题的片段:

包括 添加将google.maps.Polyline路径转换为JSTS对象的例程: 回到google.maps.LatLng数组 从缓冲区获取方向多段线并将其删除
这是一个使用Turp.js的缓冲区模块的替代解决方案。我使用了一张单张地图来展示结果——但这对任何地图库都适用

var中心=[37.78791180770003,-122.40962505340575]; var map=L.map'map'.setViewcenter,14;; 蒂莱耶 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'{ 最大缩放:18 }.addTomap; 变量行={ 类型:特征, 特性:{ 颜色:蓝色 }, 几何图形:{ 类型:LineString, 坐标:[ [-122.40447521209718, 37.79367718768535 ], [-122.40803718566895, 37.79171022624846 ], [-122.40769386291502, 37.79096412372944 ], [-122.40662097930908, 37.789641468930114 ], [-122.40941047668457, 37.789675383451495 ], [-122.40992546081543, 37.78875968591083 ], [-122.40962505340575, 37.78791180770003 ] ] } }; L.geoJSONline{ 样式:functionfeature{ 返回{ 颜色:feature.properties.color }; } }.addTomap; var polygon=草皮缓冲线,50{ 单位:米 }; L.Geojson多边形{ 样式:functionfeature{ 返回{ 颜色:feature.properties.color }; } }.addTomap; 地图{ 高度:400px; }
shell.bufferdistance期望的距离单位是多少?这是如何计算的@geocodezipIt真的很想知道你是如何计算这里的距离的?为什么要做10/111.12?这是代码var distance=10/111.12中每个注释大约10公里,//大约10公里。因为,您没有提供value of value,所以我认为distance=0.001的距离可以很好地近似于路线周围的多边形
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
    }
  }
}
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 = value / 10000, // Roughly 10km
geoInput = {
type: "LineString",
    coordinates: overviewPathGeo
};
var geoReader = new jsts.io.GeoJSONReader(),
    geoWriter = new jsts.io.GeoJSONWriter();
var geometry = geoReader.read(geoInput).buffer(distance);
var polygon = geoWriter.write(geometry);

var oLanLng = [];
var oCoordinates;
oCoordinates = polygon.coordinates[0];
for (i = 0; i < oCoordinates.length; i++) {
   var oItem;
   oItem = oCoordinates[i];
   oLanLng.push(new google.maps.LatLng(oItem[1], oItem[0]));
}

var polygone = new google.maps.Polygon({
    paths: oLanLng,
    map:map
});
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;
};
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
        });
    }
});