map : better geojson point support

This commit is contained in:
lovasoa
2023-11-11 01:24:41 +01:00
parent 13849cc0f2
commit c7351f5095
4 changed files with 48 additions and 14 deletions
+6
View File
@@ -1,5 +1,11 @@
# CHANGELOG.md
## 0.15.2 (unreleased)
- Fix a bug where the new geojson support in the map component would not work when the geojson was passed as a string. This impacted databases that do not support native json objects, such as SQLite.
- Improve support for geojson points (in addition to polygons and lines) in the map component.
- Add a new `size` parameter to the map component to set the size of markers.
## 0.15.1 (2023-11-07)
- Many improvements in the [`form`](https://sql.ophir.dev/documentation.sql?component=form#component) component
@@ -41,7 +41,7 @@ VALUES (
(
'map',
'latitude',
'Latitude of the marker. Required if geojson is not set.',
'Latitude of the marker. Required only if geojson is not set.',
'REAL',
FALSE,
FALSE
@@ -49,7 +49,7 @@ VALUES (
(
'map',
'longitude',
'Longitude of the marker. Required if geojson is not set.',
'Longitude of the marker. Required only if geojson is not set.',
'REAL',
FALSE,
FALSE
@@ -105,10 +105,18 @@ VALUES (
(
'map',
'geojson',
'A GeoJSON geometry (line, a polygon, ...) to display on the map. Can be styled using geojson properties using the name of leaflet path options.',
'A GeoJSON geometry (line, polygon, ...) to display on the map. Can be styled using geojson properties using the name of leaflet path options. Introduced in 0.15.1. Accepts raw strings in addition to JSON objects since 0.15.2.',
'JSON',
FALSE,
TRUE
),
(
'map',
'size',
'Size of the marker icon. Requires "icon" to be set.',
'INTEGER',
FALSE,
TRUE
)
;
-- Insert an example usage of the map component into the example table
@@ -117,7 +125,18 @@ VALUES (
'map',
'Basic example of a map with a marker',
JSON(
'[{ "component": "map", "zoom": 2 }, { "title": "New Delhi", "latitude": 28.6139, "longitude": 77.2090 }]'
'[{ "component": "map", "zoom": 1 }, { "title": "New Delhi", "latitude": 28.6139, "longitude": 77.2090 }]'
)
),
(
'map',
'Basic marker defined in GeoJSON. Using [leaflet marker options](https://leafletjs.com/reference.html#marker-option) as GeoJSON properties.',
JSON(
'[{ "component": "map", "zoom": 1 },
{ "icon": "peace",
"size": 20,
"link": "https://en.wikipedia.org/wiki/Nelson_Mandela",
"geojson": "{\"type\":\"Feature\", \"properties\": { \"title\":\"Birth Place of Nelson Mandela\" }, \"geometry\": { \"type\":\"Point\", \"coordinates\": [28.49, -31.96] }}"}]'
)
),
(
+12 -5
View File
@@ -62,17 +62,20 @@ function sqlpage_map() {
const marker =
dataset.coords ? createMarker(marker_elem, options)
: createGeoJSONMarker(marker_elem, options);
marker.addTo(map).bindPopup(marker_elem);
marker.addTo(map);
if (options.title) marker.bindPopup(marker_elem);
else if (marker_elem.dataset.link) marker.on('click', () => window.location = marker_elem.dataset.link);
}
function createMarker(marker_elem, options) {
const coords = marker_elem.dataset.coords.split(",").map(c => parseFloat(c));
const icon_obj = marker_elem.getElementsByClassName("mapicon")[0];
if (icon_obj) {
const size = 1.5 * +(options.size || icon_obj.firstChild?.getAttribute('width') || 24);
options.icon = L.divIcon({
html: icon_obj,
className: `border-0 bg-${options.color || 'primary'} bg-gradient text-white rounded-circle p-2 shadow`,
iconSize: [42, 42],
iconAnchor: [21, 21],
className: `border-0 bg-${options.color || 'primary'} bg-gradient text-white rounded-circle shadow d-flex justify-content-center align-items-center`,
iconSize: [size, size],
iconAnchor: [size/2, size/2],
});
}
return L.marker(coords, options);
@@ -86,7 +89,11 @@ function sqlpage_map() {
if (typeof properties !== "object") return options;
return {...options, ...properties};
}
return L.geoJSON(geojson, { style });
function pointToLayer(feature, latlng) {
marker_elem.dataset.coords = latlng.lat + "," + latlng.lng;
return createMarker(marker_elem, { ...options, ...feature.properties });
}
return L.geoJSON(geojson, { style, pointToLayer });
}
}
+7 -5
View File
@@ -18,17 +18,19 @@
<div class="d-none" hidden>
{{~#each_row~}}
<div class="marker"
{{#if latitude}}data-coords="{{latitude}},{{longitude}}"{{/if}}
{{#if color}}data-color="{{color}}"{{/if}}
{{#if geojson}}data-geojson="
{{~#if latitude}} data-coords="{{latitude}},{{longitude}}"{{/if}}
{{~#if color}} data-color="{{color}}"{{/if}}
{{~#if size}} data-size="{{size}}"{{/if}}
{{~#if link}} data-link="{{link}}"{{/if}}
{{~#if geojson}} data-geojson="
{{~#if (eq (typeof geojson) 'string')}}{{geojson}}
{{~else~}}{{stringify geojson}}
{{~/if~}}
"{{/if}}
"{{/if~}}
>
<h3>
{{~#if icon~}}
<span class="mapicon">{{~icon_img icon~}}</span>
<span class="mapicon">{{~icon_img icon size~}}</span>
{{~/if~}}
{{~#if link~}}
<a href="{{link}}">{{title}}</a>