盘算出行OD表和绘制城市热门区域

打印 上一主题 下一主题

主题 881|帖子 881|积分 2643

一、实验目的

1. 盘算出租车出行OD表
2. 绘制城市热门区域
二、实验步骤

2.1 提取出租车的出行行程

1. 提取出租车轨迹

      先将实验2处置惩罚好的出租车数据,按照出租车ID从小到大举行分组,再按照日期DATE、时间TIME举行升序排序,就可以得到某辆出租车的轨迹了。具体实现步骤:
    (1)首先创建一个数据表test3_trace,与traffic_data结构一样,用于存储出租车轨迹,SQL代码:
  1. use traffic_data;
  2. CREATE TABLE `test3_trace`  (
  3.   `GPS_ID` int  AUTO_INCREMENT,
  4.   `DATE` date ,
  5.   `TIME` time ,
  6.   `ID` varchar(15) ,
  7.   `LONGTITUDE` DECIMAL(9, 6) ,
  8.   `LATITUDE` DECIMAL(8, 6) ,
  9.   `SPEED` float,
  10.   `ALTITUDE` int ,
  11.   `PASSENGER` bit(1),
  12.   PRIMARY KEY (`GPS_ID`)
  13. );
复制代码
(2)其次从整个数据表中获取全部出租车的ID,并从小到大排列,存储在ids列表中。然后用for循环遍历ids列表,对于每一个出租车ID再遍历整个数据表,找到该ID对应的全部数据记录,并按日期DATE、时间TIME从小到大举行排列。最后将这些数据记录依次插入到test3_trace表中,由于在该表中GPS_ID是从1开始自增的序列,不需要插入数据,当每插入一条数据记录,其就会自增,这里用executemany() 批量插入,加快速率。因此在数据表test3_trace中就提取出了出租车轨迹,即全部GPS记录依次按照车牌号ID、日期DATE和时间TIME从小到大举行排序。Python代码:
  1. import pymysql
  2. # 数据库连接配置
  3. db_config = {
  4.     'host': 'localhost',
  5.     'user': '数据库用户名',
  6.     'password': '密码',
  7.     'db': 'traffic_data',
  8.     'charset': 'utf8',
  9.     'cursorclass': pymysql.cursors.DictCursor
  10. }
  11. # 连接数据库
  12. try:
  13.     db = pymysql.connect(**db_config)
  14.     cursor = db.cursor()
  15.     # 获取所有唯一的 ID 列表
  16.     cursor.execute("SELECT DISTINCT `ID` FROM `traffic_data` ORDER BY `ID`")
  17.     ids = [row['ID'] for row in cursor.fetchall()]
  18.     # 遍历每个 ID
  19.     for current_id in ids:
  20.         # 获取当前 ID 的所有记录,并按 DATE 和 TIME 排序
  21.         cursor.execute("""
  22.             SELECT `DATE`, `TIME`, `ID`, `LONGTITUDE`, `LATITUDE`, `SPEED`, `ALTITUDE`, `PASSENGER`
  23.             FROM `traffic_data`
  24.             WHERE `ID` = %s
  25.             ORDER BY `DATE`, `TIME`
  26.         """, (current_id,))
  27.         # 获取排序后的数据
  28.         sorted_records = cursor.fetchall()
  29.         # 构建用于 executemany() 的参数列表
  30.         # 不包括 GPS_ID,因为这是自增的,可以表示整个排序
  31.         insert_values = [(row['DATE'], row['TIME'], row['ID'], row['LONGTITUDE'], row['LATITUDE'], row['SPEED'],
  32.                           row['ALTITUDE'], row['PASSENGER']) for row in sorted_records]
  33.         # 构建插入语句
  34.         insert_query = "INSERT INTO test3_trace (DATE, TIME, ID, LONGTITUDE, LATITUDE, SPEED, ALTITUDE, PASSENGER)" \
  35.                        " VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"
  36.         # 使用 executemany() 执行批量插入
  37.         cursor.executemany(insert_query, insert_values)
  38.         db.commit()  # 提交事务
  39.         print(current_id + "出租车的数据已经复制完成")
  40.     print("所有数据已成功复制。")
  41. except Exception as e:
  42.     print("更新失败:", e)
  43.     db.rollback()
  44. finally:
  45.     cursor.close()
  46.     db.close()
