Realice la visualización en línea de cientos de millones de datos espaciales vectoriales basados en 100 líneas de código Ganos

Introducción: Este artículo presenta cómo utilizar RDS PG o PolarDB (compatible con la versión PG o la versión Oracle) de la tecnología de visualización rápida de la base de datos proporcionada por el motor de espacio-tiempo de Ganos, y solo utiliza cien líneas de código para realizar la visualización rápida en línea. y la interacción fluida del mapa de cientos de millones de datos espaciales geométricos masivos. Y no hay necesidad de prestar atención a los problemas de eficiencia y almacenamiento de cortes.

Autor: Li He

 

01 Introducción

Cómo realizar la visualización en línea de cientos de millones de datos espaciales vectoriales en bases de datos espacio-temporales siempre ha sido un problema en la industria. Debido a la gran cantidad de datos, el método tradicional requiere que los datos de la base de datos se publiquen en función de la división de la caché para poder visualizarlos, el proceso de operación es largo y hay muchos problemas a considerar:

  • Si se cortan previamente los datos vectoriales, ¿cuánto tiempo se deben cortar los datos? ¿Cuántos niveles son apropiados? ¿Hay suficiente espacio en el disco duro para almacenar mosaicos?
  • Si se utilizan mosaicos en tiempo real, ¿se puede garantizar el tiempo de respuesta de los mosaicos de renderizado en tiempo real?
  • Si usa mosaicos vectoriales, ¿qué tamaño podría tener un mosaico de pequeña escala? ¿Se convertirá la transmisión en un cuello de botella? ¿Cuántos datos puede admitir el renderizado de front-end?

Si desea explorar rápidamente los datos en línea a gran escala en la base de datos, el proceso tradicional de producción de corte fuera de línea utilizado para los "servicios de mapa base" es casi incomprensible, que requiere mucho tiempo y trabajo, y no se puede procesar en línea. Se acerca la tecnología Black. Este artículo presenta cómo usar RDS PG o PolarDB (compatible con la versión PG o la versión Oracle) de la tecnología de visualización rápida de la base de datos proporcionada por el motor de espacio-tiempo de Ganos, y solo usa cien líneas de código para realizar el visualización rápida en línea y fluidez de cientos de millones de datos espaciales geométricos masivos Interacción de mapas, y no hay necesidad de prestar atención a los problemas de eficiencia y almacenamiento de cortes.

02 Interpretación de características técnicas

El núcleo del procesamiento de visualización rápida en línea de Ganos es asociar la base de datos con la visualización, proporcionando una nueva tecnología de indexación de visualización: índice Sparse Vector Pyramid (SVP). SVP tiene dos características clave: rápido y económico .

Entre ellos, Kuai se refiere a dos etapas de Kuai:

  • La creación de pirámides es rápida : Ganos utiliza un índice espacial para dividir los datos en el espacio y establece un índice de pirámide vectorial disperso basado en la densidad, lo que reduce la cantidad de cálculo de datos en un 90% en comparación con el proceso tradicional de corte de gráficos. Al mismo tiempo, la creación de la pirámide adopta un modo de procesamiento completamente paralelo, e incluso si se generan los 100 millones de datos de la parcela, solo se necesitan unos 10 minutos para generar la pirámide.
  • Visualización rápida de datos : Ganos adopta un algoritmo de eliminación de visibilidad visual para filtrar una gran cantidad de datos que no afectan el efecto de visualización de acuerdo con el orden Z, lo que acelera la eficiencia de la visualización en tiempo real. Ganos admite la salida directa de mosaicos ráster en formato PNG y mosaicos vectoriales en formato MVT, y el tiempo de respuesta de la representación y visualización en tiempo real de 100 millones de datos de patrones terrestres alcanza el segundo nivel.

