Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit tests fail on s390x (big-endian) #451

Closed
EdwardBetts opened this issue Jun 7, 2023 · 10 comments
Closed

Unit tests fail on s390x (big-endian) #451

EdwardBetts opened this issue Jun 7, 2023 · 10 comments

Comments

@EdwardBetts
Copy link
Contributor

When building the Debian package on the s390x architecture the unit tests fail. This is probably because the s390x is big-endian. It is the only big-endian CPU architecture targetted by Debian, the rest are little-endian.

This bug has been reported to the Debian bug tracking system: https://bugs.debian.org/1034304

Here's the output from the tests:

============================= test session starts ==============================
platform linux -- Python 3.11.2, pytest-7.2.1, pluggy-1.0.0+repack
rootdir: /home/edward/geoalchemy2-0.13.3, configfile: pyproject.toml, testpaths: tests
collected 476 items / 6 deselected / 470 selected

tests/test_alembic_migrations.py ...                                     [  0%]
tests/test_functional.py ....s.....sFF..............s..                  [  7%]
tests/test_functional_postgresql.py .......F..........                   [ 10%]
tests/test_functional_sqlite.py ssssssss                                 [ 12%]
tests/test_pickle.py .                                                   [ 12%]
tests/gallery/test_decipher_raster.py .....FFFFFF                        [ 15%]
tests/gallery/test_length_at_insert.py .                                 [ 15%]
tests/gallery/test_specific_compilation.py .                             [ 15%]
tests/gallery/test_summarystatsagg.py .                                  [ 15%]
tests/gallery/test_type_decorator.py F                                   [ 15%]
tests/test_alembic_migrations.py sss                                     [ 16%]
tests/test_functional.py sssssssssssssssssssssssssssss                   [ 22%]
tests/test_functional_sqlite.py ssssss                                   [ 24%]
tests/test_pickle.py s                                                   [ 24%]
tests/gallery/test_length_at_insert.py s                                 [ 24%]
tests/gallery/test_specific_compilation.py s                             [ 24%]
tests/test_alembic_migrations.py ss                                      [ 25%]
tests/test_functional.py sssssssssssssssssssssssssss                     [ 30%]
tests/test_pickle.py s                                                   [ 31%]
tests/gallery/test_length_at_insert.py s                                 [ 31%]
tests/gallery/test_specific_compilation.py s                             [ 31%]
tests/test_comparator.py .........................                       [ 36%]
tests/test_elements.py ...........................................       [ 45%]
tests/test_functional_postgresql.py .....                                [ 47%]
tests/test_functions.py ................................................ [ 57%]
........................................................................ [ 72%]
........................................................................ [ 87%]
........                                                                 [ 89%]
tests/test_shape.py .....F                                               [ 90%]
tests/test_types.py .........................................            [ 99%]
tests/gallery/test_disable_wrapping.py ..                                [100%]

=================================== FAILURES ===================================
_________________ TestInsertionORM.test_WKTElement[postgresql] _________________

self = <tests.test_functional.TestInsertionORM object at 0x3ff7c5bbd10>
session = <sqlalchemy.orm.session.Session object at 0x3ff7c7efa10>
Lake = <class 'tests.schema_fixtures.Lake.<locals>.Lake'>, setup_tables = None

    def test_WKTElement(self, session, Lake, setup_tables):
        lake = Lake(WKTElement("LINESTRING(0 0,1 1)", srid=4326))
        session.add(lake)
        session.flush()
        session.expire(lake)
        assert isinstance(lake.geom, WKBElement)
>       assert str(lake.geom) == (
            "0102000020e6100000020000000000000000000000000000000000000000000"
            "0000000f03f000000000000f03f"
        )
E       AssertionError: assert '002000000200...0000000000000' == '0102000020e6...000000000f03f'
E         - 0102000020e61000000200000000000000000000000000000000000000000000000000f03f000000000000f03f
E         ?  -          ^                                                    ^^^^^ --             - --
E         + 0020000002000010e600000002000000000000000000000000000000003ff00000000000003ff0000000000000
E         ?        ++ +++++   ^                                       +++             ^

tests/test_functional.py:313: AssertionError
_________________ TestInsertionORM.test_WKBElement[postgresql] _________________

