Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate ign wmts services #166

Merged
merged 12 commits into from
Apr 3, 2024
231 changes: 107 additions & 124 deletions provider_sources/_compress_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,131 +84,114 @@ def update_year(provider_or_tile):
leaflet[key] = xyz[key]


# add the IGN tile layers

leaflet["GeoportailFrance"]["plan"] = {}
leaflet["GeoportailFrance"]["orthos"] = {}
leaflet["GeoportailFrance"]["parcels"] = {}
tilelayers_list = []
apikey_list = [
"administratif",
"agriculture",
"altimetrie",
"cartes",
"clc",
"economie",
"environnement",
"essentiels",
"lambert93",
"ocsge",
"ortho",
"orthohisto",
"satellite",
"sol",
"topographie",
"transports",
]
url_template = (
"https://wxs.ign.fr/apikey/geoportail/wmts?REQUEST=GetCapabilities&SERVICE=wmts"
# Add IGN WMTS services (Tile images)

ign_wmts_url = (
"https://data.geopf.fr/wmts?SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetCapabilities"
)
for j in range(0, len(apikey_list)):
apikey = apikey_list[j]
url = url_template.replace("apikey", apikey)
resp = requests.get(url)
resp_dict = xmltodict.parse(resp.content)
layer_list = resp_dict["Capabilities"]["Contents"]["Layer"]
addictionnal_dict = {}

for i in range(len(layer_list)):
layer = resp_dict["Capabilities"]["Contents"]["Layer"][i]
variant = layer["ows:Identifier"]
name = ""
if "." not in variant:
name = variant.lower().capitalize()
else:
name = variant.split(".")[0].lower().capitalize()
for i in range(1, len(variant.split("."))):
name = name + "_" + (variant.split(".")[i]).lower().capitalize()
name = name.replace("-", "_")

if variant == "GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2":
name = "plan"
if variant == "ORTHOIMAGERY.ORTHOPHOTOS":
name = "orthos"
if variant == "CADASTRALPARCELS.PARCELLAIRE_EXPRESS":
name = "parcels"

if "Style" in layer:
if type(layer["Style"]) is dict:
style = layer["Style"]["ows:Identifier"]

elif type(layer["Style"]) is list:
style = layer["Style"][1]["ows:Identifier"]
else:
style = "normal"

TileMatrixSetLimits = layer["TileMatrixSetLink"]["TileMatrixSetLimits"][
"TileMatrixLimits"
]
min_zoom = int(TileMatrixSetLimits[0]["TileMatrix"])
max_zoom = int(TileMatrixSetLimits[-1]["TileMatrix"])
TileMatrixSet = layer["TileMatrixSetLink"]["TileMatrixSet"]
format = layer["Format"]
bounding_lowerleft_corner = layer["ows:WGS84BoundingBox"][
"ows:LowerCorner"
] # given with lon/lat order
bounding_upperright_corner = layer["ows:WGS84BoundingBox"][
"ows:UpperCorner"
] # given with lon/lat order
lowerleft_corner_lon, lowerleft_corner_lat = bounding_lowerleft_corner.split(
" "
)
upperright_corner_lon, upperright_corner_lat = bounding_upperright_corner.split(
" "
)
bounds = [
[float(lowerleft_corner_lat), float(lowerleft_corner_lon)],
[float(upperright_corner_lat), float(upperright_corner_lon)],
]

if format == "application/x-protobuf":
pass
elif format == "image/x-bil;bits=32":
pass
elif apikey == "lambert93":
pass
else:
tilelayers_list.append("GeoportailFrance." + name)
leaflet["GeoportailFrance"][name] = {
"url": """https://wxs.ign.fr/{apikey}/geoportail/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE={style}&TILEMATRIXSET={TileMatrixSet}&FORMAT={format}&LAYER={variant}&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}""",
"html_attribution": """<a target="_blank"href="https://www.geoportail.gouv.fr/">Geoportail France</a>""",
"attribution": "Geoportail France",
"bounds": bounds,
"min_zoom": min_zoom,
"max_zoom": max_zoom,
"apikey": apikey,
"format": format,
"style": style,
"variant": variant,
"name": "GeoportailFrance." + name,
"TileMatrixSet": TileMatrixSet,
}

possibly_broken = [
"Ocsge_Constructions_2002",
"Ocsge_Constructions_2014",
"Ocsge_Couverture_2002",
"Ocsge_Couverture_2014",
"Ocsge_Usage_2002",
"Ocsge_Usage_2014",
"Orthoimagery_Orthophotos_Coast2000",
"Pcrs_Lamb93",
"Orthoimagery_Ortho_sat_Spot_2013",
"Orthoimagery_Orthophotos_1980_1995",
]

if name in possibly_broken:
leaflet["GeoportailFrance"][name]["status"] = "broken"

response = requests.get(ign_wmts_url)
response_dict = xmltodict.parse(response.content)
layers_list = response_dict["Capabilities"]["Contents"]["Layer"] # 556 layers

wmts_layers_list = []
for i in range(len(layers_list)):
layer = response_dict["Capabilities"]["Contents"]["Layer"][i]
variant = layer.get("ows:Identifier")

# Rename for better readability
name = ""
if "." not in variant:
name = variant.lower().capitalize()
else:
name = variant.split(".")[0].lower().capitalize()
for i in range(1, len(variant.split("."))):
name = name + "_" + (variant.split(".")[i]).lower().capitalize()
name = name.replace("-", "_")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name building should maybe be reviewed to enable the last word of the name to have a capital letter. Maybe a special case should be used for acronyms whatever position it has in the name.

# Rename for better readability (Frequent cases)
variant_to_name = {
"CADASTRALPARCELS.PARCELLAIRE_EXPRESS": "parcels",
"GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2": "plan",
"ORTHOIMAGERY.ORTHOPHOTOS": "orthos"
}

if variant in variant_to_name:
name = variant_to_name[variant]

# Get layer style
style = layer.get("Style")
if isinstance(style, dict):
style = style.get("ows:Identifier")

elif isinstance(style, list):
style = style[1].get("ows:Identifier") if len(style) > 1 else None
else:
style = "normal"

# Resolution levels (pyramid)
TileMatrixSet = layer["TileMatrixSetLink"]["TileMatrixSet"]

# Zoom levels
TileMatrixSetLimits = layer["TileMatrixSetLink"]["TileMatrixSetLimits"][
"TileMatrixLimits"
]
min_zoom = int(TileMatrixSetLimits[0]["TileMatrix"])
max_zoom = int(TileMatrixSetLimits[-1]["TileMatrix"])

# Tile format
output_format = layer.get("Format") # image/png...
if output_format == "application/x-protobuf" or output_format == "image/x-bil;bits=32":
continue

# Layer extent
bbox_lower_left = layer["ows:WGS84BoundingBox"][
"ows:LowerCorner"
] # given with lon/lat order
bbox_upper_right = layer["ows:WGS84BoundingBox"][
"ows:UpperCorner"
] # given with lon/lat order
lower_left_corner_lon, lower_left_corner_lat = bbox_lower_left.split(
" "
)
upper_right_corner_lon, upper_right_corner_lat = bbox_upper_right.split(
" "
)
bounds = [
[float(lower_left_corner_lat), float(lower_left_corner_lon)],
[float(upper_right_corner_lat), float(upper_right_corner_lon)],
]

wmts_layers_list.append("GeoportailFrance." + name)
leaflet["GeoportailFrance"][name] = {
"url": """https://data.geopf.fr/wmts?SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&STYLE={style}&TILEMATRIXSET={TileMatrixSet}&FORMAT={format}&LAYER={variant}&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}""",
"html_attribution": """<a target="_blank"href="https://www.geoportail.gouv.fr/">Geoportail France</a>""",
"attribution": "Geoportail France",
"bounds": bounds,
"min_zoom": min_zoom,
"max_zoom": max_zoom,
"format": output_format,
"style": style,
"variant": variant,
"name": "GeoportailFrance." + name,
"TileMatrixSet": TileMatrixSet,
"apikey": "your_api_key_here",
}

# Handle broken providers
possibly_broken_providers = [
"Ocsge_Constructions_2002",
"Ocsge_Constructions_2014",
"Orthoimagery_Orthophotos_Coast2000",
"Ocsge_Couverture_2002",
"Ocsge_Couverture_2014",
"Ocsge_Usage_2002",
"Ocsge_Usage_2014",
"Pcrs_Lamb93",
]

martinfleis marked this conversation as resolved.
Show resolved Hide resolved
if name in possibly_broken_providers:
leaflet["GeoportailFrance"][name]["status"] = "broken"

with open("../xyzservices/data/providers.json", "w") as f:
json.dump(leaflet, f, indent=4)
Loading
Loading