AlterConf

Yesterday, I attended AlterConf here in Atlanta. Thanks to The Iron Yard for sponsoring the event and giving me a chance to attend. Here are my takeaways from some of the talks:

The 12 Year Old I.T. Guy, Nicholas Black

  • It's not who you are that holds you back. Telling yourself you're not something is what holds you back.

Why Diversity in Video Games Matters, Imran Khan

  • "Video games where I can identify with the main character are more engaging than video games where I cannot."
  • 80% of black characters in video games are in sports games.

Context for People of Color, Juwan Platt

  • There is a lack of context in the community about how coding fits into the world.
  • Context → content → diversity

Being a Parent in Tech, Liberty White, John McSwain, and Alex Bowers Schoen

  • Talk to managers and others about what will work for you.

 

 

Professionally Prepared but Not Pioneer Prepared, Monica F. Cox

  • In 2012, there were about 150 female African American engineering professors in the U.S.
  • "I was prepared to be a professor, but I was not prepared to be a pioneer."

The Labors of Inclusivity, Mariam Asad & Sarah Schoemann

Job Listing Minesweeper, Pamela Vickers

  • Mines:
    • We like a homogeneous team
    • Rigid requirements
    • Vague structure/policies
    • Zealously mediocre
    • Aggressive language

The Experience of Access, Laurel Lawson

  • Everyone on a team is responsible for UX.
  • Accessibility means people can use what you build in the manner of their choice.
  • Our architecture should not dictate how people use what we build.
  • Even in diverse teams, vision is limited. A team of 4-8 people can only have so much diversity.
  • Diverse user bases are bigger and more profitable.
  • Access to culture, access to education, access to space
  • Access should be easy.

My Overall Takeaways:

Tagged

CodeAcross 2015: Creating an Asset Map of South Downtown Atlanta

This weekend, I attended the CodeAcross Atlanta hack weekend, run by Code for Atlanta and hosted by the Center for Civic Innovation. The topic of the hack weekend was the South Downtown neighborhood of Atlanta.

South Downtown is a neighborhood that's been long ignored and overlooked. But it's brimming with potential. The buildings are there, the density is there, and the people are arriving. South Downtown is waking up.

Our hosts at the Center for Civic Innovation are kicking off a long-term effort to shape the future of South Downtown, and Code for Atlanta is partnering with them on this goal.

We're going to get out of the building and take some walking tours of the area to get a real feel for it, then we'll hear from those who live, work, and play in South Downtown. Based on what we learn, we'll then get to business and start hacking on projects. There will be maps to make and data to open.

This is a rare opportunity to help revitalize a neighborhood at the perfect moment. South Downtown will be a great neighborhood in the near future, and you'll help shape it at CodeAcross Atlanta. —Code For Atlanta

Learning about South Downtown

To kick off our hack weekend, Luigi gave an intro to civic hacking. Then Kyle Kessler gave a presentation on the South Downtown neighborhood, past and present. He covered the formation of Atlanta as "Terminus", the Civil War and burning of Atlanta, Atlanta's reemergence, civil rights, Underground Atlanta, the Olympics, and more. This presentation provided a helpful overview to thinking about how South Downtown can be revitalized.

One nice thing about the event was that it actually occurred in South Downtown, the area of interest. CodeAcross was hosted by the Center for Civic Innovation, at the M. Rich Building. As a result, we all got to take a nice walking tour of the neighborhood, to better frame the work we would do over the weekend. Personally, I'm pretty familiar with South Downtown. I'm currently attending The Iron Yard Academy, which is located in the same building, and even before that course, I've biked through South Downtown quite a bit. That said, the walking tour was still beneficial to me. A few people in our group had detailed knowledge about the neighborhood, and it was helpful to know more details. The walking tour probably also helped make our map feel more real to the other contributors.

Three Groups

After lunch, we split up into groups. Three topic were presented, and people were allowed to choose which group they wanted to participate in.

A branding campaign and storytelling website for South Downtown that begins to change the hearts and minds of Atlantans and their impressions of the neighborhood. Yes, we need folks who can code and launch a website. But just as importantly, we need designers to think about the real-world implications of what a strong brand means for a neighborhood. And we'll need gifted storytellers to convey the gravity of the history of the neighborhood and the role it played in the civil rights movement.

An interactive asset map that comprehensively displays existing properties in the neighborhood and opportunities for economic development. We need mapping experts to write the code to build the map, but we also need people with expertise in commercial real estate and city planning to help guide the design of the map. We need volunteers to go out into the neighborhood and figure out what exactly is there, because the data about the neighborhood is in many instances incorrect or out-of-date.

A participatory tool that amplifies the voices of those who live and work in South Downtown. This tool needs to work both on-line and on-the-ground. In many instances of economic development, the powerful, monied interests coming in simply don't listen to the people already in the area. We'll build a platform that collects input from the community and actually delivers that input to key stakeholders. To design it well, it'll require the "soft skills" of listening and empathy. To make it effective, it'll need guidance from those experienced in advocacy and lobbying the powerful. —Luigi Montanez

Unsurprisingly, I chose the asset map group.

The Asset Map Group

The first step for the asset map group was to whiteboard out what layers we would like to see on the map. We also had to decide who the target audience was for the map. We came to the conclusion that it would be best to have different maps for different audiences (e.g. developers, advocates, visitors), but our focus for the weekend should be to find as many data layers as we could that would have relevance to any of the audiences. Then—after the weekend—we will split the map up into multiple maps. Here are just a few of the layers from our list of ideal data:

  • Zoning
  • Population density and demographics
  • Parking
  • Transit
  • Infrastructure
  • Organizations and social events
  • Art
  • Filming locations

Luigi was the leader of the asset map group. There were around 12 people who chose to work primarily on the asset map. We decided it would be most efficient with such a large group to split up into two sub-groups, one working on research and data, and the other sub-group working on creating the map. It was the first group's job to research each of the map layers we wanted, find if data was readily available, and if it was available, they would get it ready to send along to the map team. If it wasn't readily available, they would try to determine who might have the data and how it could be obtained.

I was the leader of the sub-group creating the map. We were tasked with making an interactive map showing all the layers of data found by the research and data cleaning team.

Making the Map

Day 1

On day one, the research and data cleaning sub-group created a google doc and drive folder and began collecting data to add to the map. Our coding sub-group got the preliminary map set up, and I threw in a couple data layers that I already had handy from previous map projects. The Leaflet newbies ran through a quick tutorial and we looked at alternative mapping platforms like Mapbox and Tilemill. Also on day 1, Bryan and Jimmy in the coding sub-group started working on a geocoder in Ruby, since we knew some of the data the researchers would provide us wouldn't have coordinates.

In our Leaflet map, we made use of a few libraries to help make our job of mapping easier and make our finished product look good quickly. Leaflet only supports GeoJSON by default, but by using leaflet-omnivore and leaflet.shapefile/shapefile-js, we are able to import CSV, GPX, shapefiles, and more. This is helpful for the fast prototyping needed to get something substantial finished over a weekend like this. We also used Font Awesome and Leaflet.awesome-markers to create impressive looking map markers rapidly.

This is what our map looked like at the end of day 1:

Day 1 Progress

Day 2

On day 2, the research and data sub-group continued finding data sources, and sent many of them along to our mapping group. They also helped us out with some GIS work by taking some of the shapefiles they had found and cropping them down to our area of interest. Additionally, they provided domain expertise, helping us interpret the data and deciding with us which data fields should be shown in map popups.

In the coding sub-group, Jimmy completed the geocoder and used it on a few of the data sources. We added those to the map, as well as adding several other point layers that already had coordinate data. During the night, I had implemented queries of the Foursquare API, so we spent some time on day 2 thinking of what kinds of venues we wanted to pull from Foursquare. We added government buildings, entertainment, residential buildings, and food from the Foursquare API. I also learned how to do image overlays, so we threw in a couple of maps the data group had gathered. Finally, we added in some shapefiles the data group had found. All-in-all, we had 14 map data layers at the end of day 2. When we presented our work, it seemed people were impressed by how much stuff is in South Downtown and at how quickly we were able to assemble and map so much of it.

Day 2

I was equally impressed with the branding/storytelling and participatory groups. The branding and storytelling group thought up neighborhood slogans and set up a preliminary website to host information about South Downtown. The participatory group came up with a basic survey that can be filled out via text or web and thought up ways to advertise the survey and engage individuals with interactive street displays. I was greatly impressed by how much we got done in a weekend project.

Even better yet, Code For Atlanta has structured a meetup so we can continue working on this project in the future. Usually when I do hackathons and other hack events, I'm disappointed by the project not continuing and often not getting to see my work get used. I'm really looking forward to meeting up once a month with the other hackers to continue our efforts.

And we certainly have plenty more to do. There's still much more data that the research team found that we haven't had a chance to implement in the map yet. There's also more data we haven't found yet, and data we haven't even begun to be sure how to measure (e.g. community). We also want to create separate maps for different audiences and integrate the map into the website.

I enjoyed helping to lead the asset mapping team, and I'm greatly looking forward to continuing to work on this project. I really care about South Downtown, and this weekend made me feel like I was helping the neighborhood, while also getting to do something I love with really great people. I highly recommend joining Code for Atlanta (or your local Code for America brigade). As I think our mapping project showed, even if you aren't a coder, there are huge ways you can contribute. Thanks to my team and to the organizers of the event for making it the best hack weekend or hackathon I've attended!

The map will eventually be available at southdowntown.org, but for now you can find the code on Github.

Tagged , ,

Adding a marker with a custom image to a Mapbox map in Swift

There aren't a lot of Swift mapping tutorials out there, so I'm writing a series of blog posts on the topic. First up is how to create a map marker with a custom image in a Mapbox map.

First, install the Mapbox SDK as described here.

Next, since we're using Swift, you'll need to create a bridging header by creating a new Objective-C file (empty file) in the project and answering "Yes" to "Would you like to configure an Objective-C bridging header?" In the Project Name-Bridging-Header.h file that was just created, add:

#import <UIKit/UIKit.h>
#import "Mapbox.h"

Now, in your ViewController.swift (or wherever you choose), make sure your class is a RMMapViewDelegate.

In viewDidLoad, add your API access token. You can get your API access token here.

RMConfiguration().accessToken = "your-token-goes-here"

Next, add the map view:

var mapFrame = CGRectMake(0, 20, view.bounds.width, view.bounds.height)
var mapTiles = RMMapboxSource(mapID: "your-map-id")
var mapView = RMMapView(frame: mapFrame, andTilesource: mapTiles)
mapView.delegate = self

If you want, you can also zoom and center the map now:

mapView.zoom = 10
mapView.centerCoordinate = CLLocationCoordinate2DMake(33.755, -84.39)

Now, take the file you want to use as your map marker and add it to the Images.xcassets.

Back in your View Controller (or other file), add:

var location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(33.78,-84.41)
var annotation = RMAnnotation(mapView: mapView, coordinate: location, andTitle: "Proximity Viz LLC")
annotation.subtitle = "Maps & Apps"
annotation.userInfo = "company"

Of course here you will put in your own coordinates, title, and subtitle. userInfo is a handy place to put any other information you might want, i.e. categories that the icon will be based on. E.g. "company" would have one icon and "park" would have another.

Now is when the delegate action comes in, so make sure you included RMMapViewDelegate at the beginning of your file. Let's add the function that will create a layer for each of our annotations. If you only have one image for your markers, you can use this code:

func mapView(mapView: RMMapView!, layerForAnnotation annotation: RMAnnotation!) -> RMMapLayer! {

    var marker: RMMarker = RMMarker(UIImage: UIImage(named: "proximity"))
    marker.canShowCallout = true

    return marker

}

Or if you have multiple images for different categories, you can use this code:

func mapView(mapView: RMMapView!, layerForAnnotation annotation: RMAnnotation!) -> RMMapLayer! {

    var marker: RMMarker = RMMarker(UIImage: UIImage(named: "proximity"))
    marker.canShowCallout = true

    var parkMarker: RMMarker = RMMarker(UIImage: UIImage(named: "park"))
    parkMarker.canShowCallout = true

    if(annotation.userInfo as NSString == "park"){
        return parkMarker
    } else {
        return marker
    }

}

Now when you run the app, you should see your custom marker(s)!

Mapbox map with custom marker

The code is available in a gist.

This post is one part of my series on Mapping in Swift.

Tagged , , , , , ,

LWIMW 9

I just finished my submission for Look What I Made Weekend 9. Look What I Made Weekend (LWIMW) is a chance for people to create something over the course of 48 hours. The concept is based on Ludum Dare and other game jams, but for LWIMW you don't have to make a game. Instead, you are free to pursue any creative endeavor and show off your results at the end.

NB: The content below is mostly a reprint of my submission at LWIMW.

This is my first app using Swift and also my first app using MapKit.

It's a simple app that takes an average of several GPS coordinates so that you can get a more accurate estimate of the coordinates of a point.

Main VC

Before the weekend, all I had done was a quick sketch of what the app might look like.

What I got done this weekend:

  • GPS tracking (auto mode)
  • Averaging
  • Displaying tracking and averaging on map
  • App icon
  • Sharing

Averaged Coordinates

Saved Coordinates

What still needs to be done:

  • Persistent storing of data
  • Manual mode
  • Multiple coordinate formats
  • Some testing and miscellaneous improvements

You can view the code or download the app on Github.

Tagged , , , , ,

Reality TV Show Name Generator App

The Idea

I had come across webpages like They Fight Crime and the Fantasy Name Generator, so creating a random reality TV show name generator app was not at all an original idea.

When I was flipping through channels one day and saw an endless stream of a naming convention, inspiration struck. I noticed that most reality shows have a name that's just an adjective and a noun: American Idol, Hell's Kitchen, Pawn Stars, Top Chef, just to name a few. This seemed like a really simple concept to implement while learning a new language. Really, it's the simplest unique app I've thought of.

The Javascript Implementation

In 2013, I created a Javascript version of the app. I was just learning Javascript when I thought of the idea, and it was an easy first project to complete.

Javascript version

The Objective-C Implementation

When I started learning Objective-C in December, I followed the Crystal Ball app tutorial on Team Treehouse, and after that, I had enough knowledge to build the most simple version of the Reality TV app.

Basically, all the simplest version needs to do is:

  • Have two arrays
  • Pick a random item from the first array
  • Pick a random item from the second array
  • Concatenate them
  • Display the name
  • Have a straightforward way to refresh and get a new random name

Here's a screenshot of an early version:

Early Objective-C version

Components

As I advanced in Objective-C, I wanted to add more features. The first thing I added was a "share" button. This was surprisingly simple.

Once I started taking the Mobile Engineering class at The Iron Yard, I began to add more features. I wanted to add a "recent names" list and a "favorites" list and to have a way for people to add a name to their favorites.

Once we learned about TableViewControllers, adding the recent names list was fairly straightforward.

Early Recent Items

Early Share & Recent

What was more complicated was adding a "favorites" list. I wanted to have the favorites persist between app uses. This is something we haven't covered yet in class, but I got a tip from John–one of our TAs–and I managed to figure out how to implement it using NSUserDefaults.

Now that all of the functionality worked, what was left was the design. I needed icons for favoriting and sharing, and I wanted to make a custom TV design instead of using one someone else made since it was such a central part of the app.

Design

I wasn't happy with the way the original design looked, so I changed the color palette.

#009762#13BD81#000000#ffffff

Looking better!

One thing I'd had no intention of making was a sliding drawer that would give you more options. I didn't really even think of this as being an option! But then in class we made a drawer for one of our apps, and I realized it would be the perfect way to handle all the buttons I wanted to have (favorite, favorites, recent, share). I designed a drawer and added it to the app.

Drawer

For the icons in the drawer (favorite, menu, and share) and the refresh icon, I used Font Awesome and Ionicons, which are both free-to-use icon packages.

