Urgent.News

What's breaking now, across thousands of outlets.

Tech

I Built a Cheapest Fuel Station Map from Spanish Open Data

Spain publishes the price of every public fuel station as open data. The feed is refreshed every 30 minutes, contains roughly 11,500 stations and needs no API key. That sounded like a good small project: download the data, find the cheapest station near a location, and put the result on a map that works on a phone. The result is FuelSpot , a mobile site for comparing stations by fuel and…

Spain makes every public fuel station’s price available as open data. The data is updated every 30 minutes and contains details on around 11,500 stations. It requires no API key and can be accessed through a simple URL. This proved perfect for a small project: downloading the data, locating the cheapest station near a location, and displaying the result on a mobile-friendly map.

The project, named FuelSpot, was built in just one day atop a personal data-web engine. The challenging aspect wasn’t drawing markers. Instead, it was making the government's public feed work consistently. The Spanish Ministry’s REST API is straightforward with a REST endpoint: GET https://sedeaplicaciones.minetur.gob.es/ServiciosRESTCarburantes/PreciosCarburantes/EstacionesTerrestres/

There are a few technical hurdles. The API can return either JSON or XML depending on the request. Initially, the API supplied XML, causing parsing issues. The solution was to explicitly state the request should return JSON using: const response = await fetch ( url , { headers : { Accept : application/json } } ) ; const stations = await response . json ( ) ;

Another issue was the data format. Coordinates are given as strings with decimal commas, e.g., 39,211417, instead of decimal points. Prices are also strings, with an empty string indicating no fuel sale. Some field names include spaces, dots, or parentheses, like "C.P." and "Longitud (WGS84)". These inconsistencies were dealt with by normalising all fields at the data ingestion stage rather than letting the original formatting carry over into the application.

Naming was another challenge. Province names like CORUÑA (A), PALMAS (LAS), VALENCIA / VALÈNCIA, and ARABA/ÁLAVA were mapped to more readable labels and clean slugs. For instance, CORUÑA became a-coruna, PALMAS became las-palmas, and ARABA/ÁLAVA became alava. Similarly, some municipalities like Realejos (Los) are better displayed as Los Realejos. While seemingly minor, proper names are crucial for URLs, breadcrumbs, filters, and titles.

The “near me” search function runs on the server. Users input a centre point, a fuel type, and a radius of 5, 10, or 25 kilometres. The algorithm first filters out stations outside the specified radius using a latitude/longitude bounding box. Then, it calculates the haversine distance for the remaining stations. The haversine distance determines which stations are within the chosen radius and sorts the results by price, returning the top 20 options.

For example, searching for unleaded 95 around León yielded 48 stations. The cheapest was 1.469 €/l 1.8 km away, while the average price was 1.617 €/l.

Adding a year of historical data was another feature. The API offers a second endpoint for historical data: .../EstacionesTerrestresHist/{dd-mm-yyyy}. This returns the same data type as the current feed but only for a specified past date. The API rejects today’s date, returning an HTTP 400 error message. When building the backfill, the application only processes dates up to yesterday to avoid errors.

Data was collected for 364 days, cached daily averages per fuel (both nationally and by province), and kept for a set period to manage storage.

The implementation uses MapLibre GL JS with OpenFreeMap vector tiles, which do not require an API key. Initially, each marker displayed a separate HTML price pill. This caused overcrowding at country zoom levels. The solution was to render labels with a symbol layer using GeoJSON data. MapLibre’s built-in collision detection hides labels that don’t fit, and the symbol-sort-key is set to price to prioritize cheaper stations.

For dense areas with many points, clustering is used, creating a small circle layer underneath to keep stations visible even if their labels are hidden. This approach ensures the map remains readable even when displaying numerous station options.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Understanding IaaS: A Practical Look at AWS EC2

Introduction A few years ago, if you wanted to put a website online, you had to buy a physical server, find a place to keep it, and look after it yourself.

  • IaaS provides virtual computing resources like VMs, storage, and networking over the internet.
  • Amazon EC2 is a popular IaaS compute service from Amazon Web Services (AWS).

Product photos on a white background without opening Photoshop

Marketplaces like Amazon, Etsy and most Shopify themes look best when every product sits on a plain white or transparent background.

  • Position product away from wall to avoid harsh shadows.
  • Preserve original photo resolution for best background removal.
  • Use PNG format for transparency in store themes.

Node.js Marketplace Webhooks: Rate-Limit Queues, Retries, and Delivery Guarantees

Short answer: use a queue-centered design for delayed marketplace webhooks when you need retries and basic rate-limited processing without complex orchestration.

  • Use a queue-centered design with Node.js webhooks for delayed processing and retries
  • Keep event ledger in Postgres, not the queue, for system of record
  • Implement idempotency keys and backoff strategies in workers for at-least-once delivery

More from Thursday 12 November →