<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: TaroFortune</title>
    <description>The latest articles on DEV Community by TaroFortune (@tarofortune).</description>
    <link>https://dev.to/tarofortune</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3934770%2F30160537-5d02-45ce-a74e-0e51282c334f.png</url>
      <title>DEV Community: TaroFortune</title>
      <link>https://dev.to/tarofortune</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tarofortune"/>
    <language>en</language>
    <item>
      <title>Building a nationwide flood-risk map for Korea with SRTM DEM + OpenStreetMap</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Mon, 20 Jul 2026 18:26:07 +0000</pubDate>
      <link>https://dev.to/tarofortune/building-a-nationwide-flood-risk-map-for-korea-with-srtm-dem-openstreetmap-8fc</link>
      <guid>https://dev.to/tarofortune/building-a-nationwide-flood-risk-map-for-korea-with-srtm-dem-openstreetmap-8fc</guid>
      <description>&lt;p&gt;I build &lt;a href="https://tarofortune.pythonanywhere.com/analyze?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;ZipScope&lt;/a&gt;, a Korean web app that scores the &lt;em&gt;living environment&lt;/em&gt; around 38,000+ residential complexes (apartments, officetels, and row/multi-family housing) nationwide. It is deliberately &lt;strong&gt;not&lt;/strong&gt; a real-estate listing site — no prices to chase, no agents. Just analysis: seven living-quality dimensions, commute isochrones, winter sunlight, water-view lines of sight, and the piece I want to walk through here — an estimated &lt;strong&gt;flood-risk layer&lt;/strong&gt; built entirely from open data.&lt;/p&gt;

&lt;p&gt;Among free Korean services, flood, sunlight, and view analysis are close to unique. But "estimated" is the operative word, and I will be blunt about where the estimate breaks down. If you are doing anything similar with terrain data, the tradeoffs below are the interesting part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just use the official flood map?
&lt;/h2&gt;

&lt;p&gt;Korea has an official inundation hazard map at &lt;a href="https://www.floodmap.go.kr" rel="noopener noreferrer"&gt;floodmap.go.kr&lt;/a&gt;. It is authoritative — and I link to it directly from every result. But it does not exist as a clean, queryable layer for arbitrary points across every one of 38k complexes at the resolution and cadence I wanted. So I built a &lt;strong&gt;complementary approximation&lt;/strong&gt; from two open sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SRTM 30m DEM&lt;/strong&gt; — NASA's Shuttle Radar Topography Mission elevation grid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSM waterways&lt;/strong&gt; — river and stream geometry pulled from OpenStreetMap via the Overpass API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to replace the official map. It is to give a fast, consistent, nationwide &lt;em&gt;relative&lt;/em&gt; signal — "is this complex low and near water, or high and dry?" — with the honest caveat attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extracting rivers from OSM Overpass
&lt;/h2&gt;

&lt;p&gt;The drainage network comes from OSM. An Overpass query for &lt;code&gt;waterway&lt;/code&gt; features (rivers, streams, canals) inside a bounding box returns the linework I treat as the local drainage baseline. OSM's water coverage in Korea is good for named rivers and major streams; it thins out for tiny ditches and culverted channels, which matters for the limitations section below.&lt;/p&gt;

&lt;p&gt;The practical trick is batching the Overpass calls by region rather than per-complex — you do not want 38,000 separate HTTP round-trips to a shared public endpoint. Pull the waterways for an administrative area once, cache the geometry, and reuse it for every complex inside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core: a HAND approximation
&lt;/h2&gt;

&lt;p&gt;The risk signal is a &lt;strong&gt;HAND (Height Above Nearest Drainage)&lt;/strong&gt; approximation. HAND is a well-known terrain descriptor: for any point, you ask &lt;em&gt;how far above the nearest drainage channel is it, vertically?&lt;/em&gt; A house 2 m above the local stream is far more exposed than one 40 m above it, regardless of absolute elevation.&lt;/p&gt;

&lt;p&gt;The pipeline, conceptually:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sample the SRTM DEM at the complex location and along the nearby OSM drainage lines.&lt;/li&gt;
&lt;li&gt;Find the nearest drainage segment.&lt;/li&gt;
&lt;li&gt;Compute the vertical drop from the complex to that drainage baseline.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Small HAND values (the point sits barely above nearby water) push the risk estimate up; large HAND values push it down. It is a coarse proxy for hydrological connectivity, but on 30 m terrain it captures the first-order intuition that low points near channels flood first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slope attenuation
&lt;/h2&gt;

