
Javier shared this beautiful bottle of gin. Nordes is a Galician gin, who knew?
Javier shared this beautiful bottle of gin. Nordes is a Galician gin, who knew?
Matthew Edney said “3d cast braille/tactile map of the Garden of the Five Senses, Coastal Maine Botanical Gardens, Boothbay, ME, USA. Very cool place, even for an indoor-person like me!”
You must be logged into the site to view this content.
Prezado leitor,
A Geocursos está com inscrições abertas para uma nova turma do Curso WebGIS: Crie Mapas Interativos na Web, sem precisar programar!
Aprenda a disponibilizar dados espaciais na internet com uma plataforma WebGIS através de mapas interativos, dashboards, geostories, tudo isso com controle de acesso por nível de usuários e grupos.
Nesse curso você irá aprender:
O curso é ideal para estudantes e profissionais de GIS, Geografia, Engenharia, Meio Ambiente, Planejamento Urbano e TI.
Aulas práticas |
Ferramentas livres |
SIG na Web
Inscreva-se e leve seus dados espaciais para o mundo online!
Acesse: https://geocursos.com.br/webgis
WhatsApp: https://whats.link/geocursos
Reinder said “My former employer – 82 by now – drew a primitive impression of a street in our old home town. On the right corner is his antiquarian bookshop that he actually still keeps running. In the window one can see a map of the Netherlands.”
I love this
From Reinder’s Tour de France: cartographically inspired decoration in the 18th C. library
And that’s the end of Reinder’s Tour de France. He is an example to all of us in spotting maps in the wild wherever he goes.
From Reinder’s Tour de France: “Stained glass windows in La chapelle de l’Université Catholique in Lille, France.”
From Reinder’s Tour de France: “Recommended Hotel in Lille, France (Hotel Brueghel, that was). Quite nice, actually.”
En mi serie de artículos sobre la creación de un asistente para gvSIG desktop, explore el viaje desde el prototipo hasta una solución distribuible. Hoy quiero hacer un acercamiento en un aspecto que resultó ser crucial: el arte, o ciencia, de describir las herramientas para que un LLM pueda usarlas de forma eficaz.
A la hora de describir las herramientas que tiene disponible un LLM, bien porque has hecho un cliente que las expone o porque has implementado o vas a implementar un servidor MCP, la descripción es una pieza clave para que el LLM pueda usarlas de forma adecuada.
Aquí os dejo la descripción de las herramientas que expone el servidor MCP que implementé para gvSIG Desktop.
string
, required): The ID of the data model.boolean
, optional): Whether to include data dictionaries in the schema. Defaults to true.LIMIT
clause is mandatory in your query. Queries without a LIMIT
clause will be rejected. The maximum allowed limit is 100.show_table
tool instead.DYNAMIC PLACEHOLDERS:
Dynamic placeholders are markers replaced just before executing the SQL query with contextual values. They have a format of ${COMPONENT.PROPERTY}
, and are case insensitive.
Available placeholders are:
${CURRENTVIEW.BBOX}
which is replaced by the bounding box of the active View.${CURRENTVIEW.SRID}
which is replaced by the SRID of the active View.${<TABLE>.SELECTION}
where <TABLE>
must be the name of a table in the data model, and is replaced by the list of primary keys of the table of the selected elements separated by “,”. If the list exceeds a “reasonable limit” it will be replaced by NULL. If the primary keys of the table are of character type, they will be properly quoted. This value is appropriate to be used in an IN clause of a WHERE.All used placeholders need to be declared in the ‘placeholders’ parameter.
Restrictions (must not be used in):
They are allowed in:
SELECT '${CURRENTVIEW.SRID}' AS srid
SELECT * FROM SUPPORTS WHERE ST_Within(GEOMETRY, ST_GeomFromText('${CURRENTVIEW.BBOX}'))
SELECT * FROM SUPPORTS WHERE ID IN (${SUPPORTS.SELECTION})
CRITICAL BEHAVIORAL RULES:
Examples:
QUERY CONSTRUCTION RULES:
table
not schema.table
)CATEGORIZED FIELD HANDLING:
WHERE material = 'ALUMINUM'
(not WHERE material LIKE '%aluminum%'
)ABOUT SCHEMA RETRIEVAL:
You do NOT need to call get_data_model_schema
before using this tool unless you need schema information to construct your query. If you already know the table structure from previous interactions, proceed directly with your query.
string
, required): The ID of the data model to query.string
, required): The SQL query to execute. Must include a LIMIT clause and return a small result set.array
of string
, optional): Optional list of placeholders to replace in the query.query_table
:
string
, required): The ID of the data model to query.string
, required): The SQL query to execute.string
, required): A descriptive name for the result returned by the query. This value will be used as the label or identifier for the scalar data obtained.array
of string
, optional): Optional list of placeholders to replace in the query.query_table
:
string
, required): The ID of the data model containing the table.string
, required): The name of the table to apply the selection to.string
, required): The SQL query to execute. It must return a single column of primary keys for the specified table.string
, required): The WKT (Well-Known Text) representation of the bounding box to zoom to.string
, required): The WKT (Well-Known Text) representation of the point to center the view on.query_value
tool to gather it. This may involve calling query_value
multiple times, once for each data point needed for the chart, and then assembling the results into the final diagram code.get_data_model_schema
to find the dictionary table and its possible values (e.g., SOPORTES_MATERIALES
).query_value
to get its count (e.g., SELECT COUNT(*) FROM "SOPORTES" WHERE "MATERIAL" = 'STRIATED_ALUMINUM'
).show_diagram
.Scenario B: Comparing Different, Unrelated Values
Use this pattern when the user wants to compare distinct metrics.
query_value
for each metric (e.g., SELECT COUNT(*) FROM "SOPORTES"
for the first, and SELECT COUNT(*) FROM "PLACAS"
for the second).The key principle is to use query_value
as a building block to fetch the individual numbers required by the chart.
SUPPORTED DIAGRAM TYPES:
IMPORTANT RESTRICTIONS:
string
, required): The complete diagram definition in either Mermaid or PlantUML syntax.string
, required): A descriptive title for the diagram that will be displayed to the user.query_table
:
string
, required): The ID of the data model to query.string
, required): The SQL query to execute.string
, required): A descriptive name for the result returned by the query. This value will be used as the label or identifier for the data set obtained.array
of string
, optional): Optional list of placeholders to replace in the query.Algunas herramientas comparten parte de la descripción. Para ponérosla aquí, he hecho referencia a la herramienta descrita con anterioridad que tenía esas descripciones, pero es muy importante entender que eso lo he hecho de cara a clarificar y reducir esta documentación para ser leída por una persona. Para un LLM es más adecuado repetir en cada herramienta su descripción completa, y no ir referenciando a la documentación de otras herramientas.
Cada definición de herramienta debe ser un “manual de instrucciones” completo y autocontenido.
show_table
, tiene toda la información que necesita ahí mismo. Las reglas de SQL, el manejo de placeholders, las reglas de comportamiento, etc. El camino desde la intención del usuario hasta la generación de la llamada a la herramienta es directo y claro.show_table
, lee “las reglas son las mismas que en query_table
“. Ahora, el modelo debe realizar un paso mental adicional:
show_table
.query_table
.query_table
.show_table
y aplicar esas reglas, recordando la excepción del LIMIT de 2000 filas.Cada paso adicional en una cadena de razonamiento es un punto potencial de fallo. La aproximación referencial, aunque apropiada para una persona, introduce varios riesgos para el LLM:
Al repetir la información se elimina por completo esta carga cognitiva extra y estos puntos de fallo. La instrucción es explícita, inequívoca y no requiere que el modelo “salte” por el contexto para ensamblar las reglas.
Si bien es cierto que la repetición consume más tokens, el coste de una llamada fallida a la herramienta es mucho mayor.
Resumiendo, mantén las descripciones completas y explícitas en la definición de cada herramienta que expones al LLM.
Tener una buena descripción de las herramientas puede ser determinante a la hora de que el LLM pueda llevar a cabo las tareas que le pedimos o no. Incluso, puede hacer que modelos menos capaces puedan hacer cosas que sin ellas solo podríamos hacer con modelos más “potentes”. Evidentemente para tareas simples, puede no tener mucha relevancia; pero marca una diferencia crucial cuando lo que le pedimos se complica.
Por ejemplo. Vamos a suponer que tenemos a “Gemini CLI” conectado al servidor MCP de gvSIG Desktop, y le preguntamos:
Genera un diagrama de barras con los soportes por tipo de material.
Puede parecer una consulta “complicada” para un LLM, pero con las descripciones de herramientas que acabamos de ver, el LLM no improvisa; construye un plan de ejecución metódico que sería algo así:
El plan de acción:
get_application_context
que le proporciona el marco general de gvSIG Desktop.get_data_models
para listar los modelos de datos disponibles. El resultado le proporciona el data_model_id
necesario para todas las operaciones futuras.get_data_model_schema
y analizar el DDL. Al hacerlo descubre:
"SOPORTES"
."MATERIAL"
."MATERIAL"
y ve que sus valores no son de texto libre, sino que provienen de un diccionario de datos. Esto activa una regla de comportamiento específica.show_diagram
y lee la sección “DATA GATHERING FOR CHARTS”, específicamente el “Escenario A: Aggregating by Categories from a Dictionary”. Las instrucciones son explícitas:
"MATERIAL"
es un campo categorizado. Revisa el diccionario de datos asociado en el esquema y extrae la lista de posibles valores: ‘GALVANIZED_STEEL’, ‘PLASTIC’, ‘WOOD’, ‘STRIATED_ALUMINUM’.query_value
múltiples veces, una por cada categoría.show_diagram
con ese código y el título “Soportes por tipo de material” para mostrar el resultado al usuario.Es crucial entender que, aunque este plan parece una secuencia lineal, el paso de ‘Recopilación de Datos’ es en realidad un proceso iterativo de diálogo entre el LLM y el servidor. El modelo no obtiene todos los datos de una vez, sino que pregunta activamente por el recuento de cada categoría, una por una, ensamblando pacientemente el conjunto de datos final antes de poder generar el gráfico. Esta capacidad para ejecutar un plan de múltiples pasos es una consecuencia directa de tener instrucciones claras.
Aunque no es directo obtener el diagrama, gracias a las descripciones de las herramientas que tiene a su disposición, es capaz de elaborar un plan y seguirlo para conseguir lo que el usuario le ha solicitado. E incluso el modelo flash es capaz de seguir estas instrucciones.
Ahora bien, simplemente reduciendo algo las instrucciones, como por ejemplo eliminando la sección “DATA GATHERING FOR CHARTS” de la herramienta show_diagram
es suficiente para que el modelo ya no sea capaz de elaborar ese plan de ejecución, y tanto el flash como el pro dejan de ser capaces de responder a la pregunta del usuario. E incluso con esa sección ahí, si reducimos las instrucciones eliminando la sección “ABOUT SCHEMA RETRIEVAL” o simplemente el punto “1. Prefer JOIN operations over subqueries when possible” de “QUERY CONSTRUCTION RULES”, el modelo flash dejará de poder responder a la petición del usuario. El pro seguirá pudiendo responder aunque en ocasiones se liará y fallará igualmente.
La descripción de las herramientas es crítica, no solo las describe, sino que guía al LLM a la hora de usarlas, a veces con instrucciones como:
“If this data is not directly available, you must use the query_value
tool to gather it. This may involve calling query_value
multiple times, once for each data point needed for the chart, and then assembling the results into the final diagram code”
O
“For categorized fields, perform case-insensitive comparison by converting to uppercase”
Otras simplemente son una mejor descripción de lo que realiza la herramienta.
Dicho esto, es importante tener en cuenta que una cosa es describir bien una herramienta, y otra ser redundante a la hora de describirla. Hay que evitar ser redundante en las descripciones de las herramientas. Poner una frase que describa algo, y luego otra que vuelva a describir lo mismo de otra forma puede ser contraproducente, ya que puede llevar a errores de comprensión por parte del LLM.
Bueno, y hasta aquí con esta pequeña reflexión acerca de la importancia de las descripciones de nuestras herramientas.
Un saludo
Joaquín
From Reinders Tour de France “Globes in a 2nd hand book market in Lille, France. Not quite spectacular — but still.”
GeoSpatial Techno is a startup focused on geospatial information that is providing e-learning courses to enhance the knowledge of geospatial information users, students, and other startups. The main approach of this startup is providing quality, valid specialized training in the field of geospatial information.
( YouTube | LinkedIn | Facebook | X )
The WPS Request Builder is a demo page used to try out the Web Processing Service (WPS) used to execute geospatial processes for transformation, summary and analysis. This session provides a detailed overview of the various inputs and categories in the WPS Request Builder.
If you want to access the complete tutorial, click on the link.
In GeoServer, the WPS request builder enables users to perform various geospatial processing operations with different functionality to analyze and manipulate geospatial data. Each category provides a set of specific operations tailored to a range of geospatial tasks.
Note: Be sure to download the WPS extension that corresponds exactly to your GeoServer version—mismatched versions will result in errors.
Some categories available in the WPS request builder are JTS, Geo, GS, and Vec.
The built-in GS (for GeoServer) and Vec (for Vector) processes have direct access to the layers provided by GeoServer.
The JTS (from JTS Topology Suite library) and Geo (from GeoTools library) processes are provided by external libraries. If you are interested in making your own process there is a Process Tutorial for Java Developers.
First, we will introduce the inputs of the JTS and Geo processes, and then we will delve into the GS and Vec processes.
The JTS and Geo processes refer to different sets of processing functions that are specifically dedicated to handling geometries and performing geospatial operations.
From the Demo menu, navigate to the WPS Request Builder. This section contains several types of processes, which you can view in the Choose Process section. They accept three inputs for execution: Text, Reference, and Subprocess.
In Text mode, you can enter the data geometry information in one of the standard formats supported by WPS. These standard formats are:
The main differences between these MIME types are:
Overall, the choice between the two should depend on the intended use case: for human interaction, use text/xml; subtype=gml; for application-oriented needs, choose application/gml.
The application/wkt is a MIME type that represents data encoded in the Well-Known Text (WKT) format. WKT is a text-based format for representing and exchanging geospatial data, particularly geometric shapes and objects. It supports various geometric types, including: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon.
The application/wkt and application/ewkt formats in GeoServer WPS represent geometry; WKT defines shapes without CRS, suitable for basic 2D/3D geometry. EWKT adds an SRID, embedding CRS info in the geometry string for essential context.
Here is an example of the application/wkt format:
- POINT(48.23 11.56)
- LINESTRING(45.67 9.12, 50.45 12.34, 55.89 10.67)
- POLYGON((45.67 9.12, 50.45 12.34, 55.89 10.67, 45.67 9.12))
- MULTIPOINT((45.67 9.12), (50.45 12.34), (55.89 10.67))
- MULTILINESTRING((45.67 9.12, 50.45 12.34), (55.89 10.67, 45.67 9.12))
- MULTIPOLYGON(((45.67 9.12, 50.45 12.34, 55.89 10.67, 45.67 9.12)), ((60.12 8.34, 62.45 11.67, 65.89 10.01, 60.12 8.34)))
The application/json is a MIME type used to represent data encoded in GeoJSON format for encoding geographic data structures. It is based on the JSON format and allows the representation of simple geographic features along with their associated non-spatial attributes stored in the Properties object.
This MIME type is commonly used in Web mapping applications, GIS, and various other geospatial applications because it provides a standardized way to represent and exchange geographic data.
Here is an example of the application/json document:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.41, 37.78]
},
"properties": {
"name": "San Francisco",
"population": 883306,
"elevation": 16
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[
[-122.4194, 37.7749],
[-122.4244, 37.7749],
[-122.4244, 37.7799],
[-122.4194, 37.7799],
[-122.4194, 37.7749]
]]
},
"properties": {
"name": "San Francisco City Hall",
"type": "government"
}
}
]
}
The Reference mode for specifying input geometry involves linking to an external resource containing the necessary geometry data for processing. This mode is beneficial when the geometry data is stored in a separate file or service, allowing you to provide a reference instead of including the data directly in the WPS request.
To use this option, you can choose between the GET or POST method. The choice depends on the size and nature of the referenced data, as well as any security considerations.
Using the Subprocess mode for input geometry in a WPS request, allows for seamless chaining of multiple processes. It enables you to reference data from another process without writing intermediate results to disk, significantly enhancing workflow efficiency.
This approach is particularly beneficial when managing large datasets or executing multiple processing tasks rapidly, as it eliminates unnecessary handling steps and facilitates direct data transfer between interconnected processes.
Select Subprocess from the Process Inputs dropdown menu in the WPS Request Builder section. Then, click the Define/Edit link to open a new page where you can choose an additional process for chaining.
The result output refers to a spatial data layer, typically represented in a vector format such as GML, GeoJSON, or WKT. This output can be processed further, visualized, or utilized in various spatial analyses. When generating the WPS result geometry, you can choose from several standard spatial data formats, each described in detail.
These formats are:
Selecting the appropriate format allows you to tailor the output to suit your specific use case or workflow.
These processes are specifically designed to integrate seamlessly with GeoServer layers, thereby enhancing the utilization of geospatial data. The GS process includes various GeoServer-specific operations for interacting with and managing GeoServer resources, while the Vec process specializes in vector data processing, offering tools for analyzing and transforming vector geometries.
They accept four inputs for execution: Text, Reference, Subprocess, and Vector layers.
In this mode, you can use various standard formats supported by WPS. These formats are:
Using this format allows you to submit a collection of geometries directly from a WFS request to a WPS process in GeoServer. When you use a WFS-Collection as input, you reference a set of geometries that the WPS operation can manipulate directly.
Here’s an example of how to use a WFS collection 1.1 in a WPS request:
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns:feature="http://www.openplans.org/topp" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink">
<gml:boundedBy>
<gml:Envelope srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:lowerCorner>147.291 -42.851002</gml:lowerCorner>
<gml:upperCorner>147.291 -42.851002</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<gml:featureMember>
<feature:tasmania_cities gml:id="tasmania_cities.1">
<gml:boundedBy>
<gml:Envelope srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:lowerCorner>147.291 -42.851002</gml:lowerCorner>
<gml:upperCorner>147.291 -42.851002</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<feature:the_geom>
<gml:Point srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:pos>147.291 -42.851002</gml:pos>
</gml:Point>
</feature:the_geom>
<feature:CITY_NAME>Hobart</feature:CITY_NAME>
<feature:ADMIN_NAME>Tasmania</feature:ADMIN_NAME>
<feature:CNTRY_NAME>Australia</feature:CNTRY_NAME>
<feature:STATUS>Provincial capital</feature:STATUS>
<feature:POP_CLASS>100,000 to 250,000</feature:POP_CLASS>
</feature:tasmania_cities>
</gml:featureMember>
</wfs:FeatureCollection>
It is a MIME type used for representing geospatial data in the Keyhole Markup Language (KML) format which primarily associated with Google Earth and various mapping applications. KML enables the encoding of diverse geographic features, such as points, lines, and polygons, along with their associated attributes.
Here’s an example of how to use an application/vnd.google-earth.kml+xml mime type in a WPS request:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:ns2="http://www.google.com/kml/ext/2.2" xmlns:ns3="http://www.w3.org/2005/Atom" xmlns:ns4="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
<Document>
<Schema name="poi" id="poi">
<SimpleField type="string" name="NAME"/>
</Schema>
<Folder>
<name>poi</name>
<Placemark id="poi.1">
<ExtendedData>
<SchemaData schemaUrl="#poi">
<SimpleData name="NAME">museam</SimpleData>
</SchemaData>
</ExtendedData>
<Point>
<coordinates>-74.01046109936333,40.707587626256554</coordinates>
</Point>
</Placemark>
<Placemark id="poi.2">
<ExtendedData>
<SchemaData schemaUrl="#poi">
<SimpleData name="NAME">stock</SimpleData>
</SchemaData>
</ExtendedData>
<Point>
<coordinates>-74.0108375113659,40.70754683896324</coordinates>
</Point>
</Placemark>
<Placemark id="poi.3">
<ExtendedData>
<SchemaData schemaUrl="#poi">
<SimpleData name="NAME">art</SimpleData>
</SchemaData>
</ExtendedData>
<Point>
<coordinates>-74.01053023879955,40.70938711687079</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
This mode in GeoServer allows users to utilize predefined geographical data for advanced spatial analyses, including overlay analysis, buffering, and spatial querying. This access to well-organized data, such as points, lines, and polygons, significantly enhances analytical capabilities compared to relying solely on JTS or Geo processes.
By integrating vector layers into the WPS request builder, users can perform sophisticated geospatial analyses, enabling deeper insights from their datasets and making GeoServer a preferred choice for complex spatial processing tasks.
The result output typically provides a spatial data layer in various vector formats, including GML, GeoJSON, CSV, and Shapefile. This output can be further processed, visualized, or used in other spatial analyses, making it highly versatile for different applications.
When generating geometry, you can choose the result in a variety of standard data formats, including:
This flexibility allows you to choose the most appropriate format for your specific use case or workflow, ensuring compatibility with your analysis tools and visualization platforms. By offering these multiple output formats, GeoServer effectively supports a wide range of geoprocessing needs, facilitating seamless integration and analysis of spatial data.
In this session, we discussed the types of different categories and various inputs in the WPS Request Builder. To access the full tutorial, click on this link.
Reference:
Another one from Reinder. “A fromagerie where they present cheese on a ‘France-shaped’ wooden-and-straw kind of plateau… Avec plaisir, au revoir,
Reinder spotted this in Amiens
Vom 17.-20.09.2025 hat der Junge Kongress für Geographie (JKG) in Leipzig stattgefunden. Mit circa 350 Teilnehmenden vor allem aus der Geographie war die studentisch organisierte Veranstaltung ein großer Erfolg.
Unter dem Motto “creative. critical. changing. – Junge Perspektiven auf die Geographie” bot die Veranstaltung ein vielfältiges, inspirierendes und interaktives Programm. Im Fokus standen insbesondere kreative Ansätze, kritische Sichtweisen und innovative Ideen.
Die Keynote zur Eröffnung beschäftigte sich mit studentischem Mut und kreativer Wut. Aus dem Feld der kritischen und feministischen Geographie wurden Begriffe diskutiert und wegweisende Zitate benannt. Kritik wurde mit “ENT-unterwerfung” untermalt, Creativ steht für einfallsreich und neuartig und Changing eröffnet einen Spannungsraum, in dem Veränderungen und Fortschritt gestaltet werden können. Die Referent:innen luden ein, sich von Einfachheit und Methoden zu verabschieden, tief zu denken und kollektiv zu hinterfragen, sie stellten traditionelle Denktraditionen in Frage und bekamen vielminütigen Applaus.
Am Donnerstag und Freitag bot das Programm zahlreiche Sessions sowie auch Exkursionen.
Eine Session wurde vom FOSSGIS e.V. unter dem Titel “Wir spielen mit offenen Karten” angeboten. Jochen Topf stellte den FOSSGIS e.V. und OpenStreetMap vor. Die wichtigste Botschaft war, dass OSM mehr als eine Karte ist. Die Teilnehmenden waren begeistert vom einfachen Prinzip der “on the ground Guideline” und den vielfältigen Möglichkeiten von Nutzung und Beteiligung im Nebeneinander von Hobbyisten, Firmen, Forschenden, zivilengesellschaftlichen und staatlichen Akteuren. Die Session war für die Studierenden spannend, sie stellten viele Fragen vom technischen Hintergrund über Handhabung in einzelnen Ländern bis hin zum Perfektionsgrad. Zitat Jochen: “OSM muss nicht perfekt sein, die Crowd bringt es gemeinsam an die Perfektion”. Im Raum entstand das Bedürfnis, Argumente zu sammeln, warum OSM gut ist - das war nicht schwer, ein Großteil kam aus der teilnehmenden Runde: OSM ist sehr aktuell, hält sich an den Datenschutz, sehr nützlich für alles was ÖPNV betrifft, z.B. Barrierefreiheit, eine selbstermächtigte Community handelt, Daten können selbst eingetragen werden.
Eine weitere Session mit dem Titel “Ungleichheiten und Bias in OpenStreetMap” wurde von Benjamin Herfort (HeiGIT) angeboten. In dieser Session präsentierten zwei Studierende ihre Forschungsergebnisse. Es ging weniger um technische Fragen sondern um soziale Auswirkungen und Verzerrungen, die Wissenschaft und Technologie mit ihren Anwendungen innewohnen, seien es Machtverhältnisse oder die Beteiligung von bestimmten Gruppen.
Im Beitrag “Barrieren und Motivation in OpenStreetmap aus Genderperspektive” blickte Ines Ghassouli auf die Geschlechtsungleichverteilung in OSM, beschäftigte sich mit genderspezifischen Motiven für Engagement und brachte Ideen für Umgangsstrategien mit. Als Methode wurden Expert:inneninterviews gewählt, die sich mit verschiedenen Beitragenden aus ganz verschiedenen Teilen der Welt führte.
Sie verglich Motivatoren für Engagement und betrachtete genderspezifische Barrieren. Das Bedürfnis zu helfen, zu lernen, sich weiter zu bilden und zu netzwerken ist bei allen stark vertreten. Als Motivatoren für das männliche Geschlecht kommen technische Faszination und Wettbewerb hinzu.
Barrieren für Engagement können negative Kommentare, fehlende technische Ressourcen sowie Zeitmanagement sein, als genderspezifische Barrieren zeigen sich kulturelle Barrieren, der Gender-Gap in Mint-Fächern sowie auch Belästigungen.
Ines empfielt eine Sensibilisierung für dieses Thema sowie frauenfördernde Initiativen (Mentoringprogramme, Etablierung von Woman-Only-Netzwerken).
In einem weiteren Beitrag beschäftigte sich Lilly mit “Corporate Mapping in OpenStreetMap – global evolution and small-scale effects”. Dabei wertet sie Aktivitäten von globalen Unternehmen in Form von Corporate Edits (zwischen 2019 und 2023) bei OSM aus.
Viele Teilenehmende nutzten die Gelegenheit beim Markt der Möglichkeiten mit Akteuren der geographischen Praxis in Kontakt und ins Gespräch zu kommen. Am FOSSGIS-Stand war viel los, Sylvia, Jochen, Johannes, Benjamin und Katja widmeten sich dem großem Interesse und vielen Fragen der Teilnehmenden zum FOSSGIS e.V., zur FOSSGIS-Konferenz, zu OpenStreetMap und Open-Source-Softwarelösungen. Auch bei dieser Zielgruppe erwies sich die OSGeoLive als sehr brauchbare Unterstützung die OSS-Tools kennenzulernen und auszuprobieren.
Beeindruckend war die unglaubliche Power der jungen Menschen verbunden mit großem Optimismus in der Welt etwas zu verändern - dies zog sich spürbar durch die gesamte Veranstaltung. Das Outreachteam des JKG veröffentlicht zahlreichen Aktivitäten bei Instagram: https://www.instagram.com/jkg.2025/.
Der FOSSGIS-Stand beim Jungen Kongress für Geographie (JKG) war immer gut besucht.
Reinder has been visiting France and has sent a few maps in the wild which I will post over the next few days.
“The Jules Verne museum in Amiens, France. On the floor is a giant reproduction of the map that Verne used, while composing his most famous novel: ‘Around the world in 80 days’ (first published in 1873). Quite fascinating indeed. “
I love a floor map.
La transformación digital de las administraciones locales ya no es una opción, sino una necesidad. Los municipios se enfrentan a retos cada vez más complejos: desde la gestión de servicios básicos (agua, alumbrado, recogida de residuos) hasta la planificación urbanística, el control medioambiental o la atención al ciudadano. En este contexto, disponer de una herramienta que integre toda la información espacial de manera sencilla y accesible es clave.
gvSIG Online se ha convertido en una plataforma estratégica para muchos ayuntamientos que quieren dar el salto hacia una gestión urbana más eficiente, transparente y participativa.
Adoptar gvSIG Online significa avanzar hacia el concepto de “ayuntamiento digital”, donde la información fluye de manera eficiente entre departamentos, se optimizan los procesos internos y se ofrece a la ciudadanía un acceso más sencillo y transparente a los servicios.
Con soluciones basadas en software libre e interoperable, los municipios no solo reducen costes, sino que aseguran la soberanía tecnológica, evitando depender de proveedores cerrados y potenciando la innovación local, la colaboración y la reutilización.
The digital transformation of local administrations is no longer an option but a necessity. Municipalities face increasingly complex challenges: from managing basic services (water, street lighting, waste collection) to urban planning, environmental monitoring, and citizen services. In this context, having a tool that integrates all spatial information in a simple and accessible way is essential.
gvSIG Online has become a strategic platform for many municipalities aiming to move towards more efficient, transparent, and participatory urban management.
Adopting gvSIG Online means moving towards the concept of a “digital municipality”, where information flows efficiently across departments, internal processes are optimized, and citizens are offered simpler and more transparent access to services.
With solutions based on free and interoperable software, municipalities not only reduce costs but also ensure technological sovereignty, avoiding dependency on closed vendors and fostering local innovation, collaboration, and reuse.
Hola a todos,
Si habéis estado siguiendo esta serie de artículos, ya conocéis el qué y el porqué. El viaje desde un chat simple en gvSIG desktop hasta un asistente contextual inteligente gracias al protocolo MCP. Pero hoy quiero hablaros del cómo. Y no me refiero a las librerías o el código, sino a algo más fundamental, la forma en que trabajé para hacerlo realidad.
La respuesta es simple, aunque no simplona: no lo hice solo. Pero mi colaboración con la IA no empezó con un plan de proyecto, sino con una historia de descubrimiento que lo cambió todo.
A principios de año, los LLMs eran para mí un juguete fascinante, pero totalmente desconectado de mi trabajo diario. La curiosidad me asaltó con la llegada de modelos más avanzados, y mi primer proyecto “serio” (por decir algo) con ellos no tuvo nada que ver con gvSIG desktop. Fue un experimento narrativo personal. Durante un par de fines de semana intenté usar la IA para continuar la historia del anime a partir de sus documentos originales.
El proceso fue un curso intensivo y práctico. Descubrí que la IA era increíblemente potente para analizar documentos, estructurar información (generando fichas de personajes) y co-crear contenido. También descubrí sus límites cuando la parte visual no funcionó. Aunque el experimento no cumplió su objetivo, el aprendizaje fue inmenso. Había descubierto una dinámica de trabajo, un diálogo de prueba, refinamiento y corrección.
Y en un momento dado llegó la pregunta. Si puede hacer todo esto con un texto de ficción ¿qué no podría hacer con una base de datos dentro de gvSIG desktop?”.
Con esa idea en mente, mi primer impulso fue buscar un camino estructurado. Decidí que, para “ir más rápido”, lo mejor sería buscar formación. Revisé plataformas, analicé temarios y me encontré con una realidad frustrante. Los cursos, o se centraban en una “ingeniería de prompts” demasiado básica,
o proponían proyectos de juguete, como implementar una tienda online o una app de tareas pendientes, que me recordaban a aquellos ejercicios académicos que todos hacíamos en las practicas. Reconozco que para un programador junior pueden ser un buen punto de partida, pero para mí, me parecían demasido simples, y no abordaban la complejidad de integrar IA en aplicaciones reales, o como usarla para ayudarme en trabajos de mas embergadura.
Pero también una revelación. Si los cursos no me daban la solución, tendría que encontrarla yo mismo, como tantas otras veces. Y el método ya lo había descubierto: la solución no estaba en un temario, sino en la experimentación directa.
Decidí que mi herramienta de aprendizaje sería la propia IA, aplicando la misma metodología de diálogo que había descubierto en mi proyecto personal.
Así que, con esa decisión tomada, empecé a aplicar esta nueva forma de trabajar al prototipo de gvSIG que os conté en el primer artículo. En lugar de sumergirme en la documentación de la API de Gemini, mi primera acción fue abrir un chat y empezar a conversar, aplicando el mismo principio de diálogo que tan bien me había funcionado.
Esa forma de trabajar se convirtió en el pilar de todo el proyecto. Como habéis leído, el camino desde aquel prototipo hasta la solución final fue largo: implicó una reescritura completa a Java y chocar de frente contra el muro de los costes de las APIs. Sin embargo, lo que no cambió en todo ese viaje fue la dinámica de usar la IA como un compañero de charlas técnicas para validar ideas.
El ejemplo más claro de esta colaboración llegó mucho más tarde, cuando tuve que abordar la implementación del servidor MCP. Después de pedirle que analizara por un lado la especificación del protocolo y por otro mi propia librería para crear servidores HTTP, llegó el momento clave de la validación.
(Nota: Los diálogos que veréis son recreaciones didácticas de nuestras conversaciones. Para mayor claridad, he condensado y sintetizado el flujo real, eliminando pasos intermedios (como las peticiones explícitas para leer ficheros con wget o analizar directorios) y fusionando varias interacciones técnicas en un único ejemplo representativo. El objetivo es ilustrar el método de trabajo, no transcribir literalmente el log.)
Yo: “Oye, he leído esto sobre cómo funcionan los LLMs, ¿lo he entendido bien?”
IA: “[…] un servidor MCP (Model Context Protocol) es una aplicación que expone herramientas y recursos a Gemini CLI…”
Yo: “Por lo que he entendido, en el documento habla de como configurar un cliente de MCP en gemini cli ¿correcto?”
IA: “Correcto. El documento detalla cómo configurar Gemini CLI para que se conecte y utilice servidores MCP…”
Aquí fue donde descubrí el verdadero potencial. No se trataba sólo de que me diera código. Se trataba de que validara mis ideas. Diseñaba una versión inicial de un prompt para el system prompt y se lo pasaba:
“¿Crees que esto es claro? ¿Le faltará algo al modelo para entenderlo?”.
La IA se convirtió, desde el minuto uno, en mi primer revisor de diseño. Juntos, iteramos hasta dar con los prompts robustos y precisos que necesitaba el prototipo.
Fue una fase de aprendizaje acelerado y co-creación. No era yo programando con una herramienta, éramos dos dando forma a una idea.
Cuando decidí dar el salto a Java, que conté en el segundo artículo, no tuve que aprender a colaborar de nuevo. Sólo tenía que aplicar la misma fórmula a una escala mayor. Es de esta fase más compleja, la de la reescritura a Java y la posterior implementación del servidor MCP, de donde provienen la mayoría de los diálogos que se muestran, ya que lamentablemente no conservé registros de las conversaciones iniciales del prototipo.
El flujo ya estaba claro y se había convertido en un bucle natural:
Yo: “Necesito una clase que formatee un Iterator de claves primarias en una String para cláusulas SQL IN. Debe manejarse el truncamiento si la lista es muy larga. ¿Puedes generarla?”
IA: “Claro. Te propongo una clase con un método estáticoformat()
que reciba el Iterator y un límite máximo. Devolverá una cadena con el formato ‘101’, ‘102’, ‘105’.”
Yo: “Vale, pero si la lista está vacía, que devuelva ‘(NULL)’ para evitar errores en el SQL. ¿Puedes ajustarlo?”Tras un par de iteraciones como esta, y de comprobar que compilaba, la clase estaba lista.
Este ciclo Diseño -> Validación -> Implementación -> Revisión se repetía constantemente. No era una línea recta, era una espiral donde cada vuelta nos acercaba más a un código sólido y funcional. La velocidad era asombrosa porque los posibles errores se atrapaban en las fases de diseño y validación, no al final del proceso.
Llegados al punto que relaté en el cuarto artículo, con el muro de los costes derribado por gemini-cli
y el protocolo MCP, la forma de trabajar ya la había adoptado como natural. No empecé pidiendo código, sino estableciendo el contexto y la dirección:
Yo: ‘Vamos a implementar el servidor MCP. Para ello, primero necesito que entiendas a fondo dos cosas: la especificación del protocolo, que te he proporcionado antes, y mi propia librería para crear servidores HTTP. ¿Puedes analizar las clases en esta carpeta y explicarme cómo encajarían ambas piezas?’
IA: ‘Entendido. He analizado tu librería. La arquitectura basada en
Command
yCommandFactory
es una base excelente para implementar los endpointstools/list
ytools/call
que requiere el protocolo MCP…’
A partir de ese punto de partida, el proceso para implementar cada pieza, que ya era familiar, fue idéntico:
show_table
o get_viewport
?”.IA: “Los comandos que faltarían por implementar para dar un soporte más completo son:
context/get
,context/set
…”Yo: “No he encontrado ninguna referencia a comandos genéricos tipo ‘context/get’.”
IA: “Tienes toda la razón. Mis disculpas por la confusión. He re-leído la especificación y mi afirmación anterior fue una interpretación incorrecta.”
Y este no fue un caso único. A lo largo de esa misma sesión de diseño, la IA cometió errores conceptuales similares en repetidas ocasiones. Por ejemplo, afirmó con seguridad la existencia de una sección llamada “Standard Tools” en la documentación que, tras mi insistencia y una doble verificación, resultó no existir. En otra ocasión, malinterpretó la relevancia de una convención de nomenclatura hasta que se le guio explícitamente.
Este patrón de errores es la prueba más clara de la tesis de este artículo: la IA es un compañero para la exploración de ideas y un generador de primeros borradores increíblemente rápido, pero no es una fuente de verdad absoluta. La supervisión, el escepticismo y el conocimiento del dominio por parte del desarrollador no son opcionales, son el núcleo del proceso.
La inversión inicial en Java puro y bien estructurado demostró su valor aquí. Pude reutilizar lógica de negocio ya probada y concentrarme en adaptarla al estándar MCP, con la IA acelerando la parte tediosa. Fue la culminación de todo el trabajo previo.
Quiero ser muy claro: esto no es magia. Es colaboración, y como tal, requiere esfuerzo y criterio.
Esta no es “la metodología correcta”. Es la forma que yo encontré para colaborar de forma efectiva con una nueva herramienta. Os la cuento no para que la copiéis, sino para que experimentéis y encontréis la vuestra.
El futuro del desarrollo no consiste en que la IA nos reemplace. Consiste en que nosotros, los desarrolladores, aprendamos a dirigirla, a colaborar con ella y a amplificar nuestra capacidad para crear cosas mejores, más rápido.
Un saludo
Y como apunte final, el propio proceso de dar forma a estas reflexiones ha sido, a su vez, un ejercicio de colaboración. Cada idea ha sido expuesta, validada y refinada a través del diálogo, en un bucle de feedback que ha pulido no solo el código del proyecto, sino también la historia que lo cuenta.
Reinder shared this – “This is an advertisement for a kind of party / festivity, for new students to make them feel comfortable, organised by the Humanities Faculty of the University of Amsterdam. To draw the attention, they created this kind of heart shaped image, that consists of [parts of] maps of Amsterdam
El número de incendios no ha parado de crecer en muchas regiones del mundo. Entre las causas más comunes están las altas temperaturas, las sequías prolongadas o el abandono de las áreas rurales, pero una causa no menos importante son las quemas incontroladas. Para ello, es importante disponer de un Plan de Quemas, ya sea a nivel local, regional o nacional, en el que se regulen y planifiquen las quemas en el territorio como prevención a posibles incendios.
Estos planes de quemas incluirían toda la normativa respecto a zonas, horarios, permisos o características de la quema a realizar.
Para facilitar la información a los ciudadanos, aparte del documento de texto con toda la normativa es importante poder consultar a través de geoportales la cartografía catastral y las zonas en las que se puede quemar según los periodos, basándose normalmente en áreas de influencia de zonas forestales y urbanas. De esta forma, el ciudadano accede directamente al visor, localizando su parcela, y comprueba si puede quemar en dicho periodo y a qué hora puede hacerlo. En muchos casos incluso, puede tener acceso a la descarga de la normativa completa desde el mismo geoportal, y de la declaración responsable en caso de que haya que rellenarla, incluyendo un enlace a la sede electrónica donde habría que presentarla.
En la siguiente imagen se muestra un ejemplo real de un municipio con su Plan Local de Quemas creado con gvSIG Online, todo con software libre, en el que se incluye la información antes mencionada:
Si deseas más información sobre cómo implementar gvSIG Online en una administración e incluir un geoportal con el Plan de Quemas, escribe a info@gvsig.com
El pasado 5 de junio tuvo lugar en Valencia la Jornada de Infraestructuras de Datos Espaciales en la Administración Local 2025, un encuentro dirigido a ayuntamientos y administraciones locales interesadas en aprovechar el potencial de las Tecnologías Libres de Información Geográfica (TIG libres) para mejorar la gestión pública.
Durante la jornada se presentaron casos de uso reales de la Suite gvSIG implantados en distintos municipios, mostrando aplicaciones concretas en ámbitos como la integración con gestores de expedientes, urbanismo, cementerios y otros servicios municipales.
También se dieron a conocer algunas de las últimas novedades de gvSIG Online, entre ellas la integración con Inteligencia Artificial, que abre nuevas posibilidades para el análisis y la gestión de datos espaciales.
Compartimos la grabación completa del evento, para todas aquellas entidades locales que no pudieron asistir y que han mostrado su interés en los resultados de la jornada:
+ información: info@gvsig.com
We were having a geographical conversation over dinner with friends and Toby drew this map from the remains of pimentos padron and olive pips. Can you work out where the map is illustrating?
We were drinking this wine on a family holiday in Ibiza when my son spotted the celestial map on the label.
En el artículo anterior, lo dejé justo en el momento de la revelación: la conexión inesperada entre una herramienta de línea de comandos, gemini-cli
, y un protocolo llamado MCP era la respuesta al problema de distribución que casi acaba con el proyecto. Hoy, no vamos a revivir esa búsqueda, sino a remangarnos para construir la solución. Os mostraré en detalle qué son estas piezas y cómo, apoyándome en todo el trabajo previo, encajaron para dar vida a una solución robusta y, por fin, distribuible.
La solución no vino de una única tecnología mágica, sino de la perfecta simbiosis de dos componentes clave que resolvieron, cada uno, una parte fundamental del problema.
gemini-cli
: El puente inteligente
Al principio, gemini-cli
era para mí una simple herramienta de productividad. Sin embargo, resultó ser la pieza angular de la solución por dos motivos cruciales:
gemini-cli
actuaría como un proxy local inteligente: por un lado, se comunicaría con la potente API de Gemini en la nube, gestionando la autenticación y los costes; por el otro, hablaría un lenguaje estándar y limpio (MCP) con mi aplicación local.MCP, el lenguaje común
Si gemini-cli
era el puente, el Model Context Protocol (MCP) eran los planos de construcción. Para un desarrollador, su belleza radica en su simplicidad. Es un estándar abierto que define cómo un cliente de IA (como gemini-cli
) puede descubrir y utilizar un conjunto de herramientas locales (como las que viven dentro de gvSIG desktop).
Técnicamente, MCP es un protocolo basado en JSON-RPC. La implementación de referencia de gemini-cli se comunica a través de la entrada y salida estándar (STDIO), lo que permite lanzar una herramienta como un subproceso. Sin embargo, gemini-cli también soporta la conexión a un servidor MCP a través de un endpoint HTTP.
Para una aplicación de escritorio como gvSIG, que ya está en ejecución y no es lanzada desde la terminal, el enfoque HTTP era mucho más lógico y desacoplado. Me permitía levantar un servidor ligero dentro de la propia aplicación, un patrón que ya había utilizado en el pasado. Así, en lugar de lidiar con subprocesos y STDIO, la comunicación se establecía con una simple petición de red local, algo robusto y fácil de depurar.
El protocolo se basa en tres comandos principales: initialize
(para establecer la conexión), tools/list
(para que mi servidor anuncie sus herramientas) y tools/call
(para que gemini-cli
pida ejecutar una de ellas).
El primer paso es indicarle a gemini-cli
que, además de hablar con la API de Google, debe buscar herramientas en un servidor local. Esto se hace añadiendo un bloque de configuración en su fichero settings.json
.
La configuración es tan simple como esto:
{
"mcpServers": {
"gvSIG_desktop": {
"httpUrl": "http://127.0.0.1:8091/tools",
"timeout": 600000,
"trust": true
}
}
}
Una vez guardado el fichero, podemos verificar que gemini-cli
ha establecido la conexión correctamente. Al arrancar la herramienta, podemos usar el comando interno /mcp
para listar los servidores MCP a los que está conectado y las herramientas a las que tiene acceso. El resultado confirma que todo está en orden.
_Tras configurar el settings.json
, el comando /mcp
nos confirma que gemini-cli
ha detectado y se ha conectado con éxito a nuestro servidor gvSIG_desktop
_.
Gracias a la decisión de reescribir todo en Java puro que os conté en el segundo artículo, tenía una base de código robusta y modular, lista para la acción. Implementar el servidor MCP fue sorprendentemente rápido, porque me di cuenta de que, sin saberlo, ya había construido una versión “artesanal” del mismo concepto.
De un conjunto de herramientas propio a un estándar abierto
Mi framework de “procesadores” del prototipo Java era, en esencia, una implementación privada de la misma idea que MCP estandarizaba. Solo tenía que traducir mis definiciones de herramientas al formato oficial.
Por ejemplo, así definía la herramienta para mostrar tablas en el prototipo original de Jython, dentro del fichero sql_processor.py, como un simple texto de ejemplo en el system prompt:
# ANTES: La herramienta se "programaba" en el prompt
u"""
== Consultas de tipo 'sql' ==
Utilizaras este tipo de respuesta para cualquier consulta que involucre la creacion de una consulta SQL...
Debe incluir un campo 'sql' con la sentencia SQL...
Ejemplo:
{
"type": "sql",
"sql": "SELECT ...",
"title": "Empleados por departamento",
"esValorEscalar": false
}
"""
Con MCP, la misma herramienta se define ahora en ShowTableCommandFactory.java
con un esquema JSON formal y preciso. Pasamos de la ambigüedad de un ejemplo a la rigidez de un contrato de API:
private static final JsonObject TOOL_INPUT_SCHEMA = Json.createObjectBuilder()
.add("type", "object")
.add("properties", Json.createObjectBuilder()
.add("query", Json.createObjectBuilder()
.add("type", "string")
.add("description", "The SQL query to execute.")
.build())
.add("title", Json.createObjectBuilder()
.add("type", "string")
.add("description", "A descriptive name for the result...")
.build())
)
.add("required", Json.createArrayBuilder().add("query").add("title"))
.build();
Pasamos de la ambigüedad de pedirle a un LLM que siguiera un ejemplo en texto, a la precisión de ofrecerle un esquema formal. El LLM ya no adivina; pregunta y cumple.
El gran payoff: reutilización máxima del código Java
Y aquí es donde la decisión estratégica que conté en el segundo artículo —abandonar el prototipo en Jython para reescribir todo en Java puro— se reveló como la mejor inversión de tiempo del proyecto.
Toda la lógica de negocio para ejecutar las consultas (conectar a la base de datos, procesar los placeholders, ejecutar el SQL y manejar el resultado) ya estaba encapsulada y probada en mi prototipo de asistente de chat impulsado por IA en java.
Al construir el servidor MCP, la implementación de una herramienta como show_table fue trivial. El nuevo comando simplemente actúa como un orquestador que delega toda la lógica de negocio en las clases que ya habíamos desarrollado y depurado semanas antes.
El flujo es un ejemplo claro del patrón “Adaptador”. Así es como se ve el “pegamento” que une el mundo MCP con la lógica original:
// Fichero: .../commands/tools/ToolsCommand.java
private Object tools_call(JsonObject params) throws Exception {
String toolName = params.getString("name"); // ej: "show_table"
JsonObject toolArguments = params.getJsonObject("arguments");
// Busca el comando registrado con ese nombre
MCPCommand targetCommand = (MCPCommand) this.getServer().getCommand(toolName);
// Invoca la lógica del comando específico
return mcpTargetCommand.call(toolArguments);
}
// El comando MCP se convierte en un simple orquestador que
// invoca la lógica de ejecución que ya habíamos desarrollado.
// (Fragmento simplificado de ShowTableCommand.java)
@Override
public Object call(JsonObject params) throws Exception {
// ... extraer parámetros del JSON ...
String query = params.getString("query");
String modelid = params.getString("data_model_id");
String title = params.getString("title");
try {
// ...y los usa para instanciar y ejecutar la misma lógica
// que ya habíamos desarrollado en el chat de Java. ShowTableAction action = new ShowTableAction(
applicationServices, modelid, title, query, placeholders
);
action.actionPerformed(null); // Se ejecuta la lógica reutilizada
return this.createResponseContents("Se han presentado los datos al usuario");
} catch (Exception ex) {
return this.createErrorResponseContents(ex.getMessage());
}
}
Como se puede ver, no tuve que reescribir la lógica para conectar a la base de datos, procesar placeholders o mostrar la tabla. El nuevo servidor MCP era una capa delgada que se apoyaba sobre los cimientos sólidos que ya había construido. La inversión en una base de código bien estructurada me permitió adoptar el estándar MCP en cuestión de días, no de semanas.
_El trabajo previo dando sus frutos. La imagen captura el flujo completo: una pregunta en lenguaje natural en gemini-cli (arriba), el razonamiento de la IA que culmina en la llamada a la herramienta showtable (abajo), y la aparición del resultado final directamente en una ventana de gvSIG.
He manipulado la imagen de la consola, eliminando texto para que se pueda ver el razonamiento completo en la captura de pantalla.
Con el servidor MCP implementado, el flujo para un usuario final se volvió elegante y simple.
Diagrama de bloques mostrando el flujo entre el usuario, gemini CLI y gvSIG desktop
La experiencia de usuario final ahora consiste en:
gemini-cli
(un simple comando).La solución final en acción. Una petición compleja en lenguaje natural se traduce en un diagrama ERD generado y visualizado directamente en la aplicación. Potente, contextual y, por fin, accesible.
Este viaje, lleno de frustraciones y descubrimientos, me enseñó lecciones muy valiosas que van más allá del código:
Espero que esta serie de artículos os haya resultado útil, no solo como un tutorial técnico, sino como el relato real de un viaje de desarrollo.
¿Y vosotros? ¿Habéis enfrentado problemas de distribución o costes con vuestras herramientas? ¿Cómo los resolvisteis?
>
P.D.: El mundo de la IA no se detiene. Justo cuando terminaba de escribir esta serie de articulos, ha surgido una nueva plataforma que podría cambiar las reglas del juego en cuanto a los costes, permitiéndonos retomar la visión original de un asistente totalmente integrado en gvSIG desktop. Pero esa… es una historia, que si se materializa, será para otro día.
I love those paper maps that you get from hotel receptions when you all for directions. This one comes from the stylish retro Hotel Mongibello in Ibiza. Perfect for planning a day’s exploring.
Another one from Anna Barca’s visit to Broken Hill. Imagine a gaol with stained glass windows and a global projection (bonus points for correctly identifying the projection).
For more info see https://brokenhillhistoricalsociety.com/our-museums/silverton-gaol-museum/
GeoServer 2.28-M0 release is now available with downloads (bin, war, windows), along with docs, extensions, and data directory.
This is a milestone release previewing the GeoServer 2.28.x series to let everyone try out our new ImageN raster processing engine.
This release is made as part of the GeoServer 3 “Milestone 1” activity. It is made in conjunction with ImageN 0.4.0, ImageIO-Ext 2.0.0-M0, GeoTools 34-M0, mapfish-print-v2 2.4-M0, and GeoWebCache 1.28-M0.
Thanks to Jody Garnett (GeoCat) and Ian Turton for making this release.
Milestone releases are a chance to share what we have been working on, and ask you to try it with your own data:
A new Eclipse ImageN (pronounced “imagine”) processing engine.
This project combining Java Advanced Imaging (donated by Oracle) and JAI-Ext (donated by GeoSolutions) into a single image processing engine optmized for a modern Java environment.
Speaking of modern Java Environment GeoServer now requires Java 17 minimum. Java 11 is no longer supported. GeoServer is testing with Long Term Support releases: Java 17 LTS and Java 21 LTS.
Lots of build improvements with the highlight being a bill-of-materials “geotools” pom.xml file to share managing versions across GeoTools, GeoWebCache and GeoServer
A new community module gs-sec-oidc-plugin under active development.
This plugin will be taking over the responsibilities of gs-oauth2 plugins as they are being retired for GeoServer 3.
This is a milestone release so we welcome your feedback, we already know of a couple of things:
javadocs download is empty
This is due to changing to JDK 17, and a large number of javadoc warrnings we now need to resolve.
GeoServer 2.28-M0 artifacts were not published to repo.osgeo.org
Release notes: ( 2.28-M0 )
I helped to make a Geobase blueprint application of mapping and analysing taxis, https://github.com/decision-labs/geobase-blueprint-taxi-analysis and also narrated the video:
Geobase, a serverless geospatial platform has a vector tile server, database functions, PostGIS, H3 and the MobilityDB extensions (amongst much more!) built in, and this quickstart blueprint uses all of them. On the front end we are using deck.gl and maplibre and typescript and react.
The application shows animated trails representing taxi trips in Porto, Portugal:
In the above animation you can see pulsing blue circles. These are where 2 taxis have passed close by next to each other within 10 metres. The point is actually the shortest distance between the two trips, where the taxis got the closest. Often it’s passing by on the street, and starting off by taxi ranks or dropping off in the same locations.
MobilityDB was mostly used, to represent the taxi trips as lines-with-time, in the vector tileserver function to serve these temporally aware lines, in the outlier detection and cleaning steps and in the close pass analysis steps.
The outlier detection step identifies and removes parts of the trip with impossible speeds. In the following image, the blue and red lines are the taxi trips, but the blue ones have many very straight and very long segments. These will have very high speeds. The red lines is the cleaned dataset
I’m impressed with MobilityDB, in the next image, the green polygon is a h3 hexagon. The purple line is one taxi trip, the light blue is the trip clipped to the hexagon, and the dark blue is the trip within the hexagon and clipped to a particular time frame.
Moreover, because Geobase is also PostGIS in the cloud, we can connect to it in QGIS, and here are the query layers in QGIS
The line is clipped to the timespan:
{[POINT(-965739.7745940761 5036826.935711992)@2013-07-01 09:27:07+00, POINT(-966081.4141113205 5036898.801939623)@2013-07-01 09:27:22+00, POINT(-966272.7055242998 5036942.099465625)@2013-07-01 09:27:30+00]}
The processing is mostly performed with PostGIS. For example, to identify trips with outlier periods:
whenTrue(speed(temporal_geom) #> 55) AS high_speed_periods
And then to remove these “high_speed_periods” from the trips:
WHEN high_speed_periods IS NOT NULL THEN
minusTime(temporal_geom, spanset(span(high_speed_periods)))
ELSE
temporal_geom
I hope you enjoy the video, I used OBS for the screen recording which gave me more control over it with the audio. My voice can sometimes be quiet so I hope the video is engaging for you.
And, if you have a Geobase project, I hope you can give the Geobase Blueprint for Taxis Analysis a try!
En un mundo cada vez más conectado, la información geográfica ya no es un recurso exclusivo de los técnicos en la oficina: es una herramienta estratégica que debe estar disponible allí donde ocurren las cosas, en el territorio.
Con esa visión nace gvSIG Mapps, la aplicación móvil que pone toda la potencia de la geoinformación en la palma de la mano.
gvSIG Mapps es una app móvil que se integra con gvSIG Online, permitiendo consultar, capturar y actualizar datos directamente desde el terreno. Está pensada para todo tipo de organizaciones —administraciones públicas, empresas y ONG— que necesitan trabajar con información georreferenciada en campo.
Los usos de gvSIG Mapps son tan variados como los sectores que gestionan información territorial:
Con gvSIG Mapps, la edición y mantenimiento de la información geográfica deja de estar limitada a un escritorio o plataforma web y se convierte en una herramienta dinámica, accesible y colaborativa.
+información: info@gvsig.com
Natural disasters are becoming increasingly frequent and intense: floods, wildfires, earthquakes, or adverse weather events are part of a reality that directly affects our safety and well-being.
In this context, the difference between chaos and coordination largely depends on how we manage information. Geoinformation becomes a strategic resource: it enables anticipation, rapid response coordination, and more effective recovery planning.
gvSIG Online is a geospatial management platform that turns data into decisions. In emergency situations, it supports:
The CPBV, among many other organizations, uses gvSIG Online as its geospatial reference system. Thanks to this platform:
The result is a global and real-time view of the territory, enabling faster and more effective action in critical situations.
Emergencies cannot be avoided, but they can be managed more effectively. Geoinformation and gvSIG Online provide administrations and civil protection agencies with an integral, open, and interoperable tool to address present and future challenges.
Because in emergencies, every minute counts… and having the right information and technology makes the difference.
+info: info@gvsig.com
SAC is moving the mail server to a new machine.
As per ticket #3395 Containerize osgeo6 on osgeo9 <Making sure you're not a bot!;
Expected downtime: 1 hour.
The movement is planned for *Sept 20 at 4AM UTC <https://www.worldtimebuddy.com/?qm=1&lid=100,2643743,1850147,1275339,5368361,3530597,3169070&h=2643743&date=2025-9-20&sln=5-6&hf=0>\*\.
- begin downtime: Saturday 20 September 2025, 4h UTC
- end downtime (estimated): Saturday 20 September 2025, 5h UTC
*MAY* be loss of email for messages sent / in the queue during the downtime
The current total mails on the queue are: 198
It fluctuates between 190 and 220
Regards
Vicky Vergara from SAC
1 post - 1 participant
I found this lamp in a shop in Arles
This was my last big week before the race. Now I'm tapering so that I start the Bear with fresh legs and plenty of energy.
56 miles running
12,556 feet D+ running
15 hours, 57 minutes all training
I lost Monday to inflammation that made my knees feel creaky, which was disappointing. But I felt better on Tuesday and my week rapidly improved. I went right back out to my one mile laps at Pineridge and did four repeats. Wednesday I did a half-marathon length run at Lory State Park, milking it for all the vert I could get, a yard short of 3,000 feet. I also got a reminder of how important it is to refuel the evening before a long run (I failed). Thursday I chugged up to the Towers and down, feelng better. Friday I did five laps at Pineridge.
I had been planning another hill grinding session on Saturday, but at the last minute decided to give my swollen right knee a break, and did a gravel ride instead. This set me up well for a great Sunday outing. I went out for 24 miles in Horsetooth Open Space and Lory State Park on a route that was very close to that of the Quad Rock 25-miler.
I carried the gear that I will be carrying at the Bear, the same vest and bottles and rain jacket. I used my poles on the ups and stowed them for the descents. The jagged up-and-down profile of the Quad Rock course is not unlike the last 80 miles of the Bear, so my confidence has increased.
In 2023, my biggest training week ended five weeks before my race. This year, under different circumstances, it is two weeks before my race. I feel good about this right now. I'm eager to see how I feel on Friday the 26th.
Las catástrofes naturales son cada vez más frecuentes e intensas: inundaciones, incendios forestales, terremotos o fenómenos meteorológicos adversos forman parte de una realidad que afecta directamente a nuestra seguridad y bienestar.
Ante este escenario, la diferencia entre el caos y la coordinación depende en gran medida de cómo gestionamos la información. La geoinformación se convierte en un recurso estratégico: permite anticiparse, coordinar respuestas rápidas y organizar la recuperación de manera más eficaz.
gvSIG Online es una plataforma de gestión geoespacial que transforma los datos en decisiones. En emergencias, facilita:
El CPBV, entre oros muchos organismos,utiliza gvSIG Online como su sistema geoespacial de referencia. Gracias a esta plataforma:
El resultado es una visión global y en tiempo real del territorio, que facilita actuar con rapidez y eficacia en situaciones críticas.
Las emergencias no se pueden evitar, pero sí gestionar mejor. La información geográfica y gvSIG Online ofrece a administraciones y organismos de protección civil una herramienta integral, abierta e interoperable para enfrentarse a los desafíos presentes y futuros.
Porque en emergencias, cada minuto cuenta… y contar con la información y la tecnología adecuada marca la diferencia.
+información: info@gvsig.com
Marc-Tobias said “Otterbox currently has a special edition with maps of New York, London, Paris, Tokyo https://www.otterbox.co.uk/en-gb/search?q=passport&search-button=&lang=en_GB Might not be ‘in the wild’ enough.”
I think that is wild enough but if anyone has a pic of their own case with a map, do send it to us.
I've been on the Project Steering Committee (PSC) of the GDAL project for a few years now. It's a hugely significant software project, one that I'm very fond of, and I like to think that I've had an impact in my time on the committee.
Recently, though, the steering part has become less rewarding. By granting Amazon S3 and its imitators special, featured storage protocols, GDAL is stuck carrying water for big and lucrative cloud service providers and a few hyper-scaling customers that don't adequately support the project. It's a crappy situation, not unique to GDAL. A lot of open source projects find themselves ruthlessly exploited these days. This is my personal view. I don't speak for GDAL.
More importantly, I'm doing less geospatial work these days, and thus I'm increasingly uncertain about the rapidly-changing currents in which the PSC is steering the project. Do things like "GeoParquet" and "GeoArrow" really matter to practitioners who aren't working for a handful of hyper-scaling organizations? Is "GeoAI" for real or is it bullshit? Do we steer the project towards these interests or away from them? I truly don't know. I wish I did.
Can I fully engage with the problems that GDAL faces over the next year? That's my criteria for participating in the PSC. I can't, and so it's time to go. The project is in good shape, I believe, and I hope that I'm making room for someone with a great vision to join it.
En los artículos anteriores de esta serie, conté cómo construimos un asistente de IA para gvSIG desktop, pasando de un simple chat a un potente conjunto de herramientas contextuales. Tenía un prototipo que funcionaba y que era genuinamente útil. Pero, como os adelanté, me enfrentaba a un problema que no era de código, sino del mundo real ¿cómo podía compartirlo sin que nadie se arruinara?
Hoy os voy a contar la historia de esa lucha. Una odisea a través de laberintos de precios, hardware prohibitivo y software que casi derrite mi ordenador. Es la historia de todos los callejones sin salida que exploré antes de encontrar una luz al final del túnel.
La euforia del prototipo funcional se topó con la cruda realidad. Cada una de esas respuestas “mágicas” era una llamada a una API, y cada llamada tenía un coste. Esto no era un problema técnico, sino una pesadilla logística. Empecé a evaluar mis opciones, y cada camino me llevaba a un muro.
Mi búsqueda no era solo de algo “gratuito”, sino de un modelo predecible y sostenible. Buscaba un plan asequible, con un coste fijo o con limitaciones de uso razonables que evitaran sorpresas. Lo que encontré fue desolador:
Y que no parezca que esta conclusión fue inmediata. Antes de darme por vencido, me lancé a un viaje por las páginas de precios de los principales proveedores: Google, OpenAI, Anthropic, DeepSeek, xAI… Fue un verdadero rompecabezas. Cada proveedor hablaba un dialecto diferente de “coste”. Navegar por sus tablas de precios era una misión casi imposible para mi caso de uso.
Tenía que comparar el concepto de “token” entre modelos que los medían de forma distinta, con precios diferentes para los tokens de entrada (lo que yo preguntaba) y los de salida (lo que la IA respondía). Era como intentar comparar el consumo de un coche midiendo uno en “litros por kilómetro” y otro en “galones por hora”, sin una tabla de conversión clara. El panorama era un laberinto de jerga técnica diseñada para empresas con equipos financieros, no para un desarrollador que solo quería saber “¿cuánto me costará esto al mes si 100 usuarios lo usan de forma moderada?”.
Después de horas de análisis, la conclusión fue demoledora. El ecosistema de APIs de IA no estaba pensado para mi necesidad.
Opción | Análisis / Realidad | Veredicto |
---|---|---|
Yo asumo los costes de la API | La experiencia para el usuario sería perfecta, pero para mí era económicamente inviable. Un pequeño grupo de usuarios activos podría generar una factura de cientos de euros. | Imposible. |
El usuario registra su propia API Key | Esto me liberaba de los costes, pero creaba una barrera de entrada insalvable. Nadie iba a pasar por ese calvario administrativo y de riesgo económico. | Inaceptable. |
Buscar un proveedor con un plan sostenible | Simplemente, no existía. El mercado estaba dominado por el pago por uso, un modelo diseñado para empresas, no para distribuir herramientas a una comunidad de usuarios. | Fracaso. |
Y que no se malinterprete, mi búsqueda no era de algo ‘gratuito’, sino de un modelo predecible y sostenible. Estaría encantado de pagar una tarifa plana razonable, un coste fijo mensual que me permitiera ofrecer la herramienta a mis usuarios de confianza como una inversión controlada. Pero esa opción, simplemente, no existía. El mercado estaba dominado por el ‘pago por uso’, un modelo diseñado para empresas con presupuestos elásticos, no para un desarrollador que necesita distribuir una herramienta de software libre sin miedo a la bancarrota.
Había creado una herramienta potente que, en la práctica, no podía compartir con nadie. Estaba completamente atascado.
Decidido a no rendirme, me embarqué en la que parecía la solución más lógica: si no puedo usar una API externa, traeré la IA a casa. Mi objetivo era ejecutar los modelos de lenguaje (LLMs) directamente en la máquina del usuario. La teoría era impecable; la práctica fue un desastre memorable.
Mi primera incursión fue con LM Studio. La experiencia fue… corta y aterradora. A los diez minutos de las primeras pruebas, mi equipo de desarrollo se congeló por completo. Tras cinco minutos mirando una pantalla inerte esperando a ver si revivia, no me quedó más remedio que recurrir al último recurso: el botón de apagado físico. Días después, lo intenté de nuevo con más cuidado, pero el resultado fue el mismo: todo el sistema, hasta el cursor, empezó a moverse a cámara lenta. Alternativa descartada.
Mi siguiente parada fue Ollama. ¡Al menos no me dejó el ordenador frito! Confiado, empecé a probar modelos. Los grandes (32B) eran desesperadamente lentos. Los pequeños (4B) se movían, así que lo integré en mi prototipo desarrollando un cliente compatible OpenAI, que es lo que soporta ollama, y empecé a probar.
¡Ay, dios mío! Fue como hablar con alguien con amnesia severa. El problema era el tamaño de contexto. El modelo apenas tenía un contexto de 32000 tokens (y algunos modelos solo de 15000 tokens) , y solo mi system prompt inicial ya ocupaba casi todo ese espacio. A la que yo le decía algo, el modelo empezaba a “olvidar” las instrucciones, la estructura de la base de datos o las reglas para generar JSON. Probé con DeepSeek, Gemma, Llama… el patrón era siempre el mismo: el modelo que no se quedaba corto de contexto, se moría de lentitud. El sueño de la IA local se había desvanecido.
Con la vía del software local cerrada, decidi abordarlo desde otro punto. Si mi equipo no podía, quizás un servidor dedicado en casa sí podría. Pero esto abrió una nueva caja de Pandora. Mi primera pregunta fue tan simple como aterradora: ¿Y qué hardware necesito para esto?
Empecé a buscar. Los foros y artículos solo hablaban de un tipo de hardware: las GPUs de NVIDIA. Nombres como RTX 3090, RTX 4090, H100 o A100 aparecían por todas partes. Cuando busqué sus precios, casi me caigo de la silla. Las RTX se movían en un rango de precios prohibitivo para un proyecto personal, y las H100/A100… bueno, de esas es mejor no mirar el precio para no deprimirse. A esto, por supuesto, había que sumarle el coste de un equipo adecuado para albergarlas.
El proyecto parecía muerto de nuevo, pero la curiosidad me pudo. ¿Por qué NVIDIA? ¿Qué tenían esas GPUs que las hacía tan indispensables? Me sumergí en foros, artículos técnicos y vídeos de YouTube, en un viaje que me llevó de vuelta a los fundamentos del hardware. Poco a poco, empecé a entender las claves. Descubrí una distinción fundamental: no es lo mismo entrenar un LLM, que requiere una potencia de cálculo masiva, que ejecutarlo, “inferencia”, para dar servicio a unos pocos usuarios. Mis necesidades estaban en el segundo grupo.
Eso me dio un hilo de esperanza. Para lo que yo necesitaba, no me hacía falta una RTX de miles de euros. Si sabes cómo funciona un ordenador, esa pieza de hardware que hace andar nuestro software, existen soluciones mucho más económicas.
Descubrí el fascinante mundo de las APUs de AMD, como los Ryzen 7 8700G. Estos chips son pequeñas maravillas que integran CPU, GPU y una NPU (Unidad de Procesamiento Neuronal) en una sola pieza. Su gran ventaja es que la GPU no tiene memoria dedicada, sino que utiliza la RAM del sistema. Si a esto le unes dos módulos de 32GB de RAM DDR5 de baja latencia (CL30), se convierte en un pequeño monstruo para ejecutar modelos de IA, con un coste muy inferior al de las soluciones basadas en RTX.
Hacía años que no me bajaba a un nivel tan profundo de análisis de hardware. Tuve que volver a repasar por qué es crítico usar dos módulos de RAM en lugar de uno (para aprovechar el acceso en paralelo del doble canal) o por qué la latencia CL30 era la ideal para las características de esa CPU. Ademas de entender cómo se cargan las capas de un LLM en la memoria de la GPU.
El resumen de esta odisea fue que, tras horas de investigación, di con una configuración de hardware óptima y de “bajo coste” que, probablemente, me permitiría ejecutar los modelos con una velocidad aceptable. Pero incluso esa solución, la más barata y eficiente que pude diseñar, seguía siendo una inversión demasiado grande para mi presupuesto en un proyecto personal.
Había encontrado una solución técnicamente elegante, pero económicamente inalcanzable. El proyecto volvía, una vez más, a estar en un callejón sin salida.
Estaba desmoralizado. Mi proyecto de asistente de chat impulsado por IA estaba aparcado y acumulando polvo. Había chocado contra tantos muros que lo di por un “experimento interesante pero fallido”. Así que desvié mi atención hacia herramientas más prácticas.
Por aquel entonces, para trabajar habíamos empezado a usar gemini-cli
, un nuevo agente de línea de comandos que acababa de salir. Su principal atractivo era el modelo de uso: hasta 1000 peticiones diarias gratuitas con el modelo Flash. Era perfecto para integrarlo en nuestro día a día como asistente de programación. Lo usaba para lo práctico: repasar código, documentar y depurar. El modelo Flash iba bastante bien para las tareas rutinarias; para los errores más complejos, tiraba del modelo Pro, aunque su acceso era más limitado.
La IA había inundado mi YouTube con docenas de vídeos que te contaban esta o aquella maravilla sobre gemini-cli
: “resume tus PDFs”, “genera imágenes”… Era el “Ubik” del momento, y costaba distinguir el contenido de valor del ruido hasta que ya te habías tragado medio vídeo.
Un día, entre la marabunta de vídeos, acabé en uno que mencionaba de pasada que gemini-cli
podía funcionar como un “cliente MCP”. La sigla no me dijo nada. No le di mayor importancia. No entendí qué significaba, y la idea quedó flotando en mi subconsciente durante varios días. Hasta que unas noches, mas tarde, leyendo sobre arquitecturas de IA, la primera pieza encajó. “Si gvSIG desktop actuase como un servidor MCP, podría acceder a él desde gemini-cli
. ¡Qué chulo!.” Era solo una idea curiosa mas. Lo apunté por algun sitio en la cabeza, un experimento para un fin de semana, pero nada más. No era la solución a mi problema de distribución.
Y entonces, un poco más tarde, pensando en ello, llegó el verdadero cataclismo. La segunda y la tercera pieza cayeron en su sitio. Y conecte los puntos con una linea uno a uno:
gemini-cli
es un cliente MCP.gemini-cli
… ¡es de uso gratuito y gestiona la API key por el usuario!Eso significaba que… cualquier persona con gemini-cli
instalado podría usar todas las herramientas que yo había construido en mi cliente-ai
… ¡sin ningún coste, sin registrarse en ninguna parte, sin dar su tarjeta de crédito!
¡OH!
Ese fue el momento. No fue un destello de genialidad, sino la lenta conexión de ideas dispersas que, de repente, formaron una solución perfecta al problema que me había atormentado durante semanas. Había encontrado la llave.
La transición de mi asistente de chat impulsado por IA a un servidor MCP fue asombrosamente rápida, apenas unos días. Pero no empecé de cero. Por un lado, tenía toda la lógica de los “procesadores” de mi prototipo. Y por otro, la experiencia de años en gvSIG desktop, donde ya había implementado pequeños servidores HTTP para interactuar con otras aplicaciones. Rescaté parte de ese código, lo uní al protocolo MCP y las piezas encajaron casi sin esfuerzo.
En el próximo artículo de esta serie, os contaré qué es exactamente el MCP y cómo, apoyándome en todo el trabajo previo, construí el servidor que finalmente dio vida a este proyecto.