Skip to content

Conversation

@phaarnes
Copy link
Contributor

@phaarnes phaarnes commented Dec 4, 2025

This pull request is adding the improvement required in issue #4631.

proj_normalize_for_visualization() currently fails for certain concatenated coordinate operations where the sub-operations have non-overlapping validity areas. This happens because the function internally calls ConcatenatedOperation::createComputeMetadata() with checkExtent = true, which throws an exception when the validity areas do not intersect.

This PR disables the extent check for the axis-swap wrapper. It is not necessary because the axis-swap operations added by normalizeForVisualization() have no spatial effect (they only reorder coordinates), so the extent check can be safely skipped.

@phaarnes
Copy link
Contributor Author

phaarnes commented Dec 4, 2025

A simple test script to verify:

/**
 * Example: proj_normalize_for_visualization
 *
 * Test whether "always_xy" (proj_normalize_for_visualization) works
 * for ED50 to WGS84 transformations.
 *
 * Tests both:
 * - EPSG:1612 (simple Helmert, non-concatenated)
 * - EPSG:8047 (concatenated: ED50->ED87->WGS84) (note: superseded)
 *
 */

#include <cstdio>
#include <proj.h>

void test_transformation(PJ_CONTEXT *ctx, const char *op_code, double lon, double lat) {
    char urn[100];
    snprintf(urn, sizeof(urn), "urn:ogc:def:coordinateOperation:EPSG::%s", op_code);

    PJ *P = proj_create(ctx, urn);
    if (!P) {
        printf("Failed to create EPSG:%s\n\n", op_code);
        return;
    }

    printf("=== EPSG:%s ===\n", op_code);
    printf("Name: %s\n", proj_get_name(P));
    printf("Accuracy: %.2f m\n", proj_coordoperation_get_accuracy(ctx, P));

    // Test WITHOUT normalization (native axis order: lat, lon)
    printf("\nWithout normalization (native lat/lon order):\n");
    PJ_COORD input_native = proj_coord(lat, lon, 0, 0);
    PJ_COORD output_native = proj_trans(P, PJ_FWD, input_native);
    printf("  Input:  lat=%.6f, lon=%.6f\n", lat, lon);
    printf("  Output: lat=%.6f, lon=%.6f\n", output_native.lp.lam, output_native.lp.phi);

    // Test WITH normalization (always_xy: lon, lat order)
    printf("\nWith proj_normalize_for_visualization (always_xy):\n");
    PJ *P_norm = proj_normalize_for_visualization(ctx, P);
    if (P_norm) {
        PJ_COORD input_xy = proj_coord(lon, lat, 0, 0);
        PJ_COORD output_xy = proj_trans(P_norm, PJ_FWD, input_xy);
        printf("  Input:  lon=%.6f, lat=%.6f\n", lon, lat);
        printf("  Output: lon=%.6f, lat=%.6f\n", output_xy.lp.lam, output_xy.lp.phi);
        printf("  SUCCESS: always_xy works!\n");
        proj_destroy(P_norm);
    } else {
        printf("  FAILED: proj_normalize_for_visualization returned NULL\n");

    }

    proj_destroy(P);
    printf("\n");
}

int main() {
    printf("=== Testing proj_normalize_for_visualization ===\n\n");

    PJ_CONTEXT *ctx = proj_context_create();

    // Test point in Norway (valid for both transformations)
    double lon = 10.0;
    double lat = 60.0;

    printf("Test point: lon=%.4f, lat=%.4f\n\n", lon, lat);

    // Test 1: Simple (non-concatenated) transformation
    test_transformation(ctx, "1612", lon, lat);  // ED50 to WGS 84 (23) - Helmert

    // Test 2: Concatenated transformation
    test_transformation(ctx, "8047", lon, lat);  // ED50 to WGS 84 (15) - via ED87

    proj_context_destroy(ctx);

    return 0;
}

@rouault
Copy link
Member

rouault commented Dec 4, 2025

@phaarnes I've added a commit to your pull request to better address the issue by re-applying most of the metadata of the original operation to the normalized one (name, domain of validity, accuracy, remarks), that also avoids revalidating the domain

@rouault rouault added this to the 9.8.0 milestone Dec 4, 2025
@rouault rouault force-pushed the feature/#4631-skip-extent-check-axis-swap-wrappers branch from f11ac9e to 6e42eb1 Compare December 4, 2025 14:36
@phaarnes
Copy link
Contributor Author

phaarnes commented Dec 4, 2025

@rouault
Great, thanks!

@rouault rouault merged commit 13265bd into OSGeo:master Dec 4, 2025
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add option to skip extent validation in proj_normalize_for_visualization()

2 participants