¿Cómo colocar con precisión un elemento div en un map utilizando folletos js?

Lo he intentado de varias maneras pero no he podido hacerlo funcionar. Quiero colocar relojes en la parte superior del map en varias zonas horarias. Tengo un javascript para crear el reloj y coloco el reloj en un elemento div .

Esto es lo que intenté:

  1. Crea un punto con 0,0 coorderadas.
  2. A partir de este punto, obtenga el valor de latitud para la parte superior del map utilizando containerPointToLatLng .
  3. Cree LatLng usando el lat anterior y largo para la zona horaria.
  4. Convirtió este LatLng en Punto y luego posicionó el elemento div con x,y desde este punto.

Ejecuto la lógica tanto cuando la página se procesa por primera vez como luego en el tamaño del cuerpo. Sin embargo, si cambio el tamaño de la window del browser, el reloj no se posiciona correctamente.

¿Alguna sugerencia?

2 Solutions collect form web for “¿Cómo colocar con precisión un elemento div en un map utilizando folletos js?”

Para responder al problema preciso de OP, es decir, cómo reubicar el reloj cuando se cambia el tamaño de la window del browser (por lo tanto, las dimensiones del contenedor del map pueden haber cambiado), probablemente se deba recalcular la position del reloj en el evento de "resize" del map.

Sin embargo, no está claro si OP colocó el reloj como un elemento secundario del contenedor del map, o en otro lugar en el tree DOM de la página.

Probablemente sea mucho más fácil colocarlo como un elemento secundario del map, de modo que su position siempre esté relacionada con el contenedor del map.

¿Qué OP preguntó originalmente?

Si entiendo correctamente el resultado original deseado, al OP le gustaría superponer un reloj (o cualquier información) sobre una position geográfica particular (ciudad de Toronto en ese caso [UTC -5], según los comentarios).

Sin embargo, el contenedor de información no debe colocarse en una position fija de map base, es decir, no en un punto coordinado geográficamente preciso (como un marcador o una window emergente), sino en la parte superior del contenedor del map, similar a un Control (por lo tanto, la respuesta original de iH8 )

Excepto que no debe estar totalmente fijado dentro del contenedor del map, sino que debe moverse horizontalmente con la ciudad (o las coorderadas geográficas especificadas). De ahí el comentario de OP a la respuesta de iH8.

Por lo tanto, suena como algo similar a ese sitio , excepto con un map interactivo (navegable) y el encabezado "UTC-5" reemplazado por un reloj (o cualquier información, por lo tanto un contenedor HTML debería hacerlo) y horizontalmente siguiendo a Toronto.

Dicho de otra manera, el reloj debería situarse en una línea vertical particular, es decir, longitud / meridiano .

Desafortunadamente, incluso 2 años y medio después de que se publique la pregunta, todavía no hay un complemento de Leaflet que proporcione dicha funcionalidad (al less dentro de la página de complementos de Leaflet ).

Extender el caso de uso al map con gran zoom …

Dicho esto, y dado el hecho de que el usuario puede acercarse mucho a la ciudad (OP no especificó el nivel máximo de zoom), podría no ser una muy buena experiencia de usuario teniendo ese reloj horizontalmente siguiendo una longitud precisa: para Por ejemplo, podría rastrear el centroide / ayuntamiento de Toronto / cualquier lugar en particular, y cuando el usuario está haciendo zoom en otro distrito de la ciudad, el reloj ya no está visible, mientras que él / ella todavía está viendo una parte de la ciudad de Toronto …

Para extender ese caso de uso, el reloj probablemente debería ser visible en cualquier área que aplique, es decir, tan pronto como el puerto de la vista del map se cruza con la zona horaria asociada.

Extender el caso de uso al map con gran alejamiento …

Otro punto no detallado por OP, ¿qué hacer cuando los lugares de diferentes zonas horarias son visibles en el puerto de vista de map? En el sitio mencionado anteriormente , tenemos un encabezado por zona horaria visible , que parece ser la información más completa que podemos get.

Pero como Leaflet permite alejarse hasta el nivel 0, donde el mundo integer (es decir, básicamente 24 zonas horarias / de hecho 39 según Wikipedia , sin include el efecto potencial del horario de verano) se representa con un ancho de 256 píxeles, hay poco espacio para todos estos relojes, si cada uno debe estar alineado verticalmente con su zona horaria asociada.

Por ahora, supongamos que no nos importa si los relojes se superponen.

Aún más caso personalizado …

Pero OP puede haber deseado mostrar el reloj solo para lugares particulares, no para todo el mundo. OP ni siquiera dijo que los relojes serían diferentes (podríamos tener relojes para ciudades en la misma zona horaria, aunque podría ser más interesante tener estos relojes junto a su ciudad, incluso a la par de su latitud, de modo que es más fácil detectar a qué ciudad está asociado el reloj, como en el caso de 2 ciudades en el mismo meridiano, pero en ese caso, un marcador con L.divIcon sería suficiente).

Por lo tanto, un caso personalizado sería no tener en count las zonas horarias oficiales, sino las áreas específicas del desarrollador .

Así que nos olvidamos de la latitud e intentamos alinear un reloj verticalmente sobre el área, siempre que intersecte el puerto de visualización del map.

Describiendo una solución genérica

Por lo tanto, parece que una solución genérica sería permitir que el desarrollador de la aplicación especifique una matriz de Elementos HTML, cada uno asociado con un range de longitudes (también podría ser un área / polígono).