La provincia también tiene dos dimensiones:

  • Ahorre espacio en disco : el índice piramidal generado a partir de 100 millones de datos de parcelas solo ocupa un espacio adicional del 5% de la tabla original.
  • Ahorre tiempo de desarrollo : utilizando solo declaraciones SQL simples, puede controlar de manera flexible el efecto de visualización ajustando los parámetros de la declaración.

03 Utilice pasos

El motor de visualización rápida de Ganos es muy fácil de usar y las funciones SQL han sido altamente encapsuladas. Cabe señalar que antes de utilizar el motor de visualización rápida por primera vez, debe crear explícitamente el módulo de extensión correspondiente. La declaración ejecutada es la siguiente:

CREAR EXTENSIÓN ganos_geometry_pyramid CASCADE;

Al ejecutar la declaración anterior, se cargarán los componentes informáticos del motor emergente.

3.1 Construye una pirámide vectorial dispersa

Suponga que ha creado una tabla de vectores grande e importado datos, luego puede usar el método st_buildpyramid de Ganos para crear una pirámide vectorial.

El prototipo del método es el siguiente : Para obtener descripciones más detalladas de los parámetros, consulte la documentación oficial .

boolean ST_BuildPyramid (tabla cstring, cstring geom, cstring fid, cstring config)

Nota: * Desliza el dedo hacia la izquierda y hacia la derecha para leer

entre ellos

  • table: el nombre de la tabla donde se encuentran los datos vectoriales.
  • geom: Nombre del campo de vector.
  • fid: el identificador único del registro de características vectoriales, admite el tipo Int4 / Int8.
  • config: la cadena del parámetro de configuración en formato json.
    • En este ejemplo, especificamos el nombre de la pirámide vectorial y el tamaño de mosaico lógico utilizado (este tamaño de mosaico no es un mosaico real, sino que solo representa una división lógica del espacio)

La llamada real es la siguiente:

ST_BuildPyramid ('puntos', 'geom', 'gid', '{"nombre": "puntos_geom", "tileSize": 512}')

Nota: * Desliza el dedo hacia la izquierda y hacia la derecha para leer

Hemos creado una pirámide vectorial para el campo geom de la tabla de puntos. El nombre de la pirámide se especifica como points_geom , y el tamaño de mosaico lógico de la pirámide se establece en 512.

3. 2 Obtener mosaicos de cuadrícula

Los mosaicos de cuadrícula son mosaicos en forma de imágenes y son la forma más utilizada de mosaicos de mapa. El método ST_AsPng de Ganos proporciona la función de representar dinámicamente datos vectoriales en mosaicos ráster en el lado de la base de datos bajo demanda. Esta función proporciona las capacidades de simbolización de ráster más básicas y está más orientada a escenas livianas que no requieren una simbolización compleja, como los sistemas de gestión de datos.

El prototipo del método es el siguiente . Para una descripción más detallada de los parámetros, consulte el documento oficial :

bytes ST_AsPng (nombre de cstring, mosaico de cstring, estilo de cstring)

entre ellos

  • name: el nombre de la tabla piramidal.
  • mosaico: número de fila y columna de índice de mosaico, en forma de Z_X_Y.
  • estilo: estilo de renderizado. Podemos ajustar el efecto de renderizado a través de los siguientes parámetros:
    • point_size: tamaño de punto, en píxeles.
    • line_width: ancho de línea, que afecta los bordes exteriores de los elementos de línea y los elementos de área, en píxeles.
    • line_color: color de reproducción de línea, que afecta los bordes exteriores de los elementos de línea y área. Los primeros 6 dígitos son de color hexadecimal y los últimos 2 dígitos son transparencia hexadecimal.
    • fill_color: color de relleno, que funciona en elementos de superficie.
    • fondo: color de fondo. Generalmente establecido en FFFFFF00, es decir , puro y transparente.

La llamada real es la siguiente:

