<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
code
{mso-style-priority:99;
font-family:"Courier New";}
pre
{mso-style-priority:99;
mso-style-link:"Formateret HTML Tegn";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Courier New";}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
span.FormateretHTMLTegn
{mso-style-name:"Formateret HTML Tegn";
mso-style-priority:99;
mso-style-link:"Formateret HTML";
font-family:"Courier New";
mso-fareast-language:DA;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:3.0cm 2.0cm 3.0cm 2.0cm;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="DA" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">Hello everybody,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">I want to direct your attention to the work Thomas Knudsen is doing on a new and more homogenous API for PROJ.4. Thomas presented his first ideas about a new API earlier this year when talk about transformation pipelines
first started. Since then the initial pipeline pull request has been withdrawn and the changes needed to make transformation pipelines happen are broken into smaller more logical chunks. A new API being one of those smaller chunks. Before anyone gets their
knickers in a twist, let me just stress the fact that this DOES NOT change the behavior of the old API (projects.h/proj_api.h), it merely adds a cleaner interface that will make usage of PROJ.4 a lot easier in the future.
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Thomas has already typed up a description of his work but until now it has only been available on the GitHub page. This is his introduction to the new API:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">The original proj API (defined in projects.h) has grown organically<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">over the years, but it has also grown somewhat messy.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">The same has happened with the newer high level API (defined in<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">proj_api.h): To support various historical objectives, proj_api.h<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">contains a rather complex combination of conditional defines and<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">typedefs. Probably for good (historical) reasons, which are not<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">always evident from today's perspective.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">This is an evolving attempt at creating a re-rationalized API<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">with primary design goals focused on sanitizing the namespaces.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">Hence, all symbols exposed are being moved to the pj_ namespace,<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">while all data types are being moved to the PJ_ namespace.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">Please note that this API is *orthogonal* to the previous APIs:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">Apart from some inclusion guards, projects.h and proj_api.h are not<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">touched - if you do not include proj.h, the projects and proj_api<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">APIs should work as they always have.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">A few implementation details:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">Apart from the namespacing efforts, I'm trying to eliminate three<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">proj_api elements, which I have found especially confusing.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">FIRST and foremost, I try to avoid typedef'ing away pointer<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">semantics. I agree that it can be occasionally useful, but I<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">prefer having the pointer nature of function arguments being<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">explicitly visible.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">Hence, projCtx has been replaced by PJ_CONTEXT *.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">SECOND, I try to eliminate cases of information hiding implemented<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">by redefining data types to void pointers.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">I prefer using a combination of forward declarations and typedefs.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">Hence:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"> typedef void *projCtx;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">Has been replaced by:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"> struct projCtx_t;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"> typedef struct projCtx_t PJ_CONTEXT;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">This makes it possible for the calling program to know that the<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">PJ_CONTEXT data type exists, and handle pointers to that data type<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">without having any idea about its internals.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">(obviously, in this example, struct projCtx_t should also be moved<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">to struct pj_ctx some day...)<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">THIRD, I try to eliminate implicit type punning. Hence this API<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">introduces the OBSERVATION data type, for generic coordinate and<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">ancillary data handling.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">It includes the PJ_SPATIOTEMPORAL and PJ_TRIPLET unions<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">making it possible to make explicit the previously used<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">"implicit type punning", where a XY is turned into a LP by<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">re#defining both as UV, behind the back of the user.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">The bare essentials API presented here follows the PROJ.4<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">convention of sailing the coordinate to be reprojected, up on<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">the stack ("call by value"), and symmetrically returning the<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">result on the stack. Although the OBSERVATION object is 4 times<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">as large as the traditional XY and LP objects, timing results<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">have shown the overhead to be very reasonable.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:65.2pt"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas">See pj_proj_test.c for an example of how to use the API.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">The pull request is found at <a href="https://github.com/OSGeo/proj.4/pull/445">
https://github.com/OSGeo/proj.4/pull/445</a> and the example code can be found here:
<a href="https://github.com/busstoptaktik/proj.4/blob/pipeline_plus_api/examples/pj_proj_test.c">
https://github.com/busstoptaktik/proj.4/blob/pipeline_plus_api/examples/pj_proj_test.c</a><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Please share your thoughts on the new API that Thomas has been working on. There has already been some discussion about how to expose the thread-contexts of the PJ-objects. In the current incarnation they are somewhat
hidden to the user compared the what’s in proj_api.h. On top of that, Thomas and I have personally discussed the projFileAPI which does not seem to be used outside of PROJ.4 itself (at least nothing shows up on google, closed source we have no idea about).
Is this something people actually need?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">/Kristian<o:p></o:p></span></p>
</div>
</body>
</html>