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 { mapState } from '../state/MapState.svelte.js';
9 import MapPosition from '../components/MapPosition.svelte';
12 display_minimap = false,
13 current_result = null,
14 position_marker = null
20 function mapViewboxAsString(map) {
21 var bounds = map.getBounds();
22 var west = bounds.getWest();
23 var east = bounds.getEast();
25 if ((east - west) >= 360) { // covers more than whole planet
26 west = map.getCenter().lng - 179.999;
27 east = map.getCenter().lng + 179.999;
29 east = L.latLng(77, east).wrap().lng;
30 west = L.latLng(77, west).wrap().lng;
33 west.toFixed(5), // left
34 bounds.getNorth().toFixed(5), // top
35 east.toFixed(5), // right
36 bounds.getSouth().toFixed(5) // bottom
40 function createMap(container) {
41 const attribution = Nominatim_Config.Map_Tile_Attribution;
43 map = new L.map(container, {
44 attributionControl: false,
45 scrollWheelZoom: true, // !L.Browser.touch,
47 center: mapState.center,
50 if (typeof Nominatim_Config.Map_Default_Bounds !== 'undefined'
51 && Nominatim_Config.Map_Default_Bounds) {
52 map.fitBounds(Nominatim_Config.Map_Default_Bounds);
55 if (attribution && attribution.length) {
56 L.control.attribution({ prefix: '<a href="https://leafletjs.com/">Leaflet</a>' }).addTo(map);
59 mapState.viewboxStr = mapViewboxAsString(map);
61 L.control.scale().addTo(map);
63 L.tileLayer(Nominatim_Config.Map_Tile_URL, {
64 attribution: attribution
67 if (display_minimap) {
68 let osm2 = new L.TileLayer(Nominatim_Config.Map_Tile_URL, {
71 attribution: attribution
73 new L.Control.MiniMap(osm2, { toggleDisplay: true }).addTo(map);
76 map.on('move', () => {
77 mapState.center = map.getCenter();
78 mapState.zoom = map.getZoom();
79 mapState.viewboxStr = mapViewboxAsString(map);
82 map.on('mousemove', (e) => { mapState.mousePos = e.latlng; });
83 map.on('click', (e) => { mapState.lastClick = e.latlng; });
86 function mapAction(container) {
88 setMapData(position_marker, current_result);
97 function parse_and_normalize_geojson_string(part) {
98 // normalize places the geometry into a featurecollection, similar to
99 // https://github.com/mapbox/geojson-normalize
100 var parsed_geojson = {
101 type: 'FeatureCollection',
110 return parsed_geojson;
113 function resetMapData() {
114 if (!map) { return; }
116 dataLayers.forEach(function (layer) {
117 map.removeLayer(layer);
121 function setMapData(marker, aFeature) {
122 if (!map) { return; }
127 // We don't need a marker, but L.circle would change radius when you zoom in/out
128 let cm = L.circleMarker(
133 fillColor: '#ff7800',
140 cm.bindTooltip(`Search (${marker[0]},${marker[1]})`).openTooltip();
145 var search_params = new URLSearchParams(window.location.search);
146 var viewbox = search_params.get('viewbox');
148 let coords = viewbox.split(','); // <x1>,<y1>,<x2>,<y2>
149 let bounds = L.latLngBounds([coords[1], coords[0]], [coords[3], coords[2]]);
150 let viewbox_on_map = L.rectangle(bounds, {
158 map.addLayer(viewbox_on_map);
159 dataLayers.push(viewbox_on_map);
162 if (!aFeature) return;
164 let lat = aFeature.centroid ? aFeature.centroid.coordinates[1] : aFeature.lat;
165 let lon = aFeature.centroid ? aFeature.centroid.coordinates[0] : aFeature.lon;
166 let geojson = aFeature.geometry || aFeature.geojson;
169 let circle = L.circleMarker([lat, lon], {
170 radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75
172 if (marker) { // reverse result
173 circle.bindTooltip('Result').openTooltip();
175 map.addLayer(circle);
176 dataLayers.push(circle);
181 var geojson_layer = L.geoJson(
182 // https://leafletjs.com/reference-1.7.1.html#path-option
183 parse_and_normalize_geojson_string(geojson),
186 return { interactive: false, color: 'blue' };
190 map.addLayer(geojson_layer);
191 dataLayers.push(geojson_layer);
192 map.fitBounds(geojson_layer.getBounds());
193 } else if (lat && lon && marker) {
194 map.fitBounds([[lat, lon], marker], { padding: [50, 50] });
195 } else if (lat && lon) {
196 map.setView([lat, lon], 10);
201 setMapData(position_marker, current_result);
206 <div id="map" use:mapAction></div>
215 @media (max-width: 768px) {