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

目录

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服务,在使用过程中不要关闭一下界面
WebGIS入门--如何做一个简单的校园地图服务网站
在浏览器中输入

http://localhost:8080/Cesium/

看到如下页面:
WebGIS入门--如何做一个简单的校园地图服务网站
其中Cesium test, share Buildings与OL test即为我自创的页面,项目目录需要放置在下级地址的同级目录中

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

如下图所示,test文件夹为我放置自创项目的目录,apps文件夹放置的是官方自带示例
WebGIS入门--如何做一个简单的校园地图服务网站
在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只是一种工具,我们需要去不断提高自己并观察生活,利用这种工具做出实际意义更高的项目,希望我们都可以在接下来的开发中再接再厉。

上一篇:canvas


下一篇:Mysql基本的增删查改