Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4381b96ebb | ||
|
|
de230da231 | ||
|
|
34b270a695 | ||
|
|
b285484ea3 | ||
|
|
cf1d83a4c4 | ||
|
|
f849dc37f1 | ||
|
|
166c215fc8 | ||
|
|
ec21939399 | ||
|
|
c39b6fb23c | ||
|
|
f3134c202a | ||
|
|
dfe855d66f | ||
|
|
d7cb4b7a63 | ||
|
|
6f46d55126 | ||
|
|
e07f51557c | ||
|
|
7b756576f1 | ||
|
|
f20de18ace | ||
|
|
cdb997cfaf | ||
|
|
602ada943f | ||
|
|
b31baceeb8 | ||
|
|
df8d95ab53 | ||
|
|
1f0c8867dc | ||
|
|
b693d210fa | ||
|
|
15edf4c41b | ||
|
|
0ea45a3b64 |
+3
-1
@@ -41,9 +41,11 @@ test-driver
|
||||
/DartConfiguration.tcl
|
||||
/Testing
|
||||
|
||||
# html
|
||||
# docs
|
||||
/html/dl
|
||||
/html/robots.txt
|
||||
/docs/plot/images
|
||||
/latex
|
||||
|
||||
# m4
|
||||
/m4/libtool.m4
|
||||
|
||||
@@ -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
@@ -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
@@ -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.*
|
||||
|
||||
@@ -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
@@ -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)))
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
python3 plot.py plotdefs.json images/
|
||||
Executable
+12
@@ -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/
|
||||
Executable
+9
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -12,3 +12,5 @@ the project.
|
||||
:maxdepth: 1
|
||||
|
||||
rfc-1
|
||||
rfc-2
|
||||
rfc-3
|
||||
|
||||
@@ -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.
|
||||
@@ -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
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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
|
||||
################################################################################
|
||||
|
||||
@@ -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``.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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,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
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
::
|
||||
|
||||
@@ -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 == ',' )
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user