/* * JGrass - Free Open Source Java GIS http://www.jgrass.org * (C) HydroloGIS - www.hydrologis.com * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Library General Public License as published by the Free * Software Foundation; either version 2 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 Library General Public License for more * details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.jgrasstools.gears.modules.v.intersections; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_AUTHORCONTACTS; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_AUTHORNAMES; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_KEYWORDS; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_LABEL; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_LICENSE; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_NAME; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_STATUS; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_IN_MAP_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_OUT_LINES_MAP_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSINTERSECTIONFINDER_OUT_POINTS_MAP_DESCRIPTION; import java.util.List; import oms3.annotations.Author; import oms3.annotations.Description; import oms3.annotations.Execute; import oms3.annotations.In; import oms3.annotations.Keywords; import oms3.annotations.Label; import oms3.annotations.License; import oms3.annotations.Name; import oms3.annotations.Out; import oms3.annotations.Status; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.feature.DefaultFeatureCollection; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.jgrasstools.gears.libs.exceptions.ModelsIllegalargumentException; import org.jgrasstools.gears.libs.modules.JGTModel; import org.jgrasstools.gears.utils.features.FeatureUtilities; import org.jgrasstools.gears.utils.geometry.EGeometryType; import org.jgrasstools.gears.utils.geometry.GeometryUtilities; import org.jgrasstools.gears.utils.math.NumericsUtilities; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.prep.PreparedGeometry; import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; @Description(OMSINTERSECTIONFINDER_DESCRIPTION) @Author(name = OMSINTERSECTIONFINDER_AUTHORNAMES, contact = OMSINTERSECTIONFINDER_AUTHORCONTACTS) @Keywords(OMSINTERSECTIONFINDER_KEYWORDS) @Label(OMSINTERSECTIONFINDER_LABEL) @Name(OMSINTERSECTIONFINDER_NAME) @Status(OMSINTERSECTIONFINDER_STATUS) @License(OMSINTERSECTIONFINDER_LICENSE) public class OmsIntersectionFinder extends JGTModel { @Description(OMSINTERSECTIONFINDER_IN_MAP_DESCRIPTION) @In public SimpleFeatureCollection inMap = null; @Description(OMSINTERSECTIONFINDER_OUT_POINTS_MAP_DESCRIPTION) @Out public SimpleFeatureCollection outPointsMap = null; @Description(OMSINTERSECTIONFINDER_OUT_LINES_MAP_DESCRIPTION) @Out public SimpleFeatureCollection outLinesMap = null; @Execute public void process() throws Exception { if (!concatOr(outPointsMap == null && outLinesMap == null, doReset)) { return; } outPointsMap = new DefaultFeatureCollection(); outLinesMap = new DefaultFeatureCollection(); EGeometryType geometryType = EGeometryType.forGeometryType(inMap.getSchema().getGeometryDescriptor().getType()); switch( geometryType ) { case LINE: case MULTILINE: intersectLines(); break; case POLYGON: case MULTIPOLYGON: throw new ModelsIllegalargumentException("The module doesn't work for polygons yet.", this, pm); default: throw new ModelsIllegalargumentException("The module doesn't work for points.", this, pm); } } private void intersectLines() { SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder(); b.setName("pointintersections"); b.setCRS(inMap.getSchema().getCoordinateReferenceSystem()); b.add("the_geom", Point.class); SimpleFeatureType pointType = b.buildFeatureType(); b = new SimpleFeatureTypeBuilder(); b.setName("lineintersections"); b.setCRS(inMap.getSchema().getCoordinateReferenceSystem()); b.add("the_geom", LineString.class); SimpleFeatureType linesType = b.buildFeatureType(); int size = inMap.size(); List<Geometry> geometriesList = FeatureUtilities.featureCollectionToGeometriesList(inMap, true, null); int id = 0; pm.beginTask("Checking intersections...", size); for( int i = 0; i < size; i++ ) { LineString line = (LineString) geometriesList.get(i); PreparedGeometry preparedLine = PreparedGeometryFactory.prepare(line); for( int j = i + 1; j < size; j++ ) { LineString otherLine = (LineString) geometriesList.get(j); if (preparedLine.intersects(otherLine)) { Geometry intersection = line.intersection(otherLine); int numGeometries = intersection.getNumGeometries(); if (numGeometries < 3) { Point start1 = line.getStartPoint(); Point end1 = line.getEndPoint(); Point start2 = otherLine.getStartPoint(); Point end2 = otherLine.getEndPoint(); if (numGeometries == 1) { // single intersection, control if it is not just two connected lines if (start1.distance(end2) < NumericsUtilities.D_TOLERANCE || start1.distance(start2) < NumericsUtilities.D_TOLERANCE || end1.distance(start2) < NumericsUtilities.D_TOLERANCE || end1.distance(end2) < NumericsUtilities.D_TOLERANCE) { // it is the same point continue; } } else if (numGeometries == 2) { // could still be connected lines if ((start1.distance(end2) < NumericsUtilities.D_TOLERANCE && start2.distance(end1) < NumericsUtilities.D_TOLERANCE) || (start1.distance(start2) < NumericsUtilities.D_TOLERANCE && end1.distance(end2) < NumericsUtilities.D_TOLERANCE)) { // it is the same point continue; } } } for( int k = 0; k < numGeometries; k++ ) { Geometry geometryN = intersection.getGeometryN(k); if (geometryN instanceof Point) { SimpleFeatureBuilder builder = new SimpleFeatureBuilder(pointType); Point p = (Point) geometryN; Object[] values = new Object[]{p}; builder.addAll(values); SimpleFeature feature = builder.buildFeature(pointType.getTypeName() + "." + id++); ((DefaultFeatureCollection) outPointsMap).add(feature); } else if (geometryN instanceof LineString) { SimpleFeatureBuilder builder = new SimpleFeatureBuilder(linesType); LineString l = (LineString) geometryN; Object[] values = new Object[]{l}; builder.addAll(values); SimpleFeature feature = builder.buildFeature(linesType.getTypeName() + "." + id++); ((DefaultFeatureCollection) outLinesMap).add(feature); } } } } pm.worked(1); } pm.done(); } }