PROJ 4.8.0, projects.h and projPJ struct

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

PROJ 4.8.0, projects.h and projPJ struct

José Luis García Pallero
Hello:

As it is said in NEWS files from PROJ 4.8.0 now proj_api.h file should
be included in programs instead projects.h. I've tried to compile my
old code (that has no problems with 4.7.0) and I've obtained a warning
and an error.
In my code I have a declaration like

projPJ proyec;

and I use them later as

proyec = pj_init_plus(param);

and more later, in order to check if a projections has inverse step:

if(proyec->inv==0)
{
......
}

If I compile the program using 4.8.0 version I obtain a warning and an error:

geocproj.c:202:14: warning: dereferencing ‘void *’ pointer [enabled by
default]
geocproj.c:202:14: error: request for member ‘inv’ in something not a
structure or union

Looking proj_api.h file, in both versions 4.7.0 and 4.8.0 I can see the block

for 4.7.0

#if !defined(PROJECTS_H)
    typedef struct { double u, v; } projUV;
    typedef void *projPJ;
    #define projXY projUV
    #define projLP projUV
#else
    typedef PJ *projPJ;
#   define projXY XY
#   define projLP       LP
#endif

for 4.8.0

#if !defined(PROJECTS_H)
    typedef struct { double u, v; } projUV;
    typedef void *projPJ;
    #define projXY projUV
    #define projLP projUV
    typedef void *projCtx;
#else
    typedef PJ *projPJ;
    typedef projCtx_t *projCtx;
#   define projXY XY
#   define projLP       LP
#endif

Both are the same (except for the ctx context). In both if PROJECTS_H
is not defined (i.e. if projects.h was not included) the type projPJ
is defined as void* instead PJ*. PJ is defined in projects.h. But in
the include/ folder of 4.8.0 project.h was not copied, so it's
impossible to use it. So I can't use the 'inv' field and I suppone no
PJ struct at all as projPJ was defined as void*. Then which is the
correct way in order to use the new PROJ 4.8.0 version?



On the other hand, suppose that 4.8.0 works well in my case only
including proj_api.h. Then my problem is that if I have not knowledge
about the version of PROJ in one computer, how can I proceed in order
to use the correct include depending versions.
First of all, can I use version 4.7.0 (for example) with only
#include<proj_api.h>? In my case the answer is NO because I obtain the
same warning and error that in 4.8.0. Then I try:

#include<proj_api.h>
#if PJ_VERSION<480
#include<projects.h>
#endif

PJ_VERSION is defined in proj_api.h. I check if version is older than
4.8.0 and try to include then projects.h. But I obtain some errors:

/usr/include/projects.h:139:33: error: conflicting types for ‘projUV’
/usr/include/proj_api.h:54:37: note: previous declaration of ‘projUV’
was here
geocproj.c: In function ‘ProjFwd’:
geocproj.c:120:9: error: incompatible type for argument 1 of ‘pj_fwd’
/usr/include/proj_api.h:66:8: note: expected ‘projUV’ but argument is
of type ‘projUV’
geocproj.c: In function ‘ProjInv’:
geocproj.c:202:14: warning: dereferencing ‘void *’ pointer [enabled by
default]
geocproj.c:202:14: error: request for member ‘inv’ in something not a
structure or union
geocproj.c:223:9: error: incompatible type for argument 1 of ‘pj_inv’
/usr/include/proj_api.h:67:8: note: expected ‘projUV’ but argument is
of type ‘projUV’

We can see conflicting type errors due to definitions of projUV in
proj_api.h and projects.h.

Opinions about?

Cheers