&lt;p&gt;Raw HAND on its own over-flags flat riverside land and under-weights how quickly water actually reaches — or drains away from — a point. So I add a &lt;strong&gt;slope-based attenuation&lt;/strong&gt; term derived from the DEM gradient around the complex.&lt;/p&gt;

&lt;p&gt;Steeper local terrain sheds water and attenuates the pooling signal; flatter terrain retains it. Concretely, the slope factor dampens or amplifies the HAND-derived score so that a flat floodplain and a hillside that happen to share the same height-above-drainage do not get scored identically. It is a heuristic weighting, not a hydraulic model — no Manning's equation, no rainfall-runoff simulation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Batch performance: recomputing the whole country at once
&lt;/h2&gt;

&lt;p&gt;The whole nationwide layer recomputes as a single batch over all 38,000+ complexes — fast enough to rerun on demand rather than as an overnight job. What makes that possible is not clever math — it is avoiding per-point I/O:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DEM tiles stay in memory&lt;/strong&gt; during the batch instead of being re-opened per query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSM drainage geometry is cached per region&lt;/strong&gt;, so nearest-drainage lookups are local array math, not network calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vectorized sampling&lt;/strong&gt; — elevation and slope for many points at once rather than a Python loop per complex.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stack itself is intentionally boring and cheap to host: &lt;strong&gt;Flask + React + Leaflet&lt;/strong&gt; on the front, &lt;strong&gt;SQLite&lt;/strong&gt; for storage, &lt;strong&gt;SRTM DEM + OSM Overpass&lt;/strong&gt; as the geodata sources, all running on &lt;strong&gt;PythonAnywhere&lt;/strong&gt;. No PostGIS cluster, no cloud GIS bill. That constraint — keep it runnable on modest shared hosting — shaped every decision above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limitations (this is the important part)
&lt;/h2&gt;

&lt;p&gt;I show all of these caveats in the product, next to the number, and I will repeat them here because a flood estimate you trust blindly is worse than none:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;This is an estimate, not an official inundation map.&lt;/strong&gt; For decisions that matter, check &lt;a href="https://www.floodmap.go.kr" rel="noopener noreferrer"&gt;floodmap.go.kr&lt;/a&gt;. ZipScope says so on every result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;30 m DEM is coarse.&lt;/strong&gt; SRTM resolution smooths out embankments, levees, small berms, and sub-30 m features that decisively change local flood behavior. A protective wall thinner than a pixel is invisible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HAND ignores drainage capacity and rainfall.&lt;/strong&gt; It is a static terrain descriptor. It knows nothing about storm-sewer sizing, pump stations, tides, dam releases, or how much rain fell. Urban flooding is often a drainage-capacity problem, not a topography problem — and this method cannot see that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSM waterways are incomplete.&lt;/strong&gt; Culverted or unmapped channels do not appear, so a point can look "far from drainage" when a buried stream runs right under it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slope attenuation is a heuristic&lt;/strong&gt;, tuned by inspection, not calibrated against observed flood events.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of all that, I present the output as a &lt;strong&gt;relative&lt;/strong&gt; signal for comparing complexes, always paired with its source and its limits. That honesty is also, frankly, the marketing: every estimate in ZipScope — flood, winter sunlight, view openness — ships with its provenance and its weaknesses stated plainly. In a category full of confident numbers, showing your error bars is the differentiator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways if you are building similar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HAND + open DEM + OSM waterways&lt;/strong&gt; gets you a surprisingly useful first-order flood proxy with zero paid data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch by region and keep tiles in RAM&lt;/strong&gt; — that is the difference between a batch that finishes while you wait and one that crawls for minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State your limitations louder than your results.&lt;/strong&gt; A terrain approximation dressed up as ground truth is a liability; the same number, honestly framed, is a genuinely helpful feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Live here: &lt;a href="https://tarofortune.pythonanywhere.com/analyze/" rel="noopener noreferrer"&gt;https://tarofortune.pythonanywhere.com/analyze/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— austriano&lt;/p&gt;

</description>
      <category>gis</category>
      <category>python</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>PWA with React + Leaflet: lessons from a 31-city map app</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Sat, 18 Jul 2026 18:41:58 +0000</pubDate>
      <link>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-44jg</link>
      <guid>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-44jg</guid>
      <description>&lt;p&gt;Notes from shipping a real-world PWA in Korea:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vite SSG is worth it. SPAs lose Korean SEO because Naver's crawler doesn't fully render JS.&lt;/li&gt;
