我的世界 ParaCraft 结合开源地图 OpenStreetMap 生成3D校园的方法简介
我的世界ParaCraft结合开源地图OpenStreetMap生成3D校园的方法简介
版本1.0 日期2019.2.3 作者Ray (82735589@qq.com) www.TimeGIS.com
0. 目标
Paracraft是LiXiZhi开发的一种类似我的世界Minecraft 的3D编辑软件,
Paracraft开放源码,可以在 https://github.com/LiXizhi 找到更多信息。
本文介绍使用NPL语言(一种类似LUA的语言)开发Paracraft的一个Mod插件:
·
从网页地图选择一个经纬度,将周围的免费GIS地理信息导入到Paracraft:
Raster + Vector --> blocks。 1米=1Block
·
参考 http://www.geoboxers.com/ 高度非线性,非正南正北的建筑
使得Paracraft的世界具备GIS信息。
操作形式,为一个新的Item。放到世界中,则激活。
一种可能的效果如下:

http://geoboxers.com/Stavanger/StavangerOverview/index.html#stavanger_isometric_day/0/5/1057/1044/64


1. 关于OpenStreetMap地图
经过对谷歌地图,百度地图等WebMap的研究,发现我们可以使用www.OpenStreetMap.Org的开源地图.
百度百科介绍OpenStreetMap:
OpenStreetMap(简称OSM)是一个网上地图协作计划,目标是创造一个内容自由且能让所有人编辑的世界地图。具体描述如下:
我们感兴趣的原因是它提供了全球的栅格地图数据和矢量地图数据两种格式,并且是免费的。
可以读读这里:
OpenStreetMap初探(一)——了解OpenStreetMap
http://blog.csdn.net/scy411082514/article/details/7471499

2. GIS背景知识
由于我们的需求和地图相关,所以读者可以去网上了解一些GIS, WebGIS等信息。看看这篇博客:
GIS理论(墨卡托投影、地理坐标系、地面分辨率、地图比例尺、Bing
Maps Tile System)
http://www.cnblogs.com/beniao/archive/2010/04/18/1714544.html
因为我们这里其实是用的WebGIS技术,所以我们需要阅读以下一系列博客:
http://www.cnblogs.com/naaoveGIS/category/600559.html
尤其是其中的这三篇博客:
(二)探究本质,WebGIS前端地图显示之地图比例尺换算原理
(三)WebGIS前端地图显示之根据地理范围换算出瓦片行列号的原理(核心)
(四)WebGIS中通过行列号来换算出多种瓦片的URL 之离线地图
读到这里,对于GIS新手来说,应该是比较累了,但是还要继续,下面这篇很重要:
国内主要地图瓦片坐标系定义及计算原理
http://www.jianshu.com/p/0b292688b6af
3. 关于栅格地图在Paracraft上的显示
通过前面的学习,我们知道栅格地图(或者瓦片地图)URL的规则是这样的:
格式:[Url]http://tile.openstreetmap.org/{ZOOMLEVEL}/{ROW}/{COL}.png[/Url]
名词解释:Tiles 地图切片
Tiles are rectangular slabs of ceramic
affixed in a grid arrangement to your bathroom wall! But here we're much more
likely to be talking about map tiles: square bitmap graphics displayed in a
grid arrangement to show a map. We may also be talking about tiled map data
(described below)
网上有的翻译为瓦片,个人理解为地图切片。简单的说,就是把一张大大的地图,分割成许多小正方形(如下)。这样在加载地图的时候,只需要把区域内相关的小正方形加载出来就可以了。

http://tile.openstreetmap.org/7/63/42.png
如上图,Map tiles 通常是256 x 256 像素的,虽然这不是一定的,但由于Google
Map的影响,这其实已成为实际的标准。
现在我们假设用户输入一个经纬度地址(longitude, Latitude) ,我们
要获取一个Tile: http://tile.openstreetmap.org/7/63/42.png
相应的LUA语句:
local img =
"http://tile.openstreetmap.org/7/66/42.png";
NPL.SyncFile(img, "42.png", "DownloadCallback()",
"open1");
据说可以用System.os.GetUrl()函数异步获取PNG栅格图像。
然后我们可以通过调用paracraft的blockimage命令把地图显示出来:
NPL.load("(gl)script/apps/Aries/Creator/Game/Commands/CommandManager.lua");
local CommandManager = commonlib.gettable("MyCompany.Aries.Game.CommandManager");
CommandManager:RunCommand("/home");
CommandManager:RunCommand("/blockimage -xz open.png");
效果可能如下:这里是垂直的,其实我们用参数 –xz 地图就变到了脚底水平。

