Skip to content

Commit

Permalink
- API Extension to include fwd3d / inv3d
Browse files Browse the repository at this point in the history
- New SCH coordinate system for radar imaging systems
  • Loading branch information
Piyush Agram committed Oct 23, 2015
1 parent b5d0d2d commit 757a2c8
Show file tree
Hide file tree
Showing 17 changed files with 1,111 additions and 1,732 deletions.
26 changes: 26 additions & 0 deletions nad/testvarious
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,32 @@ $EXE -f '%.7f' \
-E >>${OUT} <<EOF
10 34
EOF
echo "##############################################################" >> ${OUT}
echo "Test SCH forward projection" >> ${OUT}
#
$EXE -f '%.7f' \
+proj=latlong +datum=WGS84 +to +proj=sch +datum=WGS84 +plat_0=30.0 +plon_0=45.0 \
+phdg_0=-12.0 +nodefs \
-E >> ${OUT} <<EOF
0.0 0.0
0.0 90.0
45.0 45.0
45.1 44.9
44.9 45.1
30.0 45.0
EOF
echo "##############################################################" >> ${OUT}
echo "Test SCH inverse projection" >> ${OUT}
#
$EXE -f '%.7f' \
+proj=sch +datum=WGS84 +plat_0=30.0 +plon_0=45.0 +phdg_0=-12.0 +nodefs +to \
+proj=latlong +datum=WGS84 \
-E >> ${OUT} <<EOF
0. 0.
0. 1000.
1000. 0.
1000. 1000.
EOF
##############################################################################
# Done!
# do 'diff' with distribution results
Expand Down
14 changes: 14 additions & 0 deletions nad/tv_out.dist
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,17 @@ Test bug 245 (use +datum=carthage)
##############################################################
Test bug 245 (use expension of +datum=carthage)
10 34 592302.9819462 3762148.7340610 -30.3110170
##############################################################
Test SCH forward projection
0.0 0.0 -1977112.0305592 5551475.1418378 6595.7256583
0.0 90.0 -4303095.6927530 -4253039.2182667 6595.7256583
45.0 45.0 1630035.5650122 -342353.6396475 128.3445654
45.1 44.9 1642526.7453121 -336878.8571851 131.3265616
44.9 45.1 1617547.4295637 -347855.9734973 125.4645102
30.0 45.0 0.0000000 0.0000000 0.0000000
##############################################################
Test SCH inverse projection
0. 0. 30.0000000 45.0000000 0.0000000
0. 1000. 29.9981240 44.9898625 -0.0003617
1000. 0. 30.0088238 44.9978450 -0.0000000
1000. 1000. 30.0069477 44.9877066 -0.0005228
4 changes: 2 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ libproj_la_SOURCES = \
PJ_mbt_fps.c PJ_mbtfpp.c PJ_mbtfpq.c PJ_moll.c \
PJ_nell.c PJ_nell_h.c PJ_putp2.c PJ_putp3.c \
PJ_putp4p.c PJ_putp5.c PJ_putp6.c PJ_qsc.c PJ_robin.c \
PJ_sts.c PJ_urm5.c PJ_urmfps.c PJ_wag2.c \
PJ_sch.c PJ_sts.c PJ_urm5.c PJ_urmfps.c PJ_wag2.c \
PJ_wag3.c PJ_wink1.c PJ_wink2.c pj_latlong.c pj_geocent.c \
aasincos.c adjlon.c bch2bps.c bchgen.c \
biveval.c dmstor.c mk_cheby.c pj_auth.c \
pj_deriv.c pj_ell_set.c pj_ellps.c pj_errno.c \
pj_factors.c pj_fwd.c pj_init.c pj_inv.c \
pj_factors.c pj_fwd.c pj_init.c pj_inv.c pj_fwd3d.c pj_inv3d.c\
pj_list.c pj_malloc.c pj_mlfn.c pj_msfn.c proj_mdist.c \
pj_open_lib.c pj_param.c pj_phi2.c pj_pr_list.c \
pj_qsfn.c pj_strerrno.c pj_tsfn.c pj_units.c pj_ctx.c pj_log.c \
Expand Down
228 changes: 228 additions & 0 deletions src/PJ_sch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
/******************************************************************************
* $Id$
*
* Project: SCH Coordinate system
* Purpose: Implementation of SCH Coordinate system
* References :
* 1. Hensley. Scott. SCH Coordinates and various transformations. June 15, 2000.
* 2. Buckley, Sean Monroe. Radar interferometry measurement of land subsidence. 2000..
* PhD Thesis. UT Austin. (Appendix)
* 3. Hensley, Scott, Elaine Chapin, and T. Michel. "Improved processing of AIRSAR
* data based on the GeoSAR processor." Airsar earth science and applications
* workshop, March. 2002. (http://airsar.jpl.nasa.gov/documents/workshop2002/papers/T3.pdf)
*
* Author: Piyush Agram (piyush.agram@jpl.nasa.gov)
* Copyright (c) 2015 California Institute of Technology.
* Government sponsorship acknowledged.
*
* NOTE: The SCH coordinate system is a sensor aligned coordinate system
* developed at JPL for radar mapping missions. Details pertaining to the
* coordinate system have been release in the public domain (see references above).
* This code is an independent implementation of the SCH coordinate system
* that conforms to the PROJ.4 conventions and uses the details presented in these
* publicly released documents. All credit for the development of the coordinate
* system and its use should be directed towards the original developers at JPL.
******************************************************************************
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/

#include "geocent.h"

#define PROJ_PARMS__ \
double plat; /*Peg Latitude */ \
double plon; /*Peg Longitude*/ \
double phdg; /*Peg heading */ \
double h0; /*Average altitude */\
double transMat[9]; \
double xyzoff[3]; \
double rcurv; \
GeocentricInfo sph; \
GeocentricInfo elp_0;