复制代码
执行步伐效果:

test3_trace表效果部分数据展示:

2. 提取出租车的乘客行程

       出租车出现需求通常指出出租车乘客出行需求。在出租车数据记录中,字段PASSENGER记录了该出租车的载客状态,当载客状态字段PASSENGER为0时,表示没有乘客;当载客状态字段PASSENGER为1时,表示有乘客。因此根据该字段信息状态的变更,来提取乘客的上下车点。
       将上面提取出来的出租车轨迹数据,检测每一辆出租车载客状态字段PASSENGER的厘革,当其由0变为1,表示乘客上车点,再由1变为0时,表示乘客下车点,将如许一组厘革界说为该辆出租车的一条出行行程数据。将其输出格式为<出租车车牌号,上车位置经度,上车位置纬度,上车时间,下车位置经度,下车位置纬度,下车时间>的数据记录。具体步骤:
(1)先在test3_trace表新建一列DATE_TIME,用于将表中的日期DATE和时间TIME归并成一列DATE_TIME,python代码:
  1. # 合并日期和时间
  2. import pymysql
  3. from pymysql import cursors
  4. # 数据库连接配置
  5. db_config = {
  6.     'host': 'localhost',
  7.     'user': 'root',
  8.     'password': '123456',
  9.     'db': 'traffic_data',
  10.     'charset': 'utf8',
  11.     'cursorclass': pymysql.cursors.DictCursor
  12. }
  13. # 分批处理的批大小
  14. batch_size = 1000  # 你可以根据实际情况调整这个值
  15. # 连接到数据库
  16. try:
  17.     db = pymysql.connect(**db_config)
  18.     cursor = db.cursor()
  19. # 添加 DATE_TIME 列
  20.     cursor.execute("ALTER TABLE `test3_trace` ADD COLUMN `DATE_TIME` DATETIME NULL DEFAULT NULL;")
  21.     # 获取表中的所有记录的ID
  22.     cursor.execute("SELECT GPS_ID FROM test3_trace")
  23.     ids = cursor.fetchall()
  24.     # 分批更新数据
  25.     for i in range(0, len(ids), batch_size):
  26.         batch_ids = ids[i:i + batch_size]
  27.         # 构建SQL语句
  28.         update_query = """
  29.         UPDATE test3_trace
  30.         SET DATE_TIME = CONCAT(DATE, ' ', TIME)
  31.         WHERE GPS_ID IN ({})
  32.         """.format(', '.join(['%s'] * len(batch_ids)))
  33.         # 准备参数
  34.         params = tuple(id['GPS_ID'] for id in batch_ids)
  35.         # 执行更新操作
  36.         cursor.execute(update_query, params)
  37.         db.commit()  # 提交事务
  38.     print("所有数据已成功更新。")
  39. except Exception as e:
  40.     print("数据更新失败:", e)
  41.     db.rollback()
  42. finally:
  43.     cursor.close()
  44.     db.close()
复制代码
运行效果,部分数据展示:

(2)创建表test3_travel_running,用于存储出租车的乘客行程数据,SQL代码:
  1. use traffic_data;
  2. CREATE TABLE `test3_travel_running`  (
  3.   `travel_ID` int  AUTO_INCREMENT,
  4.   `ID` varchar(15) ,   #出租车ID
  5.   `LONGTITUDE1` DECIMAL(9, 6) ,  #上车位置
  6.   `LATITUDE1` DECIMAL(8, 6) ,
  7.   `DATE_TIME1` datetime ,
  8.   `LONGTITUDE0` DECIMAL(9, 6) ,  #下车位置
  9.   `LATITUDE0` DECIMAL(8, 6) ,
  10.   `DATE_TIME0` datetime ,
  11.   PRIMARY KEY (`travel_ID`)
  12. );
复制代码
表test3_travel_running展示:

