| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- import * as KMap from "@/utils/ol-map/KMap";
- import * as util from "@/common/ol_common.js";
- import config from "@/api/config.js";
- import StaticImgLayer from "@/utils/ol-map/StaticImgLayer";
- import Style from "ol/style/Style";
- import Icon from "ol/style/Icon";
- import Fill from "ol/style/Fill";
- import Stroke from "ol/style/Stroke";
- import { Point, Polygon } from "ol/geom";
- import Feature from "ol/Feature";
- import Overlay from "ol/Overlay";
- import WKT from "ol/format/WKT.js";
- import { reactive } from "vue";
- export let mapLocation = reactive({
- data: null,
- });
- /** 无范围时中心示意方框边长(米) */
- const NO_RANGE_SIDE_METERS = 280;
- /**
- * @description 地图层对象
- */
- class IndexMap {
- constructor() {
- let that = this;
- let vectorStyle = new KMap.VectorStyle();
- this.vectorStyle = vectorStyle;
- this.noRangeTipOverlay = null;
- this.remoteImageLayer = null;
- // 位置图标
- this.clickPointLayer = new KMap.VectorLayer("clickPointLayer", 9999, {
- style: (f) => {
- return new Style({
- image: new Icon({
- src: require("@/assets/img/home/garden-point.png"),
- scale: 0.5,
- }),
- });
- },
- });
- // 无勾画范围:中心点示意正方形
- this.noRangeGuideLayer = new KMap.VectorLayer("noRangeGuideLayer", 9998, {
- style: () =>
- new Style({
- fill: new Fill({ color: "rgba(0, 0, 0, 0.28)" }),
- stroke: new Stroke({
- color: "rgba(255, 255, 255, 0.95)",
- width: 1.5,
- lineDash: [6, 4],
- }),
- }),
- });
- }
- /** 叠加静态风险底图(与 demo growthReportMap.showRemoteImage 一致) */
- showRemoteImage(url, extent, options = {}) {
- this.hideRemoteImage();
- if (!url || !extent?.length || !this.kmap) return;
- this.remoteImageLayer = new StaticImgLayer(
- url,
- {
- extent,
- minZoom: 6,
- maxZoom: 22,
- opacity: options.opacity ?? 0.5,
- },
- 50,
- this.kmap,
- );
- }
- hideRemoteImage() {
- if (this.remoteImageLayer?.layer && this.kmap?.map) {
- this.kmap.map.removeLayer(this.remoteImageLayer.layer);
- }
- this.remoteImageLayer = null;
- }
- initMap(location, target) {
- let level = 16;
- let coordinate = util.wktCastGeom(location).getFirstCoordinate();
- this.kmap = new KMap.Map(target, level, coordinate[0], coordinate[1], null, 8, 22);
- let xyz2 = config.base_img_url3 + "map/lby/{z}/{x}/{y}.png";
- this.kmap.addXYZLayer(xyz2, { minZoom: 8, maxZoom: 22 }, 2);
- this.kmap.addLayer(this.noRangeGuideLayer.layer);
- this.kmap.addLayer(this.clickPointLayer.layer);
- this.setMapPoint(coordinate)
- // this.addMapSingerClick()
- }
- setMapPosition(center) {
- this.kmap.getView().animate({
- center,
- zoom: 16,
- duration: 0,
- });
- this.setMapPoint(center)
- }
- setMapPoint(coordinate) {
- this.clickPointLayer.source.clear()
- let point = new Feature(new Point(coordinate))
- this.clickPointLayer.addFeature(point)
- mapLocation.data = coordinate
- // 示意框跟着中心点走
- if (this.noRangeGuideLayer?.source?.getFeatures?.()?.length) {
- this.drawNoRangeSquare(coordinate);
- this.updateNoRangeTipPosition(coordinate);
- }
- }
- /** 以中心点生成正方形环坐标(EPSG:4326) */
- buildSquareRing(center, sideLengthMeters = NO_RANGE_SIDE_METERS) {
- const lng = Number(center[0]);
- const lat = Number(center[1]);
- const half = sideLengthMeters / 2;
- const latDelta = half / 111000;
- const lngDelta = half / (111000 * Math.cos((lat * Math.PI) / 180));
- return [
- [lng - lngDelta, lat + latDelta],
- [lng + lngDelta, lat + latDelta],
- [lng + lngDelta, lat - latDelta],
- [lng - lngDelta, lat - latDelta],
- [lng - lngDelta, lat + latDelta],
- ];
- }
- drawNoRangeSquare(coordinate) {
- if (!this.noRangeGuideLayer?.source || !coordinate?.length) return;
- this.noRangeGuideLayer.source.clear();
- const ring = this.buildSquareRing(coordinate);
- const feature = new Feature(new Polygon([ring]));
- this.noRangeGuideLayer.addFeature(feature);
- }
- updateNoRangeTipPosition(coordinate) {
- if (!this.noRangeTipOverlay || !coordinate?.length) return;
- const ring = this.buildSquareRing(coordinate);
- // 方框底边中点略偏下,提示贴在方框下方
- const tipCoord = [(ring[2][0] + ring[3][0]) / 2, ring[2][1] - (ring[0][1] - ring[2][1]) * 0.08];
- this.noRangeTipOverlay.setPosition(tipCoord);
- }
- /** 无范围引导:中心示意方框 + 下方提示 Overlay */
- showNoRangeGuide(coordinate, tipEl) {
- if (!this.kmap?.map || !coordinate?.length) return;
- this.drawNoRangeSquare(coordinate);
- if (tipEl) {
- if (!this.noRangeTipOverlay) {
- this.noRangeTipOverlay = new Overlay({
- element: tipEl,
- positioning: "top-center",
- offset: [0, 10],
- stopEvent: true,
- });
- this.kmap.map.addOverlay(this.noRangeTipOverlay);
- } else if (this.noRangeTipOverlay.getElement() !== tipEl) {
- this.noRangeTipOverlay.setElement(tipEl);
- }
- this.updateNoRangeTipPosition(coordinate);
- }
- }
- clearNoRangeGuide() {
- this.noRangeGuideLayer?.source?.clear?.();
- if (this.noRangeTipOverlay) {
- this.noRangeTipOverlay.setPosition(undefined);
- }
- }
- /** 当前地图点位(优先标记点,其次视图中心) */
- getCurrentCoordinate() {
- const features = this.clickPointLayer?.source?.getFeatures?.() || [];
- if (features.length) {
- return features[0].getGeometry()?.getCoordinates?.();
- }
- return this.kmap?.getView?.()?.getCenter?.() || mapLocation.data || null;
- }
- toPointWkt(coordinate) {
- if (!coordinate?.length) return null;
- return `POINT(${Number(coordinate[0])} ${Number(coordinate[1])})`;
- }
- // 地图点击事件
- addMapSingerClick() {
- let that = this;
- that.kmap.on("singleclick", (evt) => {
- // that.kmap.map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
- // if ( layer instanceof VectorLayer && layer.get("name") === "reportPolygonLayer" ) {
- // areaId.data = feature.get("id")
- // }
- // });
- that.setMapPoint(evt.coordinate)
- mapLocation.data = evt.coordinate
- });
- }
- clearLayer() {
- // this.kmap.removeLayer(this.clickPointLayer.layer)
- this.kmap.polygonLayer.source.clear();
- }
- createFarmPolygonStyle() {
- return new Style({
- fill: new Fill({
- color: "rgba(19, 162, 127, 0.25)",
- }),
- stroke: new Stroke({
- color: "#13a27f",
- width: 2,
- }),
- });
- }
- setAreaGeometry(geometryArr) {
- this.clearLayer();
- const format = new WKT();
- const mapProjection = this.kmap.map.getView().getProjection();
- geometryArr.forEach((item) => {
- const geometry = format.readGeometry(item, {
- dataProjection: "EPSG:4326",
- featureProjection: mapProjection,
- });
- const feature = new Feature({ geometry });
- feature.setStyle(this.createFarmPolygonStyle());
- this.kmap.polygonLayer.source.addFeature(feature);
- });
- this.scheduleFitView();
- }
- fitView(options = {}) {
- const map = this.kmap?.map;
- if (!map) return;
- map.updateSize();
- const extent = this.kmap.polygonLayer.source.getExtent();
- if (!extent || !isFinite(extent[0])) return;
- map.getView().fit(extent, {
- duration: options.duration ?? 0,
- padding: options.padding ?? [120, 48, 48, 48],
- maxZoom: options.maxZoom ?? 18,
- });
- }
- scheduleFitView(options = {}) {
- const run = () => this.fitView(options);
- requestAnimationFrame(() => {
- setTimeout(run, 50);
- });
- }
- }
- export default IndexMap;
|