mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Improved and generalized DCS maps handling
This commit is contained in:
parent
a53cca8dda
commit
0bdf362174
@ -33,7 +33,7 @@
|
||||
<div class="ol-group">
|
||||
<div id="map-type" class="ol-select">
|
||||
<div class="ol-select-value"><img src="resources/theme/images/icons/map-source.svg" inject-svg /><span
|
||||
class="ol-select-value-text">ArcGIS Satellite</span></div>
|
||||
class="ol-select-value-text">DCS Map</span></div>
|
||||
<div class="ol-select-options">
|
||||
<!-- Here the available map sources will be listed-->
|
||||
</div>
|
||||
|
||||
@ -154,6 +154,17 @@ export const mapBounds = {
|
||||
"SinaiMap": { bounds: new LatLngBounds([34.312222, 28.523333], [25.946944, 36.897778]), zoom: 4 },
|
||||
}
|
||||
|
||||
export const DCSMapsZoomLevelsByTheatre: { [key: string]: { minNativeZoom?: number, maxNativeZoom?: number, minZoom?: number }[] } = {
|
||||
"Syria": [],
|
||||
"MarianaIslands": [{ minNativeZoom: 1, maxNativeZoom: 13, }, { minNativeZoom: 14, maxNativeZoom: 18, minZoom: 14 }],
|
||||
"Nevada": [],
|
||||
"PersianGulf": [],
|
||||
"Caucasus": [],
|
||||
"Falklands": [],
|
||||
"Normandy": [],
|
||||
"SinaiMap": [],
|
||||
}
|
||||
|
||||
export const defaultMapLayers = {
|
||||
"ArcGIS Satellite": {
|
||||
urlTemplate: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
||||
@ -166,29 +177,7 @@ export const defaultMapLayers = {
|
||||
minZoom: 1,
|
||||
maxZoom: 20,
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
},
|
||||
"DCS Marianas Modern": [
|
||||
{
|
||||
urlTemplate: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
||||
minZoom: 1,
|
||||
maxZoom: 19
|
||||
},
|
||||
{
|
||||
urlTemplate: 'http://maps.dcsolympus.com/maps/marianas-modern/{z}/{x}/{y}.png',
|
||||
minNativeZoom: 1,
|
||||
maxNativeZoom: 13,
|
||||
minZoom: 1,
|
||||
maxZoom: 20
|
||||
},
|
||||
{
|
||||
urlTemplate: 'http://maps.dcsolympus.com/maps/marianas-modern/{z}/{x}/{y}.png',
|
||||
minNativeZoom: 14,
|
||||
maxNativeZoom: 16,
|
||||
minZoom: 14,
|
||||
maxZoom: 20,
|
||||
attribution: 'Map extracted by OzDeaDMeaT (DCS Olympus Team)'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/* Map constants */
|
||||
|
||||
49
frontend/website/src/map/dcslayer.ts
Normal file
49
frontend/website/src/map/dcslayer.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import * as L from "leaflet"
|
||||
|
||||
export class DCSLayer extends L.TileLayer {
|
||||
createTile(coords: L.Coords, done: L.DoneCallback) {
|
||||
let newDone = (error?: Error, tile?: HTMLElement) => {
|
||||
if (error === null && tile !== undefined && !tile.classList.contains('filtered')) {
|
||||
// Create a canvas and set its width and height.
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.setAttribute('width', '256px');
|
||||
canvas.setAttribute('height', '256px');
|
||||
|
||||
// Get the canvas drawing context, and draw the image to it.
|
||||
var context = canvas.getContext('2d');
|
||||
if (context) {
|
||||
context.drawImage(tile as CanvasImageSource, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Get the canvas image data.
|
||||
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Create a function for preserving a specified colour.
|
||||
var makeTransparent = function(imageData: ImageData, color: {r: number, g: number, b: number}) {
|
||||
// Get the pixel data from the source.
|
||||
var data = imageData.data;
|
||||
// Iterate through all the pixels.
|
||||
for (var i = 0; i < data.length; i += 4) {
|
||||
// Check if the current pixel should have preserved transparency. This simply compares whether the color we passed in is equivalent to our pixel data.
|
||||
var convert = data[i] > color.r - 5 && data[i] < color.r + 5
|
||||
&& data[i + 1] > color.g - 5 && data[i + 1] < color.g + 5
|
||||
&& data[i + 2] > color.b - 5 && data[i + 2] < color.b + 5;
|
||||
|
||||
// Either preserve the initial transparency or set the transparency to 0.
|
||||
data[i + 3] = convert ? 100: data[i + 3];
|
||||
}
|
||||
return imageData;
|
||||
};
|
||||
|
||||
// Get the new pixel data and set it to the canvas context.
|
||||
var newData = makeTransparent(imageData, {r: 26, g: 109, b: 127});
|
||||
context.putImageData(newData, 0, 0);
|
||||
(tile as HTMLImageElement).src = canvas.toDataURL();
|
||||
tile.classList.add('filtered');
|
||||
}
|
||||
} else {
|
||||
return done(error, tile);
|
||||
}
|
||||
}
|
||||
return super.createTile(coords, newDone);
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@ import { DestinationPreviewMarker } from "./markers/destinationpreviewmarker";
|
||||
import { TemporaryUnitMarker } from "./markers/temporaryunitmarker";
|
||||
import { ClickableMiniMap } from "./clickableminimap";
|
||||
import { SVGInjector } from '@tanem/svg-injector'
|
||||
import { defaultMapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, MOVE_UNIT, SHOW_UNIT_CONTACTS, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, SHOW_UNIT_LABELS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNITS_ACQUISITION_RINGS, HIDE_UNITS_SHORT_RANGE_RINGS, FILL_SELECTED_RING, MAP_MARKER_CONTROLS, DCS_LINK_PORT } from "../constants/constants";
|
||||
import { defaultMapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, MOVE_UNIT, SHOW_UNIT_CONTACTS, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, SHOW_UNIT_LABELS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNITS_ACQUISITION_RINGS, HIDE_UNITS_SHORT_RANGE_RINGS, FILL_SELECTED_RING, MAP_MARKER_CONTROLS, DCS_LINK_PORT, DCSMapsZoomLevelsByTheatre } from "../constants/constants";
|
||||
import { CoalitionArea } from "./coalitionarea/coalitionarea";
|
||||
import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextmenu";
|
||||
import { DrawingCursor } from "./coalitionarea/drawingcursor";
|
||||
@ -21,6 +21,7 @@ import { GestureHandling } from "leaflet-gesture-handling";
|
||||
import { TouchBoxSelect } from "./touchboxselect";
|
||||
import { DestinationPreviewHandle } from "./markers/destinationpreviewHandle";
|
||||
import { ContextActionSet } from "../unit/contextactionset";
|
||||
import { DCSLayer } from "./dcslayer";
|
||||
|
||||
var hasTouchScreen = false;
|
||||
//if ("maxTouchPoints" in navigator)
|
||||
@ -46,7 +47,7 @@ export type MapMarkerVisibilityControl = {
|
||||
"toggles": string[],
|
||||
"tooltip": string
|
||||
}
|
||||
|
||||
|
||||
export class Map extends L.Map {
|
||||
#ID: string;
|
||||
#state: string;
|
||||
@ -101,6 +102,7 @@ export class Map extends L.Map {
|
||||
#optionButtons: { [key: string]: HTMLButtonElement[] } = {}
|
||||
#visibilityOptions: { [key: string]: boolean | string | number } = {}
|
||||
#hiddenTypes: string[] = [];
|
||||
#layerName: string = "";
|
||||
|
||||
/**
|
||||
*
|
||||
@ -126,7 +128,7 @@ export class Map extends L.Map {
|
||||
|
||||
this.#ID = ID;
|
||||
|
||||
this.setLayer(Object.keys(this.#mapLayers)[0]);
|
||||
this.setLayer("DCS Map");
|
||||
|
||||
/* Minimap */
|
||||
var minimapLayer = new L.TileLayer(this.#mapLayers[Object.keys(this.#mapLayers)[0]].urlTemplate, { minZoom: 0, maxZoom: 13 });
|
||||
@ -139,7 +141,8 @@ export class Map extends L.Map {
|
||||
//L.control.scalenautic({ position: "topright", maxWidth: 300, nautic: true, metric: true, imperial: false }).addTo(this);
|
||||
|
||||
/* Map source dropdown */
|
||||
this.#mapSourceDropdown = new Dropdown("map-type", (layerName: string) => this.setLayer(layerName), this.getLayers());
|
||||
this.#mapSourceDropdown = new Dropdown("map-type", (layerName: string) => this.setLayer(layerName));
|
||||
this.#mapSourceDropdown.setOptions(this.getLayers(), null);
|
||||
|
||||
/* Visibility options dropdown */
|
||||
this.#mapVisibilityOptionsDropdown = new Dropdown("map-visibility-options", (value: string) => { });
|
||||
@ -218,7 +221,7 @@ export class Map extends L.Map {
|
||||
...this.#mapLayers,
|
||||
...additionalMaps
|
||||
}
|
||||
this.#mapSourceDropdown.setOptions(this.getLayers());
|
||||
this.#mapSourceDropdown.setOptions(this.getLayers(), null);
|
||||
}
|
||||
})
|
||||
|
||||
@ -279,23 +282,40 @@ export class Map extends L.Map {
|
||||
if (this.#layer != null)
|
||||
this.removeLayer(this.#layer)
|
||||
|
||||
let theatre = getApp().getMissionManager()?.getTheatre() ?? "Nevada";
|
||||
|
||||
/* Normal or custom layers are handled here */
|
||||
if (layerName in this.#mapLayers) {
|
||||
const layerData = this.#mapLayers[layerName];
|
||||
if (layerData instanceof Array) {
|
||||
let layers = layerData.map((layer: any) => {
|
||||
return new L.TileLayer(layer.urlTemplate, layer);
|
||||
return new L.TileLayer(layer.urlTemplate.replace("{theatre}", theatre.toLowerCase()), layer);
|
||||
})
|
||||
this.#layer = new L.LayerGroup(layers);
|
||||
} else {
|
||||
this.#layer = new L.TileLayer(layerData.urlTemplate, layerData);
|
||||
}
|
||||
/* DCS core layers are handled here */
|
||||
} else if (["DCS Map", "DCS Satellite"].includes(layerName) ) {
|
||||
let layerData = this.#mapLayers["ArcGIS Satellite"];
|
||||
let layers = [new L.TileLayer(layerData.urlTemplate, layerData)];
|
||||
|
||||
let template = `https://maps.dcsolympus.com/maps/${layerName === "DCS Map"? "alt": "sat"}-{theatre}-modern/{z}/{x}/{y}.png`;
|
||||
layers.push(...DCSMapsZoomLevelsByTheatre[theatre].map((nativeZoomLevels: any) => {
|
||||
return new L.TileLayer(template.replace("{theatre}", theatre.toLowerCase()), {...nativeZoomLevels, maxZoom: 20, crossOrigin: ""});
|
||||
}));
|
||||
|
||||
this.#layer = new L.LayerGroup(layers);
|
||||
}
|
||||
|
||||
this.#layer?.addTo(this);
|
||||
this.#layerName = layerName;
|
||||
}
|
||||
|
||||
getLayers() {
|
||||
return Object.keys(this.#mapLayers);
|
||||
let layers = ["DCS Map", "DCS Satellite"]
|
||||
layers.push(...Object.keys(this.#mapLayers));
|
||||
return layers;
|
||||
}
|
||||
|
||||
/* State machine */
|
||||
@ -471,6 +491,8 @@ export class Map extends L.Map {
|
||||
|
||||
const boundaries = this.#getMinimapBoundaries();
|
||||
this.#miniMapPolyline.setLatLngs(boundaries[theatre as keyof typeof boundaries]);
|
||||
|
||||
this.setLayer(this.#layerName);
|
||||
}
|
||||
|
||||
getMiniMapLayerGroup() {
|
||||
|
||||
@ -180,7 +180,6 @@ export class MissionManager {
|
||||
return this.#theatre;
|
||||
}
|
||||
|
||||
|
||||
getAvailableSpawnPoints() {
|
||||
if (this.getCommandModeOptions().commandMode === GAME_MASTER)
|
||||
return Infinity;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user