xonecode 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +167 -0
  2. package/dist/agent/authEnDisco.js +56 -0
  3. package/dist/agent/authEnDisco.js.map +1 -0
  4. package/dist/agent/configEnDisco.js +109 -0
  5. package/dist/agent/configEnDisco.js.map +1 -0
  6. package/dist/agent/crearProyecto.js +34 -0
  7. package/dist/agent/crearProyecto.js.map +1 -0
  8. package/dist/agent/entorno.js +124 -0
  9. package/dist/agent/entorno.js.map +1 -0
  10. package/dist/agent/guionizado.js +53 -0
  11. package/dist/agent/guionizado.js.map +1 -0
  12. package/dist/agent/instantanea.js +129 -0
  13. package/dist/agent/instantanea.js.map +1 -0
  14. package/dist/agent/interrupts.js +83 -0
  15. package/dist/agent/interrupts.js.map +1 -0
  16. package/dist/agent/mensajes.js +24 -0
  17. package/dist/agent/mensajes.js.map +1 -0
  18. package/dist/agent/modelos.js +42 -0
  19. package/dist/agent/modelos.js.map +1 -0
  20. package/dist/agent/normalizar.js +20 -0
  21. package/dist/agent/normalizar.js.map +1 -0
  22. package/dist/agent/perfiles.js +103 -0
  23. package/dist/agent/perfiles.js.map +1 -0
  24. package/dist/agent/proyecto.js +107 -0
  25. package/dist/agent/proyecto.js.map +1 -0
  26. package/dist/agent/puente.js +142 -0
  27. package/dist/agent/puente.js.map +1 -0
  28. package/dist/agent/resumenDeTool.js +48 -0
  29. package/dist/agent/resumenDeTool.js.map +1 -0
  30. package/dist/agent/skills.js +65 -0
  31. package/dist/agent/skills.js.map +1 -0
  32. package/dist/agent/textoDeTool.js +113 -0
  33. package/dist/agent/textoDeTool.js.map +1 -0
  34. package/dist/agent/turnoReal.js +173 -0
  35. package/dist/agent/turnoReal.js.map +1 -0
  36. package/dist/agent/verificador.js +65 -0
  37. package/dist/agent/verificador.js.map +1 -0
  38. package/dist/agent/xoneAgent.js +106 -0
  39. package/dist/agent/xoneAgent.js.map +1 -0
  40. package/dist/bin.js +9 -0
  41. package/dist/bin.js.map +1 -0
  42. package/dist/cli/aprobar.js +82 -0
  43. package/dist/cli/aprobar.js.map +1 -0
  44. package/dist/cli/config.js +133 -0
  45. package/dist/cli/config.js.map +1 -0
  46. package/dist/cli/consola.js +346 -0
  47. package/dist/cli/consola.js.map +1 -0
  48. package/dist/cli/describe.js +53 -0
  49. package/dist/cli/describe.js.map +1 -0
  50. package/dist/cli/doctor.js +45 -0
  51. package/dist/cli/doctor.js.map +1 -0
  52. package/dist/cli/main.js +520 -0
  53. package/dist/cli/main.js.map +1 -0
  54. package/dist/cli/markdown.js +90 -0
  55. package/dist/cli/markdown.js.map +1 -0
  56. package/dist/cli/run.js +164 -0
  57. package/dist/cli/run.js.map +1 -0
  58. package/dist/cli/spinner.js +89 -0
  59. package/dist/cli/spinner.js.map +1 -0
  60. package/dist/cli/stdio.js +193 -0
  61. package/dist/cli/stdio.js.map +1 -0
  62. package/dist/cli/tema.js +40 -0
  63. package/dist/cli/tema.js.map +1 -0
  64. package/dist/cli/verify.js +62 -0
  65. package/dist/cli/verify.js.map +1 -0
  66. package/dist/core/bitacora.js +30 -0
  67. package/dist/core/bitacora.js.map +1 -0
  68. package/dist/core/config.js +236 -0
  69. package/dist/core/config.js.map +1 -0
  70. package/dist/core/contextos.js +56 -0
  71. package/dist/core/contextos.js.map +1 -0
  72. package/dist/core/deps.js +51 -0
  73. package/dist/core/deps.js.map +1 -0
  74. package/dist/core/diff.js +79 -0
  75. package/dist/core/diff.js.map +1 -0
  76. package/dist/core/esqueleto.js +366 -0
  77. package/dist/core/esqueleto.js.map +1 -0
  78. package/dist/core/events.js +2 -0
  79. package/dist/core/events.js.map +1 -0
  80. package/dist/core/modelos.js +85 -0
  81. package/dist/core/modelos.js.map +1 -0
  82. package/dist/core/notify.js +106 -0
  83. package/dist/core/notify.js.map +1 -0
  84. package/dist/core/ports.js +114 -0
  85. package/dist/core/ports.js.map +1 -0
  86. package/dist/core/turno.js +127 -0
  87. package/dist/core/turno.js.map +1 -0
  88. package/dist/vendor/hitl.js +103 -0
  89. package/dist/vendor/hitl.js.map +1 -0
  90. package/dist/vendor/skillLoaders/catalog.js +74 -0
  91. package/dist/vendor/skillLoaders/catalog.js.map +1 -0
  92. package/dist/vendor/tokenTracking.js +58 -0
  93. package/dist/vendor/tokenTracking.js.map +1 -0
  94. package/package.json +41 -0
  95. package/skills/xone-debugging/SKILL.md +52 -0
  96. package/skills/xone-debugging/references/faq.md +561 -0
  97. package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
  98. package/skills/xone-development/SKILL.md +105 -0
  99. package/skills/xone-development/references/anti-patrones.md +94 -0
  100. package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
  101. package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
  102. package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
  103. package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
  104. package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
  105. package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
  106. package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
  107. package/skills/xone-development/references/datos/appdata.md +611 -0
  108. package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
  109. package/skills/xone-development/references/datos/http.md +366 -0
  110. package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
  111. package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
  112. package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
  113. package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
  114. package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
  115. package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
  116. package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
  117. package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
  118. package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
  119. package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
  120. package/skills/xone-development/references/indice-completo.md +77 -0
  121. package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
  122. package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
  123. package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
  124. package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
  125. package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
  126. package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
  127. package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
  128. package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
  129. package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
  130. package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
  131. package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
  132. package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
  133. package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
  134. package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
  135. package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
  136. package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
  137. package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
  138. package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
  139. package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
  140. package/skills/xone-development/references/tipos-de-prop.md +28 -0
  141. package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
  142. package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
  143. package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
  144. package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
  145. package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
  146. package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
  147. package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
  148. package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
  149. package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
  150. package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
  151. package/skills/xone-development/references/xml-ui/mapas.md +685 -0
  152. package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
  153. package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
  154. package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
  155. package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
  156. package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
  157. package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
  158. package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
  159. package/skills/xone-plan-builder/SKILL.md +183 -0
  160. package/skills/xone-plan-builder/agents/openai.yaml +5 -0
  161. package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
  162. package/skills/xone-project-generator/SKILL.md +111 -0
  163. package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
  164. package/skills/xone-project-generator/references/colecciones-base.md +16 -0
  165. package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
  166. package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
  167. package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
  168. package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
  169. package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
  170. package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
  171. package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
  172. package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
  173. package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
  174. package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
  175. package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
  176. package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
  177. package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
  178. package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
  179. package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
  180. package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
  181. package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
  182. package/skills/xone-review/SKILL.md +189 -0
  183. package/skills/xone-spec-builder/SKILL.md +235 -0
  184. package/skills/xone-spec-builder/agents/openai.yaml +5 -0
  185. package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
  186. package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
  187. package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
