Cool Job: Corporate Agent

I’ve done a lot of things for a living over the years, and after working with a number of short-lived startups, I figured it was time for a “real job.” I started with Capital Holding which rebranded as Providian while I was there.

Cool Job, Part 4: Corporate Agent

Agency GroupAfter working for several startups (six jobs in two years thanks to money running out, projects falling apart, bosses going to prison… the usual), I decided to give corporate America a try.

I went to work at Providian (which was Capital Holding when I interviewed). I interviewed at one of their main buildings, but when I showed up for work two weeks later, the building was boarded up. They’d opened their new offices in a brand new building across the street, and forgot to mention it to me. 😉

My building was known as Agency Group (since we wrote software to support insurance agents). I was officially a Corporate Agent.

There were lots of cool things about the job, like a gorgeous building with an ornate atrium, three different bosses who were peers of each other (one focused on the road ahead, one focused on the task at hand, and one focused on the people’s well-being). It was a good arrangement, and I wished that it had caught on in more of corporate America at the time.

I made a lot of good friends, including one that I would go into business with years later.

The Quest

Irv BaileyI wasn’t quite ready for corporate culture. Actually, it’s more that corporate culture wasn’t ready for me. I was young, smart, and bold. Moving through six jobs in two years, each better than the last, left little room for fear of failure or fear of reprisal. I knew that if anything were to happen to me, I’d find a better job within a couple of weeks.

I had my share of conflicts, victories, mistakes, and clashes, like most people in most jobs.

But there’s one really cool thing in particular that I’d like to focus on.

The CEO, Irv Bailey, worked in a different building a few blocks away. One day, he called an all-company meeting, so several hundreds of us crammed into the biggest room we had to listen to what was up. He spoke a lot about corporate vision, opportunities, challenges, other divisions, and many of the things that top-level execs share with their employees. But most of the company’s big picture was new to me. My brain started connecting the dots from idea to idea, and I got more excited as I listened, knowing the kind of things that I could do to help us along that a lot of long-timers didn’t realize.

I sent the CEO’s secretary an email with some thoughts. I was surprised to hear that Irv wanted to meet with me personally to discuss them. Wow.

The Tower

Providian TowerI actually dressed up, with a tie and everything. I met him in his tower office and we talked for a long time. Some of my ideas, the company was already doing, and I didn’t realize it. Some, the company had tried and failed. Some were… not actually legal (oops). But there were a few left that he really liked.

After that, he set up a quarterly meeting with me to see what things I was cooking up over in my department, even though there were probably eight managers in the hierarchy between the two of us. We’d also talk about the corporate culture, the wonders of technology, and anything else. He also expressed an interest in how my department was run, and we’d also discuss that. I kind of felt like an undercover operative, a different kind of Corporate Agent. Cool.

Using my background in startups, graphics, gaming, outer space, broadcasting, and other skills and talents from my experience toolbox, I came up with some pretty cool stuff. Cool for the time, anyway. The sales department called one of my projects “the most exciting thing they’d ever seen come out of IT.”

The Dungeon

ProvidianWord got out that I was going outside the chain of command, by meeting privately with the CEO. My new boss didn’t like that at all. (Having the three bosses was a little to progressive for most people there, and they restructured us back into “normal” org chart reporting.) She actually forbid me from going to my upcoming meeting. When I called Irv’s secretary to cancel, she was confused and asked, “Who’s this person that says you can’t come over?” Irv and his secretary had never heard of my boss before. Her reputation did not reach as far as mine, we found out.

After a lot of arguments to settle that situation, it seemed that my boss kept trying to sabotage my efforts. She’d cancel or delay software projects of mine that were ready to move to testing, that I’d already run past focus groups that I formed myself. She told me that people didn’t want that, they wanted some other thing that was crappy.

Then the bad bad news happened. We found out that all my projects my boss had mothballed were being shown to people outside the company — by my boss. My prototypes were being touted as “ready to roll into production” and “the future of the company” to outside buyers that eventually did buy Providian and laid off much of the workforce. I left before that happened, though. I felt like I was working for a traitor.

When I turned in my notice, it wasn’t long before someone had told Irv about my boss essentially driving me out of the company and misrepresenting / stealing my work (which was the company’s intellectual property, even). Things didn’t turn out well for her.

For my next job, I wanted a clean break. Something else to do. So I left town, and took a job a couple hundred miles north, in Fort Wayne, Indiana.

Go back to Part 3: Floor Show or onto Part 5: Wire Transfer

CompassioNote

“It’s sort of a cross between MacGyver and Shark Tank.”

This weekend, I built a new company with people I didn’t know.

It’s all part of the amazing event that is Startup Weekend. This happens in cities around the world every weekend.

This is my third time participating in a Startup Weekend, and my team won first place!

Startup Weekend

Startup Weekend Louisville #8

If you’ve never been to a Startup weekend, I recommend it.

A hundred or so people get together and pitch ideas to each other on Friday night, then we gather around the ones we like the best. We spend Saturday researching, building, and talking to potential customers to see if the idea is one that people want. Then we spend Sunday polishing it up to we can present our final 5-minute pitches to a panel of judges, who make their decision based on factors such as team-to-customer interviews, a working prototype, ongoing viability, and potential market size.

It’s sort of a cross between MacGyver and Shark Tank.

We all start with nothing but ideas, and after 54 hours of feverish activity, one team walks away on top.

I love doing it because it’s a great way to meet to people, hear new ideas, work on a short-term project that excites you, learn a new methodology or industry or technology, and have a final product of some sort to show when you’re done.

CompassioNote

(L to R): John Davenport, Kartik Kamat, Dave Mattingly, Aaron Price, Mihir Kotwal

Keep up with #SWLou and #StartupWeekend to stay involved.

CompassioNote

Our team initially started off with a sad story that we didn’t want to see repeated.

