-
搭建本地環境,配置瓦片數據,下載文件並找到相應路徑
鏈接: 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);
}