javascript - 将圆捕捉到传单中的多段线

标签 javascript leaflet

我在传单中有一条多段线,我想在其上捕捉一个圆,我想在多段线之间移动,这样圆总是在多段线的中心。

Circle on polyline

有没有办法将圆心对齐到中心,这样当我移动圆时它总是以多段线为中心?

最佳答案

我制作了一个 fiddle ,圆圈在 mousemove 事件中移动:http://jsfiddle.net/v0bseuqz/32/

主要想法是创建一条线(当鼠标移动时)从 map 顶部到底部描画光标坐标,并检查它是否与圆应该捕捉到的多段线相交。如果它们相交,它们的交点应该是新的圆心。

document.onload = loadMap();

function loadMap() {
  var map = L.map('map').setView([0, 0], 12);
  L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw', {   
    maxZoom: 18,
    id: 'mapbox.streets',
    accessToken: 'pk.eyJ1IjoiZW======V6ZTdlb2V5cyJ9.3HqHQ4BMRvSPaYe8ToA7YQ'
  }).addTo(map);

    L.polyline([
            [-50, 1000],
      [0, 0]
        ], {
        color: 'red',
      weight: 1
    }).addTo(map);

  var circle = L.circle([0, 0], 500, {
    color: 'red',
    fillColor: '#f03',
    fillOpacity: 0.5
    }).addTo(map);

  $( "#map" ).mousemove(function( event ) {  
    var cursorPoint = new L.Point(event.clientX, event.clientY);
    var cursorLatLng = map.containerPointToLatLng(cursorPoint);
    var intersection = (checkLineIntersection(0, 0, 1000, -50, cursorLatLng.lng, 1, cursorLatLng.lng, -1));
    if (intersection.onLine1 && intersection.onLine2) {
        circle.setLatLng(new L.LatLng(intersection.y, intersection.x));
    }
});

}


function checkLineIntersection(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) {
    // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point
    var denominator, a, b, numerator1, numerator2, result = {
        x: null,
        y: null,
        onLine1: false,
        onLine2: false
    };
    denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY));
    if (denominator == 0) {
        return result;
    }
    a = line1StartY - line2StartY;
    b = line1StartX - line2StartX;
    numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b);
    numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b);
    a = numerator1 / denominator;
    b = numerator2 / denominator;

    // if we cast these lines infinitely in both directions, they intersect here:
    result.x = line1StartX + (a * (line1EndX - line1StartX));
    result.y = line1StartY + (a * (line1EndY - line1StartY));
/*
        // it is worth noting that this should be the same as:
        x = line2StartX + (b * (line2EndX - line2StartX));
        y = line2StartX + (b * (line2EndY - line2StartY));
        */
    // if line1 is a segment and line2 is infinite, they intersect if:
    if (a > 0 && a < 1) {
        result.onLine1 = true;
    }
    // if line2 is a segment and line1 is infinite, they intersect if:
    if (b > 0 && b < 1) {
        result.onLine2 = true;
    }
    // if line1 and line2 are segments, they intersect if both of the above are true
    return result;
};

更新

如果您有一条由两个以上的点定义的多段线,您应该检查它的每段与垂直线的交点。只需循环执行即可。这是 fiddle :http://jsfiddle.net/v0bseuqz/39/

var coords = [
  [0.003, 0.080],
  [-0.008, 0.041],
  [0, 0]
];
L.polyline(coords, {
  color: 'red',
  weight: 1
}).addTo(map);

var circle = L.circle([0, 0], 500, {
  color: 'red',
  fillColor: '#f03',
  fillOpacity: 0.5
}).addTo(map);
var startY, startX, endY, endX, cursorPoint, cursorLatLng, intersection;
$( "#map" ).mousemove(function( event ) {
  for(i = coords.length, i >0; i--;) {
    if (i - 1 >= 0) {
     startY = coords[i][0];
     startX = coords[i][1];
     endY = coords[i - 1][0];
     endX = coords[i - 1][1];

     cursorPoint = new L.Point(event.clientX, event.clientY);
     cursorLatLng = map.containerPointToLatLng(cursorPoint);
     intersection = (checkLineIntersection(startX, startY, endX, endY, cursorLatLng.lng, 1, cursorLatLng.lng, -1));
     if (intersection.onLine1 && intersection.onLine2) {
       circle.setLatLng(new L.LatLng(intersection.y, intersection.x));
     }
   }
 }

});

我采用了检测两条线相交的算法 here.

关于javascript - 将圆捕捉到传单中的多段线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35814103/

相关文章:

javascript - 使用 jquery/javascript 移动未标记的表

javascript - 如何使用切换后的 Leaflet 图层组中的标记填充选区

javascript - Leaflet 标记弹出窗口中的缓存破坏

javascript - 扩展标记时传单未获取所有数据

javascript - 当模式处于事件状态时,传单 map 仍然存在。为什么?

leaflet - MediaWiki 中的自定义传单 map

javascript - Underscore.js 将对象键展平为数组

javascript - JavaScript 中的 "this"。对工厂内对象的引用

javascript - 聊天应用程序 Tut : purpose of populate()?

javascript - 为什么 jQuery 函数返回 null?