This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass.
My idea for the Touch Grass challenge was a small application that helps you choose a nearby forest for a walk. Give it a location and a radius, then get information about the forests nearby and suggestions about what you might find there. Save the result or print it, and take it outside.
I called it Forest Radar, or Leśny Radar in the Polish interface.
The original idea included mushrooms, berries, animal tracks, and questions like whether you can bring a dog. Those questions sound simple until you start looking at the available data. Forest inventory data can tell you about the trees and habitat. It cannot tell you that a mushroom is there today, or that a particular forest is safe to enter.
The current application accepts coordinates and a radius between 1 and 20 kilometres. You can also ask the browser to fill in your location. It produces a separate Polish description for each forest range returned by the search, with a Google Maps link and the same safety footer on every card.
A forest range is an administrative area, not a complete walking route. This version does not provide turn-by-turn navigation, verify dog-access rules, or guarantee a suitable entrance.
The application runs locally. The example in the screenshot uses latitude 52, longitude 21, and a search radius of 5 kilometres. The first card is for Uwieliny. It has an AI-generated forest description, a Maps link, a print button, and a mushroom-safety warning with a link to look for expert help.
Screenshot: the Uwieliny card in Leśny Radar. The description is labelled as AI-generated and potentially inaccurate; the safety footer is fixed application text.
A search at this location produces cards for Uwieliny, Bogatki, Dobiesz, Chojnów, Góra Kalwaria, and Sękocin. One run took about 97 seconds to fetch the data and generate all six descriptions. It is slow enough that I would want to prepare the cards before leaving, rather than wait for them on the trail.
The app can generate the cards, but the descriptions still contain errors. They need checking before anyone relies on them to plan a walk.
The project is written in Ruby with Sinatra and is available under the MIT licence:
I chose Sinatra because the application needs one page, a JSON endpoint, and a printable result. Rails would add more structure than I need here, while writing the HTTP and view layers myself would take time away from the application.
The interface uses i18n. The Polish translations are complete; the English translation keys exist, but their values are still empty. The README includes instructions for running the app and its tests.
The main data source is Bank Danych o Lasach, the Polish Forest Data Bank. The application queries its OGC API Features service for forest administration and inventory data near the requested location.
The useful fields include tree species, habitat type, stand age, and inventory year. A stand is a unit in the forest inventory. The application groups the relevant stands by forest range and summarizes their attributes before sending them to the model. Each forest gets its own description.
For Uwieliny, the query returned 431 stands within the search radius, with an inventory year of 2026. Here is part of the species summary:
SO (pine): 216 stands
DB (oak): 79 stands
Missing species: 53 stands
BRZ (birch): 39 stands
These are counts of stands grouped by their recorded species code. They are not hectares or percentages, and they do not count individual trees.
I keep this raw data off the user-facing card because it is hard to interpret, but include it in the model's prompt.
I chose Bielik because it is a Polish model and I wanted the forest descriptions in Polish. I run it through Ollama on a separate machine on my local network, using SpeakLeash/bielik-11b-v2.3-instruct:Q4_K_M.
I originally asked Bielik for a structured response with specific keywords and separate sections. It consistently left out the keywords or sections I requested. The forbidden-word checks described below also kept rejecting its answers, so I stopped requiring that format and now display the response as it comes back, with a disclaimer.
The prompt asks, in Polish, what the BDL data can tell us about the forest's area, accessibility for walkers, and possible animals, plants, and mushrooms. The application supplies numbered data lines, but it does not check whether the generated description accurately reflects them.
The backend also queries OpenStreetMap through Overpass and includes the retrieved trail information in each forest's prompt. The input distinguishes four cases: a mapped trail crosses the forest, the search found no crossing trail, the data was unavailable, or the forest was not checked. The prompt explains that missing data does not mean there are no trails on the ground. It also explains that the Google Maps link identifies the forest location rather than a verified walking route.
I added this trail information after reviewing the earlier output shown here. Responses remain unvalidated, so the extra context does not guarantee a correct description.
I wanted the application to suggest possible mushroom species for a habitat. I did not want it to decide whether a mushroom is edible or poisonous.
My first approach was strict validation: reject responses containing forbidden words about edibility. Bielik kept using those words when listing mushrooms, and the validator kept rejecting the answers. I removed the word check from the running version.
The screenshot shows the description mentioning "grzyby jadalne i trujące" (edible and poisonous mushrooms). In a later run, before I added the trail information, the model went further and listed named mushrooms as edible. The original validation would have rejected that output. The current application does not.
I opted for a disclaimer and the same mushroom-safety footer on every forest card. The description is labelled as AI-generated and potentially wrong. The footer warns against collecting unfamiliar mushrooms and points readers toward a sanitary station, where a qualified expert can check them. It includes a Google Maps search link to help find that service.
This is a trade-off, not a replacement safety guarantee. A disclaimer does not prevent unsafe output. Forest Radar is not a mushroom-identification or edibility tool, and its generated text is not a reason to eat something found in the forest.
Before I added the trail information to the prompt, one Uwieliny description included this phrase:
sosna (216 ha) i świerk (79 ha)
That means "pine (216 hectares) and spruce (79 hectares)." The source summary actually had 216 stands recorded with the pine code and 79 with the oak code. The model changed both the units and the species associated with the second value.
It also called the forest accessible to walkers without current access evidence. These are errors in the generated description, not facts established by BDL. Animals, berries, and mushrooms mentioned in the text are not verified sightings either.
I have not yet taken a card outside and compared it with what I found in the forest.
Checking whether a forest was closed was part of the original plan. During development, the entry-ban service returned HTTP 400 errors, so the application could not determine whether a ban was in place. I removed the check rather than keep a feature that always reported an unknown result.
That means Forest Radar does not establish current entry-ban status. The model can still write an accessibility claim, as the demo shows, but that claim is not a substitute for checking current notices from the relevant forest district.
Public forest data makes this project possible. It gives the application a source for local forest information instead of asking a model to invent it from a place name. It also lets me compare the generated description with the input and identify mistakes such as the stand-count error.
An open-weight model served through Ollama gives me control over inference. I can choose the model host and change the model without replacing the rest of the application. Running it on hardware I control avoids a proprietary model API and its per-request charges, although the hardware and electricity still have a cost.
The application still needs internet access. BDL and Overpass receive queries containing a bounding box around the user's location. The model host receives summarized forest data, trail information, and distances, rather than the raw input coordinates. Google Maps receives location information when a user opens one of the links.
For this project, the benefit is control over the model service and access to the underlying data. Neither makes the generated text automatically correct.
Forest Radar is a working local prototype for exploring nearby forest options. I want the screen to be the preparation for a walk, not the activity itself. Before relying on the descriptions as a guide, I still need to improve their accuracy and test the cards outside.