(3)然后将提取出来的乘客行程轨迹,插入到数据表test3_travel_running中:
  1. import pymysql
  2. from pymysql import cursors
  3. from decimal import Decimal
  4. # 数据库连接配置
  5. db_config = {
  6.     'host': 'localhost',
  7.     'user': 'root',
  8.     'password': '123456',
  9.     'db': 'traffic_data',
  10.     'charset': 'utf8mb4',
  11.     'cursorclass': cursors.SSDictCursor  # 使用服务器端游标
  12. }
  13. # 定义插入查询
  14. insert_query = """
  15. INSERT INTO test3_travel_running (ID, LONGTITUDE1, LATITUDE1, DATE_TIME1, LONGTITUDE0, LATITUDE0, DATE_TIME0)
  16. VALUES (%s, %s, %s, %s, %s, %s, %s)
  17. """
  18. try:
  19.     # 连接到数据库
  20.     db = pymysql.connect(**db_config)
  21.     cursor = db.cursor()
  22.     # 初始化变量
  23.     batch_size = 1000  # 设置每批处理的记录数
  24.     insert_data = []
  25.     previous_record = None
  26.     start_trip = None  # 存储上车记录
  27.     current_id = None  # 当前记录的ID
  28.     # 从test3_trace表中按顺序获取数据
  29.     cursor.execute(
  30.         "SELECT `ID`, `LONGTITUDE`, `LATITUDE`, `DATE_TIME`, `PASSENGER` "
  31.         "FROM `test3_trace` "
  32.         "ORDER BY `ID`, `GPS_ID`"
  33.     )
  34.     # 分批处理数据
  35.     more_results = True
  36.     while more_results:
  37.         records = cursor.fetchmany(batch_size)  # 获取一批数据
  38.         if not records:
  39.             more_results = cursor.nextset()  # 检查是否还有其他结果集
  40.             if more_results:
  41.                 continue
  42.             break  # 如果没有更多的数据,结束循环
  43.         for record in records:
  44.             record_id = record['ID']
  45.             passenger_status = record['PASSENGER']
  46.             is_passenger_on = passenger_status == b'\x01'
  47.             # 上车逻辑
  48.             if is_passenger_on and (previous_record is None or previous_record['PASSENGER'] == b'\x00'):
  49.                 start_trip = record  # 记录上车信息
  50.                 current_id = record_id  # 更新当前ID
  51.             # 下车逻辑
  52.             if start_trip and (start_trip['ID'] == record_id):
  53.                 if not is_passenger_on:
  54.                     # 如果当前记录与上车记录ID相同,且乘客下车
  55.                     insert_data.append((
  56.                         record_id,
  57.                         start_trip['LONGTITUDE'],
  58.                         start_trip['LATITUDE'],
  59.                         start_trip['DATE_TIME'],
  60.                         record['LONGTITUDE'],
  61.                         record['LATITUDE'],
  62.                         record['DATE_TIME']
  63.                     ))
  64.                     start_trip = None  # 重置上车记录
  65.                     current_id = None  # 重置当前ID
  66.             elif start_trip and (start_trip['ID'] != record_id):
  67.                 # 如果当前记录与上车记录ID不同,将上一条记录视为下车记录
  68.                 insert_data.append((
  69.                     previous_record['ID'],
  70.                     start_trip['LONGTITUDE'],
  71.                     start_trip['LATITUDE'],
  72.                     start_trip['DATE_TIME'],
  73.                     previous_record['LONGTITUDE'],
  74.                     previous_record['LATITUDE'],
  75.                     previous_record['DATE_TIME']
  76.                 ))
  77.                 start_trip = None  # 更新上车记录为当前记录
  78.                 current_id = None  # 重置当前ID
  79.             previous_record = record  # 更新previous_record为当前记录
  80.         # 执行批量插入,如果insert_data列表满了
  81.         if len(insert_data) >= batch_size:
  82.             cursor.executemany(insert_query, insert_data)
  83.             db.commit()
  84.             print(f"Batch inserted {len(insert_data)} records.")
  85.             insert_data = []  # 清空列表为下一批数据做准备
  86.     # 最后一批插入,如果insert_data非空
  87.     if insert_data:
  88.         cursor.executemany(insert_query, insert_data)
  89.         db.commit()
  90.         print(f"Inserted remaining {len(insert_data)} records.")
  91.     print("Data processing complete.")
  92. except Exception as e:
  93.     print("Error occurred, rolling back transaction:", e)
  94.     db.rollback()
  95. finally:
  96.     cursor.close()
  97.     db.close()
