Skip to content
Commits on Source (5)
dist: trusty
language: python
sudo: false
cache:
directories:
- $GDALINST
- ~/.cache/pip
python:
- "2.7"
- "3.6"
env:
global:
- PIP_WHEEL_DIR=$HOME/.cache/pip/wheels
- PIP_FIND_LINKS=file://$HOME/.cache/pip/wheels
- GDALINST=$HOME/gdalinstall
- GDALBUILD=$HOME/gdalbuild
- PROJINST=$HOME/gdalinstall
- PROJBUILD=$HOME/projbuild
matrix:
- GDALVERSION="1.11.5"
- GDALVERSION="2.0.3"
- GDALVERSION="2.1.4"
- GDALVERSION="2.2.4"
- GDALVERSION="2.3.3"
- GDALVERSION="2.4.1"
- GDALVERSION="3.0.0"
- GDALVERSION="master"
- GDALVERSION="1.11.5" PROJVERSION="4.8.0"
- GDALVERSION="2.0.3" PROJVERSION="4.9.3"
- GDALVERSION="2.1.4" PROJVERSION="4.9.3"
- GDALVERSION="2.2.4" PROJVERSION="4.9.3"
- GDALVERSION="2.3.3" PROJVERSION="4.9.3"
- GDALVERSION="2.4.2" PROJVERSION="4.9.3"
- GDALVERSION="3.0.1" PROJVERSION="6.1.1"
- GDALVERSION="master" PROJVERSION="6.1.1"
matrix:
allow_failures:
- env: GDALVERSION="3.0.0"
- env: GDALVERSION="master"
- env: GDALVERSION="master" PROJVERSION="6.1.1"
addons:
apt:
packages:
- gdal-bin
- libproj-dev
- libhdf5-serial-dev
- libgdal-dev
- libatlas-dev
- libatlas-base-dev
- gfortran
python:
- "2.7"
- "3.6"
before_script: # configure a headless display to test matplotlib
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- "sleep 3"
before_install:
- python -m pip install -U pip
- python -m pip install wheel
- travis_wait 20 bash ./scripts/travis_gdal_install.sh
- export PATH=$GDALINST/gdal-$GDALVERSION/bin:$PATH
- export LD_LIBRARY_PATH=$GDALINST/gdal-$GDALVERSION/lib:$LD_LIBRARY_PATH
- . ./scripts/travis_proj_install.sh
- travis_wait 20 . ./scripts/travis_gdal_install.sh
- export GDAL_DATA=$GDALINST/gdal-$GDALVERSION/share/gdal
- export PROJ_LIB=$GDALINST/gdal-$GDALVERSION/share/proj
install:
- "if [ \"$GDALVERSION\" == \"master\" -o $(gdal-config --version) == \"$GDALVERSION\" ]; then echo \"Using gdal $GDALVERSION\"; else echo \"NOT using gdal $GDALVERSION as expected; aborting\"; exit 1; fi"
- "python -m pip wheel -r requirements-dev.txt"
......@@ -57,8 +56,20 @@ install:
- "rio --version"
- "rio --gdal-version"
- "python -m pip list"
before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- "sleep 3"
script:
- "if [[ $TRAVIS_PYTHON_VERSION == 3.5 && $GDALVERSION == 2.1.0 ]]; then python -m pytest --doctest-ignore-import-errors --doctest-glob='*.rst' docs/*.rst -k 'not index and not quickstart and not switch' ; fi"
- python -m pytest -m "not wheel" -rxXs --cov rasterio --cov-report term-missing
- python -m pytest -v -m "not wheel" -rxXs --cov rasterio --cov-report term-missing
after_success:
- coveralls || echo "!! intermittent coveralls failure"
cache:
directories:
- $GDALINST
- ~/.cache/pip
Changes
=======
1.0.25 (2019-08-06)
-------------------
- In `features.rasterize()`, a shape with an associated value of `None` is now
burned in using the function's `fill` value and no longer triggers a
`TypeError` (#1738).
- Instances of pytest's tmp_path fixture in tests/test_dataset.py have been
replaced by instances of the older style tmpdir fixture (#1697).
- Add support for using GDAL 3.x and PROJ 6 libraries (#1700, #1729). Please
note that new features of GDAL 3 and PROJ 6 are not intended to surface.
Geometries and coordinates returned from rasterio keep to the traditional GIS
axis order used by GDAL versions < 3. To do this, rasterio applies a new
private extension function named osr_set_traditional_axis_mapping_strategy to
every OGRSpatialReferenceH object that will be returned from methods in the
_CRS module. Please also note that the binary wheels uploaded to PyPI for
1.0.25 will include GDAL 2.4, *not* GDAL 3.0.
- We were using pytest incorrectly and pytest 5 caught us doing it. This is
now fixed in commit b9f34ee.
- A bug preventing creation of Env instances, and thus dataset opening, when
AWS credentials exist in the environment but boto3 is unavailable has been
fixed (#1708).
1.0.24 (2019-06-05)
-------------------
......
exclude *.rst *.txt *.py
include CHANGES.txt AUTHORS.txt LICENSE.txt VERSION.txt README.rst setup.py
include CHANGES.txt AUTHORS.txt LICENSE.txt VERSION.txt README.rst setup.py pyproject.toml
include rasterio/*.c rasterio/*.cpp
exclude rasterio/_shim.c
recursive-include examples *.py
......
rasterio (1.0.25-1) unstable; urgency=medium
* Team upload.
* New upstream release.
* Refresh patches.
-- Bas Couwenberg <sebastic@debian.org> Wed, 07 Aug 2019 06:06:20 +0200
rasterio (1.0.24-3) unstable; urgency=medium
* Team upload.
......
......@@ -9,7 +9,7 @@ There is already another package providing a binary "rio".
--- a/setup.py
+++ b/setup.py
@@ -385,7 +385,7 @@ setup_args = dict(
@@ -396,7 +396,7 @@ setup_args = dict(
packages=['rasterio', 'rasterio.rio'],
entry_points='''
[console_scripts]
......
......@@ -133,7 +133,7 @@ Forwarded: https://github.com/mapbox/rasterio/pull/1695
# Conditionally copy the GDAL data. To be used in conjunction with
# the bdist_wheel command to make self-contained binary wheels.
@@ -240,13 +244,14 @@ if os.environ.get('CYTHON_COVERAGE'):
@@ -246,13 +250,14 @@ if os.environ.get('CYTHON_COVERAGE'):
log.debug('ext_options:\n%s', pprint.pformat(ext_options))
......
......@@ -259,17 +259,17 @@ write. The last 3 are optional.
In this example the coordinate reference system will be ``'+proj=latlong'``, which
describes an equirectangular coordinate reference system with units of decimal
degrees. The right affine transformation matrix can be computed using
:func:`~rasterio.transform.from_origin`.
degrees. The proper affine transformation matrix can be computed from the matrix
product of a translation and a scaling.
.. code-block:: pycon
>>> from rasterio.transform import from_origin
>>> from rasterio.transform import Affine
>>> res = (x[-1] - x[0]) / 240.0
>>> transform = from_origin(x[0] - res / 2, y[-1] + res / 2, res, res)
>>> transform = Affine.translation(x[0] - res / 2, y[0] - res / 2) * Affine.scale(res, res)
>>> transform
Affine(0.033333333333333333, 0.0, -4.0166666666666666,
0.0, -0.033333333333333333, 3.0166666666666666)
0.0, 0.033333333333333333, -3.0166666666666666)
The upper left point in the example grid is at 3 degrees west and 2 degrees
north. The raster pixel centered on this grid point extends ``res / 2``, or
......
......@@ -42,7 +42,7 @@ import rasterio.path
__all__ = ['band', 'open', 'pad', 'Env']
__version__ = "1.0.24"
__version__ = "1.0.25"
__gdal_version__ = gdal_version()
# Rasterio attaches NullHandler to the 'rasterio' logger and its
......
......@@ -15,7 +15,7 @@ from rasterio._err import (
GDALError, CPLE_BaseError, CPLE_IllegalArgError, CPLE_OpenFailedError,
CPLE_NotSupportedError)
from rasterio._err cimport exc_wrap_pointer, exc_wrap_int
from rasterio._shim cimport open_dataset
from rasterio._shim cimport open_dataset, osr_get_name, osr_set_traditional_axis_mapping_strategy
from rasterio.compat import string_types
from rasterio.control import GroundControlPoint
......@@ -1317,12 +1317,14 @@ cdef OGRSpatialReferenceH _osr_from_crs(object crs) except NULL:
if retval:
_safe_osr_release(osr)
raise CRSError("Invalid CRS: {!r}".format(crs))
exc_wrap_int(OSRMorphFromESRI(osr))
except CPLE_BaseError as exc:
_safe_osr_release(osr)
raise CRSError(str(exc))
return osr
else:
if not gdal_version().startswith("3"):
exc_wrap_int(OSRMorphFromESRI(osr))
osr_set_traditional_axis_mapping_strategy(osr)
return osr
cdef _safe_osr_release(OGRSpatialReferenceH srs):
......
......@@ -11,11 +11,23 @@ from rasterio.errors import CRSError
from rasterio._base cimport _osr_from_crs as osr_from_crs
from rasterio._base cimport _safe_osr_release
from rasterio._err cimport exc_wrap_ogrerr, exc_wrap_int, exc_wrap_pointer
from rasterio._shim cimport osr_get_name, osr_set_traditional_axis_mapping_strategy
log = logging.getLogger(__name__)
cdef int OAMS_TRADITIONAL_GIS_ORDER = 0
def gdal_version():
"""Return the version as a major.minor.patchlevel string."""
cdef char *info_c = NULL
info_c = GDALVersionInfo("RELEASE_NAME")
info_b = info_c
return info_b.decode("utf-8")
cdef class _CRS(object):
"""Cython extension class"""
......@@ -112,20 +124,23 @@ cdef class _CRS(object):
cdef char *conv_wkt = NULL
try:
if morph_to_esri_dialect:
exc_wrap_ogrerr(OSRMorphToESRI(self._osr))
exc_wrap_ogrerr(OSRExportToWkt(self._osr, &conv_wkt))
if osr_get_name(self._osr) != NULL:
if morph_to_esri_dialect and not gdal_version().startswith("3"):
exc_wrap_ogrerr(OSRMorphToESRI(self._osr))
exc_wrap_ogrerr(OSRExportToWkt(self._osr, &conv_wkt))
except CPLE_BaseError as exc:
raise CRSError("Cannot convert to WKT. {}".format(exc))
else:
return conv_wkt.decode('utf-8')
if conv_wkt != NULL:
return conv_wkt.decode('utf-8')
else:
return ''
finally:
CPLFree(conv_wkt)
def to_epsg(self):
"""The epsg code of the CRS
......@@ -180,6 +195,7 @@ cdef class _CRS(object):
except CPLE_BaseError as exc:
raise CRSError("The EPSG code is unknown. {}".format(exc))
else:
osr_set_traditional_axis_mapping_strategy(obj._osr)
return obj
@staticmethod
......@@ -215,6 +231,7 @@ cdef class _CRS(object):
except CPLE_BaseError as exc:
raise CRSError("The PROJ4 dict could not be understood. {}".format(exc))
else:
osr_set_traditional_axis_mapping_strategy(obj._osr)
return obj
@staticmethod
......@@ -254,6 +271,7 @@ cdef class _CRS(object):
except CPLE_BaseError as exc:
raise CRSError("The PROJ4 dict could not be understood. {}".format(exc))
else:
osr_set_traditional_axis_mapping_strategy(obj._osr)
return obj
@staticmethod
......@@ -285,11 +303,12 @@ cdef class _CRS(object):
try:
errcode = exc_wrap_ogrerr(OSRImportFromWkt(obj._osr, &wkt_c))
if morph_from_esri_dialect:
if morph_from_esri_dialect and not gdal_version().startswith("3"):
exc_wrap_ogrerr(OSRMorphFromESRI(obj._osr))
except CPLE_BaseError as exc:
raise CRSError("The WKT could not be parsed. {}".format(exc))
else:
osr_set_traditional_axis_mapping_strategy(obj._osr)
return obj
@staticmethod
......@@ -321,11 +340,12 @@ cdef class _CRS(object):
try:
errcode = exc_wrap_ogrerr(OSRSetFromUserInput(obj._osr, text_c))
if morph_from_esri_dialect:
if morph_from_esri_dialect and not gdal_version().startswith("3"):
exc_wrap_ogrerr(OSRMorphFromESRI(obj._osr))
except CPLE_BaseError as exc:
raise CRSError("The WKT could not be parsed. {}".format(exc))
else:
osr_set_traditional_axis_mapping_strategy(obj._osr)
return obj
def to_dict(self):
......
......@@ -5,3 +5,5 @@ cdef int delete_nodata_value(GDALRasterBandH hBand) except 3
cdef int io_band(GDALRasterBandH band, int mode, float xoff, float yoff, float width, float height, object data, int resampling=*) except -1
cdef int io_multi_band(GDALDatasetH hds, int mode, float xoff, float yoff, float width, float height, object data, Py_ssize_t[:] indexes, int resampling=*) except -1
cdef int io_multi_mask(GDALDatasetH hds, int mode, float xoff, float yoff, float width, float height, object data, Py_ssize_t[:] indexes, int resampling=*) except -1
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs)
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs)
......@@ -188,3 +188,11 @@ cdef int io_multi_mask(
break
return exc_wrap_int(retval)
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs):
return ''
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
pass
......@@ -68,3 +68,11 @@ cdef GDALDatasetH open_dataset(
cdef int delete_nodata_value(GDALRasterBandH hBand) except 3:
raise NotImplementedError(
"GDAL versions < 2.1 do not support nodata deletion")
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs):
return ''
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
pass
......@@ -69,3 +69,10 @@ cdef GDALDatasetH open_dataset(
cdef int delete_nodata_value(GDALRasterBandH hBand) except 3:
return GDALDeleteRasterNoDataValue(hBand)
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs):
return ''
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
pass
"""Rasterio shims for GDAL 3.x"""
# cython: boundscheck=False
include "directives.pxi"
# The baseline GDAL API.
include "gdal.pxi"
# Shim API for GDAL >= 3.0
include "shim_rasterioex.pxi"
# Declarations and implementations specific for GDAL >= 3.x
cdef extern from "gdal.h" nogil:
cdef CPLErr GDALDeleteRasterNoDataValue(GDALRasterBandH hBand)
GDALDatasetH GDALOpenEx(const char *filename, int flags, const char **allowed_drivers, const char **options, const char **siblings) # except -1
cdef extern from "ogr_srs_api.h" nogil:
ctypedef enum OSRAxisMappingStrategy:
OAMS_TRADITIONAL_GIS_ORDER
const char* OSRGetName(OGRSpatialReferenceH hSRS)
void OSRSetAxisMappingStrategy(OGRSpatialReferenceH hSRS, OSRAxisMappingStrategy)
from rasterio._err cimport exc_wrap_pointer
cdef GDALDatasetH open_dataset(
object filename, int flags, object allowed_drivers,
object open_options, object siblings) except NULL:
"""Wrapper for GDALOpen and GDALOpenShared"""
cdef char **drivers = NULL
cdef char **options = NULL
cdef GDALDatasetH hds = NULL
cdef const char *fname = NULL
filename = filename.encode('utf-8')
fname = filename
# Construct a null terminated C list of driver
# names for GDALOpenEx.
if allowed_drivers:
for name in allowed_drivers:
name = name.encode('utf-8')
drivers = CSLAddString(drivers, <const char *>name)
for k, v in open_options.items():
k = k.upper().encode('utf-8')
# Normalize values consistent with code in _env module.
if isinstance(v, bool):
v = ('ON' if v else 'OFF').encode('utf-8')
else:
v = str(v).encode('utf-8')
options = CSLAddNameValue(options, <const char *>k, <const char *>v)
# Support for sibling files is not yet implemented.
if siblings:
raise NotImplementedError(
"Sibling files are not implemented")
# Ensure raster flags
flags = flags | 0x02
with nogil:
hds = GDALOpenEx(fname, flags, drivers, options, NULL)
try:
return exc_wrap_pointer(hds)
finally:
CSLDestroy(drivers)
CSLDestroy(options)
cdef int delete_nodata_value(GDALRasterBandH hBand) except 3:
return GDALDeleteRasterNoDataValue(hBand)
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs):
return OSRGetName(hSrs)
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
OSRSetAxisMappingStrategy(hSrs, OAMS_TRADITIONAL_GIS_ORDER)
......@@ -63,7 +63,6 @@ class CRS(collections.Mapping):
self._crs = None
if initialdata or kwargs:
data = dict(initialdata or {})
data.update(**kwargs)
data = {k: v for k, v in data.items() if k in all_proj_keys}
......
......@@ -51,6 +51,12 @@ local = ThreadEnv()
log = logging.getLogger(__name__)
try:
import boto3
except ImportError:
log.info("failed to import boto3, continuing.")
boto3 = None
class Env(object):
"""Abstraction for GDAL and AWS configuration
......@@ -182,7 +188,9 @@ class Env(object):
RasterioDeprecationWarning
)
session = AWSSession(session=session)
self.session = session
elif aws_access_key_id or profile_name or aws_unsigned:
self.session = AWSSession(
aws_access_key_id=aws_access_key_id,
......@@ -191,8 +199,15 @@ class Env(object):
region_name=region_name,
profile_name=profile_name,
aws_unsigned=aws_unsigned)
elif 'AWS_ACCESS_KEY_ID' in os.environ and 'AWS_SECRET_ACCESS_KEY' in os.environ:
self.session = AWSSession()
elif 'AWS_ACCESS_KEY_ID' in os.environ and 'AWS_SECRET_ACCESS_KEY' in os.environ and boto3 is not None:
try:
self.session = AWSSession()
self.session.credentials
except RuntimeError as exc:
log.info("No AWS session created. Credentials in environment have expired.")
self.session = DummySession()
else:
self.session = DummySession()
......@@ -234,12 +249,9 @@ class Env(object):
None
"""
if self.session.hascreds(getenv()):
pass
else:
cred_opts = self.session.get_credential_options()
self.options.update(**cred_opts)
setenv(**cred_opts)
cred_opts = self.session.get_credential_options()
self.options.update(**cred_opts)
setenv(**cred_opts)
def drivers(self):
"""Return a mapping of registered drivers."""
......@@ -348,10 +360,13 @@ def delenv():
class NullContextManager(object):
def __init__(self):
pass
def __enter__(self):
return self
def __exit__(self, *args):
pass
......
......@@ -177,9 +177,11 @@ def rasterize(
Parameters
----------
shapes : iterable of (geometry, value) pairs or iterable over
geometries. `geometry` can either be an object that implements
the geo interface or GeoJSON-like object.
shapes : iterable of (`geometry`, `value`) pairs or iterable over
geometries. The `geometry` can either be an object that
implements the geo interface or GeoJSON-like object. If no
`value` is provided the `default_value` will be used. If `value`
is `None` the `fill` value will be used.
out_shape : tuple or list with 2 integers
Shape of output numpy ndarray.
fill : int or float, optional
......@@ -197,10 +199,11 @@ def rasterize(
false, only pixels whose center is within the polygon or that
are selected by Bresenham's line algorithm will be burned in.
merge_alg : MergeAlg, optional
Merge algorithm to use. One of:
Merge algorithm to use. One of:
MergeAlg.replace (default): the new value will overwrite the
existing value.
MergeAlg.add: the new value will be added to the existing raster.
existing value.
MergeAlg.add: the new value will be added
to the existing raster.
default_value : int or float, optional
Used as value for all geometries, if not provided in `shapes`.
dtype : rasterio or numpy data type, optional
......@@ -255,6 +258,8 @@ def rasterize(
for index, item in enumerate(shapes):
if isinstance(item, (tuple, list)):
geom, value = item
if value is None:
value = fill
else:
geom = item
value = default_value
......
......@@ -9,6 +9,7 @@ from .helpers import resolve_inout
from . import options
import rasterio
from rasterio.coords import disjoint_bounds
from rasterio.crs import CRS
from rasterio.windows import Window
......@@ -83,7 +84,7 @@ def clip(ctx, files, output, bounds, like, driver, projection,
with rasterio.open(input) as src:
if bounds:
if projection == 'geographic':
bounds = transform_bounds('epsg:4326', src.crs, *bounds)
bounds = transform_bounds(CRS.from_epsg(4326), src.crs, *bounds)
if disjoint_bounds(bounds, src.bounds):
raise click.BadParameter('must overlap the extent of '
'the input raster',
......
#!/bin/sh
#!/bin/bash
#
# originally contributed by @rbuffat to Toblerity/Fiona
set -e
......@@ -41,12 +41,6 @@ GDALOPTS=" --with-geos \
--without-perl \
--without-python"
if [ "${GDALVERSION::1}" = "1" ]; then
PROJOPT="--with-static-proj4=/usr/lib";
else
PROJOPT="--with-proj";
fi
# Create build dir if not exists
if [ ! -d "$GDALBUILD" ]; then
mkdir $GDALBUILD;
......@@ -59,35 +53,61 @@ fi
ls -l $GDALINST
if [ "$GDALVERSION" = "master" ]; then
cd $GDALBUILD
git clone --depth 1 https://github.com/OSGeo/gdal gdal-$GDALVERSION
cd gdal-$GDALVERSION/gdal
git rev-parse HEAD > newrev.txt
BUILD=no
# Only build if nothing cached or if the GDAL revision changed
if test ! -f $GDALINST/gdal-$GDALVERSION/rev.txt; then
BUILD=yes
elif ! diff newrev.txt $GDALINST/gdal-$GDALVERSION/rev.txt >/dev/null; then
BUILD=yes
fi
if test "$BUILD" = "yes"; then
mkdir -p $GDALINST/gdal-$GDALVERSION
cp newrev.txt $GDALINST/gdal-$GDALVERSION/rev.txt
./configure --prefix=$GDALINST/gdal-$GDALVERSION $GDALOPTS $PROJOPT
make -s -j 2
make install
fi
fi
PROJOPT="--with-proj=$GDALINST/gdal-$GDALVERSION"
cd $GDALBUILD
git clone --depth 1 https://github.com/OSGeo/gdal gdal-$GDALVERSION
cd gdal-$GDALVERSION/gdal
git rev-parse HEAD > newrev.txt
BUILD=no
# Only build if nothing cached or if the GDAL revision changed
if test ! -f $GDALINST/gdal-$GDALVERSION/rev.txt; then
BUILD=yes
elif ! diff newrev.txt $GDALINST/gdal-$GDALVERSION/rev.txt >/dev/null; then
BUILD=yes
fi
if test "$BUILD" = "yes"; then
mkdir -p $GDALINST/gdal-$GDALVERSION
cp newrev.txt $GDALINST/gdal-$GDALVERSION/rev.txt
./configure --prefix=$GDALINST/gdal-$GDALVERSION $GDALOPTS $PROJOPT
make -s -j 2
make install
fi
else
case "$GDALVERSION" in
3*)
PROJOPT="--with-proj=$GDALINST/gdal-$GDALVERSION"
;;
2.4*)
PROJOPT="--with-proj=$GDALINST/gdal-$GDALVERSION"
;;
2.3*)
PROJOPT="--with-proj=$GDALINST/gdal-$GDALVERSION"
;;
2.2*)
PROJOPT="--with-static-proj4=$GDALINST/gdal-$GDALVERSION"
;;
2.1*)
PROJOPT="--with-static-proj4=$GDALINST/gdal-$GDALVERSION"
;;
2.0*)
PROJOPT="--with-static-proj4=$GDALINST/gdal-$GDALVERSION"
;;
1*)
PROJOPT="--with-static-proj4=$GDALINST/gdal-$GDALVERSION"
;;
esac
if [ "$GDALVERSION" != "master" -a ! -d "$GDALINST/gdal-$GDALVERSION" ]; then
cd $GDALBUILD
gdalver=$(expr "$GDALVERSION" : '\([0-9]*.[0-9]*.[0-9]*\)')
wget -q http://download.osgeo.org/gdal/$gdalver/gdal-$GDALVERSION.tar.gz
tar -xzf gdal-$GDALVERSION.tar.gz
cd gdal-$gdalver
./configure --prefix=$GDALINST/gdal-$GDALVERSION $GDALOPTS $PROJOPT
make -s -j 2
make install
if [ ! -d "$GDALINST/gdal-$GDALVERSION/share/gdal" ]; then
cd $GDALBUILD
gdalver=$(expr "$GDALVERSION" : '\([0-9]*.[0-9]*.[0-9]*\)')
wget -q http://download.osgeo.org/gdal/$gdalver/gdal-$GDALVERSION.tar.gz
tar -xzf gdal-$GDALVERSION.tar.gz
cd gdal-$gdalver
./configure --prefix=$GDALINST/gdal-$GDALVERSION $GDALOPTS $PROJOPT
make -s -j 2
make install
fi
fi
# change back to travis build dir
......