def namer(f):
    import boundaries
    if f.get('CO_MUNCP') == 43027:
        return {
            'Le Mont-Bellevue': 'Mont-Bellevue',
            'Rock Rorest--Saint-lie--Deauville': 'Rock Forest—Saint-Élie—Deauville',
        }.get(f.get('NM_ARON'), boundaries.clean_attr('NM_ARON')(f))
    elif f.get('CO_MUNCP') == 66023:
        return {
            'Pierrefond-Roxboro': 'Pierrefonds-Roxboro',
            'Rosemont--La-Petite-Patrie': 'Rosemont—La Petite-Patrie',
        }.get(f.get('NM_ARON'), boundaries.clean_attr('NM_ARON')(f))
    else:
        return boundaries.clean_attr('NM_ARON')(f)
Example #2
0
def namer(f):
    import boundaries
    if f.get('NM_DIS'):
        return {
            "Champlain-L'Île-des-Soeurs": "Champlain—L'Île-des-Soeurs",
            "d'Ahuntsic": 'Ahuntsic',
            'de Bordeaux-Cartierville': 'Bordeaux-Cartierville',
            'de Saint-Sulpice': 'Saint-Sulpice',
            'du Sault-au-Récollet': 'Sault-au-Récollet',
            'Est (Pierrefonds-Roxboro)': 'Bois-de-Liesse',
            'Maisonneuve-Longue-Pointe': 'Maisonneuve—Longue-Pointe',
            'Ouest (Pierrefonds-Roxboro)': 'Cap-Saint-Jacques',
            'Saint-Paul-Émard': 'Saint-Paul—Émard',
            'St-Henri-Petite-Bourgogne-Pte-St-Charles':
            'Saint-Henri—Petite-Bourgogne—Pointe-Saint-Charles',
            'Étienne-Desmarteaux': 'Étienne-Desmarteau',
        }.get(f.get('NM_DIS'), f.get('NM_DIS'))
    else:
        return {
            'Le Plateau-Mont-Royal': 'Plateau-Mont-Royal',
            'Le Sud-Ouest': 'Sud-Ouest',
            'Pierrefond-Roxboro': 'Pierrefonds-Roxboro',
            'Rosemont--La-Petite-Patrie': 'Rosemont—La Petite-Patrie',
        }.get(f.get('NM_ARON'),
              boundaries.clean_attr('NM_ARON')(f))
    def setUp(self):
        self.definition = definition = Definition({
            'last_updated': date(2000, 1, 1),
            'encoding': 'utf-8',
            'name': 'Districts',
            'name_func': clean_attr('Name'),
            'id_func': attr('ID'),
            'slug_func': attr('Code'),
            'is_valid_func': lambda f: f.get('ID') == '1',
            'label_point_func': lambda f: Point(0, 1),
        })

        self.fields = {
            'Name': 'VALID',
            'ID': '1',
            'Code': '\tFoo—Bar–Baz \r Bzz\n',  # m-dash, n-dash
        }

        self.boundary_set = BoundarySet(
            last_updated=definition['last_updated'],
            name=definition['name'],
            singular=definition['singular'],
        )

        self.feature = Feature(FeatureProxy(self.fields), definition)

        self.other = Feature(FeatureProxy({
            'Name': 'INVALID',
            'ID': 100,
            'Code': 3,
        }), definition, SpatialReference(4269), self.boundary_set)
def namer(f):
    import boundaries
    n = boundaries.clean_attr('FEDENAME')(f)
    # @see http://www.parl.gc.ca/HousePublications/Publication.aspx?Language=E&Mode=1&DocId=6684609&File=4
    if n == 'Western Arctic':
        return 'Northwest Territories'
    else:
        return n
def namer(f):
    import boundaries
    n = boundaries.clean_attr('Descriptio')(f)
    if n.lower().startswith('tracadie'):
        return 'Tracadie—Hillsborough Park'
    elif n.lower().startswith('oleary'):
        return "O'Leary—Inverness"
    return n
def namer(f):
    import boundaries

    n = boundaries.clean_attr("ENNAME")(f).replace("\x97", "—").replace("\u0092", "'")  # m-dash

    mappings = {"Gaspsie—Les les-de-la-Madeleine": "Gaspésie—Les Îles-de-la-Madeleine"}

    return mappings.get(n, n)
def namer(f):
    import boundaries
    n = boundaries.clean_attr('Descriptio')(f)
    if n.lower().startswith('tracadie'):
        return 'Tracadie—Hillsborough Park'
    elif n.lower().startswith('oleary'):
        return "O'Leary—Inverness"
    return n
def namer(f):
    import boundaries
    n = boundaries.clean_attr('FEDENAME')(f)
    # @see http://www.parl.gc.ca/HousePublications/Publication.aspx?Language=E&Mode=1&DocId=6684609&File=4
    if n == 'Western Arctic':
        return 'Northwest Territories'
    else:
        return n
def namer(f):
    import boundaries
    n = boundaries.clean_attr('ENNAME')(f).replace('\x97', '—').replace("\u0092", "'")  # m-dash

    mappings = {
        'Gaspsie—Les les-de-la-Madeleine': 'Gaspésie—Les Îles-de-la-Madeleine',
    }

    return mappings.get(n, n)
def borough_namer(f):
    import boundaries
    code = f.get('CO_MUNCP')
    name = f.get('NM_ARON')

    # Sherbrooke
    if code == 43027:
        return 'Arrondissement %s' % int(f.get('NO_ARON'))

    # Montréal
    elif code == 66023:
        return {
            'Le Plateau-Mont-Royal': 'Plateau-Mont-Royal',
            'Le Sud-Ouest': 'Sud-Ouest',
            'Pierrefond-Roxboro': 'Pierrefonds-Roxboro',
            'Rosemont--La-Petite-Patrie': 'Rosemont—La Petite-Patrie',
        }.get(name, boundaries.clean_attr('NM_ARON')(f))

    else:
        return boundaries.clean_attr('NM_ARON')(f)
def borough_namer(f):
    import boundaries
    code = f.get('CO_MUNCP')
    name = f.get('NM_ARON')

    # Sherbrooke
    if code == 43027:
        return 'Arrondissement %s' % int(f.get('NO_ARON'))

    # Montréal
    elif code == 66023:
        return {
            'Le Plateau-Mont-Royal': 'Plateau-Mont-Royal',
            'Le Sud-Ouest': 'Sud-Ouest',
            'Pierrefond-Roxboro': 'Pierrefonds-Roxboro',
            'Rosemont--La-Petite-Patrie': 'Rosemont—La Petite-Patrie',
        }.get(name, boundaries.clean_attr('NM_ARON')(f))

    else:
        return boundaries.clean_attr('NM_ARON')(f)