复制代码
运行效果部分展示:

共提取出220594条乘客行程轨迹
2.2 城市交通小区划分

       利用网格划分的划分交通小区。首先获得全部出租车轨迹的最大经纬度与最小经纬度坐标,(latmax, lngmax)与(latmin, lngmin)
  1. SELECT
  2. MAX(LONGTITUDE1) AS max_start_lng,MAX(LONGTITUDE0) AS max_end_lng,
  3. MIN(LONGTITUDE1) AS min_start_lng,MIN(LONGTITUDE0) AS min_end_lng,
  4. MAX(LATITUDE1) AS max_start_lat,MAX(LATITUDE0) AS max_end_lat,
  5. MIN(LATITUDE1) AS min_start_lat,MIN(LATITUDE0) AS min_end_lat
  6. FROM test3_travel_running;
复制代码
效果:

      从效果来看出租车(latmax, lngmax)=(34.067192,118.86900),(latmin, lngmin)=(0.970307,0.132128),经度的跨度为117.899493,纬度的跨度为33.935064,明显可知经度的跨度大于纬度的跨度。因此将经度划分为10份,纬度划分成3份,将全部出租车所到达的面积划分为30份,即小区编号可以界说从01L01到03L10,前两位数字表示网格的纬度坐标,后两位数字表示网格的经度坐标。
2.3 出租车行程分配到对应交通小区

       设出租车上车点为(lat1,lng1)与下车点(lat0,lng0),假设通过盘算得到上车点对应的交通小区为01L02、下车点对应的交通小区为03L05,那么将该行程分配给交通小区对[01L02,03L05]。
2.4 并盘算出行OD

       利用pandas对OD表数据举行存储,表的横纵坐标名分别为小区的编号。对表A举行初始化,表中的全部数据都为0,读取一条行程数据,并找到其所对应的交通小区对,在表中对应交通小区对的数值上加1,对全部行程执行该操作。Python代码:
  1. import pandas as pd
  2. import pymysql
  3. import pymysql.cursors
  4. # 数据库连接配置
  5. db_config = {
  6.     'host': 'localhost',
  7.     'user': 'root',
  8.     'password': '123456',
  9.     'db': 'traffic_data',
  10.     'charset': 'utf8mb4',
  11.     'cursorclass': pymysql.cursors.DictCursor
  12. }
  13. # 连接数据库
  14. connection = pymysql.connect(**db_config)
  15. # 划分网格
  16. lng_min = 0.132128   # 经度
  17. lng_max = 118.86900
  18. lat_min = 0.970307
  19. lat_max = 34.067192
  20. lng_interval = (lng_max - lng_min) / 10
  21. lat_interval = (lat_max - lat_min) / 3
  22. grid_bounds = {}
  23. for lat_idx in range(1, 4):
  24.     for lng_idx in range(1, 11):
  25.         grid_id = f"{lat_idx:02d}L{lng_idx:02d}"
  26.         grid_bounds[grid_id] = {
  27.             'min_lng': lng_min + (lng_idx - 1) * lng_interval,
  28.             'max_lng': lng_min + lng_idx * lng_interval,
  29.             'min_lat': lat_min + (lat_idx - 1) * lat_interval,
  30.             'max_lat': lat_min + lat_idx * lat_interval
  31.         }
  32.         print(f"交通小区编号: {grid_id}, 边界: ({grid_bounds[grid_id]['min_lng']}, {grid_bounds[grid_id]['min_lat']}) to ({grid_bounds[grid_id]['max_lng']}, {grid_bounds[grid_id]['max_lat']})")
  33. # 获取行程数据
  34. query = "SELECT LONGTITUDE1, LATITUDE1, LONGTITUDE0, LATITUDE0 FROM test3_travel_running"
  35. cursor = connection.cursor()
  36. cursor.execute(query)
  37. trips = cursor.fetchall()
  38. # 初始化OD矩阵
  39. od_matrix = pd.DataFrame(0, index=grid_bounds.keys(), columns=grid_bounds.keys())
  40. # 分配行程到网格
  41. def get_traffic_zone(lng, lat):
  42.     for zone, bounds in grid_bounds.items():
  43.         if bounds['min_lng'] <= lng <= bounds['max_lng'] and bounds['min_lat'] <= lat <= bounds['max_lat']:
  44.             return zone
  45.     return None
  46. for trip in trips:
  47.     pickup_zone = get_traffic_zone(trip['LONGTITUDE1'], trip['LATITUDE1'])
  48.     dropoff_zone = get_traffic_zone(trip['LONGTITUDE0'], trip['LATITUDE0'])
  49.     if pickup_zone and dropoff_zone:
  50.         od_matrix.at[pickup_zone, dropoff_zone] += 1
  51. # 保存到Excel
  52. with pd.ExcelWriter('traffic_zones_and_od_matrix.xlsx') as writer:
  53.     od_matrix.to_excel(writer, sheet_name='OD_Matrix')
  54.     pd.DataFrame(grid_bounds).T.to_excel(writer, sheet_name='Grid_Bounds')
  55. cursor.close()
  56. connection.close()
