Skip to content

9. Guía de desarrollo

IngenieroGeomatico edited this page Apr 1, 2024 · 1 revision

Guía de desarrollo de plugins

Requisitos e instalación de dependencias: Node.js (version >=8.x.x)

Existe una herramienta para crear la estructura base del plugin, se instala con el comando npm install -g api-cnig-create-plugin@latest .

Con el "flag" -g realizamos la instalación de forma global para disponer de la herramienta en cualquier parte de nuestro equipo. En el caso de no tener disponible npm a nivel global, se tendrá que hacer npm init dentro de la carpeta en la que queramos crear el plugin y posteriormente realizar el comando npm install api-cnig-create-plugin@latest ..

Para crear el plugin base se tiene que ejecutar el comando api-cnig-create-plugin, solicitará el nombre del plugin, así como la versión de API-CORE sobre la que se desee trabajar. También nos preguntará si queremos que se instalen automáticamente las dependencias del plugin.

👉 Para la guía de desarrollo, supondremos que hemos proporcionado el nombre de 'miPlugin'

Creará la estructura de directorios y los ficheros necesarios para la construcción de un plugin dentro de una carpeta con el nombre 'miplugin' en el lugar donde se haya ejecutado la herramienta. Este plugin es autocontenido y ya contiene los scripts de pruebas y compilación, e incluye una funcionalidad básica de ejemplo 'Hola mundo'.

En este punto, deberemos desarrollar la funcionalidad específica de nuestro plugin.

Usando el comando npm install (para instalar las dependencias) y npm start para lanzar el test del plugin) para empezar el desarrollo.

Para generar el plugin compilado se ejecutará el comando npm run build.

Al ejecutar el comando npm start automáticamente se nos abrirá el test de desarrollo en el navegador y si se quiere acceder al test de producción se tendrá que cambiar la URL en el navegador apuntando al fichero prod.html (es necesario que el plugin este compilado antes).

Se tienen que tener en cuenta los requisitos de desarrollo sobre la fachada y la implementación.

Fachada e implementación

En el desarrollo son importantes los conceptos de fachada e implementación. Uno de los objetivos de la API es independizar en la medida de lo posible los desarrollos funcionales de las librerías de mapas en la que se apoyan (OpenLayers, leaflet, etc.), de modo que adaptar un desarrollo a una nueva librería de mapas implique rehacer la menor parte posible.

La API presenta una fachada común a todas las implementaciones con la que el desarrollador podrá realizar la mayoría de acciones. Bajo esta fachada están las distintas implementaciones que realizan las acciones concretas con las librerías en las que se basan.

Por tanto, a la hora de desarrollar un plugin es muy importante llevar a cabo en la fachada del mismo todas las operaciones independientes de la librería de mapas base, y dejar en la implementación las acciones que sí están ligadas a la librería base.

Estructura del proyecto/plugin

/
├── src 📁                  # Código fuente.
    ├── facade     # Fachada.
    ├── impl       # Implementación.
    ├── templates  # Plantilla handlebars.
    ├── api.json   # Definición del plugin por API-REST
    ├── index.json # Punto de entrada.
├── task 🌈                 # Crea el punto de entrada, index.js
├── test 📦                 # Código test.
├── webpack-config 🏗️       # Configuración de Webpack.
├── .eslintrc 👓            # Configuración del ESLint.
├── .gitignore 💾           # Archivos ignorados por Git.
├── LICENSE 📋              # Licencia.
└── ...

Ficheros destacados para la configuración de plugins

Referencias
Por último destacar que, como complemento a esta guía, el desarrollador siempre tendrá de referencia el código fuente de los plugins ya desarrollados.

Guía de desarrollo de visualizadores con React

La API-CNIG no obliga a utilizar ningún framework o librería para desarrollar proyectos, para su utilización se tendrá que importar los CDN necesarios para su utilización.

Requisitos e instalación de dependencias: Node.js (version 14.18+, 16+.)

Los visualizadores que realiza el CNIG con la API-CORE utilizan esta librería "React". Es una librería open source para crear interfaces de usuarios.

Se recomienda utilizar una herramienta de construcción ("Build Tools") para generar el proyecto de React. La documentación de React recomienda utilizar Vite.