Kartik Kamat told us that his retired friend and mentor had passed away, but that he didn’t hear about it until well after. Kartik’s pitch was that we’d build a tool to notify us as soon as there’s an obituary for our friends and loved ones that we don’t have daily contact with.

Many of us had similar experiences, and we formed a team to help.

Here’s a video that our teammate Aaron recorded, to explain his own experience, to help us get the concept across to our potential customers and to garner their feedback.

Aaron Price for CompassioNote

A 45-second video explaining the problem, and our solution.

We found that the idea resonated with a lot of people, and although we originally envisioned our target customer as HR departments that would want to keep track of former employees (after all, if someone has been there a long time and made a lot of friends, they probably want to hear about it after the employee had retired). But we found out that HR tended to care more about current employees than former ones, and suggested that sales teams would be more interested.

That was our lightbulb moment. Imagine being a salesperson with a list of a few hundred clients and a few thousand prospects. If one of them passes away, you’d at least like the option to send a card or flowers. Providing personal service like that, when it’s most needed, can cement a lifelong customer relationship.

We pivoted our efforts, and found that we can purchase obituary information for the entire country, and integrate it with professional sales tools like Salesforce, Microsoft Dynamics, Goldmine, and others.

We built a personal-use web version (that you can try here), to make sure we had a functional process, but we expected that the real money would come in from professionals whose careers are built upon relationships with very large numbers of people.

CompassioNote Pitch

The winning pitch!

Eleven Startups Enter… One Startup Leaves!

You can watch every pitch here (we all had five minutes to speak, and three minutes to answer questions from the judges).

Or you can skip to just our winning pitch here.

Coming Next

One of the prizes was automatic entry into a much bigger contest, so we’re gearing up for that.

While we do, we’re juggling dozens of other tasks to which I won’t get into just now, but I’m sure I’ll cover later.

Please sign up on our website, like our page on Facebook, follow us on Twitter, and connect to us at LinkedIn.

Video Games

Louisville has a fairly strong video game community.

Besides the various places that rent or sell games, like you can find anywhere, there are businesses, groups, and events geared around gaming.

Louisville Arcade Expo
Louisville Arcade Expo

If you like playing arcade and pinball games, or even classic console games, this is the event for you.

Every year, hundreds of gaming machines and thousands of attendees gather for days of flashes and beeps. Some national championships are even held at the event.

There are vendor tables with game cartridges, comic books, clothing, and other related merchandise.

There are two costume contests, including one just for the kiddos, and seminars from industry professionals.

The expo is a nonprofit event run by a group of friends and coworkers. Proceeds go to charity, usually Kosair Children’s Hospital.

It’s a fun way to spend a weekend. The flat fee at the door makes sure you don’t need to carry around pocketfuls of quarters.

SimCave

The SimCave is a new venue with an interactive dance floor, and two octagonal rooms with giant screens on its walls and a ring of seats in its center.

It can be rented for birthday parties and corporate events, or just enjoyed an individuals.

They have hundreds of video games in stock, or you can bring your own.

The Rec Bar

It hasn’t opened yet, but the Rec Bar will include video games, pinball, board and card games, and other types of recreation. Plus edibles and potables.

Warp Zone

Warp Zone is a coworking space dedicated to developing games.

Similar to iHub, The Park, LVL1, Xlerate Health, Chef Space, Warp Zone lets game developers share an office, tips and tricks, and fellowship. Plus, y’know, they play each others games a lot.

I love that Warp Zone is here, since it has the ability to really propel Louisville’s video gaming future.

Game Dev Louisvillegdl

This monthly game development group is a wonderful place to learn how to get started in game development.

They offer occasional classes, and plenty of time to compare notes with other game developers.

More Stuff to Do

 

 

Tech Community Events

“In the spring, a young man’s fancy turns to thoughts of tech…”

That’s not quite how Tennyson wrote it, but he would have, if he’d lived in Louisville at a time when coders, hackers, designers, and other geeks and nerds offer such a remarkable smorgasbord of creative techie activities. That’s my story, anyway.

Here are a few specific events that you can become a part of, plus some other cool ones further down the screen.

Code Across

Code Across America

The fifth annual Code Across is a volunteer event for civic hacking.

What is civic hacking, you ask? It’s “hacking” in the good sense, to improve something, not to break down. Code for America

Over the course of one day, coders and designers pitch ideas and settle into teams. They create an app, a site, or something else. At the end of the afternoon, they present what they’ve created and give it away to the world. There are even snacks and prizes.

It’s a great way to make friends, learn a new approach, work together, create or solve something, gain experience, and help the community.

Some cool projects we’ve done in the past include:Code Louisville

  • a pet adopter that helps you find the animal you want at a shelter close to you
  • a restaurant recommender which takes into account health scores, nearby crime, and reviews
  • a park amenities locator, to find the nearest potty while you’re on that hike

This year, the event will be held at Code Louisville, 252 E Market St, Louisville, KY 40202.

Keep June 4, 2016 open on your calendar for the National Day of Civic Hacking, also a Code for America event.Civic Data Alliance

Our local “Code for America Brigade” is the Civic Data Alliance. We advocate to make government data open and transparent, so that everyone can learn from it. We also host hackathons and educational sessions.

Startup Weekend

Startup Weekend

Louisville’s Startup Weekend is a twice annual volunteer event for business idea creation.

Similar to Code Across, people gather, pitch ideas, form into teams, work, then show their results at the end.

The difference here is that the projects tend to be entrepreneurial, with an ongoing sustainable profit plan. This one is 54-hours long (Friday afternoon through Sunday afternoon), with judges and valuable prizes. On Sunday, teams show off their creations to compete for valuable prizes.

Our local Startup Weekend has gotten some national attention. Lat year, more women than men participated. And the winning team was led by a high school girl!

Projects we’ve had in the past include:

  • Moov — Uber for pickup trucks
  • MixxThis — an easier way to process your drink orders
  • Foodinary — an app to explain the ingredients in your meal

This year, the event will take place at the UofL School of Business.

