-
Notifications
You must be signed in to change notification settings - Fork 0
Bugfix/18 fix kartverket api error on cloud #38
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
Changes from all commits
29c6d34
007a77a
e8f8fdc
6fa5ac5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,41 +1,109 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Any | ||||||||||||||||||||||||||||||||||||||||||||||
| import json | ||||||||||||||||||||||||||||||||||||||||||||||
| from io import BytesIO | ||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Any, Dict | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| import pandas as pd | ||||||||||||||||||||||||||||||||||||||||||||||
| import requests | ||||||||||||||||||||||||||||||||||||||||||||||
| import shapely | ||||||||||||||||||||||||||||||||||||||||||||||
| from duckdb import DuckDBPyConnection | ||||||||||||||||||||||||||||||||||||||||||||||
| from shapely.geometry import shape | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| from src import Config | ||||||||||||||||||||||||||||||||||||||||||||||
| from src.application.contracts import ICountyService | ||||||||||||||||||||||||||||||||||||||||||||||
| from src.domain.enums import EPSGCode | ||||||||||||||||||||||||||||||||||||||||||||||
| from src.application.contracts import ICountyService, IBlobStorageService, IBytesService | ||||||||||||||||||||||||||||||||||||||||||||||
| from src.domain.enums import EPSGCode, StorageContainer | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| class CountyService(ICountyService): | ||||||||||||||||||||||||||||||||||||||||||||||
| __db_context: DuckDBPyConnection | ||||||||||||||||||||||||||||||||||||||||||||||
| __blob_storage_service: IBlobStorageService | ||||||||||||||||||||||||||||||||||||||||||||||
| __bytes_service: IBytesService | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| def __init__(self, db_context: DuckDBPyConnection): | ||||||||||||||||||||||||||||||||||||||||||||||
| def __init__( | ||||||||||||||||||||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||||||||||||||||||||
| db_context: DuckDBPyConnection, | ||||||||||||||||||||||||||||||||||||||||||||||
| blob_storage_service: IBlobStorageService, | ||||||||||||||||||||||||||||||||||||||||||||||
| bytes_service: IBytesService | ||||||||||||||||||||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||||||||||||||||||||
| self.__db_context = db_context | ||||||||||||||||||||||||||||||||||||||||||||||
| self.__blob_storage_service = blob_storage_service | ||||||||||||||||||||||||||||||||||||||||||||||
| self.__bytes_service = bytes_service | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| def get_county_ids(self) -> list[str]: | ||||||||||||||||||||||||||||||||||||||||||||||
| response = requests.get(f"{Config.GEONORGE_BASE_URL}/fylker?sorter=fylkesnummer") | ||||||||||||||||||||||||||||||||||||||||||||||
| response.raise_for_status() | ||||||||||||||||||||||||||||||||||||||||||||||
| data = response.json() | ||||||||||||||||||||||||||||||||||||||||||||||
| return [item["fylkesnummer"] for item in data] | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| def get_county_wkb_by_id(self, county_id: str, epsg_code: EPSGCode) -> tuple[bytes, dict[str, Any]]: | ||||||||||||||||||||||||||||||||||||||||||||||
| def get_county_polygons_by_id(self, county_id: str, epsg_code: EPSGCode) -> tuple[bytes, dict[str, Any]]: | ||||||||||||||||||||||||||||||||||||||||||||||
| geometries = self.__get_county_polygons_from_blob_storage(region=county_id) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if geometries is not None: | ||||||||||||||||||||||||||||||||||||||||||||||
| return geometries | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| wkb, geo_json = self.__fetch_county_polygons_from_api(region=county_id, epsg_code=epsg_code) | ||||||||||||||||||||||||||||||||||||||||||||||
| self.__write_county_to_blob_storage(region=county_id, wkb=wkb, geo_json=geo_json) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| return wkb, geo_json | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+37
to
+46
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| @staticmethod | ||||||||||||||||||||||||||||||||||||||||||||||
| def __fetch_county_polygons_from_api(region: str, epsg_code: EPSGCode) -> tuple[bytes, dict[str, Any]]: | ||||||||||||||||||||||||||||||||||||||||||||||
jathavaan marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||
| response = requests.get( | ||||||||||||||||||||||||||||||||||||||||||||||
| f"{Config.GEONORGE_BASE_URL}/fylker/{county_id}/omrade?utkoordsys={epsg_code.value}" | ||||||||||||||||||||||||||||||||||||||||||||||
| f"{Config.GEONORGE_BASE_URL}/fylker/{region}/omrade?utkoordsys={epsg_code.value}" | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| response.raise_for_status() | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| data = response.json() | ||||||||||||||||||||||||||||||||||||||||||||||
| geom_data = data["omrade"] | ||||||||||||||||||||||||||||||||||||||||||||||
| geom = shape(geom_data) | ||||||||||||||||||||||||||||||||||||||||||||||
| wkb_data = shapely.to_wkb(geom) | ||||||||||||||||||||||||||||||||||||||||||||||
| wkb = shapely.to_wkb(geom) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| geo_json = { | ||||||||||||||||||||||||||||||||||||||||||||||
| "type": geom_data["type"], | ||||||||||||||||||||||||||||||||||||||||||||||
| "coordinates": geom_data["coordinates"] | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| return wkb_data, geo_json | ||||||||||||||||||||||||||||||||||||||||||||||
| return wkb, geo_json | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| def __get_county_polygons_from_blob_storage(self, region: str) -> tuple[bytes, dict[str, Any]] | None: | ||||||||||||||||||||||||||||||||||||||||||||||
| county_bytes = self.__blob_storage_service.download_file( | ||||||||||||||||||||||||||||||||||||||||||||||
| container_name=StorageContainer.METADATA, | ||||||||||||||||||||||||||||||||||||||||||||||
| blob_name=Config.COUNTY_FILE_NAME | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if county_bytes is None: | ||||||||||||||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| county_df = self.__bytes_service.convert_parquet_bytes_to_df(county_bytes) | ||||||||||||||||||||||||||||||||||||||||||||||
| if region not in county_df["region"].values: | ||||||||||||||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| row = county_df.loc[county_df["region"] == region].iloc[0] | ||||||||||||||||||||||||||||||||||||||||||||||
| return row["wkb"], json.loads(row["json"]) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+76
to
+82
|
||||||||||||||||||||||||||||||||||||||||||||||
| county_df = self.__bytes_service.convert_parquet_bytes_to_df(county_bytes) | |
| if region not in county_df["region"].values: | |
| return None | |
| row = county_df.loc[county_df["region"] == region].iloc[0] | |
| return row["wkb"], json.loads(row["json"]) | |
| try: | |
| county_df = self.__bytes_service.convert_parquet_bytes_to_df(county_bytes) | |
| if region not in county_df["region"].values: | |
| return None | |
| row = county_df.loc[county_df["region"] == region].iloc[0] | |
| return row["wkb"], json.loads(row["json"]) | |
| except Exception: | |
| return None |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assigning bytes directly to DataFrame cells using .loc may not work correctly with all pandas versions. The bytes object might be stored as a reference rather than properly serialized. Consider using .at for scalar assignment or explicitly setting the dtype to object when creating the DataFrame to ensure bytes are stored correctly.
| else pd.DataFrame(columns=["region", "wkb", "json"]) | |
| json_string = json.dumps(geo_json) | |
| if region in county_df["region"].values: | |
| mask = county_df["region"] == region | |
| county_df.loc[mask, "wkb"] = wkb | |
| county_df.loc[mask, "json"] = json_string | |
| else: | |
| new_row = pd.DataFrame({"region": [region], "wkb": [wkb], "json": [json_string]}) | |
| else pd.DataFrame(columns=["region", "wkb", "json"]).astype({"wkb": object}) | |
| # Ensure 'wkb' column is dtype object for bytes storage | |
| if "wkb" in county_df.columns: | |
| county_df["wkb"] = county_df["wkb"].astype(object) | |
| json_string = json.dumps(geo_json) | |
| if region in county_df["region"].values: | |
| mask = county_df["region"] == region | |
| county_df.loc[mask, "wkb"] = wkb | |
| county_df.loc[mask, "json"] = json_string | |
| else: | |
| new_row = pd.DataFrame({"region": [region], "wkb": [wkb], "json": [json_string]}).astype({"wkb": object}) |
Uh oh!
There was an error while loading. Please reload this page.