&lt;li&gt;Leaflet &amp;gt; Mapbox for cost-sensitive projects. Free OSM tiles + zero cost.&lt;/li&gt;
&lt;li&gt;Firebase Hosting rewrites let you have deep URLs (/city/suwon) without a backend.&lt;/li&gt;
&lt;li&gt;KakaoTalk share is non-negotiable in Korea — 70%+ of social traffic.&lt;/li&gt;
&lt;li&gt;PWA install banner: don't auto-prompt, let the user discover.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Project: &lt;a href="https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pwa</category>
      <category>react</category>
      <category>webdev</category>
      <category>firebase</category>
    </item>
    <item>
      <title>Building a nationwide flood-risk map for Korea with SRTM DEM + OpenStreetMap</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Fri, 17 Jul 2026 17:48:37 +0000</pubDate>
      <link>https://dev.to/tarofortune/building-a-nationwide-flood-risk-map-for-korea-with-srtm-dem-openstreetmap-13b4</link>
      <guid>https://dev.to/tarofortune/building-a-nationwide-flood-risk-map-for-korea-with-srtm-dem-openstreetmap-13b4</guid>
      <description>&lt;p&gt;I build &lt;a href="https://tarofortune.pythonanywhere.com/analyze?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;ZipScope&lt;/a&gt;, a Korean web app that scores the &lt;em&gt;living environment&lt;/em&gt; around 38,000+ residential complexes (apartments, officetels, and row/multi-family housing) nationwide. It is deliberately &lt;strong&gt;not&lt;/strong&gt; a real-estate listing site — no prices to chase, no agents. Just analysis: seven living-quality dimensions, commute isochrones, winter sunlight, water-view lines of sight, and the piece I want to walk through here — an estimated &lt;strong&gt;flood-risk layer&lt;/strong&gt; built entirely from open data.&lt;/p&gt;

&lt;p&gt;Among free Korean services, flood, sunlight, and view analysis are close to unique. But "estimated" is the operative word, and I will be blunt about where the estimate breaks down. If you are doing anything similar with terrain data, the tradeoffs below are the interesting part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just use the official flood map?
&lt;/h2&gt;

&lt;p&gt;Korea has an official inundation hazard map at &lt;a href="https://www.floodmap.go.kr" rel="noopener noreferrer"&gt;floodmap.go.kr&lt;/a&gt;. It is authoritative — and I link to it directly from every result. But it does not exist as a clean, queryable layer for arbitrary points across every one of 38k complexes at the resolution and cadence I wanted. So I built a &lt;strong&gt;complementary approximation&lt;/strong&gt; from two open sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SRTM 30m DEM&lt;/strong&gt; — NASA's Shuttle Radar Topography Mission elevation grid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSM waterways&lt;/strong&gt; — river and stream geometry pulled from OpenStreetMap via the Overpass API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to replace the official map. It is to give a fast, consistent, nationwide &lt;em&gt;relative&lt;/em&gt; signal — "is this complex low and near water, or high and dry?" — with the honest caveat attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extracting rivers from OSM Overpass
&lt;/h2&gt;

&lt;p&gt;The drainage network comes from OSM. An Overpass query for &lt;code&gt;waterway&lt;/code&gt; features (rivers, streams, canals) inside a bounding box returns the linework I treat as the local drainage baseline. OSM's water coverage in Korea is good for named rivers and major streams; it thins out for tiny ditches and culverted channels, which matters for the limitations section below.&lt;/p&gt;

&lt;p&gt;The practical trick is batching the Overpass calls by region rather than per-complex — you do not want 38,000 separate HTTP round-trips to a shared public endpoint. Pull the waterways for an administrative area once, cache the geometry, and reuse it for every complex inside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core: a HAND approximation
&lt;/h2&gt;

&lt;p&gt;The risk signal is a &lt;strong&gt;HAND (Height Above Nearest Drainage)&lt;/strong&gt; approximation. HAND is a well-known terrain descriptor: for any point, you ask &lt;em&gt;how far above the nearest drainage channel is it, vertically?&lt;/em&gt; A house 2 m above the local stream is far more exposed than one 40 m above it, regardless of absolute elevation.&lt;/p&gt;

&lt;p&gt;The pipeline, conceptually:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sample the SRTM DEM at the complex location and along the nearby OSM drainage lines.&lt;/li&gt;
&lt;li&gt;Find the nearest drainage segment.&lt;/li&gt;
&lt;li&gt;Compute the vertical drop from the complex to that drainage baseline.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Small HAND values (the point sits barely above nearby water) push the risk estimate up; large HAND values push it down. It is a coarse proxy for hydrological connectivity, but on 30 m terrain it captures the first-order intuition that low points near channels flood first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slope attenuation
&lt;/h2&gt;

