获取三维城市所需geojson文件的操作步骤

1,668 阅读4分钟

写在前面

这个文章写的很好,不想自己截图再写一遍,所以转载下,方便记录,

原地址:获取三维城市所需geojson文件的操作步骤

1. geojson简介

1.1 geojson的定义geojson是一种对各种地理数据结构进行编码的格式,基于Javascript对象表示法(JavaScript Object Notation, 简称JSON,FineReport内置的中国-area.json也是其中一种)的地理空间信息数据交换格式。geojson对象可以表示几何、特征或者特征集合。geojson支持点、线、面、多点、多线、多面等集合类型。

1.2 三维城市中的geojson在「FVS大屏编辑模式」的「三维城市」组件中,产品自动识别的geojson属性包括:

类型属性示例
命名建筑(主建筑)building&&name既有building属性又有name属性,则在三维城市中会出现该建筑的3D模型,且建筑外立面颜色闪耀,代表建筑灯光
未命名建筑(其他建筑)building没有building属性,则在三维城市中不会出现该建筑的3D模型只有building属性没有name属性,则在三维城市中,该建筑的名称不能被识别到,被纳入其他建筑中,色彩也相较于有名称的建筑更加暗淡
命名道路(主道路)road&&name既有road属性又有name属性,则在三维城市中显示该道路,且道路自带流光效果,表示人流车流
未命名道路(其他道路)road没有road属性,则在三维城市中不会显示该道路只有road属性没有name属性,则在三维城市中,该街道的名称不能被识别到,被归入其它街道,街道色泽也更暗淡些
草地grass
水系water

2. 获取基础的geojson

1)进入「overpass-turbo.eu/」网站,在搜索框内模糊查询需要圈选的城市区域,如「wuxidong」(无锡东,只支持英文) 2)点击「manually select bbox」按钮,调整方框圈选城市区域范围 3)修改浏览器「setting」中的UI language为「en」,否则后续步骤可能无法生效。 4)修改左侧代码为: [timeout:60]; nwr({{bbox}}); out;

5)点击「run」按钮,获取该区域的geojson数据点。 6)点击「Export」按钮,点击「download/copy as GeoJSON」。

3. 调整获取的geojson本章将教大家如何增删改建筑/道路模型。1)获取某块原geojson中没有的建筑:进入「geojson.io」,模糊搜索「wuxi」(无锡),这个网站搜索不会太精细,需要手动放大、定位到需要的位置。2)对需要的区域进行选择,可圈选道路、不规则区域、矩形区域,如下图所示:3)对圈选出来的建筑按照三维城市可识别的属性补充建筑模型的properties:其中building是必要包括的,name不包括则导入三维城市时被识别为其他建筑;height按照高度的比例在三维城市中展示,没有height则按照默认高度生成建筑,如果想让建筑在大屏上更突出,最好设置一个稍大的高度,100-300之间都比较合理。4)将这段建筑的代码复制到以获取的基础geojson中:用任一文本编辑器打开上一个基础文件  map.geojson,可以在开头、中间或末尾的任何对象后新增上一步骤中复制的代码。

如上图所示,在蓝框前后添加新增建筑的代码都是可以的,三维城市的识别与顺序无关,只是靠后的建筑名称在三维城市的模型列表靠后。复制粘贴的时候注意  “,”  和  “}”  不要错位(“type”前一个"{"到最后一个选点的经纬度后的 "] ] ] } },"组成一个建筑对象),如果用能对准的编辑器处理会方便很多。5)道路、草地等同理,在合并好代码后导入三维城市即可生产建筑。

4. 建筑为空的 geojson如果用户希望完全使用自定义模型,不想创建场景,此时需要导入一个空的geojson这个geojson中需要添加一个 Polygon 并作为第一个 feature,添加特殊属性:"calder:bbox": true此时场景范围(bbox)以此 Polygon 为准示例:

{   
    "type": "FeatureCollection",   
    "features": 
        [     
            {       
                "type": "Feature",       
                "properties": {         
                    "calder:bbox": true       
                },       
                "geometry": {         
                    "type": "Polygon",         
                    "coordinates": [           
                    [[109,34],[109.1,34],[109.1,34.1],[109,34.1],[109,34]]         
                    ]       
                }     
            }   
        ] 
}

纠正路网经纬度数据偏移

路网数据是对不上的,也是绝了,用以下的方法,返回这种经纬度数组[103.23213,32.123123]

// 纠正经纬度偏移
const wgs84ToGcj02 = (lng, lat) =>{
  function transformLat(lng, lat) {
    let PI = 3.14159265358979324;
    let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
    ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320.0 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
    return ret;
  }
  
  function transformLng(lng, lat) {
    let PI = 3.14159265358979324;
    let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
    ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
    return ret;
  }
  
  function outOfChina(lng, lat) {
    return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
  }
  
  const PI = 3.14159265358979324;
  const A = 6378245.0;
  const EE = 0.00669342162296594323;
  
  if (outOfChina(lng, lat)) {
    return [lng, lat];
  }
  let dLat = transformLat(lng - 105.0, lat - 35.0);
  let dLng = transformLng(lng - 105.0, lat - 35.0);
  let radLat = lat / 180.0 * PI;
  let magic = Math.sin(radLat);
  magic = 1 - EE * magic * magic;
  const sqrtMagic = Math.sqrt(magic);
  dLat = (dLat * 180.0) / ((A * (1 - EE)) / (magic * sqrtMagic) * PI);
  dLng = (dLng * 180.0) / (A / sqrtMagic * Math.cos(radLat) * PI);
  const mgLat = lat + dLat;
  const mgLng = lng + dLng;
  return [mgLng, mgLat];
}