コード例 #1
0
  /**
   * Checks that a transformation produces the expected result
   *
   * @param x the input pt x
   * @param y the input pt y
   * @param trans the transformation
   * @param xp the expected output x
   * @param yp the expected output y
   */
  void checkTransformation(double x, double y, AffineTransformation trans, double xp, double yp) {
    Coordinate p = new Coordinate(x, y);
    Coordinate p2 = new Coordinate();
    trans.transform(p, p2);
    assertEquals(xp, p2.x, .00005);
    assertEquals(yp, p2.y, .00005);

    // if the transformation is invertible, test the inverse
    try {
      AffineTransformation invTrans = trans.getInverse();
      Coordinate pInv = new Coordinate();
      invTrans.transform(p2, pInv);
      assertEquals(x, pInv.x, .00005);
      assertEquals(y, pInv.y, .00005);

      double det = trans.getDeterminant();
      double detInv = invTrans.getDeterminant();
      assertEquals(det, 1.0 / detInv, .00005);

    } catch (NoninvertibleTransformationException ex) {
    }
  }
コード例 #2
0
  /**
   * Create device locations in a path near the main zone.
   *
   * @param assignment
   * @param start
   * @return
   * @throws SiteWhereException
   */
  protected List<IDeviceLocation> createDeviceLocations(IDeviceAssignment assignment, Date date)
      throws SiteWhereException {
    long current = date.getTime();
    Polygon zone = GeoUtils.createPolygonForLocations(zoneLocations);
    Point centroid = zone.getCentroid();

    // Calculate length of steps between locations based on bounding circle.
    MinimumBoundingCircle circle = new MinimumBoundingCircle(zone);
    double step = circle.getRadius() / 10;

    double cx = centroid.getX();
    double cy = centroid.getY();
    double deltaX = (Math.sqrt(Math.random()) * step * 2) - step;
    double deltaY = (Math.sqrt(Math.random()) * step * 2) - step;

    // Used to rotate deltas to turn path and stay inside polygon.
    AffineTransformation xform = new AffineTransformation();
    xform.rotate(Math.toRadians(22.5));

    List<IDeviceLocation> results = new ArrayList<IDeviceLocation>();
    GeometryFactory factory = new GeometryFactory();
    for (int x = 0; x < LOCATIONS_PER_ASSIGNMENT; x++) {
      boolean foundNext = false;

      // Add a little randomness to path.
      double waver = ((Math.random() * 20) - 10.0);
      AffineTransformation waverXform = new AffineTransformation();
      waverXform.rotate(Math.toRadians(waver));
      Coordinate waverDelta = new Coordinate(deltaX, deltaY);
      waverXform.transform(waverDelta, waverDelta);
      deltaX = waverDelta.x;
      deltaY = waverDelta.y;

      while (!foundNext) {
        Coordinate start = new Coordinate(cx, cy);
        Coordinate end = new Coordinate(cx + deltaX, cy + deltaY);
        Coordinate[] lineCoords = {start, end};
        LineString line = factory.createLineString(lineCoords);
        if (zone.contains(line)) {
          DeviceLocationCreateRequest request = new DeviceLocationCreateRequest();
          request.setLatitude(end.y);
          request.setLongitude(end.x);
          request.setElevation(0.0);
          request.setEventDate(new Date(current));
          IDeviceLocation created =
              getDeviceManagement().addDeviceLocation(assignment.getToken(), request);
          results.add(created);

          cx = cx + deltaX;
          cy = cy + deltaY;
          foundNext = true;
        } else {
          // Rotate deltas and try again.
          Coordinate delta = new Coordinate(deltaX, deltaY);
          xform.transform(delta, delta);
          deltaX = delta.x;
          deltaY = delta.y;
        }
      }
      current += 30000;
    }
    LOGGER.info(PREFIX_CREATE_EVENTS + " " + results.size() + " locations. ");
    return results;
  }