【GeoEvent】实现点要素服务几何信息联合StreamServer流服务数据信息绑定

数据情况

通过sid字段挂接,35个一组

数据流结构 CSV

image-20240905135654-isgnkg1

IOT点位数据

image-20240905135851-5ok72jh

点位数据提前发布为FeatureServer要素服务

注意关联字段类型与GeoEvent定义一致

image-20240905141736-myvges8

image-20240905141718-m8u9rox

创建GeoEvent定义(数据结构)

根据数据流结构决定,注意关联字段与GeoEvent定义一致

image-20240905140107-7bn7pau

创建TCP接收器

image-20240905140251-3iuy15z

image-20240905140457-e5j8rvi

推送csv数据

import socket
import time

# 指定服务器的IP地址和端口号
server_ip = '192.168.1.142'
server_port = 5565

# 创建一个socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接到服务器
client_socket.connect((server_ip, server_port))

while True:
    # 打开CSV文件
    with open('stationRealTime.csv', 'r') as file:
        # 跳过标题行
        next(file)
        # 初始化行计数器
        line_count = 0
        # 初始化数据缓存
        data_buffer = ''
    
        for line in file:
            # 将当前行添加到数据缓存
            data_buffer += "STA," + line
            line_count += 1
                
            # 每35行或文件末尾,发送数据
            if line_count == 35:
                # 发送数据
                client_socket.sendall(data_buffer.encode('utf-8'))
                print(data_buffer)
                # 清空数据缓存和行计数器
                data_buffer = ''
                line_count = 0
                # 等待1秒``
                time.sleep(1)
    
        # 发送剩余的数据(如果有)
        if data_buffer:
            client_socket.sendall(data_buffer.encode('utf-8'))
            print(data_buffer)
            time.sleep(1)


client_socket.close()

image-20240905140556-zjrvi7d

创建StreamService输出器

image-20240905140840-41yo099

image-20240905141002-b9hqz3p

选择关联要素

image-20240905141642-joocl9y

创建GeoEvent定义

image-20240909095132-9njbeb8

前端页面构建

主要实现:

  1. class-breaks 根据data分级渲染
  2. popupTemplate 点击弹窗显示 sid 、data
  3. boatLabelClass 标注 data 值
<html lang="zh-cn">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,
      maximum-scale=1,user-scalable=no" />
  <title>StreamLayer | Sample </title>
  <style>
    html,
    body,
    #viewDiv {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }

    #streamLayerDiv {
      padding: 10px;
      background-color: #f5f5f5;
    }
  </style>
  <link rel="stylesheet" href="https://js.arcgis.com/4.30/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.30/"></script>
  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/StreamLayer",
      "esri/geometry/Polygon",
      "esri/Graphic",
      "esri/widgets/LayerList",
      "esri/core/reactiveUtils",
      "esri/layers/support/LabelClass",
       "esri/widgets/Legend"
    ], (Map, MapView, StreamLayer, Polygon, Graphic, LayerList, reactiveUtils, LabelClass, Legend) => {
      let streamLayer, streamLayerView;

      const svcUrl = "https://ip142.gsgz.com:6443/geoscene/rest/services/station-stream-out/StreamServer";

      const map = new Map({
        basemap: "gray-vector"
      });

      const view = new MapView({
        container: "viewDiv",
        map: map,
        center: [113, 23],
        zoom: 9
      });
      view.ui.add(new LayerList({ view }), "bottom-left");
  
      let renderer2 = {
        type: "class-breaks",
        field: "data",
        classBreakInfos: [
          {
            minValue: 100,
            maxValue: 300,
            symbol: {
              type: "simple-marker",
              size: 10,
              color: "red",
              outline: {
                color: [0, 255, 0],
                width: 1
              }
            }
          },
          {
            minValue: 300,
            maxValue: 600,
            symbol: {
              type: "simple-marker",
              size: 10,
              color: "yellow",
              outline: {
                color: [0, 255, 0],
                width: 1
              }
            }
          },
          {
            minValue: 600,
            maxValue: 1000,
            symbol: {
              type: "simple-marker",
              size: 10,
              color: "green",
              outline: {
                color: [0, 255, 0],
                width: 1
              }
            }
          }
        ],
        defaultSymbol :{
          type: "simple-marker",
          size: 10,
          color: "blue",
        }
      }

      const boatLabelClass = new LabelClass({
        labelExpressionInfo: { expression: "$feature.data" },
        symbol: {
          type: "text",  // autocasts as new LabelSymbol3D()
          symbolLayers: [{
            type: "text",  // autocasts as new TextSymbol3DLayer()
            material: { color: [ 49,163,84 ] },
            size: 12  // points
          }]
        }
      });

      // Construct Stream Layer
      const layer = new StreamLayer({
        url: svcUrl,
        purgeOptions: {
          displayCount: 10000
        },
        popupTemplate: {
          title: "{status}",
          content: "{sid}, {data}"
        },
        renderer: renderer2,
        labelingInfo : [boatLabelClass],
        timeInfo: {
          trackIdField: "sid"
        }
      });

      map.add(layer);


      const legend = new Legend({
          view: view
        });

      view.ui.add(legend, "top-left");


    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
</body>

</html>

验证

StreamServer订阅

StreamServer流服务不带位置信息

image-20240909095253-7y03koi

前端页面

值动态变化,实现数据流绑定点位

PixPin_2024-09-09_10-17-31-20240909101801-pzowrrt

posted on   wongJzzz  阅读(37)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

点击右上角即可分享
微信分享提示