Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d34c46aee | ||
|
|
8e505f30fe | ||
|
|
0c2312a1fe | ||
|
|
b9e7ba6e23 |
+5
-1
@@ -1,4 +1,6 @@
|
||||
*~
|
||||
*.bak
|
||||
*.pyc
|
||||
build.local.bat
|
||||
build.local.sh
|
||||
Makefile
|
||||
@@ -36,9 +38,11 @@ README
|
||||
/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.1 -- 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
|
||||
- gcc
|
||||
|
||||
formats:
|
||||
- pdf
|
||||
- epub
|
||||
|
||||
conda:
|
||||
environment: docs/environment.yml
|
||||
|
||||
sphinx:
|
||||
configuration: docs/source/conf.py
|
||||
fail_on_warning: true
|
||||
@@ -0,0 +1,13 @@
|
||||
name: proj
|
||||
channels:
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- descartes
|
||||
- geojson
|
||||
- matplotlib
|
||||
- shapely < 1.8
|
||||
- pip
|
||||
- pip:
|
||||
- Jinja2 < 3.1
|
||||
- sphinx < 3
|
||||
- sphinx-rtd-theme < 1.0
|
||||
Regular → Executable
+130
-65
@@ -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'
|
||||
@@ -85,7 +89,7 @@ def interp_coords(coords, tol):
|
||||
|
||||
The function tries to densify a list of coordinates based on a simple measure.
|
||||
If two adjacent points in the input coordinate list are further away from each
|
||||
other than the specified tolerance, the list will be densied between those two
|
||||
other than the specified tolerance, the list will be densified between those two
|
||||
points. Roughly speaking, a point will be inserted every `tol` between the
|
||||
points.
|
||||
|
||||
@@ -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.
|
||||
'''
|
||||
fig, axes = plt.subplots()
|
||||
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,60 +323,77 @@ 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')
|
||||
# ... and additionally switch off the visibility of the axis lines and
|
||||
# labels so they can be removed by "bbox_inches='tight'" when saving
|
||||
axes.get_xaxis().set_visible(False)
|
||||
axes.get_yaxis().set_visible(False)
|
||||
|
||||
axes.axis('off')
|
||||
font = {
|
||||
'family': 'serif',
|
||||
'color': 'black',
|
||||
'style': 'italic',
|
||||
'size': 12
|
||||
}
|
||||
fig.suptitle(plotdef['projstring'], fontdict=font)
|
||||
|
||||
axes.autoscale(tight=True)
|
||||
if not os.path.exists(outdir):
|
||||
os.makedirs(outdir)
|
||||
fig.savefig(outdir + '/' + plotdef['filename'], dpi=300)
|
||||
# Make sure the plot is not stretched
|
||||
axes.set_aspect('equal')
|
||||
|
||||
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')
|
||||
|
||||
# Clean up
|
||||
fig = None
|
||||
del fig
|
||||
axes = None
|
||||
del axes
|
||||
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
|
||||
@@ -351,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
|
||||
+17
-12
@@ -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
|
||||
@@ -55,28 +54,26 @@ 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.0.1'
|
||||
version = '5.1'
|
||||
|
||||
# use same |release| as |version|
|
||||
release = version
|
||||
release = '5.1.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 = 'June 2018'
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
@@ -152,10 +149,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.1/docs/source/',
|
||||
}
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
@@ -228,6 +231,8 @@ preamble = r"""
|
||||
\ifdefined\DeclareUnicodeCharacter
|
||||
\DeclareUnicodeCharacter{2032}{$'$}% prime
|
||||
\fi
|
||||
|
||||
\usepackage[notbib,notindex]{tocbibind}
|
||||
"""
|
||||
|
||||
latex_elements = {
|
||||
@@ -239,7 +244,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',
|
||||
|
||||
@@ -13,16 +13,16 @@ distribution of the source code and various resource files archives. See
|
||||
Current Release
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
* **2018-04-01** `proj-5.0.1.tar.gz`_ (`md5`_)
|
||||
* **2018-06-01** `proj-5.1.0.tar.gz`_ (`md5`_)
|
||||
* **2018-03-01** `proj-datumgrid-1.7.zip`_
|
||||
* **2018-03-01** `proj-datumgrid-europe-1.0.zip`_
|
||||
* **2018-03-01** `proj-datumgrid-north-america-1.0.zip`_
|
||||
* **2018-03-01** `proj-datumgrid-oceania-1.0.zip`_
|
||||
* **PDF Manual** `proj.pdf`_
|
||||
|
||||
Past Releases
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
* **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`_
|
||||
@@ -30,6 +30,7 @@ Past Releases
|
||||
|
||||
* **2016-09-11** `proj-datumgrid-1.6.zip`_
|
||||
|
||||
.. _`proj-5.1.0.tar.gz`: http://download.osgeo.org/proj/proj-5.1.0.tar.gz
|
||||
.. _`proj-5.0.1.tar.gz`: http://download.osgeo.org/proj/proj-5.0.1.tar.gz
|
||||
.. _`proj-5.0.0.tar.gz`: http://download.osgeo.org/proj/proj-5.0.0.tar.gz
|
||||
.. _`proj-4.9.1.tar.gz`: http://download.osgeo.org/proj/proj-4.9.1.tar.gz
|
||||
@@ -40,5 +41,4 @@ Past Releases
|
||||
.. _`proj-datumgrid-europe-1.0.zip`: http://download.osgeo.org/proj/proj-datumgrid-europe-1.0.zip
|
||||
.. _`proj-datumgrid-north-america-1.0.zip`: http://download.osgeo.org/proj/proj-datumgrid-north-america-1.0.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.0.1.tar.gz.md5
|
||||
.. _`proj.pdf`: https://raw.githubusercontent.com/OSGeo/proj.4/gh-pages/proj.pdf
|
||||
.. _`md5`: http://download.osgeo.org/proj/proj-5.1.0.tar.gz.md5
|
||||
|
||||
+2
-2
@@ -307,14 +307,14 @@ Output of above command:
|
||||
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.1/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.1/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?
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
.. [Evenden1995] G. I. Evenden, 1995,
|
||||
`Cartograpic Projection Procedures for the UNIX Environment -
|
||||
A User's Manual
|
||||
<https://github.com/OSGeo/proj.4/blob/master/docs/old/proj_4_3_12.pdf>`_.
|
||||
<https://github.com/OSGeo/proj.4/blob/5.1/docs/old/proj_4_3_12.pdf>`_.
|
||||
|
||||
.. [Evenden2005] G. I. Evenden, 2005,
|
||||
`libproj4: A Comprehensive Library of Cartographic Projection Functions
|
||||
(Preliminary Draft)
|
||||
<https://github.com/OSGeo/proj.4/blob/master/docs/old/libproj.pdf>`_.
|
||||
<https://github.com/OSGeo/proj.4/blob/5.1/docs/old/libproj.pdf>`_.
|
||||
|
||||
.. [EversKnudsen2017] K. Evers and T. Knudsen, 2017,
|
||||
`Transformation pipelines for PROJ.4
|
||||
|
||||
@@ -21,7 +21,7 @@ Longitude wrapping when using custom central meridian
|
||||
|
||||
By default PROJ wraps output longitudes in the range -180 to 180. Previous to
|
||||
PROJ 5, this was handled incorrectly when a custom central meridian was set with
|
||||
:option:`+lon`. This caused a change in sign on the resulting easting as seen
|
||||
:option:`+lon_0`. This caused a change in sign on the resulting easting as seen
|
||||
below::
|
||||
|
||||
$ proj +proj=merc +lon_0=110
|
||||
@@ -43,5 +43,5 @@ The change is made on the basis that :math:`\lambda=290^{\circ}` is a full
|
||||
rotation of the circle larger than :math:`\lambda=-70^{\circ}` and hence
|
||||
should return the same output for both.
|
||||
|
||||
Adding the :option:`+over` flag to the projection definition provides
|
||||
Adding the ``+over`` flag to the projection definition provides
|
||||
the old behaviour.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
./travis/before_install.sh
|
||||
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y cppcheck
|
||||
|
||||
set -e
|
||||
|
||||
Reference in New Issue
Block a user