self = <tests.test_functional.TestInsertionORM object at 0x3ff7c5c8710>
session = <sqlalchemy.orm.session.Session object at 0x3ff7c452450>
Lake = <class 'tests.schema_fixtures.Lake.<locals>.Lake'>, setup_tables = None

    def test_WKBElement(self, session, Lake, setup_tables):
        shape = LineString([[0, 0], [1, 1]])
        lake = Lake(from_shape(shape, srid=4326))
        session.add(lake)
        session.flush()
        session.expire(lake)
        assert isinstance(lake.geom, WKBElement)
>       assert str(lake.geom) == (
            "0102000020e6100000020000000000000000000000000000000000000000000"
            "0000000f03f000000000000f03f"
        )
E       AssertionError: assert '002000000200...0000000000000' == '0102000020e6...000000000f03f'
E         - 0102000020e61000000200000000000000000000000000000000000000000000000000f03f000000000000f03f
E         ?  -          ^                                                    ^^^^^ --             - --
E         + 0020000002000010e600000002000000000000000000000000000000003ff00000000000003ff0000000000000
E         ?        ++ +++++   ^                                       +++             ^

tests/test_functional.py:329: AssertionError
____________________ TestUpdateORM.test_Raster[postgresql] _____________________

self = <tests.test_functional_postgresql.TestUpdateORM object at 0x3ff7c9b1ad0>
session = <sqlalchemy.orm.session.Session object at 0x3ff7c4b5ad0>
Ocean = <class 'tests.schema_fixtures.Ocean.<locals>.Ocean'>
setup_tables = None

    def test_Raster(self, session, Ocean, setup_tables):
        skip_postgis1(session)
        polygon = WKTElement("POLYGON((0 0,1 1,0 1,0 0))", srid=4326)
        o = Ocean(polygon.ST_AsRaster(5, 5))
        session.add(o)
        session.flush()
        session.expire(o)
    
        assert isinstance(o.rast, RasterElement)
    
        rast_data = (
            "01000001009A9999999999C93F9A9999999999C9BF0000000000000000000000000000F03"
            "F00000000000000000000000000000000E610000005000500440001010101010101010100"
            "010101000001010000000100000000"
        )
    
>       assert o.rast.data == rast_data
E       AssertionError: assert '00000000013F...0000100000000' == '01000001009A...0000100000000'
E         Skipping 45 identical trailing characters in diff, use -v to show
E         - 01000001009A9999999999C93F9A9999999999C9BF0000000000000000000000000000F03F00000000000000000000000000000000E610000005000500440001010
E         ?  ^      ^^^^          - --            - ^^                ^^^^^^^^^^^^ --                                 ---           --
E         + 00000000013FC999999999999ABFC999999999999A00000000000000003FF000000000000000000000000000000000000000000000000010E600050005440001010
E         ?  ^^^      ^^^             +++           ^^                ^                                     ++++++++++++++++++

tests/test_functional_postgresql.py:365: AssertionError
__________ TestDecipherRaster.test_decipher_raster[postgresql-16BSI] ___________

self = <tests.gallery.test_decipher_raster.TestDecipherRaster object at 0x3ff7c9c93d0>
pixel_type = '16BSI'
session = <sqlalchemy.orm.session.Session object at 0x3ff7c887f90>
conn = <sqlalchemy.engine.base.Connection object at 0x3ff7c71a690>

    @pytest.mark.parametrize(
        "pixel_type",
        [
            "1BB",
            "2BUI",
            "4BUI",
            "8BSI",
            "8BUI",
            "16BSI",
            "16BUI",
            "32BSI",
            "32BUI",
            "32BF",
            "64BF",
        ],
    )
    def test_decipher_raster(self, pixel_type, session, conn):
        """Create a raster and decipher it"""
        metadata.drop_all(conn, checkfirst=True)
        metadata.create_all(conn)
    
        # Create a new raster
        polygon = WKTElement("POLYGON((0 0,1 1,0 1,0 0))", srid=4326)
        o = Ocean(polygon.ST_AsRaster(5, 6, pixel_type))
        session.add(o)
        session.flush()
    
        # Decipher data from each raster
        image = wkbImage(o.rast.data)
    
        # Define expected result
        expected = [
            [0, 1, 1, 1, 1],
            [1, 1, 1, 1, 1],
            [0, 1, 1, 1, 0],
            [0, 1, 1, 0, 0],
            [0, 1, 0, 0, 0],
            [0, 0, 0, 0, 0],
        ]
    
        # Check results
        band = image[0]