A lot of the movers and shakers of the local business and tech scenes help out with and attend these.

There is a modest fee to attend this one, but I believe it’s well worth it. I’ve attended four startup weekends so far.

Here’s my post about last year’s event.

Other Events

Here are even more ways that you, too, can join in on the fun.

Leadership

  • 3/11 – Nonprofit Leadership Network
    • American Printing House for the Blind, 1839 Frankfort Ave
    • If you work with any volunteer or charity group, the KNN can keep you abreast of resources, policies, and happenings.

 Social/Networking

Learning/Sharing

  • 2/26 – Lean Coffee
    • Press, 252 E Market St
    • Lean Coffee is a cool way of meeting in which the agenda is created during the meeting itself.

Robots/Drones

Games/Entertainment

  • 3/4-3/6 – Louisville Arcade Expo
    • Ramada Plaza, 9700 Bluegrass Parkway
    • Play Pac-Man, pinball, and hundreds of other games all weekend! Proceeds go to the children’s hospital.

Fandom/Comics/Gaming

  • 3/26 – Random Fandom Con
    • Louisville Public Library, 9725 Dixie Highway
    • Meet other fans of comics, anime, sci-fi, fantasy, horror, and other fun nerdy pursuits.
  • 4/8 – ConGlomeration
    • Ramada Plaza, 9700 Bluegrass Parkway
    • ConGlomeration is Louisville’s oldest and friendliest science fiction con. Highly recommended. The weekend includes expert panels, costumes, gaming, music, and food.

Shopping

Keep in Touch

Want to stay in the loop about events like this? There are several ways that you can do that.

 

Cool Job: Floor Show

Rug

Rug

I’ve done a lot of things for a living over the years, and after working with outer space and virtual reality I dove into the creative half of my brain. I was an artist before switching to math and tech, and I combined my art background and my programming background by working at Khazai Rug Gallery.

Cool Job, Part 3: Floor Show

The oriental rug industry certainly seems like an odd fit for developing custom software, but there was a small market of companies that needed to be able to design rugs on the computer quickly. This was back in the days of Windows 3.1. The software was essentially a cleverly disguised MS Paint, with some custom add-ins that we’d written.

Zoom

Close-Up

What we created was a very primitive version of the modern photoshop. It could do a variety of common image tricks, and some that were more useful for rugs than for general images like copying and flipping rug sections (take take a corner design and mirror it into a full rug), simplify the colors (to use fewer yarn colors), and such. It could even randomize some of the threads to create “mistakes” in the weaving, making them more quaint and obviously hand-woven, right?

The end result was that the software would spit out a “rug map” — the thread-by-thread instructions for how to weave that particular rug. The rug map was made up of large colored squares, that individual craftsmen would use as a guide. If you’ve ever seen a cross-stitch pattern book, it’s sort of like that.

Map

Rug Map

It was cool to travel to various rug design firms and demo the software. (I found out that New York City has a “rug district” where everybody who’s anybody in rug design had to have a building. Who knew?) I even got to use my art skills as a contractor designing rugs for a few weeks at such a place in Atlanta.

Mad Skillz

Thanks to writing this software, I gained the geek skill to look at any color, and take a pretty good guess to its hex value.

Color Chart

Roses are FF0000,
Violets are 0000FF

In a computer, colors are based on red/green/blue combinations, with values going from 0 to 255 (or 00 to FF in hexadecimal terms). So pure red would be FF0000, green would be 00FF00, and blue 0000FF. White is FFFFFF (all the colors at once), and black is 000000. All other colors fall somewhere between 00 and FF in those three

My color-hexing skill has waned over the years, but by guesstimating the RGB makeup of a color, I can still come relatively close much of the time. I’m told that many professional artists and designers can do the same thing with pantone colors (another way to uniquely identify a color).

Full Circle

The original way of writing computer software was through a series punch cards, similar to the way that a player piano plays music from rolls.

Loom Punch Cards

Loom Punch Cards

What’s cool is that the idea of punch cards actually came from the weaving industry. So that means the software I wrote could be used to control the predecessor of computers. As Homer & Jethro once sang, “I’m My Own Grandpaw.”

The Louisville Science Center has a kiosk showcasing that software project. The similarity between pixels and thread maps is a strong one, and finding the right match from one technology to another is still a force for innovation. “I think I see a pattern here.”

Go back to Part 2: Wolf3D or on to Part 4: Corporate Agent

Spatial Data, Part 6: Cleveland

This is followup to my part five series on spatial data:

At SQL Saturday Cleveland 473, I showed some Ohio- and Cleveland-specific examples.

Downloading the Cleveland Data

You can download the scripts and data input files here at the event page, or individually below.

Importing the Cleveland Data

Querying the Cleveland Data

This query joins those tables together into a single spatial result.

select '' name, geometry::Point(-81.935191, 41.470970, 0).STBuffer(.08).STBoundary() geom union all 
select isnull(nullif(name,''),type), geom from cle_roads union all 
select isnull(nullif(name,''),type), geom.STBoundary() from cle_landuse union all 
select isnull(nullif(name,''),type), geom.STBoundary() from cle_natural union all 
select isnull(nullif(name,''),type), geom from cle_railways union all 
select isnull(nullif(name,''),type), geom.STBoundary() from cle_waterways union all 
select isnull(nullif(name,''),type), geom.STBuffer(.00002) from cle_points union all 
select isnull(nullif(name,''),type), geom from cle_buildings

Spatial Results

Let’s break the script down:

  • the first line in the script draws the big circle around the area.
  • the other lines bring in the geom field from each table (either the whole object or just its outline via STBoundary).
  • the nullif lets us convert any blank into nulls, which lets us use ifnull to insert another value, essentially giving us the name column unless it is blank or null, in which case it gives us the type column

From here, we can:

  • zoom in for more detail
  • hover over a building, road, or other feature to see its name or other column
  • display a label on the results
  • apply filters to only show parts of the data
  • change the widths of the features by changing the STBuffer
  • do lots of other cool stuff

