9

I have a rather big json file with coordinates in the following format

"[[3.2,1],[4.8,2]]"

which represents (3.2,1) and (4.8,2)

I'm using these coördinates to generate a D3 geographic map, but when php is modelling this information into a geoJSONobject I encounter the following error:

I need to transform the coordinates into a array for which I use json_decode. However:

json_decode("[[3.2,1],[4.8,2]]")

returns

Array
(
[0] => Array
    (
        [0] => 3
        [1] => 1
    )
[1] => Array
    (
        [0] => 4
        [1] => 2
    )
)

Where I lose the decimals. How can I prevent this?

Edit:

{"type": "FeatureCollection",
 "features": [{
        "type": "Feature",
        "geometry": {
            "type": "Polygon",
            "coordinates": "[[[8.7, 11], [8.89, 12.13],[9.27, 12.13], [9.9, 12], [9.7, 10.8], [8.7, 11]]]"
        },
        "properties": {
            "name": "04",
            "count": "25"
        }
    }]
}

This is an example of the data I'm getting as output. (It is supposed to represent a map of rooms which are get a density color by its usage)

I am able to parse this using jQuery.parseJSON(data), but running the following D3 code generates the weirdest errors:

val(svgname).append("g")
    .selectAll("path")
    .data(geoJSONobject.features)
    .enter().append("path")
    .attr("d", path)
    ...

error I think it's because of the quotes around the array of coordinates.

Edit (2) - actual solution

The solution I accepted was a workaround, but the true issue was localized php-settings. using:

echo json_encode($dataset, JSON_NUMERIC_CHECK);

in the php-file, all the issues were resolved. Though I'd update the question since it is still being looked at (if anyone would encouter the issue)

dietervdf
  • 400
  • 2
  • 12
  • 2
    what version of PHP are you using? I'm running 5.5.12 and it leaves them as floats. – Tom Jardine-McNamara Jul 09 '15 at 14:35
  • 2
    I do not know what causes this, but maybe as a workaround: Pass them around as strings maybe, then cast them to floats when you receive the coordinates. – Erwin Moller Jul 09 '15 at 14:39
  • The docs (http://php.net/json_decode) do mention casting large integers to floats, but yours don't look very large ;) @ErwinMoller's suggestion of using strings will absolutely work. Whether you're curious about *why* this is happening for you is another matter. – Tom Jardine-McNamara Jul 09 '15 at 14:41
  • Looks good for `5.2.0 - 7.0.0alpha2` http://3v4l.org/rtamO#v520 `var_dump()` the var holding the JSON. – AbraCadaver Jul 09 '15 at 14:50
  • I'm still using php 5.2.4, upgrading is sadly enough not possible... Is it possible to elaborate further on the passing around as strings method? – dietervdf Jul 09 '15 at 15:41
  • It's real simple, he just means store them as strings and when you need to use them, convert them to floats. – Overcode Jul 09 '15 at 16:11
  • 1
    Just wrap the values in quotes: `json_decode('[["3.2","1"],["4.8","2"]]');` – Travesty3 Jul 09 '15 at 16:13
  • Please provide a minimal example, as per the SO guidelines. Also, mixing in some jQuery claims doesn't help either to clarify the problem. – Ulrich Eckhardt Jul 09 '15 at 16:43
  • The problem is solved by applying @Travesty3 s solution. I would gladly accept that solution if he would post it as an answer. – dietervdf Jul 09 '15 at 17:12

2 Answers2

9

I had the same problem. I solved it using the followin regex

SOLUTION 1

$yourJsonVariable = preg_replace('/:\s*(\-?\d+(\.\d+)?([e|E][\-|\+]\d+)?)/', ': "$1"', $yourJsonVariable);

Convert it into array

$array = json_decode($yourJsonVariable, true);

Credits goes to this SO LINK

SOLUTION 2

You can set ini_set('precision',1);

SOLUTION 3

$decoded = json_decode($encoded, true, null, JSON_BIGINT_AS_STRING);

NOTE: The Last solution will work only for PHP > 5.4

You might want to take a look at this Blog

Community
  • 1
  • 1
Abhinav
  • 8,028
  • 12
  • 48
  • 89
  • 1
    Should be marked as correct answer! Proposed as **Solution 1** worked for me like a charm – Ragen Dazs Nov 13 '17 at 12:39
  • After some tests, regex are matching numbers inside quotes ```/:\s*(?!\B"[^"]*)(\-?\d+(\.\d+)?([e|E][\-|\+]\d+)?)(?![^"]*"\B)/``` this condition will only quote numbers that are not already quoted – Ragen Dazs Nov 13 '17 at 12:59
0

Just wrap the values in quotes: json_decode('[["3.2","1"],["4.8","2"]]');

Travesty3
  • 14,351
  • 6
  • 61
  • 98
  • That's a workaround rather than a solution. It relies on dynamic typing in PHP and/or ECMAScript, where `"3.1"` and `3.1` are interpreted depending on the context. Formally, `"3.1"` in JSON is a string, while `3.1` is a floating-point type, and any JSON decoder worth its name should be able to decode it. – Ulrich Eckhardt Jul 09 '15 at 21:20
  • Well, I guess the solution would be to work with the lastest version of php. Since Tom Jenkins and others confirmed it to be working on their machines. Sadly enough I can't perform the upgrade. Meanwhile this *solved* my problem, which is why I marked it as *solution*. – dietervdf Jul 09 '15 at 22:00