&lt;p&gt;Raw HAND on its own over-flags flat riverside land and under-weights how quickly water actually reaches — or drains away from — a point. So I add a &lt;strong&gt;slope-based attenuation&lt;/strong&gt; term derived from the DEM gradient around the complex.&lt;/p&gt;

&lt;p&gt;Steeper local terrain sheds water and attenuates the pooling signal; flatter terrain retains it. Concretely, the slope factor dampens or amplifies the HAND-derived score so that a flat floodplain and a hillside that happen to share the same height-above-drainage do not get scored identically. It is a heuristic weighting, not a hydraulic model — no Manning's equation, no rainfall-runoff simulation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Batch performance: recomputing the whole country at once
&lt;/h2&gt;

&lt;p&gt;The whole nationwide layer recomputes as a single batch over all 38,000+ complexes — fast enough to rerun on demand rather than as an overnight job. What makes that possible is not clever math — it is avoiding per-point I/O:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DEM tiles stay in memory&lt;/strong&gt; during the batch instead of being re-opened per query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSM drainage geometry is cached per region&lt;/strong&gt;, so nearest-drainage lookups are local array math, not network calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vectorized sampling&lt;/strong&gt; — elevation and slope for many points at once rather than a Python loop per complex.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stack itself is intentionally boring and cheap to host: &lt;strong&gt;Flask + React + Leaflet&lt;/strong&gt; on the front, &lt;strong&gt;SQLite&lt;/strong&gt; for storage, &lt;strong&gt;SRTM DEM + OSM Overpass&lt;/strong&gt; as the geodata sources, all running on &lt;strong&gt;PythonAnywhere&lt;/strong&gt;. No PostGIS cluster, no cloud GIS bill. That constraint — keep it runnable on modest shared hosting — shaped every decision above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limitations (this is the important part)
&lt;/h2&gt;

&lt;p&gt;I show all of these caveats in the product, next to the number, and I will repeat them here because a flood estimate you trust blindly is worse than none:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;This is an estimate, not an official inundation map.&lt;/strong&gt; For decisions that matter, check &lt;a href="https://www.floodmap.go.kr" rel="noopener noreferrer"&gt;floodmap.go.kr&lt;/a&gt;. ZipScope says so on every result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;30 m DEM is coarse.&lt;/strong&gt; SRTM resolution smooths out embankments, levees, small berms, and sub-30 m features that decisively change local flood behavior. A protective wall thinner than a pixel is invisible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HAND ignores drainage capacity and rainfall.&lt;/strong&gt; It is a static terrain descriptor. It knows nothing about storm-sewer sizing, pump stations, tides, dam releases, or how much rain fell. Urban flooding is often a drainage-capacity problem, not a topography problem — and this method cannot see that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSM waterways are incomplete.&lt;/strong&gt; Culverted or unmapped channels do not appear, so a point can look "far from drainage" when a buried stream runs right under it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slope attenuation is a heuristic&lt;/strong&gt;, tuned by inspection, not calibrated against observed flood events.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of all that, I present the output as a &lt;strong&gt;relative&lt;/strong&gt; signal for comparing complexes, always paired with its source and its limits. That honesty is also, frankly, the marketing: every estimate in ZipScope — flood, winter sunlight, view openness — ships with its provenance and its weaknesses stated plainly. In a category full of confident numbers, showing your error bars is the differentiator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways if you are building similar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HAND + open DEM + OSM waterways&lt;/strong&gt; gets you a surprisingly useful first-order flood proxy with zero paid data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch by region and keep tiles in RAM&lt;/strong&gt; — that is the difference between a batch that finishes while you wait and one that crawls for minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State your limitations louder than your results.&lt;/strong&gt; A terrain approximation dressed up as ground truth is a liability; the same number, honestly framed, is a genuinely helpful feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Live here: &lt;a href="https://tarofortune.pythonanywhere.com/analyze/" rel="noopener noreferrer"&gt;https://tarofortune.pythonanywhere.com/analyze/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— austriano&lt;/p&gt;

