ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

WebGIS入门--如何做一个简单的校园地图服务网站

2021-12-28 20:30:34  阅读:316  来源: 互联网

标签:ol 入门 -- WebGIS Cesium import var new Math


目录

OpenLayer库的配置

在HTML中调用

Openlayers是一个开源的Javascript库,用来在Web浏览器显示地图。官网(https://openlayers.org/)提供了OpenLayer的下载包和使用案例;最常用的引用方法如一下两种:
1、在线调用

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/css/ol.css" type="text/css">
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/build/ol.js"></script>
    <title>OpenLayers example</title>
  </head>

2、调用本地安装包

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link href="安装路径\v5.3.0\css\ol.css" rel="stylesheet" type="text/css"/>
    <script src="安装路径\v5.3.0\build\ol.js" type="text/javascript" ></script>
    <title>OpenLayers example</title>
  </head>

(参考文章链接:https://blog.csdn.net/lijie45655/article/details/93314512)

在JavaScript文件中调用

官网上同样给出了一些example(https://openlayers.org/en/latest/examples/),所以会有一些问题,如何像Example一样在JS文件中写好功能然后在Html文件中引用;
3、参考Youtube上一位作者的视频,在B站上也有转载视频但没有转载全部的视频;
链接:https://www.youtube.com/watch?v=VazsQsjx3Fo&list=PLzHdTn7Pdxs4YoYM4v8OBvEgMgI3Kx101
4、使用Npm安装OL库
npm是NodeJS的包管理器,具体可以参考《npm是什么》(原文链接: https://blog.csdn.net/qq_35732147/article/details/80980124?ops_request_misc=&request_id=&biz_id=102&utm_term=NPM&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-3-80980124.pc_search_mgc_flag&spm=1018.2226.3001.4187)
在不使用npm的情况下,我用不同的编辑器(VS, WebStorm, Dreamweaver等)都无法在JavsScript中像示例一样使用OL,因此我尝试了这种方法;我配置环境的方法如下(参考书籍:

WebGIS之OpenLayer全面解析(第二版),郭明强,黄颖编著

):
第一步,新建一个项目文件夹,并在cmd控制台中打开该路径

H:\>cd H:\WebGIS\OL_Homework
H:\WebGIS\OL_Homework>

第二步,初始化项目目录
在此之前,确定已经安装好了NodeJS和NPM插件(新版的NodeJS已经集成好了NPM,不需要另外安装),确定安装好NPM的方法:在控制台输入npm -v,返回版本号即说明安装成功;

C:\Users\admin>npm -v
6.14.15

确定好安装NPM后,在项目文件下执行“npm init -y”命令

H:\WebGIS\OL_Homework>npm init -y

初始化成功后,项目目录下会生成一个package.json配置文件
第三步,安装Parcel插件,该插件用于应用程序打包;依然在项目目录下运行命令“npm install --save-dev parcel-bundler”

H:\WebGIS\OL_Homework>npm install --save-dev parcel-bundler

该步骤会生成node_modules文件夹和package-lock.json文件;
第四步,安装OpenLayer库,在项目目录下运行命令“npm install ol”即可

H:\WebGIS\OL_Homework>npm install ol

运行成功后会在package.json文件中看到:

"dependencies": {
    "ol": "^6.9.0"
  }

第五步,新建HTML文件和JS文件,并在package.json中添加如下代码

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "parcel index.html",
    "build": "parcel build --public-url . index.html"
  },

这里index.html即为我新建的HTML文件
第六步,启动应用程序,在项目目录下运行命令“npm start”

H:\WebGIS\OL_Homework>npm start

> OL_Homework@1.0.0 start H:\WebGIS\OL_Homework
> parcel index.html

Server running at http://localhost:1234
√  Built in 14.59s.

在浏览器中输入“localhost:1234”即可查看自己创建的网页,在你修改内容后,页面会自动刷新,不刷新时可以直接在cmd界面按下回车;如果需要应用程序打包,则可运行“npm run build”命令

H:\WebGIS\OL_Homework>npm run build

OpenLayer基础操作

最好的方法是参照官网案例,官网给出了比较多的基础案例

https://openlayers.org/en/latest/examples/

显示地图(天地图API)

index.html

<body>
<header>
    
<article>
    <div id="Tian" class="tdt"></div>
    <script src="./Vector.js" ></script>

</article>

</body>

JavaScript文件

import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import {OSM, Vector as VectorSource} from 'ol/source';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import {XYZ} from "ol/source";
import {fromLonLat} from "ol/proj";
import {Feature} from "ol";
import {Point} from "ol/geom";
import {Overlay} from "ol";
//天地图
var vector2 = new TileLayer({
    title: "天地图",
    source: new XYZ({
        url: "http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile" +
            "&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}" +
            "&tk=自己的密匙",
        wrapX: false
    })
});

//天地图容器
const TDTmap=new Map({
    layers:[vector2,
        new TileLayer({
            source: new OSM(),
        }),
    ],
    target: 'Tian',//地图容器,对应HTML中的“id='Tian'”
    view: new View({
        center: [13514200,3663000],
        zoom: 11,
    }),
})

百度地图API与天地图API

百度地图和天地图都提供了自己的地图服务,并且都需要申请成为开发者并创建应用以获得密匙;
百度地图的API调用及功能实现可以参考官网

https://lbsyun.baidu.com/index.php?title=jspopularGL

天地图提供了更多的影像服务,包括矢量、影像、三维地形等

http://lbs.tianditu.gov.cn/server/MapService.html

百度地图相比天地图功能使用更简洁一点,如下的路径规划,可以很方便地调用:
网页控件:

<button id="car" onclick="carRoute()">搜索行车路线</button>
        <button id="walk" onclick="walkRoute()">搜索步行路线</button>
        <div id="driving_way">
            <select id="bus_select">
                <option value="0">推荐方案</option>
                <option value="1">最少时间</option>
                <option value="2">最少换乘</option>
                <option value="3">最少步行</option>
                <option value="4">不乘地铁</option>
                <option value='5'>优先地铁</option>
            </select>
            <button id='search' onclick="busRoute()">查询公交/地铁</button>
            <p id='routeresult'></p>
        </div>

功能部分

//路径规划 
        //驾车路线
        function carRoute(){
            var output = "驾车需要";
            var searchComplete = function (results){
                if (transit.getStatus() != BMAP_STATUS_SUCCESS){
                    return ;
                }
                var plan = results.getPlan(0);
                output += plan.getDuration(true) + "\n";                //获取时间
                output += "总路程为:" ;
                output += plan.getDistance(true) + "\n";             //获取距离
            }
            var transit = new BMapGL.DrivingRoute(map, {renderOptions: {map: map},
                onSearchComplete: searchComplete,
                onPolylinesSet: function(){
                    setTimeout(function(){
                        document.getElementById("routeresult").innerText="";
                        document.getElementById("routeresult").innerText=output;
                    },"1000");
                }});
            transit.search(startPoint, desPoint);

        }
        //步行路线
        function walkRoute(){
            var walking = new BMapGL.WalkingRoute(map, {renderOptions:{map: map, autoViewport: true}});
            walking.search(startPoint, desPoint);
        }
        //公交、地铁方案
        function busRoute(){
            var routePolicy = [BMAP_TRANSIT_POLICY_RECOMMEND,BMAP_TRANSIT_POLICY_LEAST_TIME,BMAP_TRANSIT_POLICY_LEAST_TRANSFER,BMAP_TRANSIT_POLICY_LEAST_WALKING,BMAP_TRANSIT_POLICY_AVOID_SUBWAYS,BMAP_TRANSIT_POLICY_FIRST_SUBWAYS];
            var transit = new BMapGL.TransitRoute(map, {
                renderOptions: {map: map, panel: 'routeresult'},
                policy: 0,

            });
            var obj = document.getElementById("bus_select");
            var index = obj.selectedIndex; 
            var i = obj.options[index].value; 

            transit.setPolicy(routePolicy[i]);
            transit.search(startPoint, desPoint);
        }

坐标系转换之百度地图

在使用百度地图的API服务时,可以发现它的坐标系相比WGS84有一定的变动(天地图似乎也有);官网给出了地形转换的一些方法,我自己在使用的时候是加入常数项(在经纬度上)缩小差异,该方法仅适用于对精度要求不高的情况下;

坐标系转换之天地图

天地图会涉及到WGS84坐标系和墨卡托投影之间的相互转换,在示例也可以看到地图的中心为center: [13514200,3663000],而不是经纬度

参考文章:https://blog.csdn.net/qq_33356563/article/details/83795419?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164027031216780261933673%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164027031216780261933673&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-83795419.pc_search_mgc_flag&utm_term=%E5%A2%A8%E5%8D%A1%E6%89%98%E6%8A%95%E5%BD%B1%E8%BD%AC%E4%B8%BAWGS&spm=1018.2226.3001.4187

对于WGS84转墨卡托投影,有两种方法

var x= lng*20037508.34/180;
var y=Math.log(Math.tan((90+lat)*Math.PI/360))/(Math.PI/360)*20037508.34/360;
map.setView(new View({
        center: [x,y],
        zoom: 17,
    }));

或者

var point=fromLonLat([120,30]);
map.setView(new View({
        center: [point[0],point[1]],
        zoom: 17,
    }));

墨卡托投影转WGS84(这里和原文有冲突,建议大家再去找一下其他资料)

var x=e.point.lng;
var y=e.point.lat;
var lon= x/20037508.34*180;
var lat=y/20037508.34*180;
lat= 180/Math.PI*(2*Math.atan(Math.exp(lat*Math.PI/180))-Math.PI/2);

这里提供一个在线工具,可以进行墨卡托投影转WGS84

http://www.site-digger.com/tools/mct2latlng.html

视图转换

在地图中,我们需要从一个视图转换到另一个视图,最基础的方法便是改变地图的显示范围

map.centerAndZoom(point, 17);

Google Earth中的探索功能,从地球旋转到目标并绕目标旋转,实现过程:

import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import {OSM, Vector as VectorSource} from 'ol/source';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import {XYZ,TileImage} from "ol/source";
import {fromLonLat} from "ol/proj";
import {Feature} from "ol";
import {Point} from "ol/geom";
import {easeIn, easeOut} from "ol/easing"; //渐进和渐消
const Rmap=new Map({
    target:'Map_container',
    layers:[
        new TileLayer({
            title:"影像底图",
            source: new XYZ({
                url: "http://mt3.google.cn/vt/lyrs=s&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}",
                wrapX: false
            })
        })
    ],
    loadTilesWhileAnimating: true, //开启动画
    view:flyView  //视图
});
//飞行到建筑物并绕建筑物旋转
document.getElementById("fly").onclick=function (){
    //获取建筑索引
    var obj = document.getElementById("build_select");
    var index = obj.selectedIndex; 
    var i = obj.options[index].value;
    //添加标记
    var  buildFea = new Feature({
        geometry: new Point(buildings[i]),
    });

    var vectorSource = new VectorSource({
        features: [buildFea],
    });

    var makerLayer = new VectorLayer({
        source: vectorSource,
    });

    Rmap.addLayer(makerLayer);
    //添加注释
    document.getElementById("result").innerHTML=content[i];

    var center=flyView.getCenter();
    var roa=flyView.getRotation();
    flyView.animate({
        duration:3000,
        center:[
        ],
        rotation: Math.PI,  //旋转角度
        zoom: 18,
        easing:easeIn      //效果
    },
        {
            duration:6000,  //旋转时间, 单位毫秒
            center:buildings[i],
            rotation:Math.PI*2,
            easing:easeOut
        },
        //绕目标旋转
        {
            rotation:roa+Math.PI,
            duration:16000,
            anchor:buildings[i],   //中心点
        },
        {
            duration:16000,
            rotation:roa+2*Math.PI,
            anchor:buildings[i],
        });
}

由于加载的图层是平面图层,加载的效果并不如Google Earth好,建议大家慎用,下文中会涉及到三维模型的自旋效果;

Geoserver的使用中遇到的问题

关于GeoServer的安装和配置网络上有很多教程,我就不在这里详细介绍了,主要问题集中在踩过的几个坑

跨域问题

对Geoserver配置的修改(1):打开Geoserver\webapps\geoserver\web.xml文件,找到filter平级的位置,添加如下内容:

<filter>
      <filter-name>cross-origin</filter-name>
      <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
      <init-param>
        <param-name>allowedOrigins</param-name>
        <param-value>*</param-value>
      </init-param>
      <init-param>
        <param-name>allowedMethods</param-name>
        <param-value>GET,POST</param-value>
      </init-param>
      <init-param>
        <param-name>allowedHeaders</param-name>
        <param-value>x-requested-with,content-type</param-value>
      </init-param>
    </filter>

(2)找到filter-mapping平级的位置,添加如下内容:

<filter-mapping>
      <filter-name>cross-origin</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

(3)找到context-param 平级的位置,修改如下:

<context-param>
    <param-name>ENABLE_JSONP</param-name>
    <param-value>true</param-value>
  </context-param>

配置文件中可能自带以上代码,取消注释也可;
注:这个跨域访问比较玄学,我的很多同学按照这个方法好像都没有成功,但我只进行了前两个步骤好像就可以跨域了;建议大家去查看下其他的解决方案,或者使用本地文件;

调用Geoserver的服务

WMS:建议工作区和图层名全部采用英文名

import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import {OSM, ImageWMS} from 'ol/source';
import {Image} from "ol/layer";
import TileLayer from "ol/layer/Tile";
import {ZoomSlider,ZoomToExtent} from "ol/control";
import Projection from 'ol/proj/Projection';


const map = new Map({
    layers: [
        new TileLayer({
            source: new OSM(),
        }),
    ],
    target: 'js-map',
    view: new View({
        center: [0, 0],
        zoom: 2,
    }),
});

const extent4214 = [73.62, 18.11, 134.77, 53.56];  //图层范围
var projection4214 = new Projection({
    code: 'EPSG:4214',
    extent: extent4214,
    units: 'degree'
});

var myLayer = new Image({
    extent: extent4214,
    source: new ImageWMS({
        url: 'http://localhost:8084/geoserver/wms',
        params: {'LAYERS': 'TJ2021Test:Border_Nation', 'VERSION': '1.1.1'}, //工作区:图层名
        serverType: 'geoserver'
    })
});

const map = new Map({
    view: new View({
        projection: projection4214,
        center: [103.5, 35.835],     
        zoom: 1
    }),
    layers:[
        myLayer
    ],
    target: 'js-map',
    pixelRatio: 1
});

json文件:这里需要在Geoserver中导入json的插件

import 'ol/ol.css';
import ExtentInteraction from 'ol/interaction/Extent';
import GeoJSON from 'ol/format/GeoJSON';
import Map from 'ol/Map';
import View from 'ol/View';
import {OSM, Vector as VectorSource} from 'ol/source';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import {XYZ} from "ol/source";
import {fromLonLat} from "ol/proj";
import {Feature} from "ol";
import {Point} from "ol/geom";

const vectorSource = new VectorSource({
    url:"http://localhost:8084/geoserver/TJ2021Test/ows?service=WFS&version=1.0.0" +
        "&request=GetFeature&typeName=TJ2021Test%3ABorder_Nation" +
        "&outputFormat=application%2Fjson",
    // url:"/data/border_nation.xml",

    format: new GeoJSON()
});
// console.log(vectorSource);
const map = new Map({
    layers: [
        new TileLayer({
            source: new OSM(),
        }),
        new VectorLayer({
            source: vectorSource,
        }),
    ],
    target: 'js-map',
    view: new View({
        center: [0,0],
        zoom: 2,
    }),
});

这里也比较玄学,我一直无法调用本地的json文件,但在Geoserver上发布的就可以;所以建议大家遇到问题时多尝试不同的方法,确实会碰到很多奇奇怪怪也搜不到的问题。

Cesium的配置和基础操作

Cesium的配置

参考文章

Cesium安装以及环境配置: https://blog.csdn.net/u013044828/article/details/87001951

Cesium与OpenLayer类似,是一款面向三维地球和地图的,世界级的JavaScript开源产品。它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以及多平台,易用性上都有高质量的保证。
同样,Cesium也提供了庞大的案例群,可以在官网上查看它们。

https://cesium.com/platform/cesiumjs/

但是配置的过程并不像OpenLayer一样顺利,首先直接使用NPM安装的方法可以安装成功,也可以调用,但在网页端会报错,报的错误类型比较多而且比较奇怪;因此我选择了使用Tomcat架设Cesium本地服务器,优点是使用方便,缺点是该环境下似乎无法按照上文方法配置并使用OpenLayer库,所以不得不将项目文件放置于两个文件夹下。
Tomcat的安装与配置可参照下述链接:

https://blog.csdn.net/qq_40881680/article/details/83582484?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164068545116780264098730%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164068545116780264098730&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-83582484.pc_search_mgc_flag&utm_term=tomcat%E5%AE%89%E8%A3%85%E5%8F%8A%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B&spm=1018.2226.3001.4187

我使用的版本为Tomcat10.0, 端口号为默认(8080)
Cesium则从官网下载zip文件,并将其解压到Tomcat的web apps文件夹下,我这里使用的版本是Cesium1.88

https://cesium.com/downloads/

Cesium的基础操作

启动cmd控制台,运行Tomcat目录下bin文件夹中的startup.bat

D:\>cd D:\Program Files\Apache Software Foundation\Tomcat 10.0\bin

D:\Program Files\Apache Software Foundation\Tomcat 10.0\bin>startup.bat
Using CATALINA_BASE:   "D:\Program Files\Apache Software Foundation\Tomcat 10.0"
Using CATALINA_HOME:   "D:\Program Files\Apache Software Foundation\Tomcat 10.0"
Using CATALINA_TMPDIR: "D:\Program Files\Apache Software Foundation\Tomcat 10.0\temp"
Using JRE_HOME:        "C:\Program Files\Java\jre1.8.0_311"
Using CLASSPATH:       "D:\Program Files\Apache Software Foundation\Tomcat 10.0\bin\bootstrap.jar;D:\Program Files\Apache Software Foundation\Tomcat 10.0\bin\tomcat-juli.jar"
Using CATALINA_OPTS:   ""

便会启动Tomcat服务,在使用过程中不要关闭一下界面
可以看到最后服务器启动
在浏览器中输入

http://localhost:8080/Cesium/

看到如下页面:
请添加图片描述
其中Cesium test, share Buildings与OL test即为我自创的页面,项目目录需要放置在下级地址的同级目录中

安装路径\Tomcat
10.0\webapps\Cesium\Apps

如下图所示,test文件夹为我放置自创项目的目录,apps文件夹放置的是官方自带示例
请添加图片描述
在index.html中添加代码

<tr>
              <td><a href="test/Cesium_test.html">Cesium Test</a></td>
              <td>
	                A sample Cesium BY Author
              </td>
            </tr>
            <tr>
              <td><a href="test/share_building.html">Share buildings</a></td>
              <td>
                Sharing buildings with users
              </td>
            </tr>
            <tr>
              <td><a href="OL_ENV/index.html">OL Test</a></td>
              <td>
                A sample OpenLayers BY Author
              </td>
            </tr>

调用地图

<div id="cesiumContainer"></div>
var viewer = new Cesium.Viewer('cesiumContainer',{
            animation:true,       //是否显示动画控件
            homeButton:true,       //是否显示home键
            //geocoder:false,         //是否显示地名查找控件        如果设置为true,则无法查询
            baseLayerPicker:false, //是否显示图层选择控件
            timeline:true,        //是否显示时间线控件
            fullscreenButton:true, //是否全屏显示
            scene3DOnly:true,     //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
            infoBox:true,         //是否显示点击要素之后显示的信息
            sceneModePicker:false,  //是否显示投影方式控件  三维/二维
            navigationInstructionsInitiallyVisible:false,
            navigationHelpButton:false,     //是否显示帮助信息控件
            selectionIndicator:false,        //是否显示指示器组件
            //加载谷歌卫星影像
            imageryProvider : new Cesium.UrlTemplateImageryProvider({url:"http://mt1.google.cn/vt/lyrs=s&hl=zh-CN&x={x}&y={y}&z={z}&s=Gali"})

        });

加载三维模型(带有json的b3dm文件)

        var osmBuildingsTileset = new Cesium.Cesium3DTileset({ url: './DATA/tileset.json' });
        var tileset = viewer.scene.primitives.add(osmBuildingsTileset);
        viewer.scene.primitives.add(tileset);
        viewer.flyTo(tileset);

三维动画

加载完校园的三维模型后,我们需要加载一些简单的动画效果
第一条是在用户点击后,将视角移动到真实的角度

var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(function (event) {
        var earthPosition = viewer.camera.pickEllipsoid(event.position, viewer.scene.globe.ellipsoid); //返回在椭球上面的点的坐标
        if (Cesium.defined(earthPosition)) {
          var point = viewer.entities.add({
            position: earthPosition,
            point: {
              color: Cesium.Color.WHITE,
              pixelSize: 5
            }
          });
          var offset = new Cesium.HeadingPitchRange(
                  Cesium.Math.toRadians(290), // 水平方向的旋转角 0-360度
                  -Cesium.Math.toRadians(5),// 垂直平面俯仰角 // 0-90度
                  100 // 相机距离地球球心的距离
          );
          viewer.zoomTo(point, offset);   //将视角移动到真实视角

        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        //创建点
        function createPoint(worldPosition) {
            var point = viewer.entities.add({
                position: worldPosition,
                point: {
                    color: Cesium.Color.WHITE,
                    pixelSize: 5
                }
            });
            return point;
        }

第二条是围绕目标建筑物旋转,与上述功能基本相似,主要思路为给水平视角加入步长并逐步旋转

 handler.setInputAction(function (event) {
            var earthPosition = viewer.camera.pickEllipsoid(event.position, viewer.scene.globe.ellipsoid); //返回在椭球上面的点的坐标
            if (Cesium.defined(earthPosition)) {
                // createPoint(earthPosition); //在点击位置添加一个点
                var point = viewer.entities.add({
                    position: earthPosition,
                    point: {
                        color: Cesium.Color.WHITE,
                        pixelSize: 5
                    }
                });

                let initialHeading = 0; //起始水平角
                let step = 0.05;    //步长
                let setIntervalID = setInterval(function(){
                    if (initialHeading > 360) {
                        initialHeading = 0;
                    }
                    var offset = new Cesium.HeadingPitchRange(
                        Cesium.Math.toRadians(initialHeading), // 水平方向的旋转角 0-360度
                        -Cesium.Math.toRadians(12),// 垂直平面俯仰角 // 0-90度
                        150  // 相机距离地球球心的距离
                    );
                    viewer.zoomTo(point, offset);
                    initialHeading += step;

                }, step * 1000);

            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

参考链接

https://blog.csdn.net/qq_30100043/article/details/86646714?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164060059716780265464689%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164060059716780265464689&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-1-86646714.pc_search_mgc_flag&utm_term=cesium%E8%8E%B7%E5%8F%96%E7%82%B9%E7%9A%84%E5%9D%90%E6%A0%87&spm=1018.2226.3001.4187
https://blog.csdn.net/popstarqq/article/details/118155872?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164060041116780271945257%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164060041116780271945257&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-8-118155872.pc_search_mgc_flag&utm_term=cesium%E5%AE%9E%E7%8E%B0%E5%8A%A8%E7%94%BB%E6%95%88%E6%9E%9C&spm=1018.2226.3001.4187

校园地图服务

主要功能

  1. 校区位置展示
  2. 校区平面地图
  3. 前往校区的交通方式
  4. 校区三维导览
  5. 建筑物探索/特定建筑物介绍

利用OpenLayer的功能

显示校园平面位置

主要环节是添加标注和注释,这里需要在HTML文件中添加控件

 <div id="splabel" style="display: none;">
        <div id="smarker" class="marker" title="Marker">
            <a class="adress" id="address" target="_blank" href="intro_siping.html">
                *****校区
            </a>
        </div>
    </div>
var point=fromLonLat([*,*]);
var Marker=new Overlay({
    position:point,
    positioning:"center-center",
    element:document.getElementById("smarker"),
    stopEvent:false
});
TDTmap.addOverlay(Marker);
Marker.getElement().title="*****校区";
var Text= new Overlay({
    position:point,
    element:document.getElementById("address"),
})

导航到校园

获取起始点位置:因为没有外接GPS,这里采用点选或输入的方式获取起点位置(存在上文提到的坐标系问题)

function showInfo(e) {
            var x=e.point.lng;
            var y=e.point.lat;
            var lon= x/20037508.34*180;
            var lat=y/20037508.34*180;
            lat= 180/Math.PI*(2*Math.atan(Math.exp(lat*Math.PI/180))-Math.PI/2);

            document.getElementById('lng').value =  lon;
            document.getElementById('lat').value =  lat;
            var startMarker = new BMapGL.Marker(new BMapGL.Point(lon-0.002,lat+0.172)); //这里加入常数项以矫正
            startPoint= new BMapGL.Point(lon-0.002,lat+0.172);
            markersArray.push(startMarker);
            clearOL(markersArray);//起点只有一个,去除其他的标记
            map.addOverlay(startMarker);
        }

导航方式则为调用百度地图的路径规划功能。

缩放到学校以显示平面地图

HTML文件中的Button控件,用于选择校区

<div id="part">
        <select id="select">
            <option value="0">***校区</option>
            <option value="1">**校区</option>
            <option value="2">**校区</option>
            <option value="3">**校区</option>
        </select>
        <button id='search'>显示校园地图</button>
    </div>
var btn1=document.getElementById("search");
btn1.addEventListener("click",function (){
    var obj = document.getElementById("select");
    var index = obj.selectedIndex; // 选中索引
    var i = obj.options[index].value; // 选中值
    var lng=[x1,x2,x3,x4];
    var lat=[y1,y2,y3,y4];
    var x= lng[i]*20037508.34/180;
    var y=Math.log(Math.tan((90+lat[i])*Math.PI/360))/(Math.PI/360)*20037508.34/360;

    TDTmap.setView(new View({
        center: [x,y],
        zoom: 17,
    }));

})

特定建筑物介绍

采用动画的形式聚焦到特定的建筑物,详见上述“视图转换”

利用Cesium的功能

三维导览

加载并导入动画详见Cesium的基础操作
获取建筑物模型并提取属性信息(按右键)

var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
        //
        handler.setInputAction(function (movement) {
            var pick = viewer.scene.pick(movement.position);
            if (Cesium.defined(pick)) {
                alert('id:'+pick.id.id+', name:'+pick.id.name);
            }
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

总结

在官网中OpenLayer和Cesium都提供了丰富的案例,百度地图和天地图的API也都提供了基础的代码;本文中的校园地图服务网站中也只是简单地集成了一些功能。对于WebGIS开发而言,数据的获取和处理极为关键,如加载的校园三维模型,我本人使用BlenderGIS和QGIS以及一些转换工具仍然没有处理好;其次,在网页开发中,一些用户的交互部分以及数据库的连接也很重要,并且需要较高的编程能力。最重要的是,WebGIS只是一种工具,我们需要去不断提高自己并观察生活,利用这种工具做出实际意义更高的项目,希望我们都可以在接下来的开发中再接再厉。

标签:ol,入门,--,WebGIS,Cesium,import,var,new,Math
来源: https://blog.csdn.net/shemmly/article/details/122194354

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有