Esempio n. 1
0
bool
GeoClip::ClipPoint(const GeoPoint &origin, GeoPoint &pt) const
{
  const Angle zero = Angle::Zero();

  if (pt.longitude < zero) {
    if (origin.longitude <= zero)
      return false;

    pt = clip_longitude(origin, pt, zero);
  } else if (pt.longitude > width) {
    if (origin.longitude >= width)
      return false;

    pt = clip_longitude(origin, pt, width);
  }

  if (pt.latitude < south) {
    if (origin.latitude <= south)
      return false;

    pt = clip_latitude(origin, pt, south);
  } else if (pt.latitude > north) {
    if (origin.latitude >= north)
      return false;

    pt = clip_latitude(origin, pt, north);
  }

  return true;
}
Esempio n. 2
0
std::string olc_manipulate::shorten_single(std::string olc, double latitude, double longitude){
  if(!olc_check_full_single(olc)){
    throw std::range_error("The Open Location Codes provided must be complete. Incomplete code: " + olc);
  }

  if(olc.find(padding) != std::string::npos){
    throw std::range_error("The Open Location Codes provided cannot have padding characters. Padded code: " + olc);
  }

  for(unsigned int i = 0; i < olc.size(); i++){
    olc[i] = toupper(olc[i]);
  }

  std::vector < double > decoded_code = olc_decode_single(olc);
  if(decoded_code[6] < min_trim_length){
    throw std::range_error("Open Location Codes must be >6 in length to be shortened. Offending code: " + olc);
  }

  longitude = clip_longitude(longitude);
  latitude = clip_lat(latitude);
  double range = std::max(std::abs((double) decoded_code[5] - longitude), std::abs((double) decoded_code[4] - latitude));

  for(unsigned int i = resolution_levels.size() - 2; i >= 1; i--){
    if(range < (resolution_levels[i] * 0.3)){
      return olc.substr((i+1)*2);
    }
  }
  return olc;
}
Esempio n. 3
0
std::string olc_manipulate::recover_single(std::string olc, double latitude, double longitude){

  if(!olc_check_short_single(olc)){
    if(olc_check_full_single(olc)){
      return olc;
    }
    throw std::range_error("codes provided to recover_olc must be valid short Open Location Codes. Offending code: " + olc);
  }

  double ref_longitude = clip_longitude(longitude);
  double ref_latitude = clip_lat(latitude);

  for(unsigned int i = 0; i < olc.size(); i++){
    olc[i] = toupper(olc[i]);
  }

  int padding_length = (separator_position - olc.find(separator));
  double resolution = pow(20.0, (2.0 - (padding_length / 2.0)));
  double area_to_edge = resolution / 2.0;
  double round_lat = ref_latitude / resolution;
  double round_long = ref_longitude / resolution;

  std::vector < double > code_area = olc_decode_single(
    olc_encode_single(round_lat, round_long, max_pair_length).substr(0, padding_length) + olc
  );

  double degrees_difference = (code_area[4] - ref_latitude);
  if(degrees_difference > area_to_edge){
    code_area[4] -= resolution;
  } else if(degrees_difference < -area_to_edge){
    code_area[4] += resolution;
  }

  degrees_difference = (code_area[5] - ref_longitude);
  if(degrees_difference > area_to_edge){
    code_area[5] -= resolution;
  } else if(degrees_difference < -area_to_edge){
    code_area[5] += resolution;
  }

  return(olc_encode_single(code_area[4], code_area[5], code_area[6]));
}
Esempio n. 4
0
static unsigned
ClipVertexLongitude(const Angle west, const Angle east,
                    const GeoPoint &prev, GeoPoint &pt, GeoPoint &insert,
                    const GeoPoint &next)
{
  unsigned num_insert = 0;

  if (pt.longitude < west) {
    if (prev.longitude <= west) {
      if (next.longitude <= west)
        /* all three outside, middle one can be deleted */
        return 0;

      pt = clip_longitude(next, pt, west);
    } else {
      if (next.longitude > west) {
        /* both neighbours are inside, clip both lines and insert a
           new vertex */
        insert = clip_longitude(next, pt, west);
        ++num_insert;
      }

      pt = clip_longitude(prev, pt, west);
    }
  } else if (pt.longitude > east) {
    if (prev.longitude >= east) {
      if (next.longitude >= east)
        /* all three outside, middle one can be deleted */
        return 0;

      pt = clip_longitude(next, pt, east);
    } else {
      if (next.longitude < east) {
        /* both neighbours are inside, clip both lines and insert a
           new vertex */
        insert = clip_longitude(next, pt, east);
        ++num_insert;
      }

      pt = clip_longitude(prev, pt, east);
    }
  }

  return 1 + num_insert;
}