</description>
      <category>gis</category>
      <category>python</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Why I built a real-estate tool with zero real-estate listings</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Wed, 15 Jul 2026 17:47:15 +0000</pubDate>
      <link>https://dev.to/tarofortune/why-i-built-a-real-estate-tool-with-zero-real-estate-listings-3if8</link>
      <guid>https://dev.to/tarofortune/why-i-built-a-real-estate-tool-with-zero-real-estate-listings-3if8</guid>
      <description>&lt;p&gt;Every property site in Korea (Hogang-no-no, Zigbang, Dabang) shows the same listings with the same agents.&lt;/p&gt;

&lt;p&gt;What people actually need when moving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How far is the subway? (door to platform)&lt;/li&gt;
&lt;li&gt;Can my kid walk to school?&lt;/li&gt;
&lt;li&gt;Is there a mart within 10 min on foot?&lt;/li&gt;
&lt;li&gt;How long to my workplace, with transfers?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's what I built: &lt;a href="https://geoinfomatic.pythonanywhere.com?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;https://geoinfomatic.pythonanywhere.com?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No listings. No agents. Just an honest accessibility map.&lt;/p&gt;

&lt;p&gt;Funded by 5 free analyses/day + 9,900 KRW Pro tier. Built solo with Flask + Leaflet.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>civictech</category>
      <category>leaflet</category>
      <category>showdev</category>
    </item>
    <item>
      <title>PWA with React + Leaflet: lessons from a 31-city map app</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Tue, 14 Jul 2026 18:35:16 +0000</pubDate>
      <link>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-96o</link>
      <guid>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-96o</guid>
      <description>&lt;p&gt;Notes from shipping a real-world PWA in Korea:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vite SSG is worth it. SPAs lose Korean SEO because Naver's crawler doesn't fully render JS.&lt;/li&gt;
&lt;li&gt;Leaflet &amp;gt; Mapbox for cost-sensitive projects. Free OSM tiles + zero cost.&lt;/li&gt;
&lt;li&gt;Firebase Hosting rewrites let you have deep URLs (/city/suwon) without a backend.&lt;/li&gt;
&lt;li&gt;KakaoTalk share is non-negotiable in Korea — 70%+ of social traffic.&lt;/li&gt;
&lt;li&gt;PWA install banner: don't auto-prompt, let the user discover.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Project: &lt;a href="https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pwa</category>
      <category>react</category>
      <category>webdev</category>
      <category>firebase</category>
    </item>
    <item>
      <title>Building a nationwide flood-risk map for Korea with SRTM DEM + OpenStreetMap</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Tue, 14 Jul 2026 12:38:50 +0000</pubDate>
      <link>https://dev.to/tarofortune/building-a-nationwide-flood-risk-map-for-korea-with-srtm-dem-openstreetmap-4434</link>
      <guid>https://dev.to/tarofortune/building-a-nationwide-flood-risk-map-for-korea-with-srtm-dem-openstreetmap-4434</guid>
      <description>&lt;p&gt;I build &lt;a href="https://tarofortune.pythonanywhere.com/analyze?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;ZipScope&lt;/a&gt;, a Korean web app that scores the &lt;em&gt;living environment&lt;/em&gt; around 38,000+ residential complexes (apartments, officetels, and row/multi-family housing) nationwide. It is deliberately &lt;strong&gt;not&lt;/strong&gt; a real-estate listing site — no prices to chase, no agents. Just analysis: seven living-quality dimensions, commute isochrones, winter sunlight, water-view lines of sight, and the piece I want to walk through here — an estimated &lt;strong&gt;flood-risk layer&lt;/strong&gt; built entirely from open data.&lt;/p&gt;

&lt;p&gt;Among free Korean services, flood, sunlight, and view analysis are close to unique. But "estimated" is the operative word, and I will be blunt about where the estimate breaks down. If you are doing anything similar with terrain data, the tradeoffs below are the interesting part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just use the official flood map?
&lt;/h2&gt;

&lt;p&gt;Korea has an official inundation hazard map at &lt;a href="https://www.floodmap.go.kr" rel="noopener noreferrer"&gt;floodmap.go.kr&lt;/a&gt;. It is authoritative — and I link to it directly from every result. But it does not exist as a clean, queryable layer for arbitrary points across every one of 38k complexes at the resolution and cadence I wanted. So I built a &lt;strong&gt;complementary approximation&lt;/strong&gt; from two open sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SRTM 30m DEM&lt;/strong&gt; — NASA's Shuttle Radar Topography Mission elevation grid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSM waterways&lt;/strong&gt; — river and stream geometry pulled from OpenStreetMap via the Overpass API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to replace the official map. It is to give a fast, consistent, nationwide &lt;em&gt;relative&lt;/em&gt; signal — "is this complex low and near water, or high and dry?" — with the honest caveat attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extracting rivers from OSM Overpass
&lt;/h2&gt;