def namer(f):
    import boundaries
    code = f.get('CO_MUNCP')
    name = f.get('NM_DIS')
    if code == 23027:  # Québec
        return {
            'Cap-Rouge-Laurentien': 'Cap-Rouge—Laurentien',
            'La Chute-Montmorency-Seigneurial':
            'La Chute-Montmorency—Seigneurial',
            'Lac-Saint-Charles-Saint-Émile': 'Lac-Saint-Charles—Saint-Émile',
            'Montcalm-Saint-Sacrement': 'Montcalm—Saint-Sacrement',
            'Monts': 'Les Monts',
            'Plateau': 'Le Plateau',
            'Pointe-de-Sainte-Foy': 'La Pointe-de-Sainte-Foy',
            'Saint-Louis-Sillery': 'Saint-Louis—Sillery',
            'Saint-Roch-Saint-Sauveur': 'Saint-Roch—Saint-Sauveur',
        }.get(name, name)
    elif code == 58227:  # Longueuil
        return re.sub(r"\b(?:d'|de |du |des )", '', name)
    elif code == 66023:  # Montréal
        return {
            "Champlain-L'Île-des-Soeurs": "Champlain—L'Île-des-Soeurs",
            "d'Ahuntsic": 'Ahuntsic',
            'de Bordeaux-Cartierville': 'Bordeaux-Cartierville',
            'de Saint-Sulpice': 'Saint-Sulpice',
            'du Sault-au-Récollet': 'Sault-au-Récollet',
            'Est (Pierrefonds-Roxboro)': 'Bois-de-Liesse',
            'Maisonneuve-Longue-Pointe': 'Maisonneuve—Longue-Pointe',
            'Ouest (Pierrefonds-Roxboro)': 'Cap-Saint-Jacques',
            'Saint-Paul-Émard': 'Saint-Paul—Émard',
            'St-Henri-Petite-Bourgogne-Pte-St-Charles':
            'Saint-Henri—Petite-Bourgogne—Pointe-Saint-Charles',
            'Étienne-Desmarteaux': 'Étienne-Desmarteau',
        }.get(name, name)
    elif code == 66097:  # Pointe-Claire
        return name.replace('/ ', '/')
    elif code == 81017:  # Gatineau
        return {
            'de Hull-Val-Tétreau': 'de Hull—Val-Tétreau',
            'de Saint-Raymond-Vanier': 'de Saint-Raymond—Vanier',
            'de Wright-Parc-de-la-Montagne': 'Wright—Parc-de-la-Montagne',
            'du Plateau-Manoir-des-Trembles': 'du Plateau—Manoir-des-Trembles',
        }.get(name, name)
    else:
        if name:
            return boundaries.clean_attr('NM_DIS')(f)
        elif f.get('MODE_SUFRG') == 'Q':
            return 'Quartier %s' % int(f.get('NO_DIS'))
        else:
            return 'District %s' % int(f.get('NO_DIS'))
Example #13
0
def namer(f):
    import boundaries
    code = f.get('CO_MUNCP')
    name = f.get('NM_DIS')
    if code == 23027:  # Québec
        return {
            'Cap-Rouge-Laurentien': 'Cap-Rouge—Laurentien',
            'La Chute-Montmorency-Seigneurial': 'La Chute-Montmorency—Seigneurial',
            'Lac-Saint-Charles-Saint-Émile': 'Lac-Saint-Charles—Saint-Émile',
            'Montcalm-Saint-Sacrement': 'Montcalm—Saint-Sacrement',
            'Monts': 'Les Monts',
            'Plateau': 'Le Plateau',
            'Pointe-de-Sainte-Foy': 'La Pointe-de-Sainte-Foy',
            'Saint-Louis-Sillery': 'Saint-Louis—Sillery',
            'Saint-Roch-Saint-Sauveur': 'Saint-Roch—Saint-Sauveur',
        }.get(name, name)
    elif code == 58227:  # Longueuil
        return re.sub(r"\b(?:d'|de |du |des )", '', name)
    elif code == 66023:  # Montréal
        return {
            "Champlain-L'Île-des-Soeurs": "Champlain—L'Île-des-Soeurs",
            "d'Ahuntsic": 'Ahuntsic',
            'de Bordeaux-Cartierville': 'Bordeaux-Cartierville',
            'de Saint-Sulpice': 'Saint-Sulpice',
            'du Sault-au-Récollet': 'Sault-au-Récollet',
            'Est (Pierrefonds-Roxboro)': 'Bois-de-Liesse',
            'Maisonneuve-Longue-Pointe': 'Maisonneuve—Longue-Pointe',
            'Ouest (Pierrefonds-Roxboro)': 'Cap-Saint-Jacques',
            'Saint-Paul-Émard': 'Saint-Paul—Émard',
            'St-Henri-Petite-Bourgogne-Pte-St-Charles': 'Saint-Henri—Petite-Bourgogne—Pointe-Saint-Charles',
            'Étienne-Desmarteaux': 'Étienne-Desmarteau',
        }.get(name, name)
    elif code == 66097:  # Pointe-Claire
        return name.replace('/ ', '/')
    elif code == 81017:  # Gatineau
        return {
            'de Hull-Val-Tétreau': 'de Hull—Val-Tétreau',
            'de Saint-Raymond-Vanier': 'de Saint-Raymond—Vanier',
            'de Wright-Parc-de-la-Montagne': 'Wright—Parc-de-la-Montagne',
            'du Plateau-Manoir-des-Trembles': 'du Plateau—Manoir-des-Trembles',
        }.get(name, name)
    else:
        if name:
            return boundaries.clean_attr('NM_DIS')(f)
        elif f.get('MODE_SUFRG') == 'Q':
            return 'Quartier %s' % int(f.get('NO_DIS'))
        else:
            return 'District %s' % int(f.get('NO_DIS'))
