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 { map_store } from '../lib/stores.js';
10 import MapPosition from '../components/MapPosition.svelte';
13 display_minimap = false,
14 current_result = null,
15 position_marker = null
20 function createMap(container) {
21 const attribution = Nominatim_Config.Map_Tile_Attribution;
23 let map = new L.map(container, {
24 attributionControl: false,
25 scrollWheelZoom: true, // !L.Browser.touch,
28 Nominatim_Config.Map_Default_Lat,
29 Nominatim_Config.Map_Default_Lon
31 zoom: Nominatim_Config.Map_Default_Zoom
33 if (typeof Nominatim_Config.Map_Default_Bounds !== 'undefined'
34 && Nominatim_Config.Map_Default_Bounds) {
35 map.fitBounds(Nominatim_Config.Map_Default_Bounds);
38 if (attribution && attribution.length) {
39 L.control.attribution({ prefix: '<a href="https://leafletjs.com/">Leaflet</a>' }).addTo(map);
42 L.control.scale().addTo(map);
44 L.tileLayer(Nominatim_Config.Map_Tile_URL, {
45 attribution: attribution
48 if (display_minimap) {
49 let osm2 = new L.TileLayer(Nominatim_Config.Map_Tile_URL, {
52 attribution: attribution
54 new L.Control.MiniMap(osm2, { toggleDisplay: true }).addTo(map);
57 const MapPositionControl = L.Control.extend({
58 options: { position: 'topright' },
59 onAdd: () => { return document.getElementById('show-map-position'); }
61 map.addControl(new MapPositionControl());
66 function mapAction(container) {
67 let map = createMap(container);
69 setMapData(current_result);
79 function parse_and_normalize_geojson_string(part) {
80 // normalize places the geometry into a featurecollection, similar to
81 // https://github.com/mapbox/geojson-normalize
82 var parsed_geojson = {
83 type: 'FeatureCollection',
92 return parsed_geojson;
95 function resetMapData() {
96 let map = get(map_store);
99 dataLayers.forEach(function (layer) {
100 map.removeLayer(layer);
104 function setMapData(aFeature) {
105 let map = get(map_store);
106 if (!map) { return; }
110 if (position_marker) {
111 // We don't need a marker, but L.circle would change radius when you zoom in/out
112 let cm = L.circleMarker(
117 fillColor: '#ff7800',
124 cm.bindTooltip(`Search (${position_marker[0]},${position_marker[1]})`).openTooltip();
129 var search_params = new URLSearchParams(window.location.search);
130 var viewbox = search_params.get('viewbox');
132 let coords = viewbox.split(','); // <x1>,<y1>,<x2>,<y2>
133 let bounds = L.latLngBounds([coords[1], coords[0]], [coords[3], coords[2]]);
134 let viewbox_on_map = L.rectangle(bounds, {
142 map.addLayer(viewbox_on_map);
143 dataLayers.push(viewbox_on_map);
146 if (!aFeature) return;
148 let lat = aFeature.centroid ? aFeature.centroid.coordinates[1] : aFeature.lat;
149 let lon = aFeature.centroid ? aFeature.centroid.coordinates[0] : aFeature.lon;
150 let geojson = aFeature.geometry || aFeature.geojson;
153 let circle = L.circleMarker([lat, lon], {
154 radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75
156 if (position_marker) { // reverse result
157 circle.bindTooltip('Result').openTooltip();
159 map.addLayer(circle);
160 dataLayers.push(circle);
165 var geojson_layer = L.geoJson(
166 // https://leafletjs.com/reference-1.7.1.html#path-option
167 parse_and_normalize_geojson_string(geojson),
170 return { interactive: false, color: 'blue' };
174 map.addLayer(geojson_layer);
175 dataLayers.push(geojson_layer);
176 map.fitBounds(geojson_layer.getBounds());
177 } else if (lat && lon && position_marker) {
178 map.fitBounds([[lat, lon], position_marker], { padding: [50, 50] });
179 } else if (lat && lon) {
180 map.setView([lat, lon], 10);
184 $effect(() => { setMapData(current_result); });
186 function show_map_position_click(e) {
188 e.target.style.display = 'none';
189 document.getElementById('map-position').style.display = 'block';
194 <div id="map" use:mapAction></div>
195 <button id="show-map-position" class="leaflet-bar btn btn-sm btn-outline-secondary"
196 onclick={show_map_position_click}
197 >show map bounds</button>
205 .btn-outline-secondary {
206 background-color: white;
209 .btn-outline-secondary:hover {
213 @media (max-width: 768px) {