ST_AsPng ('points_geom', '1_2_1', '{"point_size": 5, "line_width": 2, "line_color": "# 003399FF", "fill_color": "# 6699CCCC", "background": "# FFFFFF00" } ')

Nota: * Desliza el dedo hacia la izquierda y hacia la derecha para leer

Obtenemos el mosaico vectorial con el número de fila y columna de índice x = 2, y = 1, z = 1 de la pirámide vectorial , y representamos el mosaico vectorial como un mosaico ráster de acuerdo con el estilo que configuramos, y devolvemos la imagen en formato PNG. .

3. 3 Obtener mosaicos vectoriales

Los mosaicos vectoriales son una tecnología emergente de mosaicos de mapas, que tiene la flexibilidad de configurar estilos en el front-end. Con la representación WebGL, el efecto es más hermoso y los marcos de mapas como Mapbox pueden admitir fácilmente este formato. El uso del método ST_Tile de Ganos puede proporcionar los datos en la pirámide vectorial en forma de mosaicos vectoriales.

El prototipo del método es el siguiente : Para obtener descripciones más detalladas de los parámetros, consulte la documentación oficial .

bytea ST_Tile (nombre cstring, clave cstring);

entre ellos

  • name: el nombre de la pirámide. En este ejemplo, es el nombre del campo name_vector de la tabla .
  • clave: El número de fila y columna del índice de mosaico, en forma de Z_X_Y.

Solo necesitamos proporcionar el número de columna y fila de TMS estándar y el nombre de la tabla piramidal a llamar.

La llamada real es la siguiente:

ST_Tile ('puntos_geom', '1_2_1');

Obtenemos el mosaico vectorial con fila de índice y número de columna x = 2, y = 1, z = 1 de la pirámide vectorial, y los datos devueltos están en formato MVT estándar.

04 Caso práctico

4.1 Datos de prueba

Preparamos dos conjuntos de datos vectoriales como ejemplos de prueba.

La tabla de edificios son datos de superficie, con un total de 125 millones de datos, que muestran el efecto de visualización en línea utilizando mosaicos de cuadrícula.

gid | geom | 
--- | ---------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------- | 
  1 | MULTIPOLÍGONO (((- 88.066953 34.916114 0, -88.066704 34.916114 0, -88.066704 34.91602 0, -88.066953 34.91602 0, -88.066953 34.916114 0)))                 
  2 | MULTIPOLÍGONO (((- 87.924658 34.994797 0, -87.924791 34.99476 0, -87.924817 34.994824 0, -87.924685 34.994861 0, -87.924658 34.994797 0)))                

Nota: * Desliza el dedo hacia la izquierda y hacia la derecha para leer

La tabla de puntos son datos de puntos, con un total de 107,000 piezas de datos, que muestran el efecto de visualización en línea usando mosaicos vectoriales.

 

id | geom | 
- | ------------------------------ | 
 1 | PUNTO (113.5350205 22.1851929) | 
 2 | PUNTO (113.5334245 22.1829781) |

 

4.2 Arquitectura de pila completa

La arquitectura de pila completa de visualización rápida de base de datos incluye tres partes: servidor de base de datos, servidor de Python y del lado del usuario. La arquitectura de pila completa se muestra en la siguiente figura.

 

1.png

 

4.3 Código del servidor

 

Para simplificar el código y enfocarnos más en la descripción lógica, elegimos Python (compatible con Python 3.6 y superior) como el lenguaje de back-end, el marco web usa el marco Flask ( pip install flaskinstalación) basado en Python y el marco de conexión de la base de datos usa Psycopg2 para Python (usar pip install psycopg2para instalar).

Cabe mencionar que hemos implementado las funciones más básicas, cuando el desempeño del propio servicio Web se convierte en un cuello de botella, se puede optimizar de acuerdo a diferentes plataformas y frameworks para obtener un mejor desempeño de respuesta.