Pasos para desarrollar una Aplicación de React de cero con la API-CNIG
En este caso se utilizará Vite como "build tools", pero este ejemplo se extiende para cualquier otro tipo de "build tools", por ejemplo npx (npx create-next-app).

  1. Usar el comando npm create vite@latest (existen otras alternativas a npm, como yarm o pnpm).
  2. Posteriormente instalar Vite, npm i vite o npm install -g vite.
  3. Incluir los CDN de la API-CNIG en el archivo index.html.
  <!-- fichero estilos -->
   <link href="https://componentes.cnig.es/api-core/assets/css/apiign.ol.min.css" rel="stylesheet" />

   <!-- ficheros javascript -->
   <script type="text/javascript" src="https://componentes.cnig.es/api-core/js/apiign.ol.min.js"></script>
   <script type="text/javascript" src="https://componentes.cnig.es/api-core/js/configuration.js"></script>
  1. Incluir los estilos básicos en el archivo index.html
<!-- estilo básico -->
<style>
 html,
 body, 
 #root {
     margin: 0;
     padding: 0;
     height: 100%;
     width: 100%;
  }

.map {
    border: 0;
    width: 100%;
    height: 100%;
}
</style>
  1. Modificar main.jsx en desarrollo
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'


ReactDOM.createRoot(document.getElementById('root')).render(

  // StrictMode renders components twice (on dev but not production) in order to detect any problems with 
  // your code and warn you about them (which can be quite useful).
  // <React.StrictMode>
  //   <App />
  // </React.StrictMode>,

  <App />

)
  1. Crear el mapa, en este ejemplo se creará en App.jsx
import { useEffect } from 'react'

function App() {
  useEffect(() => {
    const mapajs = window.M.map({
      container: "map"
    });
    console.log(mapajs)
  }, [])

  return (
    <>
      <div className='map' id='map'></div>
    </>
  )
}

export default App

En el caso de Vite para levantar el proyecto se utiliza npm run dev, es lo mismo que hacer npm start o npm run start.

*** Para poder ver el resultado en una máquina distinta a la que se levanta el proyecto, habrá que modificar el archivo vite.config.js de la siguiente manera

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    host: true,
    port:3000 // o el puerto que se quiera
  },
})

Remarcar la necesidad de importar los CDN en el archivo index.html que se encuentra en la carpeta public para poder utilizar la API-CORE dentro de la carpeta src.

Para los visualizadores creados con npx create-next-app, para el desarrollo en local se utilizará el comando npm start o npm run start, este comando levanta un servidor de desarrollo.

Para compilar el proyecto se utilizará npm run build, en el caso de utilizar Maven se usará mvn clean package.

Estructura del proyecto/plugin

/
├── src 📁                  # Código fuente.
    ├── components                 # Componentes.
    ├── index.js                   # Archivo principal de src.
    ├── languages                  # Traducciones.
    ├── pages                      # Páginas de la aplicación.
    ├── registerServiceWorker.js   # Proyectos de React que utilizan la herramienta Create React App (CRA).
    ├── static                     # Archivos estáticos.
    ├── utils                      # Funcionalidades.
├── public 🌈               # Archivos públicos
├── web.xml 📦              # Contiene la configuración de la aplicación web (Maven).
├── pom.xml 🏗️              # Configuración de Maven.
├── package.json 📋         # Configuración del package.
├── urlwrite.xml 💾         # Utilizado por la librería URLRewriteFilter (Maven).
└── ... 

Uso de Maven

Si se quiere utilizar Maven, se necesitan estos archivos con la siguiente configuración:

  • pom.xml: Archivo XML que contiene información sobre el proyecto y los detalles de configuración utilizados para construir el proyecto.
  • urlwrite.xml: Es utilizado por la librería URLRewriteFilter, que permite la reescritura de URLs en aplicaciones web Java.
  • web.xml: Contiene la configuración de la aplicación web.

Los visualizadores creados con Maven utilizan dos plugins para generar el .war del proyecto (maven-war-plugin, maven-resources-plugin y frontend-maven-plugin).

maven-war-plugin configuración:

