1553 {
1554 GDALDatasetH hdsSrc;
1555 GDALRasterBandH hbandSrc;
1557 uint32_t i = 0;
1558 int ntiles[2] = {1, 1};
1559 int _tile_size[2] = {0, 0};
1560 int xtile = 0;
1561 int ytile = 0;
1562 int naturalx = 1;
1563 int naturaly = 1;
1564 double gt[6] = {0.};
1565 const char* pszProjectionRef = NULL;
1566 int tilesize = 0;
1567
1569 uint32_t numbands = 0;
1571 char *hex;
1572 uint32_t hexlen = 0;
1573
1575
1576 hdsSrc = GDALOpenShared(config->
rt_file[idx], GA_ReadOnly);
1577 if (hdsSrc == NULL) {
1578 rterror(
_(
"convert_raster: Could not open raster: %s"), config->
rt_file[idx]);
1579 return 0;
1580 }
1581
1582 nband = GDALGetRasterCount(hdsSrc);
1583 if (!nband) {
1584 rterror(
_(
"convert_raster: No bands found in raster: %s"), config->
rt_file[idx]);
1585 GDALClose(hdsSrc);
1586 return 0;
1587 }
1588
1589
1591 if (config->
nband[i] > nband) {
1592 rterror(
_(
"convert_raster: Band %d not found in raster: %s"), config->
nband[i], config->
rt_file[idx]);
1593 GDALClose(hdsSrc);
1594 return 0;
1595 }
1596 }
1597
1598
1599 pszProjectionRef = GDALGetProjectionRef(hdsSrc);
1600 if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0') {
1601 info->
srs =
rtalloc(
sizeof(
char) * (strlen(pszProjectionRef) + 1));
1602 if (info->
srs == NULL) {
1603 rterror(
_(
"convert_raster: Could not allocate memory for storing SRS"));
1604 GDALClose(hdsSrc);
1605 return 0;
1606 }
1607 strcpy(info->
srs, pszProjectionRef);
1608
1610 OGRSpatialReferenceH hSRS = OSRNewSpatialReference(NULL);
1611 if (OSRSetFromUserInput(hSRS, pszProjectionRef) == OGRERR_NONE) {
1612 const char* pszAuthorityName = OSRGetAuthorityName(hSRS, NULL);
1613 const char* pszAuthorityCode = OSRGetAuthorityCode(hSRS, NULL);
1614 if (
1615 pszAuthorityName != NULL &&
1616 strcmp(pszAuthorityName, "EPSG") == 0 &&
1617 pszAuthorityCode != NULL
1618 ) {
1619 info->
srid = atoi(pszAuthorityCode);
1620 }
1621 }
1622 OSRDestroySpatialReference(hSRS);
1623 }
1624 }
1625
1627 rterror(
_(
"convert_raster: could not determine source srid, cannot transform to target srid %d"), config->
out_srid);
1628 GDALClose(hdsSrc);
1629 return 0;
1630 }
1631
1632
1633 if (GDALGetGeoTransform(hdsSrc, info->
gt) != CE_None) {
1634 rtinfo(
_(
"Using default geotransform matrix (0, 1, 0, 0, 0, -1) for raster: %s"), config->
rt_file[idx]);
1641 }
1642 memcpy(gt, info->
gt,
sizeof(
double) * 6);
1643
1644
1645
1649 if (info->
nband == NULL) {
1650 rterror(
_(
"convert_raster: Could not allocate memory for storing band indices"));
1651 GDALClose(hdsSrc);
1652 return 0;
1653 }
1655 }
1656
1657 else {
1660 if (info->
nband == NULL) {
1661 rterror(
_(
"convert_raster: Could not allocate memory for storing band indices"));
1662 GDALClose(hdsSrc);
1663 return 0;
1664 }
1666 info->
nband[i] = i + 1;
1667 }
1668
1669
1672 rterror(
_(
"convert_raster: Could not allocate memory for storing GDAL data type"));
1673 GDALClose(hdsSrc);
1674 return 0;
1675 }
1678 rterror(
_(
"convert_raster: Could not allocate memory for storing pixel type"));
1679 GDALClose(hdsSrc);
1680 return 0;
1681 }
1684 rterror(
_(
"convert_raster: Could not allocate memory for storing hasnodata flag"));
1685 GDALClose(hdsSrc);
1686 return 0;
1687 }
1690 rterror(
_(
"convert_raster: Could not allocate memory for storing nodata value"));
1691 GDALClose(hdsSrc);
1692 return 0;
1693 }
1698
1699
1700 info->
dim[0] = GDALGetRasterXSize(hdsSrc);
1701 info->
dim[1] = GDALGetRasterYSize(hdsSrc);
1702
1703 tilesize = 0;
1704
1705
1707 hbandSrc = GDALGetRasterBand(hdsSrc, info->
nband[i]);
1708
1709
1710 info->
gdalbandtype[i] = GDALGetRasterDataType(hbandSrc);
1711
1712
1714 rterror(
_(
"convert_raster: The pixel type of band %d is a complex data type. PostGIS raster does not support complex data types"), i + 1);
1715 GDALClose(hdsSrc);
1716 return 0;
1717 }
1718 GDALGetBlockSize(hbandSrc, &naturalx, &naturaly);
1719
1720
1722
1723
1726
1730 }
1731 else
1733 }
1734
1735
1737 }
1738
1739
1741 {
1742 calc_tile_size((naturalx > 1) ? (uint32_t)naturalx : info->dim[0],
1743 (naturaly > 1) ? (uint32_t)naturaly : info->dim[1],
1744 &(config->tile_size[0]),
1745 &(config->tile_size[1]));
1746
1748 }
1749
1750
1753 else
1757 else
1759
1760
1765
1766
1768
1769
1770 tilesize *= 1.1;
1772 rtwarn(
_(
"The size of each output tile may exceed 1 GB. Use -t to specify a reasonable tile size"));
1773
1774
1775 if (config->
outdb) {
1776 GDALClose(hdsSrc);
1777
1778
1779 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1780
1781 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1782 _tile_size[1] = info->
dim[1] - (ytile * info->
tile_size[1]);
1783 else
1785
1786 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1788
1789
1790 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1791 _tile_size[0] = info->
dim[0] - (xtile * info->
tile_size[0]);
1792 else
1794
1795
1796 GDALApplyGeoTransform(
1799 &(gt[0]), &(gt[3])
1800 );
1801
1802
1804 if (rast == NULL) {
1805 rterror(
_(
"convert_raster: Could not create raster"));
1806 return 0;
1807 }
1808
1809
1812
1813
1816 _tile_size[0], _tile_size[1],
1821 );
1822 if (band == NULL) {
1823 rterror(
_(
"convert_raster: Could not create offline band"));
1825 return 0;
1826 }
1827
1828
1830 rterror(
_(
"convert_raster: Could not add offlineband to raster"));
1833 return 0;
1834 }
1835
1836
1839 }
1840
1841
1842 if (!tile_is_nodata)
1845
1846 if (!hex && !tile_is_nodata)
1847 {
1848 rterror(
_(
"convert_raster: Could not convert PostGIS raster to hex WKB"));
1849 return 0;
1850 }
1851
1852
1853 if (!tile_is_nodata)
1855
1856
1861 config->copy_statements, config->out_srid,
1863 )) {
1864 rterror(
_(
"convert_raster: Could not convert raster tiles into INSERT or COPY statements"));
1865 return 0;
1866 }
1867
1869 }
1870 }
1871 }
1872 }
1873
1874 else {
1875 VRTDatasetH hdsDst;
1876 VRTSourcedRasterBandH hbandDst;
1877
1878
1879 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1880
1881
1882 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1883 _tile_size[1] = info->
dim[1] - (ytile * info->
tile_size[1]);
1884 else
1886
1887 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1889
1890
1891
1892
1893
1894
1895 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1896 _tile_size[0] = info->
dim[0] - (xtile * info->
tile_size[0]);
1897 else
1899
1900
1901 GDALApplyGeoTransform(
1904 &(gt[0]), &(gt[3])
1905 );
1906
1907
1908
1909
1910
1911
1912
1913
1914 hdsDst = VRTCreate(_tile_size[0], _tile_size[1]);
1915
1916
1917
1918 GDALSetProjection(hdsDst, info->
srs);
1919 GDALSetGeoTransform(hdsDst, gt);
1920
1921
1924 hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, i + 1);
1925
1927 GDALSetRasterNoDataValue(hbandDst, info->
nodataval[i]);
1928
1929 VRTAddSimpleSource(
1930 hbandDst, GDALGetRasterBand(hdsSrc, info->
nband[i]),
1932 _tile_size[0], _tile_size[1],
1933 0, 0,
1934 _tile_size[0], _tile_size[1],
1935 "near", VRT_NODATA_UNSET
1936 );
1937 }
1938
1939
1940 VRTFlushCache(hdsDst);
1941
1942
1944 if (rast == NULL) {
1945 rterror(
_(
"convert_raster: Could not convert VRT dataset to PostGIS raster"));
1946 GDALClose(hdsDst);
1947 return 0;
1948 }
1949
1950
1952
1953
1955 for (i = 0; i < numbands; i++) {
1959 }
1960
1961
1962 if (!tile_is_nodata)
1965
1966 if (!hex && !tile_is_nodata)
1967 {
1968 rterror(
_(
"convert_raster: Could not convert PostGIS raster to hex WKB"));
1969 GDALClose(hdsDst);
1970 return 0;
1971 }
1972
1973
1974 if (!tile_is_nodata)
1976
1977 GDALClose(hdsDst);
1978
1979
1984 config->copy_statements, config->out_srid,
1986 )) {
1987 rterror(
_(
"convert_raster: Could not convert raster tiles into INSERT or COPY statements"));
1988 GDALClose(hdsSrc);
1989 return 0;
1990 }
1991
1993 }
1994 }
1995 }
1996
1997 GDALClose(hdsSrc);
1998 }
1999
2000 return 1;
2001}
#define SRID_UNKNOWN
Unknown SRID value.
void rterror(const char *fmt,...) __attribute__((format(printf
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
rt_pixtype rt_util_gdal_datatype_to_pixtype(GDALDataType gdt)
Convert GDALDataType to rt_pixtype.
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
void void rtinfo(const char *fmt,...) __attribute__((format(printf
void void void rtwarn(const char *fmt,...) __attribute__((format(printf
int rt_raster_add_band(rt_raster raster, rt_band band, int index)
Add band data to a raster.
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
rt_raster rt_raster_from_gdal_dataset(GDALDatasetH ds)
Return a raster from a GDAL dataset.
int rt_band_check_is_nodata(rt_band band)
Returns TRUE if the band is only nodata values.
char * rt_raster_to_hexwkb(rt_raster raster, int outasin, uint32_t *hexwkbsize)
Return this raster in HEXWKB form (null-terminated hex)
void rt_band_destroy(rt_band band)
Destroy a raster band.
uint16_t rt_raster_get_num_bands(rt_raster raster)
rt_band rt_band_new_offline(uint16_t width, uint16_t height, rt_pixtype pixtype, uint32_t hasnodata, double nodataval, uint8_t bandNum, const char *path)
Create an out-db rt_band.
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Datum buffer(PG_FUNCTION_ARGS)
static void calc_tile_size(uint32_t dimX, uint32_t dimY, int *tileX, int *tileY)
static int append_stringbuffer(STRINGBUFFER *buffer, const char *str)
static void rtdealloc_stringbuffer(STRINGBUFFER *buffer, int freebuffer)
static int insert_records(const char *schema, const char *table, const char *column, const char *filename, const char *file_column_name, int copy_statements, int out_srid, STRINGBUFFER *tileset, STRINGBUFFER *buffer)
static void raster_destroy(rt_raster raster)
uint32_t max_tiles_per_copy
max tiles per copy
GDALDataType * gdalbandtype