public Coordinate snap ( Coordinate coordinate ) { if ( rules == null || mapModel == null ) { return coordinate ; } Coordinate snappedCoordinate = coordinate ; double snappedDistance = Double . MAX_VALUE ; for ( SnappingRuleInfo rule : rules ) { // Check for supported snapping algorithms: TODO use factory if ( rule . getType ( ) != SnappingType . CLOSEST_ENDPOINT && rule . getType ( ) != SnappingType . NEAREST_POINT ) { throw new IllegalArgumentException ( "Unknown snapping rule type was found: " + rule . getType ( ) ) ; } // Get the target snap layer: VectorLayer snapLayer ; try { snapLayer = mapModel . getVectorLayer ( rule . getLayerId ( ) ) ; } catch ( Exception e ) { // NOSONAR throw new IllegalArgumentException ( "Target snapping layer (" + rule . getLayerId ( ) + ") was not a vector layer." ) ; } SnapMode tempMode = this . mode ; if ( snapLayer . getLayerInfo ( ) . getLayerType ( ) != LayerType . POLYGON && snapLayer . getLayerInfo ( ) . getLayerType ( ) != LayerType . MULTIPOLYGON ) { // For mode=MODE_PRIORITY_TO_INTERSECTING_GEOMETRIES, an area > 0 is required. tempMode = SnapMode . ALL_GEOMETRIES_EQUAL ; } // TODO: don't create the handler every time... SnappingMode handler ; if ( tempMode == SnapMode . ALL_GEOMETRIES_EQUAL ) { handler = new EqualSnappingMode ( rule ) ; } else { handler = new IntersectPriorityMode ( rule ) ; } // Calculate snapping: handler . setCoordinate ( coordinate ) ; iterateFeatures ( snapLayer , handler ) ; if ( handler . getDistance ( ) < snappedDistance ) { snappedCoordinate = handler . getSnappedCoordinate ( ) ; snappedDistance = handler . getDistance ( ) ; } } return snappedCoordinate ; }
Execute the actual snapping!