#define PJ_LIB__
#include <projects.h>

PROJ_HEAD(sch, "Spherical Cross-track Height") "\n\tMisc\n\tplat_0 = ,plon_0 = , phdg_0 = ,[h_0 = ]";

INVERSE3D(inverse3d);
double temp[3];
double pxyz[3];

//Local lat,lon using radius
pxyz[0] = xyz.y * P->a / P->rcurv;
pxyz[1] = xyz.x * P->a / P->rcurv;
pxyz[2] = xyz.z;


if( pj_Convert_Geodetic_To_Geocentric( &(P->sph), pxyz[0], pxyz[1], pxyz[2],
temp, temp+1, temp+2) != 0)
I3_ERROR;

//Apply rotation
pxyz[0] = P->transMat[0] * temp[0] + P->transMat[1] * temp[1] + P->transMat[2] * temp[2];
pxyz[1] = P->transMat[3] * temp[0] + P->transMat[4] * temp[1] + P->transMat[5] * temp[2];
pxyz[2] = P->transMat[6] * temp[0] + P->transMat[7] * temp[1] + P->transMat[8] * temp[2];

//Apply offset
pxyz[0] += P->xyzoff[0];
pxyz[1] += P->xyzoff[1];
pxyz[2] += P->xyzoff[2];

//Convert geocentric coordinates to lat lon
pj_Convert_Geocentric_To_Geodetic( &(P->elp_0), pxyz[0], pxyz[1], pxyz[2],
temp, temp+1, temp+2);


lpz.lam = temp[0] ;
lpz.phi = temp[1] ;
lpz.z = temp[2];

// printf("INVERSE: \n");
// printf("XYZ: %f %f %f \n", xyz.x, xyz.y, xyz.z);
// printf("LPZ: %f %f %f \n", lpz.lam, lpz.phi, lpz.z);
return (lpz);
}

FORWARD3D(forward3d);
double temp[3];
double pxyz[3];

//Convert lat lon to geocentric coordinates
if( pj_Convert_Geodetic_To_Geocentric( &(P->elp_0), lpz.lam, lpz.phi, lpz.z,
temp, temp+1, temp+2 ) != 0 )
F3_ERROR;

//Adjust for offset
temp[0] -= P->xyzoff[0];
temp[1] -= P->xyzoff[1];
temp[2] -= P->xyzoff[2];