Digging Deeper

To download the data for your entire state, go to download.geofabrik.de (or a variety of other geodata sites), and drill down to the state or other area you’d like.

Download the .shp.zip file, then unzip the contents and import them using Shape2Sql.

 

 

Cool Job: Wolf3D

I’ve done a lot of things for a living over the years, and my next job after NASA was also one of the coolest.

Cool Job, Part 2: Wolf3D

After getting the human race back into outer space, I helped get us into virtual space.Wolfenstein 3D Intro

I took a job at a startup virtual reality company back in 1992, I believe. Alternate Worlds Technology (AWT), which would eventually become Agora Interactive.

Wolfenstein 3D was the most popular PC game at the time, by a longshot. I recommend the book (or audiobook) Masters of Doom for an excellent history on the game, the creators, and the culture. Id Software was on my (very) shortlist of game companies that I’d have loved to work for. A group of friends made games that were so good, they earned millions each year from shareware (a “pay what you like” business model), which was completely unheard of.

The Reality Rocket was a sit-down arcade game cabinet that could take any PC game, and pump it into a VR headset. Players could see the gamescape as they ran down the hall attacking bad guys. They could also use the helmet to turn their heads to see around corners and such.Reality Rocket

My part of this project was to take that amazingly cool game, and reprogram the software so it would work with a virtual reality helmet, which I did.

I also got to use my artistic skills to create new graphics and to “skin” the game differently just as that idea was beginning to grab hold of the developer community.

The technology and the game cabinet had the potential to go far, but a few things got in the way. First, the VR tech wasn’t quite ready for long-term usage by most people. The graphics were low-resolution (CGA), and many people (5 to 10%) experienced some motion sickness. Second, the project’s financial backer had some… problems with law enforcement.

I’m glad I got to work on such a cool project that let me help advance the state of the industry.Wolfenstein 3D Play

But around that time, I was beginning to lose my taste for electronic games. At first, I’d considered game development to be a programmer programming a game. But over time, I felt more like the game was programming the gamers, and the whole experience began to sour for me. Even now, I’ll play some word games here and there on my phone, but my days of electronic action gaming are decades-long gone.

Go back to Part 1: NASA or on to Part 3: Floor Show

Spatial Data, Part 5: Resources

This is part five in a series:

The things we’ve looked at over the last few lessons come from things that I’ve picked up from the people and places that I mention here.

Resources

1. Smart People

Much of what I’ve learned, I learned from these folks:

2. Recursion and Fractals

Simon Greener shows how to make a circle that’s made of circles, with text showing their position. The whole Spatial DB Advisor is filled with amazing tricks.

Alastair Aitchison shows have to draw recursive triangles.

Slava Murygin shows how to make recursive snowflakes.

Recursive Circles Fractal TriangleSnowflake

3. Artwork

Alex Whittles shows how to convert a vector image into geospatial data.

Click these images to see how to make Grinch, a Christmas tree with proper coloring, one with random ornaments, Venus, or a hotel floorplan.

Grinch Colored Tree Random Tree Venus Floorplan

4. Utilities

SQL Magazine offers a quite of utilities to handle a variety of graphic and charting situations.

Download here.

5. Color Palette

The default color scheme that SQL uses doesn’t always fit the bill. But by specifying the order of the items you display, you can control which one gets which color.

;with n(x) as (select 0 union all select x+1 from n where x < 99)
select cast(x as varchar) label,
geometry::Point(x%10,x/10,0).STBuffer(.5)
from n order by x

The palette ends up looking like this.

Colors

6. Finding Geospatial Data

There are many collections of geospatial data available for free (and many more for pay). Being a cheapskate myself, I tend to stick with free as much as possible.

Search for terms like shapefile, geospatial, data, and the region (Kentucky, etc.) and the type of data (geography, roads, elevation, demographics, roads, etc.) that you’re interested in.

I generally prefer to work with .SHP shapefiles, but there are a number of filetypes out there. KML (Keyhole Markup Language) is another popular one.

When I get specific local data including buildings (like I did for MTSU in Part 2), I prefer to use the service at bbbike.org, but MapSys gives an overview of the various ways to find and import geospatial data.

7. Loading Geospatial Data

The tool I prefer for load the data is Shape2SQL from SharpGIS. It’s lightweight and easy to use, and the instructions should handle whatever troubles you might run into.

The one thing to keep in mind is that if you’re loading geographical data, you’ll need to switch the datatype and pick and SRID (usually the default of 4326).

Shape2SQL

8. A Parting Gift

For a little fun, run this select:

