Compare commits

...

28 Commits
map ... server

Author SHA1 Message Date
fcb52a289e adsf 2025-10-15 15:37:52 +02:00
6adb83b12b 25dsf5 2025-10-15 15:32:16 +02:00
796960bdaf ,,, 2025-10-15 15:20:44 +02:00
1093b41260 56adfs 2025-10-15 14:17:26 +02:00
8631452475 ,,, 2025-10-15 14:16:36 +02:00
1e37b4c2a3 ... 2025-10-14 15:59:28 +02:00
959c78b62d Daniel ist doof 2025-10-14 15:55:50 +02:00
0a84ef4614 ... 2025-10-14 15:53:20 +02:00
d8aa1544e8 ... 2025-10-14 15:50:03 +02:00
1ac73eda82 n8n Data Gateway 2025-10-14 15:41:39 +02:00
3cc7dbe797 n8n Test 2025-10-08 14:01:35 +02:00
7b2445f704 n8n Test 2025-10-08 13:56:41 +02:00
bf5c508db6 data gateway connection dest 2025-09-26 22:16:21 +02:00
82700c4689 Umbau CORS auf "domain"/api/job 2025-09-24 10:06:17 +02:00
3e5c8d26a8 Merge pull request 'Gateway Test' (#7) from dev into server
Reviewed-on: #7
2025-09-14 15:26:18 +02:00
7658a12669 Gateway Test 2025-09-14 13:25:37 +00:00
fd3df826bc Merge pull request 'Error const/let' (#6) from dev into server
Reviewed-on: #6
2025-09-14 13:24:54 +02:00
da2c3c631d Error const/let 2025-09-14 11:24:21 +00:00
b01adad0e0 Merge pull request 'Grist Data ziehen Test' (#5) from dev into server
Reviewed-on: #5
2025-09-14 13:21:28 +02:00
53100c1f2a Grist Data ziehen Test 2025-09-14 11:20:09 +00:00
6e376b4f13 Merge pull request 'markers test' (#4) from dev into server
Reviewed-on: #4
2025-09-07 15:02:51 +02:00
3c94a65913 markers test 2025-09-07 13:02:12 +00:00
8697d32d7b Merge pull request 'dev' (#3) from dev into server
Reviewed-on: #3
2025-09-07 14:58:30 +02:00
8e936c3fb8 jlj 2025-09-07 12:56:31 +00:00
0716ca3d9f test 2025-09-07 12:53:28 +00:00
69ce35e03e markers data test 2025-09-07 12:51:50 +00:00
d974cf4abe grist data import 2025-09-05 22:52:24 +02:00
6c5cc0d57b Merge pull request 'map update' (#2) from map into server
Reviewed-on: #2
2025-09-04 22:18:24 +02:00
3 changed files with 51 additions and 87 deletions

15
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
// 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": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
}
]
}

View File

@ -10,8 +10,7 @@
html,body,#map {height:100%;margin:0} html,body,#map {height:100%;margin:0}
.coords{position:absolute;left:6px;bottom:6px;z-index:1000;background:rgba(255,255,255,.85); .coords{position:absolute;left:6px;bottom:6px;z-index:1000;background:rgba(255,255,255,.85);
padding:3px 6px;font-size:12px;border-radius:4px;font-family:system-ui,Segoe UI,Arial} padding:3px 6px;font-size:12px;border-radius:4px;font-family:system-ui,Segoe UI,Arial}
.center-dot{position:absolute;top:50%;left:50%;width:10px;height:10px;background:red;border-radius:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 2px rgba(255,255,255,.95),0 0 6px rgba(0,0,0,.35);pointer-events:none;z-index:1001} .center-dot{position:absolute;top:50%;left:50%;width:5px;height:5px;background:red;border-radius:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 2px rgba(255,255,255,.95),0 0 2px rgba(0,0,0,.35);pointer-events:none;z-index:1001}
.center-dot{position:absolute;top:50%;left:50%;width:10px;height:10px;background:red;border-radius:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 2px rgba(255,255,255,.95),0 0 6px rgba(0,0,0,.35);pointer-events:none;z-index:1001}
.copy-btn{position:absolute;left:6px;bottom:36px;z-index:1000;background:#ef4444;color:#fff;border:0;border-radius:6px;padding:6px 10px;font:600 12px/1 system-ui,Segoe UI,Arial;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.25)} .copy-btn{position:absolute;left:6px;bottom:36px;z-index:1000;background:#ef4444;color:#fff;border:0;border-radius:6px;padding:6px 10px;font:600 12px/1 system-ui,Segoe UI,Arial;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.25)}
.copy-btn:active{transform:translateY(1px)} .copy-btn:active{transform:translateY(1px)}
</style> </style>
@ -180,7 +179,8 @@ if (hash.length >= 2) {
}); });
}); });
</script> </script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="markers.js"></script> <script src="markers.js"></script>
</body> </body>
</html> </html>