def namer(f):
    import boundaries
    n = boundaries.clean_attr('ENNAME')(f).replace('\x97', '—')

    # @see http://www.parl.gc.ca/HousePublications/Publication.aspx?Language=E&Mode=1&DocId=6684609&File=4
    mappings = {
        "Western Arctic": "Northwest Territories",
        # "Blainville": "Thérèse-De Blainville",
        # "Boucher—Les Patriotes—Verchères": "Pierre-Boucher—Les Patriotes—Verchères",
        # "Centre-du-Bas-Saint-Laurent": "Rimouski-Neigette—Témiscouata—Les Basques",
        # "Charlevoix—Montmorency": "Beauport—Côte-de-Beaupré—Île d’Orléans—Charlevoix",
        # "Chicoutimi": "Chicoutimi—Le Fjord",
        # "Dorval—Lachine": "Dorval—Lachine—LaSalle",
        # "LaSalle—Verdun": "LaSalle—Émard—Verdun",
        # "LeMoyne": "Longueuil—Charles-LeMoyne",
        # "Longueuil": "Longueuil—Saint-Hubert",
        # "Mont-Royal": "Mount Royal",
        # "Sainte-Rose": "Marc-Aurèle-Fortin",
        # "Soulanges—Vaudreuil": "Vaudreuil—Soulanges",
        # "Ville-Marie": "Ville-Marie—Le Sud-Ouest—Île-des-Soeurs",
        # "Brant": "Brantford—Brant",
        # "Lanark—Frontenac": "Lanark—Frontenac—Kingston",
        # "Leeds—Grenville": "Leeds—Grenville—Thousand Islands and Rideau Lakes",
        # "Mississauga—Cooksville": "Mississauga East—Cooksville",
        # "Northumberland—Pine Ridge": "Northumberland—Peterborough South",
        # "Ottawa—Orléans": "Orléans",
        # "Peterborough": "Peterborough—Kawartha",
        # "Rideau—Carleton": "Carleton",
        # "St. Paul's": "Toronto—St. Paul's",
        # "York West": "Humber River—Black Creek",
        # "Humboldt—Warman—Martensville—Rosetown": "Carlton Trail—Eagle Creek",
        # "Grande Prairie": "Grande Prairie—Mackenzie",
        # "Medicine Hat": "Medicine Hat—Cardston—Warner",
        # "Red Deer—Wolf Creek": "Red Deer—Lacombe",
        # "Sturgeon River": "Sturgeon River—Parkland",
        # "Saanich—Esquimalt—Juan de Fuca": "Esquimalt—Saanich—Sooke",
        # "Vancouver Island North—Comox—Powell River": "North Island—Powell River",
    }

    for key, value in mappings.items():
        if n == key:
            return value
    return n
def namer(f):
    import boundaries
    n = boundaries.clean_attr('FEDENAME')(f)

    # @see http://www.parl.gc.ca/HousePublications/Publication.aspx?Language=E&Mode=1&DocId=6684609&File=4
    mappings = {
        "Western Arctic": "Northwest Territories",
        # "Blainville": "Thérèse-De Blainville",
        # "Boucher—Les Patriotes—Verchères": "Pierre-Boucher—Les Patriotes—Verchères",
        # "Centre-du-Bas-Saint-Laurent": "Rimouski-Neigette—Témiscouata—Les Basques",
        # "Charlevoix—Montmorency": "Beauport—Côte-de-Beaupré—Île d’Orléans—Charlevoix",
        # "Chicoutimi": "Chicoutimi—Le Fjord",
        # "Dorval—Lachine": "Dorval—Lachine—LaSalle",
        # "LaSalle—Verdun": "LaSalle—Émard—Verdun",
        # "LeMoyne": "Longueuil—Charles-LeMoyne",
        # "Longueuil": "Longueuil—Saint-Hubert",
        # "Mont-Royal": "Mount Royal",
        # "Sainte-Rose": "Marc-Aurèle-Fortin",
        # "Soulanges—Vaudreuil": "Vaudreuil—Soulanges",
        # "Ville-Marie": "Ville-Marie—Le Sud-Ouest—Île-des-Soeurs",
        # "Brant": "Brantford—Brant",
        # "Lanark—Frontenac": "Lanark—Frontenac—Kingston",
        # "Leeds—Grenville": "Leeds—Grenville—Thousand Islands and Rideau Lakes",
        # "Mississauga—Cooksville": "Mississauga East—Cooksville",
        # "Northumberland—Pine Ridge": "Northumberland—Peterborough South",
        # "Ottawa—Orléans": "Orléans",
        # "Peterborough": "Peterborough—Kawartha",
        # "Rideau—Carleton": "Carleton",
        # "St. Paul's": "Toronto—St. Paul's",
        # "York West": "Humber River—Black Creek",
        # "Humboldt—Warman—Martensville—Rosetown": "Carlton Trail—Eagle Creek",
        # "Grande Prairie": "Grande Prairie—Mackenzie",
        # "Medicine Hat": "Medicine Hat—Cardston—Warner",
        # "Red Deer—Wolf Creek": "Red Deer—Lacombe",
        # "Sturgeon River": "Sturgeon River—Parkland",
        # "Saanich—Esquimalt—Juan de Fuca": "Esquimalt—Saanich—Sooke",
        # "Vancouver Island North—Comox—Powell River": "North Island—Powell River",
    }

    for key, value in mappings.items():
        if n == key:
            return value
    return n
Example #16
0
    def setUp(self):
        self.definition = definition = Definition({
            'last_updated':
            date(2000, 1, 1),
            'encoding':
            'utf-8',
            'name':
            'Districts',
            'name_func':
            clean_attr('Name'),
            'id_func':
            attr('ID'),
            'slug_func':
            attr('Code'),
            'is_valid_func':
            lambda f: f.get('ID') == '1',
            'label_point_func':
            lambda f: Point(0, 1),
        })

        self.fields = {
            'Name': 'VALID',
            'ID': '1',
            'Code': '\tFoo—Bar–Baz \r Bzz\n',  # m-dash, n-dash
        }

        self.boundary_set = BoundarySet(
            last_updated=definition['last_updated'],
            name=definition['name'],
            singular=definition['singular'],
        )

        self.feature = Feature(FeatureProxy(self.fields), definition)

        self.other = Feature(
            FeatureProxy({
                'Name': 'INVALID',
                'ID': 100,
                'Code': 3,
            }), definition, SpatialReference(4269), self.boundary_set)
def namer(f):
    import boundaries
    if f.get('NM_DIS'):
        return {
            "Champlain-L'Île-des-Soeurs": "Champlain—L'Île-des-Soeurs",
            "d'Ahuntsic": 'Ahuntsic',
            'de Bordeaux-Cartierville': 'Bordeaux-Cartierville',
            'de Saint-Sulpice': 'Saint-Sulpice',
            'du Sault-au-Récollet': 'Sault-au-Récollet',
            'Est (Pierrefonds-Roxboro)': 'Bois-de-Liesse',
            'Maisonneuve-Longue-Pointe': 'Maisonneuve—Longue-Pointe',
            'Ouest (Pierrefonds-Roxboro)': 'Cap-Saint-Jacques',
            'Saint-Paul-Émard': 'Saint-Paul—Émard',
            'St-Henri-Petite-Bourgogne-Pte-St-Charles': 'Saint-Henri—Petite-Bourgogne—Pointe-Saint-Charles',
            'Étienne-Desmarteaux': 'Étienne-Desmarteau',
        }.get(f.get('NM_DIS'), f.get('NM_DIS'))
    else:
        return {
            'Le Plateau-Mont-Royal': 'Plateau-Mont-Royal',
            'Le Sud-Ouest': 'Sud-Ouest',
            'Pierrefond-Roxboro': 'Pierrefonds-Roxboro',
            'Rosemont--La-Petite-Patrie': 'Rosemont—La Petite-Patrie',
        }.get(f.get('NM_ARON'), boundaries.clean_attr('NM_ARON')(f))