For the TV image, I wanted to create something custom, since it was so prominently displayed in the app. I played around some in Photoshop. Even though I can't draw at all, I can sure use a rectangle tool, and I think I managed to come up with something that looks acceptable. You can see my design on Dribbble. I also used this TV as my app icon, but I gave the app version wider antennae to make them easier to see in the smaller size.

I've been learning Sketch, but I've really only used it for UI mockups, not drawing things. Hopefully soon I'll be able to use a more appropriate tool like Sketch or Illustrator instead of using Photoshop for this kind of work, but for the moment, I'm still more comfortable in Photoshop.

Custom TV

The last design decision I had to make was how to handle:

  1. Favoriting recent names
  2. Sharing recent names and favorites

Originally, I had a share icon on the side of each cell on the recent items list. But once I added favorites, I would have needed to have two icons in each cell, one for sharing and one for favoriting. I decided this would be too cluttered, so I decided to return users to the main view when they tap on a name in a list. From there, they can do anything they would have been able to do when the name first appeared. This setup has the additional benefit of allowing people to make screenshots of items from their recent items list or favorites list.

Complete

You can download the iPhone app here. The code is available on Github.

Tagged ,

NSUserDefaults Example with NSMutableArray

I was misinformed that to have information persist between app uses, you had to either use Core Data or a cloud backend. Boy, was I ever wrong. It's so much easier than that!

From NSHipster:

NSHipster's opinion

In this case, we're going to be doing something even easier than the full NSKeyedArchiver. For this blog post, we'll be creating a very simple array example for using NSUserDefaults to persistently store data. We'll be able to add items to and remove items from the array.

  • Start a new Single View Application project.
  • Delete ViewController.h and ViewController.m.
  • Remove the View Controller from the storyboard.
  • Make a new file that is a subclass of UITableViewController. Name it ItemTVC.
  • Drag a Table View Controller into the storyboard and make it the Initial View Controller (in the Attributes inspector). Give it the class ItemTVC. Give the cell the identifier "Cell".
  • Leave ItemTVC.h as it is and work in ItemTVC.m.

In viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    self.array = [[defaults arrayForKey:@"array"] mutableCopy];

}

NSUserDefaults will always return an immutable version of any object you pass it. As a result, we need to use mutableCopy before using the array we've retrieved from NSUserDefaults.

In (IBAction)addItem (storyboard for add item button) or insertNewObject (code for add item button) or similar:

// if you aren't using storyboard, this might be insertNewObject or a similar method instead of an IBAction
- (IBAction)addItem:(id)sender {

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    if ([self.array count] == 0) {
        self.array = [[NSMutableArray alloc] init];
    }

    [self.array addObject:[NSDate date]];
    [defaults setObject:self.array forKey:@"array"];
    [self.tableView reloadData];

}

In cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    NSDate *item = self.array[indexPath.row];
    cell.textLabel.text = [item description];

    return cell;
}

This step is optional. If you want to be able to remove items, add this in commitEditingStyle forRowAtIndexPath.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleDelete) {

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

        [self.array removeObjectAtIndex:indexPath.row];
        [defaults setObject:self.array forKey:@"array"];
        [self.tableView reloadData];

    }

}

The full code is available on Github.

References

Tagged , , , , , , ,

First Post with Pelican

Let's see if it works!

Tagged ,

Book Review: Leaflet.js Essentials by Paul Crickard III

This is a review of Leaflet.js Essentials by Paul Crickard III.

Contents

  • Chapter 1 introduces creating a basic map from scratch with leaflet, how to use map tiles, how to create popups, and how to enable geolocation.
  • Chapter 2 shows how to create GeoJSON data, how to style GeoJSON layers by type (LineString, Polygon, etc.), and how to filter to display only a subset of the data.
  • Chapter 3 introduces the leaflet.heat plugin for density heat maps and the heatmap.js library for intensity heat maps. It also teaches how to style and animate heat maps, how to create choropleths, and how to use buttons outside the map to change what's shown in the map.
  • Chapter 4 introduces how to create custom markers and marker shadows as well as several markers that are available online. We also learn how to cluster markers, animate markers, and create pie or bar chart markers.
  • Chapter 5 shows how to use many ESRI resources in Leaflet, including map tiles, shapefiles, and geocoding.
  • Chapter 6 introduces using Node.JS, Python, and C# with leaflet, including getting data via AJAX calls, using MongoDB to save created map points, and creating desktop applications with C#.

