Skip to content

Commit

Permalink
Add read-only AIVector (Artificial intelligence powered vector) driver
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed Oct 29, 2024
1 parent 6676353 commit aa68659
Show file tree
Hide file tree
Showing 11 changed files with 234 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,5 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda
TIGER -vector- (rov): U.S. Census TIGER/Line
AVCBin -vector- (rov): Arc/Info Binary Coverage
AVCE00 -vector- (rov): Arc/Info E00 (ASCII) Coverage (*.e00)
AIVector -vector- (ro): Artificial Intelligence powered vector driver
HTTP -raster,vector- (ro): HTTP Fetching Wrapper
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,5 @@ Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subda
TIGER -vector- (rov): U.S. Census TIGER/Line
AVCBin -vector- (rov): Arc/Info Binary Coverage
AVCE00 -vector- (rov): Arc/Info E00 (ASCII) Coverage (*.e00)
AIVector -vector- (ro): Artificial Intelligence powered vector driver
HTTP -raster,vector- (ro): HTTP Fetching Wrapper
33 changes: 33 additions & 0 deletions autotest/ogr/ogr_aivector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env pytest
###############################################################################
# $Id$
#
# Project: GDAL/OGR Test Suite
# Purpose: Test read functionality for OGR AIVector driver.
# Author: Even Rouault <even dot rouault at spatialys.com>
#
###############################################################################
# Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
#
# SPDX-License-Identifier: MIT
###############################################################################

import gdaltest
import pytest

pytestmark = pytest.mark.require_driver("AIVector")


def test_ogr_aivector_test_ogrsf():

import test_cli_utilities

if test_cli_utilities.get_test_ogrsf_path() is None:
pytest.skip()

ret = gdaltest.runexternal(
test_cli_utilities.get_test_ogrsf_path() + " -ro AIVector:foo.bin"
)

assert "INFO" in ret
assert "ERROR" not in ret
32 changes: 32 additions & 0 deletions doc/source/drivers/vector/aivector.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.. _vector.aivector:

Artificial intelligence powered vector driver
=============================================

.. versionadded:: 3.11

.. shortname:: AIVector

.. built_in_by_default::

This driver builds on many years of self-funded investments from the GDAL team on AI
technologies to bring you the ultimate driver that can read any vector format.
After that one, no need for any new vector driver!

The open syntax is ``AIVector:{filename}``, or directly specify the filename and
force the use of the AIVector driver with the ``-if`` flag of ogrinfo or ogr2ogr.
No options at all. Just enjoy the true power of AI.

.. note:: We are open to external investors to develop the write side of the driver.

Examples
--------

::

ogrinfo -if AIVector undocumented_proprietary_format.bin -al

.. note::

The above works even if you make a typo in the filename. The driver will
automatically figure out the filename you meant.
1 change: 1 addition & 0 deletions doc/source/drivers/vector/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Vector drivers
:hidden:

adbc
aivector
amigocloud
arrow
avcbin
Expand Down
3 changes: 3 additions & 0 deletions frmts/drivers.ini
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@ Tiger
AVCBin
AVCE00

# Last but not the least
AIVector

# End of OGR drivers

# Put here drivers that absolutely need to look for side car
Expand Down
2 changes: 2 additions & 0 deletions ogr/ogrsf_frmts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ if( NOT WORDS_BIGENDIAN )
ogr_optional_driver(miramon "MiraMonVector")
endif()

ogr_optional_driver(aivector AIVector)

# ######################################################################################################################
#
if (NOT OGR_ENABLE_DRIVER_GEOJSON_PLUGIN)
Expand Down
9 changes: 9 additions & 0 deletions ogr/ogrsf_frmts/aivector/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
add_gdal_driver(
TARGET ogr_AIVector
SOURCES
ograivectordriver.cpp
PLUGIN_CAPABLE
NO_DEPS
STRONG_CXX_WFLAGS)

gdal_standard_includes(ogr_AIVector)
146 changes: 146 additions & 0 deletions ogr/ogrsf_frmts/aivector/ograivectordriver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/******************************************************************************
*
* Project: GDAL
* Purpose: Artificial Intelligence powered driver
* Author: Even Rouault, <even dot rouault at spatialys.com>
*
******************************************************************************
* Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/

#include "ogrsf_frmts.h"

/************************************************************************/
/* OGRAIVectorIdentify() */
/************************************************************************/