def district_namer(f):
    import boundaries
    type_id = f.get('NO_DIS')
    code = f.get('CO_MUNCP')
    name = f.get('NM_DIS')

    # Québec
    if code == 23027:
        return {
            # Hyphens.
            'Cap-Rouge-Laurentien': 'Cap-Rouge—Laurentien',
            'Chute-Montmorency-Seigneurial': 'Chute-Montmorency—Seigneurial',
            'Lac-Saint-Charles-Saint-Émile': 'Lac-Saint-Charles—Saint-Émile',
            'Montcalm-Saint-Sacrement': 'Montcalm—Saint-Sacrement',
            'Saint-Louis-Sillery': 'Saint-Louis—Sillery',
            'Saint-Roch-Saint-Sauveur': 'Saint-Roch—Saint-Sauveur',
        }.get(name, name)

    # Sherbrooke
    elif code == 43027:
        # https://cartes.ville.sherbrooke.qc.ca/monarrondissementenligne/
        return {
            1.10: 'Deauville',
            1.20: 'Rock Forest',
            1.30: 'Saint-Élie',
            1.40: 'Brompton',
            2.10: 'Hôtel-Dieu',
            2.20: 'Desranleau',
            2.30: 'Quatre-Saisons',
            2.40: 'Pin-Solitaire',
            3.10: 'Uplands',
            3.20: 'Fairview',
            4.10: 'Université',
            4.20: 'Ascot',
            4.30: 'Lac-des-Nations',
            4.40: 'Golf',
            4.50: 'Carrefour',
        }[type_id]

    # Longueuil
    elif code == 58227:
        return re.sub(r"\b(?:d'|de |du |des )", '', name)

    # Montréal
    elif code == 66023:
        return {
            'Est (Pierrefonds-Roxboro)': 'Bois-de-Liesse',
            'Ouest (Pierrefonds-Roxboro)': 'Cap-Saint-Jacques',
            'St-Henri-Petite-Bourgogne-Pte-St-Charles':
            'Saint-Henri—Petite-Bourgogne—Pointe-Saint-Charles',
            'Étienne-Desmarteaux': 'Étienne-Desmarteau',
            # Articles.
            "d'Ahuntsic": 'Ahuntsic',
            'de Bordeaux-Cartierville': 'Bordeaux-Cartierville',
            'de Saint-Sulpice': 'Saint-Sulpice',
            'du Sault-au-Récollet': 'Sault-au-Récollet',
            # Hyphens.
            "Champlain-L'Île-des-Soeurs": "Champlain—L'Île-des-Soeurs",
            'Maisonneuve-Longue-Pointe': 'Maisonneuve—Longue-Pointe',
            'Saint-Paul-Émard': 'Saint-Paul—Émard',
        }.get(name, name)

    # Pointe-Claire
    elif code == 66097:
        # Check if required with:
        # ogrinfo -al -geom=NO boundaries/ca_qc_districts | grep '/ '
        return name.replace('/ ', '/')

    # Gatineau
    elif code == 81017:
        return {
            # Hyphens.
            'de Hull-Val-Tétreau': 'de Hull—Val-Tétreau',
            'de Saint-Raymond-Vanier': 'de Saint-Raymond—Vanier',
            'de Wright-Parc-de-la-Montagne': 'de Wright—Parc-de-la-Montagne',
            'du Plateau-Manoir-des-Trembles': 'du Plateau—Manoir-des-Trembles',
        }.get(name, name)

    else:
        if name:
            # Check if required with:
            # ogrinfo -al -geom=NO boundaries/ca_qc_districts | grep ' no '
            if 'District no ' in name:
                return f.get('NM_DIS').replace(' no ', ' ')  # Baie-Saint-Paul
            else:
                return boundaries.clean_attr('NM_DIS')(f)
        elif f.get('MODE_SUFRG') == 'Q':
            return 'Quartier %s' % int(type_id)
        else:
            return 'District %s' % int(type_id)
Example #19
0
from datetime import date

import boundaries

boundaries.register(
    'Calgary wards',
    domain='Calgary, AB',
    last_updated=date(2018, 3, 11),
    name_func=boundaries.clean_attr('label'),
    id_func=lambda f: int(f.get('ward_num')),
    authority='City of Calgary',
    source_url='https://data.calgary.ca/Government/Ward-Boundaries/r9vx-mhnf',
    licence_url='https://data.calgary.ca/stories/s/u45n-7awa',
    data_url=
    'https://data.calgary.ca/api/geospatial/r9vx-mhnf?method=export&format=Shapefile',
    encoding='iso-8859-1',
    extra={'division_id': 'ocd-division/country:ca/csd:4806016'},
)
Example #20
0
 def test_clean_attr(self):
     self.assertEqual(boundaries.clean_attr('foo')({'foo': 'Foo --\tBar\r--Baz--\nBzz--Abc - Xyz'}), 'Foo—Bar—Baz—Bzz—Abc—Xyz')
     self.assertEqual(boundaries.clean_attr('foo')({'foo': 'FOO --\tBAR\r--BAZ--\nBZZ--ABC - XYZ'}), 'Foo—Bar—Baz—Bzz—Abc—Xyz')
def namer(f):
    import boundaries
    return re.sub(' Ward \d+\Z', '', boundaries.clean_attr('NAME')(f))
from datetime import date

import boundaries

boundaries.register('Federal electoral districts (next election)',
    singular='Federal electoral district',
    domain='Canada',
    last_updated=date(2014, 5, 12),
    name_func=boundaries.clean_attr('ENNAME'),
    id_func=boundaries.attr('FEDNUM'),
    slug_func=boundaries.attr('FEDNUM'),
    authority='Her Majesty the Queen in Right of Canada',
    source_url='http://www.geobase.ca/geobase/en/search.do?produit=fed&language=en',
    licence_url='http://data.gc.ca/eng/open-government-licence-canada',
    data_url='http://ftp2.cits.rncan.gc.ca/pub/geobase/official/fed_cf/shp_eng/fed_cf_CA_2_0_shp_en.zip',
    encoding='iso-8859-1',
    metadata={'geographic_code': '01'},
)
Example #23
0
def namer(f):
    import boundaries
    return boundaries.clean_attr('DIST_NAME')(f) or boundaries.clean_attr('Elec_Distr')(f)
from datetime import date

import boundaries

boundaries.register('Calgary wards',
    domain='Calgary, AB',
    last_updated=date(2011, 11, 23),
    name_func=boundaries.clean_attr('LABEL'),
    id_func=boundaries.attr('WARD_NUM'),
    authority='City of Calgary',
    source_url='https://cityonline.calgary.ca/Pages/Category.aspx?cat=CITYonlineDefault&category=PDCAdministrativeBoundaries&publicdata',
    licence_url='https://cityonline.calgary.ca/Pages/Licensehandler.ashx',
    notes='Convert the features to 2D with: ogr2ogr -f "ESRI Shapefile" -overwrite . CALGIS.ADM_WARD.shp -nlt POLYGON',
    encoding='iso-8859-1',
)
from datetime import date