&lt;p&gt;The drainage network comes from OSM. An Overpass query for &lt;code&gt;waterway&lt;/code&gt; features (rivers, streams, canals) inside a bounding box returns the linework I treat as the local drainage baseline. OSM's water coverage in Korea is good for named rivers and major streams; it thins out for tiny ditches and culverted channels, which matters for the limitations section below.&lt;/p&gt;

&lt;p&gt;The practical trick is batching the Overpass calls by region rather than per-complex — you do not want 38,000 separate HTTP round-trips to a shared public endpoint. Pull the waterways for an administrative area once, cache the geometry, and reuse it for every complex inside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core: a HAND approximation
&lt;/h2&gt;

&lt;p&gt;The risk signal is a &lt;strong&gt;HAND (Height Above Nearest Drainage)&lt;/strong&gt; approximation. HAND is a well-known terrain descriptor: for any point, you ask &lt;em&gt;how far above the nearest drainage channel is it, vertically?&lt;/em&gt; A house 2 m above the local stream is far more exposed than one 40 m above it, regardless of absolute elevation.&lt;/p&gt;

&lt;p&gt;The pipeline, conceptually:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sample the SRTM DEM at the complex location and along the nearby OSM drainage lines.&lt;/li&gt;
&lt;li&gt;Find the nearest drainage segment.&lt;/li&gt;
&lt;li&gt;Compute the vertical drop from the complex to that drainage baseline.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Small HAND values (the point sits barely above nearby water) push the risk estimate up; large HAND values push it down. It is a coarse proxy for hydrological connectivity, but on 30 m terrain it captures the first-order intuition that low points near channels flood first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slope attenuation
&lt;/h2&gt;

&lt;p&gt;Raw HAND on its own over-flags flat riverside land and under-weights how quickly water actually reaches — or drains away from — a point. So I add a &lt;strong&gt;slope-based attenuation&lt;/strong&gt; term derived from the DEM gradient around the complex.&lt;/p&gt;

&lt;p&gt;Steeper local terrain sheds water and attenuates the pooling signal; flatter terrain retains it. Concretely, the slope factor dampens or amplifies the HAND-derived score so that a flat floodplain and a hillside that happen to share the same height-above-drainage do not get scored identically. It is a heuristic weighting, not a hydraulic model — no Manning's equation, no rainfall-runoff simulation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Batch performance: recomputing the whole country at once
&lt;/h2&gt;

&lt;p&gt;The whole nationwide layer recomputes as a single batch over all 38,000+ complexes — fast enough to rerun on demand rather than as an overnight job. What makes that possible is not clever math — it is avoiding per-point I/O:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DEM tiles stay in memory&lt;/strong&gt; during the batch instead of being re-opened per query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSM drainage geometry is cached per region&lt;/strong&gt;, so nearest-drainage lookups are local array math, not network calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vectorized sampling&lt;/strong&gt; — elevation and slope for many points at once rather than a Python loop per complex.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stack itself is intentionally boring and cheap to host: &lt;strong&gt;Flask + React + Leaflet&lt;/strong&gt; on the front, &lt;strong&gt;SQLite&lt;/strong&gt; for storage, &lt;strong&gt;SRTM DEM + OSM Overpass&lt;/strong&gt; as the geodata sources, all running on &lt;strong&gt;PythonAnywhere&lt;/strong&gt;. No PostGIS cluster, no cloud GIS bill. That constraint — keep it runnable on modest shared hosting — shaped every decision above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limitations (this is the important part)
&lt;/h2&gt;