复制代码
运行效果:



划分的效果并不抱负,有出租车行程数据的为[01L01,01L01],[02L1002L10],[03L0903L09],[03L1003L09],[03L1003L10],查看其经纬度范围:

出租车行程数据主要会合在的经度范围为[106.9953,95.12163],纬度范围为[34.06719,23.0349],在将这个经纬度范围举行细划分网格,代码:
  1. import pymysql
  2. import pandas as pd
  3. import pymysql.cursors
  4. # 数据库连接配置
  5. db_config = {
  6.     'host': 'localhost',
  7.     'user': 'root',
  8.     'password': '123456',
  9.     'db': 'traffic_data',
  10.     'charset': 'utf8mb4',
  11.     'cursorclass': pymysql.cursors.DictCursor
  12. }
  13. # 连接数据库
  14. connection = pymysql.connect(**db_config)
  15. # 获取行程数据
  16. query = "SELECT LONGTITUDE1, LATITUDE1, LONGTITUDE0, LATITUDE0 FROM test3_travel_running"
  17. cursor = connection.cursor()
  18. cursor.execute(query)
  19. trips = cursor.fetchall()
  20. # 原始网格边界03L09
  21. grid_bounds = {
  22.     '03L09': {'min_lng': 95.1216256, 'max_lng': 106.99531280000001, 'min_lat': 23.034897, 'max_lat': 34.067192}
  23. }
  24. # 细分特定网格
  25. def subdivide_grid(grid_id, bounds, subdivisions=6):
  26.     """细分特定网格"""
  27.     lat_range = bounds['max_lat'] - bounds['min_lat']
  28.     lng_range = bounds['max_lng'] - bounds['min_lng']
  29.     lat_step = lat_range / subdivisions
  30.     lng_step = lng_range / subdivisions
  31.     new_bounds = {}
  32.     for i in range(subdivisions):
  33.         print(i)
  34.         for j in range(subdivisions):
  35.             new_id = f"{grid_id}_{i + 1:02d}{j + 1:02d}"
  36.             new_bounds[new_id] = {
  37.                 'min_lat': bounds['min_lat'] + i * lat_step,
  38.                 'max_lat': bounds['min_lat'] + (i + 1) * lat_step,
  39.                 'min_lng': bounds['min_lng'] + j * lng_step,
  40.                 'max_lng': bounds['min_lng'] + (j + 1) * lng_step
  41.             }
  42.     return new_bounds
  43. # 更新网格边界信息
  44. new_grids = subdivide_grid('03L09', grid_bounds['03L09'])
  45. grid_bounds.update(new_grids)
  46. # 重新计算行程对应的网格
  47. def get_traffic_zone(lng, lat, grid_bounds):
  48.     """计算给定经纬度对应的网格"""
  49.     for grid_id, bounds in grid_bounds.items():
  50.         if bounds['min_lng'] <= lng <= bounds['max_lng'] and bounds['min_lat'] <= lat <= bounds['max_lat']:
  51.             return grid_id
  52.     return None
  53. # 初始化新的OD矩阵
  54. od_matrix = pd.DataFrame(0, index=new_grids.keys(), columns=new_grids.keys())
  55. print("OD")
  56. # 分配行程到网格
  57. for trip in trips:
  58.     pickup_zone = get_traffic_zone(trip['LONGTITUDE1'], trip['LATITUDE1'], new_grids)
  59.     dropoff_zone = get_traffic_zone(trip['LONGTITUDE0'], trip['LATITUDE0'], new_grids)
  60.     if pickup_zone and dropoff_zone:
  61.         od_matrix.at[pickup_zone, dropoff_zone] += 1
  62. # 保存到Excel
  63. with pd.ExcelWriter('subdivided_traffic_zones_and_od_matrix.xlsx') as writer:
  64.     od_matrix.to_excel(writer, sheet_name='Subdivided_OD_Matrix')
  65.     pd.DataFrame(new_grids).T.to_excel(writer, sheet_name='Subdivided_Grid_Bounds')
  66. cursor.close()
  67. connection.close()
