mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Added code for map creation and camera control
This commit is contained in:
parent
3c9af59051
commit
14679bd7d8
1
.gitignore
vendored
1
.gitignore
vendored
@ -36,3 +36,4 @@ package-lock.json
|
||||
/frontend/setup
|
||||
frontend/server/public/plugins/controltipsplugin/index.js
|
||||
frontend/website/plugins/controltips/index.js
|
||||
/frontend/server/public/maps
|
||||
|
||||
@ -190,6 +190,12 @@ export const mapLayers = {
|
||||
minZoom: 1,
|
||||
maxZoom: 20,
|
||||
attribution: '<a href="https://github.com/cyclosm/cyclosm-cartocss-style/releases" title="CyclOSM - Open Bicycle render">CyclOSM</a> | Map data: © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
},
|
||||
"DCS": {
|
||||
urlTemplate: 'http://localhost:3000/maps/dcs/{z}/{x}/{y}.png',
|
||||
minZoom: 16,
|
||||
maxZoom: 16,
|
||||
attribution: 'Eagle Dynamics'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import { AirbaseContextMenu } from "../contextmenus/airbasecontextmenu";
|
||||
import { Dropdown } from "../controls/dropdown";
|
||||
import { Airbase } from "../mission/airbase";
|
||||
import { Unit } from "../unit/unit";
|
||||
import { bearing, createCheckboxOption, polyContains } from "../other/utils";
|
||||
import { bearing, createCheckboxOption, deg2rad, getGroundElevation, polyContains } from "../other/utils";
|
||||
import { DestinationPreviewMarker } from "./markers/destinationpreviewmarker";
|
||||
import { TemporaryUnitMarker } from "./markers/temporaryunitmarker";
|
||||
import { ClickableMiniMap } from "./clickableminimap";
|
||||
@ -157,6 +157,7 @@ export class Map extends L.Map {
|
||||
this.on('drag', (e: any) => this.#onMouseMove(e));
|
||||
this.on('keydown', (e: any) => this.#onKeyDown(e));
|
||||
this.on('keyup', (e: any) => this.#onKeyUp(e));
|
||||
this.on('move', (e: any) => this.#broadcastPosition(e));
|
||||
|
||||
/* Event listeners */
|
||||
document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => {
|
||||
@ -704,6 +705,29 @@ export class Map extends L.Map {
|
||||
this.#isZooming = false;
|
||||
}
|
||||
|
||||
#broadcastPosition(e: any) {
|
||||
getGroundElevation(this.getCenter(), (response: string) => {
|
||||
var groundElevation: number | null = null;
|
||||
try {
|
||||
groundElevation = parseFloat(response);
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.open("PUT", "http://localhost:8080");
|
||||
xmlHttp.setRequestHeader("Content-Type", "application/json");
|
||||
|
||||
const C = 40075016.686;
|
||||
let mpp = C * Math.cos(deg2rad(this.getCenter().lat)) / Math.pow(2, this.getZoom() + 8);
|
||||
let d = mpp * 1920;
|
||||
let alt = d / 2 * 1 / Math.tan(deg2rad(40));
|
||||
if (alt > 100000)
|
||||
alt = 100000;
|
||||
xmlHttp.send(JSON.stringify({lat: this.getCenter().lat, lng: this.getCenter().lng, alt: alt + groundElevation}));
|
||||
} catch {
|
||||
console.warn("broadcastPosition: could not retrieve ground elevation")
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/* */
|
||||
#panToUnit(unit: Unit) {
|
||||
var unitPosition = new L.LatLng(unit.getPosition().lat, unit.getPosition().lng);
|
||||
|
||||
16
scripts/python/generateMaps/.vscode/launch.json
vendored
Normal file
16
scripts/python/generateMaps/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: Current File",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": true
|
||||
}
|
||||
]
|
||||
}
|
||||
41
scripts/python/generateMaps/generate_tiles.py
Normal file
41
scripts/python/generateMaps/generate_tiles.py
Normal file
@ -0,0 +1,41 @@
|
||||
import os
|
||||
from PIL import Image
|
||||
import concurrent.futures
|
||||
|
||||
zoom = 16
|
||||
path = "output"
|
||||
|
||||
def crop_image(filename):
|
||||
img = Image.open(os.path.join(path, filename))
|
||||
center_X, center_Y = filename.removesuffix(".png").split("_")
|
||||
center_X = int(center_X)
|
||||
center_Y = int(center_Y)
|
||||
w, h = img.size
|
||||
|
||||
box_top_left = (w / 2 - 256, h / 2 - 256, w / 2, h / 2)
|
||||
box_top_right = (w / 2, h / 2 - 256, w / 2 + 256, h / 2)
|
||||
box_bottom_left = (w / 2 - 256, h / 2, w / 2, h / 2 + 256)
|
||||
box_bottom_right = (w / 2, h / 2, w / 2 + 256, h / 2 + 256)
|
||||
|
||||
if not os.path.exists(f"output/{zoom}/{center_X - 1}"):
|
||||
os.mkdir(f"output/{zoom}/{center_X - 1}")
|
||||
|
||||
if not os.path.exists(f"output/{zoom}/{center_X}"):
|
||||
os.mkdir(f"output/{zoom}/{center_X}")
|
||||
|
||||
img.crop(box_top_left).save(f"output/{zoom}/{center_X - 1}/{center_Y - 1}.png")
|
||||
img.crop(box_top_right).save(f"output/{zoom}/{center_X}/{center_Y - 1}.png")
|
||||
img.crop(box_bottom_left).save(f"output/{zoom}/{center_X - 1}/{center_Y}.png")
|
||||
img.crop(box_bottom_right).save(f"output/{zoom}/{center_X}/{center_Y}.png")
|
||||
|
||||
return True
|
||||
|
||||
filenames = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
|
||||
|
||||
# Create output folder
|
||||
if not os.path.exists(f"output/{zoom}"):
|
||||
os.mkdir(f"output/{zoom}")
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
futures = [executor.submit(crop_image, filename) for filename in filenames]
|
||||
results = [future.result() for future in concurrent.futures.as_completed(futures)]
|
||||
75
scripts/python/generateMaps/take_screenshots.py
Normal file
75
scripts/python/generateMaps/take_screenshots.py
Normal file
@ -0,0 +1,75 @@
|
||||
import math
|
||||
import requests
|
||||
import json
|
||||
import pyautogui
|
||||
import time
|
||||
import os
|
||||
|
||||
# parameters
|
||||
start_lat = 36.31669444 # degs
|
||||
start_lng = -115.38336111 # degs
|
||||
|
||||
end_lat = 35.93336111 # degs
|
||||
end_lng = -114.95002778 # degs
|
||||
|
||||
fov = 10 # deg
|
||||
zoom = 16
|
||||
|
||||
# constants
|
||||
C = 40075016.686 # meters
|
||||
|
||||
def deg_to_num(lat_deg, lon_deg, zoom):
|
||||
lat_rad = math.radians(lat_deg)
|
||||
n = 1 << zoom
|
||||
xtile = int((lon_deg + 180.0) / 360.0 * n)
|
||||
ytile = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)
|
||||
return xtile, ytile
|
||||
|
||||
def num_to_deg(xtile, ytile, zoom):
|
||||
n = 1 << zoom
|
||||
lon_deg = xtile / n * 360.0 - 180.0
|
||||
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
|
||||
lat_deg = math.degrees(lat_rad)
|
||||
return lat_deg, lon_deg
|
||||
|
||||
def camera_altitude(lat_deg):
|
||||
mpp = C * math.cos(math.radians(lat_deg)) / math.pow(2, zoom + 8)
|
||||
d = mpp * 1920
|
||||
alt = d / 2 * 1 / math.tan(math.radians(fov) / 2)
|
||||
return alt
|
||||
|
||||
# Find the starting and ending points
|
||||
start_X, start_Y = deg_to_num(start_lat, start_lng, zoom)
|
||||
end_X, end_Y = deg_to_num(end_lat, end_lng, zoom)
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
# Create output folder
|
||||
if not os.path.exists("output"):
|
||||
os.mkdir("output")
|
||||
|
||||
# Start looping
|
||||
n = 1
|
||||
total = math.floor((end_X - start_X) / 2) * math.floor((end_Y - start_Y) / 2)
|
||||
for X in range(start_X, end_X, 2):
|
||||
for Y in range(start_Y, end_Y, 2):
|
||||
# Find the center of the screen
|
||||
center_lat, center_lng = num_to_deg(X + 1, Y + 1, zoom)
|
||||
center_alt = camera_altitude(center_lat)
|
||||
|
||||
# Making PUT request
|
||||
data = json.dumps({'lat': center_lat, 'lng': center_lng, 'alt': center_alt})
|
||||
r = requests.put('http://localhost:8080', data = data)
|
||||
|
||||
# Take and save screenshot
|
||||
screenshot = pyautogui.screenshot()
|
||||
screenshot.save(f"output/{X + 1}_{Y + 1}_{zoom}.png")
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
print(f"Shot {n} of {total}")
|
||||
n = n + 1
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user