OneBusAway / onebusaway-iphone

OBA development has moved!
https://github.com/OneBusAway/OBAKit
Apache License 2.0
219 stars 117 forks source link

Replace OBAStopIconFactory with something a little more flexible #789

Closed aaronbrethorst closed 8 years ago

aaronbrethorst commented 8 years ago

OBAStopIconFactory has served us very well for a very long time, but, as OBA becomes multi-lingual, we will need to look at replacing it.

I'd like to keep the public interface and the UIImages that are output 100% unchanged for the time being, but I'd like to see the images that are generated be created mostly in code.

Example

busstopicone 2x

Let's take the above bus stop icon as an example. The only raster image that should be used to compose this icon should be the icon of the bus itself. The white background, black squircle, arrow, and the word "STOP" should all be rendered in code.

This should work for all supported route types:

and it should work for all directions.

Icons should be rendered on demand, work for any screen density (1x to 3x), and be cached after creation.

barbeau commented 8 years ago

FYI - we generate OBA Android stop markers completely from code (there is no raster there for us, just a circle with an arrow), which has been great for white labeling, as the color can easily be re-themed. Our vehicle markers are closer to what you're proposing above, with a raster bus image and dynamic coloring.

FWIW - from my experience on Android, it's far easier to dynamically generate icons with arrows that exist within the main icon borders (which I did for the vehicle marker icons) than trying to dynamically render an arrow outside the main icon border (which I did for the stop marker icons). (EDIT - to clarify, I'm not actually generating arrows inside the vehicle markers dynamically - I do have different rasters for that).

The current iOS stop icon has the arrow rendered on the outside, while here's an example of a vehicle marker raw image that has the arrows inside the marker border:

image

The reason behind the difficulty is that if you want the marker to land at the correct lat/long on the map, and the arrow is outside the border, you have to account for the offset of the arrow itself when calculating the anchor point of the icon. If the arrows are inside, you can always anchor the icon halfway between the borders. I spent far more time than I'd like to admit getting this to work properly for the OBA Android stop icons, and this is one reason why I chose to put the arrows inside the marker for the vehicle markers.

I'm definitely not telling you to switch, but just a heads up that this might be more difficult than it appears at first glance - I wish someone would have given me a heads up on Android. Maybe (hopefully) this is easier to implement on iOS - on Android it's effectively drawing on a canvas. Anyway...my two cents :).

aaronbrethorst commented 8 years ago

@barbeau:

if you want the marker to land at the correct lat/long on the map, and the arrow is outside the border, you have to account for the offset of the arrow itself when calculating the anchor point of the icon

I hadn't thought about this... Thanks for raising this point. Have you gotten any complaints from users about legibility of the icons?

barbeau commented 8 years ago

No complaints, and I've actually gotten feedback that stop icon direction is easier to see in v2 than v1. We had gotten complaints in v1 that the stop direction arrows were hard to see - see v1 (left) vs v2 (right) below:

image

And for completeness this is how the vehicle markers look in v2:

image

barbeau commented 8 years ago

Also of note - for stop icons in OBA Android v1, the bus image was always used. We didn't have (and still don't) any visual indication that a particular stop is for rail vs. bus - I believe this is different for iOS, as you show rail vs. bus icons at stops (which I think is useful). We just rolled out an update around a month ago that shows different vehicle icons based on mode.

chadsy commented 8 years ago

Ok, so a few observations/thoughts:

The map pin still needs an obvious Anchor Point, something that’s significantly visually different from the direction indicator. Android has solved this, iOS needs to.

I also appreciate that Android doesn't show detailed pins for all stops, making the map view so much cleaner. I wonder if we can do this on iOS as well?

I’d suggest dropping the word STOP. Because it’s contextually obvious, complicates the implementation, and pollutes the appearance.

It feels like there might be a way to composite the pin image from a stop type glyph and a direction (even just using one direction asset and rotating it an appropriate amount) rather than going to full code rendering. Either way, we'd greatly reduce the breadth of icons needed.

Any other thoughts before I jump in on this?

aaronbrethorst commented 8 years ago

Any other thoughts before I jump in on this?

Nope, go for it!

chadsy commented 8 years ago

The AIGA set only has Rail, no Light Rail (OBARouteTypeLightRail) or Metro (OBARouteTypeMetro). Also the closest to Ferry is "Water Transportation" and is rather ugly for the map pin.

Perhaps for the first run at this I will focus on just replacing the existing assets with a root glyph and code for the rest.