3 import * as L from 'leaflet';
4 import 'leaflet-minimap';
5 import 'leaflet/dist/leaflet.css';
6 import 'leaflet-minimap/dist/Control.MiniMap.min.css';
8 import { get } from 'svelte/store';
9 import { get_config_value } from '../lib/config_reader.js';
10 import { map_store, current_result_store, current_request_latlon } from '../lib/stores.js';
11 import MapPosition from '../components/MapPosition.svelte';
13 export let display_minimap = false;
17 function createMap(container) {
18 const attribution = get_config_value('Map_Tile_Attribution') || null;
19 let map = new L.map(container, {
20 attributionControl: (attribution && attribution.length),
21 scrollWheelZoom: true, // !L.Browser.touch,
24 get_config_value('Map_Default_Lat'),
25 get_config_value('Map_Default_Lon')
27 zoom: get_config_value('Map_Default_Zoom')
30 L.tileLayer(get_config_value('Map_Tile_URL'), {
31 attribution: attribution
34 if (display_minimap) {
35 let osm2 = new L.TileLayer(get_config_value('Map_Tile_URL'), {
38 attribution: attribution
40 new L.Control.MiniMap(osm2, { toggleDisplay: true }).addTo(map);
43 const MapPositionControl = L.Control.extend({
44 options: { position: 'topright' },
45 onAdd: () => { return document.getElementById('show-map-position'); }
47 map.addControl(new MapPositionControl());
52 function mapAction(container) {
53 let map = createMap(container);
55 setMapData(get(current_result_store));
58 destroy: () => { map.remove(); }
62 function parse_and_normalize_geojson_string(part) {
63 // normalize places the geometry into a featurecollection, similar to
64 // https://github.com/mapbox/geojson-normalize
65 var parsed_geojson = {
66 type: 'FeatureCollection',
75 return parsed_geojson;
78 function resetMapData() {
79 let map = get(map_store);
82 dataLayers.forEach(function (layer) {
83 map.removeLayer(layer);
87 function setMapData(aFeature) {
88 let map = get(map_store);
93 let request_latlon = get(current_request_latlon);
95 // We don't need a marker, but an L.circle instance changes radius once you zoom in/out
96 let cm = L.circleMarker(
101 fillColor: '#ff7800',
112 var search_params = new URLSearchParams(window.location.search);
113 var viewbox = search_params.get('viewbox');
115 let coords = viewbox.split(','); // <x1>,<y1>,<x2>,<y2>
116 let bounds = L.latLngBounds([coords[1], coords[0]], [coords[3], coords[2]]);
117 L.rectangle(bounds, {
127 if (!aFeature) { return; }
129 let lat = aFeature.centroid ? aFeature.centroid.coordinates[1] : aFeature.lat;
130 let lon = aFeature.centroid ? aFeature.centroid.coordinates[0] : aFeature.lon;
131 let geojson = aFeature.geometry || aFeature.geojson;
134 let circle = L.circleMarker([lat, lon], {
135 radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75
137 map.addLayer(circle);
138 dataLayers.push(circle);
143 var geojson_layer = L.geoJson(
144 // https://leafletjs.com/reference-1.0.3.html#path-option
145 parse_and_normalize_geojson_string(geojson),
148 return { interactive: false, color: 'blue' };
152 map.addLayer(geojson_layer);
153 dataLayers.push(geojson_layer);
154 map.fitBounds(geojson_layer.getBounds());
155 } else if (lat && lon) {
156 map.setView([lat, lon], 10);
162 current_result_store.subscribe(aFeature => {
163 setMapData(aFeature);
167 function show_map_position_click(e) {
168 e.target.style.display = 'none';
169 document.getElementById('map-position').style.display = 'block';
174 <div id="map" use:mapAction />
175 <div id="show-map-position" class="leaflet-bar btn btn-sm btn-outline-secondary"
176 on:click|stopPropagation={show_map_position_click}
177 >show map bounds</div>
185 .btn-outline-secondary {
186 background-color: white;
189 .btn-outline-secondary:hover {
193 @media (max-width: 768px) {