select convert(geometry,'multipolygon (((0.0193705 0.678262, 0.0871671 0.678262, 0.164649 0.290852, 0.251816 0.629835, 0.329298 0.629835, 0.416465 0.281167, 0.493947 0.678262, 0.552058 0.678262, 0.455206 0.194, 0.377724 0.194, 0.290557 0.562039, 0.184019 0.194, 0.106538 0.194, 0.0193705 0.678262), (0.59037 0.678262, 0.658167 0.678262, 0.735649 0.290852, 0.822816 0.629835, 0.900298 0.629835, 0.987465 0.281167, 1.06495 0.678262, 1.12306 0.678262, 1.02621 0.194, 0.948724 0.194, 0.861557 0.562039, 0.755019 0.194, 0.677538 0.194, 0.59037 0.678262), (1.16137 0.678262, 1.22917 0.678262, 1.30665 0.290852, 1.39382 0.629835, 1.4713 0.629835, 1.55847 0.281167, 1.63595 0.678262, 1.69406 0.678262, 1.59721 0.194, 1.51972 0.194, 1.43256 0.562039, 1.32602 0.194, 1.24854 0.194, 1.16137 0.678262), (1.93576 0.329593, 2.06167 0.329593, 2.06167 0.203685, 1.93576 0.203685, 1.93576 0.329593), (2.70046 0.901022, 2.77795 0.901022, 2.77795 0.194, 2.70046 0.194, 2.70046 0.290852, 2.64235 0.223056, 2.59393 0.194, 2.56487 0.184315, 2.50676 0.184315, 2.46802 0.194, 2.42928 0.223056, 2.39054 0.271482, 2.36148 0.368334, 2.36148 0.465186, 2.38085 0.552354, 2.40991 0.610465, 2.45833 0.658891, 2.49707 0.678262, 2.52613 0.687947, 2.59393 0.687947, 2.64235 0.668576, 2.70046 0.62015, 2.70046 0.901022), (2.70046 0.562039, 2.70046 0.348964, 2.62298 0.271482, 2.58424 0.252111, 2.52613 0.252111, 2.48739 0.281167, 2.46802 0.310223, 2.44865 0.368334, 2.44865 0.484557, 2.46802 0.542668, 2.48739 0.581409, 2.51645 0.610465, 2.5455 0.629835, 2.60361 0.629835, 2.65204 0.60078, 2.70046 0.562039), (2.95185 0.658891, 3.01965 0.678262, 3.06807 0.687947, 3.17461 0.687947, 3.21335 0.678262, 3.25209 0.658891, 3.27146 0.629835, 3.29083 0.571724, 3.29083 0.271482, 3.30052 0.252111, 3.31989 0.242426, 3.35863 0.242426, 3.36832 0.203685, 3.32958 0.184315, 3.29083 0.184315, 3.25209 0.203685, 3.22304 0.252111, 3.1843 0.223056, 3.12619 0.194, 3.08745 0.184315, 3.02933 0.184315, 2.99059 0.194, 2.96154 0.21337, 2.93248 0.242426, 2.91311 0.290852, 2.91311 0.348964, 2.93248 0.39739, 2.98091 0.445816, 3.01965 0.465186, 3.08745 0.484557, 3.21335 0.484557, 3.21335 0.562039, 3.19398 0.60078, 3.14556 0.629835, 3.06807 0.629835, 3.00996 0.610465, 2.95185 0.581409, 2.95185 0.658891), (3.21335 0.436131, 3.12619 0.436131, 3.06807 0.41676, 3.02933 0.39739, 3.00028 0.348964, 3.00028 0.300538, 3.01965 0.271482, 3.05839 0.242426, 3.10682 0.242426, 3.16493 0.261797, 3.21335 0.300538, 3.21335 0.436131), (3.46474 0.678262, 3.55191 0.678262, 3.71656 0.281167, 3.88121 0.678262, 3.95869 0.678262, 3.74561 0.194, 3.66813 0.194, 3.46474 0.678262), (4.49579 0.41676, 4.15681 0.41676, 4.15681 0.368334, 4.17618 0.329593, 4.19555 0.300538, 4.24397 0.261797, 4.30208 0.242426, 4.37957 0.242426, 4.42799 0.252111, 4.49579 0.271482, 4.49579 0.21337, 4.42799 0.194, 4.36988 0.184315, 4.28271 0.184315, 4.23429 0.194, 4.16649 0.223056, 4.11806 0.261797, 4.08901 0.310223, 4.06964 0.378019, 4.06964 0.474872, 4.07932 0.523298, 4.09869 0.571724, 4.14712 0.629835, 4.19555 0.668576, 4.26334 0.687947, 4.34083 0.687947, 4.39894 0.668576, 4.43768 0.639521, 4.46673 0.60078, 4.4861 0.552354, 4.49579 0.494242, 4.49579 0.41676), (4.40862 0.474872, 4.15681 0.474872, 4.16649 0.523298, 4.18586 0.562039, 4.2246 0.610465, 4.26334 0.629835, 4.32145 0.629835, 4.3602 0.610465, 4.38925 0.581409, 4.40862 0.532983, 4.40862 0.474872), (4.62127 0.678262, 4.68906 0.678262, 4.68906 0.581409, 4.72781 0.639521, 4.76655 0.678262, 4.78592 0.687947, 4.83434 0.687947, 4.8634 0.658891, 4.88277 0.62015, 4.89245 0.581409, 4.92151 0.629835, 4.95057 0.668576, 4.98931 0.687947, 5.02805 0.687947, 5.0571 0.668576, 5.07647 0.639521, 5.08616 0.591094, 5.08616 0.194, 5.01836 0.194, 5.01836 0.591094, 4.98931 0.62015, 4.96994 0.62015, 4.9312 0.581409, 4.89245 0.513613, 4.89245 0.194, 4.82466 0.194, 4.82466 0.591094, 4.7956 0.62015, 4.77623 0.62015, 4.71812 0.562039, 4.68906 0.513613, 4.68906 0.194, 4.62127 0.194, 4.62127 0.678262), (5.23585 0.658891, 5.30365 0.678262, 5.35207 0.687947, 5.45861 0.687947, 5.49735 0.678262, 5.53609 0.658891, 5.55546 0.629835, 5.57483 0.571724, 5.57483 0.271482, 5.58452 0.252111, 5.60389 0.242426, 5.64263 0.242426, 5.65232 0.203685, 5.61358 0.184315, 5.57483 0.184315, 5.53609 0.203685, 5.50704 0.252111, 5.4683 0.223056, 5.41019 0.194, 5.37145 0.184315, 5.31333 0.184315, 5.27459 0.194, 5.24554 0.21337, 5.21648 0.242426, 5.19711 0.290852, 5.19711 0.348964, 5.21648 0.39739, 5.26491 0.445816, 5.30365 0.465186, 5.37145 0.484557, 5.49735 0.484557, 5.49735 0.562039, 5.47798 0.60078, 5.42956 0.629835, 5.35207 0.629835, 5.29396 0.610465, 5.23585 0.581409, 5.23585 0.658891), (5.49735 0.436131, 5.41019 0.436131, 5.35207 0.41676, 5.31333 0.39739, 5.28428 0.348964, 5.28428 0.300538, 5.30365 0.271482, 5.34239 0.242426, 5.39082 0.242426, 5.44893 0.261797, 5.49735 0.300538, 5.49735 0.436131), (5.9037 0.765429, 5.98119 0.765429, 5.98119 0.668576, 6.20395 0.668576, 6.20395 0.610465, 5.98119 0.610465, 5.98119 0.300538, 6.01024 0.261797, 6.06835 0.242426, 6.16521 0.242426, 6.21363 0.252111, 6.21363 0.194, 6.14583 0.184315, 6.02961 0.184315, 5.96182 0.203685, 5.93276 0.232741, 5.91339 0.261797, 5.9037 0.310223, 5.9037 0.610465, 5.7778 0.610465, 5.7778 0.668576, 5.9037 0.668576, 5.9037 0.765429), (6.4747 0.765429, 6.55219 0.765429, 6.55219 0.668576, 6.77495 0.668576, 6.77495 0.610465, 6.55219 0.610465, 6.55219 0.300538, 6.58124 0.261797, 6.63935 0.242426, 6.73621 0.242426, 6.78463 0.252111, 6.78463 0.194, 6.71683 0.184315, 6.60061 0.184315, 6.53282 0.203685, 6.50376 0.232741, 6.48439 0.261797, 6.4747 0.310223, 6.4747 0.610465, 6.3488 0.610465, 6.3488 0.668576, 6.4747 0.668576, 6.4747 0.765429), (7.16677 0.901022, 7.27331 0.901022, 7.27331 0.794484, 7.16677 0.794484, 7.16677 0.901022), (7.00212 0.678262, 7.26362 0.678262, 7.26362 0.194, 7.18614 0.194, 7.18614 0.62015, 7.00212 0.62015, 7.00212 0.678262), (7.51501 0.678262, 7.59249 0.678262, 7.59249 0.581409, 7.63123 0.629835, 7.67966 0.668576, 7.73777 0.687947, 7.79588 0.687947, 7.83462 0.678262, 7.87336 0.649206, 7.89273 0.610465, 7.90242 0.571724, 7.90242 0.194, 7.82494 0.194, 7.82494 0.552354, 7.80557 0.591094, 7.76683 0.610465, 7.7184 0.610465, 7.66997 0.591094, 7.59249 0.513613, 7.59249 0.194, 7.51501 0.194, 7.51501 0.678262), (8.42499 0.678262, 8.49279 0.678262, 8.49279 0.203685, 8.4831 0.145574, 8.46373 0.0971477, 8.43468 0.0584068, 8.39594 0.0293511, 8.34751 0.00998063, 8.29908 0.0002954, 8.21192 0.0002954, 8.16349 0.00998063, 8.11506 0.0196659, 8.11506 0.0874625, 8.18286 0.068092, 8.23129 0.0584068, 8.30877 0.0584068, 8.3572 0.0777772, 8.38625 0.106833, 8.41531 0.155259, 8.41531 0.300538, 8.37657 0.252111, 8.32814 0.21337, 8.27971 0.194, 8.21192 0.194, 8.16349 0.21337, 8.11506 0.252111, 8.08601 0.300538, 8.06664 0.368334, 8.06664 0.474872, 8.08601 0.552354, 8.12475 0.62015, 8.18286 0.668576, 8.24097 0.687947, 8.30877 0.687947, 8.37657 0.658891, 8.42499 0.62015, 8.42499 0.678262), (8.41531 0.562039, 8.41531 0.358649, 8.37657 0.310223, 8.33783 0.281167, 8.2894 0.261797, 8.25066 0.261797, 8.20223 0.290852, 8.17318 0.329593, 8.15381 0.39739, 8.15381 0.474872, 8.16349 0.523298, 8.19255 0.581409, 8.25066 0.629835, 8.31845 0.629835, 8.36688 0.60078, 8.41531 0.562039), (8.71512 0.901022, 8.98631 0.901022, 8.98631 0.194, 8.90883 0.194, 8.90883 0.84291, 8.71512 0.84291, 8.71512 0.901022), (9.17958 0.678262, 9.26675 0.678262, 9.4314 0.310223, 9.59605 0.678262, 9.66384 0.678262, 9.40234 0.0874625, 9.3636 0.0390363, 9.32486 0.0196659, 9.27644 0.00998063, 9.20864 0.00998063, 9.20864 0.068092, 9.28612 0.068092, 9.32486 0.0971477, 9.38297 0.21337, 9.17958 0.678262), (9.92976 0.329593, 10.0557 0.329593, 10.0557 0.203685, 9.92976 0.203685, 9.92976 0.329593), (10.37 0.678262, 10.4475 0.678262, 10.4475 0.581409, 10.4862 0.629835, 10.5347 0.668576, 10.5928 0.687947, 10.6509 0.687947, 10.6896 0.678262, 10.7284 0.649206, 10.7477 0.610465, 10.7574 0.571724, 10.7574 0.194, 10.6799 0.194, 10.6799 0.552354, 10.6606 0.591094, 10.6218 0.610465, 10.5734 0.610465, 10.525 0.591094, 10.4475 0.513613, 10.4475 0.194, 10.37 0.194, 10.37 0.678262), (11.3478 0.41676, 11.0088 0.41676, 11.0088 0.368334, 11.0282 0.329593, 11.0475 0.300538, 11.096 0.261797, 11.1541 0.242426, 11.2316 0.242426, 11.28 0.252111, 11.3478 0.271482, 11.3478 0.21337, 11.28 0.194, 11.2219 0.184315, 11.1347 0.184315, 11.0863 0.194, 11.0185 0.223056, 10.9701 0.261797, 10.941 0.310223, 10.9216 0.378019, 10.9216 0.474872, 10.9313 0.523298, 10.9507 0.571724, 10.9991 0.629835, 11.0475 0.668576, 11.1153 0.687947, 11.1928 0.687947, 11.2509 0.668576, 11.2897 0.639521, 11.3187 0.60078, 11.3381 0.552354, 11.3478 0.494242, 11.3478 0.41676), (11.2606 0.474872, 11.0088 0.474872, 11.0185 0.523298, 11.0379 0.562039, 11.076599999999999 0.610465, 11.1153 0.629835, 11.1735 0.629835, 11.2122 0.610465, 11.2413 0.581409, 11.2606 0.532983, 11.2606 0.474872), (11.6137 0.765429, 11.6912 0.765429, 11.6912 0.668576, 11.9139 0.668576, 11.9139 0.610465, 11.6912 0.610465, 11.6912 0.300538, 11.7202 0.261797, 11.7784 0.242426, 11.8752 0.242426, 11.9236 0.252111, 11.9236 0.194, 11.8558 0.184315, 11.7396 0.184315, 11.6718 0.203685, 11.6428 0.232741, 11.6234 0.261797, 11.6137 0.310223, 11.6137 0.610465, 11.4878 0.610465, 11.4878 0.668576, 11.6137 0.668576, 11.6137 0.765429)))',0)

 

