/** * gvSIG. Desktop Geographic Information System. * * Copyright (C) 2007-2021 gvSIG Association. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * For any additional information, do not hesitate to contact us * at info AT gvsig.com, or visit our website www.gvsig.com. */ package org.gvsig.topology.rule; import org.gvsig.expressionevaluator.Expression; import org.gvsig.expressionevaluator.ExpressionUtils; import org.gvsig.expressionevaluator.GeometryExpressionBuilder; import org.gvsig.expressionevaluator.GeometryExpressionUtils; import org.gvsig.fmap.dal.feature.Feature; import org.gvsig.fmap.dal.feature.FeatureReference; import org.gvsig.fmap.dal.feature.FeatureSet; import org.gvsig.fmap.dal.feature.FeatureStore; import org.gvsig.fmap.geom.Geometry; import org.gvsig.tools.ToolsLocator; import org.gvsig.tools.i18n.I18nManager; import org.gvsig.tools.task.SimpleTaskStatus; import org.gvsig.tools.visitor.VisitCanceledException; import org.gvsig.topology.lib.api.TopologyDataSet; import org.gvsig.topology.lib.api.TopologyReport; import org.gvsig.topology.lib.api.TopologyRuleFactory; import org.gvsig.topology.lib.spi.AbstractTopologyRule; /** * * @author jjdelcerro */ @SuppressWarnings("UseSpecificCatch") public class PolygonContainsOnePointRule extends AbstractTopologyRule { private String geomName; private Expression expression = null; private GeometryExpressionBuilder expressionBuilder = null; public PolygonContainsOnePointRule() { // for persistence only } public PolygonContainsOnePointRule( TopologyRuleFactory factory, double tolerance, String dataSet1, String dataSet2 ) { super(factory, tolerance, dataSet1, dataSet2); } @Override public long getSteps() { return this.getDataSet1().getSize()+this.getDataSet2().getSize(); } @Override public void execute(final SimpleTaskStatus taskStatus, final TopologyReport report) { try { this.getDataSet1().accept((final Object o1) -> { if (taskStatus.isCancellationRequested()) { throw new VisitCanceledException(); } taskStatus.incrementCurrentValue(); try { check(taskStatus, report, (Feature) o1); } catch (Exception ex) { throw new RuntimeException(ex); } }); this.getDataSet2().accept((final Object o1) -> { if (taskStatus.isCancellationRequested()) { throw new VisitCanceledException(); } taskStatus.incrementCurrentValue(); try { check2(taskStatus, report, (Feature) o1); } catch (Exception ex) { throw new RuntimeException(ex); } }); } catch (VisitCanceledException ex) { // return; } } @Override protected void check(SimpleTaskStatus taskStatus, TopologyReport report, Feature feature1) throws Exception { FeatureSet set = null; try { FeatureStore store2 = this.getDataSet2().getFeatureStore(); if (this.expression == null) { this.expression = ExpressionUtils.createExpression(); this.expressionBuilder = GeometryExpressionUtils.createExpressionBuilder(); this.geomName = store2.getDefaultFeatureType().getDefaultGeometryAttributeName(); } Geometry polygon = feature1.getDefaultGeometry(); double theTolerance = getTolerance(); if(theTolerance > 0){ polygon = polygon.buffer(theTolerance); } TopologyDataSet theDataSet = this.getDataSet2(); int contained = 0; if (theDataSet.getSpatialIndex() != null) { for (FeatureReference featureReference : theDataSet.query(polygon)) { Feature feature2 = featureReference.getFeature(); Geometry otherPoint = feature2.getDefaultGeometry(); if (otherPoint != null && polygon.contains(otherPoint)) { contained++; break; } } } else { this.expression.setPhrase( this.expressionBuilder.ifnull( this.expressionBuilder.column(this.geomName), this.expressionBuilder.constant(false), this.expressionBuilder.ST_Contains( this.expressionBuilder.geometry(polygon), this.expressionBuilder.column(this.geomName) ) ).toString() ); FeatureSet featSet = theDataSet.getFeatureStore().getFeatureSet(this.expression); contained = featSet.size(); } if (contained <= 0) { I18nManager i18n = ToolsLocator.getI18nManager(); report.addLine(this, this.getDataSet1(), this.getDataSet2(), polygon, polygon, feature1.getReference(), null, false, i18n.getTranslation("_The_polygon_does_not_contain_any_points") ); } else if (contained > 1) { I18nManager i18n = ToolsLocator.getI18nManager(); report.addLine(this, this.getDataSet1(), this.getDataSet2(), polygon, polygon, feature1.getReference(), null, false, i18n.getTranslation("_The_polygon_contains_more_than_a_point") ); } } catch (Exception ex) { LOGGER.warn("Can't check feature.", ex); addCodeException(report, feature1, ex); } finally { if (set != null) { set.dispose(); } } } protected void check2(SimpleTaskStatus taskStatus, TopologyReport report, Feature feature2) throws Exception { FeatureSet set = null; try { TopologyDataSet theDataSet2 = this.getDataSet2(); TopologyDataSet theDataSet1 = this.getDataSet1(); FeatureStore otherStore = theDataSet1.getFeatureStore(); if (this.expression == null) { this.expression = ExpressionUtils.createExpression(); this.expressionBuilder = GeometryExpressionUtils.createExpressionBuilder(); this.geomName = otherStore.getDefaultFeatureType().getDefaultGeometryAttributeName(); } Geometry point = feature2.getDefaultGeometry(); if (theDataSet1.getSpatialIndex() != null) { boolean contained = false; for (FeatureReference otherFeatureReference : theDataSet1.query(point)) { Feature otherFeature = otherFeatureReference.getFeature(); Geometry otherPolygon = otherFeature.getDefaultGeometry(); if( otherPolygon!=null && otherPolygon.contains(point) ) { contained = true; break; } } if( !contained ) { I18nManager i18n = ToolsLocator.getI18nManager(); report.addLine(this, theDataSet1, theDataSet2, point, point, null, feature2.getReference(), false, i18n.getTranslation("_Point_is_not_contained_in_a_polygon") ); } } else { this.expression.setPhrase( this.expressionBuilder.ifnull( this.expressionBuilder.column(this.geomName), this.expressionBuilder.constant(false), this.expressionBuilder.ST_Contains( this.expressionBuilder.column(this.geomName), this.expressionBuilder.geometry(point) ) ).toString() ); if (theDataSet1.findFirst(this.expression) == null) { I18nManager i18n = ToolsLocator.getI18nManager(); report.addLine(this, theDataSet1, theDataSet2, point, point, null, feature2.getReference(), false, i18n.getTranslation("_Point_is_not_contained_in_a_polygon") ); } } } catch (Exception ex) { LOGGER.warn("Can't check feature.", ex); addCodeException(report, feature2, ex); } finally { if (set != null) { set.dispose(); } } } }