Opened 16 years ago

Closed 16 years ago

Last modified 15 years ago

#201 closed defect (fixed)

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 (18)

comment:1 by jbronn, 16 years ago

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

comment:2 by sgillies, 16 years ago

Owner: changed from geos-devel@… to sgillies
Status: newassigned

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.

comment:3 by mloskot, 16 years ago

Component: DefaultCore
Keywords: locale wkt added
Severity: UnassignedSignificant

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?

comment:4 by jbronn, 16 years ago

Version: 3.0.0

This is with version 3.0.0.

comment:6 by sgillies, 16 years ago

I meant "C" locale.

comment:7 by mloskot, 16 years ago

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.

comment:8 by sgillies, 16 years ago

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.

comment:9 by sgillies, 16 years ago

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

comment:10 by sgillies, 16 years ago

Better solution in r2174 after consultation with Frank and Mateusz.

comment:12 by CrAsH0v3r, 16 years ago

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 comment:13 by CrAsH0v3r, 16 years ago

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

comment:14 by mloskot, 16 years ago

Owner: changed from sgillies to mloskot
Status: assignednew

comment:15 by mloskot, 16 years ago

Status: newassigned

Philippe,

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

comment:16 by mloskot, 16 years ago

Resolution: fixed
Status: assignedclosed

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.

comment:17 by CrAsH0v3r, 16 years ago

Hi,

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

Philippe

comment:18 by pramsey, 15 years ago

Milestone: 3.1.0
Note: See TracTickets for help on using tickets.