复制代码
这里出来的效果也不抱负,于是我又尝试一次,每次缩小范围,运行效果:

从上面的效果来看,可以将整个行程数据划分到几个交通小区中。
2.5 绘制聚类图和热力图

       本实验使用K-Means聚类方法提取出租车的出行热门区域,即对出租车行程的出发点和终点举行聚类分析,并通过百度舆图大概python中的舆图可视化工具对热门区域举行可视化展示。将上面的路径的出发点、终点转换成百度坐标系,并输出到point.js文件中,代码:
  1. import pymysql
  2. import json
  3. import urllib.request
  4. # 数据库连接配置
  5. db_config = {
  6.     'host': 'localhost',
  7.     'user': 'root',
  8.     'password': '123456',
  9.     'db': 'traffic_data',
  10.     'charset': 'utf8',
  11.     'cursorclass': pymysql.cursors.DictCursor
  12. }
  13. # 百度API密钥
  14. baidu_ak = 'XNeLiUBdjxiq7miI5pB7nzZqLvqdSFAy'
  15. # 定义坐标转换函数
  16. def convert_to_baidu(lat, lng):
  17.     url = f"http://api.map.baidu.com/geoconv/v1/?coords={lng},{lat}&from=1&to=5&ak={baidu_ak}"
  18.     try:
  19.         response = urllib.request.urlopen(url)
  20.         data = json.loads(response.read())
  21.         if data['status'] == 0:
  22.             return data['result'][0]['x'], data['result'][0]['y']
  23.         else:
  24.             print(f"坐标转换失败: {lat}, {lng}")
  25.             return None, None
  26.     except Exception as e:
  27.         print(f"坐标转换异常: {e}")
  28.         return None, None
  29. # 连接数据库
  30. db = pymysql.connect(**db_config)
  31. cursor = db.cursor()
  32. # 查询坐标点
  33. cursor.execute("SELECT LONGTITUDE1, LATITUDE1 FROM test3_travel_running")
  34. results = cursor.fetchall()
  35. # 准备热力图数据
  36. points = []
  37. for coord in results:
  38.     converted_lng, converted_lat = convert_to_baidu(coord['LATITUDE1'], coord['LONGTITUDE1'])
  39.     if converted_lng is not None and converted_lat is not None:
  40.         points.append({"lng": converted_lng, "lat": converted_lat, "count": 1})
  41.         print(converted_lng)
  42.     else:
  43.         print(f"Skipping coordinate conversion failed: {coord}")
  44. # 将坐标点写入 JavaScript 文件
  45. with open('points.js', 'w', encoding='utf-8') as js_file:
  46.     js_content = "var points = " + json.dumps(points, ensure_ascii=False) + ";"
  47.     js_file.write(js_content)
  48. # 关闭数据库连接
  49. cursor.close()
  50. db.close()