>       assert band == expected
E       assert [[0, 256, 256..., 0, 0, 0, 0]] == [[0, 1, 1, 1,..., 0, 0, 0, 0]]
E         At index 0 diff: [0, 256, 256, 256, 256] != [0, 1, 1, 1, 1]
E         Use -v to get more diff

tests/gallery/test_decipher_raster.py:188: AssertionError
__________ TestDecipherRaster.test_decipher_raster[postgresql-16BUI] ___________

self = <tests.gallery.test_decipher_raster.TestDecipherRaster object at 0x3ff7c9cbd90>
pixel_type = '16BUI'
session = <sqlalchemy.orm.session.Session object at 0x3ff7c7b7b90>
conn = <sqlalchemy.engine.base.Connection object at 0x3ff7c77c650>

    @pytest.mark.parametrize(
        "pixel_type",
        [
            "1BB",
            "2BUI",
            "4BUI",
            "8BSI",
            "8BUI",
            "16BSI",
            "16BUI",
            "32BSI",
            "32BUI",
            "32BF",
            "64BF",
        ],
    )
    def test_decipher_raster(self, pixel_type, session, conn):
        """Create a raster and decipher it"""
        metadata.drop_all(conn, checkfirst=True)
        metadata.create_all(conn)
    
        # Create a new raster
        polygon = WKTElement("POLYGON((0 0,1 1,0 1,0 0))", srid=4326)
        o = Ocean(polygon.ST_AsRaster(5, 6, pixel_type))
        session.add(o)
        session.flush()
    
        # Decipher data from each raster
        image = wkbImage(o.rast.data)
    
        # Define expected result
        expected = [
            [0, 1, 1, 1, 1],
            [1, 1, 1, 1, 1],
            [0, 1, 1, 1, 0],
            [0, 1, 1, 0, 0],
            [0, 1, 0, 0, 0],
            [0, 0, 0, 0, 0],
        ]
    
        # Check results
        band = image[0]
>       assert band == expected
E       assert [[0, 256, 256..., 0, 0, 0, 0]] == [[0, 1, 1, 1,..., 0, 0, 0, 0]]
E         At index 0 diff: [0, 256, 256, 256, 256] != [0, 1, 1, 1, 1]
E         Use -v to get more diff

tests/gallery/test_decipher_raster.py:188: AssertionError
__________ TestDecipherRaster.test_decipher_raster[postgresql-32BSI] ___________

self = <tests.gallery.test_decipher_raster.TestDecipherRaster object at 0x3ff7c9ca890>
pixel_type = '32BSI'
session = <sqlalchemy.orm.session.Session object at 0x3ff7c691a10>
conn = <sqlalchemy.engine.base.Connection object at 0x3ff7c756e10>

    @pytest.mark.parametrize(
        "pixel_type",
        [
            "1BB",
            "2BUI",
            "4BUI",
            "8BSI",
            "8BUI",
            "16BSI",
            "16BUI",
            "32BSI",
            "32BUI",
            "32BF",
            "64BF",
        ],
    )
    def test_decipher_raster(self, pixel_type, session, conn):
        """Create a raster and decipher it"""
        metadata.drop_all(conn, checkfirst=True)
        metadata.create_all(conn)
    
        # Create a new raster
        polygon = WKTElement("POLYGON((0 0,1 1,0 1,0 0))", srid=4326)
        o = Ocean(polygon.ST_AsRaster(5, 6, pixel_type))
        session.add(o)
        session.flush()
    
        # Decipher data from each raster
        image = wkbImage(o.rast.data)
    
        # Define expected result
        expected = [
            [0, 1, 1, 1, 1],
            [1, 1, 1, 1, 1],
            [0, 1, 1, 1, 0],
            [0, 1, 1, 0, 0],
            [0, 1, 0, 0, 0],
            [0, 0, 0, 0, 0],
        ]
    
        # Check results
        band = image[0]
>       assert band == expected
E       assert [[0, 16777216..., 0, 0, 0, 0]] == [[0, 1, 1, 1,..., 0, 0, 0, 0]]
E         At index 0 diff: [0, 16777216, 16777216, 16777216, 16777216] != [0, 1, 1, 1, 1]
E         Use -v to get more diff

