Tuesday, January 30, 2018

City Symbols (Part 9): Using City Icons on a Map

In the previous posting, I finished up creating the settings to make city icons like those used on the Skies of Fire map:
Now I'm going to talk about using these on a map.

Currently, Dragons Abound marks the locations of cities with circles:

Different size cities are indicated with different size and style of circles.  This is a very common map style, and has a lot of advantages when on procedurally generated maps.  It's easy to center the circles on a location, easy to calculate how close the label is to the circle, and it looks fine even when it overlaps the ocean or a map feature (like the symbols for "Bi en I" and "Ao Oiru" do in the map above).  

The procedurally-generation city icons, on the other hand, are relatively large and oddly shaped.  Sometimes they look fine on the map, as with these examples:
But often there are problems, as with these examples:

The icon in the upper left is floating out to sea (or more generally, interacting in a bad way with another map feature) while the icon in the lower right is colliding with it's own label.  The latter problem is a simple fix.  In the quick hack I did to add these icons to to the map, the labeling routine doesn't know that the icon is bigger than the small circle it expects, so I just have to add in a more correct size:
The other problem is more difficult.  The city icons are large and not uniformly shaped, so it seems inevitable that these will sometimes collide with other map elements in an unwelcome way.

However, I have one advantage that a real cartographer doesn't.  My maps don't have to reflect "reality."  Since I'm generating the entire map, I can choose not to generate a city in a place where the city icon would look bad!  There are a couple of ways to do this.

One approach would be to simply eliminate any city that had an icon problem.  But that might eliminate too many of the cities -- I don't want to unwittingly depopulate the map.

Another approach is to have rules during city generation that would avoid locations where the icon would look bad.  The difficulty with this approach is that at the time I'm generating the city locations I don't know how I'm going to be displaying them -- what kinds of icons or the sizes and shapes of the icons.  (And I want to keep generation and display separate.)  So the rules would need to be very general and conservative to work well. In the case of "Chuskoon" above I'd need to have a rule that keeps city locations far enough away from the coast that the biggest possible icon wouldn't stick out to sea.

Another approach is to wait until I'm going to display the cities, and then move any city location that is causing a problem.  In the case of "Chuskoon" above I'd slide the city location to the left until the actual icon I'm using no longer overlapped the ocean.  This would result in the minimal "fix" for each problematic city.  The challenge with this approach is that moving the city location might break other map features.  For example, if I've drawn a road between Chuskoon and another city, the road might now go to the wrong location.

Considering all these approaches, I'm inclined to use the last.  My intuition is that most fixes will only require moving the city a short distance, so the impact of moving the city should be minimal.  Also, with the relatively large icons, there's a good chance that the original location of the city will still be somewhere under the icon.  It doesn't really matter if a road comes into the Chuskoon icon at the lower left or the lower right.  So this should also help minimize this problem.

The question now is how to move the city location to fix any problems.  We have a desired location for the city location (the original location) and we want to find the closest nearby spot that meets the other criteria (not overlapping a map feature, etc.)...  Hey, this is sounding a lot like another problem!

In fact, this is the same as trying to find a good label location (although city locations will have different success criteria).  And there's no reason I can't run city locations at the same time as the label locations.  I'll just treat the city icons as "labels" that need to be placed on the map, with a strong preference to being near their original location.

So what criteria should I use when placing the city icons?  Consider these examples:
Here I have cases of city icons overlapping rivers, mountains and coastlines.  Most of these look fine to me.  The 7 building city near the bottom middle looks a little awkward on the river, but the other cities straddling rivers don't look as awkward.  A river passing behind a city (as with the other two cities at the bottom of the image) looks fine.  The icons that overlap upward into the ocean look fine.  The middle upper icon that overlaps a bay looks a little confusing, but is probably acceptable.

Here are some examples that don't work as well:
In each of these cases, part of the baseline of the icon is in the ocean.  It looks okay if the icon projects upward into the ocean, but it's not okay if the icon looks as if it is sitting in the ocean.

The reference map mostly follows similar rules, but breaks them in a few places:
In this excerpt there are icons overlapping mountains and rivers, as well as sticking up into the ocean.  But while most of the icons are placed to stay out of the ocean, a few like "Port Turio" have a foot in the ocean.

So it would appear that the most important criteria is to place the icon so that the baseline of the icon is entirely on land, while staying as close as possible to the original city location.  I'll also add a criteria to keep the icon on the screen.   After implementing that (and a frustrating couple of days debugging) I have this:
You can see that all of the cities have migrated onto the land, where they're generally snugged up against the coastline near the original city location.

One subtle problem this introduces is in the label for the city.  Now that cities can move around the map, the city labels need to follow them -- I can no longer tie the label to the original static city position.  For example, in the above map, you can see that "Nuochnir" has been placed close to the city's original location rather than it's final location.  To make the labels follow the cities around, I have to link the labels to the icons rather than a static point:
And now "Nuochnir" and "Nochboch" have migrated to better locations.

Here's what a full map looks like (click through for full-sized version):

No comments:

Post a Comment