注意:前面URL下载下来的图是8bit的PNG, ParaEngine目前只支持真彩色PNG,所以需要改一下,
或者用小画家Pbrush.exe工具重新存盘临时过渡一下。
4. 瓦片地图的坐标计算
瓦片地图包含经纬度坐标信息,所以我们需要将地图的位置换算一下
阅读前面的博客:国内主要地图瓦片坐标系定义及计算原理
或者这里更详细:http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
假设我们要贴一个256*256的单个PNG地图切片到Paracraft上,因为我们有了用户输入的经纬度,
可以通过下面的公式求得瓦片坐标tileX,
tileY, 这里URL的ZoomLevel我们可以取那个最大值19,然后拼出整个URL:
(格式:[Url]http://tile.openstreetmap.org/{ZOOMLEVEL}/{ROW}/{COL}.png[/Url])
然后我们利用下面的公式求得这个PNG的左下角和右上角的经纬度坐标,
256*256的PNG对应Paracraft估计是256×256个格子
并且可以得知用户的当前站立坐标对应到Paracraft格子坐标。

5. 关于3D 校园建筑的展现。
经过研究发现,OpenStreetMap.org也提供了地图的矢量格式文件,叫做OSM文件。它是一种XML文件。
关于OSM文件格式介绍我们可以读以下的博客:
http://www.cnblogs.com/LBSer/p/4451471.html
http://wiki.openstreetmap.org/wiki/Elements
并且在OSM文件内部,它部分提供了一些著名建筑的三维结构图。
http://wiki.openstreetmap.org/wiki/3D
之所以做部分,因为地图的构建是很耗时间的,据说OpenStreetMap生成了德国全境的三维地图,
但是中国境内的地图就比较少了,将来有机会我们可以参与构建地图,:)
关于OpenStreetMap中3D的例子我们可以访问这里:
http://wiki.openstreetmap.org/wiki/3D_development
利用其他软件,我从OpenStreetMap网站下载了浙江大学的校园地图,并利用一个插件把它的三维效果图也显示了出来,从图中我们可以惊喜地看到,校园建筑的轮廓已经有了,不过建筑的不同高度信息缺乏。

关于OSM的手工获取方法可以访问www.openstreetmap.org网站,然后Export出一个osm文件到本地。
这里我们下载上海陆家嘴的例子来说明。

