// ==UserScript==
// @name POI Generator
// @namespace https://leitstellenspiel.de
// @version 1.1
// @description Generates POIs based on OSM Data
// @author Lennard[TFD]
// @match https://www.leitstellenspiel.de/
// @match https://www.missionchief.com/
// @match https://www.meldkamerspel.com/
// @updateURL https://github.com/LennardTFD/LeitstellenspielScripte/raw/master/LSS_POIGenerator/poiGenerator.user.js
// @downloadURL https://github.com/LennardTFD/LeitstellenspielScripte/raw/master/LSS_POIGenerator/poiGenerator.user.js
// @grant none
// ==/UserScript==
var mapType;
if('undefined' == typeof mapkit){
mapType = "leaflet";
}
else
{
mapType = "mapkit";
}
(function() {
'use strict';
let circle;
function createElementFromHTML(htmlString) {
var div = document.createElement('div');
div.innerHTML = htmlString.trim();
return div.children[0];
}
function addToForm() {
let radius = "
"
let button = "";
let progress = "";
let input = createElementFromHTML(radius);
let generate = createElementFromHTML(button);
let progressArea = createElementFromHTML(progress);
document.getElementsByClassName("mission_position_address")[0].after(input);
document.getElementsByClassName("form-actions")[0].querySelector("input").after(generate);
document.getElementsByClassName("form-actions")[0].after(progressArea);
$( "#poiGeneratorStart" ).click(function() {
start();
});
$( "#poiGeneratorRange" ).on("change", function() {
circle.setRadius($( "#poiGeneratorRange" ).val());
});
let center = map.getBounds().getCenter();
circle = L.circle([center.lat, center.lng], {
color: "red",
fillColor: "#f03",
fillOpacity: 0.5,
radius: 1000
}).addTo(map);
map.on('move', function () {
circle.setLatLng(map.getBounds().getCenter());
});
let loaderClose, loaderSave;
$("a[href='/buildings']:eq(0)").click(function() {
loaderClose = setInterval(() => {
//console.log("Waiting for POI");
if($("#build_new_poi")[0] != undefined)
{
//console.log("POI loaded!");
circle.remove();
clearInterval(loaderClose);
clearInterval(loaderSave);
setupBtnListener();
}
}, 200);
});
$(".form-actions").find("input[value='Speichern']").click(function() {
loaderSave = setInterval(() => {
//console.log("Waiting for POI");
if($("#mission_position_address")[0] != undefined)
{
circle.remove();
//console.log("POI loaded!");
clearInterval(loaderSave);
clearInterval(loaderClose);
setupBtnListener();
}
}, 200);
});
}
function setupBtnListener()
{
if(poiIsSet)
{
return;
}
$( "#build_new_poi" ).click(function() {
//console.log("POI is clicked!");
let loader = setInterval(() => {
//console.log("Waiting for POI");
if($("#mission_position_address")[0] != undefined)
{
//console.log("POI loaded!");
clearInterval(loader);
addToForm();
}
}, 200);
});
}
const poiIsSet = true;
async function requestPOIsInRange() {
//console.log("Starting generation!");
let radius = $("#poiGeneratorRange").val();
let poiId = parseInt($("#mission_position_poi_type").val());
let pointerLocation;
if(mapType == "leaflet")
{
pointerLocation = map.getBounds().getCenter();
}
else
{
pointerLocation = map.center;
pointerLocation.lat = pointerLocation.latitude;
pointerLocation.lng = pointerLocation.longitude;
}
//console.log(pointerLocation);
let filterString = [];
switch (poiId) {
//Park
case 0:
filterString[0] = "['leisure'~'park|playground']";
break;
//See
case 1:
filterString[0] = "['natural'='water']['water'!='river']['water'!='canal']['water'!='lock']['waterway'!='river']['waterway'!='stream']['waterway'!='canal']['amenity'!='fountain']";
filterString[1] = "['natural'='water']['water'~'lake|pond|lagoon|reservoir|reflecting_pool|moat|wastewater']";
filterString[2] = "['water'~'lake|pond|lagoon|reservoir|reflecting_pool|moat|wastewater']";
filterString[3] = "['natural'='water']['waterway'='dam']";
filterString[4] = "['waterway'='dam']";
//filterString[0] = "['natural'='water']['amenity'!='fountain']";
break;
//Krankenhaus
case 2:
filterString[0] = "['amenity'~'hospital|clinic']";
break;
//Wald
case 3:
filterString[0] = "['landuse'='forest']";
break;
//Bus stop
case 4:
filterString[0] = "['bus'='yes']['public_transport'='stop_position']";
filterString[1] = "['highway'='bus_stop']";
break;
//Tram stop
case 5:
filterString[0] = "['tram'='yes']['public_transport'='stop_position']";
filterString[1] = "['tram'='yes']['railway'='tram_stop']";
filterString[2] = "['subway'='yes']['public_transport'='stop_position']";
break;
//Trainstation
case 6:
case 7:
filterString[0] = "['public_transport'='station']";
filterString[1] = "['railway'='stop']";
filterString[2] = "['public_transport'='stop_position']['train'='yes']";
break;
//Cargostation
case 8:
filterString[0] = [];
break;
//Supermarket
case 9:
case 10:
filterString[0] = "['shop'='supermarket']";
break;
//Fuelstation
case 11:
filterString[0] = "['amenity'='fuel']";
break;
//School
case 12:
filterString[0] = "['building'='school']";
filterString[1] = "['amenity'='school']";
break;
//Museum
case 13:
filterString[0] = "['tourism'='museum']";
break;
//Mall
case 14:
filterString[0] = "['shop'='mall']";
break;
//car workshop
case 15:
filterString[0] = "['shop'='car_repair']";
filterString[1] = "['shop'='car_parts']";
filterString[2] = "['shop'='car']";
break;
//Highway entrance/exit
//Shall not use!
case 16:
filterString[0] = "['highway'='motorway_link']";
break;
//Christmasmarket
case 17:
filterString[0] = "['market'='flea_market']";
filterString[1] = "['amenity'='marketplace']";
break;
//Warehouse
case 18:
filterString[0] = "['building'='industrial']";
filterString[1] = "['building'='warehouse']";
break;
//Disco
case 19:
filterString[0] = "['amenity'='nightclub']";
filterString[1] = "['amenity'='stripclub']";
filterString[2] = "['amenity'='swingerclub']";
filterString[3] = "['amenity'='brothel']";
filterString[4] = "['amenity'='pub']";
filterString[5] = "['amenity'='bar']";
break;
//Stadium
case 20:
filterString[0] = "['leisure'='stadium']";
break;
//Farm
case 21:
filterString[0] = "['building'='farm']";
filterString[1] = "['building'='barn']";
filterString[2] = "['building'='farm_auxiliary']";
filterString[3] = "['building'='stable']";
break;
//Office
case 22:
filterString[0] = "['office']";
filterString[1] = "['amenity'='embassy']";
filterString[2] = "['building'='office']";
break;
//Swimming Pool
case 23:
filterString[0] = "['leisure'='swimming_area']";
filterString[1] = "['leisure'='swimming_pool']";
filterString[2] = "['sport'='swimming']";
break;
//Train crossing
case 24:
filterString[0] = "['railway'~'crossing|level_crossing|railway_crossing']";
break;
//Theatre
case 25:
filterString[0] = "['amenity'~'cinema|theatre']";
break;
//Fairground
//Shall not use!
case 26:
filterString[0] = "['tourism'='attraction']";
break;
//Fluss
case 27:
//filterString[0] = "['natural'='water']['water'!='lake']['water'!='pond']['water'!='wastewater']['amenity'!='fountain']";
filterString[0] = "['natural'='water']['waterway'~'river|stream|riverbank|tidal_channel|canal']";
filterString[1] = "['natural'='water']['water'~'canal|oxbow|river']";
filterString[2] = "['water'~'canal|oxbow|river']";
filterString[3] = "['waterway'~'river|stream|riverbank|tidal_channel|canal']";
//filterString[1] = "['natural'='water']['waterway'='stream']";
break;
//Baumarkt
case 28:
filterString[0] = "['shop'='doityourself']";
break;
//Airport Runway
case 29:
case 32:
filterString[0] = "['aeroway'='runway']";
filterString[1] = "['aeroway'='taxiway']";
break;
//Airport Building/Terminal
case 30:
case 33:
filterString[0] = "['aeroway'='terminal']";
filterString[1] = "['aeroway'='gate']";
break;
//Airport Parking
case 31:
case 34:
filterString[0] = "['aeroway'='parking_position']";
filterString[1] = "['aeroway'='apron']";
break;
//Airport Car park
case 35:
filterString[0] = "['parking'='multi-storey']";
break;
//Biogas
case 36:
filterString[0] = "['building'='digester']";
break;
//Bank
case 37:
filterString[0] = "['amenity'='bank']";
break;
//Church
case 38:
filterString[0] = "['historic'='church']";
filterString[1] = "['building'='church']";
filterString[2] = "['building'='mosque']";
filterString[3] = "['building'='synagogue']";
break;
//Church
case 38:
filterString[0] = "['historic'='church']";
filterString[1] = "['building'='church']";
filterString[2] = "['building'='mosque']";
filterString[3] = "['building'='synagogue']";
break;
//Industry
case 39:
case 40:
case 41:
filterString[0] = "['building'='industrial']";
break;
//Trash burning
case 42:
filterString[0] = "['amenity'='waste_disposal']";
break;
//Ice Skating
case 43:
filterString[0] = "['sport'='ice_skating']";
filterString[1] = "['leisure'='ice_rink']";
break;
//Woodprocessing
case 44:
filterString[0] = "['craft'~'parquet layer|roofer|carpenter|window construction|joiner']";
filterString[1] = "['shop'='doityourself']";
break;
}
let requestString = ``;
let start = `
[out:json];
(
`;
let requestPreset = `
node$filterString$(around:${radius}, ${pointerLocation.lat},${pointerLocation.lng});
way$filterString$(around:${radius}, ${pointerLocation.lat},${pointerLocation.lng});
relation$filterString$(around:${radius}, ${pointerLocation.lat},${pointerLocation.lng});
`;
let end = `
);
out center;
>;
`;
for(let i = 0; i < filterString.length; i++)
{
//console.log(i, poiId);
requestString += requestPreset.replace(/\$filterString\$/g, filterString[i]);
}
requestString = start + requestString + end;
//console.log(requestString);
let pois = await getPOIs(requestString);
return pois;
}
function getPOIs(requestString) {
return new Promise(resolve => {
$.ajax({
url: "http://overpass-api.de/api/interpreter",
method: "GET",
data: {data: requestString}
}).done((res) => {
resolve(res);
});
});
}
async function createPOIs(poiId, poi) {
//console.log("Creating POI");
let lat, lng;
if(poi.type == "node")
{
lat = poi.lat;
lng = poi.lon;
}
else
{
lat = poi.center.lat;
lng = poi.center.lon;
}
//console.log(lat, lng);
let addressRequest = await getAddress(lat, lng);
let address = addressRequest;
//console.log(address);
$.ajax({
url: "https://www.leitstellenspiel.de/mission_positions",
method: "POST",
data: {
"mission_position[poi_type]": poiId,
"mission_position[latitude]": lat,
"mission_position[longitude]": lng,
"mission_position[address]": address,
"utf8": true,
"authentication_token": $("meta[name='csrf-token']").attr("content")
}
}).done((res) => {
//console.log("New POI created")
});
}
function getAddress(lat, lng) {
return new Promise(resolve => {
$.ajax({
url: "https://www.leitstellenspiel.de/reverse_address",
method: "GET",
data: {
latitude: lat,
longitude: lng
}
}).done((res) => {
resolve(res);
});
});
}
function createProgress(poiId, poiName, poiAmount)
{
let progressbar = '' +
'
' + poiName + '
' +
'
';
let progress = createElementFromHTML(progressbar);
$("#poiGeneratorProgress").append(progress);
return $(progress).find("div");
}
async function start()
{
let poiId = parseInt($("#mission_position_poi_type").val());
let poiName = $("#mission_position_poi_type").find("option[value='" + poiId + "']").text();
let pois = await requestPOIsInRange();
let poiAmount = Object.keys(pois.elements).length;
let bar = createProgress(poiId, poiName, poiAmount);
let max = poiAmount;
let currProgress = parseInt($(bar).attr("aria-valuenow"));
let i = 0;
$.each(pois.elements, (e, t) => {
setTimeout(() => {
$(bar).attr("aria-valuenow", ++currProgress);
$(bar).css("width", ((currProgress / max) * 100) + "%");
$(bar).text(poiName + " (" + currProgress + " / " + poiAmount + ")");
createPOIs(poiId, t);
//console.log("POI Amount:", poiAmount, "| E:", e);
if(poiAmount == e + 1)
{
//console.log("Last POI created!");
removeProgressbar(poiId);
}
}, 3200 * i);
i++;
});
if(poiAmount < 1)
{
//console.log("No POIs to create!");
removeProgressbar(poiId);
}
}
function removeProgressbar(poiId)
{
//console.log("Progressbar removed!");
//console.log($("#poiProgress_" + poiId));
$("#poiProgress_" + poiId).remove();
}
setupBtnListener();
})();