Exemple #1
0
static ERL_NIF_TERM gdal_nif_tile_to_binary(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    gdal_tile_handle* ti;
    if (!enif_get_resource(env, argv[0], gdal_tile_RESOURCE, (void**)&ti)) {
        return enif_make_badarg(env);
    }

    ErlNifBinary tilefilenameBin;
    if (!enif_inspect_iolist_as_binary(env, argv[1], &tilefilenameBin) || (tilefilenameBin.size >= FILENAME_LEN)) {
        return make_error_msg(env, "filename error, maybe too long");
    }

    char rasterFormatCode[16] = "";
    if (enif_get_string(env, argv[2], rasterFormatCode, 16, ERL_NIF_LATIN1) <= 0) {
        return enif_make_badarg(env);
    }

    char tilefilename[FILENAME_LEN] = "";
    memcpy(tilefilename, tilefilenameBin.data, tilefilenameBin.size);
    DEBUG("passed tilefilename: %s\r\n", tilefilename);

    GDALDriverH hOutDriver = GDALGetDriverByName(rasterFormatCode);
    if ( ! ti->options_resampling || (strcmp("antialias", ti->options_resampling) != 0) ) {
        char vsimemFileName[128] = "";
        sprintf(vsimemFileName, "/vsimem/%s", tilefilename);
        GDALDatasetH tileBinDataset = GDALCreateCopy(hOutDriver,
                                                     vsimemFileName, ti->dstile, 
                                                     FALSE, NULL, NULL, NULL);
        vsi_l_offset binDataLength;
        int bUnlinkAndSeize = FALSE;
        GByte* binData = VSIGetMemFileBuffer(vsimemFileName, &binDataLength, bUnlinkAndSeize);
        DEBUG("vsimem: %s, bin len: %d\r\n", vsimemFileName, binDataLength);

        ERL_NIF_TERM binTerm;
        unsigned char* buf = enif_make_new_binary(env, binDataLength, &binTerm);
        memcpy(buf, binData, binDataLength);
 //       CPLFree(binData);

        GDALClose(tileBinDataset);
        return enif_make_tuple2(env, ATOM_OK, binTerm);
    }

    return make_error_msg(env, "wrong resampling");
}
Exemple #2
0
  std::size_t	SyntaxicXML::check_line(std::string& balise_start, InputIterator file, OutputIterator end) const {
    std::string	close_balise{ balise_start };
    std::size_t	i(0);

    close_balise.insert(close_balise.begin() + 1, '/');
    for (file = file + 1; file != end; ++file) {
      std::string	line{ (*file) };
      std::string	open;
      std::string	close;
      line.erase(std::remove_if(line.begin(), line.end(), 
    				[](char c) { return c == ' ' || c == '\t'; }), line.end());
      if (line == close_balise)
    	return i;
      if (!check_open_balise(line, open))
    	throw std::runtime_error{ make_error_msg("Error, ", line, " is incorrect") };
      if (!check_close_balise(line, close))
    	throw std::runtime_error{ make_error_msg("Error, ", line, " is incorrect") };
      open.insert(open.begin() + 1, '/');
      if (open != close)
    	throw std::runtime_error{ make_error_msg("Error, ", line, " is incorrect") };
      ++i;
    }
    throw std::runtime_error{ "Error, enclosing balise is missing" };
  }
