fix:geolinien outline

This commit is contained in:
Ida Dittrich 2025-12-15 09:23:09 +01:00
parent aaf64b869f
commit f8d5c0ae2d

View file

@ -54,6 +54,27 @@ export interface ParcelSearchResponse {
id: string;
egrid?: string;
number?: string;
perimeter?: {
closed: boolean;
punkte: Array<{
koordinatensystem: string;
x: number;
y: number;
z: number | null;
}>;
};
geometry_geojson?: {
type: string;
geometry: {
type: string;
coordinates: number[][][];
};
properties: {
id: string;
egrid?: string;
number?: string;
};
};
}>;
}
@ -285,92 +306,85 @@ export function usePek() {
}
// Adjacent parcels (if available)
// Fetch geometries for adjacent parcels
// Use geometries from the response (no need to fetch separately)
if (data.adjacent_parcels && includeAdjacent && data.adjacent_parcels.length > 0) {
// Fetch geometries for each adjacent parcel
const adjacentPromises = data.adjacent_parcels.map(async (adjacent) => {
try {
// Search for the adjacent parcel by its ID or EGRID
const searchLocation = adjacent.egrid || adjacent.id || adjacent.number;
if (!searchLocation) {
if (import.meta.env.DEV) {
console.warn(`⚠️ Adjacent parcel ${adjacent.id} has no search location`);
}
return null;
}
const adjacentGeometries: ParcelGeometry[] = [];
if (import.meta.env.DEV) {
console.log(`🔍 Fetching geometry for adjacent parcel: ${searchLocation}`);
}
const adjResponse = await api.get('/api/realestate/parcel/search', {
params: {
location: searchLocation,
include_adjacent: false // Don't fetch adjacent of adjacent
}
data.adjacent_parcels.forEach((adjacent) => {
if (import.meta.env.DEV) {
console.log(`🔍 Processing adjacent parcel ${adjacent.id}:`, {
hasGeometryGeoJson: !!adjacent.geometry_geojson,
hasPerimeter: !!adjacent.perimeter,
geometryGeoJson: adjacent.geometry_geojson,
perimeter: adjacent.perimeter
});
}
const adjData: ParcelSearchResponse = adjResponse.data;
let adjCoordinates: MapPoint[] = [];
let adjCoordinates: MapPoint[] = [];
// Extract coordinates from adjacent parcel
if (adjData.map_view?.geometry_geojson?.geometry?.coordinates) {
const coords = adjData.map_view.geometry_geojson.geometry.coordinates[0];
if (Array.isArray(coords)) {
adjCoordinates = coords.map((coord: number[]) => ({
x: coord[0],
y: coord[1]
}));
}
} else if (adjData.parcel.perimeter?.punkte) {
adjCoordinates = adjData.parcel.perimeter.punkte.map((p) => ({
x: p.x,
y: p.y
// Extract coordinates from geometry_geojson if available
if (adjacent.geometry_geojson?.geometry?.coordinates) {
const coords = adjacent.geometry_geojson.geometry.coordinates[0];
if (Array.isArray(coords) && coords.length > 0) {
adjCoordinates = coords.map((coord: number[]) => ({
x: coord[0],
y: coord[1]
}));
if (import.meta.env.DEV) {
console.log(`✅ Extracted ${adjCoordinates.length} coordinates from geometry_geojson for ${adjacent.id}`);
}
}
}
// Fallback to perimeter.punkte if available
else if (adjacent.perimeter?.punkte) {
adjCoordinates = adjacent.perimeter.punkte.map((p) => ({
x: p.x,
y: p.y
}));
if (import.meta.env.DEV) {
console.log(`✅ Fetched ${adjCoordinates.length} coordinates for adjacent parcel ${adjacent.id}`);
console.log(`Extracted ${adjCoordinates.length} coordinates from perimeter for ${adjacent.id}`);
}
}
return {
// Only add if we have valid coordinates
if (adjCoordinates.length >= 3) {
adjacentGeometries.push({
id: adjacent.id,
egrid: adjacent.egrid,
number: adjacent.number,
coordinates: adjCoordinates,
isSelected: false,
isAdjacent: true
};
} catch (err) {
// If fetching fails, log error but don't add parcel
if (import.meta.env.DEV) {
console.error(`❌ Failed to fetch geometry for adjacent parcel ${adjacent.id}:`, err);
}
return null;
});
} else if (import.meta.env.DEV) {
console.warn(`⚠️ Adjacent parcel ${adjacent.id} has insufficient geometry data:`, {
coordCount: adjCoordinates.length,
hasGeometryGeoJson: !!adjacent.geometry_geojson,
hasPerimeter: !!adjacent.perimeter,
geometryGeoJsonStructure: adjacent.geometry_geojson ? {
hasGeometry: !!adjacent.geometry_geojson.geometry,
hasCoordinates: !!adjacent.geometry_geojson.geometry?.coordinates,
coordinatesLength: adjacent.geometry_geojson.geometry?.coordinates?.length,
firstCoordLength: adjacent.geometry_geojson.geometry?.coordinates?.[0]?.length
} : null
});
}
});
// Wait for all adjacent parcel geometries
const adjacentGeometries = await Promise.all(adjacentPromises);
const validAdjacentGeometries = adjacentGeometries.filter(
(g): g is ParcelGeometry => g !== null && g.coordinates.length >= 3
);
if (import.meta.env.DEV) {
console.log(`📦 Adjacent parcels summary:`, {
requested: data.adjacent_parcels.length,
fetched: adjacentGeometries.filter(g => g !== null).length,
valid: validAdjacentGeometries.length,
geometries: validAdjacentGeometries.map(g => ({
valid: adjacentGeometries.length,
geometries: adjacentGeometries.map(g => ({
id: g.id,
number: g.number,
coordCount: g.coordinates.length
}))
});
}
// Add adjacent parcels to geometries array
geometries.push(...validAdjacentGeometries);
geometries.push(...adjacentGeometries);
}
// Update parcel geometries with all parcels (main + adjacent)
@ -430,17 +444,43 @@ export function usePek() {
);
/**
* Handle parcel click on map
* Handle parcel click on map - select the clicked parcel
*/
const handleParcelClick = useCallback(async (parcelId: string) => {
// Re-search for this specific parcel with adjacent parcels
if (selectedParcel) {
const locationString = selectedParcel.parcel.centroid
? `${selectedParcel.parcel.centroid.x},${selectedParcel.parcel.centroid.y}`
: locationInput;
await searchParcel(locationString, true);
// Find the clicked parcel in the geometries
const clickedParcel = parcelGeometries.find(p => p.id === parcelId);
if (clickedParcel && clickedParcel.coordinates.length > 0) {
// Use a point inside the parcel (first coordinate is always on the boundary, which is inside)
// For better accuracy, use a point slightly inside the boundary
const firstCoord = clickedParcel.coordinates[0];
// Calculate centroid as fallback, but prefer a point we know is inside
const sumX = clickedParcel.coordinates.reduce((sum, coord) => sum + coord.x, 0);
const sumY = clickedParcel.coordinates.reduce((sum, coord) => sum + coord.y, 0);
const centroidX = sumX / clickedParcel.coordinates.length;
const centroidY = sumY / clickedParcel.coordinates.length;
// Use first coordinate (guaranteed to be on/in the parcel) for search
const locationString = `${firstCoord.x},${firstCoord.y}`;
await searchParcel(locationString, true); // Always include adjacent parcels
} else {
// Fallback: try to search by parcel ID/EGRID if available
if (selectedParcel?.adjacent_parcels) {
const adjacentParcel = selectedParcel.adjacent_parcels.find(p => p.id === parcelId);
if (adjacentParcel?.egrid) {
// Search by EGRID
await searchParcel(adjacentParcel.egrid, true);
} else if (adjacentParcel?.number) {
// Try searching by number (might need address context)
await searchParcel(adjacentParcel.number, true);
} else if (adjacentParcel?.id) {
// Last resort: try searching by ID
await searchParcel(adjacentParcel.id, true);
}
}
}
}, [selectedParcel, locationInput, searchParcel]);
}, [parcelGeometries, selectedParcel, searchParcel]);
/**
* Process natural language command