Fehler bei der Verarbeitung der Vorlage.
Java method "as.asac.template.tools.DLToolImpl.getThumbnailByJSON(String, String)" threw an exception when invoked on as.asac.template.tools.DLToolImpl object "as.asac.template.tools.DLToolImpl@33526454"; see cause exception in the Java stack trace.
----
FTL stack trace ("~" means nesting-related):
- Failed at: #assign slideThumbnail1 = dlTool.getT... [in template "37703#37743#9124970" at line 713, column 81]
----
1<#-- Services -->
2<#assign assetEntryLocalServiceUtil = serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService")/>
3<#assign assetLinkLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetLinkLocalService")/>
4<#assign journalArticleResourceServiceUtil = serviceLocator.findService("com.liferay.journal.service.JournalArticleResourceLocalService")/>
5<#assign assetVocabularyLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetVocabularyLocalService") />
6<#assign assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService")>
7<#assign ddmStructureLocalService = serviceLocator.findService("com.liferay.dynamic.data.mapping.service.DDMStructureLocalService")/>
8<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")>
9
10<#-- Reserved vbles -->
11<#assign title = .vars['reserved-article-title'].data>
12<#assign articleId=.vars["reserved-article-id"].data />
13<#assign description=.vars["reserved-article-description"].data />
14<#assign smallImageUrl=.vars["reserved-article-small-image-url"].data />
15<#assign date=.vars["reserved-article-display-date"].data />
16<#assign request = .vars['request']>
17
18<#-- Init -->
19<#assign jsonFactoryUtil = staticUtil["com.liferay.portal.kernel.json.JSONFactoryUtil"] />
20<#assign assetEntry = journalTool.getAssetEntryByArticleId(groupId, articleId)>
21<#assign journalArticle = journalTool.getJournalArticleByAssetEntry(assetEntry)>
22<#assign ddmStructureRoute = journalArticle.getDDMStructure()>
23<#assign resourcePrimKey = journalArticle.getResourcePrimKey()>
24<#assign articleURL = themeDisplay.getURLPortal()+themeDisplay.getURLCurrent()>
25<#assign articleSocialBookmarks = themeDisplay.getThemeSetting("article-social-bookmarks")!>
26<#assign layoutSetBannerPath = layoutTool.getLayoutSetBannerPath(groupId, themeDisplay.getLayout().isPrivateLayout())!>
27<#assign articleMainImageThumbnail1 = dlTool.getThumbnail(smallImageUrl, "1", layoutSetBannerPath)! />
28<#assign articleMainImageThumbnail3 = dlTool.getThumbnail(smallImageUrl, "3", layoutSetBannerPath)! />
29<#assign group = themeDisplay.getScopeGroup()/>
30<#assign defaultLocale = localeUtil.getDefault()/>
31<#setting time_zone="Europe/Madrid">
32
33<#-- Settings -->
34<#assign schema = "http://schema.org/Article"/>
35<#assign ddmStructure = journalArticle.getDDMStructure() />
36<#assign structureId = "" />
37<#assign structureKey = "" />
38<#assign filterStructuresIds = ""/>
39<#assign filterStructuresKeys = []>
40<#assign filterStructures = []>
41<#assign filterDDMStructures = []>
42<#if validator.isNotNull(ddmStructure)>
43 <#assign structureId = ddmStructure.getStructureId() />
44 <#assign structureKey = ddmStructure.getStructureKey()/>
45 <#assign filterStructuresIdsKey = "${structureId}[filterStructuresIds]"/>
46 <#assign filterStructuresIdsValue = group.getTypeSettingsProperty(filterStructuresIdsKey)!/>
47 <#if validator.isNotNull(filterStructuresIdsValue)>
48 <#assign filterStructuresIds = getterUtil.getLongValues(stringUtil.split(filterStructuresIdsValue))/>
49 <#list filterStructuresIds as filterStructuresId>
50 <#assign filterStructure = ddmStructureLocalService.fetchDDMStructure(filterStructuresId)/>
51 <#if validator.isNotNull(filterStructure)>
52 <#assign filterStructureKey = filterStructure.getStructureKey()/>
53 <#assign filterStructuresKeys = filterStructuresKeys + [filterStructureKey] >
54 <#assign filterDDMStructures = filterDDMStructures + [filterStructure] >
55 </#if>
56 </#list>
57 </#if>
58 <#assign schemaKey = "${ddmStructure.getStructureKey()}[schema]"/>
59 <#assign schemaValue = group.getTypeSettingsProperty(schemaKey)!/>
60 <#if validator.isNotNull(schemaValue)>
61 <#assign schema = "${schemaValue}"/>
62 </#if>
63</#if>
64
65<#-- Settings Senderismo -->
66<#assign tracksModesJSONObject = ""/>
67<#assign routeDetailServicesDistance = 1 />
68<#assign routeDetailPOIsShowList = false />
69<#assign routeDetailPOIsTypeIconFontAwesomeJSONObject = "" />
70<#assign ddmStructureSettingsJSONObject = "" />
71<#assign templateVblesJSONObject = jsonFactoryUtil.createJSONObject(group.getTypeSettingsProperty("templateVbles"))!/>
72<#if validator.isNotNull(templateVblesJSONObject) && templateVblesJSONObject.has("senderismo")>
73 <#assign tracksModesJSONObject = templateVblesJSONObject.getJSONObject("senderismo").getJSONObject("tracksModes")!/>
74 <#assign routeDetailServicesDistance = templateVblesJSONObject.getJSONObject("senderismo").getDouble("routeDetailServicesDistance")!/>
75 <#assign routeDetailPOIsShowList = templateVblesJSONObject.getJSONObject("senderismo").getBoolean("routeDetailPOIsShowList")!/>
76 <#assign routeDetailPOIsTypeIconFontAwesomeJSONObject = templateVblesJSONObject.getJSONObject("senderismo").getJSONObject("routeDetailPOIsTypeIconFontAwesome")!/>
77 <#assign routeDetailPOIsGPXImagesJSONObject = templateVblesJSONObject.getJSONObject("senderismo").getJSONObject("routeDetailPOIsGPXImages")!/>
78 <#assign routeDetailPOIsGPXFontAwesomeJSONObject = templateVblesJSONObject.getJSONObject("senderismo").getJSONObject("routeDetailPOIsGPXFontAwesome")!/>
79 <#assign ddmStructureSettingsJSONObject = templateVblesJSONObject.getJSONObject("senderismo").getJSONObject("structureSettings")!/>
80</#if>
81
82<#-- Vocabularies -->
83<#assign concejosVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Concejos")! />
84
85<#-- Categories -->
86<#assign concejos = journalTool.getCategories(groupId, articleId, ["Concejos"])/>
87
88<#-- Build -->
89<#assign numero = Numero.data!"">
90<#assign routeTag = "rutacicloturismo${numero}">
91<#assign portletId = portletTool.getPortletId(request)!/>
92<#assign namespace = "_"+portletId+"_" />
93<#if Denominacion.data?has_content>
94 <#assign title = Denominacion.data>
95</#if>
96<#assign markersServicesDDMStructureKeys = [] />
97<#assign markersNotices = [] />
98<#assign ddmStructureNameNormalize = "template-${friendlyURLNormalizerTool.normalize(journalArticle.getDDMStructure().getName(defaultLocale))}" />
99
100<#-- GPX -->
101<#assign gpxRoute = ""/>
102<#assign gpxPOIRoute = ""/>
103<#assign gpxRutaPath = ""/>
104<#assign gpxPOIRutaPath = ""/>
105<#if validator.isNotNull(Documentos.GPXRuta.data) && Documentos.GPXRuta.getData()!="">
106 <#assign gpxRutaJSONStr = Documentos.GPXRuta.data! />
107 <#assign gpxRutaPath = dlTool.getPathByJSON(gpxRutaJSONStr, themeDisplay.getScopeGroupId())!/>
108 <#assign gpxRutaJSONObject = jsonFactoryUtil.createJSONObject(Documentos.GPXRuta.data)! />
109 <#assign gpxRoute = gpxTool.parser(gpxRutaJSONObject.getLong("classPK"), "Parser", themeDisplay)! />
110</#if>
111<#if validator.isNotNull(Documentos.GPXPOIRuta.data) && Documentos.GPXPOIRuta.getData()!="">
112 <#assign gpxPOIRutaJSONStr = Documentos.GPXPOIRuta.data! />
113 <#assign gpxPOIRutaPath = dlTool.getPathByJSON(gpxPOIRutaJSONStr, themeDisplay.getScopeGroupId())!/>
114 <#assign gpxPOIRutaJSONObject = jsonFactoryUtil.createJSONObject(Documentos.GPXPOIRuta.data)! />
115 <#assign gpxPOIRoute = gpxTool.parser(gpxPOIRutaJSONObject.getLong("classPK"), "Parser", themeDisplay)! />
116</#if>
117
118<#function sanitizeURL url>
119 <#if !url?has_content>
120 <#return "" />
121 </#if>
122 <#assign urlTrimmed = url?trim />
123 <#if urlTrimmed?starts_with("javascript:") || urlTrimmed?starts_with("data:") || urlTrimmed?starts_with("vbscript:")>
124 <#return "" />
125 </#if>
126 <#return htmlUtil.escapeHREF(urlTrimmed) />
127</#function>
128<#function isExternalURL url>
129 <#if !url?has_content>
130 <#return false />
131 </#if>
132 <#assign portalURLlc = themeDisplay.getPortalURL()?lower_case />
133 <#assign urlLC = url?lower_case />
134 <#assign isHttp = urlLC?starts_with("http://") || urlLC?starts_with("https://") />
135 <#assign isInternal = (url?starts_with("/")) || (isHttp && urlLC?starts_with(portalURLlc)) />
136 <#return isHttp && !isInternal />
137</#function>
138
139<#-- Near routes -->
140<#assign gpxNearRoutes = [] />
141<#assign classTypeIds = [structureId]/>
142<#assign routesNearJournalArticles = assetNearTool.getNearJournalArticles(themeDisplay.getScopeGroupId(), assetEntry.getEntryId(), 50.0, classTypeIds, 5, true, [])! />
143<#list routesNearJournalArticles as routeNearJournalArticle>
144
145 <#assign routeNearJournalArticleArticleId = routeNearJournalArticle.getArticleId()! >
146 <#assign routeNearJournalArticleResourcePrimKey = routeNearJournalArticle.getResourcePrimKey()! >
147 <#assign routeNearJournalArticleJSONObject = journalTool.contentXMLtoJSONObject(routeNearJournalArticle.getContentByLocale(locale), locale)/>
148 <#assign routeNearJournalArticleEntryTitle = htmlUtil.escape(routeNearJournalArticle.getTitle(locale)) />
149 <#assign routeNearJournalArticleViewURL = journalTool.getDisplayPage(routeNearJournalArticle, themeDisplay, true) />
150 <#assign routeNearJournalArticleThumbnailPath = routeNearJournalArticle.getSmallImageURL()! />
151 <#assign routeNearJournalArticleThumbnail = dlTool.getThumbnail(routeNearJournalArticleThumbnailPath, "2", layoutSetBannerPath)! />
152
153 <#-- Fields -->
154 <#assign rutaCercanaModalidad = routeNearJournalArticleJSONObject.getString("Modalidad")! />
155 <#assign rutaCercanaModalidadLabel = ddmStructureTool.getSelectLabelValue(ddmStructureRoute, "Modalidad", rutaCercanaModalidad, locale)! />
156 <#assign rutaCercanaTipoRuta = ddmStructureTool.getSelectLabelValue(ddmStructureRoute, "TipoRuta", routeNearJournalArticleJSONObject.getString("TipoRuta"), locale)! />
157 <#assign rutaCercanaTipoRecorrido = ddmStructureTool.getSelectLabelValue(ddmStructureRoute, "TipoRecorrido", routeNearJournalArticleJSONObject.getString("TipoRecorrido"), locale)! />
158 <#assign rutaCercanaIbp = routeNearJournalArticleJSONObject.getString("IBP")! />
159 <#assign rutaCercanaDistancia = routeNearJournalArticleJSONObject.getString("Distancia")! />
160 <#assign rutaCercanaInicio = routeNearJournalArticleJSONObject.getString("Inicio")! />
161 <#assign rutaCercanaFinalizacion = routeNearJournalArticleJSONObject.getString("Finalizacion")! />
162 <#assign rutaCercanaGpxRuta = routeNearJournalArticleJSONObject.getJSONObject("Documentos").getString("GPXRuta")! />
163 <#assign rutaCercanaGpxPOIRuta = routeNearJournalArticleJSONObject.getJSONObject("Documentos").getString("GPXPOIRuta")! />
164 <#assign rutaCercanaKmlRuta = routeNearJournalArticleJSONObject.getJSONObject("Documentos").getString("KMLRuta")! />
165 <#assign rutaCercanaDenominacion = routeNearJournalArticleJSONObject.getString("Denominacion")! />
166
167 <#-- Build -->
168 <#assign rutaCercanaColor = "000" />
169 <#if validator.isNotNull(tracksModesJSONObject) && tracksModesJSONObject.has(modalidad)>
170 <#assign rutaCercanaColor = tracksModesJSONObject.getJSONObject(modalidad).getString("color") !/>
171 </#if>
172 <#if validator.isNotNull(rutaCercanaDenominacion)>
173 <#assign routeNearJournalArticleEntryTitle = rutaCercanaDenominacion !/>
174 </#if>
175
176 <#assign rutaCercanaInicioFinalizacion = rutaCercanaInicio! />
177 <#if validator.isNotNull(rutaCercanaFinalizacion)>
178 <#assign rutaCercanaInicioFinalizacion = rutaCercanaInicio + " - " + rutaCercanaFinalizacion !/>
179 </#if>
180
181 <#if validator.isNotNull(rutaCercanaGpxRuta)>
182 <#assign gpxRutaJSONObject = jsonFactoryUtil.createJSONObject(rutaCercanaGpxRuta)! />
183 <#assign jsonGPX = gpxTool.parser(gpxRutaJSONObject.getLong("classPK"), "Parser", false, true, themeDisplay)! />
184
185 <#assign jsonGPX = jsonGPX.put("articleId", routeNearJournalArticleArticleId)! />
186 <#assign jsonGPX = jsonGPX.put("color", rutaCercanaColor)! />
187 <#assign jsonGPX = jsonGPX.put("url", routeNearJournalArticleViewURL)! />
188 <#assign jsonGPX = jsonGPX.put("title", routeNearJournalArticleEntryTitle)! />
189 <#assign jsonGPX = jsonGPX.put("image", routeNearJournalArticleThumbnail)! />
190 <#assign jsonGPX = jsonGPX.put("startEnd", rutaCercanaInicioFinalizacion)! />
191 <#assign jsonGPX = jsonGPX.put("routeType", rutaCercanaTipoRecorrido)! />
192 <#assign jsonGPX = jsonGPX.put("ibp", rutaCercanaIbp)! />
193 <#assign jsonGPX = jsonGPX.put("mode", rutaCercanaModalidadLabel)! />
194 <#assign jsonGPX = jsonGPX.put("distance", rutaCercanaDistancia)! />
195
196 <#assign gpxNearRoutes = gpxNearRoutes + [jsonGPX] />
197 </#if>
198
199</#list>
200
201<article class="template template-cicloturismo template-layout-map template-route template-${ddmStructureNameNormalize} position-relative" role="article" itemscope itemtype="http://schema.org/TravelAction">
202
203 <div class="container">
204 <div class="row no-gutters">
205 <div class="col-md-5 col-12 col-sidebar">
206
207 <h2 class="article-title" itemprop="name">${title}</h2>
208
209 <div id="article-display-container" class="hide">
210 <button id="close-article-display" type="button" class="btn btn-light">
211 <span class="fas fa-times"><span class="hide-accessible">${languageUtil.get(locale, "close")}</span></span>
212 </button>
213 <div id="article-display"></div>
214 </div>
215
216 <div id="search-container">
217
218 <#if validator.isNotNull(description)>
219 <div class="article-description" itemprop="description">
220 ${htmlUtil.extractText(description)}
221 </div>
222 </#if>
223 <#if Avisos.TituloAviso.getSiblings()?has_content>
224 <#assign noticeCoordinatesIndex = 1 />
225 <#list Avisos.TituloAviso.getSiblings() as tituloAviso>
226
227 <#-- Schduler -->
228 <#assign fechaPublicacion = ""/>
229 <#assign fechaExpiracion = ""/>
230 <#assign nowDateTime = .now?long />
231 <#assign scheduler = true />
232 <#if validator.isNotNull(tituloAviso.FechaPublicacionAviso.getData()) && validator.isNotNull(tituloAviso.FechaPublicacionAviso.HoraPublicacionAviso.getData())>
233 <#assign fechaPublicacion = "${tituloAviso.FechaPublicacionAviso.getData()} ${tituloAviso.FechaPublicacionAviso.HoraPublicacionAviso.getData()}"/>
234 <#assign fechaPublicacion = fechaPublicacion?datetime("yyyy-MM-dd HH:mm:ss")/>
235 <#assign fechaPublicacion = fechaPublicacion?long/>
236 </#if>
237 <#if validator.isNotNull(tituloAviso.FechaExpiracionAviso.getData()) && validator.isNotNull(tituloAviso.FechaExpiracionAviso.HoraExpiracionAviso.getData())>
238 <#assign fechaExpiracion = "${tituloAviso.FechaExpiracionAviso.getData()} ${tituloAviso.FechaExpiracionAviso.HoraExpiracionAviso.getData()}"/>
239 <#assign fechaExpiracion = fechaExpiracion?datetime("yyyy-MM-dd HH:mm:ss")/>
240 <#assign fechaExpiracion = fechaExpiracion?long/>
241 </#if>
242
243 <#-- Filter -->
244 <#if validator.isNull(tituloAviso.getData()) >
245 <#assign scheduler = false />
246 </#if>
247 <#if validator.isNotNull(fechaPublicacion) && validator.isNotNull(fechaExpiracion)>
248 <#if !((nowDateTime gte fechaPublicacion) && (nowDateTime lte fechaExpiracion))>
249 <#assign scheduler = false />
250 </#if>
251 </#if>
252
253 <#if scheduler>
254
255 <#assign routeAlertCssClass = "route-alert alert ${tituloAviso.TipoAviso.getData()} mb-3 alert-dismissible fade hide"/>
256
257 <#assign markerNoticeCoordinates = (tituloAviso.CoordenadasAviso??)?then(tituloAviso.CoordenadasAviso.getData(),'') />
258 <#if validator.isNotNull(markerNoticeCoordinates)>
259 <#assign noticeCoordinatesIndex = noticeCoordinatesIndex + 1 />
260 <#assign routeAlertCssClass = routeAlertCssClass + " route-alert-coordinates"/>
261 </#if>
262
263 <div id="route-${articleId}-alert-coordinates-${noticeCoordinatesIndex}" class="${routeAlertCssClass}" role="alert">
264
265 <#assign markerNoticeIcon = "fa-solid fa-triangle-exclamation" />
266 <div class="alert-title-wrapper">
267 <span class="alert-icon">
268 <#switch tituloAviso.TipoAviso.getData()>
269 <#case "alert-info">
270 <i class="fa-solid fa-info"><!--icon--></i>
271 <#assign markerNoticeIcon = "fa-solid fa-info" />
272 <#break>
273 <#case "alert-success">
274 <i class="fa-regular fa-circle-check"><!--icon--></i>
275 <#assign markerNoticeIcon = "fa-solid fa-check" />
276 <#break>
277 <#case "alert-warning">
278 <i class="fa-solid fa-triangle-exclamation"><!--icon--></i>
279 <#assign markerNoticeIcon = "fa-solid fa-triangle-exclamation" />
280 <#break>
281 <#case "alert-danger">
282 <i class="fa-solid fa-ban"><!--icon--></i>
283 <#assign markerNoticeIcon = "fa-solid fa-ban" />
284 <#break>
285 <#default>
286 <i class="${markerNoticeIcon}"><!--icon--></i>
287 </#switch>
288 </span>
289
290 <#if validator.isNotNull(markerNoticeCoordinates)>
291 <#assign markerNotice = {"id": noticeCoordinatesIndex, "title": tituloAviso.getData(), "description": tituloAviso.DescripcionAviso.getData(), "type": tituloAviso.TipoAviso.getData(), "icon": markerNoticeIcon, "coordinates": markerNoticeCoordinates} />
292 <#assign markersNotices = arrayUtil.append(markersNotices, markerNotice) />
293 </#if>
294
295 <#if validator.isNotNull(tituloAviso.getData())>
296 <p class="alert-title">${stringUtil.replace(tituloAviso.getData(),"\n", "<br/>")}</p>
297 </#if>
298 </div>
299
300 <#if validator.isNotNull(tituloAviso.DescripcionAviso.getData())>
301 <div class="alert-description">${tituloAviso.DescripcionAviso.getData()}</div>
302 </#if>
303
304 <button type="button" class="close" data-dismiss="alert" aria-label="Close">
305 <span aria-hidden="true">×</span>
306 </button>
307 </div>
308 </#if>
309 </#list>
310 </#if>
311
312 <#if validator.isNotNull(smallImageUrl)>
313
314 <#assign altImgDestacada = title />
315 <#if AltImagenDestacada ??>
316 <#if validator.isNotNull(AltImagenDestacada.getData())>
317 <#assign altImgDestacada = AltImagenDestacada.getData() />
318 </#if>
319 </#if>
320
321 <div id="article-carousel" class="carousel slide carousel-fade carousel-article" data-ride="carousel" data-interval="5000">
322 <span aria-hidden="true" class="loading-animation loading-bg"></span>
323 <div class="carousel-inner my-4">
324 <div class="carousel-item active aspect-ratio-bg-cover" style="background-image: url(${articleMainImageThumbnail3});">
325 <img class="hide" src="${articleMainImageThumbnail1}" alt="${altImgDestacada}" title="${altImgDestacada}"/>
326 </div>
327 </div>
328 </div>
329 </#if>
330
331 <div class="article-data-wrapper">
332 <#if validator.isNotNull(concejos) || validator.isNotNull(Distancia.getData()) || validator.isNotNull(Dificultad.getData()) || validator.isNotNull(DesnivelAcumulado.getData()) || validator.isNotNull(AltitudMaxima.getData())
333 || validator.isNotNull(AltitudMaxima.getData()) || validator.isNotNull(AltitudMinima.getData()) || validator.isNotNull(IBP.getData()) || validator.isNotNull(TipoRuta.getData()) || validator.isNotNull(Modalidad.getData())
334 || validator.isNotNull(TipoRecorrido.getData()) || getterUtil.getBoolean(Transporte.Retorno.getData()) || validator.isNotNull(DocumentoAccesibilidad.getData())>
335
336 <#if validator.isNotNull(PoblacionesPrincipales.getData())>
337 <ul class="article-list list-unstyled article-list-info">
338 <li class="article-list-item">
339 <span class="fas fa-map-marker-alt">
340 <span class="hide-accessible">${languageUtil.get(request,"address")}</span>
341 </span>
342 <span class="field-wrapper" itemprop="address">
343 <span class="text d-block important">${PoblacionesPrincipales.getData()}</span>
344 <#assign zoneNames = [] />
345 <#if concejos?size gt 0>
346 <#list concejos as concejo>
347 <#if concejo.getParentCategoryId() == 0>
348 <#if !zoneNames?seq_contains("${concejo.getTitle(locale)}")>
349 <#assign zoneNames = zoneNames + ["${concejo.getTitle(locale)}"]/>
350 </#if>
351 </#if>
352 </#list>
353 <#if validator.isNotNull(zoneNames)>
354 <span class="text zones d-block">${zoneNames?join(", ")}</span>
355 </#if>
356 </#if>
357 </span>
358 </li>
359 </ul>
360 </#if>
361
362 <div class="article-info-table">
363 <div class="article-info-table-row">
364 <div class="article-info-table-cell">
365 <ul class="article-list list-unstyled article-list-info">
366 <#if validator.isNotNull(Distancia.getData())>
367 <li class="article-list-item">
368 <span class="fas fa-ruler-horizontal">
369 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-distancia")}</span>
370 </span>
371 <span class="field-wrapper">
372 <span class="field">${languageUtil.get(request, "infoasturias-distancia")}:</span>
373 <span class="text-featured">${Distancia.getData()} kms</span>
374 </span>
375 </li>
376 </#if>
377 <#if validator.isNotNull(Dificultad.getData())>
378 <#assign dificultad = journalTool.getDDMStructureSelectKeyByJournalArticle(journalArticle, "Dificultad", Dificultad.getData(), locale)/>
379 <li class="article-list-item">
380 <span class="fas fa-layer-group">
381 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-dificultad")}</span>
382 </span>
383 <span class="field-wrapper">
384 <span class="field">${languageUtil.get(request, "infoasturias-dificultad")}:</span>
385 <span class="text">${dificultad}</span>
386 </span>
387 </li>
388 </#if>
389 <#if validator.isNotNull(DesnivelAcumuladoPositivo.getData())>
390 <li class="article-list-item">
391 <span class="fas fa-chart-line">
392 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-desnivel-acumulado")} +</span>
393 </span>
394 <span class="field-wrapper">
395 <span class="field">${languageUtil.get(request, "infoasturias-route-desnivel-acumulado")}:</span>
396 <span class="text"> +${DesnivelAcumuladoPositivo.data} m</span>
397 </span>
398 </li>
399 </#if>
400 <#if validator.isNotNull(DesnivelAcumuladoNegativo.getData())>
401 <li class="article-list-item">
402 <span class="fas fa-chart-line">
403 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-desnivel-acumulado")} -</span>
404 </span>
405 <span class="field-wrapper">
406 <span class="field">${languageUtil.get(request, "infoasturias-route-desnivel-acumulado")}:</span>
407 <span class="text"> -${DesnivelAcumuladoNegativo.data} m</span>
408 </span>
409 </li>
410 </#if>
411 <#if validator.isNotNull(AltitudMaxima.getData())>
412 <li class="article-list-item">
413 <span class="fas fa-ruler-vertical">
414 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-altitud-maxima")}</span>
415 </span>
416 <span class="field-wrapper">
417 <span class="field">${languageUtil.get(request, "infoasturias-route-altitud-maxima")}:</span>
418 <span class="text">${AltitudMaxima.data} m</span>
419 </span>
420 </li>
421 </#if>
422 <#if validator.isNotNull(AltitudMinima.getData())>
423 <li class="article-list-item">
424 <span class="fas fa-ruler-vertical">
425 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-altitud-minima")}</span>
426 </span>
427 <span class="field-wrapper">
428 <span class="field">${languageUtil.get(request, "infoasturias-route-altitud-minima")}:</span>
429 <span class="text">${AltitudMinima.data} m</span>
430 </span>
431 </li>
432 </#if>
433 <#if validator.isNotNull(IBP.getData())>
434 <li class="article-list-item">
435 <span class="fas fa-mountain">
436 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-ibp-index")}</span>
437 </span>
438 <span class="field-wrapper">
439 <span class="field">${languageUtil.get(request, "infoasturias-route-ibp-index")}:</span>
440 <span class="text">${IBP.data}</span>
441 </span>
442 </li>
443 </#if>
444 <#if DocumentoAccesibilidad?? && DocumentoAccesibilidad.data?has_content>
445 <#assign dlFileEntry = dlTool.getDLFileEntryByPath(DocumentoAccesibilidad.data) />
446 <#if validator.isNotNull(dlFileEntry)>
447 <#assign downloadURL = sanitizeURL("/documents/${groupId}/${dlFileEntry.getUuid()}") />
448 <#assign fileSizeKB = (dlFileEntry.getSize() / 1024)?round />
449 <#assign fileExt = dlFileEntry.getExtension()?upper_case />
450 <#assign fileName = languageUtil.get(request, 'infoasturias-accesibilidad') />
451 <#assign ariaLabelText = "${languageUtil.get(request, 'download')} ${fileName}, ${languageUtil.get(request, 'format')} ${fileExt}, ${languageUtil.get(request, 'size')} ${fileSizeKB} ${languageUtil.get(request, 'kb')}" />
452 <li class="article-list-item document document-${fileExt?lower_case}">
453 <span class="fas fa-file" aria-hidden="true"></span>
454 <span class="hide-accessible">${languageUtil.get(request, 'document')}</span>
455 <span class="field-wrapper">
456 <span class="field">${languageUtil.get(request, 'document')}:</span>
457 <span class="text">
458 <a href="${downloadURL}" download aria-label="${htmlUtil.escape(ariaLabelText)}">
459 ${fileName}
460 <span class="file-info" aria-hidden="true">
461 (${fileExt}, ${fileSizeKB} KB) <span class="fas fa-download ml-1" aria-hidden="true"></span>
462 </span>
463 </a>
464 </span>
465 </span>
466 </li>
467 </#if>
468 </#if>
469 </ul>
470 </div>
471 <div class="article-info-table-cell">
472 <ul class="article-list list-unstyled article-list-info">
473 <#if validator.isNotNull(Modalidad.getData())>
474 <#assign modalidad = journalTool.getDDMStructureSelectKeyByJournalArticle(journalArticle, "Modalidad", Modalidad.getData(), locale)/>
475 <li class="article-list-item">
476 <span class="fas fa-road">
477 <span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-modalidad")}</span>
478 </span>
479 <span class="field-wrapper">
480 <span class="field">${languageUtil.get(request, "infoasturias-route-modalidad")}:</span>
481 <span class="text">${modalidad}</span>
482 </span>
483 </li>
484 </#if>
485 <#if validator.isNotNull(TipoRecorrido.getData())>
486 <#assign tipoRecorrido = journalTool.getDDMStructureSelectKeyByJournalArticle(journalArticle, "TipoRecorrido", TipoRecorrido.getData(), locale)/>
487 <li class="article-list-item">
488 <span class="fas fa-route">
489 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-tipo-recorrido")}</span>
490 </span>
491 <span class="field-wrapper">
492 <span class="field">${languageUtil.get(request, "infoasturias-route-tipo-recorrido")}:</span>
493 <span class="text">${tipoRecorrido}</span>
494 </span>
495 </li>
496 </#if>
497 <#if validator.isNotNull(TipoRuta.getData())>
498 <#assign tipoRuta = journalTool.getDDMStructureSelectKeyByJournalArticle(journalArticle, "TipoRuta", TipoRuta.getData(), locale)/>
499 <li class="article-list-item">
500 <span class="fas fa-redo">
501 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-tipo-de-ruta")}</span>
502 </span>
503 <span class="field-wrapper">
504 <span class="field">${languageUtil.get(request, "infoasturias-tipo-de-ruta")}:</span>
505 <span class="text"> ${tipoRuta}</span>
506 </span>
507 </li>
508 </#if>
509 <li class="article-list-item">
510 <span class="fas fa-train">
511 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-retorno-ferrocarril")}</span>
512 </span>
513 <span class="field-wrapper">
514 <span class="field">${languageUtil.get(request, "infoasturias-route-retorno-ferrocarril")}:</span>
515 <#if getterUtil.getBoolean(Transporte.Retorno.getData())>
516 <span class="text">${languageUtil.get(locale, "yes")}</span>
517 <#else>
518 <span class="text">${languageUtil.get(locale, "no")}</span>
519 </#if>
520 </span>
521 </li>
522 <#if validator.isNotNull(Transporte.Empresa.getData()) && getterUtil.getBoolean(Transporte.Retorno.getData())>
523 <li class="article-list-item">
524 <span class="fas fa-train">
525 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-retorno-ferrocarril")}</span>
526 </span>
527 <span class="field-wrapper">
528 <span class="field">${Transporte.Empresa.getData()}
529 <#if validator.isNotNull(Transporte.WebInformativa.getData())>
530 <#list Transporte.WebInformativa.getSiblings() as web>
531 <a class="fas fa-external-link-alt" href="${web.getData()}" onclick="this.target='_blank'" title="${languageUtil.get(locale, 'go-to')} ${web.getData()}">
532 <span class="hide-accessible">${web.getData()}</span>
533 </a>
534 </#list>
535 </#if>
536 </span>
537 </span>
538 </li>
539 </#if>
540 </ul>
541 </div>
542 </div>
543
544 <div class="article-info-table-row">
545 <div class="article-info-table-cell">
546 <ul class="article-list list-unstyled article-list-info">
547 <#if validator.isNotNull(Inicio.getData())>
548 <li class="article-list-item">
549 <span class="fas fa-map-marker">
550 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-lugar-inicio")}</span>
551 </span>
552 <span class="field-wrapper">
553 <span class="field">${languageUtil.get(request, "infoasturias-route-lugar-inicio")}:</span>
554 <span class="text">${Inicio.getData()}</span>
555 </span>
556 </li>
557 </#if>
558 <#if validator.isNotNull(Finalizacion.getData())>
559 <li class="article-list-item">
560 <span class="fas fa-map-marker">
561 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-lugar-finalizacion")}</span>
562 </span>
563 <span class="field-wrapper">
564 <span class="field">${languageUtil.get(request, "infoasturias-route-lugar-finalizacion")}:</span>
565 <span class="text">${Finalizacion.getData()}</span>
566 </span>
567 </li>
568 </#if>
569 <#if validator.isNotNull(Epoca.getData()) && validator.isNotNull(Epoca.getOptions()) && Epoca.getOptions()[0]?has_content>
570 <li class="article-list-item">
571 <span class="fas fa-sun">
572 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-epoca")}</span>
573 </span>
574 <span class="field-wrapper">
575 <span class="field">${languageUtil.get(request, 'infoasturias-epoca')}:</span>
576 <span class="text">
577 <#assign values = Epoca.getOptionsMap()/>
578 <#assign options = Epoca.getOptions()/>
579 <#list options as option>
580 ${values[option]}
581 </#list>
582 </span>
583 </span>
584 </li>
585 </#if>
586 <#if validator.isNotNull(Duracion.getData())>
587 <#assign duracion = journalTool.getDDMStructureSelectKeyByJournalArticle(journalArticle, "Duracion", Duracion.getData(), locale)/>
588 <li class="article-list-item">
589 <span class="fas fa-stopwatch">
590 <span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-duracion-estimada")}</span>
591 </span>
592 <span class="field-wrapper">
593 <span class="field">${languageUtil.get(request, "infoasturias-route-duracion-estimada")}:</span>
594 <span class="text">${duracion}</span>
595 </span>
596 </li>
597 </#if>
598
599 </ul>
600 </div>
601 <div class="article-info-table-cell">
602 <#if validator.isNotNull(Documentos.GPXRuta.getData()) || validator.isNotNull(Documentos.GPXPOIRuta.getData()) || validator.isNotNull(Documentos.KMLRuta.getData())>
603 <ul class="article-list article-list-documents">
604 <#if validator.isNotNull(Documentos.GPXRuta.getData())>
605 <li class="article-list-item">
606 <span class="field-wrapper">
607 <a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.GPXRuta.getData()}" onclick="this.target='_blank'" title="${languageUtil.get(request, 'infoasturias-download')} GPX">
608 <i class="fas fa-file-download"><!--icon--></i> ${languageUtil.format(request, "infoasturias-route-format", "GPX")}
609 </a>
610 </span>
611 </li>
612 </#if>
613 <#if validator.isNotNull(Documentos.GPXPOIRuta.getData())>
614 <li class="article-list-item">
615 <span class="field-wrapper">
616 <a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.GPXPOIRuta.getData()}" onclick="this.target='_blank'" title="${languageUtil.get(request, 'infoasturias-download')} POI GPX">
617 <i class="fas fa-file-download"><!--icon--></i> ${languageUtil.format(request, "infoasturias-poi-format", "GPX") }
618 </a>
619 </span>
620 </li>
621 </#if>
622 <#if validator.isNotNull(Documentos.KMLRuta.getData())>
623 <li class="article-list-item">
624 <span class="field-wrapper">
625 <a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.KMLRuta.getData()}" onclick="this.target='_blank'" title="${languageUtil.get(request, 'infoasturias-download')} KML">
626 <i class="fas fa-file-download"><!--icon--></i> ${languageUtil.format(request, "infoasturias-route-format", "KML")}
627 </a>
628 </span>
629 </li>
630 </#if>
631 <#if validator.isNotNull(Documentos.KMZRuta.getData())>
632 <li class="article-list-item">
633 <span class="field-wrapper">
634 <a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.KMZRuta.getData()}" onclick="this.target='_blank'" title="${languageUtil.get(request, 'infoasturias-download')} KMZ">
635 <i class="fas fa-file-download"><!--icon--></i> ${languageUtil.format(request, "infoasturias-route-format", "KMZ")}
636 </a>
637 </span>
638 </li>
639 </#if>
640 </ul>
641 </#if>
642 </div>
643 </div>
644 </#if>
645 </div>
646
647 <div class="leaflet-elevation-wrapper" id="elevation-div-${articleId}">
648 <div class="btn-route-ctrl-wrapper">
649 <button id="userLocation" type="button" class="btn-circle-icon btn-route-ctrl btn-route-ctrl-location text-white active bottom d-md-none">
650 <span class="fa-solid fa-location-crosshairs"><span class="hide-accessible">${languageUtil.format(request, "infoasturias-route-format", "KMZ")}</span>
651 </button>
652 <button id="toggleElevation" type="button" class="btn-circle-icon btn-route-ctrl btn-route-ctrl-elevation btn-selected text-white active bottom d-md-none">
653 <span class="fa-solid fa-chart-line"><span class="hide-accessible">${languageUtil.format(request, "infoasturias-route-format", "KMZ")}</span>
654 </button>
655 </div>
656 </div>
657
658 </div>
659
660 <#if validator.isNotNull(DescripcionCorta.getData()) || validator.isNotNull(DescripcionLarga.getData())>
661 <div class="article-text-wrapper article-panel-wrapper article-panel-wrapper-white">
662
663 <div class="article-social-bookmarks article-social-bookmarks-circle text-right">
664 <@liferay_social_bookmarks["bookmarks"]
665 className="com.liferay.journal.model.JournalArticle"
666 classPK=assetEntry.getEntryId()
667 displayStyle="menu"
668 target="_blank"
669 title=title
670 types=articleSocialBookmarks
671 url="${articleURL}"
672 />
673 </div>
674
675 <div class="article-text article-panel">
676
677 <#if validator.isNotNull(DescripcionCorta.getData())>
678 <div class="article-short-description">${DescripcionCorta.getData()}</div>
679 </#if>
680 <div class="article-long-description-wrapper">
681
682 <#if validator.isNotNull(DescripcionLarga.getData())>
683 <div class="article-long-description">${DescripcionLarga.getData()}</div>
684 </#if>
685
686 <#if validator.isNotNull(Observaciones.getData())>
687 <div class="article-observations">${Observaciones.getData()}</div>
688 </#if>
689
690 <#assign consejosArticleId= themeDisplay.getThemeSetting("theme-microsites-senderismo-info-article-id")!/>
691 <#if consejosArticleId?has_content>
692 <#assign journalArticle = journalTool.getJournalArticleByArticleId(themeDisplay.getScopeGroupId(), consejosArticleId)! />
693 <#assign journalArticleContent = (journalArticle?has_content)?then(journalArticleLocalService.getArticleDisplay(themeDisplay.getScopeGroupId(), journalArticle.getArticleId(), "preview", themeDisplay.getLanguageId(), themeDisplay),'')>
694
695 <#if journalArticleContent?has_content>
696 <div class="article-tips">
697 ${journalArticleContent.getContent()}
698 </div>
699 </#if>
700 </#if>
701
702 </div>
703
704 <#assign slideImagesCount = 0 />
705 <#assign slideImagesSize = Visualizador.Imagen.getSiblings()?size />
706 <#if Visualizador.Imagen.getSiblings()?has_content>
707 <#assign index = 0 />
708 <div id="article-carousel-round" class="carousel slide carousel-fade carousel-article" data-ride="carousel" data-interval="5000">
709 <span aria-hidden="true" class="loading-animation loading-bg"></span>
710 <div class="carousel-inner">
711 <#list slideImagesCount..slideImagesSize-1 as item>
712 <#assign Slide = Visualizador.Imagen.getSiblings()[item]/>
713 <#assign slideThumbnail1 = dlTool.getThumbnailByJSON(Slide.data, "1")! />
714 <#assign slideThumbnail3 = dlTool.getThumbnailByJSON(Slide.data, "3")! />
715 <#assign slideTitle = "${languageUtil.get(request, 'image')} ${title}" />
716 <#assign slideAlt = slideTitle />
717 <#if Slide.TituloImagen.data?has_content>
718 <#assign slideTitle = Slide.TituloImagen.data />
719 <#assign slideAlt = slideTitle />
720 </#if>
721 <#if Slide.AltImagen?? && validator.isNotNull(Slide.AltImagen.getData())>
722 <#assign slideAlt = Slide.AltImagen.getData() />
723 </#if>
724 <div class="carousel-item aspect-ratio-bg-cover <#if index==0> active</#if>" style="background-image: url(${slideThumbnail3});">
725 <img class="hide" src="${slideThumbnail1}" alt="${slideAlt}" title="${slideTitle}"/>
726 </div>
727 <#assign index = index + 1 />
728 </#list>
729 </div>
730
731 <#if (index>1)>
732 <a class="carousel-control-prev" href="#article-carousel-round" data-slide="prev">
733 <span class="carousel-control-prev-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "previous")} --></span>
734 <span class="hide-accessible">${languageUtil.get(request, "previous")}</span>
735 </a>
736 <a class="carousel-control-next" href="#article-carousel-round" data-slide="next">
737 <span class="carousel-control-next-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "next")}--></span>
738 <span class="hide-accessible">${languageUtil.get(request, "next")}</span>
739 </a>
740 <ol class="carousel-indicators d-none">
741 <#assign index = 0 />
742 <#list slideImagesCount..slideImagesSize-1 as item>
743 <li data-target="#article-carousel-round" data-slide-to="${index}" <#if index==0> class="active"</#if>></li>
744 <#assign index = index + 1 />
745 </#list>
746 </ol>
747 </#if>
748 </div>
749 </#if>
750 </div>
751 </div>
752 </#if>
753
754 <#-- PDI -->
755 <#assign arrayPDIs = [] />
756 <#if PDI.getSiblings()?has_content && validator.isNotNull(PDI.getSiblings()[0]) && (PDI.getSiblings()[0].JournalPDI.data?has_content || PDI.getSiblings()[0].TituloPDI.data?has_content)>
757
758 <#assign pdiCount = 0 />
759 <#list PDI.getSiblings() as pdi>
760 <#assign journalPDIComarcas = "" />
761 <#assign pdiJSONObject = "" />
762 <#assign pdiArticleId = "" />
763 <#assign pdiURL = "#" />
764 <#assign pdiTitle = "" />
765 <#assign pdiImgAlt = "" />
766 <#assign pdiImgTitle = "" />
767 <#assign pdiDescription = "" />
768 <#assign smallImageThumbnail2 = "" />
769 <#if validator.isNotNull(pdi.JournalPDI.getData()) || (validator.isNotNull(pdi.TituloPDI.getData()) && validator.isNotNull(pdi.TituloPDI.ImagenPDI.getData()))>
770 <#if validator.isNotNull(pdi.JournalPDI.getData())>
771 <#assign pdiJSON = pdi.JournalPDI.data?eval/>
772 <#assign journalPDI = journalTool.getJournalArticleByResourcePrimKey(getterUtil.getLong(pdiJSON.classPK))/>
773 <#if validator.isNotNull(journalPDI)>
774 <#assign pdiAssetEntry = journalTool.getAssetEntryByArticleId(journalPDI.getGroupId(), journalPDI.getArticleId())/>
775 <#if validator.isNotNull(pdiAssetEntry)>
776 <#assign journalPDIComarcas = journalTool.getCategoriesNames(groupId, journalPDI.getArticleId(), locale, ["Comarcas"])/>
777 <#assign pdiURL = assetPublisherTool.getAssetViewURL(renderRequest, renderResponse, pdiAssetEntry) />
778 <#assign smallImageThumbnail2 = dlTool.getThumbnail(journalPDI.getSmallImageURL(), "2", layoutSetBannerPath)! />
779 <#assign pdiImgAlt = journalPDI.getTitle(locale)! />
780 <#assign pdiArticleId = journalPDI.getArticleId() />
781 <#assign pdiId = journalPDI.getArticleId() />
782 <#assign pdiTitle = journalPDI.getTitle(locale)! />
783 <#assign pdiDescription = stringUtil.shorten(htmlUtil.extractText(journalPDI.getDescription(locale)), 150)! />
784 <#assign pdiCoordinates = journalTool.getJournalArticleField(groupId, journalPDI.getArticleId(), "Coordenadas")! />
785 <#assign pdiJournalType = friendlyURLNormalizerTool.normalize(journalPDI.getDDMStructure().getName(defaultLocale))! />
786
787 <#assign pdiJSONObject = jsonFactoryUtil.createJSONObject()! />
788 <#assign pdiJSONObject = pdiJSONObject.put("articleId", journalPDI.getArticleId())! />
789 <#assign pdiJSONObject = pdiJSONObject.put("pdiId", pdiId)! />
790 <#assign pdiJSONObject = pdiJSONObject.put("title", pdiTitle)! />
791 <#assign pdiJSONObject = pdiJSONObject.put("description", pdiDescription)! />
792 <#assign pdiJSONObject = pdiJSONObject.put("subtitle", journalPDIComarcas)! />
793 <#assign pdiJSONObject = pdiJSONObject.put("image", smallImageThumbnail2)! />
794 <#assign pdiJSONObject = pdiJSONObject.put("imageAlt", pdiImgAlt)! />
795 <#assign pdiJSONObject = pdiJSONObject.put("url", pdiURL)! />
796 <#assign pdiJSONObject = pdiJSONObject.put("coordinates", pdiCoordinates)! />
797 <#assign pdiJSONObject = pdiJSONObject.put("icon", "")! />
798 <#if validator.isNotNull(pdiJournalType) && validator.isNotNull(ddmStructureSettingsJSONObject) && ddmStructureSettingsJSONObject.has(pdiJournalType) && ddmStructureSettingsJSONObject.getJSONObject(pdiJournalType).has("icon")>
799 <#assign icon = ddmStructureSettingsJSONObject.getJSONObject(pdiJournalType).getString("icon") !/>
800 <#assign pdiJSONObject = pdiJSONObject.put("icon", icon)! />
801 </#if>
802 <#if pdi.IconFontAwesomePDI?? && validator.isNotNull(pdi.IconFontAwesomePDI.getData())>
803 <#assign pdiJSONObject = pdiJSONObject.put("icon", pdi.IconFontAwesomePDI.getData())! />
804 </#if>
805 </#if>
806 </#if>
807 <#elseif validator.isNotNull(pdi.TituloPDI.getData()) && validator.isNotNull(pdi.TituloPDI.ImagenPDI.getData())>
808
809 <#assign pdiId = pdiCount! />
810 <#assign pdiTitle = pdi.TituloPDI.getData()! />
811 <#assign pdiImgAlt = pdi.TituloPDI.getData()! />
812 <#assign pdiImgTitle = pdi.TituloPDI.getData()! />
813 <#assign pdiCoordinates = pdi.TituloPDI.CoordenadasPDI.getData()! />
814 <#assign pdiDescription = (pdi.TituloPDI.DescripcionPDI??)?then(pdi.TituloPDI.DescripcionPDI.getData(),'')! />
815 <#assign pdiType = pdi.TituloPDI.TipoPunto.getData()! />
816 <#assign pdiTypeLabel = ddmStructureTool.getSelectLabelValue(ddmStructureRoute, "TipoPunto", pdiType, locale)! />
817 <#assign smallImageThumbnail2 = dlTool.getThumbnail(pdi.TituloPDI.ImagenPDI.getData(), "2", layoutSetBannerPath)! />
818 <#if pdi.TituloPDI.ImagenPDI.TitleImagenPDI??>
819 <#if validator.isNotNull(pdi.TituloPDI.ImagenPDI.TitleImagenPDI.getData())>
820 <#assign pdiImgTitle = pdi.TituloPDI.ImagenPDI.TitleImagenPDI.getData()/>
821 </#if>
822 </#if>
823 <#if pdi.TituloPDI.ImagenPDI.AltImagenPDI??>
824 <#if validator.isNotNull(pdi.TituloPDI.ImagenPDI.AltImagenPDI.getData())>
825 <#assign pdiImgAlt = pdi.TituloPDI.ImagenPDI.AltImagenPDI.getData()/>
826 </#if>
827 </#if>
828 <#assign pdiJSONObject = jsonFactoryUtil.createJSONObject()! />
829 <#assign pdiJSONObject = pdiJSONObject.put("articleId", pdiId)! />
830 <#assign pdiJSONObject = pdiJSONObject.put("pdiId", pdiId)! />
831 <#assign pdiJSONObject = pdiJSONObject.put("title", pdiTitle)! />
832 <#assign pdiJSONObject = pdiJSONObject.put("description", pdiDescription)! />
833 <#assign pdiJSONObject = pdiJSONObject.put("subtitle", pdiTypeLabel)! />
834 <#assign pdiJSONObject = pdiJSONObject.put("image", smallImageThumbnail2)! />
835 <#assign pdiJSONObject = pdiJSONObject.put("imageAlt", pdiImgAlt)! />
836 <#assign pdiJSONObject = pdiJSONObject.put("url", "")! />
837 <#assign pdiJSONObject = pdiJSONObject.put("coordinates", pdiCoordinates)! />
838 <#assign pdiJSONObject = pdiJSONObject.put("icon", "")! />
839 <#if validator.isNotNull(pdiType) && validator.isNotNull(routeDetailPOIsTypeIconFontAwesomeJSONObject) && routeDetailPOIsTypeIconFontAwesomeJSONObject.has(pdi.TituloPDI.TipoPunto.getData())>
840 <#assign icon = routeDetailPOIsTypeIconFontAwesomeJSONObject.getString(pdiType) !/>
841 <#assign pdiJSONObject = pdiJSONObject.put("icon", icon)! />
842 </#if>
843 <#if pdi.IconFontAwesomePDI?? && validator.isNotNull(pdi.IconFontAwesomePDI.getData())>
844 <#assign pdiJSONObject = pdiJSONObject.put("icon", pdi.IconFontAwesomePDI.getData())! />
845 </#if>
846 </#if>
847 <#if validator.isNotNull(pdiJSONObject)>
848 <#assign arrayPDIs = arrayPDIs + [pdiJSONObject] />
849 </#if>
850 <#assign pdiCount = pdiCount + 1 />
851 </#if>
852 </#list>
853
854 <#if routeDetailPOIsShowList && arrayPDIs?has_content>
855 <div class="article-panel-wrapper">
856 <div class="article-panel">
857 <h3 class="title-section">${languageUtil.get(request,'infoasturias-pois')}</h3>
858 <div class="slide-wrapper">
859 <div id="slick-pdi" class="slick slick-slider">
860 <#list arrayPDIs as arrayPDI>
861 <div class="slide">
862 <a class="card poi" href="${pdiURL}" data-articleid="${arrayPDI.get('articleId')}" data-id="poi-${arrayPDI.get('pdiId')}" title="${languageUtil.format(request, 'go-to-x', htmlUtil.escape(arrayPDI.get('title')))}">
863 <span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url(${arrayPDI.get('image')});">
864 <img class="hide-accessible" src="${arrayPDI.get('image')}" alt="${pdiImgAlt}" />
865 <#if validator.isNotNull(arrayPDI.get('description'))>
866 <span class="card-hover">
867 <span class="card-hover-text" itemprop="description">
868 ${arrayPDI.get('description')}
869 </span>
870 </span>
871 </#if>
872 </span>
873 <span class="card-body">
874 <span class="card-title">${pdiTitle}</span>
875 <#if validator.isNotNull(arrayPDI.get('subtitle'))>
876 <span class="card-subtitle">${arrayPDI.get('subtitle')}</span>
877 </#if>
878 </span>
879 </a>
880 </div>
881 </#list>
882 </div>
883 </div>
884 </div>
885 </div>
886 <script type="text/javascript">
887
888 // bootstrap 4 breakpoints
889 var breakpoint${namespace} = {
890 // small screen / phone
891 sm: 576,
892 // medium screen / tablet
893 md: 768,
894 // large screen / desktop
895 lg: 992,
896 // extra large screen / wide desktop
897 xl: 1200
898 };
899
900 // bootstrap 4 responsive multi column slick carousel
901 $('#slick-pdi').slick({
902 autoplay: false,
903 autoplaySpeed: 1000,
904 draggable: true,
905 pauseOnHover: false,
906 infinite: false,
907 dots: false,
908 arrows: true,
909 speed: 1000,
910 mobileFirst: true,
911 slidesToShow: 1,
912 slidesToScroll: 1,
913 centerMode: false,
914 responsive: [{
915 breakpoint: breakpoint${namespace}.sm,
916 settings: {
917 slidesToShow: 1,
918 slidesToScroll: 1
919 }
920 },
921 {
922 breakpoint: breakpoint${namespace}.md,
923 settings: {
924 slidesToShow: 2,
925 slidesToScroll: 1
926 }
927 },
928 {
929 breakpoint: breakpoint${namespace}.lg,
930 settings: {
931 slidesToShow: 2,
932 slidesToScroll: 1
933 }
934 },
935 {
936 breakpoint: breakpoint${namespace}.xl,
937 settings: {
938 slidesToShow: 2,
939 slidesToScroll: 1
940 }
941 }
942 ]
943 });
944 </script>
945 </#if>
946 </#if>
947
948 <#-- Services -->
949 <#assign servicesNearJournalArticles = [] />
950 <div id="services-panel" class="article-panel-wrapper article-panel-services hide">
951 <div class="article-panel">
952 <h3 class="title-section">${languageUtil.get(request,'infoasturias-route-services')}</h3>
953
954 <div class="filter-categories mb-4">
955
956 <#list filterDDMStructures as filterDDMStructure>
957
958 <#assign filterStructureCustomNameKey = "${filterDDMStructure.getStructureId()}[customName]"/>
959 <#assign filterStructureCustomNameValue = group.getTypeSettingsProperty(filterStructureCustomNameKey)!/>
960
961 <#assign filterStructureKey = filterDDMStructure.getStructureKey()! />
962 <#assign filterStructureName = filterDDMStructure.getName(locale) />
963 <#assign filterStructureDescription = filterDDMStructure.getDescription(locale) />
964
965 <#if validator.isNotNull(filterStructureDescription)>
966 <#assign filterStructureCustomNameValue = filterStructureDescription! />
967 </#if>
968
969 <#if validator.isNotNull(filterStructureCustomNameValue)>
970 <#assign filterStructureCustomNameValue = languageUtil.get(request, filterStructureCustomNameValue)! />
971 </#if>
972
973 <#-- Senderismo Settings -->
974 <#assign filterStructureName = friendlyURLNormalizerTool.normalize(filterDDMStructure.getName(defaultLocale))! />
975 <#if validator.isNotNull(ddmStructureSettingsJSONObject) && ddmStructureSettingsJSONObject.has(filterStructureName) && ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("filters")>
976 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("label")>
977 <#assign filterStructureCustomNameValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getString("label")/>
978 <#assign filterStructureCustomNameValue = languageUtil.get(request, filterStructureCustomNameValue)! />
979 </#if>
980
981 </#if>
982
983 <a class="button-vocabulary-structure btn btn-border btn-thin mb-1 disabled-service" href="#" id="button-vocabulary-structure-id-${filterStructureKey}" data-vocabulary-structure-id="${filterStructureKey}">${filterStructureCustomNameValue}</a>
984
985 </#list>
986
987 </div>
988
989 <div id="services-entries-container" class="slide-wrapper lfr-spa-loading">
990 <div class="lfr-spa-loading-spinner" style="position: absolute;"></div>
991 <ul class="slider slick slick-slider pl-0"></ul>
992 <@liferay_aui["script"] use="aui-base">
993 $(function() {
994
995 // bootstrap 4 breakpoints
996 var breakpoint${namespace} = {
997 // small screen / phone
998 sm: 576,
999 // medium screen / tablet
1000 md: 768,
1001 // large screen / desktop
1002 lg: 992,
1003 // extra large screen / wide desktop
1004 xl: 1200
1005 };
1006
1007 $(".slider").slick({
1008 arrows: true,
1009 dots: false,
1010 slidesToShow: 2,
1011 slidesToScroll: 1,
1012 mobileFirst: true,
1013 centerMode: false,
1014 infinite: false,
1015 responsive: [{
1016 breakpoint: breakpoint${namespace}.sm,
1017 settings: {
1018 slidesToShow: 1,
1019 slidesToScroll: 1
1020 }
1021 },
1022 {
1023 breakpoint: breakpoint${namespace}.md,
1024 settings: {
1025 slidesToShow: 2,
1026 slidesToScroll: 1
1027 }
1028 },
1029 {
1030 breakpoint: breakpoint${namespace}.lg,
1031 settings: {
1032 slidesToShow: 2,
1033 slidesToScroll: 1
1034 }
1035 },
1036 {
1037 breakpoint: breakpoint${namespace}.xl,
1038 settings: {
1039 slidesToShow: 2,
1040 slidesToScroll: 1
1041 }
1042 }
1043 ]
1044 });
1045 });
1046 </@>
1047 </div>
1048 </div>
1049 </div>
1050
1051 <#if validator.isNotNull(routesNearJournalArticles) && routesNearJournalArticles?size gt 0>
1052 <div class="article-panel-wrapper article-panel-wrapper-white template-routes">
1053 <div class="article-panel">
1054 <h3 class="title-section">${languageUtil.get(request,'infoasturias-routes-near-here')}</h3>
1055 <div class="slide-wrapper">
1056 <div id="slick-near" class="slick slick-slider">
1057 <#list routesNearJournalArticles as currentJournalArticle>
1058 <#assign viewURL = journalTool.getDisplayPage(currentJournalArticle, themeDisplay, true)/>
1059 <#assign smallImageThumbnail2 = dlTool.getThumbnail(currentJournalArticle.getSmallImageURL(), "2", layoutSetBannerPath)! />
1060 <#assign routeTitle = currentJournalArticle.getTitle(locale)/>
1061 <#assign denominacion = journalTool.getJournalArticleField(currentJournalArticle.getGroupId(), currentJournalArticle.getArticleId(), "Denominacion", locale)/>
1062 <#assign assetEntry = journalTool.getAssetEntryByArticleId(groupId, articleId)>
1063 <#if validator.isNotNull(denominacion)>
1064 <#assign routeTitle = denominacion />
1065 </#if>
1066 <div class="slide">
1067 <a class="card route-near" data-id="route-near-${currentJournalArticle.getArticleId()}" href="${viewURL}" title="${languageUtil.format(request, 'go-to-x', routeTitle)}">
1068 <span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url('${smallImageThumbnail2}');">
1069 <img class="hide-accessible" src="${smallImageThumbnail2}" alt="${routeTitle}">
1070 <#if validator.isNotNull(htmlUtil.extractText(currentJournalArticle.getDescription(locale)))>
1071 <span class="card-hover">
1072 <span class="card-hover-text" itemprop="description">
1073 ${stringUtil.shorten(htmlUtil.extractText(currentJournalArticle.getDescription(locale)), 150)}
1074 </span>
1075 </span>
1076 </#if>
1077 </span>
1078 <span class="card-body">
1079 <span class="card-title">${routeTitle}</span>
1080 <span class="card-subtitle">
1081 <#-- <span class="d-block">${currentJournalArticle.getVersion()} Kms</span>-->
1082 <#assign currentJournalArticleConcejos = journalTool.getCategoriesNames(groupId, currentJournalArticle.getArticleId(), locale, ["Concejos"])/>
1083 <#if validator.isNotNull(currentJournalArticleConcejos)>
1084 <#assign currentJournalArticleConcejos = stringUtil.replace(currentJournalArticleConcejos,",",", ") />
1085 <span class="d-block">${currentJournalArticleConcejos}</span>
1086 </#if>
1087 </span>
1088 </span>
1089 </a>
1090 </div>
1091 </#list>
1092 </div>
1093 </div>
1094 </div>
1095 </div>
1096
1097 <script type="text/javascript">
1098
1099 // bootstrap 4 breakpoints
1100 var breakpoint${namespace} = {
1101 // small screen / phone
1102 sm: 576,
1103 // medium screen / tablet
1104 md: 768,
1105 // large screen / desktop
1106 lg: 992,
1107 // extra large screen / wide desktop
1108 xl: 1200
1109 };
1110
1111 // bootstrap 4 responsive multi column slick carousel
1112 $('#slick-near').slick({
1113 autoplay: false,
1114 autoplaySpeed: 1000,
1115 draggable: true,
1116 pauseOnHover: false,
1117 infinite: false,
1118 dots: false,
1119 arrows: true,
1120 speed: 1000,
1121 mobileFirst: true,
1122 slidesToShow: 1,
1123 slidesToScroll: 1,
1124 centerMode: false,
1125 responsive: [{
1126 breakpoint: breakpoint${namespace}.sm,
1127 settings: {
1128 slidesToShow: 1,
1129 slidesToScroll: 1
1130 }
1131 },
1132 {
1133 breakpoint: breakpoint${namespace}.md,
1134 settings: {
1135 slidesToShow: 2,
1136 slidesToScroll: 1
1137 }
1138 },
1139 {
1140 breakpoint: breakpoint${namespace}.lg,
1141 settings: {
1142 slidesToShow: 2,
1143 slidesToScroll: 1
1144 }
1145 },
1146 {
1147 breakpoint: breakpoint${namespace}.xl,
1148 settings: {
1149 slidesToShow: 2,
1150 slidesToScroll: 1
1151 }
1152 }
1153 ]
1154 });
1155 </script>
1156 </#if>
1157 </div>
1158 </div>
1159
1160 <div class="col-md-7 col-12 col-map d-md-inline-block d-none">
1161 <div id="map" class="lfr-spa-loading">
1162 <div class="lfr-spa-loading-spinner" style="position: absolute;"></div>
1163 <#if validator.isNotNull(filterStructuresIds)>
1164 <div id="map-filter" class="hide">
1165 <div class="vocabularies">
1166 <#list filterStructuresIds as filterStructuresId>
1167 <#assign filterStructure = ddmStructureLocalService.fetchDDMStructure(filterStructuresId)/>
1168 <#if validator.isNotNull(filterStructure)>
1169 <#assign filterStructureName = friendlyURLNormalizerTool.normalize(filterStructure.getName(defaultLocale))! />
1170 <#assign filterStructureKey = filterStructure.getStructureKey()/>
1171 <#assign markersServicesDDMStructureKeys = arrayUtil.append(markersServicesDDMStructureKeys, filterStructureKey) />
1172 <#assign filterStructureFontAwesomeKey = "${filterStructure.getStructureId()}[fontAwesome]"/>
1173 <#assign filterStructureFontAwesomeValue = group.getTypeSettingsProperty(filterStructureFontAwesomeKey)!/>
1174 <#assign filterStructureVocabularyKey = "${filterStructure.getStructureId()}[vocabularyId]"/>
1175 <#assign filterStructureVocabularyValue = getterUtil.getLong(group.getTypeSettingsProperty(filterStructureVocabularyKey))!/>
1176 <#assign filterStructurevocabularyLevelCategoriesKey = "${filterStructure.getStructureId()}[vocabularyLevelCategories]"/>
1177 <#assign filterStructurevocabularyLevelCategoriesValue = group.getTypeSettingsProperty(filterStructurevocabularyLevelCategoriesKey)!1/>
1178 <#assign filterStructurevocabularyCategoryIdsKey = "${filterStructure.getStructureId()}[vocabularyCategoryIds]"/>
1179 <#assign filterStructurevocabularyCategoryIdsValue = group.getTypeSettingsProperty(filterStructurevocabularyCategoryIdsKey)!/>
1180 <#assign filterStructurevocabularyTagsKey = "${filterStructure.getStructureId()}[vocabularyTags]"/>
1181 <#assign filterStructurevocabularyTagsValue = group.getTypeSettingsProperty(filterStructurevocabularyTagsKey)!/>
1182 <#assign filterStructureCustomNameKey = "${filterStructure.getStructureId()}[customName]"/>
1183 <#assign filterStructureCustomNameValue = group.getTypeSettingsProperty(filterStructureCustomNameKey)!/>
1184 <#assign filterStructureStructureIdsKey = "${filterStructure.getStructureId()}[filterStructuresIds]"/>
1185 <#assign filterStructureStructureIdsValues = group.getTypeSettingsProperty(filterStructureStructureIdsKey)!/>
1186
1187 <#-- Senderismo Settings -->
1188 <#assign filterStructureCardSubtitleCategoryIdsValue = "" />
1189 <#if validator.isNotNull(ddmStructureSettingsJSONObject) && ddmStructureSettingsJSONObject.has(filterStructureName)>
1190
1191 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("icon")>
1192 <#assign filterStructureFontAwesomeValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getString("icon")/>
1193 </#if>
1194
1195 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("label")>
1196 <#assign filterStructureCustomNameValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getString("label")/>
1197 </#if>
1198
1199 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("cardSubtitleCategoryIds")>
1200 <#assign filterStructureCardSubtitleCategoryIdsValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getString("cardSubtitleCategoryIds")/>
1201 </#if>
1202
1203 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("filters")>
1204
1205 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("vocabularyId")>
1206 <#assign filterStructureVocabularyValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getLong("vocabularyId")/>
1207 </#if>
1208
1209 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("vocabularyLevelCategories")>
1210 <#assign filterStructurevocabularyLevelCategoriesValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getString("vocabularyLevelCategories", "1")/>
1211 </#if>
1212
1213 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("vocabularyCategoryIds")>
1214 <#assign filterStructurevocabularyCategoryIdsValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getString("vocabularyCategoryIds")/>
1215 </#if>
1216
1217 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("vocabularyTags")>
1218 <#assign filterStructurevocabularyTagsValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getString("vocabularyTags")/>
1219 </#if>
1220
1221 <#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("filterStructuresIds")>
1222 <#assign filterStructureStructureIdsValues = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getString("filterStructuresIds")/>
1223 </#if>
1224
1225 </#if>
1226
1227 </#if>
1228
1229 <#-- Build -->
1230 <#assign filterStructureStructureKeys = [filterStructureKey]/>
1231 <#if validator.isNotNull(filterStructureStructureIdsValues)>
1232 <#list stringUtil.split(filterStructureStructureIdsValues) as filterStructureStructureIdsValue>
1233 <#assign ddmStructure = ddmStructureLocalService.fetchDDMStructure(getterUtil.getLong(filterStructureStructureIdsValue))! />
1234 <#if validator.isNotNull(ddmStructure)>
1235 <#assign filterStructureStructureKeys = filterStructureStructureKeys + [ddmStructure.getStructureKey()]/>
1236 </#if>
1237 </#list>
1238 </#if>
1239
1240 <#assign filterStructureJSONObject = jsonFactoryUtil.createJSONObject()>
1241 <#assign filterStructureJSONObject = filterStructureJSONObject.put("structureId", filterStructuresId)! />
1242 <#assign filterStructureJSONObject = filterStructureJSONObject.put("structureKey", filterStructureKey)! />
1243 <#assign filterStructureJSONObject = filterStructureJSONObject.put("fontAwesome", filterStructureFontAwesomeValue)! />
1244 <#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyId", filterStructureVocabularyValue)! />
1245 <#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyLevelCategories", filterStructurevocabularyLevelCategoriesValue)! />
1246 <#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyCategoryIds", filterStructurevocabularyCategoryIdsValue)! />
1247 <#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyTags", filterStructurevocabularyTagsValue)! />
1248 <#assign filterStructureJSONObject = filterStructureJSONObject.put("cardSubtitleCategoryIds", filterStructureCardSubtitleCategoryIdsValue)! />
1249 <#assign filterStructureJSONObject = filterStructureJSONObject.put("name", filterStructure.getName(locale))! />
1250 <#assign filterStructureJSONObject = filterStructureJSONObject.put("customName", filterStructureCustomNameValue)! />
1251 <#assign filterStructureJSONObject = filterStructureJSONObject.put("description", filterStructure.getDescription(locale))! />
1252 <#assign filterStructureJSONObject = filterStructureJSONObject.put("structureKeys", stringUtil.merge(filterStructureStructureKeys))! />
1253 <#assign filterStructures = filterStructures + [filterStructureJSONObject] />
1254
1255 <#assign filterStructureName = filterStructure.getName(locale) />
1256 <#assign filterStructureDescription = filterStructure.getDescription(locale) />
1257
1258 <#if validator.isNotNull(filterStructureDescription)>
1259 <#assign filterStructureName = filterStructureDescription! />
1260 </#if>
1261
1262 <#if validator.isNotNull(filterStructureCustomNameValue)>
1263 <#assign filterStructureName = languageUtil.get(request, filterStructureCustomNameValue)! />
1264 </#if>
1265
1266 <div class="vocabulary-wrapper disabled-service" title="${filterStructureName}" data-structurekey="${filterStructure.getStructureKey()}">
1267 <div class="vocabulary" id="vocabulary-structure-id-${filterStructure.getStructureKey()}" data-vocabulary-structure-id="${filterStructure.getStructureKey()}">
1268 <span class="icon ${filterStructureFontAwesomeValue}"><span class="hide-accessible">${filterStructureName}</span></span>
1269 </div>
1270 <#if validator.isNotNull(filterStructureVocabularyValue)>
1271 <#assign filterStructureVocabulary = assetVocabularyLocalService.fetchAssetVocabulary(filterStructureVocabularyValue)! />
1272 <#assign filterStructureVocabularyCategories = assetCategoryTool.getAssetCategoriesByVocabulary(filterStructureVocabulary, getterUtil.getInteger(filterStructurevocabularyLevelCategoriesValue))! />
1273
1274 <#if validator.isNotNull(filterStructurevocabularyCategoryIdsValue)>
1275 <#assign assetCategoryIds = getterUtil.getLongValues(stringUtil.split(filterStructurevocabularyCategoryIdsValue)) />
1276 <#assign filterStructureVocabularyCategories = filterStructureVocabularyCategories?filter(assetCategory -> assetCategoryIds?seq_contains(assetCategory.categoryId))>
1277 </#if>
1278
1279 <#if validator.isNotNull(filterStructureVocabularyCategories)>
1280 <div class="categories ${(filterStructureVocabularyCategories?size==1)?then('','')}"><#--TODO-->
1281 <#list filterStructureVocabularyCategories as filterStructureVocabularyCategory>
1282 <div class="category category-${filterStructureVocabularyCategory.getCategoryId()} hide">
1283 <input type="checkbox" name="category-${filterStructureVocabularyCategory.getCategoryId()}" id="category-${filterStructureVocabularyCategory.getCategoryId()}" data-id="${filterStructureVocabularyCategory.getCategoryId()}" />
1284 <label for="category-${filterStructureVocabularyCategory.getCategoryId()}">${filterStructureVocabularyCategory.getTitle(locale)}</label>
1285 </div>
1286 </#list>
1287 </div>
1288 </#if>
1289 </#if>
1290 </div>
1291 </#if>
1292 </#list>
1293 </div>
1294 </div>
1295 </#if>
1296 </div>
1297 </div>
1298 </div>
1299 </div>
1300
1301</article>
1302
1303<@liferay_aui["script"] use="aui-base, anim, aui-io-request, cookie, async-queue, node-event-simulate">
1304
1305 var mapZoom = ${getterUtil.getInteger(mapZoom, 12)};//MapZoom
1306 var mapLat = ${getterUtil.getString(mapLat, "43.362597693870434")};//MapLat
1307 var mapLng = ${getterUtil.getString(mapLng, "-5.846235457402242")};//MapLng
1308 var osm = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
1309 {
1310 attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
1311 }
1312 );
1313
1314 var map = new L.map('map', {center: [${gpxRoute.get("centerLatLon")}], zoom: mapZoom, zoomControl: false, minZoom: 9, bounceAtZoomLimits: false, layers: [osm]});
1315 map.doubleClickZoom.disable();
1316 map.whenReady(function(){
1317 A.one('#map').removeClass('lfr-spa-loading');
1318 });
1319
1320 //Map Height
1321 mapFullHeight(scroll=true, map);
1322
1323 //FilterStructures
1324 var fontAwesomeIconClassCSS = [];
1325 <#list filterStructures as filterStructure>
1326 fontAwesomeIconClassCSS['${filterStructure["structureKey"]}'] = {
1327 cssClass:'${filterStructure["fontAwesome"]}',
1328 vocabularyId: ${filterStructure["vocabularyId"]},
1329 vocabularyLevelCategories: ${filterStructure["vocabularyLevelCategories"]},
1330 vocabularyTags: '${filterStructure["vocabularyTags"]}',
1331 cardSubtitleCategoryIds: '${filterStructure["cardSubtitleCategoryIds"]}'
1332 };
1333 </#list>
1334
1335 //ServiceMarkers
1336 var serviceMarkers = [];
1337 var markersServicesGroups = {};
1338 var servicesContainer = A.one('#services-entries-container');
1339 var mapFilter = A.one('#map-filter');
1340 var servicesPanel = A.one('#services-panel');
1341
1342 Liferay.provide(window,'journalArticlesResourcesCount', function(deltaParam, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, vocabularyIds){
1343 var url = '/o/asac-web-services/ws/journalArticlesResourcesCount';
1344 A.io.request(url, {
1345 method: 'GET',
1346 type: 'JSON',
1347 data: {
1348 companyId: ${companyId},
1349 groupId: ${groupId},
1350 structureKeys: structureKeys,
1351 anyCategoryIds: assetAnyCategoryIds,
1352 allCategoryIds: assetAllCategoryIds,
1353 anyTagNames: anyTagNames,
1354 allTagNames: allTagNames,
1355 coordinates: '[${gpxRoute.get("coordinatesLatLonSplit")}]',
1356 coordinatesDistance: ${routeDetailServicesDistance}
1357 },
1358 on: {
1359 success: function() {
1360 var count = this.get('responseData');
1361 if(count>deltaParam){
1362 var pages = Math.ceil(count/deltaParam);
1363 for(var cur = 0; cur < pages; cur++){
1364 journalArticlesResources(cur, deltaParam, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, vocabularyIds, count);
1365 }
1366 }else{
1367 var cur = -1;
1368 var delta = -1;
1369 journalArticlesResources(cur, deltaParam, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, vocabularyIds, count);
1370 }
1371 }
1372 }
1373 });
1374 });
1375
1376 Liferay.provide(window,'journalArticlesResources', function(cur, delta, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, vocabularyIds, total){
1377 var structureKey = structureKeys.split(',')[0];
1378 var url = '/o/asac-web-services/ws/journalArticlesResources';
1379 A.io.request(url, {
1380 method: 'GET',
1381 type: 'JSON',
1382 data: {
1383 companyId: ${companyId},
1384 groupId: ${groupId},
1385 structureKeys: structureKeys,
1386 anyCategoryIds: anyCategoryIds,
1387 allCategoryIds: allCategoryIds,
1388 anyTagNames: anyTagNames,
1389 allTagNames: allTagNames,
1390 coordinates: '[${gpxRoute.get("coordinatesLatLonSplit")}]',
1391 coordinatesDistance: ${routeDetailServicesDistance},
1392 projectionAssetCategoriesVocabularyIds: vocabularyIds,
1393 cur: cur,
1394 delta: delta,
1395 },
1396 on: {
1397 success: function() {
1398 var vocabularyId = 0;
1399 var points = JSON.parse(this.get('responseData'));
1400 if(points && points.length>0){
1401 for(var index in points) {
1402
1403 var point = points[index];
1404 var articleId = point.articleId;
1405 var title = point.title;
1406 var descriptionText = point.descriptionText;
1407 var assetCategories = point.assetCategories;
1408 var subTypeId = point.subTypeId; //structureKey
1409 var subTypeName = point.subTypeName; //structureName
1410 var coordinates = point.coordinates;
1411 var detailURL = point.detailURL;
1412 var detailFullURL = point.detailFullURL;
1413 if(detailFullURL!='')
1414 detailURL = detailFullURL;
1415 var image = point.image;
1416 var imageThumbnail2 = point.imageThumbnail2;
1417 var icon = fontAwesomeIconClassCSS[subTypeId].cssClass;
1418 var vocabularyId = (vocabularyId==0) ? fontAwesomeIconClassCSS[subTypeId].vocabularyId : vocabularyId;
1419 var vocabularyLevelCategories = fontAwesomeIconClassCSS[subTypeId].vocabularyLevelCategories;
1420 var cardSubtitleCategoryIds = fontAwesomeIconClassCSS[subTypeId].cardSubtitleCategoryIds;
1421 var concejosVocabularyId = ${concejosVocabulary.getVocabularyId()};
1422 var pointGroups = [];
1423
1424 const fontAwesomeIcon = L.divIcon({
1425 className: 'marker-wrapper',
1426 html: "<div class='marker-icon-blue'><i class='"+icon+"'><!-- icon--></i></div>",
1427 iconSize: [26, 30],
1428 iconAnchor: [13, 30]
1429 });
1430
1431 if(coordinates!=''){
1432 var latLng = coordinates.split(',');
1433 if(!isNaN(latLng[0]) && !isNaN(latLng[1])){
1434 var pointGroup = '';
1435 var categoryTitle = '';
1436 var categoryId = '';
1437 var categoryConcejos = [];
1438 var categoryIds = [];
1439 var categoryTitles = [];
1440 var pointGroups = [];
1441 for(var assetCategoriesIndex in assetCategories) {
1442
1443 var assetCategory = assetCategories[assetCategoriesIndex];
1444 if(assetCategory){
1445
1446 categoryId = assetCategory.categoryId;
1447 categoryTitle = assetCategory.title;
1448
1449 //Concejos
1450 if(assetCategory.vocabularyId==concejosVocabularyId){
1451 if(!categoryConcejos.includes(assetCategory.title))
1452 categoryConcejos.push(assetCategory.title);
1453 }
1454
1455 if(assetCategory.vocabularyId==vocabularyId){
1456
1457 //Filter
1458 if(vocabularyLevelCategories && vocabularyLevelCategories>0){
1459 var level = assetCategory.level;
1460 if(vocabularyLevelCategories!=level)
1461 continue;
1462 }
1463
1464 if(markersServicesGroups && markersServicesGroups[categoryId]){
1465 pointGroup = markersServicesGroups[categoryId];
1466 }else{
1467 var pointGroup = L.markerClusterGroup({
1468 maxClusterRadius: 100,
1469 showCoverageOnHover: false,
1470 //zoomToBoundsOnClick: false,
1471 //spiderfyOnMaxZoom: false,
1472 iconCreateFunction: function(cluster) {
1473 var childMarkers = cluster.getAllChildMarkers();
1474 var n = 0;
1475 for (var i = 0; i < childMarkers.length; i++) {
1476 n += 1;
1477 }
1478 return L.divIcon({
1479 className: 'marker-wrapper',
1480 html: "<div class='marker-circle'>"+n+"</i></div>",
1481 iconSize: [26, 30],
1482 iconAnchor: [13, 5]
1483 });
1484 }
1485 });
1486 markersServicesGroups[categoryId] = pointGroup;
1487 }
1488
1489 if(pointGroup)
1490 pointGroups.push(pointGroup);
1491
1492 if(categoryTitle!='' && !categoryTitles.includes(categoryTitle)){
1493 if(cardSubtitleCategoryIds=='' || (cardSubtitleCategoryIds.split(",").includes(categoryId)))
1494 categoryTitles.push(categoryTitle);
1495 }
1496
1497 if(categoryId!='' && !categoryIds.includes(categoryId))
1498 categoryIds.push(categoryId);
1499
1500 var serviceFilterCategory = A.one('.categories .category-'+categoryId)
1501 if(serviceFilterCategory)
1502 serviceFilterCategory.show();
1503 }
1504 }
1505 }
1506
1507 var popupContentTemplate = '<a data-articleid="'+articleId+'" href="'+detailURL+'" class="popup popup-service">'+
1508 '<span class="popup-image-wrapper" style="background-image: url('+imageThumbnail2+');"><!-- image--></span>'+
1509 '<span class="popup-body">'+
1510 '<span class="popup-subtitle">'+categoryTitles.join()+'</span>'+
1511 '<span class="popup-title">'+title+'</span>'+
1512 '<span class="popup-desciption">'+descriptionText+'</span>'+
1513 '</span>'+
1514 '</a>';
1515
1516 var newNodeObject = A.Node.create(popupContentTemplate);
1517 newNodeObject.on('click', function(event){
1518 event.preventDefault();
1519 var nodeArticleId = this.attr('data-articleid');
1520 ${namespace}getArticleDisplay(nodeArticleId);
1521 });
1522
1523 var marker = L.marker([latLng[0],latLng[1]],
1524 {
1525 "icon": fontAwesomeIcon,
1526 "title": title
1527 }
1528 );
1529 marker.articleId='service-'+articleId;
1530 marker.bindPopup(newNodeObject.getDOMNode());
1531 marker.on('popupopen', function(e) {
1532 map.panTo(this.getLatLng());
1533 });
1534 marker.on('popupclose', function(e) {
1535 ${namespace}closeArticleDisplay();
1536 });
1537 //markersServicesGroup.addLayer(marker);
1538
1539 for(var pointGroupsIndex in pointGroups) {
1540 var pointGroup = pointGroups[pointGroupsIndex];
1541 if(pointGroup)
1542 pointGroup.addLayer(marker);
1543 }
1544
1545 serviceMarkers.push(marker);
1546
1547 //CreateObject
1548 var entry = A.Node.create('<div class="slide service-structure service-structure-'+subTypeId+' '+categoryIds.map(id => 'service-category-' + id).join(' ')+'"></div>');
1549 var anchor = A.Node.create('<a onclick="event.preventDefault(); ${namespace}getArticleDisplay('+articleId+');" class="card service item-card" data-articleid="'+articleId+'" data-id="service-'+articleId+'" href="'+detailURL+'" title="'+title+'"></a>');
1550 var anchorImageWrapper = A.Node.create('<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3"></span>');
1551 if(descriptionText!=''){
1552 var anchorImageWrapperHover = A.Node.create('<span class="card-hover"></span>');
1553 var anchorImageWrapperHoverDescription = A.Node.create('<span class="card-hover-text" itemprop="description">'+descriptionText+'</span>');
1554 anchorImageWrapperHover.append(anchorImageWrapperHoverDescription);
1555 anchorImageWrapper.append(anchorImageWrapperHover);
1556 }
1557 var anchorImage = A.Node.create('<img class="" src="'+imageThumbnail2+'" alt="'+title+'" loading="lazy" onload="this.parentElement.style.backgroundImage = \'url(\'+this.src+\')\'; this.classList.add(\'hide-accessible\');" />');
1558 var anchorBody = A.Node.create('<span class="card-body"></span>');
1559 var anchorTitle = A.Node.create('<span class="card-title">'+title+'</span>');
1560 var anchorCategories = A.Node.create('<span class="card-categories">'+categoryTitles.join()+'</span>');
1561 var anchorConcejos = A.Node.create('<span class="card-subtitle">'+categoryConcejos.join()+'</span>');
1562
1563 anchorImageWrapper.append(anchorImage);
1564 anchor.append(anchorImageWrapper);
1565 anchorBody.append(anchorTitle);
1566 anchorBody.append(anchorCategories);
1567 anchorBody.append(anchorConcejos);
1568 anchor.append(anchorBody);
1569
1570 entry.append(anchor);
1571 $('.slider').slick('slickAdd','<li class="service-structure-'+subTypeId+' '+categoryIds.map(id => 'service-category-' + id).join(' ')+'">'+entry.outerHTML()+'</li>');
1572 }
1573 }
1574 }
1575
1576 A.all('.card.service').each(function(item){
1577 item.on('mouseover', function(event){
1578 var articleId = item.getAttribute("data-id");
1579 ${namespace}markerServicePopup(articleId, true);
1580 });
1581 item.on('mouseout', function(event){
1582 var articleId = item.getAttribute("data-id");
1583 ${namespace}markerServicePopup(articleId, false);
1584 });
1585 });
1586
1587 var vocabularyWrapper = A.one('.vocabulary-wrapper[data-structurekey="' + structureKey + '"]');
1588 var vocabularyButtonWrapper = A.one('.filter-categories .button-vocabulary-structure[data-vocabulary-structure-id="' + structureKey + '"]');
1589 if(vocabularyWrapper){
1590 vocabularyWrapper.addClass("selectable");
1591 vocabularyWrapper.one('.vocabulary').on('click', function(){
1592 if($(window).width() > 768)
1593 ${namespace}toggleMarkersServicesStructure(structureKey);
1594 else
1595 vocabularyWrapper.toggleClass('hover');
1596
1597 });
1598 vocabularyWrapper.removeClass("disabled-service");
1599 if(vocabularyButtonWrapper)
1600 vocabularyButtonWrapper.removeClass("disabled-service");
1601 }
1602 }
1603
1604 if(serviceMarkers && serviceMarkers.length>0){
1605 if(servicesPanel)
1606 servicesPanel.show();
1607 if(mapFilter)
1608 mapFilter.show();
1609 }
1610 }
1611 }
1612 });
1613 });
1614
1615 <#list filterStructures as filterStructure>
1616
1617 var structureKeys = '${filterStructure["structureKeys"]}';
1618 var assetAnyCategoryIds = '${filterStructure["vocabularyCategoryIds"]}';
1619 var assetAllCategoryIds = '';
1620 var assetAnyTags = '';
1621 var assetAllTags = '';
1622 if('${filterStructure["vocabularyTags"]}'!='' && '${filterStructure["vocabularyTags"]}'!='1')
1623 var assetAllTags = '${htmlUtil.escape(routeTag)},${htmlUtil.escape(filterStructure["vocabularyTags"])}';
1624 var vocabularyIds = '${filterStructure["vocabularyId"]},${concejosVocabulary.getVocabularyId()}';
1625 var delta = 500;
1626 journalArticlesResourcesCount(delta, structureKeys, assetAnyCategoryIds, assetAllCategoryIds, assetAnyTags, assetAllTags, vocabularyIds);
1627 servicesContainer.removeClass('lfr-spa-loading');
1628
1629 </#list>
1630
1631 //Filter categories
1632 A.all('.categories input').each(function(item){
1633 item.on('click', function(e){
1634
1635 const shouldFit = (this.options && this.options.fitOnClick !== undefined) ? this.options.fitOnClick : true;
1636
1637 var categoryIds = [];
1638 var categoryIdsCssClass = '';
1639 var vocabularyWrapper = item.ancestor('.vocabulary-wrapper');
1640 var vocabulary = vocabularyWrapper.one('.vocabulary');
1641 var categoryId = item.getAttribute('data-id');
1642 var structureId = vocabulary.getAttribute('data-vocabulary-structure-id');
1643 var button = A.one('#button-vocabulary-structure-id-'+structureId);
1644 var pointsGroup = markersServicesGroups[categoryId];
1645
1646 if(pointsGroup){
1647 if(item.attr('checked')){
1648 map.addLayer(pointsGroup);
1649 if(shouldFit)
1650 fitToVisibleMarkerGroups(map, markersServicesGroups);
1651 }else{
1652 map.removeLayer(pointsGroup);
1653 }
1654 }
1655 if(item.attr('checked')){
1656 vocabularyWrapper.addClass('selected');
1657 button.addClass('selected');
1658 }else{
1659 var flag = true;
1660 var categories = vocabularyWrapper.all('.categories input').each(function(index){
1661 if(index.attr('checked'))
1662 flag = false;
1663 });
1664 if(flag){
1665 vocabularyWrapper.removeClass('selected');
1666 button.removeClass('selected');
1667 }
1668 }
1669
1670 A.all('.categories input').each(function(index){
1671 if(index.attr('checked')){
1672 var categoryId = index.getAttribute('data-id');
1673 categoryIds.push('.service-category-'+categoryId);
1674 }
1675 });
1676
1677 $(".slider").slick('slickUnfilter');
1678 categoryIdsCssClass = categoryIds.join();
1679 if(categoryIdsCssClass!='')
1680 $(".slider").slick('slickFilter', categoryIdsCssClass);
1681 });
1682 });
1683
1684 //Filter services
1685 A.all('.button-vocabulary-structure').each(function(item){
1686 item.on('click', function(event){
1687 event.preventDefault();
1688 var structureId = item.attr('data-vocabulary-structure-id');
1689 if($(window).width() > 768)
1690 ${namespace}toggleMarkersServicesStructure(structureId);
1691 });
1692 });
1693
1694 //Route
1695 var routesMainPolyline = '';
1696 var routesPolylines = [];
1697 var routesPolylinesGroup = L.featureGroup();
1698 var routesNearPolylinesGroup = L.layerGroup();
1699 const fontAwesomeRouteStartIcon = L.divIcon({
1700 className: 'marker-wrapper',
1701 html: "<div class='marker-icon marker-icon-start marker-icon-start-min'><i class='fa-solid fa-person-hiking'><!-- icon--></i></div>",
1702 iconSize: [26, 30],
1703 iconAnchor: [13, 5]
1704 });
1705 const fontAwesomeRouteEndIcon = L.divIcon({
1706 className: 'marker-wrapper',
1707 html: "<div class='marker-icon marker-icon-end marker-icon-end-min'><i class='fa-solid fa-person-hiking'><!-- icon--></i></div>",
1708 iconSize: [26, 30],
1709 iconAnchor: [13, 30]
1710 });
1711 const fontAwesomeRouteNearIcon = L.divIcon({
1712 className: 'marker-wrapper',
1713 html: "<div class='marker-icon marker-icon-near marker-icon-near-min'><i class='fa-solid fa-person-hiking'><!-- icon--></i></div>",
1714 iconSize: [26, 30],
1715 iconAnchor: [13, 5]
1716 });
1717
1718 <#if gpxRoute?has_content>
1719
1720 <#assign gpxRoute = gpxRoute.put("articleId", articleId)! />
1721 <#assign gpxRoute = gpxRoute.put("color", "000")! />
1722 <#assign gpxRoute = gpxRoute.put("url", "")! />
1723 <#assign gpxRoute = gpxRoute.put("title", title)! />
1724
1725 var popupTextStartTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-start')}</span><span class="popup-title">${htmlUtil.escape(Inicio.getData())}</span></span></span>';
1726 var popupTextEndTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-end')}</span><span class="popup-title">${htmlUtil.escape(Finalizacion.getData())}</span></span></span>';
1727
1728 //Markers Route Start/End
1729 var latLng = '${gpxRoute.get("coordinatesStart")}';
1730 latLng = latLng.replaceAll(' ', '');
1731 latLng = latLng.split(',');
1732 var markerRouteStart = L.marker([latLng[0],latLng[1]],
1733 {
1734 "icon": fontAwesomeRouteStartIcon,
1735 "title": '${languageUtil.format(request, 'infoasturias-route-start-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}'
1736 }
1737 ).bindPopup(popupTextStartTemplate).addTo(map);
1738 var latLng = '${gpxRoute.get("coordinatesEnd")}';
1739 latLng = latLng.replaceAll(' ', '');
1740 latLng = latLng.split(',');
1741 var markerRouteEnd = L.marker([latLng[0],latLng[1]],
1742 {
1743 "icon": fontAwesomeRouteEndIcon,
1744 "title": '${languageUtil.format(request, 'infoasturias-route-end-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}'
1745 }
1746 ).bindPopup(popupTextEndTemplate).addTo(map);
1747
1748 //POIs
1749 var poiMarkers = [];
1750 <#if arrayPDIs?has_content>
1751 <#list arrayPDIs as arrayPDI>
1752 var poiArticleId = '${arrayPDI.get("articleId")}';
1753 var latLng = '${arrayPDI.get("coordinates")}';
1754 var url = '${arrayPDI.get("url")}';
1755 var image = '${arrayPDI.get("image")}';
1756 var title = '${htmlUtil.escape(arrayPDI.get("title"))}';
1757 var description = '${htmlUtil.escape(arrayPDI.get("description"))}';
1758 var subtitle = '${htmlUtil.escape(arrayPDI.get("subtitle"))}';
1759 var icon = 'fas fa-info';
1760 <#if arrayPDI.get("icon")?has_content>
1761 var icon = '${arrayPDI.get("icon")}';
1762 </#if>
1763 if(latLng){
1764
1765 latLng = latLng.replaceAll(' ', '');
1766 latLng = latLng.split(',');
1767
1768 var fontAwesomeRoutePOIIcon = L.divIcon({
1769 className: 'marker-wrapper',
1770 html: "<div class='marker-icon marker-icon-poi marker-icon-poi-min'><i class='"+icon+"'><!-- icon--></i></div>",
1771 iconSize: [26, 30],
1772 iconAnchor: [13, 5]
1773 });
1774
1775 var popupContentTemplate = '<a data-articleid="'+poiArticleId+'" href="'+url+'" class="popup popup-service">'+
1776 '<span class="popup-image-wrapper" style="background-image: url('+image+');"><img src="'+image+'"/></span>'+
1777 '<span class="popup-body">'+
1778 '<span class="popup-subtitle">'+subtitle+'</span>'+
1779 '<span class="popup-title">'+title+'</span>'+
1780 '<span class="popup-desciption">'+description+'</span>'+
1781 '</span>'+
1782 '</a>';
1783
1784 var newNodeObject = A.Node.create(popupContentTemplate);
1785 newNodeObject.on('click', function(event){
1786 event.preventDefault();
1787 var nodeArticleId = this.attr('data-articleid');
1788 ${namespace}getArticleDisplay(nodeArticleId);
1789 });
1790
1791 var marker = L.marker([latLng[0],latLng[1]],
1792 {
1793 "icon": fontAwesomeRoutePOIIcon,
1794 "title": title
1795 }
1796 );
1797 marker.articleId = 'poi-'+poiArticleId;
1798 marker.bindPopup(newNodeObject.getDOMNode()).addTo(map);
1799 marker.on('popupopen', function(e) {
1800 map.panTo(this.getLatLng());
1801 });
1802 marker.getPopup().on('remove', function() {
1803 ${namespace}closeArticleDisplay();
1804 });
1805
1806 poiMarkers.push(marker);
1807 }
1808 </#list>
1809 </#if>
1810 A.all('.card.poi').each(function(item){
1811 item.on('mouseover', function(event){
1812 var articleId = item.getAttribute("data-id");
1813 ${namespace}markerPopup(articleId, true);
1814 });
1815 item.on('mouseout', function(event){
1816 var articleId = item.getAttribute("data-id");
1817 ${namespace}markerPopup(articleId, false);
1818 });
1819 });
1820
1821 //RouteNears
1822 routesNearPolylines = [];
1823 <#list gpxNearRoutes as gpxNearRoute>
1824 var polylinePopupHTML = '<a href="${gpxNearRoute.get("url")}" class="popup">'+
1825 '<span class="popup-image-wrapper" style="background-image: url(${gpxNearRoute.get("image")});"><img src="${gpxNearRoute.get("image")}"/>'+
1826 <#--'<span class="ribbon ribbon-circle"><span class="ribbon-text ">${gpxNearRoute.get("distance")}</span><span class="ribbon-text ribbon-text-meta">km</span></span>'+-->
1827 '</span>'+
1828 '<span class="popup-body">'+
1829 '<span class="popup-title" style="color: #${gpxNearRoute.get("color")};">${htmlUtil.escape(gpxNearRoute.get("title"))}</span>'+
1830 '<span class="d-block"><span class="icon fas fa-map-marker-alt"><span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-lugar-inicio-fin")}</span></span> <span class="value important text-uppercase">${htmlUtil.escape(gpxNearRoute.get("startEnd"))}</span></span>'+
1831 '<span class="d-block"><span class="icon fa-solid fa-person-hiking"><span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-recorrido")}</span></span> <span class="value">${htmlUtil.escape(gpxNearRoute.get("routeType"))}</span></span>'+
1832 '<span class="d-block"><span class="icon fas fa-mountain"><span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-ibp-index")}</span></span> <span class="important">IBP Index: </span> <span class="value">${gpxNearRoute.get("ibp")}</span></span>'+
1833 '<span class="d-block"><span class="icon fa-solid fa-person-hiking"><span class="hide-accessible">${languageUtil.get(request, "mode")}</span></span> <span class="value">${gpxNearRoute.get("mode")}</span></span>'+
1834 '</span>'+
1835 '</a>';
1836 var polyline = L.polyline(${gpxNearRoute.get("coordinates")}, {color: '#cacaca', opacity: 1, weight: 3, className: "bordered-polyline"}).bindPopup(polylinePopupHTML);
1837 polyline.articleId = 'route-near-${gpxNearRoute.get("articleId")}';
1838 polyline.flag = true;
1839 polyline.isHovered = false;
1840 polyline.isClicked = false;
1841 polyline.on('mouseover', function(e) {
1842 if(!this.isHovered){
1843 var layer = e.target;
1844 layer.setStyle({
1845 color: '#cacaca',
1846 opacity: 1,
1847 weight: 5
1848 });
1849 layer.bringToFront();
1850 this.isHovered=true;
1851 }
1852 });
1853 polyline.on('mouseout', function(e) {
1854 if(this.isHovered){
1855 var layer = e.target;
1856 layer.setStyle({
1857 color: '#cacaca',
1858 opacity: 0.9,
1859 weight: 3
1860 });
1861 this.isHovered=false;
1862 }
1863 });
1864 polyline.on('click', function(e) {
1865 var popup = this.getPopup();
1866 var layer = e.target;
1867 layer.setStyle({
1868 color: '#cacaca',
1869 opacity: 1,
1870 weight: 5
1871 });
1872 this.isHovered = false;
1873 layer.bringToFront();
1874 popup.setLatLng(this.getCenter());
1875 popup.openPopup();
1876 map.setView(this.getCenter());
1877 var pixelesCenter = map.latLngToContainerPoint(this.getCenter());
1878 pixelesCenter.y -= map.getSize().y * 0.2;
1879 var centerMap = map.containerPointToLatLng(pixelesCenter);
1880 map.setView(centerMap);
1881 this.isClicked = true;
1882 });
1883 polyline.on('popupclose', function(e) {
1884 var layer = e.target;
1885 layer.setStyle({
1886 color: '#cacaca',
1887 opacity: 0.9,
1888 weight: 3
1889 });
1890 this.isClicked = false;
1891 });
1892
1893 var popupTextStartTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-start')}</span><span class="popup-title">${htmlUtil.escape(gpxNearRoute.get("title"))}</span></span></span>';
1894 var popupTextEndTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-end')}</span><span class="popup-title">${htmlUtil.escape(gpxNearRoute.get("title"))}</span></span></span>';
1895
1896 //Markers Route Near Start/End
1897 var latLng = '${gpxNearRoute.get("coordinatesStart")}';
1898 latLng = latLng.replaceAll(' ', '');
1899 latLng = latLng.split(',');
1900 var markerRouteStart = L.marker([latLng[0],latLng[1]],
1901 {
1902 "icon": fontAwesomeRouteNearIcon,
1903 "title": '${languageUtil.format(request, 'infoasturias-route-start-x', '${htmlUtil.escape(gpxNearRoute.get("title"))}')}'
1904 }
1905 ).bindPopup(popupTextStartTemplate).addTo(routesNearPolylinesGroup);
1906 var latLng = '${gpxNearRoute.get("coordinatesEnd")}';
1907 latLng = latLng.replaceAll(' ', '');
1908 latLng = latLng.split(',');
1909 var markerRouteEnd = L.marker([latLng[0],latLng[1]],
1910 {
1911 "icon": fontAwesomeRouteNearIcon,
1912 "title": '${languageUtil.format(request, 'infoasturias-route-end-x', '${htmlUtil.escape(gpxNearRoute.get("title"))}')}'
1913 }
1914 ).bindPopup(popupTextEndTemplate).addTo(routesNearPolylinesGroup);
1915
1916 routesPolylinesGroup.addLayer(polyline);
1917 routesNearPolylinesGroup.addLayer(polyline);
1918
1919 </#list>
1920 //List
1921 A.all('.route-near').each(function(item){
1922 item.on('mouseover', function(event){
1923 var articleId = item.getAttribute("data-id");
1924 ${namespace}polylinePopup(articleId, true);
1925 });
1926 item.on('mouseout', function(event){
1927 var articleId = item.getAttribute("data-id");
1928 ${namespace}polylinePopup(articleId, false);
1929 });
1930 });
1931
1932 var gropedOverlayslehen = {
1933 "${languageUtil.get(locale, "infoasturias-routes-near")}": routesNearPolylinesGroup
1934 }
1935 var layerControl = L.control.layers('', gropedOverlayslehen, {
1936 collapsed: false,
1937 position:'topleft'
1938 });
1939 layerControl.addTo(map);
1940
1941 //Elevation
1942 var elevation_options = {
1943
1944 // Default chart colors: theme lime-theme, magenta-theme, ...
1945 theme: "custom-theme",
1946
1947 useHeightIndicator: true,
1948
1949 // Chart container outside/inside map container
1950 detached: true,
1951
1952 // if (detached), the elevation chart container
1953 elevationDiv: "#elevation-div-${articleId}",
1954
1955 // if (!detached) autohide chart profile on chart mouseleave
1956 autohide: false,
1957
1958 // if (!detached) initial state of chart profile control
1959 collapsed: false,
1960
1961 // if (!detached) control position on one of map corners
1962 position: "topright",
1963
1964 // Toggle close icon visibility
1965 closeBtn: false,
1966
1967 // Autoupdate map center on chart mouseover.
1968 followMarker: true,
1969
1970 // Autoupdate map bounds on chart update.
1971 autofitBounds: false,
1972
1973 // Chart distance/elevation units.
1974 imperial: false,
1975
1976 // [Lat, Long] vs [Long, Lat] points. (leaflet default: [Lat, Long])
1977 reverseCoords: false,
1978
1979 // Acceleration chart profile: true || "summary" || "disabled" || false
1980 acceleration: false,
1981
1982 // Slope chart profile: true || "summary" || "disabled" || false
1983 slope: false,
1984
1985 // Speed chart profile: true || "summary" || "disabled" || false
1986 speed: false,
1987
1988 // Altitude chart profile: true || "summary" || "disabled" || false
1989 altitude: true,
1990
1991 // Display time info: true || "summary" || false
1992 time: false,
1993
1994 // Display distance info: true || "summary" || false
1995 distance: true,
1996
1997 // Summary track info style: "inline" || "multiline" || false
1998 summary: false,
1999
2000 // Download link: "link" || false || "modal"
2001 downloadLink: false,
2002
2003 // Toggle chart ruler filter
2004 ruler: true,
2005
2006 // Toggle chart legend filter
2007 legend: false,
2008
2009 // Toggle "leaflet-almostover" integration
2010 almostOver: true,
2011
2012 // Toggle "leaflet-distance-markers" integration
2013 distanceMarkers: false,
2014
2015 // Toggle "leaflet-edgescale" integration
2016 edgeScale: false,
2017
2018 // Toggle "leaflet-hotline" integration
2019 hotline: true,
2020
2021 // Display track datetimes: true || false
2022 timestamps: false,
2023
2024 // Display track waypoints: true || "markers" || "dots" || false
2025 waypoints: true,
2026
2027 // Toggle custom waypoint icons: true || { associative array of <sym> tags } || false
2028 wptIcons: false,
2029
2030 // Toggle waypoint labels: true || "markers" || "dots" || false
2031 wptLabels: false,
2032
2033 // Render chart profiles as Canvas or SVG Paths
2034 preferCanvas: false,
2035
2036 height: 200,
2037 };
2038
2039 ${namespace}initializeElevation(map, elevation_options);
2040
2041 //Main polyline
2042 var routesMainPolyline = L.polyline(${gpxRoute.get("coordinates")});
2043 routesPolylinesGroup.addLayer(routesMainPolyline);
2044 map.fitBounds(routesMainPolyline.getBounds(),{
2045 padding: [15,15]
2046 });
2047
2048 //Enabled/Disabled routesNearPolylinesGroup
2049 let previousBounds = null;
2050 map.on('overlayadd', function (e) {
2051 if (e.layer === routesNearPolylinesGroup) {
2052 previousBounds = map.getBounds();
2053 const groupBounds = routesPolylinesGroup.getBounds();
2054 if (groupBounds.isValid())
2055 map.fitBounds(groupBounds);
2056 }
2057 });
2058 map.on('overlayremove', function (e) {
2059 if (e.layer === routesNearPolylinesGroup && previousBounds) {
2060 map.fitBounds(previousBounds);
2061 previousBounds = null;
2062 }
2063 });
2064
2065 <#-- POIs GPXPOI -->
2066 <#if validator.isNotNull(gpxPOIRoute)>
2067 <#if gpxPOIRoute.has("wpts") && validator.isNotNull(gpxPOIRoute.has("wpts"))>
2068 <#assign wptJSONArray = jsonFactoryUtil.createJSONArray(gpxPOIRoute.get("wpts"))! />
2069 <#list 0..wptJSONArray.length() as i>
2070 <#assign wptJSONObject = wptJSONArray.get(i)! />
2071 <#if validator.isNotNull(wptJSONObject)>
2072
2073 <#assign wptName = wptJSONObject.get("name")! />
2074 <#assign wptSym = wptJSONObject.get("sym")! />
2075 <#assign wptLat = wptJSONObject.get("lat")! />
2076 <#assign wptLon = wptJSONObject.get("lon")! />
2077 <#assign wptEle = wptJSONObject.get("ele")! />
2078 <#assign wptSymImage = validator.isNotNull(routeDetailPOIsGPXImagesJSONObject)?then(routeDetailPOIsGPXImagesJSONObject[wptSym],'')! />
2079 <#assign wptSymFontAwesome = validator.isNotNull(routeDetailPOIsGPXFontAwesomeJSONObject)?then(routeDetailPOIsGPXFontAwesomeJSONObject[wptSym],'')! />
2080 <#if validator.isNotNull(wptSymFontAwesome)>
2081
2082 var divIcon = L.divIcon({
2083 className: 'marker-wrapper',
2084 html: "<div class='marker-icon marker-icon-poi marker-icon-poi-min'><i class='${wptSymFontAwesome}'><!-- icon--></i></div>",
2085 iconSize: [26, 30],
2086 iconAnchor: [13, 30]
2087 });
2088 var popupPOITemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-title">${htmlUtil.escape(wptName)}</span></span></span>';
2089 var marker = L.marker([${wptLat}, ${wptLon}],
2090 {
2091 "icon": divIcon,
2092 "title": '${htmlUtil.escape(wptName)}'
2093 }
2094 ).bindPopup(popupPOITemplate).addTo(map);
2095 marker.on('popupopen', function(e) {
2096 map.panTo(this.getLatLng());
2097 });
2098 </#if>
2099 </#if>
2100 </#list>
2101 </#if>
2102
2103 <#-- TODO -->
2104 <#assign dlFileEntryGPXPOI = dlTool.getDLFileEntryByPath(Documentos.GPXPOIRuta.data)!/>
2105 <#if validator.isNotNull(dlFileEntryGPXPOI)>
2106 <#assign document = saxReaderUtil.read(dlFileEntryGPXPOI.getContentStream())/>
2107 <#assign root = document.getRootElement()/>
2108 <#assign trks = root.elements("trk")!>
2109 <#if validator.isNotNull(trks)>
2110 <#list trks as trk>
2111 <#assign trkName = trk.elementText("name")!>
2112 <#assign trkseg = trk.element("trkseg")!>
2113 <#if validator.isNotNull(trkseg)>
2114 <#assign trkpts = trkseg.elements("trkpt")!>
2115 <#if validator.isNotNull(trkpts)>
2116 var trksegsLatLngs = [];
2117 <#list trkpts as trkpt>
2118 <#assign trksegLat = trkpt.attributeValue("lat")!>
2119 <#assign trksegLon = trkpt.attributeValue("lon")!>
2120 <#if validator.isNotNull(trksegLat) && validator.isNotNull(trksegLon)>
2121 var trksegsLatLng = [${trksegLat}, ${trksegLon}];
2122 trksegsLatLngs.push(trksegsLatLng);
2123 </#if>
2124 </#list>
2125 if(trksegsLatLngs.length>0){
2126 var popupGpxPOITemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-title">${htmlUtil.escape(trkName)}</span></span></span>';
2127 var trkPolyline = L.polyline(trksegsLatLngs, {color: '#006db0', dashArray: '5, 10', lineCap: 'square', opacity: 1, weight: 5, className: "bordered-polyline-white"}).bindPopup(popupGpxPOITemplate).addTo(map);
2128 }
2129 </#if>
2130 </#if>
2131 </#list>
2132 </#if>
2133 </#if>
2134 </#if>
2135
2136 <#--Notices-->
2137 <#if validator.isNotNull(markersNotices) && markersNotices?size gt 0>
2138 const markersNotices = {};
2139 <#list markersNotices as markersNotice>
2140
2141 <#if validator.isNotNull(markersNotice)>
2142
2143 (function() {
2144
2145 const id = '${markersNotice.id}';
2146 var notice = A.one('#route-${articleId}-alert-coordinates-' + id);
2147 if(notice){
2148
2149 //SessionStorage
2150 if (!sessionStorage.getItem(id)) {
2151
2152 notice.show();
2153 notice.addClass('show');
2154
2155 //Marker
2156 var divIcon = L.divIcon({
2157 className: 'marker-wrapper',
2158 html: "<div class='marker-circle marker-notice marker-notice-${markersNotice.type}'><i class='${markersNotice.icon}'><!-- icon--></i></div>",
2159 iconSize: [26, 30],
2160 iconAnchor: [13, 30]
2161 });
2162 var popupPOITemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-title">${htmlUtil.escape(htmlUtil.extractText(markersNotice.title))}</span><span class="popup-text">${htmlUtil.escape(htmlUtil.extractText(markersNotice.description))}</span></span></span>';
2163 var marker = L.marker([${markersNotice.coordinates}],
2164 {
2165 "icon": divIcon,
2166 "title": '${htmlUtil.escape(htmlUtil.extractText(markersNotice.title))}'
2167 }
2168 ).bindPopup(popupPOITemplate).addTo(map);
2169 marker.on('popupopen', function(e) {
2170 map.panTo(this.getLatLng());
2171 });
2172 markersNotices[id] = marker;
2173
2174 //Notice
2175 notice.on('hover', function(){
2176 markersNotices[id].openPopup();
2177 map.panTo(markersNotices[id].getLatLng());
2178 });
2179 var close = notice.one('.close');
2180 if(close){
2181 close.on('click', function(){
2182 sessionStorage.setItem(id, 'true');
2183 });
2184 }
2185 }
2186 }
2187 })();
2188
2189 </#if>
2190
2191 </#list>
2192 </#if>
2193
2194 //Functions
2195 function ${namespace}initializeElevation(map, elevation_options) {
2196
2197 const controlElevation = L.control.elevation(elevation_options).addTo(map);
2198
2199 //Fixed random hotline route map error not rendering
2200 const hotlineLayer = L.hotline(${gpxRoute.get("coordinates")}, {
2201 min: ${gpxRoute.get("elevationMin")},
2202 max: ${gpxRoute.get("elevationMax")},
2203 palette: {
2204 0.0: 'green',
2205 0.5: 'yellow',
2206 1.0: 'red'
2207 },
2208 weight: 5,
2209 outlineColor: 'black',
2210 outlineWidth: 1
2211 }).addTo(map);
2212
2213 controlElevation.load('${gpxRutaPath}');
2214 }
2215
2216 function ${namespace}markerPopup(articleId, hover){
2217 for (var i in poiMarkers){
2218 var marker = poiMarkers[i];
2219 var id = marker.articleId;
2220 if (id == articleId){
2221 if(hover){
2222 marker.openPopup();
2223 map.panTo(marker.getLatLng());
2224 }else{
2225 //marker.closePopup();
2226 }
2227 };
2228 }
2229 }
2230
2231 function ${namespace}markerServicePopup(articleId, hover){
2232 for (var i in serviceMarkers){
2233 var marker = serviceMarkers[i];
2234 var id = marker.articleId;
2235 if (id == articleId){
2236 if(hover){
2237 map.addLayer(marker);
2238 marker.openPopup();
2239 map.panTo(marker.getLatLng());
2240 }else{
2241 //map.removeLayer(marker);
2242 //marker.closePopup();
2243 }
2244 };
2245 }
2246 }
2247
2248 function ${namespace}polylinePopup(articleId, hover){
2249 for (var i in routesNearPolylines){
2250 var polyline = routesNearPolylines[i];
2251 if (map.hasLayer(routesNearPolylinesGroup)){
2252 var id = polyline.articleId;
2253 if (id == articleId){
2254 if(hover){
2255 polyline.openPopup();
2256 polyline.setStyle({
2257 weight: 5,
2258 opacity: 1
2259 });
2260 map.panTo(polyline.getCenter());
2261 polyline.bringToFront();
2262 }else{
2263 polyline.setStyle({
2264 weight: 3,
2265 opacity: 0.9
2266 });
2267 polyline.closePopup();
2268 }
2269 }
2270 }
2271 }
2272 }
2273
2274 function ${namespace}toggleMarkersServicesStructure(structureId){
2275
2276 var fitOnClick = false;
2277 var item = A.one('#vocabulary-structure-id-'+structureId);
2278 var button = A.one('#button-vocabulary-structure-id-'+structureId);
2279 if(item){
2280 var vocabularyWrapper = item.ancestor('.vocabulary-wrapper');
2281 if(!vocabularyWrapper.hasClass('selected')){
2282 vocabularyWrapper.all('.categories input').attr('checked','');
2283 vocabularyWrapper.all('.categories input').each(function(cat){
2284 cat.simulate('click', fitOnClick);
2285 });
2286 vocabularyWrapper.addClass('selected');
2287 if(button)
2288 button.addClass('selected');
2289 fitToVisibleMarkerGroups(map, markersServicesGroups);
2290 }else{
2291 vocabularyWrapper.all('.categories input').attr('checked','checked');
2292 vocabularyWrapper.all('.categories input').each(function(cat){
2293 cat.simulate('click');
2294 });
2295 vocabularyWrapper.removeClass('selected');
2296 if(button)
2297 button.removeClass('selected');
2298 }
2299 }
2300 }
2301
2302 Liferay.provide(window, '${namespace}closeArticleDisplay', function(){
2303 A.one("#article-display-container").hide('fadeOut');
2304 A.one("#search-container").show('fadeIn');
2305 });
2306
2307 Liferay.provide(window, '${namespace}openArticleDisplay', function(){
2308 A.one("#search-container").hide();
2309 A.one("#article-display-container").show('fadeIn');
2310
2311 //Map
2312 var articleDisplayContainerMap = A.one("#article-display-container").one('.article-section-map script[type="text/javascript"]');
2313 if(articleDisplayContainerMap)
2314 eval(articleDisplayContainerMap.html());
2315
2316 //Scroll
2317 var to = A.one('#article-display-container');
2318 if(to){
2319 var position = 100;
2320 var toggleMap = A.one('#toggle-map');
2321 if(toggleMap && toggleMap.hasClass('active')){
2322 position = 0;
2323 to = A.one('body');
2324 }
2325 var anim = new A.Anim({
2326 duration: 0.2,
2327 node: A.getWin(),
2328 to: {
2329 scroll: [0, to.getY() - position]
2330 }
2331 }).run();
2332 }
2333 });
2334
2335 Liferay.provide(window, '${namespace}getArticleDisplay', function(articleId){
2336
2337 var url = "${portalUtil.getLayoutFullURL(themeDisplay.getLayout(), themeDisplay)}?p_p_id=${themeDisplay.getPortletDisplay().getId()}&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_resource_id=journalDisplayContent&p_p_cacheability=cacheLevelPage&_${themeDisplay.getPortletDisplay().getId()}_articleId="+articleId;
2338 A.io.request(url, {
2339 method: 'GET',
2340 type: 'HTML',
2341 on: {
2342 success: function() {
2343 var journalArticleContentDisplay = this.get('responseData');
2344 journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("col-md-6", "col-12");
2345 journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-wrapper", "");
2346 journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-table", "");
2347 journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-table-row", "");
2348 journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-table-cell", "");
2349 journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info", "article-info m-0 px-4 pt-4");
2350 //journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-section-map", "article-section-map hide");
2351 A.one("#article-display").html(journalArticleContentDisplay);
2352 ${namespace}openArticleDisplay();
2353 }
2354 }
2355 });
2356 });
2357
2358 </#if>
2359
2360 var closeArticleDisplayNode = A.one("#close-article-display");
2361 if(closeArticleDisplayNode){
2362 closeArticleDisplayNode.on('click', function(event) {
2363 ${namespace}closeArticleDisplay();
2364 });
2365 }
2366
2367 A.all(".template-layout-map .item-card").each(function(item) {
2368 item.on("click", function(event) {
2369 event.preventDefault();
2370 var articleId = item.attr("data-articleid");
2371 ${namespace}getArticleDisplay(articleId);
2372 });
2373 });
2374
2375 //Map Mobile Toggle
2376 mapMobileToggle('${languageUtil.get(request, "infoasturias-abrir-mapa")}','${languageUtil.get(request, "infoasturias-cerrar-mapa")}', map, '.leaflet-elevation-wrapper');
2377 var toggleMap = A.one('#toggle-map');
2378 if(toggleMap){
2379 toggleMap.on('click', function(event){
2380 A.one('.template-layout-map').toggleClass('template-layout-map-mobile');
2381 A.one('#content').toggleClass('content-map-mobile');
2382 map.closePopup();
2383 if(this.hasClass('active')){
2384
2385 //Center
2386 if(routesMainPolyline)
2387 map.fitBounds(routesMainPolyline.getBounds());
2388
2389 //Close article
2390 ${namespace}closeArticleDisplay();
2391
2392 //Scroll
2393 var to = A.one('body');
2394 if(to){
2395 var anim = new A.Anim({
2396 duration: 0.2,
2397 node: A.getWin(),
2398 to: {
2399 scroll: [0, to.getY()-100]
2400 }
2401 }).run();
2402 }
2403 }
2404 });
2405 }
2406
2407 /* Location */
2408 let userMarkerShadow = null;
2409 let userMarker = null;
2410 let currentPosition = null;
2411 function ${namespace}onUserLocationFound(e) {
2412 const baseColor = '#0f53ff';
2413 currentPosition = e.latlng;
2414 if (!userMarker) {
2415 userMarkerShadow = L.circleMarker(e.latlng, {radius: 15, color: null, fillColor: baseColor, fillOpacity: 0.3, interactive: false}).addTo(map);
2416 userMarker = L.circleMarker(e.latlng, {radius: 7, color: '#fff', fillColor: baseColor, fillOpacity: 1, weight: 2}).addTo(map);
2417 map.setView(currentPosition, 16);
2418 }else{
2419 userMarkerShadow.setLatLng(e.latlng);
2420 userMarker.setLatLng(e.latlng);
2421 }
2422 }
2423 var userLocationNode = A.one("#userLocation");
2424 if(userLocationNode){
2425 userLocationNode.on('click', function(){
2426 if(this.hasClass('btn-selected')){
2427 this.removeClass('btn-selected');
2428 currentPosition = null;
2429 if (userMarker) {
2430 map.removeLayer(userMarker);
2431 userMarker = null;
2432 }
2433 if (userMarkerShadow) {
2434 map.removeLayer(userMarkerShadow);
2435 userMarkerShadow = null;
2436 }
2437 map.stopLocate();
2438 }else{
2439 if(currentPosition){
2440 map.setView(currentPosition, 16);
2441 }else{
2442 map.locate({setView: false, maxZoom: 16, watch: true, enableHighAccuracy: true});
2443 map.on('locationfound', ${namespace}onUserLocationFound);
2444 this.addClass('btn-selected');
2445 }
2446 }
2447 });
2448 }
2449
2450 /* Toggle elevation */
2451 var toggleElevationNode = A.one("#toggleElevation");
2452 if(toggleElevationNode){
2453 var elevationPanel = A.one("#elevation-div-${articleId} .elevation-control");
2454 toggleElevationNode.on('click', function(){
2455 if (!elevationPanel.hasClass('elevation-control-hide')) {
2456 elevationPanel.addClass('elevation-control-hide');
2457 this.removeClass('btn-selected');
2458 } else {
2459 elevationPanel.removeClass('elevation-control-hide');
2460 this.addClass('btn-selected');
2461 }
2462 });
2463 }
2464
2465 /* Center Map Services */
2466 function fitToVisibleMarkerGroups(map, markersServicesGroups) {
2467
2468 //Init
2469 let bounds = null;
2470
2471 for (const key in markersServicesGroups) {
2472 if (markersServicesGroups.hasOwnProperty(key)) {
2473 const group = markersServicesGroups[key];
2474
2475 if (map.hasLayer(group) && group.getLayers().length > 0) {
2476 const groupBounds = group.getBounds();
2477 if (bounds) {
2478 bounds.extend(groupBounds);
2479 } else {
2480 bounds = groupBounds;
2481 }
2482 }
2483 }
2484 }
2485
2486 if (bounds) {
2487 map.fitBounds(bounds, { padding: [50, 50] });
2488 }
2489 }
2490
2491</@>