lujiazui.osm的文件内容示例如下:
<?xml version="1.0"
encoding="UTF-8"?>
<osm version="0.6"
generator="CGImap 0.5.8 (5035
thorn-02.openstreetmap.org)" copyright="OpenStreetMap and
contributors"
attribution="http://www.openstreetmap.org/copyright"
license="http://opendatacommons.org/licenses/odbl/1-0/">
<bounds minlat="31.2312000"
minlon="121.4892000" maxlat="31.2484000"
maxlon="121.5136000"/>
<node id="59608490"
visible="true" version="3" changeset="10130036"
timestamp="2011-12-16T10:45:50Z" user="DAJIBA" uid="360397" lat="31.2321150"
lon="121.4917826">
<tag
k="source" v="PGS"/>
</node>
。。。
<way id="40779113" visible="true"
version="13" changeset="43126825"
timestamp="2016-10-24T15:28:02Z" user="lukys1" uid="514683">
<nd ref="495634718"/>
。。。
<nd ref="495634718"/>
<tag k="building" v="yes"/>
<tag
k="building:levels"
v="6"/>
<tag
k="name" v="正大广场"/>
<tag
k="name:en"
v="Super Brand Mall"/>
<tag
k="shop" v="mall"/>
</way>
我们注意到OSM其实就是一种XML文件格式,可以利用LUA语言来分析提取其中的建筑坐标信息。
查询文件中的Way节点,我们可以提取building的轮廓组成一个个polygon,它们带了经纬度坐标信息,我们可以通过公式换算后,对应到Paracraft坐标,把它“画”出来。
<![if !supportLists]>n <![endif]>CommandManager:RunCommand("/take
126");
<![if !supportLists]>n
<![endif]>CommandManager:RunCommand("/box
1 1 1");
幸运的话,著名的建筑都有building:levels高度信息,可以使用它表示建筑的高度,但是一般校园好像没有。
那么如何通过编程的方式下载OSM文件呢?OpenStreetMap网站提供了相应的API,这里提供了说明:
http://wiki.openstreetmap.org/wiki/API_v0.6
http://wiki.openstreetmap.org/wiki/Osmapi
GET
/api/0.6/map?bbox=left,bottom,right,top
例如http://api.openstreetmap.org/api/0.6/map?bbox=120,30.1,120.25,30.2
这里有个C#
包装API的例子可以参考:https://github.com/yrtimiD/osm-api-dotnet
http://wiki.openstreetmap.org/wiki/3D
另外OSM有个工具叫JOSM可以打开OSM文件。
http://josm.openstreetmap.de/wiki/Introduction
并且有个插件可以显示3D
建筑http://wiki.openstreetmap.org/wiki/JOSM/Plugins/Kendzi3D

我改写了一个C#程序https://github.com/BjornDeRijcke/OpenStreetMap-3D
可以分析osm文件并显示建筑,效果如下:

其实最终我们需要的如下结果:(此图拼凑而成)


注:有个OpenStreetMap结合Unity3D例子,它也用C#分析了OSM文件,可以参考。
https://github.com/ActionStreetMap/demo

6.后记
将来,如果觉得建筑不够细致,我们可能需要详细解析OSM文件。
关于OSM的详细解析我们需要阅读下面的标准,并得到类似osm2wolrd的效果
https://wiki.openstreetmap.org/wiki/Simple_3D_buildings
其他参考:

关于地图的存储,我们可以直接从OpenStreetMap读取,也可事先下载到某个服务器,前面博客中有介绍。
关于显示栅格地图,前面只提到了一个瓦片地图PNG的显示,可能我们需要一次读取多个(比如4个)相邻的瓦片地图,并同时显示到一个场景中。
关于需求中提到一个格子表示一米,可能我们需要根据ZOOMLEVEL最大值时获取的瓦片地图(256×256大小)来计算,估计比一米要大,需要进一步研究,但是这个比例应该是可以显示校园了。
7.后记二
Minecraft是一款来自瑞典的沙盒建造独立游戏,玩家可以在一个由程序随机产生的三维世界内以带材质贴图的立方体为基础建造建筑物。游戏最初由瑞典人马库斯·阿列克谢·泊松(Markus
'Notch' Persson)单独开发,随后自2009年起成立Mojang公司开发此游戏。游戏中的其他活动包括探索世界,采集资源,合成物品及对战。TrueCraft是
Minecraft 1.7.3 的一个完全开源的实现,使用C# 语言开发,因此也可以用它来结合OpenStreetMap 生成3D城市。

更多内容,请访问时空地图网站:www.TimeGIS.com
我的世界 ParaCraft 结合开源地图 OpenStreetMap 生成3D校园的方法简介的更多相关文章
- 数据分析 - 开放街道地图(OpenStreetMap)
数据分析 - 开放街道地图(OpenStreetMap) Reinhard使用OpenStreetMap的开放地图数据作为本次数据分析的数据源,使用Python进行数据清洗,使用MongoDB进行数据 ...
- Openlayer4 - 最好最强大的开源地图引擎
Openlayer4 - 最好最强大的开源地图引擎 # githubhttps://github.com/openlayers/openlayers # 官网http://openlayers.org ...
- 2D地图随机生成
2D地图随机生成基础绘图 海陆分布
- Android NFC开发(二)——Android世界里的NFC所具备的条件以及使用方法
Android NFC开发(二)--Android世界里的NFC所具备的条件以及使用方法 NFC的应用比较广泛,而且知识面也是比较广的,所以就多啰嗦了几句,我还还是得跟着官方文档:http://dev ...
- [Swift通天遁地]一、超级工具-(8)地图视图MKMapView的常用代理方法
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- 高德地图与CAD图叠加显示方法汇总及优缺点分析
前言 高德地图应用在许多领域,平常我们用的地图导航,除过正常的地图导航指引功能之外,其实还有很多实用的功能.如高德影像地图应用在包括地理.土地测量.水文学.生态学.气象学以及海洋学等方面.Auto ...
- 开源地图SharpMap源码解析-(1)简介
1.简介 SharpMap最新版基于.NET Framework 4,采用C#开发的地图渲染引擎,非常易于使用.我这次研究的是比较稳定发布的V1.1版本.可以在GitHub下载该源码,地址:https ...
- Linux已经全然统治了这个世界:反对开源社区愚不可及
原文来自:http://readwrite.jp/archives/9977 不管一个企业多强大,它都不存在和开源社区抗衡的实力 十年前.Unix占有最快的计算机世界排名前10位的五席,以及超级计算机 ...
- 开源地图编辑器 MarbleMap,支持Cocos2d-x坐标系
由9秒社团开发并维护的MarbleMap是支持Cocos2d-x坐标系和as3坐标系的地图编辑器,功能完善高效.这里详细介绍一下它的使用方法! 一.功能简述 由9秒社团开发并维护的MarbleMap是 ...
随机推荐
- .NET(C#、VB)APP开发——Smobiler平台控件介绍:SliderView控件
SliderView控件 一. 样式一 我们要实现上图中的效果,需要如下的操作: 从工具栏上的“Smobiler Components”拖动一个SliderView控件到窗体界面上 ...
- 搜狗输入法与VS快捷键有冲突_处理办法
前言:搜狗输入法是大家常用的文字输入工具,但是在开启输入法的时候,VS的一些快捷键无法正常使用,如智能提示快捷键:Ctrl+.,这就非常尴尬了,除非把输入法切换成英文或者卸载搜狗改别的输入法,一个是切 ...
- docker(5):数据的管理
Docker的volume卷 为了能持久话保存和共享容器的数据. 使用docker volume卷的两种方式 1:数据卷 2:数据卷容器 1:数据卷 数据卷:数据卷会绕过docker 的ufs 直接写 ...
- C++对象生存期&&static
生存期,即从诞生到消失的时间段,在生存期内,对象的值或保持不变,知道改变他的值为止.对象生存期分为静态生存期和动态生存期两种. 静态生存期 指对象的生存期与程序运行期相同.在namespace中声明的 ...
- 联发科Helio P90,MT6779VWB芯片处理器
联发科(p90)MT6779VWB芯片是一个集成了蓝牙.fm.wlan和gps模块的高度集成的基带平台,包括调制解调器和应用处理子系统.支持LTE/LTE-A和C2K智能手机应用程序.该芯片集成了两个 ...
- SQL Server使用sp_spaceused查看表记录存在不准确的情况
在之前写过一篇博客"关系数据库如何快速查询表的记录数",里面介绍了使用sp_spaceused查看表的记录数是否正确的问题,具体如下: 关于问题3:有多个索引的表,是否记录数会 ...
- MUI开发大全
最近很久没有更新博客了,因为一直在学习前端h5 手机app的开发.曾经一度觉得自己css和js学得不错,进入到前端领域后才发现水很深~,写代码时HBuilder和VS混用,HBuilder的快捷键和代 ...
- Java提取URL某个参数的值
Java提取Url中某个参数的值. public static String getParam(String url, String name) { String params = url.subst ...
- 一道编程题: 在1~n之间选择若干个数,使其和为m
这是一道很明显的动态规划的题目. 递推公式为 用sum(n, m)表示所有可能的1~n之间存在的和为m的组合 那么 sum(n,m) = sum(n-1, m) | sum(n-1, m-n) 直接上 ...
- ==运算符和equals()方法的区别
Java语言程序中判断两个变量是否相等有两种方式:一是运用==运算符,二是运用equals方法. 1. ==运算符 对于==运算符来说,如果两个变量是基本类型的,并且是数值类型,则只要它们的值相等,就 ...