{"record":{"id":"10ff571aeaabd392","repo":"a-b-street/abstreet","slug":"malformed-coordinates","errorCode":null,"errorMessage":"Malformed coordinates: {}","messagePattern":"Malformed coordinates: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kml/src/lib.rs","lineNumber":113,"sourceCode":"            .text()\n            .map(|x| x.to_string())\n            .unwrap_or_else(String::new);\n        kv.insert(key, value);\n    } else if node.tag_name().name() == \"coordinates\" {\n        let mut any_oob = false;\n        let mut any_ok = false;\n        let mut pts: Vec<LonLat> = Vec::new();\n        if let Some(txt) = node.text() {\n            for pair in txt.trim().split(' ') {\n                if let Some(pt) = parse_pt(pair) {\n                    pts.push(pt);\n                    if gps_bounds.contains(pt) {\n                        any_ok = true;\n                    } else {\n                        any_oob = true;\n                    }\n                } else {\n                    bail!(\"Malformed coordinates: {}\", pair);\n                }\n            }\n        }\n        if any_ok && (!any_oob || !require_all_pts_in_bounds) {\n            let attributes = std::mem::take(kv);\n            shapes.push(ExtraShape {\n                points: pts,\n                attributes,\n            });\n        } else {\n            *skipped_count += 1;\n        }\n    }\n    Ok(())\n}\n\nfn parse_pt(input: &str) -> Option<LonLat> {\n    let coords: Vec<&str> = input.split(',').collect();","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/kml/src/lib.rs#L95-L131","documentation":"While recursing through KML, each <coordinates> element is parsed as space/comma-separated lon,lat pairs. When any pair fails to parse (wrong number of components or non-numeric text), recurse bails with the offending pair included in the message.","triggerScenarios":"Loading a KML file whose Placemark coordinates contain malformed entries — e.g. 'lat,lon,alt,extra', 'x,y' with non-numeric values, doubled commas, or newline-only junk between valid pairs.","commonSituations":"Hand-edited KML; KML exported by tools that emit 3D coordinates or locale-formatted decimals (comma decimal separators); copy-pasted coordinate strings with stray characters.","solutions":["Open the KML, find the pair printed in the error, and fix or remove it — coordinates must be numeric lon,lat (optionally alt) triples like '-1.2,54.5,0'.","Normalize the file: replace locale decimal commas with dots and strip empty tokens before loading.","If the file comes from an external tool, re-export it with plain 2D WGS84 coordinates."],"exampleFix":"// before (KML coordinates)\n-1.2,54.5,0 -1,3,54,6\n// after\n-1.2,54.5,0 -1.3,54.6,0","handlingStrategy":"validation","validationCode":"for pair in coords_text.split_whitespace() {\n    let parts: Vec<&str> = pair.split(',').collect();\n    if !(2..=3).contains(&parts.len()) || parts.iter().any(|p| p.parse::<f64>().is_err()) {\n        bail!(\"Malformed coordinates: {}\", pair);\n    }\n}","typeGuard":"fn is_valid_coord_pair(pair: &str) -> bool {\n    pair.split(',').map(str::trim).filter(|p| !p.is_empty())\n        .take(2).count() >= 2\n        && pair.split(',').take(2).all(|p| p.trim().parse::<f64>().is_ok())\n}","tryCatchPattern":"match load_kml(path, ...) {\n    Ok(shapes) => shapes,\n    Err(e) if e.to_string().starts_with(\"Malformed coordinates\") => {\n        eprintln!(\"Fix the KML coordinate pair: {e}\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Prefer 2D lon,lat coordinates and consistent dot decimal separators in KML","Lint KML files with an XML/coordinates checker before loading","Avoid hand-editing coordinates; re-export from the source tool"],"tags":["kml","parsing","coordinates"],"backgroundTag":"invalid-argument-format","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}