Cool Job: NASA

Challenger

Oh, the humanity!

I’ve done a lot of things for a living over the years, and one of my first was also one of the coolest.

Cool Job, Part 1: NASA

On 1/28/86, the space shuttle Challenger blew up.

Later that year, I got a call from NASA with a job offer, which I accepted. Over the phone. They didn’t realize I had an orange mohawk. I was still a teenager, after all. Ya gotta live.

A few months after that, I moved down to Florida to work at Kennedy Space Center, where I worked in the Mission Planning Office and helped write the software that scheduled shuttle launches, landings, and maintenance.

NASA's Trailer Park

Capt. Kirk: “No, I’m from Iowa. I only work in outer space.”

I got a haircut before starting, and looked like a real person. But before long, I was back to my old cranial tricks.

My office is visible in all of the footage used in the movies. That one giant building that’s always shown is the VAB – the Vehicle Assembly Building. It’s the mechanic’s garage where the shuttle goes for its oil changes and other maintenance.

My job was actually in NASA’s “Trailer Park.” There were some old railroad cars pushed together sideways with the open sliding doors lined up, making a large single office with branching rooms, sort of. It was a cheap way to use old equipment to make something new-ish. It was air-conditioned, carpeted, and otherwise very nice inside, but I found it amusing that it was practically made of garbage.

