Package: gps-activity
GPS activity🚛A light-weight module for analysis of GPS activity. Package is designed to be trade-off solution for both researchers and developers in Waste Labs. Usinggps_activityyou can:Cluster your time-series gps records to extract activity pointsJoin activity points with original plan or operation reportEstimate clustering performanceInstallation ☁️ -> 🖥️Using pip:pip3installgps_activityPython package modules📦extraction: clusters GPS records and extracts cluster activities (checkout module structure)linker: joins route plan and clustered gps recordsmetrics: estimates clustering performance based on:internal source: ones that based on inter & intra cluster distancesexternal source: joined route plan and clustered gps records (output oflinkermodule)Extraction modules🔵 🟣 ⚫️Organized by preprocessing, fragmentation & clustering steps that ultimately are packed intoActivityExtractionSessionobject and orchestrated.⚠️ActivityExtractionSessionassumptions and constrains1 vehicle = 1 session run: to avoid clusters overlapNo duplicated gps records over vehicle-timstamp: avoids division by zero during computingvelocity🚀VHFDBSCAN: Velocity hardlimit fragmentation Density-based spatial clustering of applications with noiseFragmentation is performing by applying hardlimiting on velocity computed fromlat,lonanddatetimecolumnsClustering is performed by classical DBSCAN that considers non-cluster candidates as noisefromgps_activityimportActivityExtractionSessionfromgps_activity.extraction.factory.preprocessingimportPreprocessingFactoryfromgps_activity.extraction.factory.fragmentationimportVelocityFragmentationFactoryfromgps_activity.extraction.factory.clusteringimportFDBSCANFactorypreprocessing=PreprocessingFactory.factory_pipeline(source_lat_column="lat",source_lon_column="lon",source_datetime="datetime",source_vehicle_id="plate_no",source_crs="EPSG:4326",target_crs="EPSG:2326",)fragmentation=VelocityFragmentationFactory.factory_pipeline(max_velocity_hard_limit=4)clustering=FDBSCANFactory.factory_pipeline(eps=30,min_samples=3)activity_extraction=ActivityExtractionSession(preprocessing=preprocessing,fragmentation=fragmentation,clustering=clustering,)activity_extraction.predict(gps)🚀VHFSTCM: Velocity hardlimit fragmentation spatio-temporal clustering modelFragmentation is performing by applying hardlimiting on velocity computed fromlat,lonanddatetimecolumnsClustering is performed according steps:Generated adjacent proximity mask (if cluster pair distance <=eps)Clusters ID are generated according: proximity mask and fragmentation flagGPS records grouped bycluster_idand aggregated cluster time spanCluster is validated if time span >=min_duration_secValidated cluster ids are set to original GPS recordsfromgps_activityimportActivityExtractionSessionfromgps_activity.extraction.factory.preprocessingimportPreprocessingFactoryfromgps_activity.extraction.factory.fragmentationimportVelocityFragmentationFactoryfromgps_activity.extraction.factory.clusteringimportSTCMFactorypreprocessing=PreprocessingFactory.factory_pipeline(source_lat_column="lat",source_lon_column="lon",source_datetime="datetime",source_vehicle_id="plate_no",source_crs="EPSG:4326",target_crs="EPSG:2326",)fragmentation=VelocityFragmentationFactory.factory_pipeline(max_velocity_hard_limit=4)clustering=STCMFactory.factory_pipeline(source_vehicle_id_column="plate_no",eps=30,min_duration_sec=60)stcm=ActivityExtractionSession(preprocessing=preprocessing,fragmentation=fragmentation,clustering=clustering,)Linker module implementation 🔵 🟣 ⚫️Overview linker module components# Initilize linkage componentsfromgps_activityimportActivityLinkageSessionfromgps_activity.linker.factoryimportPreprocessingFactoryfromgps_activity.linker.factoryimportClusterAggregationFactoryfromgps_activity.linker.factoryimportJoinValidatorFactoryfromgps_activity.linker.factoryimportSpatialJoinerFactoryfromgps_activity.linker.factoryimportCoverageStatisticsFactoryMAX_DISTANCE=100MAX_DAYS_DISTANCE=1gps_link_preprocess_pipeline=PreprocessingFactory.factory_pipeline(source_lat_column="lat",source_lon_column="lon",source_datetime="datetime",source_vehicle_id="plate_no",source_crs=WSG_84,target_crs=HK_CRS,generate_primary_key_for="gps",source_composite_keys=["plate_no","datetime","lat","lon"],)plans_link_preprocess_pipeline=PreprocessingFactory.factory_pipeline(source_lat_column="lat",source_lon_column="lng",source_datetime="datetime",source_vehicle_id="re-assigned by Ricky",source_crs=WSG_84,target_crs=HK_CRS,generate_primary_key_for="plan",source_composite_keys=["CRN#"],)cluster_agg_pipeline=ClusterAggregationFactory.factory_pipeline(source_lat_column="lat",source_lon_column="lon",source_datetime="datetime",source_vehicle_id="plate_no",source_crs=WSG_84,target_crs=HK_CRS,)spatial_joiner=SpatialJoinerFactory.factory_pipeline(how="inner",max_distance=MAX_DISTANCE)spatial_validator=JoinValidatorFactory.factory_pipeline(max_days_distance=MAX_DAYS_DISTANCE,ensure_vehicle_overlap=True)coverage_stats_extractor=CoverageStatisticsFactory.factory_pipeline()gps_linker_session=ActivityLinkageSession(gps_preprocessor=gps_link_preprocess_pipeline,plan_preprocessor=plans_link_preprocess_pipeline,cluster_aggregator=cluster_agg_pipeline,spatial_joiner=spatial_joiner,spatial_validator=spatial_validator,coverage_stats_extractor=coverage_stats_extractor,)linker_results=gps_linker_session.transform({"gps":clustered_gps,"plan":plans,})Metrics module implementation 📊NOTE: This module is highly experimentalNOTE: This module depends onlinkermodulefromgps_activity.metricsimportActivityMetricsSessionfromgps_activity.metrics.modelsimportMetricsmetrics=ActivityMetricsSession(beta=2)metrics=metrics.transform(linker_results)