Exemple #3
0
static ERL_NIF_TERM gdal_nif_is_imgfile(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary filenameBin;
    if (!enif_inspect_iolist_as_binary(env, argv[0], &filenameBin) || 
        (filenameBin.size >= FILENAME_LEN)) {
        return make_error_msg(env, "filename error, maybe too long");
    }

    char imgfilename[FILENAME_LEN] = "";
    memcpy(imgfilename, filenameBin.data, filenameBin.size);
    DEBUG("img filename: %s\r\n", imgfilename);

    GDALDatasetH hDataset = GDALOpen( imgfilename, GA_ReadOnly );
    if (hDataset == NULL) {
        return ATOM_FALSE;
    }
    else {
        GDALClose( hDataset );
        return ATOM_TRUE;
    }
}
Exemple #4
0
static ERL_NIF_TERM gdal_nif_copyout_rawtile(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    GDALDatasetH img_ds = NULL;
    gdal_img_handle* hImg = NULL;
    if (enif_get_resource(env, argv[0], gdal_img_RESOURCE, (void**)&hImg)) {
        img_ds = hImg->out_ds;
    }
    else {
        return enif_make_badarg(env);
    }
        
    bandregion r, w;
    if (!get_bandregion_from(env, argv + 1, &r) || !get_bandregion_from(env, argv + 2, &w)) {
        return enif_make_badarg(env);
    }

    gdal_rawtile_handle* hRawtile = enif_alloc_resource(gdal_rawtile_RESOURCE, sizeof(*hRawtile));
    *hRawtile = (gdal_rawtile_handle) {
        .data = NULL,
        .alpha = NULL,
        .w = w,
        .querysize = hImg->querysize,
        .tilesize = hImg->tilesize,
        .dataBandsCount = hImg->dataBandsCount,
        .tilebands = hImg->tilebands,
        .options_resampling = hImg->options_resampling
    };

    ERL_NIF_TERM res = enif_make_resource(env, hRawtile);
    enif_release_resource(hRawtile);  // hRawtile resource now only owned by "Erlang"

    // data buffer size when read from img AND write to tile 
    int bufsize = w.xsize * w.ysize;
    DEBUG("r.xoff: %d, r.yoff: %d, r.xsz: %d, r.ysz: %d\r\n", r.xoffset, r.yoffset, r.xsize, r.ysize); 
    DEBUG("w.xoff: %d, w.yoff: %d, w.xsz: %d, w.ysz: %d\r\n", w.xoffset, w.yoffset, w.xsize, w.ysize); 
    DEBUG("bandscount: %d, CPLCalloc size=%zu\r\n", 
          hImg->dataBandsCount, bufsize * hImg->dataBandsCount);
    hRawtile->data = (GByte*)CPLMalloc(bufsize * hImg->dataBandsCount * sizeof(*hRawtile->data));

    int panBandMap[hImg->dataBandsCount];
    fill_pband_list(hImg->dataBandsCount, panBandMap);
    CPLErr eErr = GDALDatasetRasterIO(img_ds, GF_Read, 
                                      r.xoffset, r.yoffset, r.xsize, r.ysize, hRawtile->data, 
                                      w.xsize, w.ysize, 
                                      GDT_Byte, hImg->dataBandsCount, panBandMap, 
                                      0, 0, 0);
    if (eErr == CE_Failure) {
        char buf[128] = "DatasetRasterIO read failed: ";
        const char* errmsg = CPLGetLastErrorMsg();
        strncat(buf, errmsg, strlen(errmsg));
        return make_error_msg(env, errmsg);
    }

    // read dataset alpha 
    hRawtile->alpha = (GByte*)CPLMalloc(bufsize * sizeof(*hRawtile->alpha));
    eErr = GDALRasterIO(hImg->alphaBand, GF_Read, 
                        r.xoffset, r.yoffset, r.xsize, r.ysize, hRawtile->alpha, 
                        w.xsize, w.ysize, 
                        GDT_Byte, 0, 0);
    if (eErr == CE_Failure) {
        char buf[128] = "DatasetRasterIO read failed: ";
        const char* errmsg = CPLGetLastErrorMsg();
        strncat(buf, errmsg, strlen(errmsg));
        return make_error_msg(env, errmsg);
    }

    return enif_make_tuple2(env, ATOM_OK, res);
}