//Apply rotation
pxyz[0] = P->transMat[0] * temp[0] + P->transMat[3] * temp[1] + P->transMat[6] * temp[2];
pxyz[1] = P->transMat[1] * temp[0] + P->transMat[4] * temp[1] + P->transMat[7] * temp[2];
pxyz[2] = P->transMat[2] * temp[0] + P->transMat[5] * temp[1] + P->transMat[8] * temp[2];

//Convert to local lat,lon
pj_Convert_Geocentric_To_Geodetic( &(P->sph), pxyz[0], pxyz[1], pxyz[2],
temp, temp+1, temp+2);

//Scale by radius
xyz.x = temp[1] * P->rcurv / P->a;
xyz.y = temp[0] * P->rcurv / P->a;
xyz.z = temp[2];

// printf("FORWARD: \n");
// printf("LPZ: %f %f %f \n", lpz.lam, lpz.phi, lpz.z);
// printf("XYZ: %f %f %f \n", xyz.x, xyz.y, xyz.z);

return (xyz);
}

FREEUP; if (P) pj_dalloc(P); }
static PJ *
setup(PJ *P) { /* general initialization */
double reast, rnorth;
double chdg, shdg;
double clt, slt;
double clo, slo;
double temp;
double pxyz[3];

temp = P->a * sqrt(1.0 - P->es);

//Setup original geocentric system
if ( pj_Set_Geocentric_Parameters(&(P->elp_0), P->a, temp) != 0)
E_ERROR(-37);


clt = cos(P->plat);
slt = sin(P->plat);
clo = cos(P->plon);
slo = sin(P->plon);

//Estimate the radius of curvature for given peg
temp = sqrt(1.0 - (P->es) * slt * slt);
reast = (P->a)/temp;
rnorth = (P->a) * (1.0 - (P->es))/pow(temp,3);

chdg = cos(P->phdg);
shdg = sin(P->phdg);

P->rcurv = P->h0 + (reast*rnorth)/(reast * chdg * chdg + rnorth * shdg * shdg);

// printf("North Radius: %f \n", rnorth);
// printf("East Radius: %f \n", reast);
// printf("Effective Radius: %f \n", P->rcurv);

//Set up local sphere at the given peg point
if ( pj_Set_Geocentric_Parameters(&(P->sph), P->rcurv, P->rcurv) != 0)
E_ERROR(-37);

//Set up the transformation matrices
P->transMat[0] = clt * clo;
P->transMat[1] = -shdg*slo - slt*clo * chdg;
P->transMat[2] = slo*chdg - slt*clo*shdg;
P->transMat[3] = clt*slo;
P->transMat[4] = clo*shdg - slt*slo*chdg;
P->transMat[5] = -clo*chdg - slt*slo*shdg;
P->transMat[6] = slt;
P->transMat[7] = clt*chdg;
P->transMat[8] = clt*shdg;


if( pj_Convert_Geodetic_To_Geocentric( &(P->elp_0), P->plat, P->plon, P->h0,
pxyz, pxyz+1, pxyz+2 ) != 0 )
{
E_ERROR(-14)
}


P->xyzoff[0] = pxyz[0] - (P->rcurv) * clt * clo;
P->xyzoff[1] = pxyz[1] - (P->rcurv) * clt * slo;
P->xyzoff[2] = pxyz[2] - (P->rcurv) * slt;

// printf("Offset: %f %f %f \n", P->xyzoff[0], P->xyzoff[1], P->xyzoff[2]);


P->fwd3d = forward3d;
P->inv3d = inverse3d;
return P;
}
ENTRY0(sch)
P->h0 = 0.0;

//Check if peg latitude was defined
if (pj_param(P->ctx, P->params, "tplat_0").i)
P->plat = pj_param(P->ctx, P->params, "rplat_0").f;
else
E_ERROR(-37);

//Check if peg longitude was defined
if (pj_param(P->ctx, P->params, "tplon_0").i)
P->plon = pj_param(P->ctx, P->params, "rplon_0").f;
else
E_ERROR(-37);

