private LineSegment extractShorelineInterect(SimpleFeature feature) {

      Object sceObject = ((Double) feature.getAttribute(Constants.SCE_ATTR));
      Object nsdObject = feature.getAttribute(Constants.NSD_ATTR);

      Geometry geometry = (Geometry) feature.getDefaultGeometry();
      Coordinate[] coordinates = geometry.getCoordinates();
      LineSegment segment = new LineSegment(coordinates[0], coordinates[1]);

      double length = segment.getLength();

      double sce = sceObject instanceof Number ? ((Number) sceObject).doubleValue() : Double.NaN;
      double nsd = nsdObject instanceof Number ? ((Number) nsdObject).doubleValue() : Double.NaN;

      if (sce == sce && nsd == nsd) {
        return extractShorelineInterectAndCheckLength(segment, nsd, sce);
      } else {
        if (sce != sce && nsd != nsd) {
          return extractShorelineInterectAndCheckLength(segment, 0, length);
        }
        if (sce != sce) {
          sce = length - nsd;
        } else /* if nsd != nsd */ {
          nsd = length - sce;
        }
        return extractShorelineInterectAndCheckLength(segment, nsd, sce);
      }
    }
Esempio n. 2
0
  Geometry toShape(List<LineSegment> path, double h) {
    // TODO: take into account letter alignment
    // turn the path into a single polygon by generating points orthogonal
    // to the individual line segments
    GeomBuilder gb = new GeomBuilder();

    LinkedList<Coordinate> top = new LinkedList<Coordinate>();
    for (int i = 0; i < path.size(); i++) {
      LineSegment seg = path.get(i);
      Coordinate p0 = seg.p0;
      Coordinate p1 = seg.p1;
      double theta = seg.angle();

      gb.points(p0.x, p0.y);

      // generate the perpendicular point at a distance of h
      Coordinate p2 = new Coordinate();

      if (theta > 0) {
        if (theta <= HALFPI) {
          // ne
          double phi = Math.PI - (HALFPI + theta);
          p2.x = (Math.cos(phi) * h - p0.x) * -1;
          p2.y = Math.sin(phi) * h + p0.y;
        } else {
          // nw
          double phi = Math.PI - theta;
          p2.x = Math.cos(phi) * h + p0.x;
          p2.y = Math.sin(phi) * h + p0.y;
        }
      } else {
        theta = Math.abs(theta);
        if (theta < HALFPI) {
          double phi = HALFPI - theta;
          p2.x = (Math.cos(phi) * h + p0.x);
          p2.y = (Math.sin(phi) * h + p0.y);
        } else {
          double phi = theta = HALFPI;
          p2.x = Math.cos(phi) * h + p0.x;
          p2.y = (Math.sin(phi) * h - p0.y) * -1;
        }
      }

      top.add(p2);
      if (i == path.size() - 1) {
        gb.points(p1.x, p1.y);
        top.add(new Coordinate(p1.x + p2.x - p0.x, p1.y + p2.y - p0.y));
      }
    }

    for (Iterator<Coordinate> it = top.descendingIterator(); it.hasNext(); ) {
      Coordinate c = it.next();
      gb.points(c.x, c.y);
    }

    return gb.toPolygon();
  }
Esempio n. 3
0
 @Override
 public boolean intersects(Rectangle r) {
   GeometryFactory gf = new GeometryFactory();
   GeometricShapeFactory f = new GeometricShapeFactory(gf);
   f.setBase(new Coordinate(r.x1(), r.y1()));
   f.setWidth(r.x2() - r.x1());
   f.setHeight(r.y2() - r.y1());
   Polygon rect = f.createRectangle();
   LineSegment line = new LineSegment(x1, y1, x2, y2);
   return RectangleIntersects.intersects(rect, line.toGeometry(gf));
 }
