How Dovepass was built
Try it: dovepass.com (pick a takeoff, a destination and a drone, or press "Try an example").
Why I started
Every drone delivery company I looked at was building its own full stack: its own maps, its own airspace data, its own reading of the rules, its own routing. I run a road-routing business, so my first thought was that routing would be the shared problem, and that there might be room for a layer that any operator could ask one question: can I fly this exact path, legally and safely, and how?
I picked San Francisco to find out, because it has everything that makes the question hard in one small place: tall buildings next to low ones, steep hills, SFO's airspace reaching into the south of the city, and city, state and federal land owners who all have their own drone rules. If a checker can give a correct answer here, the idea is at least worth discussing.
Routing turned out to be the easy part. Almost all of the work went into three things: knowing how tall things are, knowing what the wind is doing a few hundred feet up, and knowing which rules apply to a given patch of ground at a given time.
What a check does
You pick a takeoff, a destination, a drone and a time. Dovepass plans a path and answers GO, GO with things to know, needs permission, or NO-GO, with the rule behind each part of the answer. It also produces a printable flight card and mission files for DJI and QGroundControl. Everything runs in the browser; the site is static, and a scheduled job refreshes the FAA, weather and park data.
In order, a check looks at:
- Airspace. The FAA's LAANC grid, which caps drones at 0 to 400 ft in squares around SFO, plus controlled airspace.
- Temporary no-fly zones. The FAA's live list of flight restrictions, read down to their actual daily hours.
- Local rules. City parks, federal parkland, the Presidio, state parks, jails, the Golden Gate Bridge, and stadium restrictions during Giants games.
- Obstacles. Buildings and terrain along the whole path, not just at the ends.
- The aircraft. Weight, Remote ID, wind limit, battery with a reserve, payload.
- Weather and light. Visibility and cloud from SFO, wind at altitude, daylight or night.
- People and line of sight. Every street, plaza and park the path crosses, and the point where the drone goes beyond the pilot's sight.
The rules
What we looked at
The FAA's Part 107 is the base layer for licensed pilots: 400 ft above the ground, line of sight, no flying over people or moving cars with most drones, weather minimums, Remote ID. On top of that, San Francisco has a stack of land owners with their own rules. The city's Park Code (section 3.09) bans drones in city parks without a Rec & Park permit. The Golden Gate National Recreation Area bans them outright, except at Fort Funston when no hang gliders or paragliders are flying. The Presidio Trust permits commercial flights only. California State Parks, the Golden Gate Bridge District and the state's jail-grounds law each say something different again.
The problem
None of this exists as data. It lives in PDFs, compendiums and web pages, written for lawyers and rangers. Three land owners within a few square miles use three different ideas of what "permission" means: a permit you can apply for, a permit only some pilots can get, and no permit at all.
What we chose
A hand-built register of 25 rules, each with its source, the exact text that matters, who it applies to and how to ask for permission. Twelve of them are enforced as checks today. The rest are recorded but not checked yet, for example the Port of San Francisco, whose statement about drones over its piers is broad enough that I haven't decided how to treat it. A small monitor fingerprints each source page and flags when one changes, so a rule doesn't silently go stale.
The register also decides how an answer is phrased. A site that needs written permission is a NO-GO until you tick that you have it, and the card names the authority and how to ask. A site that bans drones outright says so, with no permission button.
Trade-off
Most of San Francisco's open space is a park of some kind, so a large share of interesting flights end in "needs permission". That is the honest answer, but it makes the product look stricter than an airspace app that only checks the FAA layer. I'd rather be right than permissive.
Building heights
The data
154,393 building footprints. 142,231 come from OpenStreetMap, 11,209 from the city's own 2010 LIDAR survey where OpenStreetMap has no height, and 953 have an estimated height from the number of floors.
The problem
About 20,000 buildings in the OpenStreetMap data for San Francisco have no height at all. Where both sources cover the same downtown building, they differ by a median of 7.4 m, and by more than 10 m on 72 of 224 matched buildings. Rooftop antennas, tanks and cranes aren't in either.
Alternatives
Overture Maps and Microsoft's machine-learning footprints were options; I deferred both to a later data pipeline and started with the two sources I could check against each other. Google's photorealistic 3D city is the best-looking source, but its terms forbid extracting geometry or heights from it, so it can only ever be a backdrop.
What we chose
The route always stays 15 m (49 ft) above anything it flies over, for every aircraft. The margin mostly protects against our own data, not the drone. I considered a smaller margin for small quadcopters and decided against it until the building data is proven better.
Trade-off
Under SFO's lower ceilings, 49 ft over a two-storey house can leave no legal height at all. The app then refuses that takeoff spot and says why in plain words, and shows the building it means.
Terrain and height
The 400 ft limit is measured from the ground below the drone, and San Francisco's ground goes from sea level to over 900 ft at Twin Peaks. A route that holds one altitude above the takeoff can be legal at the start and illegal half a mile later. The first version did exactly that.
The fix was to give every 25 m square of the city a legal height window: from the highest obstacle plus the margin, up to the ground plus 400 ft (or the FAA grid ceiling where it's lower). The planned height then follows the terrain, climbing and descending gradually at the drone's published rates. Terrain comes from the USGS 3DEP 10 m elevation model, shipped as tiles with the site. An earlier version asked the USGS elevation service live for every point; it was slow and sometimes down for minutes, so it now only fills gaps.
Different aircraft move differently. A quadcopter can stop and climb straight up; a fixed-wing can't. Each aircraft carries a class, and only quadcopters may use vertical moves in the middle of a route.
Temporary no-fly zones
The data
The FAA publishes temporary flight restrictions (TFRs) for VIP visits, air shows, security events and stadiums. Its feed can't be called from a browser, so a scheduled job copies it, along with the airspace grid, SFO weather and park data, into the site.
The problem
The first version took a zone's dates from its title, "Thursday, October 8 through Sunday, October 11 Local", and read them as whole days in UTC. During Fleet Week that ended the security zone over the waterfront an hour early on the Sunday, so for one hour the app would have said a downtown flight was clear inside an active no-fly zone. It also missed that the zone was only active from 10 am to 6 pm each day.
The fix reads the FAA's notice text, where the real hours are, area by area, and is all-or-nothing: if any part of a notice can't be read with confidence, the zone falls back to cautious whole days. A zone counts if any of its active hours overlaps the 45 minutes after takeoff. Tested against every notice the FAA had live that day (90), 72 were read fully and the rest fell back safely.
A second lesson came from the same week. The scheduled data job broke for five days because of one apostrophe in a comment, and nothing told us. The app was correct; its data was not. A failing data job is now treated as a safety problem, not housekeeping.
Weather, wind and battery
Visibility and cloud come from SFO's weather reports. Wind comes from Open-Meteo at 80, 120 and 180 m. Its grid is 1 to 3 km, so it describes an area, not the gusts between two towers; the app says so. Battery use is estimated from the published capacity and flight time, reduced by a 25% derating because brochure numbers are optimistic, with a 20% reserve by default. No manufacturer publishes power draw, so this is the weakest model in the app, and every answer says it's based on published specs.
Finding a route
The route-finder is A* over a 25 m grid of the city, run in the browser. The cost of each step is flight time, including headwind and tailwind. I looked at Dijkstra (correct but slower here), RRT (fast but gives a different route every run, which makes checking impossible) and road-network routing (the wrong model for something that flies). A* with a good estimate was the simplest thing that is repeatable.
The most useful design decision was to keep the planner and the judge separate. The planner proposes a route; a separate set of checks then judges the exported route with exact geometry, as if it had come from anywhere. If the final route fails, the planner tries to repair it, then replans around the culprit, and only then gives up. A route that fails the judge is never shown as flyable.
Buildings too tall to fly over (their top plus the margin is above the legal ceiling) are walls, and the route keeps at least 80 ft sideways from them.
What still doesn't work well
On steep slopes under a low airport ceiling, the planner sometimes can't build a path that passes the judge, and whether it succeeds can depend on the wind it plans with. Rather than guess, it says it couldn't plan, names where, and says that this is a limit of the route-finder, not a rule against flying.
People and moving cars
Part 107 doesn't allow flying over people, or keeping on flying over moving cars, with most drones. Light drones under 250 g only qualify if they have no exposed propellers that could cut skin, which rules out a stock DJI Mini. In a city that makes this the most common legal problem, and the first version didn't model it at all; it said "you can fly this route" over a dozen downtown streets.
Now every street (23,337 from OpenStreetMap), plaza and pier (477) and park (682) is known to the check. The route-finder prefers rooftops and water, and the answer leads with the condition: "Flyable only if no one is below you", the streets it crosses, and any street it follows. Following a street is the stricter case, because flying along a road above traffic isn't allowed even for drones that may fly over people.
What went wrong on the way
- One street is often several pieces in OpenStreetMap. A route running 390 m along Mission Bay Boulevard was first reported as three short "crossings". Streets are now joined by name.
- Unnamed roads, mostly freeway ramps, were dropped from the answer, so a route over only ramps said "no street crossings". They're counted now.
- Parks without known drone rules were invisible to the check. Every OpenStreetMap park is included now, for the warning only.
- Preferring rooftops made 18 of 81 test routes follow streets more, because narrow streets fall between the grid's points. A fix made three routes impossible, so it was rolled back and is still open.
Line of sight and returning home
Flying beyond your own sight needs an FAA waiver, and the rule means your own unaided sight: cameras, FPV goggles and binoculars don't count, and a visual observer can watch but doesn't extend the distance. A pilot on r/Part107 corrected us on both points: the app used to suggest an observer as a way to fly further, and assumed you could see the drone to 1,640 ft. It now uses two distances, guidance from vision research rather than legal limits: about 300 ft, beyond which you can't reliably see whether anyone is under the drone, and 800 to 1,600 ft depending on the drone's weight, beyond which you may not see it at all. A separate bug placed the point where sight is lost at the next turn of the route rather than where it really happens, so long routes said "after 3.0 mi" instead of 0.3. It now finds the exact point.
DJI drones return home in a straight line at a set height when they lose signal. On the example route that line passes a 1,070 ft tower, so the answer says not to rely on it, and gives a return-home height for routes where a straight return is safe. The exported DJI mission ends by landing at the destination, not by returning home, for the same reason.
Making the answer readable
The first versions were correct and hard to read: tabs of checks, technical codes, "MSL" and "AGL". Most of the visible work in the last two weeks went into the answer, not the engine: plain words, the real reason first, bans and permissions said truthfully, one kind of height in a sentence, and the map showing the thing the answer is talking about.
How it was built
I'm not a programmer. I built Dovepass with two AI coding agents: Kimi writing the code, and Claude reviewing it, writing the specifications and running independent checks. The rule is that whoever builds a change never judges it. When Claude has had to build something, Kimi reviews it. The work went in about 90 small, numbered checkpoints, each tested and reviewed before the next.
The review is where most of the value came from. Things it caught before or soon after release:
- The no-fly-zone time-zone error above.
- An exported DJI mission that ended with "return home" instead of landing.
- A merge of the two ends of a trip that let the milder rule hide the stricter one, so a flight landing on a federal beach showed GO.
- A DJI Mini marked as broadcasting Remote ID when it only does so with its heavier battery.
- Test answers that had been written to match what the app said rather than what the rules say, 24 of them.
- The sight errors above: the wrong crossing point, and the observer advice and 1,640 ft distance a pilot corrected.
The agents were good at code and at keeping a large test suite green. They were weak at checking a claim against the physical world. The clearest case: four attempts at choosing a "clean" example flight, each described confidently, landed on private land, in the water, in a park, and in a road. Every one was caught by looking at the map. The fix wasn't more code; it was requiring evidence in a form that can be checked, such as a list of what is under the route every 25 m.
Before the latest release, the checks were:
| Check | What it covers |
|---|---|
| 51 San Francisco test cases | Written from the published rules and sources; no wrong GO so far |
| 82-route sweep | Every route compared before and after each change |
| 221 browser checks | Run in a pinned daytime world and a pinned night-time world |
| 64 trips on the live site | Every answer read in full for wrong reasons and unclear wording |
| 18 targeted rule checks | No-fly zone, Giants game, bad weather, strong wind, jails, the bridge, payload, and others, with simulated conditions where needed |
What it doesn't do
- It hasn't been used on a real flight, and the DJI mission file hasn't been loaded on a real controller.
- It can't see people or traffic; "no one below you" is a condition the pilot has to hold.
- It doesn't file LAANC requests or talk to other drones in the area.
- It follows Part 107. A drone under 250 g flown just for fun has fewer rules, and the app only notes that.
- It's an aid for planning, not an authorization to fly.
What comes next, and other cities
The FAA layer works anywhere in the United States: the same airspace grid, the same no-fly-zone feed, the same Part 107. The local layer doesn't. Every city has its own parks code, its own state land, port authority, campuses and private plazas, and someone has to read those rules, turn them into checks and keep them current. San Francisco took about five weeks from the first research notes.
Building data is the other limit. San Francisco has good open data and its own LIDAR survey. Many cities don't. I looked at Mumbai: in OpenStreetMap, between 1% and 28% of buildings in the areas I sampled have any height, and the airport sits in the middle of the city.
So the next phase isn't more features for San Francisco. It's answering two questions: whether people who fly find these answers right and useful, and whether "the rules as a checkable answer for a specific path" is worth building city by city, or as a service other flight apps can call. If line-of-sight rules change, as the FAA has proposed for beyond-sight flights, the second question becomes more interesting.