Primero establecimos una pirámide vectorial en el backend y luego implementamos dos interfaces respectivamente. La interfaz de mosaico vectorial usa los datos en la tabla de puntos y la interfaz de mosaico ráster usa los datos en la tabla de edificios y define el estilo para el front-end. para transferir directamente. Para facilitar la explicación, el código de back-end proporciona dos interfaces de ráster vectorial al mismo tiempo, que se pueden seleccionar según sea necesario en el uso real.

 

# - * - codificación: utf-8 - * - 
# @File: Vector.py 

import json 
de psycopg2 import pool 
from threading import Semaphore 
from flask import Flask, jsonify, Response, send_from_directory 
import binascii 

# Parámetro de conexión 
CONNECTION = "dbname = postgres user = postgres password = postgres host = YOUR_HOST port = 5432 " 

class ReallyThreadedConnectionPool (pool.ThreadedConnectionPool): 
    " "" Para 
    grupos de conexiones multiproceso, mejore la respuesta de escenarios de alta concurrencia de clase de mosaico de mapa. 
    "" " 
    def __init __ (self, minconn, maxconn, * args, ** kwargs): 
        self._semaphore = Semaphore (maxconn) 
        super () .__ init __ (minconn, maxconn, * args, ** kwargs) 

    def getconn (self, * args, ** kwargs):
        self._semaphore.acquire () 
        return super (). getconn (* args, ** kwargs) 

    def putconn (self, * args, ** kwargs): 
        super (). putconn (* args, ** kwargs) 
        self._semaphore .release () 

class VectorViewer: 
    def __init __ (self, connect, table_name, column_name, fid): 
        self.table_name = 
        table_name self.column_name = 
        column_name # 创建 一个 连接 池
        self.connect = ReallyThreadedConnectionPool (5, 10, connect) 
        # 约定金字塔 表 名
        self.pyramid_table = f "{self.table_name} _ {self.column_name}" 
        self.fid = fid 
        self.tileSize = 512 
        # self._build_pyramid ()

    def _build_pyramid (self): 
        "" "创建 金字塔" "" 
        config = { 
            "name": self.pyramid_table, 
            "tileSize": self.tileSize 
        } 
        sql = f "select st_BuildPyramid ('{self.table_name}', '{ self.column_name} ',' {self.fid} ',' {json.dumps (config)} ') " 
        self.poll_query (sql) 
        
    def poll_query (self, query: str): 
        pg_connection = self.connect.getconn ( ) 
        pg_cursor = pg_connection.cursor () 
        pg_cursor.execute (consulta) 
        registro = pg_cursor.fetchone () 
        pg_connection.commit () 
        pg_cursor.close () 
        self.connect.putconn (pg_connection) 
        si el registro no es Ninguno:
            return record [0] 

class PngViewer (VectorViewer): 
    def get_png (self, x, y, z): 
        # Default parameter 
        config = { 
            "point_size": 5, 
            "line_width": 2, 
            "line_color": "# 003399FF", 
            "fill_color": "# 6699CCCC", 
            "background": "# FFFFFF00" 
        } 
        # Cuando se usa psycpg2, es más eficiente devolver los datos binarios como una cadena hexadecimal 
        sql = f "select encode (st_aspng ('{self.pyramid_table } ',' {z} _ {x} _ {y} ',' {json.dumps (config)} '),' hex ') " 
        resultado = self.poll_query (sql) 
        # Solo cuando se devuelve en forma de cadena hexadecimal, se debe convertir de nuevo 
        result = binascii.a2b_hex (result) 
        return result

class MvtViewer (VectorViewer): 
    def get_mvt (self, x, y, z): 
        # Cuando se usa psycpg2, es más eficiente devolver los datos binarios como una cadena hexadecimal 
        sql = f "select encode (st_tile ('{self.pyramid_table } ',' {z} _ {x} _ {y} '),' hex ') " 
        result = self.poll_query (sql) 
        # Solo cuando se devuelve en forma de cadena hexadecimal Necesita convertirlo de nuevo 
        result = binascii .a2b_hex (resultado) 
        return result 

