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

DWG CRS - GDAL plugin do not retrieve CRS as ODA C++ - OdDbGeoData #11672

Open
Pourfex opened this issue Jan 16, 2025 · 5 comments
Open

DWG CRS - GDAL plugin do not retrieve CRS as ODA C++ - OdDbGeoData #11672

Pourfex opened this issue Jan 16, 2025 · 5 comments

Comments

@Pourfex
Copy link

Pourfex commented Jan 16, 2025

What is the bug?

Hello,
We're using this method in ODA C++ to get CRS from a DWG file into a given XML output file :

  OdDbObjectId objIdGeoData;
  OdResult res = oddbGetGeoDataObjId(pDb, objIdGeoData);
  if (eOk != res) {
      std::cerr << "No geographic location defined." << std::endl;
      return 1;
  } else {
      OdDbGeoDataPtr pGeoData = objIdGeoData.openObject();
      if (!pGeoData.isNull()) {
          std::ofstream xmlFile(argv[4]);
          if (!xmlFile.is_open()) {
              std::cerr << "Failed to create file: " << argv[4] << std::endl;
          }
          xmlFile << (const char*)pGeoData->coordinateSystem();
          xmlFile.close();
      } else {
          std::cerr << "Geo data is null" << std::endl;
      }
  }

It works from some of the DWG file we have like : https://blocinbloc-public-test.s3.fr...4-MONTAIGU.dwg

In a second time, we built GDAL with ODA support based on https://github.com/OSGeo/gdal/blob/m...all/Dockerfile

We're succesfully getting that driver is being used for DWG, DGN and DXF with ogrinfo commands with results :

ogrinfo -al -so ./DwgFile/input/04-MONTAIGU.dwg