//Check if peg latitude is defined
if (pj_param(P->ctx, P->params, "tphdg_0").i)
P->phdg = pj_param(P->ctx, P->params, "rphdg_0").f;
else
E_ERROR(-37);


//Check if average height was defined
//If so read it in
if (pj_param(P->ctx, P->params, "th_0").i)
P->h0 = pj_param(P->ctx, P->params, "dh_0").f;

//Completed reading in the projection parameters
// printf("PSA: Lat = %f Lon = %f Hdg = %f \n", P->plat, P->plon, P->phdg);

ENDENTRY(setup(P))
3 changes: 3 additions & 0 deletions src/lib_proj.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ SET(SRC_LIBPROJ_PJ
PJ_qsc.c
PJ_robin.c
PJ_rpoly.c
PJ_sch.c
PJ_sconics.c
PJ_somerc.c
PJ_sterea.c
Expand Down Expand Up @@ -166,6 +167,7 @@ SET(SRC_LIBPROJ_CORE
pj_errno.c
pj_factors.c
pj_fwd.c
pj_fwd3d.c
pj_gauss.c
pj_gc_reader.c
pj_geocent.c
Expand All @@ -176,6 +178,7 @@ SET(SRC_LIBPROJ_CORE
pj_init.c
pj_initcache.c
pj_inv.c
pj_inv3d.c
pj_latlong.c
pj_list.c
pj_list.h
Expand Down
7 changes: 4 additions & 3 deletions src/makefile.vc
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ misc = \
PJ_airy.obj PJ_aitoff.obj PJ_august.obj PJ_bacon.obj \
PJ_chamb.obj PJ_hammer.obj PJ_lagrng.obj PJ_larr.obj \
PJ_lask.obj PJ_nocol.obj PJ_ob_tran.obj PJ_oea.obj \
PJ_tpeqd.obj PJ_vandg.obj PJ_vandg2.obj PJ_vandg4.obj \
PJ_wag7.obj pj_latlong.obj PJ_krovak.obj pj_geocent.obj \
PJ_healpix.obj PJ_natearth.obj PJ_qsc.obj
PJ_sch.obj PJ_tpeqd.obj PJ_vandg.obj PJ_vandg2.obj \
PJ_vandg4.obj PJ_wag7.obj pj_latlong.obj PJ_krovak.obj \
pj_geocent.obj PJ_healpix.obj PJ_natearth.obj PJ_qsc.obj

pseudo = \
PJ_boggs.obj PJ_collg.obj PJ_crast.obj PJ_denoy.obj \
Expand All @@ -45,6 +45,7 @@ support = \
biveval.obj dmstor.obj mk_cheby.obj pj_auth.obj \
pj_deriv.obj pj_ell_set.obj pj_ellps.obj pj_errno.obj \
pj_factors.obj pj_fwd.obj pj_init.obj pj_inv.obj \
pj_fwd3d.obj pj_inv3d.obj \
pj_list.obj pj_malloc.obj pj_mlfn.obj pj_msfn.obj \
pj_open_lib.obj pj_param.obj pj_phi2.obj pj_pr_list.obj \
pj_qsfn.obj pj_strerrno.obj pj_tsfn.obj pj_units.obj \
Expand Down
19 changes: 14 additions & 5 deletions src/pj_fwd.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,23 @@ pj_fwd(LP lp, PJ *P) {
lp.lam -= P->lam0; /* compute del lp.lam */
if (!P->over)
lp.lam = adjlon(lp.lam); /* adjust del longitude */
xy = (*P->fwd)(lp, P); /* project */
if ( P->ctx->last_errno )

//Check for NULL pointer
if (P->fwd != NULL)
{
xy = (*P->fwd)(lp, P); /* project */
if ( P->ctx->last_errno )
xy.x = xy.y = HUGE_VAL;
/* adjust for major axis and easting/northings */
else {
/* adjust for major axis and easting/northings */
else {
xy.x = P->fr_meter * (P->a * xy.x + P->x0);
xy.y = P->fr_meter * (P->a * xy.y + P->y0);
}
}
}
else
{
xy.x = xy.y = HUGE_VAL;
}
}
return xy;
}
Loading

0 comments on commit 757a2c8

Please sign in to comment.