initial
This commit is contained in:
318
ts_web/elements/00group-map/dees-geo-map/dees-geo-map.demo.ts
Normal file
318
ts_web/elements/00group-map/dees-geo-map/dees-geo-map.demo.ts
Normal file
@@ -0,0 +1,318 @@
|
||||
import { html, css, cssManager } from '@design.estate/dees-element';
|
||||
import '@design.estate/dees-wcctools/demotools';
|
||||
import type { DeesGeoMap } from './dees-geo-map.js';
|
||||
|
||||
export const demoFunc = () => html`
|
||||
<style>
|
||||
${css`
|
||||
.demo-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
padding: 24px;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.demo-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.demo-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.demo-description {
|
||||
font-size: 14px;
|
||||
color: ${cssManager.bdTheme('#666', '#999')};
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.map-wrapper {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
dees-geo-map {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.event-log {
|
||||
background: ${cssManager.bdTheme('#f5f5f5', '#1a1a1a')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e0e0e0', '#333')};
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.event-entry {
|
||||
padding: 4px 0;
|
||||
border-bottom: 1px solid ${cssManager.bdTheme('#e0e0e0', '#333')};
|
||||
color: ${cssManager.bdTheme('#555', '#aaa')};
|
||||
}
|
||||
|
||||
.event-entry:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.event-type {
|
||||
color: ${cssManager.bdTheme('#0066cc', '#66b3ff')};
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.controls-row {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
padding: 8px 16px;
|
||||
border: 1px solid ${cssManager.bdTheme('#ccc', '#444')};
|
||||
border-radius: 6px;
|
||||
background: ${cssManager.bdTheme('#fff', '#2a2a2a')};
|
||||
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
.control-button:hover {
|
||||
background: ${cssManager.bdTheme('#f0f0f0', '#333')};
|
||||
border-color: ${cssManager.bdTheme('#999', '#666')};
|
||||
}
|
||||
|
||||
.feature-display {
|
||||
background: ${cssManager.bdTheme('#f9f9f9', '#1e1e1e')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e0e0e0', '#333')};
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.feature-json {
|
||||
font-family: monospace;
|
||||
font-size: 11px;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||
}
|
||||
|
||||
.locations-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.location-button {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid ${cssManager.bdTheme('#ddd', '#444')};
|
||||
border-radius: 6px;
|
||||
background: ${cssManager.bdTheme('#fff', '#2a2a2a')};
|
||||
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
.location-button:hover {
|
||||
background: ${cssManager.bdTheme('#0066cc', '#0084ff')};
|
||||
color: #fff;
|
||||
border-color: transparent;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
|
||||
<div class="demo-container">
|
||||
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
|
||||
const map = elementArg.querySelector('dees-geo-map') as DeesGeoMap;
|
||||
const eventLog = elementArg.querySelector('#event-log') as HTMLElement;
|
||||
const featureJson = elementArg.querySelector('#feature-json') as HTMLElement;
|
||||
|
||||
const addLogEntry = (type: string, message: string) => {
|
||||
const entry = document.createElement('div');
|
||||
entry.className = 'event-entry';
|
||||
entry.innerHTML = `<span class="event-type">${type}</span>: ${message}`;
|
||||
eventLog.insertBefore(entry, eventLog.firstChild);
|
||||
};
|
||||
|
||||
const updateFeatureDisplay = () => {
|
||||
if (map && featureJson) {
|
||||
featureJson.textContent = JSON.stringify(map.getGeoJson(), null, 2);
|
||||
}
|
||||
};
|
||||
|
||||
if (map) {
|
||||
map.addEventListener('map-ready', () => {
|
||||
addLogEntry('ready', 'Map initialized successfully');
|
||||
});
|
||||
|
||||
map.addEventListener('draw-change', (e: CustomEvent) => {
|
||||
addLogEntry('change', `${e.detail.type} - ${e.detail.ids.length} feature(s) affected`);
|
||||
updateFeatureDisplay();
|
||||
});
|
||||
|
||||
map.addEventListener('draw-finish', (e: CustomEvent) => {
|
||||
addLogEntry('finish', `${e.detail.context.mode} completed (id: ${e.detail.id})`);
|
||||
});
|
||||
|
||||
map.addEventListener('map-move', (e: CustomEvent) => {
|
||||
console.log('Map moved:', e.detail);
|
||||
});
|
||||
|
||||
map.addEventListener('address-selected', (e: CustomEvent) => {
|
||||
addLogEntry('address', `Selected: ${e.detail.address.substring(0, 50)}...`);
|
||||
console.log('Address selected:', e.detail);
|
||||
});
|
||||
|
||||
map.addEventListener('route-calculated', (e: CustomEvent) => {
|
||||
const { route, mode } = e.detail;
|
||||
const distKm = (route.distance / 1000).toFixed(1);
|
||||
const durationMin = Math.round(route.duration / 60);
|
||||
addLogEntry('route', `${mode}: ${distKm} km, ${durationMin} min`);
|
||||
console.log('Route calculated:', e.detail);
|
||||
});
|
||||
}
|
||||
|
||||
// Set up navigation buttons
|
||||
const locations: Record<string, [number, number]> = {
|
||||
paris: [2.3522, 48.8566],
|
||||
london: [-0.1276, 51.5074],
|
||||
newyork: [-74.006, 40.7128],
|
||||
tokyo: [139.6917, 35.6895],
|
||||
sydney: [151.2093, -33.8688],
|
||||
rio: [-43.1729, -22.9068],
|
||||
};
|
||||
|
||||
Object.entries(locations).forEach(([name, coords]) => {
|
||||
const btn = elementArg.querySelector(`#nav-${name}`) as HTMLButtonElement;
|
||||
if (btn && map) {
|
||||
btn.addEventListener('click', () => map.flyTo(coords, 13));
|
||||
}
|
||||
});
|
||||
|
||||
// Set up control buttons
|
||||
const clearBtn = elementArg.querySelector('#btn-clear') as HTMLButtonElement;
|
||||
const fitBtn = elementArg.querySelector('#btn-fit') as HTMLButtonElement;
|
||||
const downloadBtn = elementArg.querySelector('#btn-download') as HTMLButtonElement;
|
||||
const loadBtn = elementArg.querySelector('#btn-load') as HTMLButtonElement;
|
||||
|
||||
if (clearBtn && map) {
|
||||
clearBtn.addEventListener('click', () => {
|
||||
map.clearAllFeatures();
|
||||
updateFeatureDisplay();
|
||||
});
|
||||
}
|
||||
|
||||
if (fitBtn && map) {
|
||||
fitBtn.addEventListener('click', () => map.fitToFeatures());
|
||||
}
|
||||
|
||||
if (downloadBtn && map) {
|
||||
downloadBtn.addEventListener('click', () => {
|
||||
const geojson = map.getGeoJson();
|
||||
const blob = new Blob([JSON.stringify(geojson, null, 2)], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = 'features.geojson';
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
}
|
||||
|
||||
if (loadBtn && map) {
|
||||
loadBtn.addEventListener('click', () => {
|
||||
map.loadGeoJson({
|
||||
type: 'FeatureCollection',
|
||||
features: [
|
||||
{
|
||||
type: 'Feature',
|
||||
properties: { mode: 'polygon' },
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [[
|
||||
[8.675, 50.115],
|
||||
[8.690, 50.115],
|
||||
[8.690, 50.105],
|
||||
[8.675, 50.105],
|
||||
[8.675, 50.115],
|
||||
]],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
updateFeatureDisplay();
|
||||
});
|
||||
}
|
||||
}}>
|
||||
<div class="demo-section">
|
||||
<h2 class="demo-title">Interactive Map with Drawing Tools</h2>
|
||||
<p class="demo-description">
|
||||
Click on the drawing tools in the toolbar to create shapes on the map.
|
||||
Use the Select tool to edit, move, or delete shapes. All features are
|
||||
rendered using terra-draw with MapLibre GL JS.
|
||||
</p>
|
||||
|
||||
<div class="map-wrapper">
|
||||
<dees-geo-map
|
||||
.center=${[8.6821, 50.1109] as [number, number]}
|
||||
.zoom=${12}
|
||||
.showSearch=${true}
|
||||
.showNavigation=${true}
|
||||
></dees-geo-map>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo-section">
|
||||
<h2 class="demo-title">Quick Navigation</h2>
|
||||
<div class="locations-grid">
|
||||
<button class="location-button" id="nav-paris">Paris</button>
|
||||
<button class="location-button" id="nav-london">London</button>
|
||||
<button class="location-button" id="nav-newyork">New York</button>
|
||||
<button class="location-button" id="nav-tokyo">Tokyo</button>
|
||||
<button class="location-button" id="nav-sydney">Sydney</button>
|
||||
<button class="location-button" id="nav-rio">Rio</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo-section">
|
||||
<h2 class="demo-title">Controls</h2>
|
||||
<div class="controls-row">
|
||||
<button class="control-button" id="btn-clear">Clear All Features</button>
|
||||
<button class="control-button" id="btn-fit">Fit to Features</button>
|
||||
<button class="control-button" id="btn-download">Download GeoJSON</button>
|
||||
<button class="control-button" id="btn-load">Load Sample Data</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo-section">
|
||||
<h2 class="demo-title">Event Log</h2>
|
||||
<div class="event-log">
|
||||
<div id="event-log">
|
||||
<div class="event-entry"><span class="event-type">init</span>: Waiting for map...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo-section">
|
||||
<h2 class="demo-title">Current Features (GeoJSON)</h2>
|
||||
<div class="feature-display">
|
||||
<pre class="feature-json" id="feature-json">{ "type": "FeatureCollection", "features": [] }</pre>
|
||||
</div>
|
||||
</div>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
`;
|
||||
Reference in New Issue
Block a user