TIDOP-USAL / tidoplib

TidopLib is an open-source C++ library developed by Tidop Research Group
http://tidop.usal.es/
GNU Lesser General Public License v3.0
1 stars 0 forks source link

Lectura y escritura de formatos raster, vector, nubes de puntos y malla #1

Open estebanrdo opened 1 week ago

estebanrdo commented 1 week ago

Actualmente tenemos la lectura de formatos vector y raster y esta prevista la inclusión de los formatos de nubes de puntos y malla.

La lectura y la escritura está en clases separadas tanto para raster como para vector:

Estas clases son interfaces (clases virtuales puras) y la implementación de los diferentes formatos se hace mediante clases derivadas privadas (se definen en el fichero c++ y no son directamente accesibles). Para poder crear instancias de estas clases privadas se utilizan las siguientes factorías:

Estas factorías reciben la ruta del fichero y se encargan de crear la instancia de la clase correspondiente. En el caso de ImageReader:

auto ImageReaderFactory::create(const Path &file) -> ImageReader::Ptr
{
    ImageReader::Ptr image_reader;

    try {

        TL_ASSERT(file.exists(), "File doesn't exist: {}", file.toString());

        std::string extension = file.extension().toString();
#ifdef TL_HAVE_GDAL
        if (gdalValidExtensions(extension)) {
            image_reader = ImageReaderGdal::New(file);
        } else
#endif
#ifdef TL_HAVE_EDSDK
        if (compareInsensitiveCase(extension, ".CR2")) {
            image_reader = ImageReaderCanon::New(file);
        } else
#endif
        {
            TL_THROW_EXCEPTION("Invalid Image Reader: {}", file.fileName().toString());
        }

    } catch (...) {
        TL_THROW_EXCEPTION_WITH_NESTED("Catched exception");
    }

    return image_reader;
}

La lectura:

auto image_reader = ImageReaderFactory::create(img);

image_reader->open();
if (image_reader->isOpen()) {

    Message::info("Number of bands: {}", image_reader->channels());
    Message::info("Color depth: {}", image_reader->depth());
    Message::info("Image dimensions: {}x{}", image_reader->cols(), image_reader->rows());

    std::shared_ptr<ImageMetadata> image_metadata = image_reader->metadata();
    std::map<std::string, std::string> metadata = image_metadata->activeMetadata();

    for (auto it = metadata.begin(); it != metadata.end(); ++it) {
        std::string name = it->first;
        std::string value = it->second;
        Message::info("  {}: {}", name, value);
    }

    image_reader->close();
}

Posibles mejoras

El código podría ser mas limpio si tuviésemos otras clases que internamente llamen a la factoría. Algo tipo a:

ImageReader image_reader(img);

// También se podría hacer
// ImageReader image_reader;
// image_reader.open();

if (image_reader.isOpen(img)) {

    Message::info("Number of bands: {}", image_reader.channels());
    Message::info("Color depth: {}", image_reader.depth());
    Message::info("Image dimensions: {}x{}", image_reader->cols(), image_reader.rows());

   //...

    image_reader.close();
}

De está forma se podría reutilizar el mismo objeto para abrir varias imágenes de forma mas sencilla (ahora hay que volver a utilizar la factoría).

DavidHernandezLopez commented 6 days ago

He replicado este patrón para el caso de las nubes de puntos. De momento sólo funciona con LAS/LAZ pero integrar cualquier otro formato leído por PDAL sería sencillo