app = Flask (__ name__) 

@ app.route ('/ vector') 
def vector_demo (): 
    return send_from_directory ("./", "Vector.html") 

# Definir nombres de tablas, nombres de campos, etc. 
pngViewer = PngViewer (CONNECTION, 'usbf', 'geom', 'gid') 

@ app.route ('/ vector / png / <int: z> / <int: x> / <int: y>') 
def vector_png (z, x, y): 
    png = pngViewer.get_png (x, y, z)
    return Response ( 
        response = png, 
        mimetype = "image / png" 
    ) 

mvtViewer = MvtViewer (CONNECTION, 'points', 'geom', 'gid') 

@ app.route ('/ vector / mvt / <int: z> / <int: x> / <int: y> ') 
def vector_mvt (z, x, y): 
    mvt = mvtViewer.get_mvt (x, y, z) 
    return Response ( 
        response = mvt, 
        mimetype = "application / vnd.mapbox -vector-tile " 
    ) 

if __name__ ==" __main__ ": 
    app.run (port = 5000, thread = True)

Nota: * Desliza el dedo hacia la izquierda y hacia la derecha para leer

Guarde el código anterior como un archivo Vector.py y ejecute el python Vector.pycomando para iniciar el servicio.

No es difícil inferir del código que no importa qué lenguaje o marco usemos, solo necesitamos encapsular la declaración SQL de vector o mosaico ráster como una interfaz para lograr exactamente la misma función. En comparación con la publicación de servicios de mapas tradicionales, realizar la visualización en línea con la función de pirámide vectorial de Ganos es una opción más liviana y fácil de usar:

 

  • Con respecto a los mosaicos de la cuadrícula, el estilo se puede controlar cambiando el código y la flexibilidad se mejora enormemente.
  • No es necesario introducir otros componentes de terceros, ni es necesario realizar una optimización específica, hay un rendimiento de respuesta satisfactorio.
  • Puede elegir cualquier lenguaje de programación y marco con el que los usuarios estén familiarizados, y no hay necesidad de una configuración de parámetros compleja y profesional, que es más amigable para los profesionales no geográficos.

4.4 Código de cliente

Elegimos Mapbox como el marco del mapa de front-end para mostrar la capa de mosaico vectorial y la capa de mosaico ráster proporcionada por el back-end, y configuramos los parámetros de representación para la capa de mosaico vectorial.

Para facilitar la explicación, el código de interfaz agrega dos capas de vector y ráster al mismo tiempo, que se pueden seleccionar según sea necesario en el uso real.

Creamos un nuevo archivo llamado Vector.html en el mismo directorio de archivos del código back-end y escribimos el siguiente código, después de que se inicia el servicio back-end, se puede http://localhost:5000/vectoracceder a él.

