001: /* uDig - User Friendly Desktop Internet GIS client
002: * http://udig.refractions.net
003: * (C) 2004, Refractions Research Inc.
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation;
008: * version 2.1 of the License.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: */
015: package net.refractions.udig.tools.edit.validator;
016:
017: import java.util.List;
018:
019: import net.refractions.udig.project.ui.render.displayAdapter.MapMouseEvent;
020: import net.refractions.udig.tool.edit.internal.Messages;
021: import net.refractions.udig.tools.edit.EditToolHandler;
022: import net.refractions.udig.tools.edit.EventType;
023: import net.refractions.udig.tools.edit.behaviour.IEditValidator;
024: import net.refractions.udig.tools.edit.support.EditBlackboard;
025: import net.refractions.udig.tools.edit.support.EditGeom;
026: import net.refractions.udig.tools.edit.support.EditUtils;
027: import net.refractions.udig.tools.edit.support.Point;
028: import net.refractions.udig.tools.edit.support.PrimitiveShape;
029: import net.refractions.udig.tools.edit.support.ShapeType;
030:
031: /**
032: * Checks for:
033: *
034: * <ul>
035: * <li>If polygon:
036: * <ul>
037: * <li>Self Intersection in each part of the each geometry that is flagged as changed</li>
038: * <li>Intersection between holes</li>
039: * <li>All holes are contained within shell</li>
040: * </ul>
041: * </li>
042: * <li>If other shapes then anything goes</li>
043: * </ul>
044: * @author Jesse
045: * @since 1.1.0
046: */
047: public class LegalShapeValidator implements IEditValidator {
048:
049: String holeOverlap = Messages.LegalShapeValidator_holeOverlap;
050: String holeOutside = Messages.LegalShapeValidator_holeOutside;
051:
052: public String isValid(EditToolHandler handler, MapMouseEvent event,
053: EventType type) {
054: EditBlackboard editBlackboard = handler
055: .getEditBlackboard(handler.getEditLayer());
056: List<EditGeom> geoms = editBlackboard.getGeoms();
057: for (EditGeom geom : geoms) {
058: if (geom.isChanged()
059: && geom.getShapeType() == ShapeType.POLYGON) {
060: String message = test(geom);
061: if (message != null) {
062: return message;
063: }
064: }
065: }
066: return null;
067: }
068:
069: private String test(EditGeom geom) {
070: String message = testSelfIntersection(geom);
071: if (message != null)
072: return message;
073: message = testHoleIntersection(geom);
074: if (message != null)
075: return message;
076: message = testShellContainsHoles(geom);
077: return message;
078: }
079:
080: private String testSelfIntersection(EditGeom geom) {
081: if (EditUtils.instance.selfIntersection(geom.getShell())) {
082: return Messages.LegalShapeValidator_shellIntersection;
083: }
084: for (PrimitiveShape hole : geom.getHoles()) {
085: if (EditUtils.instance.selfIntersection(hole)) {
086: return Messages.LegalShapeValidator_holeIntersection;
087: }
088: }
089: return null;
090: }
091:
092: private String testHoleIntersection(EditGeom geom) {
093: for (PrimitiveShape hole : geom.getHoles()) {
094: for (PrimitiveShape hole2 : geom.getHoles()) {
095: if (hole == hole2)
096: continue;
097:
098: if (hole.overlap(hole2, true, false))
099: return Messages.LegalShapeValidator_holeOverlap;
100: }
101: }
102: return null;
103: }
104:
105: private String testShellContainsHoles(EditGeom geom) {
106: for (PrimitiveShape shape : geom.getHoles()) {
107: for (Point point : shape) {
108: if (!geom.getShell().contains(point, true, true))
109: return Messages.LegalShapeValidator_holeOutside;
110: }
111: }
112: return null;
113: }
114:
115: }
|