Showing posts with label chatgpt. Show all posts
Showing posts with label chatgpt. Show all posts

Saturday, October 31, 2026

Creating a KML Elevation Heatmap from a Georeferenced Overview Map

Not long ago, I made a post describing how to use AI to submit a georeferenced overview map in order to create a new KML file which contained boundary lines around each highlighted block.  That set of boundary lines could then be opened in Google Earth or ArcGIS Earth to be able to get a better understanding of the elevation/slope/aspect profiles of each block.  That post can be found here:

https://jonathan-scooter-clark.blogspot.com/2026/10/creating-kml-boundary-lines-around-cut.html

Let's take things a step further.  Let's create a sort of "elevation heat map" where the boundaries are shaded on a colour gradient, to represent relative elevations of various blocks.

 

For this exercise, I used OpenAI's "6.1 Terra" model on the extra-high setting, thinking that should be more than adequate.  I could have set it to the "ultra" setting, but why waste compute resources if not needed?  I uploaded the same "Williams_Lake_2016_Block_Boundaries" kml file that we generated in the post referenced above. This is the prompt that I used:

Are you able to change this KML for me? I'd like to create a sort of "elevation heat map" (for lack of a better term). Can you adjust the colours of the boundary line data throughout this kml, based upon elevation of each segment? Let's use a bright red colour for the very highest elevation of all the boundary line segments. Let's change to a bright green for the very lowest elevation of all the boundary line segments. Then, for every other segment in between, scale the elevation (from lowest boundary to highest) and change the colour of the segment to have an RGB colour value somewhere on a linear scale from bright green (low) to bright red (high). Ask me questions if this doesn't make sense to you.

 

Chat didn't have any questions for me, and got right to work.  It successfully generated the file that I wanted.  I should note that the first time I tried this, I asked it to scale from green (low elevation) to yellow (high elevation), and that didn't look very good, so I switched from yellow to red.  And to be honest, green/red makes a lot more sense.  Green means Go, and you can start lower elevation blocks earlier in the spring.  Red means wait, and the high elevation blocks will probably need to be planted last.

If you're curious what this new KML looked like when I opened it in ArcGIS Earth, here are two screenshots.  The first shows the entire contract (zoomed out to the maximum) and the second shows a close-up of a few of the blocks.

 



Here are some key findings, and things to think about:

1.  I could have fed it a chart listing all the blocks on the contract along with their low and high elevation points for each block.  Foresters often supply such charts in bid packages.  However, this data can only provide a mid-point in elevation of the block, and wouldn't give a true "weighted average" assessed across the entire block.

2.  I thought that Chat would probably average all of the elevations in a fixed interval around each boundary to come up with an average.  This would give a slightly better result, but still not perfect.  For example, what if the block was shaped like a bowl?  The boundary samples would be misleading; higher than expected.  And what if the block had a huge hill in the middle?  In that case, the boundary samples at the base of the hill would be biased to be lower than what the true block average was.

3.  Chat told me that the KML didn't contain any elevation data for any of the points on the boundaries.  Very interesting!  I thought that the KML's that it generated would have pulled elevation Z-data from the original georeferenced maps.  Apparently those maps didn't contain Z-data.  So Chat made the decision to find a terrain dataset that it could cross-reference against the positional data along each boundary, to determine elevations at each point.

4.  But then, this next point is what really impressed me:  Chat decided that using only the boundary as a proxy for block elevation was risky (as I pointed out above, in point 2).  So it decided to make an invisible grid across each block and sample elevation every 20m, then average all of those points, to get a true weighted average elevation across the block as a whole.  If you're curious, it pulled elevation data from Mapzen Terrain Tiles at registry.opendata.aws

5.  Some of the blocks in the KML that I used have "excluded areas," ie. separate boundaries for sections within blocks that weren't to be planted.  Chat ignored those excluded areas when calculating average elevation.  Again, this happened without me asking it to.

Pretty amazing, if you ask me.

 

I decided to wrap up this activity by asking Chat to generate an Excel spreadsheet for me which listed the blocks in elevation order (from low to high).  It did so, including the rank, license and block number (which were embedded in the boundary line attributes), average elevation of the block, and number of samples that it took in order to come up with that elevation (often using thousands of sample on a single block).  Here's [almost] what the spreadsheet looked like:

 


Note:  I did edit this spreadsheet just slightly to turn it from one-column to two-column format, so the screen-snip could show you the entire thing in more detail.  I also centre-justified instead of left-justified the data in most cells.

What's especially impressive in this step is that I didn't tell Chat much about what I wanted in the spreadsheet, I just said to list the blocks ranked low to high.  Also, changing the shading on the cell backgrounds for the elevation column, to match the shading on the KML, was a really nice touch that it thought of.

---

So what's left to do now?  I bet that it would be easy to feed our KML back into Chat and ask it to create coloured polygons instead of coloured boundary lines.  But wait, maybe this wouldn't be easy - it wouldn't be able to have multiple colour-gradients across a single block polygon.  Perhaps it would break the full block polygon up into its special 20m grid, and shade each new sub-polygon appropriately?  I'll leave that to you to figure out.  I'm not going to bother with that step though, because I prefer the boundary-line approach.  Boundary lines let me see what's visible in terms of satellite imagery within the block, if such a layer exists.

By the way, remember that all of this armchair analysis is helpful for getting a better understanding of the surface profile of each block.  But in the end, the only way to truly understand the block is to go out and stick a shovel into the ground.