@@ -0,0 +1,685 @@
1
+ # XOne XML — Mapas: atributos, eventos y API JavaScript
2
+
3
+ > Fuente: `xone/v2/xone-project-generator/references/xone-xml-ui-e-mapas-errores.md` §15. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
4
+
5
+ Contenido: §15 mapas completos: atributos del prop type=Z viewmode=mapview, eventos y API JavaScript del control de mapa
6
+
7
+ ---
8
+
9
+ ## 15. Mapas: Atributos, Eventos y API JavaScript
10
+
11
+ XOne soporta dos motores de mapa: **Google Maps** (`viewmode="mapview"`) y **OpenStreetMap** (`viewmode="openstreetmap"`). Ambos comparten la misma API JavaScript salvo excepciones indicadas.
12
+
13
+ ---
14
+
15
+ ### 15.1 Atributos del prop type="Z" para mapas
16
+
17
+ Todos los atributos se definen directamente en el `<prop type="Z">`.
18
+
19
+ #### Comunes a mapview y openstreetmap
20
+
21
+ | Atributo | Valores | Descripción |
22
+ |----------|---------|-------------|
23
+ | `viewmode` | `mapview` / `openstreetmap` | Motor de mapa |
24
+ | `contents` | `@NombreContent` | Coleccion de POIs a mostrar |
25
+ | `show-user-location` | `true`/`false` | Mostrar marcador de posición del usuario |
26
+ | `zoom-to-pois` | `true`/`false` | Ajustar zoom para mostrar todos los POIs al cargar |
27
+ | `zoom-to-my-location` | `true`/`false` | Centrar mapa en ubicación del usuario al cargar |
28
+ | `map-type` | `normal` / `satellite` / `terrain` / `hybrid` / `none` | Tipo de mapa. También configurable en tiempo de ejecución con `setMapType()` |
29
+ | `show-pois` | `true`/`false` | Mostrar los POIs del contents |
30
+ | `show-google-buttons` | `true`/`false` | Mostrar botones nativos de Google Maps |
31
+ | `clear-lines-on-refresh` | `true`/`false` | Borrar lineas dibujadas al hacer refresh |
32
+ | `cluster-markers` | `true`/`false` | Agrupar marcadores cercanos en clusters |
33
+ | `follow-location-on-background` | `true`/`false` | Seguir la ubicación del usuario aunque la app este en segundo plano |
34
+ | `ignore-geocoding-errors` | `true`/`false` | No lanzar error si falla la geocodificacion de una dirección |
35
+ | `zoom-buttons-visibility` | `always` / `never` | Visibilidad de los botones de zoom |
36
+ | `min-zoom` | Número | Nivel mínimo de zoom permitido |
37
+ | `max-zoom` | Número | Nivel máximo de zoom permitido |
38
+ | `encoded-initial-bounds` | String encoded | Limites iniciales del mapa en formato polyline encoded |
39
+ | `restrict-map-to-bounds` | `"lat1,lon1,lat2,lon2"` | Restringe el desplazamiento del mapa a unos limites geograficos |
40
+
41
+ #### Eventos del prop mapa (atributos inline)
42
+
43
+ | Atributo | Descripción | Parámetros del evento |
44
+ |----------|-------------|----------------------|
45
+ | `onmapclicked` | Click en el mapa (no sobre un marcador) | `e.latitude`, `e.longitude`, `e.target` (nombre del prop) |
46
+ | `onmaplongclicked` | Click largo en el mapa | `e.latitude`, `e.longitude`, `e.target` |
47
+ | `onmapready` | Mapa inicializado y listo | `e.target` |
48
+ | `onmapzoomchanged` | Cambio de nivel de zoom | `e.zoom` (nuevo nivel); `e.bounds` = `Object[]` de 2 elementos `[noreste, suroeste]`. Cada elemento es un objeto location con `latitude`, `longitude`, `altitude`, `accuracy`, `bearing`, `speed`, `time` (los 5 últimos siempre a 0) |
49
+ | `onmarkerdragend` | Fin de arrastre de un marcador | `e.latitude`, `e.longitude`, `e.tag`, `e.marker` |
50
+ | `ondrop` | Objeto soltado sobre el mapa (drag & drop) | `e.latitude`, `e.longitude`, `e.target` |
51
+ | `ondistancemeter` | Evento del medidor de distancia | `e.distance`, `e.location1`, `e.location2` |
52
+ | `onstreetviewenabled` | StreetView activado | `e.latitude`, `e.longitude`, `e.target` (coordenadas del punto donde se activó) |
53
+ | `onstreetviewunavailable` | StreetView no disponible en la zona | `e.latitude`, `e.longitude`, `e.target` (coordenadas del punto consultado) |
54
+ | `onlocationready` | Primera localización GPS obtenida | `e.latitude`, `e.longitude` |
55
+ | `onlocationchanged` | Cambio de posición GPS | `e.latitude`, `e.longitude` |
56
+
57
+ #### Atributos exclusivos de openstreetmap
58
+
59
+ | Atributo | Valores | Descripción |
60
+ |----------|---------|-------------|
61
+ | `show-compass` | `true`/`false` | Mostrar brujula |
62
+ | `show-minimap` | `true`/`false` | Mostrar minimapa de referencia |
63
+ | `show-scale` | `true`/`false` | Mostrar escala del mapa |
64
+ | `tile-source` | `usgs_topo` / `usgs_sat` | Fuente alternativa de tiles |
65
+ | `storage-path` | Ruta | Ruta para almacenar tiles descargados offline |
66
+ | `offline-maps` | `true`/`false` | Activar modo mapas offline |
67
+ | `user-location-icon` | `nombre.png` | Icono personalizado para la posición del usuario |
68
+ | `direction-arrow-icon` | `nombre.png` | Icono de flecha de dirección |
69
+ | `allow-rotate` | `true`/`false` | Permitir rotar el mapa con dos dedos |
70
+
71
+ #### Ejemplo de declaración completa
72
+
73
+ ```xml
74
+ <prop name="MAP_MAPA" type="Z" visible="1"
75
+ viewmode="mapview"
76
+ contents="@PuntosEntrega"
77
+ map-type="normal"
78
+ show-user-location="true"
79
+ zoom-to-pois="true"
80
+ show-pois="true"
81
+ show-google-buttons="true"
82
+ clear-lines-on-refresh="false"
83
+ cluster-markers="true"
84
+ follow-location-on-background="true"
85
+ min-zoom="10" max-zoom="15"
86
+ width="100%" height="70%"
87
+ onmapclicked="onMapClicked(e);"
88
+ onmaplongclicked="onMapLongClicked(e);"
89
+ onmapready="onMapReady(e);"
90
+ onmapzoomchanged="onMapZoomChanged(e);"
91
+ onmarkerdragend="onMarkerDraggedEnd(e);" />
92
+
93
+ <contents name="@PuntosEntrega" src="PuntosEntregaColl" />
94
+ ```
95
+
96
+ ---
97
+
98
+ ### 15.2 API JavaScript del control de mapa
99
+
100
+ El control de mapa se obtiene desde JavaScript con la función global nativa `getControl(name, [dataObject])`:
101
+
102
+ ```javascript
103
+ let mapControl = getControl("MAP_MAPA");
104
+ ```
105
+
106
+ #### Navegación y zoom
107
+
108
+ ```javascript
109
+ // Centrar el mapa en unas coordenadas (sin cambiar zoom)
110
+ mapControl.moveTo(38.886546, -7.0043193);
111
+
112
+ // Centrar con nivel de zoom específico
113
+ mapControl.zoomTo(38.886546, -7.0043193);
114
+ mapControl.zoomTo(38.886546, -7.0043193, 15); // nivel de zoom 15
115
+ mapControl.zoomTo(38.886546, -7.0043193, 500, true); // 500 metros de radio
116
+
117
+ // Zoom para mostrar todos los POIs
118
+ // (equivalente al atributo zoom-to-pois en tiempo de carga)
119
+ mapControl.zoomToBounds(["lat1, lon1", "lat2, lon2"]);
120
+
121
+ // Zoom a datos polyline encoded
122
+ mapControl.zoomToEncodeData(sPolylineEncoded);
123
+
124
+ // Zoom a mi localización con nivel concreto
125
+ mapControl.zoomToMyLocation(20);
126
+
127
+ // Nivel de zoom actual
128
+ let nZoom = mapControl.getZoom();
129
+
130
+ // Establecer zoom
131
+ mapControl.setZoom(13);
132
+
133
+ // Limites de zoom
134
+ mapControl.setMinZoom(10);
135
+ mapControl.setMaxZoom(15);
136
+ mapControl.resetMinMaxZoom();
137
+
138
+ // Centro actual del mapa -> { latitude, longitude }
139
+ let center = mapControl.getMapCenter();
140
+
141
+ // Limites actuales del mapa -> array de 2 puntos: [noreste, suroeste]
142
+ let bounds = mapControl.getMapBounds();
143
+
144
+ // Restringir desplazamiento a unos limites
145
+ mapControl.restrictMapToBounds(["lat1, lon1", "lat2, lon2"]);
146
+
147
+ // Seguir/dejar de seguir la ubicación del usuario
148
+ mapControl.setFollowUserLocation(true);
149
+ mapControl.setFollowUserLocation(false);
150
+
151
+ // Cambiar tipo de mapa en tiempo de ejecución
152
+ // Valores: normal / satellite / terrain / hybrid / none
153
+ mapControl.setMapType("satellite");
154
+ let sType = mapControl.getMapType();
155
+ ```
156
+
157
+ #### Marcadores
158
+
159
+ Los marcadores se pueden añadir desde JavaScript (además de los que vienen de la colección `contents`).
160
+
161
+ > ⚠️ **Las claves de callback (`onClick`, `onClusterClick`) van en camelCase exacto.** A diferencia de los eventos en XML y en `bind()` —que son insensibles a mayúsculas/minúsculas—, estos callbacks se leen como propiedades del objeto de configuración por su nombre literal. Si los escribes en minúscula (`onclick`), el marcador se crea pero el callback **no se ejecuta nunca** (se ignora en silencio).
162
+
163
+ ```javascript
164
+ // Añadir marcador por script
165
+ let params = {
166
+ title : "Titulo del marcador", // Util con TalkBack
167
+ latitude : evento.latitude,
168
+ longitude: evento.longitude,
169
+ rotation : 0, // Grados de rotacion
170
+ alpha : 1, // Opacidad 0.0 - 1.0
171
+ draggable: true,
172
+ anchor : "top", // top / bottom / center
173
+ icon : "ic_marker.png",
174
+ width : 35, // Ancho del icono en puntos
175
+ height : 47, // Alto del icono en puntos
176
+ tag : "dato_extra", // Dato personalizado
177
+ onClick : function(evento) {
178
+ evento.marker.setIcon("ic_otro.png");
179
+ evento.marker.showInfo();
180
+ }
181
+ };
182
+ let marker = mapControl.addMarker(params);
183
+
184
+ // Operaciones sobre un marcador obtenido
185
+ marker.setVisible(true);
186
+ marker.setDraggable(true); // En MapLibre es no-op silencioso
187
+ marker.setRotation(180); // Animado por defecto. Para rotación instantánea: marker.setRotation(180, false). En MapLibre es no-op
188
+ marker.setAlpha(0.5); // En MapLibre es no-op
189
+ marker.setAnchor("top"); // top / bottom / center. En MapLibre es no-op
190
+ marker.setIcon("ic_nuevo.png");
191
+ marker.setPosition({
192
+ latitude : 38.8685452,
193
+ longitude: -6.8170906,
194
+ animate : true,
195
+ duration : 500 // ms de animacion
196
+ });
197
+ let pos = marker.getPosition(); // [latitude, longitude]
198
+ marker.remove();
199
+ marker.showInfo(); // Mostrar info window del marcador
200
+
201
+ // Eliminar todos los marcadores (coleccion + script)
202
+ let mapContent = self.getContents("@PuntosEntrega");
203
+ mapContent.unlock();
204
+ mapContent.clear();
205
+ mapContent.lock();
206
+ ui.refresh("MAP_MAPA");
207
+ ```
208
+
209
+ #### Clusters de marcadores
210
+
211
+ Solo disponible en **Google Maps** (`viewmode="mapview"`). En `openstreetmap`, `maplibre` y `picturemap`, `addClusteredMarker` y `getClusterManager` **no existen**.
212
+
213
+ ```javascript
214
+ // Añadir marcador a un cluster (solo Google Maps)
215
+ mapControl.addClusteredMarker({
216
+ clusterId : "grupo1",
217
+ clusterIcon : "ic_cluster.png",
218
+ latitude : 40.4165,
219
+ longitude : -3.70256,
220
+ icon : "ic_marker.png",
221
+ title : "Titulo",
222
+ snippet : "Descripción",
223
+ itemCounter : true, // Mostrar contador de items en el cluster
224
+ tag : "dato",
225
+ onClick : function(tag, marker) {},
226
+ onClusterClick: function(ev) {
227
+ // ev.clusterId, ev.latitude, ev.longitude, ev.target
228
+ mapControl.zoomTo(ev.latitude, ev.longitude, 15);
229
+ }
230
+ });
231
+
232
+ // Obtener gestor del cluster
233
+ let cluster = mapControl.getClusterManager("grupo1");
234
+ cluster.clear(); // Eliminar todos los marcadores del cluster
235
+ cluster.show();
236
+ cluster.hide();
237
+ ```
238
+
239
+ #### Lineas
240
+
241
+ ```javascript
242
+ // Dibujar línea
243
+ mapControl.drawLine({
244
+ line : "nombre_linea", // Identificador para poder borrarla después
245
+ strokeColor: "#FF0000",
246
+ strokeWidth: 5.0,
247
+ mode : "normal", // normal / dashed / dotted / mixed
248
+ locations : [
249
+ { latitude: 37.35, longitude: -9.72 },
250
+ { latitude: 37.35, longitude: -0.00 }
251
+ ]
252
+ });
253
+
254
+ // Dibujar línea con datos polyline encoded
255
+ mapControl.drawLine({
256
+ line : "linea_encoded",
257
+ strokeColor: "#FF00FF",
258
+ strokeWidth: 12.0,
259
+ mode : "normal",
260
+ data : "u~ilF~bwi@iH~GuC_UvDaN" // Polyline encoded
261
+ });
262
+
263
+ // Borrar una línea por nombre
264
+ mapControl.clearLine("nombre_linea");
265
+
266
+ // Borrar todas las lineas
267
+ mapControl.clearAllLines();
268
+ ```
269
+
270
+ #### Rutas
271
+
272
+ ```javascript
273
+ // Dibujar ruta calculada (Google Maps en mapview, OSRM/osm2po en openstreetmap)
274
+ mapControl.drawRoute({
275
+ route : "ruta1", // Identificador
276
+ waypoints : [
277
+ { latitude: 38.87789, longitude: -6.97061 },
278
+ { latitude: 38.41667, longitude: -6.41667 }
279
+ ],
280
+ mode : "driving", // driving / walking / bicycling / transit
281
+ strokeColor: "#00FF00",
282
+ strokeWidth: 5.0,
283
+ linePattern: "normal" // normal / dashed / dotted / mixed
284
+ // accurate: true // Ruta precisa con Google Maps (consume mas recursos)
285
+ // urlType: "osrm" // Solo OpenStreetMap: osrm / osm2po
286
+ // url: "http://..." // URL del servidor de rutas OSM
287
+ });
288
+
289
+ // Borrar una ruta por nombre
290
+ mapControl.clearRoute("ruta1");
291
+
292
+ // Borrar todas las rutas
293
+ mapControl.clearAllRoutes();
294
+
295
+ // Dibujar ruta al POI mas cercano
296
+ mapControl.drawRoute({
297
+ route : "ClosestRoute",
298
+ waypoints : [userLocation, closestPoi],
299
+ strokeColor: "#FFFF00",
300
+ strokeWidth: 5.0
301
+ });
302
+ ```
303
+
304
+ #### Rutas externas
305
+
306
+ ```javascript
307
+ // Abrir app externa de navegacion
308
+ new GpsTools().routeTo({
309
+ sourceLatitude : 40.4167747,
310
+ sourceLongitude : -3.70379019,
311
+ destinationLatitude : 41.3850632,
312
+ destinationLongitude: 2.1734035,
313
+ source : "google_maps" // internal / external / google_maps / osmand / osmand_plus
314
+ });
315
+ ```
316
+
317
+ #### Áreas (poligonos)
318
+
319
+ ```javascript
320
+ // Dibujar área con array de coordenadas
321
+ mapControl.drawArea({
322
+ id : "area1",
323
+ fillcolor: "#7F00FF00", // ARGB: semi-transparente
324
+ color : "#FF0000FF", // Color borde
325
+ width : 5,
326
+ pattern : "normal", // normal / dashed / dotted / mixed
327
+ onClick : function() { ui.showToast("Click en área"); },
328
+ data : ["43.37, -8.42", "43.26, -2.93", "38.72, -9.13"]
329
+ });
330
+
331
+ // Dibujar área con polyline encoded
332
+ mapControl.drawEncodeArea({
333
+ id : "area2",
334
+ fillcolor: "#7F0000FF",
335
+ color : "#FFFF0000",
336
+ width : 5,
337
+ pattern : "normal",
338
+ data : new GpsTools().encode(["38.87, -6.82", "40.42, -3.70"])
339
+ });
340
+
341
+ // Borrar área por ID
342
+ mapControl.removeArea("area1");
343
+
344
+ // Borrar todas las areas
345
+ mapControl.clearAllAreas();
346
+ ```
347
+
348
+ #### Circulos
349
+
350
+ ```javascript
351
+ // Dibujar circulo
352
+ let circle = mapControl.drawCircle({
353
+ location : { latitude: 38.87789, longitude: -6.97061 },
354
+ visible : true,
355
+ radius : 1000, // Radio en metros
356
+ pattern : "dashed", // normal / dashed / dotted / mixed
357
+ fillColor : "#00000000", // Color relleno (ARGB)
358
+ strokeColor: "#00FF00", // Color borde
359
+ strokeWidth: 10 // Grosor borde en pixeles
360
+ });
361
+
362
+ // Operaciones sobre el circulo
363
+ circle.setVisible(true);
364
+ let location = circle.getLocation();
365
+ circle.setLocation({
366
+ latitude : location.latitude + 0.005,
367
+ longitude: location.longitude,
368
+ animate : true
369
+ });
370
+
371
+ // Mostrar/ocultar todos los circulos
372
+ // (gestion manual con array)
373
+ ```
374
+
375
+ #### POIs (puntos de interes del contents)
376
+
377
+ ```javascript
378
+ // Cambiar el filtro de la coleccion de POIs y refrescar el mapa
379
+ let mapContent = self.getContents("@PuntosEntrega");
380
+ mapContent.setFilter("t1.NOMBRE = 'Madrid'");
381
+ mapContent.unlock();
382
+ mapContent.clear();
383
+ mapContent.loadAll();
384
+ mapContent.lock();
385
+ ui.refresh("MAP_MAPA");
386
+
387
+ // Menu de POIs
388
+ mapControl.showPoisMenu();
389
+ mapControl.hidePoisMenu();
390
+ mapControl.togglePoisMenu();
391
+
392
+ // Para gestionar muchos marcadores creados por script, guarda sus wrappers
393
+ // en una variable propia (array/objeto) al llamar a addMarker() y
394
+ // recorrelos para llamar setVisible/setDraggable/remove. No existe un
395
+ // "showMarkers/hideMarkers/setMarkersDraggable/removeMarkers" globales.
396
+ ```
397
+
398
+ #### Localización del usuario
399
+
400
+ ```javascript
401
+ // Obtener la localización actual del usuario desde el mapa
402
+ let userLocation = mapControl.getUserLocation();
403
+ // userLocation: { latitude, longitude, altitude, speed, accuracy,
404
+ // bearing, time, provider }
405
+
406
+ // Habilitar/deshabilitar la capa de localización
407
+ mapControl.isUserLocationEnabled(); // -> boolean
408
+ mapControl.enableUserLocation();
409
+ mapControl.disableUserLocation();
410
+ ```
411
+
412
+ #### Street View (solo Google Maps)
413
+
414
+ ```javascript
415
+ // Mostrar Street View en una ubicación
416
+ mapControl.showStreetView({ latitude: 38.886, longitude: -7.004 });
417
+
418
+ // Eliminar Street View y volver al mapa
419
+ mapControl.removeStreetView();
420
+
421
+ // Iniciar drag para soltar en el mapa y abrir StreetView en ese punto
422
+ // (usar con onlongclick en un frame flotante)
423
+ ui.startDrag(control, {});
424
+ // El evento ondrop del mapa recibe e.latitude, e.longitude
425
+ ```
426
+
427
+ #### Captura de imagen del mapa
428
+
429
+ ```javascript
430
+ let sImagePath = mapControl.captureImage();
431
+ ui.openFile(sImagePath);
432
+ ```
433
+
434
+ #### Capas adicionales
435
+
436
+ ```javascript
437
+ // Añadir capa WMS
438
+ mapControl.addWmsTileOverlay({
439
+ name : "nombre_capa",
440
+ urlDomain : "https://servidor.com/wms",
441
+ version : "1.1.1",
442
+ request : "GetMap",
443
+ layers : "nombre:capa",
444
+ width : 256,
445
+ height : 256,
446
+ spatialReferenceSystem: "EPSG:900913",
447
+ format : "image/png",
448
+ transparent : true,
449
+ debug : false
450
+ });
451
+
452
+ // Eliminar capa WMS (true = eliminar también cache)
453
+ mapControl.removeWmsTileOverlay(true);
454
+
455
+ // Añadir capa GeoJSON
456
+ mapControl.addGeoJson({
457
+ id : "capa_geojson",
458
+ dataFile : "fichero.json", // Fichero JSON en carpeta de la app
459
+ // data : sJsonString, // Alternativa: string JSON o objeto JS
460
+ strokeColor: "#0000FF",
461
+ fillColor : "#00FF00"
462
+ });
463
+ mapControl.removeGeoJson("capa_geojson");
464
+ mapControl.removeAllGeoJson(); // Eliminar TODAS las capas GeoJSON
465
+ let ids = mapControl.getGeoJsonLayerIds(); // -> array de strings
466
+
467
+ // Añadir capa KML / KMZ
468
+ mapControl.addKml({
469
+ id : "capa_kml",
470
+ dataFile : "fichero.kmz",
471
+ strokeColor: "#0000FF",
472
+ fillColor : "#00FF00"
473
+ });
474
+ mapControl.removeKml("capa_kml");
475
+ mapControl.removeAllKml(); // Eliminar TODAS las capas KML
476
+ let kmlIds = mapControl.getKmlLayerIds(); // -> array de strings
477
+ ```
478
+
479
+ #### Limpiar el mapa completo
480
+
481
+ ```javascript
482
+ // Limpia rutas, líneas, áreas, polylines, GeoJSON y KML dibujados por script.
483
+ // NO toca: marcadores de la coleccion @contents, capas WMS, StreetView,
484
+ // zoom/centro/tipo de mapa.
485
+ mapControl.clearMap();
486
+ ```
487
+
488
+ Equivale a llamar en cadena a `clearAllRoutes()`, `clearAllLines()`, `clearAllAreas()`, `clearAllPolylines()`, `removeAllGeoJson()` y `removeAllKml()`. Cada motor omite las operaciones que no soporta (p. ej. MapLibre solo limpia lineas y GeoJSON).
489
+
490
+ #### Utilidades de polyline
491
+
492
+ ```javascript
493
+ // Codificar array de coordenadas a polyline encoded
494
+ let sEncoded = new GpsTools().encode(["38.87, -6.82", "40.42, -3.70"]);
495
+
496
+ // Decodificar polyline encoded a array de { latitude, longitude }
497
+ let locations = new GpsTools().decode("moflFxmrh@kkmHca_R");
498
+
499
+ // Simplificar polyline (reducir puntos manteniendo forma)
500
+ let simplified = new GpsTools().simplifyPolyline({
501
+ polyline : [{ latitude: 43.104, longitude: -3.4261 }, ...],
502
+ tolerance: 3000 // En metros. Mayor = menos vertices
503
+ });
504
+
505
+ // Codificar polyline del mapa actual (solo Google Maps)
506
+ let sPolyline = mapControl.encodePolyline();
507
+
508
+ // Descargar tiles offline (solo openstreetmap)
509
+ mapControl.downloadTiles({
510
+ coordinates : [{ latitude: 38.89, longitude: -6.92 },
511
+ { latitude: 38.88, longitude: -6.89 }],
512
+ onCompleted : function(nErrors) {},
513
+ onProgressUpdated: function(nProgress, nCurrentZoomLevel) {},
514
+ onDownloadStarted: function() {}
515
+ });
516
+ ```
517
+
518
+ #### Brujula (solo openstreetmap)
519
+
520
+ ```javascript
521
+ mapControl.showCompass();
522
+ mapControl.hideCompass();
523
+ mapControl.toggleCompass();
524
+ ```
525
+
526
+ #### Medidor de distancia
527
+
528
+ Solo está implementado en Google Maps (`viewmode="mapview"`). En `openstreetmap`, `maplibre` y `picturemap` las llamadas lanzan `UnsupportedOperationException("Not implemented yet")`.
529
+
530
+ ```javascript
531
+ // Iniciar medidor de distancia interactivo (objeto JS)
532
+ mapControl.startDistanceMeter({
533
+ latitude : 38.886546,
534
+ longitude : -7.0043193,
535
+ startMarkerIcon: "ic_start.png", // opcional
536
+ endMarkerIcon : "ic_end.png" // opcional
537
+ });
538
+
539
+ // Forma posicional alternativa: location + iconos (máx. 2 iconos)
540
+ mapControl.startDistanceMeter("38.886546,-7.0043193", "ic_start.png", "ic_end.png");
541
+
542
+ // Sin parámetros: usa el centro actual de la cámara como punto de partida
543
+ mapControl.startDistanceMeter();
544
+
545
+ // El evento ondistancemeter se dispara al terminar de arrastrar
546
+ // cualquiera de los dos marcadores (no solo el final).
547
+ // Parámetros: e.distance (metros, geodésica), e.location1, e.location2.
548
+ // location1/location2 contienen latitude, longitude, altitude, accuracy,
549
+ // bearing, speed, time (los cinco últimos siempre a 0).
550
+
551
+ mapControl.stopDistanceMeter();
552
+ ```
553
+
554
+ ---
555
+
556
+ ### 15.3 GPS: ui.startGps, ui.stopGps y checkGpsStatus
557
+
558
+ El GPS del dispositivo se controla con funciones `ui` globales. Los datos GPS se exponen a traves de una coleccion **declarada por el proyecto** (convencionalmente llamada `GpsCollection`) con un connector de tipo GPS. No es una coleccion built-in del framework: el proyecto debe declararla en su mapping para poder hacer `appData.getCollection("GpsCollection")`.
559
+
560
+ ```javascript
561
+ // Activar GPS (modo básico)
562
+ ui.startGps();
563
+
564
+ // Activar GPS con configuración
565
+ ui.startGps({
566
+ nodeName : "callbackgps", // Nombre del handler custom que se invocara
567
+ timeBetweenUpdates : 10000, // Milisegundos entre actualizaciones
568
+ minimumMetersDistanceRange: 10, // Metros minimos de desplazamiento
569
+ maxUpdateDelayMillis : 0,
570
+ priority : "high", // high / balanced / low_power / passive
571
+ maxUpdates : 1000,
572
+ durationMs : 3600000,
573
+ granularity : "permission_level", // permission_level / fine / coarse
574
+ waitForAccurateLocation : true
575
+ });
576
+
577
+ // Desactivar GPS
578
+ ui.stopGps();
579
+
580
+ // Comprobar estado del GPS
581
+ let nStatus = ui.checkGpsStatus();
582
+ // 0 = Sin GPS en el dispositivo
583
+ // 1 = GPS activo
584
+ // 2 = Localización por redes wifi/telefonia activa
585
+ // 3 = Sin localización activada -> llamar a ui.askUserForGpsPermission()
586
+ // 4 = GPS + redes activos
587
+ // -1 = Error inesperado
588
+
589
+ // Pedir al usuario que active el GPS
590
+ ui.askUserForGpsPermission({
591
+ onEnabled: function() { ui.showToast("GPS activado"); },
592
+ onDenied : function() { ui.showToast("GPS denegado"); }
593
+ });
594
+ ```
595
+
596
+ #### Leer datos GPS desde GpsCollection
597
+
598
+ ```javascript
599
+ let collGps = appData.getCollection("GpsCollection");
600
+ collGps.loadAll();
601
+ let objGps = collGps.get(0);
602
+ if (objGps && objGps.STATUS == 1 && objGps.LONGITUD) {
603
+ let lat = objGps.LATITUD;
604
+ let lon = objGps.LONGITUD;
605
+ let alt = objGps.ALTITUD;
606
+ let vel = objGps.VELOCIDAD;
607
+ let rumbo = objGps.RUMBO;
608
+ let fecha = objGps.FGPS;
609
+ let hora = objGps.HGPS;
610
+ let sats = objGps.SATELITES;
611
+ let fuente = objGps.FUENTE;
612
+ let precision= objGps.PRECISION;
613
+ let fake = objGps.FAKE; // 1 = localización falsa (mock)
614
+ }
615
+ ```
616
+
617
+ #### Permiso location-background
618
+
619
+ Para tracking en segundo plano (Android) es necesario declarar el permiso en la coleccion:
620
+
621
+ ```xml
622
+ <permissions>
623
+ <permission name="location-foreground" />
624
+ <permission name="location-background" />
625
+ </permissions>
626
+ ```
627
+
628
+ ---
629
+
630
+ ### 15.4 GpsTools: API de utilidades GPS
631
+
632
+ `GpsTools` es un objeto JavaScript para calculos geograficos y geocodificacion. Se instancia con `new GpsTools()`.
633
+
634
+ ```javascript
635
+ // Calcular distancia entre dos puntos (en metros)
636
+ let nMetros = new GpsTools().distanceTo([
637
+ { latitude: 38.8685452, longitude: -6.8170906 },
638
+ { latitude: 40.4167747, longitude: -3.70379019 }
639
+ ]);
640
+
641
+ // Calcular distancia entre dos puntos (alternativa)
642
+ let nMetros2 = new GpsTools().distanceBetweenCoordinates(
643
+ { latitude: 38.87, longitude: -6.97 },
644
+ { latitude: 40.42, longitude: -3.70 }
645
+ );
646
+
647
+ // Geocodificacion inversa: coordenadas -> dirección
648
+ let result = new GpsTools().getAddressFromPosition("38.8862106, -7.0040345");
649
+ // result: { locality, subLocality, adminArea, subAdminArea, features,
650
+ // country, countryCode, street, number, address, postal }
651
+
652
+ // Geocodificacion directa: dirección -> coordenadas
653
+ let pos = new GpsTools().getPositionFromAddress("Badajoz");
654
+ // pos: { latitude, longitude } o null si no se encuentra
655
+
656
+ // Ultima localización conocida del dispositivo
657
+ let location = new GpsTools().getLastKnownLocation();
658
+ // location: { latitude, longitude, accuracy, altitude, bearing, speed, time }
659
+
660
+ // Comprobar si un punto esta dentro de un poligono
661
+ let bDentro = new GpsTools().containsLocation(
662
+ "40.3633442, -1.0893794", // Punto a comprobar
663
+ ["43.37, -8.42", "43.26, -2.93", "38.72, -9.13"] // Vertices del poligono
664
+ );
665
+
666
+ // Codificar array de coordenadas a polyline encoded
667
+ let sEncoded = new GpsTools().encode(["38.87, -6.82", "40.42, -3.70"]);
668
+
669
+ // Decodificar polyline encoded
670
+ let locations = new GpsTools().decode("moflFxmrh@kkmHca_R");
671
+
672
+ // Simplificar polyline (reducir puntos)
673
+ let simplified = new GpsTools().simplifyPolyline({
674
+ polyline : [{ latitude: 43.104, longitude: -3.4261 }, ...],
675
+ tolerance: 3000 // metros
676
+ });
677
+
678
+ // Añadir metadatos EXIF de localización a una imagen
679
+ new GpsTools().addExifLocationToFile({
680
+ file : "foto.jpg",
681
+ latitude : 40.4165000,
682
+ longitude: -3.7025600
683
+ });
684
+ ```
685
+