<! DOCTYPE html> 
<html> 
  <head> 
    <meta charset = "UTF-8" /> 
    <title> </title> 
    <link 
      href = "https://cdn.bootcdn.net/ajax/libs/mapbox- gl / 1.13.0 / mapbox-gl.min.css " 
      rel =" stylesheet " 
    /> 
  </head> 
  <script src =" https://cdn.bootcdn.net/ajax/libs/mapbox-gl/1.13. 0 / mapbox-gl.min.js "> </script> 
  <script src =" https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js "> </ script > 
  <body> 
    <div id = "map" style = "height: 100vh" /> 
    <script> 
      const sources = { 
        osm:{ 
          tipo: "raster", 
          mosaicos: ["https://b.tile.openstreetmap.org/{z}/{x}/{y}.png"],
          tileSize: 256, 
        }, 
      }; 
      capas const = [ 
        { 
          id: "mapa_base", 
          tipo: "raster", 
          fuente: "osm", 
          diseño: {visibilidad: "visible"}, 
        }, 
      ]; 
      const map = new mapboxgl.Map ({ 
        contenedor: "mapa", 
        estilo: {versión: 8, capas, fuentes}, 
      }); 
      map.on ("load", async () => { 
        map.resize (); 
        
        // 添加 栅格 瓦片 数据 源
        map.addSource ("png_source", { 
          tipo: "raster", 
          minzoom: 1, 
          mosaicos:
          tileSize: 512, 
        }); 
        // Agregar capa de mosaico ráster 
        map.addLayer ({ 
          id: "png_layer", 
          tipo: "raster", 
          diseño: {visibilidad: "visible"}, 
          fuente: "png_source", 
        }); 
        
        / / Agregar fuente de datos de mosaico vectorial 
        map.addSource ("mvt_source", { 
          type: "vector", 
          minzoom: 1, 
          tiles: [`$ {window.location.href} / mvt / {z} / {x} / {y } `], 
          tileSize: 512, 
        }); 

        // Agrega una capa de mosaico vectorial y agrega un estilo al 
        mapa de mosaico vectorial.addLayer ({ 
          id:" mvt_layer ", 
          paint: { 
            "radio-círculo ": 4,
            "circle-color": "# 6699CC", 
            "circle-stroke-width": 2, 
            "circle-opacity": 0.8, 
            "circle-stroke-color": "#ffffff", 
            "circle-stroke-opacity": 0.9, 
          }, 
          tipo: "círculo", 
          fuente: "mvt_source", 
          "source-layer": "points_geom", 
        }); 
        
      }); 
    </script> 
  </body> 
</html>

Nota: * Desliza el dedo hacia la izquierda y hacia la derecha para leer

 

4.5 Efectos dinámicos de mosaicos vectoriales

 

2.gif

Se pueden ajustar diferentes efectos en la parte delantera. Después de ajustar a los parámetros de la nueva capa, el efecto es el siguiente:

{ 
  "circle-radius": 4, 
  "circle-color": "# 000000", 
  "circle-stroke-width": 2, 
  "circle-opacity": 0.3, 
  "circle-stroke-color": "# 003399" , 
  "opacidad-trazo-círculo": 0.9, 
}

3.gif

 

4.6 Efectos dinámicos de mosaicos de cuadrícula

 

1111.gif

 

05 Integración con PGADmin

La herramienta de administración de bases de datos PG PGAdmin admite de forma nativa la visualización de datos vectoriales, pero debido a la falta de tecnología de visualización rápida, solo puede mostrar un único objeto o mostrar un conjunto de resultados limitado, y no puede realizar una vista uniforme y global de datos a gran escala. datos vectoriales. Integramos la función de visualización rápida vectorial de Ganos con PGAdmin. Cuando los datos se almacenan en la base de datos, puede explorar la situación global en línea, evaluar rápidamente la descripción general de los datos y mejorar en gran medida la experiencia de gestión de datos.

5.gif

 

06 Resumen

Este artículo comienza con los principios y ventajas de la pirámide vectorial dispersa, presenta cómo usar Ganos para implementar varias funciones de los servicios de visualización en línea y finalmente realiza un servicio de visualización de mapas que puede manejar cientos de millones de datos a través de cien líneas de código. Los lectores pueden utilizar aún más las capacidades de análisis y consulta rápida del lado del servidor de PG / PolarDB Ganos sobre la base de la visualización para realizar funciones más complejas como la consulta de atributos de objetos, la selección de círculos espaciales y el análisis espacial. Esta es la transformación traída por la tecnología de negro de aceleración de visualización de gráficos espaciales a gran escala traída por Ganos, el índice de pirámide de vector disperso.

Enlace original

Este artículo es el contenido original de Alibaba Cloud y no se puede reproducir sin permiso.

Supongo que te gusta

Origin blog.csdn.net/xxscj/article/details/114112894
Recomendado
Clasificación