&lt;p&gt;I show all of these caveats in the product, next to the number, and I will repeat them here because a flood estimate you trust blindly is worse than none:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;This is an estimate, not an official inundation map.&lt;/strong&gt; For decisions that matter, check &lt;a href="https://www.floodmap.go.kr" rel="noopener noreferrer"&gt;floodmap.go.kr&lt;/a&gt;. ZipScope says so on every result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;30 m DEM is coarse.&lt;/strong&gt; SRTM resolution smooths out embankments, levees, small berms, and sub-30 m features that decisively change local flood behavior. A protective wall thinner than a pixel is invisible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HAND ignores drainage capacity and rainfall.&lt;/strong&gt; It is a static terrain descriptor. It knows nothing about storm-sewer sizing, pump stations, tides, dam releases, or how much rain fell. Urban flooding is often a drainage-capacity problem, not a topography problem — and this method cannot see that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSM waterways are incomplete.&lt;/strong&gt; Culverted or unmapped channels do not appear, so a point can look "far from drainage" when a buried stream runs right under it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slope attenuation is a heuristic&lt;/strong&gt;, tuned by inspection, not calibrated against observed flood events.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of all that, I present the output as a &lt;strong&gt;relative&lt;/strong&gt; signal for comparing complexes, always paired with its source and its limits. That honesty is also, frankly, the marketing: every estimate in ZipScope — flood, winter sunlight, view openness — ships with its provenance and its weaknesses stated plainly. In a category full of confident numbers, showing your error bars is the differentiator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways if you are building similar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HAND + open DEM + OSM waterways&lt;/strong&gt; gets you a surprisingly useful first-order flood proxy with zero paid data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch by region and keep tiles in RAM&lt;/strong&gt; — that is the difference between a batch that finishes while you wait and one that crawls for minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State your limitations louder than your results.&lt;/strong&gt; A terrain approximation dressed up as ground truth is a liability; the same number, honestly framed, is a genuinely helpful feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Live here: &lt;a href="https://tarofortune.pythonanywhere.com/analyze/" rel="noopener noreferrer"&gt;https://tarofortune.pythonanywhere.com/analyze/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— austriano&lt;/p&gt;

</description>
      <category>gis</category>
      <category>python</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Why I built a real-estate tool with zero real-estate listings</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Mon, 13 Jul 2026 18:49:56 +0000</pubDate>
      <link>https://dev.to/tarofortune/why-i-built-a-real-estate-tool-with-zero-real-estate-listings-hak</link>
      <guid>https://dev.to/tarofortune/why-i-built-a-real-estate-tool-with-zero-real-estate-listings-hak</guid>
      <description>&lt;p&gt;Every property site in Korea (Hogang-no-no, Zigbang, Dabang) shows the same listings with the same agents.&lt;/p&gt;

&lt;p&gt;What people actually need when moving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How far is the subway? (door to platform)&lt;/li&gt;
&lt;li&gt;Can my kid walk to school?&lt;/li&gt;
&lt;li&gt;Is there a mart within 10 min on foot?&lt;/li&gt;
&lt;li&gt;How long to my workplace, with transfers?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's what I built: &lt;a href="https://geoinfomatic.pythonanywhere.com?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;https://geoinfomatic.pythonanywhere.com?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No listings. No agents. Just an honest accessibility map.&lt;/p&gt;

&lt;p&gt;Funded by 5 free analyses/day + 9,900 KRW Pro tier. Built solo with Flask + Leaflet.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>civictech</category>
      <category>leaflet</category>
      <category>showdev</category>
    </item>
    <item>
      <title>PWA with React + Leaflet: lessons from a 31-city map app</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Sun, 12 Jul 2026 17:07:19 +0000</pubDate>
      <link>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-4g32</link>
      <guid>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-4g32</guid>
      <description>&lt;p&gt;Notes from shipping a real-world PWA in Korea:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vite SSG is worth it. SPAs lose Korean SEO because Naver's crawler doesn't fully render JS.&lt;/li&gt;
&lt;li&gt;Leaflet &amp;gt; Mapbox for cost-sensitive projects. Free OSM tiles + zero cost.&lt;/li&gt;
&lt;li&gt;Firebase Hosting rewrites let you have deep URLs (/city/suwon) without a backend.&lt;/li&gt;
&lt;li&gt;KakaoTalk share is non-negotiable in Korea — 70%+ of social traffic.&lt;/li&gt;
&lt;li&gt;PWA install banner: don't auto-prompt, let the user discover.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Project: &lt;a href="https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pwa</category>
      <category>react</category>
      <category>webdev</category>
      <category>firebase</category>
    </item>
    <item>
      <title>Why I built a real-estate tool with zero real-estate listings</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Fri, 10 Jul 2026 18:02:59 +0000</pubDate>
      <link>https://dev.to/tarofortune/why-i-built-a-real-estate-tool-with-zero-real-estate-listings-24cg</link>
      <guid>https://dev.to/tarofortune/why-i-built-a-real-estate-tool-with-zero-real-estate-listings-24cg</guid>
      <description>&lt;p&gt;Every property site in Korea (Hogang-no-no, Zigbang, Dabang) shows the same listings with the same agents.&lt;/p&gt;