static int OGRAIVectorIdentify(GDALOpenInfo *poOpenInfo)
{
return STARTS_WITH_CI(poOpenInfo->pszFilename, "AIVector:") ||
poOpenInfo->IsSingleAllowedDriver("AIVector");
}

/************************************************************************/
/* OGRAIVectorOpen() */
/************************************************************************/

static GDALDataset *OGRAIVectorOpen(GDALOpenInfo *poOpenInfo)
{
if (!OGRAIVectorIdentify(poOpenInfo))
return nullptr;

class MyLayer final : public OGRLayer,
public OGRGetNextFeatureThroughRaw<MyLayer>
{
OGRFeatureDefn *m_poLayerDefn = nullptr;
bool m_bReturnedFeature = false;

CPL_DISALLOW_COPY_ASSIGN(MyLayer)

public:
MyLayer()
{
m_poLayerDefn = new OGRFeatureDefn("result");
SetDescription(m_poLayerDefn->GetName());
m_poLayerDefn->Reference();
OGRFieldDefn oFieldDefn("name", OFTString);
m_poLayerDefn->AddFieldDefn(&oFieldDefn);
OGRSpatialReference *poSRS = new OGRSpatialReference(
"GEOGCS[\"I don't know\",\n"
" DATUM[\"I don't care\",\n"
" SPHEROID[\"GRS 1980\",6378137,298.257222101,\n"
" AUTHORITY[\"EPSG\",\"7019\"]]],\n"
" PRIMEM[\"Greenwich\",0,\n"
" AUTHORITY[\"EPSG\",\"8901\"]],\n"
" UNIT[\"degree\",0.0174532925199433,\n"
" AUTHORITY[\"EPSG\",\"9122\"]],\n"
" AUTHORITY[\"AI\",\"TOTALLY_MADE_OF\"]]");
m_poLayerDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
poSRS->Release();
}

~MyLayer() override
{
m_poLayerDefn->Release();
}

void ResetReading() override
{
m_bReturnedFeature = false;
}

OGRFeatureDefn *GetLayerDefn() override
{
return m_poLayerDefn;
}
DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(MyLayer)

OGRFeature *GetNextRawFeature()
{
if (m_bReturnedFeature)
return nullptr;
m_bReturnedFeature = true;
OGRFeature *poFeature = new OGRFeature(m_poLayerDefn);
poFeature->SetFID(0);
poFeature->SetField(0, "Null Island: the place to be");
OGRPoint *poPoint = new OGRPoint(0, 0);
poPoint->assignSpatialReference(GetSpatialRef());
poFeature->SetGeometryDirectly(poPoint);
return poFeature;
}

int TestCapability(const char *) override
{
return false;
}
};

class MyDataset final : public GDALDataset
{
MyLayer m_oLayer{};

public:
MyDataset() = default;

int GetLayerCount() override
{
return 1;
}

OGRLayer *GetLayer(int idx) override
{
return idx == 0 ? &m_oLayer : nullptr;
}
};

return new MyDataset();
}

/************************************************************************/
/* RegisterOGRAIVector() */
/************************************************************************/

void RegisterOGRAIVector()
{
if (!GDAL_CHECK_VERSION("AIVector"))
return;

if (GDALGetDriverByName("AIVector") != nullptr)
return;

GDALDriver *poDriver = new GDALDriver();
poDriver->SetDescription("AIVector");
poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
"Artificial Intelligence powered vector driver");
poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC,
"drivers/vector/aivector.html");

poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, "AIVector:");

poDriver->pfnOpen = OGRAIVectorOpen;
poDriver->pfnIdentify = OGRAIVectorIdentify;
GetGDALDriverManager()->RegisterDriver(poDriver);
}
5 changes: 5 additions & 0 deletions ogr/ogrsf_frmts/generic/ogrregisterall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,9 @@ void OGRRegisterAllInternal()
RegisterOGRAVCE00();
#endif

// Last but not the least
#ifdef AIVECTOR_ENABLED
RegisterOGRAIVector();
#endif

} /* OGRRegisterAll */
1 change: 1 addition & 0 deletions ogr/ogrsf_frmts/ogrsf_frmts.h
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ void CPL_DLL RegisterOGRXODR();
void DeclareDeferredOGRXODRPlugin();
void CPL_DLL RegisterOGRADBC();
void DeclareDeferredOGRADBCPlugin();
void CPL_DLL RegisterOGRAIVector();
// @endcond

CPL_C_END
Expand Down

0 comments on commit aa68659

Please sign in to comment.