french-cities


Namefrench-cities JSON
Version 0.1.1a5 PyPI version JSON
download
home_pagehttps://github.com/tgrandje/french-cities/
SummaryToolbox on french cities: set vintage, find departments, find cities...
upload_time2023-08-07 13:50:35
maintainer
docs_urlNone
authorthomas.grandjean
requires_python>=3.8,<4.0
licenseetalab-2.0
keywords france cities
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # french-cities
Toolbox on french cities: set vintage, find departments, find cities...


# Installation

`pip install french-cities[full]`

Note that at this instant, `pynsee` doesn't support communal projection.
After installing `french-cities` from pypi, please uninstall pynsee and replace
it with the current master:
```
pip uninstall pynsee
pip install git+https://github.com/InseeFrLab/pynsee
```

Note that the "full" installation will also install geopy, which might use
Nominatim API for city recognition as a last resort.


# Configuration

## Setting INSEE's API keys
`french-cities` uses `pynsee` under the hood. For it to work, you need to set
the credentials up. You can set up to four environment variables:
* insee_key
* insee_secret, 
* http_proxy (if accessing web behind a corporate proxy)
* https_proxy (if accessing web behind a corporate proxy)

Please refer to [`pynsee`'s documentation](https://pynsee.readthedocs.io/en/latest/api_subscription.html)
to help configure the API's access.

Note that setting environment variable for proxy will set it for both `pynsee`
and `geopy`.

## Session management
Note that `pynsee` and `geopy` use their own web session. Every Session object 
you will pass to `french-cities` will **NOT** be shared with `pynsee` or `geopy`. 
This explains the possibility to pass a session as an argument to `french-cities` 
functions, even if you had to configure the corporate proxy through environment 
variables for `pynsee` and `geopy`.

## Basic usage

### Why french-cities?
There are already available packages and APIs meant to be used for basic french
cities management. For instance, `pynsee` uses the INSEE's API to retrieve
multiple data (including departement, region, ...). `geopy` can also retrieve
cities from their names using the BAN (Base Adresse Nationale) API or the 
Nominatim geocoding service.

The difference is that `french-cities` is primarly meant to perform against whole
pandas series/dataframes. It should handle better performance than multiple API 
calls and will optimize the call to each endpoints.

### Retrieve departements' codes
`french-cities` can retrieve departement's codes from postal codes or official
(COG/INSEE) codes. 

Working from postal codes will make use of the BAN (Base Adresse Nationale)
and should return correct results. The case of "Cedex" codes is only partially
covered by the BAN, so [OpenDataSoft's API](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/api/?flg=fr&q=code%3D68013&lang=fr),
constructed upon [Christian Quest works](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/information/?flg=fr&q=code%3D68013&lang=fr).
This consumes the freemium API and no authentication is included:
the user of the present package should check the current API's legal terms
directly on OpenDataSoft's website.

Working from official codes may give wrong results when working on an old
dataset and with cities which have changed of departments (which is rarely seen). 
This is deliberate: it will use the first characters of the cities' codes 
(which is a fast process and 99% accurate) instead of using an API (which is
lengthy though foolproof).

```
from french_cities import find_departements
import pandas as pd

df = pd.DataFrame(
    {
        "code_postal": ["59800", "97133", "20000"],
        "code_commune": ["59350", "97701", "2A004"],
        "communes": ["Lille", "Saint-Barthélémy", "Ajaccio"],
        "deps": ["59", "977", "2A"],
    }
)
df = find_departements(df, source="code_postal", alias="dep_A", type_code="postcode")
df = find_departements(df, source="code_commune", alias="dep_B", type_code="insee")

print(df)
```

For a complete documentation on `find_departements`, please type 
`help(find_departements)`.

### Retrieve cities' codes
`french-cities` can retrieve cities' codes from multiple fields. It will work
out basic mistakes (up to a certain limit).

The columns used by the algorithm can be (in the order of precedence used by
the algorithm):
* 'x' and 'y' (in that case, epsg must be explicitly given);
* 'postcode' and 'city'
* 'address', 'postcode' and 'city'
* 'department' and 'city'

Note that the algorithm can (and will) make errors using xy coordinates on a 
older vintage (ie different from the current one) in the case of historic 
splitting of cities (the geographic files are not vintaged yet).

The lexical (postcode, city, address, departement) recognition is based on a
python fuzzy matching, the BAN API(base adresse nationale) or the Nominatim
API of OSM (if activated). The algorithm won't collect underscored
results, but failures may still occure.

```
from french_cities import find_city
import pandas as pd

df = pd.DataFrame(
    [
        {
            "x": 2.294694,
            "y": 48.858093,
            "location": "Tour Eiffel",
            "dep": "75",
            "city": "Paris",
            "address": "5 Avenue Anatole France",
            "postcode": "75007",
            "target": "75056",
        },
        {
            "x": 8.738962,
            "y": 41.919216,
            "location": "mairie",
            "dep": "2A",
            "city": "Ajaccio",
            "address": "Antoine Sérafini",
            "postcode": "20000",
            "target": "2A004",
        },
        {
            "x": -52.334990,
            "y": 4.938194,
            "location": "mairie",
            "dep": "973",
            "city": "Cayenne",
            "address": "1 rue de Rémire",
            "postcode": "97300",
            "target": "97302",
        },
        {
            "x": np.nan,
            "y": np.nan,
            "location": "Erreur code postal Lille/Lyon",
            "dep": "59",
            "city": "Lille",
            "address": "1 rue Faidherbe",
            "postcode": "69000",
            "target": "59350",
        },
    ]
)
df = find_city(df, epsg=4326)

print(df)
```

For a complete documentation on `find_city`, please type 
`help(find_city)`.

**Note** : to activate `geopy` (Nominatim API from OpenStreeMap) usage in last 
resort, you will need to use the argument `use_nominatim_backend=True`.

### Set vintage to cities' codes
`french-cities` can try to project a given dataframe into a set vintage,
starting from an unknown vintage (or even a non-vintaged dataset, which is 
often the case).

Error may occur for splitted cities as the starting vintage is unknown
(or inexistant).

In case of a known starting vintage, you can make use of
INSEE's projection API (with `pynsee`). Note that this might prove slower as
each row will have to induce a request to the API (which allows up to 
30 requests/minute).

Basically, the algorithm of `french-cities` will try to see if a given city
code exists in the desired vintage:
* if yes, it will be kept (we the aforementionned approximation regarding
restored cities);
* if not, it will look in older vintages and make use of INSEE's projection API.

This algorithm will also:
* convert communal districts' into cities' codes;
* convert delegated or associated cities' codes into it's parent's.

```
from french_cities import set_vintage
import pandas as pd

df = pd.DataFrame(
    [
        ["07180", "Fusion"],
        ["02077", "Commune déléguée"],
        ["02564", "Commune nouvelle"],
        ["75101", "Arrondissement municipal"],
        ["59298", "Commune associée"],
        ["99999", "Code erroné"],
        ["14472", "Oudon"],
    ],
    columns=["A", "Test"],
    index=["A", "B", "C", "D", 1, 2, 3],
)
df = set_vintage(df, 2023, field="A")
print(df)
```

For a complete documentation on `set_vintage`, please type 
`help(set_vintage)`.

## External documentation

`french-cities` makes use of multiple APIs. Please read :
* [documentation](https://adresse.data.gouv.fr/api-doc/adresse) (in french) on API Adresse
* [documentation](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/api/?flg=fr&q=code%3D68013&lang=fr) (in french) on OpenDataSoft API
* [Nominatim Usage Policy](https://operations.osmfoundation.org/policies/nominatim/)

## Support
In case of bugs, please open an issue [on the repo](https://github.com/tgrandje/french-cities/issues).

## Author
Thomas GRANDJEAN (DREAL Hauts-de-France, service Information, Développement Durable et Évaluation Environnementale, pôle Promotion de la Connaissance).

## Licence
Licence Ouverte version 2.0 [etalab-2.0](https://www.etalab.gouv.fr/wp-content/uploads/2017/04/ETALAB-Licence-Ouverte-v2.0.pdf)

## Project Status
Test phase.
# french-cities
Boîte à outils sur les communes françaises : millésimage, reconnaissance de 
départements ou de communes...


# Installation

`pip install french-cities[full]`

Notez qu'à cette heure, `pynsee` ne supporte pas les projections de codes commune. 
Dans l'immédiat, après avoir installé `french-cities` depuis pypi, il faut donc
désinstaller `pynsee` puis réinstaller la version master courante depuis son repo 
github :
```
pip uninstall pynsee
pip install git+https://github.com/InseeFrLab/pynsee
```

L'installation "full" permet d'installer geopy qui est une dépendance 
optionnelle utilisable en dernier ressort.

# Configuration

## Ajout des clefs API INSEE
`french-cities` utilise `pynsee`, qui nécessite des cles API INSEE pour être 
fonctionnel. Jusqu'à quatre clefs peuvent être spécifiées à l'aide de variables
d'environnement :
* insee_key
* insee_secret, 
* http_proxy (le cas échéant, pour accès web derrière un proxy professionnel)
* https_proxy (le cas échéant, pour accès web derrière un proxy professionnel)

Merci de se référer à [la documentation de `pynsee`](https://pynsee.readthedocs.io/en/latest/api_subscription.html)
pour plus d'information sur les clefs API et la configuration.

A noter que la configuration des proxy par variable d'environnement sera 
fonctionnelle pour à la fois `pynsee` et `geopy`.

## Gestion des sessions web
`pynsee` et `geopy` utilisent leur propres gestionnaires de session web. 
Ainsi, les objets Session passés en argument à `french-cities` ne seront
**PAS** partagés avec `pynsee` ou `geopy`. Cela explique la possibilité de 
passer une session en argument alors même que des proxy professionnels peuvent 
être spécifiés par variables d'environnement (pour `pynsee` et `geopy`).

## Utilisation

### Pourquoi french-cities ?
Des packages et des API sont déjà disponibles pour des recherches usuelles. Par
exemple, `pynsee` utilise les API de l'INSEE pour retrouver de multiples données
(comme les départements, les régions, etc.) ; `geopy` peut également retrouver
des communes à partir de leurs noms en s'appuyant sur la BAN (Base Adresse 
Nationale) ou sur le service de géocodage Nominatim.

La différence est que `french-cities` est optimisé pour travailler avec des données
fournies sous la forme de Series ou DataFrames pandas. Ce package gérera mieux
de gros volumes de données que ne le feraient des appels multiples à des API.

### Trouver les départements
`french-cities` peut retrouver un code département à partir de codes postaux ou 
de codes communes officiels (COG/INSEE).

Travailler à partir de codes postaux entraînera l'utilisation de la BAN (Base
Adresse Nationale) et devrait fournir des résultats corrects. Le cas des codes
Cedex n'étant que partiellement géré par la BAN, un appel est fait dans un
second temps à l'[API d'OpenDataSoft](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/api/?flg=fr&q=code%3D68013&lang=fr)
construite sur la base des [travaux de Christian Quest](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/information/?flg=fr&q=code%3D68013&lang=fr).
Cette utilisation s'appuie sur un accès freemium non authentifié; l'utilisateur 
du package est invité à contrôler les conditions générales d'utilisation de l'API auprès du
fournisseur.

Travailler à partir de codes communes officiels peut entraîner des résultats
erronés pour des données anciennes, dans le cas de communes ayant changé de
département (ce qui est relativement rare).
Ce choix est délibéré : seuls les premiers caractères des codes commune sont
utilisés pour la reconnaissance du département (algorithme rapide et qui donne
des résultats corrects pour 99% des cas), par opposition à un requêtage
systématique aux API (processus sans erreur mais long).

```
from french_cities import find_departements
import pandas as pd

df = pd.DataFrame(
    {
        "code_postal": ["59800", "97133", "20000"],
        "code_commune": ["59350", "97701", "2A004"],
        "communes": ["Lille", "Saint-Barthélémy", "Ajaccio"],
        "deps": ["59", "977", "2A"],
    }
)
df = find_departements(df, source="code_postal", alias="dep_A", type_code="postcode")
df = find_departements(df, source="code_commune", alias="dep_B", type_code="insee")

print(df)
```

Pour une documentation complète sur la fonction `find_departements`, merci 
d'utiliser la commande suivante :
`help(find_departements)`.

### Trouver les codes communes
`french-cities` peut retrouver le code commune à partir de champs multiples.
Il est capable de détecter certaines erreurs simples dans les champs (jusqu'à 
une certaine limite).

Les colonnes utilisées par l'algorithme pour cette détection sont (par ordre
de priorité) :
* 'x' et 'y' (dans ce cas, un code EPSG doit être explicitement donné);
* 'postcode' et 'city'
* 'address', 'postcode' et 'city'
* 'department' et 'city'

Il est à noter que l'algorithme peu faire être source d'erreur dès lors que
la jointure spatiale (coordonnées x & y) sera sollicitée sur un millésime ancien.
Les communes impactées sont les communes restaurées ("scission"), le flux de données
spatialisées du COG servi par pynsee n'étant pas millésimé à ce jour.

La reconnaissance syntaxique (champs postcode, city, address, departement) est
basée sur un fuzzy matching en langage python, l'API BAN (base adresse nationale),
ou l'API Nominatim d'OSM (si activé). 
L'algorithme ne conservera pas de résultats insuffisamment fiables, mais des 
erreurs peuvent subsister.

```
from french_cities import find_city
import pandas as pd

df = pd.DataFrame(
    [
        {
            "x": 2.294694,
            "y": 48.858093,
            "location": "Tour Eiffel",
            "dep": "75",
            "city": "Paris",
            "address": "5 Avenue Anatole France",
            "postcode": "75007",
            "target": "75056",
        },
        {
            "x": 8.738962,
            "y": 41.919216,
            "location": "mairie",
            "dep": "2A",
            "city": "Ajaccio",
            "address": "Antoine Sérafini",
            "postcode": "20000",
            "target": "2A004",
        },
        {
            "x": -52.334990,
            "y": 4.938194,
            "location": "mairie",
            "dep": "973",
            "city": "Cayenne",
            "address": "1 rue de Rémire",
            "postcode": "97300",
            "target": "97302",
        },
        {
            "x": np.nan,
            "y": np.nan,
            "location": "Erreur code postal Lille/Lyon",
            "dep": "59",
            "city": "Lille",
            "address": "1 rue Faidherbe",
            "postcode": "69000",
            "target": "59350",
        },
    ]
)
df = find_city(df, epsg=4326)

print(df)
```

Pour une documentation complète sur la fonction `find_city`, merci 
d'utiliser la commande suivante :
`help(find_city)`.

**Nota** : pour activer l'utilisation de `geopy` (API Nominatim d'OpenStreeMap) 
en dernier ressort, il convient d'utiliser l'argument `use_nominatim_backend=True`.

### Projection de codes communes dans un millésime donné
`french-cities` peut tenter de "projeter" un dataframe dans un millésime donné,
la date initiale demeurant inconnue (voire inexistante, les cas de fichiers
"multi-millésimés" étant fréquents dans la vie réelle).

Des erreurs peuvent survenir, notamment pour les communes restaurées (dans la 
mesure où la date initiale de la donnée est inconnue ou inexistante).

Dans le cas où la date des données est connue, il peut être pertinent d'utiliser
l'API de projection mise à disposition par l'INSEE et accessible au travers de 
`pynsee`. Il convient de noter que cette utilisation peut être lente, dans la 
mesure ou chaque commune devra être testée via l'API (qui n'autorise que 
30 requêtes par minute).

En substance, l'algorithme de `french-cities` contrôle si le code commune existe
dans le millésime souhaité :
* s'il existe il sera conservé (à l'approximation précédente près qui peut donc
impacter les communes restaurées) ;
* s'il n'existe pas, le code est recherché dans des millésimes antérieurs (et
l'API de projection de l'INSEE sera mobilisée de manière ciblée).