${basedir} es una variable de entorno que representa el directorio base del proyecto. Es decir, la ruta absoluta al directorio que contiene el archivo pom.xml.

  • directory: Nombre de la carpeta tras realizar npm run build.
  • webXml: Especificar la ubicación del archivo web.xml que contiene la configuración de la aplicación web.
        <configuration>
          <webResources>
            <resource>
              <directory>dist</directory>
            </resource>
            <resource>
              <directory>${basedir}</directory>
              <targetPath>WEB-INF</targetPath>
              <includes>
                <include>urlrewrite.xml</include>
              </includes>
            </resource>
          </webResources>
          <webXml>${basedir}/web.xml</webXml>
        </configuration>

maven-resources-plugin configuración:

Se utiliza para copiar recursos de la aplicación en el directorio de destino. En este caso, la configuración específica del plugin se establece para la fase "clean" y utiliza el goal "resources" para copiar los recursos.

En concreto, se configura para copiar recursos filtrados a la carpeta "config". También se establece la propiedad "overwrite" en true, lo que significa que cualquier archivo existente en el directorio de destino se sobrescribirá si se encuentra una versión más reciente del mismo archivo en la carpeta de origen.

<executions>
    <execution>
	<id>npm resources filtering</id>
	<goals>
		<goal>resources</goal>
	</goals>
	<phase>clean</phase>
	<configuration>
	  <outputDirectory>config</outputDirectory>
	  <overwrite>true</overwrite>
	</configuration>
    </execution>
</executions>

frontend-maven-plugin configuración:

Este plugin se encarga de crear el "build" de la aplicación (archivos compilados) instalando Node y NPM. Utiliza npm install y npm run build, que tiene que estar configurado en el package.json.

<executions>
<!-- INSTALL NODE AND NPM -->
  <execution>
    <id>install node and npm</id>
	<goals>
	  <goal>install-node-and-npm</goal>
	</goals>
   <phase>generate-resources</phase>
	<configuration>
	  <nodeVersion>v19.7.0</nodeVersion>
	  <npmVersion>9.6.0</npmVersion>
	</configuration>

	</execution>
	<!-- RUNNING NPM -->
	  <execution>
	    <id>run npm install</id>
	      <goals>
		<goal>npm</goal>
		</goals>

	 <phase>generate-resources</phase>
		<configuration>
		  <arguments>install</arguments>
		</configuration>

		</execution>
		<!-- RUN BUILD -->
		<execution>
		<id>npm run build</id>
		<goals>
			<goal>npm</goal>
		</goals>
		<phase>generate-resources</phase>
		<configuration>
			<arguments>run build</arguments>
		</configuration>
  </execution>
</executions>

Guía de desarrollo de componentes

Para desarrollar componentes en la API-CNIG:

  1. Crear una carpeta con el componente, esta carpeta se recomienda que esté en la raíz del proyecto.
    Este directorio tiene que contener un archivo pom.xml, que debe contener las dependencias necesarias para usar el componente y la sección del "parent", igual que tienen el resto de componentes. Con esta sección, nuestro componente puede heredar algunas propiedades del POM principal (artefacto padre).

Por ejemplo, si se creara un nuevo componente llamado "api-ign-module", el archivo pom.xml quedaría de la siguiente forma:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <artifactId>api-ign-module</artifactId>
   <packaging>pom</packaging>
   <name>API IGN MODULE</name>
   <!-- SECCION DEL PARENT -->
   <parent>
     <groupId>es.ign.api</groupId>
      <artifactId>api-ign-parent</artifactId>
      <version>4.4.0</version>
      <relativePath>../api-ign-parent/pom.xml</relativePath>
   </parent>
   <!---->
</project>

