TileMill and Ocularis

A long, long time ago, I discovered TileMill. It’s an app that lets you import GIS data, style the map and create a tile-pyramid, much like the tile pyramids used in Ocularis for maps.


There are 2 ways to export the map:

  • Huge JPEG or PNG
  • MBTiles format

So far, the only supported mechanism of getting maps into Ocularis is via a huge image, which is then decomposed into a tile pyramid.

Ocularis reads the map tiles the same way Google Maps (and most other mapping apps) reads the tiles. It simply asks for the tile at x,y,z and the server then returns the tile at that location.

We’ve been able to import Google Map tiles since 2010, but we never released it for a few reasons:

  • Buildings with multiple levels
  • Maps that are not geospatially accurate (subway maps for example)
  • Most maps in Ocularis are floor plans, going through google maps is an unnecessary extra step
  • Reliance on an external server
  • Licensing
  • Feature creep

If the app is relying on Google’s servers to provide the tiles, and your internet connection is slow, or perhaps goes offline, then you lose your mapping capability. To avoid this, we cache a lot of the tiles. This is very close to bulk download which is not allowed. In fact, at one point I downloaded many thousands of tiles, which caused our IP to get blocked on Google Maps for 24 hours.

Using MBTiles

Over the weekend I brought back TileMill, and decided to take a look at the MBTile format. It’s basically a SQLite DB file, with each tile stored as a BLOB. Very simple stuff, but how do I serve the individual tiles over HTTP so that Ocularis can use them?

Turns out, Node.js is the perfect tool for this sort of thing.

Creating a HTTP server is trivial, and opening a SQLite database file is just a couple of lines. So with less than 50 lines of code, I had made myself a MBTile server that would work with Ocularis.


A few caveats : Ocularis has the Y axis pointing down, while MBTiles have the Y axis pointing up. Flipping the Y axis is simple. Ocularis has the highest resolution layer at layer 0, MBTiles have that inverted, so the “world tile” is always layer 0.

So with a few minor changes, this is what I have.


I think it would be trivial to add support for ESRI tile servers, but I don’t really know if this belongs in a VMS client. The question is time was not better utilized by making it easy for the GIS guys to add video capabilities to their app, rather than having the VMS client attempt to be a GIS planning tool.


Tagged ,

Can “Old” Companies Disrupt?


OK, so Apple did it, and Steve Jobs is considered a genius (and he was) for making it happen. But for most companies, it just isn’t going to happen.Evolution, improvement and progress – sure – but real, iPhone-type disruption? Very, very unlikely.

Mind you, that won’t stop companies from claiming that they are disrupting this or that segment or vertical.Just like Sodastream disrupted the “home carbonated beverage” business a few years back.

As companies mature, the company will adopt a certain gospel. The employees will either believe in the gospel, be indifferent to it, or leave the company. So eventually, you are left with a company where everyone believes pretty much in the same “truths”. In an environment where everyone believes that the earth is flat, it is hard, if not impossible to fund research to show that it is spherical.

Obviously. there are quite a few obvious examples to contradict this theory; Google’s moonshot projects spring to mind, and 3M is perhaps a better example, but my impression is that these examples are the exception, and that the vast majority of companies at one point or other stop challenging everything they believe and just go back to the same old s..t.

To disrupt, it’s clearly not enough to just do random things that just happen to contradict what you believe. A recent example is the use of VR in video surveillance; I doubt any police officer would feel comfortable wearing a headset for hours on end, in a potentially nauseating virtual environment where you have to physically move your head in the direction you want to see, vs. just having a fully unwrapped panoramic image on a good IPS or OLED monitor. I fail to see how limiting your field of view is a good thing. So it just doesn’t make sense to me to throw money after such a project (but it did to a lot of other people).

It’s obviously very difficult to come up with something that make commercial sense, and challenge your gospel. You’ll most likely be pitching your idea with “I believe people will love this”, which will then go up against “well, the competition is doing x, y and z, and so we should do that”, in most cases, it is easier, and better for your career, to go back to your desk and put your ideas back in the drawer. So I guess most people do just that.

