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