-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adapt urbanpy tutorial for schools in Florianópolis #5
Comments
Update 2022-01-19Hi all 👋 here's an update on the progress so far. I've got a recently committed jupyter notebook focused on a spatial model for florianopolis. I've worked through over half of the tutorial, and in the process open up a couple of issues to help solve some data problems I ran into.
🚧 Blocker When I try to run the line es = up.download.overpass_pois(bounds=ba.total_bounds, facilities='education') I get an error
Not sure why this is, since the code is identical to the tutorial and when I run ba.total_bounds for florianopolis, I get an output of array([-48.613 , -27.847 , -48.3585929, -27.379 ]) Which seems similar enough to what is output in the tutorial just without as many decimal places. Any thoughts on why this might be happening? |
I'll take a look! Rob, can you share the notebook/script you are running to use as a reproducible example? |
Thanks so much @bitsandbricks! The notebook is linked above and here. But I've set it up with Not sure if you've worked with GitHub codespaces much, but you could try running a codespace like I show below and see if everything in the notebook will run through the codespace. Let me know if this work well for you to test. 👍🏻 |
Ohh it was right in front of my eyes! Sorry Rob. I'll keep you posted |
Same thing on my edge, hope this is not a common error. Also as a side note, the new version of urbanpy (in the master branch for the moment) have a new more flexible function to download data from overpass. I did a fast example of how to query education facilities inside Florianopolis in this colab notebook. |
✅ UpdatesThanks to help from @bitsandbricks and @Claudio9701 I was able to make good progress on the model for florianopolis. I created a count of the educational facilities in florianopolis (but see my question below) Also I created a map of the educational facilities in florianopolis. Next up is calculating the walking distances to educational facilities. ❓ Questions
For now I've selected: school, kindergarten, language school, and library. What do you think?
What would be appropriate?
|
I think Other options for distance calculation are |
I appreciate that explanation 🙌 Even though florianopolis is a smaller area, I still think haversine will work 👍 |
Thanks to your help in #7, @Claudio9701. I was able to get the docker container spun up 🎉 ❓ Follow-up questions:
I get the error:
Full error message below. What do you think might be happening here? Somethings happening with the JSON decoder, but I'm not sure how to resolve.
Maybe this is due to some upstream issue with the JSON portion mentioned in my point 1 above. JSONDecodeError Traceback (most recent call last)
File /opt/homebrew/lib/python3.10/site-packages/requests/models.py:971, in Response.json(self, **kwargs)
970 try:
--> 971 return complexjson.loads(self.text, **kwargs)
972 except JSONDecodeError as e:
973 # Catch JSON-related errors and raise as requests.JSONDecodeError
974 # This aliases json.JSONDecodeError and simplejson.JSONDecodeError
File /opt/homebrew/Cellar/[email protected]/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/__init__.py:346, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
343 if (cls is None and object_hook is None and
344 parse_int is None and parse_float is None and
345 parse_constant is None and object_pairs_hook is None and not kw):
--> 346 return _default_decoder.decode(s)
347 if cls is None:
File /opt/homebrew/Cellar/[email protected]/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)
333 """Return the Python representation of ``s`` (a ``str`` instance
334 containing a JSON document).
335
336 """
--> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end())
338 end = _w(s, end).end()
File /opt/homebrew/Cellar/[email protected]/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/decoder.py:355, in JSONDecoder.raw_decode(self, s, idx)
...
973 # Catch JSON-related errors and raise as requests.JSONDecodeError
974 # This aliases json.JSONDecodeError and simplejson.JSONDecodeError
--> 975 raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
JSONDecodeError: Expecting value: line 1 column 1 (char 0) |
This notebooks can help: https://github.com/EL-BID/urbanpy/blob/master/notebooks/Creating%20an%20interactive%20webapp.ipynb https://github.com/Claudio9701/urbanpy-brazil-demo/blob/master/Pop_Access_UrbanPy_Demo_BR.ipynb |
Bravo Rob! Back to your initial questions: - We have many different types of points of interest for educational facilities. Which should we include? Based on the OSM project definitions for their keys an values (here, I always have it around cause I keep forgetting the details :D) we want "school": "School and grounds - primary, middle and seconday schools" This is a data layer that can definitely be replaced by an "official" list depending on specific needs (i.e only primary schools), but the OSM one will be fine for preliminary results
In the same spirit, until we are asked for a specific range, we can go for the population in compulsory schooling range (ages 6 to 14 in Brazil). Eyeballing the population pyramid I'd say that's a little bit under 7% of the entire population. Of course, this already vague number will differ from place to place, and specially contrasting rural vs urban areas, but should be fine for a starting point. We can document the rationale and carry on! |
@Claudio9701 thanks so much for the pairing session today 🌟 A few quick updates:
Error: No such object: osrm_routing_server_south-america_brazil_sul_foot docker: Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:5000 -> 0.0.0.0:0: listen tcp 0.0.0.0:5000: bind: address already in use. Error: No such container: osrm_extract |
Quick update!I figured out what was going on with the port error we were running into w/ docker @Claudio9701. We did need to run I'm able to connect to the osm server using the original code in the tutorial 🎉 I do need to have docker open and running on my machine for it to work :
❓ for @Claudio9701, what's the typical run time for the. Currently, I have h3_resolution set to 8, this is for the city of florianopolis. Is this too high? Right now the function below has run for 30 min. I could also trying spinning up a GitHub codespace and seeing if it runs faster on one of our servers. Let me know what you think. distance_duration = hex_flor.apply(
lambda row: up.routing.osrm_route(
origin=row.geometry.centroid,
destination = schools.iloc[row['closest_school']]['geometry']
),
result_type='expand',
axis=1,
) |
CC: @bitsandbricks on above issue for visibility. |
Hello Rob, great news you could spin up the docker container 👏🏼🙌🏽🚀! Next version of urbanpy need to give the user the ability to choose on which port to run the osrm server. Regarding the other question, resolution 8 should be good for a small city like Florianópolis. I usually run this function with from tqdm.notebook import tqdm
tqdm.pandas()
df.progress_apply(...) If this is taking to much time, I've also used pandarallel to speed up the calculation. from pandarallel import pandarallel
pandarallel.initialize(progress_bar=True)
df.parallel_apply(...) This also have a progress bar that give you a hint of how much time the processing will take. Both are install using pip. If it is still taking too much time you could filter out hexagons without population or with population bellow a certain threshold. But in my experience this it's almost never necessary. Hope you find this useful! |
Bump |
👋🏻 Just so I'm extra clear on which step/how to do this estimation for school age children based on the population pyramid does this look right to you @bitsandbricks and @Claudio9701 pop_flor = up.geom.filter_population(full_pop_brazil_southeast, flor)
pop_flor['population'] = pop_flor['population'].parallel_apply(lambda x: x*0.07)
pop_flor.head() |
It does to me! |
I am going to close this issue for our Florianópolis model since we have a notebook that does this analysis in our repo. I'll create a new issue for re-running this model with INEP's databases |
We will adapt the existing urbanpy tutorial for the city of Florianópolis as a first step to creating predictions on the much larger state of Pará
The text was updated successfully, but these errors were encountered: