Refactor symbols app: cleanup and fix issues
- Removed duplicate files (index2/3/4.html, symbols.js duplicates) - Kept index4.html as the main index.html (modular version) - Removed old text-generator.js (replaced by modular version) - Fixed ID mismatch in ui-bindings.js to match HTML - Added square and circle shape support in svg-generator.js - Added legend preview with copy functionality - Removed 580 lines of obsolete text-generator v4 code from app.js - Added addTextToLegend and addStandaloneArrowToLegend to export.js Still TODO: Split large files to comply with 300 line limit - app.js: 1219 lines - styles.css: 1319 lines - symbols.js: 870 lines 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -445,6 +445,7 @@ function openLegendModal() {
|
||||
const modal = document.getElementById('legendModal');
|
||||
modal.classList.add('active');
|
||||
renderLegendEditor();
|
||||
updateLegendPreview();
|
||||
}
|
||||
|
||||
function closeLegendModal() {
|
||||
@@ -454,34 +455,38 @@ function closeLegendModal() {
|
||||
|
||||
function renderLegendEditor() {
|
||||
const container = document.getElementById('legendItems');
|
||||
|
||||
|
||||
if (legendItems.length === 0) {
|
||||
container.innerHTML = '<div class="legend-empty">Keine Symbole in der Legende. Klicken Sie auf 📑 bei einem Symbol, um es hinzuzufügen.</div>';
|
||||
updateLegendPreview();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
container.innerHTML = legendItems.map((item, index) => `
|
||||
<div class="legend-item" data-index="${index}">
|
||||
<div class="legend-item-preview">${item.svg}</div>
|
||||
<div class="legend-item-content">
|
||||
<input type="text" class="legend-item-name" value="${item.name}"
|
||||
onchange="updateLegendItem(${index}, 'name', this.value)" placeholder="Name">
|
||||
<input type="text" class="legend-item-desc" value="${item.description || ''}"
|
||||
onchange="updateLegendItem(${index}, 'description', this.value)" placeholder="Beschreibung (optional)">
|
||||
<input type="text" class="legend-item-name" value="${item.name}"
|
||||
oninput="updateLegendItem(${index}, 'name', this.value)" placeholder="Name">
|
||||
<input type="text" class="legend-item-desc" value="${item.description || ''}"
|
||||
oninput="updateLegendItem(${index}, 'description', this.value)" placeholder="Beschreibung (optional)">
|
||||
</div>
|
||||
<div class="legend-item-actions">
|
||||
<button onclick="moveLegendItem(${index}, -1)" title="Nach oben" ${index === 0 ? 'disabled' : ''}>▲</button>
|
||||
<button onclick="moveLegendItem(${index}, 1)" title="Nach unten" ${index === legendItems.length - 1 ? 'disabled' : ''}>▼</button>
|
||||
<button onclick="removeLegendItem(${index})" title="Entfernen" class="btn-remove">✕</button>
|
||||
<button type="button" onclick="moveLegendItem(${index}, -1)" title="Nach oben" ${index === 0 ? 'disabled' : ''}>▲</button>
|
||||
<button type="button" onclick="moveLegendItem(${index}, 1)" title="Nach unten" ${index === legendItems.length - 1 ? 'disabled' : ''}>▼</button>
|
||||
<button type="button" onclick="removeLegendItem(${index})" title="Entfernen" class="btn-remove">✕</button>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
updateLegendPreview();
|
||||
}
|
||||
|
||||
function updateLegendItem(index, field, value) {
|
||||
if (legendItems[index]) {
|
||||
legendItems[index][field] = value;
|
||||
saveLegendToStorage();
|
||||
updateLegendPreview();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,28 +552,130 @@ function loadLegendFromStorage() {
|
||||
}
|
||||
}
|
||||
|
||||
// ========== LEGENDE VORSCHAU ==========
|
||||
function generateLegendSVG() {
|
||||
if (legendItems.length === 0) return null;
|
||||
|
||||
const itemHeight = 50;
|
||||
const width = 320;
|
||||
const height = legendItems.length * itemHeight + 60;
|
||||
|
||||
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="${width}" height="${height}">
|
||||
<rect width="${width}" height="${height}" fill="white"/>
|
||||
<text x="20" y="30" font-family="Arial" font-size="18" font-weight="bold">Legende</text>
|
||||
<line x1="20" y1="40" x2="${width - 20}" y2="40" stroke="#ccc" stroke-width="1"/>`;
|
||||
|
||||
legendItems.forEach((item, index) => {
|
||||
const y = 60 + index * itemHeight;
|
||||
svg += `<g transform="translate(20, ${y})">
|
||||
<g transform="scale(0.5)">${item.svg.replace(/<svg[^>]*>/, '').replace('</svg>', '')}</g>
|
||||
<text x="50" y="20" font-family="Arial" font-size="14" font-weight="bold">${escapeHtml(item.name)}</text>
|
||||
${item.description ? `<text x="50" y="35" font-family="Arial" font-size="11" fill="#666">${escapeHtml(item.description)}</text>` : ''}
|
||||
</g>`;
|
||||
});
|
||||
|
||||
svg += '</svg>';
|
||||
return svg;
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function updateLegendPreview() {
|
||||
const previewBox = document.getElementById('legendPreviewBox');
|
||||
if (!previewBox) return;
|
||||
|
||||
if (legendItems.length === 0) {
|
||||
previewBox.innerHTML = '<div class="legend-preview-empty">Keine Eintraege vorhanden</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
const svg = generateLegendSVG();
|
||||
if (svg) {
|
||||
previewBox.innerHTML = svg;
|
||||
}
|
||||
}
|
||||
|
||||
async function copyLegendAsImage() {
|
||||
if (legendItems.length === 0) {
|
||||
showNotification('Legende ist leer', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const svg = generateLegendSVG();
|
||||
if (!svg) return;
|
||||
|
||||
try {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const itemHeight = 50;
|
||||
const width = 320;
|
||||
const height = legendItems.length * itemHeight + 60;
|
||||
|
||||
canvas.width = width * 2;
|
||||
canvas.height = height * 2;
|
||||
ctx.scale(2, 2);
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
|
||||
const img = new Image();
|
||||
const svgBlob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });
|
||||
const url = URL.createObjectURL(svgBlob);
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
img.src = url;
|
||||
});
|
||||
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
URL.revokeObjectURL(url);
|
||||
|
||||
canvas.toBlob(async (blob) => {
|
||||
try {
|
||||
await navigator.clipboard.write([
|
||||
new ClipboardItem({ 'image/png': blob })
|
||||
]);
|
||||
showNotification('Legende in Zwischenablage kopiert!');
|
||||
} catch (err) {
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = 'legende.png';
|
||||
link.click();
|
||||
showNotification('Legende als PNG heruntergeladen');
|
||||
}
|
||||
}, 'image/png');
|
||||
} catch (err) {
|
||||
console.error('Fehler beim Kopieren:', err);
|
||||
showNotification('Fehler beim Kopieren', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// ========== LEGENDE EXPORTIEREN ==========
|
||||
function exportLegendSVG() {
|
||||
if (legendItems.length === 0) {
|
||||
showNotification('Legende ist leer', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const itemHeight = 50;
|
||||
const width = 400;
|
||||
const height = legendItems.length * itemHeight + 60;
|
||||
|
||||
|
||||
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="${width}" height="${height}">
|
||||
<rect width="${width}" height="${height}" fill="white"/>
|
||||
<text x="20" y="30" font-family="Arial" font-size="18" font-weight="bold">Legende</text>
|
||||
<line x1="20" y1="40" x2="${width - 20}" y2="40" stroke="#ccc" stroke-width="1"/>`;
|
||||
|
||||
|
||||
legendItems.forEach((item, index) => {
|
||||
const y = 60 + index * itemHeight;
|
||||
svg += `<g transform="translate(20, ${y})">
|
||||
<g transform="scale(0.5)">${item.svg.replace(/<svg[^>]*>/, '').replace('</svg>', '')}</g>
|
||||
<text x="50" y="20" font-family="Arial" font-size="14" font-weight="bold">${item.name}</text>
|
||||
${item.description ? `<text x="50" y="35" font-family="Arial" font-size="11" fill="#666">${item.description}</text>` : ''}
|
||||
<text x="50" y="20" font-family="Arial" font-size="14" font-weight="bold">${escapeHtml(item.name)}</text>
|
||||
${item.description ? `<text x="50" y="35" font-family="Arial" font-size="11" fill="#666">${escapeHtml(item.description)}</text>` : ''}
|
||||
</g>`;
|
||||
});
|
||||
|
||||
@@ -838,586 +945,14 @@ function parseSvgPath(d, scaleX, flipY) {
|
||||
}
|
||||
|
||||
|
||||
// ========== TEXT-GENERATOR v4 ==========
|
||||
// Features: Farben, Skalierung, abknickbare Pfeile (korrigiert), Pfeilspitzengroesse, PNG/JPG, Speichern
|
||||
|
||||
var textGenState = {
|
||||
text: '',
|
||||
fontSize: 16,
|
||||
textColor: '#000000',
|
||||
frameColor: '#000000',
|
||||
shape: 'none',
|
||||
frameScale: 100,
|
||||
framePadding: 10,
|
||||
lineStyle: 'solid',
|
||||
lineWeight: 2,
|
||||
arrow: 'none',
|
||||
arrowLength: 40,
|
||||
arrowAngle: 0,
|
||||
arrowBend: 50,
|
||||
arrowSize: 10
|
||||
};
|
||||
|
||||
// Custom Symbols aus localStorage
|
||||
var customSymbols = [];
|
||||
|
||||
function initTextGenerator() {
|
||||
// Load custom symbols
|
||||
loadCustomSymbols();
|
||||
|
||||
var textInput = document.getElementById('customText');
|
||||
var fontSizeInput = document.getElementById('fontSize');
|
||||
var fontSizeValue = document.getElementById('fontSizeValue');
|
||||
var textColorInput = document.getElementById('textColor');
|
||||
var textColorValue = document.getElementById('textColorValue');
|
||||
var frameColorInput = document.getElementById('frameColor');
|
||||
var frameColorValue = document.getElementById('frameColorValue');
|
||||
var frameScaleInput = document.getElementById('frameScale');
|
||||
var frameScaleValue = document.getElementById('frameScaleValue');
|
||||
var framePaddingInput = document.getElementById('framePadding');
|
||||
var framePaddingValue = document.getElementById('framePaddingValue');
|
||||
var arrowLengthInput = document.getElementById('arrowLength');
|
||||
var arrowLengthValue = document.getElementById('arrowLengthValue');
|
||||
var arrowAngleInput = document.getElementById('arrowAngle');
|
||||
var arrowAngleValue = document.getElementById('arrowAngleValue');
|
||||
var arrowBendInput = document.getElementById('arrowBend');
|
||||
var arrowBendValue = document.getElementById('arrowBendValue');
|
||||
var arrowSizeInput = document.getElementById('arrowSize');
|
||||
var arrowSizeValue = document.getElementById('arrowSizeValue');
|
||||
|
||||
// Text input
|
||||
if (textInput) {
|
||||
textInput.addEventListener('input', function(e) {
|
||||
textGenState.text = e.target.value;
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Font size
|
||||
if (fontSizeInput) {
|
||||
fontSizeInput.addEventListener('input', function(e) {
|
||||
textGenState.fontSize = parseInt(e.target.value);
|
||||
fontSizeValue.textContent = e.target.value + 'px';
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Text color
|
||||
if (textColorInput) {
|
||||
textColorInput.addEventListener('input', function(e) {
|
||||
textGenState.textColor = e.target.value;
|
||||
textColorValue.textContent = e.target.value;
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Frame color
|
||||
if (frameColorInput) {
|
||||
frameColorInput.addEventListener('input', function(e) {
|
||||
textGenState.frameColor = e.target.value;
|
||||
frameColorValue.textContent = e.target.value;
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Frame scale
|
||||
if (frameScaleInput) {
|
||||
frameScaleInput.addEventListener('input', function(e) {
|
||||
textGenState.frameScale = parseInt(e.target.value);
|
||||
frameScaleValue.textContent = e.target.value + '%';
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Frame padding
|
||||
if (framePaddingInput) {
|
||||
framePaddingInput.addEventListener('input', function(e) {
|
||||
textGenState.framePadding = parseInt(e.target.value);
|
||||
framePaddingValue.textContent = e.target.value + 'px';
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Arrow length
|
||||
if (arrowLengthInput) {
|
||||
arrowLengthInput.addEventListener('input', function(e) {
|
||||
textGenState.arrowLength = parseInt(e.target.value);
|
||||
arrowLengthValue.textContent = e.target.value + 'px';
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Arrow angle
|
||||
if (arrowAngleInput) {
|
||||
arrowAngleInput.addEventListener('input', function(e) {
|
||||
textGenState.arrowAngle = parseInt(e.target.value);
|
||||
arrowAngleValue.textContent = e.target.value + '\u00B0';
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Arrow bend position
|
||||
if (arrowBendInput) {
|
||||
arrowBendInput.addEventListener('input', function(e) {
|
||||
textGenState.arrowBend = parseInt(e.target.value);
|
||||
arrowBendValue.textContent = e.target.value + '%';
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Arrow size
|
||||
if (arrowSizeInput) {
|
||||
arrowSizeInput.addEventListener('input', function(e) {
|
||||
textGenState.arrowSize = parseInt(e.target.value);
|
||||
arrowSizeValue.textContent = e.target.value + 'px';
|
||||
updateTextPreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Shape buttons
|
||||
document.querySelectorAll('.shape-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
document.querySelectorAll('.shape-btn').forEach(function(b) { b.classList.remove('active'); });
|
||||
btn.classList.add('active');
|
||||
textGenState.shape = btn.dataset.shape;
|
||||
updateFrameScaleVisibility();
|
||||
updateTextPreview();
|
||||
});
|
||||
});
|
||||
|
||||
// Line style buttons
|
||||
document.querySelectorAll('.line-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
document.querySelectorAll('.line-btn').forEach(function(b) { b.classList.remove('active'); });
|
||||
btn.classList.add('active');
|
||||
textGenState.lineStyle = btn.dataset.style;
|
||||
updateTextPreview();
|
||||
});
|
||||
});
|
||||
|
||||
// Line weight buttons
|
||||
document.querySelectorAll('.weight-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
document.querySelectorAll('.weight-btn').forEach(function(b) { b.classList.remove('active'); });
|
||||
btn.classList.add('active');
|
||||
textGenState.lineWeight = parseInt(btn.dataset.weight);
|
||||
updateTextPreview();
|
||||
});
|
||||
});
|
||||
|
||||
// Arrow buttons
|
||||
document.querySelectorAll('.arrow-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
document.querySelectorAll('.arrow-btn').forEach(function(b) { b.classList.remove('active'); });
|
||||
btn.classList.add('active');
|
||||
textGenState.arrow = btn.dataset.arrow;
|
||||
updateArrowDetailsVisibility();
|
||||
updateTextPreview();
|
||||
});
|
||||
});
|
||||
|
||||
updateFrameScaleVisibility();
|
||||
updateArrowDetailsVisibility();
|
||||
updateTextPreview();
|
||||
}
|
||||
|
||||
function updateFrameScaleVisibility() {
|
||||
var row = document.getElementById('frameScaleRow');
|
||||
if (row) {
|
||||
row.style.display = textGenState.shape === 'none' ? 'none' : 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
function updateArrowDetailsVisibility() {
|
||||
var row = document.getElementById('arrowDetailsRow');
|
||||
if (row) {
|
||||
row.style.display = textGenState.arrow === 'none' ? 'none' : 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
// ========== TEXT-GENERATOR UI ==========
|
||||
function toggleTextGenerator() {
|
||||
var generator = document.querySelector('.text-generator');
|
||||
generator.classList.toggle('collapsed');
|
||||
}
|
||||
|
||||
function getStrokeDasharray(style) {
|
||||
switch(style) {
|
||||
case 'dashed': return '8,4';
|
||||
case 'dotted': return '2,3';
|
||||
default: return 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function generateTextSVG() {
|
||||
var text = textGenState.text || 'Text';
|
||||
var fontSize = textGenState.fontSize;
|
||||
var textColor = textGenState.textColor;
|
||||
var frameColor = textGenState.frameColor;
|
||||
var shape = textGenState.shape;
|
||||
var frameScale = textGenState.frameScale / 100;
|
||||
var padding = textGenState.framePadding;
|
||||
var lineStyle = textGenState.lineStyle;
|
||||
var lineWeight = textGenState.lineWeight;
|
||||
var arrow = textGenState.arrow;
|
||||
var arrowLength = textGenState.arrowLength;
|
||||
var arrowAngle = textGenState.arrowAngle;
|
||||
var arrowBend = textGenState.arrowBend / 100;
|
||||
var arrowSize = textGenState.arrowSize;
|
||||
|
||||
// Zeilen aufteilen
|
||||
var lines = text.split('\n');
|
||||
if (lines.length === 0) lines = ['Text'];
|
||||
|
||||
// Berechne die laengste Zeile
|
||||
var maxLineLength = 0;
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].length > maxLineLength) {
|
||||
maxLineLength = lines[i].length;
|
||||
}
|
||||
}
|
||||
if (maxLineLength === 0) maxLineLength = 4;
|
||||
|
||||
// Dimensionen berechnen
|
||||
var charWidth = fontSize * 0.6;
|
||||
var lineHeight = fontSize * 1.3;
|
||||
var textWidth = maxLineLength * charWidth;
|
||||
var textHeight = lines.length * lineHeight;
|
||||
|
||||
// Basis-SVG-Groesse (Text + Padding)
|
||||
var baseWidth = textWidth + (padding * 2);
|
||||
var baseHeight = textHeight + (padding * 2);
|
||||
|
||||
// Rahmen mit Skalierung
|
||||
var frameWidth = baseWidth * frameScale;
|
||||
var frameHeight = baseHeight * frameScale;
|
||||
|
||||
// Mindestgroesse
|
||||
if (frameWidth < 40) frameWidth = 40;
|
||||
if (frameHeight < 30) frameHeight = 30;
|
||||
|
||||
// Pfeil-Raum berechnen (inkl. Pfeilspitze)
|
||||
var arrowSpace = (arrow !== 'none') ? arrowLength + arrowSize + 5 : 0;
|
||||
|
||||
// SVG-Groesse mit Pfeil-Raum
|
||||
var svgWidth = frameWidth;
|
||||
var svgHeight = frameHeight;
|
||||
var offsetX = 0;
|
||||
var offsetY = 0;
|
||||
|
||||
if (arrow === 'left') {
|
||||
svgWidth += arrowSpace;
|
||||
offsetX = arrowSpace;
|
||||
} else if (arrow === 'right') {
|
||||
svgWidth += arrowSpace;
|
||||
} else if (arrow === 'top') {
|
||||
svgHeight += arrowSpace;
|
||||
offsetY = arrowSpace;
|
||||
} else if (arrow === 'bottom') {
|
||||
svgHeight += arrowSpace;
|
||||
}
|
||||
|
||||
var cx = offsetX + frameWidth / 2;
|
||||
var cy = offsetY + frameHeight / 2;
|
||||
|
||||
var dashArray = getStrokeDasharray(lineStyle);
|
||||
var dashAttr = dashArray !== 'none' ? ' stroke-dasharray="' + dashArray + '"' : '';
|
||||
|
||||
var shapeSvg = '';
|
||||
var shapeX = offsetX + lineWeight / 2;
|
||||
var shapeY = offsetY + lineWeight / 2;
|
||||
var shapeW = frameWidth - lineWeight;
|
||||
var shapeH = frameHeight - lineWeight;
|
||||
|
||||
switch(shape) {
|
||||
case 'rect':
|
||||
shapeSvg = '<rect x="' + shapeX + '" y="' + shapeY + '" width="' + shapeW + '" height="' + shapeH + '" fill="none" stroke="' + frameColor + '" stroke-width="' + lineWeight + '"' + dashAttr + '/>';
|
||||
break;
|
||||
case 'square':
|
||||
var squareSize = Math.max(shapeW, shapeH);
|
||||
var sqX = cx - squareSize / 2;
|
||||
var sqY = cy - squareSize / 2;
|
||||
shapeSvg = '<rect x="' + sqX + '" y="' + sqY + '" width="' + squareSize + '" height="' + squareSize + '" fill="none" stroke="' + frameColor + '" stroke-width="' + lineWeight + '"' + dashAttr + '/>';
|
||||
break;
|
||||
case 'circle':
|
||||
var radius = Math.max(shapeW, shapeH) / 2;
|
||||
shapeSvg = '<circle cx="' + cx + '" cy="' + cy + '" r="' + (radius - lineWeight / 2) + '" fill="none" stroke="' + frameColor + '" stroke-width="' + lineWeight + '"' + dashAttr + '/>';
|
||||
break;
|
||||
case 'oval':
|
||||
var rx = shapeW / 2;
|
||||
var ry = shapeH / 2;
|
||||
shapeSvg = '<ellipse cx="' + cx + '" cy="' + cy + '" rx="' + (rx - lineWeight / 2) + '" ry="' + (ry - lineWeight / 2) + '" fill="none" stroke="' + frameColor + '" stroke-width="' + lineWeight + '"' + dashAttr + '/>';
|
||||
break;
|
||||
case 'diamond':
|
||||
var halfW = shapeW / 2;
|
||||
var halfH = shapeH / 2;
|
||||
shapeSvg = '<polygon points="' + cx + ',' + (cy - halfH) + ' ' + (cx + halfW) + ',' + cy + ' ' + cx + ',' + (cy + halfH) + ' ' + (cx - halfW) + ',' + cy + '" fill="none" stroke="' + frameColor + '" stroke-width="' + lineWeight + '"' + dashAttr + '/>';
|
||||
break;
|
||||
}
|
||||
|
||||
// Pfeil generieren
|
||||
var arrowSvg = '';
|
||||
if (arrow !== 'none') {
|
||||
arrowSvg = generateArrowPath(arrow, cx, cy, frameWidth, frameHeight, offsetX, offsetY, arrowLength, arrowAngle, arrowBend, frameColor, lineWeight, dashAttr, arrowSize);
|
||||
}
|
||||
|
||||
// Text-Elemente erzeugen
|
||||
var textSvg = '<text x="' + cx + '" font-family="Arial, sans-serif" font-size="' + fontSize + '" fill="' + textColor + '" text-anchor="middle">';
|
||||
|
||||
var totalTextHeight = lines.length * lineHeight;
|
||||
var startY = cy - (totalTextHeight / 2) + (fontSize * 0.8);
|
||||
|
||||
for (var j = 0; j < lines.length; j++) {
|
||||
var lineY = startY + (j * lineHeight);
|
||||
var lineText = lines[j] || ' ';
|
||||
lineText = lineText.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
textSvg += '<tspan x="' + cx + '" y="' + lineY + '">' + lineText + '</tspan>';
|
||||
}
|
||||
textSvg += '</text>';
|
||||
|
||||
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + svgWidth + ' ' + svgHeight + '" width="' + svgWidth + '" height="' + svgHeight + '">' + shapeSvg + arrowSvg + textSvg + '</svg>';
|
||||
}
|
||||
|
||||
function generateArrowPath(direction, cx, cy, frameWidth, frameHeight, offsetX, offsetY, length, angle, bendPos, color, weight, dashAttr, arrowSize) {
|
||||
var startX, startY, midX, midY, endX, endY;
|
||||
var angleRad = angle * Math.PI / 180;
|
||||
|
||||
// Startpunkt am Rahmen
|
||||
switch(direction) {
|
||||
case 'top':
|
||||
startX = cx;
|
||||
startY = offsetY;
|
||||
// Erster Teil geht gerade nach oben bis zum Knickpunkt
|
||||
midX = startX;
|
||||
midY = startY - length * bendPos;
|
||||
// Zweiter Teil knickt ab
|
||||
endX = midX + Math.sin(angleRad) * (length * (1 - bendPos));
|
||||
endY = midY - Math.cos(angleRad) * (length * (1 - bendPos));
|
||||
break;
|
||||
case 'bottom':
|
||||
startX = cx;
|
||||
startY = offsetY + frameHeight;
|
||||
midX = startX;
|
||||
midY = startY + length * bendPos;
|
||||
endX = midX + Math.sin(angleRad) * (length * (1 - bendPos));
|
||||
endY = midY + Math.cos(angleRad) * (length * (1 - bendPos));
|
||||
break;
|
||||
case 'left':
|
||||
startX = offsetX;
|
||||
startY = cy;
|
||||
midX = startX - length * bendPos;
|
||||
midY = startY;
|
||||
endX = midX - Math.cos(angleRad) * (length * (1 - bendPos));
|
||||
endY = midY + Math.sin(angleRad) * (length * (1 - bendPos));
|
||||
break;
|
||||
case 'right':
|
||||
startX = offsetX + frameWidth;
|
||||
startY = cy;
|
||||
midX = startX + length * bendPos;
|
||||
midY = startY;
|
||||
endX = midX + Math.cos(angleRad) * (length * (1 - bendPos));
|
||||
endY = midY + Math.sin(angleRad) * (length * (1 - bendPos));
|
||||
break;
|
||||
}
|
||||
|
||||
// Pfad erstellen
|
||||
var pathD;
|
||||
if (angle !== 0 && bendPos > 0 && bendPos < 1) {
|
||||
// Mit Knick
|
||||
pathD = 'M ' + startX + ' ' + startY + ' L ' + midX + ' ' + midY + ' L ' + endX + ' ' + endY;
|
||||
} else {
|
||||
// Ohne Knick - gerade Linie
|
||||
pathD = 'M ' + startX + ' ' + startY + ' L ' + endX + ' ' + endY;
|
||||
}
|
||||
|
||||
// Pfeilspitze: Richtung basiert auf dem LETZTEN Segment
|
||||
var lastSegmentStartX, lastSegmentStartY;
|
||||
if (angle !== 0 && bendPos > 0 && bendPos < 1) {
|
||||
// Letztes Segment ist von mid zu end
|
||||
lastSegmentStartX = midX;
|
||||
lastSegmentStartY = midY;
|
||||
} else {
|
||||
// Letztes Segment ist von start zu end
|
||||
lastSegmentStartX = startX;
|
||||
lastSegmentStartY = startY;
|
||||
}
|
||||
|
||||
// Winkel des letzten Segments berechnen
|
||||
var arrowHeadAngle = Math.atan2(endY - lastSegmentStartY, endX - lastSegmentStartX);
|
||||
|
||||
// Pfeilspitze Punkte
|
||||
var ah1x = endX - arrowSize * Math.cos(arrowHeadAngle - Math.PI / 6);
|
||||
var ah1y = endY - arrowSize * Math.sin(arrowHeadAngle - Math.PI / 6);
|
||||
var ah2x = endX - arrowSize * Math.cos(arrowHeadAngle + Math.PI / 6);
|
||||
var ah2y = endY - arrowSize * Math.sin(arrowHeadAngle + Math.PI / 6);
|
||||
|
||||
var arrowHead = '<polygon points="' + endX + ',' + endY + ' ' + ah1x + ',' + ah1y + ' ' + ah2x + ',' + ah2y + '" fill="' + color + '"/>';
|
||||
|
||||
return '<path d="' + pathD + '" fill="none" stroke="' + color + '" stroke-width="' + weight + '"' + dashAttr + '/>' + arrowHead;
|
||||
}
|
||||
|
||||
function updateTextPreview() {
|
||||
var preview = document.getElementById('textPreview');
|
||||
if (preview) {
|
||||
preview.innerHTML = generateTextSVG();
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktion: SVG zu Canvas rendern
|
||||
async function svgToCanvas(svg, scale) {
|
||||
var parser = new DOMParser();
|
||||
var svgDoc = parser.parseFromString(svg, 'image/svg+xml');
|
||||
var svgEl = svgDoc.documentElement;
|
||||
var svgWidth = parseFloat(svgEl.getAttribute('width')) || 100;
|
||||
var svgHeight = parseFloat(svgEl.getAttribute('height')) || 100;
|
||||
|
||||
if (!scale) {
|
||||
scale = Math.max(200 / Math.min(svgWidth, svgHeight), 1);
|
||||
scale = Math.min(scale, 512 / Math.max(svgWidth, svgHeight));
|
||||
}
|
||||
|
||||
var canvasWidth = Math.round(svgWidth * scale);
|
||||
var canvasHeight = Math.round(svgHeight * scale);
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
canvas.width = canvasWidth;
|
||||
canvas.height = canvasHeight;
|
||||
|
||||
var img = new Image();
|
||||
var svgBlob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });
|
||||
var url = URL.createObjectURL(svgBlob);
|
||||
|
||||
await new Promise(function(resolve, reject) {
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
img.src = url;
|
||||
});
|
||||
|
||||
ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);
|
||||
URL.revokeObjectURL(url);
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
async function copyTextAsImage() {
|
||||
var svg = generateTextSVG();
|
||||
|
||||
try {
|
||||
var canvas = await svgToCanvas(svg);
|
||||
|
||||
canvas.toBlob(async function(blob) {
|
||||
try {
|
||||
await navigator.clipboard.write([
|
||||
new ClipboardItem({ 'image/png': blob })
|
||||
]);
|
||||
showNotification('In Zwischenablage kopiert!');
|
||||
} catch (err) {
|
||||
var link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = 'text-symbol.png';
|
||||
link.click();
|
||||
showNotification('PNG heruntergeladen');
|
||||
}
|
||||
}, 'image/png');
|
||||
} catch (err) {
|
||||
console.error('Fehler:', err);
|
||||
showNotification('Fehler beim Kopieren', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
function downloadTextSVG() {
|
||||
var svg = generateTextSVG();
|
||||
var blob = new Blob([svg], { type: 'image/svg+xml' });
|
||||
var url = URL.createObjectURL(blob);
|
||||
var link = document.createElement('a');
|
||||
link.href = url;
|
||||
var filename = textGenState.text ? textGenState.text.replace(/\n/g, '_').replace(/[^a-zA-Z0-9_-]/g, '').substring(0, 20) : 'symbol';
|
||||
link.download = 'text-' + filename + '.svg';
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
showNotification('SVG heruntergeladen!');
|
||||
}
|
||||
|
||||
async function downloadTextPNG() {
|
||||
var svg = generateTextSVG();
|
||||
try {
|
||||
var canvas = await svgToCanvas(svg, 2); // 2x Skalierung fuer bessere Qualitaet
|
||||
|
||||
canvas.toBlob(function(blob) {
|
||||
var link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
var filename = textGenState.text ? textGenState.text.replace(/\n/g, '_').replace(/[^a-zA-Z0-9_-]/g, '').substring(0, 20) : 'symbol';
|
||||
link.download = 'text-' + filename + '.png';
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
showNotification('PNG heruntergeladen!');
|
||||
}, 'image/png');
|
||||
} catch (err) {
|
||||
console.error('Fehler:', err);
|
||||
showNotification('Fehler beim PNG-Export', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function downloadTextJPG() {
|
||||
var svg = generateTextSVG();
|
||||
try {
|
||||
var canvas = await svgToCanvas(svg, 2);
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
// Weisser Hintergrund fuer JPG
|
||||
var tempCanvas = document.createElement('canvas');
|
||||
tempCanvas.width = canvas.width;
|
||||
tempCanvas.height = canvas.height;
|
||||
var tempCtx = tempCanvas.getContext('2d');
|
||||
tempCtx.fillStyle = '#FFFFFF';
|
||||
tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
|
||||
tempCtx.drawImage(canvas, 0, 0);
|
||||
|
||||
tempCanvas.toBlob(function(blob) {
|
||||
var link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
var filename = textGenState.text ? textGenState.text.replace(/\n/g, '_').replace(/[^a-zA-Z0-9_-]/g, '').substring(0, 20) : 'symbol';
|
||||
link.download = 'text-' + filename + '.jpg';
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
showNotification('JPG heruntergeladen!');
|
||||
}, 'image/jpeg', 0.95);
|
||||
} catch (err) {
|
||||
console.error('Fehler:', err);
|
||||
showNotification('Fehler beim JPG-Export', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
function downloadTextDXF() {
|
||||
var svg = generateTextSVG();
|
||||
var dxf = svgToDxf(svg, 1);
|
||||
var blob = new Blob([dxf], { type: 'application/dxf' });
|
||||
var url = URL.createObjectURL(blob);
|
||||
var link = document.createElement('a');
|
||||
link.href = url;
|
||||
var filename = textGenState.text ? textGenState.text.replace(/\n/g, '_').replace(/[^a-zA-Z0-9_-]/g, '').substring(0, 20) : 'symbol';
|
||||
link.download = 'text-' + filename + '.dxf';
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
showNotification('DXF heruntergeladen!');
|
||||
}
|
||||
|
||||
function addTextToLegend() {
|
||||
var svg = generateTextSVG();
|
||||
var text = textGenState.text || 'Text';
|
||||
var displayName = text.replace(/\n/g, ' ').substring(0, 30);
|
||||
|
||||
legendItems.push({
|
||||
id: 'custom_text_' + Date.now(),
|
||||
name: displayName,
|
||||
svg: svg,
|
||||
description: ''
|
||||
});
|
||||
|
||||
updateLegendCount();
|
||||
saveLegendToStorage();
|
||||
showNotification('Zur Legende hinzugefuegt!');
|
||||
}
|
||||
// Custom Symbols aus localStorage
|
||||
var customSymbols = [];
|
||||
|
||||
// ========== CUSTOM SYMBOLS STORAGE ==========
|
||||
|
||||
|
||||
@@ -1,859 +0,0 @@
|
||||
// ============================================
|
||||
// SYMBOL-DEFINITIONEN
|
||||
// Gutachter Symbolbibliothek v2.0
|
||||
// ============================================
|
||||
|
||||
const SYMBOLS = {
|
||||
// ========== SCHADENSARTEN ==========
|
||||
schaeden: {
|
||||
name: "Schadensarten",
|
||||
icon: "🔥",
|
||||
items: [
|
||||
{
|
||||
id: "wasserschaden",
|
||||
name: "Wasserschaden",
|
||||
filename: "wasserschaden_symbol.svg",
|
||||
tags: ["wasser", "feuchtigkeit", "nass"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M32 4 C32 4 12 28 12 42 C12 53 21 60 32 60 C43 60 52 53 52 42 C52 28 32 4 32 4 Z" fill="#3b82f6" stroke="#2563eb" stroke-width="2"/><ellipse cx="24" cy="38" rx="6" ry="10" fill="#93c5fd" opacity="0.5"/><circle cx="22" cy="32" r="3" fill="#dbeafe" opacity="0.7"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "brandschaden",
|
||||
name: "Brandschaden",
|
||||
filename: "brandschaden_symbol.svg",
|
||||
tags: ["feuer", "brand", "flamme"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M32 2 C32 2 18 18 18 34 C18 42 22 50 28 54 C24 48 24 40 28 34 C28 42 32 48 38 50 C34 44 36 36 40 32 C40 40 44 46 48 48 C50 44 52 38 52 34 C52 18 32 2 32 2 Z" fill="#f97316" stroke="#ea580c" stroke-width="1"/><path d="M32 14 C32 14 22 26 22 38 C22 44 26 50 32 52 C28 48 28 42 32 38 C32 44 36 48 40 48 C44 44 46 40 46 36 C46 26 32 14 32 14 Z" fill="#fb923c"/><path d="M32 26 C32 26 26 34 26 42 C26 46 28 50 32 52 C30 48 30 44 32 42 C34 46 36 48 38 48 C40 46 42 44 42 42 C42 34 32 26 32 26 Z" fill="#fbbf24"/><ellipse cx="32" cy="48" rx="4" ry="6" fill="#fef08a"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "rauchschaden",
|
||||
name: "Rauchschaden",
|
||||
filename: "rauchschaden_symbol.svg",
|
||||
tags: ["rauch", "russ", "qualm"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><ellipse cx="32" cy="54" rx="14" ry="6" fill="#4b5563" opacity="0.9"/><ellipse cx="24" cy="42" rx="10" ry="8" fill="#6b7280" opacity="0.8"/><ellipse cx="40" cy="40" rx="12" ry="9" fill="#6b7280" opacity="0.75"/><ellipse cx="32" cy="28" rx="14" ry="10" fill="#9ca3af" opacity="0.7"/><ellipse cx="20" cy="24" rx="8" ry="7" fill="#9ca3af" opacity="0.6"/><ellipse cx="44" cy="26" rx="9" ry="7" fill="#9ca3af" opacity="0.6"/><ellipse cx="32" cy="14" rx="10" ry="7" fill="#d1d5db" opacity="0.5"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "leitungswasser",
|
||||
name: "Leitungswasser / Rohrbruch",
|
||||
filename: "leitungswasserschaden_symbol.svg",
|
||||
tags: ["rohr", "leitung", "bruch", "wasser"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="2" y="24" width="22" height="16" rx="2" fill="#71717a" stroke="#52525b" stroke-width="2"/><rect x="20" y="22" width="6" height="20" rx="1" fill="#a1a1aa" stroke="#71717a" stroke-width="1"/><rect x="40" y="24" width="22" height="16" rx="2" fill="#71717a" stroke="#52525b" stroke-width="2"/><rect x="38" y="22" width="6" height="20" rx="1" fill="#a1a1aa" stroke="#71717a" stroke-width="1"/><path d="M26 22 L28 28 L26 32 L28 36 L26 42" stroke="#dc2626" stroke-width="2" fill="none" stroke-linecap="round"/><path d="M38 22 L36 28 L38 32 L36 36 L38 42" stroke="#dc2626" stroke-width="2" fill="none" stroke-linecap="round"/><path d="M30 28 Q34 20 38 10" stroke="#3b82f6" stroke-width="3" fill="none" stroke-linecap="round"/><path d="M31 32 Q36 32 42 28" stroke="#3b82f6" stroke-width="3" fill="none" stroke-linecap="round"/><path d="M30 36 Q34 44 38 54" stroke="#3b82f6" stroke-width="3" fill="none" stroke-linecap="round"/><circle cx="40" cy="8" r="3" fill="#60a5fa"/><circle cx="36" cy="56" r="3" fill="#60a5fa"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "schimmel",
|
||||
name: "Schimmelschaden",
|
||||
filename: "schimmelschaden_symbol.svg",
|
||||
tags: ["schimmel", "pilz", "feucht", "sporen"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><ellipse cx="32" cy="34" rx="24" ry="20" fill="#1f2937" opacity="0.3"/><ellipse cx="24" cy="28" rx="10" ry="8" fill="#166534"/><ellipse cx="38" cy="32" rx="12" ry="10" fill="#15803d"/><ellipse cx="28" cy="40" rx="9" ry="7" fill="#166534"/><ellipse cx="42" cy="24" rx="7" ry="6" fill="#14532d"/><ellipse cx="18" cy="38" rx="6" ry="5" fill="#15803d"/><circle cx="20" cy="26" r="2" fill="#052e16"/><circle cx="30" cy="30" r="2.5" fill="#052e16"/><circle cx="40" cy="28" r="2" fill="#052e16"/><circle cx="35" cy="38" r="2" fill="#052e16"/><circle cx="52" cy="12" r="10" fill="#dc2626"/><text x="52" y="17" font-family="Arial" font-size="14" font-weight="bold" fill="white" text-anchor="middle">!</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "sturm",
|
||||
name: "Sturmschaden",
|
||||
filename: "sturmschaden_symbol.svg",
|
||||
tags: ["sturm", "wind", "dach", "unwetter"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="14" y="32" width="28" height="24" fill="#78716c" stroke="#57534e" stroke-width="2"/><polygon points="10,32 28,14 50,32" fill="#991b1b" stroke="#7f1d1d" stroke-width="2"/><polygon points="38,18 46,26 50,22 42,14" fill="#78716c" stroke="#57534e" stroke-width="1"/><rect x="18" y="38" width="8" height="8" fill="#bfdbfe" stroke="#57534e" stroke-width="1"/><rect x="30" y="38" width="8" height="8" fill="#bfdbfe" stroke="#57534e" stroke-width="1"/><rect x="24" y="46" width="8" height="10" fill="#44403c"/><path d="M48 10 Q56 10 54 6" stroke="#6b7280" stroke-width="3" fill="none" stroke-linecap="round"/><path d="M50 18 Q60 18 58 14" stroke="#6b7280" stroke-width="3" fill="none" stroke-linecap="round"/><path d="M52 26 Q62 26 60 22" stroke="#6b7280" stroke-width="2" fill="none" stroke-linecap="round"/><rect x="54" y="8" width="6" height="3" fill="#991b1b" transform="rotate(25 57 9)"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "einbruch",
|
||||
name: "Einbruchschaden",
|
||||
filename: "einbruchschaden_symbol.svg",
|
||||
tags: ["einbruch", "diebstahl", "fenster", "tür"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="8" y="8" width="48" height="48" fill="none" stroke="#57534e" stroke-width="4" rx="2"/><line x1="32" y1="8" x2="32" y2="56" stroke="#57534e" stroke-width="3"/><line x1="8" y1="32" x2="56" y2="32" stroke="#57534e" stroke-width="3"/><polygon points="12,12 20,20 12,28 18,20" fill="#bfdbfe" stroke="#93c5fd" stroke-width="1"/><polygon points="20,14 28,12 24,24 16,20" fill="#dbeafe" stroke="#93c5fd" stroke-width="1"/><polygon points="10,36 18,42 12,52 8,44" fill="#bfdbfe" stroke="#93c5fd" stroke-width="1"/><rect x="36" y="16" width="4" height="32" rx="1" fill="#1f2937" transform="rotate(20 38 32)"/><rect x="34" y="14" width="8" height="6" rx="1" fill="#1f2937" transform="rotate(20 38 17)"/><circle cx="52" cy="52" r="8" fill="#dc2626"/><line x1="48" y1="48" x2="56" y2="56" stroke="white" stroke-width="2" stroke-linecap="round"/><line x1="56" y1="48" x2="48" y2="56" stroke="white" stroke-width="2" stroke-linecap="round"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "elektro",
|
||||
name: "Elektroschaden",
|
||||
filename: "elektroschaden_symbol.svg",
|
||||
tags: ["elektro", "strom", "blitz", "kurzschluss"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><polygon points="36,2 20,28 30,28 24,46 44,18 34,18" fill="#fbbf24" stroke="#f59e0b" stroke-width="2" stroke-linejoin="round"/><rect x="12" y="38" width="24" height="22" rx="3" fill="#e5e7eb" stroke="#9ca3af" stroke-width="2"/><circle cx="20" cy="46" r="3" fill="#1f2937"/><circle cx="28" cy="46" r="3" fill="#1f2937"/><rect x="22" y="52" width="4" height="4" rx="1" fill="#1f2937"/><line x1="40" y1="42" x2="48" y2="38" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/><line x1="42" y1="48" x2="52" y2="46" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/><line x1="40" y1="54" x2="50" y2="56" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/><polygon points="50,36 46,42 48,42 46,48 52,40 50,40" fill="#fbbf24"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "hagel",
|
||||
name: "Hagelschaden",
|
||||
filename: "hagelschaden_symbol.svg",
|
||||
tags: ["hagel", "eis", "dellen", "unwetter"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><ellipse cx="32" cy="20" rx="24" ry="14" fill="#6b7280"/><ellipse cx="32" cy="18" rx="22" ry="12" fill="#9ca3af"/><circle cx="14" cy="36" r="6" fill="#e0f2fe" stroke="#7dd3fc" stroke-width="2"/><circle cx="32" cy="40" r="7" fill="#e0f2fe" stroke="#7dd3fc" stroke-width="2"/><circle cx="50" cy="34" r="5" fill="#e0f2fe" stroke="#7dd3fc" stroke-width="2"/><circle cx="22" cy="52" r="6" fill="#e0f2fe" stroke="#7dd3fc" stroke-width="2"/><circle cx="44" cy="50" r="5" fill="#e0f2fe" stroke="#7dd3fc" stroke-width="2"/><line x1="14" y1="26" x2="14" y2="30" stroke="#7dd3fc" stroke-width="2"/><line x1="32" y1="24" x2="32" y2="32" stroke="#7dd3fc" stroke-width="2"/><line x1="50" y1="26" x2="50" y2="28" stroke="#7dd3fc" stroke-width="2"/><line x1="22" y1="28" x2="22" y2="46" stroke="#7dd3fc" stroke-width="1.5"/><line x1="44" y1="28" x2="44" y2="44" stroke="#7dd3fc" stroke-width="1.5"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vandalismus",
|
||||
name: "Vandalismus",
|
||||
filename: "vandalismus_symbol.svg",
|
||||
tags: ["vandalismus", "graffiti", "zerstörung", "sachbeschädigung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="20" width="56" height="40" fill="#d6d3d1" stroke="#78716c" stroke-width="2"/><path d="M10 30 Q20 25 30 35 Q40 45 50 30" stroke="#dc2626" stroke-width="4" fill="none" stroke-linecap="round"/><path d="M15 45 Q25 55 35 40 Q45 25 55 45" stroke="#2563eb" stroke-width="3" fill="none" stroke-linecap="round"/><text x="32" y="54" font-family="Arial" font-size="10" fill="#000" text-anchor="middle" font-style="italic">TAG</text><circle cx="52" cy="12" r="10" fill="#dc2626"/><line x1="48" y1="8" x2="56" y2="16" stroke="white" stroke-width="2.5" stroke-linecap="round"/><line x1="56" y1="8" x2="48" y2="16" stroke="white" stroke-width="2.5" stroke-linecap="round"/></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== WERKZEUGE & MARKIERUNGEN ==========
|
||||
werkzeuge: {
|
||||
name: "Werkzeuge & Markierungen",
|
||||
icon: "🔧",
|
||||
items: [
|
||||
{
|
||||
id: "massstab",
|
||||
name: "Maßstab 1m",
|
||||
filename: "massstab_1m.svg",
|
||||
tags: ["maßstab", "meter", "lineal", "messen"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="24" width="56" height="16" fill="#fef3c7" stroke="#f59e0b" stroke-width="2"/><g stroke="#92400e" stroke-width="1"><line x1="4" y1="28" x2="4" y2="36"/><line x1="10" y1="30" x2="10" y2="34"/><line x1="16" y1="30" x2="16" y2="34"/><line x1="22" y1="30" x2="22" y2="34"/><line x1="28" y1="30" x2="28" y2="34"/><line x1="32" y1="28" x2="32" y2="36"/><line x1="38" y1="30" x2="38" y2="34"/><line x1="44" y1="30" x2="44" y2="34"/><line x1="50" y1="30" x2="50" y2="34"/><line x1="56" y1="30" x2="56" y2="34"/><line x1="60" y1="28" x2="60" y2="36"/></g><text x="8" y="22" font-family="Arial" font-size="8" fill="#92400e">0</text><text x="28" y="22" font-family="Arial" font-size="8" fill="#92400e">50</text><text x="54" y="22" font-family="Arial" font-size="8" fill="#92400e">100</text><text x="32" y="48" font-family="Arial" font-size="10" fill="#92400e" text-anchor="middle">1 Meter</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "messpunkt",
|
||||
name: "Messpunkt",
|
||||
filename: "messpunkt.svg",
|
||||
tags: ["messpunkt", "markierung", "punkt", "messen"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="24" fill="none" stroke="#dc2626" stroke-width="3"/><circle cx="32" cy="32" r="16" fill="none" stroke="#dc2626" stroke-width="2"/><circle cx="32" cy="32" r="6" fill="#dc2626"/><line x1="32" y1="2" x2="32" y2="14" stroke="#dc2626" stroke-width="2"/><line x1="32" y1="50" x2="32" y2="62" stroke="#dc2626" stroke-width="2"/><line x1="2" y1="32" x2="14" y2="32" stroke="#dc2626" stroke-width="2"/><line x1="50" y1="32" x2="62" y2="32" stroke="#dc2626" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "kamera",
|
||||
name: "Fotostandpunkt",
|
||||
filename: "fotostandpunkt.svg",
|
||||
tags: ["foto", "kamera", "standpunkt", "aufnahme"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="8" y="20" width="48" height="32" rx="4" fill="#374151" stroke="#1f2937" stroke-width="2"/><circle cx="32" cy="36" r="12" fill="#1f2937" stroke="#6b7280" stroke-width="2"/><circle cx="32" cy="36" r="8" fill="#3b82f6"/><circle cx="32" cy="36" r="4" fill="#1e3a5f"/><rect x="20" y="14" width="24" height="8" rx="2" fill="#4b5563"/><circle cx="48" cy="26" r="3" fill="#fbbf24"/><rect x="10" y="26" width="6" height="4" rx="1" fill="#6b7280"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "lupe",
|
||||
name: "Detailbereich",
|
||||
filename: "detailbereich.svg",
|
||||
tags: ["detail", "lupe", "vergrößerung", "zoom"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="26" cy="26" r="20" fill="#dbeafe" stroke="#3b82f6" stroke-width="3"/><circle cx="26" cy="26" r="14" fill="white" stroke="#93c5fd" stroke-width="2"/><line x1="40" y1="40" x2="58" y2="58" stroke="#3b82f6" stroke-width="6" stroke-linecap="round"/><line x1="40" y1="40" x2="56" y2="56" stroke="#60a5fa" stroke-width="3" stroke-linecap="round"/><text x="26" y="30" font-family="Arial" font-size="14" fill="#3b82f6" text-anchor="middle" font-weight="bold">+</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "notiz",
|
||||
name: "Notiz / Hinweis",
|
||||
filename: "notiz_hinweis.svg",
|
||||
tags: ["notiz", "hinweis", "anmerkung", "text"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M8 4 L56 4 L56 48 L40 48 L40 60 L8 60 Z" fill="#fef3c7" stroke="#f59e0b" stroke-width="2"/><path d="M40 48 L56 48 L40 60 Z" fill="#fcd34d" stroke="#f59e0b" stroke-width="2"/><line x1="14" y1="16" x2="50" y2="16" stroke="#d97706" stroke-width="2"/><line x1="14" y1="26" x2="50" y2="26" stroke="#d97706" stroke-width="2"/><line x1="14" y1="36" x2="50" y2="36" stroke="#d97706" stroke-width="2"/><line x1="14" y1="46" x2="34" y2="46" stroke="#d97706" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "warnung",
|
||||
name: "Warnung / Achtung",
|
||||
filename: "warnung_achtung.svg",
|
||||
tags: ["warnung", "achtung", "gefahr", "vorsicht"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><polygon points="32,4 60,56 4,56" fill="#fbbf24" stroke="#f59e0b" stroke-width="2" stroke-linejoin="round"/><polygon points="32,10 54,52 10,52" fill="#fef3c7"/><text x="32" y="46" font-family="Arial" font-size="32" fill="#92400e" text-anchor="middle" font-weight="bold">!</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "info",
|
||||
name: "Information",
|
||||
filename: "information.svg",
|
||||
tags: ["info", "information", "hinweis", "details"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="#3b82f6" stroke="#2563eb" stroke-width="2"/><circle cx="32" cy="16" r="4" fill="white"/><rect x="28" y="26" width="8" height="24" rx="2" fill="white"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "haken",
|
||||
name: "Erledigt / OK",
|
||||
filename: "erledigt_ok.svg",
|
||||
tags: ["ok", "erledigt", "fertig", "haken", "check"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="#22c55e" stroke="#16a34a" stroke-width="2"/><polyline points="18,32 28,42 46,22" fill="none" stroke="white" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "kreuz",
|
||||
name: "Fehler / Mangel",
|
||||
filename: "fehler_mangel.svg",
|
||||
tags: ["fehler", "mangel", "falsch", "kreuz"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="#dc2626" stroke="#b91c1c" stroke-width="2"/><line x1="20" y1="20" x2="44" y2="44" stroke="white" stroke-width="6" stroke-linecap="round"/><line x1="44" y1="20" x2="20" y2="44" stroke="white" stroke-width="6" stroke-linecap="round"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "fragezeichen",
|
||||
name: "Unklar / Prüfen",
|
||||
filename: "unklar_pruefen.svg",
|
||||
tags: ["unklar", "prüfen", "frage", "unbekannt"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="#f59e0b" stroke="#d97706" stroke-width="2"/><text x="32" y="44" font-family="Arial" font-size="36" fill="white" text-anchor="middle" font-weight="bold">?</text></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== BAUTEILE ==========
|
||||
bauteile: {
|
||||
name: "Bauteile",
|
||||
icon: "🏗️",
|
||||
items: [
|
||||
{
|
||||
id: "fenster",
|
||||
name: "Fenster",
|
||||
filename: "bauteil_fenster.svg",
|
||||
tags: ["fenster", "verglasung", "rahmen"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="8" y="4" width="48" height="56" fill="#bfdbfe" stroke="#3b82f6" stroke-width="3"/><line x1="32" y1="4" x2="32" y2="60" stroke="#3b82f6" stroke-width="3"/><line x1="8" y1="32" x2="56" y2="32" stroke="#3b82f6" stroke-width="3"/><rect x="12" y="8" width="16" height="20" fill="#dbeafe"/><rect x="36" y="8" width="16" height="20" fill="#dbeafe"/><rect x="12" y="36" width="16" height="20" fill="#dbeafe"/><rect x="36" y="36" width="16" height="20" fill="#dbeafe"/><circle cx="28" cy="32" r="2" fill="#1e40af"/><circle cx="36" cy="32" r="2" fill="#1e40af"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "tuer",
|
||||
name: "Tür",
|
||||
filename: "bauteil_tuer.svg",
|
||||
tags: ["tür", "türblatt", "eingang"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="12" y="4" width="40" height="56" fill="#92400e" stroke="#78350f" stroke-width="3"/><rect x="16" y="8" width="14" height="20" fill="#a16207" rx="1"/><rect x="34" y="8" width="14" height="20" fill="#a16207" rx="1"/><rect x="16" y="32" width="14" height="20" fill="#a16207" rx="1"/><rect x="34" y="32" width="14" height="20" fill="#a16207" rx="1"/><circle cx="44" cy="34" r="3" fill="#fbbf24" stroke="#92400e" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "wand",
|
||||
name: "Wand (Mauerwerk)",
|
||||
filename: "bauteil_wand.svg",
|
||||
tags: ["wand", "mauer", "mauerwerk", "ziegel"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="4" width="56" height="56" fill="#fca5a5" stroke="#dc2626" stroke-width="2"/><g stroke="#b91c1c" stroke-width="1"><line x1="4" y1="12" x2="60" y2="12"/><line x1="4" y1="20" x2="60" y2="20"/><line x1="4" y1="28" x2="60" y2="28"/><line x1="4" y1="36" x2="60" y2="36"/><line x1="4" y1="44" x2="60" y2="44"/><line x1="4" y1="52" x2="60" y2="52"/><line x1="18" y1="4" x2="18" y2="12"/><line x1="40" y1="4" x2="40" y2="12"/><line x1="8" y1="12" x2="8" y2="20"/><line x1="30" y1="12" x2="30" y2="20"/><line x1="52" y1="12" x2="52" y2="20"/><line x1="18" y1="20" x2="18" y2="28"/><line x1="40" y1="20" x2="40" y2="28"/><line x1="8" y1="28" x2="8" y2="36"/><line x1="30" y1="28" x2="30" y2="36"/><line x1="52" y1="28" x2="52" y2="36"/><line x1="18" y1="36" x2="18" y2="44"/><line x1="40" y1="36" x2="40" y2="44"/><line x1="8" y1="44" x2="8" y2="52"/><line x1="30" y1="44" x2="30" y2="52"/><line x1="52" y1="44" x2="52" y2="52"/><line x1="18" y1="52" x2="18" y2="60"/><line x1="40" y1="52" x2="40" y2="60"/></g></svg>`
|
||||
},
|
||||
{
|
||||
id: "wand_beton",
|
||||
name: "Wand (Beton)",
|
||||
filename: "bauteil_wand_beton.svg",
|
||||
tags: ["wand", "beton", "stahlbeton", "massiv"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="4" width="56" height="56" fill="#9ca3af" stroke="#6b7280" stroke-width="2"/><circle cx="12" cy="14" r="2" fill="#6b7280" opacity="0.5"/><circle cx="28" cy="8" r="1.5" fill="#6b7280" opacity="0.4"/><circle cx="48" cy="18" r="2.5" fill="#6b7280" opacity="0.5"/><circle cx="8" cy="36" r="1.5" fill="#6b7280" opacity="0.4"/><circle cx="38" cy="28" r="2" fill="#6b7280" opacity="0.5"/><circle cx="54" cy="42" r="1.5" fill="#6b7280" opacity="0.4"/><circle cx="18" cy="48" r="2" fill="#6b7280" opacity="0.5"/><circle cx="44" cy="52" r="1.5" fill="#6b7280" opacity="0.4"/><circle cx="32" cy="44" r="2.5" fill="#6b7280" opacity="0.5"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "boden_fliesen",
|
||||
name: "Fliesen",
|
||||
filename: "bauteil_fliesen.svg",
|
||||
tags: ["fliesen", "boden", "wand", "keramik", "kacheln"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="4" width="56" height="56" fill="#e7e5e4" stroke="#78716c" stroke-width="2"/><g stroke="#a8a29e" stroke-width="2"><line x1="4" y1="18" x2="60" y2="18"/><line x1="4" y1="32" x2="60" y2="32"/><line x1="4" y1="46" x2="60" y2="46"/><line x1="18" y1="4" x2="18" y2="60"/><line x1="32" y1="4" x2="32" y2="60"/><line x1="46" y1="4" x2="46" y2="60"/></g><rect x="6" y="6" width="10" height="10" fill="#f5f5f4"/><rect x="34" y="20" width="10" height="10" fill="#f5f5f4"/><rect x="20" y="34" width="10" height="10" fill="#f5f5f4"/><rect x="48" y="48" width="10" height="10" fill="#f5f5f4"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "boden_parkett",
|
||||
name: "Parkett / Holzboden",
|
||||
filename: "bauteil_parkett.svg",
|
||||
tags: ["parkett", "holz", "boden", "laminat", "dielen"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="4" width="56" height="56" fill="#d4a574" stroke="#92400e" stroke-width="2"/><g stroke="#b8860b" stroke-width="1"><rect x="4" y="4" width="14" height="28" fill="#deb887"/><rect x="18" y="4" width="14" height="28" fill="#d4a574"/><rect x="32" y="4" width="14" height="28" fill="#c9a066"/><rect x="46" y="4" width="14" height="28" fill="#deb887"/><rect x="4" y="32" width="14" height="28" fill="#c9a066"/><rect x="18" y="32" width="14" height="28" fill="#deb887"/><rect x="32" y="32" width="14" height="28" fill="#d4a574"/><rect x="46" y="32" width="14" height="28" fill="#c9a066"/></g></svg>`
|
||||
},
|
||||
{
|
||||
id: "dach",
|
||||
name: "Dach",
|
||||
filename: "bauteil_dach.svg",
|
||||
tags: ["dach", "dachstuhl", "ziegel", "bedachung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><polygon points="32,4 4,40 60,40" fill="#991b1b" stroke="#7f1d1d" stroke-width="2"/><polygon points="32,10 10,38 54,38" fill="#b91c1c"/><g stroke="#7f1d1d" stroke-width="1"><line x1="12" y1="36" x2="52" y2="36"/><line x1="16" y1="32" x2="48" y2="32"/><line x1="20" y1="28" x2="44" y2="28"/><line x1="24" y1="24" x2="40" y2="24"/><line x1="28" y1="20" x2="36" y2="20"/></g><rect x="4" y="40" width="56" height="8" fill="#78716c" stroke="#57534e" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "treppe",
|
||||
name: "Treppe",
|
||||
filename: "bauteil_treppe.svg",
|
||||
tags: ["treppe", "stufen", "aufgang", "treppenhaus"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><g fill="#d6d3d1" stroke="#78716c" stroke-width="2"><rect x="4" y="52" width="56" height="8"/><rect x="4" y="44" width="48" height="8"/><rect x="4" y="36" width="40" height="8"/><rect x="4" y="28" width="32" height="8"/><rect x="4" y="20" width="24" height="8"/><rect x="4" y="12" width="16" height="8"/><rect x="4" y="4" width="8" height="8"/></g><path d="M8 8 L8 56 L58 56" stroke="#57534e" stroke-width="3" fill="none"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "daemmung",
|
||||
name: "Dämmung / Isolierung",
|
||||
filename: "bauteil_daemmung.svg",
|
||||
tags: ["dämmung", "isolierung", "wärme", "kälte"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="4" width="56" height="56" fill="#fef08a" stroke="#eab308" stroke-width="2"/><g stroke="#ca8a04" stroke-width="1"><path d="M4 14 Q16 10 28 14 Q40 18 52 14 L60 14"/><path d="M4 24 Q14 28 26 24 Q38 20 50 24 L60 24"/><path d="M4 34 Q16 30 28 34 Q40 38 52 34 L60 34"/><path d="M4 44 Q14 48 26 44 Q38 40 50 44 L60 44"/><path d="M4 54 Q16 50 28 54 Q40 58 52 54 L60 54"/></g><circle cx="12" cy="20" r="2" fill="#facc15"/><circle cx="32" cy="30" r="2" fill="#facc15"/><circle cx="50" cy="40" r="2" fill="#facc15"/><circle cx="20" cy="50" r="2" fill="#facc15"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "rohr",
|
||||
name: "Rohrleitung",
|
||||
filename: "bauteil_rohr.svg",
|
||||
tags: ["rohr", "leitung", "rohrleitung", "installation"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="26" width="56" height="12" fill="#6b7280" stroke="#4b5563" stroke-width="2"/><ellipse cx="4" cy="32" rx="3" ry="8" fill="#9ca3af" stroke="#4b5563" stroke-width="1"/><ellipse cx="60" cy="32" rx="3" ry="8" fill="#9ca3af" stroke="#4b5563" stroke-width="1"/><line x1="14" y1="26" x2="14" y2="38" stroke="#4b5563" stroke-width="1"/><line x1="32" y1="26" x2="32" y2="38" stroke="#4b5563" stroke-width="1"/><line x1="50" y1="26" x2="50" y2="38" stroke="#4b5563" stroke-width="1"/><rect x="20" y="22" width="8" height="20" rx="1" fill="#ef4444" stroke="#dc2626" stroke-width="1"/><polygon points="24,18 20,22 28,22" fill="#ef4444"/></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== MÖBEL ==========
|
||||
moebel: {
|
||||
name: "Möbel",
|
||||
icon: "🛋️",
|
||||
items: [
|
||||
{
|
||||
id: "sofa",
|
||||
name: "Sofa / Couch",
|
||||
filename: "moebel_sofa.svg",
|
||||
tags: ["sofa", "couch", "sitzmoebel", "wohnzimmer"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="24" width="56" height="28" rx="4" fill="#78716c" stroke="#57534e" stroke-width="2"/><rect x="8" y="20" width="48" height="20" rx="3" fill="#a8a29e" stroke="#78716c" stroke-width="1"/><rect x="4" y="28" width="10" height="20" rx="2" fill="#78716c" stroke="#57534e" stroke-width="1"/><rect x="50" y="28" width="10" height="20" rx="2" fill="#78716c" stroke="#57534e" stroke-width="1"/><rect x="6" y="52" width="6" height="6" rx="1" fill="#57534e"/><rect x="52" y="52" width="6" height="6" rx="1" fill="#57534e"/><line x1="22" y1="24" x2="22" y2="40" stroke="#57534e" stroke-width="1" opacity="0.5"/><line x1="42" y1="24" x2="42" y2="40" stroke="#57534e" stroke-width="1" opacity="0.5"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "tisch",
|
||||
name: "Tisch",
|
||||
filename: "moebel_tisch.svg",
|
||||
tags: ["tisch", "esstisch", "schreibtisch", "möbel"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="6" y="20" width="52" height="6" rx="1" fill="#92400e" stroke="#78350f" stroke-width="2"/><rect x="10" y="26" width="4" height="30" fill="#a16207"/><rect x="50" y="26" width="4" height="30" fill="#a16207"/><rect x="8" y="54" width="8" height="4" rx="1" fill="#78350f"/><rect x="48" y="54" width="8" height="4" rx="1" fill="#78350f"/><line x1="14" y1="40" x2="50" y2="40" stroke="#a16207" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "stuhl",
|
||||
name: "Stuhl",
|
||||
filename: "moebel_stuhl.svg",
|
||||
tags: ["stuhl", "sitz", "möbel", "esszimmer"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="14" y="4" width="36" height="32" rx="2" fill="#a16207" stroke="#92400e" stroke-width="2"/><rect x="18" y="8" width="28" height="24" rx="1" fill="#ca8a04"/><rect x="14" y="36" width="36" height="6" rx="1" fill="#92400e" stroke="#78350f" stroke-width="1"/><rect x="16" y="42" width="4" height="18" fill="#78350f"/><rect x="44" y="42" width="4" height="18" fill="#78350f"/><rect x="14" y="58" width="8" height="3" rx="1" fill="#57534e"/><rect x="42" y="58" width="8" height="3" rx="1" fill="#57534e"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "schrank",
|
||||
name: "Schrank",
|
||||
filename: "moebel_schrank.svg",
|
||||
tags: ["schrank", "kleiderschrank", "möbel", "stauraum"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="6" y="4" width="52" height="54" rx="2" fill="#a16207" stroke="#92400e" stroke-width="2"/><line x1="32" y1="4" x2="32" y2="58" stroke="#92400e" stroke-width="2"/><rect x="10" y="8" width="18" height="46" fill="#ca8a04" rx="1"/><rect x="36" y="8" width="18" height="46" fill="#ca8a04" rx="1"/><circle cx="26" cy="32" r="2" fill="#78350f"/><circle cx="38" cy="32" r="2" fill="#78350f"/><rect x="8" y="58" width="6" height="4" fill="#78350f"/><rect x="50" y="58" width="6" height="4" fill="#78350f"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "bett",
|
||||
name: "Bett",
|
||||
filename: "moebel_bett.svg",
|
||||
tags: ["bett", "schlafzimmer", "möbel", "schlafen"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="20" width="56" height="32" rx="2" fill="#78716c" stroke="#57534e" stroke-width="2"/><rect x="8" y="16" width="14" height="12" rx="2" fill="#a8a29e" stroke="#78716c" stroke-width="1"/><rect x="42" y="16" width="14" height="12" rx="2" fill="#a8a29e" stroke="#78716c" stroke-width="1"/><rect x="8" y="24" width="48" height="24" fill="#e7e5e4" stroke="#d6d3d1" stroke-width="1"/><rect x="4" y="52" width="8" height="8" rx="1" fill="#57534e"/><rect x="52" y="52" width="8" height="8" rx="1" fill="#57534e"/><path d="M12 28 Q32 20 52 28" stroke="#d6d3d1" stroke-width="1" fill="none"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "regal",
|
||||
name: "Regal",
|
||||
filename: "moebel_regal.svg",
|
||||
tags: ["regal", "bücherregal", "möbel", "stauraum"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="8" y="4" width="48" height="56" fill="none" stroke="#92400e" stroke-width="3"/><line x1="8" y1="18" x2="56" y2="18" stroke="#92400e" stroke-width="2"/><line x1="8" y1="32" x2="56" y2="32" stroke="#92400e" stroke-width="2"/><line x1="8" y1="46" x2="56" y2="46" stroke="#92400e" stroke-width="2"/><rect x="12" y="8" width="6" height="8" fill="#3b82f6" rx="1"/><rect x="20" y="6" width="5" height="10" fill="#22c55e" rx="1"/><rect x="28" y="8" width="8" height="8" fill="#f59e0b" rx="1"/><rect x="14" y="22" width="10" height="8" fill="#a8a29e" rx="1"/><rect x="30" y="20" width="6" height="10" fill="#ef4444" rx="1"/><rect x="44" y="22" width="8" height="8" fill="#8b5cf6" rx="1"/><rect x="12" y="36" width="12" height="8" fill="#06b6d4" rx="1"/><rect x="40" y="34" width="10" height="10" fill="#ec4899" rx="1"/></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== KÜCHE ==========
|
||||
kueche: {
|
||||
|
||||
// ========== BAD / SANITÄR ==========
|
||||
bad: {
|
||||
name: "Bad & Sanitär",
|
||||
icon: "🚿",
|
||||
items: [
|
||||
{
|
||||
id: "wc",
|
||||
name: "WC / Toilette",
|
||||
filename: "wc_draufsicht.svg",
|
||||
tags: ["wc", "toilette", "klo", "bad", "sanitär"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><ellipse cx="32" cy="38" rx="14" ry="18" fill="#f5f5f5" stroke="#333" stroke-width="2"/><ellipse cx="32" cy="38" rx="8" ry="12" fill="#e0f2fe" stroke="#333" stroke-width="1.5"/><rect x="22" y="8" width="20" height="16" rx="3" fill="#f5f5f5" stroke="#333" stroke-width="2"/><rect x="26" y="10" width="12" height="6" rx="1" fill="#ddd" stroke="#333" stroke-width="1"/></svg>`,
|
||||
dxfSvg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><ellipse cx="32" cy="38" rx="14" ry="18" fill="none" stroke="#000" stroke-width="1"/><ellipse cx="32" cy="38" rx="8" ry="12" fill="none" stroke="#000" stroke-width="1"/><rect x="22" y="8" width="20" height="16" rx="0" fill="none" stroke="#000" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "waschbecken",
|
||||
name: "Waschbecken",
|
||||
filename: "waschbecken_draufsicht.svg",
|
||||
tags: ["waschbecken", "waschtisch", "bad", "sanitär", "lavabo"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="8" y="16" width="48" height="40" rx="4" fill="#f5f5f5" stroke="#333" stroke-width="2"/><ellipse cx="32" cy="36" rx="16" ry="12" fill="#e0f2fe" stroke="#333" stroke-width="1.5"/><circle cx="32" cy="40" r="3" fill="#333"/><rect x="30" y="18" width="4" height="8" rx="1" fill="#999" stroke="#333" stroke-width="1"/></svg>`,
|
||||
dxfSvg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="8" y="16" width="48" height="40" fill="none" stroke="#000" stroke-width="1"/><ellipse cx="32" cy="36" rx="16" ry="12" fill="none" stroke="#000" stroke-width="1"/><circle cx="32" cy="40" r="3" fill="none" stroke="#000" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "badewanne",
|
||||
name: "Badewanne",
|
||||
filename: "badewanne_draufsicht.svg",
|
||||
tags: ["badewanne", "wanne", "bad", "sanitär", "baden"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="8" width="56" height="48" rx="8" fill="#f5f5f5" stroke="#333" stroke-width="2"/><rect x="8" y="12" width="48" height="40" rx="6" fill="#e0f2fe" stroke="#333" stroke-width="1.5"/><circle cx="50" cy="18" r="3" fill="#999" stroke="#333" stroke-width="1"/><ellipse cx="50" cy="46" rx="4" ry="3" fill="#999" stroke="#333" stroke-width="1"/></svg>`,
|
||||
dxfSvg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="8" width="56" height="48" rx="0" fill="none" stroke="#000" stroke-width="1"/><rect x="8" y="12" width="48" height="40" rx="0" fill="none" stroke="#000" stroke-width="1"/><circle cx="50" cy="18" r="3" fill="none" stroke="#000" stroke-width="1"/><ellipse cx="50" cy="46" rx="4" ry="3" fill="none" stroke="#000" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "dusche",
|
||||
name: "Dusche",
|
||||
filename: "dusche_draufsicht.svg",
|
||||
tags: ["dusche", "duschwanne", "bad", "sanitär", "brause"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="4" width="56" height="56" rx="2" fill="#f5f5f5" stroke="#333" stroke-width="2"/><rect x="8" y="8" width="48" height="48" rx="1" fill="#e0f2fe" stroke="#333" stroke-width="1"/><circle cx="52" cy="12" r="4" fill="#999" stroke="#333" stroke-width="1"/><line x1="8" y1="8" x2="56" y2="56" stroke="#333" stroke-width="1" stroke-dasharray="4,2"/></svg>`,
|
||||
dxfSvg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="4" width="56" height="56" fill="none" stroke="#000" stroke-width="1"/><circle cx="52" cy="12" r="4" fill="none" stroke="#000" stroke-width="1"/><line x1="4" y1="4" x2="60" y2="60" stroke="#000" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "bidet",
|
||||
name: "Bidet",
|
||||
filename: "bidet_draufsicht.svg",
|
||||
tags: ["bidet", "bad", "sanitär"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><ellipse cx="32" cy="32" rx="14" ry="20" fill="#f5f5f5" stroke="#333" stroke-width="2"/><ellipse cx="32" cy="32" rx="8" ry="14" fill="#e0f2fe" stroke="#333" stroke-width="1.5"/><circle cx="32" cy="18" r="2" fill="#999" stroke="#333" stroke-width="1"/></svg>`,
|
||||
dxfSvg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><ellipse cx="32" cy="32" rx="14" ry="20" fill="none" stroke="#000" stroke-width="1"/><ellipse cx="32" cy="32" rx="8" ry="14" fill="none" stroke="#000" stroke-width="1"/><circle cx="32" cy="18" r="2" fill="none" stroke="#000" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "doppelwaschbecken",
|
||||
name: "Doppelwaschbecken",
|
||||
filename: "doppelwaschbecken_draufsicht.svg",
|
||||
tags: ["doppelwaschbecken", "waschtisch", "bad", "sanitär", "doppel"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="2" y="16" width="60" height="32" rx="2" fill="#f5f5f5" stroke="#333" stroke-width="2"/><ellipse cx="18" cy="32" rx="10" ry="8" fill="#e0f2fe" stroke="#333" stroke-width="1"/><ellipse cx="46" cy="32" rx="10" ry="8" fill="#e0f2fe" stroke="#333" stroke-width="1"/><circle cx="18" cy="34" r="2" fill="#333"/><circle cx="46" cy="34" r="2" fill="#333"/></svg>`,
|
||||
dxfSvg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="2" y="16" width="60" height="32" fill="none" stroke="#000" stroke-width="1"/><ellipse cx="18" cy="32" rx="10" ry="8" fill="none" stroke="#000" stroke-width="1"/><ellipse cx="46" cy="32" rx="10" ry="8" fill="none" stroke="#000" stroke-width="1"/><circle cx="18" cy="34" r="2" fill="none" stroke="#000" stroke-width="1"/><circle cx="46" cy="34" r="2" fill="none" stroke="#000" stroke-width="1"/></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
name: "Küche",
|
||||
icon: "🍳",
|
||||
items: [
|
||||
{
|
||||
id: "herd",
|
||||
name: "Herd / Kochfeld",
|
||||
filename: "kueche_herd.svg",
|
||||
tags: ["herd", "kochfeld", "küche", "kochen"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="4" width="56" height="56" rx="3" fill="#1f2937" stroke="#111827" stroke-width="2"/><rect x="8" y="8" width="48" height="48" fill="#374151" rx="2"/><circle cx="22" cy="22" r="8" fill="#111827" stroke="#4b5563" stroke-width="2"/><circle cx="42" cy="22" r="8" fill="#111827" stroke="#4b5563" stroke-width="2"/><circle cx="22" cy="42" r="8" fill="#111827" stroke="#4b5563" stroke-width="2"/><circle cx="42" cy="42" r="8" fill="#111827" stroke="#4b5563" stroke-width="2"/><circle cx="22" cy="22" r="4" fill="#dc2626" opacity="0.8"/><circle cx="42" cy="22" r="4" fill="#dc2626" opacity="0.8"/><circle cx="22" cy="42" r="4" fill="#dc2626" opacity="0.4"/><circle cx="42" cy="42" r="4" fill="#dc2626" opacity="0.4"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "spuele",
|
||||
name: "Spüle",
|
||||
filename: "kueche_spuele.svg",
|
||||
tags: ["spüle", "waschbecken", "küche", "abwasch"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="8" width="56" height="48" rx="3" fill="#9ca3af" stroke="#6b7280" stroke-width="2"/><rect x="8" y="12" width="24" height="32" rx="4" fill="#4b5563" stroke="#374151" stroke-width="2"/><rect x="36" y="12" width="20" height="32" rx="4" fill="#4b5563" stroke="#374151" stroke-width="2"/><circle cx="20" cy="28" r="3" fill="#1f2937"/><ellipse cx="46" cy="28" rx="6" ry="8" fill="#374151"/><circle cx="50" cy="6" r="4" fill="#6b7280" stroke="#4b5563" stroke-width="1"/><rect x="48" y="6" width="4" height="8" fill="#6b7280"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "kuehlschrank",
|
||||
name: "Kühlschrank",
|
||||
filename: "kueche_kuehlschrank.svg",
|
||||
tags: ["kühlschrank", "kühlen", "küche", "elektrogerät"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="10" y="4" width="44" height="56" rx="3" fill="#e5e7eb" stroke="#9ca3af" stroke-width="2"/><line x1="10" y1="24" x2="54" y2="24" stroke="#9ca3af" stroke-width="2"/><rect x="46" y="10" width="4" height="8" rx="1" fill="#6b7280"/><rect x="46" y="30" width="4" height="12" rx="1" fill="#6b7280"/><rect x="16" y="8" width="8" height="4" fill="#bfdbfe" rx="1"/><rect x="28" y="8" width="12" height="4" fill="#bfdbfe" rx="1"/><circle cx="20" cy="16" r="3" fill="#fbbf24"/><rect x="16" y="30" width="12" height="8" fill="#bbf7d0" rx="1"/><rect x="16" y="42" width="8" height="10" fill="#fecaca" rx="1"/><rect x="28" y="38" width="14" height="6" fill="#e0f2fe" rx="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "backofen",
|
||||
name: "Backofen",
|
||||
filename: "kueche_backofen.svg",
|
||||
tags: ["backofen", "ofen", "küche", "backen"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="6" y="4" width="52" height="56" rx="3" fill="#1f2937" stroke="#111827" stroke-width="2"/><rect x="10" y="18" width="44" height="38" rx="2" fill="#111827" stroke="#374151" stroke-width="2"/><rect x="14" y="22" width="36" height="30" fill="#292524" stroke="#4b5563" stroke-width="1"/><line x1="14" y1="32" x2="50" y2="32" stroke="#4b5563" stroke-width="1"/><line x1="14" y1="42" x2="50" y2="42" stroke="#4b5563" stroke-width="1"/><circle cx="16" cy="10" r="3" fill="#4b5563"/><circle cx="28" cy="10" r="3" fill="#4b5563"/><circle cx="40" cy="10" r="3" fill="#4b5563"/><rect x="46" y="8" width="8" height="4" rx="1" fill="#22c55e"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "spuelmaschine",
|
||||
name: "Spülmaschine",
|
||||
filename: "kueche_spuelmaschine.svg",
|
||||
tags: ["spülmaschine", "geschirrspüler", "küche", "elektrogerät"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="6" y="4" width="52" height="56" rx="3" fill="#e5e7eb" stroke="#9ca3af" stroke-width="2"/><rect x="10" y="16" width="44" height="40" rx="2" fill="#d1d5db" stroke="#9ca3af" stroke-width="1"/><rect x="10" y="8" width="44" height="6" fill="#9ca3af" rx="1"/><circle cx="16" cy="11" r="2" fill="#4b5563"/><rect x="22" y="9" width="12" height="4" rx="1" fill="#1f2937"/><circle cx="48" cy="11" r="2" fill="#22c55e"/><ellipse cx="32" cy="36" rx="16" ry="14" fill="#93c5fd" stroke="#3b82f6" stroke-width="2"/><line x1="32" y1="24" x2="32" y2="48" stroke="#3b82f6" stroke-width="1" stroke-dasharray="2,2"/><line x1="18" y1="36" x2="46" y2="36" stroke="#3b82f6" stroke-width="1" stroke-dasharray="2,2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "dunstabzug",
|
||||
name: "Dunstabzugshaube",
|
||||
filename: "kueche_dunstabzug.svg",
|
||||
tags: ["dunstabzug", "dunstabzugshaube", "küche", "abzug"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><polygon points="8,32 56,32 52,56 12,56" fill="#9ca3af" stroke="#6b7280" stroke-width="2"/><rect x="20" y="4" width="24" height="28" fill="#78716c" stroke="#57534e" stroke-width="2"/><rect x="24" y="8" width="16" height="8" fill="#57534e" rx="1"/><rect x="14" y="36" width="36" height="4" fill="#6b7280"/><rect x="14" y="44" width="36" height="4" fill="#6b7280"/><circle cx="32" cy="52" r="2" fill="#4b5563"/><g stroke="#d1d5db" stroke-width="1" opacity="0.5"><path d="M20 20 Q24 16 28 20" fill="none"/><path d="M36 20 Q40 16 44 20" fill="none"/></g></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== PFEILE (dynamisch) ==========
|
||||
pfeile: {
|
||||
name: "Richtungspfeile (Rot)",
|
||||
icon: "➡️",
|
||||
items: []
|
||||
},
|
||||
|
||||
// ========== KOMPASS (dynamisch) ==========
|
||||
kompass: {
|
||||
name: "Nordpfeile / Kompass",
|
||||
icon: "🧭",
|
||||
items: []
|
||||
},
|
||||
|
||||
// ========== VERMESSUNG - STATUS ==========
|
||||
vermessung_status: {
|
||||
name: "Vermessung - Status",
|
||||
icon: "📋",
|
||||
items: [
|
||||
{
|
||||
id: "vm_reparatur",
|
||||
name: "Reparatur",
|
||||
filename: "vermessung_reparatur.svg",
|
||||
tags: ["reparatur", "instandsetzung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="38" font-family="Arial" font-size="16" font-weight="bold" fill="#000" text-anchor="middle">R</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_neu",
|
||||
name: "Neu",
|
||||
filename: "vermessung_neu.svg",
|
||||
tags: ["neu", "neubau", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="38" font-family="Arial" font-size="16" font-weight="bold" fill="#000" text-anchor="middle">N</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_bestand",
|
||||
name: "Bestand",
|
||||
filename: "vermessung_bestand.svg",
|
||||
tags: ["bestand", "bestehend", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="38" font-family="Arial" font-size="16" font-weight="bold" fill="#000" text-anchor="middle">B</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_abriss",
|
||||
name: "Abriss",
|
||||
filename: "vermessung_abriss.svg",
|
||||
tags: ["abriss", "rückbau", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="none" stroke="#000" stroke-width="2"/><line x1="12" y1="12" x2="52" y2="52" stroke="#000" stroke-width="2"/><line x1="52" y1="12" x2="12" y2="52" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_geplant",
|
||||
name: "Geplant",
|
||||
filename: "vermessung_geplant.svg",
|
||||
tags: ["geplant", "planung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="none" stroke="#000" stroke-width="2" stroke-dasharray="6,4"/><text x="32" y="38" font-family="Arial" font-size="16" font-weight="bold" fill="#000" text-anchor="middle">P</text></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== VERMESSUNG - GRENZEN ==========
|
||||
vermessung_grenzen: {
|
||||
name: "Vermessung - Grenzen",
|
||||
icon: "📍",
|
||||
items: [
|
||||
{
|
||||
id: "vm_grundstuecksgrenze",
|
||||
name: "Grundstücksgrenze",
|
||||
filename: "vermessung_grundstuecksgrenze.svg",
|
||||
tags: ["grundstück", "grenze", "flurstück", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="32" x2="60" y2="32" stroke="#000" stroke-width="3"/><line x1="12" y1="26" x2="12" y2="38" stroke="#000" stroke-width="2"/><line x1="52" y1="26" x2="52" y2="38" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_grenzpunkt_vermarkt",
|
||||
name: "Grenzpunkt (vermarkt)",
|
||||
filename: "vermessung_grenzpunkt_vermarkt.svg",
|
||||
tags: ["grenzpunkt", "grenzstein", "vermarkt", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="12" fill="#000"/><circle cx="32" cy="32" r="6" fill="#fff"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_grenzpunkt_unvermarkt",
|
||||
name: "Grenzpunkt (unvermarkt)",
|
||||
filename: "vermessung_grenzpunkt_unvermarkt.svg",
|
||||
tags: ["grenzpunkt", "unvermarkt", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="10" fill="none" stroke="#000" stroke-width="2"/><line x1="32" y1="22" x2="32" y2="42" stroke="#000" stroke-width="2"/><line x1="22" y1="32" x2="42" y2="32" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_flurstucksgrenze",
|
||||
name: "Flurstücksgrenze",
|
||||
filename: "vermessung_flurstucksgrenze.svg",
|
||||
tags: ["flurstück", "grenze", "kataster", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="32" x2="60" y2="32" stroke="#000" stroke-width="2" stroke-dasharray="12,4"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_zaun",
|
||||
name: "Zaun",
|
||||
filename: "vermessung_zaun.svg",
|
||||
tags: ["zaun", "einfriedung", "grenze", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="32" x2="60" y2="32" stroke="#000" stroke-width="1.5"/><line x1="12" y1="24" x2="12" y2="40" stroke="#000" stroke-width="1.5"/><line x1="24" y1="24" x2="24" y2="40" stroke="#000" stroke-width="1.5"/><line x1="36" y1="24" x2="36" y2="40" stroke="#000" stroke-width="1.5"/><line x1="48" y1="24" x2="48" y2="40" stroke="#000" stroke-width="1.5"/><line x1="12" y1="28" x2="24" y2="28" stroke="#000" stroke-width="1"/><line x1="24" y1="28" x2="36" y2="28" stroke="#000" stroke-width="1"/><line x1="36" y1="28" x2="48" y2="28" stroke="#000" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_mauer",
|
||||
name: "Mauer",
|
||||
filename: "vermessung_mauer.svg",
|
||||
tags: ["mauer", "wand", "einfriedung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="4" y="26" width="56" height="12" fill="none" stroke="#000" stroke-width="2"/><line x1="16" y1="26" x2="16" y2="38" stroke="#000" stroke-width="1"/><line x1="28" y1="26" x2="28" y2="38" stroke="#000" stroke-width="1"/><line x1="40" y1="26" x2="40" y2="38" stroke="#000" stroke-width="1"/><line x1="52" y1="26" x2="52" y2="38" stroke="#000" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_hecke",
|
||||
name: "Hecke",
|
||||
filename: "vermessung_hecke.svg",
|
||||
tags: ["hecke", "grün", "bepflanzung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="38" x2="60" y2="38" stroke="#000" stroke-width="1.5"/><circle cx="12" cy="32" r="6" fill="none" stroke="#000" stroke-width="1.5"/><circle cx="24" cy="30" r="7" fill="none" stroke="#000" stroke-width="1.5"/><circle cx="38" cy="31" r="6" fill="none" stroke="#000" stroke-width="1.5"/><circle cx="52" cy="32" r="6" fill="none" stroke="#000" stroke-width="1.5"/></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== VERMESSUNG - WASSER ==========
|
||||
vermessung_wasser: {
|
||||
name: "Vermessung - Wasser",
|
||||
icon: "💧",
|
||||
items: [
|
||||
{
|
||||
id: "vm_hydrant_unterflur",
|
||||
name: "Hydrant (Unterflur)",
|
||||
filename: "vermessung_hydrant_unterflur.svg",
|
||||
tags: ["hydrant", "unterflur", "wasser", "feuerwehr", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="16" fill="none" stroke="#000" stroke-width="2"/><line x1="32" y1="16" x2="32" y2="48" stroke="#000" stroke-width="2"/><line x1="16" y1="32" x2="48" y2="32" stroke="#000" stroke-width="2"/><circle cx="32" cy="32" r="4" fill="#000"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_hydrant_ueberflur",
|
||||
name: "Hydrant (Überflur)",
|
||||
filename: "vermessung_hydrant_ueberflur.svg",
|
||||
tags: ["hydrant", "überflur", "wasser", "feuerwehr", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><polygon points="32,8 48,24 48,56 16,56 16,24" fill="none" stroke="#000" stroke-width="2"/><line x1="16" y1="36" x2="48" y2="36" stroke="#000" stroke-width="2"/><circle cx="32" cy="46" r="4" fill="#000"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_wasserschacht",
|
||||
name: "Trinkwasserschacht",
|
||||
filename: "vermessung_wasserschacht.svg",
|
||||
tags: ["schacht", "wasser", "trinkwasser", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="16" y="16" width="32" height="32" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="38" font-family="Arial" font-size="14" font-weight="bold" fill="#000" text-anchor="middle">W</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_wasserschieber",
|
||||
name: "Wasserschieber",
|
||||
filename: "vermessung_wasserschieber.svg",
|
||||
tags: ["schieber", "absperrer", "wasser", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="8" y1="32" x2="56" y2="32" stroke="#000" stroke-width="2"/><line x1="32" y1="20" x2="32" y2="44" stroke="#000" stroke-width="3"/><circle cx="32" cy="32" r="6" fill="none" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_brunnen",
|
||||
name: "Brunnen",
|
||||
filename: "vermessung_brunnen.svg",
|
||||
tags: ["brunnen", "wasser", "quelle", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="20" fill="none" stroke="#000" stroke-width="2"/><circle cx="32" cy="32" r="8" fill="none" stroke="#000" stroke-width="2"/><line x1="32" y1="12" x2="32" y2="4" stroke="#000" stroke-width="2"/><line x1="32" y1="52" x2="32" y2="60" stroke="#000" stroke-width="2"/><line x1="12" y1="32" x2="4" y2="32" stroke="#000" stroke-width="2"/><line x1="52" y1="32" x2="60" y2="32" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_wasserleitung",
|
||||
name: "Wasserleitung",
|
||||
filename: "vermessung_wasserleitung.svg",
|
||||
tags: ["leitung", "wasser", "rohr", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="32" x2="60" y2="32" stroke="#000" stroke-width="3"/><text x="32" y="24" font-family="Arial" font-size="10" fill="#000" text-anchor="middle">W</text></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== VERMESSUNG - ABWASSER ==========
|
||||
vermessung_abwasser: {
|
||||
name: "Vermessung - Abwasser",
|
||||
icon: "🚰",
|
||||
items: [
|
||||
{
|
||||
id: "vm_abwasserschacht",
|
||||
name: "Abwasserschacht",
|
||||
filename: "vermessung_abwasserschacht.svg",
|
||||
tags: ["schacht", "abwasser", "kanal", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="16" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="38" font-family="Arial" font-size="14" font-weight="bold" fill="#000" text-anchor="middle">S</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_schacht_rund",
|
||||
name: "Schacht (rund)",
|
||||
filename: "vermessung_schacht_rund.svg",
|
||||
tags: ["schacht", "rund", "kanal", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="18" fill="none" stroke="#000" stroke-width="2"/><circle cx="32" cy="32" r="10" fill="none" stroke="#000" stroke-width="1.5"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_schacht_eckig",
|
||||
name: "Schacht (eckig)",
|
||||
filename: "vermessung_schacht_eckig.svg",
|
||||
tags: ["schacht", "eckig", "kanal", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="14" y="14" width="36" height="36" fill="none" stroke="#000" stroke-width="2"/><rect x="22" y="22" width="20" height="20" fill="none" stroke="#000" stroke-width="1.5"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_einlauf",
|
||||
name: "Einlauf / Gully",
|
||||
filename: "vermessung_einlauf.svg",
|
||||
tags: ["einlauf", "gully", "straßenablauf", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="18" y="18" width="28" height="28" fill="none" stroke="#000" stroke-width="2"/><line x1="22" y1="26" x2="42" y2="26" stroke="#000" stroke-width="1.5"/><line x1="22" y1="32" x2="42" y2="32" stroke="#000" stroke-width="1.5"/><line x1="22" y1="38" x2="42" y2="38" stroke="#000" stroke-width="1.5"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_abwasserleitung",
|
||||
name: "Abwasserleitung",
|
||||
filename: "vermessung_abwasserleitung.svg",
|
||||
tags: ["leitung", "abwasser", "kanal", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="32" x2="60" y2="32" stroke="#000" stroke-width="2" stroke-dasharray="10,4"/></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== VERMESSUNG - STROM ==========
|
||||
vermessung_strom: {
|
||||
name: "Vermessung - Strom",
|
||||
icon: "⚡",
|
||||
items: [
|
||||
{
|
||||
id: "vm_hausanschluss_elektro",
|
||||
name: "Hausanschluss Elektro",
|
||||
filename: "vermessung_hausanschluss_elektro.svg",
|
||||
tags: ["hausanschluss", "elektro", "strom", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="14" fill="none" stroke="#000" stroke-width="2"/><polygon points="32,20 26,34 30,34 28,44 38,30 34,30" fill="#000"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_laterne",
|
||||
name: "Laterne / Mast",
|
||||
filename: "vermessung_laterne.svg",
|
||||
tags: ["laterne", "mast", "beleuchtung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="4" fill="#000"/><line x1="32" y1="8" x2="32" y2="28" stroke="#000" stroke-width="2"/><line x1="32" y1="36" x2="32" y2="56" stroke="#000" stroke-width="2"/><line x1="8" y1="32" x2="28" y2="32" stroke="#000" stroke-width="2"/><line x1="36" y1="32" x2="56" y2="32" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_stromkabel",
|
||||
name: "Stromkabel",
|
||||
filename: "vermessung_stromkabel.svg",
|
||||
tags: ["kabel", "strom", "leitung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="32" x2="60" y2="32" stroke="#000" stroke-width="3"/><text x="32" y="24" font-family="Arial" font-size="10" fill="#000" text-anchor="middle">E</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_schaltkasten",
|
||||
name: "Schaltkasten",
|
||||
filename: "vermessung_schaltkasten.svg",
|
||||
tags: ["schaltkasten", "verteiler", "strom", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="16" y="12" width="32" height="40" fill="none" stroke="#000" stroke-width="2"/><line x1="16" y1="24" x2="48" y2="24" stroke="#000" stroke-width="1"/><text x="32" y="42" font-family="Arial" font-size="12" fill="#000" text-anchor="middle">E</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_trafostation",
|
||||
name: "Trafostation",
|
||||
filename: "vermessung_trafostation.svg",
|
||||
tags: ["trafo", "station", "umspanner", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="12" y="12" width="40" height="40" fill="none" stroke="#000" stroke-width="2"/><line x1="12" y1="12" x2="52" y2="52" stroke="#000" stroke-width="2"/><line x1="52" y1="12" x2="12" y2="52" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_mast_holz",
|
||||
name: "Mast (Holz)",
|
||||
filename: "vermessung_mast_holz.svg",
|
||||
tags: ["mast", "holz", "freileitung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="12" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="38" font-family="Arial" font-size="14" fill="#000" text-anchor="middle">H</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_mast_beton",
|
||||
name: "Mast (Beton)",
|
||||
filename: "vermessung_mast_beton.svg",
|
||||
tags: ["mast", "beton", "freileitung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="12" fill="none" stroke="#000" stroke-width="2"/><circle cx="32" cy="32" r="6" fill="none" stroke="#000" stroke-width="1.5"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_mast_stahl",
|
||||
name: "Mast (Stahl)",
|
||||
filename: "vermessung_mast_stahl.svg",
|
||||
tags: ["mast", "stahl", "freileitung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="20" y="20" width="24" height="24" fill="none" stroke="#000" stroke-width="2"/></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== VERMESSUNG - GAS ==========
|
||||
vermessung_gas: {
|
||||
name: "Vermessung - Gas",
|
||||
icon: "🔥",
|
||||
items: [
|
||||
{
|
||||
id: "vm_gasschieber",
|
||||
name: "Gasschieber",
|
||||
filename: "vermessung_gasschieber.svg",
|
||||
tags: ["schieber", "absperrer", "gas", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="8" y1="32" x2="56" y2="32" stroke="#000" stroke-width="2" stroke-dasharray="8,4"/><line x1="32" y1="20" x2="32" y2="44" stroke="#000" stroke-width="3"/><text x="32" y="56" font-family="Arial" font-size="10" fill="#000" text-anchor="middle">G</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_gasleitung",
|
||||
name: "Gasleitung",
|
||||
filename: "vermessung_gasleitung.svg",
|
||||
tags: ["leitung", "gas", "rohr", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="32" x2="60" y2="32" stroke="#000" stroke-width="2" stroke-dasharray="8,4"/><text x="32" y="24" font-family="Arial" font-size="10" fill="#000" text-anchor="middle">G</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_hausanschluss_gas",
|
||||
name: "Hausanschluss Gas",
|
||||
filename: "vermessung_hausanschluss_gas.svg",
|
||||
tags: ["hausanschluss", "gas", "anschluss", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="18" y="18" width="28" height="28" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="38" font-family="Arial" font-size="14" font-weight="bold" fill="#000" text-anchor="middle">G</text></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== VERMESSUNG - VERKEHR ==========
|
||||
vermessung_verkehr: {
|
||||
name: "Vermessung - Verkehr",
|
||||
icon: "🚗",
|
||||
items: [
|
||||
{
|
||||
id: "vm_gleise",
|
||||
name: "Gleise / Schienen",
|
||||
filename: "vermessung_gleise.svg",
|
||||
tags: ["gleise", "schienen", "bahn", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="24" x2="60" y2="24" stroke="#000" stroke-width="2"/><line x1="4" y1="40" x2="60" y2="40" stroke="#000" stroke-width="2"/><line x1="12" y1="24" x2="12" y2="40" stroke="#000" stroke-width="1.5"/><line x1="24" y1="24" x2="24" y2="40" stroke="#000" stroke-width="1.5"/><line x1="36" y1="24" x2="36" y2="40" stroke="#000" stroke-width="1.5"/><line x1="48" y1="24" x2="48" y2="40" stroke="#000" stroke-width="1.5"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_prellbock",
|
||||
name: "Prellbock",
|
||||
filename: "vermessung_prellbock.svg",
|
||||
tags: ["prellbock", "gleisende", "bahn", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="4" y1="32" x2="40" y2="32" stroke="#000" stroke-width="2"/><line x1="40" y1="16" x2="40" y2="48" stroke="#000" stroke-width="4"/><line x1="44" y1="20" x2="56" y2="20" stroke="#000" stroke-width="2"/><line x1="44" y1="44" x2="56" y2="44" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_verkehrsschild",
|
||||
name: "Verkehrsschild",
|
||||
filename: "vermessung_verkehrsschild.svg",
|
||||
tags: ["schild", "verkehr", "straße", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="32" y1="36" x2="32" y2="60" stroke="#000" stroke-width="2"/><polygon points="32,8 50,24 50,36 14,36 14,24" fill="none" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_ampel",
|
||||
name: "Ampel",
|
||||
filename: "vermessung_ampel.svg",
|
||||
tags: ["ampel", "signal", "verkehr", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="22" y="8" width="20" height="40" fill="none" stroke="#000" stroke-width="2"/><circle cx="32" cy="18" r="5" fill="none" stroke="#000" stroke-width="1.5"/><circle cx="32" cy="28" r="5" fill="none" stroke="#000" stroke-width="1.5"/><circle cx="32" cy="38" r="5" fill="none" stroke="#000" stroke-width="1.5"/><line x1="32" y1="48" x2="32" y2="60" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_haltestelle",
|
||||
name: "Haltestelle",
|
||||
filename: "vermessung_haltestelle.svg",
|
||||
tags: ["haltestelle", "bus", "bahn", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="20" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="38" font-family="Arial" font-size="16" font-weight="bold" fill="#000" text-anchor="middle">H</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_parkplatz",
|
||||
name: "Parkplatz",
|
||||
filename: "vermessung_parkplatz.svg",
|
||||
tags: ["parkplatz", "parken", "stellplatz", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="14" y="14" width="36" height="36" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="40" font-family="Arial" font-size="24" font-weight="bold" fill="#000" text-anchor="middle">P</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_schranke",
|
||||
name: "Schranke",
|
||||
filename: "vermessung_schranke.svg",
|
||||
tags: ["schranke", "bahnübergang", "absperrung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="12" cy="32" r="6" fill="none" stroke="#000" stroke-width="2"/><line x1="18" y1="32" x2="60" y2="32" stroke="#000" stroke-width="3"/><line x1="24" y1="28" x2="28" y2="36" stroke="#000" stroke-width="2"/><line x1="36" y1="28" x2="40" y2="36" stroke="#000" stroke-width="2"/><line x1="48" y1="28" x2="52" y2="36" stroke="#000" stroke-width="2"/></svg>`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// ========== VERMESSUNG - TOPOGRAFIE ==========
|
||||
vermessung_topografie: {
|
||||
name: "Vermessung - Topografie",
|
||||
icon: "🌳",
|
||||
items: [
|
||||
{
|
||||
id: "vm_laubbaum",
|
||||
name: "Laubbaum",
|
||||
filename: "vermessung_laubbaum.svg",
|
||||
tags: ["baum", "laubbaum", "vegetation", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="28" r="18" fill="none" stroke="#000" stroke-width="2"/><line x1="32" y1="46" x2="32" y2="60" stroke="#000" stroke-width="3"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_nadelbaum",
|
||||
name: "Nadelbaum",
|
||||
filename: "vermessung_nadelbaum.svg",
|
||||
tags: ["baum", "nadelbaum", "tanne", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><polygon points="32,4 48,28 40,28 52,48 12,48 24,28 16,28" fill="none" stroke="#000" stroke-width="2"/><line x1="32" y1="48" x2="32" y2="60" stroke="#000" stroke-width="3"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_gebaeude",
|
||||
name: "Gebäude",
|
||||
filename: "vermessung_gebaeude.svg",
|
||||
tags: ["gebäude", "haus", "bauwerk", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="12" y="20" width="40" height="36" fill="none" stroke="#000" stroke-width="2"/><line x1="12" y1="20" x2="32" y2="8" stroke="#000" stroke-width="2"/><line x1="52" y1="20" x2="32" y2="8" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_hoehenpunkt",
|
||||
name: "Höhenpunkt",
|
||||
filename: "vermessung_hoehenpunkt.svg",
|
||||
tags: ["höhe", "nivellement", "punkt", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="22" y1="42" x2="42" y2="42" stroke="#000" stroke-width="2"/><line x1="32" y1="42" x2="32" y2="22" stroke="#000" stroke-width="2"/><circle cx="32" cy="22" r="4" fill="#000"/><text x="46" y="28" font-family="Arial" font-size="10" fill="#000">HP</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_boeschung",
|
||||
name: "Böschung",
|
||||
filename: "vermessung_boeschung.svg",
|
||||
tags: ["böschung", "hang", "gelände", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="8" y1="20" x2="56" y2="20" stroke="#000" stroke-width="2"/><line x1="8" y1="44" x2="56" y2="44" stroke="#000" stroke-width="2"/><line x1="12" y1="20" x2="8" y2="44" stroke="#000" stroke-width="1"/><line x1="20" y1="20" x2="16" y2="44" stroke="#000" stroke-width="1"/><line x1="28" y1="20" x2="24" y2="44" stroke="#000" stroke-width="1"/><line x1="36" y1="20" x2="32" y2="44" stroke="#000" stroke-width="1"/><line x1="44" y1="20" x2="40" y2="44" stroke="#000" stroke-width="1"/><line x1="52" y1="20" x2="48" y2="44" stroke="#000" stroke-width="1"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_fliessrichtung",
|
||||
name: "Fließrichtung",
|
||||
filename: "vermessung_fliessrichtung.svg",
|
||||
tags: ["fließrichtung", "gewässer", "bach", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><line x1="8" y1="32" x2="48" y2="32" stroke="#000" stroke-width="2"/><polygon points="56,32 44,24 44,40" fill="#000"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_quelle",
|
||||
name: "Quelle",
|
||||
filename: "vermessung_quelle.svg",
|
||||
tags: ["quelle", "wasser", "ursprung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="16" fill="none" stroke="#000" stroke-width="2"/><path d="M32 24 Q36 28 32 32 Q28 36 32 40" stroke="#000" stroke-width="2" fill="none"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_durchlass",
|
||||
name: "Durchlass",
|
||||
filename: "vermessung_durchlass.svg",
|
||||
tags: ["durchlass", "rohr", "kanal", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect x="8" y="24" width="48" height="16" fill="none" stroke="#000" stroke-width="2"/><line x1="8" y1="32" x2="0" y2="32" stroke="#000" stroke-width="2"/><line x1="56" y1="32" x2="64" y2="32" stroke="#000" stroke-width="2"/></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_kilometerstein",
|
||||
name: "Kilometerstein",
|
||||
filename: "vermessung_kilometerstein.svg",
|
||||
tags: ["kilometer", "stein", "markierung", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><polygon points="32,8 44,20 44,56 20,56 20,20" fill="none" stroke="#000" stroke-width="2"/><text x="32" y="42" font-family="Arial" font-size="12" fill="#000" text-anchor="middle">km</text></svg>`
|
||||
},
|
||||
{
|
||||
id: "vm_poller",
|
||||
name: "Poller",
|
||||
filename: "vermessung_poller.svg",
|
||||
tags: ["poller", "absperrung", "pfosten", "vermessung"],
|
||||
svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><circle cx="32" cy="32" r="10" fill="#000"/><circle cx="32" cy="32" r="4" fill="#fff"/></svg>`
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// ========== DYNAMISCHE PFEILE GENERIEREN ==========
|
||||
function generateArrowSVG(angle) {
|
||||
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><g transform="rotate(${angle}, 32, 32)"><rect x="28" y="20" width="8" height="30" fill="#dc2626"/><polygon points="32,4 16,24 24,24 24,20 40,20 40,24 48,24" fill="#dc2626"/></g></svg>`;
|
||||
}
|
||||
|
||||
function generateNorthArrowSVG(angle) {
|
||||
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><g transform="rotate(${angle}, 32, 32)"><circle cx="32" cy="32" r="28" fill="none" stroke="#374151" stroke-width="2"/><polygon points="32,6 26,32 32,28 38,32" fill="#dc2626"/><polygon points="32,58 26,32 32,36 38,32" fill="#ffffff" stroke="#374151" stroke-width="1"/><text x="32" y="18" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#1f2937" text-anchor="middle">N</text></g></svg>`;
|
||||
}
|
||||
|
||||
// Pfeile und Kompass generieren
|
||||
for (let angle = 0; angle < 360; angle += 15) {
|
||||
SYMBOLS.pfeile.items.push({
|
||||
id: `pfeil_${angle}`,
|
||||
name: `${angle}°`,
|
||||
filename: `richtungspfeil_rot_${angle}grad.svg`,
|
||||
tags: ["pfeil", "richtung", "rot", angle.toString()],
|
||||
svg: generateArrowSVG(angle)
|
||||
});
|
||||
|
||||
SYMBOLS.kompass.items.push({
|
||||
id: `nord_${angle}`,
|
||||
name: `${angle}°`,
|
||||
filename: `kompass_nord_${angle}grad.svg`,
|
||||
tags: ["nord", "kompass", "himmelsrichtung", angle.toString()],
|
||||
svg: generateNorthArrowSVG(angle)
|
||||
});
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -319,3 +319,44 @@ window.downloadStandaloneArrowDXF = function() {
|
||||
window.TextExport.downloadDxf(svg, 'pfeil.dxf');
|
||||
}
|
||||
};
|
||||
|
||||
// Zur Legende hinzufuegen
|
||||
window.addTextToLegend = function() {
|
||||
var state = window.TextGenState.current;
|
||||
var svg = window.SvgGenerator.generate(state);
|
||||
var name = state.text || 'Text-Symbol';
|
||||
|
||||
if (typeof legendItems !== 'undefined' && typeof updateLegendCount === 'function') {
|
||||
legendItems.push({
|
||||
id: 'text_' + Date.now(),
|
||||
name: name.split('\n')[0].substring(0, 30),
|
||||
svg: svg,
|
||||
description: ''
|
||||
});
|
||||
updateLegendCount();
|
||||
saveLegendToStorage();
|
||||
if (typeof showNotification === 'function') {
|
||||
showNotification('Zur Legende hinzugefuegt!');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addStandaloneArrowToLegend = function() {
|
||||
var state = window.TextGenState.current;
|
||||
var svg = window.SvgGenerator.generateArrowOnly(state);
|
||||
if (!svg) return;
|
||||
|
||||
if (typeof legendItems !== 'undefined' && typeof updateLegendCount === 'function') {
|
||||
legendItems.push({
|
||||
id: 'arrow_' + Date.now(),
|
||||
name: 'Pfeil ' + state.arrow,
|
||||
svg: svg,
|
||||
description: ''
|
||||
});
|
||||
updateLegendCount();
|
||||
saveLegendToStorage();
|
||||
if (typeof showNotification === 'function') {
|
||||
showNotification('Pfeil zur Legende hinzugefuegt!');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,9 +44,19 @@ var SvgGenerator = {
|
||||
case 'rect':
|
||||
shapeEl = draw.rect(width, height).move(x, y).radius(4);
|
||||
break;
|
||||
case 'square':
|
||||
var squareSize = Math.max(width, height);
|
||||
var squareX = x - (squareSize - width) / 2;
|
||||
var squareY = y - (squareSize - height) / 2;
|
||||
shapeEl = draw.rect(squareSize, squareSize).move(squareX, squareY).radius(4);
|
||||
break;
|
||||
case 'rounded':
|
||||
shapeEl = draw.rect(width, height).move(x, y).radius(Math.min(halfW, halfH) * 0.5);
|
||||
break;
|
||||
case 'circle':
|
||||
var circleRadius = Math.max(halfW, halfH);
|
||||
shapeEl = draw.circle(circleRadius * 2).center(cx, cy);
|
||||
break;
|
||||
case 'oval':
|
||||
shapeEl = draw.ellipse(width, height).center(cx, cy);
|
||||
break;
|
||||
|
||||
@@ -18,11 +18,13 @@ var UiBindings = {
|
||||
var e = this.elements;
|
||||
|
||||
// Text & Farben
|
||||
e.textInput = document.getElementById('textInput');
|
||||
e.textInput = document.getElementById('customText');
|
||||
e.fontSizeInput = document.getElementById('fontSize');
|
||||
e.fontSizeValue = document.getElementById('fontSizeValue');
|
||||
e.textColorInput = document.getElementById('textColor');
|
||||
e.textColorValue = document.getElementById('textColorValue');
|
||||
e.frameColorInput = document.getElementById('frameColor');
|
||||
e.frameColorValue = document.getElementById('frameColorValue');
|
||||
|
||||
// Rahmen
|
||||
e.frameScaleInput = document.getElementById('frameScale');
|
||||
@@ -30,16 +32,16 @@ var UiBindings = {
|
||||
e.frameScaleRow = document.getElementById('frameScaleRow');
|
||||
|
||||
// Padding
|
||||
e.paddingAllInput = document.getElementById('framePaddingAll');
|
||||
e.paddingAllValue = document.getElementById('framePaddingAllValue');
|
||||
e.paddingTopInput = document.getElementById('framePaddingTop');
|
||||
e.paddingTopValue = document.getElementById('framePaddingTopValue');
|
||||
e.paddingRightInput = document.getElementById('framePaddingRight');
|
||||
e.paddingRightValue = document.getElementById('framePaddingRightValue');
|
||||
e.paddingBottomInput = document.getElementById('framePaddingBottom');
|
||||
e.paddingBottomValue = document.getElementById('framePaddingBottomValue');
|
||||
e.paddingLeftInput = document.getElementById('framePaddingLeft');
|
||||
e.paddingLeftValue = document.getElementById('framePaddingLeftValue');
|
||||
e.paddingAllInput = document.getElementById('paddingAll');
|
||||
e.paddingAllValue = document.getElementById('paddingAllValue');
|
||||
e.paddingTopInput = document.getElementById('paddingTop');
|
||||
e.paddingTopValue = document.getElementById('paddingTopValue');
|
||||
e.paddingRightInput = document.getElementById('paddingRight');
|
||||
e.paddingRightValue = document.getElementById('paddingRightValue');
|
||||
e.paddingBottomInput = document.getElementById('paddingBottom');
|
||||
e.paddingBottomValue = document.getElementById('paddingBottomValue');
|
||||
e.paddingLeftInput = document.getElementById('paddingLeft');
|
||||
e.paddingLeftValue = document.getElementById('paddingLeftValue');
|
||||
e.paddingAllRow = document.getElementById('framePaddingAllRow');
|
||||
e.paddingRow = document.getElementById('framePaddingRow');
|
||||
|
||||
@@ -64,8 +66,8 @@ var UiBindings = {
|
||||
// Buttons
|
||||
e.shapeButtons = document.querySelectorAll('.shape-btn');
|
||||
e.arrowButtons = document.querySelectorAll('.arrow-btn');
|
||||
e.lineStyleButtons = document.querySelectorAll('.line-style-btn');
|
||||
e.lineWeightButtons = document.querySelectorAll('.line-weight-btn');
|
||||
e.lineStyleButtons = document.querySelectorAll('.line-btn');
|
||||
e.lineWeightButtons = document.querySelectorAll('.weight-btn');
|
||||
},
|
||||
|
||||
bindEvents: function() {
|
||||
@@ -95,12 +97,14 @@ var UiBindings = {
|
||||
if (e.textColorInput) {
|
||||
e.textColorInput.addEventListener('input', function(ev) {
|
||||
state.set('textColor', ev.target.value);
|
||||
if (e.textColorValue) e.textColorValue.textContent = ev.target.value;
|
||||
self.updatePreview();
|
||||
});
|
||||
}
|
||||
if (e.frameColorInput) {
|
||||
e.frameColorInput.addEventListener('input', function(ev) {
|
||||
state.set('frameColor', ev.target.value);
|
||||
if (e.frameColorValue) e.frameColorValue.textContent = ev.target.value;
|
||||
self.updatePreview();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user