复制代码
将出租车出行路径的出发点、终点提取出来,然后使用K-Means聚类方法提取出租车的出行热门区域,代码:
  1. import numpy as np
  2. import pandas as pd
  3. import folium
  4. from folium.plugins import HeatMap
  5. import pymysql
  6. from pymysql import cursors
  7. from sklearn.cluster import KMeans
  8. # 数据库连接配置
  9. db_config = {
  10.     'host': 'localhost',
  11.     'user': 'root',
  12.     'password': '123456',
  13.     'db': 'traffic_data',
  14.     'charset': 'utf8mb4',
  15.     'cursorclass': cursors.SSDictCursor  # 使用服务器端游标
  16. }
  17. db = pymysql.connect(**db_config)
  18. cursor = db.cursor()
  19. cursor.execute("SELECT LONGTITUDE1, LATITUDE1, LONGTITUDE0, LATITUDE0 FROM test3_travel_running")
  20. results = cursor.fetchall()
  21. df = pd.DataFrame(results, columns=['LONGTITUDE1', 'LATITUDE1', 'LONGTITUDE0', 'LATITUDE0'])
  22. # 提取起点和终点坐标,并合并到一个数组中
  23. pickup_coords = df[['LONGTITUDE1', 'LATITUDE1']].values
  24. dropoff_coords = df[['LONGTITUDE0', 'LATITUDE0']].values
  25. X = np.concatenate((pickup_coords, dropoff_coords), axis=0)
  26. # 使用K-Means聚类
  27. '''
  28. kmeans = KMeans(n_clusters=10, n_init=10, random_state=0)  # 显式设置n_init的值
  29. kmeans.fit(X)
  30. labels = kmeans.labels_
  31. # 可视化聚类结果
  32. plt.figure(figsize=(10, 8))
  33. sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=labels, palette='viridis', s=50, edgecolor='none')
  34. plt.title('K-Means Clustering of Taxi Trips with 10 Clusters')
  35. plt.xlabel('Longitude')
  36. plt.ylabel('Latitude')
  37. plt.legend(title='Cluster', loc='upper left')
  38. plt.grid(False)
  39. plt.show()
  40. '''
  41. cursor.close()
  42. db.close()
复制代码
运行代码,得到聚类效果:

