-
搭建本地环境,配置瓦片数据,下载文件并找到相应路径
链接: https://pan.baidu.com/s/1c6nfZodGBzUxyG2PhmFzPA
提取码: p3qi -
开启本地服务器
-
导入本地包
链接: https://pan.baidu.com/s/1qhe4kxwpmez5-7dBVA1S1g
提取码: w6hp
将文件解压放到asset文件夹
-
在index.html中引入
-
配置全局变量,初始化地图
declare var ol: any //配置全局变量
protected map;
protected initMap(): void {
//对应源代码中的全图范围信息
let fullExtent = [106.55377197265625, 29.634521484751, 106.57006656576985, 29.646849848303482];
//对应源代码中的切片方案信息
let resolutions = [3.8071376093284481e-005, 1.903568804664224e-005, 9.5178440233211202e-006, 4.7589220116605601e-006, 2.3794610058302801e-006, 1.18973050291514e-006];
this.baseLayers = [
new ol.layer.Tile({
source: new ol.source.TileWMS({
url: environment.openlayerPath, //http://localhost:98/geowebcache/service/wms 本地服务地址
params: {
'LAYERS': 'chongqing1', //对应源代码中的名称
'FORMAT': 'image/png',
'SRS': 'EPSG:4326', //对应源代码中的标识
'VERSION': '1.1.3'
},
tileGrid: new ol.tilegrid.TileGrid({
//resolution和conf.xml中保持一致
extent: fullExtent,
resolutions: resolutions,
tileSize: [256, 256],
origin: [-400, 399.99999999999977]
})
})
})
];
this.map = new ol.Map({
controls: [],
layers: this.baseLayers,
target: 'map',
view: new ol.View({
projection: 'EPSG:4326',
center: [106.56010, 29.64105],
resolution: 2.1794610058302801e-006,
zoom: 10
})
});
}
显示效果:
6. 在地图上添加标注
数据格式如下
protected markerList = [];
public baseLayers; // 基础图层
public vectorLayerPerson; //标记图层
protected showMarkers(result: Array<any>, name = 'name'): void {
this.markerList.forEach(marker => this.map.remove(marker));
this.markerList = [];
this.initMark(result)
}
/**
* 加载标记方法
* */
public initMark(data) {
let vectorSourceNetPerson = new ol.source.Vector({});
data.forEach(item => {
if (item.longitude == null || item.latitude == null) {
return
}
//创建图标特性
let iconFeature = new ol.Feature({
geometry: new ol.geom.Point([item.longitude, item.latitude]),
title: "eventLayer",
Id: item.id,
type: 'event'
});
//因瓦片数据有限,所以可能标注不会显示在地图上,这里使用假数据,保证标注能够正确显示在地图中
/*let iconFeature = new ol.Feature({
geometry: new ol.geom.Point([106.56063002597645, 29.641131347586256]),
name: "personLayer",
})*/
//将图标特性添加进矢量中
vectorSourceNetPerson.addFeature(iconFeature);
})
//创建图标样式
let iconStyle = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: "../assets/img/alarm.png" //标注点的图片
}),
});
//创建矢量层
this.vectorLayerPerson = new ol.layer.Vector({
source: vectorSourceNetPerson,
style: iconStyle
});
//添加进map层
this.map.addLayer(this.vectorLayerPerson);
}
显示效果:
7.在初始化地图的时候, 为标志添加事件交互
/**
* 初始地图化点击事件
* */
initMapClickEvent() {
let $this = this;
/**
* 为map添加点击事件监听,渲染弹出popup
*/
this.map.on('click', function (evt) {
//在点击时获取像素区域
let pixel = $this.map.getEventPixel(evt.originalEvent);
$this.map.forEachFeatureAtPixel(pixel, function (feature) {
//evt.coodinate 存放了点击时的坐标信息
//feature.values_.Id 存放了当前标注的id
});
});
/**
* 为map添加鼠标移动事件监听,当指向标注时改变鼠标光标状态
*/
this.map.on('pointermove', function (e) {
let pixel = $this.map.getEventPixel(e.originalEvent);
let hit = $this.map.hasFeatureAtPixel(pixel);
$this.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
}
- 移除某标注图层
this.map.removeLayer(this.vectorLayerPerson);
- 在地图上绘制并显示热区
显示热区
数据格式如下:
//在地图上加载热区方法
createPolygon(longitude, latitude, pathList) { // pathList:热区的各个点数据
let newPathlist = [];
pathList.forEach(item => {
let a = [];
a.push(item.lng);
a.push(item.lat);
newPathlist.push(a);
});
let polygon = new ol.Feature({
geometry: new ol.geom.Polygon([
newPathlist,
]),
});
//设置热区样式信息
polygon.setStyle(
new ol.style.Style({
//填充色
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.5)',
}),
//边线颜色
stroke: new ol.style.Stroke({
color: '#018fd3',
width: 1,
}),
}),
);
//实例化一个矢量图层Vector作为绘制层
let source = new ol.source.Vector({
features: [polygon],
});
//创建一个图层
this.hotAreaLayer = new ol.layer.Vector({
source: source,
});
this.map.addLayer(this.hotAreaLayer);
}
显示效果:
绘制热区
public addHotArea() {
let $this = this;
let source = new ol.source.Vector({wrapX: false})
this.hotAreaLayer = new ol.layer.Vector({
source: source
});
let drawHot = new ol.interaction.Draw({
source: source,
type: 'Polygon'
});
drawHot.on('drawend', function (evt) {
let feature = evt.feature;
let geometry = feature.getGeometry();
let coordinate = geometry.getCoordinates();
//coordinate :热区每个点的数据
drawHot.setActive(false);//绘制结束
$this.map.addLayer($this.hotAreaLayer);
});
this.map.addInteraction(drawHot);
}
显示效果:
获取并设置中心点和层级
//获取地图中心点
private getMapCenter() {
let mapExtent = this.map.getView().calculateExtent(this.map.getSize())
let map_center = ol.extent.getCenter(mapExtent);
return map_center;
}
//设置中心点
this.map.getView().setCenter(['经度','纬度']);
//获取地图层级
this.map.getView().getZoom()
//设置层级
this.map.getView().setZoom(gotoZoom);
鼠标移入或点击时弹出提示信息
html设置
alarmWindowInfo: 存放基本信息的对象
alarmInfoDetails: 查看详情的函数
<div id="popup" class="ol-popup" #showPopupDiv>
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content">
<!--信息弹窗-->
<div class="my-security-panel-info">
<div class="panel-info-content">
<div class="flex-row">
<div class="info-content-text">
<div class="info-content-text-row flex-row">
<div class="row-label flex-row">
<span>姓</span>
<span>名:</span>
</div>
<div class="row-value">{{alarmWindowInfo?.name}}</div>
</div>
<div class="info-content-text-row flex-row">
<div class="row-label flex-row">
<span>性</span>
<span>别:</span>
</div>
<div class="row-value" *ngIf="alarmWindowInfo?.sex=='1'">男性</div>
<div class="row-value" *ngIf="alarmWindowInfo?.sex=='2'">女性</div>
<div class="row-value" *ngIf="alarmWindowInfo?.sex=='0'">未知性别</div>
</div>
<div class="info-content-text-row flex-row">
<div class="row-label flex-row">
<span>手</span>
<span>机</span>
<span>号:</span>
</div>
<div class="row-value">{{alarmWindowInfo?.phone}}</div>
</div>
<button nz-button nzType="default" nzSize="small"
(click)="alarmInfoDetails(alarmWindowInfo)">详情
</button>
</div>
</div>
<div class="info-content-closebtn" (click)="closePopup()">
<img src="https://webapi.amap.com/images/close2.gif" alt="">
</div>
</div>
</div>
</div>
</div>
css设置
. ol-popup
{
position: absolute;
background-color: white;
-webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
}
.ol-popup:after, .ol-popup:before
{
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after
{
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before
{
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer
{
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after
{
content: "✖";
height:30px;
padding:12px;
}
#popup-content
{
font-size: 14px;
font-family: "微软雅黑", serif;
width:100px;
}
.my-security-panel-info {
width: 320px;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 7px;
box-shadow: 4px 4px 25px #ccc;
}
js设置,当点击或鼠标移入标注时,获取popup节点对象
//地图交互事件
private initMapClickEvent() {
let $this = this;
/**
* 为map添加点击事件监听,渲染弹出popup
*/
this.map.on('singleclick', function (evt) {
//在js中获取HTML元素
$this.popupContainer = document.getElementById("popup");
let overlay = new ol.Overlay({
element: $this.popupContainer, //设置弹出框的容器
autoPan: true, //是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见
autoPanAnimation: {
duration: 300 //当Popup超出地图边界时,为了Popup全部可见,地图移动的速度.
}
});
let coodinate = evt.coordinate; // coodinate存放了点击时的坐标信息
overlay.setPosition(coodinate);
let pixel = $this.map.getEventPixel(evt.originalEvent); //在点击时获取像素区域
$this.map.forEachFeatureAtPixel(pixel, function (feature) { //在点击时获取像素区域
if (feature.values_.type == 'event') {
//获取基本信息
$this.http.get(`${environment.requestPath}/event/get/${feature.values_.Id}`, {
success: (data => {
$this.alarmWindowInfo = data.result;
$this.showPopupDiv.nativeElement.style.display = 'block';
$this.map.addOverlay(overlay);
})
});
}
});
});
}
框选标注并获取id
public camerasActive = false; //框选功能激活
public allCameraData = []; //所有摄像头数据
public isDrow() {
this.camerasActive = !this.camerasActive;
if (this.camerasActive) {
this.drow('camerasActive');
} else {
this.map.removeLayer(this.drawVectorLayer); //删除框选图层
}
}
//框选
//allCameraData :所有的标注数据
public drow(name) {
let $this = this;
//新建source和layer
let source = new ol.source.Vector({wrapX: false});
this.drawVectorLayer = new ol.layer.Vector({source: source});
//设置geometryFunction
let geometryFunction = ol.interaction.Draw.createBox();
//新建绘制正方形interaction
let drawSquare = new ol.interaction.Draw({
source: source,
type: "Circle",
geometryFunction: geometryFunction,
});
//框选结束
drawSquare.on('drawend', function (evt) {
let feature = evt.feature;
let geometry = feature.getGeometry();
let coordinate = geometry.getCoordinates();
//获取到点
let pointList = [];
let coordinateOne = coordinate[0][0];
let coordinateTwo = coordinate[0][2];
//框选摄像头
if (name == 'camerasActive') {
for (let i = 0; i < $this.allCameraData.length; i++) {
let List = $this.allCameraData[i];
//1经度 >= 点经度
//2经度 <= 2点经度
//1纬度 >= 点纬度
//2纬度 <= 2点纬度
let isTrue = coordinateOne[1] <= List.latitude && List.latitude <= coordinateTwo[1] && coordinateOne[0] <= List.longitude && List.longitude <= coordinateTwo[0];
if (isTrue) {
//满足以上条件及当前标注在框选范围内
pointList.push($this.allCameraData[i].id)
}
}
if (pointList.length > 0) {
// pointList:选框内的摄像头数据
} else {
$this.message.error('此框选范围没有任何摄像头');
}
$this.camerasActive = false;
drawSquare.setActive(false);
$this.map.removeLayer($this.drawVectorLayer)
}
});
//将layer和interaction添加到地图上
this.map.addLayer(this.drawVectorLayer);
this.map.addInteraction(drawSquare);
}