Another factor is that ideas have to be possible to implement. Not just theoretically, but in practice too, with consideration to the staff and financial resources you have. A small contractor would be better served bidding on projects he can actually finish, rather than drafting plans for a new bridge or skyscraper that he has no chance of completing even if he wins the bid. If you don’t have the financial capacity to actually fund the first batch, setting up logistics, handling returns and warranties, then why bother? It may be a great idea, but if you can’t possibly execute it, then it won’t happen. Dropcam was able to go to market by buying cheap cameras off Amazon, updating the firmware, relabeling the cameras and shipping them. It was clearly suboptimal from an operational standpoint, but it allowed them to discover that the idea was viable, even if it seemed to contradict the whole “open platform” mantra.

For newer companies, that are not carrying around a lot of outdated and perhaps questionable gospel, this is a golden age. It has never been cheaper to set up extremely powerful cloud based computing and storage systems, and I don’t ever recall a time where I could buy a fully functional and plenty powerful computer for $10 – including the OS!

Enough ranting, let me get back to doing something that aligns with our gospel.

*Betteridge’s law in full effect here

On Rationalization and UX

A while ago I read about a rationalization experiment conducted by Tim Wilson at the University of Virginia. Two groups were asked to pick a poster to take home as a gift. One group were asked to explain why they liked the poster before taking it home, the other could just pick one and go home.

After a while, they were asked for feedback. How did they like their posters now?

The group that were asked for an explanation, hated theirs while the others were still happy with their choice. This is a little surprising (it was to me at least). Why would explaining your choice affect it so profoundly?

I think this behaviour is important to keep in mind when we talk to our clients.

A potential client may be reviewing 4 different bids, and while they are pretty similar, the client decides that he likes #2. At some point the client may have to rationalize why he picked #2. If there are very obvious and compelling reasons to go with #2, it presents no problems. But what if all 4 are very similar, and the reason the client wants #2 is really because he quite simply, just likes it better. He can’t explain his choice by just jotting “I like #2 better”, so he will rationalize.

And so, unless there are very clear, objective, advantages of #2 over #4, we are entering that dangerous territory. The Poster Test (and other variations of the same thing), show that people simply make things up. It’s not that people consciously think “oh, let me just make up a story”. They genuinely feel that they are making a rational argument.

In the realm of software development, requirement specifications quite often deal exclusively with what one might call itemizable features. E.g. “open a file”, “delete a user”, “send an email”, and very little effort is put into discussing the “feel” of the application. When bad managers sit in a management meeting the focus is on Product X does Y, we need to do Y too, and then Z to be “better”, and the assumption is that the user doesn’t care one bit about how the app feels. Almost no feedback exists that complain about how an application “feels” (it does exists, there is just not a lot of it), and it is very rare that managers take that sort of thing to heart.

At Prescienta.com, the “feel” is important. I believe that if the product feels robust and thoughtful, that the customer will happily make up a story about why some small unique feature in our product is crucial. “Feel” is about timing, animations, and non-blocking activities, it’s about consistency and meaningful boundaries. Some companies seem to understand this, and consistently move towards improving the user experience, others give up, forget, or lose the people that have the ability to create pleasing user experiences, and instead let their product degrade into a jumble of disjointed UX ideas, inconsistent graphical language and bad modal activities (hmmm.. a bit of introspection here?)

A well designed application is designed with the technical limitations in mind – a good example is dropcam, where the audio delay is so large that the UI is designed to take this into consideration. The push to talk metaphor is a perfect way to handle the latency. If the UI was designed to work like a phone (that has almost no latency), there would be a massive gap between what the UI is suggesting and what the technology can deliver.

Another example, a bit closer to home, is the way you move cameras around in privilege groups. The goal here was to design the UI to ensure that the user did not get the idea that they could add the same camera to two different groups. If the UI suggests that you can do so, you may be puzzled as to why you can’t. I decided to prevent multi-group membership to avoid contradictory privileges (e.g. in one group you are allowed to use PTZ in another it is forbidden, so which is correct?).

H.265 vs VP9

Netflix did the research. 50% improvement on HD video is real.


First Axis, now NUUO. Full disclosure.

On The Axis Zombiefication

OrwellLabs just released a POC on how to hack Axis certain cameras and video servers (h.t. Gavin Millard). This is just a few days after I received a marketing email from Axis (the July 2016 Axis ADP eNewsletter), containing this verbiage.

Service release for critical security vulnerability
Recently, a critical security vulnerability was discovered in some of Axis’ products that are accessible from the Internet. We have now published firmware service releases for the majority of our products; see http://www.axis.com/support/product-security. Axis recommends users to update the affected products’ firmware as soon as possible, especially if the products are accessible from the Internet.