&lt;p&gt;What people actually need when moving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How far is the subway? (door to platform)&lt;/li&gt;
&lt;li&gt;Can my kid walk to school?&lt;/li&gt;
&lt;li&gt;Is there a mart within 10 min on foot?&lt;/li&gt;
&lt;li&gt;How long to my workplace, with transfers?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's what I built: &lt;a href="https://geoinfomatic.pythonanywhere.com?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;https://geoinfomatic.pythonanywhere.com?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No listings. No agents. Just an honest accessibility map.&lt;/p&gt;

&lt;p&gt;Funded by 5 free analyses/day + 9,900 KRW Pro tier. Built solo with Flask + Leaflet.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>civictech</category>
      <category>leaflet</category>
      <category>showdev</category>
    </item>
    <item>
      <title>PWA with React + Leaflet: lessons from a 31-city map app</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Thu, 09 Jul 2026 18:21:33 +0000</pubDate>
      <link>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-3la2</link>
      <guid>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-3la2</guid>
      <description>&lt;p&gt;Notes from shipping a real-world PWA in Korea:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vite SSG is worth it. SPAs lose Korean SEO because Naver's crawler doesn't fully render JS.&lt;/li&gt;
&lt;li&gt;Leaflet &amp;gt; Mapbox for cost-sensitive projects. Free OSM tiles + zero cost.&lt;/li&gt;
&lt;li&gt;Firebase Hosting rewrites let you have deep URLs (/city/suwon) without a backend.&lt;/li&gt;
&lt;li&gt;KakaoTalk share is non-negotiable in Korea — 70%+ of social traffic.&lt;/li&gt;
&lt;li&gt;PWA install banner: don't auto-prompt, let the user discover.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Project: &lt;a href="https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pwa</category>
      <category>react</category>
      <category>webdev</category>
      <category>firebase</category>
    </item>
    <item>
      <title>Why I built a real-estate tool with zero real-estate listings</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Tue, 07 Jul 2026 18:14:53 +0000</pubDate>
      <link>https://dev.to/tarofortune/why-i-built-a-real-estate-tool-with-zero-real-estate-listings-43c</link>
      <guid>https://dev.to/tarofortune/why-i-built-a-real-estate-tool-with-zero-real-estate-listings-43c</guid>
      <description>&lt;p&gt;Every property site in Korea (Hogang-no-no, Zigbang, Dabang) shows the same listings with the same agents.&lt;/p&gt;

&lt;p&gt;What people actually need when moving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How far is the subway? (door to platform)&lt;/li&gt;
&lt;li&gt;Can my kid walk to school?&lt;/li&gt;
&lt;li&gt;Is there a mart within 10 min on foot?&lt;/li&gt;
&lt;li&gt;How long to my workplace, with transfers?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's what I built: &lt;a href="https://geoinfomatic.pythonanywhere.com?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;https://geoinfomatic.pythonanywhere.com?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No listings. No agents. Just an honest accessibility map.&lt;/p&gt;

&lt;p&gt;Funded by 5 free analyses/day + 9,900 KRW Pro tier. Built solo with Flask + Leaflet.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>civictech</category>
      <category>leaflet</category>
      <category>showdev</category>
    </item>
    <item>
      <title>PWA with React + Leaflet: lessons from a 31-city map app</title>
      <dc:creator>TaroFortune</dc:creator>
      <pubDate>Mon, 06 Jul 2026 18:29:57 +0000</pubDate>
      <link>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-k2n</link>
      <guid>https://dev.to/tarofortune/pwa-with-react-leaflet-lessons-from-a-31-city-map-app-k2n</guid>
      <description>&lt;p&gt;Notes from shipping a real-world PWA in Korea:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vite SSG is worth it. SPAs lose Korean SEO because Naver's crawler doesn't fully render JS.&lt;/li&gt;
&lt;li&gt;Leaflet &amp;gt; Mapbox for cost-sensitive projects. Free OSM tiles + zero cost.&lt;/li&gt;
&lt;li&gt;Firebase Hosting rewrites let you have deep URLs (/city/suwon) without a backend.&lt;/li&gt;
&lt;li&gt;KakaoTalk share is non-negotiable in Korea — 70%+ of social traffic.&lt;/li&gt;
&lt;li&gt;PWA install banner: don't auto-prompt, let the user discover.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Project: &lt;a href="https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot" rel="noopener noreferrer"&gt;https://gyeonggi-currency-map.web.app?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=multi-site-bot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pwa</category>
      <category>react</category>
      <category>webdev</category>
      <category>firebase</category>
    </item>
  </channel>
</rss>
