int pj_datum_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, double *x, double *y, double *z ) { double src_a, src_es, dst_a, dst_es; int z_is_temp = FALSE; pj_errno = 0; /* -------------------------------------------------------------------- */ /* Short cut if the datums are identical. */ /* -------------------------------------------------------------------- */ if( pj_compare_datums( srcdefn, dstdefn ) ) return 0; src_a = srcdefn->a; src_es = srcdefn->es; dst_a = dstdefn->a; dst_es = dstdefn->es; /* -------------------------------------------------------------------- */ /* Create a temporary Z array if one is not provided. */ /* -------------------------------------------------------------------- */ if( z == NULL ) { int bytes = sizeof(double) * point_count * point_offset; z = (double *) pj_malloc(bytes); memset( z, 0, bytes ); z_is_temp = TRUE; } #define CHECK_RETURN {if( pj_errno != 0 ) { if( z_is_temp ) pj_dalloc(z); return pj_errno; }} /* -------------------------------------------------------------------- */ /* If this datum requires grid shifts, then apply it to geodetic */ /* coordinates. */ /* -------------------------------------------------------------------- */ if( srcdefn->datum_type == PJD_GRIDSHIFT ) { pj_apply_gridshift( pj_param(srcdefn->params,"snadgrids").s, 0, point_count, point_offset, x, y, z ); CHECK_RETURN; src_a = SRS_WGS84_SEMIMAJOR; src_es = 0.006694379990; } if( dstdefn->datum_type == PJD_GRIDSHIFT ) { dst_a = SRS_WGS84_SEMIMAJOR; dst_es = 0.006694379990; } /* ==================================================================== */ /* Do we need to go through geocentric coordinates? */ /* ==================================================================== */ if( src_es != dst_es || src_a != dst_a || srcdefn->datum_type == PJD_3PARAM || srcdefn->datum_type == PJD_7PARAM || dstdefn->datum_type == PJD_3PARAM || dstdefn->datum_type == PJD_7PARAM) { /* -------------------------------------------------------------------- */ /* Convert to geocentric coordinates. */ /* -------------------------------------------------------------------- */ pj_geodetic_to_geocentric( src_a, src_es, point_count, point_offset, x, y, z ); CHECK_RETURN; /* -------------------------------------------------------------------- */ /* Convert between datums. */ /* -------------------------------------------------------------------- */ if( srcdefn->datum_type == PJD_3PARAM || srcdefn->datum_type == PJD_7PARAM ) { pj_geocentric_to_wgs84( srcdefn, point_count, point_offset,x,y,z); CHECK_RETURN; } if( dstdefn->datum_type == PJD_3PARAM || dstdefn->datum_type == PJD_7PARAM ) { pj_geocentric_from_wgs84( dstdefn, point_count,point_offset,x,y,z); CHECK_RETURN; } /* -------------------------------------------------------------------- */ /* Convert back to geodetic coordinates. */ /* -------------------------------------------------------------------- */ pj_geocentric_to_geodetic( dst_a, dst_es, point_count, point_offset, x, y, z ); CHECK_RETURN; } /* -------------------------------------------------------------------- */ /* Apply grid shift to destination if required. */ /* -------------------------------------------------------------------- */ if( dstdefn->datum_type == PJD_GRIDSHIFT ) { pj_apply_gridshift( pj_param(dstdefn->params,"snadgrids").s, 1, point_count, point_offset, x, y, z ); CHECK_RETURN; } if( z_is_temp ) pj_dalloc( z ); return 0; }
int pj_datum_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, double *x, double *y, double *z ) { double src_a, src_es, dst_a, dst_es; int z_is_temp = FALSE; pj_errno = 0; /* -------------------------------------------------------------------- */ /* We cannot do any meaningful datum transformation if either */ /* the source or destination are of an unknown datum type */ /* (ie. only a +ellps declaration, no +datum). This is new */ /* behavior for PROJ 4.6.0. */ /* -------------------------------------------------------------------- */ if( srcdefn->datum_type == PJD_UNKNOWN || dstdefn->datum_type == PJD_UNKNOWN ) return 0; /* -------------------------------------------------------------------- */ /* Short cut if the datums are identical. */ /* -------------------------------------------------------------------- */ if( pj_compare_datums( srcdefn, dstdefn ) ) return 0; src_a = srcdefn->a_orig; src_es = srcdefn->es_orig; dst_a = dstdefn->a_orig; dst_es = dstdefn->es_orig; /* -------------------------------------------------------------------- */ /* Create a temporary Z array if one is not provided. */ /* -------------------------------------------------------------------- */ if( z == NULL ) { int bytes = sizeof(double) * point_count * point_offset; z = (double *) pj_malloc(bytes); memset( z, 0, bytes ); z_is_temp = TRUE; } #define CHECK_RETURN {if( pj_errno != 0 && (pj_errno > 0 || transient_error[-pj_errno] == 0) ) { if( z_is_temp ) pj_dalloc(z); return pj_errno; }} /* -------------------------------------------------------------------- */ /* If this datum requires grid shifts, then apply it to geodetic */ /* coordinates. */ /* -------------------------------------------------------------------- */ if( srcdefn->datum_type == PJD_GRIDSHIFT ) { pj_apply_gridshift( pj_param(srcdefn->params,"snadgrids").s, 0, point_count, point_offset, x, y, z ); CHECK_RETURN; src_a = SRS_WGS84_SEMIMAJOR; src_es = SRS_WGS84_ESQUARED; } if( dstdefn->datum_type == PJD_GRIDSHIFT ) { dst_a = SRS_WGS84_SEMIMAJOR; dst_es = SRS_WGS84_ESQUARED; } /* ==================================================================== */ /* Do we need to go through geocentric coordinates? */ /* ==================================================================== */ if( src_es != dst_es || src_a != dst_a || srcdefn->datum_type == PJD_3PARAM || srcdefn->datum_type == PJD_7PARAM || dstdefn->datum_type == PJD_3PARAM || dstdefn->datum_type == PJD_7PARAM) { /* -------------------------------------------------------------------- */ /* Convert to geocentric coordinates. */ /* -------------------------------------------------------------------- */ pj_geodetic_to_geocentric( src_a, src_es, point_count, point_offset, x, y, z ); CHECK_RETURN; /* -------------------------------------------------------------------- */ /* Convert between datums. */ /* -------------------------------------------------------------------- */ if( srcdefn->datum_type == PJD_3PARAM || srcdefn->datum_type == PJD_7PARAM ) { pj_geocentric_to_wgs84( srcdefn, point_count, point_offset,x,y,z); CHECK_RETURN; } if( dstdefn->datum_type == PJD_3PARAM || dstdefn->datum_type == PJD_7PARAM ) { pj_geocentric_from_wgs84( dstdefn, point_count,point_offset,x,y,z); CHECK_RETURN; } /* -------------------------------------------------------------------- */ /* Convert back to geodetic coordinates. */ /* -------------------------------------------------------------------- */ pj_geocentric_to_geodetic( dst_a, dst_es, point_count, point_offset, x, y, z ); CHECK_RETURN; } /* -------------------------------------------------------------------- */ /* Apply grid shift to destination if required. */ /* -------------------------------------------------------------------- */ if( dstdefn->datum_type == PJD_GRIDSHIFT ) { pj_apply_gridshift( pj_param(dstdefn->params,"snadgrids").s, 1, point_count, point_offset, x, y, z ); CHECK_RETURN; } if( z_is_temp ) pj_dalloc( z ); return 0; }
int pj_datum_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, double *x, double *y, double *z ) { double src_a, src_es, dst_a, dst_es; pj_errno = 0; /* -------------------------------------------------------------------- */ /* Short cut if the datums are identical. */ /* -------------------------------------------------------------------- */ if( pj_compare_datums( srcdefn, dstdefn ) ) return 0; src_a = srcdefn->a; src_es = srcdefn->es; dst_a = dstdefn->a; dst_es = dstdefn->es; /* -------------------------------------------------------------------- */ /* If this datum requires grid shifts, then apply it to geodetic */ /* coordinates. */ /* -------------------------------------------------------------------- */ if( srcdefn->datum_type == PJD_GRIDSHIFT ) { pj_apply_gridshift( pj_param(srcdefn->params,"snadgrids").s, 0, point_count, point_offset, x, y, z ); if( pj_errno != 0 ) return pj_errno; src_a = SRS_WGS84_SEMIMAJOR; src_es = 0.006694379990; } if( dstdefn->datum_type == PJD_GRIDSHIFT ) { dst_a = SRS_WGS84_SEMIMAJOR; dst_es = 0.006694379990; } /* ==================================================================== */ /* Do we need to go through geocentric coordinates? */ /* ==================================================================== */ if( srcdefn->datum_type == PJD_3PARAM || srcdefn->datum_type == PJD_7PARAM || dstdefn->datum_type == PJD_3PARAM || dstdefn->datum_type == PJD_7PARAM) { /* -------------------------------------------------------------------- */ /* Convert to geocentric coordinates. */ /* -------------------------------------------------------------------- */ pj_geodetic_to_geocentric( src_a, src_es, point_count, point_offset, x, y, z ); if( pj_errno ) return pj_errno; /* -------------------------------------------------------------------- */ /* Convert between datums. */ /* -------------------------------------------------------------------- */ if( srcdefn->datum_type != PJD_UNKNOWN && dstdefn->datum_type != PJD_UNKNOWN ) { pj_geocentric_to_wgs84( srcdefn, point_count, point_offset,x,y,z); if( pj_errno != 0 ) return pj_errno; pj_geocentric_from_wgs84( dstdefn, point_count,point_offset,x,y,z); if( pj_errno != 0 ) return pj_errno; } /* -------------------------------------------------------------------- */ /* Convert back to geodetic coordinates. */ /* -------------------------------------------------------------------- */ pj_geocentric_to_geodetic( dst_a, dst_es, point_count, point_offset, x, y, z ); if( pj_errno ) return pj_errno; } /* -------------------------------------------------------------------- */ /* Apply grid shift to destination if required. */ /* -------------------------------------------------------------------- */ if( dstdefn->datum_type == PJD_GRIDSHIFT ) { pj_apply_gridshift( pj_param(dstdefn->params,"snadgrids").s, 1, point_count, point_offset, x, y, z ); if( pj_errno != 0 ) return pj_errno; } return 0; }