Blog

  • ROTFLMFAO at 3am!

    I’m sitting here laughing hysterically at 3am trying not to wake the whole house.
    Found this old fail surfing youtube:

  • MySQL GIS Extensions Quick Start

    A friend is busy putting together a kick ass startup with a strong geographic component. He’s using Google Maps API version 3 which is a vast improvement (and total rewrite) from previous versions. But he needs to store and query his geographic data in a fast efficient way. There are many options out there, but if you want massive speed and scaleability you really want to use MySQL. So I’m writing this quickstart guide for his (and your) benefit.

    Most websites don’t need to do complicated things like store polygon data. They just need to store points on a map and then retrieve those points. They also need to be able to ask the database for all points within a rectangle. So I’m going to run you through schema creation, inserting data, getting your lat/lon data out of the database again, and querying the database for all points within a rectangle. We’re also going to deal with the nasty little issue of asking the database for points in a rectangle that crosses the 180 degree boundary (or the International Date Line).

    Why use MySQL’s GIS extensions?

    The main, and possibly only reason is because you want speed. You could store lat/lon coordinates as decimal degrees in MySQL. Then when you query the database you’d say “Give me all records where the lat is > X and < Y and the lon is > A and < B. But MySQL (and many other databases) is slow when you’re doing range queries like that because it can’t use it’s regular B-Tree indexes effectively for a range query.

    So instead you create a column called a geometry. Then you create an index on that column called a spatial index. This is really an R-Tree index that is very fast when you’re doing range queries.

    It’s really that simple. You want to use MySQL’s GIS because spatial indexes are faster for lat/lon range queries than regular indexes. I honestly can’t think of another reason I’d go through the effort of storing/retrieving my data using GIS functions.

    How do I create a table to store lat/lon points?

    I’m assuming you know how to create a regular table in MySQL. You create a basic table containing coordinates like so:

    CREATE TABLE geom (
      lat float(10,7) NOT NULL,
      lon float(10,7) NOT NULL,
      g GEOMETRY NOT NULL,
      SPATIAL INDEX(g)
    ) ENGINE=MyISAM;

    Firstly note that I’m storing the coordinates as decimal degrees AND in a spatial column (g). I’m a little paranoid and I like to store the source data.

    Note that I’ve specified the table type to be MyISAM. You currently can only create a spatial index on MyISAM tables. You CAN create geometry columns on other table types like InnoDB, but without a spatial index it’s going to be slow which defeates the whole point of using GIS extensions because the only reason you’re using them is SPEED. The down-side of using MyISAM is that if you’re going to be doing a lot of writes to your table (by a lot I mean more than 10 per second) then MyISAM is going to slow down because it doesn’t support row level locking. But if you’re just going to be adding a few hundred thousand records a day and doing a lot more reads than writes, then this will work just fine for you. And remember that you can always replicate this table to a small cluster of slaves and have your web servers query the slaves when you want to scale your website.

    How do I insert data into my fancy new spatial table?

    I’m going to assume you’ve figured out how to get the lat/lon coordinates you need from the Google Maps API or whatever your source is. Here’s how you insert the data:

    INSERT INTO geom (lat, lon, g) VALUES
        (47.37, -122.21, GeomFromText('POINT(47.37 -122.21)'));

    Some things to note here: The value inside the GeomFromText function is a string. So in your application you’re going to have to create that string by concatenating together ‘POINT(‘, your lat, a space, your lon and ‘)’. Then you’re probably going to prepare a statement that looks like:

    insert into geom (lat, lon, g) values
       (?, ?, GeomFromText(?))

    When you execute it you’ll pass in the decimal degrees and the string you created.

    Great, so how do I get the data back out again?

    MySQL will tell you to use the AsText function to turn that geometry point back into something your application can use or pass to the Google Maps API. But because you also stored it as decimal degrees you can just do:

    select lat, lon from geom;

    But what you really care about is getting it back out FAST! When you ask the database for all points inside a rectangle you need to define that rectangle. So if you imagine a map you need to give the database two points on that map. So we’ll use a point in the South West and a point in the North East.

    Lets say you want all points inside the rectangle where the South West point is latitude 46, longitude -123 and the North East point is latitude 48 and longitude -121. NOTE: -121 is further east than -123 degrees of longitude. Just to make it clearer:

    SW Lat: 46
    SW Lon: -123
    NE Lat: 48
    NE Lon: -121

    You’ll do the following query:

    select lat, lon from geom where
       MBRContains(
        GeomFromText('Polygon((46 -123, 48 -123, 48 -121, 46 -121, 46 -123))'),
        p
       );

    If all those numbers look a little confusing, what you’re actually doing is drawing a square (polygon) starting at the south west corner and ending back at the south west corner. A square has four corners, but you have to close the box for MySQL so you have to repeat the last coordinate. ‘p’ is the second parameter to MBRContains and it specifies which column in the table must be contained in the box you’ve created. Lets replace the coordinates with variables to make it easier to read:

    select lat, lon from geom where
       MBRContains(
        GeomFromText('Polygon((swLat swLon, neLat swLon, neLat neLon,
          swLat neLon, swLat swLon))'),
       p );

    NOTE: I had to break the above lines up for readability. You may want to have this all as a single line in your code.

    Well that’s just peachy, but what if my rectangle is in the middle of the Pacific ocean and crosses the International Date Line?

    The Earth is, unfortunately, round. If it were flat we could end the conversation here, I could get on with some work and you could do whatever it is you do on a Saturday at 11:46am mountain standard time. But the Earth is round, so you and I are stuck with each other for another few minutes.

    The reason roundness matters is because if the rectangle you are painting on Earth crosses 180 (or -180) degrees of longitude, then you need to change your logic a little. Normally your south-west longitude will be less than your north-east longitude. West is less than east. But if your square crosses the dreaded 180 boundary, then your western longitude will be greater than your eastern longitude. For example you might have a western longitude of 170 and an eastern longitude of 10 degrees.

    If you don’t deal with this little hiccup then when you ask the database for points that are inside a square that crosses the 180 boundary, then you’re going to get everything to the left and right of that square and nothing inside it. So you have to draw two squares on either side of the 180 boundary.

    You do this in your application logic. I’m going to throw a little code at you. Here goes:

    sub makeMBR {
     my ($swLat, $swLon, $neLat, $neLon) = @_;
    
     if($swLon > $neLon) {
     return (' (' .
     'MBRContains(GeomFromText(\'Polygon((' .
     $swLat . ' ' . $swLon . ',' . $neLat . ' ' . $swLon . ',' .
     $neLat . ' 180,' . $swLat . ' 180,' .
     $swLat . ' ' . $swLon .
     '))\'), g) ' .
     ' OR ' .
     ' MBRContains(GeomFromText(\'Polygon((' .
     $swLat . ' -180,' . $neLat . ' -180,' .
     $neLat . ' ' . $neLon . ',' . $swLat . ' ' . $neLon . ',' .
     $swLat . ' -180' .
     '))\'), g) ' .
     ') ', 1);
    
     } else {
     return (' MBRContains(GeomFromText(\'Polygon((' .
     $swLat . ' ' . $swLon . ',' . $neLat . ' ' . $swLon . ',' .
     $neLat . ' ' . $neLon . ',' . $swLat . ' ' . $neLon . ',' .
     $swLat . ' ' . $swLon .
     '))\'), g) ', 0);
     }
    }

    The code above is Perl. It looks horrendous but it’s actually quite simple. It creates the MBRContains() part of the SQL statement for you automatically. It simply says: If the swLon is greater than the neLon then create two boxes and ask the database for all points in both those boxes. Otherwise just create one box as per normal. The two boxes that area created are on either side of the dreaded 180 boundary.

    The function actually returns two values. The first is the MBRContains string that you can combine with the SQL in your application and feed to the database. The second value is either a 1 or a zero. A 1 indicates that the box has crossed the dreaded 180 boundary and you’re actually asking for points in 2 boxes. A zero indicates that it’s a regular single box. You may want to use this value in your application to determine how things are displayed. Generally when a box crosses the 180 boundary I tend to zoom out a little more so the user can see what’s going on.

    You’ll use this code like so:

    my ($geoSQL, $crossesIDL) = makeMBR(46, -123, 48, -121);
    #Then you'll run this query on the database:
    $dbh->selectrow_array("select lat, lon from geom where $geoSQL");

    Conclusion

    If this helped you and you’ve discovered a tip that could help others or have something to add, please post a comment. Muchos gracias, baaie dankie, dis mos lekker by die see and have a spectacular day!

    Mark.

  • NASA's little security oops

    Last night I logged on to NASA’s Mauna Kea observatory live video feed to watch LCROSS slam into the moon. After LCROSS was finished pancaking into the moon and not producing the expected 6 mile plume, I noticed an IP address flash on the top right of the video display. So I hit it with a web browser. I found this:

    NASA videoconf system

    The big green button was begging to be hit, so I did. And up came a directory:

    Picture 4

    So I made a call and holy crap the video feed for Mauna Kea stopped and switched to the call I was busy making.

    Making NASA call

    So I called “Bob’s Office” and watched Bob at his desk for a while, then I called something else and these guys showed up on the feed:

    Picture 6

    At at this point sanity took over and I realized I’m controlling a federal government video feed that probably still has a few hundred people logged on. So I Googled around for as many email addresses as I could find at AMES Research Center (@mail.arc.nasa.gov) and emailed them to let them know about their open feed. Of course NASA engineers are very busy and probably speak in formulas anyway, so they didn’t reply. But today thankfully the feed is password protected.

  • Will Twitter's lax data ownership policy result in jail time?

    Update: My real-time traffic feed says it all. 🙂 Thanks for the mention and link-love M.G. and Techcrunch.

    Two people died and 19 passed out at an Arizona sweat lodge last night. The author who hosted the event is James Arthur Ray and is an avid Twitterer. He deleted his 10 most recent tweets after the deaths, but Twitter search still has them cached. I’ve been aware of this for a while because every now and then I’ll go flying into asshole mode, post a tweet and then delete it within the hour. But it remains in Twitter search for all to see.

    But I suspect this case of losing control of your data is going to show up in court and be very high profile for Twitter. James most recent tweets are shown in the screenshot below. The two most recent tweets are the pertinent ones.

    twitter search

  • Remove GoBoingo to fix MacBook WiFi pauses, stutters, hiccups, latency, delays

    I recently upgraded our router to the Linksys WRT320N router. I set the router to only transmit on 5GHz and the performance has been awesome because all our neighbors are still on 2.4 GHz, our 2.4 GHz cordless phones don’t interfere with our WiFi anymore and because 5GHz is better at getting around corners and going through walls.

    Awesome… except on my personal MacBook.

    Earlier today  I was on a 3.5 hour skype call (!!!) and every few minutes I’d get a 1 second delay before the other side’s conversation continued. They told me the same would happen with my voice. I also use SSH on my MacBook which requires a real-time response from the server. Every minute or so I’d notice a 1 to 3 second pause in my internet connection. The WiFi didn’t drop, it just paused as if it was busy doing something, and then continued as normal.

    If you’re browsing or streaming something that pause probably won’t affect you because browsing usually has a second or two delay while DNS lookups occur etc, and streaming isn’t affected because it usually has a few seconds of content buffered. But with Skype and SSH it’s a real pain in the ass.

    After tweaking the hell out of my router’s settings including Beacon Interval, RTS Threshold etc. and trying to disable things like Interference Robustness on my MacBook I finally found the culprit.

    A little piece of software called GoBoingo was causing the problem. I launched Activity Monitor (under Applications / Utilities ) and stopped the GoBoingo process and voila! No more hiccups every 1 minute.

    I’ve seen a few reports of other background MacBook apps that monitor your WiFi that cause this exact problem. So if you’re getting stutter, hiccups, pauses, latency or delays every minute or so, kill these apps and check if that’s fixed your connection quality.

  • Home remedy to de-skunk your dog, FAST!

    Our 4 year old aussie cattle dog Joey just got skunked. My sister in law feeds left-over chicken to the local skunks and a big one arrived. We accidentally left Joey outside. Next thing the neighbor knocks on the door saying “Your dog is outside and he’s been skunked!”

    I’ve never smelled skunk before. It’s BAAAAHAAAAD!!

    So we found an old home remedy that worked unbelievably well. I’ve heard from people have tried soap, tomato juice, baking soda, vinegar and a whole bunch of other stuff and none of them work as well as this recipe.

    When you’re done, please post your skunk story in my comments!

    This recipe is for a 30 to 40 pound dog. Adjust it for your dogs weight. (For an 80 pound dog use 2 quarts peroxide etc..)

    • 1 Quart of 3% Hydrogen peroxide.
    • A quarter cup of baking soda
    • A Tablespoon of liquid soap (the kind you do the dishes with).
    • Rubber gloves and old clothes for everyone involved to wear. Seriously, if your dog got badly skunked you’re going to get some on you.
    1. Put on your old clothes and rubber gloves
    2. Mix the peroxide, baking soda and liquid soap in a small bucket. Don’t worry it won’t react or foam or anything.
    3. Wet your dog thoroughly with warm water.
    4. KEEP A SMALL AMOUNT OF SOLUTION before completing the next step.
    5. Gradually work the solution into the doggies fur. Keep it away from eyes, ears and mouths.
    6. Once you’ve worked the solution into your dog, let it stand for about 4 minutes. Your skin may itch slightly from the peroxide. Use your own comfort level to gauge how your dog is feeling – if the itching on your skin turns to burning, your dog is probably feeling the same and it’s time for the next step.
    7. Then rinse your dog off with warm water.
    8. Now sniff your dog from nose to tail. If you still smell a few stubborn spots, rub dry baking soda into that spot. Then work some of the solution you kept into that spot. then rinse it off. The water should remove the smell from the stubborn spots.
    9. Once your dog has no more smell and has been rinsed, wash him with your favorite dog shampoo and rinse it all out thoroughly. This last shampoo step is to remove any leftover peroxide which can burn your dogs skin if you leave it on.
    10. Towel dry your dog
    11. Give him or her an awesome treat! [Joey tells me he prefers Ribeye steak]
    12. Throw away your rubber gloves, put those smelly clothes in the laundry and take a shower.
    13. Post your skunk story in my comments. Thanks! 🙂
  • Advice to a new Seattle entrepreneur

    Google Groups archive of the STS mailing list isn’t working reliably, so I’m archiving a few emails I’ve sent to the STS list here. One day when I have too much time I’ll create a reliable threaded archive of the whole list. I sent this as a reply to a “getting started” advice request from a Seattle entrepreneur:

    Alfredo,

    I’m sure you’re going to get a lot of advice from the good folks on this list. I’m going to give you my three cents:

    Firstly, welcome to the very difficult but very rewarding world of creating a business out of nothing. It’s people like you who are the foundation of this country’s economy and prosperity. If you succeed you will be providing job security for hundreds, possibly thousands of people and you will have created a useful product or service.

    You are joining the entrepreneurial ranks at an interesting time. Things are changing. Two years ago, if you hired a few developers on elance, created some useful software in an interesting sector and got a few hundred thousand people using it it was quite likely that you could sell your company to a bigger company without actually having to earn any money.

    Today it’s a much harder environment. It’s more difficult to find investors and you can’t “build to flip” (build a business to sell it) as easily. But things aren’t as bad as they might sound.

    People with great ideas who live in places outside the normal technology centers have been creating businesses every year that earn good old fashioned cash. People who are in the traditional technology centers like Silicon Valley are now catching on to the idea of having their businesses earn cash too.

    That’s a good thing because it makes things much simpler. It’s a lot like running a lemonade stand: You create something that is worth more to your customers than the price you charge them for it. Perhaps you create a cup of lemonade that is worth a whole lot to a customer because it tastes so good and they’re darn thirsty, so they pay you 25c for it.

    Rule 1: Create a business that brings in cash.

    People think that running a business is complicated and that you need to do all kinds of preparation before you can even start actually doing the things that are going to make you money. They’ll tell you that you should incorporate, that you should get trademarked, that you should get office space etc..etc. Usually these are the same people that will make money out of you every time you do one of these things. The only thing you need to figure out is how to bring cash money through the door to pay yourself and grow your business.

    Rule 2: If you are doing something that isn’t helping your business bring in cash, see rule 1.

    So don’t worry about incorporating for now. Don’t worry about funding. Don’t worry about legal fees. Just start doing the thing that is going to make you cash money. Work fast because every day you work full-time on this business is a day you’re not earning a full-time salary. Once you have a company that is earning money you can worry about getting the legal protection that incorporating gives you, getting office space for your new employees and about protecting your now valuable trademark.

    Entrepreneurs don’t often realize how hard it is to create a profitable company because they look around and see everyone creating or running a startup. But most startups, especially in technology centers like Seattle are not profitable. They are burning through investor cash or founder cash and will eventually go away and be replaced by other startups that are burning through investor cash and confusing entrepreneurs. That wouldn’t be a problem, except that every time one of them goes away, it leaves an entrepreneur in its wake with 4 wasted years and usually poorer than if he or she was earning a regular salary.

    To get an idea of how hard it is to create a profitable company, think about creating a company that earns you $200,000 per year. I don’t mean go out and get a consulting job and work 14 hour days. I mean create a real business that earns you slightly more than you would earn at a regular job. Sounds a little harder now doesn’t it?

    The good news is that it’s almost as hard to create a small profitable business as it is to create a big profitable business. In fact if you create a small profitable business that can scale, then you’ve actually solved much of the problem of creating a big profitable business. And once you have a small profitable business that works, it’s easy to find investors to help you grow it. In fact you might not even need investors to grow your small profitable company and you can keep 100% of your company for yourself.

    So my advice to you so that instead of getting investors to buy you a few years to test one idea that is very likely not going to work, why not start off small and take an approach that lets you try out many ideas until you find one that works.

    Rule 3: Your first goal in creating your new cash generating business is to pay your own salary.

    If you can pay yourself and still have money left for the business then you’ve solved a very very hard problem and they only thing you need to do is to scale that business. But it’s very important that you don’t cheat and make the business completely reliant on you. So you can’t get a consulting job where you’re selling yourself.  You must create a business with multiple customers in which an employee can replace you at any time without any disruption to the business.

    Rule 4: Create a business that can scale – with multiple customers and in which you can be replaced.

    As I mentioned before, every day you work full-time on this business is a day you’re not going to be earning a full-time wage. So you need to work fast. You need to get from zero to the day that you can pay yourself as quickly as possible.

    Most business ideas fail. Many of them seem like great ideas before they become real, but once they’re created as businesses in the real world they turn out to be hopless. The way you solve this problem is you try out as many ideas as you can as quickly and as cheaply as possible. Take $4,000 that you were going to spend on legal fees and use it to get cheap offshore developers to create 8 websites that you can test. If it costs too much to create fully fledged products then create pretend products that you can use to gauge customer interest. As quickly as you can, figure out which onces the customers love and, more importantly, which one they will pay for. And then do that as fast as you can.

    Rule 5: Rapidly try out ideas until you find one that is highly likely to work.

    If at any time you find out that your new business is not going to work out then stop wasting your time and money on it and move on to the next idea as fast as possible.

    Rule 6: Fail fast because wasting time on a business that will fail wastes money and opportunity.

    Once you find a business that you know will bring in cash, focus all your energy on getting that business as fast as possible from that starting point to the day it can pay your salary and earn enough money to hire your first employee.

    Remember that companies like Twitter may look glamarous and exciting, but they aren’t yet profitable and there are plenty of people making millions in profit picking up garbage and fixing plumbing – even in the online world. [Why does GoDaddy come to mind]

    The last piece of advice I have for you is to do something you love. You’re going to be spending many late nights and early mornings working very hard and that love for your work is what will keep you coming back.

    Mark Maunder

  • The Two Universes

    I posted this today to the Seattle tech startup mailing list. A few folks liked it, so I’m reposting it here. It’s in response to a NY Times article talking about VC’s not caring about a business plan.

    In my experience the most interesting things to a prospective valley based technology investor in descending order are:

    1. Traction and (rapid) growth to date
    2. Team and their history
    3. Product

    My view is that there are two universes you can exist in with distinctly different laws of investment and business physics. There’s the Universe of the Valley and there’s the Universe of the Real.

    In the Universe of the Valley the laws are something like this:

    • Investors are interested in traction, team and product
    • They aren’t very interested in your business plan, revenue projections or even where that revenue will come from
    • They are more interested in your rapid growth
    • They’re also interested in your track record, team and the strategic relevance of your business
    • They’re interested in whether your business could pose a significant strategic threat or opportunity to a potential buyer
    • If your business does go the revenue route rather than being acquired, the view is that, like Google, a revenue model can be bolted on to a business that has scaled massively by really smart folks who will be hired at that point to solve that particular problem. (Like Google did and like Twitter will.)
    • In this universe, most investors have an attitude of go big or go home. They have a large appetite for risk and of course reward and they are generally relaxed and fun to work with and are fairly hands-off your business.

    In the Universe of the Real the laws are something like this:

    • Investors are interested in exactly how you plan to make money
    • They want to know how long it’s going to take to achieve certain product, growth and revenue milestones
    • They also care about traction, team and product, but as it pertains to revenue and it’s timescale
    • They care about many of the things the other universe cares about, like network effects that make your business more defensible, but in order to defend that current or future revenue stream.
    • If you change strategy or product mid-stride, they want to know why and how much (more) money it’s going to bring in and if it’s going to happen sooner
    • In this universe investors play a more active role in your business and like to be regularly reminded of progress towards the revenue they’re so interested in.

    The Universe of the Real is filled with companies that build oil rigs, real-estate developers, Kinko’s, Ben & Jerry’s and similar companies. Many of the stars in this universe remain nebulous but some manage to coalesce into stable businesses that burn bright and give off lots of energy for a long time.

    The Universe of the Valley is filled with stars like Twitter and Facebook that have enormous gravitational pull and that may some day turn into giant supernovae or implode into black holes.  There has been speculation recently that the Universe of the Valley may itself implode, but whether or not that sad day will come remains unclear.

    It’s up to you to decide which universe you want to live in. If you can, try to get an investor from the Universe of the Valley to cross over and help you build your business in the Universe of the Real.

  • Great elder care resource launched today

    Congrats to Chris Rodde and Jay Goldstein, two fellow Seattle entrepreneurs and friends for launching http://seniorhomes.com/ today. If you’re looking for a great resource forassisted living, memory carenursing homes and independent living homes for an elderly relative or friend, be sure to visit the site.