Package org.geomajas.gwt.client.spatial.snapping

Source Code of org.geomajas.gwt.client.spatial.snapping.IntersectPriorityMode

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/

package org.geomajas.gwt.client.spatial.snapping;

import java.util.ArrayList;
import java.util.List;

import org.geomajas.configuration.SnappingRuleInfo;
import org.geomajas.configuration.SnappingRuleInfo.SnappingType;
import org.geomajas.geometry.Coordinate;
import org.geomajas.gwt.client.map.feature.Feature;
import org.geomajas.gwt.client.spatial.Mathlib;
import org.geomajas.gwt.client.spatial.geometry.Geometry;
import org.geomajas.gwt.client.spatial.geometry.MultiLineString;
import org.geomajas.gwt.client.spatial.geometry.MultiPoint;
import org.geomajas.gwt.client.spatial.geometry.MultiPolygon;

/**
* <p>
* Implementation of the <code>SnappingHandler</code> that gives priority to geometries that intersect the original
* coordinate that is to be snapped. If no such geometry is found, then it continues the normal way: trying to snap to
* any geometry.
* </p>
* <p>
* When the {@link Snapper} uses <code>mode = SnapMode.PRIORITY_TO_INTERSECTING_GEOMETRIES</code> then this
* implementation of the <code>SnappingHandler</code> is used.
* </p>
*
* @author Pieter De Graef
*/
public class IntersectPriorityMode extends SnappingMode {

  /**
   * The snapping distance found on intersecting geometries only.
   */
  private double intersectDistance;

  /**
   * The snapped coordinate found when using intersecting geometries only.
   */
  private Coordinate intersectSnappedCoordinate;

  //-------------------------------------------------------------------------
  // Constructor:
  //-------------------------------------------------------------------------

  protected IntersectPriorityMode(SnappingRuleInfo rule) {
    super(rule);
  }

  public void execute(List<Feature> features) {
    List<Geometry> geometries = new ArrayList<Geometry>();

    for (Feature feature : features) {
      Geometry geometry = feature.getGeometry();
      // For multipolygons and multilinestrings, we calculate bounds intersection
      // for each partial geometry. This way we can send parts of the complex
      // geometries to the snapping list, and not always the entire geometry.(=faster)
      List<Geometry> currentGeometries = new ArrayList<Geometry>();
      if (geometry instanceof MultiLineString || geometry instanceof MultiPoint
          || geometry instanceof MultiPolygon) {
        for (int n = 0; n < geometry.getNumGeometries(); n++) {
          Geometry geometryN = geometry.getGeometryN(n);
          if (geometryN.getBounds().intersects(bounds)) {
            currentGeometries.add(geometryN);
          }
        }
      } else {
        if (geometry.getBounds().intersects(bounds)) {
          currentGeometries.add(geometry);
        }
      }
      if (currentGeometries.size() != 0) {
        if (Mathlib.isWithin(geometry, coordinate)) {
          SnappingAlgorithm algorithm;
          if (rule.getType() == SnappingType.CLOSEST_ENDPOINT) {
            algorithm = new ClosestPointAlgorithm(currentGeometries, rule.getDistance());
          } else {
            algorithm = new NearestAlgorithm(currentGeometries, rule.getDistance());
          }
          Coordinate snapPointIfFound = algorithm.getSnappingPoint(coordinate, intersectDistance);
          if (snapPointIfFound != null) {
            snappedCoordinate = snapPointIfFound;
            intersectSnappedCoordinate = snappedCoordinate;
            intersectDistance = algorithm.getMinimumDistance();
          }
        } else {
          geometries.addAll(currentGeometries);
        }
      }
    }

    if (intersectSnappedCoordinate == null && !geometries.isEmpty()) {
      SnappingAlgorithm algorithm;
      if (rule.getType() == SnappingType.CLOSEST_ENDPOINT) {
        algorithm = new ClosestPointAlgorithm(geometries, rule.getDistance());
      } else {
        algorithm = new NearestAlgorithm(geometries, rule.getDistance());
      }
      Coordinate snapPointIfFound = algorithm.getSnappingPoint(coordinate, intersectDistance);
      if (snapPointIfFound != null) {
        snappedCoordinate = snapPointIfFound;
        distance = algorithm.getMinimumDistance();
      }
    }
  }

  public void setCoordinate(Coordinate coordinate) {
    super.setCoordinate(coordinate);
    intersectDistance = Double.MAX_VALUE;
    intersectSnappedCoordinate = null;
  }
}
TOP

Related Classes of org.geomajas.gwt.client.spatial.snapping.IntersectPriorityMode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.