Warm tip: This article is reproduced from serverfault.com, please click

Obtain a segment of Polyline which was clicked

发布于 2020-11-30 22:37:26

In my app I have:

<MapContainer {...opts} scrollWheelZoom>
  <>..</>
  <Polyline eventHandlers={{ click: e => { console.log('line clicked', e.sourceTarget) }, }} positions={positonArrat}/>}
</MapContainer>

Each polyline consists of N straight line sections.

How can I get the segment of polyline which was clicked without using rocket science?

Another option would be to replace a single polyline with mulitple lines, so that each click would get a single result, but a out-of-box solution would be nice...

Questioner
injecteer
Viewed
0
injecteer 2020-12-01 23:48:50

I ended up using simple math and the onClick-function looks like:

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

It sets the index of the 1st point of the matching section in state.

Then to visualize the selected section I show an orange polyline of 2 points on top:

<MapContainer {...opts} scrollWheelZoom>

  <Polyline eventHandlers={{ click:this.onPolylineClick }} positions={points} />}
  
  {-1 !== selectedSection && 
     <Polyline color="orange" positions={points.slice( selectedSection, selectedSection + 2 )}/>}

</MapContainer>