Esempio n. 4
0
  public void pushSegment(final LineSegment segment) {
    final double length = segment.getLength();

    /* update station of segment points */
    m_length1 = m_length2;
    m_length2 = m_length1 + length;

    /* update distance at station */
    // REMARK: NaN check needed for very first segment
    m_distance1 = Double.isNaN(m_distance2) ? m_bufferBuilder.getDistance(m_length1) : m_distance2;
    m_distance2 = m_bufferBuilder.getDistance(m_length2);

    /*
     * Only push the segment, if length is greater than the tolerance, the distance is always updated however, in order
     * to keep the correct stationing of the line
     */
    if (length > m_tolerance) {
      m_segment0 = m_segment1;
      m_segment1 = segment;

      m_buffer0 = m_buffer1;
      m_buffer1 = calculateBuffer(m_segment1, m_distance1, m_distance2);
    }

    addBufferCoordinates();
  }
  /**
   * Computes the closest points on two line segments.
   *
   * @param line the segment to find the closest point to
   * @return a pair of Coordinates which are the closest points on the line segments
   */
  public Coordinate[] closestPoints(LineSegment line) {
    // test for intersection
    Coordinate intPt = intersection(line);
    if (intPt != null) {
      return new Coordinate[] {intPt, intPt};
    }

    /**
     * if no intersection closest pair contains at least one endpoint. Test each endpoint in turn.
     */
    Coordinate[] closestPt = new Coordinate[2];
    double minDistance = Double.MAX_VALUE;
    double dist;

    Coordinate close00 = closestPoint(line.p0);
    minDistance = close00.distance(line.p0);
    closestPt[0] = close00;
    closestPt[1] = line.p0;

    Coordinate close01 = closestPoint(line.p1);
    dist = close01.distance(line.p1);
    if (dist < minDistance) {
      minDistance = dist;
      closestPt[0] = close01;
      closestPt[1] = line.p1;
    }

    Coordinate close10 = line.closestPoint(p0);
    dist = close10.distance(p0);
    if (dist < minDistance) {
      minDistance = dist;
      closestPt[0] = p0;
      closestPt[1] = close10;
    }

    Coordinate close11 = line.closestPoint(p1);
    dist = close11.distance(p1);
    if (dist < minDistance) {
      minDistance = dist;
      closestPt[0] = p1;
      closestPt[1] = close11;
    }

    return closestPt;
  }