import boundaries

boundaries.register('Thunder Bay wards',
    domain='Thunder Bay, ON',
    last_updated=date(2014, 3, 25),
    name_func=boundaries.clean_attr('WARD_NAME'),
    id_func=lambda f: f.get('WARD_NO').replace('00', ''),
    authority='City of Thunder Bay',
    encoding='iso-8859-1',
    metadata={'geographic_code': '3558004'},
)
Example #26
0
from __future__ import unicode_literals

from datetime import date

import boundaries

boundaries.register('Halifax districts',
    domain='Halifax, NS',
    last_updated=date(2016, 1, 4),
    name_func=boundaries.clean_attr('DISTNAME'),
    id_func=boundaries.attr('DIST_ID'),
    authority='Halifax Regional Municipality',
    source_url='http://catalogue.hrm.opendata.arcgis.com/datasets/b2c71fb0d90f41488fae2ad2c8278f6d_0',
    data_url='http://catalogue.hrm.opendata.arcgis.com/datasets/b2c71fb0d90f41488fae2ad2c8278f6d_0.zip',
    licence_url='http://www.halifax.ca/opendata/OD_TermsOfUse.php',
    encoding='utf-8',
    extra={'division_id': 'ocd-division/country:ca/csd:1209034'},
)
from datetime import date

import boundaries

boundaries.register('Winnipeg wards',
    domain='Winnipeg, MB',
    last_updated=date(2018, 11, 22),
    name_func=boundaries.clean_attr('name'),
    id_func=lambda f: int(f.get('id')),
    authority='City of Winnipeg',
    source_url='https://data.winnipeg.ca/Council-Services/Electoral-Boundaries-as-of-September-17th-2018/qake-hdwc',
    licence_url='https://data.winnipeg.ca/open-data-licence',
    data_url='https://data.winnipeg.ca/api/geospatial/qake-hdwc?method=export&format=Shapefile',
    encoding='iso-8859-1',
    extra={'division_id': 'ocd-division/country:ca/csd:4611040'},
)
from datetime import date

import boundaries

boundaries.register(
    'Saskatoon wards',
    domain='Saskatoon, SK',
    last_updated=date(2016, 10, 14),
    name_func=boundaries.clean_attr('Name'),
    authority='City of Saskatoon',
    source_url=
    'http://opendata-saskatoon.cloudapp.net/DataBrowser/SaskatoonOpenDataCatalogueBeta/MunicipalWardArea#param=NOFILTER--DataView--Results',
    licence_url='http://opendata-saskatoon.cloudapp.net/TermsOfUse/TermsOfUse',
    data_url=
    'http://opendata-saskatoon.cloudapp.net:8080/v1/SaskatoonOpenDataCatalogueBeta/MunicipalWardArea/?format=kml',
    encoding='iso-8859-1',
    extra={'division_id': 'ocd-division/country:ca/csd:4711066'},
)
def namer(f):
    import boundaries
    return boundaries.clean_attr('FEDENAME')(f).replace('\u0092', "'")
Example #30
0
    # the shapefile:
    #
    # * `attr` retrieves a feature's attribute without making changes.
    # * `clean_attr` title-cases a string if it is all-caps, normalizes
    #   whitespace, and normalizes long dashes.
    # * `dashed_attr` does the same as `clean_attr`, but replaces all hyphens
    #   with long dashes.
    #
    # If you want to write your own function, set for example `name_func=namer`
    # and define a function that looks like:
    #
    # def namer(f):
    #   return f.get('FEDENAME')

    # A function that returns a feature's name.
    name_func=boundaries.clean_attr('district'),

    # (Optional) A function that returns a feature's identifier, which should
    # be unique across the features in the shapefile and relatively stable
    # across time: for example, a district number or a geographic code. By
    # default, features have no identifiers.
    id_func=boundaries.attr('id'),
    # (Optional) A function that returns a feature's slug (the last part of its
    # URL path). By default, it will use the feature's name.
    slug_func=boundaries.attr('district'),
    # (Optional) A function that returns whether a feature should be loaded. By
    # default, all features are loaded.
    #is_valid_func=lambda feature: True,
    # (Optional) A function that returns the Point at which to place a label
    # for the boundary, in EPSG:4326.
    #label_point_func=lambda feature: None,
Example #31
0
class FeatureTestCase(TestCase):
    definition = Definition({
        'last_updated': date(2000, 1, 1),
        'encoding': 'utf-8',
        'name': 'Districts',
        'name_func': clean_attr('Name'),
        'id_func': attr('ID'),
        'slug_func': attr('Code'),
        'is_valid_func': lambda f: f.get('ID') == '1',
        'label_point_func': lambda f: Point(0, 1),
    })

    fields = {
        'Name': 'VALID',
        'ID': '1',
        'Code': '\tFoo—Bar–Baz \r Bzz\n',  # m-dash, n-dash
    }

    boundary_set = BoundarySet(
        last_updated=definition['last_updated'],
        name=definition['name'],
        singular=definition['singular'],
    )

    feature = Feature(FeatureProxy(fields), definition)

    other = Feature(FeatureProxy({
        'Name': 'INVALID',
        'ID': 100,
        'Code': 3,
    }), definition, SpatialReference(4269), boundary_set)

    def test_init(self):
        self.assertEqual(self.feature.boundary_set, None)
        self.assertEqual(self.other.boundary_set, self.boundary_set)

    def test_str(self):
        self.assertEqual(str(self.feature), 'Valid')
        self.assertEqual(str(self.other), 'Invalid')

    def test_get(self):
        self.assertEqual(self.feature.get('Name'), 'VALID')

    def test_is_valid(self):
        self.assertTrue(self.feature.is_valid())
        self.assertFalse(self.other.is_valid())

    def test_name(self):
        self.assertEqual(self.feature.name, 'Valid')
        self.assertEqual(self.other.name, 'Invalid')

    def test_id(self):
        self.assertEqual(self.feature.id, '1')
        self.assertEqual(self.other.id, '100')

    def test_slug(self):
        self.assertEqual(self.feature.slug, 'foo-bar-baz-bzz')
        self.assertEqual(self.other.slug, '3')

    def test_label_point(self):
        self.assertEqual(self.feature.label_point, Point(0, 1))

    def test_metadata(self):
        self.assertEqual(self.feature.metadata, self.fields)

    def test_boundary_set(self):
        self.feature.boundary_set = self.boundary_set

        self.assertEqual(self.feature.boundary_set, self.boundary_set)

        self.feature.boundary_set = None

    def test_create_boundary(self):
        self.feature.boundary_set = self.boundary_set

        self.boundary_set.save()
        boundary = self.feature.create_boundary()
        self.assertEqual(boundary.set, self.boundary_set)
        self.assertEqual(boundary.set_name, 'District')
        self.assertEqual(boundary.external_id, '1')
        self.assertEqual(boundary.name, 'Valid')
        self.assertEqual(boundary.slug, 'foo-bar-baz-bzz')
        self.assertEqual(boundary.metadata, self.fields)
        self.assertEqual(boundary.shape.ogr.wkt, 'MULTIPOLYGON (((0 0,0.0001 0.0001,0 5,5 5,0 0)))')
        self.assertEqual(boundary.simple_shape.ogr.wkt, 'MULTIPOLYGON (((0 0,0 5,5 5,0 0)))')
        self.assertEqual(boundary.centroid.ogr.wkt, 'POINT (1.6667 3.333366666666666)')
        self.assertEqual(boundary.extent, (0.0, 0.0, 4.999999999999999, 4.999999999999999))
        self.assertEqual(boundary.label_point, Point(0, 1))

        self.feature.boundary_set = None
Example #32
0
def district_name(d):
    district_num_func = boundaries.clean_attr('DISTRICT')
    return 'District {}'.format(district_num_func(d))
from datetime import date

import boundaries

boundaries.register(
    'Chicago Districts',
    encoding='iso-8859-1',
    last_updated=date(2018, 12, 18),
    name_func=boundaries.clean_attr('COMMUNITY'),
)
def namer(f):
    import boundaries
    n = boundaries.clean_attr('ELEC_DISTR')(f)
    if n == 'Ths Isles of Notre Dame':
        return u'The Isles of Notre Dame'
    return n
from datetime import date

import boundaries

boundaries.register('Halifax districts',
    domain='Halifax, NS',
    last_updated=date(2017, 10, 31),
    name_func=boundaries.clean_attr('DISTNAME'),
    id_func=boundaries.attr('DIST_ID'),
    authority='Halifax Regional Municipality',
    source_url='http://catalogue-hrm.opendata.arcgis.com/datasets/polling-districts',
    licence_url='https://www.halifax.ca/home/open-data/open-data-license',
    data_url='https://opendata.arcgis.com/datasets/04c5bee564f84b4a8f1c8dd305896079_0.zip',
    encoding='utf-8',
    extra={'division_id': 'ocd-division/country:ca/csd:1209034'},
)
#coding: utf-8
from datetime import date

import boundaries

boundaries.register(u'Montréal boroughs',
    domain=u'Montréal, QC',
    last_updated=date(2013, 8, 9),
    name_func=boundaries.clean_attr('ARROND'),
    authority=u'Ville de Montréal',
    source_url='http://donnees.ville.montreal.qc.ca/fiche/polygones-arrondissements/',
    licence_url='http://donnees.ville.montreal.qc.ca/licence/licence-texte-complet/',
    data_url='http://depot.ville.montreal.qc.ca/polygones-arrondissements/data.zip',
    notes='The Ahuntsic-Cartierville borough is split into two features. We merge them using Quantum GIS.',
    encoding='iso-8859-1',
    metadata={'geographic_code': '2466023'},
)
Example #37
0
from datetime import date

import boundaries

boundaries.register('Ottawa wards',
    domain='Ottawa, ON',
    last_updated=date(2018, 4, 24),
    name_func=boundaries.clean_attr('WARD_EN'),
    id_func=boundaries.attr('WARD_NUM'),
    authority='City of Ottawa',
    source_url='http://data.ottawa.ca/en/dataset/wards-2014',
    licence_url='https://ottawa.ca/en/city-hall/get-know-your-city/open-data#open-data-licence-version-2-0',
    data_url='http://data.ottawa.ca/dataset/8321248d-0b86-47cd-9c83-c848a1bc0098/resource/8152e707-fc28-409c-9bbe-8cb9f88dca86/download/wards-2014shp.shp.zip',
    encoding='utf-8',
    extra={'division_id': 'ocd-division/country:ca/csd:3506008'},
)
def namer(f):
    import boundaries
    return boundaries.clean_attr('FEDENAME')(f).replace('\u0092', "'")
#coding: utf-8
from datetime import date

import boundaries

boundaries.register(u'Côte-Saint-Luc districts',
    domain=u'Côte-Saint-Luc, QC',
    last_updated=date(2013, 8, 21),
    name_func=boundaries.clean_attr('NOM_DISTRI'),
    authority=u'Ville de Montréal',
    source_url='http://donnees.ville.montreal.qc.ca/fiche/elections-2009-districts/',
    licence_url='http://donnees.ville.montreal.qc.ca/licence/licence-texte-complet/',
    data_url='http://depot.ville.montreal.qc.ca/elections-2009-districts/multi-poly/data.zip',
    encoding='iso-8859-1',
    metadata={'geographic_code': '2466058'},
    ogr2ogr='''-where "MONTREAL='0'" -where "NUM_ARR='72'"''',
)
from datetime import date

import boundaries

boundaries.register('Calgary wards',
    domain='Calgary, AB',
    last_updated=date(2018, 3, 11),
    name_func=boundaries.clean_attr('label'),
    id_func=lambda f: int(f.get('ward_num')),
    authority='City of Calgary',
    source_url='https://data.calgary.ca/Government/Ward-Boundaries/r9vx-mhnf',
    licence_url='https://data.calgary.ca/stories/s/u45n-7awa',
    data_url='https://data.calgary.ca/api/geospatial/r9vx-mhnf?method=export&format=Shapefile',
    encoding='iso-8859-1',
    extra={'division_id': 'ocd-division/country:ca/csd:4806016'},
)
Example #41
0
def namer(f):
    import boundaries
    n = boundaries.clean_attr('ELEC_DISTR')(f)
    if n == 'Ths Isles of Notre Dame':
        return 'The Isles of Notre Dame'
    return n
from __future__ import unicode_literals

from datetime import date

import boundaries

boundaries.register(
    "Alberta electoral districts",
    domain="Alberta",
    last_updated=date(2012, 6, 4),
    name_func=boundaries.clean_attr("EDNAME"),
    id_func=boundaries.attr("EDNUMBER"),
    authority="Her Majesty the Queen in Right of Alberta",
    source_url="http://www.altalis.com/products/base/20k_base_features.html",
    licence_url="http://data.alberta.ca/licence",
    # The data_url contains multiple shapefiles, and the URL expires.
    # data_url='http://data.altalis.com/AltalisDataDownload/Download/525711F29A214C1AB5ED8F5578A983C3',
    encoding="iso-8859-1",
    metadata={"geographic_code": "48"},
)
def namer(f):
    import boundaries
    return re.sub(' Ward \d+\Z', '', boundaries.clean_attr('NAME')(f))
from __future__ import unicode_literals

from datetime import date

import boundaries

