One day, I read a passage in a newspaper.
“The president directly observed the construction of earthquake-resistant houses in Sirnagalih Village, Cilaku Subdistrict, Cianjur Regency.”
Now, I’m just curious. How is the situation regarding the completion of OpenStreetMap data around that village? Who is the most active mapper around that area?
First, find the exact coordinates of Sirnagalih Village. Search for it on OpenStreetMap, zoom in enough, right-click, and then click ‘show address.’ The coordinates will be displayed.
Next, we need to convert these coordinates into a ‘bounding box’ format. I have created a simple Python script to convert coordinates into a bounding box (with a specified radius_km).
from geopy.distance import geodesic
def calculate_bounding_box(input_coordinate, radius_km):
# Convert input coordinate to (latitude, longitude) format
input_lat, input_lon = map(float, input_coordinate.split(','))
# Calculate bounding box coordinates
bounding_box = (
input_lon - (radius_km / 111.32), # left
input_lat - (radius_km / 111.32), # bottom
input_lon + (radius_km / 111.32), # right
input_lat + (radius_km / 111.32) # top
)
return bounding_box
# Example usage:
input_coordinate = "-6.855560091864419, 107.12470041831004" # Replace with your input coordinate
radius_km = 1
result = calculate_bounding_box(input_coordinate, radius_km)
count = 0
bbox_str = ""
bbox_view = "https://altilunium.github.io/bbox/?bbox="
bbox_api ="https://api.openstreetmap.org/api/0.6/map?bbox="
for i in result:
count = count + 1
if count == 4:
print(i)
bbox_str = bbox_str + str(i)
else:
print(i,end=",")
bbox_str = bbox_str + str(i) +","
print()
print("See bbox visualization : ")
print(bbox_view+bbox_str)
print()
print("Download OSM data : ")
print(bbox_api+bbox_str)
Input the coordinates, run the Python program, and you will receive the bounding box coordinates. In my case, the bounding box coordinates are “106.76161822320681,-6.645804632233569,106.77958444670664,-6.627838408733748”.
Next, use the OSM API to retrieve all the data around that bounding box.
Simply access https://api.openstreetmap.org/api/0.6/map?bbox=106.76161822320681,-6.645804632233569,106.77958444670664,-6.627838408733748 directly in your browser, but make sure to change the “bbox=” parameter to your bounding box coordinates first. Then, an XML file named “map.osm” will be downloaded.
Finally, use this script to process the downloaded OSM file.
import xml.etree.ElementTree as ET
import sys
sys.stdout = open(sys.stdout.fileno(), mode='w', encoding='utf-8', buffering=1)
dictuser = dict()
currentUser = ""
def iterate_osm_objects(osm_file_path):
try:
tree = ET.parse(osm_file_path)
root = tree.getroot()
# Iterate through all elements in the OSM file
for element in root.iter():
# Process each element as needed
for i in element.attrib:
if i == "user":
currentUser = element.attrib[i]
if element.attrib[i] not in dictuser:
dictuser[element.attrib[i]] = dict()
dictuser[element.attrib[i]]['count'] = 1
dictuser[element.attrib[i]]['bagtags'] = dict()
else:
dictuser[element.attrib[i]]['count'] = dictuser[element.attrib[i]]['count'] + 1
for j in element:
if j.tag == "tag":
kstring = j.attrib["k"]+"="+j.attrib["v"]
#print(j.attrib["k"]+"="+j.attrib["v"])
if kstring not in dictuser[currentUser]['bagtags']:
dictuser[currentUser]['bagtags'][kstring] = 1
else:
dictuser[currentUser]['bagtags'][kstring] = dictuser[currentUser]['bagtags'][kstring] + 1
except ET.ParseError as e:
print(f"Error parsing the OSM file: {e}")
except Exception as ex:
print(f"An error occurred: {ex}")
# Example usage:
osm_file_path = "sirnagalih.xml" # Replace with the actual path to your OSM XML file
iterate_osm_objects(osm_file_path)
sorted_dict = dict(sorted(dictuser.items(), key=lambda item: item[1]['count'], reverse=True))
for i in sorted_dict:
print (i,dictuser[i]['count'])
sorted_dict2 = dict(sorted(dictuser[i]['bagtags'].items(), key=lambda item: item[1], reverse=True))
for i in sorted_dict2:
print("["+str(sorted_dict2[i])+"] "+str(i))
print()
You’ll see the report regarding the most active users around that area, sorted by edit count and their frequently used tags. Something like this :
Dyah Wuri 9950
[2520] building=yes
[3] natural=wood
[2] leisure=sports_centre
[1] landuse=farmland
[1] highway=construction
Alex Rollin 4460
[365] building=yes
[50] natural=tree
[14] natural=water
[13] bicycle=designated
[13] foot=designated
[13] highway=path
[13] segregated=no
[9] natural=wood
[9] building=house
[4] highway=residential
[4] water=pond
[4] highway=pedestrian
[3] landuse=farmland
[3] service=driveway
[3] surface=cobblestone
[2] incline=10°
[2] surface=paving_stones
[2] width=2.5
[2] landuse=grass
[2] leisure=pitch
[2] landuse=cemetery
[1] amenity=toilets
[1] access=private
[1] leisure=swimming_pool
...