El caso de uso de zonas horarias sería un caso particular en el que las áreas especificadas son simplemente las de las zonas horarias.

Entonces, cada Elemento debería ser visible si y solo si su área asociada se cruza con el puerto de visualización (por lo tanto, presentamos la posibilidad de ocultarlo cuando el range de latitud está fuera de la vista).

En cuanto a posicionamiento, elijamos:

  • Por la parte superior del contenedor del map (similar a un Control), como lo menciona OP.
  • Centrado horizontalmente dentro de la intersección del puerto de vista y del área asociada.

HTML:

 <div id="map"></div> <div id="clockToronto" class="clock leaflet-control">Clock here for Toronto</div> <div id="clockBurlington" class="clock leaflet-control">Clock here for Burlington</div> 

CSS:

 .clock { width: 150px; text-align: center; position: absolute; border: 1px solid black; } #clockToronto { background-color: yellow; } #clockBurlington { background-color: orange; } 

JavaScript:

 var map = L.map("map").setView([43.7, -79.4], 10); // Application specific. var clockTorontoElement = L.DomUtil.get("clockToronto"), clockBurlingtonElement = L.DomUtil.get("clockBurlington"), zones = [ { element: clockTorontoElement, // Using the HTML Element for now. width: parseInt(window.getComputedStyle(clockTorontoElement, null).getPropertyValue("width"), 10), area: L.latLngBounds([43.58, -79.64], [43.86, -79.10]) // Using L.latLngBounds for now. }, { element: clockBurlingtonElement, // Using the HTML Element for now. width: parseInt(window.getComputedStyle(clockBurlingtonElement, null).getPropertyValue("width"), 10), area: L.latLngBounds([43.28, -79.96], [43.48, -79.71]) // Using L.latLngBounds for now. } ]; // Initialization var controlsContainer = map._container.getElementsByClassName("leaflet-control-container")[0], firstCorner = controlsContainer.firstChild, mapContainerWidth; map.on("resize", setMapContainerWidth); setMapContainerWidth(); // Applying the zones. for (var i = 0; i < zones.length; i += 1) { setZone(zones[i]); } function setZone(zoneData) { // Visualize the area. L.rectangle(zoneData.area).addTo(map); console.log("width: " + zoneData.width); controlsContainer.insertBefore(zoneData.element, firstCorner); map.on("move resize", function () { updateZone(zoneData); }); updateZone(zoneData); } function updateZone(zoneData) { var mapBounds = map.getBounds(), zoneArea = zoneData.area, style = zoneData.element.style; if (mapBounds.intersects(zoneArea)) { style.display = "block"; var hcenterLng = getIntersectionHorizontalCenter(mapBounds, zoneArea), hcenter = isNaN(hcenterLng) ? 0 : map.latLngToContainerPoint([0, hcenterLng]).x; // Update Element position. // Could be refined to keep the entire Element visible, rather than cropping it. style.left = (hcenter - (zoneData.width / 2)) + "px"; } else { style.display = "none"; } } function getIntersectionHorizontalCenter(bounds1, bounds2) { var west1 = bounds1.getWest(), west2 = bounds2.getWest(), westIn = west1 < west2 ? west2 : west1, east1 = bounds1.getEast(), east2 = bounds2.getEast(), eastIn = east1 < east2 ? east1 : east2; return (westIn + eastIn) / 2; } function setMapContainerWidth() { mapContainerWidth = map.getSize().x; } 

enter image description here

Demostración en vivo: http://plnkr.co/edit/V2pvcva5S9OZ2N7LlI8r?p=preview

Por lo general, uno usaría L.Control para crear un control personalizado que luego puede agregar a la capa de control. Si lo hace, prospecto se ocupará de posicionamiento al cambiar el tamaño del map. Eche un vistazo a la reference de L.Control: http://leafletjs.com/reference.html#control

Hay un ejemplo de control personalizado en la reference: http://leafletjs.com/reference.html#icontrol. Si desea ver más ejemplos, puede consultar uno de los muchos complementos de control personalizados para ver cómo implementaron L .Control: http://leafletjs.com/plugins.html (en Controles e interacción)

El único inconveniente de L.Control es que no puede colocar un control vertical u horizontalmente centrado. Solo puede usar para ver arriba, abajo, abajo y abajo.

  • ¿Cómo actualizar la opacidad de la capa WMS en el folleto?
  • problema de performance con canvas.getImageData + canvas.putImageData
  • ¿Cambia dinámicamente el color de un polígono en el folleto?
  • Folleto: ajuste la window emergente al tamaño de la image
  • ¿Cómo puedo get el object de map para un map de folleto a partir del ID del elemento div?
  • Leaflet :: Cómo comprobar el punto se encuentra dentro / fuera del polígono o rectángulo
  • cómo agregar text para mostrar en el map a un object geojson en el folleto
  • Cómo get la cadena de área de un polígono usando leaflet.draw
  • Leaflet: Disparar un evento cuando cambian los límites
  • actualizar mapa de folletos: el contenedor del mapa ya está inicializado
  • ¿Es Leaflet una buena herramienta para imágenes que no son de maps?
  • ¿Cómo fuerzo un map de folleto para que vuelva a cargar todas las fichas, incluidas las visibles?
  • Folleto de dibujo de azulejos de manera desarticulada.
  • Javascript tiene muchos buenos JS marco (como Node.js AngularJS Vue.js React.js) es el mejor lenguaje de script.