A point at (0, 0), or somewhere in the Gulf of Guinea: four ways a coordinate goes missing
Short answer: a point at (0, 0) is not a place your data came from. It is a coordinate that went missing, got swapped, or was read from the wrong column — and the cluster you see need not be at (0, 0) at all: the one measured for this post sits a thousand kilometres off West Africa, in the Gulf of Guinea. Four failures produce it: two the tools count out loud, two are silent.
Tested on 23 September 2026 against static-page-tools@79fc1f6 — the csv-viewer and the coordinate-converter as deployed today. Every quoted string is the tool's own; every coordinate is the first pair of an Export GeoJSON download, except the GDAL transcript under "Fixing it", which is repeated unchanged from the CSV guide's command-line run (GDAL 3.13.3 "Iowa City"). Test files at the end.
The empty cell: a counted skip, and it always was
Header id,lat,lon,nome, rows 1,-23.55,-46.63,São Paulo, 2,,,Brasília, 3,-3.12,-60.02,Manaus. The panel reads 2 points · 1 row without valid coordinates, there is no banner, and the blank row is not in the export at all: two features, no [0,0] anywhere. Blank a second row and it reads 1 point · 2 rows without valid coordinates. Blank all three and the counter goes with the layer it was counting, leaving the banner quoted further down.
The viewer never drew that row at zero — not in this version, and not in the one before September's fix. The same file through the parser as it stood before September's fix gives the same two points and the same single skip: the old code used parseFloat, and parseFloat of an empty string is already not a number. The explicit empty-string check the fix added bought preservation, not repair — it swapped parseFloat for Number so a 23°33'S cell would stop plotting in Saudi Arabia, and Number of an empty string is 0, so without that line the change would have introduced the point at (0, 0). On the same harness the 23°33'S row did move, from drawn at [46, 23] to a counted skip, so the blank cell's non-change is a real one.
The converter turns the same defect into a typing instruction: fill Latitude, leave Longitude empty, and the card says Fill both latitude and longitude to convert. in amber and renders nothing. With both empty it says nothing at all. Neither tool puts an empty cell at (0, 0).
Swapped: nothing can detect it
Same header, values reversed: 1,-46.63,-23.55,São Paulo. Counts line 3 points, no counter, no banner, first pair [-23.55, -46.63] — 3,290.4 km from São Paulo on a bearing of 147°, in the South Atlantic; Manaus lands 7,934.8 km from Manaus. Nothing says anything is wrong and nothing can: −46.63 is a good latitude and −23.55 a good longitude. The converter agrees by converting — -46.63 and -23.55 leave the helper line empty and return -46.63000000 and -23.55000000.
One row can be caught, by accident, when the swap drops a longitude beyond ±90 into the latitude column. Make the third row 3,139.69,35.69,Tokyo and the viewer reads 2 points · 1 row without valid coordinates; the other two are still 3,290 km out. The converter refuses 139.69 with Invalid latitude or longitude.
The wrong column: what the magnitude rule misses
Change only the header, to id,este,norte,nome. The picker opens on every file and pre-selects by name: known aliases, then a substring match on lat and lon, then the first two columns. Neither este nor norte matches, so Latitude column is pre-set to id and Longitude column to este. Accept that and you get 3 points, no counter, no banner, first pair [-46.63, 1] — the real latitude sitting in the attribute table under norte, as -23.55.
The magnitude rule below cannot see this one. The latitudes are 1, 2 and 3, each a plausible Brazilian latitude, and the map is 2,729.8 km due north of where it belongs with every number on it passing inspection. The tell is the column's shape: a latitude that counts upward by one is a row number.
Put true UTM metres under the same header — 1,333283.88,7394643.65,São Paulo — and the outcome inverts. The pre-selection is identical, but 333283.88 is not a longitude, so every row fails the bounds check, no layer is created, and you get No valid coordinate columns found. Check that the selected columns contain numeric latitude and longitude values. Which of the two you get depends on the values, not on anything the tool understands. If the numbers are metres you need the zone's EPSG code, listed under "Picking a UTM zone in Brazil" in the EPSG cheat sheet.
In the converter there is no column to pick and the only check is the bound: 90 and 180 convert, 90.01 and 180 give Invalid latitude or longitude. A six-figure easting falls outside that bound, so the rule refuses it — that one is read off the rule, not typed into the card for this post — while a row counter of 1 falls inside it and converts.
The decimal comma that did not survive the save
Right columns, right numbers, wrong file: 1,-23,55,-46,63,São Paulo under id,lat,lon,nome. In a comma-delimited file that is six cells, not four, before any coordinate parser sees it — lat takes -23, lon takes 55, nome takes -46, and São Paulo falls off the end. Both coordinate cells are whole numbers, so nothing is refused: 3 points, no counter, no banner. São Paulo draws at [55, -23], 10,096.7 km away; Manaus at [12, -3], 1,374.8 km from the origin — the Gulf of Guinea in the title. The tell is in the attribute table, where nome reads -46.
Quoting is the whole difference: 1,"-23,55","-46,63",São Paulo comes back as [-46.63, -23.55] with nome reading São Paulo. The rescue runs per cell, after the row is split, so it can only save a comma that was never a delimiter.
The converter has the same defect and hides it better. Type -23,55 and -46,63 and there is no error line and no red field — and the result reads -23.00000000 and -46.00000000. Its validator swaps the comma for a dot before checking, so the value passes; its parser does not, so it stops at the comma. That is 61.2 km north of the point you typed when only the latitude carries a comma, 88.8 km on a bearing of 047° when both do. With dots it gives -23.55000000 and -46.63000000. It is a bug, it is filed, and nothing warns you today.
The ten-second diagnosis
Brazil is roughly −74° to −29° of longitude and +5° to −34° of latitude, and most of this is a magnitude check against that box. A longitude outside −74 to −29 is the tell for a swap: the swapped file's are −23.55, −15.79 and −3.12, all failing, where the correct file's −46.63, −47.88 and −60.02 all pass. A longitude between +12 and +79 is the tell for a lost decimal comma — that file exports 55, 79 and 12. A latitude beyond ±90 is the one thing both tools catch alone.
Two things the rule will not tell you. The wrong column sails through it: latitudes of 1, 2 and 3 are inside the band and the map is still 2,729.8 km out. And (0, 0) means absent rather than zero, except when it does not — a blank cell never reaches the map, before or after that fix, while a cell holding a literal 0 does and is drawn at the origin. So exactly (0, 0) came from a cell that held a zero, and a cluster merely near it, like [12, -3] at 1,374.8 km, came from a number that got shortened. The near miss is the dangerous one, because it looks like data.
Fixing it
A swap and a wrong column are both fixed in the picker, with no re-export. Open the file in the csv-viewer again, set Latitude column and Longitude column to the columns that really hold them, and click Open on map. On the swapped file that moves the first pair from [-23.55, -46.63] to [-46.63, -23.55]; on the wrong-column file, choosing norte as the latitude does the same. Watch the export, not the counter — the counts line reads 3 points before and after, so only the pair tells you it worked.
In the converter it is the button between the two fields, labelled Swap latitude and longitude: one click turns -46.63 and -23.55 into -23.55 and -46.63.
For the comma the fix is in the file, and the part of it measured here is the quoting — identical digits quoted per cell read correctly, unquoted do not. Which spreadsheet setting produces which file was not tested for this post, and no spreadsheet was run at all, so treat "save with a dot as the decimal separator" as the shape of the fix and check the bytes you actually get.
Outside the browser the picker's equivalent is two GDAL flags: ogr2ogr -f GeoJSON out.geojson in.csv -oo X_POSSIBLE_NAMES=lon -oo Y_POSSIBLE_NAMES=lat. On the clean three-row file that exits 0 and writes {"type":"Point","coordinates":[-46.63,-23.55]} for São Paulo — the control run from the CSV guide's command line, not a browser reading. Put your own column names in the flags.
Title rows, Latin-1 accents and a dropped .xlsx go wrong in the same file; the CSV on a map guide covers those.
Test files you can use
Nothing is hosted — paste the rows into a text editor and save each as a UTF-8 .csv.
- The empty cell:
id,lat,lon,nome,1,-23.55,-46.63,São Paulo,2,,,Brasília,3,-3.12,-60.02,Manaus. - Swapped:
id,lat,lon,nome,1,-46.63,-23.55,São Paulo,2,-47.88,-15.79,Brasília,3,-60.02,-3.12,Manaus. - The wrong column:
id,este,norte,nome,1,-46.63,-23.55,São Paulo,2,-47.88,-15.79,Brasília,3,-60.02,-3.12,Manaus. - The decimal comma:
id,lat,lon,nome,1,-23,55,-46,63,São Paulo,2,-15,79,-47,88,Brasília,3,-3,12,-60,02,Manaus.
For teams
A swap or a wrong column is a handover problem, not a file problem: it happens where a spreadsheet leaves one person and lands on someone else's map. Geodocs keeps field data on a shared map where the coordinate fields are decided once, when the form is built.