Esempio n. 6
0
  /**
   * Adds a limited mitre join connecting the two reflex offset segments. A limited mitre is a mitre
   * which is beveled at the distance determined by the mitre ratio limit.
   *
   * @param offset0 the first offset segment
   * @param offset1 the second offset segment
   * @param distance the offset distance
   * @param mitreLimit the mitre limit ratio
   */
  private void addLimitedMitreJoin(final double distance, final double mitreLimit) {
    final Coordinate basePt = m_segment0.p1;

    final double ang0 = Angle.angle(basePt, m_segment0.p0);

    // oriented angle between segments
    final double angDiff = Angle.angleBetweenOriented(m_segment0.p0, basePt, m_segment1.p1);
    // half of the interior angle
    final double angDiffHalf = angDiff / 2;

    // angle for bisector of the interior angle between the segments
    final double midAng = Angle.normalize(ang0 + angDiffHalf);
    // rotating this by PI gives the bisector of the reflex angle
    final double mitreMidAng = Angle.normalize(midAng + Math.PI);

    // the miterLimit determines the distance to the mitre bevel
    final double mitreDist = mitreLimit * distance;
    // the bevel delta is the difference between the buffer distance
    // and half of the length of the bevel segment
    final double bevelDelta = mitreDist * Math.abs(Math.sin(angDiffHalf));
    final double bevelHalfLen = distance - bevelDelta;

    // compute the midpoint of the bevel segment
    final double bevelMidX = basePt.x + mitreDist * Math.cos(mitreMidAng);
    final double bevelMidY = basePt.y + mitreDist * Math.sin(mitreMidAng);
    final Coordinate bevelMidPt = new Coordinate(bevelMidX, bevelMidY);

    // compute the mitre midline segment from the corner point to the bevel segment midpoint
    final LineSegment mitreMidLine = new LineSegment(basePt, bevelMidPt);

    // finally the bevel segment endpoints are computed as offsets from
    // the mitre midline
    final Coordinate bevelEndLeft = mitreMidLine.pointAlongOffset(1.0, bevelHalfLen);
    final Coordinate bevelEndRight = mitreMidLine.pointAlongOffset(1.0, -bevelHalfLen);

    if (m_side == Position.LEFT) {
      m_bufferBuilder.addVertices(bevelEndLeft);
      m_bufferBuilder.addVertices(bevelEndRight);
    } else {
      m_bufferBuilder.addVertices(bevelEndRight);
      m_bufferBuilder.addVertices(bevelEndLeft);
    }
  }
  public void run(IProgressMonitor monitor) throws Exception {

    final ILayer editLayer = handler.getEditLayer();
    final Point mouseLocation = position;

    final EditBlackboard layerBlackboard = handler.getEditBlackboard(editLayer);
    final boolean includeSegmentsInCurrent = true;
    final SnapBehaviour snapBehaviour = SnapBehaviour.CURRENT_LAYER;

    final CoordinateReferenceSystem mapCrs = handler.getContext().getCRS();
    final int snappingRadius = PreferenceUtil.instance().getSnappingRadius();

    final SnapSegmentFinder segmentFinder = new SnapSegmentFinder(mapCrs);
    List<LineSegment> linesList = new ArrayList<LineSegment>();
    LineSegment closestSnapSegment;
    closestSnapSegment =
        segmentFinder.getClosestSnapSegment(
            handler,
            layerBlackboard,
            mouseLocation,
            includeSegmentsInCurrent,
            snapBehaviour,
            snappingRadius);

    if (closestSnapSegment != null) {
      CoordinateReferenceSystem layerCrs = editLayer.getCRS();
      closestSnapSegment = GeoToolsUtils.reproject(closestSnapSegment, mapCrs, layerCrs);
    }
    linesList.add(closestSnapSegment);
    if (this.mapMouseEvent.isShiftDown()) {
      this.segmentCopyContext.addSegments(linesList);
    } else {
      this.segmentCopyContext.setReferenceLineSegment(closestSnapSegment);
    }
    this.segmentCopyContext.setMode(PrecisionToolsMode.WAITING);

    System.out.println("\nSegment: " + closestSnapSegment.toString());
  }
 private void simplifySection(int i, int j) {
   if ((i + 1) == j) {
     return;
   }
   seg.p0 = pts[i];
   seg.p1 = pts[j];
   double maxDistance = -1.0;
   int maxIndex = i;
   for (int k = i + 1; k < j; k++) {
     double distance = seg.distance(pts[k]);
     if (distance > maxDistance) {
       maxDistance = distance;
       maxIndex = k;
     }
   }
   if (maxDistance <= distanceTolerance) {
     for (int k = i + 1; k < j; k++) {
       usePt[k] = false;
     }
   } else {
     simplifySection(i, maxIndex);
     simplifySection(maxIndex, j);
   }
 }
 private LineSegment extractShorelineInterectAndCheckLength(
     LineSegment transect, double nsd, double sce) {
   double tl = transect.getLength();
   LineSegment shorelineIntersect =
       new LineSegment(transect.pointAlong(nsd / tl), transect.pointAlong((nsd + sce) / tl));
   double shorelineIntersectLength = shorelineIntersect.getLength();
   if (minimumLengthMeters > 0 && shorelineIntersectLength < minimumLengthMeters) {
     double halfRatio = (minimumLengthMeters / shorelineIntersectLength) / 2;
     shorelineIntersect =
         new LineSegment(
             shorelineIntersect.pointAlong(0 - halfRatio),
             shorelineIntersect.pointAlong(1 + halfRatio));
   }
   return shorelineIntersect;
 }
  /*
   * (non-Javadoc)
   *
   * @see com.iver.cit.gvsig.gui.cad.snapping.ISnapper#getSnapPoint(Point2D
   * point, IGeometry geom,double tolerance, Point2D lastPointEntered)
   */
  public Point2D getSnapPoint(
      Point2D point, IGeometry geom, double tolerance, Point2D lastPointEntered) {
    Point2D resul = null;
    Coordinate c = new Coordinate(point.getX(), point.getY());

    if (lastPointEntered == null) {
      return null;
    }

    Coordinate cLastPoint = new Coordinate(lastPointEntered.getX(), lastPointEntered.getY());
    PathIterator theIterator =
        geom.getPathIterator(null, FConverter.FLATNESS); // polyLine.getPathIterator(null,
    // flatness);
    double[] theData = new double[6];
    double minDist = tolerance;
    Coordinate from = null;
    Coordinate first = null;

    while (!theIterator.isDone()) {
      // while not done
      int theType = theIterator.currentSegment(theData);

      switch (theType) {
        case PathIterator.SEG_MOVETO:
          from = new Coordinate(theData[0], theData[1]);
          first = from;

          break;

        case PathIterator.SEG_LINETO:

          // System.out.println("SEG_LINETO");
          Coordinate to = new Coordinate(theData[0], theData[1]);
          LineSegment line = new LineSegment(from, to);
          Coordinate closestPoint = line.closestPoint(cLastPoint);
          double dist = c.distance(closestPoint);

          if (!(line.getCoordinate(0).equals2D(closestPoint)
              || line.getCoordinate(1).equals2D(closestPoint))) {
            if ((dist < minDist)) {
              resul = new Point2D.Double(closestPoint.x, closestPoint.y);
              minDist = dist;
            }
          }

          from = to;

          break;

        case PathIterator.SEG_CLOSE:
          line = new LineSegment(from, first);
          closestPoint = line.closestPoint(cLastPoint);
          dist = c.distance(closestPoint);

          if (!(line.getCoordinate(0).equals2D(closestPoint)
              || line.getCoordinate(1).equals2D(closestPoint))) {
            if ((dist < minDist)) {
              resul = new Point2D.Double(closestPoint.x, closestPoint.y);
              minDist = dist;
            }
          }

          from = first;

          break;
      } // end switch

      theIterator.next();
    }

    return resul;
  }
 public void select(LineSegment ls) {
   rcc.countSegment(ls.getCoordinate(0), ls.getCoordinate(1));
 }
Esempio n. 12
0
 public void visitItem(Object item) {
   LineSegment seg = (LineSegment) item;
   counter.countSegment(seg.getCoordinate(0), seg.getCoordinate(1));
 }