static ERL_NIF_TERM gdal_nif_build_tile(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    gdal_rawtile_handle* hRawtile;
    if (!enif_get_resource(env, argv[0], gdal_rawtile_RESOURCE, (void**)&hRawtile)) {
        return enif_make_badarg(env);
    }

    bandregion w = hRawtile->w;
    int xoffset = w.xoffset;
    int yoffset = w.yoffset;
    int xsize = w.xsize;
    int ysize = w.ysize;
    int dataBandsCount = hRawtile->dataBandsCount;
    int tilebands = hRawtile->tilebands;
    int tilesize = hRawtile->tilesize;

    const char *options_resampling = hRawtile->options_resampling;

    GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
    GDALDatasetH dstile = GDALCreate(hMemDriver, "",
                                     tilesize, tilesize, tilebands, 
                                     GDT_Byte, NULL);
    GByte* data = hRawtile->data;
    GByte* alpha = hRawtile->alpha;

    CPLErr eErr = CE_None;
    if (hRawtile->tilesize == hRawtile->querysize) {
        eErr = write_data_and_alpha_to_raster(dstile, 
                                              xoffset, yoffset, xsize, ysize, 
                                              data, alpha, 
                                              dataBandsCount, tilebands);
        if (eErr == CE_Failure) {
            return make_error_msg(env, "write_data_and_alpha_to_raster");
        }
        // Note: For source drivers based on WaveLet compression (JPEG2000, ECW, MrSID)
        // the ReadRaster function returns high-quality raster (not ugly nearest neighbour)
        // TODO: Use directly 'near' for WaveLet files
    }
    else {
        GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
        GDALDatasetH dsquery = GDALCreate(hMemDriver, "", 
                                          hRawtile->querysize, hRawtile->querysize, hRawtile->tilebands, 
                                          GDT_Byte, NULL);
        if (dsquery == NULL) {
            return make_error_msg(env, "create dsquery");
        }

        eErr = write_data_and_alpha_to_raster(dsquery, 
                                              xoffset, yoffset, xsize, ysize, 
                                              data, alpha, 
                                              dataBandsCount, tilebands);
        if (eErr == CE_Failure) {
            GDALClose(dsquery);
            return make_error_msg(env, "write data and alpha to raster");
        }

        CPLErrorReset();
        eErr = scale_query_to_tile(dsquery, dstile, hRawtile->options_resampling);
        GDALClose(dsquery);
        if (eErr == CE_Failure) {
            return make_error_msg(env, "ScaleQueryTo_tile");
        }
    }

//    free_temp_rawdata(hRawtile);

    gdal_tile_handle* hTile = enif_alloc_resource(gdal_tile_RESOURCE, sizeof(*hTile));
    *hTile = (gdal_tile_handle) {
        .dstile = dstile,
        .options_resampling = options_resampling
    };

    ERL_NIF_TERM builtTileRes = enif_make_resource(env, hTile);
    enif_release_resource(hTile);  // hRawtile resource now only owned by "Erlang"

    return enif_make_tuple2(env, ATOM_OK, builtTileRes);
}
Exemple #5
0
// build out_ds
static ERL_NIF_TERM gdal_nif_create_warped_vrtimg(ErlNifEnv* env, int argc,
                                          const ERL_NIF_TERM argv[])
{
    ErlNifBinary filenameBin;
    if (!enif_inspect_iolist_as_binary(env, argv[0], &filenameBin) || 
        (filenameBin.size >= FILENAME_LEN)) {
        return make_error_msg(env, "filename error, maybe too long");
    }

    char imgfilename[FILENAME_LEN] = "";
    size_t name_sz = filenameBin.size;
    memcpy(imgfilename, filenameBin.data, filenameBin.size);
    DEBUG("img filename: %s\r\n", imgfilename);

    int epsg_code;
    if (!enif_get_int(env, argv[1], &epsg_code)) {
        return enif_make_badarg(env);
    }

    GDALDatasetH in_ds = GDALOpenShared(imgfilename, GA_ReadOnly);
    if (in_ds == NULL) {
        const char* msg = "It is not possible to open the input file '%s'.";
        char errstr[name_sz + strlen(msg) + 1];
        sprintf(errstr, msg, imgfilename);
        return make_error_msg(env, errstr);
    }

    gdal_img_handle* handle = enif_alloc_resource(
                                            gdal_img_RESOURCE, 
                                            sizeof(gdal_img_handle));
    memset(handle, '\0', sizeof(*handle));
    handle->in_ds = in_ds;
    handle->options_resampling = "average";
    handle->querysize = 256 * 4;
    handle->tilesize = 256;

    int rasterCount = GDALGetRasterCount(in_ds);
    if (rasterCount == 0) {
        const char* msg = "Input file '%s' has no raster band";
        char errstr[name_sz + strlen(msg) + 1];
        sprintf(errstr, msg, imgfilename);

        destroy_img_handle(handle);
        return make_error_msg(env, errstr);
    }

    GDALRasterBandH hBand = GDALGetRasterBand(in_ds, 1);
    if (GDALGetRasterColorTable(hBand) != NULL) {
        const char* msg = 
            "Please convert this file to RGB/RGBA and run gdal2tiles on the result.\n" 
            "From paletted file you can create RGBA file (temp.vrt) by:\n"
            "gdal_translate -of vrt -expand rgba %s temp.vrt\n"
            "then run this program: gdal2tiles temp.vrt";
        char errstr[name_sz + strlen(msg) + 1];
        sprintf(errstr, msg, imgfilename);

        destroy_img_handle(handle);
        return make_error_msg(env, errstr);
    }

    double padfTransform[6];
    double errTransform[6] = {0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
    GDALGetGeoTransform(in_ds, padfTransform);
    if (0 == memcmp(padfTransform, errTransform, sizeof(errTransform))
             && GDALGetGCPCount(in_ds) == 0) {
        destroy_img_handle(handle);
        return make_error_msg(env, 
                              "There is no georeference - "
                              "neither affine transformation (worldfile) nor GCPs");
    }

    const char* in_srs_wkt = GDALGetProjectionRef(in_ds);
    if (in_srs_wkt == NULL && GDALGetGCPCount(in_ds) != 0) {
        in_srs_wkt = GDALGetGCPProjection(in_ds);
    }
    char* out_srs_wkt = get_wkt_of(epsg_code);
    GDALDatasetH out_ds = GDALAutoCreateWarpedVRT(in_ds, 
                                                  in_srs_wkt, 
                                                  out_srs_wkt, 
                                                  GRA_NearestNeighbour, 
                                                  0.0, 
                                                  NULL);
    handle->out_ds = out_ds;
    OGRFree(out_srs_wkt);


    handle->alphaBand = GDALGetMaskBand(GDALGetRasterBand(handle->out_ds, 1));
    rasterCount = GDALGetRasterCount(handle->out_ds);
    unsigned int dataBandsCount;
    if (GDALGetMaskFlags(handle->alphaBand) & GMF_ALPHA || 
            rasterCount == 4 || rasterCount == 2) {
        dataBandsCount = rasterCount - 1;
    }
    else {
        dataBandsCount = rasterCount;
    }
    handle->dataBandsCount = dataBandsCount;
    handle->tilebands = dataBandsCount + 1;


    ERL_NIF_TERM imginfo = get_imginfo(env, out_ds);
    if (enif_compare(ATOM_ERROR, imginfo) == 0) {
        destroy_img_handle(handle);
        return make_error_msg(env,
                              "Georeference of the raster contains rotation or skew. "
                              "Such raster is not supported. "
                              "Please use gdalwarp first");
    }

    ERL_NIF_TERM imgref = enif_make_resource(env, handle);
    enif_release_resource(handle);

    return enif_make_tuple3(env, ATOM_OK, imgref, imginfo);
}