Ticket #201 (closed defect: fixed)

Opened 6 years ago

Last modified 5 years ago

Current locale considered when converting a geometry to WKT

Reported by: luizvital Owned by: mloskot
Priority: major Milestone: 3.1.0
Component: Core Version: 3.0.0
Severity: Significant Keywords: locale wkt
Cc:

Description

This was noticed when using geodjango ctypes wraper in python. A more detailed description here  http://code.djangoproject.com/ticket/8563

Change History

  Changed 6 years ago by jbronn

More specifically, GeoDjango's GEOSGeometry object is essentially just returning the output of the GEOS C API method GEOSGeomToWKT (link).

  Changed 6 years ago by sgillies

  • owner changed from geos-devel@… to sgillies
  • status changed from new to assigned

From the Django ticket:

I'm getting a OGRGeometry Exception intermittently, when saving a form.

After debuging the code I noticed that the WKT string generated from geometries were taking the current locale into account, thus raising the Exceptions due to a bad WKT string representation. Here goes an example:

>>> import locale
>>> from django.contrib.gis.geos import Point
>>> p = Point(-45.23, -23.15)
>>> p.wkt
'POINT (-45.2299999999999969 -23.1499999999999986)'
>>> locale.getlocale()
(None, None)
>>> locale.setlocale(locale.LC_ALL, ('pt_BR','UTF-8'))
'pt_BR.UTF8'
>>> p.wkt
'POINT (-45,2299999999999969 -23,1499999999999986)'

Notice de comma "," for decimal separator in the last output.

It must be something in the GEOS C library and in this case should be fixed there, but maybe it should be avoided reseting de locale before calling the C routine and restoring the locale to what it was just after.

I think the reason this problem was not always happening is related to the some setlocale thread safety issue.

I was using the wkt from the geometry in a custom form PointField?? to get the coordinate transformed to the desired srid.

  Changed 6 years ago by mloskot

  • keywords locale wkt added
  • component changed from Default to Core
  • severity changed from Unassigned to Significant

AFAIU, the problem is that GEOS does not ignore current locale in numeric/string operations and casting. Obviously, WKT processing should be locale-indenepdent.

Please, to complete the report, what version of GEOS you use?

  Changed 6 years ago by jbronn

  • version set to 3.0.0

This is with version 3.0.0.

  Changed 6 years ago by sgillies

  Changed 6 years ago by sgillies

I meant "C" locale.

  Changed 6 years ago by mloskot

Sean, yes forcing C or POSIX locale should fix the problem. This schema should be sufficient:

#include <iostream>
#include <sstream>
#include <locale>
int main()
{
    double a = 1.234;

    std::ostringstream s;
    std::locale loc("C");
    s.imbue(loc);
    s<<a;
    std::cout << s.str() << std::endl;

    return 0;
}

However, I'm not very happy with (re)setting locale in every call of toString(), as potentially decreasing performance. Better would be to do it from WKT reader and writer. I can look at it but after Wednesday next week.

  Changed 6 years ago by sgillies

I looked into the WKTWriter code for a while today and found it rather confusing. There is code in there that doesn't seem to be called by anything, mixtures of C and C++ patterns ... ugh. Geometry::toString() doesn't appear to be used by the writer after all. Seems like sprintf() in WKTWriter::writeNumber might be the problem.

  Changed 6 years ago by sgillies

Fix for the C API (read and write, old function and new) is in r2172.

  Changed 6 years ago by sgillies

Better solution in r2174 after consultation with Frank and Mateusz.

  Changed 6 years ago by sgillies

follow-up: ↓ 13   Changed 6 years ago by CrAsH0v3r

The trunk is currently broken because of theses changes.

I'm building on Windows using msvc8 and I'm getting the following "unresolved external" at the linker step.

 Creating library geos_i.
lib and object geos_i.exp
geos_c.obj : error LNK2019: unresolved external symbol "public: __thiscall geos::io::CLocalizer::~CLocalizer(void)" (??1CLocalizer@io@geos@@QAE@XZ) referenced in function _GEOSGeom
FromWKT
geos_c.obj : error LNK2019: unresolved external symbol "public: __thiscall geos::io::CLocalizer::CLocalizer(void)" (??0CLocalizer@io@geos@@QAE@XZ) referenced in function _GEOSGeomF
romWKT
geos.dll : fatal error LNK1120: 2 unresolved externals

I'm looking into it, i'll will come back with the solution if I find it.

Thanks for help.

Philippe

in reply to: ↑ 12   Changed 6 years ago by CrAsH0v3r

Update of the situation : CLocalizer.cpp is never compiled. I added it to the project file under "Build/msvc80..." and it does not compile, due to following :

1>c:\geos\geos-lag\source\io\clocalizer.cpp(12) : error C2039: 'setlocale' : is not a member of 'std'
1>c:\geos\geos-lag\source\io\clocalizer.cpp(17) : error C2039: 'setlocale' : is not a member of 'std'
1>c:\geos\geos-lag\source\io\clocalizer.cpp(22) : error C2039: 'setlocale' : is not a member of 'std'

I'll work on that tomorrow.

Thanks

Phil

Replying to CrAsH0v3r:

The trunk is currently broken because of theses changes. I'm building on Windows using msvc8 and I'm getting the following "unresolved external" at the linker step. {{{ Creating library geos_i. lib and object geos_i.exp geos_c.obj : error LNK2019: unresolved external symbol "public: thiscall geos::io::CLocalizer::~CLocalizer(void)" (??1CLocalizer@io@geos@@QAE@XZ) referenced in function _GEOSGeom FromWKT geos_c.obj : error LNK2019: unresolved external symbol "public: thiscall geos::io::CLocalizer::CLocalizer(void)" (??0CLocalizer@io@geos@@QAE@XZ) referenced in function _GEOSGeomF romWKT geos.dll : fatal error LNK1120: 2 unresolved externals }}} I'm looking into it, i'll will come back with the solution if I find it. Thanks for help. Philippe

  Changed 6 years ago by mloskot

  • owner changed from sgillies to mloskot
  • status changed from assigned to new

  Changed 6 years ago by mloskot

  • status changed from new to assigned

Philippe,

Thanks for reporting this issue. I've applied patch, so should be fixed in trunk (r2183)

  Changed 6 years ago by mloskot

  • status changed from assigned to closed
  • resolution set to fixed

I've also updated Visual C++ 2005/2008 project - geos_lib.vcproj (r2185)

I would consider this issue as fixed, so closing. Please, verify if it works and reopen if something is wrong still.

  Changed 6 years ago by CrAsH0v3r

Hi,

Thanks a lot. It works both ways, command line and via the project file.

Philippe

  Changed 5 years ago by pramsey

  • milestone set to 3.1.0
Note: See TracTickets for help on using tickets.