在我的应用程序中,我有:
<MapContainer {...opts} scrollWheelZoom>
<>..</>
<Polyline eventHandlers={{ click: e => { console.log('line clicked', e.sourceTarget) }, }} positions={positonArrat}/>}
</MapContainer>
每条折线由N个直线部分组成。
在不使用火箭科学的情况下,如何获得被单击的折线段?
另一种选择是用多条线替换一条多段线,以便每次单击都可以得到一个结果,但是开箱即用的解决方案将是不错的...
我最终使用了简单的数学运算,onClick函数如下所示:
const TOLERANCE = 3
onPolylineClick = e => {
const { x, y } = e.layerPoint
const parts = e.target._parts[ 0 ] // some undocumented shit
let prev = parts[ 0 ]
const section = parts.slice( 1, parts.length ).findIndex( p => {
try{
// check if in bounds
if( !( Math.min( prev.x, p.x ) <= x <= Math.max( prev.x, p.x ) &&
Math.min( prev.y, p.y ) <= y <= Math.max( prev.y, p.y ) ) ) return false
const yCalc = ( x - prev.x ) * ( p.y - prev.y ) / ( p.x - prev.x ) + prev.y
return Math.abs( y - yCalc ) < TOLERANCE
}finally{
prev = p
}
})
this.setState( { selectedSection:section } )
}
它在中设置匹配部分的第一个点的索引state
。
然后,为了可视化所选部分,我在顶部显示了一个2点的橙色折线:
<MapContainer {...opts} scrollWheelZoom>
<Polyline eventHandlers={{ click:this.onPolylineClick }} positions={points} />}
{-1 !== selectedSection &&
<Polyline color="orange" positions={points.slice( selectedSection, selectedSection + 2 )}/>}
</MapContainer>
这对你有用吗?您必须小心使用
._parts
,因为如果smoothFactor
设置了缩放比例,或者部分折线的一部分不在画面中,除非您指定,否则它可能会随每个缩放级别而变化noClip
。我从使用._parts
道具开始回答,但是因为这个而遇到了问题是的,它有效。据我了解,
_parts
以及layerPoint
包含以像素为单位的坐标,而不是latlng,因此缩放级别和其余部分不会产生任何影响是的,它们确实包含关联的像素坐标,但是没有记录的是,该
_parts
道具会随着每次缩放/平移事件进行更新,以仅包含帧中的内容,或者以较低的缩放级别平滑多段线。我了解到这很困难。如果您最终得到的结果是不确定的或不一致的,请记住这一点@SethLutske我唯一注意到的是,在地图的边界上,x和y变为负数,并且可能对放大的部分可见部分产生错误的结果,这实际上并不重要,在这种情况下,我仅显示警告