View File

@ -1,91 +1,40 @@
// === CONFIG === let Data_api = "/webhook/data";
const WIKI_API = 'https://wiki.arenos.danielnagel.at/api.php'; // dein Wiki-Host (mit index.php) let freight = null;
const CATEGORY_TITLE = 'Kategorie:Orte'; // Hauptkategorie let testing = true;
const MAX_PAGES = 500; // genug Luft
// Hilfsfunktion: MediaWiki API-URL bauen let ReqData = { Places: "Stadte"}
function apiURL(params) {
const u = new URL(WIKI_API);
u.search = new URLSearchParams({ ...params, format: 'json', origin: '*' }).toString();
return u.toString();
}
// 1) Alle Mitglieder einer Kategorie holen // Post to n8n Server to get Data from Grist in JSON format.
async function fetchCategoryMembers(categoryTitle) { async function GetMarkerData() {
const url = apiURL({
action: 'query',
list: 'categorymembers',
cmtitle: categoryTitle,
cmlimit: String(MAX_PAGES)
});
const res = await fetch(url);
if (!res.ok) throw new Error(`categorymembers failed: ${res.status}`);
const data = await res.json();
return data?.query?.categorymembers || [];
}
// 2) Gerendertes HTML einer Seite holen (damit <div class="place-data"> drin ist)
async function fetchPageHTML(title) {
const url = apiURL({
action: 'parse',
page: title,
prop: 'text'
});
const res = await fetch(url);
if (!res.ok) throw new Error(`parse failed for ${title}: ${res.status}`);
const data = await res.json();
const html = data?.parse?.text?.['*'] || '';
const div = document.createElement('div');
div.innerHTML = html;
return div;
}
// 3) Daten aus dem versteckten Div extrahieren
function extractPlaceData(container) {
const node = container.querySelector('.place-data');
if (!node) return null;
const name = node.getAttribute('data-name') || '';
const xStr = node.getAttribute('data-x') || '';
const yStr = node.getAttribute('data-y') || '';
const desc = node.getAttribute('data-description') || '';
const link = node.getAttribute('data-link') || '';
const x = parseFloat(xStr);
const y = parseFloat(yStr);
if (Number.isNaN(x) || Number.isNaN(y)) return null;
return { name, x, y, desc, link };
}
// 4) Marker laden + hinzufügen
async function loadWikiMarkers(map) {
try { try {
const pages = await fetchCategoryMembers(CATEGORY_TITLE); const res = await axios.post(Data_api, ReqData);
console.log (res.data);
RenderMarkers(res.data);
// Optionales Bounding, falls du später auto-fit willst } catch (err) {
const layers = []; console.error (err);
for (const p of pages) {
try {
const html = await fetchPageHTML(p.title);
const d = extractPlaceData(html);
if (!d) continue;
// Leaflet: Bei CRS.Simple = [y, x]
const m = L.marker([d.y, d.x]).addTo(map);
const wikiLink = d.link || `https://wiki.arenos.danielnagel.at/index.php/${encodeURIComponent(p.title)}`;
const popup = `
<b>${d.name || p.title}</b><br>
${d.desc ? `${d.desc}<br>` : ''}
<a href="${wikiLink}" target="_blank" rel="noopener">Open in Wiki</a>
`;
m.bindPopup(popup);
layers.push(m);
} catch (e) {
console.warn('skip page due to parse error:', p.title, e);
}
}
} catch (e) {
console.error('Failed to load wiki markers:', e);
} }
} }
//Render Map Markers with the Position from Grist Database
function RenderMarkers(rows){
if (!Array.isArray(rows)) {
console.error('Erwarte ein Array, bekam:', rows);
return;
}
rows.forEach((row) => {
const x = Number(row.X);
const y = Number(row.Y);
if (!Number.isFinite(x) || !Number.isFinite(y)) return;
L.marker([y, x]) // [lat, lng] -> [Y, X]
.addTo(map)
.bindPopup(`<b>${row.Name ?? ''}</b>`);
});
}
GetMarkerData();