from bs4 import BeautifulSoup import xml.etree.cElementTree as ET import requests from segment import soup_to_segment, Segment from station_on_line import soup_to_station_on_line, Station_on_line from stationsweb import get_page import time def distance_coords(c1,c2): latd1 = c1[0] longd1 = c1[1] latd2 = c2[0] longd2 = c2[1] R = 6378.137 lat1 = math.radians(latd1) long1 = math.radians(longd1) lat2 = math.radians(latd2) long2 = math.radians(longd2) #d = 2R × sin⁻¹(√[sin²((θ₂ - θ₁)/2) + cosθ₁ × cosθ₂ × sin²((φ₂ - φ₁)/2)]) d = 2*R*math.asin(math.sqrt(math.sin((lat1-lat2)/2)**2+math.cos(lat1)*math.cos(lat2)*math.sin((long2-long1)/2)**2)) return(d) class Line: def __init__(self,number,segments,stations_on_line): self.number = number self.segments = segments self.stations_on_line = stations_on_line def vertices(self): gpx_tree = ET.parse(f"../data/gpx/{self.number}.gpx") gpx_element = gpx_tree.getroot() trk_element = gpx_element[1] trkseg_element = trk_element[1] coords = [] for trkpt_element in trkseg_element: coords.append((float(trkpt_element.attrib["lat"]),float(trkpt_element.attrib["lon"]))) return(coords) @classmethod def fromXML(cls,line_element): number = int(line_element.attrib["number"]) segments_element = line_element[0] segments=[] for segment_element in segments_element: segments.append(Segment.fromXML(segment_element)) stations_on_line_element = line_element[1] stations_on_line = [] for station_on_line_element in stations_on_line_element: stations_on_line.append(Station_on_line.fromXML(station_on_line_element)) return(cls(number,segments,stations_on_line)) def toXML(self): line_element = ET.Element("Line") line_element.attrib["number"]=str(self.number) segments_element = ET.Element("Segments") for segment in self.segments: segments_element.append(segment.toXML()) line_element.append(segments_element) stations_on_line_element = ET.Element("Stations_on_line") for station_on_line in self.stations_on_line: stations_on_line_element.append(station_on_line.toXML()) line_element.append(stations_on_line_element) return(line_element) def stationsweb_url(number): return(f"https://www.stationsweb.nl/lijnlijst.asp?lijn={number}") def table_to_segments(segments_table): segments = [] for segment_soup in segments_table.findAll("tr"): segments.append(soup_to_segment(segment_soup)) return(segments) def table_to_stations_on_line(stations_on_line_table): stations_on_line = [] even = False for station_on_line_soup in stations_on_line_table.findAll("tr"): #If this was not here every station station would come two times #In the list. if(even): even = False continue station_on_line = soup_to_station_on_line(station_on_line_soup) if(station_on_line!=None): stations_on_line.append(station_on_line) even = True return(stations_on_line) def retrieve_line(number): stationsweb_page = get_page(stationsweb_url(number)) stationsweb_soup = BeautifulSoup(stationsweb_page.text, "html.parser") tables = stationsweb_soup.findAll("table") try: segments_table = tables[3] except: print(f"The following url had an issue: {stationsweb_url(number)}, and the table array has length {len(tables)} and has the following contents {tables}") stations_on_line_table = tables[4] segments = table_to_segments(segments_table) stations_on_line = table_to_stations_on_line(stations_on_line_table) line = Line(number,segments,stations_on_line) return(line)