Esempio n. 1
0
static void line_samp_to_proj(ImageInfo *ii, double line, double samp,
                              double *x, double *y)
{
  meta_parameters *meta = ii->meta;
  if (meta_supports_meta_get_latLon(meta))
  {
    double lat, lon, projZ;
    meta_get_latLon(meta, line, samp, 0, &lat, &lon);
    if (meta->projection &&
        meta->projection->type != LAT_LONG_PSEUDO_PROJECTION)
    {
      latlon_to_proj(meta->projection, 'R', lat*D2R, lon*D2R, 0,
                     x, y, &projZ);
    }
    else {
      int zone;
      if (meta_is_valid_double(meta->general->center_longitude) &&
          meta->general->center_longitude > -180 &&
          meta->general->center_longitude < 180)
      {
        zone = utm_zone(meta->general->center_longitude);
      }
      else {
        zone = utm_zone(lon);
      }
      latLon2UTM_zone(lat, lon, 0, zone, x, y);
    }
  } else {
    *x = samp;
    *y = line;
  }
}
Esempio n. 2
0
void fill_in_utm(double lat, double lon, project_parameters_t *pps)
{
  pps->utm.zone = utm_zone(lon);
  pps->utm.scale_factor = 0.9996;
  pps->utm.lon0 = (double) (pps->utm.zone - 1) * 6.0 - 177.0;
  pps->utm.lat0 = 0.0;
  pps->utm.false_easting = 500000.0;
  if (lat > 0.0)
    pps->utm.false_northing = 0.0;
  else
    pps->utm.false_northing = 10000000.0;
}
Esempio n. 3
0
static int proj_getls(double *line, double *samp)
{
  meta_parameters *meta = curr->meta;
  if (meta->projection || (meta->sar&&meta->state_vectors) ||
      meta->transform || meta->airsar)
  {
    double x = get_double_from_entry("go_to_projx_entry");
    double y = get_double_from_entry("go_to_projy_entry");

    double lat, lon;

    if (curr->meta->projection) {
      double h;
      proj_to_latlon(curr->meta->projection, x, y, 0, &lat, &lon, &h);
      if (lat==y && lon==x) {
        // this is usually indicative of failure... an error will have
        // been printed out already by libproj
        return FALSE;
      }
      lat *= R2D;
      lon *= R2D;
    }
    else {
      int zone = utm_zone(curr->meta->general->center_longitude);
      asfPrintStatus("Unprojected data -- assuming UTM (zone: %d)\n", zone);
      UTM2latLon(x, y, 0, zone, &lat, &lon);
      if (lat==y*R2D && lon==x*R2D) {
        // this is usually indicative of failure... an error will have
        // been printed out already by libproj
        return FALSE;
      }
    }

    int bad = meta_get_lineSamp(curr->meta, lat, lon, 0, line, samp);
    return !bad;
  }
  else {
    asfPrintWarning("No geolocation information available -- GoTo will only\n"
                    "work for GoTo by Line/Sample.\n");
    return FALSE;

  }
}
Esempio n. 4
0
void location_to_latlon(meta_parameters *meta,
			double x, double y, double z,
			double *lat_d, double *lon, double *height)
{
  double x_ul, y_ul, x_ur, y_ur, x_ll, y_ll, x_lr, y_lr;
  
  // Define the UTM zone to make sure everything happens to make sure that
  // everything happens in the right coordinate space.
  int zone = utm_zone(meta->general->center_longitude);

  // Get corner coordinates into UTM
  latLon2UTM_zone(meta->location->lat_start_near_range,
		  meta->location->lon_start_near_range, 0.0, zone,
		  &x_ul, &y_ul);
  latLon2UTM_zone(meta->location->lat_start_far_range,
		  meta->location->lon_start_far_range, 0.0, zone,
		  &x_ur, &y_ur);
  latLon2UTM_zone(meta->location->lat_end_near_range,
		  meta->location->lon_end_near_range, 0.0, zone,
		  &x_ll, &y_ll);
  latLon2UTM_zone(meta->location->lat_end_far_range,
		  meta->location->lon_end_far_range, 0.0, zone,
		  &x_lr, &y_lr);

  // Bilinear interpolation to determine line/sample position in UTM coords
  double x_scale = x / meta->general->sample_count;
  double y_scale = y / meta->general->line_count;
  double x_up = x_ul + x_scale*(x_ur - x_ul);
  double y_up = y_ul + x_scale*(y_ur - y_ul);
  double x_down = x_ll + x_scale*(x_lr - x_ll);
  double y_down = y_ll + x_scale*(y_lr - y_ll);
  double x_sample = x_up + y_scale*(x_down - x_up);
  double y_line = y_up + y_scale*(y_down - y_up);

  // Convert from UTM coordinates back to lat/lon and call it a day
  UTM2latLon(x_sample, y_line, 0.0, zone, lat_d, lon);
  *height = 0.0;
}
Esempio n. 5
0
static Poly *
get_viewable_region(stateVector *st, BeamModeInfo *bmi, double look_angle,
                    int target_zone, double target_lat, double target_lon,
                    double *region_clat, double *region_clon)
{
  static const int verbose = FALSE;

  if (bmi->min_look_angle>0) {
    assert(look_angle >= D2R*(bmi->min_look_angle-.0001));
    assert(look_angle <= D2R*(bmi->max_look_angle+.0001));
  }

  double center_lat, center_lon, center_x, center_y;
  get_target_latlon(st, look_angle, &center_lat, &center_lon);

  // return NULL if we are "far away" (UTM only)
  if (is_utm(target_zone)) {
    int zone = utm_zone(center_lon);
    if (iabs(zone - target_zone) > 2)
      return NULL;
  }
  if (fabs(center_lat - target_lat) > 20)
    return NULL;

  ll2pr(center_lat, center_lon, target_zone, &center_x, &center_y);
  if (verbose) {
    printf("--------------------------------------------------------------\n");
    printf("center: x,y: %f %f lat,lon: %f %f\n",
           center_x, center_y, center_lat, center_lon);
  }

  // location of a point just a bit ahead of us
  stateVector ahead_st = propagate(*st, 0, 1);
  double ahead_lat, ahead_lon, ahead_x, ahead_y;
  get_target_latlon(&ahead_st, look_angle, &ahead_lat, &ahead_lon);
  ll2pr(ahead_lat, ahead_lon, target_zone, &ahead_x, &ahead_y);
  if (verbose)
    printf("ahead: x,y: %f %f lat,lon: %f %f\n",
           ahead_x, ahead_y, ahead_lat, ahead_lon);

  // now we know the orientation of the rectangle on the ground
  // ==> can find the 4 corners
  double tilt = atan2(ahead_y-center_y, ahead_x-center_x);
  double xl = bmi->length_m;
  double yl = bmi->width_m;

  double x_side1 = cos(tilt)*xl;
  double y_side1 = sin(tilt)*xl;
  double x_side2 = sin(tilt)*yl;
  double y_side2 = cos(tilt)*yl;

  double x[4], y[4];

  //x[0] = center_x + x_side1/2. - x_side2/2.;
  //y[0] = center_y + y_side1/2. - y_side2/2.;
  x[0] = center_x + x_side1/2. - x_side2/2.;
  y[0] = center_y + y_side1/2. + y_side2/2.;

  x[1] = x[0] - x_side1;
  y[1] = y[0] - y_side1;

  x[2] = x[1] + x_side2;
  y[2] = y[1] - y_side2;

  x[3] = x[2] + x_side1;
  y[3] = y[2] + y_side1;

  if (verbose) {
    int i;
    printf("corners:\n");
    double xa=0, ya=0;
    for (i=0; i<4; ++i) {
      double lat, lon;
      pr2ll(x[i],y[i],target_zone,&lat,&lon);
      printf("x,y: %f %f lat,lon: %f %f\n", x[i], y[i], lat, lon);
      xa += x[i]; ya += y[i];
    }
    xa/=4.; ya/=4.;
    double lata, lona;
    pr2ll(xa,ya,target_zone, &lata, &lona);
    printf("avg x,y: %f %f lat,lon: %f %f\n\n", xa, ya, lata, lona);
  }

  if (region_clat) *region_clat = center_lat;
  if (region_clon) *region_clon = center_lon;

  return polygon_new_closed(4, x, y);
}
Esempio n. 6
0
int main(int c, char *v[])
{
    if (c < 6 || c > 48) {
        help(v[0]);
        return 1;
    }

    // utm zone and hemisphere: true for 'N' and false for 'S'
    int zone;
    bool hem;
    const char *utm_string = pick_option(&c, &v, "-utm-zone", "no_utm_zone");
    parse_utm_string(&zone, &hem, utm_string);

    // ascii flag
    bool ascii = pick_option(&c, &v, "-ascii", NULL);

    // longitude-latitude bounding box
    double lon_m = atof(pick_option(&c, &v, "-lon-m", "-inf"));
    double lon_M = atof(pick_option(&c, &v, "-lon-M", "inf"));
    double lat_m = atof(pick_option(&c, &v, "-lat-m", "-inf"));
    double lat_M = atof(pick_option(&c, &v, "-lat-M", "inf"));

    // x-y bounding box
    double col_m = atof(pick_option(&c, &v, "-col-m", "-inf"));
    double col_M = atof(pick_option(&c, &v, "-col-M", "inf"));
    double row_m = atof(pick_option(&c, &v, "-row-m", "-inf"));
    double row_M = atof(pick_option(&c, &v, "-row-M", "inf"));

    // mask on the unrectified image grid
    const char *msk_orig_fname = pick_option(&c, &v, "-mask-orig", "");
    int msk_orig_w, msk_orig_h;
    float *msk_orig = iio_read_image_float(msk_orig_fname, &msk_orig_w,
                                           &msk_orig_h);

    // rectifying homography
    double href_inv[9], hsec_inv[9];
    int n_hom;
    const char *hom_string_ref = pick_option(&c, &v, "href", "");
    if (*hom_string_ref) {
        double *hom = alloc_parse_doubles(9, hom_string_ref, &n_hom);
        if (n_hom != 9)
            fail("can not read 3x3 matrix from \"%s\"", hom_string_ref);
        invert_homography(href_inv, hom);
    }
    const char *hom_string_sec = pick_option(&c, &v, "hsec", "");
    if (*hom_string_sec) {
        double *hom = alloc_parse_doubles(9, hom_string_sec, &n_hom);
        if (n_hom != 9)
            fail("can not read 3x3 matrix from \"%s\"", hom_string_sec);
        invert_homography(hsec_inv, hom);
    }

    // open disp and mask input images
    int w, h, nch, ww, hh, pd;
    float *dispy;
    float *dispx = iio_read_image_float_split(v[2], &w, &h, &nch);
    if (nch > 1) dispy = dispx + w*h;
    else dispy = calloc(w*h, sizeof(*dispy));

    float *mask = iio_read_image_float(v[3], &ww, &hh);
    if (w != ww || h != hh) fail("disp and mask image size mismatch\n");

    // open color images if provided
    uint8_t *clr = NULL;
    if (c > 6) {
        clr = iio_read_image_uint8_vec(v[6], &ww, &hh, &pd);
        if (w != ww || h != hh) fail("disp and color image size mismatch\n");
    }

    // read input rpc models
    struct rpc rpc_ref[1], rpc_sec[1];
    read_rpc_file_xml(rpc_ref, v[4]);
    read_rpc_file_xml(rpc_sec, v[5]);

    // outputs
    double p[2], q[2], X[3];

    // count number of valid pixels, and determine utm zone
    int npoints = 0;
    for (int row=0; row<h; row++)
    for (int col=0; col<w; col++) {
        int pix = row*w + col;
        if (!mask[pix]) continue;

        // compute coordinates of pix in the full reference image
        double a[2] = {col, row};
        apply_homography(p, href_inv, a);

        // check that it lies in the image domain bounding box
        if (round(p[0]) < col_m || round(p[0]) > col_M ||
            round(p[1]) < row_m || round(p[1]) > row_M)
            continue;

        // check that it passes the image domain mask
        int x = (int) round(p[0]) - col_m;
        int y = (int) round(p[1]) - row_m;
        if ((x < msk_orig_w) && (y < msk_orig_h))
            if (!msk_orig[y * msk_orig_w + x])
                continue;

        // compute (lon, lat, alt) of the 3D point
        float dx = dispx[pix];
        float dy = dispy[pix];
        double b[2] = {col + dx, row + dy};
        apply_homography(q, hsec_inv, b);
        intersect_rays(X, p, q, rpc_ref, rpc_sec);

        // check with lon/lat bounding box
        if (X[0] < lon_m || X[0] > lon_M || X[1] < lat_m || X[1] > lat_M)
            continue;

        // if it passed all these tests then it's a valid point
        npoints++;

        // if not defined, utm zone is that of the first point
        if (zone < 0)
            utm_zone(&zone, &hem, X[1], X[0]);
    }

    // print header for ply file
    FILE *ply_file = fopen(v[1], "w");
    write_ply_header(ply_file, ascii, npoints, zone, hem, (bool) clr, false);

    // loop over all the pixels of the input disp map
    // a 3D point is produced for each non-masked disparity
    for (int row=0; row<h; row++)
    for (int col=0; col<w; col++) {
        int pix = row*w + col;
        if (!mask[pix]) continue;

        // compute coordinates of pix in the full reference image
        double a[2] = {col, row};
        apply_homography(p, href_inv, a);

        // check that it lies in the image domain bounding box
        if (round(p[0]) < col_m || round(p[0]) > col_M ||
            round(p[1]) < row_m || round(p[1]) > row_M)
            continue;

        // check that it passes the image domain mask
        int x = (int) round(p[0]) - col_m;
        int y = (int) round(p[1]) - row_m;
        if ((x < msk_orig_w) && (y < msk_orig_h))
            if (!msk_orig[y * msk_orig_w + x])
                continue;

        // compute (lon, lat, alt) of the 3D point
        float dx = dispx[pix];
        float dy = dispy[pix];
        double b[2] = {col + dx, row + dy};
        apply_homography(q, hsec_inv, b);
        intersect_rays(X, p, q, rpc_ref, rpc_sec);

        // check with lon/lat bounding box
        if (X[0] < lon_m || X[0] > lon_M || X[1] < lat_m || X[1] > lat_M)
            continue;

        // convert (lon, lat, alt) to utm
        utm_alt_zone(X, X[1], X[0], zone);

        // colorization: if greyscale, copy the grey level on each channel
        uint8_t rgb[3];
        if (clr) {
            for (int k = 0; k < pd; k++) rgb[k] = clr[k + pd*pix];
            for (int k = pd; k < 3; k++) rgb[k] = rgb[k-1];
        }

        // write to ply
        if (ascii) {
            fprintf(ply_file, "%0.17g %0.17g %0.17g ", X[0], X[1], X[2]);
            if (clr)
                fprintf(ply_file, "%d %d %d", rgb[0], rgb[1], rgb[2]);
            fprintf(ply_file, "\n");
        } else {
            double XX[3] = {X[0], X[1], X[2]};
            fwrite(XX, sizeof(double), 3, ply_file);
            if (clr) {
                unsigned char C[3] = {rgb[0], rgb[1], rgb[2]};
                fwrite(rgb, sizeof(unsigned char), 3, ply_file);
            }
        }
    }

    fclose(ply_file);
    return 0;
}
Esempio n. 7
0
// return TRUE if there is any overlap between the two scenes
static int test_overlap(meta_parameters *meta1, meta_parameters *meta2)
{
    if (!meta_is_valid_double(meta1->general->center_longitude)) {
        int nl = meta1->general->line_count;
        int ns = meta1->general->sample_count;

        meta_get_latLon(meta1, nl/2, ns/2, 0,
            &meta1->general->center_latitude,
            &meta1->general->center_longitude);
    }

    if (!meta_is_valid_double(meta2->general->center_longitude)) {
        int nl = meta2->general->line_count;
        int ns = meta2->general->sample_count;

        meta_get_latLon(meta2, nl/2, ns/2, 0,
            &meta2->general->center_latitude,
            &meta2->general->center_longitude);
    }

    int zone1 = utm_zone(meta1->general->center_longitude);
    int zone2 = utm_zone(meta2->general->center_longitude);

    // if zone1 & zone2 differ by more than 1, we can stop now
    if (iabs(zone1-zone2) > 1) {
        return FALSE;
    }

    // The Plan:
    // Generate polygons for each metadata, then test of any pair of
    // line segments between the polygons intersect.

    // Other possibility: meta1 is completely contained within meta2,
    // or the reverse.

    // corners of meta1.
    double xp_1[5], yp_1[5];

    if (meta1->location) {
        // use the location block if available
        latLon2UTM_zone(meta1->location->lat_start_near_range,
            meta1->location->lon_start_near_range, 0, zone1, &xp_1[0], &yp_1[0]);
        latLon2UTM_zone(meta1->location->lat_start_far_range,
            meta1->location->lon_start_far_range, 0, zone1, &xp_1[1], &yp_1[1]);
        latLon2UTM_zone(meta1->location->lat_end_far_range,
            meta1->location->lon_end_far_range, 0, zone1, &xp_1[2], &yp_1[2]);
        latLon2UTM_zone(meta1->location->lat_end_near_range,
            meta1->location->lon_end_near_range, 0, zone1, &xp_1[3], &yp_1[3]);
    } else {
        double lat, lon;
        int nl1 = meta1->general->line_count;
        int ns1 = meta1->general->sample_count;

        // must call meta_get_latLon for each corner
        meta_get_latLon(meta1, 0, 0, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_1[0], &yp_1[0]);

        meta_get_latLon(meta1, nl1-1, 0, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_1[1], &yp_1[1]);

        meta_get_latLon(meta1, nl1-1, ns1-1, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_1[2], &yp_1[2]);

        meta_get_latLon(meta1, 0, ns1-1, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_1[3], &yp_1[3]);
    }

    // close the polygon
    xp_1[4] = xp_1[0];
    yp_1[4] = yp_1[0];

    // corners of meta2.
    double xp_2[5], yp_2[5];

    if (meta2->location) {
        // use the location block if available
        latLon2UTM_zone(meta2->location->lat_start_near_range,
            meta2->location->lon_start_near_range, 0, zone1, &xp_2[0], &yp_2[0]);
        latLon2UTM_zone(meta2->location->lat_start_far_range,
            meta2->location->lon_start_far_range, 0, zone1, &xp_2[1], &yp_2[1]);
        latLon2UTM_zone(meta2->location->lat_end_far_range,
            meta2->location->lon_end_far_range, 0, zone1, &xp_2[2], &yp_2[2]);
        latLon2UTM_zone(meta2->location->lat_end_near_range,
            meta2->location->lon_end_near_range, 0, zone1, &xp_2[3], &yp_2[3]);
    } else {
        double lat, lon;
        int nl2 = meta2->general->line_count;
        int ns2 = meta2->general->sample_count;

        // must call meta_get_latLon for each corner
        meta_get_latLon(meta2, 0, 0, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_2[0], &yp_2[0]);

        meta_get_latLon(meta2, nl2-1, 0, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_2[1], &yp_2[1]);

        meta_get_latLon(meta2, nl2-1, ns2-1, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_2[2], &yp_2[2]);

        meta_get_latLon(meta2, 0, ns2-1, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_2[3], &yp_2[3]);
    }

    // close the polygon
    xp_2[4] = xp_2[0];
    yp_2[4] = yp_2[0];

    // loop over each pair of line segments, testing for intersection
    int i, j;
    for (i = 0; i < 4; ++i) {
        for (j = 0; j < 4; ++j) {
            if (lineSegmentsIntersect(
                xp_1[i], yp_1[i], xp_1[i+1], yp_1[i+1],
                xp_2[j], yp_2[j], xp_2[j+1], yp_2[j+1]))
            {
                return TRUE;
            }
        }
    }

    // test for containment: meta2 in meta1
    int all_in=TRUE;
    for (i=0; i<4; ++i) {
        if (!pnpoly(5, xp_1, yp_1, xp_2[i], yp_2[i])) {
            all_in=FALSE;
            break;
        }
    }

    if (all_in)
        return TRUE;

    // test for containment: meta1 in meta2
    all_in = TRUE;
    for (i=0; i<4; ++i) {
        if (!pnpoly(5, xp_2, yp_2, xp_1[i], yp_1[i])) {
            all_in=FALSE;
            break;
        }
    }

    if (all_in)
        return TRUE;

    // no overlap
    return FALSE;
}
Esempio n. 8
0
// External entry point
//  --> meta: SAR metadata
//  --> dem_cla_arg: either (1) a DEM, (2) a directory with DEMs,
//                   (3) a file containing directories of DEMs.
// In case (1), nothing is done, return value is dem_cla_arg.
// In case (2), the directory is scanned and a DEM is built from
//              the DEMs found in that directory.
// In case (3), All of the directories are scanned, and a DEM is
//              built from the DEMs in all of the directories.
char *build_dem(meta_parameters *meta, const char *dem_cla_arg,
                const char *dir_for_tmp_dem)
{
    char *ext = findExt(dem_cla_arg);
    if (ext) {
        // check against known DEM extensions
        if (strcmp_case(ext, ".img") == 0 ||
            strcmp_case(ext, ".tif") == 0 ||
            strcmp_case(ext, ".tiff") == 0)
        {
            asfPrintStatus("%s: DEM.\n", dem_cla_arg);
            // presumably, this is a DEM -- case (1) above.
            return STRDUP(dem_cla_arg);
        }
    }
    else {
        // no extension -- user may have just provided the basename
        if (try_ext(dem_cla_arg, ".img")) {
            asfPrintStatus("%s: DEM.\n", dem_cla_arg);
            return STRDUP(dem_cla_arg);
        } else if (try_ext(dem_cla_arg, ".tiff")) {
            asfPrintStatus("%s: DEM.\n", dem_cla_arg);
            return STRDUP(dem_cla_arg);
        } else if (try_ext(dem_cla_arg, ".tif")) {
            asfPrintStatus("%s: DEM.\n", dem_cla_arg);
            return STRDUP(dem_cla_arg);
        }
    }

    char **list_of_dems = NULL;
    // Eliminated case (1) -- try case (2)
    if (is_dir_s(dem_cla_arg)) {
        asfPrintStatus("%s: directory containing DEMs.\n", dem_cla_arg);
        int n;
        list_of_dems =
            find_overlapping_dems_dir(meta, dem_cla_arg, &n);
    }
    else {
        // this is case (3)
        asfPrintStatus("%s: file containing directories of DEMs.\n", dem_cla_arg);
        if (fileExists(dem_cla_arg)) {
            int n;
            list_of_dems =
                find_overlapping_dems(meta, dem_cla_arg, &n);
        }
    }

    if (list_of_dems) {
        // form a bounding box
        double lat_lo, lat_hi, lon_lo, lon_hi;
        get_bounding_box_latlon(meta, &lat_lo, &lat_hi, &lon_lo, &lon_hi);

        // hard-coded name of the built dem
        char *built_dem;
        if (strlen(dir_for_tmp_dem) > 0) {
            built_dem = MALLOC(sizeof(char)*(strlen(dir_for_tmp_dem)+10));
            sprintf(built_dem, "%s/built_dem", dir_for_tmp_dem);
        } else
            built_dem = STRDUP("built_dem");

        // always geocode to utm -- we may wish change this to use the
        // user's preferred projection...
        asf_mosaic_utm(list_of_dems, built_dem,
            utm_zone(meta->general->center_longitude), lat_lo, lat_hi,
            lon_lo, lon_hi, meta->general->no_data);

        asfPrintStatus("Constructed DEM: %s\n", built_dem);
        return built_dem;
    }
    else {
        asfPrintError("DEM not found: %s\n", dem_cla_arg);
        return NULL; // not reached
    }
}