Installing Setuptools and PIP for Python

Python logoI’ve installed a lot of Python packages over the years using Distutils, SetupTools/easy_install and PIP. Distutils is Python’s built-in package distribution module and is pretty easy to use. However, it has some limitations, primarily that you have to manually download the package dependencies and there is no method to uninstall packages.

The Setuptools easy_install script takes care of downloading packages and package dependencies but still lacks certain features you would want from a fully functioning package manager. It doesn’t provide version control support, package tracking and uninstallation. There is a lot more to the Python package discussion but there is no point in bringing it up.

Anyway, while I use package distribution tools I rarely have to install the tools themselves since they only get loaded once. When I do have to set up a new machine or upgrade someone elses, I always forget the steps to get Setuptools and PIP installed. So I thought I would document the steps here. Now I just have to remember to come back here when I need them.

 Installing Setuptools:

1. Right click on this ez_setup.py link and save the file to your Python Scripts folder (If you have ArcGIS loaded you will usually find this at C:\Python27\ArcGIS10.x\Scripts).

2. Open a command prompt and change into the SCRIPTS directory.

3. Type

python ez_setup.py

then hit enter to execute the code. This will run the script which will download and install setuptools on your system.

For the official installation instructions for setuptools, which includes instructions for installing on Windows 8 with Powershell visit https://pypi.python.org/pypi/setuptools.

Installing PIP:

1. Open a command prompt and change into the C:\Python27 directory.

2. Type

easy_install pip

then hit enter to execute. Pip should now be installed on your system.

To actually install a package using PIP from a command prompt you simply type

pip install "PackageName"

and everything will be taken care of for you. To explore the more than 54,000 packages that are available for Pip to load visit PyPI – the Python Package Index.

Be Different with Custom Styled Google Maps

If you are developing with the Google Maps JavaScript API you’re already creating custom code so you might as well go the extra mile and change the default style of your map so it doesn’t look like every other Google map out there.

Getting a unique looking map that fits well with the style of your web page is actually really very easy. The Google API gives you the option of re-styling the existing standard map types or creating new map types containing your styles. Either way, if you are comfortable with the Google Maps JavaScript API you can put a fresh face on your map in no time.

Click here to see an example of a custom Google Map style.

For detailed instructions on how to custom style your map, you can see the Styled Maps section of the Google Map JavaScript API Developer’s guide.

If you would rather use a tool to generate your code you can use the ones listed below for free. Some of them even have pre-built styles that are ready to be plugged into your code.

Styled Map Wizard

Evoluted Style Tool

MapStylr

SnazzyMaps

Google Maps Colorizr

Custom Google Maps Style Tool

 

Tourist Pine to Fly Drones in Antarctica? Weird!

antarctica

The International Association of Antarctica Tour Operators is cautioning all potential travelers to Antarctica who pine to fly a drone to check with their travel agent or tour operator before packing their device.  – The Washington Times

Tourists are pining to fly drones in Antarctica? What kind of tourist pines to fly drones in Antarctica? The bigger question is who uses the word pining anymore?

Is IE on its Last Legs?

Internet Explorer logo

Tidings of a new browser coming from Microsoft have some wondering whether IE is on its last legs. The sad news is that there are still so many old versions (7, 8 and 9)  sitting on millions of computers, and their users don’t know any better. So even if Spartan, or its children, eventually displace Internet Explorer, front-end developers will be playing patty cake with old versions for years to come.

It’s interesting that Microsoft is coming out with a brand new browser when IE11 has so many improvements and seems much less maligned than its older versions. Makes me think maybe this is just the start of a rebranding effort.

 

Further Reading:

http://www.computerworld.com/article/2863746/what-microsofts-fresh-start-browser-strategy-means.html

How to Organize Your CSS

Organizing my css styles does not come easily. I like to just throw styles on the page when I need them and then forget about them. If I need to edit the style I can always use a Find or Search function for the id, class or tag name I need.

If you are the only one working on your project you might be able to get away with just using the search function in your IDE. You probably know (generally) where things are because you put them there. But organization is still important.

The real power of organization comes when other people use and modify your css. If anyone other than yourself is going to even look at your stylesheet you have to make if accessible.

There might be a hundred ways to put your stylesheet together in a logical, readable way. Here is one way that works for me:

1. It goes without saying to get your style definitions out of your html document. Putting your styles in a <style> tag really only works for an extremely small project that will never grow. If you want to scale your project, having your html and css in one page gets ugly. As far as inline styles, I only use them occasionally when I am dynamically generating certain elements. I never use inline styles in static html.

2. Use /**/ comments to explain and segment your external stylesheet. At the beginning of the .css file it is convenient to have a comment block that describes how the style rules are organized and the stylesheet’s relationship to other stylesheets, if there are any.

Some developers like to put common block level element (body, header, footer, p, h1 …) styles on a sheet separate from all other css. Others have separate sheets for each type of page on their site. This should be documented at the top of each css file to make style navigation easier.

A lot of my work is done for single page GIS apps so I usually have a single external css page. In these cases I note that this is the only css stylesheet for the app.

3. Everyone has their own favorite way of laying out their styleswithing the stylesheet. Some organize their ids and classes alphabetically while others might order them parallel to their element’s order in the html. I find that it makes most sense to group styles according to sections of the page. Sometimes I put css blocks in order of how the html sections are created but this isn’t always the case. Within each of these sections I try to further order elements from top to bottom as they appear in the html.

There are a lot of ways to organize css and what I outlined above is only one of them. The most important thing is just to have some form of organization and then be consistent in applying it.

Use Python to Keep Your Brain Sharp

“Use it or lose it” certainly applies where brain function is concerned. The experts tell you to exercise your brain to keep it in shape and ward off forgetfulness and possibly dementia when you are older.

One way to exercise your brain is to do computations in your head. Not long ago I read a book called The Power of Forgetting by Mike Byster that introduced several tricks and methods for doing these mental computations. One that stuck with me was how to multiply two, two-digit numbers in your head. Here’s an excerpt from the book explaining how to do it:

addnumbersThere are probably easier ways to do mental multiplication but Byster’s method is meant to be an exercise in remembering and forgetting numbers at will to make your brain stronger.

I wanted to find a way to challenge myself with the above multiplication method on a regular basis. My solution was to write a very small Python script that would generate random two-digit by two-digit multiplication problems and display them on screen. Here is what I came up with:

from random import randint
from ctypes import windll

firstNumber = randint(10,99)
secondNumber = randint(10,99)

problem = str(firstNumber) + " x " + str(secondNumber)
answer = str(firstNumber*secondNumber)

windll.user32.MessageBoxA(0, problem, "Can you multiply these in your head?", 0)
windll.user32.MessageBoxA(0, "The answer is: " + answer, "How did you do?", 0)

The script simply generates two random two-digit numbers, displays them to the user, then displays the correct answer when the user closes the first message box. I used Python’s ctypes library to create Windows message boxes,so you would need to make some adjustments if you wanted to use it on a different operating system. I also set up my task scheduler to run the script automatically every hour. Now, throughout the day at work and at home I’m reminded to exercise my mind in a way I wouldn’t normally exercise it.

Efficient ArcServer Cache Management with a Staging Server

Getting a cache built can sometimes be a challenge but caching an ArcServer map service can be important if you want your web apps to display fast. Depending on the subject of your cache and what scales you cache at you can end up with tens or hundreds of gigabytes of data.

Art Tiles

In my office we cache both vector and imagery data for an entire county. We have 20 aerial mosaic data sets dating back to 1937 and several vector data sets that also cover the entire county. Caching all of this can put a real strain on a server and takes up limited server resources that can cause the server to perform poorly.

I’ve found that the best solution is to cache on a staging server and then transfer the cached tiles to a prepared production server. Here is how you can easily do the same:

  1. Create a service on your staging server.
  2. Set up caching in the Services Properties dialog.
  3. Create a service on your production server that has the same name as your staged service.
  4. Set up caching in the Services Properties dialog. From the “Tiling Scheme” drop down select “An existing cached map / image service” and navigate to the staging service. This will import all of your cache advanced setting that you defined on your staging service like scale levels.
  5. Run the Manage Map Server Cache Tiles tool to create the staged cache.
  6. Now you just want to copy your level folder (L00, L01, L02…) located in \arcgisserver\directories\arcgiscache\[your map service name]\_alllayers to the same location on your production server.

At this point your production server should have a full working cache. If you have a cache service that will need to be updated regularly you could even script the whole process and schedule it to run at night or on the weekend.

 

How to Think Like Sherlock Holmes

Mastermind book cover.

I often go to the library to try and find something entertaining, intriguing or just different. Last week I found just the thing. It was a book called Master-Mind: How to think like Sherlock Holmes by Maria Konnikova. Now this is the kind of book I love to find. After all, who wouldn’t want to be able to think like the famous detective of 221B  Baker Street?

The title itself intrigued me enough to take it home right away. It promised to free my mind from being common and show me how to be a logical processing machine. Perhaps I could become as great a thinker as Holmes was portrayed to be in his stories.

I won’t go into a deep book review here. If you want to know the details you will have to read it yourself.  I will tell you, however, that after reading the entire thing, my brain is not yet governed by a Holmes-like system of thinking. I have not yet mastered the skills of observation, imagination or deduction that it takes to become a master thinker. But I am further along that road than before reading Mastermind. Many of the book’s insights have actually already helped me solve problems with my programming using the methods that Holmes used to solve his own puzzles.

