Compare commits

...
24 Commits
Author SHA1 Message Date
Mike Taves 4381b96ebb ReadTheDocs: use ninja, fix branch ref 2023-01-25 22:08:36 +13:00
Mike Taves de230da231 Improve docs for 5.2 2023-01-25 00:46:56 +13:00
Mike Taves 34b270a695 Implement ReadTheDocs for 5.2, disable other CI workflows (#3584) 2023-01-22 22:50:10 +13:00
Even Rouault b285484ea3 Disable website deployment for branch 5.2 2019-08-06 19:45:40 +02:00
Kristian Evers cf1d83a4c4 Fix tests still running despite being disabled in Release 5.2 (#1559)
Fix tests still running despite being disabled in Release 5.2
2019-08-06 17:20:53 +02:00
Conlan Cesar f849dc37f1 Remove the "LANGUAGES" CMake 3 keyword
`LANGUAGES` in this context was first introduced as a CMake 3 feature, but we advertise 2.6 support. Removing the keyword restores compatibility.
2019-08-06 09:13:47 -04:00
Conlan Cesar 166c215fc8 Fix tests still running despite being disabled
This fix was included in release 6.0, simple backport to 5.2.
2019-08-05 10:28:33 -04:00
Even Rouault ec21939399 Doc: typo fix 2019-01-21 21:18:56 +01:00
Kristian Evers c39b6fb23c [MOTIONED] RFC3: Dependency management (#1168)
RFC3: Dependency management
2019-01-16 16:54:34 +01:00
magau f3134c202a Update bindings.rst
Added Fortran-Proj, bindings for PROJ in Fortran.
2018-12-18 14:12:40 +01:00
Kristian Evers dfe855d66f Update URL to mailing list 2018-12-06 13:07:59 +01:00
Even Rouault d7cb4b7a63 Doc: fix geos projection explanation about the appropriate value for the sweep parameter depending on the satellite (fixes #1179) 2018-11-19 11:58:34 +01:00
Even Rouault 6f46d55126 Doc: add RFC2 initial version
squashed cherry-picking of master commits:
be58913801
5511ab8f4d
1b5e8db29f
9ae6713916
0196fc54f7
ed0ee0bc9f
2f48fe12db
2018-10-31 11:23:01 +01:00
Kristian Evers e07f51557c Remove British grids from non-free section of docs
Closes #1159
2018-10-28 16:24:12 +01:00
Even Rouault 7b756576f1 Doc: Add missing entry in references.bib 2018-10-25 03:40:37 +02:00
Mike Toews f20de18ace alphabetize titles in 'Non-Free Grids' section (content unchanged) 2018-10-25 03:38:38 +02:00
Mike Toews cdb997cfaf Remove free grids from 'Non-Free Grids' section
These are included with proj-datumgrid:
 - Australia
 - Canada: ntv2_0.gsb
 - Germany: BETA2007.gsb
2018-10-25 03:38:37 +02:00
Kristian Evers 602ada943f Add docs for the horner operation 2018-10-15 10:24:43 +02:00
Kristian Evers b31baceeb8 Exclude option-includes to avoid blocking warnings in doc builds 2018-10-15 10:24:34 +02:00
Marco Bernasocchi df8d95ab53 fix typo 2018-10-08 19:29:11 +02:00
Marco Bernasocchi 1f0c8867dc Update install.rst 2018-10-08 19:29:05 +02:00
Even Rouault b693d210fa cs2cs_emulation_setup: fix issue with non C-locale
in +towgs84 case, we use sprintf() with floating-point formatter to output
the ellipsoid parameters. For a locale with decimal separtor != dot, the
resulting string will not be parsed correctly by proj_atof(), leading to
wrong numeric result.

The fix is similar to the one done in pj_latlong_from_proj()

Note for later: if using C++, we could use a locale-independent formatting
solution to avoid such issue.
2018-09-28 13:53:02 +02:00
Kristian Evers 15edf4c41b Clean up FAQ
This removes some questions that are no longer valid
(covered elsewhere in the docs), adjusts the wording in other questions
and fixes formatting and making it proper rst/sphinx syntax.

With this, #1070 is almost fixed.
2018-09-20 11:04:41 +02:00
Kristian Evers 0ea45a3b64 Build docs from most recent maintenance branch 2018-09-19 20:11:11 +02:00
35 changed files with 1648 additions and 292 deletions
+3 -1
View File
@@ -41,9 +41,11 @@ test-driver
/DartConfiguration.tcl
/Testing
# html
# docs
/html/dl
/html/robots.txt
/docs/plot/images
/latex
# m4
/m4/libtool.m4
+45
View File
@@ -0,0 +1,45 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
build:
os: "ubuntu-22.04"
tools:
python: "mambaforge-4.10"
jobs:
post_checkout:
# Cancel building pull requests when there aren't changed in the docs directory or YAML file.
# You can add any other files or directories that you'd like here as well,
# like your docs requirements file, or other files that will change your docs build.
#
# If there are no changes (git diff exits with 0) we force the command to return with 183.
# This is a special exit code on Read the Docs that will cancel the build immediately.
- |
if [ "$READTHEDOCS_VERSION_TYPE" = "external" ] && git diff --quiet origin/5.2 -- docs/ .readthedocs.yaml;
then
exit 183;
fi
- (git --no-pager log --pretty="tformat:%s -- %b" -1 | grep -viq "skip ci") || exit 183
pre_build:
- ./docs/rtd/pre_build.sh
- ./docs/rtd/plot.sh
apt_packages:
- cmake
- ninja-build
- g++
formats:
- pdf
- epub
conda:
environment: docs/environment.yml
sphinx:
configuration: docs/source/conf.py
fail_on_warning: true
+4 -3
View File
@@ -12,7 +12,7 @@
cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)
# For historic reasons, the CMake PROJECT-NAME is PROJ4
project(PROJ4 LANGUAGES C CXX)
project(PROJ4 C CXX)
set(PROJECT_INTERN_NAME PROJ)
if (NOT CMAKE_VERSION VERSION_LESS 3.1)
@@ -164,5 +164,6 @@ add_subdirectory(nad)
add_subdirectory(src)
add_subdirectory(man)
add_subdirectory(cmake)
add_subdirectory(test)
if(PROJ_TESTS)
add_subdirectory(test)
endif(PROJ_TESTS)
+3 -1
View File
@@ -175,9 +175,10 @@ See step 1.6 above. Do not rename the archives with RC postfixes.
2.2 Update website
------------------------------------------------------------------------------
- Update the version number in `doc/source/conf.py`
- Add the release notes from `NEWS` to `docs/source/news.rst`
- Update download links in `docs/source/download.rst`
- Update `$TRAVIS_BRANCH` in `travis\after_success.sh` to new maintenance
branch.
*Commit the changes to master and cherry-pick into maintenance branch.*
@@ -231,6 +232,7 @@ version numbers in the files.
- src/proj_api.h: Update PJ_VERSION.
- src/pj_release.c: Update date to the scheduled release date.
- CMakelists.txt: Update proj_version()
- doc/source/conf.py: Update version number
*Commit changes to master branch.*
+15
View File
@@ -0,0 +1,15 @@
name: proj
channels:
- conda-forge
dependencies:
- descartes
- geojson
- matplotlib
- shapely < 1.8
- pip
- pip:
- Jinja2 < 3.1
- pybtex
- sphinx < 3
- sphinx-rtd-theme < 1.0
- sphinxcontrib-bibtex
Regular → Executable
+117 -59
View File
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
'''
Plot map data in different projections supported by PROJ.4
Plot map data in different projections supported by PROJ.
Call with:
@@ -41,28 +42,31 @@ or "line". The rest of the inputs are fairly free form.
Change PROJ to path on your local system before running the script.
'''
from __future__ import print_function
from __future__ import division
import argparse
import os
import os.path
import shutil
import sys
import json
import subprocess
import functools
from pathlib import Path
import geojson
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import fiona
from shapely.geometry import Polygon
from shapely.geometry import MultiPolygon
from shapely.geometry import MultiPolygon, Polygon, box as Box
from shapely.geometry import shape
from shapely.ops import transform
from descartes import PolygonPatch
PROJ = '../../src/proj'
PROJ_LIB = '../../nad'
PROJ_COMMAND = os.environ.get('PROJ_EXE', '../../src/proj')
if not os.path.exists(PROJ_COMMAND):
PROJ = shutil.which('proj')
if PROJ is None:
raise ValueError("specify PROJ_EXE or modify PATH to find proj")
else:
PROJ = PROJ_COMMAND
PROJ_LIB = os.environ.get('PROJ_LIB', '../../nad')
LINE_LOW = 'data/coastline.geojson'
LINE_MED = 'data/coastline50.geojson'
@@ -118,7 +122,7 @@ def interp_coords(coords, tol):
xy.append((x[offset:i], y[offset:i]))
# Interpolate between points above tolerance.
n = np.ceil(dsts[i] / tol)
n = int(np.ceil(dsts[i] / tol))
x1 = np.linspace(x[i], x[i + 1], n + 1)
y1 = np.linspace(y[i], y[i + 1], n + 1)
xy.append((x1[:-1], y1[:-1]))
@@ -157,8 +161,14 @@ def project(coordinates, proj_string, in_radians=False):
args = [PROJ, '-b']
args.extend(proj_string.split(' '))
proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
env={'PROJ_LIB': os.path.abspath(PROJ_LIB)})
try:
proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
env={'PROJ_LIB': os.path.abspath(PROJ_LIB)})
except FileNotFoundError as e:
print("'proj' binary not found, set the PROJ_EXE environment variable "
"to point to your local 'proj' binary --%s--" % e)
exit(1)
stdout, _ = proc.communicate(coordinates.tobytes(order='C'))
out = np.frombuffer(stdout, dtype=np.double)
@@ -217,7 +227,10 @@ def resample_polygon(polygon):
'''
Use interp_coords() to resample (multi)polygons.
'''
xy = polygon.exterior.coords.xy
try:
xy = polygon.exterior.coords.xy
except AttributeError: #no xy's
return polygon
ext = interp_coords(xy, 2)
# interiors
rings = []
@@ -226,27 +239,46 @@ def resample_polygon(polygon):
return Polygon(ext, rings)
def plot_with_interruptions(axes, x, y, delta_cut=1e100, **kwargs):
"""
Plot x/y with proper splitting for interrupted projections.
"""
_x = np.atleast_1d(x)
_y = np.atleast_1d(y)
dx = np.nan_to_num(_x[1: ]) - np.nan_to_num(_x[0: -1])
dy = np.nan_to_num(_y[1: ]) - np.nan_to_num(_y[0: -1])
split, = ((np.abs(dx) > delta_cut) | (np.abs(dy) > delta_cut)).nonzero()
split = np.append(split, _x.size - 1)
split += 1
last_part = 0
for part in split:
axes.plot(x[last_part: part],
y[last_part: part],
**kwargs)
last_part = part
def plotproj(plotdef, data, outdir):
'''
Plot map.
'''
axes = plt.axes()
bounds = (plotdef['lonmin'], plotdef['latmin'], plotdef['lonmax'], plotdef['latmax'])
for geom in data.filter(bbox=bounds):
temp_pol = shape(geom['geometry'])
box = Box(
plotdef['lonmin'], plotdef['latmin'],
plotdef['lonmax'], plotdef['latmax'])
for feat in data["features"]:
geom = shape(feat["geometry"])
if not geom.intersects(box):
continue
box = Polygon([
(plotdef['lonmin'], plotdef['latmin']),
(plotdef['lonmin'], plotdef['latmax']),
(plotdef['lonmax'], plotdef['latmax']),
(plotdef['lonmax'], plotdef['latmin']),
])
temp_pol = temp_pol.intersection(box)
temp_pol = geom.intersection(box)
if plotdef['type'] == 'poly':
if isinstance(temp_pol, MultiPolygon):
polys = [resample_polygon(polygon) for polygon in temp_pol]
polys = [resample_polygon(polygon) for polygon in temp_pol.geoms]
pol = MultiPolygon(polys)
else:
pol = resample_polygon(temp_pol)
@@ -257,11 +289,15 @@ def plotproj(plotdef, data, outdir):
proj_geom = transform(trans, pol)
if plotdef['type'] == 'poly':
patch = PolygonPatch(proj_geom, fc=COLOR_LAND, zorder=0)
axes.add_patch(patch)
try:
patch = PolygonPatch(proj_geom, fc=COLOR_LAND, zorder=0)
axes.add_patch(patch)
except TypeError:
pass
else:
x, y = proj_geom.xy
axes.plot(x, y, color=COLOR_COAST, linewidth=0.5)
plot_with_interruptions(axes, x, y, color=COLOR_COAST, linewidth=0.5,
delta_cut=plotdef.get('delta_cut', 1e100))
# Plot frame
frame = [
@@ -272,7 +308,8 @@ def plotproj(plotdef, data, outdir):
line = project(line, plotdef['projstring'])
x = line[:, 0]
y = line[:, 1]
axes.plot(x, y, '-k')
plot_with_interruptions(axes, x, y, color='black', linestyle='-',
delta_cut=plotdef.get('delta_cut', 1e6))
graticule = build_graticule(
plotdef['lonmin'],
@@ -286,7 +323,28 @@ def plotproj(plotdef, data, outdir):
feature = project(feature, plotdef['projstring'])
x = feature[:, 0]
y = feature[:, 1]
axes.plot(x, y, color=COLOR_GRAT, linewidth=0.4)
plot_with_interruptions(axes, x, y, color=COLOR_GRAT, linewidth=0.4,
delta_cut=plotdef.get('delta_cut', 1e6))
# Plot interrupted boundaries if necessary
interrupted_lines = []
if 'top_interrupted_lons' in plotdef:
for lon in plotdef['top_interrupted_lons']:
for delta in [-0.0001, 0.0001]:
merid = meridian(lon + delta, 0.0, plotdef['latmax'])
interrupted_lines.append(project(merid, plotdef['projstring']))
if 'bottom_interrupted_lons' in plotdef:
for lon in plotdef['bottom_interrupted_lons']:
for delta in [-0.0001, 0.0001]:
merid = meridian(lon + delta, plotdef['latmin'], 0)
interrupted_lines.append(project(merid, plotdef['projstring']))
for line in interrupted_lines:
x = line[:, 0]
y = line[:, 1]
plot_with_interruptions(axes, x, y, color=COLOR_GRAT, linewidth=0.4,
delta_cut=plotdef.get('delta_cut', 1e100))
# Switch off the axis lines...
plt.axis('off')
@@ -304,10 +362,13 @@ def plotproj(plotdef, data, outdir):
# Make sure the plot is not stretched
axes.set_aspect('equal')
if not os.path.exists(outdir):
os.makedirs(outdir)
plt.savefig(outdir + '/' + plotdef['filename'],
outdir = Path(outdir)
if not outdir.exists():
outdir.mkdir(parents=True)
if not outdir.is_dir():
raise OSError("outdir is not a directory")
plt.savefig(outdir / plotdef['filename'],
dpi=400,
bbox_inches='tight')
@@ -317,36 +378,22 @@ def plotproj(plotdef, data, outdir):
plt.close()
def main():
def main(plotdefs, outdir, plots=[]):
'''
Main function of plotting script.
Parses json-file with plot setups and runs the plotting
for each plot setup.
'''
plotdefs = json.loads(Path(plotdefs).read_text())
data = {
('line', 'low'): fiona.open(LINE_LOW),
('line', 'med'): fiona.open(LINE_MED),
('poly', 'low'): fiona.open(POLY_LOW),
('poly', 'med'): fiona.open(POLY_MED),
('line', 'low'): geojson.loads(Path(LINE_LOW).read_text()),
('line', 'med'): geojson.loads(Path(LINE_MED).read_text()),
('poly', 'low'): geojson.loads(Path(POLY_LOW).read_text()),
('poly', 'med'): geojson.loads(Path(POLY_MED).read_text()),
}
if os.path.exists(sys.argv[1]):
# first argument is the JSON plot definition setup file
with open(sys.argv[1]) as plotsetup:
plotdefs = json.load(plotsetup)
else:
raise ValueError('No plot definition file entered')
plots = []
# second argument is the output dir
outdir = sys.argv[2]
# subsecond arguments are (optional) names of plot in plotdef.json
if len(sys.argv) > 3:
plots = sys.argv[3:len(sys.argv)]
for i, plotdef in enumerate(plotdefs):
if plots != [] and plotdef['name'] not in plots:
continue
@@ -358,9 +405,20 @@ def main():
plotproj(plotdef, data[(plotdef['type'], plotdef['res'])], outdir)
for key in data:
data[key].close()
if __name__ == "__main__":
sys.exit(main())
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument(
'plotdefs',
help='A JSON file with setup for each auto-generated plot')
parser.add_argument(
'outdir',
help='Directory to put the plots in.')
parser.add_argument(
'plots', nargs='*',
help='A list of plot names within the plotdefs file. '
'More than one plotname can be given at once.')
args = parser.parse_args()
sys.exit(main(**vars(args)))
-2
View File
@@ -1,2 +0,0 @@
python3 plot.py plotdefs.json images/
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
set -e
export PATH="$HOME/.local/bin:$PATH"
export PROJ_LIB="$HOME/.local/share/proj"
cd docs/plot
python plot.py plotdefs.json images
cd ../..
mkdir -p docs/source/operations/projections/images/
cp -r docs/plot/images/* docs/source/operations/projections/images/
+9
View File
@@ -0,0 +1,9 @@
#!/bin/sh
set -e
mkdir build
cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DPROJ_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$HOME/.local ..
ninja install
+1 -1
View File
@@ -14,7 +14,7 @@ about the development of the library and from time to time interesting discussio
on geodesy appear as well. You are more than welcome to join in on the discussions!
The PROJ mailing list can be found at http://lists.maptools.org/mailman/listinfo/proj
The PROJ mailing list can be found at https://lists.osgeo.org/mailman/listinfo/proj
GitHub
+2
View File
@@ -12,3 +12,5 @@ the project.
:maxdepth: 1
rfc-1
rfc-2
rfc-3
+933
View File
@@ -0,0 +1,933 @@
.. _rfc2:
====================================================================
PROJ RFC 2: Initial integration of "GDAL SRS barn" work
====================================================================
:Author: Even Rouault
:Contact: even.rouault at spatialys.com
:Status: Adopted (not yet merged into master)
:Initial version: 2018-10-09
:Last Updated: 2018-10-31
Summary
-------
This RFC is the result of a first phase of the `GDAL Coordinate System Barn Raising`_
efforts. In its current state, this work mostly consists of:
- a C++ implementation of the ISO-19111:2018 / OGC Topic 2 "Referencing by
coordinates" classes to represent Datums, Coordinate systems, CRSs
(Coordinate Reference Systems) and Coordinate Operations.
- methods to convert between this C++ modeling and WKT1, WKT2 and PROJ string representations of those objects
- management and query of a SQLite3 database of CRS and Coordinate Operation definition
- a C API binding part of those capabilities
.. _`GDAL Coordinate System Barn Raising`: https://gdalbarn.com/
Related standards
-----------------
Consult `Applicable standards`_
.. _`Applicable standards`: http://even.rouault.free.fr/proj_cpp_api/html/general_doc.html#standards
(They will be linked from the PROJ documentation)
Details
-------
Structure in packages / namespaces
**********************************
The C++ implementation of the (upcoming) ISO-19111:2018 / OGC Topic 2 "Referencing by
coordinates" classes follows this abstract modeling as much as possible, using
package names as C++ namespaces, abstract classes and method names. A new
BoundCRS class has been added to cover the modeling of the WKT2 BoundCRS
construct, that is a generalization of the WKT1 TOWGS84 concept. It is
strongly recommended to have the ISO-19111 standard open to have an introduction
for the concepts when looking at the code. A few classes have also been
inspired by the GeoAPI
The classes are organized into several namespaces:
- osgeo::proj::util
A set of base types from ISO 19103, GeoAPI and other PROJ "technical"
specific classes
Template optional<T>, classes BaseObject, IComparable, BoxedValue,
ArrayOfBaseObject, PropertyMap, LocalName, NameSpace, GenericName,
NameFactory, CodeList, Exception, InvalidValueTypeException,
UnsupportedOperationException
- osgeo::proj::metadata:
Common classes from ISO 19115 (Metadata) standard
Classes Citation, GeographicExtent, GeographicBoundingBox,
TemporalExtent, VerticalExtent, Extent, Identifier, PositionalAccuracy,
- osgeo::proj::common:
Common classes: UnitOfMeasure, Measure, Scale, Angle, Length, DateTime,
DateEpoch, IdentifiedObject, ObjectDomain, ObjectUsage
- osgeo::proj::cs:
Coordinate systems and their axis
Classes AxisDirection, Meridian, CoordinateSystemAxis, CoordinateSystem,
SphericalCS, EllipsoidalCS, VerticalCS, CartesianCS, OrdinalCS,
ParametricCS, TemporalCS, DateTimeTemporalCS, TemporalCountCS,
TemporalMeasureCS
- osgeo::proj::datum:
Datum (the relationship of a coordinate system to the body)
Classes Ellipsoid, PrimeMeridian, Datum, DatumEnsemble,
GeodeticReferenceFrame, DynamicGeodeticReferenceFrame,
VerticalReferenceFrame, DynamicVerticalReferenceFrame, TemporalDatum,
EngineeringDatum, ParametricDatum
- osgeo::proj::crs:
CRS = coordinate reference system = coordinate system with a datum
Classes CRS, GeodeticCRS, GeographicCRS, DerivedCRS, ProjectedCRS,
VerticalCRS, CompoundCRS, BoundCRS, TemporalCRS, EngineeringCRS,
ParametricCRS, DerivedGeodeticCRS, DerivedGeographicCRS,
DerivedProjectedCRS, DerivedVerticalCRS
- osgeo::proj::operation:
Coordinate operations (relationship between any two coordinate
reference systems)
Classes CoordinateOperation, GeneralOperationParameter,
OperationParameter, GeneralParameterValue, ParameterValue,
OperationParameterValue, OperationMethod, InvalidOperation,
SingleOperation, Conversion, Transformation, PointMotionOperation,
ConcatenatedOperation
- osgeo::proj::io:
I/O classes: WKTFormatter, PROJStringFormatter, FormattingException,
ParsingException, IWKTExportable, IPROJStringExportable, WKTNode,
WKTParser, PROJStringParser, DatabaseContext, AuthorityFactory,
FactoryException, NoSuchAuthorityCodeException
What does what?
***************
The code to parse WKT and PROJ strings and build ISO-19111 objects is
contained in `io.cpp`_
The code to format WKT and PROJ strings from ISO-19111 objects is mostly
contained in the related exportToWKT() and exportToPROJString() methods
overridden in the applicable classes. `io.cpp`_ contains the general mechanics
to build such strings.
Regarding WKT strings, three variants are handled in import and export:
- WKT2_2018: variant corresponding to the upcoming ISO-19162:2018 standard
- WKT2_2015: variant corresponding to the current ISO-19162:2015 standard
- WKT1_GDAL: variant corresponding to the way GDAL understands the OGC
01-099 and OGC 99-049 standards
Regarding PROJ strings, two variants are handled in import and export:
- PROJ5: variant used by PROJ >= 5, possibly using pipeline constructs,
and avoiding +towgs84 / +nadgrids legacy constructs. This variant honours
axis order and input/output units. That is the pipeline for the conversion
of EPSG:4326 to EPSG:32631 will assume that the input coordinates are in
latitude, longitude order, with degrees.
- PROJ4: variant used by PROJ 4.x
The raw query of the proj.db database and the upper level construction of
ISO-19111 objects from the database contents is done in `factory.cpp`_
A few design principles
***********************
Methods generally take and return xxxNNPtr objects, that is non-null shared
pointers (pointers with internal reference counting). The advantage of this
approach is that the user has not to care about the life-cycle of the
instances (and this makes the code leak-free by design). The only point of
attention is to make sure no reference cycles are made. This is the case for
all classes, except the CoordinateOperation class that point to CRS for
sourceCRS and targetCRS members, whereas DerivedCRS point to a Conversion
instance (which derives from CoordinateOperation). This issue was detected in
the ISO-19111 standard. The solution adopted here is to use std::weak_ptr
in the CoordinateOperation class to avoid the cycle. This design artifact is
transparent to users.
Another important design point is that all ISO19111 objects are immutable after
creation, that is they only have getters that do not modify their states.
Consequently they could possibly use in a thread-safe way. There are however
classes like PROJStringFormatter, WKTFormatter, DatabaseContext, AuthorityFactory
and CoordinateOperationContext whose instances are mutable and thus can not be
used by multiple threads at once.
Example how to build the EPSG:4326 / WGS84 Geographic2D definition from scratch:
::
auto greenwich = PrimeMeridian::create(
util::PropertyMap()
.set(metadata::Identifier::CODESPACE_KEY,
metadata::Identifier::EPSG)
.set(metadata::Identifier::CODE_KEY, 8901)
.set(common::IdentifiedObject::NAME_KEY, "Greenwich"),
common::Angle(0));
// actually predefined as PrimeMeridian::GREENWICH constant
auto ellipsoid = Ellipsoid::createFlattenedSphere(
util::PropertyMap()
.set(metadata::Identifier::CODESPACE_KEY, metadata::Identifier::EPSG)
.set(metadata::Identifier::CODE_KEY, 7030)
.set(common::IdentifiedObject::NAME_KEY, "WGS 84"),
common::Length(6378137),
common::Scale(298.257223563));
// actually predefined as Ellipsoid::WGS84 constant
auto datum = GeodeticReferenceFrame::create(
util::PropertyMap()
.set(metadata::Identifier::CODESPACE_KEY, metadata::Identifier::EPSG)
.set(metadata::Identifier::CODE_KEY, 6326)
.set(common::IdentifiedObject::NAME_KEY, "World Geodetic System 1984");
ellipsoid
util::optional<std::string>(), // anchor
greenwich);
// actually predefined as GeodeticReferenceFrame::EPSG_6326 constant
auto geogCRS = GeographicCRS::create(
util::PropertyMap()
.set(metadata::Identifier::CODESPACE_KEY, metadata::Identifier::EPSG)
.set(metadata::Identifier::CODE_KEY, 4326)
.set(common::IdentifiedObject::NAME_KEY, "WGS 84"),
datum,
cs::EllipsoidalCS::createLatitudeLongitude(scommon::UnitOfMeasure::DEGREE));
// actually predefined as GeographicCRS::EPSG_4326 constant
Algorithmic focus
*****************
On the algorithmic side, a somewhat involved logic is the
CoordinateOperationFactory::createOperations() in `coordinateoperation.cpp`_
that takes a pair of source and target CRS and returns a set of possible
`coordinate operations`_ (either single operations like a Conversion or a
Transformation, or concatenated operations). It uses the intrinsinc structure
of those objects to create the coordinate operation pipeline. That is, if
going from a ProjectedCRS to another one, by doing first the inverse conversion
from the source ProjectedCRS to its base GeographicCRS, then finding the
appropriate transformation(s) from this base GeographicCRS to the base
GeographicCRS of the target CRS, and then appyling the conversion from this
base GeographicCRS to the target ProjectedCRS. At each step, it queries the
database to find if one or several transformations are available. The
resulting coordinate operations are filtered, and sorted, with user provided hints:
- desired accuracy
- area of use, defined as a bounding box in longitude, latitude space (its
actual CRS does not matter for the intended use)
- if no area of use is defined, if and how the area of use of the source
and target CRS should be used. By default, the smallest area of use is
used. The rationale is for example when transforming between a national
ProjectedCRS and a world-scope GeographicCRS to use the are of use of
this ProjectedCRS to select the appropriate datum shifts.
- how the area of use of the candidate transformations and the desired area of
use (either explicitly or implicitly defined, as explained above) are
compared. By default, only transformations whose area of use is fully
contained in the desired area of use are selected. It is also possible
to relax this test by specifying that only an intersection test must be used.
- whether `PROJ transformation grid`_ names should be susbstituted to the
official names, when a match is found in the `grid_alternatives` table
of the database. Defaults to true
- whether the availability of those grids should be used to filter and sort
the results. By default, the transformations using grids available in the
system will be presented first.
The results are sorted, with the most relevant ones appearing first in the
result vector. The criteria used are in that order
- grid actual availability: operations referencing grids not available will be
listed after ones with available grids
- grid potential availability: operation referencing grids not known at
all in the proj.db will be listed after operations with grids known, but
not available.
- known accuracy: operations with unknown accuracies will be listed
after operations with known accuracy
- area of use: operations with smaller area of use (the intersection of the
operation area of used with the desired area of use) will be listed after
the ones with larger area of use
- accuracy: operations with lower accuracy will be listed after operations
with higher accuracy (caution: lower accuracy actually means a higher numeric
value of the accuracy property, since it is a precision in metre)
All those settings can be specified in the CoordinateOperationContext instance
passed to createOperations().
An interesting example to understand how those parameters play together is
to use `projinfo -s EPSG:4267 -t EPSG:4326` (NAD27 to WGS84 conversions),
and see how specifying desired area of use, spatial criterion, grid availability,
etc. affects the results.
The following command currently returns 78 results:
::
projinfo -s EPSG:4267 -t EPSG:4326 --summary --spatial-test intersects
The createOperations() algorithm also does a kind of "CRS routing".
A typical example is if wanting to transform between CRS A and
CRS B, but no direct transformation is referenced in proj.db between those.
But if there are transformations between A <--> C and B <--> C, then it
is possible to build a concatenated operation A --> C --> B. The typical
example is when C is WGS84, but the implementation is generic and just finds
a common pivot from the database. An example of finding a non-WGS84 pivot is
when searching a transformation between EPSG:4326 and EPSG:6668 (JGD2011 -
Japanese Geodetic Datum 2011), which has no direct transformation registered
in the EPSG database . However there are transformations between those two
CRS and JGD2000 (and also Tokyo datum, but that one involves less accurate
transformations)
::
projinfo -s EPSG:4326 -t EPSG:6668 --grid-check none --bbox 135.42,34.84,142.14,41.58 --summary
Candidate operations found: 7
unknown id, Inverse of JGD2000 to WGS 84 (1) + JGD2000 to JGD2011 (1), 1.2 m, Japan - northern Honshu
unknown id, Inverse of JGD2000 to WGS 84 (1) + JGD2000 to JGD2011 (2), 2 m, Japan excluding northern main province
unknown id, Inverse of Tokyo to WGS 84 (108) + Tokyo to JGD2011 (2), 9.2 m, Japan onshore excluding northern main province
unknown id, Inverse of Tokyo to WGS 84 (108) + Tokyo to JGD2000 (2) + JGD2000 to JGD2011 (1), 9.4 m, Japan - northern Honshu
unknown id, Inverse of Tokyo to WGS 84 (2) + Tokyo to JGD2011 (2), 13.2 m, Japan - onshore mainland and adjacent islands
unknown id, Inverse of Tokyo to WGS 84 (2) + Tokyo to JGD2000 (2) + JGD2000 to JGD2011 (1), 13.4 m, Japan - northern Honshu
unknown id, Inverse of Tokyo to WGS 84 (1) + Tokyo to JGD2011 (2), 29.2 m, Asia - Japan and South Korea
.. _`coordinate operations`: https://proj4.org/operations/index.html
.. _`PROJ transformation grid`: https://proj4.org/resource_files.html#transformation-grids
Code repository
---------------
The current state of the work can be found in the
`iso19111 branch of rouault/proj.4 repository`_ , and is also available as
a GitHub pull request at https://github.com/OSGeo/proj.4/pull/1040
Here is a not-so-usable `comparison with a fixed snapshot of master branch`_
.. _`iso19111 branch of rouault/proj.4 repository`: https://github.com/rouault/proj.4/tree/iso19111
.. _`comparison with a fixed snapshot of master branch`: https://github.com/OSGeo/proj.4/compare/iso19111_dev...rouault:iso19111
Database
--------
Content
*******
The database contains CRS and coordinate operation definitions from the `EPSG`_
database (IOGP’s EPSG Geodetic Parameter Dataset) v9.5.3,
`IGNF registry`_ (French National Geographic Institute), ESRI database, as well
as a few customizations.
.. _`EPSG`: http://www.epsg.org/
.. _`IGNF registry`: https://geodesie.ign.fr/index.php?page=documentation#titre3
Building (for PROJ developers creating the database)
****************************************************
The building of the database is a several stage process:
Construct SQL scripts for EPSG
++++++++++++++++++++++++++++++
The first stage consists in constructing .sql scripts mostly with
CREATE TABLE and INSERT statements to create the database structure and
populate it. There is one .sql file for each database table, populated
with the content of the EPSG database, automatically
generated with the `build_db.py`_ script, which processes the PostgreSQL
dumps issued by IOGP. A number of other scripts are dedicated to manual
editing, for example `grid_alternatives.sql`_ file that binds official
grid names to PROJ grid names
Concert UTF8 SQL to sqlite3 db
++++++++++++++++++++++++++++++
The second stage is done automatically by the make process. It pipes the
.sql script, in the right order, to the sqlite3 binary to generate a
first version of the proj.db SQLite3 database.
Add extra registries
++++++++++++++++++++
The third stage consists in creating additional .sql files from the
content of other registries. For that process, we need to bind some
definitions of those registries to those of the EPSG database, to be
able to link to existing objects and detect some boring duplicates.
The `ignf.sql`_ file has been generated using
the `build_db_create_ignf.py`_ script from the current data/IGNF file
that contains CRS definitions (and implicit transformations to WGS84)
as PROJ.4 strings.
The `esri.sql`_ file has been generated using the `build_db_from_esri.py`_
script, from the .csv files in
https://github.com/Esri/projection-engine-db-doc/tree/master/csv
Finalize proj.db
++++++++++++++++
The last stage runs make again to incorporate the new .sql files generated
in the previous stage (so the process of building the database involves
a kind of bootstrapping...)
Building (for PROJ users)
*************************
The make process just runs the second stage mentionned above from the .sql
files. The resulting proj.db is currently 5.3 MB large.
Structure
*********
The database is structured into the following tables and views. They generally
match a ISO-19111 concept, and is generally close to the general structure of
the EPSG database. Regarding identification of objects, where the EPSG database
only contains a 'code' numeric column, the PROJ database identifies objects
with a (auth_name, code) tuple of string values, allowing several registries to
be combined together.
- Technical:
- `authority_list`: view enumerating the authorities present in the database. Currently: EPSG, IGNF, PROJ
- `metadata`: a few key/value pairs, for example to indicate the version of the registries imported in the database
- `object_view`: synthetic view listing objects (ellipsoids, datums, CRS, coordinate operations...) code and name, and the table name where they are further described
- `alias_names`: list possible alias for the `name` field of object table
- `link_from_deprecated_to_non_deprecated`: to handle the link between old ESRI to new ESRI/EPSG codes
- Commmon:
- `unit_of_measure`: table with UnitOfMeasure definitions.
- `area`: table with area-of-use (bounding boxes) applicable to CRS and coordinate operations.
- Coordinate systems:
- `axis`: table with CoordinateSystemAxis definitions.
- `coordinate_system`: table with CoordinateSystem definitions.
- Ellipsoid and datums:
- `ellipsoid`: table with ellipsoid definitions.
- `prime_meridian`: table with PrimeMeridian definitions.
- `geodetic_datum`: table with GeodeticReferenceFrame definitions.
- `vertical_datum`: table with VerticalReferenceFrame definitions.
- CRS:
- `geodetic_crs`: table with GeodeticCRS and GeographicCRS definitions.
- `projected_crs`: table with ProjectedCRS definitions.
- `vertical_crs`: table with VerticalCRS definitions.
- `compound_crs`: table with CompoundCRS definitions.
- Coordinate operations:
- `coordinate_operation_view`: view giving a number of common attributes shared by the concrete tables implementing CoordinateOperation
- `conversion`: table with definitions of Conversion (mostly parameter and values of Projection)
- `concatenated_operation`: table with definitions of ConcatenatedOperation.
- `grid_transformation`: table with all grid-based transformations.
- `grid_packages`: table listing packages in which grids can be found. ie "proj-datumgrid", "proj-datumgrid-europe", ...
- `grid_alternatives`: table binding official grid names to PROJ grid names. e.g "Und_min2.5x2.5_egm2008_isw=82_WGS84_TideFree.gz" --> "egm08_25.gtx"
- `helmert_transformation`: table with all Helmert-based transformations.
- `other_transformation`: table with other type of transformations.
The main departure with the structure of the EPSG database is the split of
the various coordinate operations over several tables. This was done mostly
for human-readability as the EPSG organization of coordoperation,
coordoperationmethod, coordoperationparam, coordoperationparamusage,
coordoperationparamvalue tables makes it hard to grasp at once all the
parameters and values for a given operation.
Utilities
---------
A new `projinfo` utility has been added. It enables the user to enter a CRS or
coordinate operation by a AUTHORITY:CODE, PROJ string or WKT string, and see
it translated in the different flavors of PROJ and WKT strings.
It also enables to build coordinate operations between two CRSs.
Usage
*****
::
usage: projinfo [-o formats] [-k crs|operation] [--summary] [-q]
[--bbox min_long,min_lat,max_long,max_lat]
[--spatial-test contains|intersects]
[--crs-extent-use none|both|intersection|smallest]
[--grid-check none|discard_missing|sort]
[--boundcrs-to-wgs84]
{object_definition} | (-s {srs_def} -t {srs_def})
-o: formats is a comma separated combination of: all,default,PROJ4,PROJ,WKT_ALL,WKT2_2015,WKT2_2018,WKT1_GDAL
Except 'all' and 'default', other format can be preceded by '-' to disable them
Examples
********
Specify CRS by AUTHORITY:CODE
+++++++++++++++++++++++++++++
::
$ projinfo EPSG:4326
PROJ string:
+proj=pipeline +step +proj=longlat +ellps=WGS84 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1
WKT2_2015 string:
GEODCRS["WGS 84",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
CS[ellipsoidal,2],
AXIS["geodetic latitude (Lat)",north,
ORDER[1],
ANGLEUNIT["degree",0.0174532925199433]],
AXIS["geodetic longitude (Lon)",east,
ORDER[2],
ANGLEUNIT["degree",0.0174532925199433]],
AREA["World"],
BBOX[-90,-180,90,180],
ID["EPSG",4326]]
Specify CRS by PROJ string and specify output formats
++++++++++++++++++++++++++++++++++++++++++++++++++++++
::
$ projinfo -o PROJ4,PROJ,WKT1_GDAL,WKT2_2018 "+title=IGN 1972 Nuku Hiva - UTM fuseau 7 Sud +proj=tmerc +towgs84=165.7320,216.7200,180.5050,-0.6434,-0.4512,-0.0791,7.420400 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-141.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs"
PROJ string:
Error when exporting to PROJ string: BoundCRS cannot be exported as a PROJ.5 string, but its baseCRS might
PROJ.4 string:
+proj=utm +zone=7 +south +ellps=intl +towgs84=165.732,216.72,180.505,-0.6434,-0.4512,-0.0791,7.4204
WKT2_2018 string:
BOUNDCRS[
SOURCECRS[
PROJCRS["IGN 1972 Nuku Hiva - UTM fuseau 7 Sud",
BASEGEOGCRS["unknown",
DATUM["unknown",
ELLIPSOID["International 1909 (Hayford)",6378388,297,
LENGTHUNIT["metre",1,
ID["EPSG",9001]]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8901]]],
CONVERSION["unknown",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",0,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",-141,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",0.9996,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",500000,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",10000000,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["(E)",east,
ORDER[1],
LENGTHUNIT["metre",1,
ID["EPSG",9001]]],
AXIS["(N)",north,
ORDER[2],
LENGTHUNIT["metre",1,
ID["EPSG",9001]]]]],
TARGETCRS[
GEOGCRS["WGS 84",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
CS[ellipsoidal,2],
AXIS["latitude",north,
ORDER[1],
ANGLEUNIT["degree",0.0174532925199433]],
AXIS["longitude",east,
ORDER[2],
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4326]]],
ABRIDGEDTRANSFORMATION["Transformation from unknown to WGS84",
METHOD["Position Vector transformation (geog2D domain)",
ID["EPSG",9606]],
PARAMETER["X-axis translation",165.732,
ID["EPSG",8605]],
PARAMETER["Y-axis translation",216.72,
ID["EPSG",8606]],
PARAMETER["Z-axis translation",180.505,
ID["EPSG",8607]],
PARAMETER["X-axis rotation",-0.6434,
ID["EPSG",8608]],
PARAMETER["Y-axis rotation",-0.4512,
ID["EPSG",8609]],
PARAMETER["Z-axis rotation",-0.0791,
ID["EPSG",8610]],
PARAMETER["Scale difference",1.0000074204,
ID["EPSG",8611]]]]
WKT1_GDAL:
PROJCS["IGN 1972 Nuku Hiva - UTM fuseau 7 Sud",
GEOGCS["unknown",
DATUM["unknown",
SPHEROID["International 1909 (Hayford)",6378388,297],
TOWGS84[165.732,216.72,180.505,-0.6434,-0.4512,-0.0791,7.4204]],
PRIMEM["Greenwich",0,
AUTHORITY["EPSG","8901"]],
UNIT["degree",0.0174532925199433,
AUTHORITY["EPSG","9122"]],
AXIS["Longitude",EAST],
AXIS["Latitude",NORTH]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",0],
PARAMETER["central_meridian",-141],
PARAMETER["scale_factor",0.9996],
PARAMETER["false_easting",500000],
PARAMETER["false_northing",10000000],
UNIT["metre",1,
AUTHORITY["EPSG","9001"]],
AXIS["Easting",EAST],
AXIS["Northing",NORTH]]
Find transformations between 2 CRS
++++++++++++++++++++++++++++++++++
Between "Poland zone I" (based on Pulkovo 42 datum) and "UTM WGS84 zone 34N"
Summary view:
::
$ projinfo -s EPSG:2171 -t EPSG:32634 --summary
Candidate operations found: 1
unknown id, Inverse of Poland zone I + Pulkovo 1942(58) to WGS 84 (1) + UTM zone 34N, 1 m, Poland - onshore
Display of pipelines:
::
$ PROJ_LIB=data src/projinfo -s EPSG:2171 -t EPSG:32634 -o PROJ
PROJ string:
+proj=pipeline +step +proj=axisswap +order=2,1 +step +inv +proj=sterea +lat_0=50.625 +lon_0=21.0833333333333 +k=0.9998 +x_0=4637000 +y_0=5647000 +ellps=krass +step +proj=cart +ellps=krass +step +proj=helmert +x=33.4 +y=-146.6 +z=-76.3 +rx=-0.359 +ry=-0.053 +rz=0.844 +s=-0.84 +convention=position_vector +step +inv +proj=cart +ellps=WGS84 +step +proj=utm +zone=34 +ellps=WGS84
Impacted files
--------------
New files (excluding makefile.am, CMakeLists.txt and other build infrastructure
artifacts):
* include/proj/: Public installed C++ headers
- `common.hpp`_: declarations of osgeo::proj::common namespace.
- `coordinateoperation.hpp`_: declarations of osgeo::proj::operation namespace.
- `coordinatesystem.hpp`_: declarations of osgeo::proj::cs namespace.
- `crs.hpp`_: declarations of osgeo::proj::crs namespace.
- `datum.hpp`_: declarations of osgeo::proj::datum namespace.
- `io.hpp`_: declarations of osgeo::proj::io namespace.
- `metadata.hpp`_: declarations of osgeo::proj::metadata namespace.
- `util.hpp`_: declarations of osgeo::proj::util namespace.
- `nn.hpp`_: Code from https://github.com/dropbox/nn to manage Non-nullable pointers for C++
.. _`common.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/common.hpp
.. _`coordinateoperation.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/coordinateoperation.hpp
.. _`coordinatesystem.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/coordinatesystem.hpp
.. _`crs.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/crs.hpp
.. _`datum.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/datum.hpp
.. _`io.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/io.hpp
.. _`metadata.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/metadata.hpp
.. _`nn.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/nn.hpp
.. _`util.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/util.hpp
* include/proj/internal: Private non-installed C++ headers
- `coordinateoperation_internal.hpp`_: classes InverseCoordinateOperation, InverseConversion, InverseTransformation, PROJBasedOperation, and functions to get conversion mappings between WKT and PROJ syntax
- `coordinateoperation_constants.hpp`_: Select subset of conversion/transformation EPSG names and codes for the purpose of translating them to PROJ strings
- `coordinatesystem_internal.hpp`_: classes AxisDirectionWKT1, AxisName and AxisAbbreviation
- `internal.hpp`_: a few helper functions, mostly to do string-based operations
- `io_internal.hpp`_: class WKTConstants
- `helmert_constants.hpp`_: Helmert-based transformation & parameters names and codes.
- `lru_cache.hpp`_: code from https://github.com/mohaps/lrucache11 to have a generic Least-Recently-Used cache of objects
.. _`coordinateoperation_internal.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/internal/coordinateoperation_internal.hpp
.. _`coordinatesystem_internal.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/internal/coordinatesystem_internal.hpp
.. _`internal.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/internal/internal.hpp
.. _`io_internal.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/internal/io_internal.hpp
.. _`coordinateoperation_constants.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/internal/coordinateoperation_constants.hpp
.. _`helmert_constants.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/internal/helmert_constants.hpp
.. _`lru_cache.hpp`: https://github.com/rouault/proj.4/blob/iso19111/include/proj/internal/lru_cache.hpp
* src/:
- `c_api.cpp`_: C++ API mapped to C functions
- `common.cpp`_: implementation of `common.hpp`_
- `coordinateoperation.cpp`_: implementation of `coordinateoperation.hpp`_
- `coordinatesystem.cpp`_: implementation of `coordinatesystem.hpp`_
- `crs.cpp`_: implementation of `crs.hpp`_
- `datum.cpp`_: implementation of `datum.hpp`_
- `factory.cpp`_: implementation of AuthorityFactory class (from `io.hpp`_)
- `internal.cpp`_: implementation of `internal.hpp`_
- `io.cpp`_: implementation of `io.hpp`_
- `metadata.cpp`_: implementation of `metadata.hpp`_
- `static.cpp`_: a number of static constants (like pre-defined well-known ellipsoid, datum and CRS), put in the right order for correct static initializations
- `util.cpp`_: implementation of `util.hpp`_
- `projinfo.cpp`_: new 'projinfo' binary
- `general.dox`_: generic introduction documentation.
.. _`c_api.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/c_api.cpp
.. _`common.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/common.cpp
.. _`coordinateoperation.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/coordinateoperation.cpp
.. _`coordinatesystem.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/coordinatesystem.cpp
.. _`crs.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/crs.cpp
.. _`datum.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/datum.cpp
.. _`factory.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/factory.cpp
.. _`internal.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/internal.cpp
.. _`io.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/io.cpp
.. _`metadata.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/metadata.cpp
.. _`projinfo.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/projinfo.cpp
.. _`static.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/static.cpp
.. _`util.cpp`: https://github.com/rouault/proj.4/blob/iso19111/src/util.cpp
.. _`general.dox`: https://github.com/rouault/proj.4/blob/iso19111/src/general.dox
* data/sql/:
- `area.sql`_: generated by `build_db.py`_
- `axis.sql`_: generated by `build_db.py`_
- `begin.sql`_: hand generated (trivial)
- `commit.sql`_: hand generated (trivial)
- `compound_crs.sql`_: generated by `build_db.py`_
- `concatenated_operation.sql`_: generated by `build_db.py`_
- `conversion.sql`_: generated by `build_db.py`_
- `coordinate_operation.sql`_: generated by `build_db.py`_
- `coordinate_system.sql`_: generated by `build_db.py`_
- `crs.sql`_: generated by `build_db.py`_
- `customizations.sql`_: hand generated (empty)
- `ellipsoid.sql`_: generated by `build_db.py`_
- `geodetic_crs.sql`_: generated by `build_db.py`_
- `geodetic_datum.sql`_: generated by `build_db.py`_
- `grid_alternatives.sql`_: hand-generated. Contains links between official registry grid names and PROJ ones
- `grid_transformation.sql`_: generated by `build_db.py`_
- `grid_transformation_custom.sql`_: hand-generated
- `helmert_transformation.sql`_: generated by `build_db.py`_
- `ignf.sql`_: generated by `build_db_create_ignf.py`_
- `esri.sql`_: generated by `build_db_from_esri.py`_
- `metadata.sql`_: hand-generated
- `other_transformation.sql`_: generated by `build_db.py`_
- `prime_meridian.sql`_: generated by `build_db.py`_
- `proj_db_table_defs.sql`_: hand-generated. Database structure: CREATE TABLE / CREATE VIEW / CREATE TRIGGER
- `projected_crs.sql`_: generated by `build_db.py`_
- `unit_of_measure.sql`_: generated by `build_db.py`_
- `vertical_crs.sql`_: generated by `build_db.py`_
- `vertical_datum.sql`_: generated by `build_db.py`_
.. _`area.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/area.sql
.. _`axis.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/axis.sql
.. _`begin.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/begin.sql
.. _`commit.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/commit.sql
.. _`compound_crs.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/compound_crs.sql
.. _`concatenated_operation.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/concatenated_operation.sql
.. _`conversion.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/conversion.sql
.. _`coordinate_operation.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/coordinate_operation.sql
.. _`coordinate_system.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/coordinate_system.sql
.. _`crs.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/crs.sql
.. _`customizations.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/customizations.sql
.. _`ellipsoid.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/ellipsoid.sql
.. _`geodetic_crs.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/geodetic_crs.sql
.. _`geodetic_datum.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/geodetic_datum.sql
.. _`grid_alternatives.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/grid_alternatives.sql
.. _`grid_transformation_custom.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/grid_transformation_custom.sql
.. _`grid_transformation.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/grid_transformation.sql
.. _`helmert_transformation.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/helmert_transformation.sql
.. _`ignf.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/ignf.sql
.. _`esri.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/esri.sql
.. _`metadata.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/metadata.sql
.. _`other_transformation.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/other_transformation.sql
.. _`prime_meridian.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/prime_meridian.sql
.. _`proj_db_table_defs.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/proj_db_table_defs.sql
.. _`projected_crs.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/projected_crs.sql
.. _`unit_of_measure.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/unit_of_measure.sql
.. _`vertical_crs.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/vertical_crs.sql
.. _`vertical_datum.sql`: https://github.com/rouault/proj.4/blob/iso19111/data/sql/vertical_datum.sql
* scripts/:
- `build_db.py`_ : generate .sql files from EPSG database dumps
- `build_db_create_ignf.py`_: generates data/sql/`ignf.sql`_
- `build_db_from_esri.py`_: generates data/sql/`esri.sql`_
- `doxygen.sh`_: generates Doxygen documentation
- `gen_html_coverage.sh`_: generates HTML report of the coverage for --coverage build
- `filter_lcov_info.py`_: utility used by gen_html_coverage.sh
- `reformat.sh`_: used by reformat_cpp.sh
- `reformat_cpp.sh`_: reformat all .cpp/.hpp files according to LLVM-style formatting rules
.. _`build_db.py`: https://github.com/rouault/proj.4/blob/iso19111/scripts/build_db.py
.. _`build_db_create_ignf.py`: https://github.com/rouault/proj.4/blob/iso19111/scripts/build_db_create_ignf.py
.. _`build_db_from_esri.py`: https://github.com/rouault/proj.4/blob/iso19111/scripts/build_db_from_esri.py
.. _`doxygen.sh`: https://github.com/rouault/proj.4/blob/iso19111/scripts/doxygen.sh
.. _`gen_html_coverage.sh`: https://github.com/rouault/proj.4/blob/iso19111/scripts/gen_html_coverage.sh
.. _`filter_lcov_info.py`: https://github.com/rouault/proj.4/blob/iso19111/scripts/filter_lcov_info.py
.. _`reformat.sh`: https://github.com/rouault/proj.4/blob/iso19111/scripts/reformat.sh
.. _`reformat_cpp.sh`: https://github.com/rouault/proj.4/blob/iso19111/scripts/reformat_cpp.sh
* tests/unit/
- `test_c_api.cpp`_: test of src/c_api.cpp
- `test_common.cpp`_: test of src/common.cpp
- `test_util.cpp`_: test of src/util.cpp
- `test_crs.cpp`_: test of src/crs.cpp
- `test_datum.cpp`_: test of src/datum.cpp
- `test_factory.cpp`_: test of src/factory.cpp
- `test_io.cpp`_: test of src/io.cpp
- `test_metadata.cpp`_: test of src/metadata.cpp
- `test_operation.cpp`_: test of src/operation.cpp
.. _`test_c_api.cpp`: https://github.com/rouault/proj.4/blob/iso19111/test/unit/test_c_api.cpp
.. _`test_common.cpp`: https://github.com/rouault/proj.4/blob/iso19111/test/unit/test_common.cpp
.. _`test_util.cpp`: https://github.com/rouault/proj.4/blob/iso19111/test/unit/test_util.cpp
.. _`test_crs.cpp`: https://github.com/rouault/proj.4/blob/iso19111/test/unit/test_crs.cpp
.. _`test_datum.cpp`: https://github.com/rouault/proj.4/blob/iso19111/test/unit/test_datum.cpp
.. _`test_factory.cpp`: https://github.com/rouault/proj.4/blob/iso19111/test/unit/test_factory.cpp
.. _`test_io.cpp`: https://github.com/rouault/proj.4/blob/iso19111/test/unit/test_io.cpp
.. _`test_metadata.cpp`: https://github.com/rouault/proj.4/blob/iso19111/test/unit/test_metadata.cpp
.. _`test_operation.cpp`: https://github.com/rouault/proj.4/blob/iso19111/test/unit/test_operation.cpp
C API
-----
`proj.h`_ has been extended to bind a number of C++ classes/methods to a C API.
The main structure is an opaque PJ_OBJ* roughly encapsulating a osgeo::proj::BaseObject,
that can represent a CRS or a CoordinateOperation object. A number of the
C functions will work only if the right type of underlying C++ object is used
with them. Misuse will be properly handled at runtime. If a user passes
a PJ_OBJ* representing a coordinate operation to a pj_obj_crs_xxxx() function,
it will properly error out. This design has been chosen over creating a
dedicate PJ_xxx object for each C++ class, because such an approach would
require adding many conversion and free functions for little benefit.
This C API is incomplete. In particular, it does not allow to
build ISO19111 objects at hand. However it currently permits a number of
actions:
- building CRS and coordinate operations from WKT and PROJ strings, or
from the proj.db database
- exporting CRS and coordinate operations as WKT and PROJ strings
- querying main attributes of those objects
- finding coordinate operations between two CRS.
`test_c_api.cpp`_ should demonstrates simple usage of the API (note:
for the conveniency of writing the tests in C++, test_c_api.cpp wraps the C PJ_OBJ*
instances in C++ 'keeper' objects that automatically call the pj_obj_unref()
function at function end. In a pure C use, the caller must use pj_obj_unref()
to prevent leaks.)
.. _`proj.h`: http://even.rouault.free.fr/proj_cpp_api/html/proj_8h.html
Documentation
-------------
All public C++ classes and methods and C functions are documented with
Doxygen.
`Current snapshot of Class list`_
`Spaghetti inheritance diagram`_
.. _`Current snapshot of Class list`: http://even.rouault.free.fr/proj_cpp_api/html/annotated.html
.. _`Spaghetti inheritance diagram`: http://even.rouault.free.fr/proj_cpp_api/html/inherits.html
A basic integration of the Doxygen XML output into the general PROJ
documentation (using reStructuredText format) has been done with the the
Sphinx extension `Breathe`_, producing:
* `One section with the C++ API`_
* `One section with the C API`_
.. _`Breathe`: https://breathe.readthedocs.io/en/latest/
.. _`One section with the C++ API`: http://even.rouault.free.fr/proj_cpp_api/rst_generated/html/development/reference/cpp/index.html
.. _`One section with the C API`: http://even.rouault.free.fr/proj_cpp_api/rst_generated/html/development/reference/functions.html#c-api-for-iso-19111-functionality
Testing
-------
Nearly all exported methods are tested by a unit test. Global line coverage
of the new files is 92%. Those tests represent 16k lines of codes.
Build requirements
------------------
The new code leverages on a number of C++11 features (auto keyword, constexpr,
initializer list, std::shared_ptr, lambda functions, etc.), which means that
a C++11-compliant compiler must be used to generate PROJ:
* gcc >= 4.8
* clang >= 3.3
* Visual Studio >= 2015.
Compilers tested by the Travis-CI and AppVeyor continuous integration
environments:
* GCC 4.8
* mingw-w64-x86-64 4.8
* clang 5.0
* Apple LLVM version 9.1.0 (clang-902.0.39.2)
* MSVC 2015 32 and 64 bit
* MSVC 2017 32 and 64 bit
The libsqlite3 >= 3.7 development package must also be available. And the sqlite3
binary must be available to build the proj.db files from the .sql files.
Runtime requirements
--------------------
* libc++/libstdc++/MSVC runtime consistent with the compiler used
* libsqlite3 >= 3.7
Backward compatibility
----------------------
At this stage, no backward compatibility issue is foreseen, as no
existing functional C code has been modified to use the new capabilities
Future work
-----------
The work described in this RFC will be pursued in a number of directions.
Non-exhaustively:
- Support for ESRI WKT1 dialect (PROJ currently ingest the ProjectedCRS in
`esri.sql`_ in that dialect, but there is no mapping between it and EPSG
operation and parameter names, so conversion to PROJ strings does not
always work.
- closer integration with the existing code base. In particular, the +init=dict:code
syntax should now go first to the database (then the `epsg` and `IGNF`
files can be removed). Similarly proj_create_crs_to_crs() could use the
new capabilities to find an appropriate coordinate transformation.
- and whatever else changes are needed to address GDAL and libgeotiff needs
Adoption status
---------------
The RFC has been adopted with support from PSC members Kurt Schwehr, Kristian
Evers, Howard Butler and Even Rouault.
+151
View File
@@ -0,0 +1,151 @@
.. _rfc3:
====================================================================
PROJ RFC 3: Dependency management
====================================================================
:Author: Kristian Evers
:Contact: kreve@sdfe.dk
:Status: Adopted
:Last Updated: 2019-01-16
Summary
-------------------------------------------------------------------------------
This document defines a set of guidelines for dependency management in PROJ.
With PROJ being a core component in many downstream software packages clearly
stating which dependencies the library has is of great value. This document
concern both programming language standards as well as minimum required
versions of library dependencies and build tools.
It is proposed to adopt a rolling update scheme that ensures that PROJ is
sufficiently accessible, even on older systems, as well as keeping up with the
technological evolution. The scheme is divided in two parts, one concerning
versions of used programming languages within PROJ and the other concerning
software packages that PROJ depend on.
With adoption of this RFC, versions used for
1. programming languages will always be at least two revisions behind the most
recent standard
2. software packages will always be at least two years old
(patch releases are exempt)
A change in programming language standard can only be introduced with a new
major version release of PROJ. Changes for software package dependencies can be
introduced with minor version releases of PROJ. Changing the version
requirements for a dependency needs to be approved by the PSC.
Following the above rule set will ensure that all but the most conservative
users of PROJ will be able to build and use the most recent version of the
library.
In the sections below details concerning programming languages and software
dependencies are outlined. The RFC is concluded with a bootstrapping section
that details the state of dependencies after the accept of the RFC.
Background
-------------------------------------------------------------------------------
PROJ has traditionally been written in C89. Until recently, no formal
requirements of e.g. build systems has been defined and formally accepted by
the project. :ref:RFC2 <rfc2>` formally introduces dependencies on C++11 and
SQLite 3.7.
In this RFC a rolling update of version or standard requirements is described.
The reasoning behind a rolling update scheme is that it has become increasingly
evident that C89 is becoming outdated and creating a less than optimal
development environment for contributors. It has been noted that the most
commonly used compilers all now support more recent versions of C, so the
strict usage of C89 is no longer as critical as it used to be.
Similarly, rolling updates to other tools and libraries that PROJ depend on
will ensure that the code base can be kept modern and in line with the rest of
the open source software ecosphere.
C and C++
-------------------------------------------------------------------------------
Following :ref:`RFC2 <rfc2>` PROJ is written in both C and C++. At the time of
writing the core library is C based and the code described in RFC2 is written
in C++. While the core library is mostly written in C it is compiled as C++.
Minor sections of PROJ, like the geodesic algorithms are still compiled as C
since there is no apparent benefit of compiling with a C++ compiler. This may
change in the future.
Both the C and C++ standards are updated with regular intervals. After an
update of a standard it takes time for compiler manufacturers to implement the
standards fully, which makes adaption of new standards potentially troublesome
if done too soon. On the other hand, waiting too long to adopt new standards
will eventually make the code base feel old and new contributors are more
likely to stay away because they don't want to work using tools of the past.
With a rolling update scheme both concerns can be managed by always staying
behind the most recent standard, but not so far away that potential
contributors are scared away. Keeping a policy of always lagging behind be two
iterations of the standard is thought to be the best comprise between the two
concerns.
C comes in four ISO standardised varieties: C89, C99, C11, C18. In this
document we refer to their informal names for ease of reading. C++ exists in
five varieties: C++98, C++03, C++11, C++14, C++17. Before adoption of this RFC
PROJ uses C89 and C++11. For C, that means that the used standard is three
iterations behind the most recent standard. C++ is two iterations behind.
Following the rules in this RFC the required C standard used in PROJ is at
allowed to be two iterations behind the most recent standard. That means that a
change to C99 is possible, as long as the PROJ PSC aknowledges such a change.
When a new standard for either C or C++ is released PROJ should consider
changing its requirement to the next standard in the line. For C++ that means a
change in standard roughly every three years, for C the periods between
standard updates is expected to be longer. Adaptation of new programming
language standards should be coordinated with a major version release of PROJ.
Software dependencies
-------------------------------------------------------------------------------
At the time of writing PROJ is dependent on very few external packages. In
fact only one runtime dependency is present: SQLite. Building PROJ also
requires one of two external dependencies for configuration: Autotools or
CMake.
As with programming language standards it is preferable that software
dependencies are a bit behind the most recent development. For this reason it
is required that the minimum version supported in PROJ dependencies is at least
two years old, preferably more. It is not a requirement that the minimum
version of dependencies is always kept strictly two years behind current
development, but it is allowed in case future development of PROJ warrants an
update. Changes in minimum version requirements are allowed to happen with
minor version releases of PROJ.
At the time of writing the minimum version requried for SQLite it 3.7 which was
released in 2010. CMake currently is required to be at least at version 2.8.3
which was also released in 2010.
Bootstrapping
-------------------------------------------------------------------------------
This RFC comes with a set of guidelines for handling dependencies for PROJ in
the future. Up until now dependencies hasn't been handled consistently, with
some dependencies not being approved formally by the projects governing body.
Therefore minimum versions of PROJ dependencies is proposed so that at the
acception of this RFC PROJ will have the following external requirements:
* C99 (was C89)
* C++11 (already approved in :ref:`RFC2 <rfc2>`)
* SQLite 3.7 (already approved in :ref:`RFC2 <rfc2>`)
* CMake 3.5 (was 2.8.3)
Adoption status
-------------------------------------------------------------------------------
The RFC was adopted on 2018-01-19 with +1's from the following PSC members
* Kristian Evers
* Even Rouault
* Thomas Knudsen
* Howard Butler
+21 -15
View File
@@ -14,7 +14,6 @@
import sys
import os
import datetime
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
@@ -39,6 +38,9 @@ extensions = [
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# BibTeX configuration
bibtex_bibfiles = ['references.bib']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
@@ -58,34 +60,30 @@ project = 'PROJ.4'
# See CITATION file
title = 'PROJ coordinate transformation software library'
author = 'PROJ contributors'
now = datetime.datetime.now()
copyright = u'1983-{0}'.format(now.year)
copyright = u'1983-2018'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
version = '5.2.0'
# use same |release| as |version|
release = version
version = '5.2'
release = '5.2.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# language = 'en'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
today = 'September 2018'
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
exclude_patterns = ['operations/options/*.rst']
# The reST default role (used for this markup: `text`) to use for all
# documents.
@@ -155,10 +153,16 @@ html_theme_options = {}
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
htm_css_files = [
'theme_overrides.css', # override wide tables in RTD theme
]
html_context = {
'css_files': [
'_static/theme_overrides.css', # override wide tables in RTD theme
],
'display_github': True,
'theme_vcs_pageview_mode': 'edit',
'github_user': 'OSGeo',
'github_repo': 'PROJ',
'github_version': '/5.2/docs/source/',
}
# Add any extra paths that contain custom files (such as robots.txt or
@@ -231,6 +235,8 @@ preamble = r"""
\ifdefined\DeclareUnicodeCharacter
\DeclareUnicodeCharacter{2032}{$'$}% prime
\fi
\usepackage[notbib,notindex]{tocbibind}
"""
latex_elements = {
@@ -242,7 +248,7 @@ latex_elements = {
# Additional stuff for the LaTeX preamble.
'preamble': preamble,
'inputenc':'\usepackage[utf8]{inputenc}'
'inputenc': r'\usepackage[utf8]{inputenc}',
# Latex figure (float) alignment
#'figure_align': 'htbp',
+6
View File
@@ -41,3 +41,9 @@ Visual Basic
`PROJ VB Wrappers <http://ftp.dfg.ca.gov/Public/BDB/Tools/proj4/proj_api.zip>`_:
By Eric G. Miller.
Fortran
=======
`Fortran-Proj <https://gitlab.com/likeno/fortran-proj>`_:
Bindings for PROJ in Fortran (By João Macedo @likeno)
+2 -4
View File
@@ -18,13 +18,12 @@ Current Release
* **2018-09-15** `proj-datumgrid-europe-1.1.zip`_
* **2018-09-15** `proj-datumgrid-north-america-1.1.zip`_
* **2018-03-01** `proj-datumgrid-oceania-1.0.zip`_
* **PDF Manual** `proj.pdf`_
Past Releases
--------------------------------------------------------------------------------
* **2018-06-01** `proj-5.1.0.tar.gz`_ (`md5`_)
* **2018-04-01** `proj-5.0.1.tar.gz`_ (`md5`_)
* **2018-06-01** `proj-5.1.0.tar.gz`_
* **2018-04-01** `proj-5.0.1.tar.gz`_
* **2018-03-01** `proj-5.0.0.tar.gz`_
* **2016-09-02** `proj-4.9.3.tar.gz`_
* **2015-09-13** `proj-4.9.2.tar.gz`_
@@ -51,4 +50,3 @@ Past Releases
.. _`proj-datumgrid-north-america-1.1.zip`: http://download.osgeo.org/proj/proj-datumgrid-north-america-1.1.zip
.. _`proj-datumgrid-oceania-1.0.zip`: http://download.osgeo.org/proj/proj-datumgrid-oceania-1.0.zip
.. _`md5`: http://download.osgeo.org/proj/proj-5.2.0.tar.gz.md5
.. _`proj.pdf`: https://raw.githubusercontent.com/OSGeo/proj.4/gh-pages/proj.pdf
+41 -122
View File
@@ -15,33 +15,23 @@ FAQ
Where can I find the list of projections and their arguments?
--------------------------------------------------------------------------------
There is no simple single location to find all the required information. The
!PostScript/PDF documents listed on the [http://trac.osgeo.org/proj/wiki main]
PROJ page under documentation are the authoritative source but projections
and options are spread over several documents in a form more related to their
order of implementation than anything else.
:doc:`Here<../operations/projections/index>`.
The '''proj''' command itself can report the list of projections using the
'''-lp''' option, the list of ellipsoids with the '''-le''' option, the list of
units with the '''-lu''' option, and the list of built-in datums with the
'''-ld''' option.
Additinoally, the ``proj`` command itself can report the list of projections
using the ``-lp`` option, the list of ellipsoids with the ``-le`` option,
the list of units with the ``-lu`` option, and the list of built-in datums with
the ``-ld`` option.
The [http://geotiff.maptools.org/proj_list/ GeoTIFF Projections Pages]
include most of the common PROJ projections, and a definition of the
projection specific options for each.
How do I do datum shifts between NAD27 and NAD83?
--------------------------------------------------------------------------------
* How do I do datum shifts between NAD27 and NAD83?
While the '''nad2nad''' program can be used in some cases, the '''cs2cs''' is
now the preferred mechanism. The following example demonstrates using the
Using the ``cs2cs`` application. The following example demonstrates using the
default shift parameters for NAD27 to NAD83:
::
% cs2cs +proj=latlong +datum=NAD27 +to +proj=latlong +datum=NAD83 -117 30
producing:
::
@@ -49,8 +39,8 @@ producing:
117d0'2.901"W 30d0'0.407"N 0.000
In order for datum shifting to work properly the various grid shift files must
be available. See below. More details are available in the
[wiki:GenParms#nadgrids-GridBasedDatumAdjustments General Parameters] document.
be available. See below. More details are available in the
section on :doc:`resource files<resource_files>`.
How do I build/configure PROJ to support datum shifting?
--------------------------------------------------------------------------------
@@ -64,7 +54,7 @@ On Windows the extra nadshift target must be used. For instance
A default build and install on Unix will normally build knowledge of the
directory where the grid shift files are installed into the PROJ library
(usually /usr/local/share/proj). On Windows the library is normally built
(usually ``/usr/local/share/proj``). On Windows the library is normally built
thinking that C:\PROJ\NAD is the installed directory for the grid shift files.
If the built in concept of the PROJ data directory is incorrect, the ``PROJ_LIB``
environment can be defined with the correct directory.
@@ -72,24 +62,24 @@ environment can be defined with the correct directory.
How do I debug problems with NAD27/NAD83 datum shifting?
--------------------------------------------------------------------------------
1. Verify that you have the binary files (eg. /usr/local/share/proj/conus)
1. Verify that you have the binary files (eg. ``/usr/local/share/proj/conus``)
installed on your system. If not, see the previous question.
2. Try a datum shifting operation in relative isolation, such as with the cs2cs
2. Try a datum shifting operation in relative isolation, such as with the :program:`cs2cs`
command listed above. Do you get reasonable results? If not it is likely
the grid shift files aren't being found. Perhaps you need to define
PROJ_LIB?
3. The cs2cs command and the underlying pj_transform() API know how to do a
:envvar:`PROJ_LIB`?
3. The :program:`cs2cs` command and the underlying :c:func:`pj_transform()` API know how to do a
grid shift as part of a more complex coordinate transformation; however, it
is imperative that both the source and destination coordinate system be
defined with appropriate datum information. That means that implicitly or
explicitly there must be a +datum= clause, a +nadgrids= clause or a
+towgs84= clause. For instance
explicitly there must be a ``+datum=`` clause, a ``+nadgrids=`` clause or a
``+towgs84=`` clause. For instance
``cs2cs +proj=latlong +datum=NAD27 +to +proj=latlong +ellps=WGS84`` won't work because defining the output
coordinate system as using the ellipse WGS84 isn't the same as defining it
to use the datum WGS84 (use +datum=WGS84). If either the input or output
to use the datum WGS84 (use ``+datum=WGS84``). If either the input or output
are not identified as having a datum, the datum shifting (and ellipsoid
change) step is just quietly skipped!
4. The ``PROJ_DEBUG`` environment can be defined (any value) to force extra output
4. The :envvar:`PROJ_DEBUG` environment can be defined (any value) to force extra output
from the PROJ library to stderr (the text console normally) with
information on what data files are being opened and in some cases why a
transformation fails.
@@ -103,16 +93,16 @@ How do I debug problems with NAD27/NAD83 datum shifting?
.. note::
``PROJ_DEBUG`` support is not yet very mature in the PROJ library.
5. The ``-v`` flag to cs2cs can be useful in establishing more detail on what
5. The :option:`-v` flag to :program:`cs2cs` can be useful in establishing more detail on what
parameters being used internally for a coordinate system. This will include
expanding the definition of +datum clause.
expanding the definition of ``+datum`` clause.
How do I use EPSG coordinate system codes with PROJ?
--------------------------------------------------------------------------------
There is somewhat imperfect translation between 2d geographic and projected
There is somewhat imperfect translation between 2D geographic and projected
coordinate system codes and PROJ descriptions of the coordinate system
available in the epsg definition file that normally lives in the proj/nad
available in the ``epsg`` definition file that normally lives in the ``proj/nad``
directory. If installed (it is installed by default on Unix), it is possible
to use EPSG numbers like this:
@@ -136,26 +126,28 @@ to use EPSG numbers like this:
The proj/nad/epsg file can be browsed and searched in a text editor for
coordinate systems. There are known to be problems with some coordinate
systems, and any coordinate systems with odd axes, a non-greenwich prime
meridian or other quirkiness are unlikely to work properly. Caveat Emptor!
meridian or other quirkiness are unlikely to work properly. Caveat Emptor!
How do I use 3 parameter and 7 parameter datum shifting
--------------------------------------------------------------------------------
Datum shifts can be approximated with 3 and 7 parameter transformations. Their
use is more fully described in the
[wiki:GenParms#towgs84-DatumtransformationtoWGS84 towgs84] parameter
discussion.
Datum shifts can be approximated with 3 and 7 parameter transformations. Their
use with :program:`cs2cs` is more fully described in the
:ref:`geodetic tranformation<cs2cs_specific_options>` section.
More generically, the :ref:`helmert` can be used with :program:`cct`.
Does PROJ work in different international numeric locales?
--------------------------------------------------------------------------------
No. PROJ makes extensive use of sprintf() and atof() internally to translate
numeric values. If a locale is in effect that modifies formatting of numbers,
altering the role of commas and periods in numbers, then PROJ will not work.
This problem is common in some European locales.
No. PROJ makes extensive use of the :c:func:`sprintf()` and :c:func:`atof()` C functions
internally to translate numeric values. If a locale is in effect that modifies
formatting of numbers, altering the role of commas and periods in numbers, then
PROJ will not work. This problem is common in some European locales.
On unix-like platforms, this problem can be avoided by forcing the use of the
default numeric locale by setting the LC_NUMERIC environment variable to C.
On UNIX-like platforms, this problem can be avoided by forcing the use of the
default numeric locale by setting the :envvar:`LC_NUMERIC` environment variable to C.
::
@@ -189,7 +181,7 @@ But, if you do something like:
+x_0=0.0 +y_0=0 +k=1.0 +units=m +no_defs
to convert between WGS84 and mercator on the sphere there will be substantial
shifts in the Y mercator coordinates. This is because internally cs2cs is
shifts in the Y mercator coordinates. This is because internally :program:`cs2cs` is
having to adjust the lat/long coordinates from being on the sphere to being on
the WGS84 datum which has a quite differently shaped ellipsoid.
@@ -207,7 +199,7 @@ your spherical lat/long coordinates to WGS84.
+to +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 \
+x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs
Note the strategic addition of +nadgrids=@null to the spherical projection
Note the strategic addition of ``+nadgrids=@null`` to the spherical projection
definition.
Similar issues apply with many other datasets distributed with projections
@@ -215,7 +207,7 @@ based on a spherical earth model - such as many NASA datasets. This coordinate
system is now known by the EPSG code 3857 and has in the past been known as
EPSG:3785 and EPSG:900913. When using this coordinate system with GDAL/OGR it
is helpful to include the +wktext so the exact PROJ string will be preserved
in the WKT representation (otherwise key parameters like `+nadgrids=@null` will
in the WKT representation (otherwise key parameters like ``+nadgrids=@null`` will
be dropped):
::
@@ -223,17 +215,6 @@ be dropped):
+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0
+units=m +nadgrids=@null +wktext +no_defs
Why do I get different results with 4.5.0 and 4.6.0?
--------------------------------------------------------------------------------
The default datum application behavior changed with the 4.6.0 release. PROJ
will now only apply a datum shift if both the source and destination coordinate
system have valid datum shift information.
From the PROJ 4.6.0 Release Notes (in NEWS):
* MAJOR: Rework pj_transform() to avoid applying ellipsoid to ellipsoid
transformations as a datum shift when no datum info is available.
How do I calculate distances/directions on the surface of the earth?
--------------------------------------------------------------------------------
@@ -241,80 +222,18 @@ How do I calculate distances/directions on the surface of the earth?
These are called geodesic calculations. There is a page about it here:
:ref:`geodesic`.
What is the HEALPix projection and how can I use it?
--------------------------------------------------------------------------------
.. figure::
../images/rhealpix.png
:scale: 40%
:align: left
The HEALPix projection is area preserving and can be used with a
spherical and ellipsoidal model. It was initially developed for mapping cosmic
background microwave radiation. The image below is the graphical
representation of the mapping and consists of eight isomorphic triangular
interrupted map graticules. The north and south contains four in which
straight meridians converge polewards to a point and unequally spaced
horizontal parallels. HEALPix provides a mapping in which points of equal
latitude and equally spaced longitude are mapped to points of equal latitude
and equally spaced longitude with the module of the polar interruptions. ||
To run a forward HEALPix projection on a unit sphere model, use the following command:
::
proj +proj=healpix +lon_0=0 +a=1 -E <<EOF
0 0
EOF
Output of the above command.
::
0 0 0.00 0.00
What is the rHEALPix projection and how can I use it?
--------------------------------------------------------------------------------
.. figure::
../images/healpix.png
:scale: 40%
:align: left
rHEALPix is a projection based on the HEALPix projection. The implementation
of rHEALPix uses the HEALPix projection. The rHEALPix combines the peaks of
the HEALPix into a square. The square's position can be translated and rotated
across the x-axis which is a novel approach for the rHEALPix projection. The
initial intention of using rHEALPix in the Spatial Computation Engine Science
Collaboration Environment (SCENZGrid).
To run a inverse rHEALPix projection on a WGS84 ellipsoidal model, use the following command:
::
proj +proj=rhealpix -f '%.2f' -I +lon_0=0 +a=1 +ellps=WGS84 +npole=0 +spole=0 -E <<EOF
0 0.7853981633974483
EOF
Where spole and npole are integers from the range of 0 to 3 inclusive and represent the positions of the north polar and south polar squares.
Output of above command:
::
0 0.7853981633974483 0.00 41.94
What options does PROJ allow for the shape of the Earth (geodesy)?
--------------------------------------------------------------------------------
See https://github.com/OSGeo/proj.4/blob/master/src/pj_ellps.c
See https://github.com/OSGeo/proj.4/blob/5.2/src/pj_ellps.c
for possible ellipse options. For example, putting ``+ellps=WGS84`` uses
the ``WGS84`` Earth shape.
What if I want a spherical Earth?
--------------------------------------------------------------------------------
Use ``+ellps=sphere``. See https://github.com/OSGeo/proj.4/blob/master/src/pj_ellps.c
Use ``+ellps=sphere``. See https://github.com/OSGeo/proj.4/blob/5.2/src/pj_ellps.c
for the radius used in this case.
How do I change the radius of the Earth? How do I use PROJ for work on Mars?
-5
View File
@@ -45,8 +45,3 @@ PROJ
You can download the source code for PROJ on the :ref:`download section<download>`
and find links to prepackaged executables in the
:ref:`installation section<install>`.
In addition to this website the PROJ documentation is also available in `PDF`_
form.
.. _`PDF`: https://raw.githubusercontent.com/OSGeo/proj.4/gh-pages/proj.pdf
+1 -1
View File
@@ -32,7 +32,7 @@ Docker
A `Docker`_ image with just PROJ binaries and a full compliment of grid shift
files is available on `DockerHub`_. Get the package with::
docker pull osgeo/proj.4
docker pull osgeo/proj
.. _`Docker`: https://docker.org
.. _`DockerHub`: https://hub.docker.com/r/osgeo/proj.4/
+2 -2
View File
@@ -69,8 +69,8 @@ E/W axis (``x``) as the sweep-angle axis, and the N/S (``y``) as the fixed-angle
The sweep argument is used to tell PROJ which on which axis the outer-gimbal
is rotating. The possible values are x or y, y being the default. Thus, the
scanning geometry of the Meteosat series satellite should take sweep as x, and
GOES should take sweep as y.
scanning geometry of the Meteosat series satellite should take sweep as y, and
GOES should take sweep as x.
Parameters
################################################################################
+1 -1
View File
@@ -92,7 +92,7 @@ Parameters
Mathematical definition
#######################
The formulas describing the Transverse Mercator are all taken from Evenden's [Evenden2005]_.
The formulas describing the Transverse Mercator are all taken from :cite:`Evenden2005`.
:math:`\phi_0` is the latitude of origin that match the center of the map. It can be set with ``+lat_0``.
+1 -1
View File
@@ -37,7 +37,7 @@ to which specific parameters, such as central meridians, have been applied.
The Earth is divided into 60 zones each generally 6° wide in longitude.
Bounding meridians are evenly divisible by 6°, and zones are
numbered from 1 to 60 proceeding east from the 180th meridian from Greenwich
with minor exceptions [Snyder1987]_.
with minor exceptions :cite:`Snyder1987`.
Usage
#####
@@ -64,7 +64,7 @@ Parameters
Mathematical definition
#######################
The formulas describing the Mercator projection are all taken from G. Evenden's libproj manuals [Evenden2005]_.
The formulas describing the Mercator projection are all taken from G. Evenden's libproj manuals :cite:`Evenden2005`.
Forward projection
==================
@@ -180,7 +180,7 @@ Parameters
.. option:: +t_obs=<value>
Observation time of coordinate(s) given in decicalyear. Mostly useful
Observation time of coordinate(s) given in decimalyear. Mostly useful
in 2D and 3D transformations where the observation time is not passed
as part of the input coordinate. Can be used to override the observation
time from the input coordinate.
@@ -0,0 +1,213 @@
.. _horner:
================================================================================
Horner polynomial evaluation
================================================================================
.. versionadded:: 5.0.0
+-----------------+-------------------------------------------------------------------+
| **Alias** | horner |
+-----------------+-------------------------------------------------------------------+
| **Domain** | 2D and 3D |
+-----------------+-------------------------------------------------------------------+
| **Input type** | Geodetic and projected coordinates |
+-----------------+-------------------------------------------------------------------+
| **Output type** | Geodetic and projected coordinates |
+-----------------+-------------------------------------------------------------------+
The Horner polynomial evaluation scheme is used for transformations between reference
frames where one or both are inhomogenous or internally distorted. This will typically
be reference frames created before the introduction of space geodetic techniques such
as GPS.
Horner polynomials, or Multiple Regression Equations as they are also known as, have
their strength in being able to create complicated mappings between coordinate
reference frames while still being lightweight in both computational cost and disk
space used.
PROJ implements two versions of the Horner evaluation scheme: Real and complex
polynomial evaluation. Below both are briefly described. For more details consult
:cite:`Ruffhead2016` and :cite:`EPSGGuidanceNumber7Part2`.
The polynomial evaluation in real number space is defined by the following equations:
.. math::
:label: real_poly
\Delta X = \sum_{i,j} u_{i,j} U^i V^j
\Delta Y = \sum_{i,j} v_{i,j} U^i V^j
where
.. math::
:label: UV
U = X_{in} - X_{origin}
V = Y_{in} - Y_{origin}
and :math:`u_{i,j}` and :math:`v_{i,j}` are coefficients that make up
the polynomial.
The final coordinates are determined as
.. math::
:label: xy_out
X_{out} = X_{in} + \Delta X
Y_{out} = Y_{in} + \Delta Y
The inverse transform is the same as the above but requires a different set of
coefficients.
Evaluation of the complex polynomials are defined by the following equations:
.. math::
:label: complex_poly
\Delta X + i \Delta Y = \sum_{j=1}^n (c_{2j-1} + i c_{2j}) (U + i V)^j
Where :math:`n` is the degree of the polynomial. :math:`U` and :math:`V` are
defined as in :eq:`UV` and the resulting coordinates are again determined
by :eq:`xy_out`.
Examples
################################################################################
Mapping between Danish TC32 and ETRS89/UTM zone 32 using polynomials in real
number space::
+proj=horner
+ellps=intl
+range=500000
+fwd_origin=877605.269066,6125810.306769
+inv_origin=877605.760036,6125811.281773
+deg=4
+fwd_v=6.1258112678e+06,9.9999971567e-01,1.5372750011e-10,5.9300860915e-15,2.2609497633e-19,4.3188227445e-05,2.8225130416e-10,7.8740007114e-16,-1.7453997279e-19,1.6877465415e-10,-1.1234649773e-14,-1.7042333358e-18,-7.9303467953e-15,-5.2906832535e-19,3.9984284847e-19
+fwd_u=8.7760574982e+05,9.9999752475e-01,2.8817299305e-10,5.5641310680e-15,-1.5544700949e-18,-4.1357045890e-05,4.2106213519e-11,2.8525551629e-14,-1.9107771273e-18,3.3615590093e-10,2.4380247154e-14,-2.0241230315e-18,1.2429019719e-15,5.3886155968e-19,-1.0167505000e-18
+inv_v=6.1258103208e+06,1.0000002826e+00,-1.5372762184e-10,-5.9304261011e-15,-2.2612705361e-19,-4.3188331419e-05,-2.8225549995e-10,-7.8529116371e-16,1.7476576773e-19,-1.6875687989e-10,1.1236475299e-14,1.7042518057e-18,7.9300735257e-15,5.2881862699e-19,-3.9990736798e-19
+inv_u=8.7760527928e+05,1.0000024735e+00,-2.8817540032e-10,-5.5627059451e-15,1.5543637570e-18,4.1357152105e-05,-4.2114813612e-11,-2.8523713454e-14,1.9109017837e-18,-3.3616407783e-10,-2.4382678126e-14,2.0245020199e-18,-1.2441377565e-15,-5.3885232238e-19,1.0167203661e-18
Mapping between Danish System Storebælt and ETRS89/UTM zone 32 using complex
polynomials::
+proj=horner
+ellps=intl
+range=500000
+fwd_origin=4.94690026817276e+05,6.13342113183056e+06
+inv_origin=6.19480258923588e+05,6.13258568148837e+06
+deg=3
+fwd_c=6.13258562111350e+06,6.19480105709997e+05,9.99378966275206e-01,-2.82153291753490e-02,-2.27089979140026e-10,-1.77019590701470e-09,1.08522286274070e-14,2.11430298751604e-15
+inv_c=6.13342118787027e+06,4.94690181709311e+05,9.99824464710368e-01,2.82279070814774e-02,7.66123542220864e-11,1.78425334628927e-09,-1.05584823306400e-14,-3.32554258683744e-15
Parameters
################################################################################
Setting up Horner polynomials requires many coefficients being explicitly
written, even for polynomials of low degree. For this reason it is recommended
to store the polynomial definitions in an :ref:`init file <init_files>` for
easier writing and reuse.
Required
-------------------------------------------------------------------------------
Below is a list of required parameters that can be set for the Horner polynomial
transformation. As stated above, the transformation takes to forms, either using
real or complex polynomials. These are divided into separate sections below.
Parameters from the two sections are mutually exclusive, that is parameters
describing real and complex polynomials can't be mixed.
.. include:: ../options/ellps.rst
.. option:: +deg=<value>
Degree of polynomial
.. option:: +fwd_origin=<northing,easting>
Coordinate of origin for the forward mapping
.. option:: +inv_origin=<northing,easting>
Coordinate of origin for the inverse mapping
Real polynomials
..............................................................................
The following parameters has to be set if the transformation consists of
polynomials in real space. Each parameter takes a comma-separated list of
coefficients. The number of coefficients is governed by the degree, :math:`d`,
of the polynomial:
.. math::
N = \frac{(d + 1)(d + 2)}{2}
.. option:: +fwd_u=<u_11,u_12,...,u_ij,..,u_mn>
Coefficients for the forward transformation i.e. latitude to northing
as described in :eq:`real_poly`.
.. option:: +fwd_v=<v_11,v_12,...,v_ij,..,v_mn>
Coefficients for the forward transformation i.e. longitude to easting
as described in :eq:`real_poly`.
.. option:: +inv_u=<u_11,u_12,...,u_ij,..,u_mn>
Coefficients for the inverse transformation i.e. latitude to northing
as described in :eq:`real_poly`.
.. option:: +inv_v=<v_11,v_12,...,v_ij,..,v_mn>
Coefficients for the inverse transformation i.e. longitude to easting
as described in :eq:`real_poly`.
Complex polynomials
..............................................................................
The following parameters has to be set if the transformation consists of
polynomials in complex space. Each parameter takes a comma-separated list of
coefficients. The number of coefficients is governed by the degree, :math:`d`,
of the polynomial:
.. math::
N = 2d + 2
.. option:: +fwd_c=<c_1,c_2,...,c_N>
Coefficients for the complex forward transformation
as described in :eq:`complex_poly`.
.. option:: +inv_c=<c_1,c_2,...,c_N>
Coefficients for the complex inverse transformation
as described in :eq:`complex_poly`.
Optional
-------------------------------------------------------------------------------
.. option:: +range=<value>
Radius of the region of validity.
.. option:: +uneg
Express latitude as southing. Only applies for complex polynomials.
.. option:: +vneg
Express longitude as westing. Only applies for complex polynomials.
Further reading
################################################################################
#. `Wikipedia <https://en.wikipedia.org/wiki/Horner%27s_method>`_
@@ -12,6 +12,7 @@ systems are based on different datums.
deformation
helmert
horner
molodensky
hgridshift
vgridshift
+22 -2
View File
@@ -82,12 +82,20 @@
Url = {http://www.calcofi.org/publications/calcofireports/v20/Vol_20_Eber___Hewitt.pdf}
}
@Manual{EPSGGuidanceNumber7Part2,
Title = {Geomatics Guidance Note 7, part 2 - Coordinate Conversions & Transformations including Formulas},
Institution = {International Association For Oil And Gas Producers},
Year = {2018},
Url = {https://www.iogp.org/bookstore/product/coordinate-conversions-and-transformation-including-formulas/}
}
@Manual{Evenden2005,
Title = {libproj4: A Comprehensive Library of Cartographic Projection Functions (Preliminary Draft)},
Author = {G. I. Evenden},
Year = {2005},
Url = {https://github.com/OSGeo/proj.4/blob/master/docs/old/libproj.pdf}
Url = {https://github.com/OSGeo/proj.4/blob/5.2/docs/old/libproj.pdf}
}
@Manual{Evenden1995,
@@ -95,7 +103,7 @@
Author = {G. I. Evenden},
Year = {1995},
Url = {https://github.com/OSGeo/proj.4/blob/master/docs/old/of90-284.pdf}
Url = {https://github.com/OSGeo/proj.4/blob/5.2/docs/old/of90-284.pdf}
}
@InProceedings{EversKnudsen2017,
@@ -189,6 +197,18 @@
Url = {https://archive.org/details/DTIC_ADA026294}
}
@article{Ruffhead2016,
author = {A. C. Ruffhead},
title = {Introduction to multiple regression equations in datum transformations and their reversibility},
journal = {Survey Review},
volume = {50},
number = {358},
pages = {82-90},
year = {2016},
publisher = {Taylor & Francis},
doi = {10.1080/00396265.2016.1244143},
}
@Book{Snyder1993,
Title = {Flattening the Earth},
Author = {J. P. Snyder},
+12 -58
View File
@@ -93,81 +93,35 @@ Non-Free Grids
Not all grid shift files have licensing that allows them to be freely
distributed, but can be obtained by users through free and legal methods.
Canada NTv2.0
................................................................................
Although NTv1 grid shifts are provided freely with PROJ, the higher-quality
NTv2.0 file needs to be downloaded from Natural Resources Canada. More info:
http://www.geod.nrcan.gc.ca/tools-outils/ntv2_e.php.
Procedure:
1. Visit the `NTv2 <http://webapp.geod.nrcan.gc.ca/geod/tools-outils/applications.php?locale=en#ntv2>`__, and register/login
2. Follow the Download NTv2 link near the bottom of the page.
3. Unzip ``ntv2_100325.zip`` (or similar), and move the grid shift file ``NTV2_0.GSB`` to the proj directory (be sure to change the name to lowercase for consistency)
e.g.: ``mv NTV2_0.GSB /usr/local/share/proj/ntv2_0.gsb``
4. Test it using:
::
cs2cs +proj=latlong +ellps=clrk66 +nadgrids=@ntv2_0.gsb +to +proj=latlong +ellps=GRS80 +datum=NAD83
-111 50
::
111d0'3.006"W 50d0'0.103"N 0.000 # correct answer
Australia
................................................................................
`Geocentric Datum of Australia AGD66/AGD84 <http://www.icsm.gov.au/gda/tech.html>`__
Canada
................................................................................
`Canadian NTv2 grid shift binary <http://open.canada.ca/data/en/dataset/b3534942-31ea-59cf-bcc3-f8dc4875081a>`__ for NAD27 <=> NAD83.
Germany
................................................................................
`German BeTA2007 DHDN GK3 => ETRS89/UTM <http://crs.bkg.bund.de/crseu/crs/descrtrans/BeTA/de_dhdn2etrs_beta.php>`__
Great Britain
................................................................................
`Great Britain's OSTN15_NTv2: OSGB 1936 => ETRS89 <https://www.ordnancesurvey.co.uk/docs/gps/OSTN15_NTv2.zip>`__
`Great Britain's OSTN02_NTv2: OSGB 1936 => ETRS89 <http://www.ordnancesurvey.co.uk/business-and-government/help-and-support/navigation-technology/os-net/ostn02-ntv2-format.html>`__
Austria
................................................................................
`Austrian Grid <http://www.bev.gv.at/portal/page?_pageid=713,2204753&_dad=portal&_schema=PORTAL>`__ for MGI
Spain
................................................................................
`Spanish grids <http://www.ign.es/ign/layoutIn/herramientas.do#DATUM>`__ for ED50.
Portugal
................................................................................
`Portuguese grids <http://www.fc.up.pt/pessoas/jagoncal/coordenadas/index.htm>`__ for ED50, Lisbon 1890, Lisbon 1937 and Datum 73
Brazil
................................................................................
`Brazilian grids <http://www.ibge.gov.br/home/geociencias/geodesia/param_transf/default_param_transf.shtm>`__ for datums Corrego Alegre 1961, Corrego Alegre 1970-72, SAD69 and SAD69(96)
Netherlands
................................................................................
`Dutch grid <https://www.kadaster.nl/web/Themas/Registraties/Rijksdriehoeksmeting/Transformatie-van-coordinaten.htm>`__ (Registration required before download)
Portugal
................................................................................
`Portuguese grids <http://www.fc.up.pt/pessoas/jagoncal/coordenadas/index.htm>`__ for ED50, Lisbon 1890, Lisbon 1937 and Datum 73
South Africa
................................................................................
`South African grid <http://eepublishers.co.za/article/datum-transformations-using-the-ntv2-grid.html>`__ (Cape to Hartebeesthoek94 or WGS84)
Netherlands
Spain
................................................................................
`Dutch grid <https://www.kadaster.nl/web/Themas/Registraties/Rijksdriehoeksmeting/Transformatie-van-coordinaten.htm>`__ (Registration required before download)
`Spanish grids <http://www.ign.es/ign/layoutIn/herramientas.do#DATUM>`__ for ED50.
+13
View File
@@ -13,6 +13,19 @@ that uses PROJ.
Behavioural changes caused by new bugs are not tracked here, as they should be
fixed in later versions of PROJ.
Version 4.6.0
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The default datum application behavior changed with the 4.6.0 release. PROJ
will now only apply a datum shift if both the source and destination coordinate
system have valid datum shift information.
The PROJ 4.6.0 Release Notes states
MAJOR: Rework :c:func:`pj_transform()` to avoid applying ellipsoid to ellipsoid
transformations as a datum shift when no datum info is available.
Version 5.0.0
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+2 -1
View File
@@ -135,6 +135,7 @@ coordinate timestamps back to GPS weeks.
cs2cs paradigm
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. _cs2cs_specific_options:
============ ==============================================================
Parameter Description
@@ -252,7 +253,7 @@ Skipping Missing Grids
The special prefix ``@`` may be prefixed to a grid to make it optional. If it
not found, the search will continue to the next grid. Normally any grid not
found will cause an error. For instance, the following would use the
``ntv2_0.gsb`` file if available (see :ref:`nonfreegrids`), otherwise it would
``ntv2_0.gsb`` file if available, otherwise it would
fallback to using the ``ntv1_can.dat`` file.
::
+2
View File
@@ -105,6 +105,8 @@ PJ *pj_latlong_from_proj( PJ *pj_in )
{
char* ptr = defn+strlen(defn);
sprintf( ptr, " +es=%.16g", pj_in->es );
/* TODO later: use C++ ostringstream with imbue(std::locale::classic()) */
/* to be locale unaware */
for(; *ptr; ptr++)
{
if( *ptr == ',' )
+11
View File
@@ -519,6 +519,17 @@ Returns 1 on success, 0 on failure
if (P->is_geocent || P->helmert || do_cart) {
char def[150];
sprintf (def, "break_cs2cs_recursion proj=cart a=%40.20g es=%40.20g", P->a_orig, P->es_orig);
{
/* In case the current locale does not use dot but comma as decimal */
/* separator, replace it with dot, so that proj_atof() behaves */
/* correctly. */
/* TODO later: use C++ ostringstream with imbue(std::locale::classic()) */
/* to be locale unaware */
char* next_pos;
for (next_pos = def; (next_pos = strchr (next_pos, ',')) != NULL; next_pos++) {
*next_pos = '.';
}
}
Q = proj_create (P->ctx, def);
if (0==Q)
return 0;
-11
View File
@@ -6,14 +6,3 @@ set -e
coveralls --extension .c --exclude build_autoconf --exclude build_cmake
echo "$TRAVIS_SECURE_ENV_VARS"
./travis/build_docs.sh
if test "$TRAVIS_SECURE_ENV_VARS" = "true" -a "$TRAVIS_BRANCH" = "master"; then
echo "publish website";
./travis/add_deploy_key.sh;
./travis/deploy_website.sh $TRAVIS_BUILD_DIR/docs/build /tmp;
# Disabled: see discussion of https://github.com/OSGeo/proj.4/pull/1035
# if test "$BUILD_NAME" = "linux_gcc"; then
# ./scripts/gen_html_coverage.sh
# ./travis/deploy_html_coverage.sh
# fi
fi