tests/gallery/test_decipher_raster.py:188: AssertionError
__________ TestDecipherRaster.test_decipher_raster[postgresql-32BUI] ___________

self = <tests.gallery.test_decipher_raster.TestDecipherRaster object at 0x3ff7c9ca650>
pixel_type = '32BUI'
session = <sqlalchemy.orm.session.Session object at 0x3ff7c4d26d0>
conn = <sqlalchemy.engine.base.Connection object at 0x3ff7c4d1890>

    @pytest.mark.parametrize(
        "pixel_type",
        [
            "1BB",
            "2BUI",
            "4BUI",
            "8BSI",
            "8BUI",
            "16BSI",
            "16BUI",
            "32BSI",
            "32BUI",
            "32BF",
            "64BF",
        ],
    )
    def test_decipher_raster(self, pixel_type, session, conn):
        """Create a raster and decipher it"""
        metadata.drop_all(conn, checkfirst=True)
        metadata.create_all(conn)
    
        # Create a new raster
        polygon = WKTElement("POLYGON((0 0,1 1,0 1,0 0))", srid=4326)
        o = Ocean(polygon.ST_AsRaster(5, 6, pixel_type))
        session.add(o)
        session.flush()
    
        # Decipher data from each raster
        image = wkbImage(o.rast.data)
    
        # Define expected result
        expected = [
            [0, 1, 1, 1, 1],
            [1, 1, 1, 1, 1],
            [0, 1, 1, 1, 0],
            [0, 1, 1, 0, 0],
            [0, 1, 0, 0, 0],
            [0, 0, 0, 0, 0],
        ]
    
        # Check results
        band = image[0]
>       assert band == expected
E       assert [[0, 16777216..., 0, 0, 0, 0]] == [[0, 1, 1, 1,..., 0, 0, 0, 0]]
E         At index 0 diff: [0, 16777216, 16777216, 16777216, 16777216] != [0, 1, 1, 1, 1]
E         Use -v to get more diff

tests/gallery/test_decipher_raster.py:188: AssertionError
___________ TestDecipherRaster.test_decipher_raster[postgresql-32BF] ___________

self = <tests.gallery.test_decipher_raster.TestDecipherRaster object at 0x3ff7c9ca710>
pixel_type = '32BF'
session = <sqlalchemy.orm.session.Session object at 0x3ff7c9c2090>
conn = <sqlalchemy.engine.base.Connection object at 0x3ff7c9c2150>

    @pytest.mark.parametrize(
        "pixel_type",
        [
            "1BB",
            "2BUI",
            "4BUI",
            "8BSI",
            "8BUI",
            "16BSI",
            "16BUI",
            "32BSI",
            "32BUI",
            "32BF",
            "64BF",
        ],
    )
    def test_decipher_raster(self, pixel_type, session, conn):
        """Create a raster and decipher it"""
        metadata.drop_all(conn, checkfirst=True)
        metadata.create_all(conn)
    
        # Create a new raster
        polygon = WKTElement("POLYGON((0 0,1 1,0 1,0 0))", srid=4326)
        o = Ocean(polygon.ST_AsRaster(5, 6, pixel_type))
        session.add(o)
        session.flush()
    
        # Decipher data from each raster
        image = wkbImage(o.rast.data)
    
        # Define expected result
        expected = [
            [0, 1, 1, 1, 1],
            [1, 1, 1, 1, 1],
            [0, 1, 1, 1, 0],
            [0, 1, 1, 0, 0],
            [0, 1, 0, 0, 0],
            [0, 0, 0, 0, 0],
        ]
    
        # Check results
        band = image[0]
>       assert band == expected
E       assert [[0.0, 4.6006....0, 0.0, 0.0]] == [[0, 1, 1, 1,..., 0, 0, 0, 0]]
E         At index 0 diff: [0.0, 4.600602988224807e-41, 4.600602988224807e-41, 4.600602988224807e-41, 4.600602988224807e-41] != [0, 1, 1, 1, 1]
E         Use -v to get more diff

tests/gallery/test_decipher_raster.py:188: AssertionError
___________ TestDecipherRaster.test_decipher_raster[postgresql-64BF] ___________

