aboutsummaryrefslogtreecommitdiff
path: root/community/rfc/rfc-6.html
diff options
context:
space:
mode:
Diffstat (limited to 'community/rfc/rfc-6.html')
-rw-r--r--community/rfc/rfc-6.html474
1 files changed, 474 insertions, 0 deletions
diff --git a/community/rfc/rfc-6.html b/community/rfc/rfc-6.html
new file mode 100644
index 00000000..ed464a2e
--- /dev/null
+++ b/community/rfc/rfc-6.html
@@ -0,0 +1,474 @@
+<!DOCTYPE html>
+<html class="writer-html5" lang="en" >
+<head>
+ <meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>PROJ RFC 6: Triangulation-based transformations &mdash; PROJ 9.0.0 documentation</title>
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
+ <link rel="shortcut icon" href="../../_static/favicon.png"/>
+ <link rel="canonical" href="https://proj.orgcommunity/rfc/rfc-6.html"/>
+ <!--[if lt IE 9]>
+ <script src="../../_static/js/html5shiv.min.js"></script>
+ <![endif]-->
+
+ <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
+ <script src="../../_static/jquery.js"></script>
+ <script src="../../_static/underscore.js"></script>
+ <script src="../../_static/doctools.js"></script>
+ <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
+ <script src="../../_static/js/theme.js"></script>
+ <link rel="author" title="About these documents" href="../../about.html" />
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+ <link rel="next" title="PROJ RFC 7: Drop Autotools, maintain CMake" href="rfc-7.html" />
+ <link rel="prev" title="PROJ RFC 5: Adopt GeoTIFF-based grids for grids delivered with PROJ" href="rfc-5.html" />
+</head>
+
+<body class="wy-body-for-nav">
+ <div class="wy-grid-for-nav">
+ <nav data-toggle="wy-nav-shift" class="wy-nav-side">
+ <div class="wy-side-scroll">
+ <div class="wy-side-nav-search" style="background: #353130" >
+ <a href="../../index.html">
+ <img src="../../_static/logo.png" class="logo" alt="Logo"/>
+ </a>
+ <div class="version">
+ 9.0.0
+ </div>
+<div role="search">
+ <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
+ <input type="text" name="q" placeholder="Search docs" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+</div>
+ </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
+ <ul class="current">
+<li class="toctree-l1"><a class="reference internal" href="../../about.html">About</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../news.html">News</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../download.html">Download</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../install.html">Installation</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../usage/index.html">Using PROJ</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../apps/index.html">Applications</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../operations/index.html">Coordinate operations</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../resource_files.html">Resource files</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../geodesic.html">Geodesic calculations</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../development/index.html">Development</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../specifications/index.html">Specifications</a></li>
+<li class="toctree-l1 current"><a class="reference internal" href="../index.html">Community</a><ul class="current">
+<li class="toctree-l2"><a class="reference internal" href="../channels.html">Communication channels</a></li>
+<li class="toctree-l2"><a class="reference internal" href="../contributing.html">Contributing</a></li>
+<li class="toctree-l2"><a class="reference internal" href="../code_contributions.html">Guidelines for PROJ code contributors</a></li>
+<li class="toctree-l2"><a class="reference internal" href="../code_of_conduct.html">Code of Conduct</a></li>
+<li class="toctree-l2 current"><a class="reference internal" href="index.html">Request for Comments</a><ul class="current">
+<li class="toctree-l3"><a class="reference internal" href="rfc-1.html">PROJ RFC 1: Project Committee Guidelines</a></li>
+<li class="toctree-l3"><a class="reference internal" href="rfc-2.html">PROJ RFC 2: Initial integration of “GDAL SRS barn” work</a></li>
+<li class="toctree-l3"><a class="reference internal" href="rfc-3.html">PROJ RFC 3: Dependency management</a></li>
+<li class="toctree-l3"><a class="reference internal" href="rfc-4.html">PROJ RFC 4: Remote access to grids and GeoTIFF grids</a></li>
+<li class="toctree-l3"><a class="reference internal" href="rfc-5.html">PROJ RFC 5: Adopt GeoTIFF-based grids for grids delivered with PROJ</a></li>
+<li class="toctree-l3 current"><a class="current reference internal" href="#">PROJ RFC 6: Triangulation-based transformations</a><ul>
+<li class="toctree-l4"><a class="reference internal" href="#summary">Summary</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#details">Details</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#backward-compatibility">Backward compatibility</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#testing">Testing</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#documentation">Documentation</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#proposed-implementation">Proposed implementation</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#references">References</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#adoption-status">Adoption status</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#funding">Funding</a></li>
+</ul>
+</li>
+<li class="toctree-l3"><a class="reference internal" href="rfc-7.html">PROJ RFC 7: Drop Autotools, maintain CMake</a></li>
+</ul>
+</li>
+<li class="toctree-l2"><a class="reference internal" href="../index.html#conference">Conference</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="../../faq.html">FAQ</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../glossary.html">Glossary</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../../zreferences.html">References</a></li>
+</ul>
+
+ </div>
+ </div>
+ </nav>
+
+ <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" style="background: #353130" >
+ <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
+ <a href="../../index.html">PROJ</a>
+ </nav>
+
+ <div class="wy-nav-content">
+ <div class="rst-content">
+ <div role="navigation" aria-label="Page navigation">
+ <ul class="wy-breadcrumbs">
+ <li><a href="../../index.html" class="icon icon-home"></a> &raquo;</li>
+ <li><a href="../index.html">Community</a> &raquo;</li>
+ <li><a href="index.html">Request for Comments</a> &raquo;</li>
+ <li>PROJ RFC 6: Triangulation-based transformations</li>
+ <li class="wy-breadcrumbs-aside">
+ <a href="https://github.com/OSGeo/PROJ/edit/8.2/docs/source/community/rfc/rfc-6.rst" class="fa fa-github"> Edit on GitHub</a>
+ </li>
+ </ul><div class="rst-breadcrumbs-buttons" role="navigation" aria-label="Sequential page navigation">
+ <a href="rfc-5.html" class="btn btn-neutral float-left" title="PROJ RFC 5: Adopt GeoTIFF-based grids for grids delivered with PROJ" accesskey="p"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
+ <a href="rfc-7.html" class="btn btn-neutral float-right" title="PROJ RFC 7: Drop Autotools, maintain CMake" accesskey="n">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
+ </div>
+ <hr/>
+</div>
+ <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
+ <div itemprop="articleBody">
+
+ <section id="proj-rfc-6-triangulation-based-transformations">
+<span id="rfc6"></span><h1>PROJ RFC 6: Triangulation-based transformations<a class="headerlink" href="#proj-rfc-6-triangulation-based-transformations" title="Permalink to this headline">¶</a></h1>
+<dl class="field-list simple">
+<dt class="field-odd">Author</dt>
+<dd class="field-odd"><p>Even Rouault</p>
+</dd>
+<dt class="field-even">Contact</dt>
+<dd class="field-even"><p><a class="reference external" href="mailto:even&#46;rouault&#37;&#52;&#48;spatialys&#46;com">even<span>&#46;</span>rouault<span>&#64;</span>spatialys<span>&#46;</span>com</a></p>
+</dd>
+<dt class="field-odd">Status</dt>
+<dd class="field-odd"><p>Adopted</p>
+</dd>
+<dt class="field-even">Implementation target</dt>
+<dd class="field-even"><p>PROJ 7.2</p>
+</dd>
+<dt class="field-odd">Last Updated</dt>
+<dd class="field-odd"><p>2020-09-02</p>
+</dd>
+</dl>
+<section id="summary">
+<h2>Summary<a class="headerlink" href="#summary" title="Permalink to this headline">¶</a></h2>
+<p>This RFC adds a new transformation method, <code class="docutils literal notranslate"><span class="pre">tinshift</span></code> (TIN stands for
+Triangulated Irregular Network)</p>
+<p>The motivation for this work is to be able to handle the official transformations
+created by National Land Survey of Finland, for:</p>
+<ul class="simple">
+<li><p>horizontal transformation between the KKJ and ETRS89 horizontal datums</p></li>
+<li><p>vertical transformations between N43 and N60 heights, and N60 and N2000 heights.</p></li>
+</ul>
+<p>Such transformations are somehow related to traditional grid-based transformations,
+except that the correction values are hold by the vertices of the triangulation,
+instead of being at nodes of a grid.</p>
+<p>Triangulation are in a number of cases the initial product of a geodesic adjustment,
+with grids being a derived product. The Swiss grids have for example
+derived products of an original triangulation.</p>
+<p>Grid-based transformations remain very convenient to use because accessing
+correction values is really easy and efficient, so triangulation-based transformations
+are not meant as replacing them, but more about it being a complement, that is
+sometimes necessary to be able to replicate the results of a officially vetted
+transformation to a millimetric or better precision (speaking here about reproducibility
+of numeric results, rather than the physical accuracy of the transformation that
+might rather be centimetric). It is always possible to approach the result of
+the triangulation with a grid, but that may require to adopt a small grid step,
+and thus generate a grid that can be much larger than the original triangulation.</p>
+</section>
+<section id="details">
+<h2>Details<a class="headerlink" href="#details" title="Permalink to this headline">¶</a></h2>
+<section id="transformation">
+<h3>Transformation<a class="headerlink" href="#transformation" title="Permalink to this headline">¶</a></h3>
+<p>A new transformation method, <code class="docutils literal notranslate"><span class="pre">tinshift</span></code>, is added. It takes one mandatory
+argument, <code class="docutils literal notranslate"><span class="pre">file</span></code>, that points to a JSON file, which contains the triangulation
+and associated metadata. Input and output coordinates must be geographic or projected.
+Depending on the content
+of the JSON file, horizontal, vertical or both components of the coordinates may
+be transformed.</p>
+<p>The transformation is used like:</p>
+<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ echo 3210000.0000 6700000.0000 0 2020 | cct +proj=tinshift +file=./triangulation_kkj.json
+
+209948.3217 6697187.0009 0.0000 2020
+</pre></div>
+</div>
+<p>The transformation is invertible, with the same computational complexity than
+the forward transformation.</p>
+</section>
+<section id="algorithm">
+<h3>Algorithm<a class="headerlink" href="#algorithm" title="Permalink to this headline">¶</a></h3>
+<p>Internally, <code class="docutils literal notranslate"><span class="pre">tinshift</span></code> ingest the whole file into memory. It is considered that
+triangulation should be small enough for that. The above mentioned KKJ to ETRS89
+triangulation fits into 65 KB of JSON, for 1449 triangles and 767 vertices.</p>
+<p>When a point is transformed, one must find the triangle into which it falls into.
+Instead of iterating over all triangles, we build a in-memory quadtree to speed-up
+the identification of candidates triangles. On the above mentioned KKJ -&gt; ETRS89
+triangulation, this speeds up the whole transformation by a factor of 10. The
+quadtree structure is a very good compromise between the performance gain it brings
+and the simplicity of its implementation (we have ported the implementation coming
+from GDAL, inherit from the one used for shapefile .spx spatial indices).</p>
+<p>To determine if a point falls into a triangle, one computes its 3
+<a class="reference external" href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system#Conversion_between_barycentric_and_Cartesian_coordinates">barycentric coordinates</a>
+from its projected coordinates, <span class="math notranslate nohighlight">\(\lambda_i\)</span> for <span class="math notranslate nohighlight">\(i=1,2,3\)</span>.
+They are real values (in the [0,1] range for a point inside the triangle),
+giving the weight of each of the 3 vertices of the triangles.</p>
+<p>Once those weights are known, interpolating the target horizontal
+coordinate is a matter of doing the linear combination of those weights with
+the target horizontal coordinates at the 3 vertices of the triangle (<span class="math notranslate nohighlight">\(Xt_i\)</span> and <span class="math notranslate nohighlight">\(Yt_i\)</span>):</p>
+<div class="math notranslate nohighlight">
+\[ \begin{align}\begin{aligned}X_{target} = Xt_1 * \lambda_1 + Xt_2 * \lambda_2 + Xt_3 * \lambda_3\\Y_{target} = Yt_1 * \lambda_1 + Yt_2 * \lambda_2 + Yt_3 * \lambda_3\end{aligned}\end{align} \]</div>
+<p>This interpolation is exact at the vertices of the triangulation, and has linear properties
+inside each triangle. It is completely equivalent to other formulations of
+triangular interpolation, such as</p>
+<div class="math notranslate nohighlight">
+\[ \begin{align}\begin{aligned}X_{target} = A + X_{source} * B + Y_{source} * C\\Y_{target} = D + X_{source} * E + Y_{source} * F\end{aligned}\end{align} \]</div>
+<p>where the A, B, C, D, E, F constants (for a given triangle) are found by solving
+the 2 systems of 3 linear equations, constraint by the source and target coordinate pairs
+of the 3 vertices of the triangle:</p>
+<div class="math notranslate nohighlight">
+\[ \begin{align}\begin{aligned}Xt_i = A + Xs_i * B + Ys_i * C\\Yt_i = D + Xs_i * E + Ys_i * F\end{aligned}\end{align} \]</div>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>From experiments, the interpolation using barycentric coordinates is slightly
+more numerically robust when interpolating projected coordinates of amplitude of the
+order of 1e5 / 1e6, due to computations involving differences of coordinates.
+Whereas the formulation with the A, B, C, D, E, F tends to have big values for
+the A and D constants, and values clause to 0 for C and E, and close to 1 for
+B and F. However, the difference between the two approaches is negligible for
+practical purposes (below micrometre precision)</p>
+</div>
+<p>Similarly for a vertical coordinate transformation, where <span class="math notranslate nohighlight">\(Zoff_i\)</span> is the vertical
+offset at each vertex of the triangle:</p>
+<div class="math notranslate nohighlight">
+\[Z_{target} = Z_{source} + Zoff_1 * \lambda_1 + Zoff_2 * \lambda_2 + Zoff_3 * \lambda_3\]</div>
+</section>
+<section id="constraints-on-the-triangulation">
+<h3>Constraints on the triangulation<a class="headerlink" href="#constraints-on-the-triangulation" title="Permalink to this headline">¶</a></h3>
+<p>No check is done on the consistence of the triangulation. It is highly
+recommended that triangles do not overlap each other (when considering the
+source coordinates or the forward transformation, or the target coordinates for
+the inverse transformation), otherwise which triangle will be selected is
+unspecified. Besides that, the triangulation does not need to have particular
+properties (like being a Delaunay triangulation)</p>
+</section>
+<section id="file-format">
+<h3>File format<a class="headerlink" href="#file-format" title="Permalink to this headline">¶</a></h3>
+<p>To the best of our knowledge, there are no established file formats to convey
+geodetic transformations as triangulations. Potential similar formats to store TINs
+are <a class="reference external" href="http://vterrain.org/Implementation/Formats/ITF.html">ITF</a> or
+<a class="reference external" href="https://www.xmswiki.com/wiki/TIN_Files">XMS</a>.
+Both of them would need to be extended in order to handle datum shift information,
+since they are both intended for mostly DEM use.</p>
+<p>We thus propose a text-based format, using JSON as a serialization. Using a text-based
+format could potentially be thought as a limitation performance-wise compared to
+binary formats, but for the size of triangulations considered (a few thousands triangles / vertices),
+there is no issue. Loading such file is a matter of 20 milliseconds or so. For reference,
+loading a triangulation of about 115 000 triangles and 71 000 vertices takes 450 ms.</p>
+<p>Using JSON provides generic formatting and parsing rules, and convenience to
+create it from Python script for examples. This could also be easily generated “at hand”
+by non-JSON aware writers.</p>
+<p>For generic metadata, we reuse closely what has been used for the
+<a class="reference external" href="https://github.com/linz/deformation-model-format">Deformation model master file</a></p>
+<p>Below a minimal example, from the KKJ to ETRS89 transformation, with just a
+single triangle:</p>
+<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;file_type&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;triangulation_file&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;format_version&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;1.0&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Name&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;version&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Version&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;publication_date&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;2018-07-01T00:00:00Z&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;license&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Creative Commons Attribution 4.0 International&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;description&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Test triangulation&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;authority&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Authority name&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;url&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;http://example.com&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;address&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Address&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;email&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;test@example.com&quot;</span><span class="w"></span>
+<span class="w"> </span><span class="p">},</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;links&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"></span>
+<span class="w"> </span><span class="p">{</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;href&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://example.com/about.html&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;rel&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;about&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;text/html&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;title&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;About&quot;</span><span class="w"></span>
+<span class="w"> </span><span class="p">},</span><span class="w"></span>
+<span class="w"> </span><span class="p">{</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;href&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://example.com/download&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;rel&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;source&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;application/zip&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;title&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Authoritative source&quot;</span><span class="w"></span>
+<span class="w"> </span><span class="p">},</span><span class="w"></span>
+<span class="w"> </span><span class="p">{</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;href&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://creativecommons.org/licenses/by/4.0/&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;rel&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;license&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;text/html&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;title&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Creative Commons Attribution 4.0 International license&quot;</span><span class="w"></span>
+<span class="w"> </span><span class="p">},</span><span class="w"></span>
+<span class="w"> </span><span class="p">{</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;href&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://example.com/metadata.xml&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;rel&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;metadata&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;application/xml&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;title&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot; ISO 19115 XML encoded metadata regarding the triangulation&quot;</span><span class="w"></span>
+<span class="w"> </span><span class="p">}</span><span class="w"></span>
+<span class="w"> </span><span class="p">],</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;input_crs&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;EPSG:2393&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;target_crs&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;EPSG:3067&quot;</span><span class="p">,</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;transformed_components&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">&quot;horizontal&quot;</span><span class="w"> </span><span class="p">],</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;vertices_columns&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">&quot;source_x&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;source_y&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;target_x&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;target_y&quot;</span><span class="w"> </span><span class="p">],</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;triangles_columns&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">&quot;idx_vertex1&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;idx_vertex2&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;idx_vertex3&quot;</span><span class="w"> </span><span class="p">],</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;vertices&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">[</span><span class="mf">3244102.707</span><span class="p">,</span><span class="w"> </span><span class="mf">6693710.937</span><span class="p">,</span><span class="w"> </span><span class="mf">244037.137</span><span class="p">,</span><span class="w"> </span><span class="mf">6690900.686</span><span class="p">],</span><span class="w"></span>
+<span class="w"> </span><span class="p">[</span><span class="mf">3205290.722</span><span class="p">,</span><span class="w"> </span><span class="mf">6715311.822</span><span class="p">,</span><span class="w"> </span><span class="mf">205240.895</span><span class="p">,</span><span class="w"> </span><span class="mf">6712492.577</span><span class="p">],</span><span class="w"></span>
+<span class="w"> </span><span class="p">[</span><span class="mf">3218328.492</span><span class="p">,</span><span class="w"> </span><span class="mf">6649538.429</span><span class="p">,</span><span class="w"> </span><span class="mf">218273.648</span><span class="p">,</span><span class="w"> </span><span class="mf">6646745.973</span><span class="p">]</span><span class="w"> </span><span class="p">],</span><span class="w"></span>
+<span class="w"> </span><span class="nt">&quot;triangles&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">]</span><span class="w"> </span><span class="p">]</span><span class="w"></span>
+<span class="p">}</span><span class="w"></span>
+</pre></div>
+</div>
+<p>So after the generic metadata, we define the input and output CRS (informative
+only), and that the transformation affects horizontal components of
+coordinates. We name the columns of the <code class="docutils literal notranslate"><span class="pre">vertices</span></code> and <code class="docutils literal notranslate"><span class="pre">triangles</span></code> arrays.
+We defined the source and target coordinates of each vertex, and define a
+triangle by referring to the index of its vertices in the <code class="docutils literal notranslate"><span class="pre">vertices</span></code> array.</p>
+<p>More formally, the specific items for the triangulation file are:</p>
+<dl class="simple">
+<dt>input_crs</dt><dd><p>String identifying the CRS of source coordinates
+in the vertices. Typically <code class="docutils literal notranslate"><span class="pre">EPSG:XXXX</span></code>. If the transformation is for vertical
+component, this should be the code for a compound CRS (can be EPSG:XXXX+YYYY
+where XXXX is the code of the horizontal CRS and YYYY the code of the vertical CRS).
+For example, for the KKJ-&gt;ETRS89 transformation, this is EPSG:2393
+(<code class="docutils literal notranslate"><span class="pre">KKJ</span> <span class="pre">/</span> <span class="pre">Finland</span> <span class="pre">Uniform</span> <span class="pre">Coordinate</span> <span class="pre">System</span></code>). The input coordinates are assumed
+to be passed in the “normalized for visualisation” / “GIS friendly” order,
+that is longitude, latitude for geographic coordinates and
+easting, northing for projected coordinates.</p>
+</dd>
+<dt>output_crs</dt><dd><p>String identifying the CRS of target coordinates in the vertices.
+Typically <code class="docutils literal notranslate"><span class="pre">EPSG:XXXX</span></code>. If the transformation is for vertical component,
+this should be the code for a compound CRS (can be EPSG:XXXX+YYYY where
+XXXX is the code of the horizontal CRS and YYYY the code of the vertical CRS).
+For example, for the KKJ-&gt;ETRS89 transformation, this is EPSG:3067
+(&quot;ETRS89 / TM35FIN(E,N)&quot;). The output coordinates will be returned in
+the “normalized for visualisation” / “GIS friendly” order,
+that is longitude, latitude for geographic coordinates and
+easting, northing for projected coordinates.</p>
+</dd>
+<dt>transformed_components</dt><dd><p>Array which may contain one or two strings: “horizontal” when horizontal
+components of the coordinates are transformed and/or “vertical” when the
+vertical component is transformed.</p>
+</dd>
+<dt>vertices_columns</dt><dd><p>Specify the name of the columns of the rows in the <code class="docutils literal notranslate"><span class="pre">vertices</span></code>
+array. There must be exactly as many elements in <code class="docutils literal notranslate"><span class="pre">vertices_columns</span></code> as in a
+row of <code class="docutils literal notranslate"><span class="pre">vertices</span></code>. The following names have a special meaning: <code class="docutils literal notranslate"><span class="pre">source_x</span></code>,
+<code class="docutils literal notranslate"><span class="pre">source_y</span></code>, <code class="docutils literal notranslate"><span class="pre">target_x</span></code>, <code class="docutils literal notranslate"><span class="pre">target_y</span></code>, <code class="docutils literal notranslate"><span class="pre">source_z</span></code>, <code class="docutils literal notranslate"><span class="pre">target_z</span></code> and
+<code class="docutils literal notranslate"><span class="pre">offset_z</span></code>. <code class="docutils literal notranslate"><span class="pre">source_x</span></code> and <code class="docutils literal notranslate"><span class="pre">source_y</span></code> are compulsory.
+<code class="docutils literal notranslate"><span class="pre">source_x</span></code> is for the source longitude (in degree) or easting.
+<code class="docutils literal notranslate"><span class="pre">source_y</span></code> is for the source latitude (in degree) or northing.
+<code class="docutils literal notranslate"><span class="pre">target_x</span></code> and <code class="docutils literal notranslate"><span class="pre">target_y</span></code> are compulsory when <code class="docutils literal notranslate"><span class="pre">horizontal</span></code> is specified
+in <code class="docutils literal notranslate"><span class="pre">transformed_components</span></code>. (<code class="docutils literal notranslate"><span class="pre">source_z</span></code> and <code class="docutils literal notranslate"><span class="pre">target_z</span></code>) or
+<code class="docutils literal notranslate"><span class="pre">offset_z</span></code> are compulsory when <code class="docutils literal notranslate"><span class="pre">vertical</span></code> is specified in <code class="docutils literal notranslate"><span class="pre">transformed_components</span></code></p>
+</dd>
+<dt>triangles_columns</dt><dd><p>Specify the name of the columns of the rows in the
+<code class="docutils literal notranslate"><span class="pre">triangles</span></code> array. There must be exactly as many elements in <code class="docutils literal notranslate"><span class="pre">triangles_columns</span></code>
+as in a row of <code class="docutils literal notranslate"><span class="pre">triangles</span></code>. The following names have a special meaning:
+<code class="docutils literal notranslate"><span class="pre">idx_vertex1</span></code>, <code class="docutils literal notranslate"><span class="pre">idx_vertex2</span></code>, <code class="docutils literal notranslate"><span class="pre">idx_vertex3</span></code>. They are compulsory.</p>
+</dd>
+<dt>vertices</dt><dd><p>An array whose items are themselves arrays with as many columns as
+described in <code class="docutils literal notranslate"><span class="pre">vertices_columns</span></code>.</p>
+</dd>
+<dt>triangles</dt><dd><p>An array whose items are themselves arrays with as many columns as
+described in <code class="docutils literal notranslate"><span class="pre">triangles_columns</span></code>.
+The value of the <code class="docutils literal notranslate"><span class="pre">idx_vertexN</span></code> columns must be indices
+(between 0 and len(<code class="docutils literal notranslate"><span class="pre">vertices</span></code>-1) of items of the <code class="docutils literal notranslate"><span class="pre">vertices</span></code> array.</p>
+</dd>
+</dl>
+</section>
+<section id="code-impacts">
+<h3>Code impacts<a class="headerlink" href="#code-impacts" title="Permalink to this headline">¶</a></h3>
+<p>The following new files are added in src/transformations:</p>
+<ul class="simple">
+<li><p>tinshift.cpp: PROJ specific code for defining the new operation. Takes care
+of the input and output coordinate conversions (between input_crs and triangulation_source_crs,
+and triangulation_target_crs and output_crs), when needed.</p></li>
+<li><p>tinshift.hpp: Header-based implementation. This file contains the API.</p></li>
+<li><p>tinshift_exceptions.hpp: Exceptions that can be raised during file parsing</p></li>
+<li><p>tinshift_impl.hpp: Implementation of file loading, triangle search and interpolation.</p></li>
+</ul>
+<p>This is the approach that has been followed for the deformation model implementation,
+and which makes it easier to do unit test.</p>
+<p>src/quadtree.hpp contains a quadtree implementation.</p>
+</section>
+<section id="performance-indications">
+<h3>Performance indications<a class="headerlink" href="#performance-indications" title="Permalink to this headline">¶</a></h3>
+<p>Tested on Intel(R) Core(TM) i7-6700HQ CPU &#64; 2.60GHz, transforming 4 million points</p>
+<p>For the KKJ to ETRS89 transformation (1449 triangles and 767 vertices),
+4.4 million points / sec can be transformed.</p>
+<p>For comparison, the Helmert-based KKJ to ETRS89 transformation operates at
+1.6 million points / sec.</p>
+<p>A triangulation with about 115 000 triangles and 71 000 vertices
+operates at 2.2 million points / sec
+(throughput on more points would be better since the initial loading of the
+triangulation is non-negligible here)</p>
+</section>
+</section>
+<section id="backward-compatibility">
+<h2>Backward compatibility<a class="headerlink" href="#backward-compatibility" title="Permalink to this headline">¶</a></h2>
+<p>New functionality fully backward compatible.</p>
+</section>
+<section id="testing">
+<h2>Testing<a class="headerlink" href="#testing" title="Permalink to this headline">¶</a></h2>
+<p>The PROJ test suite will be enhanced to test the new transformation, with a
+new .gie file, and a C++ unit test to test at a lower level.</p>
+</section>
+<section id="documentation">
+<h2>Documentation<a class="headerlink" href="#documentation" title="Permalink to this headline">¶</a></h2>
+<ul class="simple">
+<li><p>The tinshift method will be documented.</p></li>
+<li><p>The JSON format will be documented under <a class="reference external" href="https://proj.org/specifications/">https://proj.org/specifications/</a></p></li>
+<li><p>A JSON schema will also be provided.</p></li>
+</ul>
+</section>
+<section id="proposed-implementation">
+<h2>Proposed implementation<a class="headerlink" href="#proposed-implementation" title="Permalink to this headline">¶</a></h2>
+<p>An initial implementation is available at <a class="reference external" href="https://github.com/rouault/PROJ/tree/tinshift">https://github.com/rouault/PROJ/tree/tinshift</a></p>
+</section>
+<section id="references">
+<h2>References<a class="headerlink" href="#references" title="Permalink to this headline">¶</a></h2>
+<p><a class="reference external" href="https://translate.google.fr/translate?sl=auto&amp;tl=en&amp;u=https%3A%2F%2Fwww.maanmittauslaitos.fi%2Fkartat-ja-paikkatieto%2Fasiantuntevalle-kayttajalle%2Fkoordinaattimuunnokset">Finnish coordinate transformation (automated translation to English)</a></p>
+</section>
+<section id="adoption-status">
+<h2>Adoption status<a class="headerlink" href="#adoption-status" title="Permalink to this headline">¶</a></h2>
+<p>The RFC was adopted on 2020-09-02 with +1’s from the following PSC members</p>
+<ul class="simple">
+<li><p>Kristian Evers</p></li>
+<li><p>Charles Karney</p></li>
+<li><p>Thomas Knudsen</p></li>
+<li><p>Even Rouault</p></li>
+</ul>
+</section>
+<section id="funding">
+<h2>Funding<a class="headerlink" href="#funding" title="Permalink to this headline">¶</a></h2>
+<p>This work is funded by <a class="reference external" href="https://www.maanmittauslaitos.fi/en">National Land Survey of Finland</a></p>
+</section>
+</section>
+
+
+ </div>
+ </div>
+ <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
+ <a href="rfc-5.html" class="btn btn-neutral float-left" title="PROJ RFC 5: Adopt GeoTIFF-based grids for grids delivered with PROJ" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
+ <a href="rfc-7.html" class="btn btn-neutral float-right" title="PROJ RFC 7: Drop Autotools, maintain CMake" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
+ </div>
+
+ <hr/>
+
+ <div role="contentinfo">
+ <p>&#169; Copyright 1983-2022.
+ <span class="lastupdated">Last updated on 22 Mar 2022.
+ </span></p>
+ </div>
+
+ Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
+ <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
+ provided by <a href="https://readthedocs.org">Read the Docs</a>.
+
+
+</footer>
+ </div>
+ </div>
+ </section>
+ </div>
+ <script>
+ jQuery(function () {
+ SphinxRtdTheme.Navigation.enable(true);
+ });
+ </script>
+
+</body>
+</html> \ No newline at end of file