When we went back into space the following year, I got to stand on my office rooftop to watch the launch. The vibrations shook my whole body. It was amazing.

I didn’t like Florida, so once we got back into space, I considered my work done, and I moved a thousand miles north so I could do some other nifty tech stuff instead. More on that in my next cool job installment.

Space Shuttle

The stars look very different today.

But writing space shuttle software for NASA as a teenager is certainly a powerful feather in anyone’s geek cred hat.

Go on to Part 2: Wolf3D

Spatial Data, Part 4: Data Sets

This is part four in a series:

Besides just looking around at geographical features like states, roads, and buildings, we can incorporate human-centric data like restaurants, crimes, and more.

Data Sets

1. Toxic Release Inventory

A “TRI” as reported by the EPA is a Toxic Release Inventory. This could be a chemical spill or some other accident that’s not in our best health interests. Here are the incidents that took place in Kentucky over a ten-year period.

select geometry::CollectionAggregate(geom)
from ky_counties
union all
select geom.STBuffer(.05)
from ky_tri
where geom.STWithin((select geom from us_stateshapes where state = 'KY')) = 1

The EPA offers an interactive map of TRI’s around the country here.

TRIs in KY

2. Toxic Incidents in Jefferson County

select geometry::CollectionAggregate(geom).STBuffer(.001)
from ky_interstates where geom.STWithin((select geom from ky_counties where id = 24)) = 1
union all 
select geometry::CollectionAggregate(geom) from ky_counties where id = 24
union all
select geom.STBuffer(.01) from ky_tri where geom.STWithin((select geom from ky_counties where id = 24)) = 1

Bringing it close to home, here are the incidents that have taken place in my own hometown of Louisville, KY.

TRIs in Jefferson County

3. Add in the Sirens

select geometry::CollectionAggregate(geom).STBuffer(.001)
from ky_interstates where geom.STWithin((select geom from ky_counties where id = 24)) = 1
union all 
select geom from ky_counties where id = 24
union all
select geometry::UnionAggregate(geom.STBuffer(.01)) from ky_tri where geom.STWithin((select geom from ky_counties where id = 24)) = 1
union all
select geometry::UnionAggregate(geom.STBuffer(.02)) from ky_sirens

The siren radius is an estimate, since the hearing distance can depend on a lot of factors. Still, it’s disturbing to see that there are some parts of the county that have had several incidents but have no sirens for tens of miles. The I-65 corridor on the southern half of Louisville has its share of problems, but no active alert system.

TRIs with Sirens

4. Toxic Incidents per County

;with tox (id, ct) as
(select c.id, count(*) from ky_counties c join ky_tri t on c.geom.STContains(t.geom) = 1 group by c.id)
select c.geom, isnull(tox.ct,0) Incidents
from ky_counties c
left outer join tox on c.id = tox.id

By counting the number of incidents per county in a CTE, and joining that to the county map, we can display that number on the SQL map.

On the good side, it’s good to see that there are several counties with zero incidents; on the bad side, 73 in my county? Ouch.

TRIs per County

5. Toxic Incident Range Bands

select geometry::CollectionAggregate(geom), '0' Incidents
from ky_counties c where c.id not in (select id from tox) union all
select geometry::CollectionAggregate(geom), '< 5'
from ky_counties c inner join tox on tox.id = c.id where tox.ct < 5 union all
select geometry::CollectionAggregate(geom), '5 - 10'
from ky_counties c inner join tox on tox.id = c.id where tox.ct between 5 and 10 union all
select geometry::CollectionAggregate(geom), '11 - 25'
from ky_counties c inner join tox on tox.id = c.id where tox.ct between 11 and 25 union all
select geometry::CollectionAggregate(geom), '> 25'
from ky_counties c inner join tox on tox.id = c.id where tox.ct > 25

Seeing the individual numbers is informative, but divvying up the data into range bands can make it easier to find patterns and trends.

TRIs with Range Bands

Since we aggregated the counts into just five range bands, they’re considered just five objects, and therefore only five labels appear.

The southeast part of the state looks pretty good, with mostly light blue zeros and a scattering of tan lows. There’s an almost solid dark blue of tens riding up along I-75. And, if I had to present this kind of bad news to my boss, you can see that I’ve cleverly downplayed Louisville’s 73 TRIs into an “over 25” category.

6. Low Food Scores

;with s (id, dt) as
(select establishmentid, max(inspectiondate) from ky_food
where typedescription = 'food service' group by establishmentid)
select geom.STBuffer(.01) Geom, establishmentname + ': ' + convert(varchar,f.score) Name
from ky_food f 
inner join s on f.establishmentid = s.id and f.inspectiondate = s.dt
where score < 90
union all
select geometry::CollectionAggregate(geom), ''
from ky_interstates where geom.STWithin((select geom from ky_counties where id = 24)) = 1
union all
select geom.STBoundary(), '' from ky_counties where id = 24

Instead of the bad stuff that we may inadvertently breathe and drink due to industrial accidents or chemical spills, let’s look at the bad stuff that we put into our bodies on purpose. Here are the restaurant health inspection codes (usually the “A” papers that we see posted) that are not up to the A level (score < 90).

Here, I’m plotting the low-grade restaurants (using a CTE because I only want the most recent inspection date for each restaurant) around the city, and setting the hover-text to be the name and score.

Low Food Scores

The data I’m using is from early 2015. So Phi Binh Minh (and the others) might have an “A” in the window these days. Don’t take my map as a food critic review.

7. Violent Crimes in Jefferson County

select geom.STBuffer(.001), left(Crime,1) Crime, convert(varchar,IncidentDate,111) Date
from ky_crime
where geom.STWithin((select geom from ky_counties where id = 24)) = 1
and crime in ('homicide', 'aggravated assault', 'simple assault') and year(incidentdate) = 2014
union all
select geometry::CollectionAggregate(geom), null, null
from ky_interstates where geom.STWithin((select geom from ky_counties where id = 24)) = 1
union all
select geom.STBoundary(), null, null from ky_counties where id = 24

More bad news! Sorry.

Here are the violent crimes in town (thankfully, relatively few homicides) over the course of a year, with the first letter of each of those crimes in our hover-text.

Louisville Violent Crimes

The west end, downtown, and the airport region seem to have the worst of it.

8. Violent Crimes in Jefferson County with Bubble Sizes

;with siz (lat, lon, sz) as
(select latitude, longitude, count(*) size from ky_crime where crime in ('homicide', 'aggravated assault', 'simple assault') group by latitude, longitude)
select geom.STBuffer(sz * .0003) from ky_crime c 
inner join siz on c.latitude = siz.lat and c.longitude = siz.lon
where crime in ('homicide', 'aggravated assault', 'simple assault')
and geom.STWithin((select geom from ky_counties where id = 24)) = 1 and sz > 1
union all
select geometry::CollectionAggregate(geom)
from ky_interstates where geom.STWithin((select geom from ky_counties where id = 24)) = 1
union all
select geom.STBoundary() from ky_counties where id = 24

Instead of just seeing where they are, how about we highlight the dangerous parts of town by making each dot (an address where a crime happened) wider for every crime that happened there, and ignore the dots where only one crime happened. The previous maps showed us which parts of town are dangerous, but this shows us which specific places are “repeat customers” for crimes.

KY Crime Bubbles

Of course, even one violent crime is too many. And my filename for this image (KY Crime Bubbles) sounds like a street gang made up of clowns or janitors.

The underlying data shows that one of the larger circles could actually be removed. The puke-green circle around the center of the second grid square is some sort of default address for the city. The address is listed simply as “Louisville Metro.” Even so, we learn a lot by plotting our own data on a map like this.

9. Reported Crimes (Bad Geo)

select geom.STBuffer(.5), crime, convert(varchar,IncidentDate,111) Date
from ky_crime
where geom.STWithin((select geom from us_stateshapes where state = 'KY')) = 0
union all
select geometry::CollectionAggregate(geom), null, null from us_stateshapes

So far, I’ve been limited the data displayed just to what happens within Louisville/Jefferson County, but sometimes crimes get reported to the Louisville Metro Police that take place out of town.

Bad Geo

Oh, and there are a lot of crimes (32 of them, not all that many compared to the overall volume, really) that happen way out in the middle of the ocean. Actually, no. That’s location 0, 0 (one of those 0’s is the equator, and the other is the prime meridian, which is also where the GMT time zone starts). If no geodata was recorded with the incident, many systems will default it to there. For data like that, you can ignore it or correct it by geocoding it (assigning a latitude and longitude to an address). There are some services that will do that for free, for a given amount of addresses (google maps will geocode 10,000 per day, for example), and other services that will geocode for a fee.

Data Sources

Here are the data sets use for this lesson (the us_stateshapes, ky_counties, and ky_interstates have appeared previously.)

  • TRI data is here.
  • Siren, food, and crime data (and dozens of other Louisville data sets) are here.

Getting Involved

I encourage all of you to join in this year’s National Day of Civic Hacking, which is sponsored by the White House’s data.gov open data portal. It’s an annual event put on by the Code for America Brigade to build apps in a single day with other local coders / designers / data’ers, primarily based on using open data sets.

In Louisville, in the past few years, we’ve had apps that:

Your area might also have a chapter of MapTime, which uses and enhances geodata in a variety of ways.