Dependiendo del componente se tendrá que definir que dependencias y que proceso de "build" se necesita seguir. Por ejemplo, si se quiere cargar un componente de JavaScript quedaría de la siguiente forma:

   <build>
      <finalName>api-core</finalName>
      <plugins>
         <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>1.6</version>
            <configuration>
               <workingDirectory></workingDirectory>
            </configuration>
            <executions>
               <!-- INSTALL NODE AND NPM -->
               <execution>
                  <id>install node and npm</id>
                  <goals>
                     <goal>install-node-and-npm</goal>
                  </goals>
                  <phase>generate-resources</phase>
                  <configuration>
                     <nodeVersion>v12.18.4</nodeVersion>
                     <npmVersion>6.14.8</npmVersion>
                     <!--<nodeDownloadRoot>http://nodejs.org/dist/</nodeDownloadRoot>
                        <npmDownloadRoot>http://nodejs.org/dist/</npmDownloadRoot> -->
                  </configuration>
               </execution>
               <!-- RUNNING NPM -->
               <execution>
                  <id>run npm install</id>
                  <goals>
                     <goal>npm</goal>
                  </goals>
                  <phase>generate-resources</phase>
                  <configuration>
                     <arguments>install</arguments>
                  </configuration>
               </execution>
               <!-- RUNNING NPM BUILD -->
               <execution>
                  <id>run npm build</id>
                  <goals>
                     <goal>npm</goal>
                  </goals>
                  <phase>generate-resources</phase>
                  <configuration>
                     <arguments>run build</arguments>
                  </configuration>
               </execution>
            </executions>
         </plugin>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
               <execution>
                  <id>packed build javascript</id>
                  <goals>
                     <goal>single</goal>
                  </goals>
                  <phase>package</phase>
                  <configuration>
                     <descriptors>
                        <descriptor>assembly/dist-resources.xml</descriptor>
                        <descriptor>assembly/doc-resources.xml</descriptor>
                        <descriptor>assembly/templates-resources.xml</descriptor>
                     </descriptors>
                  </configuration>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>

Todo esto se realiza dentro de la etiqueta <build>, se usan los plugins necesarios para definir que versión de Node.js y de NPM se va a utilizar, genera el "build" con los archivos minificados, ...

  1. Se tiene que configurar el archivo pom.xml que se encuentra dentro de la carpeta api-ign-parent, añadiendo a la etiqueta modules un nuevo componente, por ejemplo "api-ign-module" que quedaría de la siguiente forma:
   <modules>
      <module>../api-ign-js</module>
      <module>../api-ign-proxy</module>
      <module>../api-ign-database</module>
      <module>../api-ign-rest</module>
      <module>../api-ign-module</module>
   </modules>

1.INICIO
   1.1. Componentes de la API-CNIG
   1.2. Documentación y Puntos de acceso
   1.3. Primeros pasos
   1.4. Diagrama API CNIG

2. MAPA
2.1. Capas

 ■ 2.1.1. Fuentes
   • 2.1.1.1. Capas vectoriales
     + Vector
     + WFS
     + GeoJSON
     + KML
     + MVT
     + OGCAPIFeatures
     + MBTilesVector
     + GenericVector
   • 2.1.1.2. Capas ráster
     + WMS
     + WMTS
     + TMS
     + XYZ
     + OSM
     + MBTiles
     + GenericRaster
   • 2.1.1.3. Capas rápidas

 ■ 2.1.2. Simbolización
   • 2.1.2.1. Genérica
     + Puntos
     + Líneas
     + Polígonos
   • 2.1.2.2. Básica
     + Puntos
     + Líneas
     + Polígonos
   • 2.1.2.3. Avanzada
     + Coropletas
     + Proporcional
     + Categorías
     + Estadísticos
     + Mapas de Calor
     + Cluster
     + Línea de flujo
     + Composición

 ■ 2.1.3. Filtros

    2.3. Plugins

2.4. Paneles

  ■ Creación de panel desde cero sin controles

  ■ Tutorial Panel de un único control

  ■ Tutorial Panel de un único control con más de un botón

  ■ Tutorial Panel con más de un control

2.5. Eventos

  ■ Gestión de eventos
  ■ Gestión de eventos en controles personalizados

    2.6. Internacionalización

    2.7. Configuración

    2.8. Acceso librerías base

3. UTILIDADES

4. PROXY

5. API REST
 5.1. Parametrización API-REST
 5.2. Base de Datos API-REST
 5.3. API REST Actions
 5.4. Servicio de correos electrónicos
 5.5. Capas rápidas

6. PARAMETRIZACIÓN VISUALIZADORES

7. SOLUCIÓN DE PROBLEMAS

8. PROCESO DE VERSIONADO

9. GUÍA DE DESARROLLO
  > Guía de desarrollo de plugins
  > Guía de desarrollo de visualizadores con React
  > Guía de desarrollo de componentes
  > Guía para el desarrollo de API-CNIG
  > Compilación proyecto API-CNIG

Clone this wiki locally