-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Add coordinate system retrieve for DWG using ODA (fixes https://github.com/OSGeo/gdal/issues/11672) #11694
base: master
Are you sure you want to change the base?
Conversation
Testing is extensively described in #11672 Basically : |
poFeatureDefn->SetGeomType(wkbUnknown); // presumably, as I think DWG layers might fix geometries of different kind | ||
poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); | ||
poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); | ||
poSRS->Release(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be moved after line 72, so poSRS is released in case of error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree.
// Extract coordinate system string | ||
OdDbGeoCoordinateSystemPtr pCS; | ||
OdDbGeoCoordinateSystem::create(pGeoData->coordinateSystem(), pCS); | ||
if (pCS.isNull()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it really an error ? I've not checked, but couldn't a GeoData object be valid without a coordinateSystem() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at ODA's examples codebase, it seems it only serves as container for Geodata.
Basically it is use to CRUD the OdDbGeoCoordinateSystemPtr.
I'm no expert but will ask ODA member.
Co-authored-by: Even Rouault <[email protected]>
Co-authored-by: Even Rouault <[email protected]>
ogr/ogrsf_frmts/dwg/ogrdwglayer.cpp
Outdated
{ | ||
CPLError(CE_Warning, CPLE_AppDefined, "Invalid WKT format extracted."); | ||
} | ||
}else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code-formatting issue. See https://gdal.org/en/stable/development/dev_practices.html#commit-hooks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do all those those code formatting issues once the pull request is working
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done !
Succesfully setup a gdal compiling with ODA with good result on ogrinfo.
Main thing is to add the CSMap Dicts from ODA and correctly set the CS_MAP_DIR env variable. I've done checks if the variables are correctly set. Here is the updated DockerFile if anyone interested :
|
"Cannot load OdSpatialReference.tx The setup of " | ||
"MENTOR_DICTIONARY_PATH (or CS_MAP_DIR) is probably missing"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need an explanation in the DWG driver docs
- what is this, and why it doesn't match the usual GDAL/PROJ-supported CRS definitions
- where to get this data. Either ODA...Downloads...Thirdparty Libraries; or https://trac.osgeo.org/csmap/ with a FTBFS patch
- and what environment variable to set
(though I have no idea what MENTOR_DICTIONARY_PATH
is??)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Complete ODA support answer (deleting names, timestamps and so on) :
ODA member :
Hello,
To correctly work with OdDbGeoData you must set the MENTOR_DICTIONARY_PATH (or CS_MAP_DIR) environment variable to the path where your csmap library dictionaries are stored.
e.g., in my case it is: C:\ODA\CSDicts
see also: https://docs.opendesign.com/td/db_geo_functionality.html
About “Layer SRS WKT: (unknown)” in GDAL: I don't know how exactly GDAL tries to get WKT string, but you can do it in a next way:
OdDbObjectId objId;
oddbGetGeoDataObjId(pDb, objId);
OdDbGeoDataPtr pGeoData = objId.openObject();
//NOTE: pGeoData->coordinateSystem() can be represented in:
// XML (special autocad representation), WKT or coordinate system id (e.g. "WORLD-MERCATOR")
//Therefore OdDbGeoCoordinateSystem must be used for parsing.
OdDbGeoCoordinateSystemPtr pCS;
OdDbGeoCoordinateSystem::create(pGeoData->coordinateSystem(), pCS);
OdString sWktId;
pCS->getWktRepresentation(sWktId);
e.g. on your file “04-MONTAIGU.dwg“ as result I got next WKT string:
PROJCS["Lambert93",GEOGCS["LL-RGF93",DATUM["RGF93",SPHEROID["GRS1980",6378137.000,298.25722210]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["false_easting",700000.000],PARAMETER["false_northing",6600000.000],PARAMETER["central_meridian",3.00000000000000],PARAMETER["latitude_of_origin",46.50000000000000],PARAMETER["standard_parallel_1",44.00000000000000],PARAMETER["standard_parallel_2",49.00000000000000],UNIT["Meter",1.00000000000000]]
and pGeoData->coordinateSystem() string is represented by xml:
<?xml version="1.0" encoding="UTF-16" standalone="no" ?>
<Dictionary version="1.0" xmlns="http://www.osgeo.org/mapguide/coordinatesystem">
<ProjectedCoordinateSystem id="Lambert93">
<Name>Lambert93</Name>
<Description>Lambert-93 with RGF93 datum, whole country</Description>
<Authority>IGN Paris</Authority>
<AdditionalInformation>
<ParameterItem type="CsMap">
<Key>CSQuadrantSimplified</Key>
<IntegerValue>1</IntegerValue>
</ParameterItem>
</AdditionalInformation>
<DomainOfValidity>
<Extent>
<GeographicElement>
<GeographicBoundingBox>
<WestBoundLongitude>-10.8666666666667</WestBoundLongitude>
<EastBoundLongitude>11.3833333333333</EastBoundLongitude>
<SouthBoundLatitude>40.6166666666667</SouthBoundLatitude>
<NorthBoundLatitude>52.0833333333333</NorthBoundLatitude>
</GeographicBoundingBox>
</GeographicElement>
</Extent>
</DomainOfValidity>
<DatumId>RGF93</DatumId>
<Axis uom="METER">
<CoordinateSystemAxis>
<AxisOrder>1</AxisOrder>
<AxisName>Easting</AxisName>
<AxisAbbreviation>E</AxisAbbreviation>
<AxisDirection>east</AxisDirection>
</CoordinateSystemAxis>
<CoordinateSystemAxis>
<AxisOrder>2</AxisOrder>
<AxisName>Northing</AxisName>
<AxisAbbreviation>N</AxisAbbreviation>
<AxisDirection>north</AxisDirection>
</CoordinateSystemAxis>
</Axis>
<Conversion>
<Projection>
<OperationMethodId>Lambert Conic Conformal (2SP)</OperationMethodId>
<ParameterValue>
<OperationParameterId>Latitude of 1st standard parallel</OperationParameterId>
<Value uom="degree">44</Value>
</ParameterValue>
<ParameterValue>
<OperationParameterId>Latitude of 2nd standard parallel</OperationParameterId>
<Value uom="degree">49</Value>
</ParameterValue>
<ParameterValue>
<OperationParameterId>Longitude of false origin</OperationParameterId>
<Value uom="degree">3</Value>
</ParameterValue>
<ParameterValue>
<OperationParameterId>Latitude of false origin</OperationParameterId>
<Value uom="degree">46.5</Value>
</ParameterValue>
<ParameterValue>
<OperationParameterId>False easting</OperationParameterId>
<Value uom="METER">700000</Value>
</ParameterValue>
<ParameterValue>
<OperationParameterId>False northing</OperationParameterId>
<Value uom="METER">6600000</Value>
</ParameterValue>
</Projection>
</Conversion>
</ProjectedCoordinateSystem>
<Alias id="2154" type="CoordinateSystem">
<ObjectId>Lambert93</ObjectId>
<Namespace>EPSG Code</Namespace>
</Alias>
<GeodeticDatum id="RGF93">
<Name>RGF93</Name>
<Description>Reseau Geodesique Francais, RGF93</Description>
<Authority>IGN Paris</Authority>
<PrimeMeridianId>Greenwich</PrimeMeridianId>
<EllipsoidId>GRS1980</EllipsoidId>
</GeodeticDatum>
<Alias id="6171" type="Datum">
<ObjectId>RGF93</ObjectId>
<Namespace>EPSG Code</Namespace>
</Alias>
<Ellipsoid id="GRS1980">
<Name>GRS1980</Name>
<Description>Geodetic Reference System of 1980</Description>
<Authority>Stem, L.E., Jan 1989, State Plane Coordinate System of 1983</Authority>
<SemiMajorAxis uom="meter">6378137</SemiMajorAxis>
<SecondDefiningParameter>
<SemiMinorAxis uom="meter">6356752.31414035</SemiMinorAxis>
</SecondDefiningParameter>
</Ellipsoid>
<Alias id="7019" type="Ellipsoid">
<ObjectId>GRS1980</ObjectId>
<Namespace>EPSG Code</Namespace>
</Alias>
<Transformation id="RGF93_to_WGS84">
<Name>RGF93_to_WGS84</Name>
<Description>Reseau Geodesique Francais, RGF93</Description>
<Authority>IGN Paris</Authority>
<DomainOfValidity>
<Extent>
<GeographicElement>
<GeographicBoundingBox>
<WestBoundLongitude>-12.11</WestBoundLongitude>
<EastBoundLongitude>12.79</EastBoundLongitude>
<SouthBoundLatitude>39.885</SouthBoundLatitude>
<NorthBoundLatitude>52.835</NorthBoundLatitude>
</GeographicBoundingBox>
</GeographicElement>
</Extent>
</DomainOfValidity>
<OperationVersion>1</OperationVersion>
<CoordinateOperationAccuracy>
<Accuracy uom="meter">1</Accuracy>
</CoordinateOperationAccuracy>
<SourceDatumId>RGF93</SourceDatumId>
<TargetDatumId>WGS84</TargetDatumId>
<IsReversible>true</IsReversible>
<OperationMethod>
<OperationMethodId>Null transformation (no coordinate change)</OperationMethodId>
</OperationMethod>
</Transformation>
<Alias id="1671" type="Transformation">
<ObjectId>RGF93_to_WGS84</ObjectId>
<Namespace>EPSG Code</Namespace>
</Alias>
</Dictionary>
Best Regards
Me :
Hello !
Thanks for pointing out the CSDicts; they’re now installed and the env variable is set.
If you have a simple test for me to test if everything's ok; it’ll be great (like a simple script and a file to see if everything’s ok).
I’ve been working with gdal members to get gdal + oda working.
Here are the associated issues and PR :
https://github.com/OSGeo/gdal/issues/11672
https://github.com/OSGeo/gdal/pull/11694
as the issue state; I’m stuck at :
OdDbDatabasePtr pDb = poDS->GetDB();
if (pDb.isNull())
{
CPLError(CE_Failure, CPLE_AppDefined, "Invalid DWG database pointer.");
return;
}
// Get the GeoData object ID from the database
OdDbObjectId objId;
oddbGetGeoDataObjId(pDb, objId);
if (objId.isNull())
{
CPLError(CE_Warning, CPLE_AppDefined, "No GeoData found in DWG file.");
return;
}
// Open the GeoData object
OdDbGeoDataPtr pGeoData = objId.openObject();
if (pGeoData.isNull())
{
CPLError(CE_Failure, CPLE_AppDefined, "Failed to open GeoData object.");
return;
}
// Extract coordinate system string
OdDbGeoCoordinateSystemPtr pCS;
OdDbGeoCoordinateSystem::create(pGeoData->coordinateSystem(), pCS);
if (pCS.isNull())
{
CPLError(CE_Failure, CPLE_AppDefined, "Failed to create GeoCoordinateSystem.");
return;
}
// Retrieve the WKT representation of the coordinate system
OdString sWktId;
if (pCS->getWktRepresentation(sWktId) == eOk)
{
// Store the WKT in OGR layer's spatial reference
OGRSpatialReference *poSRS = new OGRSpatialReference();
if (poSRS->importFromWkt(TextUnescape(sWktId, false)) == OGRERR_NONE)
{
poFeatureDefn->SetGeomType(wkbUnknown); // presumably, as I think DWG layers might fix geometries of different kind
poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
poSRS->Release();
}
else
{
CPLError(CE_Warning, CPLE_AppDefined, "Invalid WKT format extracted.");
}
}else
{
CPLError(CE_Warning, CPLE_AppDefined, "Cannot get WKT Representation ");
}
at line 27 ; I cannot create the OdDbGeoCoordinateSystemPtr.
If you have any ways to debug the pGeoData and see what would be wrong and why the create method return a null object.
If you want to join the PR and issue, you’re welcome !
ODA member:
Hello,
I forgot to add that it is also needed to load module that enables PE (Protocol Extension) for GeoData-related classes (OdGeoData.tx):
odrxDynamicLinker()->loadModule(OdGeoDataModuleName, false);
About test case - you can try to execute your code with string above and file you have attached.
Just in case: here is the list of current geo-related modules dependencies (how they are loaded):
TD_DbCore.dll - stores OdDbGeoData class and interfaces for OdDbGeoCoordinateSystem related classes.
GeoCommands.tx - set of AutoCAD-like commands for working with GEO.
OdDbGeoMapPE.tx - implementation of online maps functionality.
AcGeolocationObj.tx - implementation of OdDbGeoMap (OdDbRasterImage) class.
OdGeoData.tx - implementation of GEO Protocol Extension (PE) interfaces related to Coordinate Systems.
OdSpatialReference.tx - part of Kernel SDK.
But for your needs you would need to load only OdGeoData.tx. It will try to load OdSpatialReference.tx. If your env variable setup is incorrect in some way, you will get exeption like "csmap initialization failed: OdSpatialReferenceModule is not loaded.". If there will be no such message - setup is ok and all should work.
Me :
Hello,
Added odrxDynamicLinker()->loadModule(OdGeoDataModuleName, false); to gdal usage of ODA ; please see here : https://github.com/OSGeo/gdal/pull/11694
Yet, same thing happens that is seen here : https://github.com/OSGeo/gdal/issues/11672
OdDbGeoCoordinateSystemPtr pCS;
OdDbGeoCoordinateSystem::create(pGeoData->coordinateSystem(), pCS);
if (pCS.isNull())
{
CPLError(CE_Failure, CPLE_AppDefined, "Failed to create GeoCoordinateSystem.");
return;
}
Gives error : ERROR 1: Failed to create GeoCoordinateSystem.
Please look at issue and pull request; as it is not a standard ODA env but gdal compiled with ODA.
ODA Member :
Hello,
So OdGeoData.tx module wasn’t loaded? That means that MENTOR_DICTIONARY_PATH (or CS_MAP_DIR (old name)) env variable setup is missing…
Your can try to load OdSpatialReference.tx module and check result for null:
OdRxModulePtr pOdSpatialReferenceModule = odrxDynamicLinker()->loadModule(OdSpatialReferenceModuleName);
if (pOdSpatialReferenceModule.isNull())
{
// The setup of MENTOR_DICTIONARY_PATH (or CS_MAP_DIR) is missing.
}
Best Regards,
Me :
Thanks it was that; env variable was not correctly set to the right folder. Thanks for pointing out. The issue is now resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So now you have as much as info as I have ; so either is sufficient to write some docs about it or we should double check with ODA members. What do you think ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the cs-map codebase only talks about CS_MAP_DIR
, and the ODA docs mention the two as alternatives, so I'd be tempted to just document the former. Google suggests MENTOR_DICTIONARY_PATH
is part of MapGuide, another Autodesk thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rcoup updated the documentation, feel free to review
Nevermind, I thought the GDAL driver did writing. That's a future project! |
@Pourfex
|
@Pourfex We also have unit tests in autotest/ogr/ogr_dwg.py . It would be great if they could be enhanced, with a new test file (redistribuable under the MIT license of GDAL), as small as possible, added in autotest/ogr/data/cad/ |
The GDAL project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 28 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
What does this PR do?
Get Coordinate System WKT representation from ODA capabilities when GDAL is build with ODA. Uses the existing system of SpatialReference from gdal.
What are related issues/pull requests?
#11672
Tasklist
Environment
Provide environment details, if relevant: