A Little Background on Map Elements

The problem

If you’ve ever had to place map elements like north arrows, text or scalebars on an ArcGIS made map, you know how they can get lost in the background of imagery or some other basemap. You can always try to change the items color or size to make it stand out. But the easier and more effective method is to change its background color to a solid color like white.

Map elements can get lost in the noise.

The problem with doing that is the background extent only stretches to the edges of its element. There is no padding between the element edge and the background edge.  Thankfully, ArcMap provides us with the ability to set a gap between the two edges.

Default backgrounds on map elements have no padding.

How to fix it

In ArcMap, right-click or double-click on the element to open its properties. Open the Borders and Background tab and select your backround color from the dropdown. Next, change the X and Y values next to “Gap”. The higher the number, the more padding you’ll get between element and background edge. You can also apply a “Rounding” percentage value to give your background panel rounded corners. That’s all it takes to make your ArcGIS map easier to read and more professional looking.

map elements
Adjusting backgound gap gives elements room to breathe.

 

Categories GIS

Mapping The Dead

Skull and Crossbones

I’ve seen a lot of interesting mapping applications in the news over the last year. One that’s caught my attention is cemetery mapping. I had never really thought about just how ideal a cemetery is to be mapped. Each plot has a distinct spatial location. They have measurable attributes like occupant, location, depth and width. They are often laid out like a grid or a table but sometimes (especially on older properties) they are spread out seemingly without much thought to being easily located again.

Locating a plot is obviously the most important attribute for cemetery mapping. Caretakers have to be able to determine where a body is located so they can avoid accidentally digging it up when placing another body. Relatives of the deceased want to know where their family members are too so they and those in the future can find them again.

One of the first articles I cam across last year was about the cemeteries in the City of Mackinac Island Michigan. The city’s cemetery committee (I bet those meetings are fun) recognized that its current data holdings (hand-drawn paper maps, incomplete lists of cemetery residents and the memories of senior committee members who are increasingly ending up in the cemetery themselves) were not adequate. So they started mapping out plots using GPS and building a database of names.

The City of Mackinac Island Cemetery Committee hopes to have a completed digital mapping system by next June, which will help the city clerk’s office keep track of plots and burials more efficiently. The map is one of many updates the city is considering relating to its cemeteries and burial policies.

It didn’t surprise me to find that some cities are using GIS technology to keep track of cemeteries. What did surprise me was the number of software packages that have been created for mapping and managing them. A quick search for cemetery mapping software reveals several pages of apps, services and companies with interesting names like Memorial Business systems, CemMapper and The Crypt Keeper.

Yet with all of these software solutions, none of the cemeteries that I was interested in searching had detailed mapping of their plots. Only one even had a website. Although the mapping technology is there, this kind of project doesn’t seem like one many cemeteries are willing to undertake.

Shapefile as a Multi User Editing Environment?

I had a ArcGIS user that I support come to me with a corrupted shapefile the other day. It had the old “number of shapes does not match number of table records” error. It turns out, he’s still using this shapefile as his layer’s main data source and he and several others regularly edit it! In this day and age?

I tried to convince him using a file geodatabase would be more stable for editing but he had been using shapefiles so long I don’t even think my comments registered. He just wanted a tool that could fix the shapefile.

I pointed him to the shapechk tool by Andrew Williamson. I’ve used the tool for years because <sarcasm>for some odd reason</sarcasm> I often run into people with corrupted shapefiles after people edit them over long periods of time. The shapefile works OK as a data exchange format but doesn’t always hold together under regular heavy use.

In the words of Pete Seeger, “when will we ever learn?”

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

 

Map your business

Believe it or not, maps aren’t magical. They don’t just happen. Online mapping companies like Google, Microsoft, Apple and MapQuest get data on their maps through good old fashioned research. But there is a limit to the amount of information they are willing to collect and display by default.

Fortunately, if you’re a business owner you can help make online map applications more complete while increasing your business’ exposure. The four companies mentioned above all offer free services for verified businesses to be able to update the information presented on their maps.

If you own a business you owe it to yourself to research your own map listings and update them if you don’t like what you see. Here are the links so you can get verified and start updating now:

https://www.google.com/business/

https://mapsconnect.apple.com/

https://www.bingplaces.com/

MapQuest no longer supports accessing your basic listing information through their Local Business Center. You can add your business listing to MapQuest but you can only submit limited information. In order to enhance your listing you need to upgrade to a premium account.

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.

 

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="">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.

Master Google Maps, Research WWII and Convert Data

As I tooled around the web last week looking for anything useful, interesting or entertaining I came across the following four pages that I thought I would share. Hope you like them.

1. Gizmodo.com – 10 Tricks to Make Yourself a Google Maps Master

Google Maps MasterA great up-to-date look at Google Maps and what it takes to master its ins and outs. The bulk of the article deals with using Maps’ search box. That’s great because the search box is full of great functionality that most users probably don’t have experience with. No matter what your level of skill with Google Maps, there is probably a trick or two to learn here.

2. Worldology.com – World War II: Interactive Map

World War II Map

This is a great little Flash based map that gives you an interactive look at the progression of World War II in the European theater. You can visually see the progression of the war and you can read the popup excerpts as you mouse over the different countries. There is even an option to see current political boundaries overlaid on the map. Cool.

3. freegeographytools.com – Download Page

Free stuff is really neat. Free GIS stuff is even neater. Freegeographytools.com is a nifty little blog that focuses on, you guessed it, free geography tools. The download page provides links to many of these tools like data conversion utilities, KML tools and raster tools. It doesn’t seem like the blog has been updated since 2011. There might be better alternative out there but there is still some good information here.

Jump Start Your Geospatial Career with This Free E-book

It’s a great time to be a GIS professional. There are no shortages of jobs and the field keeps changing and expanding to include amazing technologies and applications. However, with increasing demand often comes increasing competition. Anyone who wants to enter the geospatial field or advance in it needs to pay attention to fast changing industry needs and make sure they are positioned to fill those needs.

The folks over at DirectionsMag.com have put together a collection of articles dealing with topics of interest to all levels of the geospatial community. It is called GIS Jobs, GISP Certification and Geospatial Careers and can be downloaded at

 

**

Update:  The following page has been removed from directionsmag.com

**

http://www.directionsmag.com/books/gis-jobs-gisp-certification-and-geospatial-careers/347075.

It is a great little PDF e-book covering things from GIS job interviews to issues surrounding certification. Have a look, it’s free.

 

Easily Export ArcGIS Attribute Table to CSV

For many ArcGIS users, exporting an attribute table to a .csv file or excel format file is a common part of their workflow. Unfortunately, exporting to either of these formats directly from the attribute table has never been a core functionality of ArcGIS. To overcome this you typically have had two choices: write a script using third party libraries or use an ArcToolbox tool like the Export Feature Attributes to ASCII Tool or the Table to Excel conversion tool. But with each of these you have to open special tools or go through multiple steps to convert.

However, there is a little shortcut you can take to quickly export your data to .csv right from the attribute table.

  • From the table, click Export.
  • Under “Output Table” browse to the folder you want to put your .csv file in, save type as .txt and enter a name for your output making sure to leave off the ‘.txt’ from the end of the name.

If the ‘.txt’ extension is present in the name the tool will output a normal text file of your data. If, however, your name does not include the ‘.txt’ extension or if you specify .csv, then your output will be a .csv file by default.