@ignfab/geocontext 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/gpf/adminexpress.d.ts +15 -0
  4. package/dist/gpf/adminexpress.js +50 -0
  5. package/dist/gpf/adminexpress.js.map +1 -0
  6. package/dist/gpf/altitude.d.ts +16 -0
  7. package/dist/gpf/altitude.js +35 -0
  8. package/dist/gpf/altitude.js.map +1 -0
  9. package/dist/gpf/geocode.d.ts +10 -0
  10. package/dist/gpf/geocode.js +27 -0
  11. package/dist/gpf/geocode.js.map +1 -0
  12. package/dist/gpf/parcellaire-express.d.ts +12 -0
  13. package/dist/gpf/parcellaire-express.js +74 -0
  14. package/dist/gpf/parcellaire-express.js.map +1 -0
  15. package/dist/gpf/urbanisme.d.ts +18 -0
  16. package/dist/gpf/urbanisme.js +95 -0
  17. package/dist/gpf/urbanisme.js.map +1 -0
  18. package/dist/gpf/wfs.d.ts +22 -0
  19. package/dist/gpf/wfs.js +65 -0
  20. package/dist/gpf/wfs.js.map +1 -0
  21. package/dist/helpers/distance.d.ts +7 -0
  22. package/dist/helpers/distance.js +17 -0
  23. package/dist/helpers/distance.js.map +1 -0
  24. package/dist/helpers/http.d.ts +6 -0
  25. package/dist/helpers/http.js +24 -0
  26. package/dist/helpers/http.js.map +1 -0
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.js +41 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/logger.d.ts +2 -0
  31. package/dist/logger.js +25 -0
  32. package/dist/logger.js.map +1 -0
  33. package/dist/tools/AdminexpressTool.d.ts +22 -0
  34. package/dist/tools/AdminexpressTool.js +23 -0
  35. package/dist/tools/AdminexpressTool.js.map +1 -0
  36. package/dist/tools/AltitudeTool.d.ts +27 -0
  37. package/dist/tools/AltitudeTool.js +24 -0
  38. package/dist/tools/AltitudeTool.js.map +1 -0
  39. package/dist/tools/AssietteSupTool.d.ts +22 -0
  40. package/dist/tools/AssietteSupTool.js +23 -0
  41. package/dist/tools/AssietteSupTool.js.map +1 -0
  42. package/dist/tools/CadastreTool.d.ts +22 -0
  43. package/dist/tools/CadastreTool.js +23 -0
  44. package/dist/tools/CadastreTool.js.map +1 -0
  45. package/dist/tools/GeocodeTool.d.ts +17 -0
  46. package/dist/tools/GeocodeTool.js +20 -0
  47. package/dist/tools/GeocodeTool.js.map +1 -0
  48. package/dist/tools/GpfWfsDescribeTypeTool.d.ts +32 -0
  49. package/dist/tools/GpfWfsDescribeTypeTool.js +32 -0
  50. package/dist/tools/GpfWfsDescribeTypeTool.js.map +1 -0
  51. package/dist/tools/GpfWfsGetFeaturesTool.d.ts +42 -0
  52. package/dist/tools/GpfWfsGetFeaturesTool.js +89 -0
  53. package/dist/tools/GpfWfsGetFeaturesTool.js.map +1 -0
  54. package/dist/tools/GpfWfsListTypesTool.d.ts +10 -0
  55. package/dist/tools/GpfWfsListTypesTool.js +18 -0
  56. package/dist/tools/GpfWfsListTypesTool.js.map +1 -0
  57. package/dist/tools/GpfWfsSearchTypesTool.d.ts +22 -0
  58. package/dist/tools/GpfWfsSearchTypesTool.js +31 -0
  59. package/dist/tools/GpfWfsSearchTypesTool.js.map +1 -0
  60. package/dist/tools/UrbanismeTool.d.ts +22 -0
  61. package/dist/tools/UrbanismeTool.js +23 -0
  62. package/dist/tools/UrbanismeTool.js.map +1 -0
  63. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2024 Mickaël Borne <https://github.com/mborne>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,195 @@
1
+ # geocontext
2
+
3
+ Un serveur MCP expérimental fournissant du contexte spatial pour les LLM.
4
+
5
+ ## Motivation
6
+
7
+ Les LLM renforcent l'idée que la magie est possible avec l'informatique. Il n'en est rien. Pour qu'un assistant soit en mesure de connaître la date et l'heure, il faut par exemple l'interfacer avec un [MCP time](https://mcpservers.org/servers/modelcontextprotocol/time). De même, pour qu'il soit en mesure de lire une page, il faut par exemple l'interfacer un [MCP fetch](https://github.com/modelcontextprotocol/servers/tree/main/src/fetch#readme).
8
+
9
+ En matière de données géographique, si un utilisateur pose une question impliquant que l'assistant soit en mesure de [connaître la position d'une adresse, il y a de bonne chance que la réponse soit plausible mais fausse](https://github.com/mborne/llm-experimentations/tree/main/chatgpt-geocodage-limites#readme).
10
+
11
+ S'il est techniquement possible de brancher des API REST/GeoJSON telle APICARTO, la conception de ces dernières n'est pas adaptée (5000 résultat par défaut, grosse géométrie dans les réponses, géométries complexes à fournir,...).
12
+
13
+ L'idée est ici d'**expérimenter la conception d'un MCP rendant les données et les services de la Géoplateforme accessibles par un LLM**.
14
+
15
+ ## Mises en garde
16
+
17
+ - Ce développement est un POC en incubation avec IgnFab (migration en cours de `mborne/geocontext` en `ignfab/geocontext`)
18
+ - S'il s'avère utile de l'industrialiser, le dépôt sera migré sous responsabilité IGN et l'outil sera renommé (ex : `IGNF/mcp-gpf-server`)
19
+ - Plusieurs problèmes et améliorations possibles ont été identifiés et sont en cours de mitigation/résolution (c.f. [issues](https://github.com/ignfab/geocontext/issues?q=is%3Aissue%20state%3Aopen%20label%3Ametadata)).
20
+ - Cet outil n'est pas magique (voir [Fonctionnalités](#fonctionnalités) pour avoir une idée de ses capacités)
21
+
22
+ ## Principes de conception
23
+
24
+ - **Ne pas copier les données de la Géoplateforme** (but : identifier les améliorations possibles sur le services plutôt que les doublonner)
25
+ - **Limiter au maximum la taille des réponses** (but : optimiser le nombre de jeton / éviter les hallucinations / pouvoir utiliser des modèles locaux)
26
+ - ...
27
+
28
+ ## Utilisation
29
+
30
+ ### Utilisation de la version publiée
31
+
32
+ Par exemple, avec "Cursor Settings / MCP / Add server" :
33
+
34
+ ```json
35
+ {
36
+ "mcpServers": {
37
+ "geocontext": {
38
+ "command": "npx",
39
+ "args": ["-y", "@ignfab/geocontext"]
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ ### Utilisation avec Docker
46
+
47
+ ```bash
48
+ docker compose build
49
+ docker compose up -d
50
+ ```
51
+
52
+ Ensuite :
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "geocontext": {
58
+ "url": "http://localhost:3000/mcp"
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ ## Développement
65
+
66
+ ### Construction de la version locale
67
+
68
+ ```bash
69
+ git clone https://github.com/ignfab/geocontext
70
+ cd geocontext
71
+ npm install
72
+ npm run build
73
+ ```
74
+
75
+ ### Utilisation de la version locale
76
+
77
+ ```json
78
+ {
79
+ "mcpServers": {
80
+ "mcp-helloworld": {
81
+ "command": "node",
82
+ "args":["/chemin/absolu/vers/geocontext/dist/index.js"]
83
+ }
84
+ }
85
+ }
86
+ ```
87
+
88
+ ### Debug de la version locale
89
+
90
+ ```bash
91
+ npx -y @modelcontextprotocol/inspector node dist/index.js
92
+ ```
93
+
94
+ ## Paramétrage
95
+
96
+ Pour une utilisation avancée :
97
+
98
+ | Nom | Description | Valeur par défaut |
99
+ | ---------------- | -------------------------------------------------------------------------------------------------------------------- | ----------------- |
100
+ | `TRANSPORT_TYPE` | [Transport](https://mcp-framework.com/docs/Transports/transports-overview) permet de choisir entre "stdio" et "http" | "stdio" |
101
+
102
+ ## Fonctionnalités
103
+
104
+ ### Utiliser des services spatiaux
105
+
106
+ Quelques services de la Géoplateforme :
107
+
108
+ * [geocode(text)](src/tools/GeocodeTool.ts) s'appuie sur le [service d’autocomplétion de la Géoplateforme](https://geoservices.ign.fr/documentation/services/services-geoplateforme/autocompletion) pour **convertir un nom de lieu en position (lon,lat)**.
109
+
110
+ > Ex : Quelle est la position (lon,lat) de la mairie de Vincennes?
111
+
112
+ * [altitude(lon,lat)](src/tools/AltitudeTool.ts) s'appuie sur le [service de calcul altimétrique de la Géoplateforme](https://geoservices.ign.fr/documentation/services/services-geoplateforme/altimetrie) pour **convertir une position en altitude**.
113
+
114
+ > Ex : Quelle est l'altitude de la mairie de Loray (25)?
115
+
116
+ ### Recherche d'informations pour un lieu
117
+
118
+ L'idée est ici de répondre à des précises en traitant côté serveur les appels aux services WFS de la Géoplateforme :
119
+
120
+ * [adminexpress(lon,lat)](src/tools/AdminexpressTool.ts) permet de **récupérer les informations administratives (commune, département, région,...)** pour un lieu donné par sa position.
121
+
122
+ > Ex : Quelles sont les informations administrative pour la mairie de Vincennes?
123
+
124
+ * [cadastre(lon,lat)](src/tools/CadastreTool.ts) permet de **récupérer les informations cadastrales (parcelle, feuille,...)**.
125
+
126
+ > Ex : Quelles sont les informations du cadastre pour la mairie de Vincennes?
127
+
128
+ * [urbanisme(lon,lat)](src/tools/UrbanismeTool.ts) permet de **récupérer les informations d'urbanisme (PLU,POS,CC,PSMV)**
129
+
130
+ > Ex : Quel est le document PLU en vigueur pour le port de Marseille?
131
+
132
+ * [assiette_sup(lon,lat)](src/tools/AssietteSupTool.ts) permet de **récupérer les Servitude d'Utilité Publiques (SUP)**
133
+
134
+ ### Explorer les données vecteurs
135
+
136
+ #### Explorer les tables
137
+
138
+ * [gpf_wfs_list_types()](src/tools/GpfWfsListTypesTool.ts) pour **lister les tables disponibles sur le WFS de la Géoplateforme** ([GetCapabilities](https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=GetCapabilities)) - **déprécié (trop de résultats)**
139
+ * [gpf_wfs_search_types(keywords,max_results=10)](src/tools/GpfSearchFeatureTypes.ts) pour **rechercher les tables disponibles sur le WFS de la Géoplateforme** ([GetCapabilities](https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=GetCapabilities))
140
+
141
+ > - Quels sont les millésimes ADMINEXPRESS disponibles sur la Géoplateforme?
142
+ > - Quelle est la table de la BDTOPO correspondant aux bâtiments?
143
+ > - Dans quelle table de la BDTOPO peut-on trouver les ponts?
144
+
145
+ #### Explorer la structure des tables
146
+
147
+ * [gpf_wfs_describe_type(typename)](src/tools/GpfWfsDescribeTypeTool.ts) pour récupérer le **schéma d'une table** ([DescribeFeatureType](https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=DescribeFeatureType&typename=ADMINEXPRESS-COG.LATEST:commune&outputFormat=application/json))
148
+
149
+ > - Quelles sont les informations disponibles pour les communes avec ADMINEXPRESS-COG.LATEST?
150
+ > - Compare le modèle des communes entre ADMINEXPRESS-COG:2024 et ADMINEXPRESS-COG.LATEST
151
+
152
+ #### Explorer les données des tables
153
+
154
+ * [gpf_wfs_get_features(typename,...)](src/tools/GpfWfsGetFeaturesTool.ts) pour **récupérer les données d'une table** ([GetFeature](https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=GetFeature&typename=ADMINEXPRESS-COG.LATEST:commune&outputFormat=application/json&count=1))
155
+
156
+ > - Quelles sont les 5 communes les plus peuplées du Doubs (25)?
157
+ > - Combien y-a-t'il de bâtiments à moins de 5 km de la tour Eiffel?
158
+
159
+ ## Contribution
160
+
161
+ ### Problèmes et demandes d'évolutions
162
+
163
+ N'hésitez pas à [créer une issue](https://github.com/ignfab/geocontext/issues) si vous rencontrez un problème! Merci de fournir :
164
+
165
+ - L'assistant et le modèle utilisé
166
+ - La demande que vous faite à l'assistant (ex : "Combien y a-t'il de pont franchissant la seine?")
167
+
168
+ ### Proposer une nouvelle fonctionnalité
169
+
170
+ N'hésitez pas :
171
+
172
+ - Forker le dépôt
173
+ - Créer un nouveau tool
174
+ - Tester de votre côté
175
+ - Faire une pull-request
176
+
177
+
178
+
179
+ ## Crédits
180
+
181
+ * [mcp-framework](https://mcp-framework.com) fournit le **cadre de développement du MCP** :
182
+
183
+ ```bash
184
+ # Par exemple, pour exposer la liste des couches WMTS
185
+ mcp add tool gpf_wmts_layers
186
+ ```
187
+
188
+ * [@camptocamp/ogc-client](https://camptocamp.github.io/ogc-client/#/) pour la **lecture des réponses XML des services WFS, WMTS,...**
189
+ * [MiniSearch](https://github.com/lucaong/minisearch) pour la **recherche par mot clé**.
190
+ * [jsts](https://bjornharrtell.github.io/jsts/) pour les **traitements géométriques** (ex : tri des réponses par distance au point recherché).
191
+
192
+ ## Licence
193
+
194
+ [MIT](LICENSE)
195
+
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Get administrative units (commune, departement,...) intersecting a given location
3
+ *
4
+ * @param {number} lon
5
+ * @param {number} lat
6
+ * @returns {object[]}
7
+ */
8
+ export function getAdminUnits(lon: number, lat: number): object[];
9
+ /**
10
+ * ADMINEXPRESS-COG.LATEST:{type}
11
+ *
12
+ * https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=GetCapabilities
13
+ */
14
+ export const ADMINEXPRESS_SOURCE: "G\u00E9oplateforme (WFS, ADMINEXPRESS-COG.LATEST)";
15
+ export const ADMINEXPRESS_TYPES: string[];
@@ -0,0 +1,50 @@
1
+ import { fetchJSON } from '../helpers/http.js';
2
+ import logger from '../logger.js';
3
+ import _ from 'lodash';
4
+ /**
5
+ * ADMINEXPRESS-COG.LATEST:{type}
6
+ *
7
+ * https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=GetCapabilities
8
+ */
9
+ export const ADMINEXPRESS_SOURCE = "Géoplateforme (WFS, ADMINEXPRESS-COG.LATEST)";
10
+ export const ADMINEXPRESS_TYPES = [
11
+ 'commune',
12
+ 'canton',
13
+ 'collectivite_territoriale',
14
+ 'epci',
15
+ 'departement',
16
+ 'region',
17
+ 'arrondissement'
18
+ ];
19
+ /**
20
+ * Get administrative units (commune, departement,...) intersecting a given location
21
+ *
22
+ * @param {number} lon
23
+ * @param {number} lat
24
+ * @returns {object[]}
25
+ */
26
+ export async function getAdminUnits(lon, lat) {
27
+ logger.info(`[adminexpress] getAdminUnits(${lon},${lat})...`);
28
+ // note that EPSG:4326 means lat,lon order for GeoServer -> flipped coordinates...
29
+ const cql_filter = `INTERSECTS(geometrie,Point(${lat} ${lon}))`;
30
+ // TODO : avoid useless geometry retrieval at WFS level
31
+ const url = 'https://data.geopf.fr/wfs?' + new URLSearchParams({
32
+ service: 'WFS',
33
+ request: 'GetFeature',
34
+ typeName: ADMINEXPRESS_TYPES.map((type) => { return `ADMINEXPRESS-COG.LATEST:${type}`; }).join(','),
35
+ outputFormat: 'application/json',
36
+ cql_filter: cql_filter
37
+ }).toString();
38
+ const featureCollection = await fetchJSON(url);
39
+ return featureCollection.features.map((feature) => {
40
+ // parse type from id (ex: "commune.3837")
41
+ const type = feature.id.split('.')[0];
42
+ // ignore geometry and extend properties
43
+ return Object.assign({
44
+ type: type,
45
+ id: feature.id,
46
+ bbox: feature.bbox
47
+ }, feature.properties);
48
+ });
49
+ }
50
+ //# sourceMappingURL=adminexpress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adminexpress.js","sourceRoot":"","sources":["../../src/gpf/adminexpress.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,MAAM,MAAM,cAAc,CAAC;AAElC,OAAO,CAAC,MAAM,QAAQ,CAAC;AAEvB;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,8CAA8C,CAAC;AAClF,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAC9B,SAAS;IACT,QAAQ;IACR,2BAA2B;IAC3B,MAAM;IACN,aAAa;IACb,QAAQ;IACR,gBAAgB;CACnB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAG,EAAE,GAAG;IACxC,MAAM,CAAC,IAAI,CAAC,gCAAgC,GAAG,IAAI,GAAG,MAAM,CAAC,CAAC;IAE9D,kFAAkF;IAClF,MAAM,UAAU,GAAG,8BAA8B,GAAG,IAAI,GAAG,IAAI,CAAC;IAEhE,uDAAuD;IACvD,MAAM,GAAG,GAAG,4BAA4B,GAAG,IAAI,eAAe,CAAC;QAC3D,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,YAAY;QACrB,QAAQ,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,2BAA2B,IAAI,EAAE,CAAA,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAClG,YAAY,EAAE,kBAAkB;QAChC,UAAU,EAAE,UAAU;KACzB,CAAC,CAAC,QAAQ,EAAE,CAAC;IAEd,MAAM,iBAAiB,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9C,0CAA0C;QAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,wCAAwC;QACxC,OAAO,MAAM,CAAC,MAAM,CAAC;YACjB,IAAI,EAAE,IAAI;YACV,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;SACrB,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Get altitude for a given location.
3
+ *
4
+ * @see https://geoservices.ign.fr/documentation/services/services-deprecies/calcul-altimetrique-rest#1872
5
+ *
6
+ * @param {number} lon
7
+ * @param {number} lat
8
+ * @returns
9
+ */
10
+ export function getAltitudeByLocation(lon: number, lat: number): Promise<{
11
+ lon: number;
12
+ lat: number;
13
+ altitude: any;
14
+ accuracy: any;
15
+ }>;
16
+ export const ALTITUDE_SOURCE: "G\u00E9oplateforme (altim\u00E9trie)";
@@ -0,0 +1,35 @@
1
+ import logger from "../logger.js";
2
+ import { fetchJSON } from "../helpers/http.js";
3
+ export const ALTITUDE_SOURCE = "Géoplateforme (altimétrie)";
4
+ /**
5
+ * Get altitude for a given location.
6
+ *
7
+ * @see https://geoservices.ign.fr/documentation/services/services-deprecies/calcul-altimetrique-rest#1872
8
+ *
9
+ * @param {number} lon
10
+ * @param {number} lat
11
+ * @returns
12
+ */
13
+ export async function getAltitudeByLocation(lon, lat) {
14
+ logger.info(`getAltitudeByLocation(${lon},${lat})...`);
15
+ const url = `https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json?lon=${lon}&lat=${lat}&resource=ign_rge_alti_wld`;
16
+ try {
17
+ const json = await fetchJSON(url);
18
+ const elevation = json.elevations[0];
19
+ return {
20
+ lon: lon,
21
+ lat: lat,
22
+ altitude: elevation.z,
23
+ accuracy: elevation.acc,
24
+ };
25
+ }
26
+ catch (e) {
27
+ return {
28
+ lon: lon,
29
+ lat: lat,
30
+ altitude: null,
31
+ accuracy: 'No data',
32
+ };
33
+ }
34
+ }
35
+ //# sourceMappingURL=altitude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"altitude.js","sourceRoot":"","sources":["../../src/gpf/altitude.js"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,CAAC,MAAM,eAAe,GAAG,4BAA4B,CAAC;AAE5D;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAG,EAAE,GAAG;IAChD,MAAM,CAAC,IAAI,CAAC,yBAAyB,GAAG,IAAI,GAAG,MAAM,CAAC,CAAC;IAEvD,MAAM,GAAG,GAAG,4EAA4E,GAAG,QAAQ,GAAG,4BAA4B,CAAC;IACnI,IAAI,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAE;QACtC,OAAO;YACH,GAAG,EAAE,GAAG;YACR,GAAG,EAAE,GAAG;YACR,QAAQ,EAAE,SAAS,CAAC,CAAC;YACrB,QAAQ,EAAE,SAAS,CAAC,GAAG;SAC1B,CAAC;IACN,CAAC;IAAA,OAAM,CAAC,EAAC,CAAC;QACN,OAAO;YACH,GAAG,EAAE,GAAG;YACR,GAAG,EAAE,GAAG;YACR,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,SAAS;SACtB,CAAC;IACN,CAAC;AAGL,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Get coordinates for a given location
3
+ *
4
+ * @see https://geoservices.ign.fr/documentation/services/services-geoplateforme/autocompletion
5
+ *
6
+ * @param {string} text
7
+ * @returns
8
+ */
9
+ export function geocode(text: string): Promise<any>;
10
+ export const GEOCODE_SOURCE: "G\u00E9oplateforme (service d'autocompl\u00E9tion)";
@@ -0,0 +1,27 @@
1
+ import logger from "../logger.js";
2
+ import { fetchJSON } from "../helpers/http.js";
3
+ export const GEOCODE_SOURCE = "Géoplateforme (service d'autocomplétion)";
4
+ /**
5
+ * Get coordinates for a given location
6
+ *
7
+ * @see https://geoservices.ign.fr/documentation/services/services-geoplateforme/autocompletion
8
+ *
9
+ * @param {string} text
10
+ * @returns
11
+ */
12
+ export async function geocode(text) {
13
+ logger.info(`geocode(${JSON.stringify(text)})...`);
14
+ const url = 'https://data.geopf.fr/geocodage/completion/?' + new URLSearchParams({
15
+ text: text,
16
+ maximumResponses: 3
17
+ }).toString();
18
+ const json = await fetchJSON(url);
19
+ return json.results.map((item) => {
20
+ return {
21
+ lon: item.x,
22
+ lat: item.y,
23
+ fulltext: item.fulltext
24
+ };
25
+ });
26
+ }
27
+ //# sourceMappingURL=geocode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geocode.js","sourceRoot":"","sources":["../../src/gpf/geocode.js"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,CAAC,MAAM,cAAc,GAAG,0CAA0C,CAAC;AAEzE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAI;IAC9B,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEnD,MAAM,GAAG,GAAG,8CAA8C,GAAG,IAAI,eAAe,CAAC;QAC/E,IAAI,EAAE,IAAI;QACV,gBAAgB,EAAE,CAAC;KACpB,CAAC,CAAC,QAAQ,EAAE,CAAC;IAEd,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAC,EAAE;QAAC,OAAO;YACtC,GAAG,EAAE,IAAI,CAAC,CAAC;YACX,GAAG,EAAE,IAAI,CAAC,CAAC;YACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAA;IAAA,CAAC,CAAC,CAAC;AACR,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Get items from CADASTRALPARCELS.PARCELLAIRE_EXPRESS near of a given location.
3
+ *
4
+ * @see https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=GetCapabilities
5
+ *
6
+ * @param {number} lon
7
+ * @param {number} lat
8
+ * @returns
9
+ */
10
+ export function getParcellaireExpress(lon: number, lat: number): Promise<array<object>>;
11
+ export const PARCELLAIRE_EXPRESS_SOURCE: "G\u00E9oplateforme (WFS, CADASTRALPARCELS.PARCELLAIRE_EXPRESS)";
12
+ export const PARCELLAIRE_EXPRESS_TYPES: string[];
@@ -0,0 +1,74 @@
1
+ import logger from '../logger.js';
2
+ import distance from '../helpers/distance.js';
3
+ import _ from 'lodash';
4
+ import { fetchJSON } from '../helpers/http.js';
5
+ // CADASTRALPARCELS.PARCELLAIRE_EXPRESS:
6
+ // https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=GetCapabilities
7
+ export const PARCELLAIRE_EXPRESS_SOURCE = "Géoplateforme (WFS, CADASTRALPARCELS.PARCELLAIRE_EXPRESS)";
8
+ export const PARCELLAIRE_EXPRESS_TYPES = [
9
+ 'arrondissement',
10
+ 'commune',
11
+ 'feuille',
12
+ 'parcelle',
13
+ 'subdivision_fiscale',
14
+ 'localisant'
15
+ ];
16
+ /**
17
+ * Filter items by distance keeping the nearest for each type.
18
+ *
19
+ * @param {array<object>} items
20
+ * @returns {array<object>}
21
+ */
22
+ function filterByDistance(items) {
23
+ const sortedItems = _.orderBy(items, ['type', 'distance'], ['asc', 'asc']);
24
+ const result = [];
25
+ let lastType = null;
26
+ for (const item of sortedItems) {
27
+ if (lastType == item.type) {
28
+ continue;
29
+ }
30
+ result.push(item);
31
+ lastType = item.type;
32
+ }
33
+ return result;
34
+ }
35
+ /**
36
+ * Get items from CADASTRALPARCELS.PARCELLAIRE_EXPRESS near of a given location.
37
+ *
38
+ * @see https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=GetCapabilities
39
+ *
40
+ * @param {number} lon
41
+ * @param {number} lat
42
+ * @returns
43
+ */
44
+ export async function getParcellaireExpress(lon, lat) {
45
+ logger.info(`getParcellaireExpress(${lon},${lat}) ...`);
46
+ // note that EPSG:4326 means lat,lon order for GeoServer -> flipped coordinates...
47
+ const cql_filter = `DWITHIN(geom,Point(${lat} ${lon}),10,meters)`;
48
+ const sourceGeom = {
49
+ "type": "Point",
50
+ "coordinates": [lon, lat]
51
+ };
52
+ // TODO : avoid useless geometry retrieval at WFS level
53
+ const url = 'https://data.geopf.fr/wfs?' + new URLSearchParams({
54
+ service: 'WFS',
55
+ request: 'GetFeature',
56
+ typeName: PARCELLAIRE_EXPRESS_TYPES.map((type) => { return `CADASTRALPARCELS.PARCELLAIRE_EXPRESS:${type}`; }).join(','),
57
+ outputFormat: 'application/json',
58
+ cql_filter: cql_filter
59
+ }).toString();
60
+ const featureCollection = await fetchJSON(url);
61
+ return filterByDistance(featureCollection.features.map((feature) => {
62
+ // parse type from id (ex: "commune.3837")
63
+ const type = feature.id.split('.')[0];
64
+ // ignore geometry and extend properties
65
+ return Object.assign({
66
+ type: type,
67
+ id: feature.id,
68
+ bbox: feature.bbox,
69
+ distance: distance(sourceGeom, feature.geometry),
70
+ source: PARCELLAIRE_EXPRESS_SOURCE,
71
+ }, feature.properties);
72
+ }));
73
+ }
74
+ //# sourceMappingURL=parcellaire-express.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parcellaire-express.js","sourceRoot":"","sources":["../../src/gpf/parcellaire-express.js"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,cAAc,CAAC;AAElC,OAAO,QAAQ,MAAM,wBAAwB,CAAC;AAE9C,OAAO,CAAC,MAAM,QAAQ,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,wCAAwC;AACxC,kFAAkF;AAElF,MAAM,CAAC,MAAM,0BAA0B,GAAG,2DAA2D,CAAC;AACtG,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACrC,gBAAgB;IAChB,SAAS;IACT,SAAS;IACT,UAAU;IACV,qBAAqB;IACrB,YAAY;CACf,CAAC;AAEF;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,KAAK;IAC3B,MAAM,WAAW,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAE3E,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,KAAM,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACzB,SAAS;QACb,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;IACzB,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAGD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAG,EAAE,GAAG;IAChD,MAAM,CAAC,IAAI,CAAC,yBAAyB,GAAG,IAAI,GAAG,OAAO,CAAC,CAAC;IACxD,kFAAkF;IAClF,MAAM,UAAU,GAAG,sBAAsB,GAAG,IAAI,GAAG,cAAc,CAAC;IAElE,MAAM,UAAU,GAAG;QACf,MAAM,EAAE,OAAO;QACf,aAAa,EAAE,CAAC,GAAG,EAAC,GAAG,CAAC;KAC3B,CAAC;IAEF,uDAAuD;IACvD,MAAM,GAAG,GAAG,4BAA4B,GAAG,IAAI,eAAe,CAAC;QAC3D,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,YAAY;QACrB,QAAQ,EAAE,yBAAyB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,wCAAwC,IAAI,EAAE,CAAA,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QACtH,YAAY,EAAE,kBAAkB;QAChC,UAAU,EAAE,UAAU;KACzB,CAAC,CAAC,QAAQ,EAAE,CAAC;IAEd,MAAM,iBAAiB,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,gBAAgB,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC/D,0CAA0C;QAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,wCAAwC;QACxC,OAAO,MAAM,CAAC,MAAM,CAAC;YACjB,IAAI,EAAE,IAAI;YACV,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,QAAQ,CACd,UAAU,EACV,OAAO,CAAC,QAAQ,CACnB;YACD,MAAM,EAAE,0BAA0B;SACrC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC,CAAC;AACR,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Get urbanism infos for a given location
3
+ *
4
+ * @param {number} lon
5
+ * @param {number} lat
6
+ * @returns
7
+ */
8
+ export function getUrbanisme(lon: number, lat: number): Promise<any>;
9
+ /**
10
+ * Get SUP infos for a given location
11
+ *
12
+ * @param {number} lon
13
+ * @param {number} lat
14
+ * @returns
15
+ */
16
+ export function getAssiettesServitudes(lon: number, lat: number): Promise<any>;
17
+ export const URBANISME_TYPES: string[];
18
+ export const URBANISME_SOURCE: "G\u00E9oplateforme - (WFS G\u00E9oportail de l'Urbanisme)";
@@ -0,0 +1,95 @@
1
+ import distance from "../helpers/distance.js";
2
+ import { fetchJSON } from "../helpers/http.js";
3
+ import logger from "../logger.js";
4
+ // https://data.geopf.fr/wfs/ows?service=WFS&version=2.0.0&request=GetCapabilities
5
+ export const URBANISME_TYPES = [
6
+ 'wfs_scot:scot',
7
+ 'wfs_du:document',
8
+ 'wfs_du:zone_urba',
9
+ 'wfs_du:secteur_cc',
10
+ 'wfs_du:info_pct',
11
+ 'wfs_du:info_lin',
12
+ 'wfs_du:info_surf',
13
+ 'wfs_du:prescription_pct',
14
+ 'wfs_du:prescription_lin',
15
+ 'wfs_du:prescription_surf'
16
+ ];
17
+ export const URBANISME_SOURCE = "Géoplateforme - (WFS Géoportail de l'Urbanisme)";
18
+ /**
19
+ * Get urbanism infos for a given location
20
+ *
21
+ * @param {number} lon
22
+ * @param {number} lat
23
+ * @returns
24
+ */
25
+ export async function getUrbanisme(lon, lat) {
26
+ logger.info(`getUrbanisme(${lon},${lat})...`);
27
+ // note that EPSG:4326 means lat,lon order for GeoServer -> flipped coordinates...
28
+ const cql_filter = `DWITHIN(the_geom,Point(${lat} ${lon}),30,meters)`;
29
+ const sourceGeom = {
30
+ "type": "Point",
31
+ "coordinates": [lon, lat]
32
+ };
33
+ // TODO : avoid useless geometry retrieval at WFS level
34
+ const url = 'https://data.geopf.fr/wfs?' + new URLSearchParams({
35
+ service: 'WFS',
36
+ request: 'GetFeature',
37
+ typeName: URBANISME_TYPES.join(','),
38
+ outputFormat: 'application/json',
39
+ cql_filter: cql_filter
40
+ }).toString();
41
+ const featureCollection = await fetchJSON(url);
42
+ return featureCollection.features.map((feature) => {
43
+ // parse type from id (ex: "commune.3837")
44
+ const type = feature.id.split('.')[0];
45
+ // ignore geometry and extend properties
46
+ return Object.assign({
47
+ type: type,
48
+ id: feature.id,
49
+ bbox: feature.bbox,
50
+ distance: (distance(sourceGeom, feature.geometry) * 1000.0)
51
+ }, feature.properties);
52
+ });
53
+ }
54
+ const ASSIETTES_SUP_TYPES = [
55
+ 'wfs_sup:assiette_sup_p',
56
+ 'wfs_sup:assiette_sup_l',
57
+ 'wfs_sup:assiette_sup_s',
58
+ ];
59
+ /**
60
+ * Get SUP infos for a given location
61
+ *
62
+ * @param {number} lon
63
+ * @param {number} lat
64
+ * @returns
65
+ */
66
+ export async function getAssiettesServitudes(lon, lat) {
67
+ logger.info(`getAssiettesServitudes(${lon},${lat})...`);
68
+ // note that EPSG:4326 means lat,lon order for GeoServer -> flipped coordinates...
69
+ const cql_filter = `DWITHIN(the_geom,Point(${lat} ${lon}),30,meters)`;
70
+ const sourceGeom = {
71
+ "type": "Point",
72
+ "coordinates": [lon, lat]
73
+ };
74
+ // TODO : avoid useless geometry retrieval at WFS level
75
+ const url = 'https://data.geopf.fr/wfs?' + new URLSearchParams({
76
+ service: 'WFS',
77
+ request: 'GetFeature',
78
+ typeName: ASSIETTES_SUP_TYPES.join(','),
79
+ outputFormat: 'application/json',
80
+ cql_filter: cql_filter
81
+ }).toString();
82
+ const featureCollection = await fetchJSON(url);
83
+ return featureCollection.features.map((feature) => {
84
+ // parse type from id (ex: "commune.3837")
85
+ const type = feature.id.split('.')[0];
86
+ // ignore geometry and extend properties
87
+ return Object.assign({
88
+ type: type,
89
+ id: feature.id,
90
+ bbox: feature.bbox,
91
+ distance: (distance(sourceGeom, feature.geometry) * 1000.0)
92
+ }, feature.properties);
93
+ });
94
+ }
95
+ //# sourceMappingURL=urbanisme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urbanisme.js","sourceRoot":"","sources":["../../src/gpf/urbanisme.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export declare const GPF_WFS_URL = "https://data.geopf.fr/wfs";
2
+ import { WfsFeatureTypeBrief, WfsFeatureTypeFull } from "@camptocamp/ogc-client";
3
+ export declare class FeatureTypeNotFoundError extends Error {
4
+ constructor(name: string);
5
+ }
6
+ export declare class FeatureTypeSearch {
7
+ private featureTypes;
8
+ private miniSearch;
9
+ constructor(featureTypes: WfsFeatureTypeBrief[]);
10
+ search(query: string): import("minisearch").SearchResult[];
11
+ }
12
+ export declare class WfsClient {
13
+ baseUrl: string;
14
+ private endpoint;
15
+ private featureTypes;
16
+ private featureTypeSearch;
17
+ constructor(baseUrl?: string);
18
+ getFeatureTypes(): Promise<WfsFeatureTypeBrief[]>;
19
+ searchFeatureTypes(query: string, maxResults?: number): Promise<WfsFeatureTypeBrief[]>;
20
+ getFeatureType(name: string): Promise<WfsFeatureTypeFull>;
21
+ }
22
+ export declare const wfsClient: WfsClient;