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; } }
static void test_p2utm(double projY, double projX, double height, int zone, double lon, double lat) { double testLat, testLon; UTM2latLon(projX, projY, height, zone, &testLat, &testLon); CU_ASSERT(double_equals(lat, testLat, 5)); CU_ASSERT(double_equals(lon, testLon, 5)); if (double_equals(lat, testLat, 5) && double_equals(lon, testLon, 5)) { //asfPrintStatus("UTM2latLon Testing: %f, %f ... OK\n", projX, projY); ++n_ok; } else { asfPrintStatus("UTM2latLon Testing: %f, %f ... ERROR\n", projX, projY); asfPrintStatus("Result: %.10f %.10f\n", testLat, testLon); asfPrintStatus("Expected: %.10f %.10f\n", lat, lon); ++n_bad; } double x, y; latLon2UTM(lat, lon, height, &x, &y); CU_ASSERT(double_equals(x, projX, 5)); CU_ASSERT(double_equals(y, projY, 5)); if (double_equals(x, projX, 5) && double_equals(y, projY, 5)) { //asfPrintStatus("latLon2UTM Testing: %f, %f ... OK\n", lat, lon); ++n_ok; } else { asfPrintStatus("latLon2UTM Testing: %f, %f ... ERROR\n", lat, lon); asfPrintStatus("Result: %.10f %.10f\n", x, y); asfPrintStatus("Expected: %.10f %.10f\n", projX, projY); ++n_bad; } latLon2UTM_zone(lat, lon, height, zone, &x, &y); CU_ASSERT(double_equals(x, projX, 5)); CU_ASSERT(double_equals(y, projY, 5)); if (double_equals(x, projX, 5) && double_equals(y, projY, 5)) { //asfPrintStatus("latLon2UTM_zone Testing: %f, %f ... OK\n", lat, lon); ++n_ok; } else { asfPrintStatus("latLon2UTM_zone Testing: %f, %f ... ERROR\n", lat, lon); asfPrintStatus("Result: %.10f %.10f\n", x, y); asfPrintStatus("Expected: %.10f %.10f\n", projX, projY); ++n_bad; } }
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; }
// 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; }