The very same email contains this message

Taking responsibility
CEO Ray Mauritsson comments on privacy, business ethics, the Axis code of conduct, and how we – together with our partners – are working to create a smarter, safer world

Axis did put out a press release on the 6th of July 2016 about the vulnerability on their security page (about 9 months after Axis was notified by Orwelllabs). But honestly, how many owners of the affected devices will go there? How many owners of the affected devices will get an email about this sort of thing? Even if they do, they have to visit a link to determine the severity. I don’t know if issuing a press release 9 months later, that your company’s cameras may become part of a botnet army is “taking responsibility”. I know it is not uncommon for companies to behave this way, but that doesn’t make it right.

For all intents and purposes, the impact of this bug is not that big. The vast majority of sensible users will not expose their CCTV system directly to the internet. Your camera may access the internet – outbound – to send notifications etc. but that will not make you vulnerable. To be vulnerable, you need to map a port on your firewall to your camera, so that you can see the camera web-interface from a public IP address.

But there are a minority of users who will, and who do this sort of thing. And even if it is the minority, they can do a lot of damage to others (by participating in botnets), and obviously to themselves too (paying $$$ for a useless/dangerous device).

It’s depressing because Axis does a lot of things to improve security : no default passwords is a pain in the ass, but it does make things a little more secure (only just a little because people will put in 12346, pass, or something similar).


It Just Doesn’t Work

A while ago I read a piece about a guy who stopped reading industry news. Reading industry news can be a massive distraction to a long term strategy. Every time your competitors (real or imagined) launch something, there’s a line of pundits ready to hail praise to the “innovation”. You start wondering why you aren’t doing gait-recognition in your app. Then a few months later, it’s psychoacoustic categorization and so on.

The default assumption is that “oh, they got that working?”, and then I remember that people have wildly different opinions on what “works” means. I usually have the opposite point of view; until I have seen the thing, I don’t believe that it works.

I saw some Kinect footage before it was released, and I was pretty suspicious – once I tried it, I wasn’t disappointed. It was shit. There was, maybe, once in awhile, if I was willing to suspend my belief, a few times where raising my arm would make something happen on the screen. You’ll probably find a bunch of people who would tell you that bundling Kinect with Xbox One was a stroke of genius. If selling half the number of devices of your competitor is “genius”, then I wonder what “stupid” is. In any case, they removed the crap completely from Xbox One S (although you can get an adaptor if you are a masochist).

I decided not to get an Oculus Rift either. The dev kits we had were just too shitty for my taste. Sure, it was very odd/cool, to watch myself from somewhere else. But nothing I would pay a large sum of money for, and I predict that there will be a lot of unused VR kits lying around in boxes 12 months from now (Google cardboard is good enough for me, but I am told the HTC Vive is pretty good). The AR “demos” also seems too fake. Tango seems fine, but Hololens and Magic Leap will surely disappoint me.

And the same thing goes for some of the services we’ve tested in the office. A lot of them are just not reliable. There’s a large chasm between, “what a cool idea, and it sorta, kinda works, if you hold it juuuust right”, to “it just works”.  A while ago I did a trial on a ALPR system, and the results were terrible. Sure, from time to time, it would get it right, but too often it would fail. I am not going to buy into a system that promises plug and play, but then, when I test it, I am led down the maze of infinite tweaks and caveats. If you require special lighting, special positioning, external sensors and so on, then I might as well write the damn thing myself. We also tried another product that made marketing and sales people drool, even potential customers were excited. But I could not get anyone to set this stuff up to work the way people imagined that it worked. They were so thrilled about the idea, that they lost sight of the implementation and result.

I have a pet theory that a lot of products are really turds. To mask the smell, the turd is doused in condiments, and the more condiments the better, even if the condiments are tasteless/bitter themselves.

I suggest that the first company to offer real cake will take the price. I bet that a large number of people would rather eat a donut with NO condiments than a turd, regardless of the amount of great stuff pile on top of it.


Blast From The Past

For kicks I downloaded Milestone Xprotect GO this morning.

My handiwork is still in there!

In the Milestone/Milestone Surveillance folder, you’ll find a file called “mask.exe”. Don’t try executing the file, just copy the file and rename the extension to .jpeg. So you get

mask.exe -> mask.jpeg

Then open the file in your favorite JPEG viewer, and behold, a wonderful image i made in 3DSMax about 10 years ago.