self = <tests.gallery.test_decipher_raster.TestDecipherRaster object at 0x3ff7c9c8710>
pixel_type = '64BF'
session = <sqlalchemy.orm.session.Session object at 0x3ff7c805ed0>
conn = <sqlalchemy.engine.base.Connection object at 0x3ff7c805290>

    @pytest.mark.parametrize(
        "pixel_type",
        [
            "1BB",
            "2BUI",
            "4BUI",
            "8BSI",
            "8BUI",
            "16BSI",
            "16BUI",
            "32BSI",
            "32BUI",
            "32BF",
            "64BF",
        ],
    )
    def test_decipher_raster(self, pixel_type, session, conn):
        """Create a raster and decipher it"""
        metadata.drop_all(conn, checkfirst=True)
        metadata.create_all(conn)
    
        # Create a new raster
        polygon = WKTElement("POLYGON((0 0,1 1,0 1,0 0))", srid=4326)
        o = Ocean(polygon.ST_AsRaster(5, 6, pixel_type))
        session.add(o)
        session.flush()
    
        # Decipher data from each raster
        image = wkbImage(o.rast.data)
    
        # Define expected result
        expected = [
            [0, 1, 1, 1, 1],
            [1, 1, 1, 1, 1],
            [0, 1, 1, 1, 0],
            [0, 1, 1, 0, 0],
            [0, 1, 0, 0, 0],
            [0, 0, 0, 0, 0],
        ]
    
        # Check results
        band = image[0]
>       assert band == expected
E       assert [[0.0, 3.0386....0, 0.0, 0.0]] == [[0, 1, 1, 1,..., 0, 0, 0, 0]]
E         At index 0 diff: [0.0, 3.03865e-319, 3.03865e-319, 3.03865e-319, 3.03865e-319] != [0, 1, 1, 1, 1]
E         Use -v to get more diff

tests/gallery/test_decipher_raster.py:188: AssertionError
_________________ TestTypeDecorator.test_force_3d[postgresql] __________________

self = <tests.gallery.test_type_decorator.TestTypeDecorator object at 0x3ff7c506250>
session = <sqlalchemy.orm.session.Session object at 0x3ff7caa8c90>
conn = <sqlalchemy.engine.base.Connection object at 0x3ff7c4ec690>

    def test_force_3d(self, session, conn):
        self._create_one_point(session, conn)
    
        # Query the point and check the result
        pt = session.query(Point).one()
    
        assert pt.id == 1
        assert pt.three_d_geom.srid == 4326
>       assert pt.three_d_geom.desc.lower() == (
            "01010000a0e6100000000000000000144000000000008046400000000000000000"
        )
E       AssertionError: assert '00a000000100...0000000000000' == '01010000a0e6...0000000000000'
E         - 01010000a0e6100000000000000000144000000000008046400000000000000000
E         + 00a0000001000010e6401400000000000040468000000000000000000000000000

tests/gallery/test_type_decorator.py:168: AssertionError
_______________________________ test_from_shape ________________________________

    def test_from_shape():
        # Standard case: POINT(1 2)
        expected = WKBElement(str("0101000000000000000000f03f0000000000000040"))
        p = Point(1, 2)
        e = from_shape(p)
        assert isinstance(e, WKBElement)
        assert isinstance(e.data, memoryview)
>       assert e == expected
E       assert <WKBElement at 0x3ff7c1ad410; 00000000013ff00000000000004000000000000000> == <WKBElement at 0x3ff7c1acb50; 0101000000000000000000f03f0000000000000040>

