问题
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?
回答1:
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
});
}
});
回答2:
This is the working solution. You can find the JSTS files at coderwall.com.
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
});
来源:https://stackoverflow.com/questions/19369363/how-to-draw-a-polygon-around-a-polyline-in-javascript