目录
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
校园地图服务
主要功能
- 校区位置展示
- 校区平面地图
- 前往校区的交通方式
- 校区三维导览
- 建筑物探索/特定建筑物介绍
利用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只是一种工具,我们需要去不断提高自己并观察生活,利用这种工具做出实际意义更高的项目,希望我们都可以在接下来的开发中再接再厉。