Ich arbeite an einem flaskbasierten Geolocation-Tool, das (LAT, LON) in vier Wörter koordiniert, wobei ein benutzerdefiniertes Netzsystem über Land und Wasser verwendet wird. Hier ist eine vereinfachte Version des Code: < /p>
import math
import csv
from typing import List, Tuple, Dict
import geopandas as gpd
from shapely.geometry import Point
from flask import Flask, request, render_template
from geopy.geocoders import ArcGIS
# ------------------------------------------------------------------------------
# FLASK APP INIT
# ------------------------------------------------------------------------------
app = Flask(__name__)
geolocator = ArcGIS()
# ------------------------------------------------------------------------------
# CONSTANTS
# ------------------------------------------------------------------------------
GRID_SIZE_LAND = 5 # metres
GRID_SIZE_WATER = 10 # metres
NUM_LAT_CELLS_LAND = int(180_000_000 / GRID_SIZE_LAND)
NUM_LON_CELLS_LAND = int(360_000_000 / GRID_SIZE_LAND)
NUM_LAT_CELLS_WATER = int(180_000_000 / GRID_SIZE_WATER)
NUM_LON_CELLS_WATER = int(360_000_000 / GRID_SIZE_WATER)
TOTAL_LAND_CELLS = NUM_LAT_CELLS_LAND * NUM_LON_CELLS_LAND
LEGACY_SPLIT = 10 ** 12 # old 4-digit prefix boundary
# ------------------------------------------------------------------------------
# WORD LIST
# ------------------------------------------------------------------------------
def load_words_from_csv(filename: str) -> Tuple[List[str], Dict[str, int]]:
"""Return a de-duplicated word list and lookup table."""
words: List[str] = []
lookup: Dict[str, int] = {}
with open(filename, newline="") as fh:
for row in csv.DictReader(fh):
w = row["word"].strip().lower()
if w and w not in lookup: # drop blanks & duplicates
lookup[w] = len(words)
words.append(w)
return words, lookup
WORDS, WORD_TO_INDEX = load_words_from_csv("data/fourwords_wordlist.csv")
BASE = len(WORDS)
# ------------------------------------------------------------------------------
# LAND / WATER TEST
# ------------------------------------------------------------------------------
land_union = gpd.read_file("data/ne_50m_land.shp").unary_union
def is_land(lat: float, lon: float) -> bool:
return land_union.covers(Point(lon, lat))
# ------------------------------------------------------------------------------
# ENCODING
# ------------------------------------------------------------------------------
def latlon_to_cell(lat: float, lon: float) -> int:
"""Current contiguous ID scheme (land first, then water)."""
grid = GRID_SIZE_LAND if is_land(lat, lon) else GRID_SIZE_WATER
if grid == GRID_SIZE_LAND:
lat_i = int((lat + 90) * 1e6 // GRID_SIZE_LAND)
lon_i = int((lon + 180) * 1e6 // GRID_SIZE_LAND)
return lat_i * NUM_LON_CELLS_LAND + lon_i
else: # water
lat_i = int((lat + 90) * 1e6 // GRID_SIZE_WATER)
lon_i = int((lon + 180) * 1e6 // GRID_SIZE_WATER)
return TOTAL_LAND_CELLS + lat_i * NUM_LON_CELLS_WATER + lon_i
def encode(lat: float, lon: float) -> List[str]:
cell_id = latlon_to_cell(lat, lon)
digits = [(cell_id // BASE ** i) % BASE for i in range(3, -1, -1)] # MSB→LSB
return [WORDS[d] for d in digits]
# ------------------------------------------------------------------------------
# DECODING
# ------------------------------------------------------------------------------
def _decode_current(cell_id: int) -> Tuple[float, float]:
"""Decode using the current contiguous ID scheme."""
if cell_id < TOTAL_LAND_CELLS:
grid = GRID_SIZE_LAND
lon_cells = NUM_LON_CELLS_LAND
core_id = cell_id
else:
grid = GRID_SIZE_WATER
lon_cells = NUM_LON_CELLS_WATER
core_id = cell_id - TOTAL_LAND_CELLS
lat_i = core_id // lon_cells
lon_i = core_id % lon_cells
lat = (lat_i * grid) / 1e6 - 90 + grid / (2 * 1e6)
lon = (lon_i * grid) / 1e6 - 180 + grid / (2 * 1e6)
return lat, lon
def _decode_legacy(cell_id: int) -> Tuple[float, float]:
"""Decode a legacy ID using the 10¹² prefix trick."""
prefix = cell_id // LEGACY_SPLIT
core_id = cell_id % LEGACY_SPLIT
if prefix not in (0, 1):
raise ValueError
grid = GRID_SIZE_LAND if prefix == 0 else GRID_SIZE_WATER
lon_cells = NUM_LON_CELLS_LAND if prefix == 0 else NUM_LON_CELLS_WATER
lat_i = core_id // lon_cells
lon_i = core_id % lon_cells
lat = (lat_i * grid) / 1e6 - 90 + grid / (2 * 1e6)
lon = (lon_i * grid) / 1e6 - 180 + grid / (2 * 1e6)
return lat, lon
def decode(words: List[str]) -> Tuple[float, float]:
"""Decode four words to (lat, lon)."""
try:
digits = [WORD_TO_INDEX[w] for w in words]
except KeyError as e:
raise ValueError(f"Unknown word in code: {e.args[0]}") from None
cell_id = 0
for d in digits:
cell_id = cell_id * BASE + d
lat, lon = _decode_current(cell_id)
if lat < -89.82: # likely bogus, near South Pole
try:
lat, lon = _decode_legacy(cell_id)
except ValueError:
pass
return lat, lon
# ------------------------------------------------------------------------------
# UTILITIES
# ------------------------------------------------------------------------------
def format_words(words: List[str]) -> str:
return ".".join(words)
def parse_words(code: str) -> List[str]:
return code.lower().strip().split(".")
def resolve_input(query: str):
query = query.strip()
if "." in query and len(query.split(".")) == 4:
return "decode", query.lower().split(".")
try:
lat, lon = map(float, query.split(","))
return "encode", (lat, lon)
except:
pass
location = geolocator.geocode(query)
if location:
return "encode", (location.latitude, location.longitude)
raise ValueError("Input could not be recognized.")`
Die Ausgabe
Die Funktion codode () gibt eine Liste von vier Wörtern zurück, basierend auf einem berechneten cell_id . Wenn ich diese vier Wörter jedoch mit Decode () dekodieren, unterscheiden sich die resultierenden (lat, lon) Koordinaten oft signifikant von den ursprünglichen -, manchmal um mehrere Kilometer oder mehr. /> Ich wende die Wortliste ein und erstelle ein sauberes Wort → Index Mapping. /> [*] testete sowohl das Legacy- als auch die aktuelle Dekodierungslogik: < /strong>
für IDs behandle ich sie als aktuelles Format; Andere greifen auf die Legacy Decodes Logic zurück. Noch kein Erfolg. /> Off-by-One-Fehler in der Gittermathematik < /li>
Basisumwandlung Fehlausrichtung (MSB /LSB-Bestellung, Überlauf) < /li>
Word-Index-Order-Ausgabe < /li>
< /ul>
< /li>
< /li>
< /ul>
Fragen < /h3>
Gibt es offensichtlich etwas nicht, wie ich cell_id < /code> → Wörter und zurück-Rücken umwandeln kann. Land/Wasser aufgeteilt, ohne die cell_id math?
Ist Decode () stillschweigend fehlschlagen und eine "Fallback" -Koordinate ohne Werfen? PrettyPrint-Override ">
Ich arbeite an einem flaskbasierten Geolocation-Tool, das (LAT, LON) in vier Wörter koordiniert, wobei ein benutzerdefiniertes Netzsystem über Land und Wasser verwendet wird. Hier ist eine vereinfachte Version des Code: < /p> [code]import math import csv from typing import List, Tuple, Dict
import geopandas as gpd from shapely.geometry import Point from flask import Flask, request, render_template from geopy.geocoders import ArcGIS
# ------------------------------------------------------------------------------ # WORD LIST # ------------------------------------------------------------------------------
def load_words_from_csv(filename: str) -> Tuple[List[str], Dict[str, int]]: """Return a de-duplicated word list and lookup table.""" words: List[str] = [] lookup: Dict[str, int] = {}
with open(filename, newline="") as fh: for row in csv.DictReader(fh): w = row["word"].strip().lower() if w and w not in lookup: # drop blanks & duplicates lookup[w] = len(words) words.append(w)
return words, lookup
WORDS, WORD_TO_INDEX = load_words_from_csv("data/fourwords_wordlist.csv") BASE = len(WORDS)
# ------------------------------------------------------------------------------ # LAND / WATER TEST # ------------------------------------------------------------------------------
def encode(lat: float, lon: float) -> List[str]: cell_id = latlon_to_cell(lat, lon) digits = [(cell_id // BASE ** i) % BASE for i in range(3, -1, -1)] # MSB→LSB return [WORDS[d] for d in digits]
def decode(words: List[str]) -> Tuple[float, float]: """Decode four words to (lat, lon).""" try: digits = [WORD_TO_INDEX[w] for w in words] except KeyError as e: raise ValueError(f"Unknown word in code: {e.args[0]}") from None
cell_id = 0 for d in digits: cell_id = cell_id * BASE + d
lat, lon = _decode_current(cell_id)
if lat < -89.82: # likely bogus, near South Pole try: lat, lon = _decode_legacy(cell_id) except ValueError: pass
location = geolocator.geocode(query) if location: return "encode", (location.latitude, location.longitude)
raise ValueError("Input could not be recognized.")` [/code] Die Ausgabe Die Funktion codode () gibt eine Liste von vier Wörtern zurück, basierend auf einem berechneten cell_id . Wenn ich diese vier Wörter jedoch mit Decode () dekodieren, unterscheiden sich die resultierenden (lat, lon) Koordinaten oft signifikant von den ursprünglichen -, manchmal um mehrere Kilometer oder mehr. /> Ich wende die Wortliste ein und erstelle ein sauberes Wort → Index Mapping. /> [*] [b] testete sowohl das Legacy- als auch die aktuelle Dekodierungslogik: < /strong> für IDs behandle ich sie als aktuelles Format; Andere greifen auf die Legacy Decodes Logic zurück. Noch kein Erfolg. /> Off-by-One-Fehler in der Gittermathematik < /li> Basisumwandlung Fehlausrichtung (MSB /LSB-Bestellung, Überlauf) < /li> Word-Index-Order-Ausgabe < /li> < /ul> < /li> < /li> < /ul> Fragen < /h3>
Gibt es offensichtlich etwas nicht, wie ich cell_id < /code> → Wörter und zurück-Rücken [url=viewtopic.php?t=20495]umwandeln[/url] kann. Land/Wasser aufgeteilt, ohne die cell_id math? Ist Decode () stillschweigend fehlschlagen und eine "Fallback" -Koordinate ohne Werfen? PrettyPrint-Override ">[code]lat, lon = 48.8584, 2.2945 words = encode(lat, lon) decoded = decode(words) print(f"Original: {lat}, {lon} → Encoded: {format_words(words)} → Decoded: {decoded}") [/code] Wenn der dekodierte Ort nicht nur wenige Meter vom Original entfernt ist, bricht etwas zusammen.
In einem C#-/.NET-Projekt haben wir während des Builds die Codeanalyse aktiviert. Wir verwenden die .editorconfig, um anzupassen, welche Regeln aktiviert/deaktiviert werden und den Schweregrad...
Ich habe eine native React -App, in der ich Firebase/Auth .
Ich habe in meinem Paket.json Datei:
. dependencies : {
....
@react-native-firebase/analytics : ^21.7.1 ,
@react-native-firebase/app :...
Ich versuche eine Site zu erstellen, auf der der Benutzer auf dem Bildschirm nach Wörtern suchen kann, indem ich auf einen weißen Hintergrund ziehe. Die Wörter sind in weiß und unsichtbar, bis der...
Ich versuche eine Site zu erstellen, auf der der Benutzer auf dem Bildschirm nach Wörtern suchen kann, indem ich auf einen weißen Hintergrund ziehe. Die Wörter sind in weiß und unsichtbar, bis der...
Ich versuche eine Site zu erstellen, auf der der Benutzer auf dem Bildschirm nach Wörtern suchen kann, indem ich auf einen weißen Hintergrund ziehe. Die Wörter sind in weiß und unsichtbar, bis der...