INFO: Open of {{./DwgFile/input/04-MONTAIGU.dwg' using driver }}DWG' successful.
Layer name: entities
Geometry: Unknown (any)
Feature Count: 4017
Extent: (894961.977581, 6619909.555172) - (898410.145520, 6621914.678879)
Layer SRS WKT:
(unknown)
Layer: String (0.0)
SubClasses: String (0.0)
ExtendedEntity: String (0.0)
Linetype: String (0.0)
EntityHandle: String (0.0)
Text: String (0.0)

The extent is correct but the Layer SRS WKT is always "unknown".
We would like to have the same output as OdDbGeoData in the SRS WKT into the ogr ODA driver.

Steps to reproduce the issue

# syntax=docker/dockerfile:1

##
# osgeo/gdal:ubuntu-small

# This file is available at the option of the licensee under:
# Public domain
# or licensed under MIT (LICENSE.TXT) Copyright 2019 Even Rouault <[email protected]>

ARG PROJ_INSTALL_PREFIX=/usr/local
ARG BASE_IMAGE=ubuntu:24.04
ARG TARGET_BASE_IMAGE=ubuntu:24.04

FROM $BASE_IMAGE AS builder

# Derived from osgeo/proj by Howard Butler <[email protected]>
LABEL maintainer="Even Rouault <[email protected]>"

ENV HOME="/root"

ARG TARGET_ARCH=
RUN echo ${TARGET_ARCH}
COPY ./bh-set-envvars.sh /buildscripts/bh-set-envvars.sh

RUN rm -f /etc/apt/apt.conf.d/docker-clean \
    && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache \
    && echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80-retries
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    . /buildscripts/bh-set-envvars.sh \
    && if test "${TARGET_ARCH}" != ""; then \
    rm -f /etc/apt/sources.list /etc/apt/sources.list.d/ubuntu.sources \
    && echo "deb [arch=amd64] http://us.archive.ubuntu.com/ubuntu/ noble main restricted universe" >> /etc/apt/sources.list \
    && echo "deb [arch=amd64] http://us.archive.ubuntu.com/ubuntu/ noble-updates main restricted universe" >> /etc/apt/sources.list \
    && echo "deb [arch=amd64] http://us.archive.ubuntu.com/ubuntu/ noble-backports main restricted universe" >> /etc/apt/sources.list \
    && echo "deb [arch=amd64] http://security.ubuntu.com/ubuntu noble-security main restricted universe" >> /etc/apt/sources.list \
    && echo "deb [arch=${TARGET_ARCH}] http://ports.ubuntu.com/ubuntu-ports/ noble main restricted universe" >> /etc/apt/sources.list \
    && echo "deb [arch=${TARGET_ARCH}] http://ports.ubuntu.com/ubuntu-ports/ noble-updates main restricted universe" >> /etc/apt/sources.list \
    && echo "deb [arch=${TARGET_ARCH}] http://ports.ubuntu.com/ubuntu-ports/ noble-security main restricted universe" >> /etc/apt/sources.list \
    && dpkg --add-architecture ${TARGET_ARCH} \
    && apt-get update -y \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y g++-13-${GCC_ARCH}-linux-gnu \
    && ln -s ${GCC_ARCH}-linux-gnu-gcc-13 /usr/bin/${GCC_ARCH}-linux-gnu-gcc \
    && ln -s ${GCC_ARCH}-linux-gnu-g++-13 /usr/bin/${GCC_ARCH}-linux-gnu-g++; \
    fi

# Setup build env for PROJ
USER root
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    . /buildscripts/bh-set-envvars.sh \
    && apt-get update -y \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing --no-install-recommends \
            build-essential ca-certificates ccache \
            git make ninja-build cmake wget unzip libtool automake \
            zlib1g-dev${APT_ARCH_SUFFIX} libsqlite3-dev${APT_ARCH_SUFFIX} pkg-config sqlite3 libcurl4-openssl-dev${APT_ARCH_SUFFIX} \
            libtiff-dev${APT_ARCH_SUFFIX} \
            rsync

# Setup build env for GDAL
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    . /buildscripts/bh-set-envvars.sh \
    && apt-get update -y \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing --no-install-recommends \
       python3-dev${APT_ARCH_SUFFIX} python3-numpy${APT_ARCH_SUFFIX} python3-setuptools${APT_ARCH_SUFFIX} \
       libjpeg-dev${APT_ARCH_SUFFIX} libgeos-dev${APT_ARCH_SUFFIX} \
       libexpat-dev${APT_ARCH_SUFFIX} libxerces-c-dev${APT_ARCH_SUFFIX} \
       libwebp-dev${APT_ARCH_SUFFIX} libpng-dev${APT_ARCH_SUFFIX} \
       libdeflate-dev${APT_ARCH_SUFFIX} \
       libzstd-dev${APT_ARCH_SUFFIX} bash zip curl \
       libpq-dev${APT_ARCH_SUFFIX} libssl-dev${APT_ARCH_SUFFIX} libopenjp2-7-dev${APT_ARCH_SUFFIX} \
       libspatialite-dev${APT_ARCH_SUFFIX} \
       autoconf automake sqlite3 bash-completion swig

# Build openjpeg
ARG OPENJPEG_VERSION=
RUN . /buildscripts/bh-set-envvars.sh \
    && if test "${OPENJPEG_VERSION}" != ""; then ( \
    curl -LO -fsS https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz \
    && tar xzf v${OPENJPEG_VERSION}.tar.gz \
    && rm -f v${OPENJPEG_VERSION}.tar.gz \
    && cd openjpeg-${OPENJPEG_VERSION} \
    && cmake . -G Ninja -DBUILD_SHARED_LIBS=ON  -DBUILD_STATIC_LIBS=OFF -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=/usr \
    && ninja \
    && ninja install \
    && mkdir -p /build_thirdparty/usr/lib \
    && cp -P /usr/lib/libopenjp2*.so* /build_thirdparty/usr/lib \
    && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \
    && cd .. \
    && rm -rf openjpeg-${OPENJPEG_VERSION} \
    ); fi

ARG PROJ_INSTALL_PREFIX
ARG PROJ_DATUMGRID_LATEST_LAST_MODIFIED
RUN \
    mkdir -p /build_projgrids/${PROJ_INSTALL_PREFIX}/share/proj \
    && curl -LO -fsS http://download.osgeo.org/proj/proj-datumgrid-latest.zip \
    && unzip -q -j -u -o proj-datumgrid-latest.zip  -d /build_projgrids/${PROJ_INSTALL_PREFIX}/share/proj \
    && rm -f *.zip

ARG RSYNC_REMOTE
ARG WITH_CCACHE

ARG oda_directory="oda_directory"

ARG oda_drawing="https://***/Drawings_lnxX64_13dll_25.12.tar"

ARG oda_kernel="https://***/Kernel_lnxX64_13dll_25.12.tar"

ARG oda_activation="https://***/OdActivationInfo"

RUN apt-get update && apt-get install -y \
    libgl1-mesa-dev \
    libx11-dev
# Prepare ODA Libraries
RUN if ! [ -d "$oda_directory" ]; then \
    curl -o oda_drawing.tar $oda_drawing \
    && curl -o oda_kernel.tar $oda_kernel \
    && curl -o OdActivationInfo $oda_activation \
    && mkdir -p "$oda_directory" \
    && tar xvf oda_kernel.tar -C "$oda_directory" \
    && tar xvf oda_drawing.tar -C "$oda_directory" \
    && rm oda_drawing.tar \
    && rm oda_kernel.tar \
    && cp OdActivationInfo "$oda_directory/ThirdParty/activation/"; \
fi

# Configure and build ODA Libraries - don't use -j options as it makes error in docker
RUN cd "$oda_directory" \
    && ./configure \
    && make \
    && cd ..

# Set LD_LIBRARY_PATH environment variable

RUN cd "$oda_directory" \
    && cd bin/lnxX64_13dll \
    && for f in *.tx ; do echo "Processing $f"; ln -s $f lib$f.so; done \
    && ldconfig

RUN apt install -y findutils \
    && find . -name "TG_Db.tx"

ARG LD_LIBRARY_PATH="/usr/local/bin/oda_directory/bin/lnxX64_13dll"
ARG TEIGHA_ROOT="oda_directory"
ARG TEIGHA_ACTIVATION_FILE_DIRECTORY="oda_directory/ThirdParty/activation"

# Build PROJ
ARG PROJ_VERSION=master
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    apt-get update -y \
    && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y patchelf

RUN --mount=type=cache,id=ubuntu-small-proj,target=$HOME/.cache \
    . /buildscripts/bh-set-envvars.sh \
    && mkdir proj \
    && curl -L -fsS https://github.com/OSGeo/PROJ/archive/${PROJ_VERSION}.tar.gz \
        | tar xz -C proj --strip-components=1 \
    && export PROJ_DB_CACHE_PARAM="" \
    && cd proj \
    && if test "${RSYNC_REMOTE:-}" != ""; then \
        echo "Downloading cache..."; \
        rsync -ra ${RSYNC_REMOTE}/proj/${GCC_ARCH}/ $HOME/.cache/; \
        echo "Finished"; \
    fi \
    && if [ -n "${WITH_CCACHE:-}" ]; then \
        export CC="ccache ${GCC_ARCH}-linux-gnu-gcc"; \
        export CXX="ccache ${GCC_ARCH}-linux-gnu-g++"; \
        export PROJ_DB_CACHE_PARAM="-DPROJ_DB_CACHE_DIR=$HOME/.cache"; \
        ccache -M 100M; \
    fi \
    && CFLAGS='-DPROJ_RENAME_SYMBOLS -O2' CXXFLAGS='-DPROJ_RENAME_SYMBOLS -DPROJ_INTERNAL_CPP_NAMESPACE -O2' \
        cmake . \
	-G Ninja \
        -DBUILD_SHARED_LIBS=ON \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=${PROJ_INSTALL_PREFIX} \
        -DBUILD_TESTING=OFF \
        $PROJ_DB_CACHE_PARAM \
    && ninja \
    && DESTDIR="/build" ninja install \
    && if test "${RSYNC_REMOTE:-}" != ""; then \
        echo "Uploading cache..."; \
        rsync -ra --delete $HOME/.cache/ ${RSYNC_REMOTE}/proj/${GCC_ARCH}/; \
        echo "Finished"; \
    fi \
    && if [ -n "${WITH_CCACHE:-}" ]; then \
        ccache -s; \
        unset CC; \
        unset CXX; \
    fi \
    && cd .. \
    && rm -rf proj \
    && PROJ_SO=$(readlink -f /build${PROJ_INSTALL_PREFIX}/lib/libproj.so | awk 'BEGIN {FS="libproj.so."} {print $2}') \
    && PROJ_SO_FIRST=$(echo $PROJ_SO | awk 'BEGIN {FS="."} {print $1}') \
    && mv /build${PROJ_INSTALL_PREFIX}/lib/libproj.so.${PROJ_SO} /build${PROJ_INSTALL_PREFIX}/lib/libinternalproj.so.${PROJ_SO} \
    && ln -s libinternalproj.so.${PROJ_SO} /build${PROJ_INSTALL_PREFIX}/lib/libinternalproj.so.${PROJ_SO_FIRST} \
    && ln -s libinternalproj.so.${PROJ_SO} /build${PROJ_INSTALL_PREFIX}/lib/libinternalproj.so \
    && rm /build${PROJ_INSTALL_PREFIX}/lib/libproj.*  \
    && ${GCC_ARCH}-linux-gnu-strip -s /build${PROJ_INSTALL_PREFIX}/lib/libinternalproj.so.${PROJ_SO} \
    && for i in /build${PROJ_INSTALL_PREFIX}/bin/*; do ${GCC_ARCH}-linux-gnu-strip -s $i 2>/dev/null || /bin/true; done \
    && patchelf --set-soname libinternalproj.so.${PROJ_SO_FIRST} /build${PROJ_INSTALL_PREFIX}/lib/libinternalproj.so.${PROJ_SO} \
    && for i in /build${PROJ_INSTALL_PREFIX}/bin/*; do patchelf --replace-needed libproj.so.${PROJ_SO_FIRST} libinternalproj.so.${PROJ_SO_FIRST} $i; done

# Build GDAL
ARG GDAL_VERSION=3.10.1
ARG GDAL_RELEASE_DATE
ARG GDAL_BUILD_IS_RELEASE
ARG GDAL_REPOSITORY=OSGeo/gdal

RUN --mount=type=cache,id=ubuntu-small-gdal,target=$HOME/.cache \
    . /buildscripts/bh-set-envvars.sh \
    && if test "${GDAL_VERSION}" = "master"; then \
        export GDAL_VERSION=$(curl -Ls https://api.github.com/repos/${GDAL_REPOSITORY}/commits/HEAD -H "Accept: application/vnd.github.VERSION.sha"); \
        export GDAL_RELEASE_DATE=$(date "+%Y%m%d"); \
    fi \
    && if test "x${GDAL_BUILD_IS_RELEASE:-}" = "x"; then \
        export GDAL_SHA1SUM=${GDAL_VERSION}; \
    fi \
    && mkdir gdal \
    && curl -L -fsS https://github.com/${GDAL_REPOSITORY}/releases/download/v${GDAL_VERSION}/gdal-${GDAL_VERSION}.tar.gz \
        | tar xz -C gdal --strip-components=1 \
    && cd gdal \
    && if test "${RSYNC_REMOTE:-}" != ""; then \
        echo "Downloading cache..."; \
        rsync -ra ${RSYNC_REMOTE}/gdal/${GCC_ARCH}/ $HOME/.cache/; \
        echo "Finished"; \
    fi \
    && if [ -n "${WITH_CCACHE:-}" ]; then \
        # Little trick to avoid issues with Python bindings
        printf "#!/bin/sh\nccache %s-linux-gnu-gcc \$*" "${GCC_ARCH}" > ccache_gcc.sh; \
        chmod +x ccache_gcc.sh; \
        printf "#!/bin/sh\nccache %s-linux-gnu-g++ \$*" "${GCC_ARCH}" > ccache_g++.sh; \
        chmod +x ccache_g++.sh; \
        export CC=$PWD/ccache_gcc.sh; \
        export CXX=$PWD/ccache_g++.sh; \
        ccache -M 1G; \
    fi

RUN echo "root"  \
    && ls \
    && cd gdal \
    && mkdir build \
    && cd build \
    && echo "build"  \
    && ls \
    && echo "teigha"  \
    && ls ../../${TEIGHA_ROOT}/ \
    && echo "teiga lib"  \
    && ls ../../${TEIGHA_ROOT}/lib \
    # -Wno-psabi avoid 'note: parameter passing for argument of type 'std::pair<double, double>' when C++17 is enabled changed to match C++14 in GCC 10.1' on arm64
    && CFLAGS='-DPROJ_RENAME_SYMBOLS -O2' CXXFLAGS='-DPROJ_RENAME_SYMBOLS -DPROJ_INTERNAL_CPP_NAMESPACE -O2 -Wno-psabi' \
       cmake .. \
        -G Ninja \
        -DODBC=ON \
        -DCMAKE_INSTALL_PREFIX=/usr \
        -DGDAL_FIND_PACKAGE_PROJ_MODE=MODULE \
        -DPROJ_INCLUDE_DIR="/build${PROJ_INSTALL_PREFIX-/usr/local}/include" \
        -DPROJ_LIBRARY="/build${PROJ_INSTALL_PREFIX-/usr/local}/lib/libinternalproj.so" \
        -DGDAL_USE_TIFF_INTERNAL=ON \
        -DGDAL_USE_GEOTIFF_INTERNAL=ON \
        -DBUILD_TESTING=OFF \
        -DTEIGHA_ROOT="/../../${TEIGHA_ROOT}"  \
        -DTEIGHA_PLATFORM="lnxX64_13dll"  \
        -DTEIGHA_ACTIVATION_FILE_DIRECTORY="/../../${TEIGHA_ACTIVATION_FILE_DIRECTORY}"

RUN cd gdal \
    && cd build \
    && ninja \
    && DESTDIR="/build" ninja install \
    && cd .. \
    && if test "${RSYNC_REMOTE:-}" != ""; then \
        echo "Uploading cache..."; \
        rsync -ra --delete $HOME/.cache/ ${RSYNC_REMOTE}/gdal/${GCC_ARCH}/; \
        echo "Finished"; \
    fi \
    && if [ -n "${WITH_CCACHE:-}" ]; then \
        ccache -s; \
        unset CC; \
        unset CXX; \
    fi

RUN rm -rf gdal \
    && mkdir -p /build_gdal_python/usr/lib \
    && mkdir -p /build_gdal_python/usr/bin \
    && mkdir -p /build_gdal_version_changing/usr/include \
    && ls /build/usr/lib/ \
    && mv /build/usr/lib/python*            /build_gdal_python/usr/lib \
    && mv /build/usr/lib                    /build_gdal_version_changing/usr \
    && mv /build/usr/include/gdal_version.h /build_gdal_version_changing/usr/include \
    && mv /build/usr/bin/*.py               /build_gdal_python/usr/bin \
    && mv /build/usr/bin                    /build_gdal_version_changing/usr \
    && for i in /build_gdal_version_changing/usr/lib/${GCC_ARCH}-linux-gnu/*; do ${GCC_ARCH}-linux-gnu-strip -s $i 2>/dev/null || /bin/true; done \
    && for i in /build_gdal_python/usr/lib/python3/dist-packages/osgeo/*.so; do ${GCC_ARCH}-linux-gnu-strip -s $i 2>/dev/null || /bin/true; done \
    && for i in /build_gdal_version_changing/usr/bin/*; do ${GCC_ARCH}-linux-gnu-strip -s $i 2>/dev/null || /bin/true; done

# Build final image
FROM $TARGET_BASE_IMAGE AS runner

USER root
RUN date

# Update distro
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    export DEBIAN_FRONTEND=noninteractive \
    && apt-get update -y \
    && apt-get upgrade -y \
    # PROJ dependencies
    && apt-get install -y --no-install-recommends \
        libsqlite3-0 libtiff6 libcurl4 \
        curl unzip ca-certificates \
    # GDAL dependencies
    && apt-get install -y --no-install-recommends \
        python3-numpy libpython3.12 \
        libjpeg-turbo8 libgeos3.12.1 libgeos-c1v5 \
        libexpat1 \
        libxerces-c3.2 \
        libwebp7 libpng16-16 \
        libdeflate0 \
        libzstd1 bash libpq5 libssl3 libopenjp2-7 libspatialite8 \
        # pil for antialias option of gdal2tiles
        python3-pil \
    && apt-get install -y python-is-python3

# Order layers starting with less frequently varying ones
# Only used for custom libopenjp2
# COPY --from=builder  /build_thirdparty/usr/ /usr/

COPY --from=builder  /build_projgrids/usr/ /usr/

ARG PROJ_INSTALL_PREFIX
COPY --from=builder  /build${PROJ_INSTALL_PREFIX}/share/proj/ ${PROJ_INSTALL_PREFIX}/share/proj/
COPY --from=builder  /build${PROJ_INSTALL_PREFIX}/include/ ${PROJ_INSTALL_PREFIX}/include/
COPY --from=builder  /build${PROJ_INSTALL_PREFIX}/bin/ ${PROJ_INSTALL_PREFIX}/bin/
COPY --from=builder  /build${PROJ_INSTALL_PREFIX}/lib/ ${PROJ_INSTALL_PREFIX}/lib/

COPY --from=builder  /build/usr/share/gdal/ /usr/share/gdal/
COPY --from=builder  /build/usr/include/ /usr/include/
COPY --from=builder  /build_gdal_python/usr/ /usr/
COPY --from=builder  /build_gdal_version_changing/usr/ /usr/
COPY --from=builder /oda_directory/ /usr/local/bin/oda_directory/

ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/bin/oda_directory/bin/lnxX64_13dll
RUN ldconfig

To build this docker :

docker build . -t tag -f ./Dockerfile --progress=plain

After build we can use it like this to have local DWG files in the docker container:

docker run --rm -it --platform linux/amd64 -v $(pwd):/DwgFile tag

Make ogrinfo command in the docker :

ogrinfo -al -so ./DwgFile/input/04-MONTAIGU.dwg

Versions and provenance

GDAL 3.10 built from Ubuntu 24.04 ubuntu_small docker with modifications.

Additional context

No response

@rcoup
Copy link
Member

rcoup commented Jan 16, 2025

AFAIK there's no support for CRS in the OGR Teigha driver.

DWG files are considered to have no georeferencing information through OGR. (docs)

As you've found, it's probably relatively straightforward to add

@Pourfex
Copy link
Author

Pourfex commented Jan 16, 2025

Ah you're right, thanks for pointing out.

Can you guide me where to look at for making this improvements ?

@rcoup
Copy link
Member

rcoup commented Jan 16, 2025

The ODA Teigha DWG driver code is in /ogr/ogrsf_frmts/dwg/.

There's a vector driver tutorial and plenty of existing drivers to examine — some are a lot more complex than others, so it's probably worth looking at something simpler like CSV initially.

@Pourfex
Copy link
Author

Pourfex commented Jan 17, 2025

Hello back,

Been trying to look around the vector drivers and it's not easy to get a grasp on SpatialReference Object on how they work.

If we take a look into ogrinfo_lib.cpp (line 1270-1282) ; we see that the input from ogrinfo commands come from :

char *pszWKT = nullptr;
  auto poSRS = poLayer->GetSpatialRef();
  if (poSRS == nullptr)
  {
      pszWKT = CPLStrdup("(unknown)");
  }
  else
  {
      poSRS->exportToWkt(&pszWKT, apszWKTOptions);
  }

  Concat(osRet, psOptions->bStdoutOutput, "Layer SRS WKT:\n%s\n",
         pszWKT);

So let's look on for exemple csv driver; we can follow where the GetSpatialRef() takes it's information from :

1 - ogrgeomfielddefn.cpp : method to get spatial ref :

const OGRSpatialReference *OGRGeomFieldDefn::GetSpatialRef() const
{
    return poSRS;
}

2 - ogrgeomfielddefn.cpp defines poSRS :

void OGRGeomFieldDefn::SetSpatialRef(const OGRSpatialReference *poSRSIn)
{

***

    poSRS = poSRSIn;

    if (poSRS != nullptr)
        const_cast<OGRSpatialReference *>(poSRS)->Reference();
}

3 - orgcvslayer.cpp is using SetSpatialRef:

OGRSpatialReference *poSRS = new OGRSpatialReference();
poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
poSRS->importFromEPSG(nEPSGCode);
oGeomFieldDefn.SetSpatialRef(poSRS);
poSRS->Release();

But this mecanism is nowhere to be found for dwg driver because we don't have any oGeomFieldDefn. So it seems it would be either : another method to get the Layers SRS not using oGeomFieldDefn ; or implement oGeomFieldDefn in the dwg driver. I would be eager to ear any thougts on this !

@rouault
Copy link
Member

rouault commented Jan 17, 2025

you need to do in the layer constructor something like

poFeatureDefn->SetGeomType(wkbUnknown);  // presumably, as I think DWG layers might fix geometries of different kind
OGRSpatialReference *poSRS = new OGRSpatialReference();
poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
poSRS->importFromWkt(...)  or SetFromUserInput()  // depends on how the SRS is actually encoded in DWG (no idea)
poFeatureDefn->GetGemFieldDefn(0)->SetSpatialRef(poSRS);
poSRS->Release();

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

No branches or pull requests

3 participants