Geopandas III (Kafka-Stream)
Geopandas III (Kafka-Stream)
大家好,
在本文中,我们将使用 geopandas 和 matplotlib 以及来自 kafka 的数据制作如下实时地图。文章中使用的代码和数据 关联 您可以通过访问
对于这个项目,我们将使用 matplotlib 中的 pause() 函数。 pause() 函数是一个可以让我们轻松制作简单动画的函数。要使用这个函数,我们需要一个循环。
在本文中,我们的场景将是使用来自 kafka 的坐标数据制作一个简单的跟踪系统。来自 Kafka 的数据格式如下。
{'id': 3, '坐标': [29.924233539415862, 40.82190084163631]}
{'id': 3, '坐标': [29.923649713593697, 40.82234632927804]}
{'id': 3, '坐标': [29.923129135568924, 40.82271081694114]}
{'id': 3, '坐标': [29.922632883620075, 40.82309002925243]}
现在让我们开始一步一步地编写我们的项目。首先,我们创建一个能够从 kafka 读取数据的消费者。我们从一个简单的 for 循环中获取数据。
消费者=KafkaConsumer('step',bootstrap_servers='127.0.0.1:9092') 对于消费者中的数据: 值=json.loads(data.value)
打印(值)
上述代码的输出如下。
现在让我们一步一步开发上面的简单for循环。首先,我们创建将找到地图的窗口和 ax 对象,该对象允许我们对其执行自定义操作,其中 subplots 函数位于循环之外。
消费者=KafkaConsumer('step',bootstrap_servers='127.0.0.1:9092')
无花果,斧头 = plt.subplots(figsize=(15,20))
对于消费者中的数据:
值=json.loads(data.value)
坐标=值[“坐标”]
present_point=点(坐标[0],坐标[1])
df_point=gpd.GeoDataFrame(geometry=[present_point])
df_point.plot(ax=ax)
plt.pause(0.1)
plt.show()
输出如下。
看上面的输出,可以说结果意义不大。所以让我们继续开发我们的项目。
现在是添加栅格的时候了。在循环之外,我们在第一步中加载栅格数据。在第二步中,我们指定角坐标。第三步,我们处理轴上的栅格数据。您可以在 geopandas 系列的第一篇文章中访问这些步骤的详细信息。
然后我们在 plot 方法中输入一些参数以将点放在一个模式中。这些分别是
- color:我们指定颜色的参数。
- marker:我们指定点形状的参数。
- markersize:我们指定点大小的参数。
经过这些操作,我们的代码最终版本如下。
消费者=KafkaConsumer('step',bootstrap_servers='127.0.0.1:9092')
无花果,斧头 = plt.subplots(figsize=(15,20))
src=rasterio.open("/home/ozan/Desktop/Qgis/kou_modified.tif")
范围=[src.bounds[0],src.bounds[1],src.bounds[2],src.bounds[3]]
ax = rasterio.plot.show(src,范围=范围,ax=ax)
对于消费者中的数据:
值=json.loads(data.value)
坐标=值[“坐标”]
present_point=点(坐标[0],坐标[1])
df_point=gpd.GeoDataFrame(geometry=[present_point])
df_point.plot(ax=ax,color="black",marker="*",markersize=75)
plt.pause(0.1)
输出如下。
当我们查看输出时,我们可以看到栅格上的所有点位置。但是,如果我们只想查看即时位置,而不是所有点,我们需要在 for 循环内的 matplotlib 中添加 plt.cla() 函数。这个函数可以让我们删除当前轴上的所有值。这里只有一个重要的点。由于该函数会删除坐标区中的所有值,因此也会删除我们添加到坐标区中的栅格。为了避免这种情况,我们只需要在光栅插入操作中的 for 循环中添加第三步即可。因此,将首先删除所有值,然后在循环中添加新值。
修改后的代码最终版本如下。
消费者=KafkaConsumer('step',bootstrap_servers='127.0.0.1:9092')
无花果,斧头 = plt.subplots(figsize=(15,20))
src=rasterio.open("/home/ozan/Desktop/Qgis/kou_modified.tif")
范围=[src.bounds[0],src.bounds[1],src.bounds[2],src.bounds[3]]
对于消费者中的数据:
plt.cla()
ax = rasterio.plot.show(src,范围=范围,ax=ax)
值=json.loads(data.value)
坐标=值[“坐标”]
present_point=点(坐标[0],坐标[1])
df_point=gpd.GeoDataFrame(geometry=[present_point])
df_point.plot(ax=ax,color="black",marker="*",markersize=75)
plt.pause(0.1)
plt.show()
输出如下。
我们可以立即获得如上所示的位置信息。接下来是创建一条使用此位置信息指示路线的线。为此,我们需要将点添加到列表中。所以我们首先在循环外定义一个空列表。然后我们将循环中获得的所有点附加到这个列表中。众所周知,我们需要至少 2 个点坐标(起点和终点)来创建一条线。这就是为什么我们在追加操作之后用 if 条件查看列表中的点数。如果我们的点数超过 2,我们创建一个线对象,就像我们创建一个点对象一样。为此,这次我们使用 LineString 函数而不是 Point。然后我们使用 GeoDataFrame 函数创建一个数据框,并使用 plot 方法进行绘制。这里和点不同的是,我们只输入linewidth参数。使用此参数,我们确定线条粗细。可选地,可以输入颜色参数或任何用于 matplotlib 中线图的参数。
进行更改后,我们的代码的最终版本如下。
消费者=KafkaConsumer('step',bootstrap_servers='127.0.0.1:9092')
无花果,斧头 = plt.subplots(figsize=(15,20))
src=rasterio.open("/home/ozan/Desktop/Qgis/kou_modified.tif")
范围=[src.bounds[0],src.bounds[1],src.bounds[2],src.bounds[3]]
坐标列表=[]
对于消费者中的数据:
plt.cla()
ax = rasterio.plot.show(src,范围=范围,ax=ax)
值=json.loads(data.value)
坐标=值[“坐标”]
present_point=点(坐标[0],坐标[1])
坐标列表附加(现在点)
如果 len(coordinate_list)>1:
present_line = LineString(coordinate_list)
df_line = gpd.GeoDataFrame(geometry=[present_line])
df_line.plot(ax=ax,线宽=3)
df_point=gpd.GeoDataFrame(geometry=[present_point])
df_point.plot(ax=ax,color="black",marker="*",markersize=75)
plt.pause(0.1)
plt.show()
输出如下。
最后,如果需要,您可以通过将其添加到循环中来自定义下面的代码。
plt.title("Geopandas III (Kafka-Stream)",size=15)
plt.xlabel(datetime.now())
plt.ylabel("https://medium.com/@uzunozan41")
暂停功能通常不是有用的功能。 FuncAnimation 函数推荐用于更复杂的动画。但是,如果我们希望能够以一种简单的方式在 Kafka 等工具中查看流动的数据,而不需要在任何地方记录它,那么它对我们很有用。当然,为此,坐标所在的区域必须有我们可以参考的数据。除栅格数据外,此数据可以是形状、geojson 或包含位置信息的 csv 文件。我们上面做的例子是一个适合固定区域的项目。例如,它可以用于跟踪工厂中的无人机或机器人设备或动物园中的动物跟踪等场所。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明