Cómo integrar elementos 3D sobre el terreno utilizando la API de TR3.js


Recreando en TR3.js la ermita de Los Santos de la Humosa


La ermita de Los Santos de la Humosa fue modelizada mediante dron (RPA) como trabajo de fin de grado por Javier Gabás Jiménez, quien ha compartido el modelo para poder integrarlo con los mapas 3D de terre3.


1. Introducción

Una de las posibilidades de la API TR3 es la integración de elementos 3D sobre el terreno y para ello vamos a integrar un elemento de interés patrimonial como una ermita que data en sus orígenes en 1384.

Como se ve el resultado es la ermita 3D geolocalizada en escala y forma sobre un mapa 3D utilizando software libre como Openlayers y ThreeJS, utilizando la cobertura de mapa de OpenStreetMap.


2. Estructura

Estructura de carpetas

Tiene una estructura sencilla donde encontramos TR3-min, unas librerías de jquery para manejar algunos elementos gráficos y proj4js para hacer un cambio de proyección.

TR3-min: Contiene algunos recursos extra lo acompañan como un pdf para hacerse unas gafas anaglifo caseras o imágenes para el panel de mandos.

TR3.js: Este recurso no se encuentra en guithub directamente si no que los ejemplos lo recogen de la ruta que centraliza este recurso en http://terre3.es/API/TR3.js

De este modo las actualizaciones de la API afectan a toda la gama de ejemplos conservando su transversalidad y consistencia.

Jquery: Se usa para dos utilidades que son los sliders y un selector de colores para las geometrías que se quieran dibujar de forma interactiva.

Proj4js: Se utiliza para el ejemplo y se encarga de solicitar en EPSG:25830 el mapa de OpenStreetMap.

Index: Ejecuta el código para la realización del ejemplo.


3. Código

El código son básicamente 3 líneas de TR3 introducido en un ejemplo base de openlayers que pasamos a desglosar.

• En el HEAD tenemos las llamadas internas de todas las librerías que hemos mencionado Jquery, OL6, TR3 y proj4js y un poco de estilo CSS. El orden de llamada es indiferente ya que son librerías independientes que no interfieren en su base de código.

• En el BODY se crean algunos dív para alojar los elementos HTML del ejemplo:

						
<div id="map" class="map"></div>
<div id="TR3" class="TR3"></div>
<div id="tools" class="tools" ></div>
<div id="progress" style=”display:none”></div>
						
					

Map contiene el mapa de openlayers que realizamos, TR3 es el lugar donde crea el CANVAS para el mapa 3D y toos es la zona donde se crea el diálogo de jquery para alojar la caja de herramientas de TR3. Por lo demás progress es un añadido de openlayers que resulta útil pero no necesario, así que le introducimos un estilo para ocultarlo y no afecte al ejemplo.

• La zona de SCRIPT resuelve la integración:

						
TR3.setLoader( 'TR3-min/' );
document.getElementById('tools').innerHTML = TR3.setPanel();
$( "#tools" ).dialog();
						
					

Aquí aparecen ya dos de las tres líneas de TR3 que se requieren. setLoader, es la línea que prepara el código e indica como parámetro la ruta a la carpeta donde obtiene el resto de recursos, que en este caso se llama TR3-min, así cualquier desarrollador puede manipular esta carpeta a su antojo y referenciarla como desee.

La siguiente setPanel, no tiene parámetro ya que simplemente trae el HTML de la caja de herramientas para incorporarlo al div preparado para ello en tools.

Finalmente se introduce éste último en un diálogo de jquery:

						
function setTR3fn() {
	var bbox = map.getView().calculateExtent(map.getSize());
	var code = map.getView().getProjection().getCode();
	var desty = document.getElementById('TR3');
	var oriAux = $('#map').find('canvas');
	var ori = oriAux[0];
	TR3.setStart(ori, desty, bbox, code);
	if (isFinite(ol.extent.getIntersection(bbox, [coordsOBJ[0], coordsOBJ[1], coordsOBJ[0], coordsOBJ[1]])[0])) {
		TR3.loadFile("TR3-min/obj3d/ermita.glb" /*src*/ , [coordsOBJ[0], coordsOBJ[1], 606.3] /*coords*/ , false /*animation*/ , [14, 14, 14, true] /*scale*/ , false /*rotate*/ , false /*transformControls*/ , false, 'http://oa.upm.es/47389/');
		TR3.setLookAt([476439.46238117624, -0.15672329751986722, -4486180.010050892, 476491.00072438107, 47.47845359301541, -4486073.679598657]);
		TR3.setOptions(false /*imgControl*/ , false /*cursor*/ , false /*anaglyph*/ , true /*autoRotate*/ , false /*wireframeMesh*/ );
	}
}
map.on('moveend', setTR3);
//map.on('update', setTR3);
						
					

Para ejecutar la función que genera el mapa 3D propiamente necesitamos incluirlo en una función ya que dependerá de eventos de openlayers. Moveend es el evento que ejecuta cuando el usuario termina de mover el mapa, y update es el evento que ejecuta cuando las tiles terminan de cargar.

Para ejecutar setStart se necesitan varios parámetros:

  • Ori: Es el lugar concreto donde la imagen del mapa de openlayers se crea, que en este caso es un CANVAS.
  • Desty: Es el div que hemos creado y llamado “TR3” para ubicar el mapa 3D resultante.
  • Bbox: Son las coordenadas que contienen la imagen del mapa en el CANVAS, la esquina inferior izquierda y la superior derecha en un array [x,y,X,Y].
  • Code: Es el sistema de coordenadas empleado según el formato EPSG.

Así que cada vez que se ejecute esta función se recogen los parámetros y se ejecuta la función que genera el mapa 3D.


4. Integración del elemento 3D

La integración la aplicamos mediante 3 funciones que nos permiten configrurar el entorno 3D tal como lo queremos recrear.

• TR3.loadFile: Se encarga de localizar y ajustar el modelo 3D para sumar a la escena, indicando la dirección del objeto, coordenadas, escala y enlace de acceso al interactuar con click sobre el objeto, entre otros.

• TR3.setLookAt: Adapta la cámara para una visualización del objeto adecuada, mediante las coordenadas de posición de cámara y del punto al que visualiza.

• TR3.setOptions: Utilizamos esta función para que la cámara rote sobre el objeto obteniendo una panorámica 360 del mismo con autoRotate: true.


5. Conclusión

Así que de esta forma aplicando 3 sencillas funciones, setLoader, setPanel y setStart y algo de conociendo el entorno de openlayers 6 para pasar los parámetros adecuados, logramos incluir en nuestro visor un completo entorno 3D con herramientas para utilizar de forma directa como la integración de objetos tridimensionales. Utilizando además recursos totalmente gratuitos y sin ningún tipo de suscripción partiendo de datos fiables y públicos.




Sobre el Autor


Agustin Costa Cimadevilla

Desarrollador de web en entornos geoespaciales desde 2010 con una larga trayectoria profesional vinculado a proyectos del Instituto Geográfico Nacional y el Centro Nacional de Información Geográfica en proyectos como la fototeca o iberpix.

Mi experiencia ligada a proyectos de I+D e inquietud por los recursos gráficos como WebGL me ha llevado a crear proyectos personales como https://terre3.es donde trato de innovar libremente y aportar prototipos a la comunidad que resuelvan nuevas maneras de aplicar la información geoespacial en 3D.

Involucrado en el análisis estadístico espacial mediante Big Data y el estudio de algoritmos de aplicación para Data Science.


¿Eres desarrollador? Únete a la red