/**
* This file is part of Relation Analyzer for OSM.
* Copyright (c) 2001 by Adrian Stabiszewski, as@grundid.de
*
* Relation Analyzer is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Relation Analyzer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Relation Analyzer. If not, see <http://www.gnu.org/licenses/>.
*/
package org.osmtools.ra.analyzer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.osmtools.ra.context.AnalyzerContext;
import org.osmtools.ra.segment.ConnectableSegment;
import org.springframework.stereotype.Service;
@Service
public class AggregationService {
public void aggregate(AnalyzerContext analyzerContext) {
List<AggregatedSegment> aggregatedSegments = aggregateSegments(analyzerContext.getSegments());
analyzerContext.setAggregatedSegments(aggregatedSegments);
}
public List<AggregatedSegment> aggregateSegments(List<? extends ConnectableSegment> segments) {
List<AggregatedSegment> aggregatedSegments = new ArrayList<AggregatedSegment>();
for (Iterator<? extends ConnectableSegment> it = segments.iterator(); it.hasNext();) {
ConnectableSegment segment = it.next();
AggregatedSegment newAggregatedSegment = new AggregatedSegment(segment);
if (!canConnect(aggregatedSegments, newAggregatedSegment))
aggregatedSegments.add(newAggregatedSegment);
}
return aggregateMore(aggregatedSegments);
}
private List<AggregatedSegment> aggregateMore(List<AggregatedSegment> segments) {
List<AggregatedSegment> aggregatedSegments = new ArrayList<AggregatedSegment>();
int lastRun = 0;
do {
lastRun = segments.size();
aggregatedSegments = new ArrayList<AggregatedSegment>();
for (Iterator<AggregatedSegment> it = segments.iterator(); it.hasNext();) {
AggregatedSegment segment = it.next();
if (!canConnect(aggregatedSegments, segment))
aggregatedSegments.add(segment);
}
segments = aggregatedSegments;
} while (aggregatedSegments.size() > 1 && lastRun != aggregatedSegments.size());
return aggregatedSegments;
}
private boolean canConnect(List<AggregatedSegment> connectableSegments, AggregatedSegment segment) {
Collection<ConnectableNode> newSegmentEndpointNodes = segment.getEndpointNodes();
for (AggregatedSegment connectableSegment : connectableSegments) {
Collection<ConnectableNode> endpointNodes = connectableSegment.getEndpointNodes();
if (isConnectable(endpointNodes, newSegmentEndpointNodes)) {
connectableSegment.addSegment(segment);
return true;
}
}
return false;
}
private boolean isConnectable(Collection<ConnectableNode> nodes1, Collection<ConnectableNode> nodes2) {
for (ConnectableNode node1 : nodes1) {
for (ConnectableNode node2 : nodes2) {
if (node1.isConnectable(node2))
return true;
}
}
return false;
}
}