--
*****************************************
José Luis García Pallero
[hidden email]
(o<
/ / \
V_/_
Use Debian GNU/Linux and enjoy!
*****************************************
_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

Sisyphus

----- Original Message -----
From: "José Luis García Pallero"

> #include<proj_api.h>
> #if PJ_VERSION<480
> #include<projects.h>
> #endif

I think that if PJ_VERSION < 480, then projects.h needs to be included
*before* proj_api.h.
And if PJ_VERSION == 480 then you need to *not* include projects.h at all.
Am I right ? If so, then I believe you have what is commonly referred to as
a "gotcha" (because it's impossible to cater for both requirements).

I think your problem is probably that, in the eyes of the proj developers,
you've accessed parts of projects.h that you shouldn't have - or at least,
you've accessed parts that they didn't expect you would.
But I'll leave the detailed explanation to those more qualified.

Cheers,
Rob

_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

José Luis García Pallero
El día 11 de abril de 2012 13:08, Sisyphus <[hidden email]> escribió:

>
> ----- Original Message -----
> From: "José Luis García Pallero"
>
>> #include<proj_api.h>
>> #if PJ_VERSION<480
>> #include<projects.h>
>> #endif
>
> I think that if PJ_VERSION < 480, then projects.h needs to be included
> *before* proj_api.h.

But the problem is that PJ_VERSION is defined in proj_api.h, so it
should be included first.

> And if PJ_VERSION == 480 then you need to *not* include projects.h at all.
> Am I right ? If so, then I believe you have what is commonly referred to as
> a "gotcha" (because it's impossible to cater for both requirements).
>
> I think your problem is probably that, in the eyes of the proj developers,
> you've accessed parts of projects.h that you shouldn't have - or at least,
> you've accessed parts that they didn't expect you would.

Mmmm... I'm not so sure of it. I think that check the field 'inv' of
projPJ struct (that is the source of the error) is a common behavior
in order to know if a projection implements the inverse step.

> But I'll leave the detailed explanation to those more qualified.
>
> Cheers,
> Rob
>
> _______________________________________________
> Proj mailing list
> [hidden email]
> http://lists.maptools.org/mailman/listinfo/proj



--
*****************************************
José Luis García Pallero
[hidden email]
(o<
/ / \
V_/_
Use Debian GNU/Linux and enjoy!
*****************************************
_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

Eric Miller-4
In reply to this post by José Luis García Pallero
I think that being able to interrogate the projection definition to know
if it has an inverse is useful, so a function should be added to
proj_api.h.

Perhaps:

int pj_has_inverse(projPJ);

And in pj_utils.c

/******************************************************************/
/*                                 pj_has_inverse()                    
            */
/*                                                                    
                   */
/*            Return TRUE if this coordinate system object has     */
/*            and inverse projection method.                          
  */
/*****************************************************************/
int pj_has_inverse( PJ *pj )
{
         return pj != NULL && pj->inv != NULL;
}

--

Eric G. Miller
Software Developer
CA Dept. of Fish & Game


>>> On 4/11/2012 at  3:30 AM, José Luis García Pallero
<[hidden email]>
wrote:
> Hello:
>
> As it is said in NEWS files from PROJ 4.8.0 now proj_api.h file
should
> be included in programs instead projects.h. I've tried to compile my
> old code (that has no problems with 4.7.0) and I've obtained a
warning

> and an error.
> In my code I have a declaration like
>
> projPJ proyec;
>
> and I use them later as
>
> proyec = pj_init_plus(param);
>
> and more later, in order to check if a projections has inverse step:
>
> if(proyec->inv==0)
> {
> ......
> }
>
> If I compile the program using 4.8.0 version I obtain a warning and
an
> error:
>
> geocproj.c:202:14: warning: dereferencing *void ** pointer
[enabled by
> default]
> geocproj.c:202:14: error: request for member *inv* in something
not a
> structure or union
>
> Looking proj_api.h file, in both versions 4.7.0 and 4.8.0 I can see
the

> block
>
> for 4.7.0
>
> #if !defined(PROJECTS_H)
>     typedef struct { double u, v; } projUV;
>     typedef void *projPJ;
>     #define projXY projUV
>     #define projLP projUV
> #else
>     typedef PJ *projPJ;
> #   define projXY XY
> #   define projLP       LP
> #endif
>
> for 4.8.0
>
> #if !defined(PROJECTS_H)
>     typedef struct { double u, v; } projUV;
>     typedef void *projPJ;
>     #define projXY projUV
>     #define projLP projUV
>     typedef void *projCtx;
> #else
>     typedef PJ *projPJ;
>     typedef projCtx_t *projCtx;
> #   define projXY XY
> #   define projLP       LP
> #endif
>
> Both are the same (except for the ctx context). In both if
PROJECTS_H
> is not defined (i.e. if projects.h was not included) the type projPJ
> is defined as void* instead PJ*. PJ is defined in projects.h. But in
> the include/ folder of 4.8.0 project.h was not copied, so it's
> impossible to use it. So I can't use the 'inv' field and I suppone
no
> PJ struct at all as projPJ was defined as void*. Then which is the
> correct way in order to use the new PROJ 4.8.0 version?
>
>
>
> On the other hand, suppose that 4.8.0 works well in my case only
> including proj_api.h. Then my problem is that if I have not
knowledge
> about the version of PROJ in one computer, how can I proceed in
order
> to use the correct include depending versions.
> First of all, can I use version 4.7.0 (for example) with only
> #include<proj_api.h>? In my case the answer is NO because I obtain
the
> same warning and error that in 4.8.0. Then I try:
>
> #include<proj_api.h>
> #if PJ_VERSION<480
> #include<projects.h>
> #endif
>
> PJ_VERSION is defined in proj_api.h. I check if version is older
than
> 4.8.0 and try to include then projects.h. But I obtain some errors:
>
> /usr/include/projects.h:139:33: error: conflicting types for
*projUV*
> /usr/include/proj_api.h:54:37: note: previous declaration of
*projUV*
> was here
> geocproj.c: In function *ProjFwd*:
> geocproj.c:120:9: error: incompatible type for argument 1 of
*pj_fwd*
> /usr/include/proj_api.h:66:8: note: expected *projUV* but
argument is
> of type *projUV*
> geocproj.c: In function *ProjInv*:
> geocproj.c:202:14: warning: dereferencing *void ** pointer
[enabled by
> default]
> geocproj.c:202:14: error: request for member *inv* in something
not a
> structure or union
> geocproj.c:223:9: error: incompatible type for argument 1 of
*pj_inv*
> /usr/include/proj_api.h:67:8: note: expected *projUV* but
argument is
> of type *projUV*
>
> We can see conflicting type errors due to definitions of projUV in
> proj_api.h and projects.h.
>
> Opinions about?
>
> Cheers

_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

Frank Warmerdam
Eric,

This seems reasonable.  Don't hesitate to file a ticket ideally with a patch.

Best regards,
Frank

On Wed, Apr 11, 2012 at 8:25 AM, Eric Miller <[hidden email]> wrote:

> I think that being able to interrogate the projection definition to know
> if it has an inverse is useful, so a function should be added to
> proj_api.h.
>
> Perhaps:
>
> int pj_has_inverse(projPJ);
>
> And in pj_utils.c
>
> /******************************************************************/
> /*                                 pj_has_inverse()
>            */
> /*
>                   */
> /*            Return TRUE if this coordinate system object has     */
> /*            and inverse projection method.
>  */
> /*****************************************************************/
> int pj_has_inverse( PJ *pj )
> {
>         return pj != NULL && pj->inv != NULL;
> }
>
> --
>
> Eric G. Miller
> Software Developer
> CA Dept. of Fish & Game
>
>
>>>> On 4/11/2012 at  3:30 AM, José Luis García Pallero
> <[hidden email]>
> wrote:
>> Hello:
>>
>> As it is said in NEWS files from PROJ 4.8.0 now proj_api.h file
> should
>> be included in programs instead projects.h. I've tried to compile my
>> old code (that has no problems with 4.7.0) and I've obtained a
> warning
>> and an error.
>> In my code I have a declaration like
>>
>> projPJ proyec;
>>
>> and I use them later as
>>
>> proyec = pj_init_plus(param);
>>
>> and more later, in order to check if a projections has inverse step:
>>
>> if(proyec->inv==0)
>> {
>> ......
>> }
>>
>> If I compile the program using 4.8.0 version I obtain a warning and
> an
>> error:
>>
>> geocproj.c:202:14: warning: dereferencing *void ** pointer
> [enabled by
>> default]
>> geocproj.c:202:14: error: request for member *inv* in something
> not a
>> structure or union
>>
>> Looking proj_api.h file, in both versions 4.7.0 and 4.8.0 I can see
> the
>> block
>>
>> for 4.7.0
>>
>> #if !defined(PROJECTS_H)
>>     typedef struct { double u, v; } projUV;
>>     typedef void *projPJ;
>>     #define projXY projUV
>>     #define projLP projUV
>> #else
>>     typedef PJ *projPJ;
>> #   define projXY     XY
>> #   define projLP       LP
>> #endif
>>
>> for 4.8.0
>>
>> #if !defined(PROJECTS_H)
>>     typedef struct { double u, v; } projUV;
>>     typedef void *projPJ;
>>     #define projXY projUV
>>     #define projLP projUV
>>     typedef void *projCtx;
>> #else
>>     typedef PJ *projPJ;
>>     typedef projCtx_t *projCtx;
>> #   define projXY     XY
>> #   define projLP       LP
>> #endif
>>
>> Both are the same (except for the ctx context). In both if
> PROJECTS_H
>> is not defined (i.e. if projects.h was not included) the type projPJ
>> is defined as void* instead PJ*. PJ is defined in projects.h. But in
>> the include/ folder of 4.8.0 project.h was not copied, so it's
>> impossible to use it. So I can't use the 'inv' field and I suppone
> no
>> PJ struct at all as projPJ was defined as void*. Then which is the
>> correct way in order to use the new PROJ 4.8.0 version?
>>
>>
>>
>> On the other hand, suppose that 4.8.0 works well in my case only
>> including proj_api.h. Then my problem is that if I have not
> knowledge
>> about the version of PROJ in one computer, how can I proceed in
> order
>> to use the correct include depending versions.
>> First of all, can I use version 4.7.0 (for example) with only
>> #include<proj_api.h>? In my case the answer is NO because I obtain
> the
>> same warning and error that in 4.8.0. Then I try:
>>
>> #include<proj_api.h>
>> #if PJ_VERSION<480
>> #include<projects.h>
>> #endif
>>
>> PJ_VERSION is defined in proj_api.h. I check if version is older
> than
>> 4.8.0 and try to include then projects.h. But I obtain some errors:
>>
>> /usr/include/projects.h:139:33: error: conflicting types for
> *projUV*
>> /usr/include/proj_api.h:54:37: note: previous declaration of
> *projUV*
>> was here
>> geocproj.c: In function *ProjFwd*:
>> geocproj.c:120:9: error: incompatible type for argument 1 of
> *pj_fwd*
>> /usr/include/proj_api.h:66:8: note: expected *projUV* but
> argument is
>> of type *projUV*
>> geocproj.c: In function *ProjInv*:
>> geocproj.c:202:14: warning: dereferencing *void ** pointer
> [enabled by
>> default]
>> geocproj.c:202:14: error: request for member *inv* in something
> not a
>> structure or union
>> geocproj.c:223:9: error: incompatible type for argument 1 of
> *pj_inv*
>> /usr/include/proj_api.h:67:8: note: expected *projUV* but
> argument is
>> of type *projUV*
>>
>> We can see conflicting type errors due to definitions of projUV in
>> proj_api.h and projects.h.
>>
>> Opinions about?
>>
>> Cheers
>
> _______________________________________________
> Proj mailing list
> [hidden email]
> http://lists.maptools.org/mailman/listinfo/proj



--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, [hidden email]
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | Geospatial Software Developer
_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

José Luis García Pallero
El día 11 de abril de 2012 19:27, Frank Warmerdam
<[hidden email]> escribió:

> Eric,
>
> This seems reasonable.  Don't hesitate to file a ticket ideally with a patch.
>
> Best regards,
> Frank
>
> On Wed, Apr 11, 2012 at 8:25 AM, Eric Miller <[hidden email]> wrote:
>> I think that being able to interrogate the projection definition to know
>> if it has an inverse is useful, so a function should be added to
>> proj_api.h.
>>
>> Perhaps:
>>
>> int pj_has_inverse(projPJ);
>>
>> And in pj_utils.c
>>
>> /******************************************************************/
>> /*                                 pj_has_inverse()
>>            */
>> /*
>>                   */
>> /*            Return TRUE if this coordinate system object has     */
>> /*            and inverse projection method.
>>  */
>> /*****************************************************************/
>> int pj_has_inverse( PJ *pj )
>> {
>>         return pj != NULL && pj->inv != NULL;
>> }

Hello:

This function sounds good, but I have a couple of objections:

1. First of all, the portability of old code. The programs that until
now include projects.h instead proj_api.h should be corrected. I
propose to rename projects.h to projects_internal.h (for example) and
create a new projects.h that contains only #include<proj_api.h> Then,
it can be maintained in programs the #include<projects.h> and it runs
always: prior to 4.8.0 and 4.8.0 or higher. Previously on this same
topic I explained that is impossible to check automatically the
version of PROJ via PJ_VERSION and select the correct header to
include because if projects.h is included after proj_api.h some errors
of conflicting types appears. Creating new projects.h could avoid this
gotcha.

2. What about the old code that uses explicitly some fields of projPJ
structs? Why in 4.8.0 projPJ fields are not public? For old code that
uses explicitly fields of projPJ the solution of the point 1 is not
valid. Another solution could be to define explicitly the PJ struct in
proj_api.h. Whith this solution plus the new projects.h I think that
almost all old code should have not problems with new 4.8.0 version

Cheers

>>
>> --
>>
>> Eric G. Miller
>> Software Developer
>> CA Dept. of Fish & Game
>>
>>
>>>>> On 4/11/2012 at  3:30 AM, José Luis García Pallero
>> <[hidden email]>
>> wrote:
>>> Hello:
>>>
>>> As it is said in NEWS files from PROJ 4.8.0 now proj_api.h file
>> should
>>> be included in programs instead projects.h. I've tried to compile my
>>> old code (that has no problems with 4.7.0) and I've obtained a
>> warning
>>> and an error.
>>> In my code I have a declaration like
>>>
>>> projPJ proyec;
>>>
>>> and I use them later as
>>>
>>> proyec = pj_init_plus(param);
>>>
>>> and more later, in order to check if a projections has inverse step:
>>>
>>> if(proyec->inv==0)
>>> {
>>> ......
>>> }
>>>
>>> If I compile the program using 4.8.0 version I obtain a warning and
>> an
>>> error:
>>>
>>> geocproj.c:202:14: warning: dereferencing *void ** pointer
>> [enabled by
>>> default]
>>> geocproj.c:202:14: error: request for member *inv* in something
>> not a
>>> structure or union
>>>
>>> Looking proj_api.h file, in both versions 4.7.0 and 4.8.0 I can see
>> the
>>> block
>>>
>>> for 4.7.0
>>>
>>> #if !defined(PROJECTS_H)
>>>     typedef struct { double u, v; } projUV;
>>>     typedef void *projPJ;
>>>     #define projXY projUV
>>>     #define projLP projUV
>>> #else
>>>     typedef PJ *projPJ;
>>> #   define projXY     XY
>>> #   define projLP       LP
>>> #endif
>>>
>>> for 4.8.0
>>>
>>> #if !defined(PROJECTS_H)
>>>     typedef struct { double u, v; } projUV;
>>>     typedef void *projPJ;
>>>     #define projXY projUV
>>>     #define projLP projUV
>>>     typedef void *projCtx;
>>> #else
>>>     typedef PJ *projPJ;
>>>     typedef projCtx_t *projCtx;
>>> #   define projXY     XY
>>> #   define projLP       LP
>>> #endif
>>>
>>> Both are the same (except for the ctx context). In both if
>> PROJECTS_H
>>> is not defined (i.e. if projects.h was not included) the type projPJ
>>> is defined as void* instead PJ*. PJ is defined in projects.h. But in
>>> the include/ folder of 4.8.0 project.h was not copied, so it's
>>> impossible to use it. So I can't use the 'inv' field and I suppone
>> no
>>> PJ struct at all as projPJ was defined as void*. Then which is the
>>> correct way in order to use the new PROJ 4.8.0 version?
>>>
>>>
>>>
>>> On the other hand, suppose that 4.8.0 works well in my case only
>>> including proj_api.h. Then my problem is that if I have not
>> knowledge
>>> about the version of PROJ in one computer, how can I proceed in
>> order
>>> to use the correct include depending versions.
>>> First of all, can I use version 4.7.0 (for example) with only
>>> #include<proj_api.h>? In my case the answer is NO because I obtain
>> the
>>> same warning and error that in 4.8.0. Then I try:
>>>
>>> #include<proj_api.h>
>>> #if PJ_VERSION<480
>>> #include<projects.h>
>>> #endif
>>>
>>> PJ_VERSION is defined in proj_api.h. I check if version is older
>> than
>>> 4.8.0 and try to include then projects.h. But I obtain some errors:
>>>
>>> /usr/include/projects.h:139:33: error: conflicting types for
>> *projUV*
>>> /usr/include/proj_api.h:54:37: note: previous declaration of
>> *projUV*
>>> was here
>>> geocproj.c: In function *ProjFwd*:
>>> geocproj.c:120:9: error: incompatible type for argument 1 of
>> *pj_fwd*
>>> /usr/include/proj_api.h:66:8: note: expected *projUV* but
>> argument is
>>> of type *projUV*
>>> geocproj.c: In function *ProjInv*:
>>> geocproj.c:202:14: warning: dereferencing *void ** pointer
>> [enabled by
>>> default]
>>> geocproj.c:202:14: error: request for member *inv* in something
>> not a
>>> structure or union
>>> geocproj.c:223:9: error: incompatible type for argument 1 of
>> *pj_inv*
>>> /usr/include/proj_api.h:67:8: note: expected *projUV* but
>> argument is
>>> of type *projUV*
>>>
>>> We can see conflicting type errors due to definitions of projUV in
>>> proj_api.h and projects.h.
>>>
>>> Opinions about?
>>>
>>> Cheers
>>
>> _______________________________________________
>> Proj mailing list
>> [hidden email]
>> http://lists.maptools.org/mailman/listinfo/proj
>
>
>
> --
> ---------------------------------------+--------------------------------------
> I set the clouds in motion - turn up   | Frank Warmerdam, [hidden email]
> light and sound - activate the windows | http://pobox.com/~warmerdam
> and watch the world go round - Rush    | Geospatial Software Developer
> _______________________________________________
> Proj mailing list
> [hidden email]
> http://lists.maptools.org/mailman/listinfo/proj



--
*****************************************
José Luis García Pallero
[hidden email]
(o<
/ / \
V_/_
Use Debian GNU/Linux and enjoy!
*****************************************
_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

Eric Miller-4
José,

I don't have a strong opinion about the matter, but I will reiterate
what has already been written.

The "projects.h" file has been noted as internal/private for many
years.  I don't know when the "private" designation first appeared, but
it was at least five years ago.  The "proj_api.h" header was created to
provide the public api for consumers of the library. Again, this was
many years ago.

I might have waited for a 5.0 release to break the old API by removing
"projects.h", but not everybody follows or agrees with the major/minor
API compatibility concept.

As to why the structure should be hidden, I can only say that it is
pretty standard practice to hide the implementation details from the
outside world.  Usually, that insulates the outside world from changes
that would otherwise break their code.  For instance, if a particular
variable was renamed or removed from PJConsts, your application might
break.  Should the library internals be held captive to the outside
world for backwards compatibility? For how long?

See: http://en.wikipedia.org/wiki/Information_hiding

>>> On 4/11/2012 at  1:50 PM, José Luis García Pallero
<[hidden email]> wrote:
>
> Hello:
>
> This function sounds good, but I have a couple of objections:
>
> 1. First of all, the portability of old code. The programs that
until
> now include projects.h instead proj_api.h should be corrected. I
> propose to rename projects.h to projects_internal.h (for example)
and
> create a new projects.h that contains only #include<proj_api.h>
Then,
> it can be maintained in programs the #include<projects.h> and it
runs
> always: prior to 4.8.0 and 4.8.0 or higher. Previously on this same
> topic I explained that is impossible to check automatically the
> version of PROJ via PJ_VERSION and select the correct header to
> include because if projects.h is included after proj_api.h some
errors
> of conflicting types appears. Creating new projects.h could avoid
this
> gotcha.
>
> 2. What about the old code that uses explicitly some fields of
projPJ
> structs? Why in 4.8.0 projPJ fields are not public? For old code
that
> uses explicitly fields of projPJ the solution of the point 1 is not
> valid. Another solution could be to define explicitly the PJ struct
in

> proj_api.h. Whith this solution plus the new projects.h I think that
> almost all old code should have not problems with new 4.8.0 version
>
> Cheers
>
> El día 11 de abril de 2012 19:27, Frank Warmerdam
> <[hidden email]> escribió:
>> Eric,
>>
>> This seems reasonable.  Don't hesitate to file a ticket ideally with
a
> patch.
>>
>> Best regards,
>> Frank
>>
>> On Wed, Apr 11, 2012 at 8:25 AM, Eric Miller <[hidden email]>
wrote:
>>> I think that being able to interrogate the projection definition to
know

>>> if it has an inverse is useful, so a function should be added to
>>> proj_api.h.
>>>
>>> Perhaps:
>>>
>>> int pj_has_inverse(projPJ);
>>>
>>> And in pj_utils.c
>>>
>>>
/******************************************************************/
>>> /*                                 pj_has_inverse()
>>>            */
>>> /*
>>>                   */
>>> /*            Return TRUE if this coordinate system object has    
*/
>>> /*            and inverse projection method.
>>>  */
>>>
/*****************************************************************/

>>> int pj_has_inverse( PJ *pj )
>>> {
>>>         return pj != NULL && pj->inv != NULL;
>>> }
>>>
>>> --
>>>
>>> Eric G. Miller
>>> Software Developer
>>> CA Dept. of Fish & Game
>>>
>>>
>>>>>> On 4/11/2012 at  3:30 AM, José Luis García Pallero
>>> <[hidden email]>
>>> wrote:
>>>> Hello:
>>>>
>>>> As it is said in NEWS files from PROJ 4.8.0 now proj_api.h file
>>> should
>>>> be included in programs instead projects.h. I've tried to compile
my

>>>> old code (that has no problems with 4.7.0) and I've obtained a
>>> warning
>>>> and an error.
>>>> In my code I have a declaration like
>>>>
>>>> projPJ proyec;
>>>>
>>>> and I use them later as
>>>>
>>>> proyec = pj_init_plus(param);
>>>>
>>>> and more later, in order to check if a projections has inverse
step:
>>>>
>>>> if(proyec->inv==0)
>>>> {
>>>> ......
>>>> }
>>>>
>>>> If I compile the program using 4.8.0 version I obtain a warning
and

>>> an
>>>> error:
>>>>
>>>> geocproj.c:202:14: warning: dereferencing *void ** pointer
>>> [enabled by
>>>> default]
>>>> geocproj.c:202:14: error: request for member *inv* in something
>>> not a
>>>> structure or union
>>>>
>>>> Looking proj_api.h file, in both versions 4.7.0 and 4.8.0 I can
see

>>> the
>>>> block
>>>>
>>>> for 4.7.0
>>>>
>>>> #if !defined(PROJECTS_H)
>>>>     typedef struct { double u, v; } projUV;
>>>>     typedef void *projPJ;
>>>>     #define projXY projUV
>>>>     #define projLP projUV
>>>> #else
>>>>     typedef PJ *projPJ;
>>>> #   define projXY     XY
>>>> #   define projLP       LP
>>>> #endif
>>>>
>>>> for 4.8.0
>>>>
>>>> #if !defined(PROJECTS_H)
>>>>     typedef struct { double u, v; } projUV;
>>>>     typedef void *projPJ;
>>>>     #define projXY projUV
>>>>     #define projLP projUV
>>>>     typedef void *projCtx;
>>>> #else
>>>>     typedef PJ *projPJ;
>>>>     typedef projCtx_t *projCtx;
>>>> #   define projXY     XY
>>>> #   define projLP       LP
>>>> #endif
>>>>
>>>> Both are the same (except for the ctx context). In both if
>>> PROJECTS_H
>>>> is not defined (i.e. if projects.h was not included) the type
projPJ
>>>> is defined as void* instead PJ*. PJ is defined in projects.h. But
in
>>>> the include/ folder of 4.8.0 project.h was not copied, so it's
>>>> impossible to use it. So I can't use the 'inv' field and I
suppone
>>> no
>>>> PJ struct at all as projPJ was defined as void*. Then which is
the

>>>> correct way in order to use the new PROJ 4.8.0 version?
>>>>
>>>>
>>>>
>>>> On the other hand, suppose that 4.8.0 works well in my case only
>>>> including proj_api.h. Then my problem is that if I have not
>>> knowledge
>>>> about the version of PROJ in one computer, how can I proceed in
>>> order
>>>> to use the correct include depending versions.
>>>> First of all, can I use version 4.7.0 (for example) with only
>>>> #include<proj_api.h>? In my case the answer is NO because I
obtain

>>> the
>>>> same warning and error that in 4.8.0. Then I try:
>>>>
>>>> #include<proj_api.h>
>>>> #if PJ_VERSION<480
>>>> #include<projects.h>
>>>> #endif
>>>>
>>>> PJ_VERSION is defined in proj_api.h. I check if version is older
>>> than
>>>> 4.8.0 and try to include then projects.h. But I obtain some
errors:

>>>>
>>>> /usr/include/projects.h:139:33: error: conflicting types for
>>> *projUV*
>>>> /usr/include/proj_api.h:54:37: note: previous declaration of
>>> *projUV*
>>>> was here
>>>> geocproj.c: In function *ProjFwd*:
>>>> geocproj.c:120:9: error: incompatible type for argument 1 of
>>> *pj_fwd*
>>>> /usr/include/proj_api.h:66:8: note: expected *projUV* but
>>> argument is
>>>> of type *projUV*
>>>> geocproj.c: In function *ProjInv*:
>>>> geocproj.c:202:14: warning: dereferencing *void ** pointer
>>> [enabled by
>>>> default]
>>>> geocproj.c:202:14: error: request for member *inv* in something
>>> not a
>>>> structure or union
>>>> geocproj.c:223:9: error: incompatible type for argument 1 of
>>> *pj_inv*
>>>> /usr/include/proj_api.h:67:8: note: expected *projUV* but
>>> argument is
>>>> of type *projUV*
>>>>
>>>> We can see conflicting type errors due to definitions of projUV
in
>>>> proj_api.h and projects.h.
>>>>
>>>> Opinions about?
>>>>
>>>> Cheers


_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

Frank Warmerdam
In reply to this post by José Luis García Pallero
2012/4/11 José Luis García Pallero <[hidden email]>:

> This function sounds good, but I have a couple of objections:
>
> 1. First of all, the portability of old code. The programs that until
> now include projects.h instead proj_api.h should be corrected. I
> propose to rename projects.h to projects_internal.h (for example) and
> create a new projects.h that contains only #include<proj_api.h> Then,
> it can be maintained in programs the #include<projects.h> and it runs
> always: prior to 4.8.0 and 4.8.0 or higher. Previously on this same
> topic I explained that is impossible to check automatically the
> version of PROJ via PJ_VERSION and select the correct header to
> include because if projects.h is included after proj_api.h some errors
> of conflicting types appears. Creating new projects.h could avoid this
> gotcha.

José,

On linux configure can check for projects.h and probe for versions.

On windows you are generally having to handle proj yourself so what
is the big issue about different versions?

I guess I just don't feel this as a serious issue.

> 2. What about the old code that uses explicitly some fields of projPJ
> structs? Why in 4.8.0 projPJ fields are not public? For old code that
> uses explicitly fields of projPJ the solution of the point 1 is not
> valid. Another solution could be to define explicitly the PJ struct in
> proj_api.h. Whith this solution plus the new projects.h I think that
> almost all old code should have not problems with new 4.8.0 version

A large part of the reason for making projects.h private was to break
the dependence of application on the particulars of the layout of the
projPJ structure!  So, if you really need it, just include projects.h and
manually copy that from the source distribution.  But if you want to
follow the public API contract then stick to proj_api.h.

I don't mean to be peevish, but to me this seems to be an issue from
half a decade ago.  I've certainly been advising all to migrate to proj_api.h
for a long time.

Best regards,
--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, [hidden email]
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | Geospatial Software Developer
_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

José Luis García Pallero
El día 12 de abril de 2012 07:32, Frank Warmerdam
<[hidden email]> escribió:

> 2012/4/11 José Luis García Pallero <[hidden email]>:
>> This function sounds good, but I have a couple of objections:
>>
>> 1. First of all, the portability of old code. The programs that until
>> now include projects.h instead proj_api.h should be corrected. I
>> propose to rename projects.h to projects_internal.h (for example) and
>> create a new projects.h that contains only #include<proj_api.h> Then,
>> it can be maintained in programs the #include<projects.h> and it runs
>> always: prior to 4.8.0 and 4.8.0 or higher. Previously on this same
>> topic I explained that is impossible to check automatically the
>> version of PROJ via PJ_VERSION and select the correct header to
>> include because if projects.h is included after proj_api.h some errors
>> of conflicting types appears. Creating new projects.h could avoid this
>> gotcha.
>
> José,
>
> On linux configure can check for projects.h and probe for versions.
>
> On windows you are generally having to handle proj yourself so what
> is the big issue about different versions?
>
> I guess I just don't feel this as a serious issue.
>
>> 2. What about the old code that uses explicitly some fields of projPJ
>> structs? Why in 4.8.0 projPJ fields are not public? For old code that
>> uses explicitly fields of projPJ the solution of the point 1 is not
>> valid. Another solution could be to define explicitly the PJ struct in
>> proj_api.h. Whith this solution plus the new projects.h I think that
>> almost all old code should have not problems with new 4.8.0 version
>
> A large part of the reason for making projects.h private was to break
> the dependence of application on the particulars of the layout of the
> projPJ structure!  So, if you really need it, just include projects.h and
> manually copy that from the source distribution.  But if you want to
> follow the public API contract then stick to proj_api.h.
>
> I don't mean to be peevish, but to me this seems to be an issue from
> half a decade ago.  I've certainly been advising all to migrate to proj_api.h
> for a long time.

OK, I understand. Thank you for your answers.

And about checking if a projection has inverse step, if I can't access
to projPJ->inv field I'll try to detect it via pj_get_errno_ref(). In
the source of pj_transform.c I can see that a projection that has not
inverse step returns an error code -17. This -17 is hardcoded in
pj_transform.c. Can you confirm that for no inverse step was always
-17 the error value, in old releases included?

Cheers

>
> Best regards,
> --
> ---------------------------------------+--------------------------------------
> I set the clouds in motion - turn up   | Frank Warmerdam, [hidden email]
> light and sound - activate the windows | http://pobox.com/~warmerdam
> and watch the world go round - Rush    | Geospatial Software Developer
> _______________________________________________
> Proj mailing list
> [hidden email]
> http://lists.maptools.org/mailman/listinfo/proj



--
*****************************************
José Luis García Pallero
[hidden email]
(o<
/ / \
V_/_
Use Debian GNU/Linux and enjoy!
*****************************************
_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

Frank Warmerdam
2012/4/12 José Luis García Pallero <[hidden email]>:
> And about checking if a projection has inverse step, if I can't access
> to projPJ->inv field I'll try to detect it via pj_get_errno_ref(). In
> the source of pj_transform.c I can see that a projection that has not
> inverse step returns an error code -17. This -17 is hardcoded in
> pj_transform.c. Can you confirm that for no inverse step was always
> -17 the error value, in old releases included?

José,

This has not changed.

Best regards,

--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, [hidden email]
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | Geospatial Software Developer
_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
Reply | Threaded
Open this post in threaded view
|

Re: PROJ 4.8.0, projects.h and projPJ struct

Judd Taylor-2
In reply to this post by Frank Warmerdam
Using configure assumes you're doing a C/C++ configure build, which is not true in the case of the PDL/Perl bindings, so it's not very helpful. Configure will compile a test program to pull the value.

That's a lot to ask to build into every build system out there where someone wants to use the proj library.


The PDL binding works by first adding a low level layer that provides access to the library directly. This includes the interrogation of the projections available and the parameters. The next layer up uses a code generator at build time to generate a PDL::Transforms compatible code stub and documentation based on that projection information. So the reason I need the internal projection information is to be used in a code generator that works with PDL.

Describing how the PDL code generators (called PDL::PP) work, is probably beyond the scope of this exchange. But in general it handles generating C (perlXS/C) code for all of the potential data types/array configurations where the binding could be called. The run time PDL code will select the proper C code for the case in hand. This enables C speed with perl ease of use. There's also lots of built in threading and parallelization optimizations possible.


Other versioning issues aside, I think this feature should be enabled in the proj_api.h interface. In fact, I think all of the features that the proj binary uses should be enabled through the proj_api.h interface. Especially since "look at the proj source" has been the advice given on this list for so long. Taking care of those uses will likely enable backwards compatibility for all of the existing code out there that uses projects.h.


-Judd

____________________________
Judd Taylor
Software Engineer

Orbital Systems, Ltd.
3807 Carbon Rd.
Irving, TX 75038-3415

[hidden email]
(972) 915-3669 x127

________________________________________
From: [hidden email] [[hidden email]] on behalf of Frank Warmerdam [[hidden email]]
Sent: Thursday, April 12, 2012 12:32 AM
To: PROJ.4 and general Projections Discussions
Subject: Re: [Proj] PROJ 4.8.0, projects.h and projPJ struct

2012/4/11 José Luis García Pallero <[hidden email]>:

> This function sounds good, but I have a couple of objections:
>
> 1. First of all, the portability of old code. The programs that until
> now include projects.h instead proj_api.h should be corrected. I
> propose to rename projects.h to projects_internal.h (for example) and
> create a new projects.h that contains only #include<proj_api.h> Then,
> it can be maintained in programs the #include<projects.h> and it runs
> always: prior to 4.8.0 and 4.8.0 or higher. Previously on this same
> topic I explained that is impossible to check automatically the
> version of PROJ via PJ_VERSION and select the correct header to
> include because if projects.h is included after proj_api.h some errors
> of conflicting types appears. Creating new projects.h could avoid this
> gotcha.

José,

On linux configure can check for projects.h and probe for versions.

On windows you are generally having to handle proj yourself so what
is the big issue about different versions?

I guess I just don't feel this as a serious issue.

> 2. What about the old code that uses explicitly some fields of projPJ
> structs? Why in 4.8.0 projPJ fields are not public? For old code that
> uses explicitly fields of projPJ the solution of the point 1 is not
> valid. Another solution could be to define explicitly the PJ struct in
> proj_api.h. Whith this solution plus the new projects.h I think that
> almost all old code should have not problems with new 4.8.0 version

A large part of the reason for making projects.h private was to break
the dependence of application on the particulars of the layout of the
projPJ structure!  So, if you really need it, just include projects.h and
manually copy that from the source distribution.  But if you want to
follow the public API contract then stick to proj_api.h.

I don't mean to be peevish, but to me this seems to be an issue from
half a decade ago.  I've certainly been advising all to migrate to proj_api.h
for a long time.

Best regards,
--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, [hidden email]
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | Geospatial Software Developer
_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj
_______________________________________________
Proj mailing list
[hidden email]
http://lists.maptools.org/mailman/listinfo/proj