#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 , 16 years ago
comment:2 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | new → 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.
comment:3 by , 16 years ago
Component: | Default → Core |
---|---|
Keywords: | locale wkt added |
Severity: | Unassigned → 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?
comment:5 by , 16 years ago
So, we imbue the stream at
http://trac.osgeo.org/geos/browser/trunk/source/geom/Coordinate.cpp?rev=2144#L36
with a null locale?
comment:7 by , 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 , 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:11 by , 16 years ago
Snapshot with the fix at http://gispython.org/downloads/geos/geos-r2174.tar.gz.
follow-up: 13 comment:12 by , 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
comment:13 by , 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 externalsI'm looking into it, i'll will come back with the solution if I find it.
Thanks for help.
Philippe
comment:14 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
comment:15 by , 16 years ago
Status: | new → assigned |
---|
Philippe,
Thanks for reporting this issue. I've applied patch, so should be fixed in trunk (r2183)
comment:16 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
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 , 16 years ago
Hi,
Thanks a lot. It works both ways, command line and via the project file.
Philippe
comment:18 by , 15 years ago
Milestone: | → 3.1.0 |
---|
More specifically, GeoDjango's
GEOSGeometry
object is essentially just returning the output of the GEOS C API methodGEOSGeomToWKT
(link).