Cet algorithme va également :
* convertir les codes des éventuels arrondissements municipaux en celui de leur
commune de rattachement;
* convertir les codes des communes associées et déléguées en celui de leur 
commune de rattachement.

```
from french_cities import set_vintage
import pandas as pd

df = pd.DataFrame(
    [
        ["07180", "Fusion"],
        ["02077", "Commune déléguée"],
        ["02564", "Commune nouvelle"],
        ["75101", "Arrondissement municipal"],
        ["59298", "Commune associée"],
        ["99999", "Code erroné"],
        ["14472", "Oudon"],
    ],
    columns=["A", "Test"],
    index=["A", "B", "C", "D", 1, 2, 3],
)
df = set_vintage(df, 2023, field="A")
print(df)
```

Pour une documentation complète sur la fonction `set_vintage`, merci 
d'utiliser la commande suivante :
`help(set_vintage)`.

## Documentation externe

`french-cities` utilise plusieurs API externes. N'hésitez pas à consulter :
* [documentation](https://adresse.data.gouv.fr/api-doc/adresse) (en Français) de l'API Adresse
* [documentation](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/api/?flg=fr&q=code%3D68013&lang=fr) (en Français) de l'API OpenDataSoft.
* [Politique d'usage de Nominatim](https://operations.osmfoundation.org/policies/nominatim/)

## Support
En cas de bugues, merci d'ouvrir un ticket [sur le repo](https://github.com/tgrandje/french-cities/issues).

## Auteur
Thomas GRANDJEAN (DREAL Hauts-de-France, service Information, Développement Durable et Évaluation Environnementale, pôle Promotion de la Connaissance).

## Licence
Licence Ouverte version 2.0 [etalab-2.0](https://www.etalab.gouv.fr/wp-content/uploads/2017/04/ETALAB-Licence-Ouverte-v2.0.pdf)

## État du projet
Phase de test.
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/tgrandje/french-cities/",
    "name": "french-cities",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8,<4.0",
    "maintainer_email": "",
    "keywords": "france,cities",
    "author": "thomas.grandjean",
    "author_email": "thomas.grandjean@developpement-durable.gouv.fr",
    "download_url": "https://files.pythonhosted.org/packages/d6/60/7f1f95b4e868baaebe976ed6e81a24a396fecf73139409993baaa1bcc1eb/french_cities-0.1.1a5.tar.gz",
    "platform": null,
    "description": "# french-cities\nToolbox on french cities: set vintage, find departments, find cities...\n\n\n# Installation\n\n`pip install french-cities[full]`\n\nNote that at this instant, `pynsee` doesn't support communal projection.\nAfter installing `french-cities` from pypi, please uninstall pynsee and replace\nit with the current master:\n```\npip uninstall pynsee\npip install git+https://github.com/InseeFrLab/pynsee\n```\n\nNote that the \"full\" installation will also install geopy, which might use\nNominatim API for city recognition as a last resort.\n\n\n# Configuration\n\n## Setting INSEE's API keys\n`french-cities` uses `pynsee` under the hood. For it to work, you need to set\nthe credentials up. You can set up to four environment variables:\n* insee_key\n* insee_secret, \n* http_proxy (if accessing web behind a corporate proxy)\n* https_proxy (if accessing web behind a corporate proxy)\n\nPlease refer to [`pynsee`'s documentation](https://pynsee.readthedocs.io/en/latest/api_subscription.html)\nto help configure the API's access.\n\nNote that setting environment variable for proxy will set it for both `pynsee`\nand `geopy`.\n\n## Session management\nNote that `pynsee` and `geopy` use their own web session. Every Session object \nyou will pass to `french-cities` will **NOT** be shared with `pynsee` or `geopy`. \nThis explains the possibility to pass a session as an argument to `french-cities` \nfunctions, even if you had to configure the corporate proxy through environment \nvariables for `pynsee` and `geopy`.\n\n## Basic usage\n\n### Why french-cities?\nThere are already available packages and APIs meant to be used for basic french\ncities management. For instance, `pynsee` uses the INSEE's API to retrieve\nmultiple data (including departement, region, ...). `geopy` can also retrieve\ncities from their names using the BAN (Base Adresse Nationale) API or the \nNominatim geocoding service.\n\nThe difference is that `french-cities` is primarly meant to perform against whole\npandas series/dataframes. It should handle better performance than multiple API \ncalls and will optimize the call to each endpoints.\n\n### Retrieve departements' codes\n`french-cities` can retrieve departement's codes from postal codes or official\n(COG/INSEE) codes. \n\nWorking from postal codes will make use of the BAN (Base Adresse Nationale)\nand should return correct results. The case of \"Cedex\" codes is only partially\ncovered by the BAN, so [OpenDataSoft's API](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/api/?flg=fr&q=code%3D68013&lang=fr),\nconstructed upon [Christian Quest works](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/information/?flg=fr&q=code%3D68013&lang=fr).\nThis consumes the freemium API and no authentication is included:\nthe user of the present package should check the current API's legal terms\ndirectly on OpenDataSoft's website.\n\nWorking from official codes may give wrong results when working on an old\ndataset and with cities which have changed of departments (which is rarely seen). \nThis is deliberate: it will use the first characters of the cities' codes \n(which is a fast process and 99% accurate) instead of using an API (which is\nlengthy though foolproof).\n\n```\nfrom french_cities import find_departements\nimport pandas as pd\n\ndf = pd.DataFrame(\n    {\n        \"code_postal\": [\"59800\", \"97133\", \"20000\"],\n        \"code_commune\": [\"59350\", \"97701\", \"2A004\"],\n        \"communes\": [\"Lille\", \"Saint-Barth\u00e9l\u00e9my\", \"Ajaccio\"],\n        \"deps\": [\"59\", \"977\", \"2A\"],\n    }\n)\ndf = find_departements(df, source=\"code_postal\", alias=\"dep_A\", type_code=\"postcode\")\ndf = find_departements(df, source=\"code_commune\", alias=\"dep_B\", type_code=\"insee\")\n\nprint(df)\n```\n\nFor a complete documentation on `find_departements`, please type \n`help(find_departements)`.\n\n### Retrieve cities' codes\n`french-cities` can retrieve cities' codes from multiple fields. It will work\nout basic mistakes (up to a certain limit).\n\nThe columns used by the algorithm can be (in the order of precedence used by\nthe algorithm):\n* 'x' and 'y' (in that case, epsg must be explicitly given);\n* 'postcode' and 'city'\n* 'address', 'postcode' and 'city'\n* 'department' and 'city'\n\nNote that the algorithm can (and will) make errors using xy coordinates on a \nolder vintage (ie different from the current one) in the case of historic \nsplitting of cities (the geographic files are not vintaged yet).\n\nThe lexical (postcode, city, address, departement) recognition is based on a\npython fuzzy matching, the BAN API(base adresse nationale) or the Nominatim\nAPI of OSM (if activated). The algorithm won't collect underscored\nresults, but failures may still occure.\n\n```\nfrom french_cities import find_city\nimport pandas as pd\n\ndf = pd.DataFrame(\n    [\n        {\n            \"x\": 2.294694,\n            \"y\": 48.858093,\n            \"location\": \"Tour Eiffel\",\n            \"dep\": \"75\",\n            \"city\": \"Paris\",\n            \"address\": \"5 Avenue Anatole France\",\n            \"postcode\": \"75007\",\n            \"target\": \"75056\",\n        },\n        {\n            \"x\": 8.738962,\n            \"y\": 41.919216,\n            \"location\": \"mairie\",\n            \"dep\": \"2A\",\n            \"city\": \"Ajaccio\",\n            \"address\": \"Antoine S\u00e9rafini\",\n            \"postcode\": \"20000\",\n            \"target\": \"2A004\",\n        },\n        {\n            \"x\": -52.334990,\n            \"y\": 4.938194,\n            \"location\": \"mairie\",\n            \"dep\": \"973\",\n            \"city\": \"Cayenne\",\n            \"address\": \"1 rue de R\u00e9mire\",\n            \"postcode\": \"97300\",\n            \"target\": \"97302\",\n        },\n        {\n            \"x\": np.nan,\n            \"y\": np.nan,\n            \"location\": \"Erreur code postal Lille/Lyon\",\n            \"dep\": \"59\",\n            \"city\": \"Lille\",\n            \"address\": \"1 rue Faidherbe\",\n            \"postcode\": \"69000\",\n            \"target\": \"59350\",\n        },\n    ]\n)\ndf = find_city(df, epsg=4326)\n\nprint(df)\n```\n\nFor a complete documentation on `find_city`, please type \n`help(find_city)`.\n\n**Note** : to activate `geopy` (Nominatim API from OpenStreeMap) usage in last \nresort, you will need to use the argument `use_nominatim_backend=True`.\n\n### Set vintage to cities' codes\n`french-cities` can try to project a given dataframe into a set vintage,\nstarting from an unknown vintage (or even a non-vintaged dataset, which is \noften the case).\n\nError may occur for splitted cities as the starting vintage is unknown\n(or inexistant).\n\nIn case of a known starting vintage, you can make use of\nINSEE's projection API (with `pynsee`). Note that this might prove slower as\neach row will have to induce a request to the API (which allows up to \n30 requests/minute).\n\nBasically, the algorithm of `french-cities` will try to see if a given city\ncode exists in the desired vintage:\n* if yes, it will be kept (we the aforementionned approximation regarding\nrestored cities);\n* if not, it will look in older vintages and make use of INSEE's projection API.\n\nThis algorithm will also:\n* convert communal districts' into cities' codes;\n* convert delegated or associated cities' codes into it's parent's.\n\n```\nfrom french_cities import set_vintage\nimport pandas as pd\n\ndf = pd.DataFrame(\n    [\n        [\"07180\", \"Fusion\"],\n        [\"02077\", \"Commune d\u00e9l\u00e9gu\u00e9e\"],\n        [\"02564\", \"Commune nouvelle\"],\n        [\"75101\", \"Arrondissement municipal\"],\n        [\"59298\", \"Commune associ\u00e9e\"],\n        [\"99999\", \"Code erron\u00e9\"],\n        [\"14472\", \"Oudon\"],\n    ],\n    columns=[\"A\", \"Test\"],\n    index=[\"A\", \"B\", \"C\", \"D\", 1, 2, 3],\n)\ndf = set_vintage(df, 2023, field=\"A\")\nprint(df)\n```\n\nFor a complete documentation on `set_vintage`, please type \n`help(set_vintage)`.\n\n## External documentation\n\n`french-cities` makes use of multiple APIs. Please read :\n* [documentation](https://adresse.data.gouv.fr/api-doc/adresse) (in french) on API Adresse\n* [documentation](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/api/?flg=fr&q=code%3D68013&lang=fr) (in french) on OpenDataSoft API\n* [Nominatim Usage Policy](https://operations.osmfoundation.org/policies/nominatim/)\n\n## Support\nIn case of bugs, please open an issue [on the repo](https://github.com/tgrandje/french-cities/issues).\n\n## Author\nThomas GRANDJEAN (DREAL Hauts-de-France, service Information, D\u00e9veloppement Durable et \u00c9valuation Environnementale, p\u00f4le Promotion de la Connaissance).\n\n## Licence\nLicence Ouverte version 2.0 [etalab-2.0](https://www.etalab.gouv.fr/wp-content/uploads/2017/04/ETALAB-Licence-Ouverte-v2.0.pdf)\n\n## Project Status\nTest phase.\n# french-cities\nBo\u00eete \u00e0 outils sur les communes fran\u00e7aises : mill\u00e9simage, reconnaissance de \nd\u00e9partements ou de communes...\n\n\n# Installation\n\n`pip install french-cities[full]`\n\nNotez qu'\u00e0 cette heure, `pynsee` ne supporte pas les projections de codes commune. \nDans l'imm\u00e9diat, apr\u00e8s avoir install\u00e9 `french-cities` depuis pypi, il faut donc\nd\u00e9sinstaller `pynsee` puis r\u00e9installer la version master courante depuis son repo \ngithub :\n```\npip uninstall pynsee\npip install git+https://github.com/InseeFrLab/pynsee\n```\n\nL'installation \"full\" permet d'installer geopy qui est une d\u00e9pendance \noptionnelle utilisable en dernier ressort.\n\n# Configuration\n\n## Ajout des clefs API INSEE\n`french-cities` utilise `pynsee`, qui n\u00e9cessite des cles API INSEE pour \u00eatre \nfonctionnel. Jusqu'\u00e0 quatre clefs peuvent \u00eatre sp\u00e9cifi\u00e9es \u00e0 l'aide de variables\nd'environnement :\n* insee_key\n* insee_secret, \n* http_proxy (le cas \u00e9ch\u00e9ant, pour acc\u00e8s web derri\u00e8re un proxy professionnel)\n* https_proxy (le cas \u00e9ch\u00e9ant, pour acc\u00e8s web derri\u00e8re un proxy professionnel)\n\nMerci de se r\u00e9f\u00e9rer \u00e0 [la documentation de `pynsee`](https://pynsee.readthedocs.io/en/latest/api_subscription.html)\npour plus d'information sur les clefs API et la configuration.\n\nA noter que la configuration des proxy par variable d'environnement sera \nfonctionnelle pour \u00e0 la fois `pynsee` et `geopy`.\n\n## Gestion des sessions web\n`pynsee` et `geopy` utilisent leur propres gestionnaires de session web. \nAinsi, les objets Session pass\u00e9s en argument \u00e0 `french-cities` ne seront\n**PAS** partag\u00e9s avec `pynsee` ou `geopy`. Cela explique la possibilit\u00e9 de \npasser une session en argument alors m\u00eame que des proxy professionnels peuvent \n\u00eatre sp\u00e9cifi\u00e9s par variables d'environnement (pour `pynsee` et `geopy`).\n\n## Utilisation\n\n### Pourquoi french-cities ?\nDes packages et des API sont d\u00e9j\u00e0 disponibles pour des recherches usuelles. Par\nexemple, `pynsee` utilise les API de l'INSEE pour retrouver de multiples donn\u00e9es\n(comme les d\u00e9partements, les r\u00e9gions, etc.) ; `geopy` peut \u00e9galement retrouver\ndes communes \u00e0 partir de leurs noms en s'appuyant sur la BAN (Base Adresse \nNationale) ou sur le service de g\u00e9ocodage Nominatim.\n\nLa diff\u00e9rence est que `french-cities` est optimis\u00e9 pour travailler avec des donn\u00e9es\nfournies sous la forme de Series ou DataFrames pandas. Ce package g\u00e9rera mieux\nde gros volumes de donn\u00e9es que ne le feraient des appels multiples \u00e0 des API.\n\n### Trouver les d\u00e9partements\n`french-cities` peut retrouver un code d\u00e9partement \u00e0 partir de codes postaux ou \nde codes communes officiels (COG/INSEE).\n\nTravailler \u00e0 partir de codes postaux entra\u00eenera l'utilisation de la BAN (Base\nAdresse Nationale) et devrait fournir des r\u00e9sultats corrects. Le cas des codes\nCedex n'\u00e9tant que partiellement g\u00e9r\u00e9 par la BAN, un appel est fait dans un\nsecond temps \u00e0 l'[API d'OpenDataSoft](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/api/?flg=fr&q=code%3D68013&lang=fr)\nconstruite sur la base des [travaux de Christian Quest](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/information/?flg=fr&q=code%3D68013&lang=fr).\nCette utilisation s'appuie sur un acc\u00e8s freemium non authentifi\u00e9; l'utilisateur \ndu package est invit\u00e9 \u00e0 contr\u00f4ler les conditions g\u00e9n\u00e9rales d'utilisation de l'API aupr\u00e8s du\nfournisseur.\n\nTravailler \u00e0 partir de codes communes officiels peut entra\u00eener des r\u00e9sultats\nerron\u00e9s pour des donn\u00e9es anciennes, dans le cas de communes ayant chang\u00e9 de\nd\u00e9partement (ce qui est relativement rare).\nCe choix est d\u00e9lib\u00e9r\u00e9 : seuls les premiers caract\u00e8res des codes commune sont\nutilis\u00e9s pour la reconnaissance du d\u00e9partement (algorithme rapide et qui donne\ndes r\u00e9sultats corrects pour 99% des cas), par opposition \u00e0 un requ\u00eatage\nsyst\u00e9matique aux API (processus sans erreur mais long).\n\n```\nfrom french_cities import find_departements\nimport pandas as pd\n\ndf = pd.DataFrame(\n    {\n        \"code_postal\": [\"59800\", \"97133\", \"20000\"],\n        \"code_commune\": [\"59350\", \"97701\", \"2A004\"],\n        \"communes\": [\"Lille\", \"Saint-Barth\u00e9l\u00e9my\", \"Ajaccio\"],\n        \"deps\": [\"59\", \"977\", \"2A\"],\n    }\n)\ndf = find_departements(df, source=\"code_postal\", alias=\"dep_A\", type_code=\"postcode\")\ndf = find_departements(df, source=\"code_commune\", alias=\"dep_B\", type_code=\"insee\")\n\nprint(df)\n```\n\nPour une documentation compl\u00e8te sur la fonction `find_departements`, merci \nd'utiliser la commande suivante :\n`help(find_departements)`.\n\n### Trouver les codes communes\n`french-cities` peut retrouver le code commune \u00e0 partir de champs multiples.\nIl est capable de d\u00e9tecter certaines erreurs simples dans les champs (jusqu'\u00e0 \nune certaine limite).\n\nLes colonnes utilis\u00e9es par l'algorithme pour cette d\u00e9tection sont (par ordre\nde priorit\u00e9) :\n* 'x' et 'y' (dans ce cas, un code EPSG doit \u00eatre explicitement donn\u00e9);\n* 'postcode' et 'city'\n* 'address', 'postcode' et 'city'\n* 'department' et 'city'\n\nIl est \u00e0 noter que l'algorithme peu faire \u00eatre source d'erreur d\u00e8s lors que\nla jointure spatiale (coordonn\u00e9es x & y) sera sollicit\u00e9e sur un mill\u00e9sime ancien.\nLes communes impact\u00e9es sont les communes restaur\u00e9es (\"scission\"), le flux de donn\u00e9es\nspatialis\u00e9es du COG servi par pynsee n'\u00e9tant pas mill\u00e9sim\u00e9 \u00e0 ce jour.\n\nLa reconnaissance syntaxique (champs postcode, city, address, departement) est\nbas\u00e9e sur un fuzzy matching en langage python, l'API BAN (base adresse nationale),\nou l'API Nominatim d'OSM (si activ\u00e9). \nL'algorithme ne conservera pas de r\u00e9sultats insuffisamment fiables, mais des \nerreurs peuvent subsister.\n\n```\nfrom french_cities import find_city\nimport pandas as pd\n\ndf = pd.DataFrame(\n    [\n        {\n            \"x\": 2.294694,\n            \"y\": 48.858093,\n            \"location\": \"Tour Eiffel\",\n            \"dep\": \"75\",\n            \"city\": \"Paris\",\n            \"address\": \"5 Avenue Anatole France\",\n            \"postcode\": \"75007\",\n            \"target\": \"75056\",\n        },\n        {\n            \"x\": 8.738962,\n            \"y\": 41.919216,\n            \"location\": \"mairie\",\n            \"dep\": \"2A\",\n            \"city\": \"Ajaccio\",\n            \"address\": \"Antoine S\u00e9rafini\",\n            \"postcode\": \"20000\",\n            \"target\": \"2A004\",\n        },\n        {\n            \"x\": -52.334990,\n            \"y\": 4.938194,\n            \"location\": \"mairie\",\n            \"dep\": \"973\",\n            \"city\": \"Cayenne\",\n            \"address\": \"1 rue de R\u00e9mire\",\n            \"postcode\": \"97300\",\n            \"target\": \"97302\",\n        },\n        {\n            \"x\": np.nan,\n            \"y\": np.nan,\n            \"location\": \"Erreur code postal Lille/Lyon\",\n            \"dep\": \"59\",\n            \"city\": \"Lille\",\n            \"address\": \"1 rue Faidherbe\",\n            \"postcode\": \"69000\",\n            \"target\": \"59350\",\n        },\n    ]\n)\ndf = find_city(df, epsg=4326)\n\nprint(df)\n```\n\nPour une documentation compl\u00e8te sur la fonction `find_city`, merci \nd'utiliser la commande suivante :\n`help(find_city)`.\n\n**Nota** : pour activer l'utilisation de `geopy` (API Nominatim d'OpenStreeMap) \nen dernier ressort, il convient d'utiliser l'argument `use_nominatim_backend=True`.\n\n### Projection de codes communes dans un mill\u00e9sime donn\u00e9\n`french-cities` peut tenter de \"projeter\" un dataframe dans un mill\u00e9sime donn\u00e9,\nla date initiale demeurant inconnue (voire inexistante, les cas de fichiers\n\"multi-mill\u00e9sim\u00e9s\" \u00e9tant fr\u00e9quents dans la vie r\u00e9elle).\n\nDes erreurs peuvent survenir, notamment pour les communes restaur\u00e9es (dans la \nmesure o\u00f9 la date initiale de la donn\u00e9e est inconnue ou inexistante).\n\nDans le cas o\u00f9 la date des donn\u00e9es est connue, il peut \u00eatre pertinent d'utiliser\nl'API de projection mise \u00e0 disposition par l'INSEE et accessible au travers de \n`pynsee`. Il convient de noter que cette utilisation peut \u00eatre lente, dans la \nmesure ou chaque commune devra \u00eatre test\u00e9e via l'API (qui n'autorise que \n30 requ\u00eates par minute).\n\nEn substance, l'algorithme de `french-cities` contr\u00f4le si le code commune existe\ndans le mill\u00e9sime souhait\u00e9 :\n* s'il existe il sera conserv\u00e9 (\u00e0 l'approximation pr\u00e9c\u00e9dente pr\u00e8s qui peut donc\nimpacter les communes restaur\u00e9es) ;\n* s'il n'existe pas, le code est recherch\u00e9 dans des mill\u00e9simes ant\u00e9rieurs (et\nl'API de projection de l'INSEE sera mobilis\u00e9e de mani\u00e8re cibl\u00e9e).\n\nCet algorithme va \u00e9galement :\n* convertir les codes des \u00e9ventuels arrondissements municipaux en celui de leur\ncommune de rattachement;\n* convertir les codes des communes associ\u00e9es et d\u00e9l\u00e9gu\u00e9es en celui de leur \ncommune de rattachement.\n\n```\nfrom french_cities import set_vintage\nimport pandas as pd\n\ndf = pd.DataFrame(\n    [\n        [\"07180\", \"Fusion\"],\n        [\"02077\", \"Commune d\u00e9l\u00e9gu\u00e9e\"],\n        [\"02564\", \"Commune nouvelle\"],\n        [\"75101\", \"Arrondissement municipal\"],\n        [\"59298\", \"Commune associ\u00e9e\"],\n        [\"99999\", \"Code erron\u00e9\"],\n        [\"14472\", \"Oudon\"],\n    ],\n    columns=[\"A\", \"Test\"],\n    index=[\"A\", \"B\", \"C\", \"D\", 1, 2, 3],\n)\ndf = set_vintage(df, 2023, field=\"A\")\nprint(df)\n```\n\nPour une documentation compl\u00e8te sur la fonction `set_vintage`, merci \nd'utiliser la commande suivante :\n`help(set_vintage)`.\n\n## Documentation externe\n\n`french-cities` utilise plusieurs API externes. N'h\u00e9sitez pas \u00e0 consulter :\n* [documentation](https://adresse.data.gouv.fr/api-doc/adresse) (en Fran\u00e7ais) de l'API Adresse\n* [documentation](https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/api/?flg=fr&q=code%3D68013&lang=fr) (en Fran\u00e7ais) de l'API OpenDataSoft.\n* [Politique d'usage de Nominatim](https://operations.osmfoundation.org/policies/nominatim/)\n\n## Support\nEn cas de bugues, merci d'ouvrir un ticket [sur le repo](https://github.com/tgrandje/french-cities/issues).\n\n## Auteur\nThomas GRANDJEAN (DREAL Hauts-de-France, service Information, D\u00e9veloppement Durable et \u00c9valuation Environnementale, p\u00f4le Promotion de la Connaissance).\n\n## Licence\nLicence Ouverte version 2.0 [etalab-2.0](https://www.etalab.gouv.fr/wp-content/uploads/2017/04/ETALAB-Licence-Ouverte-v2.0.pdf)\n\n## \u00c9tat du projet\nPhase de test.",
    "bugtrack_url": null,
    "license": "etalab-2.0",
    "summary": "Toolbox on french cities: set vintage, find departments, find cities...",
    "version": "0.1.1a5",
    "project_urls": {
        "Bug Tracker": "https://github.com/tgrandje/french-cities/issues",
        "Documentation": "https://github.com/tgrandje/french-cities/",
        "Homepage": "https://github.com/tgrandje/french-cities/",
        "Repository": "https://github.com/tgrandje/french-cities/"
    },
    "split_keywords": [
        "france",
        "cities"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f23abf4e6a7637a20db90b52f2082760a89045b3675c80f32061de1abc869a53",
                "md5": "2c1c706100908d16826bd0043522233c",
                "sha256": "84811a2266c014f62f90354bdf9bee960604d651406714ce61e09444637f4d14"
            },
            "downloads": -1,
            "filename": "french_cities-0.1.1a5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2c1c706100908d16826bd0043522233c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8,<4.0",
            "size": 22028,
            "upload_time": "2023-08-07T13:50:33",
            "upload_time_iso_8601": "2023-08-07T13:50:33.537093Z",
            "url": "https://files.pythonhosted.org/packages/f2/3a/bf4e6a7637a20db90b52f2082760a89045b3675c80f32061de1abc869a53/french_cities-0.1.1a5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d6607f1f95b4e868baaebe976ed6e81a24a396fecf73139409993baaa1bcc1eb",
                "md5": "ff397a81e4e4b30b148ff9a436f07f2a",
                "sha256": "a95c7babf3af4be4a2358c889d2f60e403fc0e850efb498f1fa45646a3c09d5b"
            },
            "downloads": -1,
            "filename": "french_cities-0.1.1a5.tar.gz",
            "has_sig": false,
            "md5_digest": "ff397a81e4e4b30b148ff9a436f07f2a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8,<4.0",
            "size": 25053,
            "upload_time": "2023-08-07T13:50:35",
            "upload_time_iso_8601": "2023-08-07T13:50:35.022937Z",
            "url": "https://files.pythonhosted.org/packages/d6/60/7f1f95b4e868baaebe976ed6e81a24a396fecf73139409993baaa1bcc1eb/french_cities-0.1.1a5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-08-07 13:50:35",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "tgrandje",
    "github_project": "french-cities",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "french-cities"
}
        
Elapsed time: 0.10710s