dd-l2-bangkok-multicrs-audit
Map (reference ← swipe → agent)
0:00
A contractor just shipped `bangkok_contractor_delivery.gpkg` and I need a defect cite-sheet before I sign off. Please walk every layer in the file and write one row per layer to `crs_audit.csv` with these columns: layer_name, declared_crs (formatted as `EPSG:NNNN`), geometry_type, feature_count, sample_x and sample_y for a sample coordinate taken from the layer as it sits on disk, and encoding_detected. For encoding_detected, look at the text attributes for anomalies and report either `latin1-mojibake` or `utf-8`.
0:00
System info
{
"adapter": "openrouter",
"model": "google/gemma-4-26b-a4b-it",
"base_url": "https://openrouter.ai/api/v1"
}
0:05
Bash
ls -lh bangkok_contractor_delivery.gpkg
-rw-r--r-- 1 agent agent 2.6M Jun 15 23:13 bangkok_contractor_delivery.gpkg
0:37
Write
/work/solve.py
content · 122 lines · py
import geopandas as gpd
import pandas as pd
import fiona
from shapely.geometry import Point
def detect_encoding(df):
"""
Heuristic to detect if a dataframe contains mojibake.
We check string columns for common mojibake patterns or
characters that look like they were incorrectly decoded.
"""
# Identify object (string) columns
str_cols = df.select_dtypes(include=['object']).columns
for col in str_cols:
for val in df[col].dropna().unique():
if isinstance(val, str):
# A common sign of latin1-mojibake is the presence of
# characters like Ã, ©, etc., in places they shouldn't be,
# or specific patterns.
# However, a more robust way is to try encoding to ascii and
# seeing if it fails, but that's not quite right for mojibake.
# Let's check for common mojibake patterns (e.g., Ã followed by something).
# Since we can't be 100% sure without a dictionary, we'll look
# for "broken" looking sequences.
try:
# If it's valid utf-8 and contains weird sequences, it might be mojibake.
# In many cases, mojibake happens when latin1 is read as utf-8.
# Let's try a simple check: if we can re-encode it back to latin1
# and it produces a 'cleaner' looking string, it's mojibake.
# This is a heuristic.
# Try to see if the string contains high-bit characters that
# look like they are part of a multi-byte sequence being interpreted as latin1.
# Example: 'é' instead of 'é'.
# We check for sequences like 'Ã' followed by another high-bit char.
if any(c in val for c in ['Ã', 'Â', 'Ê', 'Ì', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö']):
# This is a very naive check.
return 'latin1-mojibake'
except:
pass
return 'utf-8'
def audit_gpkg(file_path):
audit_results = []
# Get layer names using fiona
layers = fiona.listlayers(file_path)
for layer in layers:
# Load layer
gdf = gpd.read_file(file_path, layer=layer)
# Layer metadata
layer_name = layer
# CRS
crs = gdf.crs
if crs is not None:
try:
epsg_code = f"EPSG:{crs.to_epsg()}"
except:
epsg_code = str(crs)
else:
epsg_code = "None"
# Geometry Type
# Note: Geopandas/Shapely might have mixed types, but usually it's one per layer.
# We'll take the type of the first non-null geometry.
geom_type = "None"
sample_x = None
sample_y = None
if not gdf.empty:
first_geom = gdf.geometry.dropna().iloc[0] if not gdf.geometry.dropna().empty else None
if first_geom:
geom_type = first_geom.geom_type
# Get sample coordinates from the geometry as it sits
if first_geom.geom_type in ['Point', 'MultiPoint']:
# For Point, use the coordinate. For MultiPoint, use the first point.
if first_geom.geom_type == 'Point':
sample_x, sample_y = first_geom.x, first_geom.y
else:
sample_x, sample_y = first_geom.geoms[0].x, first_geom.geoms[0].y
elif first_geom.geom_type in ['LineString', 'MultiLineString']:
# Use the first coordinate of the line
if first_geom.geom_type == 'LineString':
sample_x, sample_y = first_geom.coords[0]
else:
sample_x, sample_y = first_geom.geoms[0].coords[0]
elif first_geom.geom_type in ['Polygon', 'MultiPolygon']:
# Use the first coordinate of the exterior ring
if first_geom.geom_type == 'Polygon':
sample_x, sample_y = first_geom.exterior.coords[0]
else:
sample_x, sample_y = first_geom.geoms[0].exterior.coords[0]
feature_count = len(gdf)
# Encoding detection
encoding = detect_encoding(gdf)
audit_results.append({
'layer_name': layer_name,
'declared_crs': epsg_code,
'geometry_type': geom_type,
'feature_count': feature_count,
'sample_x': sample_x,
'sample_y': sample_y,
'encoding_detected': encoding
})
return pd.DataFrame(audit_results)
if __name__ == "__main__":
input_file = 'bangkok_contractor_delivery.gpkg'
output_file = 'crs_audit.csv'
df_audit = audit_gpkg(input_file)
df_audit.to_csv(output_file, index=False)
print(f"Audit complete. Results written to {output_file}")
Wrote /work/solve.py (5102 chars).
0:43
Bash
python solve.py
Audit complete. Results written to crs_audit.csv
/work/solve.py:13: Pandas4Warning: For backward compatibility, 'str' dtypes are included by select_dtypes when 'object' dtype is specified. This behavior is deprecated and will be removed in a future version. Explicitly pass 'str' to `include` to select them, or to `exclude` to remove them and silence this warning. See https://pandas.pydata.org/docs/user_guide/migration-3-strings.html#string-migration-select-dtypes for details on how to write code that works with pandas 2 and 3. str_cols = df.select_dtypes(include=['object']).columns /work/solve.py:13: Pandas4Warning: For backward compatibility, 'str' dtypes are included by select_dtypes when 'object' dtype is specified. This behavior is deprecated and will be removed in a future version. Explicitly pass 'str' to `include` to select them, or to `exclude` to remove them and silence this warning. See https://pandas.pydata.org/docs/user_guide/migration-3-strings.html#string-migration-select-dtypes for details on how to write code that works with pandas 2 and 3. str_cols = df.select_dtypes(include=['object']).columns /work/solve.py:13: Pandas4Warning: For backward compatibility, 'str' dtypes are included by select_dtypes when 'object' dtype is specified. This behavior is deprecated and will be removed in a future version. Explicitly pass 'str' to `include` to select them, or to `exclude` to remove them and silence this warning. See https://pandas.pydata.org/docs/user_guide/migration-3-strings.html#string-migration-select-dtypes for details on how to write code that works with pandas 2 and 3. str_cols = df.select_dtypes(include=['object']).columns
0:47
Read
crs_audit.csv
1 layer_name,declared_crs,geometry_type,feature_count,sample_x,sample_y,encoding_detected
2 parcels,EPSG:24047,Polygon,4000,657421.5158199039,1509162.3701859994,utf-8
3 roads,EPSG:32647,LineString,5000,656835.6850029442,1509487.0031804747,utf-8
4 markets,EPSG:4326,Point,1000,100.4533,13.655000000000001,utf-8
1:08
Write
/work/solve.py
content · 78 lines · py
import geopandas as gpd
import pandas as pd
import fiona
def detect_encoding(df):
"""
Heuristic to detect if a dataframe contains mojibake.
"""
str_cols = df.select_dtypes(include=['object']).columns
for col in str_cols:
for val in df[col].dropna().unique():
if isinstance(val, str):
# Heuristic: many common mojibake characters resulting from
# interpreting UTF-8 as Latin-1 (e.g., 'Ã')
if any(c in val for c in ['Ã', 'Â', 'Ê', 'Ì', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö']):
return 'latin1-mojibake'
return 'utf-8'
def audit_gpkg(file_path):
audit_results = []
layers = fiona.listlayers(file_path)
for layer in layers:
gdf = gpd.read_file(file_path, layer=layer)
# CRS
crs = gdf.crs
if crs is not None:
try:
epsg_code = f"EPSG:{crs.to_epsg()}"
except:
epsg_code = str(crs)
else:
epsg_code = "None"
# Geometry and Sample Coords
geom_type = "None"
sample_x = None
sample_y = None
if not gdf.empty:
# Ensure we work with valid geometries
valid_geoms = gdf.geometry.dropna()
if not valid_geoms.empty:
first_geom = valid_geoms.iloc[0]
geom_type = first_geom.geom_type
if first_geom.geom_type == 'Point':
sample_x, sample_y = first_geom.x, first_geom.y
elif first_geom.geom_type == 'MultiPoint':
sample_x, sample_y = first_geom.geoms[0].x, first_geom.geoms[0].y
elif first_geom.geom_type == 'LineString':
sample_x, sample_y = first_geom.coords[0]
elif first_geom.geom_type == 'MultiLineString':
sample_x, sample_y = first_geom.geoms[0].coords[0]
elif first_geom.geom_type == 'Polygon':
sample_x, sample_y = first_geom.exterior.coords[0]
elif first_geom.geom_type == 'MultiPolygon':
sample_x, sample_y = first_geom.geoms[0].exterior.coords[0]
audit_results.append({
'layer_name': layer,
'declared_crs': epsg_code,
'geometry_type': geom_type,
'feature_count': len(gdf),
'sample_x': sample_x,
'sample_y': sample_y,
'encoding_detected': detect_encoding(gdf)
})
return pd.DataFrame(audit_results)
if __name__ == "__main__":
input_file = 'bangkok_contractor_delivery.gpkg'
output_file = 'crs_audit.csv'
df_audit = audit_gpkg(input_file)
df_audit.to_csv(output_file, index=False)
Wrote /work/solve.py (2800 chars).
1:13
Bash
python solve.py
/work/solve.py:9: Pandas4Warning: For backward compatibility, 'str' dtypes are included by select_dtypes when 'object' dtype is specified. This behavior is deprecated and will be removed in a future version. Explicitly pass 'str' to `include` to select them, or to `exclude` to remove them and silence this warning. See https://pandas.pydata.org/docs/user_guide/migration-3-strings.html#string-migration-select-dtypes for details on how to write code that works with pandas 2 and 3. str_cols = df.select_dtypes(include=['object']).columns /work/solve.py:9: Pandas4Warning: For backward compatibility, 'str' dtypes are included by select_dtypes when 'object' dtype is specified. This behavior is deprecated and will be removed in a future version. Explicitly pass 'str' to `include` to select them, or to `exclude` to remove them and silence this warning. See https://pandas.pydata.org/docs/user_guide/migration-3-strings.html#string-migration-select-dtypes for details on how to write code that works with pandas 2 and 3. str_cols = df.select_dtypes(include=['object']).columns /work/solve.py:9: Pandas4Warning: For backward compatibility, 'str' dtypes are included by select_dtypes when 'object' dtype is specified. This behavior is deprecated and will be removed in a future version. Explicitly pass 'str' to `include` to select them, or to `exclude` to remove them and silence this warning. See https://pandas.pydata.org/docs/user_guide/migration-3-strings.html#string-migration-select-dtypes for details on how to write code that works with pandas 2 and 3. str_cols = df.select_dtypes(include=['object']).columns
1:16
Read
crs_audit.csv
1 layer_name,declared_crs,geometry_type,feature_count,sample_x,sample_y,encoding_detected
2 parcels,EPSG:24047,Polygon,4000,657421.5158199039,1509162.3701859994,utf-8
3 roads,EPSG:32647,LineString,5000,656835.6850029442,1509487.0031804747,utf-8
4 markets,EPSG:4326,Point,1000,100.4533,13.655000000000001,utf-8
1:33
Bash
# I will check the actual data content in one of the layers to see if I missed a...
# I will check the actual data content in one of the layers to see if I missed anything.
python -c "import geopandas as gpd; gdf = gpd.read_file('bangkok_contractor_delivery.gpkg', layer='parcels'); print(gdf.head())"
python -c "import geopandas as gpd; gdf = gpd.read_file('bangkok_contractor_delivery.gpkg', layer='roads'); print(gdf.head())"
python -c "import geopandas as gpd; gdf = gpd.read_file('bangkok_contractor_delivery.gpkg', layer='markets'); print(gdf.head())"
id ... geometry
0 P00000 ... POLYGON ((657421.516 1509162.37, 657992.722 15...
1 P00001 ... POLYGON ((658135.524 1509166.644, 658706.731 1...
2 P00002 ... POLYGON ((658849.533 1509170.937, 659420.743 1...
3 P00003 ... POLYGON ((659563.545 1509175.249, 660134.756 1...
4 P00004 ... POLYGON ((660277.558 1509179.581, 660848.771 1...
[5 rows x 4 columns]
id ... geometry
0 R00000 ... LINESTRING (656835.685 1509487.003, 657156.989...
1 R00001 ... LINESTRING (657192.69 1509489.138, 657190.305 ...
2 R00002 ... LINESTRING (657549.695 1509491.278, 657871 150...
3 R00003 ... LINESTRING (657906.701 1509493.423, 657904.305...
4 R00004 ... LINESTRING (658263.707 1509495.572, 658585.013...
[5 rows x 4 columns]
id name_th kind geometry
0 M00000 ตลาดนัดจตุจักร fresh POINT (100.4533 13.655)
1 M00001 ตลาดอ.ต.ก. wet POINT (100.4599 13.655)
2 M00002 ตลาดคลองเตย night POINT (100.4665 13.655)
3 M00003 ตลาดสะพานขาว fresh POINT (100.4731 13.655)
4 M00004 ตลาดบางรัก wet POINT (100.4797 13.655)
1:45
Bash
# Let's check if there's any mojibake in the markets layer specifically.
# Let's check if there's any mojibake in the markets layer specifically.
python -c "import geopandas as gpd; gdf = gpd.read_file('bangkok_contractor_delivery.gpkg', layer='markets'); print(gdf['name_th'].tolist())"
['ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี', 'ตลาดนัดจตุจักร', 'ตลาดอ.ต.ก.', 'ตลาดคลองเตย', 'ตลาดสะพานขาว', 'ตลาดบางรัก', 'ตลาดน้อย', 'ตลาดบางกะปิ', 'ตลาดมีนบุรี']
2:23
Write
/work/solve.py
content · 81 lines · py
import geopandas as gpd
import pandas as pd
import fiona
def detect_encoding(df):
"""
Heuristic to detect if a dataframe contains mojibake.
"""
str_cols = df.select_dtypes(include=['object']).columns
for col in str_cols:
# Extract unique strings
uniques = df[col].dropna().unique()
for val in uniques:
if isinstance(val, str):
# Heuristic: Check for common mojibake patterns.
# Many encoding errors result in characters like à or Â.
# We look for characters that are often part of a multi-byte sequence
# incorrectly interpreted as single bytes.
if any(c in val for c in ['Ã', 'Â', 'Ê', 'Ì', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö']):
return 'latin1-mojibake'
return 'utf-8'
def audit_gpkg(file_path):
audit_results = []
layers = fiona.listlayers(file_path)
for layer in layers:
gdf = gpd.read_file(file_path, layer=layer)
# CRS
crs = gdf.crs
if crs is not None:
try:
epsg_code = f"EPSG:{crs.to_epsg()}"
except:
epsg_code = str(crs)
else:
epsg_code = "None"
# Geometry and Sample Coords
geom_type = "None"
sample_x = None
sample_y = None
if not gdf.empty:
valid_geoms = gdf.geometry.dropna()
if not valid_geoms.empty:
first_geom = valid_geoms.iloc[0]
geom_type = first_geom.geom_type
if first_geom.geom_type == 'Point':
sample_x, sample_y = first_geom.x, first_geom.y
elif first_geom.geom_type == 'MultiPoint':
sample_x, sample_y = first_geom.geoms[0].x, first_geom.geoms[0].y
elif first_geom.geom_type == 'LineString':
sample_x, sample_y = first_geom.coords[0]
elif first_geom.geom_type == 'MultiLineString':
sample_x, sample_y = first_geom.geoms[0].coords[0]
elif first_geom.geom_type == 'Polygon':
sample_x, sample_y = first_geom.exterior.coords[0]
elif first_geom.geom_type == 'MultiPolygon':
sample_x, sample_y = first_geom.geoms[0].exterior.coords[0]
audit_results.append({
'layer_name': layer,
'declared_crs': epsg_code,
'geometry_type': geom_type,
'feature_count': len(gdf),
'sample_x': sample_x,
'sample_y': sample_y,
'encoding_detected': detect_encoding(gdf)
})
return pd.DataFrame(audit_results)
if __name__ == "__main__":
input_file = 'bangkok_contractor_delivery.gpkg'
output_file = 'crs_audit.csv'
df_audit = audit_gpkg(input_file)
df_audit.to_csv(output_file, index=False)
Wrote /work/solve.py (2955 chars).
2:25
Bash
python solve.py
/work/solve.py:9: Pandas4Warning: For backward compatibility, 'str' dtypes are included by select_dtypes when 'object' dtype is specified. This behavior is deprecated and will be removed in a future version. Explicitly pass 'str' to `include` to select them, or to `exclude` to remove them and silence this warning. See https://pandas.pydata.org/docs/user_guide/migration-3-strings.html#string-migration-select-dtypes for details on how to write code that works with pandas 2 and 3. str_cols = df.select_dtypes(include=['object']).columns /work/solve.py:9: Pandas4Warning: For backward compatibility, 'str' dtypes are included by select_dtypes when 'object' dtype is specified. This behavior is deprecated and will be removed in a future version. Explicitly pass 'str' to `include` to select them, or to `exclude` to remove them and silence this warning. See https://pandas.pydata.org/docs/user_guide/migration-3-strings.html#string-migration-select-dtypes for details on how to write code that works with pandas 2 and 3. str_cols = df.select_dtypes(include=['object']).columns /work/solve.py:9: Pandas4Warning: For backward compatibility, 'str' dtypes are included by select_dtypes when 'object' dtype is specified. This behavior is deprecated and will be removed in a future version. Explicitly pass 'str' to `include` to select them, or to `exclude` to remove them and silence this warning. See https://pandas.pydata.org/docs/user_guide/migration-3-strings.html#string-migration-select-dtypes for details on how to write code that works with pandas 2 and 3. str_cols = df.select_dtypes(include=['object']).columns
2:29
Read
crs_audit.csv
1 layer_name,declared_crs,geometry_type,feature_count,sample_x,sample_y,encoding_detected
2 parcels,EPSG:24047,Polygon,4000,657421.5158199039,1509162.3701859994,utf-8
3 roads,EPSG:32647,LineString,5000,656835.6850029442,1509487.0031804747,utf-8
4 markets,EPSG:4326,Point,1000,100.4533,13.655000000000001,utf-8
2:50