引用
import { Map, View } from "ol";
import { Tile as TileLayer, Vector, Image, Tile } from "ol/layer";
import {
OSM,
XYZ,
Vector as sourceVector,
ImageStatic,
TileImage,
} from "ol/source";
import GeoJSON from "ol/format/GeoJSON";
import { Style, Fill, Stroke, Text, Icon, Circle } from "ol/style";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import Polygon from "ol/geom/Polygon";
import Overlay from "ol/Overlay";
import Projection from "ol/proj/Projection";
import { addProjection, addCoordinateTransforms } from "ol/proj";
import { Draw } from "ol/interaction";
import TileGrid from "ol/tilegrid/TileGrid";
import { lngLatToMercator, mercatorToLngLat } from "./bd09";
一、地图初始化
let map = new Map({
layers: [
mapLayer,
],
view: new View({
projection: "EPSG:4326", // 4326经纬度 || 5328 屏幕坐标
center: [110.41103, 19.81555], //中心点
zoom: 6,
minZoom: 8,
maxZoom: 12,
}),
target: "mapContainer",
});
二、离线瓦片(WGB84经纬度坐标)
1、常规坐标系瓦片
//tms瓦片(全球)
a.globalLayer = new TileLayer({
source: new XYZ({
url: window.configItem.globalLayer + `{z}/{x}/{-y}.png`,
}),
})
//tms瓦片(河南)
a.HNLayer = new TileLayer({
source: new XYZ({
url: window.configItem.areaLayer + `{z}/{x}/{-y}.png`,
}),
});
2、百度坐标瓦片
//添加百度地图投影 url 瓦片地址
addBmap(url) {
var projBD09 = new Projection({
code: "BD:09",
extent: [-20037726.37, -11708041.66, 20037726.37, 12474104.17],
units: "m",
axisOrientation: "neu",
global: false,
});
addProjection(projBD09);
addCoordinateTransforms(
"EPSG:4326",
"BD:09",
function (coordinate) {
return lngLatToMercator(coordinate);
},
function (coordinate) {
return mercatorToLngLat(coordinate);
}
);
/*定义百度地图分辨率与瓦片网格*/
var resolutions = [];
for (var i = 0; i <= 18; i++) {
resolutions[i] = Math.pow(2, 18 - i);
}
var tilegrid = new TileGrid({
origin: [0, 0],
resolutions: resolutions,
});
/*加载百度地图离线瓦片不能用ol.source.XYZ,ol.source.XYZ针对谷歌地图(注意:是谷歌地图)而设计,
而百度地图与谷歌地图使用了不同的投影、分辨率和瓦片网格。因此这里使用ol.source.TileImage来自行指定
投影、分辨率、瓦片网格。*/
var source = new TileImage({
projection: "BD:09",
tileGrid: tilegrid,
tileUrlFunction: function (tileCoord, pixelRatio, proj) {
var z = tileCoord[0];
var x = tileCoord[1];
var y = tileCoord[2];
return url + z + "/" + x + "/" + y + ".png";
// return url + z + "/" + x + "/" + Math.abs(y) + ".png";
},
});
var mapLayer = new Tile({
source: source,
});
return mapLayer;
}
bd09JS链接:
三、高德在线瓦片
//加载高德在线瓦片
addAmap(url) {
// let url;
// 矢量路网含注记
url = 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7';
// 矢量路网不含注记
// url = 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=7';
// 影像路网含注记
// url = 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=8';
// 影像路网不含注记
// url = 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=8';
// 影像图(不含路网、不含注记)
// url = 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=6';
let layer = new TileLayer({
source: new XYZ({
url: url
})
})
return layer;
}
四、矢量边界线
// 添加矢量数据 (json格式边界)
addVector(map, jsonData, config) {
let option = {
stroke: {
width: 1,
color: "rgba(201,209,229, 0.6)",
},
text: {
fill: {
color: "rgba(255,255,255, 1)",
},
},
};
option = Object.assign(option, config);
var layer = new Vector({
name: "边界线",
source: new sourceVector({
features: new GeoJSON().readFeatures(jsonData),
}),
projection: "EPSG:4326",
// projection: 'BD:09',
zIndex: 999,
style: function (feature) {
return new Style({
stroke: new Stroke({
width: option.stroke.width,
color: option.stroke.color,
}),
text: new Text({
show: false,
textAlign: "center", //位置
textBaseline: "middle", //基准线
font: "normal 12px 微软雅黑", //文字样式
text: "",
// text: feature.values_.name
// ? feature.values_.name
// : feature.values_.Name, //文本内容
fill: new Fill({
color: option.text.fill.color,
}),
}),
});
},
});
map.addLayer(layer);
}
五、dom标注 (矢量标注 搭配dom)
//ele 为dom element
addAnimatePoint(map, lnglat, ele, data) {
var point_overlay = new Overlay({
element: ele,
data,
positioning: "center-center",
});
map.addOverlay(point_overlay);
point_overlay.setPosition(lnglat);
return point_overlay;
}
六、图片图层
// 添加图片图层
addImage(url, boundary) {
var a = this;
// var extent = [116.048649, 35.630463, 117.999231, 36.476049]; //表示图片的尺寸
var extent = [
boundary.minlng,
boundary.minlat,
boundary.maxlng,
boundary.maxlat,
]; //表示图片的尺寸
var projection = new Projection({
code: "EPSG:4326",
extent: extent,
});
var imgSource = new ImageStatic({
url: url,
projection: projection,
imageExtent: extent,
});
var imageLayer = new Image({
zIndex: 1,
source: imgSource,
});
a.map.addLayer(imageLayer);
a.imageLayer = imageLayer;
return imageLayer;
}
七、矢量点 (图标 | 文本)
// 添加图标
addTaggingPoint(lnglat, icon) {
var point = new Feature({
geometry: new Point(lnglat),
});
//实例化一个矢量图层Vector作为绘制层
var source = new sourceVector({
features: [point],
});
// 设置样式
point.setStyle(
new Style({
//形状
image: new Icon({
//图片样式
src: icon, //图片路径
size: [26, 30],
imgSize: [26, 30],
offset: [0, 0],
scale: 1, //图标缩放比例
}),
text: new Text({
text: text ? text : "",
offsetX: 3,
offsetY: 35,
textAlign: "center",
fill: new Fill({
color: "#FFF",
}),
font: "12px Calibri,sans-serif",
// stroke: new Stroke({
// color: "#000",
// width: 5,
// }),
backgroundFill: new Fill({
color: "rgba(12,76,99,0.8)",
}),
backgroundStroke: new Stroke({
color: "#4B937F",
width: 2,
}),
padding: [5, 10, 5, 10],
}),
})
);
//创建一个图层
var vector = new Vector({
source: source,
});
//将绘制层添加到地图容器中
this.map.addLayer(vector);
return vector;
}
八、信息窗体 (搭配dom)
// 添加信息窗体
addInfowindow(domId, lnglat, offset = [0, 0]) {
const overlay = new Overlay({
element: document.getElementById(domId), // 将自定义 html 内容添加到覆盖层
positioning: "bottom-center", // 覆盖层位置
autoPan: true, // 是否自动平移,当点击时对话框超出屏幕边距,会自动平移地图使其可见
autoPanMargin: 0, // 设置自动平移边距
offset: offset ? offset : [5, 45], // 覆盖层偏移起点的位置
className: "overlay-test", // 覆盖物在覆盖层的类名
autoPanAnimation: {
duration: 250,
},
});
// 设置覆盖物的经纬度
overlay.setPosition(lnglat);
// 将覆盖物添加到地图上
this.map.addOverlay(overlay);
return overlay;
}
九、移除标注 图层
let layers = map.getLayers() // 获取全部图层
map.removeLayer(layer) //循环移除全部 (适用于图片图层、矢量标注)
十、手动绘制多边形
drawPolygon(map) {
const _this = this;
this.source = new sourceVector();
let draw = new Draw({
source: _this.source,
type: 'Polygon',
style: new Style({
image: new Circle({
radius: 10,
fill: new Fill({ color: "rgba(64,158,255,1)" })
}),
stroke: new Stroke({ color: 'rgba(64,158,255,1)', width: 2 }),
fill: new Fill({ color: 'rgba(64,158,255,0.8)' })
})
});
map.addInteraction(draw); //添加交互
return draw;
}
draw.setActive(true); //设置画笔开启
draw.setActive(false); //设置画笔关闭
map.removeInteraction(draw);//移除交互
//监听绘制结束
draw.on("drawend", (DrawEvent) => {
let lngLats = DrawEvent.feature.getGeometry().flatCoordinates; //获取绘制多边形顶点集合
});