@@ -4,6 +4,7 @@ import Feature from 'ol/Feature';
44import Vector from 'ol/layer/Vector' ;
55import VectorSource from 'ol/source/Vector' ;
66import { Pointer , Snap } from 'ol/interaction' ;
7+ import { distance as euclideanDistance } from 'ol/coordinate' ;
78import { OverlayOp } from 'jsts/org/locationtech/jts/operation/overlay' ;
89import { getUid } from 'ol/util' ;
910import Control from './control' ;
@@ -40,6 +41,8 @@ class CadControl extends Control {
4041 * @param {Function } [options.lineFilter] An optional filter for the generated snapping lines
4142 * array (takes the lines and cursor coordinate as arguments and returns the new line array)
4243 * @param {Number } [options.nbClosestFeatures] Number of features to use for snapping (closest first). Default is 5.
44+ * @param {Number } [options.limitGuidesPerFeature] A feature with complex geometry may generate
45+ * a large number of lines. This option can be used to limit the guides to the n closest segments. Deafult is 3.
4346 * @param {Number } [options.snapTolerance] Snap tolerance in pixel
4447 * for snap lines. Default is 10.
4548 * @param {Boolean } [options.showSnapLines] Whether to show
@@ -134,6 +137,18 @@ class CadControl extends Control {
134137 this . nbClosestFeatures =
135138 options . nbClosestFeatures === undefined ? 5 : options . nbClosestFeatures ;
136139
140+ /**
141+ * Number of guide lines to limit cad to generate for a single feature.
142+ * this.nbClosestFeatures * this.limitGuidesPerFeature will be the maximum
143+ * number of guides shown at any time. Default is 3.
144+ * @type {Number }
145+ * @private
146+ */
147+ this . limitGuidesPerFeature =
148+ options . limitGuidesPerFeature === undefined
149+ ? 3
150+ : options . limitGuidesPerFeature ;
151+
137152 /**
138153 * Snap tolerance in pixel.
139154 * @type {Number }
@@ -505,7 +520,6 @@ class CadControl extends Control {
505520 getSegmentLines ( coordinate , snapCoords , snapCoordsBefore ) {
506521 const mousePx = this . map . getPixelFromCoordinate ( coordinate ) ;
507522 const doubleTol = this . snapTolerance * 2 ;
508- const [ mouseX , mouseY ] = mousePx ;
509523 const lines = [ ] ;
510524
511525 for ( let i = 0 ; i < snapCoords . length ; i += 1 ) {
@@ -522,13 +536,12 @@ class CadControl extends Control {
522536
523537 // Calculate projected point
524538 const projMousePx = getProjectedPoint ( mousePx , snapPxBefore , snapPx ) ;
525- const [ projMouseX , projMouseY ] = projMousePx ;
526- const distance = Math . sqrt (
527- ( projMouseX - mouseX ) ** 2 + ( projMouseY - mouseY ) ** 2 ,
528- ) ;
539+ const distance = euclideanDistance ( mousePx , projMousePx ) ;
540+
529541 let newPt ;
530542
531543 if ( distance <= this . snapTolerance ) {
544+ const [ projMouseX , projMouseY ] = projMousePx ;
532545 // lineFunc is undefined when it's a vertical line
533546 const lineFunc = getEquationOfLine ( snapPxBefore , snapPx ) ;
534547 const newX = projMouseX + ( projMouseX < snapX ? - doubleTol : doubleTol ) ;
@@ -557,7 +570,6 @@ class CadControl extends Control {
557570 getOrthoLines ( coordinate , snapCoords , snapCoordsBefore ) {
558571 const mousePx = this . map . getPixelFromCoordinate ( coordinate ) ;
559572 const doubleTol = this . snapTolerance * 2 ;
560- const [ mouseX , mouseY ] = mousePx ;
561573 const lines = [ ] ;
562574
563575 for ( let i = 0 ; i < snapCoords . length ; i += 1 ) {
@@ -579,13 +591,11 @@ class CadControl extends Control {
579591 [ orthoLine1 , orthoLine2 ] . forEach ( ( line ) => {
580592 const [ anchorPx , last ] = line . getCoordinates ( ) ;
581593 const projMousePx = getProjectedPoint ( mousePx , anchorPx , last ) ;
582- const [ projMouseX , projMouseY ] = projMousePx ;
583- const distance = Math . sqrt (
584- ( projMouseX - mouseX ) ** 2 + ( projMouseY - mouseY ) ** 2 ,
585- ) ;
594+ const distance = euclideanDistance ( mousePx , projMousePx ) ;
586595
587596 let newPt ;
588597 if ( distance <= this . snapTolerance ) {
598+ const [ projMouseX , projMouseY ] = projMousePx ;
589599 // lineFunc is undefined when it's a vertical line
590600 const lineFunc = getEquationOfLine ( anchorPx , projMousePx ) ;
591601 const newX =
@@ -623,6 +633,27 @@ class CadControl extends Control {
623633 const snapCoords = [ ] ;
624634 const snapCoordsAfter = [ ] ; // store the direct next point in the coordinate array
625635
636+ // Parse the list of coords, we will add the ortho and segment lines which
637+ // are closest to the users cursor up until the limit of `this.limitGuidesPerFeature`
638+ const parseCoordList = ( coords ) => {
639+ // Check the euclidean distance between coord at index and the
640+ // included vertices so far. Create an array of `this.limitGuidesPerFeature`
641+ // closest items.
642+ const sortedCoords = coords
643+ . slice ( )
644+ . sort (
645+ ( a , b ) =>
646+ euclideanDistance ( a , coordinate ) - euclideanDistance ( b , coordinate ) ,
647+ ) ;
648+ const includedCoords = sortedCoords . slice ( 0 , this . limitGuidesPerFeature ) ;
649+
650+ includedCoords . forEach ( ( index ) => {
651+ snapCoordsBefore . push ( coords [ index - 1 ] ) ;
652+ snapCoords . push ( coords [ index ] ) ;
653+ snapCoordsAfter . push ( coords [ index + 1 ] ) ;
654+ } ) ;
655+ } ;
656+
626657 for ( let i = 0 ; i < features . length ; i += 1 ) {
627658 const geom = features [ i ] . getGeometry ( ) ;
628659 let featureCoord = geom . getCoordinates ( ) ;
@@ -641,17 +672,9 @@ class CadControl extends Control {
641672 // Add feature vertices
642673 // eslint-disable-next-line no-lonely-if
643674 if ( geom instanceof LineString ) {
644- for ( let j = 0 ; j < featureCoord . length ; j += 1 ) {
645- snapCoordsBefore . push ( featureCoord [ j - 1 ] ) ;
646- snapCoords . push ( featureCoord [ j ] ) ;
647- snapCoordsAfter . push ( featureCoord [ j + 1 ] ) ;
648- }
675+ parseCoordList ( featureCoord ) ;
649676 } else if ( geom instanceof Polygon ) {
650- for ( let j = 0 ; j < featureCoord [ 0 ] . length ; j += 1 ) {
651- snapCoordsBefore . push ( featureCoord [ 0 ] [ j - 1 ] ) ;
652- snapCoords . push ( featureCoord [ 0 ] [ j ] ) ;
653- snapCoordsAfter . push ( featureCoord [ 0 ] [ j + 1 ] ) ;
654- }
677+ parseCoordList ( featureCoord [ 0 ] ) ;
655678 }
656679
657680 // Add extent vertices
0 commit comments