boundaries.register(
    'Alberta electoral districts',
    domain='Alberta',
    last_updated=date(2012, 6, 4),
    name_func=boundaries.clean_attr('EDNAME'),
    id_func=boundaries.attr('EDNUMBER'),
    authority='Her Majesty the Queen in Right of Alberta',
    source_url='http://www.altalis.com/products/base/20k_base_features.html',
    licence_url='http://data.alberta.ca/licence',
    # The data_url contains multiple shapefiles, and the URL expires.
    # data_url='http://data.altalis.com/AltalisDataDownload/Download/525711F29A214C1AB5ED8F5578A983C3',
    encoding='iso-8859-1',
    extra={'division_id': 'ocd-division/country:ca/province:ab'},
)
Example #45
0
# coding: utf-8
from __future__ import unicode_literals

from datetime import date

import boundaries

boundaries.register(
    'Kirkland districts',
    domain='Kirkland, QC',
    last_updated=date(2013, 10, 6),
    name_func=boundaries.clean_attr('NOM_DISTRI'),
    authority='Ville de Montréal',
    source_url=
    'http://donnees.ville.montreal.qc.ca/dataset/elections-2009-districts-electoraux',
    licence_url=
    'http://donnees.ville.montreal.qc.ca/licence/licence-texte-complet/',
    data_url=
    'http://donnees.ville.montreal.qc.ca/storage/f/2013-10-06T16:49:49.153Z/elections-2009-districts-multi-poly.zip',
    encoding='iso-8859-1',
    extra={'division_id': 'ocd-division/country:ca/csd:2466102'},
    ogr2ogr='''-where "MONTREAL='0' AND NUM_ARR='3'"''',
)
def district_namer(f):
    import boundaries
    type_id = f.get('NO_DIS')
    code = f.get('CO_MUNCP')
    name = f.get('NM_DIS')

    # Québec
    if code == 23027:
        return {
            # Hyphens.
            'Cap-Rouge-Laurentien': 'Cap-Rouge—Laurentien',
            'Chute-Montmorency-Seigneurial': 'Chute-Montmorency—Seigneurial',
            'Lac-Saint-Charles-Saint-Émile': 'Lac-Saint-Charles—Saint-Émile',
            'Montcalm-Saint-Sacrement': 'Montcalm—Saint-Sacrement',
            'Saint-Louis-Sillery': 'Saint-Louis—Sillery',
            'Saint-Roch-Saint-Sauveur': 'Saint-Roch—Saint-Sauveur',
        }.get(name, name)

    # Sherbrooke
    elif code == 43027:
        # https://cartes.ville.sherbrooke.qc.ca/monarrondissementenligne/
        return {
            1.10: 'Deauville',
            1.20: 'Rock Forest',
            1.30: 'Saint-Élie',
            1.40: 'Brompton',
            2.10: 'Hôtel-Dieu',
            2.20: 'Desranleau',
            2.30: 'Quatre-Saisons',
            2.40: 'Pin-Solitaire',
            3.10: 'Uplands',
            3.20: 'Fairview',
            4.10: 'Université',
            4.20: 'Ascot',
            4.30: 'Lac-des-Nations',
            4.40: 'Golf',
            4.50: 'Carrefour',
        }[type_id]

    # Longueuil
    elif code == 58227:
        return re.sub(r"\b(?:d'|de |du |des )", '', name)

    # Montréal
    elif code == 66023:
        return {
            'Est (Pierrefonds-Roxboro)': 'Bois-de-Liesse',
            'Ouest (Pierrefonds-Roxboro)': 'Cap-Saint-Jacques',
            'St-Henri-Petite-Bourgogne-Pte-St-Charles': 'Saint-Henri—Petite-Bourgogne—Pointe-Saint-Charles',
            'Étienne-Desmarteaux': 'Étienne-Desmarteau',
            # Articles.
            "d'Ahuntsic": 'Ahuntsic',
            'de Bordeaux-Cartierville': 'Bordeaux-Cartierville',
            'de Saint-Sulpice': 'Saint-Sulpice',
            'du Sault-au-Récollet': 'Sault-au-Récollet',
            # Hyphens.
            "Champlain-L'Île-des-Soeurs": "Champlain—L'Île-des-Soeurs",
            'Maisonneuve-Longue-Pointe': 'Maisonneuve—Longue-Pointe',
            'Saint-Paul-Émard': 'Saint-Paul—Émard',
        }.get(name, name)

    # Pointe-Claire
    elif code == 66097:
            # Check if required with:
            # ogrinfo -al -geom=NO boundaries/ca_qc_districts | grep '/ '
        return name.replace('/ ', '/')

    # Gatineau
    elif code == 81017:
        return {
            # Hyphens.
            'de Hull-Val-Tétreau': 'de Hull—Val-Tétreau',
            'de Saint-Raymond-Vanier': 'de Saint-Raymond—Vanier',
            'de Wright-Parc-de-la-Montagne': 'de Wright—Parc-de-la-Montagne',
            'du Plateau-Manoir-des-Trembles': 'du Plateau—Manoir-des-Trembles',
        }.get(name, name)

    else:
        if name:
            # Check if required with:
            # ogrinfo -al -geom=NO boundaries/ca_qc_districts | grep ' no '
            if 'District no ' in name:
                return f.get('NM_DIS').replace(' no ', ' ')  # Baie-Saint-Paul
            else:
                return boundaries.clean_attr('NM_DIS')(f)
        elif f.get('MODE_SUFRG') == 'Q':
            return 'Quartier %s' % int(type_id)
        else:
            return 'District %s' % int(type_id)
Example #47
0
from __future__ import unicode_literals

from datetime import date

import boundaries

boundaries.register(
    'Thunder Bay wards',
    domain='Thunder Bay, ON',
    last_updated=date(2014, 3, 25),
    name_func=boundaries.clean_attr('WARD_NAME'),
    id_func=lambda f: f.get('WARD_NO').replace('00', ''),
    authority='City of Thunder Bay',
    encoding='iso-8859-1',
    extra={'division_id': 'ocd-division/country:ca/csd:3558004'},
)
from __future__ import unicode_literals

from datetime import date

import boundaries

boundaries.register(
    "Calgary wards",
    domain="Calgary, AB",
    last_updated=date(2015, 1, 27),
    name_func=boundaries.clean_attr("LABEL"),
    id_func=boundaries.attr("WARD_NUM"),
    authority="City of Calgary",
    source_url="https://data.calgary.ca/OpenData/Pages/DatasetDetails.aspx?DatasetID=PDC0-99999-99999-00009-P%28CITYonlineDefault%29",
    licence_url="https://data.calgary.ca/OpenData/Pages/TermsofUse.aspx",
    data_url="https://data.calgary.ca/_layouts/OpenData/DownloadDataset.ashx?Format=SHP&DatasetId=PDC0-99999-99999-00009-P(CITYonlineDefault)&VariantId=3(CITYonlineDefault)",
    encoding="iso-8859-1",
    metadata={"geographic_code": "4806016"},
)
from __future__ import unicode_literals

from datetime import date

import boundaries

