fix:geolinien outline
This commit is contained in:
parent
aaf64b869f
commit
f8d5c0ae2d
1 changed files with 105 additions and 65 deletions
|
|
@ -54,6 +54,27 @@ export interface ParcelSearchResponse {
|
||||||
id: string;
|
id: string;
|
||||||
egrid?: string;
|
egrid?: string;
|
||||||
number?: 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)
|
// 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) {
|
if (data.adjacent_parcels && includeAdjacent && data.adjacent_parcels.length > 0) {
|
||||||
// Fetch geometries for each adjacent parcel
|
const adjacentGeometries: ParcelGeometry[] = [];
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (import.meta.env.DEV) {
|
data.adjacent_parcels.forEach((adjacent) => {
|
||||||
console.log(`🔍 Fetching geometry for adjacent parcel: ${searchLocation}`);
|
if (import.meta.env.DEV) {
|
||||||
}
|
console.log(`🔍 Processing adjacent parcel ${adjacent.id}:`, {
|
||||||
|
hasGeometryGeoJson: !!adjacent.geometry_geojson,
|
||||||
const adjResponse = await api.get('/api/realestate/parcel/search', {
|
hasPerimeter: !!adjacent.perimeter,
|
||||||
params: {
|
geometryGeoJson: adjacent.geometry_geojson,
|
||||||
location: searchLocation,
|
perimeter: adjacent.perimeter
|
||||||
include_adjacent: false // Don't fetch adjacent of adjacent
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const adjData: ParcelSearchResponse = adjResponse.data;
|
let adjCoordinates: MapPoint[] = [];
|
||||||
let adjCoordinates: MapPoint[] = [];
|
|
||||||
|
|
||||||
// Extract coordinates from adjacent parcel
|
// Extract coordinates from geometry_geojson if available
|
||||||
if (adjData.map_view?.geometry_geojson?.geometry?.coordinates) {
|
if (adjacent.geometry_geojson?.geometry?.coordinates) {
|
||||||
const coords = adjData.map_view.geometry_geojson.geometry.coordinates[0];
|
const coords = adjacent.geometry_geojson.geometry.coordinates[0];
|
||||||
if (Array.isArray(coords)) {
|
if (Array.isArray(coords) && coords.length > 0) {
|
||||||
adjCoordinates = coords.map((coord: number[]) => ({
|
adjCoordinates = coords.map((coord: number[]) => ({
|
||||||
x: coord[0],
|
x: coord[0],
|
||||||
y: coord[1]
|
y: coord[1]
|
||||||
}));
|
|
||||||
}
|
|
||||||
} else if (adjData.parcel.perimeter?.punkte) {
|
|
||||||
adjCoordinates = adjData.parcel.perimeter.punkte.map((p) => ({
|
|
||||||
x: p.x,
|
|
||||||
y: p.y
|
|
||||||
}));
|
}));
|
||||||
|
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) {
|
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,
|
id: adjacent.id,
|
||||||
egrid: adjacent.egrid,
|
egrid: adjacent.egrid,
|
||||||
number: adjacent.number,
|
number: adjacent.number,
|
||||||
coordinates: adjCoordinates,
|
coordinates: adjCoordinates,
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
isAdjacent: true
|
isAdjacent: true
|
||||||
};
|
});
|
||||||
} catch (err) {
|
} else if (import.meta.env.DEV) {
|
||||||
// If fetching fails, log error but don't add parcel
|
console.warn(`⚠️ Adjacent parcel ${adjacent.id} has insufficient geometry data:`, {
|
||||||
if (import.meta.env.DEV) {
|
coordCount: adjCoordinates.length,
|
||||||
console.error(`❌ Failed to fetch geometry for adjacent parcel ${adjacent.id}:`, err);
|
hasGeometryGeoJson: !!adjacent.geometry_geojson,
|
||||||
}
|
hasPerimeter: !!adjacent.perimeter,
|
||||||
return null;
|
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) {
|
if (import.meta.env.DEV) {
|
||||||
console.log(`📦 Adjacent parcels summary:`, {
|
console.log(`📦 Adjacent parcels summary:`, {
|
||||||
requested: data.adjacent_parcels.length,
|
requested: data.adjacent_parcels.length,
|
||||||
fetched: adjacentGeometries.filter(g => g !== null).length,
|
valid: adjacentGeometries.length,
|
||||||
valid: validAdjacentGeometries.length,
|
geometries: adjacentGeometries.map(g => ({
|
||||||
geometries: validAdjacentGeometries.map(g => ({
|
|
||||||
id: g.id,
|
id: g.id,
|
||||||
number: g.number,
|
number: g.number,
|
||||||
coordCount: g.coordinates.length
|
coordCount: g.coordinates.length
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add adjacent parcels to geometries array
|
// Add adjacent parcels to geometries array
|
||||||
geometries.push(...validAdjacentGeometries);
|
geometries.push(...adjacentGeometries);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update parcel geometries with all parcels (main + adjacent)
|
// 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) => {
|
const handleParcelClick = useCallback(async (parcelId: string) => {
|
||||||
// Re-search for this specific parcel with adjacent parcels
|
// Find the clicked parcel in the geometries
|
||||||
if (selectedParcel) {
|
const clickedParcel = parcelGeometries.find(p => p.id === parcelId);
|
||||||
const locationString = selectedParcel.parcel.centroid
|
|
||||||
? `${selectedParcel.parcel.centroid.x},${selectedParcel.parcel.centroid.y}`
|
if (clickedParcel && clickedParcel.coordinates.length > 0) {
|
||||||
: locationInput;
|
// Use a point inside the parcel (first coordinate is always on the boundary, which is inside)
|
||||||
await searchParcel(locationString, true);
|
// 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
|
* Process natural language command
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue