GeoJSON转STL:地形3D打印

我们通过将 GeoJSON 形状坐标提取到点云中并使用 Open3d 应用泊松重建,从 GeoJSON 数据重建 STL 网格。
在这里插入图片描述

推荐:用 NSDT编辑器 快速搭建可编程3D场景

我对打印 GeoJSON 山丘的第一次尝试深感不满,因此想出了一个三步流程,仅使用开源软件即可生成高保真复制品。 这个过程分为三个步骤:

  • 使用 Geopandas 对大型 geojson 地图进行切片。
  • 创建 geojson 几何体的 XYZ 点云(利用 Shapely 和 Geopandas)。
  • 使用 Open3D 为 XYZ 点云构建 TriangleMesh。
  • 使用 Blender 从该网格中挤出实体。

对于本次迭代,我们将尝试对包括电报山在内的悬崖边进行建模。 如果你想自己尝试一下,这是我的脚本和 SF GeoJSON 数据。

不过我发现了一个更好的方法实现3D地形的打印:你可以用NSDT 3DConvert这个在线工具将GeoJSON转换为STL,不需要本地安装任何软件,只需要把你的GeoJSON文件拖拽到网页的面板里就好了:

在这里插入图片描述

1、地球切片

GeoPandas 使用地理数据和空间基元扩展了 Pandas 数据框。 它允许我们将形状剪辑到我们感兴趣的经度、纬度指定窗口,将坐标转换为 UTM X 和 Y 米等等。

首先,我们对 SF geojson 地图进行切片,使其仅包含 Telegraph Hill 坐标内的要素(以及要素的各个方面):

#!/usr/bin/env python3
import geopandas
from shapely.geometry import Polygonoutname = "telegraph_hill"
y1, x1 = (37.8053307084282, -122.40853235179131)
y2, x2 = (37.79953896610929, -122.40128101638189)gdf = geopandas.read_file('geojson/sf.geojson')
polygon = Polygon([(x1, y1), (x1, y2), (x2, y2), (x2, y1), (x1, y1)])
gdf_clipped = gdf.clip(polygon)
gdf_clipped.to_file(f"geojson/{outname}.geojson", driver='GeoJSON')
gdf_clipped = gdf_clipped.explode(index_parts=True)  #Line Segments only!

2、从 GeoJSON 生成点云

第 1 步为我们提供了所需坐标内形状的“GeoDataFrame”。 我们现在需要将这些相关形状转换为点云,然后转换为三角形网格以进行 3D 打印。

我们将继续使用 geopandas 将坐标从长、纬度转换为距原点的 X、Y 米,并将这些坐标与源数据“高程”属性中的 Z 数据连接起来。 然后,这些数据点会初始化 Open3d 点云。

import open3d as open3dCONV_FT_TO_M = 0.3048  # SFData provides elevation in feet :(def compute_gdf_pointcloud(gdf: geopandas.GeoDataFrame, z_scale: float) -> o3d.geometry.PointCloud:"""Compute the PointCloud of the GeoDataFrame."""min_x, min_y = (99999999,99999999)min_elevation = min([e for e in gdf['elevation']])for f in gdf['geometry']:for c in f.coords:if c[0] < min_x:min_x = c[0]if c[1] < min_y:min_y = c[1]logging.debug(f"min_x={min_x} min_y={min_y} min_elevation={min_elevation}")gdf['flat_coordinates'] = gdf['geometry'].combine(gdf['elevation'],(lambda g, e: [(float(c[0] - min_x),float(c[1] - min_y),float(e) * CONV_FT_TO_M * z_scale) for c in g.coords]))# Add these coordinates to an Open3d point cloud.pcd = o3d.geometry.PointCloud()pcd.points = o3d.utility.Vector3dVector()for coordinate_list in gdf['flat_coordinates']:pcd.points.extend(o3d.utility.Vector3dVector(coordinate_list))# Estimate normals.pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30))pcd.orient_normals_to_align_with_direction()return pcd

在这里插入图片描述

3、为 XYZ 点云构建 TriangleMesh

我们现在尝试使用法线从点云重建泊松网格。 泊松网格重建还返回每个推断三角形的密度数据,这使我们能够在必要时修剪无关的推断区域。 这也是我们唯一有趣的颜色。

import open3d as o3d
import numpy as np
import matplotlib.pyplot as pltdef compute_poisson_mesh(pcd: o3d.geometry.PointCloud, depth: int) -> o3d.geometry.TriangleMesh:"""Compute the mesh of the point cloud.depth:    The depth of the octree used for the surface reconstruction determines resolution of the resulting triangle mesh."""poisson_mesh, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=depth, width=0, scale=1.1, linear_fit=True)# Color the supporting point density.densities = np.asarray(densities)graph_rate = (densities - densities.min()) / (densities.max() - densities.min())density_colors = plt.get_cmap('plasma')(graph_rate)density_colors = density_colors[:, :3]poisson_mesh.vertex_colors = o3d.utility.Vector3dVector(density_colors)# Trim any excess surface from the Poisson reconstruction.bbox = pcd.get_axis_aligned_bounding_box()p_mesh_crop = poisson_mesh.crop(bbox)p_mesh_crop.compute_triangle_normals()return p_mesh_crop

在这里插入图片描述

总的来说还不错! 从点密度推断,网格的颜色表示有多少点(来自我们的点云)表示给定多边形的置信度。 由于我们的流程受益于矩形网格(请参阅下一步),因此我们不会修剪任何多余的区域。

4、修复和3D打印

我们需要修复几何体中的一些孔,并可选择创建一个有效的实体(山应该是空心的)。 要修复孔,请将 STL 导入 Blender 并在编辑模式下选择孔周围的顶点,然后按“alt-F”用三角形填充孔。

在这里插入图片描述

STL 漏洞修补的通用解决方案留给读者作为练习。

我们现在应该能够挤出网格并使用二等分工具保留上部。 沿途检查非流形面,并在导出前重新计算法线。
在这里插入图片描述

这比我最初的预期要好得多!


原文链接:GeoJSON转STL打印地形 — BimAnt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/134113.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

私域流量的优势

私域流量是指由自身品牌或个人拥有并具备完全掌控权的流量资源。它相比于传统的广告推广&#xff0c;拥有独特的优势。 首先&#xff0c;私域流量能够更加精准地定位目标用户&#xff0c;实现精准传播。不再盲目投放广告&#xff0c;而是通过建立自身社群、粉丝群&#xff0c;获…

HarmonyOS开发:那些开发中常见的问题汇总(一)

前言 本来这篇文章需要讲述静态共享包如何实现远程依赖和上传以及关于静态共享包私服的搭建&#xff0c;非常遗憾的告诉大家&#xff0c;由于组织管理申请迟迟未通过&#xff0c;和部分文档官方权限暂未开放&#xff0c;关于这方面的讲解需要延后了&#xff0c;大概需要等到202…

什么是 JxBrowser

什么是 JxBrowser 文章目录 什么是 JxBrowser如何使用 JxBrowser容易集成支持的平台Java丰富的文档如何运行主要功能值得信赖成熟的专业技术团队及时的支持与帮助参考资料 JxBrowser 是一个商业跨平台 Java 库&#xff0c;可以让您将基于 Chromium 的网页浏览器控件集成到您的 …

基于springboot+vue的药店管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

为什么选择C/C++内存检测工具AddressSanitizer?如何使用AddressSanitizer?

目录 1、C程序中的内存问题 2、AddressSanitizer是什么&#xff1f; 3、AddressSanitizer内存检测原理简述 3.1、内存映射 3.2、插桩 4、为什么选择AddressSanitizer&#xff1f; 4.1、Valgrind介绍 4.2、AddressSanitizer在速度和内存方面为什么明显优于Valgrind 4.3…

无需开通美团外卖会员一日三餐都可天天免费领取美团外卖红包优惠券?

美团外卖红包一天三餐都可用享优惠&#xff1f; 通过草柴公众号&#xff0c;回复美团外卖&#xff0c;天天都可以免费领取一次美团外卖节红包、天天神券1-3个。根据用餐标准早上吃少用3元天天神券、午餐吃饱用7元外卖节红包、晚餐吃好用6元外卖节红包。 *注&#xff1a;每天的…

stm32---定时器输入捕获

一、输入捕获介绍 在定时器中断实验章节中我们介绍了通用定时器具有多种功能&#xff0c;输入捕获就是其中一种。 STM32F1除了基本定时器TIM6和TIM7&#xff0c;其他定时器都具有输入捕获功能 。输入捕获可以对输入的信号的上升沿&#xff0c;下降沿或者双边沿进行捕获&#xf…

VR航天航空巡展VR科技馆航天主题科普设备沉浸遨游太空

每当飞机飞过头顶&#xff0c;我们总是忍不住抬头去仰望。从嫦娥奔月的神话传说&#xff0c;到莱特兄弟实现了上天翱翔的梦想&#xff0c;人类一直在不断探索更辽阔的天空和浩瀚的宇宙。 航空科普 寻梦而行 普乐蛙VR航天航空巡展&#xff0c;正在湖南郴州如火如荼的进行中&…