boundaries.register(
    'Calgary wards',
    domain='Calgary, AB',
    last_updated=date(2016, 1, 4),
    name_func=boundaries.clean_attr('LABEL'),
    id_func=boundaries.attr('WARD_NUM'),
    authority='City of Calgary',
    source_url=
    'https://data.calgary.ca/OpenData/Pages/DatasetDetails.aspx?DatasetID=PDC0-99999-99999-00009-P%28CITYonlineDefault%29',
    licence_url='https://data.calgary.ca/OpenData/Pages/TermsofUse.aspx',
    data_url=
    'https://data.calgary.ca/_layouts/OpenData/DownloadDataset.ashx?Format=SHP&DatasetId=PDC0-99999-99999-00009-P(CITYonlineDefault)&VariantId=3(CITYonlineDefault)',
    encoding='iso-8859-1',
    extra={'division_id': 'ocd-division/country:ca/csd:4806016'},
)
Example #50
0
def district_name(d):
    district_num_func = boundaries.clean_attr('DISTRICT')
    return 'District {}'.format(district_num_func(d))
Example #51
0
# coding: utf-8
from datetime import date

import boundaries

boundaries.register(
    'Quebec electoral districts (2011)',
    singular='Quebec electoral district',
    domain='Quebec',
    last_updated=date(2012, 2, 24),
    name_func=boundaries.clean_attr('NM_CEP'),
    id_func=boundaries.attr('CO_CEP'),
    authority='Directeur général des élections du Québec',
    source_url=
    'https://www.electionsquebec.qc.ca/francais/provincial/carte-electorale/geometrie-des-circonscriptions-provinciales-du-quebec.php',
    licence_url=
    'https://www.electionsquebec.qc.ca/francais/conditions-d-utilisation-de-notre-site-web.php',
    data_url=
    'https://www.electionsquebec.qc.ca/documents/zip/circonscriptions-electorales-2011-shapefile-v2.zip',
    encoding='windows-1252',
    extra={'division_id': 'ocd-division/country:ca/province:qc'},
)
    # the shapefile:
    #
    # * `attr` retrieves a feature's attribute without making changes.
    # * `clean_attr` title-cases a string if it is all-caps, normalizes
    #   whitespace, and normalizes long dashes.
    # * `dashed_attr` does the same as `clean_attr`, but replaces all hyphens
    #   with long dashes.
    #
    # If you want to write your own function, set for example `name_func=namer`
    # and define a function that looks like:
    #
    # def namer(f):
    #   return f.get('FEDENAME')

    # A function that returns a feature's name.
    name_func=boundaries.clean_attr('FEDENAME'),

    # (Optional) A function that returns a feature's identifier, which should
    # be unique across the features in the shapefile and relatively stable
    # across time: for example, a district number or a geographic code. By
    # default, features have no identifiers.
    id_func=boundaries.attr('FEDUID'),
    # (Optional) A function that returns a feature's slug (the last part of its
    # URL path). By default, it will use the feature's name.
    slug_func=boundaries.attr('FEDUID'),
    # (Optional) A function that returns whether a feature should be loaded. By
    # default, all features are loaded.
    is_valid_func=lambda feature: True,
    # (Optional) A function that returns the Point at which to place a label
    # for the boundary, in EPSG:4326.
    label_point_func=lambda feature: None,
# coding: utf-8
from datetime import date

import boundaries

boundaries.register('Quebec electoral districts (2011)',
    singular='Quebec electoral district',
    domain='Quebec',
    last_updated=date(2012, 2, 24),
    name_func=boundaries.clean_attr('NM_CEP'),
    id_func=boundaries.attr('CO_CEP'),
    authority='Directeur général des élections du Québec',
    source_url='https://www.electionsquebec.qc.ca/francais/provincial/carte-electorale/geometrie-des-circonscriptions-provinciales-du-quebec.php',
    licence_url='https://www.electionsquebec.qc.ca/francais/conditions-d-utilisation-de-notre-site-web.php',
    data_url='https://www.electionsquebec.qc.ca/documents/zip/circonscriptions-electorales-2011-shapefile-v2.zip',
    encoding='windows-1252',
    extra={'division_id': 'ocd-division/country:ca/province:qc'},
)
from datetime import date

import boundaries

boundaries.register('St. Catharines wards',
    domain='St. Catharines, ON',
    last_updated=date(2016, 5, 17),
    name_func=boundaries.clean_attr('WardName'),
    authority='City of St. Catharines',
    encoding='iso-8859-1',
    source_url='https://niagaraopendata.ca/dataset/st-catharines-wards',
    licence_url='https://niagaraopendata.ca/pages/open-government-license-2-0-the-corporation-of-the-city-of-st-catharines',
    data_url='https://www.niagaraopendata.ca//dataset/04304ccc-e282-41df-9bd9-e997bc1f2d96/resource/77dfbcf3-4faf-446e-a816-c6def452150f/download/stcathwards.zip',
    extra={'division_id': 'ocd-division/country:ca/csd:3526053'},
)
#coding: utf-8
from datetime import date

import boundaries

boundaries.register(u'Québec boroughs',
    domain=u'Québec, QC',
    last_updated=date(2013, 8, 20),
    name_func=boundaries.clean_attr('NOM'),
    id_func=boundaries.attr('CODE'),
    authority=u'Ville de Québec',
    source_url='http://donnees.ville.quebec.qc.ca/donne_details.aspx?jdid=2',
    licence_url='http://donnees.ville.quebec.qc.ca/licence.aspx',
    data_url='http://donnees.ville.quebec.qc.ca/Handler.ashx?id=2&f=SHP',
    encoding='iso-8859-1',
    metadata={'geographic_code': '2423027'},
    prj='http://spatialreference.org/ref/epsg/4326/prj/',
)
    # the shapefile:
    #
    # * `attr` retrieves a feature's attribute without making changes.
    # * `clean_attr` title-cases a string if it is all-caps, normalizes
    #   whitespace, and normalizes long dashes.
    # * `dashed_attr` does the same as `clean_attr`, but replaces all hyphens
    #   with long dashes.
    #
    # If you want to write your own function, set for example `name_func=namer`
    # and define a function that looks like:
    #
    # def namer(f):
    #   return f.get('FEDENAME')

    # A function that returns a feature's name.
    name_func=boundaries.clean_attr('FEDENAME'),

    # (Optional) A function that returns a feature's identifier, which should
    # be unique across the features in the shapefile and relatively stable
    # across time: for example, a district number or a geographic code. By
    # default, features have no identifiers.
    id_func=boundaries.attr('FEDUID'),
    # (Optional) A function that returns a feature's slug (the last part of its
    # URL path). By default, it will use the feature's name.
    slug_func=boundaries.attr('FEDUID'),
    # (Optional) A function that returns whether a feature should be loaded. By
    # default, all features are loaded.
    is_valid_func=lambda feature: True,
    # (Optional) A function that returns the Point at which to place a label
    # for the boundary, in EPSG:4326.
    label_point_func=lambda feature: None,