Active mappers around us

Posted by rtnf on 20 November 2023 in English (English).

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 = "" 
bbox_api =""
for i in result:
    count = count + 1
    if count == 4:
        bbox_str = bbox_str + str(i)
        bbox_str = bbox_str + str(i) +","
print("See bbox visualization : ")
print("Download OSM data : ")

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,-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):
        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()
                        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"]
                    if kstring not in dictuser[currentUser]['bagtags']:
                        dictuser[currentUser]['bagtags'][kstring] = 1
                        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

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))

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

Login to leave a comment