前端vue3分享——项目封装axios、vite使用env环境变量

文章目录 ⭐前言⭐vue3封装统一的axios请求&#x1f496; 请求拦截器 ⭐vue3使用env环境变量&#x1f496; vite env变量规则&#x1f496; vite.config获取env参数 ⭐总结&#x1f496; 编码sliod原则 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于前端…

C. Manipulating History

Problem - 1688C - Codeforces 思路&#xff1a;因为它给定了最终的串&#xff0c;能够想到能够通过逆操作将整个序列变回去&#xff0c;那我们需要有一个形式str,a,b即在str中将a替换为b&#xff0c;很容易能够看出来&#xff0c;a中的字符串出现了两次&#xff0c;在str中一次…

关于老项目从JDK8升级到JDK17所需要注意的细节

文章目录 ☀️1.关于老项目从JDK8升级到JDK17所需要注意的细节&#x1f338;1.1.更新JDK&#x1f338;1.2.修改Idea中的JDK版本&#x1f338;1.3.关于修改过程中遇到的异常&#x1f338;1.4.IDEA工具栏操作Maven正常&#xff0c;但使用mvn命令运行就报错 ☀️1.关于老项目从JDK…

PCB layout在布线上的设计规范有哪些?

PCB Layout是一项技术活&#xff0c;也是经验活&#xff0c;良好的PCB Layout布线可帮助工程师确保最终的电路板性能、可靠性和制造质量&#xff0c;因此是很多电子工程师的学习重点&#xff0c;下面我们来盘点下PCB Layout关于布线的规范有哪些。 1、地管的引脚接地越短越好&a…

高阶数据结构(2)-----红黑树(未完成)

一)红黑树的基本概念和基本性质: 1)红黑树就是一种高度平衡的二叉搜索树&#xff0c;但是在每一个节点上面都增加了一个存储位来表示结点的颜色&#xff0c;可以是红色或者是黑色&#xff0c;通过对任何一条从根节点到叶子节点上面的路径各个节点着色方式的限制&#xff0c;红黑…

java:逆序排序的三种方法

// 逆序第一种方法 public static void main(String[] args) {int arr[] {11, 22, 33, 44, 55, 66};for (int i arr.length-1; i > 0; i--) {System.out.print("\t"arr[i]);}}缺点&#xff1a;这个是直接逆转&#xff0c;如果里面是随机数没办法比较 逆序第二种…

在ubuntu18.04上编译C++版本jsoncpp/opencv/onnxruntime且如何配置CMakelist把他们用起来~

这篇文章背景是笔者在ubuntu上编译C代码&#xff0c;依赖一些包&#xff0c;然后需要编译并配置到CMakelist做的笔记。主要也是一直不太懂CMakellist&#xff0c;做个笔记以防忘记&#xff0c;也给读者提供一站式的参考&#xff0c;可能您需要的不是这几个包&#xff0c;但大同…

【多区域电力系统模型】三区域电力系统的LQR和模糊逻辑控制(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【Python从入门到进阶】35、selenium基本语法学习

接上篇《34、selenium基本概念及安装流程》 上一篇我们介绍了selenium技术的基础概念以及安装和调用的流程&#xff0c;本篇我们来学习selenium的基本语法&#xff0c;包括元素定位以及访问元素信息的操作。 一、元素定位 Selenium元素定位是指通过特定的方法在网页中准确定位…

【教程】IDEA操作GIT

不小心推送代码之后 进行回退 1 找到需要回退的记录 比如要回退13分钟之前提交的代码 选中 右键还原提交 最后再重新推送被还原的提交 就可以了

ArcGIS10.1软件安装教程

ArcGIS10.1中英文&#xff08;32/64位)下载地址&#xff1a; 链接&#xff1a; https://pan.baidu.com/s/1Ksm112WaKMMk6La9ircCng 密码&#xff1a;t70f 安装步骤&#xff1a; 1、我们对安装包进行解压&#xff0c;直接鼠标右击解压即可。 2、 打开我们解压的文件夹&#…

【抖音小游戏】 Unity制作抖音小游戏方案 最新完整详细教程来袭【持续更新】

前言【抖音小游戏】 Unity制作抖音小游戏方案 最新完整详细教程来袭【持续更新】一、相关准备工作1.1 用到的相关网址1.2 注册字节开发者后台账号二、相关集成工作2.1 下载需要的集成资源2.2 安装StarkSDK和starksdk-unity-tools工具包2.3 搭建测试场景三、构建发布3.1 发布Nat…