-
Notifications
You must be signed in to change notification settings - Fork 789
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pipeline plus api - in continuation of the Genereic Coordinates pull request #445
Conversation
This commit reflects continued work on the new rationalized API with geodetic extensions (see rationale in proj.h). It also reflects the parallel work on the transformation pipeline reimplementation, by introducing the PJ_cart cartesian/ellipsoidal converter.
int pj_show_triplet (FILE *stream, const char *banner, PJ_TRIPLET point); | ||
|
||
/* Constructor for the OBSERVATION object */ | ||
PJ *pj_pj (PJ_CONTEXT *ctx, char *definition); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- const char* would be better
- pj_pj() isn't really explicit. pj_create_from_def() maybe ?
- This is a more general question, but how should we document functions and structures. Informally here as comments, or with Doxygen formalism in the .c file (or in .h) ? Update: I see we have https://github.com/OSGeo/proj.4/tree/master/docs/source/development now, so that would be the place for that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with 1 and 2. Even though the most obvious name is occupied it must be possible to come out with something more explicit thapj_pj
. pj_setup
maybe?
3. Yes, I added that recently but I am not happy with it yet. For now a proj_h.rst or something like that would be good enough. I think eventually we should use a system like Doxygen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with 1 & 2 and changed the char * arg to const char *, and the name to pj_create which I believe strikes a balance between brevity and expressivity :-)
|
||
/* This is mostly a direct copy of (parts of) the proj_api header, but with cleaned up name space */ | ||
|
||
#define PJ_VERSION 493 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit error prone to have PJ_VERSION defines in 2 header files (but we probably don't want to have a proj_version.h with just that #define ?). HOWTO-RELEASE will have to be updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed it now, so it lives in proj_api.h only - but making it work requires some ugly defines.
@@ -74,7 +74,7 @@ libproj_la_SOURCES = \ | |||
jniproj.c pj_mutex.c pj_initcache.c pj_apply_vgridshift.c geodesic.c \ | |||
pj_strtod.c \ | |||
\ | |||
pj_observation.c | |||
pj_observation.c pj_cart.c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if makefiles are filename case sensitive. But if so, should be PJ_cart.c.
Or should PJ_cart.c be in lowercase itself? (I tend to prever lower case for filenames but proj is a mix of both...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeping with the tradition the file should be PJ_cart.c
since all files with "projections" are named that way, and the rest uses the lower-cases nomenclature. I don't like it either (I'd prefer to organise the files in directories instead).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that was a bug. Actually, I think that 8 years ago, Gerald had planned to move all projection files into a proj_NAME.c namespace (cf. proj_etmerc.c and proj_rouss.c)
Doing that would also make it way easier to find the right file in a lexicographically ordered file open dialog.
But it would probably make it slightly harder to follow the development history of the code in git.
printf ("%15.9f %15.9f\n", a.coo.lpz.lam, a.coo.lpz.phi); | ||
err = pj_ctx_get_errno (pj_ctx (p)); | ||
printf ("pj_ctx_errno: %d\n", err); | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be a good practice to free p
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done - thanks for spotting that!
@@ -49,20 +49,21 @@ extern "C" { | |||
* are padded with leading zeros if necessary); e.g., PJ_VERSION=401000 | |||
* for version 4.10.0. | |||
*/ | |||
#ifndef PROJ_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that there's a provision to do #include "proj.h" and then #include "proj_api.h", but the reverse wouldn't work well, right ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have now added inclusion guards - they are implemented using the "error" preprocessor directive, which is not universally supported, but have the strange property that it is supported even where not - since if it is not supported it magically turns into a conditional syntax error
PJ_FILEAPI *pj_ctx_get_fileapi (PJ_CONTEXT *); | ||
PJ_FILEAPI *pj_get_default_fileapi(); | ||
|
||
PJ_FILE pj_ctx_fopen (PJ_CONTEXT *ctx, const char *filename, const char *access); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need those pj_ctx_fopen() and the like in the public API ? Looks like they should be used only by the proj.4 implementation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remember Frank's explanation when they were introduced, they were actually intended as user accessible, for making the proj.4 library play nice with other environments.
Personally I wouldn't mind moving them to a lower level API, but I do not think thay are intended as proj.4 internals (on the other hand, I have never seen them in use...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is Franks introduction to the context file API. He mentions that it is used in the init and gridshift file accessors. I am not sure if that is actually true since I am having a hard time finding said code. I am not very familiar with that part of the code base though, so it is likely that I have missed something.
I wouldn't be surprised if no one has ever used that functionality.
|
||
|
||
/* Logging API */ | ||
void pj_log (PJ_CONTEXT *ctx, int level, const char *fmt, ... ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pj_log() probably doesn't need to be public
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been up until now, but I agree that keeping things compact from start would be a good idea
return pj_init_ctx (ctx, argc, argv); | ||
} | ||
|
||
PJ_CONTEXT *pj_ctx (PJ *P) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would one need to get the context of a PJ* object ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do the same with the API in proj_api.h
as documentend here: http://proj4.org/development/threads.html
This, and the one below, is just to get consistent naming across all pj_ctx*
functions. I am not really able to comment on why you would need that functionality though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably in order to pass it on to pj_init_ctx in order to initialize another PJ running in the same thread?
return pj_get_ctx (P); | ||
} | ||
|
||
void pj_ctx_set (PJ *P, PJ_CONTEXT *ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would one need to set the context of a PJ* object ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably reason closely related to the above mentioned. Basically I have never seen it in use.
This might be another of the "drop them now, and reintroduce if necessary later" crowd
void pj_ctx_fclose (PJ_CONTEXT *ctx, PJ_FILE *file); | ||
char *pj_ctx_fgets (PJ_CONTEXT *ctx, char *line, int size, PJ_FILE *file); | ||
|
||
PJ_FILE pj_open_lib(PJ_CONTEXT *, const char *, const char *); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this isn't a new function that you added, but the naming is quite bad. It doesn't open the lib, but a file.
OK so if we keep that one public (could potentially be useful if people wants to parse the 'epsg' file at hand?), we need to keep the fread(), fseek() etc public as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name is horrible... but I think this API should live its life inside the library and evolve a bit on the trip to the next release, and for a new API we do not need to keep the old names.
I will probably remove some of these, and reintroduce them when need (and better ideas) arise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My initial comments are inlined. I'll probably have more after my second read-through of the code. In general it looks good.
The build fails that obviously has to change before merging...
}; | ||
|
||
PJ_OBSERVATION pj_fwdobs (PJ_OBSERVATION obs, PJ *P) { | ||
#if 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this should have been removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
|
||
PJ_OBSERVATION pj_invobs (PJ_OBSERVATION obs, PJ *P) { | ||
#if 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as the above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -116,20 +205,17 @@ typedef struct { double lam, phi, z; } LPZ; | |||
typedef struct { double d, m, s; } PJ_DMS; | |||
|
|||
/* Geoid undulation (N) and deflections of the vertical (z, e) */ | |||
typedef struct { double N, z, e; } PJ_NZE; | |||
typedef struct { double z, e, N; } PJ_ZEN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you change this just to have a cool name? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, not really - and I have changed it again now to EZN, since eta is the east-west component, zeta the north-south, and N is related to heights, so EZN makes most sense
int pj_show_triplet (FILE *stream, const char *banner, PJ_TRIPLET point); | ||
|
||
/* Constructor for the OBSERVATION object */ | ||
PJ *pj_pj (PJ_CONTEXT *ctx, char *definition); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with 1 and 2. Even though the most obvious name is occupied it must be possible to come out with something more explicit thapj_pj
. pj_setup
maybe?
3. Yes, I added that recently but I am not happy with it yet. For now a proj_h.rst or something like that would be good enough. I think eventually we should use a system like Doxygen.
@@ -0,0 +1,39 @@ | |||
/* Tiny test of an evolving new API. Thomas Knudsen, 2016-10-30 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this file is not really a part of the main library I think it would be better to move it to either the test
folder or a new examples
. This way it is more clear what is what.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduced the examples folder now
@@ -74,7 +74,7 @@ libproj_la_SOURCES = \ | |||
jniproj.c pj_mutex.c pj_initcache.c pj_apply_vgridshift.c geodesic.c \ | |||
pj_strtod.c \ | |||
\ | |||
pj_observation.c | |||
pj_observation.c pj_cart.c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeping with the tradition the file should be PJ_cart.c
since all files with "projections" are named that way, and the rest uses the lower-cases nomenclature. I don't like it either (I'd prefer to organise the files in directories instead).
return pj_init_ctx (ctx, argc, argv); | ||
} | ||
|
||
PJ_CONTEXT *pj_ctx (PJ *P) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do the same with the API in proj_api.h
as documentend here: http://proj4.org/development/threads.html
This, and the one below, is just to get consistent naming across all pj_ctx*
functions. I am not really able to comment on why you would need that functionality though...
|
||
|
||
static void freeup (PJ *P) { | ||
pj_freeup_plain (P); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function does not appear to be defined anywhere. pj_dealloc
would usually be used here. Is this meant to be an alias?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is defined in pj_malloc.c and has a slightly different prototype than pj_dealloc: It takes a PJ as arg and frees its opaque object. It can be used to simplify/eliminate the freeup code for a large number of projections.
In response to reviews by Even Rouault and Kristian Evers
pj_roundtrip @95 | ||
pj_pj @96 | ||
pj_pj_argv @97 | ||
pj_roundtrip @98 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defined twice
Almost all references to the ctx subsystem eliminated
pj_context_inherit plus distance operators for two PJ_OBSERVATIONS
@busstoptaktik Your last commit, Minor extensions to new API, adds 1800+ lines of code. That doesn't seem very minor to me :) Was it your intention to add |
horner.c PJ_helmert.c PJ_pipeline.c. They will probably be added again in a short time - either to this PR or to an upcomming follow-up.
Definitely a "git add" blunder. Removed now. |
Everything accessed through the PJ object
(Trying to enforce a rebuild with const initializers 1/0 hoping this works for MSVC, which has a non-const HUGE_VAL)
static initialization with HUGE_VAL in MSVC is annoying.
pj_observation.c -> pj_obs_api.c PJ_OBSERVATION -> PJ_OBS PJ_SPATIOTEMPORAL -> PJ_COORD
OK - this PR has been announced on the mailing list (see thread "A re-rationalized API for PROJ.4"), without generating any negative response. It passes all checks, and has "no conflicts with the base branch". I find it ready for merging, and will do so in a moment. Thanks for reviewing, @kbevers and @rouault - your comments and change requests took the PR in a different, but much better, direction |
This PR continues the work on a rationalized (i.e. better namespaced) API, and also, as another step down the road to implementing transformation pipelines, reintrodices the PJ_cart.c cartesian/ellipsoidal converter, previously discussed in a former PR.
Regarding the API improvements, the full story is in the comments in proj.h, which I, for completeness, include below: