मैं म्यूनिख से वेनिस तक पैदल यात्रा करने और खूबसूरत आल्प्स में ट्रैकिंग करने का सपना देखता हूं। लेकिन चूंकि मुझे अभी भी अपना रोजमर्रा का जीवन जीना है, इसलिए मेरी यात्रा में कई चरण शामिल होंगे, प्रत्येक साहसिक कार्य के बीच सप्ताह, महीने या यहां तक कि साल भी लगेंगे। यह ठीक है, क्योंकि यह गंतव्य से अधिक यात्रा के बारे में है। हालाँकि, मैं हमेशा इन रास्तों को फिर से देखने का एक तरीका चाहता था, यह देखने के लिए कि मैं कितनी दूर आ गया हूँ और अपने लक्ष्य के कितने करीब हूँ। मैं अपनी प्रगति का जश्न मनाने और यात्रा को आगे बढ़ाने के लिए खुद को प्रेरित करने का एक तरीका चाहता था।
सौभाग्य से, कई आउटडोर और स्पोर्ट्स ऐप्स, जैसे एडिडास रनिंग, कोमूट, स्ट्रावा और अन्य, हमें दयालुतापूर्वक अपनी गतिविधियों को जीपीएक्स फ़ाइलों के रूप में निर्यात करने की अनुमति देते हैं। हालाँकि, उन GPX फ़ाइलों के साथ जाने के लिए कहीं नहीं है।
यहीं पर पाइथॉन और फोलियम काम में आते हैं। हाल ही में मेरी नजर फोलियम पर पड़ी, जो इंटरैक्टिव मानचित्र बनाने के लिए एक शक्तिशाली पायथन लाइब्रेरी है। यह GPX फ़ाइलों जैसे भौगोलिक डेटा को आसानी से शामिल कर सकता है, और अनुकूलन और अन्वेषण की अनुमति देता है। मेरे द्वारा एकत्र किए गए जीपीएस डेटा की प्रचुरता का लाभ उठाते हुए, मैंने एक मानचित्र तैयार करने के लिए फोलियम के साथ प्रयोग करना शुरू किया, जो मेरे बाहरी भ्रमण को जीवंत बनाता है।
कुछ शोध और बहुत सारे परीक्षण के बाद, मैं एक मानचित्र लेकर आया जो मुझे अपनी पिछली बाहरी गतिविधियों को फिर से देखने की अनुमति देता है:
इसलिए, यदि आप भी मेरे जैसे हैं और आपके पास बिना किसी उद्देश्य के जीपीएस डेटा का खजाना है, तो आपको आश्चर्य हो सकता है कि मैं वहां तक कैसे पहुंचा। तो, इस लेख में, मैं समझाऊंगा कि अपनी जीपीएक्स फाइलों में जान कैसे फूंकी जाए।
आइए अन्वेषण और मानचित्रण के अभियान पर चलें!
इस साहसिक कार्य को शुरू करने के लिए, हम ज्यूपिटर नोटबुक का उपयोग करेंगे। ज्यूपिटर नोटबुक क्यों? यह एक शानदार इंटरैक्टिव कंप्यूटिंग वातावरण है जो हमें कोड, विज़ुअलाइज़ेशन और टेक्स्ट को संयोजित करने की अनुमति देता है, जो इसे हमारे डेटा और फोलियम लाइब्रेरी के साथ प्रयोग करने के लिए एकदम सही बनाता है।
यदि आपने अभी तक ज्यूपिटर नोटबुक स्थापित नहीं किया है, तो उनकी आधिकारिक वेबसाइट पर दिए गए निर्देशों का पालन करें। एक बार इंस्टॉल हो जाने पर, आप एक नया ज्यूपिटर नोटबुक बना सकते हैं और अपनी यात्रा के लिए तैयार हो सकते हैं।
इसके बाद, हमें अपने मानचित्र के लिए कच्चे माल की आवश्यकता है - जीपीएक्स फाइलें। जीपीएक्स (जीपीएस एक्सचेंज फॉर्मेट) एक व्यापक रूप से उपयोग किया जाने वाला फ़ाइल प्रारूप है जो स्थान डेटा, जैसे अक्षांश, देशांतर, ऊंचाई और समय को संग्रहीत करता है, जो इसे बाहरी गतिविधियों पर नज़र रखने के लिए आदर्श बनाता है।
यदि आप एक उत्साही पैदल यात्री, धावक, साइकिल चालक या स्कीयर हैं, तो संभावना है कि आपने पहले से ही किसी आउटडोर या खेल ऐप का उपयोग करके विभिन्न भ्रमणों को ट्रैक कर लिया है। उनमें से बहुत सारे ऐप्स आपको अपनी गतिविधियों को जीपीएक्स प्रारूप में निर्यात करने की अनुमति देते हैं। तो उन GPX फ़ाइलों को इकट्ठा करें, और चलिए शुरू करें!
हमारे पायथन कोड में, हम GPX फ़ाइलों को पार्स करने और अक्षांश, देशांतर, ऊंचाई, गति और दूरी जैसे आवश्यक ट्रेल डेटा निकालने के लिए gpxpy लाइब्रेरी का उपयोग करेंगे। Parse_gpx() फ़ंक्शन हमारे लिए सभी भारी काम करेगा:
### READ GPX FILES import gpxpy import pandas as pd import numpy as np import haversine as hs from pathlib import Path def parse_gpx(file_path): # parse gpx file to pandas dataframe gpx = gpxpy.parse(open(file_path), version='1.0') data = [] points = [] for track in gpx.tracks: for segment in track.segments: for point_idx, point in enumerate(segment.points): points.append(tuple([point.latitude, point.longitude])) # calculate distances between points if point_idx == 0: distance = np.nan else: distance = hs.haversine( point1=points[point_idx-1], point2=points[point_idx], unit=hs.Unit.METERS ) data.append([point.longitude, point.latitude,point.elevation, point.time, segment.get_speed(point_idx), distance]) columns = ['Longitude', 'Latitude', 'Elevation', 'Time', 'Speed', 'Distance'] gpx_df = pd.DataFrame(data, columns=columns) return points, gpx_df activities = {} frames = [] for activity_type in ACTIVITY_TYPES: activities[activity_type] = {} pathlist = Path(activity_type).glob('**/*.gpx') for path in pathlist: # exclude hidden directories and files # will lead to performance issues if there are lots of hidden files if any(part.startswith('.') for part in path.parts): continue activity_group = path.parts[1] activity_name = path.parts[2] if activity_group not in activities[activity_type]: activities[activity_type][activity_group] = [] points, gpx_df = parse_gpx(path) gpx_df['Elevation_Diff'] = np.round(gpx_df['Elevation'].diff(), 2) gpx_df['Cum_Elevation'] = np.round(gpx_df['Elevation_Diff'].cumsum(), 2) gpx_df['Cum_Distance'] = np.round(gpx_df['Distance'].cumsum(), 2) gpx_df['Gradient'] = np.round(gpx_df['Elevation_Diff'] / gpx_df['Distance'] * 100, 1) activities[activity_type][activity_group].append({ 'name': activity_name.replace('.gpx', '').replace('_', ' '), 'points': points, 'gpx_df': gpx_df }) frames.append(gpx_df) df = pd.concat(frames) df
इससे हमें किसी गतिविधि का सभी आवश्यक डेटा मिल जाता है: सभी जीपीएस निर्देशांक की एक सूची और एक पांडा डेटाफ़्रेम जिसमें सभी प्रकार के मेट्रिक्स होते हैं।
हमारे जीपीएस डेटा को अब पांडास डेटाफ़्रेम में व्यवस्थित करके, हम एक इंटरैक्टिव मानचित्र पर अपनी बाहरी गतिविधियों की कल्पना कर सकते हैं। फोलियम इस कार्य को आसान बनाता है:
### CONFIG # LOCATION = None LOCATION = [48.13743, 11.57549] # latitude, longitude ZOOM_START = 10 ACTIVITY_TYPES = { 'Hiking': { 'icon': 'person-hiking', 'color': 'green' }, 'Running': { 'icon': 'person-running', 'color': 'orange' }, 'Biking': { 'icon': 'person-biking', 'color': 'red' }, 'Skiing': { 'icon': 'person-skiing', 'color': 'blue' } }
### READ GPX FILES import gpxpy import pandas as pd import numpy as np import haversine as hs from pathlib import Path def parse_gpx(file_path): # parse gpx file to pandas dataframe gpx = gpxpy.parse(open(file_path), version='1.0') data = [] points = [] for track in gpx.tracks: for segment in track.segments: for point_idx, point in enumerate(segment.points): points.append(tuple([point.latitude, point.longitude])) # calculate distances between points if point_idx == 0: distance = np.nan else: distance = hs.haversine( point1=points[point_idx-1], point2=points[point_idx], unit=hs.Unit.METERS ) data.append([point.longitude, point.latitude,point.elevation, point.time, segment.get_speed(point_idx), distance]) columns = ['Longitude', 'Latitude', 'Elevation', 'Time', 'Speed', 'Distance'] gpx_df = pd.DataFrame(data, columns=columns) return points, gpx_df activities = {} frames = [] for activity_type in ACTIVITY_TYPES: activities[activity_type] = {} pathlist = Path(activity_type).glob('**/*.gpx') for path in pathlist: # exclude hidden directories and files # will lead to performance issues if there are lots of hidden files if any(part.startswith('.') for part in path.parts): continue activity_group = path.parts[1] activity_name = path.parts[2] if activity_group not in activities[activity_type]: activities[activity_type][activity_group] = [] points, gpx_df = parse_gpx(path) gpx_df['Elevation_Diff'] = np.round(gpx_df['Elevation'].diff(), 2) gpx_df['Cum_Elevation'] = np.round(gpx_df['Elevation_Diff'].cumsum(), 2) gpx_df['Cum_Distance'] = np.round(gpx_df['Distance'].cumsum(), 2) gpx_df['Gradient'] = np.round(gpx_df['Elevation_Diff'] / gpx_df['Distance'] * 100, 1) activities[activity_type][activity_group].append({ 'name': activity_name.replace('.gpx', '').replace('_', ' '), 'points': points, 'gpx_df': gpx_df }) frames.append(gpx_df) df = pd.concat(frames) df That leaves us with all the necessary data of an activity: a list of all the GPS coordinates and a Pandas DataFrame containing all kinds of metrics. Plotting GPX Trails on the Interactive Map With our GPS data now organized in a Pandas DataFrame, we can visualize our outdoor activities on an interactive map. Folium makes this task a breeze: ### CONFIG # LOCATION = None LOCATION = [48.13743, 11.57549] # latitude, longitude ZOOM_START = 10 ACTIVITY_TYPES = { 'Hiking': { 'icon': 'person-hiking', 'color': 'green' }, 'Running': { 'icon': 'person-running', 'color': 'orange' }, 'Biking': { 'icon': 'person-biking', 'color': 'red' }, 'Skiing': { 'icon': 'person-skiing', 'color': 'blue' } } We'll create a map centered at a specific location (you can choose one or let the code determine the center based on your data). We'll assign unique colors and icons to each activity type, such as hiking, running, biking, or skiing. The ACTIVITY_TYPES dictionary will help us with this. ### CREATE MAP import folium from folium import plugins as folium_plugins if LOCATION: location = LOCATION else: location=[df.Latitude.mean(), df.Longitude.mean()] map = folium.Map(location=location, zoom_start=ZOOM_START, tiles=None) folium.TileLayer('OpenStreetMap', name='OpenStreet Map').add_to(map) folium.TileLayer('Stamen Terrain', name='Stamen Terrain').add_to(map) ### MAP TRAILS def timedelta_formatter(td): td_sec = td.seconds hour_count, rem = divmod(td_sec, 3600) hour_count += td.days * 24 minute_count, second_count = divmod(rem, 60) return f'{hour_count}h, {minute_count}min, {second_count}s' def create_activity_popup(activity): df = activity['gpx_df'] attributes = { 'Date': { 'value': df['Time'][df.index[0]].strftime("%m/%d/%Y"), 'icon': 'calendar' }, 'Start': { 'value': df['Time'][df.index[0]].strftime("%H:%M:%S"), 'icon': 'clock' }, 'End': { 'value': df['Time'][df.index[-1]].strftime("%H:%M:%S"), 'icon': 'flag-checkered' }, 'Duration': { 'value': timedelta_formatter(df['Time'][df.index[-1]]-df['Time'][df.index[0]]), 'icon': 'stopwatch' }, 'Distance': { 'value': f"{np.round(df['Cum_Distance'][df.index[-1]] / 1000, 2)} km", 'icon': 'arrows-left-right' }, 'Average Speed': { 'value': f'{np.round(df.Speed.mean() * 3.6, 2)} km/h', 'icon': 'gauge-high' }, 'Max. Elevation': { 'value': f'{np.round(df.Elevation.max(), 2)} m', 'icon': 'mountain' }, 'Uphill': { 'value': f"{np.round(df[df['Elevation_Diff']>0]['Elevation_Diff'].sum(), 2)} m", 'icon': 'arrow-trend-up' }, 'Downhill': { 'value': f"{np.round(abs(df[df['Elevation_Diff']<0]['Elevation_Diff'].sum()), 2)} m", 'icon': 'arrow-trend-down' }, } html = f"<h4>{activity['name'].upper()}</h4>" for attribute in attributes: html += f'<i class="fa-solid fa-{attributes[attribute]["icon"]}" title="{attribute}"> {attributes[attribute]["value"]}</i></br>' return folium.Popup(html, max_width=300) feature_groups = {} for activity_type in activities: color = ACTIVITY_TYPES[activity_type]['color'] icon = ACTIVITY_TYPES[activity_type]['icon'] for activity_group in activities[activity_type]: # create and store feature groups # this allows different activity types in the same feature group if activity_group not in feature_groups: # create new feature group fg = folium.FeatureGroup(name=activity_group, show=True) feature_groups[activity_group] = fg map.add_child(fg) else: # use existing fg = feature_groups[activity_group] for activity in activities[activity_type][activity_group]: # create line on map points = activity['points'] line = folium.PolyLine(points, color=color, weight=4.5, opacity=.5) fg.add_child(line) # create marker marker = folium.Marker(points[0], popup=create_activity_popup(activity), icon=folium.Icon(color=color, icon_color='white', icon=icon, prefix='fa')) fg.add_child(marker) map.add_child(folium.LayerControl(position='bottomright')) folium_plugins.Fullscreen(position='topright').add_to(map) map
अन्वेषण और मानचित्रण की इस यात्रा में, हमने सीखा है कि सांसारिक जीपीएक्स फ़ाइलों को एक गतिशील और इंटरैक्टिव मानचित्र में बदलने के लिए पायथन और फोलियम का उपयोग कैसे करें। अब, आप अपने बाहरी रोमांचों को फिर से जी सकते हैं, अपनी प्रगति का जश्न मना सकते हैं और अपनी यात्रा के अगले चरण के लिए प्रेरित रह सकते हैं।
हालाँकि, आपके मानचित्र को अनुकूलित, विस्तारित और बेहतर बनाने के कई तरीके हैं। तो अपनी जीपीएक्स फ़ाइलें लें, ज्यूपिटर नोटबुक चालू करें, और अपनी पिछली बाहरी गतिविधियों को मानचित्र पर जीवंत होने दें!
हैप्पी मैपिंग!
देखते रहिए क्योंकि अभी बहुत कुछ आना बाकी है:
यहाँ भी प्रकाशित किया गया है.