import { Component, Prop, Vue } from 'vue-facing-decorator'; import * as L from 'leaflet'; import 'leaflet/dist/leaflet.css'; @Component({ name: 'Minimap', }) export default class Minimap extends Vue { @Prop({ type: Array, required: true }) bounds!: L.LatLngBoundsLiteral; // private originalCenter: L.LatLngExpression = [47.71, 13.55]; // Original center // private originalZoom: number = 6; // Original zoom level mounted() { const map = L.map('map', { center: [47.71, 13.55], zoomControl: true, zoom: 6, minZoom: 5, maxBounds: [ [44.0, 9.0], // Southwest corner of the bounds [51.0, 18.0] // Northeast corner of the bounds ], maxBoundsViscosity: 1.0 // Ensure the map cannot be dragged outside the bounds }); // Remove Leaflet logo and text map.attributionControl.setPrefix(false); const basemapAtLayer = L.tileLayer('https://maps{s}.wien.gv.at/basemap/geolandbasemap/normal/google3857/{z}/{y}/{x}.png', { attribution: 'basemap.at', noWrap: true, subdomains: ['', '1', '2', '3', '4'] }).addTo(map); const esriImageryLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { attribution: 'Tiles © Esri' }); const esriTopoLayer = L.tileLayer('https://server.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', { attribution: 'Tiles © Esri' }); const baseMaps = { // "OpenStreetMap": openStreetMapLayer, "basemap.at": basemapAtLayer, "ESRI Imagery": esriImageryLayer, "ESRI Topo": esriTopoLayer }; L.control.layers(baseMaps).addTo(map); const [southWest, northEast] = this.bounds; if (southWest[0] === northEast[0] || southWest[1] === northEast[1]) { // If y_min and y_max (and x_min and x_max) are equal, generate a circle const center = [southWest[0], southWest[1]] as [number, number]; // Using CircleMarker to maintain constant size regardless of zoom level const circleMarker = L.circleMarker(center, { color: '#30D5C8', // Outline color fillColor: '#336699', // Fill color fillOpacity: 1, // Opacity of the fill opacity: 0.5, // Outline opacity weight: 10, // Outline weight radius: 10 // Radius in pixels }).addTo(map); // Manually create a small bounding box around the marker's center to fit bounds const buffer = 0.01; // Adjust this value to control the area around the marker const markerBounds = L.latLngBounds( [center[0] - buffer, center[1] - buffer], // Southwest corner [center[0] + buffer, center[1] + buffer] // Northeast corner ); // Add a click event to the CircleMarker circleMarker.on('click', () => { map.fitBounds(markerBounds, { padding: [10, 10] }); }); map.fitBounds(markerBounds, { padding: [10, 10] }); } else { // Otherwise, generate a rectangle const rectangle = L.rectangle(this.bounds, { color: '#30D5C8', weight: 2, opacity: 1 }).addTo(map); //336699 // Add a click event to the Rectangle rectangle.on('click', () => { map.fitBounds(this.bounds, { padding: [18, 18] }); }); // Fit the map's view to the rectangle's bounds with padding map.fitBounds(this.bounds, { padding: [18, 18] }); } } }