/** * 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.EditableFeature; 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.fmap.geom.primitive.Point; import org.gvsig.tools.ToolsLocator; import org.gvsig.tools.dynobject.DynObject; import org.gvsig.tools.i18n.I18nManager; import org.gvsig.tools.task.SimpleTaskStatus; import org.gvsig.topology.lib.api.ExecuteTopologyRuleActionException; import org.gvsig.topology.lib.api.TopologyDataSet; import org.gvsig.topology.lib.api.TopologyReport; import org.gvsig.topology.lib.api.TopologyReportLine; import org.gvsig.topology.lib.api.TopologyRule; import org.gvsig.topology.lib.api.TopologyRuleFactory; import org.gvsig.topology.lib.spi.AbstractTopologyRule; import org.gvsig.topology.lib.spi.AbstractTopologyRuleAction; /** * * @author jjdelcerro */ @SuppressWarnings("UseSpecificCatch") public class PolygonContainsPointRule extends AbstractTopologyRule { private class CreateFetureAction extends AbstractTopologyRuleAction { public CreateFetureAction() { super( PolygonContainsPointRuleFactory.NAME, "CreateFeature", "Create Feature", "The Create Feature fix creates a new point feature at the centroid of the polygon feature that is causing the error. The point feature that is created is guaranteed to be within the polygon feature." ); } @Override public int execute(TopologyRule rule, TopologyReportLine line, DynObject parameters) { try { Geometry polygon = line.getGeometry(); Point point = polygon.centroid(); if( !polygon.contains(point) ) { point = polygon.getInteriorPoint(); } TopologyDataSet dataSet = rule.getDataSet2(); EditableFeature feature = dataSet.createNewFeature(); feature.setDefaultGeometry(point); dataSet.insert(feature); return EXECUTE_OK; } catch (Exception ex) { throw new ExecuteTopologyRuleActionException(ex); } } } private String geomName; private Expression expression = null; private GeometryExpressionBuilder expressionBuilder = null; public PolygonContainsPointRule() { // for persistence only } public PolygonContainsPointRule( TopologyRuleFactory factory, double tolerance, String dataSet1, String dataSet2 ) { super(factory, tolerance, dataSet1, dataSet2); this.addAction(new CreateFetureAction()); } @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(); } double theTolerance = getTolerance(); Geometry polygon = feature1.getDefaultGeometry(); if(theTolerance > 0){ polygon = polygon.buffer(theTolerance); } TopologyDataSet theDataSet = this.getDataSet2(); if (theDataSet.getSpatialIndex() != null) { boolean contains = false; for (FeatureReference featureReference : theDataSet.query(polygon)) { Feature feature2 = featureReference.getFeature(); Geometry otherPoint = feature2.getDefaultGeometry(); if( otherPoint!=null && polygon.contains(otherPoint) ) { contains = true; break; } } if( !contains ) { polygon = feature1.getDefaultGeometry(); 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 { 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() ); if (theDataSet.findFirst(this.expression) == null) { polygon = feature1.getDefaultGeometry(); 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") ); } } } catch (Exception ex) { LOGGER.warn("Can't check feature.", ex); addCodeException(report, feature1, ex); } finally { if (set != null) { set.dispose(); } } } }