001/* *********************************************************************** *
002 * project: org.matsim.*
003 *                                                                         *
004 * *********************************************************************** *
005 *                                                                         *
006 * copyright       : (C) 2013 by the members listed in the COPYING,        *
007 *                   LICENSE and WARRANTY file.                            *
008 * email           : info at matsim dot org                                *
009 *                                                                         *
010 * *********************************************************************** *
011 *                                                                         *
012 *   This program is free software; you can redistribute it and/or modify  *
013 *   it under the terms of the GNU General Public License as published by  *
014 *   the Free Software Foundation; either version 2 of the License, or     *
015 *   (at your option) any later version.                                   *
016 *   See also COPYING, LICENSE and WARRANTY file                           *
017 *                                                                         *
018 * *********************************************************************** */
019
020package org.matsim.contrib.util;
021
022import java.util.List;
023import java.util.stream.Stream;
024
025import org.matsim.api.core.v01.Coord;
026import org.matsim.contrib.util.distance.DistanceUtils;
027
028/**
029 * @author michalm
030 */
031public class StraightLineKnnFinder<T, N> {
032        private final int k;
033        private final LinkProvider<T> objectToLink;
034        private final LinkProvider<N> neighbourToLink;
035
036        public StraightLineKnnFinder(int k, LinkProvider<T> objectToLink, LinkProvider<N> neighbourToLink) {
037                this.k = k;
038                this.objectToLink = objectToLink;
039                this.neighbourToLink = neighbourToLink;
040        }
041
042        public List<N> findNearest(T obj, Stream<N> neighbours) {
043                Coord objectCoord = objectToLink.apply(obj).getCoord();
044                return PartialSort.kSmallestElements(k, neighbours,
045                                n -> DistanceUtils.calculateSquaredDistance(objectCoord, neighbourToLink.apply(n).getCoord()));
046        }
047}