聚类的效果通过散点图可视化,不同的聚类用不同的颜色表示,以便直观地查看哪些区域的出租车活动较为麋集。从聚类效果来看,出租车行程麋集在经度范围为(103,116)之间,纬度范围在(25,32)之间。
利用上面得到的出租车百度舆图的轨迹点,绘制出租车出行轨迹热力图,HTML代码:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.         <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
  6.         <style type="text/css">
  7.                body, html {width: 100%;height: 100%;margin:0;font-family:"微软雅黑";}
  8.                #allmap{width:700px;height:100%;}
  9.                p{margin-left:5px; font-size:14px;}
  10.         </style>
  11.         <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=XNeLiUBdjxiq7miI5pB7nzZqLvqdSFAy"></script>
  12.         <script type="text/javascript" src="point.js"></script>
  13.         <title>个性化地图设置页</title>
  14. </head>
  15. <body>
  16.         <div id="allmap"></div>
  17.                 <div style="width:70px;height:280px;border:#ccc solid 0px;position:absolute; top:420px; left:630px" >
  18.   <img src="tu.png" width="64" height="276" />
  19.   </div>
  20. </body>
  21. </html>
  22. <script type="text/javascript">
  23.         var map = new BMap.Map('allmap');
  24.         map.centerAndZoom(new BMap.Point(106.568056104,28.5432091717), 12);
  25.         map.addControl(new BMap.NavigationControl());        // 添加平移缩放控件
  26.         map.addControl(new BMap.ScaleControl());             // 添加比例尺控件
  27.         map.addControl(new BMap.OverviewMapControl());       //添加缩略地图控件
  28.         map.enableScrollWheelZoom();                         //启用滚轮放大缩小
  29.         map.disable3DBuilding();
  30.         //个性化在线编辑器地址:http://lbsyun.baidu.com/custom/
  31.           var styleJson = [
  32.           {
  33.                     "featureType": "land",
  34.                     "elementType": "all",
  35.                     "stylers": {
  36.                               "lightness": 100,
  37.                               "saturation": -100}
  38.           },
  39.           {
  40.                     "featureType": "water",
  41.                     "elementType": "all",
  42.                     "stylers": {
  43.                               "lightness": 47}
  44.           },
  45.           {
  46.                     "featureType": "manmade",
  47.                     "elementType": "geometry",
  48.                     "stylers": {
  49.                               "lightness": 28}
  50.           },
  51.           {
  52.                     "featureType": "road",
  53.                     "elementType": "geometry.fill",
  54.                     "stylers": {
  55.                               "lightness": 82}
  56.           },
  57.           {
  58.                     "featureType": "road",
  59.                     "elementType": "geometry.stroke",
  60.                     "stylers": {
  61.                               "lightness": -76}
  62.           },
  63.           {
  64.                     "featureType": "green",
  65.                     "elementType": "all",
  66.                     "stylers": {
  67.                               "lightness": 63,
  68.                               "saturation": -100}
  69.           },
  70.           {
  71.                     "featureType": "boundary",
  72.                     "elementType": "geometry.fill",
  73.                     "stylers": {
  74.                               "lightness": 80,
  75.                               "saturation": 1}
  76.           },
  77.           {
  78.                     "featureType": "boundary",
  79.                     "elementType": "geometry.stroke",
  80.                     "stylers": {
  81.                               "lightness": -75,
  82.                               "saturation": -100}
  83.           }
  84.         ]
  85.         map.setMapStyle({styleJson:styleJson});
  86.         //添加覆盖物
  87.         function add_overlay(){
  88.                for( var i=0;i<data_set1.length;i++){
  89.                   var d_temp=data_set1[i].point;
  90.                   var point_set=new Array();
  91.                   for (var j=0;j<d_temp.length;j++){
  92.                                point_set[j]=new BMap.Point(d_temp[j].split(",")[0],d_temp[j].split(",")[1]);
  93.                   }
  94.                   var rectangle = new BMap.Polygon(point_set, {strokeColor:"none", fillColor:"green", strokeWeight:1,fillOpacity:0.7, strokeOpacity:0.3});  //创建矩形
  95.                        map.addOverlay(rectangle);
  96.                        //增加矩形
  97.                }
  98.                for( var i=0;i<data_set2.length;i++){
  99.                   var d_temp=data_set2[i].point;
  100.                   var point_set=new Array();
  101.                   for (var j=0;j<d_temp.length;j++){
  102.                                point_set[j]=new BMap.Point(d_temp[j].split(",")[0],d_temp[j].split(",")[1]);
  103.                   }
  104.                   var rectangle = new BMap.Polygon(point_set, {strokeColor:"none", fillColor:"orange", strokeWeight:1,fillOpacity:0.7, strokeOpacity:0.3});  //创建矩形
  105.                        map.addOverlay(rectangle);
  106.                        //增加矩形
  107.                }
  108.                for( var i=0;i<data_set3.length;i++){
  109.                   var d_temp=data_set3[i].point;
  110.                   var point_set=new Array();
  111.                   for (var j=0;j<d_temp.length;j++){
  112.                                point_set[j]=new BMap.Point(d_temp[j].split(",")[0],d_temp[j].split(",")[1]);
  113.                   }
  114.                   var rectangle = new BMap.Polygon(point_set, {strokeColor:"none", fillColor:"red", strokeWeight:1,fillOpacity:0.7, strokeOpacity:0.3});  //创建矩形
  115.                        map.addOverlay(rectangle);
  116.                        //增加矩形
  117.                }
  118.         }     
  119.         add_overlay()
  120. </script>
复制代码
运行,得到热力图:

从上面的热力图可以看出,哪些地方的交通流量比较大,哪些相对比较少,有利于相关部门对交通举行监管。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王柳

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表