The book was a fun read. I would encourage you to buy a copy or go to the library and check it out.

Better Basemap Management for the ESRI Javascript API

If you use ESRI’s Javascript API to build web maps you have probably noticed that your ability to manage base map layers is somewhat limited. You really only have three out-of-the-box alternatives:

  1. Define an ArcGIS.com basemap in the map constructor
  2. Create and fill a Basemap Gallery
  3. Switch between two basemaps with Basemap Toggle

But what if you don’t want to use an ArcGIS.com basemap, you want to use something other than thumbnail images to switch between basemaps or you have more than two basemaps to switch between? In that case, you probably need something a little more flexible.

I recently found myself in one of those situations. I wanted to be able to switch between a vector basemap and a basemap of current imagery as well as give viewers the opportunity to choose imagery as far back as the 1930s. I really didn’t want to show thumbnails for every year of imagery. Instead, it seemed to make more sense to allow selection by year from a drop down menu.

So I went ahead and built my own little version of a basemap switcher to handle different situations. To be fair, I could have used the ESRI Basemap Toggle dijit to handle the two main basemaps but I like having more control over my code than Dojo based dijits allow.

I put together a simple map to demonstrate switching multiple basemaps through various means like buttons, thumbnails and drop downs. The html markup and CSS  styling is pretty basic. We create a header as a toolbar (in this case our switcher is the only tool), a div for the map to be injected and markup for the the jQuery UI dialog box that will hold our switching controls.

Edit: FC Basson’s comment got me thinking about the code samples here being too complicated for what they were actually doing. I went back through and removed the toolbar and all jQuery UI and jQuery code. None of these added anything special to the app and since Dojo is already available to us, it should be used instead

<!doctype html>
<html lang="en">
<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9, IE=10">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="translucent-black">

    <title>Custom Basemap Switcher</title>

    <script src="http://js.arcgis.com/3.7/"></script>

    <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/dojo/dijit/themes/nihilo/nihilo.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/esri/css/esri.css">

    <style>
        html, body, #map
        {
            height: 100%;
            width: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }

        #map
        {
            position: fixed;
        }

        #basemapButton
        {
            position: absolute;
            top: 25px;
            left: 70px;
            z-index: 100;
        }

        button
        {
            border-radius: 4px;
            background-color: #F1F1F1;
            font-size: 1em;
            color: #33A7DE;
        }

        #basemapDialog
        {
            background: white;
            display: none;
            font-size: 0.75em;
            height: 200px;
            left: 65px;
            position: absolute;
            top: 70px;
            width: 300px;
            border: 0.5px solid black;
            border-radius: 5px;
        }

            #basemapDialog ul, li
            {
                list-style: none;
                margin-top: 1em;
            }

        a img
        {
            border: 1px solid black;
        }

        a:hover img
        {
            border: 1px solid white;
        }
    </style>


</head>
<body class="container tundra">
 <button id="basemapButton" title="Open a basemap switching dialog">Switch Basemaps</button>
 <div id="map"></div>
 <div id="basemapDialog" title="Choose a Basemap">
 <ul>
 <li>
 <button id="wldImagery" title="Load the World Imagery layer as a basemap using this button">Imagery</button> Select by button</li>
 <li><a id="streetView">
 <img title="You can use an image thumbnail like this one to select a basemap" src="http://ryanrandom.com/examples/images/vegas.jpg" alt="Street Map View" height="50" width="50" />
 </a> Select by thumbnail</li>
 <li id="differentBase" title="View historical imagery as a basemap">
 <select name="bmSelect" id="bmSelect" title="Selecting a basemap from a dropdown is handy when you have many choices, like historical basemaps">
 <option value="none" selected>None Selected</option>
 <option value="topo">Topo</option>
 <option value="relief">Shaded Relief</option>
 </select> Select by dropdown
 </li>
 </ul>
 </div>
</body>
</html>

