Ejemplos
Estos guiones usan la interfaz de programación de aplicaciones (API) de la Referencia del módulo lop. Para ejecutar uno, cópialo en el editor del panel Python y pulsa Ejecutar.
Datos de la vista y de las nubes
Escribe en Salida el tamaño del área de dibujo, la caja de las nubes abiertas, el punto de referencia para la navegación y las nubes editables.
import lop
v = lop.viewer
tamano = v.SizeInPixels
print("Área de dibujo:", tamano.Item1, "x", tamano.Item2, "píxeles")
caja = v.Domain
print("Mínimo:", caja.Min.X, caja.Min.Y, caja.Min.Z)
print("Máximo:", caja.Max.X, caja.Max.Y, caja.Max.Z)
origen = v.NavigationReferencePoint
print("Punto de referencia para la navegación:", "no disponible" if origen is None else origen)
nubes = v.EditableClouds
print(nubes.Count, "nubes editables:")
for ruta in nubes:
print(" ", ruta)
Cambiar la visualización
Colorea los puntos por cota con la escala Viridis, aplica el factor de tamaño 2, activa el sombreado por profundidad (EDL, del inglés Eye-Dome Lighting) y fija un fondo gris oscuro.
import lop
from Lop.Core.Models import ColorAttribute, ColorRamp
from Lop.Core.Services import ColorRgba
v = lop.viewer
v.ColorAttribute = int(ColorAttribute.Elevation)
v.ColorRamp = int(ColorRamp.Viridis)
v.PointSizeScale = 2
v.EdlEnabled = True
v.SetBackgroundColor(ColorRgba.FromHex("#202020"))
Vista superior de todas las nubes
Lanza las órdenes Arriba y Zoom extensión, igual que sus botones de la pestaña Visualización.
import lop
lop.run_command("lop.view.top")
lop.run_command("lop.view.zoom-extents")
El punto del centro de la pantalla
Busca el punto de la nube que se ve en el centro del área de dibujo, escribe sus coordenadas y lo marca en la vista.
import lop
v = lop.viewer
tamano = v.SizeInPixels
centro_x = tamano.Item1 / 2
centro_y = tamano.Item2 / 2
punto = v.LocatePoint(centro_x, centro_y, 10)
if punto is None:
print("No hay ningún punto en el centro de la pantalla.")
else:
print(f"X {punto.X:.3f} Y {punto.Y:.3f} Z {punto.Z:.3f}")
v.SelectedPoint = punto
Borrar los puntos de una esfera
Selecciona los puntos dentro de un radio de 2 unidades de la nube del punto del centro de la pantalla y anota su borrado en el registro de ediciones de las nubes. El borrado se deshace con Deshacer de la barra de título.
import lop
from Lop.Core.Services import EditAction
v = lop.viewer
tamano = v.SizeInPixels
centro = v.LocatePoint(tamano.Item1 / 2, tamano.Item2 / 2, 10)
if centro is None:
print("No hay ningún punto en el centro de la pantalla.")
else:
v.SelectBySphere(centro, 2.0)
nubes = v.ConfirmEdit("Sphere", EditAction.Delete, 0)
print("Borrado anotado en", nubes, "nubes")
Para clasificar los puntos en vez de borrarlos, usa EditAction.AssignClass y la clase en el tercer argumento:
v.ConfirmEdit("Sphere", EditAction.AssignClass, 6).
Historial de ediciones
Escribe los eventos de los registros de ediciones de las nubes abiertas, con su fecha.
import lop
from datetime import datetime
for evento in lop.viewer.EditingHistory:
fecha = datetime.fromtimestamp(evento.EventId / 1000)
print(f"{fecha:%d/%m/%Y %H:%M:%S} {evento.EventCode} ({evento.Clouds} nubes)")
Ejecutar un algoritmo por teselas
Lanza Clasificar por altura, de Algoritmos básicos en Clasificación de puntos.
El identificador de la orden es
lop.algorithm. seguido del identificador del algoritmo. El algoritmo usa los valores de sus parámetros de la
ventana Configuración y sigue ejecutándose cuando el guion termina.
import lop
lop.run_command("lop.algorithm.lop.example.height_classifier")
Ocultar las esferas de las imágenes esféricas
Escribe el nombre y las coordenadas de cada imagen esférica y deja de dibujar su esfera.
import lop
for foto in lop.viewer.SphericalPhotos:
c = foto.Coordinates
print(f"{foto.Name}: {c.X:.3f} {c.Y:.3f} {c.Z:.3f}")
foto.ShowSphere = False
Perfil del terreno con numpy
Recorre la caja de las nubes desde la coordenada X mínima hasta la máxima por su centro, en 50 posiciones, y busca en cada una el punto cargado más bajo en un cilindro vertical de 0,5 unidades de la nube de radio, como la herramienta Dibujar altura. Escribe cuántas posiciones tienen punto y las cotas mínima y máxima.
import lop
import numpy as np
from Geometries import Point3D
v = lop.viewer
caja = v.Domain
y = (caja.Min.Y + caja.Max.Y) / 2
abajo = caja.Min.Z - 1
arriba = caja.Max.Z + 1
xs = np.linspace(caja.Min.X, caja.Max.X, 50)
cotas = []
for x in xs:
suelo = v.FirstPointInCylinder(Point3D(float(x), y, abajo), Point3D(float(x), y, arriba), 0.5)
cotas.append(np.nan if suelo is None else suelo.Z)
cotas = np.array(cotas)
encontrados = np.count_nonzero(~np.isnan(cotas))
print("Posiciones con punto:", encontrados, "de", len(cotas))
if encontrados > 0:
print("Cota mínima:", np.nanmin(cotas), " cota máxima:", np.nanmax(cotas))
FirstPointInCylinder busca entre los puntos que el visor tiene cargados en ese momento, y los nodos cargados
dependen de la posición de la cámara: el mismo guion puede dar cotas distintas con otra vista.
Comando que filtra puntos y nubes
Guarda este código como select_building.py en %AppData%\lop\commands y reinicia Lot Of Points.
El comando acepta puntos de clase 6 de nubes editables, consulta la esfera de esa nube y selecciona sus puntos
de clase 6. El filtro puede aceptar candidatos de una nube oculta cercana al punto pulsado.
import lop
import numpy as np
@lop.command("example.select_building", "Seleccionar clase 6",
existing_tab_id="lop.tab.edit", ribbon_section="Mis comandos",
requirements=lop.REQUIRES_VISIBLE_CLOUD | lop.REQUIRES_EDITABLE_CLOUD)
def select_building(host):
point = host.ask_point(
"Pulsa un punto de clase 6; Esc para cancelar",
accept_point=lambda p, cloud: p.classification == 6
and cloud.editable and cloud.has_original_point_indices)
if point is None:
return
points = host.points_in_sphere(point, 2.0, cloud_ids=[point.cloud_id])
if points is None:
return
if not points.complete:
host.log("La consulta no ha cargado todos los puntos.")
return
host.select_points(points, np.flatnonzero(points.classification == 6))
Al terminar el comando, aplica Borrar, Clasificar o Aislar desde Acciones. El radio de búsqueda es de 2 unidades de la nube.
Comando que procesa nubes por teselas
Guarda este código como classify_tiles.py en la carpeta de comandos y reinicia Lot Of Points.
El comando elige las nubes editables con índices originales, incluidas las ocultas, y asigna la clase 1
a sus puntos mediante process_tiles.
import lop
@lop.command("example.python.classify_tiles", "Asignar clase 1",
existing_tab_id="lop.tab.classification",
ribbon_section="Mis comandos", requirements=lop.REQUIRES_EDITABLE_CLOUD)
def classify_tiles(host):
clouds = host.clouds()
if clouds is None:
return
ids = [c.cloud_id for c in clouds
if c.editable and c.has_original_point_indices]
if not ids:
return
options = lop.TileOptions(tile_core_side_length_cloud_units=100.0,
estimated_peak_bytes_per_point=1.0)
def process_tile(tile, result, tile_host):
if tile_host.cancelled():
return
result.classification[:] = 1
tile_host.report_tile_progress(1.0)
summary = host.process_tiles(ids, options, process_tile)
if summary is not None:
host.log(f"{summary.reclassified_point_count} puntos reclasificados")
Para consultar puntos sin editarlos, usa read_only=True y trata result como None.
Para cargar un GeoPackage generado por un comando, llama a host.load_geopackage(r"C:\datos\resultado.gpkg")
antes de terminar la función del comando.