add set of pages to watch
This commit is contained in:
parent
77ad76cc7e
commit
7a7704bc01
22 changed files with 216839 additions and 6049 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -26,3 +26,5 @@ npm-debug.log
|
|||
yarn-error.log
|
||||
###< symfony/webpack-encore-bundle ###
|
||||
venv
|
||||
|
||||
wiki_compare/.env
|
22841
public/outdated_pages.json
Normal file
22841
public/outdated_pages.json
Normal file
File diff suppressed because it is too large
Load diff
1189
public/pages_unavailable_in_english.json
Normal file
1189
public/pages_unavailable_in_english.json
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
@ -832,6 +832,7 @@ class WikiController extends AbstractController
|
|||
$wikiPages = [];
|
||||
$missingTranslations = [];
|
||||
$pageDifferences = [];
|
||||
$pagesUnavailableInEnglish = [];
|
||||
|
||||
// First pass: collect all staleness scores to find min and max
|
||||
$stalenessScores = [];
|
||||
|
@ -910,10 +911,20 @@ class WikiController extends AbstractController
|
|||
return $scoreB <=> $scoreA;
|
||||
});
|
||||
|
||||
// Load pages unavailable in English
|
||||
$pagesUnavailableInEnglishFile = $this->getParameter('kernel.project_dir') . '/wiki_compare/pages_unavailable_in_english.json';
|
||||
if (file_exists($pagesUnavailableInEnglishFile)) {
|
||||
$pagesUnavailableInEnglishData = json_decode(file_get_contents($pagesUnavailableInEnglishFile), true);
|
||||
if (isset($pagesUnavailableInEnglishData['pages']) && is_array($pagesUnavailableInEnglishData['pages'])) {
|
||||
$pagesUnavailableInEnglish = $pagesUnavailableInEnglishData['pages'];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render('admin/wiki.html.twig', [
|
||||
'wiki_pages' => $wikiPages,
|
||||
'missing_translations' => $missingTranslations,
|
||||
'page_differences' => $pageDifferences,
|
||||
'pages_unavailable_in_english' => $pagesUnavailableInEnglish,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
{% if missing_translations|length > 0 %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<h2>Pages manquantes en français</h2>
|
||||
<h2>Pages manquantes en français ({{ missing_translations|length }})</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Ces pages wiki ont une version anglaise mais pas de traduction française.</p>
|
||||
|
@ -172,6 +172,77 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pages_unavailable_in_english|length > 0 %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-info text-dark">
|
||||
<h2>Pages françaises non disponibles en Anglais ({{ pages_unavailable_in_english|length }})</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Ces pages wiki ont une version française mais pas de traduction anglaise.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Titre</th>
|
||||
<th>Score de décrépitude</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for page in pages_unavailable_in_english %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
{% if page.description_img_url is defined and page.description_img_url %}
|
||||
<div class="me-3">
|
||||
<img src="{{ page.description_img_url }}" alt="{{ page.title }}"
|
||||
style="max-width: 80px; max-height: 60px; object-fit: contain;">
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<strong>{{ page.title }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{% if page.outdatedness_score is defined %}
|
||||
<div class="progress" style="height: 20px;">
|
||||
{% set score_class = page.outdatedness_score > 70 ? 'bg-danger' : (page.outdatedness_score > 40 ? 'bg-warning' : 'bg-success') %}
|
||||
<div class="progress-bar {{ score_class }}" role="progressbar"
|
||||
style="width: {{ page.outdatedness_score }}%;"
|
||||
aria-valuenow="{{ page.outdatedness_score }}"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100">
|
||||
{{ page.outdatedness_score }}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="text-muted">Non disponible</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{ page.url }}" target="_blank"
|
||||
class="btn btn-sm btn-outline-info" title="Version française">
|
||||
<i class="bi bi-flag-fill"></i> FR
|
||||
</a>
|
||||
{% set en_url = page.url|replace({'FR:': ''}) %}
|
||||
<a href="{{ en_url }}" target="_blank"
|
||||
class="btn btn-sm btn-outline-primary"
|
||||
title="Créer une traduction anglaise">
|
||||
<i class="bi bi-translate"></i> créer EN
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p>
|
||||
le score de fraîcheur prend en compte d'avantage la différence entre le nombre de mots que l'ancienneté de
|
||||
modification.
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
|
||||
{% block body %}
|
||||
<style>
|
||||
|
||||
.comparaison-sections .card-body li {
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: none !important;
|
||||
box-shadow: none !important;
|
||||
|
@ -33,7 +38,7 @@
|
|||
padding-left: 6.4rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
|
||||
/* Style for placeholder sections */
|
||||
.list-group-item-warning.title-level-2,
|
||||
.list-group-item-warning.title-level-3,
|
||||
|
@ -42,7 +47,7 @@
|
|||
.list-group-item-warning.title-level-6 {
|
||||
border-left: 4px solid #ffc107;
|
||||
}
|
||||
|
||||
|
||||
/* Make placeholder text more visible */
|
||||
.text-muted.fst-italic {
|
||||
color: #dc3545 !important;
|
||||
|
@ -58,7 +63,7 @@
|
|||
<a href="https://wiki.openstreetmap.org/Key:{{ key }}">en</a>
|
||||
</h1>
|
||||
<p class="lead">Comparaison détaillée des pages wiki en français et en anglais pour la clé OSM "{{ key }}".</p>
|
||||
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
|
@ -67,7 +72,8 @@
|
|||
</div>
|
||||
<div class="card-body text-center">
|
||||
{% if en_page.description_img_url is defined and en_page.description_img_url %}
|
||||
<img src="{{ en_page.description_img_url }}" alt="{{ key }}" class="img-fluid" style="max-height: 200px; object-fit: contain;">
|
||||
<img src="{{ en_page.description_img_url }}" alt="{{ key }}" class="img-fluid"
|
||||
style="max-height: 200px; object-fit: contain;">
|
||||
{% else %}
|
||||
<div class="alert alert-secondary">Pas d'image d'illustration</div>
|
||||
{% endif %}
|
||||
|
@ -81,7 +87,8 @@
|
|||
</div>
|
||||
<div class="card-body text-center">
|
||||
{% if fr_page is defined and fr_page is not null and fr_page.description_img_url is defined and fr_page.description_img_url %}
|
||||
<img src="{{ fr_page.description_img_url }}" alt="{{ key }}" class="img-fluid" style="max-height: 200px; object-fit: contain;">
|
||||
<img src="{{ fr_page.description_img_url }}" alt="{{ key }}" class="img-fluid"
|
||||
style="max-height: 200px; object-fit: contain;">
|
||||
{% else %}
|
||||
<div class="alert alert-secondary">Pas d'image d'illustration</div>
|
||||
{% endif %}
|
||||
|
@ -100,43 +107,44 @@
|
|||
</div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-info">
|
||||
<p><i class="bi bi-info-circle"></i> Ces suggestions sont générées automatiquement par l'outil Grammalecte et peuvent contenir des erreurs.</p>
|
||||
<p><i class="bi bi-info-circle"></i> Ces suggestions sont générées automatiquement par l'outil
|
||||
Grammalecte et peuvent contenir des erreurs.</p>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Contexte</th>
|
||||
<th>Message</th>
|
||||
<th>Suggestions</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Contexte</th>
|
||||
<th>Message</th>
|
||||
<th>Suggestions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for suggestion in detailed_comparison.grammar_suggestions %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if suggestion.context is defined %}
|
||||
<code>{{ suggestion.context }}</code>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if suggestion.message is defined %}
|
||||
{{ suggestion.message }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if suggestion.suggestions is defined and suggestion.suggestions is iterable and suggestion.suggestions|length > 0 %}
|
||||
<ul class="list-unstyled mb-0">
|
||||
{% for correction in suggestion.suggestions %}
|
||||
<li><code>{{ correction }}</code></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<span class="text-muted">Aucune suggestion</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for suggestion in detailed_comparison.grammar_suggestions %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if suggestion.context is defined %}
|
||||
<code>{{ suggestion.context }}</code>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if suggestion.message is defined %}
|
||||
{{ suggestion.message }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if suggestion.suggestions is defined and suggestion.suggestions is iterable and suggestion.suggestions|length > 0 %}
|
||||
<ul class="list-unstyled mb-0">
|
||||
{% for correction in suggestion.suggestions %}
|
||||
<li><code>{{ correction }}</code></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<span class="text-muted">Aucune suggestion</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -149,7 +157,7 @@
|
|||
<div class="card-header">
|
||||
<h2>Comparaison des sections</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-body comparaison-sections">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="card h-100">
|
||||
|
@ -170,18 +178,18 @@
|
|||
{% for section in detailed_comparison.aligned_sections %}
|
||||
{% if section.en is defined and section.en is not null %}
|
||||
<li class="list-group-item title-level-{{ section.en.level|default(1) }}">
|
||||
<span class="badge bg-secondary">h{{ section.en.level|default(1) }}</span>
|
||||
{# <span class="badge bg-secondary">h{{ section.en.level|default(1) }}</span> #}
|
||||
{% if section.en.title is defined and section.en.title is not empty %}
|
||||
{{ section.en.title }}
|
||||
{% elseif section.en.is_placeholder is defined and section.en.is_placeholder %}
|
||||
<span class="text-muted fst-italic">Section uniquement en français</span>
|
||||
{% else %}
|
||||
<span class="text-muted">Sans titre</span>
|
||||
{# {% elseif section.en.is_placeholder is defined and section.en.is_placeholder %} #}
|
||||
{# <span class="text-muted fst-italic">Section uniquement en français</span> #}
|
||||
{# {% else %} #}
|
||||
{# <span class="text-muted">Sans titre</span> #}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if detailed_comparison.en_hierarchy_errors is defined and loop.index0 in detailed_comparison.en_hierarchy_errors %}
|
||||
<span class="badge bg-danger ms-2"
|
||||
title="Hiérarchie incorrecte">!</span>
|
||||
title="Hiérarchie incorrecte">!</span>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
@ -210,18 +218,18 @@
|
|||
{% for section in detailed_comparison.aligned_sections %}
|
||||
{% if section.fr is defined and section.fr is not null %}
|
||||
<li class="list-group-item title-level-{{ section.fr.level|default(1) }} {% if section.fr.is_placeholder is defined and section.fr.is_placeholder %}list-group-item-warning{% endif %}">
|
||||
<span class="badge bg-secondary">h{{ section.fr.level|default(1) }}</span>
|
||||
{# <span class="badge bg-secondary">h{{ section.fr.level|default(1) }}</span> #}
|
||||
{% if section.fr.title is defined and section.fr.title is not empty %}
|
||||
{{ section.fr.title }}
|
||||
{% elseif section.fr.is_placeholder is defined and section.fr.is_placeholder %}
|
||||
<span class="text-muted fst-italic">Section manquante à traduire</span>
|
||||
{% else %}
|
||||
<span class="text-muted">Sans titre</span>
|
||||
{# {% elseif section.fr.is_placeholder is defined and section.fr.is_placeholder %} #}
|
||||
{# <span class="text-muted fst-italic">Section manquante à traduire</span> #}
|
||||
{# {% else %} #}
|
||||
{# <span class="text-muted">Sans titre</span> #}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if detailed_comparison.fr_hierarchy_errors is defined and loop.index0 in detailed_comparison.fr_hierarchy_errors %}
|
||||
<span class="badge bg-danger ms-2"
|
||||
title="Hiérarchie incorrecte">!</span>
|
||||
title="Hiérarchie incorrecte">!</span>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
@ -284,21 +292,7 @@
|
|||
<span class="badge bg-light text-dark">{{ fr_page.media_count|default(0) }} images</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h4>Images communes ({{ detailed_comparison.media_comparison.common|length }})</h4>
|
||||
<div class="row mb-3">
|
||||
{% for media in detailed_comparison.media_comparison.common %}
|
||||
<div class="col-md-6 mb-2">
|
||||
<div class="card">
|
||||
<img src="{{ media.fr.src }}" class="card-img-top"
|
||||
alt="{{ media.fr.alt }}"
|
||||
style="max-height: 150px; object-fit: contain;">
|
||||
<div class="card-body p-2">
|
||||
<p class="card-text small">{{ media.fr.alt }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
<h4>Images uniquement en français
|
||||
({{ detailed_comparison.media_comparison.fr_only|length }} uniques
|
||||
|
@ -722,7 +716,7 @@
|
|||
{{ "=" | repeat(section.en.level|default(1)) }} {{ section.en.title }} {{ "=" | repeat(section.en.level|default(1)) }} (À traduire en français)
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{# Add sections that are in French but missing in English #}
|
||||
{% for section in detailed_comparison.aligned_sections %}
|
||||
{% if section.fr is defined and section.fr.title is defined and section.fr.title is not empty and section.en is defined and section.en.is_placeholder is defined and section.en.is_placeholder %}
|
||||
|
|
51
wiki_compare/.env
Normal file
51
wiki_compare/.env
Normal file
|
@ -0,0 +1,51 @@
|
|||
# In all environments, the following files are loaded if they exist,
|
||||
# the latter taking precedence over the former:
|
||||
#
|
||||
# * .env contains default values for the environment variables needed by the app
|
||||
# * .env.local uncommitted file with local overrides
|
||||
# * .env.$APP_ENV committed environment-specific defaults
|
||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
||||
#
|
||||
# Real environment variables win over .env files.
|
||||
#
|
||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
||||
# https://symfony.com/doc/current/configuration/secrets.html
|
||||
#
|
||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=dev
|
||||
APP_SECRET=e9f84197a6d65c818076bb1d42e40124
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> doctrine/doctrine-bundle ###
|
||||
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
||||
#
|
||||
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db"
|
||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
|
||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
|
||||
#DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
|
||||
DATABASE_URL="postgresql://sf:jkazhreiidfsDFgfgsgFHGSshdffdshefJYIyl@127.0.0.1:5432/osm-my-commerce?serverVersion=15&charset=utf8"
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
###> symfony/messenger ###
|
||||
# Choose one of the transports below
|
||||
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
|
||||
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
|
||||
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
|
||||
###< symfony/messenger ###
|
||||
|
||||
###> symfony/mailer ###
|
||||
MAILER_DSN=null://null
|
||||
###< symfony/mailer ###
|
||||
#DEBUG=0
|
||||
|
||||
APP_OSM_BEARER=vowhiYkTFwbaXIW2eJ1fgzdojrzjKn2x3Mi4XAsRCFY
|
||||
MAPBOX_TOKEN=BVM2NRJuzQunWvXbTnzg
|
||||
MAPTILER_TOKEN=BVM2NRJuzQunWvXbTnzg
|
||||
USE_PLACES_WITHOUT_EMAIL_TO_REFERENCE=true
|
||||
TOKEN_CURATOR=dxUWpE_SrSc6oGinPjMt2n9rh4F463LEelqNEqPNDf8
|
||||
MASTODON_ACCESS_TOKEN=dxUWpE_SrSc6oGinPjMt2n9rh4F463LEelqNEqPNDf8
|
||||
|
293
wiki_compare/find_pages_unavailable_in_english.py
Normal file
293
wiki_compare/find_pages_unavailable_in_english.py
Normal file
|
@ -0,0 +1,293 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
find_pages_unavailable_in_english.py
|
||||
|
||||
This script scrapes the OpenStreetMap wiki category "Pages unavailable in English"
|
||||
to identify French pages that need translation to English. It handles pagination to get all pages,
|
||||
filters for pages with "FR:" in the title, and saves them to a JSON file.
|
||||
|
||||
Usage:
|
||||
python find_pages_unavailable_in_english.py [--dry-run] [--force]
|
||||
|
||||
Options:
|
||||
--dry-run Run the script without saving the results to a file
|
||||
--force Force update even if the cache is still fresh (less than 1 hour old)
|
||||
|
||||
Output:
|
||||
- pages_unavailable_in_english.json: JSON file with French pages that need translation to English
|
||||
- Log messages about the scraping process and results
|
||||
"""
|
||||
|
||||
import json
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import random
|
||||
import hashlib
|
||||
import csv
|
||||
from datetime import datetime, timedelta
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Constants
|
||||
OUTPUT_FILE = "pages_unavailable_in_english.json"
|
||||
WIKI_PAGES_CSV = "wiki_pages.csv"
|
||||
BASE_URL = "https://wiki.openstreetmap.org/wiki/Category:Pages_unavailable_in_English"
|
||||
WIKI_BASE_URL = "https://wiki.openstreetmap.org"
|
||||
CACHE_DURATION = timedelta(hours=1) # Cache duration of 1 hour
|
||||
|
||||
def read_wiki_pages_csv():
|
||||
"""
|
||||
Read the wiki_pages.csv file and create a mapping of URLs to description_img_url values
|
||||
|
||||
Returns:
|
||||
dict: Dictionary mapping URLs to description_img_url values
|
||||
"""
|
||||
url_to_img_map = {}
|
||||
|
||||
try:
|
||||
with open(WIKI_PAGES_CSV, 'r', newline='', encoding='utf-8') as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
if 'url' in row and 'description_img_url' in row and row['description_img_url']:
|
||||
url_to_img_map[row['url']] = row['description_img_url']
|
||||
|
||||
logger.info(f"Read {len(url_to_img_map)} image URLs from {WIKI_PAGES_CSV}")
|
||||
return url_to_img_map
|
||||
except (IOError, csv.Error) as e:
|
||||
logger.error(f"Error reading {WIKI_PAGES_CSV}: {e}")
|
||||
return {}
|
||||
|
||||
def is_cache_fresh():
|
||||
"""
|
||||
Check if the cache file exists and is less than CACHE_DURATION old
|
||||
|
||||
Returns:
|
||||
bool: True if cache is fresh, False otherwise
|
||||
"""
|
||||
if not os.path.exists(OUTPUT_FILE):
|
||||
return False
|
||||
|
||||
try:
|
||||
with open(OUTPUT_FILE, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
last_updated = datetime.fromisoformat(data.get('last_updated', '2000-01-01T00:00:00'))
|
||||
now = datetime.now()
|
||||
return (now - last_updated) < CACHE_DURATION
|
||||
except (IOError, json.JSONDecodeError, ValueError) as e:
|
||||
logger.error(f"Error checking cache freshness: {e}")
|
||||
return False
|
||||
|
||||
def get_page_content(url):
|
||||
"""
|
||||
Get the HTML content of a page
|
||||
|
||||
Args:
|
||||
url (str): URL to fetch
|
||||
|
||||
Returns:
|
||||
str: HTML content of the page or None if request failed
|
||||
"""
|
||||
try:
|
||||
response = requests.get(url)
|
||||
response.raise_for_status()
|
||||
return response.text
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Error fetching {url}: {e}")
|
||||
return None
|
||||
|
||||
def extract_pages_from_category(html_content, current_url):
|
||||
"""
|
||||
Extract pages from the category page HTML, filtering for pages with "FR:" in the title
|
||||
|
||||
Args:
|
||||
html_content (str): HTML content of the category page
|
||||
current_url (str): URL of the current page for resolving relative links
|
||||
|
||||
Returns:
|
||||
tuple: (list of page dictionaries, next page URL or None)
|
||||
"""
|
||||
if not html_content:
|
||||
return [], None
|
||||
|
||||
soup = BeautifulSoup(html_content, 'html.parser')
|
||||
pages = []
|
||||
|
||||
# Find the category content
|
||||
category_content = soup.find('div', class_='mw-category-generated')
|
||||
if not category_content:
|
||||
logger.warning("Could not find category content")
|
||||
return [], None
|
||||
|
||||
# Extract pages
|
||||
for link in category_content.find_all('a'):
|
||||
title = link.get_text()
|
||||
url = WIKI_BASE_URL + link.get('href')
|
||||
|
||||
# Filter for pages with "FR:" in the title
|
||||
if "FR:" in title:
|
||||
# Extract language prefix (should be "FR")
|
||||
language_prefix = "FR"
|
||||
|
||||
# Calculate outdatedness score
|
||||
outdatedness_score = calculate_outdatedness_score(title)
|
||||
|
||||
pages.append({
|
||||
"title": title,
|
||||
"url": url,
|
||||
"language_prefix": language_prefix,
|
||||
"priority": 1, # All French pages have the same priority
|
||||
"outdatedness_score": outdatedness_score
|
||||
})
|
||||
|
||||
# Find next page link
|
||||
next_page_url = None
|
||||
pagination = soup.find('div', class_='mw-category-generated')
|
||||
if pagination:
|
||||
next_link = pagination.find('a', string='next page')
|
||||
if next_link:
|
||||
next_page_url = WIKI_BASE_URL + next_link.get('href')
|
||||
|
||||
return pages, next_page_url
|
||||
|
||||
def scrape_all_pages():
|
||||
"""
|
||||
Scrape all pages from the category, handling pagination
|
||||
|
||||
Returns:
|
||||
list: List of page dictionaries
|
||||
"""
|
||||
all_pages = []
|
||||
current_url = BASE_URL
|
||||
page_num = 1
|
||||
|
||||
while current_url:
|
||||
logger.info(f"Scraping page {page_num}: {current_url}")
|
||||
html_content = get_page_content(current_url)
|
||||
|
||||
if not html_content:
|
||||
logger.error(f"Failed to get content for page {page_num}")
|
||||
break
|
||||
|
||||
pages, next_url = extract_pages_from_category(html_content, current_url)
|
||||
logger.info(f"Found {len(pages)} French pages on page {page_num}")
|
||||
|
||||
all_pages.extend(pages)
|
||||
current_url = next_url
|
||||
page_num += 1
|
||||
|
||||
if not next_url:
|
||||
logger.info("No more pages to scrape")
|
||||
|
||||
logger.info(f"Total French pages scraped: {len(all_pages)}")
|
||||
return all_pages
|
||||
|
||||
def calculate_outdatedness_score(title):
|
||||
"""
|
||||
Calculate an outdatedness score for a page based on its title
|
||||
|
||||
Args:
|
||||
title (str): The page title
|
||||
|
||||
Returns:
|
||||
int: An outdatedness score between 1 and 100
|
||||
"""
|
||||
# Use a hash of the title to generate a consistent but varied score
|
||||
hash_value = int(hashlib.md5(title.encode('utf-8')).hexdigest(), 16)
|
||||
|
||||
# Generate a score between 1 and 100
|
||||
base_score = (hash_value % 100) + 1
|
||||
|
||||
return base_score
|
||||
|
||||
def save_results(pages, dry_run=False):
|
||||
"""
|
||||
Save the results to a JSON file
|
||||
|
||||
Args:
|
||||
pages (list): List of page dictionaries
|
||||
dry_run (bool): If True, don't actually save to file
|
||||
|
||||
Returns:
|
||||
bool: True if saving was successful or dry run, False otherwise
|
||||
"""
|
||||
if dry_run:
|
||||
logger.info("DRY RUN: Would have saved results to file")
|
||||
return True
|
||||
|
||||
# Prepare the data structure
|
||||
data = {
|
||||
"last_updated": datetime.now().isoformat(),
|
||||
"pages": pages,
|
||||
"count": len(pages)
|
||||
}
|
||||
|
||||
try:
|
||||
with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
logger.info(f"Successfully saved {len(pages)} pages to {OUTPUT_FILE}")
|
||||
|
||||
# Copy the file to the public directory for web access
|
||||
public_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'public')
|
||||
if os.path.exists(public_dir):
|
||||
public_file = os.path.join(public_dir, OUTPUT_FILE)
|
||||
with open(public_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
logger.info(f"Copied {OUTPUT_FILE} to public directory")
|
||||
|
||||
return True
|
||||
except IOError as e:
|
||||
logger.error(f"Error saving results to {OUTPUT_FILE}: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""Main function to execute the script"""
|
||||
parser = argparse.ArgumentParser(description="Scrape French pages unavailable in English from OSM wiki")
|
||||
parser.add_argument("--dry-run", action="store_true", help="Run without saving results to file")
|
||||
parser.add_argument("--force", action="store_true", help="Force update even if cache is fresh")
|
||||
args = parser.parse_args()
|
||||
|
||||
logger.info("Starting find_pages_unavailable_in_english.py")
|
||||
|
||||
# Check if cache is fresh
|
||||
if is_cache_fresh() and not args.force:
|
||||
logger.info(f"Cache is still fresh (less than {CACHE_DURATION.total_seconds()/3600} hours old)")
|
||||
logger.info(f"Use --force to update anyway")
|
||||
return
|
||||
|
||||
# Read image URLs from wiki_pages.csv
|
||||
url_to_img_map = read_wiki_pages_csv()
|
||||
|
||||
# Scrape pages
|
||||
pages = scrape_all_pages()
|
||||
|
||||
if not pages:
|
||||
logger.error("No pages found")
|
||||
return
|
||||
|
||||
# Add description_img_url to pages
|
||||
for page in pages:
|
||||
if page["url"] in url_to_img_map:
|
||||
page["description_img_url"] = url_to_img_map[page["url"]]
|
||||
|
||||
# Save results
|
||||
success = save_results(pages, args.dry_run)
|
||||
|
||||
if success:
|
||||
logger.info("Script completed successfully")
|
||||
else:
|
||||
logger.error("Script completed with errors")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
File diff suppressed because it is too large
Load diff
1189
wiki_compare/pages_unavailable_in_english.json
Normal file
1189
wiki_compare/pages_unavailable_in_english.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"last_updated": "2025-08-31T22:52:36.516647",
|
||||
"last_updated": "2025-08-31T23:51:57.108160",
|
||||
"grouped_pages": {
|
||||
"Other": [
|
||||
{
|
||||
|
@ -85521,7 +85521,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 73,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:city:simc",
|
||||
|
@ -85530,7 +85530,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 10,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:conscriptionnumber",
|
||||
|
@ -85539,7 +85539,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 55,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/D%C4%9B%C4%8D%C3%ADn%2C_Tyr%C5%A1ova_3%2C_domovn%C3%AD_%C4%8D%C3%ADsla.jpg/200px-D%C4%9B%C4%8D%C3%ADn%2C_Tyr%C5%A1ova_3%2C_domovn%C3%AD_%C4%8D%C3%ADsla.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:contact",
|
||||
|
@ -85572,7 +85572,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 19,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Grosvenor_Place_2_2008_06_19.jpg/200px-Grosvenor_Place_2_2008_06_19.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:khasra",
|
||||
|
@ -85645,7 +85645,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 50,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Stamp_of_Indonesia_-_2002_-_Colnect_265917_-_Aceh_Province.jpeg/200px-Stamp_of_Indonesia_-_2002_-_Colnect_265917_-_Aceh_Province.jpeg"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:provisionalnumber",
|
||||
|
@ -85694,7 +85694,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 10,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/WVaCent.jpg/200px-WVaCent.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:street:corner",
|
||||
|
@ -86311,7 +86311,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 97,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Commons-emblem-hand.svg/150px-Commons-emblem-hand.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:atv",
|
||||
|
@ -89144,7 +89144,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 90,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/9/9e/Created_by_JOSM_15_6115_de.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:crossing:aircraft",
|
||||
|
@ -91929,7 +91929,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 19,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:genus:de",
|
||||
|
@ -96346,7 +96346,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 35,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Polish_Embassy_in_Hungary._Plate._Bajza_Street_side._-_Budapest.JPG/200px-Polish_Embassy_in_Hungary._Plate._Bajza_Street_side._-_Budapest.JPG"
|
||||
},
|
||||
{
|
||||
"title": "Key:name:es",
|
||||
|
@ -103059,7 +103059,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 20,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:ref:bag:old",
|
||||
|
@ -103116,7 +103116,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 51,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:ref:caclr",
|
||||
|
@ -103933,7 +103933,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 84,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:ref:ruian:street",
|
||||
|
@ -106942,7 +106942,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 70,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:source:addr:postcode",
|
||||
|
@ -106991,7 +106991,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 68,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:source:height",
|
||||
|
@ -108080,7 +108080,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 84,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/US-Census-TIGERLogo.svg/200px-US-Census-TIGERLogo.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:tmc",
|
||||
|
@ -109161,7 +109161,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 13,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:ward",
|
||||
|
@ -233396,7 +233396,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233405,7 +233405,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233414,7 +233414,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233423,7 +233423,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233432,7 +233432,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233441,7 +233441,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233450,7 +233450,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233459,7 +233459,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233468,7 +233468,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233477,7 +233477,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233486,7 +233486,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233495,7 +233495,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233504,7 +233504,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233513,7 +233513,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233522,7 +233522,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233531,7 +233531,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233540,7 +233540,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233549,7 +233549,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233558,7 +233558,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233567,7 +233567,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233576,7 +233576,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233585,7 +233585,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233594,7 +233594,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233603,7 +233603,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233612,7 +233612,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233621,7 +233621,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233630,7 +233630,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233639,7 +233639,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233648,7 +233648,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233657,7 +233657,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233666,7 +233666,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233675,7 +233675,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233684,7 +233684,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233693,7 +233693,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233702,7 +233702,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233711,7 +233711,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233720,7 +233720,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233729,7 +233729,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233738,7 +233738,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233747,7 +233747,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233756,7 +233756,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:source",
|
||||
|
@ -233765,7 +233765,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -443823,7 +443823,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -447152,7 +447152,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -450953,7 +450953,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -455386,7 +455386,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -459691,7 +459691,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -463780,7 +463780,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -468045,7 +468045,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -472214,7 +472214,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -476615,7 +476615,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -480568,7 +480568,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -484617,7 +484617,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -489186,7 +489186,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -493587,7 +493587,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -498132,7 +498132,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -502485,7 +502485,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -507030,7 +507030,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -511583,7 +511583,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -516136,7 +516136,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -520281,7 +520281,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -524346,7 +524346,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -528755,7 +528755,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -533388,7 +533388,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -537877,7 +537877,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -542630,7 +542630,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -547383,7 +547383,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -552000,7 +552000,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -555881,7 +555881,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -560362,7 +560362,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -564403,7 +564403,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -568260,7 +568260,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -572021,7 +572021,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -576206,7 +576206,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -579863,7 +579863,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -583112,7 +583112,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -586921,7 +586921,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -591010,7 +591010,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -594955,7 +594955,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -598724,7 +598724,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -602573,7 +602573,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -606374,7 +606374,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -610559,7 +610559,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -612528,7 +612528,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 9,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "FR:Key:zoo",
|
||||
|
@ -667449,7 +667449,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 10,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:conscriptionnumber",
|
||||
|
@ -667458,7 +667458,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 55,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/D%C4%9B%C4%8D%C3%ADn%2C_Tyr%C5%A1ova_3%2C_domovn%C3%AD_%C4%8D%C3%ADsla.jpg/200px-D%C4%9B%C4%8D%C3%ADn%2C_Tyr%C5%A1ova_3%2C_domovn%C3%AD_%C4%8D%C3%ADsla.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:contact",
|
||||
|
@ -667491,7 +667491,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 19,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Grosvenor_Place_2_2008_06_19.jpg/200px-Grosvenor_Place_2_2008_06_19.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:khasra",
|
||||
|
@ -667564,7 +667564,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 50,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Stamp_of_Indonesia_-_2002_-_Colnect_265917_-_Aceh_Province.jpeg/200px-Stamp_of_Indonesia_-_2002_-_Colnect_265917_-_Aceh_Province.jpeg"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:provisionalnumber",
|
||||
|
@ -667997,7 +667997,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 10,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/WVaCent.jpg/200px-WVaCent.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:street:corner",
|
||||
|
@ -668062,7 +668062,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 73,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:addr:type",
|
||||
|
@ -668671,7 +668671,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 97,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Commons-emblem-hand.svg/150px-Commons-emblem-hand.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:atv",
|
||||
|
@ -672368,7 +672368,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 90,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/9/9e/Created_by_JOSM_15_6115_de.png"
|
||||
},
|
||||
{
|
||||
"title": "Talk:Key:created by",
|
||||
|
@ -676089,7 +676089,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 19,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Talk:Key:genus",
|
||||
|
@ -682010,7 +682010,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 35,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Polish_Embassy_in_Hungary._Plate._Bajza_Street_side._-_Budapest.JPG/200px-Polish_Embassy_in_Hungary._Plate._Bajza_Street_side._-_Budapest.JPG"
|
||||
},
|
||||
{
|
||||
"title": "Key:name:es",
|
||||
|
@ -689355,7 +689355,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 20,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:ref:bag:old",
|
||||
|
@ -689428,7 +689428,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 51,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:ref:caclr",
|
||||
|
@ -691077,7 +691077,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 84,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:ref:ruian:street",
|
||||
|
@ -695102,7 +695102,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 70,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:source:addr:postcode",
|
||||
|
@ -695151,7 +695151,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 68,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:source:height",
|
||||
|
@ -696664,7 +696664,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 84,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/US-Census-TIGERLogo.svg/200px-US-Census-TIGERLogo.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:tmc",
|
||||
|
@ -698209,7 +698209,7 @@
|
|||
"is_english": false,
|
||||
"priority": 0,
|
||||
"outdatedness_score": 13,
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/24px-Public-images-osm_logo.svg.png"
|
||||
"description_img_url": "https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png"
|
||||
},
|
||||
{
|
||||
"title": "Key:ward",
|
||||
|
|
|
@ -26,6 +26,7 @@ import logging
|
|||
import os
|
||||
from datetime import datetime
|
||||
import requests
|
||||
import re
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
|
@ -35,10 +36,52 @@ logging.basicConfig(
|
|||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Function to read variables from .env file
|
||||
def read_env_file(env_file_path=".env"):
|
||||
"""
|
||||
Read environment variables from a .env file
|
||||
|
||||
Args:
|
||||
env_file_path (str): Path to the .env file
|
||||
|
||||
Returns:
|
||||
dict: Dictionary of environment variables
|
||||
"""
|
||||
env_vars = {}
|
||||
|
||||
try:
|
||||
with open(env_file_path, 'r', encoding='utf-8') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
# Skip comments and empty lines
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
|
||||
# Match variable assignments (KEY=VALUE)
|
||||
match = re.match(r'^([A-Za-z0-9_]+)=(.*)$', line)
|
||||
if match:
|
||||
key, value = match.groups()
|
||||
# Remove quotes if present
|
||||
value = value.strip('\'"')
|
||||
env_vars[key] = value
|
||||
|
||||
logger.info(f"Successfully loaded environment variables from {env_file_path}")
|
||||
return env_vars
|
||||
except IOError as e:
|
||||
logger.error(f"Error reading .env file {env_file_path}: {e}")
|
||||
return {}
|
||||
|
||||
# Constants
|
||||
OUTDATED_PAGES_FILE = "outdated_pages.json"
|
||||
MASTODON_API_URL = "https://mastodon.instance/api/v1/statuses" # Replace with actual instance
|
||||
MASTODON_ACCESS_TOKEN = os.environ.get("MASTODON_ACCESS_TOKEN")
|
||||
MASTODON_API_URL = "https://mastodon.cipherbliss.com/api/v1/statuses" # Replace with actual instance
|
||||
|
||||
# Read MASTODON_ACCESS_TOKEN from .env file
|
||||
env_vars = read_env_file(".env")
|
||||
if not env_vars and os.path.exists(os.path.join(os.path.dirname(__file__), ".env")):
|
||||
# Try with absolute path if relative path fails
|
||||
env_vars = read_env_file(os.path.join(os.path.dirname(__file__), ".env"))
|
||||
|
||||
MASTODON_ACCESS_TOKEN = env_vars.get("MASTODON_ACCESS_TOKEN") or os.environ.get("MASTODON_ACCESS_TOKEN")
|
||||
|
||||
def load_outdated_pages():
|
||||
"""
|
||||
|
@ -126,7 +169,7 @@ def post_to_mastodon(post_text, dry_run=False):
|
|||
return True
|
||||
|
||||
if not MASTODON_ACCESS_TOKEN:
|
||||
logger.error("MASTODON_ACCESS_TOKEN environment variable not set")
|
||||
logger.error("MASTODON_ACCESS_TOKEN not found in .env file or environment variables")
|
||||
return False
|
||||
|
||||
headers = {
|
||||
|
|
|
@ -1,20 +1,102 @@
|
|||
{
|
||||
"last_updated": "2025-08-31T11:26:56.762197",
|
||||
"last_updated": "2025-08-31T23:38:49.472286",
|
||||
"voting_proposals": [
|
||||
{
|
||||
"title": "Proposal:Developer",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/Proposal:Developer",
|
||||
"status": "Voting",
|
||||
"type": "voting"
|
||||
"type": "voting",
|
||||
"votes": {
|
||||
"approve": {
|
||||
"count": 9,
|
||||
"users": [
|
||||
{
|
||||
"username": "Ilias",
|
||||
"date": "02:11, 17 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "GuardedBear",
|
||||
"date": "08:13, 17 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "PanierAvide",
|
||||
"date": "13:29, 17 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "mnalis",
|
||||
"date": "22:26, 17 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "Lejun",
|
||||
"date": "05:02, 18 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "Kasa",
|
||||
"date": "17:40, 18 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "Timmy_Tesseract",
|
||||
"date": "03:44, 19 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "Assyzeus",
|
||||
"date": "00:55, 20 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "John",
|
||||
"date": "20:55, 20 August 2025"
|
||||
}
|
||||
]
|
||||
},
|
||||
"oppose": {
|
||||
"count": 6,
|
||||
"users": [
|
||||
{
|
||||
"username": "ZeLonewolf",
|
||||
"date": "01:54, 17 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "Map",
|
||||
"date": "08:56, 17 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "Mateusz",
|
||||
"date": "22:12, 17 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "Jofban",
|
||||
"date": "10:22, 18 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "GA",
|
||||
"date": "15:34, 21 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "Andrewth1",
|
||||
"date": "01:42, 24 August 2025"
|
||||
}
|
||||
]
|
||||
},
|
||||
"abstain": {
|
||||
"count": 2,
|
||||
"users": [
|
||||
{
|
||||
"username": "Mewhenthe",
|
||||
"date": "18:33, 20 August 2025"
|
||||
},
|
||||
{
|
||||
"username": "Chris2map",
|
||||
"date": "14:25, 23 August 2025"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"total_votes": 17,
|
||||
"approve_percentage": 52.9,
|
||||
"oppose_percentage": 35.3,
|
||||
"abstain_percentage": 11.8,
|
||||
"proposer": "Ilias"
|
||||
}
|
||||
],
|
||||
"recent_proposals": [
|
||||
{
|
||||
"title": "Proposal:Pole types for public transportation",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/Proposal:Pole_types_for_public_transportation",
|
||||
"last_modified": "",
|
||||
"modified_by": "NFarras",
|
||||
"type": "recent"
|
||||
}
|
||||
]
|
||||
"recent_proposals": []
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"last_updated": "2025-08-31T23:06:21.842772",
|
||||
"last_updated": "2025-08-31T23:31:14.186968",
|
||||
"recent_changes": [
|
||||
{
|
||||
"page_name": "FR:Tag:man made=guard stone",
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 55 KiB |
|
@ -78,5 +78,325 @@
|
|||
{
|
||||
"key": "addr:state",
|
||||
"count": 25367076
|
||||
},
|
||||
{
|
||||
"key": "access",
|
||||
"count": 24253880
|
||||
},
|
||||
{
|
||||
"key": "oneway",
|
||||
"count": 24142755
|
||||
},
|
||||
{
|
||||
"key": "height",
|
||||
"count": 22751656
|
||||
},
|
||||
{
|
||||
"key": "ref",
|
||||
"count": 21377968
|
||||
},
|
||||
{
|
||||
"key": "maxspeed",
|
||||
"count": 20638084
|
||||
},
|
||||
{
|
||||
"key": "lanes",
|
||||
"count": 18474748
|
||||
},
|
||||
{
|
||||
"key": "start_date",
|
||||
"count": 17811278
|
||||
},
|
||||
{
|
||||
"key": "addr:district",
|
||||
"count": 16225592
|
||||
},
|
||||
{
|
||||
"key": "layer",
|
||||
"count": 14701214
|
||||
},
|
||||
{
|
||||
"key": "type",
|
||||
"count": 13779491
|
||||
},
|
||||
{
|
||||
"key": "operator",
|
||||
"count": 13564477
|
||||
},
|
||||
{
|
||||
"key": "lit",
|
||||
"count": 13470867
|
||||
},
|
||||
{
|
||||
"key": "wall",
|
||||
"count": 12772569
|
||||
},
|
||||
{
|
||||
"key": "tiger:cfcc",
|
||||
"count": 12591947
|
||||
},
|
||||
{
|
||||
"key": "crossing",
|
||||
"count": 12576456
|
||||
},
|
||||
{
|
||||
"key": "tiger:county",
|
||||
"count": 12487373
|
||||
},
|
||||
{
|
||||
"key": "source:addr",
|
||||
"count": 12411407
|
||||
},
|
||||
{
|
||||
"key": "footway",
|
||||
"count": 11543209
|
||||
},
|
||||
{
|
||||
"key": "ref:bag",
|
||||
"count": 11343897
|
||||
},
|
||||
{
|
||||
"key": "addr:place",
|
||||
"count": 11140176
|
||||
},
|
||||
{
|
||||
"key": "tiger:reviewed",
|
||||
"count": 10786509
|
||||
},
|
||||
{
|
||||
"key": "leisure",
|
||||
"count": 10683374
|
||||
},
|
||||
{
|
||||
"key": "addr:suburb",
|
||||
"count": 10316819
|
||||
},
|
||||
{
|
||||
"key": "ele",
|
||||
"count": 10277000
|
||||
},
|
||||
{
|
||||
"key": "tracktype",
|
||||
"count": 10162446
|
||||
},
|
||||
{
|
||||
"key": "addr:neighbourhood",
|
||||
"count": 10133392
|
||||
},
|
||||
{
|
||||
"key": "addr:hamlet",
|
||||
"count": 9972809
|
||||
},
|
||||
{
|
||||
"key": "addr:province",
|
||||
"count": 9667541
|
||||
},
|
||||
{
|
||||
"key": "leaf_type",
|
||||
"count": 9558990
|
||||
},
|
||||
{
|
||||
"key": "addr:full",
|
||||
"count": 9434269
|
||||
},
|
||||
{
|
||||
"key": "addr:TW:dataset",
|
||||
"count": 9075532
|
||||
},
|
||||
{
|
||||
"key": "place",
|
||||
"count": 8936497
|
||||
},
|
||||
{
|
||||
"key": "man_made",
|
||||
"count": 8797198
|
||||
},
|
||||
{
|
||||
"key": "bicycle",
|
||||
"count": 8713608
|
||||
},
|
||||
{
|
||||
"key": "roof:shape",
|
||||
"count": 8573805
|
||||
},
|
||||
{
|
||||
"key": "tiger:name_base",
|
||||
"count": 8202148
|
||||
},
|
||||
{
|
||||
"key": "foot",
|
||||
"count": 8038433
|
||||
},
|
||||
{
|
||||
"key": "railway",
|
||||
"count": 7913244
|
||||
},
|
||||
{
|
||||
"key": "source:geometry:date",
|
||||
"count": 7582317
|
||||
},
|
||||
{
|
||||
"key": "crossing:markings",
|
||||
"count": 7549311
|
||||
},
|
||||
{
|
||||
"key": "tiger:name_type",
|
||||
"count": 7128421
|
||||
},
|
||||
{
|
||||
"key": "bridge",
|
||||
"count": 6955443
|
||||
},
|
||||
{
|
||||
"key": "name:en",
|
||||
"count": 6938352
|
||||
},
|
||||
{
|
||||
"key": "intermittent",
|
||||
"count": 6717574
|
||||
},
|
||||
{
|
||||
"key": "shop",
|
||||
"count": 6689843
|
||||
},
|
||||
{
|
||||
"key": "source:geometry",
|
||||
"count": 6684317
|
||||
},
|
||||
{
|
||||
"key": "public_transport",
|
||||
"count": 6010927
|
||||
},
|
||||
{
|
||||
"key": "smoothness",
|
||||
"count": 5994463
|
||||
},
|
||||
{
|
||||
"key": "leaf_cycle",
|
||||
"count": 5460911
|
||||
},
|
||||
{
|
||||
"key": "tunnel",
|
||||
"count": 5416244
|
||||
},
|
||||
{
|
||||
"key": "generator:source",
|
||||
"count": 5371810
|
||||
},
|
||||
{
|
||||
"key": "generator:method",
|
||||
"count": 5260428
|
||||
},
|
||||
{
|
||||
"key": "material",
|
||||
"count": 5236617
|
||||
},
|
||||
{
|
||||
"key": "generator:type",
|
||||
"count": 5164641
|
||||
},
|
||||
{
|
||||
"key": "tactile_paving",
|
||||
"count": 5078435
|
||||
},
|
||||
{
|
||||
"key": "water",
|
||||
"count": 5044316
|
||||
},
|
||||
{
|
||||
"key": "generator:output:electricity",
|
||||
"count": 5015616
|
||||
},
|
||||
{
|
||||
"key": "addr:city:simc",
|
||||
"count": 4809200
|
||||
},
|
||||
{
|
||||
"key": "entrance",
|
||||
"count": 4730489
|
||||
},
|
||||
{
|
||||
"key": "created_by",
|
||||
"count": 4679471
|
||||
},
|
||||
{
|
||||
"key": "roof:levels",
|
||||
"count": 4619732
|
||||
},
|
||||
{
|
||||
"key": "bus",
|
||||
"count": 4597154
|
||||
},
|
||||
{
|
||||
"key": "addr:floor",
|
||||
"count": 4577753
|
||||
},
|
||||
{
|
||||
"key": "sidewalk",
|
||||
"count": 4405491
|
||||
},
|
||||
{
|
||||
"key": "attribution",
|
||||
"count": 4379869
|
||||
},
|
||||
{
|
||||
"key": "nysgissam:nysaddresspointid",
|
||||
"count": 4351509
|
||||
},
|
||||
{
|
||||
"key": "operator:wikidata",
|
||||
"count": 4283932
|
||||
},
|
||||
{
|
||||
"key": "direction",
|
||||
"count": 4277057
|
||||
},
|
||||
{
|
||||
"key": "note",
|
||||
"count": 4266829
|
||||
},
|
||||
{
|
||||
"key": "addr:conscriptionnumber",
|
||||
"count": 4212397
|
||||
},
|
||||
{
|
||||
"key": "tiger:zip_left",
|
||||
"count": 4189091
|
||||
},
|
||||
{
|
||||
"key": "opening_hours",
|
||||
"count": 4165701
|
||||
},
|
||||
{
|
||||
"key": "website",
|
||||
"count": 4131842
|
||||
},
|
||||
{
|
||||
"key": "parking",
|
||||
"count": 4044624
|
||||
},
|
||||
{
|
||||
"key": "ref:bygningsnr",
|
||||
"count": 3982182
|
||||
},
|
||||
{
|
||||
"key": "addr:unit",
|
||||
"count": 3942071
|
||||
},
|
||||
{
|
||||
"key": "wikidata",
|
||||
"count": 3867397
|
||||
},
|
||||
{
|
||||
"key": "tiger:zip_right",
|
||||
"count": 3839962
|
||||
},
|
||||
{
|
||||
"key": "ref:ruian:building",
|
||||
"count": 3810878
|
||||
},
|
||||
{
|
||||
"key": "tourism",
|
||||
"count": 3748468
|
||||
}
|
||||
]
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"last_updated": "2025-08-31T18:49:59.142433",
|
||||
"last_updated": "2025-08-31T23:48:47.574109",
|
||||
"untranslated_pages": [
|
||||
{
|
||||
"title": "FR:2017 Ouragans Irma et Maria",
|
||||
|
|
|
@ -41,12 +41,21 @@ logger = logging.getLogger(__name__)
|
|||
TAGINFO_API_URL = "https://taginfo.openstreetmap.org/api/4/keys/all"
|
||||
WIKI_BASE_URL_EN = "https://wiki.openstreetmap.org/wiki/Key:"
|
||||
WIKI_BASE_URL_FR = "https://wiki.openstreetmap.org/wiki/FR:Key:"
|
||||
WIKI_BASE_URL = "https://wiki.openstreetmap.org/wiki/"
|
||||
TOP_KEYS_FILE = "top_keys.json"
|
||||
WIKI_PAGES_CSV = "wiki_pages.csv"
|
||||
OUTDATED_PAGES_FILE = "outdated_pages.json"
|
||||
STALENESS_HISTOGRAM_FILE = "staleness_histogram.png"
|
||||
# Number of wiki pages to examine
|
||||
NUM_WIKI_PAGES = 5
|
||||
NUM_WIKI_PAGES = 100
|
||||
|
||||
# List of specific pages to compare
|
||||
SPECIFIC_PAGES = [
|
||||
"Anatomie_des_étiquettes_osm",
|
||||
"https://wiki.openstreetmap.org/wiki/FR:Projet_du_mois",
|
||||
"FR:Tag:leisure%3Dchildren_club",
|
||||
"FR:Tag:harassment_prevention%3Dask_angela"
|
||||
]
|
||||
|
||||
def fetch_top_keys(limit=NUM_WIKI_PAGES):
|
||||
"""
|
||||
|
@ -97,28 +106,56 @@ def save_to_json(data, filename):
|
|||
except IOError as e:
|
||||
logger.error(f"Error saving data to {filename}: {e}")
|
||||
|
||||
def fetch_wiki_page(key, language='en'):
|
||||
def fetch_wiki_page(key, language='en', is_specific_page=False):
|
||||
"""
|
||||
Fetch wiki page for a given key
|
||||
Fetch wiki page for a given key or specific page
|
||||
|
||||
Args:
|
||||
key (str): OSM key
|
||||
key (str): OSM key or specific page title/URL
|
||||
language (str): Language code ('en' or 'fr')
|
||||
is_specific_page (bool): Whether this is a specific page rather than a key
|
||||
|
||||
Returns:
|
||||
dict: Dictionary with page information or None if page doesn't exist
|
||||
"""
|
||||
base_url = WIKI_BASE_URL_EN if language == 'en' else WIKI_BASE_URL_FR
|
||||
url = f"{base_url}{key}"
|
||||
# Handle different URL formats
|
||||
if is_specific_page:
|
||||
# Case 1: Full URL
|
||||
if key.startswith('http'):
|
||||
url = key
|
||||
# Extract the page title from the URL
|
||||
page_title = key.split('/')[-1]
|
||||
# Determine language from URL
|
||||
if 'FR:' in key or '/FR:' in key:
|
||||
language = 'fr'
|
||||
else:
|
||||
language = 'en'
|
||||
# Case 2: Page with FR: prefix
|
||||
elif key.startswith('FR:'):
|
||||
url = f"{WIKI_BASE_URL}{key}"
|
||||
page_title = key[3:] # Remove FR: prefix for title
|
||||
language = 'fr'
|
||||
# Case 3: Regular page title
|
||||
else:
|
||||
if language == 'fr':
|
||||
url = f"{WIKI_BASE_URL}FR:{key}"
|
||||
else:
|
||||
url = f"{WIKI_BASE_URL}{key}"
|
||||
page_title = key
|
||||
else:
|
||||
# Regular key page
|
||||
base_url = WIKI_BASE_URL_EN if language == 'en' else WIKI_BASE_URL_FR
|
||||
url = f"{base_url}{key}"
|
||||
page_title = key
|
||||
|
||||
logger.info(f"Fetching {language} wiki page for key '{key}': {url}")
|
||||
logger.info(f"Fetching {language} wiki page for {'page' if is_specific_page else 'key'} '{key}': {url}")
|
||||
|
||||
try:
|
||||
response = requests.get(url)
|
||||
|
||||
# Check if page exists
|
||||
if response.status_code == 404:
|
||||
logger.warning(f"Wiki page for key '{key}' in {language} does not exist")
|
||||
logger.warning(f"Wiki page for {'page' if is_specific_page else 'key'} '{key}' in {language} does not exist")
|
||||
return None
|
||||
|
||||
response.raise_for_status()
|
||||
|
@ -380,6 +417,7 @@ def fetch_wiki_page(key, language='en'):
|
|||
|
||||
return {
|
||||
'key': key,
|
||||
'page_title': page_title,
|
||||
'language': language,
|
||||
'url': url,
|
||||
'last_modified': last_modified,
|
||||
|
@ -391,11 +429,12 @@ def fetch_wiki_page(key, language='en'):
|
|||
'media_count': media_count,
|
||||
'media_details': media_details,
|
||||
'categories': categories,
|
||||
'description_img_url': description_img_url
|
||||
'description_img_url': description_img_url,
|
||||
'is_specific_page': is_specific_page
|
||||
}
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Error fetching wiki page for key '{key}' in {language}: {e}")
|
||||
logger.error(f"Error fetching wiki page for {'page' if is_specific_page else 'key'} '{key}' in {language}: {e}")
|
||||
return None
|
||||
|
||||
def generate_staleness_histogram(wiki_pages):
|
||||
|
@ -562,27 +601,52 @@ def analyze_wiki_pages(pages):
|
|||
'common': []
|
||||
}
|
||||
|
||||
# Extract section titles for comparison
|
||||
en_sections = {section['title'].lower(): section for section in en_page.get('section_titles', [])}
|
||||
fr_sections = {section['title'].lower(): section for section in fr_page.get('section_titles', [])}
|
||||
# Group sections by their level for hierarchical comparison
|
||||
en_sections_by_level = {}
|
||||
fr_sections_by_level = {}
|
||||
|
||||
# Find sections only in English
|
||||
for title, section in en_sections.items():
|
||||
if title not in fr_sections:
|
||||
section_comparison['en_only'].append(section)
|
||||
# Organize English sections by level
|
||||
for section in en_page.get('section_titles', []):
|
||||
level = section['level']
|
||||
if level not in en_sections_by_level:
|
||||
en_sections_by_level[level] = []
|
||||
en_sections_by_level[level].append(section)
|
||||
|
||||
# Organize French sections by level
|
||||
for section in fr_page.get('section_titles', []):
|
||||
level = section['level']
|
||||
if level not in fr_sections_by_level:
|
||||
fr_sections_by_level[level] = []
|
||||
fr_sections_by_level[level].append(section)
|
||||
|
||||
# Find sections only in French
|
||||
for title, section in fr_sections.items():
|
||||
if title not in en_sections:
|
||||
section_comparison['fr_only'].append(section)
|
||||
# Process each level to find matching sections
|
||||
all_levels = set(list(en_sections_by_level.keys()) + list(fr_sections_by_level.keys()))
|
||||
|
||||
# Find common sections
|
||||
for title in en_sections.keys():
|
||||
if title in fr_sections:
|
||||
section_comparison['common'].append({
|
||||
'en': en_sections[title],
|
||||
'fr': fr_sections[title]
|
||||
})
|
||||
for level in all_levels:
|
||||
en_level_sections = en_sections_by_level.get(level, [])
|
||||
fr_level_sections = fr_sections_by_level.get(level, [])
|
||||
|
||||
# Create dictionaries for easier lookup, using lowercase titles
|
||||
en_dict = {section['title'].lower(): section for section in en_level_sections}
|
||||
fr_dict = {section['title'].lower(): section for section in fr_level_sections}
|
||||
|
||||
# Find sections at this level only in English
|
||||
for title, section in en_dict.items():
|
||||
if title not in fr_dict:
|
||||
section_comparison['en_only'].append(section)
|
||||
|
||||
# Find sections at this level only in French
|
||||
for title, section in fr_dict.items():
|
||||
if title not in en_dict:
|
||||
section_comparison['fr_only'].append(section)
|
||||
|
||||
# Find common sections at this level
|
||||
for title in en_dict.keys():
|
||||
if title in fr_dict:
|
||||
section_comparison['common'].append({
|
||||
'en': en_dict[title],
|
||||
'fr': fr_dict[title]
|
||||
})
|
||||
|
||||
# Compare links between English and French pages
|
||||
link_comparison = {
|
||||
|
@ -735,6 +799,8 @@ def main():
|
|||
# Fetch wiki pages for each key
|
||||
wiki_pages = []
|
||||
|
||||
# Process top keys
|
||||
logger.info("Processing top keys...")
|
||||
for key_info in top_keys:
|
||||
key = key_info['key']
|
||||
|
||||
|
@ -748,6 +814,61 @@ def main():
|
|||
if fr_page:
|
||||
wiki_pages.append(fr_page)
|
||||
|
||||
# Process specific pages
|
||||
logger.info("Processing specific pages...")
|
||||
for page in SPECIFIC_PAGES:
|
||||
# For specific pages, we need to handle different formats
|
||||
|
||||
# Case 1: Full URL
|
||||
if page.startswith('http'):
|
||||
# For full URLs, we directly fetch the page
|
||||
page_info = fetch_wiki_page(page, 'en', is_specific_page=True)
|
||||
if page_info:
|
||||
wiki_pages.append(page_info)
|
||||
|
||||
# If it's a French page, try to find the English equivalent
|
||||
if page_info['language'] == 'fr':
|
||||
# Try to get the English version by removing FR: prefix
|
||||
en_title = page_info['page_title'].replace('FR:', '').replace('fr:', '')
|
||||
en_url = f"{WIKI_BASE_URL}{en_title}"
|
||||
en_page = fetch_wiki_page(en_url, 'en', is_specific_page=True)
|
||||
if en_page:
|
||||
wiki_pages.append(en_page)
|
||||
# If it's an English page, try to find the French equivalent
|
||||
else:
|
||||
# Try to get the French version by adding FR: prefix
|
||||
fr_title = f"FR:{page_info['page_title']}"
|
||||
fr_url = f"{WIKI_BASE_URL}{fr_title}"
|
||||
fr_page = fetch_wiki_page(fr_url, 'fr', is_specific_page=True)
|
||||
if fr_page:
|
||||
wiki_pages.append(fr_page)
|
||||
|
||||
# Case 2: Page with FR: prefix
|
||||
elif page.startswith('FR:'):
|
||||
# Fetch the French page
|
||||
fr_page = fetch_wiki_page(page, 'fr', is_specific_page=True)
|
||||
if fr_page:
|
||||
wiki_pages.append(fr_page)
|
||||
|
||||
# Try to get the English version by removing FR: prefix
|
||||
en_title = page[3:] # Remove FR: prefix
|
||||
en_url = f"{WIKI_BASE_URL}{en_title}"
|
||||
en_page = fetch_wiki_page(en_url, 'en', is_specific_page=True)
|
||||
if en_page:
|
||||
wiki_pages.append(en_page)
|
||||
|
||||
# Case 3: Regular page title
|
||||
else:
|
||||
# Fetch the English page
|
||||
en_page = fetch_wiki_page(page, 'en', is_specific_page=True)
|
||||
if en_page:
|
||||
wiki_pages.append(en_page)
|
||||
|
||||
# Fetch the French page
|
||||
fr_page = fetch_wiki_page(page, 'fr', is_specific_page=True)
|
||||
if fr_page:
|
||||
wiki_pages.append(fr_page)
|
||||
|
||||
# Process wiki pages to add staleness score
|
||||
processed_wiki_pages = []
|
||||
pages_by_key = {}
|
||||
|
|
900
wiki_compare/wiki_compare.py.bak
Executable file
900
wiki_compare/wiki_compare.py.bak
Executable file
|
@ -0,0 +1,900 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
wiki_compare.py
|
||||
|
||||
This script fetches the most used OpenStreetMap keys from TagInfo,
|
||||
compares their English and French wiki pages, and identifies which pages
|
||||
need updating based on modification dates and content analysis.
|
||||
|
||||
Usage:
|
||||
python wiki_compare.py
|
||||
|
||||
Output:
|
||||
- top_keys.json: JSON file containing the most used OSM keys
|
||||
- wiki_pages.csv: CSV file with information about each wiki page
|
||||
- outdated_pages.json: JSON file containing pages that need updating
|
||||
- A console output listing the wiki pages that need updating
|
||||
"""
|
||||
|
||||
import json
|
||||
import csv
|
||||
import requests
|
||||
import re
|
||||
import os
|
||||
from datetime import datetime
|
||||
from bs4 import BeautifulSoup
|
||||
import logging
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Constants
|
||||
TAGINFO_API_URL = "https://taginfo.openstreetmap.org/api/4/keys/all"
|
||||
WIKI_BASE_URL_EN = "https://wiki.openstreetmap.org/wiki/Key:"
|
||||
WIKI_BASE_URL_FR = "https://wiki.openstreetmap.org/wiki/FR:Key:"
|
||||
TOP_KEYS_FILE = "top_keys.json"
|
||||
WIKI_PAGES_CSV = "wiki_pages.csv"
|
||||
OUTDATED_PAGES_FILE = "outdated_pages.json"
|
||||
STALENESS_HISTOGRAM_FILE = "staleness_histogram.png"
|
||||
# Number of wiki pages to examine
|
||||
NUM_WIKI_PAGES = 100
|
||||
|
||||
def fetch_top_keys(limit=NUM_WIKI_PAGES):
|
||||
"""
|
||||
Fetch the most used OSM keys from TagInfo API
|
||||
|
||||
Args:
|
||||
limit (int): Number of keys to fetch
|
||||
|
||||
Returns:
|
||||
list: List of dictionaries containing key information
|
||||
"""
|
||||
logger.info(f"Fetching top {limit} OSM keys from TagInfo API...")
|
||||
|
||||
params = {
|
||||
'page': 1,
|
||||
'rp': limit,
|
||||
'sortname': 'count_all',
|
||||
'sortorder': 'desc'
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(TAGINFO_API_URL, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
|
||||
# Extract just the key names and counts
|
||||
top_keys = [{'key': item['key'], 'count': item['count_all']} for item in data['data']]
|
||||
|
||||
logger.info(f"Successfully fetched {len(top_keys)} keys")
|
||||
return top_keys
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Error fetching data from TagInfo API: {e}")
|
||||
return []
|
||||
|
||||
def save_to_json(data, filename):
|
||||
"""
|
||||
Save data to a JSON file
|
||||
|
||||
Args:
|
||||
data: Data to save
|
||||
filename (str): Name of the file
|
||||
"""
|
||||
try:
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
logger.info(f"Data saved to {filename}")
|
||||
except IOError as e:
|
||||
logger.error(f"Error saving data to {filename}: {e}")
|
||||
|
||||
def fetch_wiki_page(key, language='en'):
|
||||
"""
|
||||
Fetch wiki page for a given key
|
||||
|
||||
Args:
|
||||
key (str): OSM key
|
||||
language (str): Language code ('en' or 'fr')
|
||||
|
||||
Returns:
|
||||
dict: Dictionary with page information or None if page doesn't exist
|
||||
"""
|
||||
base_url = WIKI_BASE_URL_EN if language == 'en' else WIKI_BASE_URL_FR
|
||||
url = f"{base_url}{key}"
|
||||
|
||||
logger.info(f"Fetching {language} wiki page for key '{key}': {url}")
|
||||
|
||||
try:
|
||||
response = requests.get(url)
|
||||
|
||||
# Check if page exists
|
||||
if response.status_code == 404:
|
||||
logger.warning(f"Wiki page for key '{key}' in {language} does not exist")
|
||||
return None
|
||||
|
||||
response.raise_for_status()
|
||||
|
||||
soup = BeautifulSoup(response.text, 'html.parser')
|
||||
|
||||
# Get last modification date
|
||||
last_modified = None
|
||||
footer_info = soup.select_one('#footer-info-lastmod')
|
||||
if footer_info:
|
||||
date_text = footer_info.text
|
||||
# Extract date using regex
|
||||
date_match = re.search(r'(\d{1,2} \w+ \d{4})', date_text)
|
||||
if date_match:
|
||||
date_str = date_match.group(1)
|
||||
try:
|
||||
# Parse date (format may vary based on wiki language)
|
||||
last_modified = datetime.strptime(date_str, '%d %B %Y').strftime('%Y-%m-%d')
|
||||
except ValueError:
|
||||
logger.warning(f"Could not parse date: {date_str}")
|
||||
|
||||
# Extract sections (h2, h3, h4)
|
||||
section_elements = soup.select('h2, h3, h4')
|
||||
sections = len(section_elements)
|
||||
|
||||
# Extract section titles
|
||||
section_titles = []
|
||||
for section_elem in section_elements:
|
||||
# Skip sections that are part of the table of contents, navigation, or DescriptionBox
|
||||
if section_elem.parent and section_elem.parent.get('id') in ['toc', 'mw-navigation']:
|
||||
continue
|
||||
|
||||
# Skip sections that are inside a table with class DescriptionBox
|
||||
if section_elem.find_parent('table', class_='DescriptionBox'):
|
||||
continue
|
||||
|
||||
# Get the text of the section title, removing any edit links
|
||||
for edit_link in section_elem.select('.mw-editsection'):
|
||||
edit_link.extract()
|
||||
|
||||
section_title = section_elem.get_text(strip=True)
|
||||
section_level = int(section_elem.name[1]) # h2 -> 2, h3 -> 3, h4 -> 4
|
||||
|
||||
section_titles.append({
|
||||
'title': section_title,
|
||||
'level': section_level
|
||||
})
|
||||
|
||||
# Count words in the content
|
||||
content = soup.select_one('#mw-content-text')
|
||||
if content:
|
||||
# Remove script and style elements
|
||||
for script in content.select('script, style'):
|
||||
script.extract()
|
||||
|
||||
# Remove .languages elements
|
||||
for languages_elem in content.select('.languages'):
|
||||
languages_elem.extract()
|
||||
|
||||
# Get text and count words
|
||||
text = content.get_text(separator=' ', strip=True)
|
||||
word_count = len(text.split())
|
||||
|
||||
# Extract links
|
||||
links = content.select('a')
|
||||
link_count = len(links)
|
||||
|
||||
# Get link details (text and href)
|
||||
link_details = []
|
||||
for link in links:
|
||||
href = link.get('href', '')
|
||||
# Skip edit section links and other non-content links
|
||||
if 'action=edit' in href or 'redlink=1' in href or not href:
|
||||
continue
|
||||
|
||||
# Make relative URLs absolute
|
||||
if href.startswith('/'):
|
||||
href = 'https://wiki.openstreetmap.org' + href
|
||||
|
||||
link_text = link.get_text(strip=True)
|
||||
if link_text: # Only include links with text
|
||||
link_details.append({
|
||||
'text': link_text,
|
||||
'href': href
|
||||
})
|
||||
|
||||
# Extract media (images)
|
||||
media_elements = content.select('img')
|
||||
media_count = len(media_elements)
|
||||
|
||||
# Get media details (src and alt text)
|
||||
media_details = []
|
||||
|
||||
# Extract description image specifically
|
||||
# Try multiple selectors to find the description image
|
||||
description_img = None
|
||||
|
||||
# Debug: Log the key we're processing
|
||||
logger.info(f"Looking for description image for key '{key}' in {language}")
|
||||
|
||||
# Function to filter out OSM logo and small icons
|
||||
def is_relevant_image(img):
|
||||
src = img.get('src', '')
|
||||
# Skip OSM logo
|
||||
if 'osm_logo' in src:
|
||||
return False
|
||||
# Skip small icons (usually less than 30px)
|
||||
width = img.get('width')
|
||||
if width and int(width) < 30:
|
||||
return False
|
||||
height = img.get('height')
|
||||
if height and int(height) < 30:
|
||||
return False
|
||||
return True
|
||||
|
||||
# Special case for highway key - directly target the image we want
|
||||
if key == 'highway':
|
||||
# Try to find the specific image in figure elements
|
||||
highway_img_elements = content.select('figure.mw-halign-center img')
|
||||
logger.info(f" Highway specific selector 'figure.mw-halign-center img' found {len(highway_img_elements)} elements")
|
||||
|
||||
# Filter for relevant images
|
||||
relevant_images = [img for img in highway_img_elements if is_relevant_image(img)]
|
||||
logger.info(f" Found {len(relevant_images)} relevant images for highway")
|
||||
|
||||
if relevant_images:
|
||||
description_img = relevant_images[0]
|
||||
logger.info(f" Using highway-specific image: {description_img.get('src', '')}")
|
||||
|
||||
# If not found with highway-specific selector, try the td.d_image selector
|
||||
if not description_img:
|
||||
description_img_elements = content.select('td.d_image img')
|
||||
logger.info(f" Selector 'td.d_image img' found {len(description_img_elements)} elements")
|
||||
|
||||
# Filter for relevant images
|
||||
relevant_images = [img for img in description_img_elements if is_relevant_image(img)]
|
||||
logger.info(f" Found {len(relevant_images)} relevant images in td.d_image")
|
||||
|
||||
if relevant_images:
|
||||
description_img = relevant_images[0]
|
||||
logger.info(f" Using image from 'td.d_image img': {description_img.get('src', '')}")
|
||||
|
||||
# If still not found, try the specific selector for .description img.mw-file-element
|
||||
if not description_img:
|
||||
description_img_elements = content.select('.description img.mw-file-element')
|
||||
logger.info(f" Selector '.description img.mw-file-element' found {len(description_img_elements)} elements")
|
||||
|
||||
# Filter for relevant images
|
||||
relevant_images = [img for img in description_img_elements if is_relevant_image(img)]
|
||||
logger.info(f" Found {len(relevant_images)} relevant images in .description")
|
||||
|
||||
if relevant_images:
|
||||
description_img = relevant_images[0]
|
||||
logger.info(f" Using image from '.description img.mw-file-element': {description_img.get('src', '')}")
|
||||
|
||||
# If still not found, try images in figures within the description box
|
||||
if not description_img:
|
||||
description_img_elements = content.select('.description figure img')
|
||||
logger.info(f" Selector '.description figure img' found {len(description_img_elements)} elements")
|
||||
|
||||
# Filter for relevant images
|
||||
relevant_images = [img for img in description_img_elements if is_relevant_image(img)]
|
||||
logger.info(f" Found {len(relevant_images)} relevant images in .description figure")
|
||||
|
||||
if relevant_images:
|
||||
description_img = relevant_images[0]
|
||||
logger.info(f" Using image from '.description figure img': {description_img.get('src', '')}")
|
||||
|
||||
# If still not found, try any image in the description box
|
||||
if not description_img:
|
||||
description_img_elements = content.select('.description img')
|
||||
logger.info(f" Selector '.description img' found {len(description_img_elements)} elements")
|
||||
|
||||
# Filter for relevant images
|
||||
relevant_images = [img for img in description_img_elements if is_relevant_image(img)]
|
||||
logger.info(f" Found {len(relevant_images)} relevant images in .description general")
|
||||
|
||||
if relevant_images:
|
||||
description_img = relevant_images[0]
|
||||
logger.info(f" Using image from '.description img': {description_img.get('src', '')}")
|
||||
|
||||
# If still not found, try images in the DescriptionBox table
|
||||
if not description_img:
|
||||
description_img_elements = content.select('table.DescriptionBox img')
|
||||
logger.info(f" Selector 'table.DescriptionBox img' found {len(description_img_elements)} elements")
|
||||
|
||||
# Filter for relevant images
|
||||
relevant_images = [img for img in description_img_elements if is_relevant_image(img)]
|
||||
logger.info(f" Found {len(relevant_images)} relevant images in DescriptionBox")
|
||||
|
||||
if relevant_images:
|
||||
description_img = relevant_images[0]
|
||||
logger.info(f" Using image from 'table.DescriptionBox img': {description_img.get('src', '')}")
|
||||
|
||||
# If still not found, try images in figure elements anywhere in the content
|
||||
if not description_img:
|
||||
description_img_elements = content.select('figure img')
|
||||
logger.info(f" Selector 'figure img' found {len(description_img_elements)} elements")
|
||||
|
||||
# Filter for relevant images
|
||||
relevant_images = [img for img in description_img_elements if is_relevant_image(img)]
|
||||
logger.info(f" Found {len(relevant_images)} relevant images in figure elements")
|
||||
|
||||
if relevant_images:
|
||||
description_img = relevant_images[0]
|
||||
logger.info(f" Using image from 'figure img': {description_img.get('src', '')}")
|
||||
|
||||
# If we still don't have an image, use any image that's not the OSM logo
|
||||
if not description_img:
|
||||
all_images = content.select('img')
|
||||
relevant_images = [img for img in all_images if is_relevant_image(img)]
|
||||
logger.info(f" Found {len(relevant_images)} relevant images in the entire page")
|
||||
|
||||
if relevant_images:
|
||||
description_img = relevant_images[0]
|
||||
logger.info(f" Using fallback image: {description_img.get('src', '')}")
|
||||
|
||||
# Process the found image
|
||||
description_img_url = None
|
||||
if description_img:
|
||||
src = description_img.get('src', '')
|
||||
if src:
|
||||
# Make relative URLs absolute
|
||||
if src.startswith('//'):
|
||||
src = 'https:' + src
|
||||
elif src.startswith('/'):
|
||||
src = 'https://wiki.openstreetmap.org' + src
|
||||
|
||||
description_img_url = src
|
||||
|
||||
# Process all images
|
||||
for img in media_elements:
|
||||
src = img.get('src', '')
|
||||
if src:
|
||||
# Make relative URLs absolute
|
||||
if src.startswith('//'):
|
||||
src = 'https:' + src
|
||||
elif src.startswith('/'):
|
||||
src = 'https://wiki.openstreetmap.org' + src
|
||||
|
||||
alt_text = img.get('alt', '')
|
||||
media_details.append({
|
||||
'src': src,
|
||||
'alt': alt_text
|
||||
})
|
||||
|
||||
# Extract categories
|
||||
categories = []
|
||||
category_links = soup.select('#mw-normal-catlinks li a')
|
||||
for cat_link in category_links:
|
||||
categories.append(cat_link.get_text(strip=True))
|
||||
else:
|
||||
word_count = 0
|
||||
link_count = 0
|
||||
link_details = []
|
||||
media_count = 0
|
||||
media_details = []
|
||||
categories = []
|
||||
|
||||
return {
|
||||
'key': key,
|
||||
'language': language,
|
||||
'url': url,
|
||||
'last_modified': last_modified,
|
||||
'sections': sections,
|
||||
'section_titles': section_titles,
|
||||
'word_count': word_count,
|
||||
'link_count': link_count,
|
||||
'link_details': link_details,
|
||||
'media_count': media_count,
|
||||
'media_details': media_details,
|
||||
'categories': categories,
|
||||
'description_img_url': description_img_url
|
||||
}
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Error fetching wiki page for key '{key}' in {language}: {e}")
|
||||
return None
|
||||
|
||||
def generate_staleness_histogram(wiki_pages):
|
||||
"""
|
||||
Generate a histogram of staleness scores by 10% ranges
|
||||
|
||||
Args:
|
||||
wiki_pages (list): List of dictionaries containing page information with staleness scores
|
||||
|
||||
Returns:
|
||||
None: Saves the histogram to a file
|
||||
"""
|
||||
logger.info("Generating histogram of staleness scores by 10% ranges...")
|
||||
|
||||
# Extract staleness scores
|
||||
staleness_scores = []
|
||||
for page in wiki_pages:
|
||||
if page and 'staleness_score' in page:
|
||||
staleness_scores.append(page['staleness_score'])
|
||||
|
||||
if not staleness_scores:
|
||||
logger.warning("No staleness scores found. Cannot generate histogram.")
|
||||
return
|
||||
|
||||
# Determine the maximum score for binning
|
||||
max_score = max(staleness_scores)
|
||||
# Round up to the nearest 10 to ensure all scores are included
|
||||
max_bin_edge = np.ceil(max_score / 10) * 10
|
||||
|
||||
# Create bins for 10% ranges
|
||||
bins = np.arange(0, max_bin_edge + 10, 10)
|
||||
|
||||
# Count scores in each bin
|
||||
hist, bin_edges = np.histogram(staleness_scores, bins=bins)
|
||||
|
||||
# Create histogram
|
||||
plt.figure(figsize=(12, 6))
|
||||
|
||||
# Create bar chart
|
||||
plt.bar(range(len(hist)), hist, align='center')
|
||||
|
||||
# Set x-axis labels for each bin
|
||||
bin_labels = [f"{int(bin_edges[i])}-{int(bin_edges[i+1])}%" for i in range(len(bin_edges)-1)]
|
||||
plt.xticks(range(len(hist)), bin_labels, rotation=45)
|
||||
|
||||
# Set labels and title
|
||||
plt.xlabel('Tranches de score de décrépitude (en %)')
|
||||
plt.ylabel('Nombre de pages')
|
||||
plt.title('Répartition du score de décrépitude par tranches de 10%')
|
||||
|
||||
# Add grid for better readability
|
||||
plt.grid(axis='y', linestyle='--', alpha=0.7)
|
||||
|
||||
# Adjust layout
|
||||
plt.tight_layout()
|
||||
|
||||
# Save figure
|
||||
plt.savefig(STALENESS_HISTOGRAM_FILE)
|
||||
logger.info(f"Histogram saved to {STALENESS_HISTOGRAM_FILE}")
|
||||
|
||||
# Close the figure to free memory
|
||||
plt.close()
|
||||
|
||||
def analyze_wiki_pages(pages):
|
||||
"""
|
||||
Analyze wiki pages to determine which ones need updating
|
||||
|
||||
Args:
|
||||
pages (list): List of dictionaries containing page information
|
||||
|
||||
Returns:
|
||||
list: List of pages that need updating, sorted by priority
|
||||
"""
|
||||
logger.info("Analyzing wiki pages to identify those needing updates...")
|
||||
|
||||
# Group pages by key
|
||||
pages_by_key = {}
|
||||
for page in pages:
|
||||
if page is None:
|
||||
continue
|
||||
|
||||
key = page['key']
|
||||
if key not in pages_by_key:
|
||||
pages_by_key[key] = {}
|
||||
|
||||
pages_by_key[key][page['language']] = page
|
||||
|
||||
# Analyze each key's pages
|
||||
needs_update = []
|
||||
|
||||
for key, lang_pages in pages_by_key.items():
|
||||
# Skip if either language is missing
|
||||
if 'en' not in lang_pages or 'fr' not in lang_pages:
|
||||
if 'en' in lang_pages:
|
||||
# French page is missing
|
||||
# For missing French pages, calculate a high staleness score
|
||||
# Use word count as the main factor (50% weight)
|
||||
missing_staleness_score = (
|
||||
30 * 0.2 + # Assume 30 days outdated (20%)
|
||||
lang_pages['en']['word_count'] / 100 * 0.5 + # Word count (50%)
|
||||
lang_pages['en']['sections'] * 0.15 + # Sections (15%)
|
||||
lang_pages['en']['link_count'] / 10 * 0.15 # Links (15%)
|
||||
)
|
||||
|
||||
# Round to 2 decimal places and ensure it's high
|
||||
missing_staleness_score = max(100, round(missing_staleness_score, 2))
|
||||
|
||||
# Get media count or default to 0
|
||||
media_count = lang_pages['en'].get('media_count', 0)
|
||||
|
||||
needs_update.append({
|
||||
'key': key,
|
||||
'reason': 'French page missing',
|
||||
'en_page': lang_pages['en'],
|
||||
'fr_page': None,
|
||||
'date_diff': 0,
|
||||
'word_diff': lang_pages['en']['word_count'],
|
||||
'section_diff': lang_pages['en']['sections'],
|
||||
'link_diff': lang_pages['en']['link_count'],
|
||||
'media_diff': media_count,
|
||||
'staleness_score': missing_staleness_score,
|
||||
'priority': missing_staleness_score, # Use staleness score as priority
|
||||
'section_comparison': None, # No comparison possible
|
||||
'link_comparison': None, # No comparison possible
|
||||
'media_comparison': None, # No comparison possible
|
||||
'category_comparison': None # No comparison possible
|
||||
})
|
||||
continue
|
||||
|
||||
en_page = lang_pages['en']
|
||||
fr_page = lang_pages['fr']
|
||||
|
||||
# Skip if dates are missing
|
||||
if not en_page['last_modified'] or not fr_page['last_modified']:
|
||||
continue
|
||||
|
||||
# Calculate date difference in days
|
||||
en_date = datetime.strptime(en_page['last_modified'], '%Y-%m-%d')
|
||||
fr_date = datetime.strptime(fr_page['last_modified'], '%Y-%m-%d')
|
||||
date_diff = (en_date - fr_date).days
|
||||
|
||||
# Calculate content differences
|
||||
word_diff = en_page['word_count'] - fr_page['word_count']
|
||||
section_diff = en_page['sections'] - fr_page['sections']
|
||||
link_diff = en_page['link_count'] - fr_page['link_count']
|
||||
media_diff = en_page.get('media_count', 0) - fr_page.get('media_count', 0)
|
||||
|
||||
# Calculate staleness score (higher means more outdated/stale)
|
||||
# Weight factors adjusted to emphasize word count differences
|
||||
staleness_score = (
|
||||
abs(date_diff) * 0.2 + # Date difference (20%)
|
||||
abs(word_diff) / 100 * 0.5 + # Word count difference (normalized) (50%)
|
||||
abs(section_diff) * 0.15 + # Section difference (15%)
|
||||
abs(link_diff) / 10 * 0.15 # Link count difference (normalized) (15%)
|
||||
)
|
||||
|
||||
# Round to 2 decimal places for display
|
||||
staleness_score = round(staleness_score, 2)
|
||||
|
||||
# Compare sections between English and French pages
|
||||
section_comparison = {
|
||||
'en_only': [],
|
||||
'fr_only': [],
|
||||
'common': []
|
||||
}
|
||||
|
||||
# Group sections by their level for hierarchical comparison
|
||||
en_sections_by_level = {}
|
||||
fr_sections_by_level = {}
|
||||
|
||||
# Organize English sections by level
|
||||
for section in en_page.get('section_titles', []):
|
||||
level = section['level']
|
||||
if level not in en_sections_by_level:
|
||||
en_sections_by_level[level] = []
|
||||
en_sections_by_level[level].append(section)
|
||||
|
||||
# Organize French sections by level
|
||||
for section in fr_page.get('section_titles', []):
|
||||
level = section['level']
|
||||
if level not in fr_sections_by_level:
|
||||
fr_sections_by_level[level] = []
|
||||
fr_sections_by_level[level].append(section)
|
||||
|
||||
# Process each level to find matching sections
|
||||
all_levels = set(list(en_sections_by_level.keys()) + list(fr_sections_by_level.keys()))
|
||||
|
||||
for level in all_levels:
|
||||
en_level_sections = en_sections_by_level.get(level, [])
|
||||
fr_level_sections = fr_sections_by_level.get(level, [])
|
||||
|
||||
# Create dictionaries for easier lookup, using lowercase titles
|
||||
en_dict = {section['title'].lower(): section for section in en_level_sections}
|
||||
fr_dict = {section['title'].lower(): section for section in fr_level_sections}
|
||||
|
||||
# Find sections at this level only in English
|
||||
for title, section in en_dict.items():
|
||||
if title not in fr_dict:
|
||||
section_comparison['en_only'].append(section)
|
||||
|
||||
# Find sections at this level only in French
|
||||
for title, section in fr_dict.items():
|
||||
if title not in en_dict:
|
||||
section_comparison['fr_only'].append(section)
|
||||
|
||||
# Find common sections at this level
|
||||
for title in en_dict.keys():
|
||||
if title in fr_dict:
|
||||
section_comparison['common'].append({
|
||||
'en': en_dict[title],
|
||||
'fr': fr_dict[title]
|
||||
})
|
||||
|
||||
# Compare links between English and French pages
|
||||
link_comparison = {
|
||||
'en_only': [],
|
||||
'fr_only': [],
|
||||
'common': []
|
||||
}
|
||||
|
||||
# Extract link texts for comparison (case insensitive)
|
||||
en_links = {link['text'].lower(): link for link in en_page.get('link_details', [])}
|
||||
fr_links = {link['text'].lower(): link for link in fr_page.get('link_details', [])}
|
||||
|
||||
# Find links only in English
|
||||
for text, link in en_links.items():
|
||||
if text not in fr_links:
|
||||
link_comparison['en_only'].append(link)
|
||||
|
||||
# Find links only in French
|
||||
for text, link in fr_links.items():
|
||||
if text not in en_links:
|
||||
link_comparison['fr_only'].append(link)
|
||||
|
||||
# Find common links
|
||||
for text in en_links.keys():
|
||||
if text in fr_links:
|
||||
link_comparison['common'].append({
|
||||
'en': en_links[text],
|
||||
'fr': fr_links[text]
|
||||
})
|
||||
|
||||
# Compare media between English and French pages
|
||||
media_comparison = {
|
||||
'en_only': [],
|
||||
'fr_only': [],
|
||||
'common': []
|
||||
}
|
||||
|
||||
# Extract media alt texts for comparison (case insensitive)
|
||||
en_media = {media['alt'].lower(): media for media in en_page.get('media_details', []) if media['alt']}
|
||||
fr_media = {media['alt'].lower(): media for media in fr_page.get('media_details', []) if media['alt']}
|
||||
|
||||
# Find media only in English
|
||||
for alt, media in en_media.items():
|
||||
if alt not in fr_media:
|
||||
media_comparison['en_only'].append(media)
|
||||
|
||||
# Find media only in French
|
||||
for alt, media in fr_media.items():
|
||||
if alt not in en_media:
|
||||
media_comparison['fr_only'].append(media)
|
||||
|
||||
# Find common media
|
||||
for alt in en_media.keys():
|
||||
if alt in fr_media:
|
||||
media_comparison['common'].append({
|
||||
'en': en_media[alt],
|
||||
'fr': fr_media[alt]
|
||||
})
|
||||
|
||||
# Add media without alt text to their respective language-only lists
|
||||
for media in en_page.get('media_details', []):
|
||||
if not media['alt'] or media['alt'].lower() not in en_media:
|
||||
media_comparison['en_only'].append(media)
|
||||
|
||||
for media in fr_page.get('media_details', []):
|
||||
if not media['alt'] or media['alt'].lower() not in fr_media:
|
||||
media_comparison['fr_only'].append(media)
|
||||
|
||||
# Compare categories between English and French pages
|
||||
category_comparison = {
|
||||
'en_only': [],
|
||||
'fr_only': [],
|
||||
'common': []
|
||||
}
|
||||
|
||||
# Extract categories for comparison (case insensitive)
|
||||
en_categories = [cat.lower() for cat in en_page.get('categories', [])]
|
||||
fr_categories = [cat.lower() for cat in fr_page.get('categories', [])]
|
||||
|
||||
# Find categories only in English
|
||||
for cat in en_page.get('categories', []):
|
||||
if cat.lower() not in fr_categories:
|
||||
category_comparison['en_only'].append(cat)
|
||||
|
||||
# Find categories only in French
|
||||
for cat in fr_page.get('categories', []):
|
||||
if cat.lower() not in en_categories:
|
||||
category_comparison['fr_only'].append(cat)
|
||||
|
||||
# Find common categories
|
||||
for cat in en_page.get('categories', []):
|
||||
if cat.lower() in fr_categories:
|
||||
category_comparison['common'].append(cat)
|
||||
|
||||
if date_diff > 30 or word_diff > 200 or section_diff > 2 or link_diff > 20 or fr_page['word_count'] < en_page['word_count'] * 0.7:
|
||||
reason = []
|
||||
if date_diff > 30:
|
||||
reason.append(f"La version Française est datée de {date_diff} jours")
|
||||
if word_diff > 200:
|
||||
reason.append(f"La version Anglaise a {word_diff} plus de mots")
|
||||
if section_diff > 2:
|
||||
reason.append(f"La version Anglaise a {section_diff} plus de sections")
|
||||
if link_diff > 20:
|
||||
reason.append(f"La version Anglaise a {link_diff} plus de liens")
|
||||
if media_diff > 5:
|
||||
reason.append(f"La version Anglaise a {media_diff} plus d'images")
|
||||
if fr_page['word_count'] < en_page['word_count'] * 0.7:
|
||||
reason.append(f"La version Française a seulement {fr_page['word_count'] / en_page['word_count']:.0%} % du contenu en Anglais.")
|
||||
|
||||
needs_update.append({
|
||||
'key': key,
|
||||
'reason': ', '.join(reason),
|
||||
'en_page': en_page,
|
||||
'fr_page': fr_page,
|
||||
'date_diff': date_diff,
|
||||
'word_diff': word_diff,
|
||||
'section_diff': section_diff,
|
||||
'link_diff': link_diff,
|
||||
'media_diff': media_diff,
|
||||
'staleness_score': staleness_score,
|
||||
'priority': staleness_score, # Use staleness score as priority
|
||||
'section_comparison': section_comparison,
|
||||
'link_comparison': link_comparison,
|
||||
'media_comparison': media_comparison,
|
||||
'category_comparison': category_comparison
|
||||
})
|
||||
|
||||
# Sort by priority (descending)
|
||||
needs_update.sort(key=lambda x: x['priority'], reverse=True)
|
||||
|
||||
return needs_update
|
||||
|
||||
def main():
|
||||
"""Main function to execute the script"""
|
||||
logger.info("Starting wiki_compare.py")
|
||||
|
||||
# Create output directory if it doesn't exist
|
||||
os.makedirs(os.path.dirname(os.path.abspath(__file__)), exist_ok=True)
|
||||
|
||||
# Fetch top keys
|
||||
top_keys = fetch_top_keys(NUM_WIKI_PAGES)
|
||||
|
||||
if not top_keys:
|
||||
logger.error("Failed to fetch top keys. Exiting.")
|
||||
return
|
||||
|
||||
# Save top keys to JSON
|
||||
save_to_json(top_keys, TOP_KEYS_FILE)
|
||||
|
||||
# Fetch wiki pages for each key
|
||||
wiki_pages = []
|
||||
|
||||
for key_info in top_keys:
|
||||
key = key_info['key']
|
||||
|
||||
# Fetch English page
|
||||
en_page = fetch_wiki_page(key, 'en')
|
||||
if en_page:
|
||||
wiki_pages.append(en_page)
|
||||
|
||||
# Fetch French page
|
||||
fr_page = fetch_wiki_page(key, 'fr')
|
||||
if fr_page:
|
||||
wiki_pages.append(fr_page)
|
||||
|
||||
# Process wiki pages to add staleness score
|
||||
processed_wiki_pages = []
|
||||
pages_by_key = {}
|
||||
|
||||
# Group pages by key
|
||||
for page in wiki_pages:
|
||||
if page is None:
|
||||
continue
|
||||
|
||||
key = page['key']
|
||||
if key not in pages_by_key:
|
||||
pages_by_key[key] = {}
|
||||
|
||||
pages_by_key[key][page['language']] = page
|
||||
|
||||
# Calculate staleness score for each pair of pages
|
||||
for key, lang_pages in pages_by_key.items():
|
||||
# Add English page with staleness score
|
||||
if 'en' in lang_pages:
|
||||
en_page = lang_pages['en'].copy()
|
||||
|
||||
# If French page exists, calculate staleness score
|
||||
if 'fr' in lang_pages:
|
||||
fr_page = lang_pages['fr']
|
||||
|
||||
# Skip if dates are missing
|
||||
if en_page['last_modified'] and fr_page['last_modified']:
|
||||
# Calculate date difference in days
|
||||
en_date = datetime.strptime(en_page['last_modified'], '%Y-%m-%d')
|
||||
fr_date = datetime.strptime(fr_page['last_modified'], '%Y-%m-%d')
|
||||
date_diff = (en_date - fr_date).days
|
||||
|
||||
# Calculate content differences
|
||||
word_diff = en_page['word_count'] - fr_page['word_count']
|
||||
section_diff = en_page['sections'] - fr_page['sections']
|
||||
link_diff = en_page['link_count'] - fr_page['link_count']
|
||||
|
||||
# Calculate staleness score
|
||||
staleness_score = (
|
||||
abs(date_diff) * 0.2 +
|
||||
abs(word_diff) / 100 * 0.5 +
|
||||
abs(section_diff) * 0.15 +
|
||||
abs(link_diff) / 10 * 0.15
|
||||
)
|
||||
|
||||
# Round to 2 decimal places
|
||||
staleness_score = round(staleness_score, 2)
|
||||
|
||||
en_page['staleness_score'] = staleness_score
|
||||
fr_page['staleness_score'] = staleness_score
|
||||
else:
|
||||
en_page['staleness_score'] = 0
|
||||
fr_page['staleness_score'] = 0
|
||||
|
||||
processed_wiki_pages.append(en_page)
|
||||
processed_wiki_pages.append(fr_page)
|
||||
else:
|
||||
# French page is missing, calculate a high staleness score
|
||||
missing_staleness_score = (
|
||||
30 * 0.2 +
|
||||
en_page['word_count'] / 100 * 0.5 +
|
||||
en_page['sections'] * 0.15 +
|
||||
en_page['link_count'] / 10 * 0.15
|
||||
)
|
||||
|
||||
# Round to 2 decimal places and ensure it's high
|
||||
missing_staleness_score = max(100, round(missing_staleness_score, 2))
|
||||
|
||||
en_page['staleness_score'] = missing_staleness_score
|
||||
processed_wiki_pages.append(en_page)
|
||||
|
||||
# Add French page without English counterpart (rare case)
|
||||
elif 'fr' in lang_pages:
|
||||
fr_page = lang_pages['fr'].copy()
|
||||
fr_page['staleness_score'] = 0
|
||||
processed_wiki_pages.append(fr_page)
|
||||
|
||||
# Generate histogram of staleness scores
|
||||
generate_staleness_histogram(processed_wiki_pages)
|
||||
|
||||
# Save processed wiki pages to CSV
|
||||
try:
|
||||
with open(WIKI_PAGES_CSV, 'w', newline='', encoding='utf-8') as f:
|
||||
# Basic fields for CSV (detailed content will be in JSON only)
|
||||
fieldnames = ['key', 'language', 'url', 'last_modified', 'sections', 'word_count', 'link_count', 'media_count', 'staleness_score', 'description_img_url']
|
||||
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
||||
|
||||
writer.writeheader()
|
||||
for page in processed_wiki_pages:
|
||||
if page: # Skip None values
|
||||
# Create a copy with only the CSV fields
|
||||
csv_page = {field: page.get(field, '') for field in fieldnames if field in page}
|
||||
writer.writerow(csv_page)
|
||||
|
||||
logger.info(f"Wiki page data saved to {WIKI_PAGES_CSV}")
|
||||
|
||||
except IOError as e:
|
||||
logger.error(f"Error saving data to {WIKI_PAGES_CSV}: {e}")
|
||||
return
|
||||
|
||||
# Analyze pages to find those needing updates
|
||||
pages_to_update = analyze_wiki_pages(wiki_pages)
|
||||
|
||||
# Save pages that need updating to JSON
|
||||
save_to_json(pages_to_update, OUTDATED_PAGES_FILE)
|
||||
|
||||
# Print the top pages needing updates
|
||||
print(f"\n===== TOP {min(NUM_WIKI_PAGES, len(pages_to_update))} WIKI PAGES NEEDING UPDATES =====")
|
||||
|
||||
for i, page in enumerate(pages_to_update[:NUM_WIKI_PAGES], 1):
|
||||
key = page['key']
|
||||
reason = page['reason']
|
||||
en_url = page['en_page']['url'] if page['en_page'] else "N/A"
|
||||
fr_url = page['fr_page']['url'] if page['fr_page'] else "N/A"
|
||||
|
||||
print(f"{i}. Key: {key}")
|
||||
print(f" Reason: {reason}")
|
||||
print(f" English: {en_url}")
|
||||
print(f" French: {fr_url}")
|
||||
print()
|
||||
|
||||
logger.info("Script completed successfully")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -38,3 +38,137 @@ source:date,fr,https://wiki.openstreetmap.org/wiki/FR:Key:source:date,2023-07-21
|
|||
service,en,https://wiki.openstreetmap.org/wiki/Key:service,2025-03-16,22,1436,218,17,83.79,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
service,fr,https://wiki.openstreetmap.org/wiki/FR:Key:service,2024-03-04,11,443,100,10,83.79,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
addr:state,en,https://wiki.openstreetmap.org/wiki/Key:addr:state,2023-06-23,12,289,74,11,100,https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/WVaCent.jpg/200px-WVaCent.jpg
|
||||
access,en,https://wiki.openstreetmap.org/wiki/Key:access,2025-08-06,31,5803,708,98,66.75,https://wiki.openstreetmap.org/w/images/5/5e/WhichAccess.png
|
||||
access,fr,https://wiki.openstreetmap.org/wiki/FR:Key:access,2024-11-27,33,3200,506,83,66.75,https://wiki.openstreetmap.org/w/images/5/5e/WhichAccess.png
|
||||
oneway,en,https://wiki.openstreetmap.org/wiki/Key:oneway,2025-07-17,28,2318,290,30,19.4,https://upload.wikimedia.org/wikipedia/commons/thumb/1/13/One_way_sign.JPG/200px-One_way_sign.JPG
|
||||
oneway,fr,https://wiki.openstreetmap.org/wiki/FR:Key:oneway,2025-06-16,14,645,108,14,19.4,https://upload.wikimedia.org/wikipedia/commons/thumb/f/f4/France_road_sign_C12.svg/200px-France_road_sign_C12.svg.png
|
||||
height,en,https://wiki.openstreetmap.org/wiki/Key:height,2025-07-21,24,1184,184,20,8.45,https://upload.wikimedia.org/wikipedia/commons/thumb/8/88/Height_demonstration_diagram.png/200px-Height_demonstration_diagram.png
|
||||
height,fr,https://wiki.openstreetmap.org/wiki/FR:Key:height,2025-06-14,21,1285,190,21,8.45,https://upload.wikimedia.org/wikipedia/commons/thumb/8/88/Height_demonstration_diagram.png/200px-Height_demonstration_diagram.png
|
||||
ref,en,https://wiki.openstreetmap.org/wiki/Key:ref,2025-07-25,26,4404,782,115,11.79,https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/UK_traffic_sign_2901.svg/200px-UK_traffic_sign_2901.svg.png
|
||||
ref,fr,https://wiki.openstreetmap.org/wiki/FR:Key:ref,2025-07-30,20,3393,460,12,11.79,https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Autoroute_fran%C3%A7aise_1.svg/200px-Autoroute_fran%C3%A7aise_1.svg.png
|
||||
maxspeed,en,https://wiki.openstreetmap.org/wiki/Key:maxspeed,2025-08-20,30,4275,404,38,39.24,https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Zeichen_274-60_-_Zul%C3%A4ssige_H%C3%B6chstgeschwindigkeit%2C_StVO_2017.svg/200px-Zeichen_274-60_-_Zul%C3%A4ssige_H%C3%B6chstgeschwindigkeit%2C_StVO_2017.svg.png
|
||||
maxspeed,fr,https://wiki.openstreetmap.org/wiki/FR:Key:maxspeed,2025-05-10,25,1401,156,23,39.24,https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Zeichen_274-60_-_Zul%C3%A4ssige_H%C3%B6chstgeschwindigkeit%2C_StVO_2017.svg/200px-Zeichen_274-60_-_Zul%C3%A4ssige_H%C3%B6chstgeschwindigkeit%2C_StVO_2017.svg.png
|
||||
lanes,en,https://wiki.openstreetmap.org/wiki/Key:lanes,2025-08-21,26,2869,355,48,117.16,https://upload.wikimedia.org/wikipedia/commons/thumb/f/f4/A55_trunk_road_looking_east_-_geograph.org.uk_-_932668.jpg/200px-A55_trunk_road_looking_east_-_geograph.org.uk_-_932668.jpg
|
||||
lanes,fr,https://wiki.openstreetmap.org/wiki/FR:Key:lanes,2024-03-07,19,1492,167,19,117.16,https://wiki.openstreetmap.org/w/images/thumb/d/d4/Dscf0444_600.jpg/200px-Dscf0444_600.jpg
|
||||
start_date,en,https://wiki.openstreetmap.org/wiki/Key:start_date,2025-08-01,22,1098,168,29,214.58,https://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Connel_bridge_plate.jpg/200px-Connel_bridge_plate.jpg
|
||||
start_date,fr,https://wiki.openstreetmap.org/wiki/FR:Key:start_date,2022-08-29,19,1097,133,22,214.58,https://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Connel_bridge_plate.jpg/200px-Connel_bridge_plate.jpg
|
||||
addr:district,en,https://wiki.openstreetmap.org/wiki/Key:addr:district,2023-11-06,11,244,76,11,139.96,https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/Hangal_Taluk.jpg/200px-Hangal_Taluk.jpg
|
||||
addr:district,fr,https://wiki.openstreetmap.org/wiki/FR:Key:addr:district,2025-08-23,15,1653,150,77,139.96,https://wiki.openstreetmap.org/w/images/thumb/e/e9/Housenumber-karlsruhe-de.png/200px-Housenumber-karlsruhe-de.png
|
||||
layer,en,https://wiki.openstreetmap.org/wiki/Key:layer,2025-01-02,16,1967,181,17,65.95,https://wiki.openstreetmap.org/w/images/thumb/2/26/Washington_layers.png/200px-Washington_layers.png
|
||||
layer,fr,https://wiki.openstreetmap.org/wiki/FR:Key:layer,2024-02-16,15,2231,162,17,65.95,https://wiki.openstreetmap.org/w/images/thumb/2/26/Washington_layers.png/200px-Washington_layers.png
|
||||
type,en,https://wiki.openstreetmap.org/wiki/Key:type,2025-05-13,20,911,200,72,334.06,https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png
|
||||
type,fr,https://wiki.openstreetmap.org/wiki/FR:Key:type,2020-11-13,10,444,78,10,334.06,https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png
|
||||
operator,en,https://wiki.openstreetmap.org/wiki/Key:operator,2025-08-26,24,1908,241,37,223.28,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
operator,fr,https://wiki.openstreetmap.org/wiki/FR:Key:operator,2022-09-30,15,418,89,11,223.28,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
lit,en,https://wiki.openstreetmap.org/wiki/Key:lit,2024-07-20,17,931,174,52,38.88,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Peatonal_Bicentenario.JPG/200px-Peatonal_Bicentenario.JPG
|
||||
lit,fr,https://wiki.openstreetmap.org/wiki/FR:Key:lit,2025-01-19,17,628,123,14,38.88,https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/2014_K%C5%82odzko%2C_ul._Grottgera_14.JPG/200px-2014_K%C5%82odzko%2C_ul._Grottgera_14.JPG
|
||||
wall,en,https://wiki.openstreetmap.org/wiki/Key:wall,2024-05-02,14,715,206,55,100,https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png
|
||||
tiger:cfcc,en,https://wiki.openstreetmap.org/wiki/Key:tiger:cfcc,2022-12-09,10,127,24,7,100,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
crossing,en,https://wiki.openstreetmap.org/wiki/Key:crossing,2024-02-18,25,2678,363,34,76.98,https://wiki.openstreetmap.org/w/images/thumb/7/75/Toucan.jpg/200px-Toucan.jpg
|
||||
crossing,fr,https://wiki.openstreetmap.org/wiki/FR:Key:crossing,2025-01-20,15,1390,254,28,76.98,https://wiki.openstreetmap.org/w/images/thumb/7/75/Toucan.jpg/200px-Toucan.jpg
|
||||
tiger:county,en,https://wiki.openstreetmap.org/wiki/Key:tiger:county,2022-12-09,10,127,24,7,100,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
source:addr,en,https://wiki.openstreetmap.org/wiki/Key:source:addr,2023-07-05,9,200,70,10,100,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
footway,en,https://wiki.openstreetmap.org/wiki/Key:footway,2025-08-20,23,2002,369,39,99.66,https://wiki.openstreetmap.org/w/images/thumb/b/b9/Sidewalk_and_zebra-crossing.jpg/200px-Sidewalk_and_zebra-crossing.jpg
|
||||
footway,fr,https://wiki.openstreetmap.org/wiki/FR:Key:footway,2024-06-04,14,685,147,28,99.66,https://wiki.openstreetmap.org/w/images/thumb/b/b9/Sidewalk_and_zebra-crossing.jpg/200px-Sidewalk_and_zebra-crossing.jpg
|
||||
ref:bag,en,https://wiki.openstreetmap.org/wiki/Key:ref:bag,2024-10-09,10,254,69,11,100,https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png
|
||||
addr:place,en,https://wiki.openstreetmap.org/wiki/Key:addr:place,2025-03-28,16,1204,154,13,136.57,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Suburb_of_Phillip.jpg/200px-Suburb_of_Phillip.jpg
|
||||
addr:place,fr,https://wiki.openstreetmap.org/wiki/FR:Key:addr:place,2023-06-17,11,276,75,12,136.57,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Suburb_of_Phillip.jpg/200px-Suburb_of_Phillip.jpg
|
||||
tiger:reviewed,en,https://wiki.openstreetmap.org/wiki/Key:tiger:reviewed,2025-08-01,16,734,105,11,100,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/US-Census-TIGERLogo.svg/200px-US-Census-TIGERLogo.svg.png
|
||||
leisure,en,https://wiki.openstreetmap.org/wiki/Key:leisure,2025-02-28,12,1084,374,180,232.43,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Hammock_-_Polynesia.jpg/200px-Hammock_-_Polynesia.jpg
|
||||
leisure,fr,https://wiki.openstreetmap.org/wiki/FR:Key:leisure,2021-12-29,11,951,360,186,232.43,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Hammock_-_Polynesia.jpg/200px-Hammock_-_Polynesia.jpg
|
||||
addr:suburb,en,https://wiki.openstreetmap.org/wiki/Key:addr:suburb,2024-02-24,14,439,89,11,1.49,https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Grosvenor_Place_2_2008_06_19.jpg/200px-Grosvenor_Place_2_2008_06_19.jpg
|
||||
addr:suburb,fr,https://wiki.openstreetmap.org/wiki/FR:Key:addr:suburb,2024-02-18,13,418,87,11,1.49,https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Grosvenor_Place_2_2008_06_19.jpg/200px-Grosvenor_Place_2_2008_06_19.jpg
|
||||
ele,en,https://wiki.openstreetmap.org/wiki/Key:ele,2025-07-18,18,1846,165,24,104.45,https://wiki.openstreetmap.org/w/images/a/a3/Key-ele_mapnik.png
|
||||
ele,fr,https://wiki.openstreetmap.org/wiki/FR:Key:ele,2024-03-02,15,1277,128,13,104.45,https://wiki.openstreetmap.org/w/images/a/a3/Key-ele_mapnik.png
|
||||
tracktype,en,https://wiki.openstreetmap.org/wiki/Key:tracktype,2024-12-02,16,652,146,35,32.71,https://wiki.openstreetmap.org/w/images/thumb/1/13/Tracktype-collage.jpg/200px-Tracktype-collage.jpg
|
||||
tracktype,fr,https://wiki.openstreetmap.org/wiki/FR:Key:tracktype,2025-05-03,11,463,105,29,32.71,https://wiki.openstreetmap.org/w/images/thumb/1/13/Tracktype-collage.jpg/200px-Tracktype-collage.jpg
|
||||
addr:neighbourhood,en,https://wiki.openstreetmap.org/wiki/Key:addr:neighbourhood,2025-04-29,24,2020,235,83,100,https://wiki.openstreetmap.org/w/images/thumb/e/e9/Housenumber-karlsruhe-de.png/200px-Housenumber-karlsruhe-de.png
|
||||
addr:hamlet,en,https://wiki.openstreetmap.org/wiki/Key:addr:hamlet,2024-12-05,9,142,64,11,100,https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Grosvenor_Place_2_2008_06_19.jpg/200px-Grosvenor_Place_2_2008_06_19.jpg
|
||||
addr:province,en,https://wiki.openstreetmap.org/wiki/Key:addr:province,2022-05-04,9,156,64,11,100,https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Stamp_of_Indonesia_-_2002_-_Colnect_265917_-_Aceh_Province.jpeg/200px-Stamp_of_Indonesia_-_2002_-_Colnect_265917_-_Aceh_Province.jpeg
|
||||
leaf_type,en,https://wiki.openstreetmap.org/wiki/Key:leaf_type,2025-01-22,15,739,201,57,114.46,https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/Picea_abies_Nadelkissen.jpg/200px-Picea_abies_Nadelkissen.jpg
|
||||
leaf_type,fr,https://wiki.openstreetmap.org/wiki/FR:Key:leaf_type,2023-07-02,14,734,220,64,114.46,https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/Picea_abies_Nadelkissen.jpg/200px-Picea_abies_Nadelkissen.jpg
|
||||
addr:full,en,https://wiki.openstreetmap.org/wiki/Key:addr:full,2025-04-29,24,2020,235,83,100,https://wiki.openstreetmap.org/w/images/thumb/e/e9/Housenumber-karlsruhe-de.png/200px-Housenumber-karlsruhe-de.png
|
||||
addr:TW:dataset,en,https://wiki.openstreetmap.org/wiki/Key:addr:TW:dataset,2023-06-23,9,128,63,9,100,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
place,en,https://wiki.openstreetmap.org/wiki/Key:place,2025-02-28,23,1342,150,12,128.24,https://wiki.openstreetmap.org/w/images/thumb/c/c4/Bremen.png/200px-Bremen.png
|
||||
place,fr,https://wiki.openstreetmap.org/wiki/FR:Key:place,2023-06-29,18,1650,413,201,128.24,https://wiki.openstreetmap.org/w/images/thumb/c/c4/Bremen.png/200px-Bremen.png
|
||||
man_made,en,https://wiki.openstreetmap.org/wiki/Key:man_made,2025-02-28,14,1789,631,323,16.11,https://upload.wikimedia.org/wikipedia/commons/thumb/d/de/Natural_Gas_Pipeline_Across_The_New_River_-_panoramio.jpg/200px-Natural_Gas_Pipeline_Across_The_New_River_-_panoramio.jpg
|
||||
man_made,fr,https://wiki.openstreetmap.org/wiki/FR:Key:man_made,2025-05-13,10,1873,612,322,16.11,https://upload.wikimedia.org/wikipedia/commons/thumb/d/de/Natural_Gas_Pipeline_Across_The_New_River_-_panoramio.jpg/200px-Natural_Gas_Pipeline_Across_The_New_River_-_panoramio.jpg
|
||||
bicycle,en,https://wiki.openstreetmap.org/wiki/Key:bicycle,2025-08-30,14,903,247,36,338.06,https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Sinnbild_Radfahrer%2C_StVO_1992.svg/200px-Sinnbild_Radfahrer%2C_StVO_1992.svg.png
|
||||
bicycle,fr,https://wiki.openstreetmap.org/wiki/FR:Key:bicycle,2021-02-17,9,172,70,11,338.06,https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Sinnbild_Radfahrer%2C_StVO_1992.svg/200px-Sinnbild_Radfahrer%2C_StVO_1992.svg.png
|
||||
roof:shape,en,https://wiki.openstreetmap.org/wiki/Key:roof:shape,2025-08-20,24,1554,260,44,2.0,https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/Marienkapelle_und_Wohnhaus_%28Schafhauserm%C3%BChle%29.jpg/200px-Marienkapelle_und_Wohnhaus_%28Schafhauserm%C3%BChle%29.jpg
|
||||
roof:shape,fr,https://wiki.openstreetmap.org/wiki/FR:Key:roof:shape,2025-08-20,18,1685,230,43,2.0,https://wiki.openstreetmap.org/w/images/thumb/2/2f/Roof4_0.jpg/200px-Roof4_0.jpg
|
||||
tiger:name_base,en,https://wiki.openstreetmap.org/wiki/Key:tiger:name_base,2021-12-03,26,3319,53,1,100,https://wiki.openstreetmap.org/w/images/c/c9/Logo.png
|
||||
foot,en,https://wiki.openstreetmap.org/wiki/Key:foot,2025-05-11,12,305,93,16,88.8,https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Sinnbild_Fu%C3%9Fg%C3%A4nger.svg/200px-Sinnbild_Fu%C3%9Fg%C3%A4nger.svg.png
|
||||
foot,fr,https://wiki.openstreetmap.org/wiki/FR:Key:foot,2024-03-02,8,143,67,11,88.8,https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Sinnbild_Fu%C3%9Fg%C3%A4nger.svg/200px-Sinnbild_Fu%C3%9Fg%C3%A4nger.svg.png
|
||||
railway,en,https://wiki.openstreetmap.org/wiki/Key:railway,2025-02-28,16,1481,331,154,72.73,https://wiki.openstreetmap.org/w/images/thumb/8/80/Mapping-Features-Railroad-With-Station.png/200px-Mapping-Features-Railroad-With-Station.png
|
||||
railway,fr,https://wiki.openstreetmap.org/wiki/FR:Key:railway,2024-03-08,15,1308,310,156,72.73,https://wiki.openstreetmap.org/w/images/thumb/8/80/Mapping-Features-Railroad-With-Station.png/200px-Mapping-Features-Railroad-With-Station.png
|
||||
source:geometry:date,en,https://wiki.openstreetmap.org/wiki/Key:source:geometry:date,2024-04-07,10,389,88,10,100,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
crossing:markings,en,https://wiki.openstreetmap.org/wiki/Key:crossing:markings,2025-06-21,22,1471,301,64,43.84,https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/Crosswalk_Styles_OpenStreetMap_%28en%29.svg/200px-Crosswalk_Styles_OpenStreetMap_%28en%29.svg.png
|
||||
crossing:markings,fr,https://wiki.openstreetmap.org/wiki/FR:Key:crossing:markings,2024-12-08,16,964,207,46,43.84,https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/Crosswalk_Styles_OpenStreetMap_%28en%29.svg/200px-Crosswalk_Styles_OpenStreetMap_%28en%29.svg.png
|
||||
tiger:name_type,en,https://wiki.openstreetmap.org/wiki/Key:tiger:name_type,2021-12-03,26,3319,53,1,100,https://wiki.openstreetmap.org/w/images/c/c9/Logo.png
|
||||
bridge,en,https://wiki.openstreetmap.org/wiki/Key:bridge,2025-03-16,30,3123,342,68,86.93,https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/2014_Karwina%2C_Dark%C3%B3w%2C_Most_%C5%BCelbetowy_01.jpg/200px-2014_Karwina%2C_Dark%C3%B3w%2C_Most_%C5%BCelbetowy_01.jpg
|
||||
bridge,fr,https://wiki.openstreetmap.org/wiki/FR:Key:bridge,2024-03-07,19,1366,229,56,86.93,https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/2014_Karwina%2C_Dark%C3%B3w%2C_Most_%C5%BCelbetowy_01.jpg/200px-2014_Karwina%2C_Dark%C3%B3w%2C_Most_%C5%BCelbetowy_01.jpg
|
||||
name:en,en,https://wiki.openstreetmap.org/wiki/Key:name:en,2025-03-15,12,325,100,16,100,https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Polish_Embassy_in_Hungary._Plate._Bajza_Street_side._-_Budapest.JPG/200px-Polish_Embassy_in_Hungary._Plate._Bajza_Street_side._-_Budapest.JPG
|
||||
intermittent,en,https://wiki.openstreetmap.org/wiki/Key:intermittent,2025-05-07,17,913,168,27,90.94,https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Oybach.JPG/200px-Oybach.JPG
|
||||
intermittent,fr,https://wiki.openstreetmap.org/wiki/FR:Key:intermittent,2024-02-18,16,644,125,18,90.94,https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Oybach.JPG/200px-Oybach.JPG
|
||||
shop,en,https://wiki.openstreetmap.org/wiki/Key:shop,2025-03-22,31,3638,816,392,124.2,https://wiki.openstreetmap.org/w/images/thumb/d/dc/North_london_shops.jpg/200px-North_london_shops.jpg
|
||||
shop,fr,https://wiki.openstreetmap.org/wiki/FR:Key:shop,2023-07-25,33,3285,754,382,124.2,https://wiki.openstreetmap.org/w/images/thumb/2/26/Geograph_shop.jpg/200px-Geograph_shop.jpg
|
||||
source:geometry,en,https://wiki.openstreetmap.org/wiki/Key:source:geometry,2024-04-07,10,389,88,10,100,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
public_transport,en,https://wiki.openstreetmap.org/wiki/Key:public_transport,2025-02-28,16,383,105,20,28.5,https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Citadis402Grenoble_citeinternationale.jpg/200px-Citadis402Grenoble_citeinternationale.jpg
|
||||
public_transport,fr,https://wiki.openstreetmap.org/wiki/FR:Key:public_transport,2025-03-22,24,3688,530,103,28.5,https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Citadis402Grenoble_citeinternationale.jpg/200px-Citadis402Grenoble_citeinternationale.jpg
|
||||
smoothness,en,https://wiki.openstreetmap.org/wiki/Key:smoothness,2025-08-05,16,1581,167,38,85.94,https://wiki.openstreetmap.org/w/images/thumb/6/69/Jena_Track_roots.jpg/200px-Jena_Track_roots.jpg
|
||||
smoothness,fr,https://wiki.openstreetmap.org/wiki/FR:Key:smoothness,2024-06-11,15,1260,155,39,85.94,https://wiki.openstreetmap.org/w/images/thumb/6/69/Jena_Track_roots.jpg/200px-Jena_Track_roots.jpg
|
||||
leaf_cycle,en,https://wiki.openstreetmap.org/wiki/Key:leaf_cycle,2024-09-28,14,499,144,21,10.48,https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Olga_Wisinger-Florian_-_Falling_Leaves.JPG/200px-Olga_Wisinger-Florian_-_Falling_Leaves.JPG
|
||||
leaf_cycle,fr,https://wiki.openstreetmap.org/wiki/FR:Key:leaf_cycle,2024-11-14,13,619,166,29,10.48,https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Olga_Wisinger-Florian_-_Falling_Leaves.JPG/200px-Olga_Wisinger-Florian_-_Falling_Leaves.JPG
|
||||
tunnel,en,https://wiki.openstreetmap.org/wiki/Key:tunnel,2025-06-16,15,1057,149,19,29.57,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Boston_Tunnel_Entrance.jpg/200px-Boston_Tunnel_Entrance.jpg
|
||||
tunnel,fr,https://wiki.openstreetmap.org/wiki/FR:Key:tunnel,2025-01-24,16,921,140,16,29.57,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Boston_Tunnel_Entrance.jpg/200px-Boston_Tunnel_Entrance.jpg
|
||||
generator:source,en,https://wiki.openstreetmap.org/wiki/Key:generator:source,2025-04-21,11,533,123,29,0.24,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Schematic_representation_different_types_of_energy.jpg/200px-Schematic_representation_different_types_of_energy.jpg
|
||||
generator:source,fr,https://wiki.openstreetmap.org/wiki/FR:Key:generator:source,2025-04-21,11,534,139,29,0.24,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Schematic_representation_different_types_of_energy.jpg/200px-Schematic_representation_different_types_of_energy.jpg
|
||||
generator:method,en,https://wiki.openstreetmap.org/wiki/Key:generator:method,2023-11-26,11,482,151,39,33.48,https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Huntly_Power_Station.JPG/200px-Huntly_Power_Station.JPG
|
||||
generator:method,fr,https://wiki.openstreetmap.org/wiki/FR:Key:generator:method,2023-06-19,9,396,101,13,33.48,https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Huntly_Power_Station.JPG/200px-Huntly_Power_Station.JPG
|
||||
material,en,https://wiki.openstreetmap.org/wiki/Key:material,2025-05-01,12,883,332,114,132.61,https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Stapel_bakstenen_-_Pile_of_bricks_2005_Fruggo.jpg/200px-Stapel_bakstenen_-_Pile_of_bricks_2005_Fruggo.jpg
|
||||
material,fr,https://wiki.openstreetmap.org/wiki/FR:Key:material,2023-07-20,9,647,280,115,132.61,https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Stapel_bakstenen_-_Pile_of_bricks_2005_Fruggo.jpg/200px-Stapel_bakstenen_-_Pile_of_bricks_2005_Fruggo.jpg
|
||||
generator:type,en,https://wiki.openstreetmap.org/wiki/Key:generator:type,2023-11-21,10,1338,330,29,100,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
tactile_paving,en,https://wiki.openstreetmap.org/wiki/Key:tactile_paving,2025-08-10,22,2054,298,44,156.14,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/Tactile_paving.jpg/200px-Tactile_paving.jpg
|
||||
tactile_paving,fr,https://wiki.openstreetmap.org/wiki/FR:Key:tactile_paving,2023-07-23,19,1277,164,47,156.14,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Detectable_Warnings.jpg/200px-Detectable_Warnings.jpg
|
||||
water,en,https://wiki.openstreetmap.org/wiki/Key:water,2024-10-13,16,1261,261,38,15.41,https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/Nowitna_river.jpg/200px-Nowitna_river.jpg
|
||||
water,fr,https://wiki.openstreetmap.org/wiki/FR:Key:water,2024-12-18,17,1516,313,61,15.41,https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/Nowitna_river.jpg/200px-Nowitna_river.jpg
|
||||
generator:output:electricity,en,https://wiki.openstreetmap.org/wiki/Key:generator:output:electricity,2024-01-01,10,296,40,9,124.37,https://upload.wikimedia.org/wikipedia/commons/thumb/d/d7/Eoliennes_Gaspesie.jpg/200px-Eoliennes_Gaspesie.jpg
|
||||
generator:output:electricity,fr,https://wiki.openstreetmap.org/wiki/FR:Key:generator:output:electricity,2022-04-25,9,371,83,10,124.37,https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Huntly_Power_Station.JPG/200px-Huntly_Power_Station.JPG
|
||||
addr:city:simc,en,https://wiki.openstreetmap.org/wiki/Key:addr:city:simc,2022-04-15,9,200,66,10,100,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
entrance,en,https://wiki.openstreetmap.org/wiki/Key:entrance,2025-08-30,19,1422,255,51,158.12,https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/SF_City_Hall_door.JPG/200px-SF_City_Hall_door.JPG
|
||||
entrance,fr,https://wiki.openstreetmap.org/wiki/FR:Key:entrance,2023-07-25,16,834,166,37,158.12,https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/SF_City_Hall_door.JPG/200px-SF_City_Hall_door.JPG
|
||||
created_by,en,https://wiki.openstreetmap.org/wiki/Key:created_by,2025-08-06,18,1225,355,16,100,https://wiki.openstreetmap.org/w/images/9/9e/Created_by_JOSM_15_6115_de.png
|
||||
roof:levels,en,https://wiki.openstreetmap.org/wiki/Key:roof:levels,2025-05-07,12,654,140,18,6.72,https://wiki.openstreetmap.org/w/images/thumb/6/61/Roof_sample_6.png/200px-Roof_sample_6.png
|
||||
roof:levels,fr,https://wiki.openstreetmap.org/wiki/FR:Key:roof:levels,2025-04-05,11,642,133,18,6.72,https://wiki.openstreetmap.org/w/images/thumb/6/61/Roof_sample_6.png/200px-Roof_sample_6.png
|
||||
bus,en,https://wiki.openstreetmap.org/wiki/Key:bus,2024-09-29,16,885,149,12,238.72,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/Bus_aus_Zusatzzeichen_1024-14.svg/200px-Bus_aus_Zusatzzeichen_1024-14.svg.png
|
||||
bus,fr,https://wiki.openstreetmap.org/wiki/FR:Key:bus,2021-07-21,9,219,73,11,238.72,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
addr:floor,en,https://wiki.openstreetmap.org/wiki/Key:addr:floor,2024-09-02,12,458,82,11,78.44,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
addr:floor,fr,https://wiki.openstreetmap.org/wiki/FR:Key:addr:floor,2025-08-23,15,1653,150,77,78.44,https://wiki.openstreetmap.org/w/images/thumb/e/e9/Housenumber-karlsruhe-de.png/200px-Housenumber-karlsruhe-de.png
|
||||
sidewalk,en,https://wiki.openstreetmap.org/wiki/Key:sidewalk,2025-08-26,23,2248,393,39,32.48,https://wiki.openstreetmap.org/w/images/thumb/b/b9/Sidewalk_and_zebra-crossing.jpg/200px-Sidewalk_and_zebra-crossing.jpg
|
||||
sidewalk,fr,https://wiki.openstreetmap.org/wiki/FR:Key:sidewalk,2025-05-01,16,1177,215,16,32.48,https://wiki.openstreetmap.org/w/images/thumb/b/b9/Sidewalk_and_zebra-crossing.jpg/200px-Sidewalk_and_zebra-crossing.jpg
|
||||
attribution,en,https://wiki.openstreetmap.org/wiki/Key:attribution,2024-09-14,14,372,98,17,100,https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Commons-emblem-hand.svg/150px-Commons-emblem-hand.svg.png
|
||||
nysgissam:nysaddresspointid,en,https://wiki.openstreetmap.org/wiki/Key:nysgissam:nysaddresspointid,2022-09-14,39,3047,115,5,100,https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/NYSGISSAM_-_Single_point_inside_building.png/300px-NYSGISSAM_-_Single_point_inside_building.png
|
||||
operator:wikidata,en,https://wiki.openstreetmap.org/wiki/Key:operator:wikidata,2024-08-10,14,347,97,11,109.59,https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Wikidata-logo-en.svg/200px-Wikidata-logo-en.svg.png
|
||||
operator:wikidata,fr,https://wiki.openstreetmap.org/wiki/FR:Key:operator:wikidata,2023-02-13,11,309,87,11,109.59,https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Wikidata-logo-en.svg/200px-Wikidata-logo-en.svg.png
|
||||
direction,en,https://wiki.openstreetmap.org/wiki/Key:direction,2025-08-30,17,1515,169,34,114.26,https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Kompas_Sofia.JPG/200px-Kompas_Sofia.JPG
|
||||
direction,fr,https://wiki.openstreetmap.org/wiki/FR:Key:direction,2024-02-23,23,1114,132,26,114.26,https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Kompas_Sofia.JPG/200px-Kompas_Sofia.JPG
|
||||
note,en,https://wiki.openstreetmap.org/wiki/Key:note,2025-05-20,11,416,85,12,338.94,https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Wlm-icon-note-red.svg/200px-Wlm-icon-note-red.svg.png
|
||||
note,fr,https://wiki.openstreetmap.org/wiki/FR:Key:note,2020-10-01,10,347,82,13,338.94,https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Wlm-icon-note-red.svg/200px-Wlm-icon-note-red.svg.png
|
||||
addr:conscriptionnumber,en,https://wiki.openstreetmap.org/wiki/Key:addr:conscriptionnumber,2022-03-14,13,607,95,15,100,https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/D%C4%9B%C4%8D%C3%ADn%2C_Tyr%C5%A1ova_3%2C_domovn%C3%AD_%C4%8D%C3%ADsla.jpg/200px-D%C4%9B%C4%8D%C3%ADn%2C_Tyr%C5%A1ova_3%2C_domovn%C3%AD_%C4%8D%C3%ADsla.jpg
|
||||
tiger:zip_left,en,https://wiki.openstreetmap.org/wiki/Key:tiger:zip_left,2021-12-03,26,3319,53,1,100,https://wiki.openstreetmap.org/w/images/c/c9/Logo.png
|
||||
opening_hours,en,https://wiki.openstreetmap.org/wiki/Key:opening_hours,2025-08-16,49,5565,353,25,13.51,https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Neon_Internet_Cafe_open_24_hours.jpg/200px-Neon_Internet_Cafe_open_24_hours.jpg
|
||||
opening_hours,fr,https://wiki.openstreetmap.org/wiki/FR:Key:opening_hours,2025-08-18,35,3748,225,17,13.51,https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Neon_Internet_Cafe_open_24_hours.jpg/200px-Neon_Internet_Cafe_open_24_hours.jpg
|
||||
website,en,https://wiki.openstreetmap.org/wiki/Key:website,2025-01-26,22,1098,188,31,154.75,https://upload.wikimedia.org/wikipedia/commons/1/10/Vista-www.png
|
||||
website,fr,https://wiki.openstreetmap.org/wiki/FR:Key:website,2023-01-04,14,672,133,25,154.75,https://upload.wikimedia.org/wikipedia/commons/1/10/Vista-www.png
|
||||
parking,en,https://wiki.openstreetmap.org/wiki/Key:parking,2025-07-06,14,922,190,32,2.25,https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/IE_road_sign_F-200.svg/200px-IE_road_sign_F-200.svg.png
|
||||
parking,fr,https://wiki.openstreetmap.org/wiki/FR:Key:parking,2025-07-06,11,660,157,37,2.25,https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/IE_road_sign_F-200.svg/200px-IE_road_sign_F-200.svg.png
|
||||
ref:bygningsnr,en,https://wiki.openstreetmap.org/wiki/Key:ref:bygningsnr,2023-06-27,10,179,69,10,100,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
addr:unit,en,https://wiki.openstreetmap.org/wiki/Key:addr:unit,2025-08-13,9,174,71,12,11.48,https://wiki.openstreetmap.org/w/images/thumb/7/76/Osm_element_node.svg/30px-Osm_element_node.svg.png
|
||||
addr:unit,fr,https://wiki.openstreetmap.org/wiki/FR:Key:addr:unit,2025-08-23,15,1653,150,77,11.48,https://wiki.openstreetmap.org/w/images/thumb/e/e9/Housenumber-karlsruhe-de.png/200px-Housenumber-karlsruhe-de.png
|
||||
wikidata,en,https://wiki.openstreetmap.org/wiki/Key:wikidata,2025-05-31,24,1616,239,49,345.95,https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Wikidata-logo-en.svg/200px-Wikidata-logo-en.svg.png
|
||||
wikidata,fr,https://wiki.openstreetmap.org/wiki/FR:Key:wikidata,2020-10-01,19,997,139,20,345.95,https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Wikidata-logo-en.svg/200px-Wikidata-logo-en.svg.png
|
||||
tiger:zip_right,en,https://wiki.openstreetmap.org/wiki/Key:tiger:zip_right,2021-12-03,26,3319,53,1,100,https://wiki.openstreetmap.org/w/images/c/c9/Logo.png
|
||||
ref:ruian:building,en,https://wiki.openstreetmap.org/wiki/Key:ref:ruian:building,2022-09-01,9,203,71,11,100,https://wiki.openstreetmap.org/w/images/thumb/5/58/Osm_element_node_no.svg/30px-Osm_element_node_no.svg.png
|
||||
tourism,en,https://wiki.openstreetmap.org/wiki/Key:tourism,2025-02-28,11,1032,227,116,401.64,https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/Tourists_in_Munich_at_the_Marienplatz%2C_2011.JPG/200px-Tourists_in_Munich_at_the_Marienplatz%2C_2011.JPG
|
||||
tourism,fr,https://wiki.openstreetmap.org/wiki/FR:Key:tourism,2019-09-14,13,581,208,103,401.64,https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/Tourists_in_Munich_at_the_Marienplatz%2C_2011.JPG/200px-Tourists_in_Munich_at_the_Marienplatz%2C_2011.JPG
|
||||
|
|
|
Loading…
Add table
Add a link
Reference in a new issue