如何在JavaScript中围绕多段线绘制多边形? [英] How to draw a polygon around a polyline in 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的答案)和以下相关问题中的部分内容:
- 包含 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 并缓存它
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:
- How to calculate intersection area in Google Maps API with JSTS Library?
- 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;
}
- get the directions polyline from the DirectionsService and buffer it
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屋!