1541 {
1542 GDALDatasetH hdsSrc;
1543 GDALRasterBandH hbandSrc;
1545 uint32_t i = 0;
1546 int ntiles[2] = {1, 1};
1547 int _tile_size[2] = {0, 0};
1548 int xtile = 0;
1549 int ytile = 0;
1550 int naturalx = 1;
1551 int naturaly = 1;
1552 double gt[6] = {0.};
1553 const char* pszProjectionRef = NULL;
1554 int tilesize = 0;
1555
1557 uint32_t numbands = 0;
1559 char *hex;
1560 uint32_t hexlen = 0;
1561
1563
1564 hdsSrc = GDALOpenShared(config->
rt_file[idx], GA_ReadOnly);
1565 if (hdsSrc == NULL) {
1566 rterror(
_(
"convert_raster: Could not open raster: %s"), config->
rt_file[idx]);
1567 return 0;
1568 }
1569
1570 nband = GDALGetRasterCount(hdsSrc);
1571 if (!nband) {
1572 rterror(
_(
"convert_raster: No bands found in raster: %s"), config->
rt_file[idx]);
1573 GDALClose(hdsSrc);
1574 return 0;
1575 }
1576
1577
1579 if (config->
nband[i] > nband) {
1580 rterror(
_(
"convert_raster: Band %d not found in raster: %s"), config->
nband[i], config->
rt_file[idx]);
1581 GDALClose(hdsSrc);
1582 return 0;
1583 }
1584 }
1585
1586
1587 pszProjectionRef = GDALGetProjectionRef(hdsSrc);
1588 if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0') {
1589 info->
srs =
rtalloc(
sizeof(
char) * (strlen(pszProjectionRef) + 1));
1590 if (info->
srs == NULL) {
1591 rterror(
_(
"convert_raster: Could not allocate memory for storing SRS"));
1592 GDALClose(hdsSrc);
1593 return 0;
1594 }
1595 strcpy(info->
srs, pszProjectionRef);
1596
1598 OGRSpatialReferenceH hSRS = OSRNewSpatialReference(NULL);
1599 if (OSRSetFromUserInput(hSRS, pszProjectionRef) == OGRERR_NONE) {
1600 const char* pszAuthorityName = OSRGetAuthorityName(hSRS, NULL);
1601 const char* pszAuthorityCode = OSRGetAuthorityCode(hSRS, NULL);
1602 if (
1603 pszAuthorityName != NULL &&
1604 strcmp(pszAuthorityName, "EPSG") == 0 &&
1605 pszAuthorityCode != NULL
1606 ) {
1607 info->
srid = atoi(pszAuthorityCode);
1608 }
1609 }
1610 OSRDestroySpatialReference(hSRS);
1611 }
1612 }
1613
1615 rterror(
_(
"convert_raster: could not determine source srid, cannot transform to target srid %d"), config->
out_srid);
1616 GDALClose(hdsSrc);
1617 return 0;
1618 }
1619
1620
1621 if (GDALGetGeoTransform(hdsSrc, info->
gt) != CE_None) {
1622 rtinfo(
_(
"Using default geotransform matrix (0, 1, 0, 0, 0, -1) for raster: %s"), config->
rt_file[idx]);
1629 }
1630 memcpy(gt, info->
gt,
sizeof(
double) * 6);
1631
1632
1633
1637 if (info->
nband == NULL) {
1638 rterror(
_(
"convert_raster: Could not allocate memory for storing band indices"));
1639 GDALClose(hdsSrc);
1640 return 0;
1641 }
1643 }
1644
1645 else {
1648 if (info->
nband == NULL) {
1649 rterror(
_(
"convert_raster: Could not allocate memory for storing band indices"));
1650 GDALClose(hdsSrc);
1651 return 0;
1652 }
1654 info->
nband[i] = i + 1;
1655 }
1656
1657
1660 rterror(
_(
"convert_raster: Could not allocate memory for storing GDAL data type"));
1661 GDALClose(hdsSrc);
1662 return 0;
1663 }
1666 rterror(
_(
"convert_raster: Could not allocate memory for storing pixel type"));
1667 GDALClose(hdsSrc);
1668 return 0;
1669 }
1672 rterror(
_(
"convert_raster: Could not allocate memory for storing hasnodata flag"));
1673 GDALClose(hdsSrc);
1674 return 0;
1675 }
1678 rterror(
_(
"convert_raster: Could not allocate memory for storing nodata value"));
1679 GDALClose(hdsSrc);
1680 return 0;
1681 }
1686
1687
1688 info->
dim[0] = GDALGetRasterXSize(hdsSrc);
1689 info->
dim[1] = GDALGetRasterYSize(hdsSrc);
1690
1691 tilesize = 0;
1692
1693
1695 hbandSrc = GDALGetRasterBand(hdsSrc, info->
nband[i]);
1696
1697
1698 info->
gdalbandtype[i] = GDALGetRasterDataType(hbandSrc);
1699
1700
1702 rterror(
_(
"convert_raster: The pixel type of band %d is a complex data type. PostGIS raster does not support complex data types"), i + 1);
1703 GDALClose(hdsSrc);
1704 return 0;
1705 }
1706 GDALGetBlockSize(hbandSrc, &naturalx, &naturaly);
1707
1708
1710
1711
1714
1718 }
1719 else
1721 }
1722
1723
1725 }
1726
1727
1729 {
1730 calc_tile_size((naturalx > 1) ? (uint32_t)naturalx : info->dim[0],
1731 (naturaly > 1) ? (uint32_t)naturaly : info->dim[1],
1732 &(config->tile_size[0]),
1733 &(config->tile_size[1]));
1734
1736 }
1737
1738
1741 else
1745 else
1747
1748
1753
1754
1756
1757
1758 tilesize *= 1.1;
1760 rtwarn(
_(
"The size of each output tile may exceed 1 GB. Use -t to specify a reasonable tile size"));
1761
1762
1763 if (config->
outdb) {
1764 GDALClose(hdsSrc);
1765
1766
1767 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1768
1769 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1770 _tile_size[1] = info->
dim[1] - (ytile * info->
tile_size[1]);
1771 else
1773
1774 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1776
1777
1778 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1779 _tile_size[0] = info->
dim[0] - (xtile * info->
tile_size[0]);
1780 else
1782
1783
1784 GDALApplyGeoTransform(
1787 &(gt[0]), &(gt[3])
1788 );
1789
1790
1792 if (rast == NULL) {
1793 rterror(
_(
"convert_raster: Could not create raster"));
1794 return 0;
1795 }
1796
1797
1800
1801
1804 _tile_size[0], _tile_size[1],
1809 );
1810 if (band == NULL) {
1811 rterror(
_(
"convert_raster: Could not create offline band"));
1813 return 0;
1814 }
1815
1816
1818 rterror(
_(
"convert_raster: Could not add offlineband to raster"));
1821 return 0;
1822 }
1823
1824
1827 }
1828
1829
1830 if (!tile_is_nodata)
1833
1834 if (!hex && !tile_is_nodata)
1835 {
1836 rterror(
_(
"convert_raster: Could not convert PostGIS raster to hex WKB"));
1837 return 0;
1838 }
1839
1840
1841 if (!tile_is_nodata)
1843
1844
1845 if (tileset->
length > 10) {
1849 config->copy_statements, config->out_srid,
1851 )) {
1852 rterror(
_(
"convert_raster: Could not convert raster tiles into INSERT or COPY statements"));
1853 return 0;
1854 }
1855
1857 }
1858 }
1859 }
1860 }
1861
1862 else {
1863 VRTDatasetH hdsDst;
1864 VRTSourcedRasterBandH hbandDst;
1865
1866
1867 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1868
1869
1870 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1871 _tile_size[1] = info->
dim[1] - (ytile * info->
tile_size[1]);
1872 else
1874
1875 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1877
1878
1879
1880
1881
1882
1883 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1884 _tile_size[0] = info->
dim[0] - (xtile * info->
tile_size[0]);
1885 else
1887
1888
1889 GDALApplyGeoTransform(
1892 &(gt[0]), &(gt[3])
1893 );
1894
1895
1896
1897
1898
1899
1900
1901
1902 hdsDst = VRTCreate(_tile_size[0], _tile_size[1]);
1903
1904
1905
1906 GDALSetProjection(hdsDst, info->
srs);
1907 GDALSetGeoTransform(hdsDst, gt);
1908
1909
1912 hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, i + 1);
1913
1915 GDALSetRasterNoDataValue(hbandDst, info->
nodataval[i]);
1916
1917 VRTAddSimpleSource(
1918 hbandDst, GDALGetRasterBand(hdsSrc, info->
nband[i]),
1920 _tile_size[0], _tile_size[1],
1921 0, 0,
1922 _tile_size[0], _tile_size[1],
1923 "near", VRT_NODATA_UNSET
1924 );
1925 }
1926
1927
1928 VRTFlushCache(hdsDst);
1929
1930
1932 if (rast == NULL) {
1933 rterror(
_(
"convert_raster: Could not convert VRT dataset to PostGIS raster"));
1934 GDALClose(hdsDst);
1935 return 0;
1936 }
1937
1938
1940
1941
1943 for (i = 0; i < numbands; i++) {
1947 }
1948
1949
1950 if (!tile_is_nodata)
1953
1954 if (!hex && !tile_is_nodata)
1955 {
1956 rterror(
_(
"convert_raster: Could not convert PostGIS raster to hex WKB"));
1957 GDALClose(hdsDst);
1958 return 0;
1959 }
1960
1961
1962 if (!tile_is_nodata)
1964
1965 GDALClose(hdsDst);
1966
1967
1968 if (tileset->
length > 10) {
1972 config->copy_statements, config->out_srid,
1974 )) {
1975 rterror(
_(
"convert_raster: Could not convert raster tiles into INSERT or COPY statements"));
1976 GDALClose(hdsSrc);
1977 return 0;
1978 }
1979
1981 }
1982 }
1983 }
1984
1985 GDALClose(hdsSrc);
1986 }
1987
1988 return 1;
1989}
#define SRID_UNKNOWN
Unknown SRID value.
void rterror(const char *fmt,...)
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 rtinfo(const char *fmt,...)
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.
void rtwarn(const char *fmt,...)
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)
GDALDataType * gdalbandtype