The code needed to run the switcher isn’t too complex either. You just need to create an ESRI Javascript map reference, create variable references to the basemaps you want to use then create a function that does the actual changing of the layers.  The rest of the code is just some jQuery Dojo/JavaScript to interact with the controls.

    <script>
        require([
            "esri/map",
            "esri/layers/ArcGISTiledMapServiceLayer",
            "esri/geometry/Extent",
            "dojo/dom",
            "dojo/dom-attr",
            "dojo/dom-prop",
            "dojo/on",
            "dojo/query",
            "dojo/NodeList-traverse"
        ], function (
            Map, ArcGISTiledMapServiceLayer, Extent, dom, domAttr, domProp, on, query
          ) {
            //We can set an extent like this one which takes us to Las Vegas, NV
            var initialExtent = new Extent(-115.68, 35.77, -114.75, 36.45);

            //Create an empty array to store a reference to the currently selected basemap layer
            currentBasemap = []

            map = new Map("map", {
                extent: initialExtent,
                logo: false,
                slider: true
            });

            //create references to all of your basemap layers but only add one to the map initially
            imagery = new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer");
            //add the current basemap layer to the currentBasemap array so you can keep track of what is active.
            currentBasemap.push(imagery);
            map.addLayer(imagery);
            //call reorderLayer on the map object and set your basemap to zero every time you change basemaps. This ensures that your basemap is always the bottom layer.
            map.reorderLayer(imagery, 0);

            street = new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
            topo = new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
            relief = new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer");

            //Opens and closes the basemap dialog using the basemaps button
            on(dom.byId("basemapButton"), "click", function () {
                if (!(dom.byId("basemapDialog").style.display == 'block')) {
                    dom.byId("basemapDialog").style.display = "block";
                } else {
                    dom.byId("basemapDialog").style.display = 'none';
                }
            });

            //This function does just what its name says and changes the layer
            function changeLayer(layerName) {
                map.removeLayer(currentBasemap[0])
                currentBasemap.length = 0;
                currentBasemap.push(layerName)
                map.addLayer(layerName)
                map.reorderLayer(layerName, 0);
            }

            //Here is where we switch the basemap using a button
            on(dom.byId("streetView"), "click", function () {
                domProp.set(query("#differentBase option")[0], "selected", true);
                changeLayer(street)
            });

            //Here is where we switch the basemap using a thumbnail image
            on(dom.byId("wldImagery"), "click", function () {
                domProp.set(query("#differentBase option")[0], "selected", true);
                changeLayer(imagery)
            });

            //Here is the code for handling changing your basemap based on a html select box dropdown.
            dom.byId("bmSelect").onchange = function () {
                var newBasemap = dom.byId("bmSelect").value

                //Default to the imagery basemap if "none Selected" is the choice in the dropdown 
                if (newBasemap === "none") {
                    changeLayer(imagery)
                } else {
                    //The following allows you to map the dropdown values with an object reference to the tiled service layers created above
                    var bmList = ({
                        "topo": topo, "relief": relief
                    })

                    //Find the selected basemap in the array above and use the associated object to add the selected theme layer to the map
                    for (var x in bmList) {
                        if (x === newBasemap) {
                            changeLayer(bmList[x])
                        }
                    }
                }
            }
        });
    </script>

You will notice in the code above that we have create an empty array called currentBasemap.  This array is the key to making the tool work. We store a reference to the currently loaded basemap here. That way we can access it, remove it’s corresponding basemap and load a reference to whatever new basemap that we want to display.

That’s all there is to it. You can get the full code from GitHub. You can also view a working example of the code.

Let me know if you have any suggestions on how to make it better.

Five Things I Love About the ESRI Javascript API

Having worked with both the ArcGIS Silverlight and Javascript APIs I have to say Javascript has been much more fun. There is just something about working on the front end of a web map and being able to have it do so many amazing things. Here are my top five reasons I enjoy working with this API.

1. Your maps are device independent. Unlike the Flex and Silverlight APIs, Javascript and HTML5 can be viewed on almost any device. The obvious advantage here is that you can reach more people with your spatial data.  Of course having the ability to code for multiple devices means having to customize your code for different screen sizes which can turn into a lot of work. Check out this post from the Treehouse Blog for a great primer on responsive web design.

2. Plenty of code samples and live examples. Code samples are a great way to get your own map up and running quickly without having to figure everything out first. While the samples are not perfect they are a good way to discover map functionality that you might want to incorporate.

3. Support for a ton of layer and data formats. From GeoRSS and GeoJSON to KML and shapefile, this API pretty much covers it.

4. Well written API reference documentation. If you are going to use an API (any API) you want to be able to understand it so you can use it effectively. Good documentation is critical for this. The Esri JS API is (in my own humble opinion) extremely easy to read and understand. Each class has all the information you need to use it without having to decode any meanings. Furthermore, there are links from each class to samples that use it.

5.  Editing tools for online editing of SDE data. Let’s be honest, online editing through a web browser is not a great idea if you are trying to build accurate data. However, there is definitely a place for it. If you are trying to outline an area inhabited by a herd of elk or mark an area of weed infestation, browser editing is probably fine.  It is great just to be able to have this ability so more diverse mapping applications can be developed.

Wow, this list was a lot harder to write than 5 Things I Hate About the ESRI Javascript API. One reason is that there are other APIs out there that do a lot of what the ESRI API does (yes I am thinking about OpenLayers). Another reason is that as I write I think about things I would like ESRI to do better or differently. Oh well, you can’t have everything. Let me know what your thoughts are on the ESRI Javascript API – good or bad.