gisviewer-vue3-arcgis
Version:
在应用中引入私服的包, 项目根目录下 新建文件 .npmrc 在 .npmrc 中对包源进行配置:
454 lines (453 loc) • 15.7 kB
JavaScript
import k from "ol/format/GeoJSON";
import x from "ol/layer/Image";
import p from "ol/layer/Tile";
import w from "ol/layer/Vector";
import g from "ol/Map";
import "ol/ol.css";
import { Projection as C } from "ol/proj";
import { ImageWMS as d, WMTS as S, TileWMS as M, XYZ as b } from "ol/source";
import A from "ol/source/Vector";
import { TileGrid as I } from "ol/tilegrid";
import L from "ol/tilegrid/WMTS";
import V from "ol/View";
import { getLineStyle as F } from "./style/line-style.mjs";
import { getPointStyle as z } from "./style/point-style.mjs";
import { getPolygonStyle as P } from "./style/polygon-style.mjs";
class J {
constructor() {
this.mapConfig = {}, this.pointerMoveRaf = null, this.isCursorCrosshair = !1, this.coordinateClickCallback = null, this.clickListeners = [];
}
subscribeClick(e, t = {}) {
const o = {
listener: e,
triggerOnBlankClick: t.triggerOnBlankClick ?? !1
};
return this.clickListeners.push(o), () => {
const i = this.clickListeners.indexOf(o);
i >= 0 && this.clickListeners.splice(i, 1);
};
}
/** 统一派发给所有监听者 */
emitFeatureClick(e, t, o, i) {
var n;
(n = this.markerClick) == null || n.call(this, e, t, o, i);
for (const { listener: c } of this.clickListeners)
c(e, t, o, i);
}
/** 点击地图空白处时,仅派发给需要此事件的监听者 */
emitBlankClick(e) {
for (const { listener: t, triggerOnBlankClick: o } of this.clickListeners)
o && t("map-blank", "", null, e);
}
initialize(e) {
return this.mapConfig = e.mapConfig || {}, this.markerClick = e.markerClickCallback, this.mapClick = e.mapClickCallback, this.map = this.createMap(e.container), this.mapConfig.baseLayers && this.loadLayers(this.mapConfig.baseLayers), this.map;
}
processUrl(e) {
return e && (e.startsWith("http://") || e.startsWith("https://") ? e : e.startsWith("{{") ? e.replace("{{geoServer}}", this.mapConfig.geoServer) : e);
}
getRendererSymbol(e, t) {
var c, a;
if (((c = e == null ? void 0 : e.type) == null ? void 0 : c.toLowerCase()) !== "unique-value")
return e == null ? void 0 : e.symbol;
const i = [e.field, e.field2, e.field3].filter(
Boolean
).map((s) => String((t == null ? void 0 : t[s]) ?? "")).join(e.fieldDelimiter ?? ","), n = (a = e.uniqueValueInfos) == null ? void 0 : a.find(
(s) => String(s.value) === i || Array.isArray(s.value) && s.value.map(String).join(e.fieldDelimiter ?? ",") === i
);
return (n == null ? void 0 : n.symbol) ?? e.defaultSymbol;
}
loadLayers(e) {
if (!this.map)
return;
const t = 1 / 0, o = 16384;
e.forEach((i) => {
var c, a;
(c = i.source) != null && c.url && (i.source.url = this.processUrl(i.source.url));
let n;
switch (i.type.toLowerCase()) {
case "webtile": {
if (n = new p({
preload: t,
cacheSize: o,
source: new b({
url: i.source.url,
projection: i.source.projection,
tileSize: i.source.tileSize,
minZoom: i.source.minZoom,
maxZoom: i.source.maxZoom
// crossOrigin: layerConfig.source.crossOrigin || 'anonymous'
}),
...i.options
}), i.source.canvasFilter) {
const s = i.source.canvasFilter;
n.on("prerender", (r) => {
r.context && (r.context.filter = s);
}), n.on("postrender", (r) => {
r.context && (r.context.filter = "none");
});
}
break;
}
case "gwc-wms": {
if (n = new p({
preload: t,
cacheSize: o,
source: new M({
...i.source,
tileGrid: new I({
...i.source.tileGrid
})
}),
...i.options
}), i.source.canvasFilter) {
const s = i.source.canvasFilter;
n.on("prerender", (r) => {
r.context && (r.context.filter = s);
}), n.on("postrender", (r) => {
r.context && (r.context.filter = "none");
});
}
break;
}
case "wmts": {
const s = i.source.matrixSet || "", r = Array.from(
{ length: 22 },
(l, m) => `${s}:${m}`
);
n = new p({
preload: t,
cacheSize: o,
source: new S({
...i.source,
format: "image/png",
projection: new C({
code: i.source.projection || "EPSG:4326"
}),
tileGrid: new L({
resolutions: [
1.4078260157100582,
0.703913007855028,
0.35195650392751515,
0.17597825196375638,
0.08798912598187819,
0.043994562990939096,
0.021997281495469548,
0.010998640747734774,
0.005499320373868577,
0.0027496601869330985,
0.001374830093467739,
6874150467326798e-19,
3437075233663399e-19,
17185376168316996e-20,
8592688084158498e-20,
4296344042198222e-20,
2148172021099111e-20,
10740860104305824e-21,
53704300533426425e-22,
2685215025481591e-21,
13426075127407955e-22,
6713037563703978e-22
],
matrixIds: r,
tileSize: 256,
origin: [-400, 400]
})
}),
...i.options
});
break;
}
case "image-wms": {
n = new x({
source: new d({ ...i.source }),
...i.options
});
break;
}
case "geojson": {
const { renderer: s, ...r } = i.options ?? {}, l = i.renderer ?? s;
n = new w({
source: new A({
url: i.source.url,
format: new k()
}),
...r,
style: l ? (m) => {
var y;
const h = (y = m.getGeometry()) == null ? void 0 : y.getType(), u = m.getProperties(), f = this.getRendererSymbol(
l,
u
);
if (f)
switch (h) {
case "Point":
case "MultiPoint":
return z(f, u);
case "LineString":
case "MultiLineString":
return F(f, u);
case "Polygon":
case "MultiPolygon":
return P(
f,
u,
() => n.changed()
);
default:
return;
}
} : void 0
});
break;
}
}
n && (n.set("id", i.id), n.set("group", i.group), (a = this.map) == null || a.addLayer(n));
});
}
createMap(e) {
const t = this.mapConfig.view, o = { ...t };
this.mapView = new V(o), this.mapConfig.camera ? this.mapConfig.camera.home = t : this.mapConfig.camera = {
home: t
};
const i = new g({
target: e,
view: this.mapView
});
return Array.isArray(t.extent) && t.extent.length === 4 && this.mapView.fit(t.extent, {
size: i.getSize(),
padding: [20, 20, 20, 20],
duration: 0
}), i.on("pointermove", (n) => {
n.dragging || this.pointerMoveRaf === null && (this.pointerMoveRaf = requestAnimationFrame(() => {
if (this.isCursorCrosshair) {
this.pointerMoveRaf = null;
return;
}
const c = i.hasFeatureAtPixel(n.pixel), a = i.getTargetElement();
a && (a.style.cursor = c ? "pointer" : ""), this.pointerMoveRaf = null;
}));
}), i.on("click", (n) => {
var a;
this.coordinateClickCallback && this.coordinateClickCallback(n.coordinate, n.pixel, n), (a = this.mapClick) == null || a.call(this, n.coordinate, n.pixel, n);
const c = i.forEachFeatureAtPixel(n.pixel, (s) => s);
if (c) {
const s = c.get("type") ?? "", r = c.get("id") ?? "", l = c.getProperties();
this.emitFeatureClick(s, r, l, n);
} else
this.emitBlankClick(n), this.queryImageWMSFeatureInfo(n);
}), i;
}
/**
* 查询 ImageWMS 图层的要素信息
* @param evt 点击事件
*/
async queryImageWMSFeatureInfo(e) {
var i;
if (!this.map || !this.markerClick)
return;
const t = this.mapView.getResolution();
if (!t)
return;
const o = this.map.getLayers().getArray();
for (const n of o) {
if (!(n instanceof x) || !n.getVisible())
continue;
const c = n.getSource();
if (!(c instanceof d))
continue;
const a = c.getFeatureInfoUrl(
e.coordinate,
t,
this.mapView.getProjection() || "EPSG:4326",
{ INFO_FORMAT: "application/json" }
);
if (a)
try {
const r = await (await fetch(a)).json();
if (r.features && r.features.length > 0) {
const l = r.features[0], m = n.get("id") || "", h = ((i = l.geometry) == null ? void 0 : i.type) || "wms-feature", u = l.id || "", f = {
...l.properties,
layerId: m,
geometry: l.geometry
};
this.markerClick(h, u, f, e);
return;
}
} catch (s) {
console.warn("GetFeatureInfo 请求失败:", s);
}
}
}
/**
* 设置地图中心点和缩放级别
* @param params
* @returns
*/
async setMapCenter(e) {
if (!this.map)
return { status: -1, message: "地图未初始化" };
let t, o;
if (e.target) {
const n = this.parseArcGISGeometry(e.target);
t = n.center, o = n.extent;
}
const i = e.center || t || this.mapView.getCenter();
return new Promise((n) => {
if (o && !e.center) {
this.mapView.fit(o, {
duration: e.duration ? e.duration * 1e3 : 0,
callback: () => {
n({ status: 0, message: "成功" });
}
});
return;
}
e.duration && e.duration > 0 ? this.mapView.animate(
{
center: i,
zoom: e.zoom || this.mapView.getZoom(),
duration: e.duration * 1e3
},
() => {
n({ status: 0, message: "成功" });
}
) : (e.zoom && this.mapView.setZoom(e.zoom), this.mapView.setCenter(i), n({ status: 0, message: "成功" }));
});
}
/**
* 解析 ArcGIS API geometry 格式
* @param target ArcGIS geometry 对象
* @returns 中心点和范围
*/
parseArcGISGeometry(e) {
if (!e)
return {};
if (Array.isArray(e)) {
if (e.length === 2 && typeof e[0] == "number")
return { center: e };
if (e.length > 0 && e[0].x !== void 0)
return { center: [e[0].x, e[0].y] };
}
if (e.type === "point" || e.x !== void 0 && e.y !== void 0)
return { center: [e.x, e.y] };
if (e.type === "extent" || e.xmin !== void 0 && e.xmax !== void 0) {
const t = [e.xmin, e.ymin, e.xmax, e.ymax];
return { center: [
(e.xmin + e.xmax) / 2,
(e.ymin + e.ymax) / 2
], extent: t };
}
if (e.type === "multipoint" || e.points && Array.isArray(e.points)) {
const t = this.calculateExtentFromPoints(e.points);
if (t)
return { center: [
(t[0] + t[2]) / 2,
(t[1] + t[3]) / 2
], extent: t };
}
if (e.extent) {
const t = e.extent, o = [t.xmin, t.ymin, t.xmax, t.ymax];
return { center: [(t.xmin + t.xmax) / 2, (t.ymin + t.ymax) / 2], extent: o };
}
if (e.paths && Array.isArray(e.paths)) {
const t = this.calculateExtentFromCoordinates(e.paths);
if (t)
return { center: [
(t[0] + t[2]) / 2,
(t[1] + t[3]) / 2
], extent: t };
}
if (e.rings && Array.isArray(e.rings)) {
const t = this.calculateExtentFromCoordinates(e.rings);
if (t)
return { center: [
(t[0] + t[2]) / 2,
(t[1] + t[3]) / 2
], extent: t };
}
if (e.geometry)
return this.parseArcGISGeometry(e.geometry);
if (e.center) {
if (Array.isArray(e.center))
return { center: e.center };
if (e.center.x !== void 0)
return { center: [e.center.x, e.center.y] };
}
return {};
}
/**
* 从 paths 或 rings 坐标数组计算 extent
* @param coordinateArrays paths 或 rings 数组,格式为 [[[x, y], [x, y], ...], ...]
* @returns [xmin, ymin, xmax, ymax] 或 null
*/
calculateExtentFromCoordinates(e) {
let t = 1 / 0, o = 1 / 0, i = -1 / 0, n = -1 / 0, c = !1;
for (const a of e)
if (Array.isArray(a)) {
for (const s of a)
if (Array.isArray(s) && s.length >= 2) {
const [r, l] = s;
typeof r == "number" && typeof l == "number" && (t = Math.min(t, r), o = Math.min(o, l), i = Math.max(i, r), n = Math.max(n, l), c = !0);
}
}
return c ? [t, o, i, n] : null;
}
/**
* 从 points 坐标数组计算 extent(用于 Multipoint)
* @param points 点数组,格式为 [[x, y], [x, y], ...]
* @returns [xmin, ymin, xmax, ymax] 或 null
*/
calculateExtentFromPoints(e) {
if (!Array.isArray(e) || e.length === 0)
return null;
let t = 1 / 0, o = 1 / 0, i = -1 / 0, n = -1 / 0, c = !1;
for (const a of e)
if (Array.isArray(a) && a.length >= 2) {
const [s, r] = a;
typeof s == "number" && typeof r == "number" && (t = Math.min(t, s), o = Math.min(o, r), i = Math.max(i, s), n = Math.max(n, r), c = !0);
}
return c ? [t, o, i, n] : null;
}
setMapZoom(e) {
if (!this.map)
return { status: -1, message: "地图未初始化" };
const t = this.mapView.getMinZoom(), o = this.mapView.getMaxZoom(), i = Math.max(t, Math.min(o, e.zoom));
return this.mapView.setZoom(i), { status: 0, message: "成功" };
}
/**
* 设置地图预存的相机视图
* @param params
* @returns
*/
async setMapCamera(e) {
if (!this.map)
return { status: -1, message: "地图未初始化" };
const t = this.mapConfig.camera[e.name];
return t ? await this.setMapCenter({
center: t.center,
zoom: e.zoom || t.zoom,
duration: e.duration || 0
}) : { status: -1, message: `未找到名称为 ${e.name} 的相机视图` };
}
async setLayerVisibility(e) {
const t = this.map.getLayers().getArray().filter((o) => o.get("id") === e.id || o.get("group") === e.id);
return t.length > 0 ? (t.forEach((o) => o.setVisible(e.visible)), { status: 0, message: "成功" }) : { status: -1, message: `未找到ID为 ${e.id} 的图层` };
}
/**
* 注册地图点击事件,并返回取消注册的函数
* @param params
* @returns
*/
getClickCoordinates(e) {
if (!this.map)
return console.warn("地图未初始化,无法注册点击事件"), () => {
};
const { changeCursor: t = !0, callback: o } = e, i = this.map.getTargetElement();
return t && i && (this.isCursorCrosshair = !0, i.style.cursor = "crosshair"), this.coordinateClickCallback = o, () => {
this.coordinateClickCallback = null, t && i && (this.isCursorCrosshair = !1, i.style.cursor = "");
};
}
}
export {
J as default
};