123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512 |
- // 引入OpenLayers的主模块
- import Map from 'ol/Map';
- import View from 'ol/View';
- import TileState from 'ol/TileState';
- import Feature from 'ol/Feature';
- import Point from 'ol/geom/Point';
- import VectorLayer from 'ol/layer/Vector';
- import VectorSource from 'ol/source/Vector';
- import Style from 'ol/style/Style';
- import Icon from 'ol/style/Icon';
- import Text from 'ol/style/Text';
- import Projection from 'ol/proj/Projection';
- import { getWidth, getTopLeft } from 'ol/extent';
- import TileLayer from 'ol/layer/Tile';
- import WMTS from 'ol/source/WMTS';
- import WMTSTileGrid from 'ol/tilegrid/WMTS';
- import WMTSCapabilities from 'ol/format/WMTSCapabilities';
- import { Fill, Stroke } from 'ol/style';
- import proj4 from 'proj4';
- import { register } from 'ol/proj/proj4';
- import { defaults, ScaleLine } from 'ol/control';
- import Vector from 'ol/layer/Vector';
- import SourceVector from 'ol/source/Vector';
- import GeoJSON from 'ol/format/GeoJSON';
- import axios from 'axios';
- import { fromExtent } from 'ol/geom/Polygon';
- import { LinearRing, LineString, Polygon } from 'ol/geom';
- import { Graticule } from 'ol/layer';
- import { Cluster } from 'ol/source';
- import CircleStyle from 'ol/style/Circle';
- import Overlay from 'ol/Overlay';
- import { DoubleClickZoom, DragPan, Draw, Select } from 'ol/interaction';
- import { click } from 'ol/events/condition';
- import Circle from 'ol/geom/Circle';
- import { deepClone, getRgba, hexToRgba, initDrag, rgbToRgba } from '@/utils';
- import { createBox } from 'ol/interaction/Draw';
- import * as turf from '@turf/turf';
- import { nanoid } from 'nanoid';
- import carImg from '@/assets/images/car.png';
- import { globalHeaders } from '@/utils/request';
- import { iconList } from '@/views/globalMap/data/mapData';
- import gdJson from '@/assets/json/gd.json';
- const tk = 'a8df87f1695d224d2679aa805c1268d9';
- const commonUrl = import.meta.env.VITE_APP_BASE_API2 + 'api/oneShare/proxyHandler/gd/';
- // proj4.defs('EPSG:4490', '+proj=longlat +ellps=GRS80 +no_defs +type=crs');
- proj4.defs(
- 'EPSG:4490',
- 'GEOGCS["China Geodetic Coordinate System 2000",DATUM["China_2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","1043"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]'
- );
- // proj4.defs('EPSG:4525', '+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs');
- register(proj4);
- const projection = new Projection({
- code: 'EPSG:4490',
- units: 'degrees',
- axisOrientation: 'neu'
- });
- projection.setExtent([-180, -90, 180, 90]);
- projection.setWorldExtent([-180, -90, 180, 90]);
- const projectionExtent = [-180, -90, 180, 90];
- const size = getWidth(projectionExtent) / 256;
- const resolutions = [];
- for (let z = 2; z < 22; ++z) {
- resolutions[z] = size / Math.pow(2, z);
- }
- export class olMap {
- private map;
- private options;
- private markers = [];
- private drawOptions = {
- graphicsType: 'circle',
- strokeColor: '#f80102',
- strokeOpacity: 1,
- strokeWeight: 2,
- fillColor: '#f80102',
- fillOpacity: 0,
- strokeStyle: 'solid',
- icon: '',
- iconName: ''
- };
- private drawVector;
- private drawTool;
- private vectorLayer;
- // 边界遮罩图层
- private maskLayer;
- private maskLayer2;
- // 显示信息框
- private clickMarker;
- private infoWindow;
- private select;
- // 车辆轨迹
- private carLayer;
- private carFeature;
- private traceFeature;
- // 自定义绘制结束调用方法
- private drawEndMethod;
- private drawing;
- private path;
- private anyLine;
- private scale;
- // 标绘图层
- private plotLayers = {};
- private addressMarker;
- private addPoints = [];
- constructor(options) {
- this.options = options;
- this.map = new Map({
- controls: defaults({
- zoom: false,
- rotate: false
- }),
- layers: [],
- target: options.dom,
- view: new View({
- center: options.center && options.center.length === 2 ? [options.center[0], options.center[1]] : [110.90153121597234, 21.98323671981171],
- zoom: options.zoom ? options.zoom : 9.6,
- projection: projection,
- maxZoom: options.maxZoom ? options.maxZoom : 18,
- minZoom: options.minZoom ? options.minZoom : 1
- })
- });
- // 初始化比例尺
- if (options.showScale) {
- this.scale = new ScaleLine();
- this.map.addControl(this.scale);
- }
- if (options.drawTool?.use) {
- this.initMouseTool(options.drawTool);
- }
- this.initLayer(options);
- // 给标注点添加手势
- this.map.on('pointermove', (e) => {
- this.map.getTargetElement().style.cursor = 'auto';
- const features = this.map.getFeaturesAtPixel(e.pixel);
- features.forEach((feature) => {
- const originalFeature = feature.get('features') ? feature.get('features')[0] : '';
- if (!!originalFeature && originalFeature.get('pointer')) {
- this.map.getTargetElement().style.cursor = 'pointer'; //设置鼠标样式
- } else {
- this.map.getTargetElement().style.cursor = 'auto';
- }
- });
- });
- // 创建选择交互
- this.select = new Select({
- condition: click,
- style: null,
- filter: (feature, layer) => {
- // 检查当前图层是否在 plotLayers 中
- return Object.values(this.plotLayers).includes(layer);
- }
- });
- this.map.addInteraction(this.select);
- // 监听Select交互的select事件
- this.select.on('select', (event) => {
- const feature = event.selected[0]; // 获取被选中的要素集合
- const extData = feature.get('extData');
- if (!!feature) {
- if (this.clickMarker) {
- const selectData = this.clickMarker.get('extData');
- this.clickMarker.setStyle(
- new Style({
- image: new Icon({
- src: selectData.image,
- scale: selectData.scale,
- anchor: [0.5, 0.5],
- anchorXUnits: 'fraction',
- anchorYUnits: 'fraction'
- })
- })
- );
- }
- if (['1', '2'].includes(extData.type)) {
- // 多点位 单点
- if (this.clickMarker !== feature) {
- this.clickMarker = feature;
- feature.setStyle(
- new Style({
- image: new Icon({
- src: extData.imageHover,
- scale: extData.scale,
- anchor: [0.5, 0.5],
- anchorXUnits: 'fraction',
- anchorYUnits: 'fraction'
- })
- })
- );
- options.onMarkerClick(extData);
- }
- } else if (extData.type === '3') {
- // 聚合要素
- // this.select.getFeatures().clear();
- const currentZoom = this.map.getView().getZoom();
- this.map.getView().setZoom(currentZoom + 1);
- this.map.getView().setCenter([Number(extData.longitude), Number(extData.latitude)]);
- event.selected = [];
- }
- }
- });
- }
- async initLayer(options) {
- // 添加新的图层
- if (Array.isArray(options.id)) {
- for (const layer of options.id) {
- if (layer.layerType === 'JSON') {
- await this.createJsonLayer(layer);
- } else {
- await this.formatXml(layer);
- }
- }
- } else if (options.id === 'tianditu') {
- await this.formatXml2();
- } else if (options.id) {
- await this.formatXml(options);
- }
- // 创建Vector层并添加到地图上
- this.vectorLayer = new VectorLayer({
- source: new VectorSource({
- features: []
- }),
- zIndex: options.zIndex ? options.zIndex : 100
- });
- this.map.addLayer(this.vectorLayer);
- if (typeof this.options.onLoadCompleted === 'function') {
- this.options.onLoadCompleted(this.map);
- }
- }
- formatXml2() {
- const baseUrl = 'https://t{0-7}.tianditu.gov.cn/';
- const vecType = 'vec'; // 矢量图层类型
- const projType = 'w'; // 投影类型:web mercator
- const reqParams = {
- SERVICE: 'WMTS',
- REQUEST: 'GetTile',
- VERSION: '1.0.0',
- LAYER: '',
- STYLE: 'default',
- TILEMATRIXSET: projType,
- FORMAT: 'tiles',
- TILECOL: '{x}',
- TILEROW: '{y}',
- TILEMATRIX: '{z}',
- tk: key
- };
- const newParams = Object.assign({}, params, { LAYER: dataType });
- let paramsStr = '';
- for (const [k, v] of Object.entries(newParams)) {
- paramsStr += `${k}=${v}&`;
- }
- return `${baseUrl}${dataType}_${projType}/wmts?${paramsStr.slice(0, -1)}`;
- }
- formatXml(options) {
- const xml = new WMTSCapabilities();
- return this.getCapabilities(options.code, options.layerType).then((res) => {
- if (options.layerType === 'WMTS') {
- const geoJson = xml.read(res.data);
- const data = geoJson.Contents.Layer[0];
- const layerParam = {
- layerName: data.Abstract,
- styleName: data.Identifier,
- tilematrixset: data.TileMatrixSetLink[0].TileMatrixSet,
- format: data.Format[0]
- };
- this.createWmtsLayer(options, layerParam);
- } else if (options.layerType === 'WFS') {
- const parser = new DOMParser();
- const xmlDoc = parser.parseFromString(res.data, 'text/xml');
- const featureType = xmlDoc.getElementsByTagName('FeatureType')[0];
- const layerParam = {
- typeName: featureType.getElementsByTagName('Name')[0].textContent
- };
- this.createWfsLayer(options, layerParam);
- }
- });
- }
- // 请求接口获取地图信息
- getCapabilities(code, service) {
- return axios.get(commonUrl + code + '?SERVICE=' + service + '&REQUEST=GetCapabilities', {
- headers: globalHeaders()
- });
- }
- // 请求WMTS地图图片加载图层
- createWmtsLayer(options, layerParam) {
- const source = new WMTS({
- url: commonUrl + options.code,
- crossOrigin: 'Anonymous',
- layer: layerParam.layerName,
- style: layerParam.styleName,
- matrixSet: layerParam.tilematrixset,
- format: layerParam.format,
- wrapX: true,
- tileGrid: new WMTSTileGrid({
- origin: getTopLeft(projectionExtent),
- resolutions: resolutions,
- matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21']
- }),
- tileLoadFunction: function (tile, src) {
- const xhr = new XMLHttpRequest();
- xhr.open('GET', src);
- // 添加自定义 Headers
- const headers = globalHeaders();
- xhr.setRequestHeader('Authorization', headers.Authorization);
- xhr.responseType = 'arraybuffer'; // 确保支持图片二进制数据
- xhr.onload = function () {
- if (xhr.status === 200) {
- const type = xhr.getResponseHeader('Content-Type');
- const blob = new Blob([xhr.response], { type: type });
- const url = window.URL.createObjectURL(blob);
- tile.getImage().src = url; // 将图像数据绑定到瓦片
- } else {
- tile.setState(TileState.ERROR); // 处理请求失败
- }
- };
- xhr.onerror = function () {
- tile.setState(TileState.ERROR);
- };
- xhr.send();
- }
- });
- const layer = new TileLayer({
- source: source,
- zIndex: options.zIndex,
- visible: options.visible
- });
- layer.set('layerName', options.layer);
- layer.set('id', options.code);
- this.map.addLayer(layer);
- }
- //
- createWfsLayer(options, layerParam) {
- const source = new VectorSource({
- format: new GeoJSON(),
- loader: function (extent, resolution, projection) {
- // 构建带认证头的请求参数
- const url =
- `${commonUrl}${options.code}?` +
- `REQUEST=GetFeature` +
- `&typeName=${encodeURIComponent(layerParam.typeName)}` +
- `&outputFormat=application/json`;
- const headers = globalHeaders();
- fetch(url, {
- headers: {
- 'Authorization': headers.Authorization
- }
- })
- .then((response) => {
- if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
- return response.json();
- })
- .then((json) => {
- const features = new GeoJSON().readFeatures(json, {
- dataProjection: layerParam.srsName,
- featureProjection: projection
- });
- this.addFeatures(features);
- })
- .catch(error => console.error('WFS加载失败:', error));
- }
- });
- const vectorLayer = new VectorLayer({
- source: source,
- style: new Style({
- // 必须设置样式才能显示
- fill: new Fill({ color: 'rgba(0,0,0, 0)' }),
- stroke: new Stroke({ color: 'rgba(0,0,0, 1)', width: 1 })
- }),
- zIndex: options.zIndex ? options.zIndex : -99
- });
- this.map.addLayer(vectorLayer);
- }
- // 加载json图层
- createJsonLayer(layer) {
- return new Promise((resolve, reject) => {
- const geojsonParser = new GeoJSON();
- console.log(this.map.getView().getProjection());
- const features = geojsonParser.readFeatures(gdJson, {
- dataProjection: 'EPSG:4326',
- featureProjection: this.map.getView().getProjection()
- });
- const jsonLayer = new VectorLayer({
- source: new VectorSource({ features }),
- style: new Style({
- // 必须设置样式才能显示
- fill: new Fill({ color: '#ffffff' }),
- stroke: new Stroke({ color: 'rgba(0,0,0, 1)', width: 1 })
- }),
- zIndex: layer.zIndex ? layer.zIndex : -99
- });
- this.map.addLayer(jsonLayer);
- resolve({});
- });
- }
- // 初始化绘画工具
- initMouseTool(options) {
- this.drawOptions = {
- graphicsType: options.graphicsType ? options.graphicsType : 'cirlce',
- strokeColor: options.color,
- strokeOpacity: 1,
- strokeWeight: 2,
- fillColor: options.color,
- fillOpacity: options.drawType === '1' ? 0 : 0.5,
- strokeStyle: 'solid'
- };
- // 创建矢量图层用于绘制
- this.drawVector = new Vector({
- source: new VectorSource({
- features: []
- })
- });
- this.map.addLayer(this.drawVector);
- }
- // 绘制结束事件
- onDrawEnd(event) {
- const feature = event.feature;
- const aa = feature.getGeometry();
- // 继续编辑编辑
- this.drawGraphics(this.drawOptions.graphicsType);
- }
- // 绘制图形
- drawGraphics(newOptions: MouseTool) {
- const typeList = {
- circle: 'Circle',
- rectangle: 'Circle',
- polygon: 'Polygon',
- measureArea: 'Polygon',
- straightLine: 'LineString',
- marker: 'Point',
- text: 'Point',
- anyLine: 'AnyLine'
- };
- const data = getRgba(newOptions.color);
- let geometryFunction = null;
- if (newOptions.graphicsType === 'rectangle') {
- // 绘制矩形的方法
- geometryFunction = createBox();
- }
- if (!!typeList[newOptions.graphicsType]) {
- if (newOptions.graphicsType === 'text') {
- this.drawOptions = {
- type: newOptions.graphicsType,
- title: newOptions.title,
- text: newOptions.text,
- fontSize: newOptions.fontSize,
- fontColor: newOptions.fontColor,
- lnglat: newOptions.lnglat
- };
- // 绘制文字
- return this.addText(this.drawOptions);
- } else {
- this.drawOptions = {
- type: newOptions.graphicsType,
- title: newOptions.title,
- strokeColor: !!data.color ? data.color : newOptions.color,
- strokeOpacity: 1,
- strokeWeight: 1,
- fillColor: data.color,
- fillOpacity: data.opacity,
- strokeStyle: 'solid'
- };
- if (newOptions.graphicsType === 'marker') {
- this.drawOptions.icon = newOptions.icon;
- this.drawOptions.iconName = newOptions.iconName;
- this.drawOptions.size = newOptions.size;
- }
- this.closeDraw();
- if (newOptions.graphicsType === 'anyLine') {
- this.drawOptions.fillOpacity = 0;
- this.drawAnyLine(this.drawOptions);
- } else {
- // 创建绘制交互
- let style = new Style({
- stroke: new Stroke({
- color: rgbToRgba(this.drawOptions.strokeColor, this.drawOptions.strokeOpacity),
- width: this.drawOptions.strokeWeight
- }),
- fill: new Fill({
- color: rgbToRgba(this.drawOptions.fillColor, this.drawOptions.fillOpacity)
- })
- });
- this.drawTool = new Draw({
- source: this.drawVector.getSource(),
- type: typeList[newOptions.graphicsType],
- geometryFunction: geometryFunction,
- style: style
- });
- // 添加绘制交互到地图
- this.map.addInteraction(this.drawTool);
- // 监听绘制结束事件
- this.drawTool.on('drawend', (event) => {
- const feature = event.feature;
- // 获取几何对象
- if (newOptions.graphicsType !== 'marker') {
- if (newOptions.graphicsType === 'measureArea') {
- const geometry = feature.getGeometry();
- const coordinates = geometry.getCoordinates();
- const pathArr = coordinates[0];
- const area = turf.area(turf.polygon([pathArr]));
- style = new Style({
- stroke: style.getStroke(),
- fill: style.getFill(),
- text: new Text({
- text: '区域面积' + area.toFixed(2) + '平方米',
- font: '14px Calibri,sans-serif',
- fill: new Fill({ color: '#000' }),
- stroke: new Stroke({
- color: '#fff',
- width: 3
- }),
- overflow: true
- })
- });
- }
- feature.setStyle(style);
- }
- });
- }
- }
- }
- return this.drawOptions;
- }
- // 空间分析绘制图形
- drawGraphics2(newOptions: MouseTool) {
- const typeList = {
- circle: 'Circle',
- rectangle: 'Circle',
- polygon: 'Polygon'
- };
- let geometryFunction = null;
- if (newOptions.graphicsType === 'rectangle') {
- // 绘制矩形的方法
- geometryFunction = createBox();
- }
- if (!!typeList[newOptions.graphicsType]) {
- this.drawOptions = {
- type: newOptions.graphicsType,
- strokeColor: newOptions.color,
- strokeOpacity: 1,
- strokeWeight: 1,
- fillColor: newOptions.color,
- fillOpacity: newOptions.drawType === '1' ? '0' : '0.5',
- strokeStyle: 'solid'
- };
- this.closeDraw();
- // 创建绘制交互
- const style = new Style({
- stroke: new Stroke({
- color: hexToRgba(this.drawOptions.strokeColor, this.drawOptions.strokeOpacity),
- width: this.drawOptions.strokeWeight
- }),
- fill: new Fill({
- color: hexToRgba(this.drawOptions.fillColor, this.drawOptions.fillOpacity)
- })
- });
- this.drawTool = new Draw({
- source: this.drawVector.getSource(),
- type: typeList[newOptions.graphicsType],
- geometryFunction: geometryFunction,
- style: style
- });
- // 添加绘制交互到地图
- this.map.addInteraction(this.drawTool);
- // 监听绘制结束事件
- this.drawTool.on('drawend', (event) => {
- const feature = event.feature;
- // 获取几何对象
- feature.setStyle(style);
- });
- }
- }
- addText(options) {
- // 创建文本覆盖物
- const style = new Style({
- text: new Text({
- text: options.text,
- font: options.fontSize + ' Calibri,sans-serif',
- fill: new Fill({ color: options.fontColor }),
- // stroke: new Stroke({
- // color: '#fff',
- // width: 3
- // }),
- overflow: true
- })
- });
- const text = new Feature({
- geometry: new Point(options.lnglat)
- });
- text.setStyle(style);
- // 将文本覆盖物添加到地图
- this.drawVector.getSource().addFeature(text);
- const id = nanoid();
- text.set('id', id);
- const data: any = deepClone(options);
- data.id = id;
- return { text, data };
- }
- drawAnyLine(drawOptions) {
- const handleTouchStart = (e) => {
- this.drawing = true;
- const interactions = this.map.getInteractions();
- interactions.forEach((interaction) => {
- if (interaction instanceof DragPan || interaction instanceof DoubleClickZoom) {
- interaction.setActive(false); // 修改为需要的值,true或false
- }
- });
- this.path = [e.coordinate];
- // 移除旧的线段
- if (this.anyLine) {
- this.drawVector.getSource().removeFeature(this.anyLine);
- }
- };
- const handleTouchMove = (e) => {
- if (!this.drawing) return;
- this.path.push(e.coordinate);
- // 移除旧的线段
- if (this.anyLine) {
- this.drawVector.getSource().removeFeature(this.anyLine);
- }
- this.anyLine = new Feature({
- geometry: new LineString(this.path)
- });
- const lineStyle = new Style({
- stroke: new Stroke({
- color: hexToRgba(this.drawOptions.strokeColor, this.drawOptions.strokeOpacity), // 合并颜色与透明度
- width: this.drawOptions.strokeWeight,
- lineJoin: 'round' // 线段连接处圆角
- })
- });
- this.anyLine.setStyle(lineStyle);
- this.drawVector.getSource().addFeature(this.anyLine);
- };
- const handleTouchEnd = () => {
- this.drawing = false;
- document.removeEventListener('touchend', handleTouchEnd);
- this.map.un('pointerdown', handleTouchStart);
- this.map.un('pointermove', handleTouchMove);
- document.removeEventListener('mouseup', handleTouchEnd);
- if (!!this.drawEndMethod) {
- this.drawEndMethod(drawOptions, this.anyLine);
- }
- this.anyLine = null;
- };
- document.addEventListener('touchend', handleTouchEnd);
- this.map.on('pointerdown', handleTouchStart);
- this.map.on('pointermove', handleTouchMove);
- document.addEventListener('mouseup', handleTouchEnd);
- }
- // 关闭绘制
- closeDraw() {
- if (!this.drawTool) return;
- this.map.removeInteraction(this.drawTool);
- // this.drawTool.abortDrawing();
- }
- // 切换图层
- async replaceLayers(newLayers, loadendFunc) {
- // 遍历当前的所有图层并移除它们
- const layers = this.map.getLayers();
- const layerArray = layers.getArray().slice();
- layerArray.forEach((layer) => {
- // 标注现在都是用同一个暂不移除'annotation'
- if (!!layer && ['map'].includes(layer.get('layerName'))) {
- layer.getSource().clear();
- layer.dispose();
- this.map.removeLayer(layer);
- }
- });
- if (Array.isArray(newLayers)) {
- for (const layer of newLayers) {
- await this.formatXml(layer);
- }
- } else if (newLayers.id === 'tianditu') {
- await this.formatXml2();
- } else {
- await this.formatXml(newLayers);
- }
- if (loadendFunc) {
- loadendFunc();
- }
- }
- // 集群点样式
- clusterStyle(feature) {
- const originalFeature = feature.get('features')[0];
- const size = feature.get('features').length;
- if (size > 1) {
- const outerCircle = new CircleStyle({
- radius: 20,
- fill: new Fill({
- color: 'rgba(79, 176, 206, 0.5)'
- }),
- stroke: new Stroke({
- color: 'rgba(79, 176, 206, 1)'
- })
- });
- return [
- new Style({
- image: outerCircle,
- text: new Text({
- text: size.toString(),
- font: '14px sans-serif',
- fill: new Fill({
- color: '#ffff'
- })
- })
- })
- ];
- }
- const pointSize = originalFeature.get('size');
- const originalWidth = originalFeature.get('originalWidth');
- const originalHeight = originalFeature.get('originalHeight');
- const icon = originalFeature.get('icon');
- const name = originalFeature.get('name');
- const showName = originalFeature.get('showName');
- const scale = !!pointSize[0] ? pointSize[0] / originalWidth : 1;
- const style = new Style({
- geometry: originalFeature.getGeometry(),
- image: new Icon({
- src: icon,
- scale: scale,
- anchor: [0.5, 0.5],
- anchorXUnits: 'fraction',
- anchorYUnits: 'fraction'
- })
- });
- if (!!showName) {
- style.setText(
- new Text({
- text: name,
- font: '12px sans-serif',
- fill: new Fill({
- color: '#000'
- }),
- stroke: new Stroke({
- color: '#fff',
- width: 3
- }),
- offsetY: (originalHeight / 2) * scale + 4
- })
- );
- }
- return style;
- }
- // 添加搜索的标记的
- addSearchMarker(item) {
- const view = this.map.getView();
- view.setZoom(18);
- view.setCenter([Number(item.longitude), Number(item.latitude)]);
- // 获取到上一次的搜索标记并移除
- const index = this.markers.findIndex((m) => {
- return m.dataType === 'search';
- });
- if (index > -1) {
- this.markers.splice(index, 1);
- }
- if (!this.plotLayers['search']) {
- this.plotLayers['search'] = new VectorLayer({
- source: new VectorSource({
- features: []
- })
- });
- this.map.addLayer(this.plotLayers['search']);
- } else {
- this.plotLayers['search'].getSource().clear();
- }
- this.addMarker2({ 'search': item });
- this.clickMarker = item;
- this.options.onMarkerClick(item);
- }
- addMarker(points) {
- this.clearMarker();
- const vectorSource = new VectorSource({
- features: []
- });
- points.forEach((point) => {
- // 创建标注点
- const feature = new Feature({
- // 必须是数字类型,字符串不识别
- geometry: new Point([Number(point.longitude), Number(point.latitude)]),
- name: point.name,
- icon: point.icon,
- image: point.icon,
- imageHover: point.imageHover,
- size: point.size,
- showName: point.showName,
- pointer: true,
- extData: point
- });
- // 设置自定义属性
- const img = new Image();
- img.onload = () => {
- // 图片加载完成后,可以访问其 width 和 height 属性
- const width = img.width;
- const height = img.width;
- feature.set('originalWidth', width);
- feature.set('originalHeight', height);
- feature.set('img', img);
- vectorSource.addFeature(feature);
- };
- img.src = point.icon; // 设置图片的 URL,触发加载
- this.markers.push(point);
- });
- const clusterSource = new Cluster({
- distance: 30,
- source: vectorSource
- });
- this.vectorLayer.setStyle(this.clusterStyle);
- this.vectorLayer.setSource(clusterSource);
- }
- addMarker2(obj) {
- this.clearMarker2('point');
- if (!!this.plotLayers['point']) {
- this.markers = [];
- }
- let hideInfoFlag = true;
- Object.keys(obj).forEach((key: string) => {
- const data = obj[key];
- const name = key === 'search' ? 'search' : 'point';
- if (this.clickMarker) {
- const extData = this.clickMarker.get('extData');
- if (data.id === extData.id && data.dataType === extData.dataType) {
- hideInfoFlag = false;
- data.isHover = true;
- }
- }
- if (data.type === '3') {
- // 聚合点
- const outerCircle = new CircleStyle({
- radius: 20,
- fill: new Fill({
- color: 'rgba(79, 176, 206, 0.5)'
- }),
- stroke: new Stroke({
- color: 'rgba(79, 176, 206, 1)'
- })
- });
- const feature = new Feature({
- // 必须是数字类型,字符串不识别
- geometry: new Point([Number(data.longitude), Number(data.latitude)]),
- name: data.name,
- pointer: true,
- extData: data
- });
- feature.setStyle(
- new Style({
- image: outerCircle,
- text: new Text({
- text: data.count.toString(),
- font: '14px sans-serif',
- fill: new Fill({
- color: '#ffff'
- })
- })
- })
- );
- this.plotLayers[name].getSource().addFeature(feature);
- this.markers.push(data);
- } else {
- // 单个点
- const iconConfig = iconList[data.dataType] || (name === 'search' ? iconList.common2 : iconList.common);
- data.image = iconConfig.image;
- data.imageHover = iconConfig.imageHover;
- data.size = iconConfig.size;
- if (data.materia_name) {
- data.name = data.materia_name;
- }
- if (data.dataType === 43) {
- data.showName = true;
- }
- if (!data.id) {
- data.id = nanoid(8);
- }
- data.lnglat = [data.longitude, data.latitude];
- const feature = new Feature({
- // 必须是数字类型,字符串不识别
- geometry: new Point([Number(data.longitude), Number(data.latitude)]),
- name: data.name,
- pointer: true,
- extData: data
- });
- // 设置自定义属性
- const img = new Image();
- img.onload = () => {
- // 图片加载完成后,可以访问其 width 和 height 属性
- const scale = data.size[0] ? data.size[0] / img.width : 1;
- data.scale = scale;
- feature.set('extData', data);
- feature.setStyle(
- new Style({
- image: new Icon({
- src: data.isHover ? data.imageHover : data.image,
- scale: scale,
- anchor: [0.5, 0.5],
- anchorXUnits: 'fraction',
- anchorYUnits: 'fraction'
- })
- })
- );
- this.plotLayers[name].getSource().addFeature(feature);
- if (data.isHover) {
- this.clickMarker = feature;
- this.options.onMarkerClick(data);
- }
- };
- img.src = data.image; // 设置图片的 URL,触发加载
- this.markers.push(data);
- }
- });
- if (hideInfoFlag) {
- this.clickMarker = null;
- this.hideInfo(true);
- }
- }
- // 清除所有标加
- clearMarker() {
- if (!this.vectorLayer) return;
- this.vectorLayer.getSource().clear();
- }
- clearMarker2(name) {
- // 新增图层
- if (!this.plotLayers[name]) {
- this.plotLayers[name] = new VectorLayer({
- source: new VectorSource({
- features: []
- })
- });
- this.map.addLayer(this.plotLayers[name]);
- } else {
- this.plotLayers[name].getSource().clear();
- // this.clickMarker = null;
- // this.hideInfo();
- }
- }
- // 设置灾害地点 单独图册
- setAddress(data) {
- this.clearMarker2('address');
- this.addressMarker = new Feature({
- // 必须是数字类型,字符串不识别
- geometry: new Point([Number(data.longitude), Number(data.latitude)]),
- name: data.name,
- pointer: true,
- extData: data
- });
- this.addressMarker.setStyle(
- new Style({
- image: new Icon({
- src: data.image,
- scale: [0.288, 0.288],
- anchor: [0.5, 0.5],
- anchorXUnits: 'fraction',
- anchorYUnits: 'fraction'
- })
- })
- );
- this.plotLayers['address'].getSource().addFeature(this.addressMarker);
- }
- showInfo(content, position, offsetY, isCustom) {
- this.hideInfo();
- if (!this.infoWindow) {
- this.infoWindow = new Overlay({
- element: content,
- positioning: 'bottom-center', // 你可以根据需要调整定位方式
- offset: [0, offsetY ? offsetY : 0] // 偏移量,用于调整覆盖层相对于要素的位置
- });
- }
- this.infoWindow.setPosition(position);
- initDrag(this.infoWindow.element);
- this.map.addOverlay(this.infoWindow);
- }
- hideInfo(flag?: boolean) {
- this.map.removeOverlay(this.infoWindow);
- this.infoWindow = null;
- if (!!flag && this.clickMarker) {
- const selectData = this.clickMarker.get('extData');
- this.clickMarker.setStyle(
- new Style({
- image: new Icon({
- src: selectData.image,
- scale: selectData.scale,
- anchor: [0.5, 0.5],
- anchorXUnits: 'fraction',
- anchorYUnits: 'fraction'
- })
- })
- );
- this.clickMarker = null;
- }
- }
- /**
- *
- * @param {Geojon} chaozhou 根据geoJson对象创建Featrue对象
- * @returns VectorLayer
- */
- createVecByJson(json, options) {
- const format = new GeoJSON();
- const fs = format.readFeatures(json);
- this.maskLayer = new VectorLayer({
- source: new VectorSource(),
- style: new Style({
- fill: new Fill({
- color: options.fillColor ? options.fillColor : 'rgba(16, 36, 59, 0.65)'
- }),
- stroke: new Stroke({
- color: options.strokeColor ? options.strokeColor : 'rgba(38, 138, 185, 1)',
- width: 2
- })
- }),
- zIndex: options.zIndex ? options.zIndex : 99
- });
- this.map.addLayer(this.maskLayer);
- const extent = [-180, -90, 180, 90];
- const polygonRing = fromExtent(extent);
- fs.forEach((x) => {
- const ft = x.values_.geometry;
- const coords = ft.getCoordinates();
- coords.forEach((coord) => {
- const linearRing = new LinearRing(coord[0]);
- polygonRing.appendLinearRing(linearRing);
- });
- });
- const convertFt = new Feature({
- geometry: polygonRing
- });
- this.maskLayer.getSource().addFeature(convertFt);
- }
- createVecByJson2(json, options) {
- if (!!this.maskLayer2) {
- // this.map.addLayer(this.maskLayer);
- this.map.addLayer(this.maskLayer2);
- } else {
- this.maskLayer2 = new VectorLayer({
- source: new VectorSource(),
- style: new Style({
- fill: new Fill({
- color: 'rgba(0, 0, 0, 0)'
- }),
- stroke: new Stroke({
- color: options.strokeColor ? options.strokeColor : '#268ab9',
- width: options.strokeWeight ? options.strokeWeight : 1
- })
- })
- });
- this.map.addLayer(this.maskLayer2);
- this.maskLayer = new VectorLayer({
- source: new VectorSource(),
- style: new Style({
- fill: new Fill({
- color: options.fillColor ? options.fillColor : 'rgba(16, 36, 59, 0.65)'
- }),
- stroke: new Stroke({
- color: options.strokeColor ? options.strokeColor : 'rgba(38, 138, 185, 1)',
- width: 2
- })
- }),
- zIndex: options.zIndex ? options.zIndex : -97
- });
- // // 合并区边界
- // const format = new GeoJSON();
- // const data2 = mergeGeoJsonPolygons(json);
- // const fs = format.readFeatures(data2);
- // const extent = [-180, -90, 180, 90];
- // const polygonRing = fromExtent(extent);
- // fs.forEach((x) => {
- // const ft = x.values_.geometry;
- // const coords = ft.getCoordinates();
- // coords.forEach((coord) => {
- // const linearRing = new LinearRing(coord[0]);
- // polygonRing.appendLinearRing(linearRing);
- // });
- // });
- // const convertFt = new Feature({
- // geometry: polygonRing
- // });
- // this.maskLayer.getSource().addFeature(convertFt);
- // this.map.addLayer(this.maskLayer);
- // 边界部分
- json.features.forEach((feature) => {
- if (feature.geometry.type === 'Polygon') {
- const feature2 = new Feature({
- geometry: new LineString(feature.geometry.coordinates[0])
- });
- this.maskLayer2.getSource().addFeature(feature2);
- } else if (feature.geometry.type === 'MultiPolygon') {
- feature.geometry.coordinates.forEach((polygonCoords) => {
- const feature2 = new Feature({
- geometry: new LineString(polygonCoords[0])
- });
- this.maskLayer2.getSource().addFeature(feature2);
- });
- }
- });
- }
- }
- /**
- * @description 创建矢量图层
- * @param {String} layerName 图层名称
- * @param {Number} zIndex 地图层级默认是0
- * @returns
- */
- createVecLayer(layerName = '', zIndex = 0) {
- const source = new SourceVector({
- crossOrigin: 'anonymous'
- });
- const layer = new Vector({
- source,
- zIndex
- });
- layer.set('layerName', layerName);
- return layer;
- }
- // 分布图遮罩层
- createMask(data) {
- this.removeMask();
- if (!data || data.length === 0) return;
- data.forEach((item) => {
- if (!item.points || item.points.length === 0) return;
- // 遮罩图层的样式
- const maskStyle = new Style({
- fill: new Fill({
- color: item.color // 红色遮罩,50%透明度
- }),
- stroke: new Stroke({
- color: 'rgba(159,159,159,0.7)',
- width: 1
- })
- });
- // 遮罩图层的矢量数据源(初始为空)
- const maskSource = new VectorSource();
- // 创建一个多边形特征
- const polygonFeature = new Feature({
- geometry: new Polygon(item.points)
- });
- const maskLayer = new VectorLayer({
- source: maskSource,
- style: maskStyle,
- properties: {
- name: 'mask'
- }
- });
- this.map.addLayer(maskLayer);
- // 将多边形特征添加到遮罩数据源中
- maskSource.addFeature(polygonFeature);
- });
- }
- removeMask() {
- //移除图层
- const layersArray = this.map.getLayers().getArray();
- layersArray.forEach((layer) => {
- // 检查图层是否有自定义属性,并且该属性是否匹配你要移除的图层的标识符
- if (layer.get('name') === 'mask') {
- this.map.removeLayer(layer);
- }
- });
- }
- removeMask2() {
- if (this.maskLayer) {
- this.map.removeLayer(this.maskLayer);
- this.maskLayer = null;
- }
- }
- removeMask3(isHide) {
- if (this.maskLayer) {
- this.map.removeLayer(this.maskLayer);
- if (!isHide) {
- this.maskLayer = [];
- }
- }
- if (this.maskLayer2) {
- this.map.removeLayer(this.maskLayer2);
- if (!isHide) {
- this.maskLayer2 = [];
- }
- }
- }
- /**
- * 绘制经纬线
- * visible: boolean 是否可见
- */
- handleLngLatLine(visible: boolean) {
- // 创建经纬网图层
- const graticule = new Graticule({
- name: 'Graticule',
- showLabels: true, // 为每条刻度线绘制一个带有各自纬度/经度的标签
- wrapX: false, // 是否水平重复经纬网
- targetSize: 230,
- zIndex: 99999,
- strokeStyle: new Stroke({
- // 用于绘制刻度线的样式
- color: '#dcdcdc', // 线条颜色
- width: 1 // 线条宽度
- }),
- lonLabelStyle: new Text({
- font: '12px Calibri,sans-serif',
- textBaseline: 'bottom',
- fill: new Fill({
- color: '#9d9d9d'
- })
- }),
- latLabelPosition: 0,
- latLabelStyle: new Text({
- font: '12px Calibri,sans-serif',
- textAlign: 'left',
- textBaseline: 'end',
- fill: new Fill({
- color: '#9d9d9d'
- })
- })
- });
- if (visible) {
- this.map.addLayer(graticule);
- } else {
- this.removeLayer('Graticule');
- }
- }
- /**
- * 移除指定name的layer
- * layerName: string
- * */
- removeLayer(layerName: string) {
- const layers = this.map.getLayers();
- layers.forEach((element) => {
- if (!!element && element.get('name') === layerName) {
- //移除
- this.map.removeLayer(element);
- }
- });
- }
- // 创建图形
- createGraphics(data: any) {
- if (data.type === 'circle') {
- // 绘制圆形
- return this.createCircle(data);
- } else if (['polygon', 'rectangle'].includes(data.type)) {
- // 绘制矩形、多边形
- return this.createPolygon(data);
- }
- // else if (data.type === 'marker') {
- // // 绘制图标
- // return createMarker(data);
- // } else if (data.type === 'measureArea') {
- // // 绘制面积
- // return createMeasureArea(data);
- // } else if (data.type === 'text') {
- // // 文字
- // return addText(data);
- // } else if (data.type === 'straightLine') {
- // // 直线
- // return createStraightLine(data);
- // }
- }
- createCircle(data) {
- const circle = new Circle(data.center, data.radius);
- const feature = new Feature(circle);
- feature.setStyle(
- new Style({
- stroke: new Stroke({
- color: rgbToRgba(data.strokeColor, data.strokeOpacity),
- width: data.strokeWeight
- }),
- fill: new Fill({
- color: rgbToRgba(data.fillColor, data.fillOpacity)
- })
- })
- );
- this.drawVector.getSource().addFeature(feature);
- return feature;
- }
- createPolygon(data) {
- const polygon = new Polygon([data.path]);
- const feature = new Feature(polygon);
- feature.setStyle(
- new Style({
- stroke: new Stroke({
- color: rgbToRgba(data.strokeColor, data.strokeOpacity),
- width: data.strokeWeight
- }),
- fill: new Fill({
- color: rgbToRgba(data.fillColor, data.fillOpacity)
- })
- })
- );
- this.drawVector.getSource().addFeature(feature);
- return feature;
- }
- createLineString(data) {
- const lineString = new LineString(data.path);
- const feature = new Feature(lineString);
- feature.setStyle(
- new Style({
- stroke: new Stroke({
- color: rgbToRgba(data.strokeColor, data.strokeOpacity),
- width: data.strokeWeight
- }),
- fill: new Fill({
- color: rgbToRgba(data.fillColor, data.fillOpacity)
- })
- })
- );
- this.drawVector.getSource().addFeature(feature);
- return feature;
- }
- trackPlayback(lineArr) {
- if (!!this.carFeature) {
- this.carLayer.getSource().removeFeature(this.carFeature);
- }
- if (!!this.traceFeature) {
- this.carLayer.getSource().removeFeature(this.traceFeature);
- }
- const getAngle = (point1, point2) => {
- let arc = 0;
- if (point2 && point2.length && point1 && point1.length) {
- if ((point2[0] - point1[0] >= 0 && point2[1] - point1[1] >= 0) || (point2[0] - point1[0] < 0 && point2[1] - point1[1] > 0)) {
- arc = Math.atan((point2[0] - point1[0]) / (point2[1] - point1[1]));
- } else if ((point2[0] - point1[0] > 0 && point2[1] - point1[1] < 0) || (point2[0] - point1[0] < 0 && point2[1] - point1[1] < 0)) {
- arc = Math.PI + Math.atan((point2[0] - point1[0]) / (point2[1] - point1[1]));
- }
- }
- return arc;
- };
- let lastTime = Date.now();
- const source = new VectorSource();
- let distance = 0;
- const angle = getAngle(lineArr[0], lineArr[1]);
- const speed = 500;
- let animationFlag = false;
- this.carFeature = new Feature({
- geometry: new Point(lineArr[0])
- });
- const icon = new Icon({
- crossOrigin: 'anonymous',
- src: carImg,
- width: 13,
- height: 26,
- anchor: [0.5, 0.5],
- rotation: angle
- });
- this.carFeature.setStyle(
- new Style({
- image: icon
- })
- );
- this.traceFeature = new Feature({
- geometry: new LineString(lineArr)
- });
- const route = new LineString(lineArr);
- this.carLayer = new VectorLayer({
- source: source,
- style: new Style({
- stroke: new Stroke({
- color: '#AF5',
- width: 5
- })
- })
- });
- this.carLayer.getSource().addFeatures([this.carFeature, this.traceFeature]);
- const move = (e) => {
- const time = e.frameState.time;
- // 时间戳差(毫秒)
- const elapsedTime = time - lastTime;
- // 距离(其实是比例的概念)
- distance = distance + (speed * elapsedTime) / 1e6;
- if (distance >= 1) {
- distance = 0;
- animationFlag = false;
- stopAnimation();
- return;
- }
- // 保存当前时间
- lastTime = time;
- // 上次坐标
- const lastCoord = this.carFeature.getGeometry().getCoordinates();
- // 获取新位置的坐标点
- const curCoord = route.getCoordinateAt(distance);
- // 设置新坐标
- this.carFeature.getGeometry().setCoordinates(curCoord);
- this.map.getView().setCenter(curCoord);
- // 设置角度
- this.carFeature.getStyle().getImage().setRotation(getAngle(lastCoord, curCoord));
- // 调用地图渲染
- this.map.render();
- };
- const stopAnimation = () => {
- this.carLayer.un('postrender', move);
- };
- this.map.addLayer(this.carLayer);
- this.carLayer.on('postrender', move);
- // 触发地图渲染
- const geo = this.carFeature.getGeometry().clone();
- this.carFeature.setGeometry(geo);
- return [this.carLayer];
- }
- drawData(data) {
- const res = [];
- data.forEach((item) => {
- let graphic;
- if (['rectangle', 'polygon', 'anyLine'].includes(item.type)) {
- graphic = this.createPolygon(item);
- graphic.set('id', item.id);
- res.push(graphic);
- } else if (item.type === 'circle') {
- graphic = this.createCircle(item);
- graphic.set('id', item.id);
- res.push(graphic);
- } else if (item.type === 'straightLine') {
- graphic = this.createLineString(item);
- graphic.set('id', item.id);
- res.push(graphic);
- } else if (item.type === 'text') {
- const { text } = this.addText(item);
- res.push(text);
- } else if (item.type === 'measureArea') {
- graphic = this.createPolygon(item);
- graphic.set('id', item.id);
- const style = new Style({
- stroke: new Stroke({
- color: rgbToRgba(item.strokeColor, item.strokeOpacity),
- width: item.strokeWeight
- }),
- fill: new Fill({
- color: rgbToRgba(item.fillColor, item.fillOpacity)
- }),
- text: new Text({
- text: '区域面积' + item.area.toFixed(2) + '平方米',
- font: '14px Calibri,sans-serif',
- fill: new Fill({ color: '#000' }),
- stroke: new Stroke({
- color: '#fff',
- width: 3
- }),
- overflow: true
- })
- });
- graphic.setStyle(style);
- res.push(graphic);
- } else if (item.type === 'marker') {
- // 创建标注点
- const marker = new Feature({
- // 必须是数字类型,字符串不识别
- geometry: new Point([item.longitude, item.latitude]),
- // name: item.name,
- // icon: item.icon,
- // imageHover: item.imageHover,
- // size: item.size,
- pointer: true
- });
- marker.set('id', item.id);
- const img = new Image();
- img.onload = () => {
- // 图片加载完成后,可以访问其 width 和 height 属性
- const width = img.width;
- const height = img.height;
- const style = new Style({
- image: new Icon({
- anchor: [0.5, 1],
- src: item.icon,
- size: [width, height],
- scale: !!item.size[0] ? item.size[0] / width : 1
- }),
- text: new Text({
- text: item.name,
- fill: new Fill({
- color: '#000'
- }),
- stroke: new Stroke({
- color: '#fff',
- width: 3
- })
- })
- });
- marker.setStyle(style);
- };
- img.src = item.icon; // 设置图片的 URL,触发加载
- this.drawVector.getSource().addFeature(marker);
- res.push(marker);
- }
- });
- return res;
- }
- getVectorLayer() {
- return this.vectorLayer;
- }
- getDrawVector() {
- return this.drawVector;
- }
- getMap() {
- return this.map;
- }
- getScale() {
- return this.scale;
- }
- getMouseTool() {
- return this.drawTool;
- }
- setDrawEndMethod(newMethod) {
- this.drawEndMethod = newMethod;
- }
- }
|