I was in a similar boat with a site I was working on recently. Unfortunately, Drupal 7 does not fully support tokens on field entities; see http://drupal.org/node/691078. This is why the "location node" type exists in the location module -- it is easier to define tokens for your locations. However, I did not like the UX for location nodes; I greatly preferred the result that can easily be obtained with cck locations.
Since it was not possible to easily support tokens on cck locations, I instead wrote my own custom token code in my custom module for my site. I did spend quite a few hours trying to do the former first, before giving it up as much too large of an effort.
I'm not sure if you are using the location module, or if you are just defining your own entities that happen to contain locations. The fact that you have your location entities chained together implies that you're using your own entity types. Here's the result I came up with for the location module; you should be able to adapt it for standard entities without much trouble. The code below could probably use some minor improvements; 'und' should be LANGUAGE_NONE, the special-checking for a specific content type is probably unnecessary, etc.; it shouldn't be too hard for you to adapt in some code that resolves your chained entity references to build the tokens you need.
Once you've written your code, it's easy to select your new tokens in pathauto to define your URL structure.
function MYMODULE_token_info() {
// Because of http://drupal.org/node/691078, we just hack in our own
// field-based tokens here for now (cough).
// These tokens are only available for nodes of type MY_CONTENT_TYPE_WITH_LOCATION_FIELD
$node['field_location_street'] = array(
'name' => t("Location Street"),
'description' => t('The street address that a location is located at.'),
);
$node['field_location_city'] = array(
'name' => t("Location City"),
'description' => t('The city that a location is in.'),
);
$node['field_location_province'] = array(
'name' => t("Location Province"),
'description' => t('The abbreviation for the province (State) that a location is in.'),
);
$node['field_location_province_name'] = array(
'name' => t("Location Province Name"),
'description' => t('The full name of the province (State) that a location is in.'),
);
$node['field_location_country'] = array(
'name' => t("Location Country"),
'description' => t('The country that a location is in.'),
);
$node['field_location_country_name'] = array(
'name' => t("Location Country Name"),
'description' => t('The full name of the country that a location is in.'),
);
$node['field_location_summary'] = array(
'name' => t("Location Summary"),
'description' => t('A parenthesized summary of the location (City, State).'),
);
return array(
'tokens' => array('node' => $node),
);
}
function MYMODULE_tokens($type, $tokens, array $data = array(), array $options = array()) {
$replacements = array();
if ($type == 'node' && !empty($data['node'])) {
$node = $data['node'];
$location_field = array();
if (($node->type == 'MY_CONTENT_TYPE_WITH_LOCATION_FIELD') && (isset($node->field_location['und'][0]))) {
$location_field = $node->field_location['und'][0];
}
if (($node->type == 'MY_CONTENT_TYPE_WITH_NODE_REF_TO_TYPE_WITH_LOCATION_FIELD') && (isset($node->field_event_site['und'][0]))) {
$location_nid = $node->field_event_site['und'][0]['nid'];
$location_node = node_load($location_nid);
if (isset($location_node->field_location['und'][0])) {
$location_field = $location_node->field_location['und'][0];
}
}
if (!empty($location_field)) {
$location_field['summary'] = "(" . $location_field['city'] . ", " . $location_field['province'] . ")";
foreach ($tokens as $name => $original) {
if (substr($name,0,15) == 'field_location_') {
// $name is always 'field_location_xxx', so key is 'xxx'.
$key = substr($name, 15);
if (isset($location_field[$key])) {
$replacements[$original] = $location_field[$key];
}
else {
$replacements[$original] = '';
}
}
}
}
}
return $replacements;
}