paint-brush
मैंने अपनी बाहरी गतिविधियों को देखने के लिए पायथन और फोलियम का उपयोग कैसे कियाद्वारा@lukaskrimphove
7,795 रीडिंग
7,795 रीडिंग

मैंने अपनी बाहरी गतिविधियों को देखने के लिए पायथन और फोलियम का उपयोग कैसे किया

द्वारा Lukas Krimphove14m2023/09/06
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

अन्वेषण और मानचित्रण के अभियान पर निकलें! जानें कि अपनी GPX फ़ाइलों में जान कैसे डालें और फ़ोलियम का उपयोग करके इंटरैक्टिव मानचित्र कैसे बनाएं।
featured image - मैंने अपनी बाहरी गतिविधियों को देखने के लिए पायथन और फोलियम का उपयोग कैसे किया
Lukas Krimphove HackerNoon profile picture
0-item

मैं म्यूनिख से वेनिस तक पैदल यात्रा करने और खूबसूरत आल्प्स में ट्रैकिंग करने का सपना देखता हूं। लेकिन चूंकि मुझे अभी भी अपना रोजमर्रा का जीवन जीना है, इसलिए मेरी यात्रा में कई चरण शामिल होंगे, प्रत्येक साहसिक कार्य के बीच सप्ताह, महीने या यहां तक कि साल भी लगेंगे। यह ठीक है, क्योंकि यह गंतव्य से अधिक यात्रा के बारे में है। हालाँकि, मैं हमेशा इन रास्तों को फिर से देखने का एक तरीका चाहता था, यह देखने के लिए कि मैं कितनी दूर आ गया हूँ और अपने लक्ष्य के कितने करीब हूँ। मैं अपनी प्रगति का जश्न मनाने और यात्रा को आगे बढ़ाने के लिए खुद को प्रेरित करने का एक तरीका चाहता था।


सौभाग्य से, कई आउटडोर और स्पोर्ट्स ऐप्स, जैसे एडिडास रनिंग, कोमूट, स्ट्रावा और अन्य, हमें दयालुतापूर्वक अपनी गतिविधियों को जीपीएक्स फ़ाइलों के रूप में निर्यात करने की अनुमति देते हैं। हालाँकि, उन GPX फ़ाइलों के साथ जाने के लिए कहीं नहीं है।


यहीं पर पाइथॉन और फोलियम काम में आते हैं। हाल ही में मेरी नजर फोलियम पर पड़ी, जो इंटरैक्टिव मानचित्र बनाने के लिए एक शक्तिशाली पायथन लाइब्रेरी है। यह 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

इससे हमें किसी गतिविधि का सभी आवश्यक डेटा मिल जाता है: सभी जीपीएस निर्देशांक की एक सूची और एक पांडा डेटाफ़्रेम जिसमें सभी प्रकार के मेट्रिक्स होते हैं।

इंटरैक्टिव मानचित्र पर GPX ट्रेल्स प्लॉट करना

हमारे जीपीएस डेटा को अब पांडास डेटाफ़्रेम में व्यवस्थित करके, हम एक इंटरैक्टिव मानचित्र पर अपनी बाहरी गतिविधियों की कल्पना कर सकते हैं। फोलियम इस कार्य को आसान बनाता है:


 ### 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' } }
  • हम एक विशिष्ट स्थान पर केंद्रित एक मानचित्र बनाएंगे (आप किसी एक को चुन सकते हैं या कोड को आपके डेटा के आधार पर केंद्र निर्धारित करने दे सकते हैं)।
  • हम प्रत्येक गतिविधि प्रकार, जैसे लंबी पैदल यात्रा, दौड़, बाइकिंग या स्कीइंग के लिए अद्वितीय रंग और आइकन निर्दिष्ट करेंगे। ACTIVITY_TYPES शब्दकोश इसमें हमारी सहायता करेगा।
 ### 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
  • हम ट्रेल्स को उनके समूह नाम के आधार पर समूहीकृत करने के लिए फोलियम्स फ़ीचरग्रुप अवधारणाओं का उपयोग करेंगे। यह हमें बाद में कुछ गतिविधि समूहों को दिखाने और छिपाने की अनुमति देगा।
  • अब, हम अपने पार्स किए गए डेटा के माध्यम से पुनरावृत्ति करेंगे और फोलियम की पॉलीलाइन और मार्कर ऑब्जेक्ट का उपयोग करके मानचित्र पर प्रत्येक निशान को प्लॉट करेंगे। पॉलीलाइन वास्तविक निशान का प्रतिनिधित्व करेगी, जबकि मार्कर प्रत्येक गतिविधि के लिए शुरुआती बिंदु के रूप में कार्य करेगा। जब आप किसी मार्कर पर क्लिक करते हैं, तो एक पॉपअप संबंधित निशान के बारे में प्रासंगिक जानकारी प्रदर्शित करेगा।

निष्कर्ष

अन्वेषण और मानचित्रण की इस यात्रा में, हमने सीखा है कि सांसारिक जीपीएक्स फ़ाइलों को एक गतिशील और इंटरैक्टिव मानचित्र में बदलने के लिए पायथन और फोलियम का उपयोग कैसे करें। अब, आप अपने बाहरी रोमांचों को फिर से जी सकते हैं, अपनी प्रगति का जश्न मना सकते हैं और अपनी यात्रा के अगले चरण के लिए प्रेरित रह सकते हैं।


हालाँकि, आपके मानचित्र को अनुकूलित, विस्तारित और बेहतर बनाने के कई तरीके हैं। तो अपनी जीपीएक्स फ़ाइलें लें, ज्यूपिटर नोटबुक चालू करें, और अपनी पिछली बाहरी गतिविधियों को मानचित्र पर जीवंत होने दें!

हैप्पी मैपिंग!

आगे क्या होगा?

देखते रहिए क्योंकि अभी बहुत कुछ आना बाकी है:


  • AWS का उपयोग करके अपने मानचित्र के साथ एक वेबसाइट तैनात करना
  • पायथन और प्लॉटली का उपयोग करके उन्नयन और गति प्रोफाइल की साजिश रचना
  • एक तरफ से ली गई तस्वीरों के साथ ट्रेल्स को बढ़ाना
  • और भी बहुत कुछ

संदर्भ

  • ज्यूपिटर नोटबुक सहित सभी कोड मेरे GitHub पर हैं।
  • फोलियम पर अपना शोध करते समय, मुझे पैट्रिक का एक बेहतरीन लेख मिला, जिसने वही किया जो मैंने करने की योजना बनाई थी। उनका काम मेरे समाधान को आगे बढ़ाने का एक बड़ा आधार था, इसलिए कृपया इसे जांचें।
  • ज्यूपिटर नोटबुक
  • पुटक
  • पांडा

यहाँ भी प्रकाशित किया गया है.