Review

This is a very well laid-out, detailed guide to Leaflet. It is intended for complete newbies to Leaflet, but it provides some very advanced information as well. The book claims you should have some JavaScript knowledge before beginning, but I'm not entirely sure this is necessary, since Leaflet maps rely on only very minimal JavaScript.

I enjoyed the breadth of this book. I think the book does a great job of covering the information a beginner would need. It also provides information on a wide variety of topics like good tips for designing for mobile, a very comprehensive list of map tiles (many of these I did not know about), and information on several JavaScript libraries and Leaflet plug-ins that allow for additional functionality within the maps.

On the other hand, there is one major criticism I have with this book, especially for a beginner audience. I'm not that happy with the included code samples or how they are organized. This may just be personal preference, but I prefer books that have the "before this section" code and the "after this section" code so you can start with the before and then double-check with the after if you made an error or didn't understand something. I feel like the provided code samples made it difficult to follow along with programming while reading.

All in all, I wouldn't hesitate to recommend this book to someone beginning to learn Leaflet. For more advanced Leaflet users, there are some gems that may or may not make the book a worthwhile purchase. I will say that I use Leaflet almost every day, and I did learn several things from reading Leaflet.js Essentials.

4 out of 5 stars

Tagged ,

Add Icons to Layer Control in Leaflet

When you have multiple layers, it can help to add a legend to the map. This tutorial shows how to add icons to the layer control in Leaflet. This tutorial shows only marker layers, but you could create icons for polygon layers and use those as well.

Legend with marker icons

The following code sets up our map, layers, and the layer control. This is the standard way maps look in Leaflet, with no visual indication of which layer goes with which markers, without checking the boxes on and off.

var map = L.map('map', {
    center: [33.8, -84.4],
    zoom: 11,
        layers: [trainLayer, treeLayer]
});

var overlayMaps = {
    "Train": trainLayer,
    "Tree": treeLayer
};

L.control.layers(null, overlayMaps, {
    collapsed: false
}).addTo(map);

Default legend

In order to add a legend to the layer control, you can simply change the overlayMaps code to add any HTML you'd like. In this case, we'll add the map icon pngs with a small height so they will look okay in the layer control:

var overlayMaps = {
    "<img src='http://mollietaylor.com/skills/js/leaflet/train.png' height=24>Train": trainLayer,
    "<img src='http://mollietaylor.com/skills/js/leaflet/arbol.png' height=24>Tree": treeLayer
};

It's really that simple! I searched the documentation and the web, and I couldn't figure out how to do this, so I figured I'd just try adding the HTML. Turns out it looks great!

Full code available on CodePen. Map icons by Nicolas Mollet and Axel Rodriguez.

Tagged , , ,

Changing Leaflet Slidemapper to a Side-by-Side View

The default setup in slidemapper is to have the slides either above or below the map. However, it is also possible to place the slides to one side of the map.

Slides beside map

CSS changes

We need to make a couple of changes to how the smapp-show and smapp-map classes are displayed. You'll want to play around with these some, but this is what worked well for me:

.smapp-show { 
    width:50%; 
}
.smapp-show .slide { 
    overflow-y:visible; 
}
.smapp-map { 
    margin:10px; 
    width:48%; 
    height:95%; 
    position:absolute; 
    top:0; 
    right:0; 
}

Slidemapper changes

On the slidemapper side of things, the only edit we need to make is changing the options of our slideshow. Specifically, we need to edit the slideHeight and mapHeight to something appropriate for having the slides beside the map. For example, I chose:

$mySlideMap = $('#slideshow-container').slideMapper({
    slideHeight: 540,
    mapHeight: '98%'
});

And that's all the changes you need to make to have a side-by-side slideshow in slidemapper! The full code is available as a gist.

References

Tagged , , , ,