You could put the neighborfinder in a custom transformer with a loop, with each base feature per go-around in the loop. Then, only put the unmatched candidates as the candidates-input for the next loop. However, this isn't something that will produce consistent results, as the order of the base features will determine the order in which the candidates become unavailable, thus not guaranteeing the closest feature being selected anymore. In theory, you could end up with a neighbor quite far away, although several features are closer (but have already been taken by a previous base feature).
If that's not an issue for you, then a loop inside the custom transformer is probably good. Please note, that you can only have one loop, so you'd have to use a single port on the return loop and have previously tagged the features as base or candidate, and test/testfilter them into two separate pipes. I think something like this, would work. If, again, you're ok with the above listed "risks".
You will also need some circuit breaker to limit the number of loops. Probably a good idea to count the number of bases beforehand and set the MAX_LOOP_ITERATIONS to that, so you don't run into infinite looping with only candidates remaining.
So you have bases and candidates and want to attach some information from the base to it's nearest candidate only?
I think i would do something along the following lines
- extract geometry of candidate to attribute
- send base and candidates to neighbourfinder
- build list containing candidate ids and geometry
- sort list by distance
- use the first candidate id in the list to become the candidate id
- use the first geometry in the list to rebuild the geometry
- you now have a candidate point with the base id
- keep these along with any unmerged candidates
Actually, you don't even need the geometry extractor step
A quick thought is to swap the base and the candidates. Then each candidate is now a base (call it a new-base) and will only match one other old-base (new-candidate) feature. The old-base then gets the ID of that new-base. It sounds odd, but I think it works.
But there's still some work to do - what if an old-base is matched by two or more new-bases? So you'd have to keep a list and maybe do some duplicate removal, but I think it will still work.
OK, that's a bit odd to get your head around (I'm confused re-reading that) but I think it might help.
Thanks for all yours answers.
It is what I thought : not easy :)
It's a good start, I will deepen yours ideas.