Skip to content

Commit d776655

Browse files
authored
Merge pull request #1790 from griidc/feature/PELAGOS-5444-upgrade-data-landing-page-map-to-leaflet
Added leaflet map to dataland instead of GeoViz
2 parents 0072e04 + e1ba16a commit d776655

File tree

9 files changed

+406
-33
lines changed

9 files changed

+406
-33
lines changed

.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,6 @@ SITEMAP_MIN_DATE='2025-01-01'
112112
WKHTMLTOPDF_PATH=/usr/local/bin/wkhtmltopdf
113113
WKHTMLTOIMAGE_PATH=/usr/local/bin/wkhtmltoimage
114114
###< knplabs/knp-snappy-bundle ###
115+
116+
###> ESRI API KEY ###
117+
ESRI_API_KEY='yourkeyhere'

assets/css/leaflet-custom.css

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.leaflet-control-attribution {
2+
max-height: 3rem;
3+
overflow-x: auto;
4+
}
5+
6+
.leaflet-control-zoom-in span,
7+
.leaflet-control-zoom-out span {
8+
color: white;
9+
}
10+
11+
.leaflet-control-zoom-in:focus span,
12+
.leaflet-control-zoom-in:hover span,
13+
.leaflet-control-zoom-out:focus span,
14+
.leaflet-control-zoom-out:hover span {
15+
color: black;
16+
}
17+
18+
.leaflet-bar {
19+
background-color: rgba(0, 60, 136, 0.5);
20+
}
21+
22+
.leaflet-bar a:hover,
23+
.leaflet-bar a:focus {
24+
background-color: rgba(0, 60, 136, 0.5);
25+
}

assets/js/entry/data-land.js

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,68 @@
11
import Vue from 'vue';
22
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue';
3+
4+
import * as Leaflet from 'leaflet';
5+
import 'esri-leaflet';
6+
import * as EsriLeafletVector from 'esri-leaflet-vector';
7+
import '../../css/leaflet-custom.css';
8+
import Routing from '../../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min';
39
import FileManager from '../vue/FileManager.vue';
410
import '../../css/file-manager.css';
511
import '@fortawesome/fontawesome-free/css/all.min.css';
612
import DownloadZipBtn from '../vue/components/data-land/DownloadZipBtn.vue';
713
import HelpModal from '../vue/components/data-land/HelpModal.vue';
814
import '../../scss/data-land.scss';
915

16+
const leafletMap = document.getElementById('leaflet-map');
17+
18+
if (typeof (leafletMap) !== 'undefined' && leafletMap != null) {
19+
const { datasetId } = leafletMap.dataset;
20+
const esriApiKey = process.env.ESRI_API_KEY;
21+
22+
const GRIIDCStyle = {
23+
color: 'orange',
24+
weight: 4,
25+
opacity: 1,
26+
fillOpacity: 0.15,
27+
};
28+
29+
const map = Leaflet.map('leaflet-map', {
30+
preferCanvas: true,
31+
minZoom: 3,
32+
maxZoom: 14,
33+
attributionControl: true,
34+
worldCopyJump: true,
35+
});
36+
37+
const basemapEnum = 'ArcGIS:Imagery';
38+
EsriLeafletVector.vectorBasemapLayer(basemapEnum, {
39+
apiKey: esriApiKey,
40+
}).addTo(map);
41+
42+
Leaflet.featureGroup().addTo(map);
43+
44+
const url = `${Routing.generate('pelagos_app_ui_dataland_get_json')}/${datasetId}`;
45+
fetch(url).then((response) => response.json()).then((response) => {
46+
const geojsonMarkerOptions = {
47+
radius: 12,
48+
fill: false,
49+
weight: 4,
50+
opacity: 1,
51+
};
52+
const geojsonLayer = Leaflet.geoJson(response, {
53+
pointToLayer(feature, latlng) {
54+
return Leaflet.circleMarker(latlng, geojsonMarkerOptions);
55+
},
56+
style: GRIIDCStyle,
57+
onEachFeature(feature, layer) {
58+
layer.bindTooltip(feature.properties.name.toString(), { permanent: false, className: 'label' });
59+
},
60+
}).addTo(map);
61+
const bounds = geojsonLayer.getBounds();
62+
map.fitBounds(bounds, { padding: [20, 20] });
63+
});
64+
}
65+
1066
// Mount File Manager vue component
1167
const fileManagerElement = document.getElementById('file-manager-app');
1268
if (fileManagerElement) {
@@ -87,25 +143,6 @@ if (helpBtnElement) {
87143
});
88144
}
89145