tests/test_shape.py:68: AssertionError
=============================== warnings summary ===============================
tests/test_functional.py: 4 warnings
tests/test_functional_postgresql.py: 10 warnings
  /home/edward/geoalchemy2-0.13.3/geoalchemy2/types.py:150: PendingDeprecationWarning: The 'management' parameter is going to be deprecated and will raise an error in the version 0.14
    warnings.warn(

tests/test_functional.py::TestSelectBindParam::test_select_bindparam[postgresql]
  /home/edward/geoalchemy2-0.13.3/tests/test_functional.py:234: RemovedIn20Warning: Deprecated API features detected! These feature(s) are not compatible with SQLAlchemy 2.0. To prevent incompatible upgrades prior to updating applications, ensure requirements files are pinned to "sqlalchemy<2.0". Set environment variable SQLALCHEMY_WARN_20=1 to show all deprecation warnings.  Set environment variable SQLALCHEMY_SILENCE_UBER_WARNING=1 to silence this message. (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9)
    results = conn.execute(s, **params)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/test_functional.py::TestInsertionORM::test_WKTElement[postgresql]
FAILED tests/test_functional.py::TestInsertionORM::test_WKBElement[postgresql]
FAILED tests/test_functional_postgresql.py::TestUpdateORM::test_Raster[postgresql]
FAILED tests/gallery/test_decipher_raster.py::TestDecipherRaster::test_decipher_raster[postgresql-16BSI]
FAILED tests/gallery/test_decipher_raster.py::TestDecipherRaster::test_decipher_raster[postgresql-16BUI]
FAILED tests/gallery/test_decipher_raster.py::TestDecipherRaster::test_decipher_raster[postgresql-32BSI]
FAILED tests/gallery/test_decipher_raster.py::TestDecipherRaster::test_decipher_raster[postgresql-32BUI]
FAILED tests/gallery/test_decipher_raster.py::TestDecipherRaster::test_decipher_raster[postgresql-32BF]
FAILED tests/gallery/test_decipher_raster.py::TestDecipherRaster::test_decipher_raster[postgresql-64BF]
FAILED tests/gallery/test_type_decorator.py::TestTypeDecorator::test_force_3d[postgresql]
FAILED tests/test_shape.py::test_from_shape - assert <WKBElement at 0x3ff7c1a...
= 11 failed, 375 passed, 84 skipped, 6 deselected, 15 warnings in 118.39s (0:01:58) =
@adrien-berchet
Copy link
Member

Hi @EdwardBetts

Thanks for your report!

May I ask why you have to run these tests? Also, did they pass with a previous version of GeoAlchemy2?

Anyway, the tests were indeed never meant to run on any platform, especially the big-endian ones. This is because GeoAlchemy2 is mainly a wrapper, so the main point of the tests is to check that the proper functions are called in the DB. So I don't think we need to test on big-endian platforms (and as we can see in the report you posted, the tests only fail when we compare the raw values where endian matters, so it seems to confirm that the proper functions are called, it's just that they don't return the same values as the expected ones but, from a GeoAlchemy2 point of view, it does not really matter). Of course it would be possible to make the tests pass with big-endians but it would be quite long (too much for me at the moment, but any PR to improve this is welcome 😊 ).

@EdwardBetts
Copy link
Contributor Author

When a Python module is packaged for Debian the tests are run as part of the build process to ensure the package isn't broken in some way.

The tests are also run whenever one of the package dependencies are modified. This is to catch breakages caused by a change to a dependency.

We run the tests on all available architectures to catch architecture specific bugs.

I don't think this is a regression. I don't think the tests were passing with an older version of GeoAlchemy2.

I'm going to modify the Debian package so it doesn't run the failing tests on big-endian architectures.

@adrien-berchet
Copy link
Member

Ok, I see, thanks for the explanation.
So yeah I think that just skipping the tests on big-endian architectures is the best option. And it should still be safe since you keep the tests on all other architectures.

Just out of curiosity, do you know which package pulled the GeoAlchemy2 dependency?

@EdwardBetts
Copy link
Contributor Author

The tests were run on the s390x architecture to check the package worked there. The test run wasn't trigged by another package that depends on GeoAlchemy2.

I checked, there are no packages in Debian that depend on GeoAlchemy2. The dependencies of GeoAlchemy2 are python3-packaging, python3-sqlalchemy and python3.

@adrien-berchet
Copy link
Member

Ok.
I'm a bit surprised that GeoAlchemy2 is packaged in Debian just for its own, not because it's pulled by another package as a dependency. But I'm glad to know :-)

@EdwardBetts
Copy link
Contributor Author

I've built a web-based tool for matching objects with coordinates in OpenStreetMap and Wikidata. The tool is built using GeoAlchemy2. Deploying the tool is easier for me if the dependencies are part of Debian, that's why I packaged GeoAlchemy2.

The tool is here: https://osm.wikidata.link/

@adrien-berchet
Copy link
Member

Ah ok ok.
Nice tool btw! I didn't know it.

@adrien-berchet
Copy link
Member

Can we consider this issue as solved and close it? Or is there still anything we can do?

@EdwardBetts
Copy link
Contributor Author

Yes, let's close it.

@adrien-berchet
Copy link
Member

Ok, thanks.
See you around!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants