IsochroneUtility.java
/* This file is part of Openrouteservice.
*
* Openrouteservice is free software; you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
* This library 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 Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this library;
* if not, see <https://www.gnu.org/licenses/>.
*/
package org.heigit.ors.isochrones;
import org.heigit.ors.common.Pair;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class IsochroneUtility {
private IsochroneUtility() {
}
public static List<IsochronesIntersection> computeIntersections(IsochroneMapCollection isochroneMaps) {
List<IsochronesIntersection> result = new ArrayList<>();
if (isochroneMaps.size() == 1)
return result;
int im = 0;
for (IsochroneMap isoMap : isochroneMaps.getIsochroneMaps()) {
int ii = 0;
for (Isochrone isoLine : isoMap.getIsochrones()) {
List<IsochronesIntersection> isoIntersection = computeIntersection(isoLine, ii, isoMap, im, isochroneMaps);
if (!isoIntersection.isEmpty()) {
result.addAll(isoIntersection);
}
ii++;
}
im++;
}
// Find intersections between IsochronesIntersection objects
if (result.size() > 1) {
List<IsochronesIntersection> isoIntersections = new ArrayList<>();
int i = 0;
for (IsochronesIntersection isoIntersection : result) {
List<IsochronesIntersection> overlaps = computeIntersection(isoIntersection, i, result);
if (!overlaps.isEmpty()) {
isoIntersections.addAll(overlaps);
}
i++;
}
if (!isoIntersections.isEmpty())
result.addAll(isoIntersections);
}
return result;
}
private static List<IsochronesIntersection> computeIntersection(IsochronesIntersection isoIntersection, Integer intersectionIndex, List<IsochronesIntersection> intersections) {
List<IsochronesIntersection> result = new ArrayList<>();
for (int i = intersectionIndex + 1; i < intersections.size(); i++) {
IsochronesIntersection isoIntersection2 = intersections.get(i);
if (isoIntersection.intersects(isoIntersection2)) {
Geometry geomIntersection = isoIntersection.getGeometry().intersection(isoIntersection2.getGeometry());
if (geomIntersection != null) {
IsochronesIntersection isoIntersectionNew = new IsochronesIntersection(geomIntersection);
isoIntersectionNew.addContourRefs(isoIntersection.getContourRefs());
isoIntersectionNew.addContourRefs(isoIntersection2.getContourRefs());
}
}
}
return result;
}
private static List<IsochronesIntersection> computeIntersection(Isochrone isoLine, Integer isoIndex, IsochroneMap isoMap, Integer isoMapIndex, IsochroneMapCollection isochroneMaps) {
List<IsochronesIntersection> result = new ArrayList<>();
Envelope isoEnvelope = isoLine.getEnvelope();
Geometry isoGeometry = isoLine.getGeometry();
for (int im = isoMapIndex + 1; im < isochroneMaps.size(); im++) {
IsochroneMap isoMap2 = isochroneMaps.getIsochrone(im);
if (!Objects.equals(isoMap2, isoMap) && isoMap2.getEnvelope().intersects(isoEnvelope)) {
int ii = 0;
for (Isochrone isoLine2 : isoMap2.getIsochrones()) {
if (isoEnvelope.intersects(isoLine2.getEnvelope())) {
Geometry geomIntersection = isoGeometry.intersection(isoLine2.getGeometry());
if (geomIntersection != null && !geomIntersection.isEmpty()) {
IsochronesIntersection isoIntersection = new IsochronesIntersection(geomIntersection);
isoIntersection.addContourRefs(new Pair<>(isoMapIndex, isoIndex));
isoIntersection.addContourRefs(new Pair<>(im, ii));
result.add(isoIntersection);
}
}
ii++;
}
}
}
return result;
}
}