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: false, // Disable zoom controls zoom: 6, // maxZoom: 9, minZoom: 5, maxBounds: [ [45.0, 10.0], // Southwest corner of the bounds [50.0, 17.0] // Northeast corner of the bounds ], maxBoundsViscosity: 1.0 // Ensure the map cannot be dragged outside the bounds }); // const openStreetMapLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { // attribution: '© OpenStreetMap contributors', // noWrap: true // Prevent tiles from wrapping outside the bounds // }).addTo(map); const basemapAtLayer = L.tileLayer('https://maps{s}.wien.gv.at/basemap/geolandbasemap/normal/google3857/{z}/{y}/{x}.png', { attribution: 'Datenquelle: 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 L.LatLngExpression; const center = [southWest[0], southWest[1]] as [number, number]; // const radius = 1000; // You can adjust the radius as needed // // Draw a filled circle // var circle = L.circle(center, { // color: '#30D5C8', // Outline color // fillColor: '#336699' , // Fill color // fillOpacity: 1, // Opacity of the fill // opacity: 0.5, // weight: 10, // radius: radius // Radius in meters // }).addTo(map); // 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); // // Create an empty circle to adjust the map to it // var circle = L.circle(center, {radius: radius}).addTo(map); // // Fit the map's view to the circle's bounds // map.fitBounds(circle.getBounds()); // 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.setView(this.originalCenter, this.originalZoom); map.fitBounds(markerBounds); }); map.fitBounds(markerBounds); } 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.setView(this.originalCenter, this.originalZoom); map.fitBounds(this.bounds); }); // Fit the map's view to the rectangle's bounds map.fitBounds(this.bounds); } } }