geolocation_tian-4.0.1-beta1/js/MapProvider/Tian.js
js/MapProvider/Tian.js
import { GeolocationCoordinates } from "../../../geolocation/js/Base/GeolocationCoordinates.js";
import { GeolocationMapBase } from "../../../geolocation/js/MapProvider/GeolocationMapBase.js";
import { GeolocationBoundaries } from "../../../geolocation/js/Base/GeolocationBoundaries.js";
import { TianMapMarker } from "../TianMapMarker.js";
/* global TMAP_ANCHOR_TOP_LEFT */
/**
* @typedef TianMapSettings
*
* @extends GeolocationMapSettings
*
* @prop {String} tian_api_url
* @prop {MapOptions} tian_settings
*/
/**
* @prop {T.Map} tianMap
* @prop {T.Control[]} customControls
* @prop {TianMapSettings} settings
*/
export default class Tian extends GeolocationMapBase {
/**
* @constructor
*
* @param {TianMapSettings} mapSettings
* Settings.
*/
constructor(mapSettings) {
super(mapSettings);
this.customControls = [];
// Set the container size.
this.container.style.height = this.settings.tian_settings.height;
this.container.style.width = this.settings.tian_settings.width;
}
initialize() {
return super
.initialize()
// .then(() => {
// return new Promise((resolve) => {
// Drupal.geolocation.maps.addMapProviderCallback("Tian", resolve);
// });
// })
.then(() => {
return new Promise((resolve) => {
this.tianMap = new T.Map(this.container, this.settings.tian_settings);
this.tianMap.centerAndZoom(new T.LngLat(this.settings.lng, this.settings.lat), this.settings.zoom ?? 2);
resolve();
}).then(() => {
return new Promise((resolve) => {
let singleClick;
this.tianMap.addEventListener("click", (event) => {
singleClick = setTimeout(() => {
this.features.forEach((feature) => {
// feature.onClick(new GeolocationCoordinates(event.point.lat, event.point.lng));
feature.onClick(new GeolocationCoordinates(event.x, event.y));
});
}, 500);
});
this.tianMap.addEventListener("dblclick", (event) => {
clearTimeout(singleClick);
this.features.forEach((feature) => {
// feature.onDoubleClick(new GeolocationCoordinates(event.point.lat, event.point.lng));
feature.onDoubleClick(new GeolocationCoordinates(event.x, event.y));
});
});
this.tianMap.addEventListener("rightclick", (event) => {
this.features.forEach((feature) => {
// feature.onContextClick(new GeolocationCoordinates(event.point.lat, event.point.lng));
feature.onContextClick(new GeolocationCoordinates(event.x, event.y));
});
});
this.tianMap.addEventListener("moveend", () => {
this.updatingBounds = false;
this.features.forEach((feature) => {
feature.onMapIdle();
});
});
this.tianMap.addEventListener("moveend", () => {
const bounds = this.getBoundaries();
if (!bounds) {
return;
}
this.features.forEach((feature) => {
feature.onBoundsChanged(bounds);
});
});
resolve(this);
});
});
});
}
createMarker(coordinates, settings) {
const marker = new TianMapMarker(coordinates, settings, this);
this.tianMap.addOverLay(marker.tianMarker);
if (settings.label) {
var markerInfoWin = new T.InfoWindow(settings.label);
marker.tianMarker.addEventListener("click", function () {
marker.tianMarker.openInfoWindow(markerInfoWin);
});
}
return marker;
}
addTitleToShape(shape, title) {
/** @type T.InfoWindow */
const infoWindow = new T.InfoWindow(title);
shape.addEventListener("mouseover", (e) => {
this.tianMap.openInfoWindow(infoWindow, e.point);
});
shape.addEventListener("mouseout", () => {
this.tianMap.closeInfoWindow();
});
}
createShapeLine(geometry, settings) {
const shape = super.createShapeLine(geometry, settings);
shape.tianShapes = [];
const points = [];
geometry.points.forEach((value) => {
points.push(new T.LngLat(value.lng, value.lat));
});
const line = new T.Polyline(points, {
strokeColor: settings.strokeColor,
strokeOpacity: parseFloat(settings.strokeOpacity),
strokeWeight: parseInt(settings.strokeWidth),
});
if (settings.title) {
this.addTitleToShape(line, settings.title);
}
this.tianMap.addOverLay(line);
shape.tianShapes.push(line);
return shape;
}
createShapePolygon(geometry, settings) {
const shape = super.createShapePolygon(geometry, settings);
shape.tianShapes = [];
const points = [];
geometry.points.forEach((value) => {
points.push(new T.LngLat(value.lng, value.lat));
});
const polygon = new T.Polygon(points, {
strokeColor: settings.strokeColor,
strokeOpacity: parseFloat(settings.strokeOpacity),
strokeWeight: parseInt(settings.strokeWidth),
fillColor: settings.fillColor,
fillOpacity: parseFloat(settings.fillOpacity),
});
if (settings.title) {
this.addTitleToShape(polygon, settings.title);
}
this.tianMap.addOverLay(polygon);
shape.tianShapes.push(polygon);
return shape;
}
createShapeMultiLine(geometry, settings) {
const shape = super.createShapeMultiLine(geometry, settings);
shape.tianShapes = [];
shape.geometry.lines.forEach((lineGeometry) => {
const points = [];
lineGeometry.points.forEach((value) => {
points.push(new T.LngLat(value.lng, value.lat));
});
const line = new T.Polyline(points, {
strokeColor: settings.strokeColor,
strokeOpacity: parseFloat(settings.strokeOpacity),
strokeWeight: parseInt(settings.strokeWidth),
});
if (settings.title) {
this.addTitleToShape(line, settings.title);
}
this.tianMap.addOverLay(line);
shape.tianShapes.push(line);
});
return shape;
}
createShapeMultiPolygon(geometry, settings) {
const shape = super.createShapeMultiPolygon(geometry, settings);
shape.tianShapes = [];
shape.geometry.polygons.forEach((polygonGeometry) => {
const points = [];
polygonGeometry.points.forEach((value) => {
points.push(new T.LngLat(value.lng, value.lat));
});
const polygon = new T.Polygon(points, {
strokeColor: settings.strokeColor,
strokeOpacity: parseFloat(settings.strokeOpacity),
strokeWeight: parseInt(settings.strokeWidth),
fillColor: settings.fillColor,
fillOpacity: parseFloat(settings.fillOpacity),
});
if (settings.title) {
this.addTitleToShape(polygon, settings.title);
}
this.tianMap.addOverLay(polygon);
shape.tianShapes.push(polygon);
});
return shape;
}
removeShape(shape) {
if (!shape) {
return;
}
if (shape.tianShapes) {
shape.tianShapes.forEach((tianShape) => {
tianShape.remove();
});
}
shape.remove();
}
getBoundaries() {
super.getBoundaries();
return this.normalizeBoundaries(this.tianMap.getBounds());
}
getShapeBoundaries(shapes) {
super.getShapeBoundaries(shapes);
shapes = shapes || this.dataLayers.get("default").shapes;
if (!shapes.length) {
return null;
}
let bounds;
shapes.forEach((shape) => {
shape.tianShapes.forEach((tianShape) => {
tianShape.getPath().forEach((point) => {
if (!bounds) {
bounds = new T.Bounds(point, point);
} else {
bounds.extend(point);
}
});
});
});
return this.normalizeBoundaries(bounds);
}
getMarkerBoundaries(markers) {
super.getMarkerBoundaries(markers);
markers = markers || this.dataLayers.get("default").markers;
if (!markers) {
return null;
}
let bounds;
markers.forEach((marker) => {
if (!bounds) {
bounds = new T.Bounds(marker.tianMarker.getPosition(), marker.tianMarker.getPosition());
} else {
bounds.extend(marker.tianMarker.getPosition());
}
});
return this.normalizeBoundaries(bounds);
}
setBoundaries(boundaries) {
if (super.setBoundaries(boundaries) === false) {
return false;
}
/** @type {T.Bounds} */
boundaries = this.denormalizeBoundaries(boundaries);
this.tianMap.setViewport([boundaries.getNorthEast(), boundaries.getSouthWest()]);
return this;
}
getZoom() {
this.tianMap.getZoom();
}
setZoom(zoom, defer) {
if (!zoom) {
zoom = this.settings.tian_settings.zoom;
}
zoom = parseInt(zoom);
this.tianMap.setZoom(zoom);
}
getCenter() {
const center = this.tianMap.getCenter();
return new GeolocationCoordinates(center.lat, center.lng);
}
setCenterByCoordinates(coordinates, accuracy) {
super.setCenterByCoordinates(coordinates, accuracy);
if (typeof accuracy === "undefined") {
this.tianMap.panTo(new T.LngLat(coordinates.lng, coordinates.lat));
return;
}
const circle = this.addAccuracyIndicatorCircle(coordinates, accuracy);
// Set the zoom level to the accuracy circle's size.
this.setBoundaries(this.normalizeBoundaries(circle.getBounds()));
// Fade circle away.
setInterval(() => {
let fillOpacity = circle.getFillOpacity();
fillOpacity -= 0.01;
let strokeOpacity = circle.getStrokeOpacity();
strokeOpacity -= 0.02;
if (strokeOpacity > 0 && fillOpacity > 0) {
circle.setFillOpacity(fillOpacity);
circle.setStrokeOpacity(strokeOpacity);
} else {
this.tianMap.removeOverlay(circle);
}
}, 200);
}
normalizeBoundaries(boundaries) {
if (boundaries instanceof GeolocationBoundaries) {
return boundaries;
}
if (T.bounds && boundaries instanceof T.bounds) {
if (boundaries.isEmpty()) {
return null;
}
return new GeolocationBoundaries({
north: boundaries.getNorthEast().lat,
east: boundaries.getNorthEast().lng,
south: boundaries.getSouthWest().lat,
west: boundaries.getSouthWest().lng,
});
}
return null;
}
denormalizeBoundaries(boundaries) {
if (boundaries instanceof T.Bounds) {
return boundaries;
}
if (boundaries instanceof GeolocationBoundaries) {
return new T.Bounds(new T.LngLat(boundaries.east, boundaries.north), new T.LngLat(boundaries.west, boundaries.south));
}
return false;
}
addControl(element) {
element.classList.remove("hidden");
element.style.position = "absolute";
element.style.zIndex = "400";
const control = new T.Control({
anchor: window[element.getAttribute("data-map-control-position")] ?? TMAP_ANCHOR_TOP_LEFT,
offset: new T.Size(50, 50),
});
control.initialize = (map) => {
map.getContainer().appendChild(element);
};
this.tianMap.addControl(control);
}
removeControls() {
this.customControls.forEach((control) => {
this.tianMap.removeControl(control);
});
}
addAccuracyIndicatorCircle(coordinates, accuracy) {
const circle = new T.Circle(new T.LngLat(coordinates.lng, coordinates.lat), accuracy, {
fillColor: "#4285F4",
fillOpacity: 0.15,
strokeColor: "#4285F4",
strokeOpacity: 0.3,
strokeWeight: 1,
enableClicking: false,
});
this.tianMap.addOverLay(circle);
return circle;
}
wgs84ToWebMercator(lon, lat) {
const x = (lon * 20037508.34) / 180;
let y = Math.log(Math.tan(((90 + lat) * Math.PI) / 360)) / (Math.PI / 180);
y = (y * 20037508.34) / 180;
return { x, y };
}
loadTileLayer(layerId, layerSettings) {
const layer = new T.TileLayer();
layer.getTilesUrl = (tileCoord, zoom) => {
const offset = 2 ** (zoom - 1);
const tileX = tileCoord.x + offset;
const tileY = offset - tileCoord.y - 1;
return layerSettings.url.replace("{s}", "a").replace("{x}", tileX.toString()).replace("{y}", tileY.toString()).replace("{z}", zoom.toString());
};
this.tianMap.addTileLayer(layer);
this.tileLayers.set(layerId, layer);
}
unloadTileLayer(layerId) {
if (!this.tileLayers.has(layerId)) {
return;
}
const layer = this.tileLayers.get(layerId);
this.tianMap.removeTileLayer(layer);
}
}
