Source code for tracktable.info.cities

#
# Copyright (c) 2014-2017 National Technology and Engineering
# Solutions of Sandia, LLC. Under the terms of Contract DE-NA0003525
# with National Technology and Engineering Solutions of Sandia, LLC,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# -*- encoding: utf-8; -*-

"""
cities.py - Locations and population values for many cities of the world
"""

#
# This code is derived from a list of cities provided by MaxMind at
# http://www.maxmind.com/en/worldcities.  Here is the license under
# which we use and redistribute the data:
#
# OPEN DATA LICENSE for MaxMind WorldCities and Postal Code Databases
#
# Copyright (c) 2008 MaxMind Inc.  All Rights Reserved.
#
# The database uses toponymic information, based on the Geographic
# Names Data Base, containing official standard names approved by the
# United States Board on Geographic Names and maintained by the
# National Geospatial-Intelligence Agency. More information is
# available at the Maps and Geodata link at www.nga.mil. The National
# Geospatial-Intelligence Agency name, initials, and seal are
# protected by 10 United States Code Section 445.
#
# It also uses free population data from Stefan Helders www.world-gazetteer.com.
# Visit his website to download the free population data.  Our database
# combines Stefan's population data with the list of all cities in the world.
#
# All advertising materials and documentation mentioning features or
# use of this database must display the following acknowledgment:
# "This product includes data created by MaxMind, available from
# http://www.maxmind.com/"
#
# Redistribution and use with or without modification, are permitted provided
# that the following conditions are met:
#
# 1. Redistributions must retain the above copyright notice, this list of
# conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 2. All advertising materials and documentation mentioning features or use of
# this database must display the following acknowledgement:
# "This product includes data created by MaxMind, available from
# http://www.maxmind.com/"
#
# 3. "MaxMind" may not be used to endorse or promote products derived from this
# database without specific prior written permission.
#
# THIS DATABASE IS PROVIDED BY MAXMIND.COM ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL MAXMIND.COM BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DATABASE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from __future__ import print_function, absolute_import, division

import logging

from tracktable.core.geomath import latitude, longitude

CITY_TABLE = None
CITY_HEADERS = None

# ----------------------------------------------------------------------

[docs]class CityInfo(object): """Brief information about a city. Attributes: country_code (string): 2-character abbreviation for country name (string): City name population (integer): Estimated population latitude (float): Latitude of city location longitude (float): Longitude of city location """ def __init__(self): """Initialize an empty city.""" self.country_code = None self.name = None self.population = None self.latitude = None self.longitude = None
# ----------------------------------------------------------------------
[docs]def cities_in_bbox(bbox_min=(-180, -90), bbox_max=(180, 90), minimum_population=0): """Return all the cities in a bounding box. Kwargs: bbox_min (TrajectoryPoint): Southwest corner of bounding box, default (-180, -90) bbox_max (TrajectoryPoint): Northeast corner of bounding box, default (180, 90) minimum_population (integer): Cities with lower population than this will not be returned. Default 0. Returns: List of CityInfo objects. """ global CITY_TABLE if not CITY_TABLE: from tracktable.info.data.city_table import city_table as cities CITY_TABLE = cities result = [] logger = logging.getLogger(__name__) logging.debug(logger, ("cities_in_bbox: bbox_min is {}, " "bbox_max is {}".format(bbox_min, bbox_max))) logging.debug( logger, ("DEBUG: min_longitude is {}, min_latitude is {}, " "max_longitude is {}, max_latitude is {}").format( longitude(bbox_min), latitude(bbox_min), longitude(bbox_max), latitude(bbox_max))) min_longitude = longitude(bbox_min) max_longitude = longitude(bbox_max) min_latitude = latitude(bbox_min) max_latitude = latitude(bbox_max) for row in CITY_TABLE: lat = row[3] lon = row[4] if ( lon >= min_longitude and lon <= max_longitude and lat >= min_latitude and lat <= max_latitude and ((not minimum_population) or (row[2] >= minimum_population)) ): info = CityInfo() info.country_code = row[0] info.name = row[1] info.population = row[2] info.latitude = row[3] info.longitude = row[4] result.append(info) return result
# ----------------------------------------------------------------------
[docs]def largest_cities_in_bbox(bbox_min=(-180, -90), bbox_max=(180, 90), count=10): """Return the largest N cities in a bounding box. A city's size is measured by its population. Args: bbox_min (TrajectoryPoint): Southwest corner of bounding box. Defaults to (-180, -90). bbox_max (TrajectoryPoint): Northeast corner of bounding box. Defaults to (180, 90). count (integer): How many cities to return. Defaults to 10. Returns: A list of CityInfo objects. """ all_cities = cities_in_bbox(bbox_min, bbox_max) sorted_cities = sorted(all_cities, key=lambda city: city.population, reverse=True) return sorted_cities[0:count]
HEADINGS = [ u"Country",u"AccentCity",'Population','Latitude','Longitude' ]