mirror of
https://github.com/morgan9e/KorailMap
synced 2026-04-14 00:14:06 +09:00
init
This commit is contained in:
772
static/ol-helper.js
Normal file
772
static/ol-helper.js
Normal file
@@ -0,0 +1,772 @@
|
||||
/**
|
||||
* Openlayers Map
|
||||
* author: khy
|
||||
* date: 23.09.07
|
||||
* */
|
||||
|
||||
const proj = {
|
||||
viewProjection: "EPSG:3857",
|
||||
WGS84Projection: "EPSG:4326",
|
||||
};
|
||||
Object.freeze(proj);
|
||||
Array.prototype.toWGS84 = function () {
|
||||
if (this.length === 2) {
|
||||
//coordinate
|
||||
return ol.proj.transform(this, proj.viewProjection, proj.WGS84Projection);
|
||||
} else if (this.length === 4) {
|
||||
//extent
|
||||
return ol.proj.transformExtent(this, proj.viewProjection, proj.WGS84Projection);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
Array.prototype.toEPSG3857 = function () {
|
||||
if (this.length === 2) {
|
||||
//coordinate
|
||||
return ol.proj.transform(this, proj.WGS84Projection, proj.viewProjection);
|
||||
} else if (this.length === 4) {
|
||||
//extent
|
||||
return ol.proj.transformExtent(this, proj.WGS84Projection, proj.viewProjection);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
ol.Map.prototype.getProxyURL = function (url) {
|
||||
return `${document.location.protocol}//${document.location.host}/proxy/?${url ? url : ""}`;
|
||||
};
|
||||
|
||||
ol.Map.prototype.addBaseTileLayer = function (options) {
|
||||
let host = 'gis.korail.com';
|
||||
function createBaseTileLayer(map) {
|
||||
const proxy = map.getProxyURL();
|
||||
const base = new ol.layer.Tile({
|
||||
name: "base",
|
||||
source: new ol.source.XYZ({
|
||||
tileUrlFunction: (zxy) => {
|
||||
const [z, x, y] = zxy;
|
||||
if (z < 5 || z > 15) {
|
||||
return;
|
||||
}
|
||||
return `https://${host}/tilemap/background/${z}/${x}/${y}.png`;
|
||||
},
|
||||
minZoom: 5,
|
||||
maxZoom: 15,
|
||||
}),
|
||||
zIndex: 0,
|
||||
});
|
||||
|
||||
if (options === "korean") {
|
||||
const label = new ol.layer.Tile({
|
||||
name: "base-label",
|
||||
source: new ol.source.XYZ({
|
||||
tileUrlFunction: (zxy) => {
|
||||
const [z, x, y] = zxy;
|
||||
if (z < 5 || z > 15) {
|
||||
return;
|
||||
}
|
||||
return `https://${host}/tilemap/korean/${z}/${x}/${y}.png`;
|
||||
},
|
||||
minZoom: 5,
|
||||
maxZoom: 15,
|
||||
}),
|
||||
zIndex: 0,
|
||||
});
|
||||
|
||||
const layergroup = new ol.layer.Group({
|
||||
layers: [base, label],
|
||||
});
|
||||
return layergroup;
|
||||
} else {
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
const layer = createBaseTileLayer(this);
|
||||
this.addLayer(layer);
|
||||
|
||||
return layer;
|
||||
};
|
||||
ol.Map.prototype.createBaseLayerButton = function () {
|
||||
const mapElement = this.getTargetElement();
|
||||
|
||||
if (!mapElement.querySelector("button[usage=base]")) {
|
||||
const toggleButton = document.createElement("button");
|
||||
toggleButton.setAttribute("usage", "base");
|
||||
toggleButton.textContent = "";
|
||||
toggleButton.style.position = "absolute";
|
||||
toggleButton.style.top = "0px";
|
||||
toggleButton.style.left = "0px";
|
||||
toggleButton.style.margin = "10px";
|
||||
toggleButton.style.marginLeft = "42px";
|
||||
toggleButton.style.width = "30px";
|
||||
toggleButton.style.height = "30px";
|
||||
toggleButton.style.borderRadius = "50%";
|
||||
toggleButton.style.border = "1px solid gray";
|
||||
toggleButton.style.background = "white";
|
||||
toggleButton.style.color = "black";
|
||||
toggleButton.style.textAlign = "center";
|
||||
|
||||
let status = false;
|
||||
|
||||
const toggleLayer = () => {
|
||||
this.getAllLayers()
|
||||
.filter((l) => l.get("name") !== "base" && l.get("name") !== "base-label" && l.get("name") !== "grid-tile")
|
||||
.forEach((l) => {
|
||||
l.setVisible(status);
|
||||
});
|
||||
|
||||
status = !status;
|
||||
|
||||
toggleButton.style.background = status ? "dodgerblue" : "white";
|
||||
toggleButton.style.color = status ? "white" : "black";
|
||||
|
||||
if (status) {
|
||||
viewChange(null, null);
|
||||
map.getView().setConstrainResolution(true);
|
||||
} else {
|
||||
map.getView().setConstrainResolution(false);
|
||||
viewChange(0, document.querySelector("ul.notice > li"));
|
||||
}
|
||||
};
|
||||
toggleButton.onclick = toggleLayer;
|
||||
|
||||
let zoomLevel = undefined;
|
||||
this.on("moveend", (view) => {
|
||||
const nowZoomLevel = Number(this.getView().getZoom().toFixed());
|
||||
if (zoomLevel !== nowZoomLevel) {
|
||||
zoomLevel = nowZoomLevel;
|
||||
toggleButton.textContent = zoomLevel;
|
||||
}
|
||||
});
|
||||
|
||||
mapElement.appendChild(toggleButton);
|
||||
}
|
||||
};
|
||||
|
||||
ol.Map.prototype.createGridTiles = function () {
|
||||
const mapElement = this.getTargetElement();
|
||||
|
||||
if (!mapElement.querySelector("button[usage=grid-tile]")) {
|
||||
const toggleButton = document.createElement("button");
|
||||
toggleButton.setAttribute("usage", "grid-tile");
|
||||
toggleButton.textContent = "#";
|
||||
toggleButton.style.position = "absolute";
|
||||
toggleButton.style.top = "0px";
|
||||
toggleButton.style.left = "0px";
|
||||
toggleButton.style.margin = "10px";
|
||||
toggleButton.style.width = "30px";
|
||||
toggleButton.style.height = "30px";
|
||||
toggleButton.style.borderRadius = "50%";
|
||||
toggleButton.style.border = "1px solid gray";
|
||||
toggleButton.style.background = "white";
|
||||
toggleButton.style.color = "black";
|
||||
toggleButton.style.textAlign = "center";
|
||||
|
||||
const toggleLayer = () => {
|
||||
const layer = this.getLayer("grid-tile");
|
||||
|
||||
if (layer) {
|
||||
const currentVisible = layer.getVisible();
|
||||
const postVisible = !currentVisible;
|
||||
|
||||
this.getAllLayers()
|
||||
.filter((l) => l.get("name") !== "base" && l.get("name") !== "base-label" && l.get("name") !== "grid-tile")
|
||||
.forEach((l) => {
|
||||
l.setVisible(currentVisible);
|
||||
});
|
||||
|
||||
layer.setVisible(postVisible);
|
||||
|
||||
toggleButton.style.background = postVisible ? "dodgerblue" : "white";
|
||||
toggleButton.style.color = postVisible ? "white" : "black";
|
||||
|
||||
if (postVisible) {
|
||||
viewChange(null, null);
|
||||
} else {
|
||||
viewChange(0, document.querySelector("ul.notice > li"));
|
||||
}
|
||||
}
|
||||
};
|
||||
toggleButton.onclick = toggleLayer;
|
||||
|
||||
mapElement.appendChild(toggleButton);
|
||||
}
|
||||
|
||||
if (!this.getLayer("grid-tile")) {
|
||||
const tileSize = 256;
|
||||
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = tileSize;
|
||||
canvas.height = tileSize;
|
||||
|
||||
const context = canvas.getContext("2d");
|
||||
context.strokeStyle = "gray";
|
||||
context.textAlign = "center";
|
||||
const lineHeight = 30;
|
||||
context.font = `${lineHeight - 6}px sans-serif`;
|
||||
|
||||
const layer = new ol.layer.WebGLTile({
|
||||
name: "grid-tile",
|
||||
source: new ol.source.DataTile({
|
||||
loader: (z, x, y) => {
|
||||
const half = tileSize / 2;
|
||||
|
||||
context.clearRect(0, 0, tileSize, tileSize);
|
||||
// context.fillStyle = 'rgba(255, 255, 255, 0.7)';
|
||||
// context.fillRect(0, 0, tileSize, tileSize);
|
||||
|
||||
context.fillStyle = "black";
|
||||
context.fillText(`z: ${z}`, half, half - lineHeight);
|
||||
context.fillText(`x: ${x}`, half, half);
|
||||
context.fillText(`y: ${y}`, half, half + lineHeight);
|
||||
|
||||
context.strokeRect(0, 0, tileSize, tileSize);
|
||||
|
||||
const data = context.getImageData(0, 0, tileSize, tileSize).data;
|
||||
|
||||
return new Uint8Array(data.buffer);
|
||||
},
|
||||
}),
|
||||
zIndex: 999,
|
||||
});
|
||||
|
||||
layer.setVisible(false);
|
||||
|
||||
this.addLayer(layer);
|
||||
}
|
||||
};
|
||||
|
||||
ol.source.Vector.fromGeoJSON = function (geojson) {
|
||||
return new ol.source.Vector({
|
||||
features: new ol.format.GeoJSON().readFeatures(geojson, { featureProjection: proj.viewProjection }),
|
||||
format: new ol.format.GeoJSON(),
|
||||
strategy: ol.loadingstrategy.bbox,
|
||||
});
|
||||
};
|
||||
|
||||
ol.Map.prototype.addRegionalLayer = async function () {
|
||||
const regional_lines = new Array(8);
|
||||
|
||||
async function createRegionalLine(url, index) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
const json = await response.json();
|
||||
insertLine(json, index);
|
||||
resolve();
|
||||
} catch {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 권역 라인이 포인트 형식으로 되어있어서 라인형식으로 바꾸고 데이터 교체하는 함수
|
||||
function insertLine(json, i) {
|
||||
const coordinates = json.features.map((point) => {
|
||||
const converted = point.geometry.coordinates.toEPSG3857();
|
||||
return converted;
|
||||
});
|
||||
const geomLineString = new ol.geom.LineString(coordinates);
|
||||
const featureLineString = new ol.Feature({ geometry: geomLineString });
|
||||
regional_lines[i] = featureLineString;
|
||||
}
|
||||
|
||||
// $.getJOSN 으로 json 데이터 읽어 드리고 insertLine 은 현재 json 파일이 line 형식이 아닌 포인트
|
||||
// 형식으로
|
||||
// 만들었음
|
||||
// 포인트 형식을 만든 이유는 수정시 포인트 형식이 필요해서 우선 포인트 형식으로 저장
|
||||
|
||||
await Promise.all([
|
||||
createRegionalLine("resource/Regional_point_chungbuk.json", 0),
|
||||
createRegionalLine("resource/Regional_point_gang.json", 1),
|
||||
createRegionalLine("resource/Regional_point_seoul_east.json", 2),
|
||||
createRegionalLine("resource/Regional_point_seoul_west.json", 3),
|
||||
createRegionalLine("resource/Regional_point_daejeon_chungnam.json", 4),
|
||||
createRegionalLine("resource/Regional_point_jeonbuk.json", 5),
|
||||
createRegionalLine("resource/Regional_point_jeonnam.json", 6),
|
||||
createRegionalLine("resource/Regional_point_daegu.json", 7),
|
||||
]);
|
||||
|
||||
const regionalSource = new ol.source.Vector({
|
||||
features: regional_lines,
|
||||
});
|
||||
|
||||
this.addVectorLayer({
|
||||
name: "Regional_Line",
|
||||
source: regionalSource,
|
||||
style: layerStyles.regional,
|
||||
zIndex: 0,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* WebGL Layer
|
||||
* author: khy
|
||||
*/
|
||||
const canvas = document.createElement("canvas");
|
||||
const gl = canvas?.getContext("webgl") || canvas?.getContext("experimental-webgl");
|
||||
const webglAvailable = gl instanceof WebGLRenderingContext;
|
||||
|
||||
class WebGLVectorLayer extends ol.layer.Layer {
|
||||
constructor(params) {
|
||||
super(params);
|
||||
this.style = params.style;
|
||||
}
|
||||
createRenderer() {
|
||||
const style = this.style;
|
||||
|
||||
return new ol.renderer.webgl.VectorLayer(this, {
|
||||
style,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function VectorLayer(params) {
|
||||
return new ol.layer.Vector(params);
|
||||
//return (webglAvailable) ? new WebGLVectorLayer(params) : new ol.layer.Vector(params);
|
||||
}
|
||||
|
||||
function PointsLayer(params) {
|
||||
const hasStyleFunction = typeof params?.style === "function";
|
||||
|
||||
return (webglAvailable && !hasStyleFunction) ? new ol.layer.WebGLPoints(params) : new ol.layer.Vector(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* ol.Map prototype 확장
|
||||
* @param ...args
|
||||
* @returns
|
||||
*/
|
||||
ol.Map.prototype.addLayerWithType = async function (...args) {
|
||||
const LayerType = args[0];
|
||||
args = args[1];
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let url, fetchOption, layerOption;
|
||||
let response, geojson;
|
||||
|
||||
switch (args.length) {
|
||||
case 3:
|
||||
if (
|
||||
typeof args[0] === "string" && //fetch url
|
||||
typeof args[1] === "object" && //fetch option
|
||||
typeof args[2] === "object"
|
||||
) {
|
||||
//layer option
|
||||
(url = args[0]), (fetchOption = args[1]), (layerOption = args[2]);
|
||||
response = await fetch(url, fetchOption);
|
||||
geojson = await response.json();
|
||||
layerOption.source = await ol.source.Vector.fromGeoJSON(geojson);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (
|
||||
typeof args[0] === "string" && //fetch url
|
||||
typeof args[1] === "object"
|
||||
) {
|
||||
//layer option
|
||||
(url = args[0]), (layerOption = args[1]);
|
||||
|
||||
console.log(`addLayerWithType(${url})`, fetch);
|
||||
response = await fetch(url);
|
||||
geojson = await response.json();
|
||||
console.log(geojson);
|
||||
layerOption.source = await ol.source.Vector.fromGeoJSON(geojson);
|
||||
} else if (
|
||||
typeof args[0] === "object" && //layer option
|
||||
typeof args[1] === "object"
|
||||
) {
|
||||
//map object
|
||||
layerOption = args[0];
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
break;
|
||||
case 1: //layer option
|
||||
default:
|
||||
layerOption = args[0];
|
||||
}
|
||||
|
||||
if (layerOption.labelStyleFunction) {
|
||||
const layergroup = new ol.layer.Group({
|
||||
layers: [
|
||||
new LayerType({
|
||||
...layerOption,
|
||||
source: layerOption.source || new ol.source.Vector(),
|
||||
style: layerOption.style || ol.style.flat.createDefaultStyle(),
|
||||
}),
|
||||
new ol.layer.Vector({
|
||||
name: layerOption.name ? `${layerOption.name}_label` : "label",
|
||||
source: layerOption.source || new ol.source.Vector(),
|
||||
style: layerOption.labelStyleFunction,
|
||||
declutter: true,
|
||||
zIndex: layerOption.zIndex + 1,
|
||||
}),
|
||||
],
|
||||
});
|
||||
this.addLayer(layergroup);
|
||||
|
||||
resolve(layergroup);
|
||||
} else {
|
||||
const layer = new LayerType({
|
||||
...layerOption,
|
||||
source: layerOption.source || new ol.source.Vector(),
|
||||
style: layerOption.style || ol.style.flat.createDefaultStyle(),
|
||||
});
|
||||
|
||||
this.addLayer(layer);
|
||||
|
||||
resolve(layer);
|
||||
}
|
||||
} catch {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @author khy
|
||||
* @description WebGL벡터레이어나 일반벡터레이어를 생성하여 map객체에 addLayer()함
|
||||
* 전달인자를 1개, 2개, 3개를 줄 수 있음.
|
||||
* 전달인자 1개: layer option
|
||||
* 전달인자 2개: fetch url, layer option
|
||||
* 전달인자 3개: fetch url, fetch option, layer option
|
||||
* @param ...args
|
||||
* case (args0) Layer option
|
||||
* case (args0, args1) fetch url, layer option || layer option, map target
|
||||
* case (args0, args1, args2) fetch url, fetch option, layer option
|
||||
*/
|
||||
|
||||
/**
|
||||
* @returns
|
||||
* ol.layer.vector || WebGLVectorLayer
|
||||
*/
|
||||
ol.Map.prototype.addVectorLayer = async function (...args) {
|
||||
return new Promise(async (resolve) => {
|
||||
resolve(this.addLayerWithType(VectorLayer, args));
|
||||
});
|
||||
};
|
||||
ol.Map.prototype.addRailLayer = async function (...args) {
|
||||
return new Promise(async (resolve) => {
|
||||
resolve(this.addLayerWithType(ol.layer.Vector, args));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns
|
||||
* ol.layer.vector || ol.layer.WebGLPoints
|
||||
*/
|
||||
ol.Map.prototype.addPointsLayer = async function (...args) {
|
||||
return new Promise(async (resolve) => {
|
||||
resolve(this.addLayerWithType(PointsLayer, args));
|
||||
});
|
||||
};
|
||||
ol.Map.prototype.addNormalRailLayer = function (options) {
|
||||
return this.addVectorLayer(
|
||||
"resource/NormalLine.json",
|
||||
Object.assign(
|
||||
{
|
||||
name: "NormalLine",
|
||||
style: {
|
||||
"stroke-width": 2,
|
||||
},
|
||||
zIndex: 2,
|
||||
},
|
||||
options
|
||||
)
|
||||
);
|
||||
};
|
||||
ol.Map.prototype.addNormalStationLayer = function (options) {
|
||||
return this.addPointsLayer(
|
||||
"resource/NormalStation.json",
|
||||
Object.assign(
|
||||
{
|
||||
name: "NormalStation",
|
||||
style: {
|
||||
"circle-radius": 5,
|
||||
"circle-stroke-width": 3,
|
||||
"circle-fill-color": "gainsboro",
|
||||
},
|
||||
zIndex: 3,
|
||||
},
|
||||
options
|
||||
)
|
||||
);
|
||||
};
|
||||
ol.Map.prototype.addKTXRailLayer = function (options) {
|
||||
return this.addVectorLayer(
|
||||
"resource/KTXLine.json",
|
||||
Object.assign(
|
||||
{
|
||||
name: "KTXLine",
|
||||
style: {
|
||||
"stroke-color": "#005BAC",
|
||||
"stroke-width": 5,
|
||||
},
|
||||
zIndex: 1,
|
||||
},
|
||||
options
|
||||
)
|
||||
);
|
||||
};
|
||||
ol.Map.prototype.addKTXStationLayer = function (options) {
|
||||
return this.addPointsLayer(
|
||||
"resource/KTXStation.json",
|
||||
Object.assign(
|
||||
{
|
||||
name: "KTXStation",
|
||||
style: {
|
||||
"circle-radius": 7,
|
||||
"circle-stroke-color": "#005BAC",
|
||||
"circle-stroke-width": 3,
|
||||
"circle-fill-color": "gainsboro",
|
||||
},
|
||||
zIndex: 4,
|
||||
},
|
||||
options
|
||||
)
|
||||
);
|
||||
};
|
||||
ol.Map.prototype.addBaseRailLayer = function () {
|
||||
this.addNormalRailLayer();
|
||||
this.addKTXRailLayer();
|
||||
};
|
||||
ol.Map.prototype.addBaseStationLayer = function () {
|
||||
this.addNormalStationLayer();
|
||||
this.addKTXStationLayer();
|
||||
};
|
||||
|
||||
/*
|
||||
function removeLayer(layername) {
|
||||
getLayers(layername).forEach((layer) => {
|
||||
layer.dispose();
|
||||
map.removeLayer(layer);
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
||||
ol.Map.prototype.getLayer = function (layername) {
|
||||
return this.getLayers(layername)[0];
|
||||
};
|
||||
ol.Map.prototype.getLayers = function (layername) {
|
||||
return layername ? this.getAllLayers().filter((layer) => layer.get("name") === layername) : this.getLayerGroup().getLayers();
|
||||
};
|
||||
ol.Map.prototype.flyTo = function (params) {
|
||||
this.once("postrender", () => {
|
||||
this.flyToNow(params);
|
||||
});
|
||||
};
|
||||
ol.Map.prototype.flyToNow = function (params) {
|
||||
const convertedCenter = params.center.toEPSG3857();
|
||||
|
||||
const option = Object.assign(params, {
|
||||
center: convertedCenter,
|
||||
duration: 700,
|
||||
easing: ol.easing.easeOut,
|
||||
});
|
||||
this.getView().animate(option);
|
||||
};
|
||||
ol.Map.prototype.setVisibleLayer = function (layername, visible) {
|
||||
this.getLayers(layername).forEach((layer) => {
|
||||
layer.setVisible(visible);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Overlay
|
||||
* author: khy
|
||||
* date: 23.09.07
|
||||
* */
|
||||
ol.Map.prototype.createOverlay = function () {
|
||||
if (!document.getElementById("popup")) {
|
||||
const popupElement = document.createElement("div");
|
||||
popupElement.id = "popup";
|
||||
this.getTargetElement().appendChild(popupElement);
|
||||
}
|
||||
|
||||
const popup = new ol.Overlay({
|
||||
id: "popup",
|
||||
element: document.getElementById("popup"),
|
||||
autoPan: true
|
||||
});
|
||||
|
||||
this.addOverlay(popup);
|
||||
|
||||
return popup;
|
||||
};
|
||||
ol.Map.prototype.getOverlay = function () {
|
||||
const popup = this.getOverlayById("popup") || this.createOverlay();
|
||||
|
||||
return popup;
|
||||
};
|
||||
ol.Map.prototype.showOverlay = function () {
|
||||
this.getOverlay().element.style.display = null;
|
||||
};
|
||||
ol.Map.prototype.hideOverlay = function () {
|
||||
this.getOverlay().element.style.display = "none";
|
||||
};
|
||||
ol.Map.prototype.isShowingOverlay = function () {
|
||||
return (map.getOverlay().element.style.display !== "none")
|
||||
}
|
||||
|
||||
/**
|
||||
* Drag Interaction
|
||||
* author: khy
|
||||
* param
|
||||
* options : {
|
||||
* layerFilter: function(default=undefined),
|
||||
* hitTolerance: number(default=0),
|
||||
* checkWrapped: boolean(default=true),
|
||||
* }
|
||||
* usage
|
||||
* map.addInteraction(new Drag( options | null ));
|
||||
*
|
||||
*/
|
||||
class Drag extends ol.interaction.Pointer {
|
||||
constructor(options) {
|
||||
super({
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleMoveEvent: handleMoveEvent,
|
||||
handleUpEvent: handleUpEvent,
|
||||
});
|
||||
|
||||
this.options_ = options;
|
||||
|
||||
this.coordinate_ = null;
|
||||
this.cursor_ = "grabbing";
|
||||
this.feature_ = null;
|
||||
this.previousCursor_ = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function handleDownEvent(evt) {
|
||||
const map = evt.map;
|
||||
const feature = map.forEachFeatureAtPixel(evt.pixel, (feature) => feature, this.options_);
|
||||
|
||||
if (feature) {
|
||||
this.coordinate_ = evt.coordinate;
|
||||
this.feature_ = feature;
|
||||
}
|
||||
|
||||
return !!feature;
|
||||
}
|
||||
function handleDragEvent(evt) {
|
||||
const deltaX = evt.coordinate[0] - this.coordinate_[0];
|
||||
const deltaY = evt.coordinate[1] - this.coordinate_[1];
|
||||
|
||||
const geometry = this.feature_.getGeometry();
|
||||
geometry.translate(deltaX, deltaY);
|
||||
|
||||
this.coordinate_[0] = evt.coordinate[0];
|
||||
this.coordinate_[1] = evt.coordinate[1];
|
||||
}
|
||||
function handleMoveEvent(evt) {
|
||||
if (this.cursor_) {
|
||||
const map = evt.map;
|
||||
const feature = map.forEachFeatureAtPixel(evt.pixel, (feature) => feature, this.options_);
|
||||
|
||||
const element = evt.map.getTargetElement();
|
||||
|
||||
if (feature) {
|
||||
if (element.style.cursor != this.cursor_) {
|
||||
this.previousCursor_ = element.style.cursor;
|
||||
element.style.cursor = this.cursor_;
|
||||
}
|
||||
} else if (this.previousCursor_ !== undefined) {
|
||||
element.style.cursor = this.previousCursor_;
|
||||
this.previousCursor_ = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
function handleUpEvent() {
|
||||
this.coordinate_ = null;
|
||||
this.feature_ = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* loading spinner
|
||||
* author: khy
|
||||
* start
|
||||
* mapLoadStart();
|
||||
* end
|
||||
* mapLoadEnd();
|
||||
*/
|
||||
ol.Map.prototype.addLoadingEffect = function (option) {
|
||||
const css = `
|
||||
@keyframes spinner {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
#map {
|
||||
background: linear-gradient(to top left, #005bac, #3a3a3f);
|
||||
}
|
||||
${option?.transparent ? "/*" : ""}
|
||||
#map > .ol-viewport {
|
||||
display: none;
|
||||
}
|
||||
${option?.transparent ? "*/" : ""}
|
||||
${option?.background ? "" : "/*"}
|
||||
#map.spinner::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: ${option?.background};
|
||||
z-index:8;
|
||||
}
|
||||
${option?.background ? "" : "*/"}
|
||||
#map.spinner::after {
|
||||
content: "";
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-top: -20px;
|
||||
margin-left: -20px;
|
||||
border-radius: 50%;
|
||||
border: 4px solid ${option?.color ? option.color : "white"};
|
||||
border-top-color: transparent;
|
||||
animation: spinner 0.6s linear infinite;
|
||||
z-index:9;
|
||||
}
|
||||
`;
|
||||
|
||||
const head = document.head || document.getElementsByTagName("head")[0];
|
||||
|
||||
if (head.querySelector("style[usage=spinner]")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const style = document.createElement("style");
|
||||
style.setAttribute("usage", "spinner");
|
||||
style.type = "text/css";
|
||||
|
||||
if (style.styleSheet) {
|
||||
style.styleSheet.cssText = css;
|
||||
} else {
|
||||
style.appendChild(document.createTextNode(css));
|
||||
}
|
||||
|
||||
head.appendChild(style);
|
||||
};
|
||||
ol.Map.prototype.removeLoadingEffect = function () {
|
||||
const head = document.head || document.getElementsByTagName("head")[0];
|
||||
head.querySelector("style[usage=spinner]")?.remove();
|
||||
};
|
||||
ol.Map.prototype.startLoadingEffect = function (option) {
|
||||
this.addLoadingEffect(option);
|
||||
this.getTargetElement().classList.add("spinner");
|
||||
};
|
||||
ol.Map.prototype.finishLoadingEffect = function () {
|
||||
this.removeLoadingEffect();
|
||||
this.getTargetElement().classList.remove("spinner");
|
||||
};
|
||||
Reference in New Issue
Block a user