90-
// eslint-disable-next-line no-undef
91-
const dlmap = new GeoViz();
92-
93-
dlmap.initMap('dlolmap', {
94-
onlyOneFeature: false, allowModify: false, allowDelete: false, staticMap: false, labelAttr: 'udi',
95-
});
96-
97-
// eslint-disable-next-line no-undef
98-
const geovizMap = $('#dlolmap');
99-
100-
if (geovizMap.attr('description') !== '' && geovizMap.attr('wkt') === '') {
101-
const imagePath = geovizMap.attr('labimage');
102-
dlmap.addImage(imagePath, 0.4);
103-
dlmap.makeStatic();
104-
} else if (geovizMap.attr('wkt')) {
105-
dlmap.addFeatureFromWKT(geovizMap.attr('wkt'), { udi: geovizMap.attr('udi') });
106-
dlmap.gotoAllFeatures();
107-
}
108-
109146
const metadataDownloadBtn = document.getElementById('metadata-download');
110147
if (metadataDownloadBtn) {
111148
metadataDownloadBtn.addEventListener('click', () => {

config/services.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ parameters:
1212
custom_template: '%env(CUSTOM_BASE_TEMPLATE)%'
1313
main_site: '%env(MAINSITE)%'
1414
sitemap_min_date: '%env(SITEMAP_MIN_DATE)%'
15+
esri_api_key: '%env(ESRI_API_KEY)%'
1516

1617
services:
1718
# default configuration for services in *this* file

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,16 @@
5454
"devextreme-vue": "^21.1.6",
5555
"dotenv-webpack": "^8.1.0",
5656
"dropzone": "^5.7.2",
57+
"esri-leaflet": "^3.0.14",
58+
"esri-leaflet-vector": "^4.2.7",
5759
"exceljs": "^4.3.0",
5860
"file-saver": "^2.0.5",
5961
"jquery": "^3.5.1",
6062
"jquery-migrate": "^3.1.0",
6163
"jquery-ui": "^1.13.2",
6264
"jquery.cookie": "^1.4.1",
65+
"leaflet": "^1.9.4",
66+
"maplibre-gl": "^4.7.1",
6367
"postcss-loader": "^7.0.0",
6468
"prop-types": "^15.8.1",
6569
"qtip2": "2.2.0",

src/Controller/UI/DatalandController.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use App\Entity\Dataset;
1515
use App\Util\GmlUtil;
1616
use Doctrine\ORM\EntityManagerInterface;
17+
use Symfony\Component\HttpFoundation\JsonResponse;
1718

1819
/**
1920
* The Dataset Monitoring controller.
@@ -269,6 +270,7 @@ public function indexPage(string $udi, EntityManagerInterface $entityManager)
269270
'wkt' => $wkt,
270271
'datasetSubmissionLockStatus' => true,
271272
'issuetracker' => $this->issueTrackingBaseUrl,
273+
'esri_api_key' => $mainsite = $this->getParameter('esri_api_key'),
272274
)
273275
);
274276
}
@@ -302,4 +304,18 @@ public function getFormattedMetadata(string $udi)
302304
)
303305
);
304306
}
307+
308+
#[Route('/data/json/{dataset}', name: 'pelagos_app_ui_dataland_get_json', methods: ['GET', 'HEAD'])]
309+
public function getjson(Dataset $dataset, Geometry $geometryUtil): Response
310+
{
311+
$geoJson = [];
312+
$udi = $dataset->getUdi();
313+
$spatialExtent = $dataset->getSpatialExtentGeometry();
314+
315+
if ($spatialExtent !== null) {
316+
$geoJson = $geometryUtil->convertGmlToGeoJSON(gml:$spatialExtent, udi:$udi, id:$udi);
317+
}
318+
319+
return new JsonResponse($geoJson, 200, [], true);
320+
}
305321
}

src/Util/Geometry.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,24 @@ public function convertGmlToWkt(string $gml)
125125

126126
return $wkt[0];
127127
}
128+
129+
/**
130+
* Convert GML to GeoJSON representation
131+
*
132+
* @param string $gml Textual GML of geometry.
133+
* @param string $udi Dataset UDI.
134+
* @param string $id Identifier for feature.
135+
*/
136+
public function convertGmlToGeoJSON(string $gml, string $udi = 'unknown', string $id = 'A'): mixed
137+
{
138+
$sql = "SELECT ST_AsGeoJSON(t.*) FROM (VALUES(:id, :name, ST_GeomFromGML(:gml))) AS t(id, name, geom)";
139+
$connection = $this->entityManager->getConnection();
140+
$statement = $connection->prepare($sql);
141+
try {
142+
$result = $statement->executeQuery(array('gml' => $gml, 'id' => $id, 'name' => $udi));
143+
} catch (DriverException $e) {
144+
throw new InvalidGmlException($e->getMessage());
145+
}
146+
return $result->fetchOne();
147+
}
128148
}

templates/Dataland/v2/index.html.twig

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
{% endblock %}
1313

1414
{% block stylesheets %}
15+
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
1516
{{ encore_entry_link_tags('data-land') }}
1617
{{ parent() }}
1718
{% endblock stylesheets %}
@@ -89,12 +90,7 @@
8990
<hr>
9091
{% if dataset.datasetSubmission.spatialExtent|default %}
9192
<div class="py-2">
92-
<div id="dlolmap" style="width: 100%;height:480px;"
93-
wkt="{{wkt|default}}"
94-
udi="{{dataset.udi}}"
95-
description= {{ (dataset.datasetStatus == constant('App\\Entity\\Dataset::DATASET_STATUS_ACCEPTED')) ? dataset.datasetSubmission.spatialExtentDescription : "" }}
96-
labimage="{{ asset('build/images/labonly.png') }}">
97-
</div>
93+
<div id="leaflet-map" data-dataset-id="{{ dataset.id }}" style="width: 100%;height:480px;"></div>
9894
</div>
9995
<hr>
10096
{% endif %}
@@ -128,9 +124,5 @@
128124
{% block javascripts %}
129125
{{ parent() }}
130126

131-
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/openlayers/2.13.1/OpenLayers.js"></script>
132-
<script type="text/javascript" src="//maps.google.com/maps/api/js?v=3.51&key={{ google_maps_api_key }}&callback=Function.prototype"></script>
133-
<script type="text/javascript" src="{{ asset('build/js/geoviz.js') }}"></script>
134-
135127
{{ encore_entry_script_tags('data-land') }}
136128
{% endblock %}

0 commit comments

Comments
 (0)