Creating Google Maps with PowerShell
You know, it’s funny how projects sometimes grow from something very small and become something quite different. This is a story about exactly that.
It all started with the most simple little email from PowerShell.com. It was an easy little one-liner to show the latest earthquakes from a site call SEISMI.org. It was a great example for how to use Invoke-RestMethod to pull data from a JSON feed. This is a growing standard for retrieving data and Invoke-RestMethod will take that data stream and create PowerShell objects for you, and everything from there is simple object manipulation–just like every other PowerShell script!
But there’s another problem. The zoom level on the map is all the way zoomed in. You can’t see a thing. Zoom it out and it all looks wonderful! Shouldn’t be a big deal right? Just set the zoom and walk away? Turns out there’s a map option called zoomLevel, so I put it in the code and absolutely nothing happens. More Googling and I discover that there’s a bug in the Map Visualization that zoomLevel doesn’t work. Since Google is focusing all of their energy on the Google Map API who knows when this will get fixed so it’s game over. I’ll have to switch gears.
What I wanted was a script where you could specify how big the map was, where you wanted to save the HTML and how many quakes you wanted to be displayed. So first we need to specify the parameters and set the path up. I decided I wanted the script to default to the same path that the script is run from, or what you specify.
On line 18 I insert the Markers variable which has all of our data in it. Then on lines 25-33 we loop through the multi-dimensional array and insert the markers into the map. I’d love to say this part all went smoothly, but it didn’t. It took me a lot of Google searching and trial and error before I finally got everything finalized and working. I was quite proud of how it came out. But during testing I ran into another big problem. If there was more than one data element everything worked fine, but if there was only 1 data element it was zoomed way out. It didn’t make sense to be so far out when there’s only 1 element, you want to be closer so you can see more information about the area the quake was in. I already knew about the zoomLevel so I knew it had to be something like that, and indeed mapZoom(x) was the way to do it. Only it didn’t work. At all. Sheesh, here we go again. A bit more Googling discovered that when using the fitBound method (which will center and zoom the map to multiple selections) you can’t then turn around and use setZoom right after it. A bit more Googling and I was able to find lines 35-41 which essentially tests for more than one marker, if there are then use fitBound and if there isn’t use setZoom.
Finally, after several hours fully a working Last Earthquake mapping script! How cool is that?! After that I wrapped some Verbose output, some error trapping for common problems, that kind of thing and published it on Spiceworks as a goofy script to play with.
Not Done Yet
Of course, it wasn’t long before someone at Spiceworks noticed a problem. What Amazilia noticed was the data on SEISMI.org was actually quite a bit out of date. And when I actually looked at it closer he some completely right. Damn. Luckily he provided a link to a site where I might be able to find what I need. A little digging around found the data feeds and sure enough they have a JSON feed! Found the right feed, and then had to figure out how to use it.
First thing I noticed when I used Invoke-RestMethod on the website though was that I only got one record back. Turns out that’s the format. It has only a couple of properties, one is a very high level metadata about the data feed itself. But go into the Features property and that actually holds an array of objects of all of the earthquakes in the feed. But there are multiple properties and they all hold arrays of their own so we’re going to have to loop through each record and tease out the data I wanted, creating a new PSCustomObject as I go. By creating a PSCustomObject this allowed me to reuse all of the code from before without doing a major rewrite. Here’s how I got the data and created my object:
Just loop through the $QuakesData.Features property, which itself is a collection of objects and pull out the data I needed. This is the great thing about PowerShell, it’s so easy to explore these complex objects by just typing $QuakesData.Features and seeing what comes out and then just adding the next property on that, and so on until you get right down to what you want. This kind of thing was so hard with VBScript that I would never do a project like this!
But I had retrofitted the new data source into the script and it’s working great (see the link below if you want to see the full script).
Next post, I’m going to talk about how this project morphed into something else! A type of project I’ve been wanting to do before but never really got around to it but I realized that with the framework I have worked up for this script I could do! And this script would actually be something that could be useful in a business environment! Don’t you love foreshadowing?