def generate_osm_xml(project_id: int, task_ids_str: str) -> str: """ Generate xml response suitable for loading into JOSM. A sample output file is in /backend/helpers/testfiles/osm-sample.xml """ # Note XML created with upload No to ensure it will be rejected by OSM if uploaded by mistake root = ET.Element( "osm", attrib=dict(version="0.6", upload="never", creator="HOT Tasking Manager"), ) if task_ids_str: task_ids = map(int, task_ids_str.split(",")) tasks = Task.get_tasks(project_id, task_ids) if not tasks or len(tasks) == 0: raise NotFound() else: tasks = Task.get_all_tasks(project_id) if not tasks or len(tasks) == 0: raise NotFound() fake_id = -1 # We use fake-ids to ensure XML will not be validated by OSM for task in tasks: task_geom = shape.to_shape(task.geometry) way = ET.SubElement( root, "way", attrib=dict(id=str((task.id * -1)), action="modify", visible="true"), ) for poly in task_geom: for point in poly.exterior.coords: ET.SubElement( root, "node", attrib=dict( action="modify", visible="true", id=str(fake_id), lon=str(point[0]), lat=str(point[1]), ), ) ET.SubElement(way, "nd", attrib=dict(ref=str(fake_id))) fake_id -= 1 xml_gpx = ET.tostring(root, encoding="utf8") return xml_gpx
def generate_gpx(project_id: int, task_ids_str: str, timestamp=None): """ Creates a GPX file for supplied tasks. Timestamp is for unit testing only. You can use the following URL to test locally: http://www.openstreetmap.org/edit?editor=id&#map=11/31.50362930069913/34.628906243797054&comment=CHANGSET_COMMENT&gpx=http://localhost:5000/api/v2/projects/{project_id}/tasks/queries/gpx%3Ftasks=2 """ if timestamp is None: timestamp = datetime.datetime.utcnow() root = ET.Element( "gpx", attrib=dict( xmlns="http://www.topografix.com/GPX/1/1", version="1.1", creator="HOT Tasking Manager", ), ) # Create GPX Metadata element metadata = ET.Element("metadata") link = ET.SubElement( metadata, "link", attrib=dict(href="https://github.com/hotosm/tasking-manager"), ) ET.SubElement(link, "text").text = "HOT Tasking Manager" ET.SubElement(metadata, "time").text = timestamp.isoformat() root.append(metadata) # Create trk element trk = ET.Element("trk") root.append(trk) ET.SubElement( trk, "name" ).text = f"Task for project {project_id}. Do not edit outside of this area!" # Construct trkseg elements if task_ids_str is not None: task_ids = map(int, task_ids_str.split(",")) tasks = Task.get_tasks(project_id, task_ids) if not tasks or len(tasks) == 0: raise NotFound() else: tasks = Task.get_all_tasks(project_id) if not tasks or len(tasks) == 0: raise NotFound() for task in tasks: task_geom = shape.to_shape(task.geometry) for poly in task_geom: trkseg = ET.SubElement(trk, "trkseg") for point in poly.exterior.coords: ET.SubElement( trkseg, "trkpt", attrib=dict(lon=str(point[0]), lat=str(point[1])), ) # Append wpt elements to end of doc wpt = ET.Element("wpt", attrib=dict(lon=str(point[0]), lat=str(point[1]))) root.append(wpt) xml_gpx = ET.tostring(root, encoding="utf8") return xml_gpx