2013-10-14 4 views
9

Я хочу нарисовать многоугольник вокруг полилинии. Полилиния в моем случае - это направление Google Maps, и мне нужно показать многоугольник вокруг него в холсте Google Maps.Как нарисовать многоугольник вокруг полилинии в JavaScript?

Первое:

Для компенсации я использую JavaScript Clipper Library. У меня есть следующая полилиния (маршрут): я делаю смежный многоугольник ниже с помощью Clipper:

У меня есть рабочий JS Bin example.

Код:

<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> 

И все это хорошо, но теперь я должен заменить переменные многоугольник с точками из направлений 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; 

     //REST OF CODE 
    } 
    } 
} 

У меня есть a JS Bin example с этим кодом для смещения многоугольника вокруг полилинии.

Но есть некоторые проблемы, которые я не могу зарегистрировать, и я не могу получить многоугольник вокруг направлений.

Есть ли способ решить эту проблему?

+0

почему - минус на этот вопрос, что не так? –

+0

Это был не я, но я могу себе представить, потому что ваш вопрос был слишком широким. ТАК. здесь не отлаживаются ваши программы.Вам нужно показать, какие шаги вы предприняли для решения проблемы самостоятельно. Например, первым шагом было бы убрать ваш код и избавиться от ошибок JavaScript, которые отображаются в консоли. Затем вы можете отобразить маршрут (без полигона)? Затем попробуйте добавить многоугольный код. –

+0

да, я пытаюсь решить свою проблему с var polygon = response.routes [0] .overview_path; –

ответ

7

Это рабочее решение. Вы можете найти 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 
}); 
9

Мой рабочий раствор: working example (на основе от ответа Манолис Xountasis), и части из этих смежных вопросов:

  1. How to calculate intersection area in Google Maps API with JSTS Library?
  2. Google Maps Polygons self intersecting detection
  • включают JSTS library
  • добавить подпрограммы перевести пути google.maps.Polyline на JSTS объекты:
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; 
}; 
  • и обратно к google.maps.LatLng массивов
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 и буфера он
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

Какова единица расстояния, которую ожидает 'shell.buffer (distance)'? Как это рассчитывается? @geocodezip – jbgarr

+0

Было бы неплохо понять, как вы вычисляете расстояние здесь? Почему вы делаете 10/111.12? –

+0

Это примерно 10 км (https://www.google.com/#q=km%20per%20degree%20longitude%20km) за комментарий в коде ('var distance = 10/111.12, // Примерно 10 км') – geocodezip