This was used for demo-mode purposes. If you had not entered a valid license code, we’d embed this frame into the video (a costly process). To ensure that you didn’t just replace the demo image with a 1×1 pixel image, we validated a hash of the file content.

Fun times.

Hacked Sites

LinkedIn’s user database was leaked online a while ago, now usernames and passwords are for sale in the dark net. LinkedIn were not the first, nor the last to have their user database stolen, and published online.

Companies go to great lengths to protect their databases from outside intrusion; but what about the disgruntled employee? Your best friend had root access to the system, but when things went sour, he had already made a copy of the database (just in case), and so when he was finally let go, he decided to post the database snapshot online.

In the terrible old days, the database would contain the username and password in plaintext, so you’d see something like this:

User      | Pass
Morten    | 123456

Then someone thought to encrypt the passwords, but the disgruntled employee has access to the key and the algo used, so he could just post that information online as well. A tell-tale sign of such a (horrific) implementation is that the system sends your password to your email address if you forget it, instead of the usual reset password email that you get today.

These days we do salted hashes to make it hard to determine the passwords if the database is compromised. The basic idea is that you no longer store the password, but instead store the result of a hash function. When the user provide their password, the system combines the password with another value and computes the resulting hash value. This value is then compared to the value stored in the database, if they match the user gets access. Since the user database contains the RESULT of a computation, there is “no way” to deduce the original password from the hash value stored in the database.

Here is a very simple example:

Say we only allow 4 digits as our password, and our hash is simply to add the numbers together (this is a TERRIBLE hashing function!), but this will serve as an example.

So the user has a pin of 1234, and for this user we have made a salt value of 3333.

So the user enters 1234, we then append the salt, so we get 12343333, then hash that value (1+2+3+4+3+3+3+3 = 22), so we store 22 in the database.

User      | Salt | Hash
Morten    | 3333 | 22

Now, say someone tries to use my account, and attempted to gain access. He then enters 1111 as the PIN. The system then computes the hash (1+1+1+1+3+3+3+3 = 16). The hash computed (16) is then compared to the value in the database (22), since they don’t match, the user is denied access.

The observant reader will have realized that if I know the salt it will be simple to find a combination of PIN that will give us the desired result (22). 4321 would work and grant us access, so even if I don’t have exactly the same PIN we will get access just the same.

This is primarily because the hash function is so terrible; so you do not use idiotic hash functions, but pick some that are generally accepted as being “good”, for example MD5 is widely used. So when you use good hash functions, the likelihood of 2 PINS given the same hash is very small. This means that you have to try a lot of combinations to find a combination where function ( guess, known_salt ) == hash. But computers are happy to try a lot of combinations, and the number of combinations can be greatly reduced by using “rainbow tables”. These are tables of known, often used passwords, usually retrieved from other hacks, and while this doesn’t give us all the passwords, it usually breaks enough accounts for whatever purpose is needed. We might also want to target just one account in the DB, and try a much wider range of passwords.

Someone might argue that since I don’t have the hashing algo used I will be unable to set up my little script to run through the rainbow table, but this could have been leaked as well. Even if it wasn’t there might be known accounts in the database, where I will be able to try different hashes with a known username, password and salt.

If you are in the “same password everywhere” camp, then you are SOL. Even if the blog comes clean and discloses that they have been compromised, it is too late. Changing the password on the blog does not remove the password in the leaked database.

Breadboards and LEDs

I had forgotten the smell of an electronics store. I am not talking about Best Buy, or Radioshack, but one where you can get LEDs, resistors, wires and breadboards, where the guy behind the counter tells you that a 220 ohm resistor is suitable for the LED.

The computers I am playing with these days are very low cost (down to $5), but they have digital IOs readily available, and I must say that I am amazed the kinds of things that are available. RFID readers, 433MHz transceivers, PIR detectors, touch screens, cameras etc. And did I mention that you can play Minecraft on these things?

So today I got myself a breadboard, some LEDs and resistors, and set up my little script so that when motion is detected by a camera, the LED turns on for 5 seconds. It feels almost magical to see the little LED light up when I move in front of the cameras. Strange how this little addition somehow makes it all seem more “real”.

Most of the code for this little NVR is javascript; there is a little bit of c++ in there too, but I think I can move that to javascript in a day or so. The caveat is that this is H.264 only, but I can live with that for now.