Struggling with what feels like it should be an easy JSON-> Map Coordinates issue

Hey all,

I'm new to App Inventor but it looks great.

I'm working on a Geocaching App as a way of learning how this all fits together, and I'm at a point where I've got the app to fetch some JSON from a webserver which looks like this (ignore the coordinate values, these are just for testing, I'm yet to write the full backend!):

{"waypoints": [
  {
    "name": "Our House",
    "coordinates": {
      "latitude": 51,
      "longitude": 24
    }
  },
  {
    "name": "The 1st Target",
    "coordinates": {
      "latitude": 52,
      "longitude": 23
    }
  },

  {
    "name": "The 2nd Target",
    "coordinates": {
      "latitude": 53,
      "longitude": 22
    }
  }
]
}

When I initialise the screen, I want to set the map coordinates to the lat/lng at the first waypoint (Our House), but I'm really struggling to work out how to iterate over the list.

I've read the documentation and many of the posts on here, but for some reason my brain just can't get it right :frowning:

This is the relevant block - note that I come from a Python background, so this may just be me holding it wrong!

Thanks in advance for the help!

Like so ?

You may want to go a bit further, extract the names from the json, put them in a list, to be able to select which item to return

Thanks, this is the approach I'm used to taking with Python:

import json

jdict = json.loads("{JSON STRING}")

latitude = jdict["waypoints"][0]["coordinates"]["latitude"]

So I guess I'm getting a bit confused about why I can't just reference the appropriate sub-field.

I'll give your approach a go a bit later on, thanks again :slight_smile:

You are doing the same thing, just appears more long winded with blocks...

2 Likes

OK, that worked a treat, thanks, I can get the coordinates from the JSON and pass them to the map, however for some reason they appear to be truncated to 4 decimal places.

I've looked at the format as decimal number block, but even if I set that to 10, the value is truncated to ~4 places.

Obviously this throws the map out by miles, have I missed something somewhere?

Edit: If this should be in a new thread, I'm happy to do that... :slight_smile:

Can you capture the JSON as far back upstream as possible, to see how many digits it has originally?

Your code is correct in the first post, except for the fact that App Inventor is 1-based rather than 0-based, so for your key path you need to use 1 instead of 0 to get the first element in the list.

A reality check: When working with geocoordinate degrees, the following is an excellent example showing the precision of measurement using various degree decimal places.

decimal places |degrees |distance
0 |1.0 111 km
1 |0.1 11.1 km
2 |0.01 1.11 km
3 |0.001 111 m
4 |0.0001 11.1 m
5 |0.00001 1.11 m
6 |0.000001 |0.111 m
7 |0.0000001 1.11 cm
8 |0.00000001 1.11 mm

  • 10 decimal places is entirely inappropriate. That precision can never be resolved on an MIT Map
  • 5 decimal places is the maximum resolution possible with most gps receivers using the Location control. Newer cell phones have the ability to use multiple constellations to achieve slightly better maximum resolution; the LocationSensor cannot handle those.
  • I don't know the resolution possible with OpenStreetMaps (Map component) but the resolution is certainly no better than 6 or perhaps 7 places.
  • the behavior of the directory blocks is interesting

Your Blocks example yields the above information when the lat/long are set to 10 decimal precision as shown in green. The Blocks show what happens if you use the Format Math Blocks to extract the other values. Certainly no problem here.

by miles, hardly. Yes you are missing something somewhere, whether it is how you entered the coordinates on the json file, how you used the Map component or something else is not known because you did not share an example of what happened. You could show a screen capture, block images etc. It is apparent the dictionary blocks display six digits doing a DoIt but all the coded lat/lon information using an unlikely example of 10 digits after doing the DoIt is present. Maybe @ewpatton can explain the DoIT behavior.

Perhaps this information will help you understand what is wrong in your app. See Decimal degrees - GIS Wiki | The GIS Encyclopedia

Regards,
Steve

When a real number is rendered as a string it is rendered by default with 5 decimal places. Internally the system will use as many places as required to store the original precision though.

Examples:

From top to bottom:

  1. We can see that 1/3 is rendered as 0.33333 but the result of adding 1/3 + 1/3 + 1/3 is 1, as expected.
  2. If you try to add the string 0.33333 to itself twice then you only get 0.99999.
  3. If you place the number into a property that coerces it to a text, you will get the same result (because the default is 5 places).
  4. If you use the format as decimal number and give it a high precision, then when the text is converted back to a number it will be approximately the same (within the error limits of an IEEE 754 double floating point number).
1 Like