diff --git a/check.sh b/check.sh index 1643930..34a7968 100755 --- a/check.sh +++ b/check.sh @@ -23,6 +23,7 @@ step "Python unit tests" uv run pytest \ step "Frontend lint: ESLint" npm run lint step "Frontend format check: Prettier" npm run format:check step "Frontend typecheck: TypeScript" npm run typecheck + step "Frontend i18n completeness" npm run check:i18n step "Frontend unit tests: Vitest" npm run test ) diff --git a/frontend/package.json b/frontend/package.json index db8b3d6..22ff5fc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,7 +11,8 @@ "lint": "eslint src --ext .ts,.tsx", "lint:fix": "eslint src --ext .ts,.tsx --fix", "format": "prettier --write \"src/**/*.{ts,tsx,css}\"", - "format:check": "prettier --check \"src/**/*.{ts,tsx,css}\"" + "format:check": "prettier --check \"src/**/*.{ts,tsx,css}\"", + "check:i18n": "node scripts/check-translations.mjs" }, "dependencies": { "@deck.gl/core": "^9.0.0", diff --git a/frontend/public/video/poster.jpg b/frontend/public/video/poster.jpg index b759748..039f491 100644 Binary files a/frontend/public/video/poster.jpg and b/frontend/public/video/poster.jpg differ diff --git a/frontend/public/video/recording.mp4 b/frontend/public/video/recording.mp4 index 2afa0ce..17e3a76 100644 Binary files a/frontend/public/video/recording.mp4 and b/frontend/public/video/recording.mp4 differ diff --git a/frontend/scripts/check-translations.mjs b/frontend/scripts/check-translations.mjs new file mode 100644 index 0000000..c68effd --- /dev/null +++ b/frontend/scripts/check-translations.mjs @@ -0,0 +1,259 @@ +#!/usr/bin/env node +// Validates that every translation file under src/i18n is complete and consistent. +// +// Checks: +// 1. Locales declared in SUPPORTED_LANGUAGES (index.ts) match the files in locales/ +// and the language records in descriptions.ts / details.ts. +// 2. Every leaf key in en.ts is present and non-empty in every other locale. +// 3. Every {{placeholder}} and HTML tag in an English string also appears, +// with the same multiset, in the translated string. +// 4. descriptions.ts and details.ts: the union of feature-name keys across +// languages is treated as canonical; every language must cover all of them. +// +// The script parses the TypeScript source with the compiler API and walks the +// AST — no runtime import, no transpilation, no temp files. Run it with: +// node frontend/scripts/check-translations.mjs + +import { readFileSync, readdirSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; +import ts from 'typescript'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const I18N_DIR = join(__dirname, '..', 'src', 'i18n'); +const LOCALES_DIR = join(I18N_DIR, 'locales'); + +const PLACEHOLDER_RE = /\{\{\s*[a-zA-Z_][\w]*\s*\}\}/g; +const HTML_TAG_RE = /<\/?[a-zA-Z][\w]*\b[^>]*>/g; + +const errors = []; +const warnings = []; +const fail = (msg) => errors.push(msg); +const warn = (msg) => warnings.push(msg); + +function parseFile(path) { + const src = readFileSync(path, 'utf8'); + return ts.createSourceFile(path, src, ts.ScriptTarget.Latest, true); +} + +// Recursively turn a TS literal expression into a plain JS value. +// Returns undefined for nodes we don't understand — callers must check. +function literalToJs(node) { + if (!node) return undefined; + if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) return node.text; + if (ts.isAsExpression(node) || ts.isParenthesizedExpression(node)) { + return literalToJs(node.expression); + } + if (ts.isObjectLiteralExpression(node)) { + const out = {}; + for (const prop of node.properties) { + if (!ts.isPropertyAssignment(prop)) continue; + const k = prop.name; + let key; + if (ts.isIdentifier(k)) key = k.text; + else if (ts.isStringLiteral(k) || ts.isNoSubstitutionTemplateLiteral(k)) key = k.text; + else continue; + out[key] = literalToJs(prop.initializer); + } + return out; + } + if (ts.isArrayLiteralExpression(node)) { + return node.elements.map((e) => literalToJs(e)); + } + return undefined; +} + +function findVarInitializer(sourceFile, name) { + let result; + function visit(node) { + if (ts.isVariableStatement(node)) { + for (const decl of node.declarationList.declarations) { + if (ts.isIdentifier(decl.name) && decl.name.text === name) { + result = decl.initializer; + } + } + } + ts.forEachChild(node, visit); + } + visit(sourceFile); + return result; +} + +function readSupportedLanguages() { + const sf = parseFile(join(I18N_DIR, 'index.ts')); + const init = findVarInitializer(sf, 'SUPPORTED_LANGUAGES'); + if (!init) throw new Error('Could not find SUPPORTED_LANGUAGES in index.ts'); + const arr = literalToJs(init); + if (!Array.isArray(arr)) throw new Error('SUPPORTED_LANGUAGES is not an array literal'); + return arr.map((entry) => entry.code); +} + +function readLocale(code) { + const path = join(LOCALES_DIR, `${code}.ts`); + const sf = parseFile(path); + const init = findVarInitializer(sf, code); + if (!init) throw new Error(`Could not find const ${code} in ${path}`); + const obj = literalToJs(init); + if (!obj || typeof obj !== 'object') throw new Error(`${code}.ts: not an object literal`); + return obj; +} + +function readNamedRecord(file, varName) { + const sf = parseFile(join(I18N_DIR, file)); + const init = findVarInitializer(sf, varName); + if (!init) throw new Error(`Could not find ${varName} in ${file}`); + const obj = literalToJs(init); + if (!obj || typeof obj !== 'object') throw new Error(`${file}: ${varName} is not an object`); + return obj; +} + +function flatten(obj, prefix = '', out = new Map()) { + for (const [k, v] of Object.entries(obj)) { + const path = prefix ? `${prefix}.${k}` : k; + if (v !== null && typeof v === 'object' && !Array.isArray(v)) { + flatten(v, path, out); + } else { + out.set(path, v); + } + } + return out; +} + +function tokenMultiset(s, re) { + const matches = String(s).match(re) || []; + // Normalise whitespace inside placeholders so '{{ count }}' == '{{count}}'. + return matches.map((t) => t.replace(/\s+/g, '')).sort(); +} + +function multisetsEqual(a, b) { + if (a.length !== b.length) return false; + for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false; + return true; +} + +function checkLeafConsistency(path, enValue, trValue, lang) { + if (typeof trValue !== 'string') { + fail(`[${lang}] ${path}: missing translation`); + return; + } + if (trValue.trim() === '') { + fail(`[${lang}] ${path}: empty translation`); + return; + } + for (const [re, label] of [ + [PLACEHOLDER_RE, 'placeholder'], + [HTML_TAG_RE, 'HTML tag'], + ]) { + const want = tokenMultiset(enValue, re); + const got = tokenMultiset(trValue, re); + if (!multisetsEqual(want, got)) { + fail( + `[${lang}] ${path}: ${label} mismatch — en=${JSON.stringify(want)} ` + + `${lang}=${JSON.stringify(got)}` + ); + } + } +} + +function checkLocales(supportedCodes) { + const localeFiles = readdirSync(LOCALES_DIR) + .filter((f) => f.endsWith('.ts')) + .map((f) => f.replace(/\.ts$/, '')); + + for (const code of supportedCodes) { + if (!localeFiles.includes(code)) { + fail(`SUPPORTED_LANGUAGES lists "${code}" but locales/${code}.ts is missing`); + } + } + for (const code of localeFiles) { + if (!supportedCodes.includes(code)) { + warn(`locales/${code}.ts exists but is not listed in SUPPORTED_LANGUAGES`); + } + } + + const en = flatten(readLocale('en')); + for (const code of supportedCodes) { + if (code === 'en') continue; + if (!localeFiles.includes(code)) continue; + const tr = flatten(readLocale(code)); + for (const [path, enValue] of en) { + checkLeafConsistency(path, enValue, tr.get(path), code); + } + for (const path of tr.keys()) { + if (!en.has(path)) warn(`[${code}] ${path}: extra key not in en.ts`); + } + } +} + +function checkRecordCoverage(file, varName, supportedCodes, serverKeys) { + const record = readNamedRecord(file, varName); + const expected = supportedCodes.filter((c) => c !== 'en'); + const present = Object.keys(record); + + for (const code of expected) { + if (!present.includes(code)) { + fail(`${file}: missing language record "${code}"`); + } + } + for (const code of present) { + if (!expected.includes(code)) { + warn(`${file}: unexpected language record "${code}"`); + } + } + + // Use the union of feature-name keys across languages as canonical. + const union = new Set(); + for (const code of expected) { + if (record[code]) for (const k of Object.keys(record[code])) union.add(k); + } + + for (const code of expected) { + const langKeys = new Set(Object.keys(record[code] ?? {})); + for (const key of union) { + if (!langKeys.has(key)) { + fail(`${file} [${code}]: missing translation for "${key}"`); + } else { + const v = record[code][key]; + if (typeof v !== 'string' || v.trim() === '') { + fail(`${file} [${code}]: empty translation for "${key}"`); + } + } + } + } + + // Every key here must also be a translatable feature name in en.ts > server. + // Otherwise the description is unreachable — ts() looks up server.${name}. + for (const key of union) { + if (!serverKeys.has(key)) { + fail(`${file}: key "${key}" has no matching entry in en.ts > server`); + } + } +} + +function main() { + let supportedCodes; + try { + supportedCodes = readSupportedLanguages(); + } catch (e) { + console.error(`fatal: ${e.message}`); + process.exit(2); + } + + checkLocales(supportedCodes); + const en = readLocale('en'); + const serverKeys = new Set(Object.keys(en.server ?? {})); + checkRecordCoverage('descriptions.ts', 'descriptions', supportedCodes, serverKeys); + checkRecordCoverage('details.ts', 'details', supportedCodes, serverKeys); + + for (const w of warnings) console.warn(`warn: ${w}`); + if (errors.length > 0) { + for (const e of errors) console.error(`error: ${e}`); + console.error(`\n${errors.length} translation error(s).`); + process.exit(1); + } + console.log( + `i18n OK — ${supportedCodes.length} languages, ${warnings.length} warning(s).` + ); +} + +main(); diff --git a/frontend/src/components/home/HomePage.tsx b/frontend/src/components/home/HomePage.tsx index f9b80a0..072d18f 100644 --- a/frontend/src/components/home/HomePage.tsx +++ b/frontend/src/components/home/HomePage.tsx @@ -15,11 +15,13 @@ import { TickerValue } from '../ui/TickerValue'; import { ChartBarIcon, CheckIcon, + ChevronIcon, ClipboardIcon, DownloadIcon, FilterIcon, LogoIcon, MapPinIcon, + PlayIcon, RouteIcon, } from '../ui/icons'; import { trackEvent } from '../../lib/analytics'; @@ -84,7 +86,9 @@ function highlightBrandText(text: string) { function ProductDemoVideo() { const sectionRef = useRef(null); + const videoRef = useRef(null); const [shouldLoadVideo, setShouldLoadVideo] = useState(false); + const [isVideoPlaying, setIsVideoPlaying] = useState(false); useEffect(() => { const section = sectionRef.current; @@ -108,14 +112,30 @@ function ProductDemoVideo() { return () => observer.disconnect(); }, [shouldLoadVideo]); + const playVideo = () => { + const video = videoRef.current; + setShouldLoadVideo(true); + if (!video) return; + + if (!video.getAttribute('src')) { + video.src = PRODUCT_DEMO_VIDEO_SRC; + video.load(); + } + + void video.play().catch(() => { + setIsVideoPlaying(false); + }); + }; + return (
-
+
); @@ -131,7 +166,7 @@ function ProductDemoVideo() { const DEMO_FEATURES: FeatureMeta[] = [ { - name: 'Last known price', + name: 'Estimated price', type: 'numeric', group: 'Properties', min: 0, @@ -165,13 +200,13 @@ const DEMO_FEATURES: FeatureMeta[] = [ suffix: ' dB', }, { - name: 'Distance to nearest train or tube station (km)', + name: 'Travel time to nearest train or tube station (min)', type: 'numeric', group: 'Transport', min: 0, - max: 5, - step: 0.1, - suffix: ' km', + max: 60, + step: 1, + suffix: ' min', }, ]; @@ -234,15 +269,6 @@ const HOUSE_PRICE_BREAKDOWN = [ { label: '£/sq ft', value: '£872', helper: 'local median' }, ]; -const RECENT_SALES = [ - { address: '2-bed flat, Lexham Gardens', price: '£612k', meta: 'Mar 2025 · 710 sq ft' }, - { address: '1-bed flat, Earl\'s Court Road', price: '£485k', meta: 'Feb 2025 · 544 sq ft' }, - { address: '3-bed maisonette, Warwick Road', price: '£918k', meta: 'Jan 2025 · 1,020 sq ft' }, - { address: 'Studio, Courtfield Gardens', price: '£365k', meta: 'Dec 2024 · 361 sq ft' }, - { address: '2-bed flat, Collingham Place', price: '£755k', meta: 'Nov 2024 · 814 sq ft' }, - { address: '4-bed terrace, Nevern Square', price: '£1.64m', meta: 'Oct 2024 · 1,780 sq ft' }, -]; - const PRICE_SIGNALS = [ ['5-year change', '+22%'], ['Last 12 months', '+2.1%'], @@ -295,9 +321,9 @@ const ENGLAND_SHOWCASE_POLYGON: number[][] = [ ]; const SHOWCASE_MAP_START_VIEW: ViewState = { - longitude: -1.52, - latitude: 52.92, - zoom: 5.55, + longitude: -1.7, + latitude: 52.7, + zoom: 6.6, pitch: 0, bearing: 0, }; @@ -386,10 +412,10 @@ function interpolateViewState(progress: number): ViewState { } function demoSliderStep(feature: FeatureMeta): number { - if (feature.name === 'Last known price') return 1000; + if (feature.name === 'Estimated price') return 1000; if (feature.name === 'Noise (dB)') return 0.05; if (feature.name === 'Good+ primary schools within 2km') return 0.01; - if (feature.name === 'Distance to nearest train or tube station (km)') return 0.01; + if (feature.name === 'Travel time to nearest train or tube station (min)') return 0.1; return feature.step ?? 1; } @@ -420,7 +446,7 @@ function FilterPreviewRow({ feature, value, rangeLabel, - withoutLabel, + withoutCount, index, isTightened, onValueChange, @@ -428,19 +454,21 @@ function FilterPreviewRow({ feature: FeatureMeta; value: [number, number]; rangeLabel: string; - withoutLabel: string; + withoutCount: number; index: number; isTightened: boolean; onValueChange: (value: [number, number]) => void; }) { + const { t } = useTranslation(); const style = FILTER_ROW_STYLES[index % FILTER_ROW_STYLES.length]; - const shortLabel = - { - 'Last known price': 'Price', - 'Noise (dB)': 'Noise', - 'Good+ primary schools within 2km': 'Schools', - 'Distance to nearest train or tube station (km)': 'Station', - }[feature.name] ?? feature.name; + const shortLabelKeys = { + 'Estimated price': 'home.showcaseFeaturePriceShort', + 'Noise (dB)': 'home.showcaseFeatureNoiseShort', + 'Good+ primary schools within 2km': 'home.showcaseFeatureSchoolsShort', + 'Travel time to nearest train or tube station (min)': 'home.showcaseFeatureTravelShort', + } as const; + const shortLabelKey = shortLabelKeys[feature.name as keyof typeof shortLabelKeys]; + const shortLabel = shortLabelKey ? t(shortLabelKey) : undefined; return (
- +
{rangeLabel} @@ -462,7 +490,9 @@ function FilterPreviewRow({ - {withoutLabel} + + + {withoutCount.toLocaleString()} + {' without this filter'}
@@ -484,7 +514,7 @@ function formatCompactCurrency(value: number): string { } function formatDemoRange(feature: FeatureMeta, value: [number, number]): string { - if (feature.name === 'Last known price') { + if (feature.name === 'Estimated price') { return `${formatCompactCurrency(value[0])} - ${formatCompactCurrency(value[1])}`; } if (feature.name === 'Noise (dB)') { @@ -493,8 +523,8 @@ function formatDemoRange(feature: FeatureMeta, value: [number, number]): string if (feature.name === 'Good+ primary schools within 2km') { return `${Math.round(value[0])}+ good primaries nearby`; } - if (feature.name === 'Distance to nearest train or tube station (km)') { - return `Within ${value[1].toFixed(1)} km of rail`; + if (feature.name === 'Travel time to nearest train or tube station (min)') { + return `Within ${Math.round(value[1])} min of rail`; } return `${value[0]} - ${value[1]}`; } @@ -539,32 +569,36 @@ function FilterOnlyScreen({ isActive }: { isActive: boolean }) { [240000, 535000], [135000, 485000], [285000, 610000], + [0, 650000], ] as [number, number][], - without: [41820, 50622, 24860, 18645, 29796], + without: [41820, 50622, 24860, 18645, 29796, 41820], }, { feature: DEMO_FEATURES[3], values: [ [40, 58], [43, 52], + [40, 58], ] as [number, number][], - without: [19412, 8706], + without: [19412, 8706, 19412], + }, + { + feature: DEMO_FEATURES[4], + values: [ + [0, 60], + [5, 25], + [0, 60], + ] as [number, number][], + without: [11209, 4118, 11209], }, { feature: DEMO_FEATURES[2], values: [ [1, 8], [2, 6], + [1, 8], ] as [number, number][], - without: [13608, 6944], - }, - { - feature: DEMO_FEATURES[4], - values: [ - [0, 1.4], - [0.25, 0.9], - ] as [number, number][], - without: [11209, 4118], + without: [13608, 6944, 13608], }, ], [] @@ -617,15 +651,15 @@ function FilterOnlyScreen({ isActive }: { isActive: boolean }) { }; return ( -
-
+
+
{rows.map((row, index) => (
= 3 ? 'hidden sm:block' : undefined}> updateFilter(index, value)} @@ -671,7 +705,7 @@ function EnglandHexMapScreen({ isActive }: { isActive: boolean }) { }, [isActive]); return ( -
+
+
-
+
@@ -771,22 +805,6 @@ function RightPaneOnlyScreen({
-
- {[ - ['Sales', '1,284'], - ['Median sold', '£492k'], - ['Scout rank', '#3'], - ].map(([label, value]) => ( -
-
- {label} -
-
- {value} -
-
- ))} -
-
+
@@ -807,7 +825,7 @@ function RightPaneOnlyScreen({ {HOUSE_PRICE_BREAKDOWN.map((item) => (
{item.label} @@ -823,35 +841,7 @@ function RightPaneOnlyScreen({
))}
-
-
- - Recent sold prices - - within 0.5 mi -
-
- {RECENT_SALES.map((sale, index) => ( -
= 3 ? 'hidden sm:flex' : 'flex' - }`} - > -
-
- {sale.address} -
-
{sale.meta}
-
-
- {sale.price} -
-
- ))} -
-
-
+
{PRICE_SIGNALS.map(([label, value]) => (
{label}
@@ -862,7 +852,7 @@ function RightPaneOnlyScreen({ ))}
-
+
Journey routes @@ -876,7 +866,7 @@ function RightPaneOnlyScreen({ showGoogleMapsLink={false} />
-
+
@@ -892,14 +882,14 @@ function RightPaneOnlyScreen({ formatLabel={(value) => value.toFixed(0)} />
-
+
{t('home.showcaseStep3Stat2Label')}
-
+
@@ -928,10 +918,10 @@ function ScoutScreen() { const { t } = useTranslation(); return ( -
-
+
+
-
+
@@ -973,13 +963,16 @@ function ScoutScreen() { aria-hidden="true" > - + -
-
- - {t('home.showcaseStep4Title')} -
-
+
+
{t('home.showcaseStep4Conclusion')}
@@ -1045,9 +1037,9 @@ function DashboardShowcase({ const showStageHeader = activeStep !== 3; return ( -
+
{showStageHeader && ( -
+
@@ -1086,23 +1078,9 @@ function DashboardShowcase({ function HeroProductShowcase() { const { t } = useTranslation(); const [activeStep, setActiveStep] = useState(0); - const isStagePausedRef = useRef(false); + const [isStagePaused, setIsStagePaused] = useState(false); const inspectUserScrolledRef = useRef(false); - useEffect(() => { - const prefersReducedMotion = - typeof window !== 'undefined' && - window.matchMedia('(prefers-reduced-motion: reduce)').matches; - if (prefersReducedMotion) return; - - const timer = window.setInterval(() => { - if (isStagePausedRef.current) return; - setActiveStep((step) => (step + 1) % SHOWCASE_STEP_COUNT); - }, SHOWCASE_INTERVAL_MS); - - return () => window.clearInterval(timer); - }, []); - const steps: ShowcaseStep[] = [ { tab: t('home.showcaseStep1Tab'), @@ -1134,22 +1112,14 @@ function HeroProductShowcase() { return (
{ - isStagePausedRef.current = true; - }} - onMouseLeave={() => { - isStagePausedRef.current = false; - }} - onFocus={() => { - isStagePausedRef.current = true; - }} - onBlur={() => { - isStagePausedRef.current = false; - }} + className="dark relative w-full min-w-0 max-w-[58rem] justify-self-center lg:max-w-none lg:justify-self-stretch" + onMouseEnter={() => setIsStagePaused(true)} + onMouseLeave={() => setIsStagePaused(false)} + onFocus={() => setIsStagePaused(true)} + onBlur={() => setIsStagePaused(false)} aria-label={t('home.showcaseContext')} > -
+
{steps.map((step, index) => { @@ -1184,7 +1154,11 @@ function HeroProductShowcase() { className="showcase-progress block h-full origin-left bg-teal-400" style={{ animationDuration: `${SHOWCASE_INTERVAL_MS}ms`, + animationPlayState: isStagePaused ? 'paused' : 'running', }} + onAnimationEnd={() => + setActiveStep((step) => (step + 1) % SHOWCASE_STEP_COUNT) + } /> )} @@ -1255,15 +1229,39 @@ export default function HomePage({ return () => clearTimeout(timer); }, []); + const scrollToProductDemoVideo = () => { + const target = document.getElementById(PRODUCT_DEMO_SECTION_ID); + if (!target) return; + const scroller = target.closest('.overflow-y-auto') as HTMLElement | null; + if (!scroller) return; + const start = scroller.scrollTop; + const end = + start + + target.getBoundingClientRect().top - + scroller.getBoundingClientRect().top + + 24; + const distance = end - start; + const duration = 1200; + let startTime: number; + const step = (time: number) => { + if (!startTime) startTime = time; + const p = Math.min((time - startTime) / duration, 1); + const ease = p < 0.5 ? 4 * p * p * p : 1 - Math.pow(-2 * p + 2, 3) / 2; + scroller.scrollTop = start + distance * ease; + if (p < 1) requestAnimationFrame(step); + }; + requestAnimationFrame(step); + }; + return (
{/* Hero */}
-
-
-
+
+
+

{t('home.heroEyebrow')}

{t('home.heroTitle1')}{' '} @@ -1290,27 +1288,7 @@ export default function HomePage({

-
+
diff --git a/frontend/src/components/map/Map.tsx b/frontend/src/components/map/Map.tsx index bee8b9a..d054a53 100644 --- a/frontend/src/components/map/Map.tsx +++ b/frontend/src/components/map/Map.tsx @@ -67,6 +67,7 @@ interface MapProps { currentLocation?: { lat: number; lng: number } | null; bounds?: Bounds | null; hideLegend?: boolean; + hideLocationSearch?: boolean; travelTimeEntries?: TravelTimeEntry[]; densityLabel?: string; totalCount?: number; @@ -173,6 +174,7 @@ export default memo(function Map({ currentLocation, bounds: viewportBounds, hideLegend = false, + hideLocationSearch = false, travelTimeEntries = EMPTY_TRAVEL_ENTRIES, densityLabel: densityLabelProp, totalCount: totalCountProp, @@ -231,6 +233,7 @@ export default memo(function Map({ }, [viewState, dimensions, onViewChange]); const handleMove = useCallback((evt: { viewState: ViewState }) => { + if (window.__demoRecording) window.__demoMapIdle = false; setInternalViewState((prev) => { const next = evt.viewState; // Skip re-render when viewport values haven't changed (e.g. container resize @@ -249,6 +252,14 @@ export default memo(function Map({ }); }, []); + const handleIdle = useCallback(() => { + if (screenshotMode) window.__map_idle = true; + if (window.__demoRecording) { + window.__demoMapIdle = true; + window.__demoMapIdleVersion = (window.__demoMapIdleVersion ?? 0) + 1; + } + }, [screenshotMode]); + const handleFlyTo = useCallback((lat: number, lng: number, zoom: number) => { setInternalViewState((prev) => ({ ...prev, latitude: lat, longitude: lng, zoom })); }, []); @@ -293,13 +304,7 @@ export default memo(function Map({ {...viewState} onMove={handleMove} onLoad={undefined} - onIdle={ - screenshotMode - ? () => { - window.__map_idle = true; - } - : undefined - } + onIdle={handleIdle} mapStyle={mapStyle} style={{ width: '100%', height: '100%' }} attributionControl={false} @@ -362,12 +367,14 @@ export default memo(function Map({ ) : ( <>
- + {!hideLocationSearch && ( + + )} {!hideLegend && (viewFeature && colorRange ? ( viewFeature.startsWith('tt_') ? ( diff --git a/frontend/src/components/map/MapPage.tsx b/frontend/src/components/map/MapPage.tsx index e7873af..21e8a8e 100644 --- a/frontend/src/components/map/MapPage.tsx +++ b/frontend/src/components/map/MapPage.tsx @@ -33,6 +33,7 @@ import { apiUrl, authHeaders, buildFilterString, logNonAbortError } from '../../ import { useFilterCounts } from '../../hooks/useFilterCounts'; import { ts } from '../../i18n/server'; import { trackEvent } from '../../lib/analytics'; +import { canWheelScrollInsideTarget } from '../../lib/dom-scroll'; import { INITIAL_VIEW_STATE } from '../../lib/consts'; import { getSchoolBackendFeatureName } from '../../lib/school-filter'; import { useLicense } from '../../hooks/useLicense'; @@ -54,6 +55,18 @@ const MapPageSelectionPane = lazy(() => const UpgradeModal = lazy(() => import('../ui/UpgradeModal')); const Joyride = lazy(() => import('react-joyride')); +declare global { + interface Window { + __demoRecording?: boolean; + __demoOpenBestHexagon?: () => string | null; + __demoMapSettled?: boolean; + __demoMapSettleVersion?: number; + __demoMapIdle?: boolean; + __demoMapIdleVersion?: number; + __demoSelectionReady?: boolean; + } +} + function MapFallback() { return (
@@ -218,6 +231,9 @@ export default function MapPage({ travelTimeEntries: entries, shareCode, }); + const demoMapHasData = mapData.usePostcodeView + ? mapData.postcodeData.length > 0 + : mapData.data.length > 0; const handleAiFilterSubmit = useCallback( async (query: string) => { @@ -416,6 +432,48 @@ export default function MapPage({ setRightPaneTab(initialTab); }, []); // eslint-disable-line react-hooks/exhaustive-deps + useEffect(() => { + if (!window.__demoRecording) return; + void import('./MapPageSelectionPane'); + void import('./AreaPane'); + void import('./PropertiesPane'); + }, []); + + useEffect(() => { + if (!window.__demoRecording) return; + window.__demoMapSettled = !mapData.loading && demoMapHasData; + if (window.__demoMapSettled) { + window.__demoMapSettleVersion = (window.__demoMapSettleVersion ?? 0) + 1; + } + return () => { + window.__demoMapSettled = false; + }; + }, [demoMapHasData, mapData.loading]); + + useEffect(() => { + if (!window.__demoRecording) return; + window.__demoSelectionReady = Boolean(selectedHexagon && areaStats && !loadingAreaStats); + return () => { + window.__demoSelectionReady = false; + }; + }, [areaStats, loadingAreaStats, selectedHexagon]); + + useEffect(() => { + if (!window.__demoRecording) return; + window.__demoOpenBestHexagon = () => { + const best = mapData.data.reduce<(typeof mapData.data)[number] | null>((winner, item) => { + if (!winner || item.count > winner.count) return item; + return winner; + }, null); + if (!best) return null; + handleHexagonClick(best.h3); + return best.h3; + }; + return () => { + delete window.__demoOpenBestHexagon; + }; + }, [handleHexagonClick, mapData.data]); + // Navigate to a specific postcode on mount (e.g. from saved properties) useEffect(() => { if (!initialPostcode) return; @@ -451,7 +509,10 @@ export default function MapPage({ // Prevent browser back/forward navigation from horizontal trackpad swipes useEffect(() => { const handleWheel = (e: WheelEvent) => { - if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) { + if ( + Math.abs(e.deltaX) > Math.abs(e.deltaY) && + !canWheelScrollInsideTarget(e.target, e.deltaX, e.deltaY) + ) { e.preventDefault(); } }; @@ -873,6 +934,7 @@ export default function MapPage({ currentLocation={currentLocation} bounds={mapData.bounds} hideLegend + hideLocationSearch={mobileDrawerOpen && !!selectedHexagon} travelTimeEntries={entries} /> @@ -898,7 +960,7 @@ export default function MapPage({ {poiPaneOpen && ( -
+
{renderPOIPane()}
)} @@ -1045,7 +1107,7 @@ export default function MapPage({ {/* Floating POI panel */} {poiPaneOpen && ( -
+
{renderPOIPane()}
)} @@ -1062,6 +1124,7 @@ export default function MapPage({ onClose={handleCloseSelection} renderAreaPane={renderAreaPane} renderPropertiesPane={renderPropertiesPane} + demoReady={Boolean(areaStats && !loadingAreaStats)} /> )} diff --git a/frontend/src/components/map/MapPageSelectionPane.tsx b/frontend/src/components/map/MapPageSelectionPane.tsx index dc6d697..4a56558 100644 --- a/frontend/src/components/map/MapPageSelectionPane.tsx +++ b/frontend/src/components/map/MapPageSelectionPane.tsx @@ -18,6 +18,7 @@ interface MapPageSelectionPaneProps { onClose: () => void; renderAreaPane: () => ReactNode; renderPropertiesPane: () => ReactNode; + demoReady?: boolean; } export function MapPageSelectionPane({ @@ -29,10 +30,12 @@ export function MapPageSelectionPane({ onClose, renderAreaPane, renderPropertiesPane, + demoReady = false, }: MapPageSelectionPaneProps) { return (
diff --git a/frontend/src/components/map/POIPane.tsx b/frontend/src/components/map/POIPane.tsx index baf6832..366c9a2 100644 --- a/frontend/src/components/map/POIPane.tsx +++ b/frontend/src/components/map/POIPane.tsx @@ -90,7 +90,7 @@ export default function POIPane({ const selectedCount = selectedCategories.size; return ( -
+
@@ -150,7 +150,7 @@ export default function POIPane({ )}
-
+
{children}
diff --git a/frontend/src/components/ui/icons/PlayIcon.tsx b/frontend/src/components/ui/icons/PlayIcon.tsx new file mode 100644 index 0000000..1bc28b6 --- /dev/null +++ b/frontend/src/components/ui/icons/PlayIcon.tsx @@ -0,0 +1,11 @@ +interface IconProps { + className?: string; +} + +export function PlayIcon({ className = 'w-4 h-4' }: IconProps) { + return ( + + ); +} diff --git a/frontend/src/components/ui/icons/index.ts b/frontend/src/components/ui/icons/index.ts index 3b5bf0a..1506d39 100644 --- a/frontend/src/components/ui/icons/index.ts +++ b/frontend/src/components/ui/icons/index.ts @@ -20,6 +20,7 @@ export { LogoIcon } from './LogoIcon'; export { MapPinIcon } from './MapPinIcon'; export { MenuIcon } from './MenuIcon'; export { MoonIcon } from './MoonIcon'; +export { PlayIcon } from './PlayIcon'; export { PlusIcon } from './PlusIcon'; export { RouteIcon } from './RouteIcon'; export { SearchIcon } from './SearchIcon'; diff --git a/frontend/src/i18n/locales/de.ts b/frontend/src/i18n/locales/de.ts index 8b52d56..8c80784 100644 --- a/frontend/src/i18n/locales/de.ts +++ b/frontend/src/i18n/locales/de.ts @@ -348,6 +348,10 @@ const de: Translations = { seeTheDifference: 'So funktioniert es', showcaseHeader: 'So funktioniert es', showcaseContext: 'So funktioniert Perfect Postcode', + showcaseFeaturePriceShort: 'Preis', + showcaseFeatureNoiseShort: 'Lärm', + showcaseFeatureSchoolsShort: 'Schulen', + showcaseFeatureTravelShort: 'Fahrzeit', showcaseStep1Tab: 'Filtern', showcaseStep1Title: 'Aus vagen Wünschen eine präzise Suche machen', showcaseStep1Body: @@ -801,6 +805,7 @@ const de: Translations = { 'Property type': 'Immobilientyp', 'Leasehold/Freehold': 'Erbbaurecht/Volleigentum', 'Last known price': 'Letzter bekannter Preis', + 'Estimated price': 'Geschätzter Preis', 'Estimated current price': 'Geschätzter aktueller Preis', 'Price per sqm': 'Preis pro m²', 'Est. price per sqm': 'Gesch. Preis pro m²', @@ -817,6 +822,8 @@ const de: Translations = { // ─ Feature names (Transport) ─ 'Distance to nearest train or tube station (km)': 'Entfernung zum nächsten Bahn- oder U-Bahnhof (km)', + 'Travel time to nearest train or tube station (min)': + 'Fahrzeit zum nächsten Bahn- oder U-Bahnhof (Min.)', // ─ Feature names (Education) ─ 'Good+ primary schools within 2km': 'Gute+ Grundschulen im Umkreis von 2 km', diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index cd36a95..62f508e 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -343,6 +343,10 @@ const en = { seeTheDifference: 'See how it works', showcaseHeader: 'How it works', showcaseContext: 'How Perfect Postcode works', + showcaseFeaturePriceShort: 'Price', + showcaseFeatureNoiseShort: 'Noise', + showcaseFeatureSchoolsShort: 'Schools', + showcaseFeatureTravelShort: 'Travel', showcaseStep1Tab: 'Filter', showcaseStep1Title: 'Turn vague needs into a tight search', showcaseStep1Body: @@ -788,6 +792,7 @@ const en = { 'Property type': 'Property type', 'Leasehold/Freehold': 'Leasehold/Freehold', 'Last known price': 'Last known price', + 'Estimated price': 'Estimated price', 'Estimated current price': 'Estimated current price', 'Price per sqm': 'Price per sqm', 'Est. price per sqm': 'Est. price per sqm', @@ -804,6 +809,8 @@ const en = { // ─ Feature names (Transport) ─ 'Distance to nearest train or tube station (km)': 'Distance to nearest train or tube station (km)', + 'Travel time to nearest train or tube station (min)': + 'Travel time to nearest train or tube station (min)', // ─ Feature names (Education) ─ 'Good+ primary schools within 2km': 'Good+ primary schools within 2km', diff --git a/frontend/src/i18n/locales/fr.ts b/frontend/src/i18n/locales/fr.ts index 54ef02d..e3c70ff 100644 --- a/frontend/src/i18n/locales/fr.ts +++ b/frontend/src/i18n/locales/fr.ts @@ -351,6 +351,10 @@ const fr: Translations = { seeTheDifference: 'Voir comment ça marche', showcaseHeader: 'Comment ça marche', showcaseContext: 'Comment fonctionne Perfect Postcode', + showcaseFeaturePriceShort: 'Prix', + showcaseFeatureNoiseShort: 'Bruit', + showcaseFeatureSchoolsShort: 'Écoles', + showcaseFeatureTravelShort: 'Trajet', showcaseStep1Tab: 'Filtrer', showcaseStep1Title: 'Transformez des besoins vagues en recherche précise', showcaseStep1Body: @@ -802,6 +806,7 @@ const fr: Translations = { 'Property type': 'Type de bien', 'Leasehold/Freehold': 'Bail/Pleine propriété', 'Last known price': 'Dernier prix connu', + 'Estimated price': 'Prix estimé', 'Estimated current price': 'Prix actuel estimé', 'Price per sqm': 'Prix au m²', 'Est. price per sqm': 'Prix estimé au m²', @@ -818,6 +823,8 @@ const fr: Translations = { // ─ Feature names (Transport) ─ 'Distance to nearest train or tube station (km)': 'Distance à la gare ou station de métro la plus proche (km)', + 'Travel time to nearest train or tube station (min)': + 'Temps de trajet jusqu’à la gare ou station de métro la plus proche (min)', // ─ Feature names (Education) ─ 'Good+ primary schools within 2km': 'Écoles primaires Bien+ dans un rayon de 2 km', diff --git a/frontend/src/i18n/locales/hi.ts b/frontend/src/i18n/locales/hi.ts index d202e72..2b3c0b6 100644 --- a/frontend/src/i18n/locales/hi.ts +++ b/frontend/src/i18n/locales/hi.ts @@ -323,6 +323,10 @@ const hi: Translations = { seeTheDifference: 'देखें यह कैसे काम करता है', showcaseHeader: 'यह कैसे काम करता है', showcaseContext: 'Perfect Postcode कैसे काम करता है', + showcaseFeaturePriceShort: 'कीमत', + showcaseFeatureNoiseShort: 'शोर', + showcaseFeatureSchoolsShort: 'स्कूल', + showcaseFeatureTravelShort: 'यात्रा', showcaseStep1Tab: 'फिल्टर', showcaseStep1Title: 'अस्पष्ट जरूरतों को सटीक खोज में बदलें', showcaseStep1Body: @@ -738,6 +742,7 @@ const hi: Translations = { 'Property type': 'संपत्ति प्रकार', 'Leasehold/Freehold': 'लीजहोल्ड/फ्रीहोल्ड', 'Last known price': 'अंतिम ज्ञात कीमत', + 'Estimated price': 'अनुमानित कीमत', 'Estimated current price': 'अनुमानित मौजूदा कीमत', 'Price per sqm': 'प्रति वर्ग मी कीमत', 'Est. price per sqm': 'अनु. प्रति वर्ग मी कीमत', @@ -751,6 +756,8 @@ const hi: Translations = { 'Potential energy rating': 'संभावित ऊर्जा रेटिंग', 'Interior height (m)': 'भीतरी ऊंचाई (मी)', 'Distance to nearest train or tube station (km)': 'निकटतम ट्रेन या ट्यूब स्टेशन तक दूरी (किमी)', + 'Travel time to nearest train or tube station (min)': + 'निकटतम ट्रेन या ट्यूब स्टेशन तक यात्रा समय (मिनट)', 'Good+ primary schools within 2km': '2 किमी के अंदर Good+ प्राथमिक स्कूल', 'Good+ secondary schools within 2km': '2 किमी के अंदर Good+ सेकेंडरी स्कूल', 'Good+ primary schools within 5km': '5 किमी के अंदर Good+ प्राथमिक स्कूल', diff --git a/frontend/src/i18n/locales/hu.ts b/frontend/src/i18n/locales/hu.ts index 33f8cb1..53ab83a 100644 --- a/frontend/src/i18n/locales/hu.ts +++ b/frontend/src/i18n/locales/hu.ts @@ -345,6 +345,10 @@ const hu: Translations = { seeTheDifference: 'Így működik', showcaseHeader: 'Így működik', showcaseContext: 'Így működik a Perfect Postcode', + showcaseFeaturePriceShort: 'Ár', + showcaseFeatureNoiseShort: 'Zaj', + showcaseFeatureSchoolsShort: 'Iskolák', + showcaseFeatureTravelShort: 'Utazás', showcaseStep1Tab: 'Szűrés', showcaseStep1Title: 'A homályos igényekből pontos keresés lesz', showcaseStep1Body: @@ -796,6 +800,7 @@ const hu: Translations = { 'Property type': 'Ingatlantípus', 'Leasehold/Freehold': 'Bérleti/Tulajdonjog', 'Last known price': 'Utolsó ismert ár', + 'Estimated price': 'Becsült ár', 'Estimated current price': 'Becsült jelenlegi ár', 'Price per sqm': 'Ár per nm', 'Est. price per sqm': 'Becsült ár per nm', @@ -812,6 +817,8 @@ const hu: Translations = { // ─ Feature names (Transport) ─ 'Distance to nearest train or tube station (km)': 'Távolság a legközelebbi vonat- vagy metróállomástól (km)', + 'Travel time to nearest train or tube station (min)': + 'Utazási idő a legközelebbi vonat- vagy metróállomásig (perc)', // ─ Feature names (Education) ─ 'Good+ primary schools within 2km': 'Jó+ általános iskolák 2 km-en belül', diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index ca76489..336fc25 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -340,6 +340,10 @@ const zh: Translations = { seeTheDifference: '查看使用方式', showcaseHeader: '工作原理', showcaseContext: 'Perfect Postcode 的工作流程', + showcaseFeaturePriceShort: '价格', + showcaseFeatureNoiseShort: '噪声', + showcaseFeatureSchoolsShort: '学校', + showcaseFeatureTravelShort: '出行', showcaseStep1Tab: '筛选', showcaseStep1Title: '把模糊需求变成精准搜索', showcaseStep1Body: @@ -772,6 +776,7 @@ const zh: Translations = { 'Property type': '房产类型', 'Leasehold/Freehold': '租赁产权/永久产权', 'Last known price': '上次成交价', + 'Estimated price': '估计价格', 'Estimated current price': '估计当前价格', 'Price per sqm': '每平方米价格', 'Est. price per sqm': '估计每平方米价格', @@ -787,6 +792,7 @@ const zh: Translations = { // ─ Feature names (Transport) ─ 'Distance to nearest train or tube station (km)': '到最近火车或地铁站的距离(公里)', + 'Travel time to nearest train or tube station (min)': '到最近火车或地铁站的出行时间(分钟)', // ─ Feature names (Education) ─ 'Good+ primary schools within 2km': '2公里内良好+小学数量', diff --git a/frontend/src/index.css b/frontend/src/index.css index cd43391..6246e93 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -135,10 +135,42 @@ h3 { .showcase-progress { animation-name: showcase-progress; animation-timing-function: linear; - animation-iteration-count: infinite; + animation-iteration-count: 1; animation-fill-mode: forwards; } +.hero-roomy-lift { + transform: translateY(0); + transition: transform 0.25s ease; +} + +.hero-scroll-chevron { + display: none; + bottom: 0.75rem; + width: 5rem; + height: 5rem; +} + +@media (min-width: 1024px) and (min-height: 900px) { + .hero-roomy-lift { + transform: translateY(-2.5rem); + } + + .hero-scroll-chevron { + display: flex; + } +} + +@media (min-width: 1280px) and (min-height: 1040px) { + .hero-roomy-lift { + transform: translateY(-3.5rem); + } + + .hero-scroll-chevron { + bottom: 0.9rem; + } +} + @keyframes scout-export-click { 0%, 52%, diff --git a/frontend/src/lib/dom-scroll.test.ts b/frontend/src/lib/dom-scroll.test.ts new file mode 100644 index 0000000..86e43d2 --- /dev/null +++ b/frontend/src/lib/dom-scroll.test.ts @@ -0,0 +1,58 @@ +import { describe, expect, it } from 'vitest'; +import { canWheelScrollInsideTarget } from './dom-scroll'; + +function setElementMetrics( + element: HTMLElement, + metrics: Partial<{ + clientHeight: number; + clientWidth: number; + scrollHeight: number; + scrollWidth: number; + }> +) { + for (const [key, value] of Object.entries(metrics)) { + Object.defineProperty(element, key, { configurable: true, value }); + } +} + +describe('canWheelScrollInsideTarget', () => { + it('allows horizontal wheel gestures inside a horizontal scroller', () => { + const scroller = document.createElement('div'); + scroller.style.overflowX = 'auto'; + scroller.scrollLeft = 20; + setElementMetrics(scroller, { clientWidth: 100, scrollWidth: 240 }); + + const child = document.createElement('button'); + scroller.appendChild(child); + document.body.appendChild(scroller); + + expect(canWheelScrollInsideTarget(child, 40, 0)).toBe(true); + scroller.remove(); + }); + + it('allows vertical wheel gestures inside a vertical scroller', () => { + const scroller = document.createElement('div'); + scroller.style.overflowY = 'auto'; + scroller.scrollTop = 20; + setElementMetrics(scroller, { clientHeight: 100, scrollHeight: 240 }); + + const child = document.createElement('button'); + scroller.appendChild(child); + document.body.appendChild(scroller); + + expect(canWheelScrollInsideTarget(child, 60, 20)).toBe(true); + scroller.remove(); + }); + + it('does not allow horizontal gestures at the edge of a scroller', () => { + const scroller = document.createElement('div'); + scroller.style.overflowX = 'auto'; + scroller.scrollLeft = 0; + setElementMetrics(scroller, { clientWidth: 100, scrollWidth: 240 }); + + document.body.appendChild(scroller); + + expect(canWheelScrollInsideTarget(scroller, -40, 0)).toBe(false); + scroller.remove(); + }); +}); diff --git a/frontend/src/lib/dom-scroll.ts b/frontend/src/lib/dom-scroll.ts new file mode 100644 index 0000000..286e0f7 --- /dev/null +++ b/frontend/src/lib/dom-scroll.ts @@ -0,0 +1,45 @@ +const SCROLLABLE_OVERFLOW = new Set(['auto', 'scroll', 'overlay']); + +function canScrollHorizontally(element: HTMLElement, deltaX: number): boolean { + if (deltaX === 0) return false; + + const style = window.getComputedStyle(element); + if (!SCROLLABLE_OVERFLOW.has(style.overflowX)) return false; + if (element.scrollWidth <= element.clientWidth) return false; + + const maxScrollLeft = element.scrollWidth - element.clientWidth; + if (deltaX < 0) return element.scrollLeft > 0; + return element.scrollLeft < maxScrollLeft - 1; +} + +function canScrollVertically(element: HTMLElement, deltaY: number): boolean { + if (deltaY === 0) return false; + + const style = window.getComputedStyle(element); + if (!SCROLLABLE_OVERFLOW.has(style.overflowY)) return false; + if (element.scrollHeight <= element.clientHeight) return false; + + const maxScrollTop = element.scrollHeight - element.clientHeight; + if (deltaY < 0) return element.scrollTop > 0; + return element.scrollTop < maxScrollTop - 1; +} + +export function canWheelScrollInsideTarget( + target: EventTarget | null, + deltaX: number, + deltaY: number +): boolean { + let element = target instanceof Element ? target : null; + + while (element && element !== document.body && element !== document.documentElement) { + if ( + element instanceof HTMLElement && + (canScrollHorizontally(element, deltaX) || canScrollVertically(element, deltaY)) + ) { + return true; + } + element = element.parentElement; + } + + return false; +} diff --git a/frontend/src/lib/feature-icons.tsx b/frontend/src/lib/feature-icons.tsx index da249bd..37712e7 100644 --- a/frontend/src/lib/feature-icons.tsx +++ b/frontend/src/lib/feature-icons.tsx @@ -19,6 +19,12 @@ const FEATURE_ICON_PATHS: Record = { ), + 'Estimated price': ( + <> + + + + ), 'Price per sqm': ( <> @@ -109,6 +115,18 @@ const FEATURE_ICON_PATHS: Record = { ), + 'Travel time to nearest train or tube station (min)': ( + <> + + + + + + + + + + ), // ── Education ──────────────────────────────── 'Education, Skills and Training Score': ( diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 8be4415..a09ac10 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -31,9 +31,11 @@ module.exports = { 950: '#003330', }, coral: { + 50: '#fff7ed', 400: '#fb923c', 500: '#f97316', 600: '#ea580c', + 700: '#c2410c', }, warm: { 50: '#fafaf9', diff --git a/server-rs/logs/server.log.2026-05-05 b/server-rs/logs/server.log.2026-05-05 index 255fb31..3341a91 100644 --- a/server-rs/logs/server.log.2026-05-05 +++ b/server-rs/logs/server.log.2026-05-05 @@ -2409,3 +2409,569 @@ 2026-05-05T21:26:06.465961Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 2026-05-05T21:26:06.773040Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=11318 parallel=false cells_before_filter=380 cells_after_filter=363 truncated=false bounds=50.9954,-1.3207,51.0982,-1.0405 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.3 json_ms=0.3 total_ms=0.6 2026-05-05T21:26:08.686005Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=8 rows=291392 parallel=true cells_before_filter=2485 cells_after_filter=2481 truncated=false bounds=50.8884,-1.6525,51.2556,-0.6513 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=3.8 json_ms=1.6 total_ms=5.3 +2026-05-05T21:35:19.535962Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:35:19.536004Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:35:20.928669Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:35:20.943703Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:35:21.260328Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:35:21.263080Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:35:22.518336Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:35:22.519413Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:35:22.552338Z INFO property_map_server::routes::postcodes: GET /api/postcode/M44FZ postcode=M4 4FZ +2026-05-05T21:35:22.579079Z INFO property_map_server::routes::postcode_stats: GET /api/postcode-stats postcode=M4 4FZ total_count=144 filters=0 filters_raw="-" ms=0.4 +2026-05-05T21:35:22.579978Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.6 +2026-05-05T21:35:22.595218Z INFO property_map_server::routes::postcodes: GET /api/postcode/M4 4FZ postcode=M4 4FZ +2026-05-05T21:35:22.684822Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=881951b74bfffff resolution=8 total_count=2958 filters=0 filters_raw="-" ms=1.1 +2026-05-05T21:35:23.324836Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=1241 filters=0 filters_raw="-" ms=0.6 +2026-05-05T21:35:23.507421Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.4548,53.5912,-2.0354 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.9 json_ms=0.1 total_ms=3.1 +2026-05-05T21:35:23.866219Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=1 travel=1 total=41544 filters_raw="-" ms=11.3 +2026-05-05T21:35:32.108784Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.7 +2026-05-05T21:35:32.135015Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=310 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.3 +2026-05-05T21:35:32.136509Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.7 +2026-05-05T21:35:33.790810Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.0 json_ms=0.2 total_ms=4.1 +2026-05-05T21:35:33.818308Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=20.4 +2026-05-05T21:35:37.753394Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=2156 cells_after_filter=2155 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=7.4 json_ms=2.0 total_ms=9.4 +2026-05-05T21:35:39.940308Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.9 json_ms=0.1 total_ms=4.0 +2026-05-05T21:35:40.981422Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.6 json_ms=0.1 total_ms=4.7 +2026-05-05T21:35:41.681395Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=23.1 +2026-05-05T21:36:50.130617Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:36:50.137912Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:37:36.248757Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:37:36.255038Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:37:36.856875Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:37:36.856933Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:37:36.873429Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:37:36.880771Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:40:03.751467Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:40:09.196030Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:40:10.589453Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:40:10.589833Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:40:10.622151Z INFO property_map_server::routes::postcodes: GET /api/postcode/M44FZ postcode=M4 4FZ +2026-05-05T21:40:10.650954Z INFO property_map_server::routes::postcode_stats: GET /api/postcode-stats postcode=M4 4FZ total_count=144 filters=0 filters_raw="-" ms=0.3 +2026-05-05T21:40:10.651985Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.6 +2026-05-05T21:40:10.699279Z INFO property_map_server::routes::postcodes: GET /api/postcode/M4 4FZ postcode=M4 4FZ +2026-05-05T21:40:10.712262Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=881951b74bfffff resolution=8 total_count=2958 filters=0 filters_raw="-" ms=1.1 +2026-05-05T21:40:10.882037Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=1241 filters=0 filters_raw="-" ms=0.6 +2026-05-05T21:40:11.183074Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.4548,53.5912,-2.0354 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.5 json_ms=0.1 total_ms=3.6 +2026-05-05T21:40:11.556734Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=1 travel=1 total=41544 filters_raw="-" ms=12.9 +2026-05-05T21:40:20.767960Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.5 +2026-05-05T21:40:20.796799Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=310 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.4 +2026-05-05T21:40:20.798737Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.5 +2026-05-05T21:40:21.381833Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=7.7 json_ms=0.2 total_ms=7.9 +2026-05-05T21:40:21.399664Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=20.6 +2026-05-05T21:40:24.897526Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=2156 cells_after_filter=2155 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=10.6 json_ms=1.9 total_ms=12.5 +2026-05-05T21:40:25.086271Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.0 json_ms=0.1 total_ms=4.1 +2026-05-05T21:40:27.093792Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.6 json_ms=0.1 total_ms=2.7 +2026-05-05T21:40:27.109216Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=17.8 +2026-05-05T21:41:49.677712Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:41:51.102585Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:41:51.103971Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:41:51.136237Z INFO property_map_server::routes::postcodes: GET /api/postcode/M44FZ postcode=M4 4FZ +2026-05-05T21:41:51.164096Z INFO property_map_server::routes::postcode_stats: GET /api/postcode-stats postcode=M4 4FZ total_count=144 filters=0 filters_raw="-" ms=0.3 +2026-05-05T21:41:51.165332Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.8 +2026-05-05T21:41:51.181286Z INFO property_map_server::routes::postcodes: GET /api/postcode/M4 4FZ postcode=M4 4FZ +2026-05-05T21:41:51.269962Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=881951b74bfffff resolution=8 total_count=2958 filters=0 filters_raw="-" ms=1.1 +2026-05-05T21:41:51.920774Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=1241 filters=0 filters_raw="-" ms=0.5 +2026-05-05T21:41:52.111652Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.4548,53.5912,-2.0354 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.5 json_ms=0.1 total_ms=3.6 +2026-05-05T21:41:52.396733Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=1 travel=1 total=41544 filters_raw="-" ms=12.1 +2026-05-05T21:42:01.835682Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.9 +2026-05-05T21:42:01.856925Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=310 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.4 +2026-05-05T21:42:01.861410Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=4.9 +2026-05-05T21:42:02.025694Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4548,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=11.1 json_ms=0.1 total_ms=11.3 +2026-05-05T21:42:03.370679Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.5 json_ms=0.2 total_ms=3.7 +2026-05-05T21:42:03.390285Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=23.1 +2026-05-05T21:42:07.747532Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=2156 cells_after_filter=2155 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=7.0 json_ms=2.2 total_ms=9.3 +2026-05-05T21:42:07.971145Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.8 json_ms=0.1 total_ms=4.9 +2026-05-05T21:42:10.063960Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.0 json_ms=0.1 total_ms=4.1 +2026-05-05T21:42:13.030016Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=22.1 +2026-05-05T21:43:23.988313Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:43:23.989906Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:43:38.937614Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:43:40.739899Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:43:40.741294Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:43:40.836366Z INFO property_map_server::routes::postcodes: GET /api/postcode/M44FZ postcode=M4 4FZ +2026-05-05T21:43:40.871628Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.7 +2026-05-05T21:43:40.871677Z INFO property_map_server::routes::postcode_stats: GET /api/postcode-stats postcode=M4 4FZ total_count=144 filters=0 filters_raw="-" ms=0.3 +2026-05-05T21:43:40.963658Z INFO property_map_server::routes::postcodes: GET /api/postcode/M4 4FZ postcode=M4 4FZ +2026-05-05T21:43:40.972553Z INFO property_map_server::routes::postcodes: GET /api/postcode/M4 4FZ postcode=M4 4FZ +2026-05-05T21:43:41.228623Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.8 json_ms=0.2 total_ms=3.0 +2026-05-05T21:43:41.589568Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=1241 filters=0 filters_raw="-" ms=0.9 +2026-05-05T21:43:41.611940Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=15.0 +2026-05-05T21:43:42.106439Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.4548,53.5912,-2.0354 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.9 json_ms=0.2 total_ms=5.1 +2026-05-05T21:43:42.148975Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=1 travel=1 total=41544 filters_raw="-" ms=12.9 +2026-05-05T21:43:50.925280Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.7 +2026-05-05T21:43:50.950197Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=310 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.4 +2026-05-05T21:43:50.952039Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.3 +2026-05-05T21:43:51.901986Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.9 json_ms=0.1 total_ms=3.1 +2026-05-05T21:43:51.952950Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=23.4 +2026-05-05T21:43:56.136201Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=2156 cells_after_filter=2155 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=6.7 json_ms=1.6 total_ms=8.3 +2026-05-05T21:43:56.549574Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.0 json_ms=0.2 total_ms=4.1 +2026-05-05T21:43:58.005257Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.6 json_ms=0.1 total_ms=3.7 +2026-05-05T21:43:58.316362Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=21.2 +2026-05-05T21:43:59.526091Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:43:59.526363Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:44:05.897144Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:44:05.899027Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:44:23.329571Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=223412 parallel=true cells_before_filter=740 cells_after_filter=698 truncated=false bounds=51.4896,-0.2000,51.5404,-0.0600 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=1.6 json_ms=0.4 total_ms=2.0 +2026-05-05T21:45:36.770349Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:45:36.770355Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:46:55.780524Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:46:57.151058Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:46:57.152528Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:46:57.183975Z INFO property_map_server::routes::postcodes: GET /api/postcode/M44FZ postcode=M4 4FZ +2026-05-05T21:46:57.210662Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T21:46:57.210978Z INFO property_map_server::routes::postcode_stats: GET /api/postcode-stats postcode=M4 4FZ total_count=144 filters=0 filters_raw="-" ms=0.3 +2026-05-05T21:46:57.229878Z INFO property_map_server::routes::postcodes: GET /api/postcode/M4 4FZ postcode=M4 4FZ +2026-05-05T21:46:57.313945Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=881951b74bfffff resolution=8 total_count=2958 filters=0 filters_raw="-" ms=1.1 +2026-05-05T21:46:57.497295Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=1241 filters=0 filters_raw="-" ms=0.8 +2026-05-05T21:46:57.674945Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.4548,53.5912,-2.0354 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.9 json_ms=0.1 total_ms=3.0 +2026-05-05T21:46:58.291511Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=1 travel=1 total=41544 filters_raw="-" ms=12.0 +2026-05-05T21:47:08.638543Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:47:08.640080Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:47:08.693213Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:47:08.696020Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:47:08.698555Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:47:08.698706Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:47:08.708540Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:47:08.712376Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:47:08.881143Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.7 +2026-05-05T21:47:08.922170Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.5 +2026-05-05T21:47:08.922265Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=310 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.4 +2026-05-05T21:47:09.053354Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4548,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.7 json_ms=0.1 total_ms=2.8 +2026-05-05T21:47:09.585970Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.7 json_ms=0.1 total_ms=2.8 +2026-05-05T21:47:09.606306Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=23.2 +2026-05-05T21:47:14.368249Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=2156 cells_after_filter=2155 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=9.1 json_ms=2.6 total_ms=11.7 +2026-05-05T21:47:15.268987Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.2 json_ms=0.1 total_ms=4.4 +2026-05-05T21:47:16.742521Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:47:16.742526Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:47:19.144031Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.8 json_ms=0.1 total_ms=4.9 +2026-05-05T21:47:21.329311Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=18.9 +2026-05-05T21:48:19.552426Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:48:20.910287Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:48:20.911597Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:48:20.944503Z INFO property_map_server::routes::postcodes: GET /api/postcode/M44FZ postcode=M4 4FZ +2026-05-05T21:48:20.970972Z INFO property_map_server::routes::postcode_stats: GET /api/postcode-stats postcode=M4 4FZ total_count=144 filters=0 filters_raw="-" ms=0.3 +2026-05-05T21:48:20.971485Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T21:48:20.988965Z INFO property_map_server::routes::postcodes: GET /api/postcode/M4 4FZ postcode=M4 4FZ +2026-05-05T21:48:21.070355Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=881951b74bfffff resolution=8 total_count=2958 filters=0 filters_raw="-" ms=1.3 +2026-05-05T21:48:21.194673Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=1241 filters=0 filters_raw="-" ms=0.7 +2026-05-05T21:48:21.406038Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.4548,53.5912,-2.0354 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=5.1 json_ms=0.2 total_ms=5.3 +2026-05-05T21:48:22.149166Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=1 travel=1 total=41544 filters_raw="-" ms=11.6 +2026-05-05T21:48:26.000886Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:48:26.000890Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:48:27.742269Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:48:27.743395Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:48:27.877066Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:48:27.877153Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:48:27.877463Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:48:27.882051Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:48:27.891902Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:48:27.892061Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:48:31.303985Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.2 +2026-05-05T21:48:31.324969Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=310 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.3 +2026-05-05T21:48:31.326996Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.4 +2026-05-05T21:48:31.688134Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.8 json_ms=0.1 total_ms=5.0 +2026-05-05T21:48:32.516497Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=18.0 +2026-05-05T21:48:38.027758Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=2156 cells_after_filter=2155 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=6.0 json_ms=1.7 total_ms=7.7 +2026-05-05T21:48:38.546001Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.2 json_ms=0.1 total_ms=3.3 +2026-05-05T21:48:40.622421Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.1 json_ms=0.1 total_ms=4.2 +2026-05-05T21:48:42.032479Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=22.6 +2026-05-05T21:49:10.338613Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:49:10.339888Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:46.231350Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:46.232494Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:46.232853Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:46.234575Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:46.261419Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:46.261843Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:46.286185Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:46.287577Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:47.072067Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:47.072362Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:47.073288Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:47.076801Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:47.117663Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:47.117695Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:47.118146Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:47.125177Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:52.820159Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:52.826259Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:52.826495Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:52.836857Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:52.858218Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:52.858230Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:50:52.894119Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:50:52.895473Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:52:16.280628Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:52:17.757767Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:52:17.759242Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:52:17.784497Z INFO property_map_server::routes::postcodes: GET /api/postcode/M44FZ postcode=M4 4FZ +2026-05-05T21:52:17.795311Z INFO property_map_server::routes::postcode_stats: GET /api/postcode-stats postcode=M4 4FZ total_count=144 filters=0 filters_raw="-" ms=0.4 +2026-05-05T21:52:17.821652Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T21:52:17.830328Z INFO property_map_server::routes::postcodes: GET /api/postcode/M4 4FZ postcode=M4 4FZ +2026-05-05T21:52:17.906952Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=881951b74bfffff resolution=8 total_count=2958 filters=0 filters_raw="-" ms=1.4 +2026-05-05T21:52:18.280692Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=1241 filters=0 filters_raw="-" ms=0.6 +2026-05-05T21:52:18.442852Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.4548,53.5912,-2.0354 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.3 json_ms=0.1 total_ms=2.4 +2026-05-05T21:52:18.775913Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=1 travel=1 total=41544 filters_raw="-" ms=12.3 +2026-05-05T21:52:29.653339Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:52:29.661372Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:52:29.947627Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.0 +2026-05-05T21:52:29.968963Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b74a3ffff resolution=9 total_count=310 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.3 +2026-05-05T21:52:29.970311Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.8 +2026-05-05T21:52:30.307589Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.7 json_ms=0.1 total_ms=3.8 +2026-05-05T21:52:30.524199Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:52:30.524204Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:52:30.624729Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=26.4 +2026-05-05T21:52:35.559305Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=2156 cells_after_filter=2155 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=9.0 json_ms=2.1 total_ms=11.1 +2026-05-05T21:52:35.822961Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.7 json_ms=0.1 total_ms=2.9 +2026-05-05T21:52:37.260802Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.5 json_ms=0.1 total_ms=3.5 +2026-05-05T21:52:37.768202Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=21.9 +2026-05-05T21:53:03.831217Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:53:03.831449Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:53:03.848657Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:53:03.848697Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:53:03.880252Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:53:03.880653Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:53:03.890238Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:53:03.891728Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:53:03.901154Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:53:03.902246Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:53:18.725683Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:53:18.725685Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:54:05.076079Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:54:05.076294Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:56:34.822373Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:56:36.141237Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:56:36.142948Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:56:36.207992Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.8 +2026-05-05T21:56:36.504745Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.2 json_ms=0.2 total_ms=3.3 +2026-05-05T21:56:36.733128Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=13.1 +2026-05-05T21:56:40.571881Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.3 +2026-05-05T21:56:40.583234Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.5 +2026-05-05T21:56:40.892631Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.5 json_ms=0.2 total_ms=4.6 +2026-05-05T21:56:41.062742Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=24.6 +2026-05-05T21:56:43.955287Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=7.9 json_ms=2.5 total_ms=10.4 +2026-05-05T21:56:44.345169Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=9.5 json_ms=0.1 total_ms=9.7 +2026-05-05T21:56:46.004109Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=5.2 json_ms=0.1 total_ms=5.2 +2026-05-05T21:56:46.078279Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=24.5 +2026-05-05T21:56:51.868367Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=268290 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4198,-2.4014,53.5395,-2.1022 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.3 json_ms=0.1 total_ms=2.4 +2026-05-05T21:56:51.879357Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=268290 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=13.3 +2026-05-05T21:56:52.896449Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=173011 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4360,-2.3633,53.5235,-2.1444 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=1.8 json_ms=0.1 total_ms=1.8 +2026-05-05T21:56:52.901548Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=173011 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=6.9 +2026-05-05T21:57:14.298418Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b7467ffff resolution=9 total_count=149 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.3 +2026-05-05T21:57:14.913263Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:57:15.416546Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=141822 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4360,-2.3359,53.5235,-2.1718 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=1.8 json_ms=0.1 total_ms=1.9 +2026-05-05T21:57:15.455008Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=141822 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=8.2 +2026-05-05T21:57:18.611959Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:57:18.611965Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:57:18.724225Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.3 +2026-05-05T21:57:19.334648Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=8.3 json_ms=0.2 total_ms=8.5 +2026-05-05T21:57:20.412105Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=26.8 +2026-05-05T21:57:23.399746Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.1 +2026-05-05T21:57:23.425315Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.1 +2026-05-05T21:57:23.643747Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=7.9 json_ms=0.1 total_ms=8.0 +2026-05-05T21:57:25.019448Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=27.7 +2026-05-05T21:57:27.456478Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=21.8 json_ms=2.6 total_ms=24.5 +2026-05-05T21:57:27.801520Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=7.9 json_ms=0.2 total_ms=8.0 +2026-05-05T21:57:29.430108Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=5.0 json_ms=0.1 total_ms=5.1 +2026-05-05T21:57:29.984292Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=27.1 +2026-05-05T21:57:37.788237Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=268290 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4198,-2.4014,53.5395,-2.1022 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.6 json_ms=0.1 total_ms=4.7 +2026-05-05T21:57:38.031795Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=173011 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4360,-2.3633,53.5235,-2.1444 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.3 json_ms=0.1 total_ms=4.4 +2026-05-05T21:57:39.262206Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=173011 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=9.9 +2026-05-05T21:57:58.793587Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b7467ffff resolution=9 total_count=149 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.2 +2026-05-05T21:57:59.886649Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=141822 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4360,-2.3359,53.5235,-2.1718 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.2 json_ms=0.1 total_ms=2.3 +2026-05-05T21:57:59.945458Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=141822 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=6.3 +2026-05-05T21:58:10.755620Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:58:10.757205Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T21:58:26.903364Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T21:58:26.904448Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:01:32.049909Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:01:34.012407Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:01:34.014056Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:01:34.073888Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.9 +2026-05-05T22:01:34.604384Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.2 json_ms=0.2 total_ms=3.3 +2026-05-05T22:01:35.318029Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=14.1 +2026-05-05T22:01:38.545948Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.1 +2026-05-05T22:01:38.559798Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.9 +2026-05-05T22:01:39.087439Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.9 json_ms=0.1 total_ms=4.1 +2026-05-05T22:01:39.111716Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=21.4 +2026-05-05T22:01:42.572213Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=9.2 json_ms=2.5 total_ms=11.7 +2026-05-05T22:01:42.812709Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.5 json_ms=0.1 total_ms=3.6 +2026-05-05T22:01:44.895449Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.4 json_ms=0.1 total_ms=4.5 +2026-05-05T22:01:44.915751Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=21.0 +2026-05-05T22:02:00.539658Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.6 +2026-05-05T22:02:01.209769Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.1 json_ms=0.1 total_ms=4.2 +2026-05-05T22:02:01.410662Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=21.9 +2026-05-05T22:02:30.280215Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:02:30.280220Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:02:30.494339Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:02:30.494338Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:03:04.445153Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:03:05.814766Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:03:05.816218Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:03:05.877835Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.5 +2026-05-05T22:03:06.171149Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.1 json_ms=0.2 total_ms=3.3 +2026-05-05T22:03:06.416637Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=13.0 +2026-05-05T22:03:10.243319Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T22:03:10.254863Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.3 +2026-05-05T22:03:11.600208Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.8 json_ms=0.1 total_ms=4.9 +2026-05-05T22:03:11.620435Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=24.2 +2026-05-05T22:03:14.007173Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=6.0 json_ms=1.9 total_ms=7.9 +2026-05-05T22:03:17.458780Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.2 json_ms=0.2 total_ms=3.5 +2026-05-05T22:03:18.845895Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.8 json_ms=0.1 total_ms=4.9 +2026-05-05T22:03:18.864525Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=22.8 +2026-05-05T22:03:35.601665Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=0.6 +2026-05-05T22:03:36.222150Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.7 json_ms=0.1 total_ms=3.8 +2026-05-05T22:03:36.513454Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=23.9 +2026-05-05T22:04:11.176851Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:04:12.558667Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:04:12.559951Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:04:12.628604Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.5 +2026-05-05T22:04:12.929976Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.4 json_ms=0.2 total_ms=3.6 +2026-05-05T22:04:13.173110Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=13.1 +2026-05-05T22:04:16.988146Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.6 +2026-05-05T22:04:17.000016Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T22:04:17.925005Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=5.9 json_ms=0.1 total_ms=6.0 +2026-05-05T22:04:17.940327Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=21.2 +2026-05-05T22:04:20.338637Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=6.4 json_ms=1.9 total_ms=8.3 +2026-05-05T22:04:20.819388Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.2 json_ms=0.2 total_ms=3.4 +2026-05-05T22:04:23.030591Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.9 json_ms=0.1 total_ms=4.9 +2026-05-05T22:04:23.052922Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=27.3 +2026-05-05T22:04:40.188074Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.0 +2026-05-05T22:04:40.729235Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.9 json_ms=0.1 total_ms=4.0 +2026-05-05T22:04:40.995511Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=25.3 +2026-05-05T22:05:34.435389Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:05:35.713246Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:05:35.713807Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:05:35.775163Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.8 +2026-05-05T22:05:36.061950Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.9 json_ms=0.1 total_ms=4.1 +2026-05-05T22:05:36.320303Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=12.8 +2026-05-05T22:05:40.134229Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.3 +2026-05-05T22:05:40.151547Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.6 +2026-05-05T22:05:41.222363Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.0 json_ms=0.1 total_ms=4.1 +2026-05-05T22:05:41.245295Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=27.0 +2026-05-05T22:05:44.655480Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=8.1 json_ms=2.4 total_ms=10.5 +2026-05-05T22:05:45.759197Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.4 json_ms=0.1 total_ms=3.5 +2026-05-05T22:05:46.783618Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.7 json_ms=0.1 total_ms=3.7 +2026-05-05T22:05:47.179663Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=26.6 +2026-05-05T22:05:52.156396Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.1 +2026-05-05T22:05:56.697343Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.4 json_ms=0.1 total_ms=3.5 +2026-05-05T22:06:00.750033Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=29.0 +2026-05-05T22:07:46.408950Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:07:47.806303Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:07:47.807699Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:07:47.869410Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.5 +2026-05-05T22:07:48.207181Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.6 json_ms=0.1 total_ms=4.8 +2026-05-05T22:07:48.419634Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=14.1 +2026-05-05T22:07:52.350175Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.0 +2026-05-05T22:07:52.364217Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.0 +2026-05-05T22:07:52.637745Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.7 json_ms=0.2 total_ms=3.9 +2026-05-05T22:07:53.569400Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=23.5 +2026-05-05T22:07:58.242591Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=8.5 json_ms=1.7 total_ms=10.2 +2026-05-05T22:07:59.705019Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.7 json_ms=0.2 total_ms=3.9 +2026-05-05T22:08:01.282032Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.0 json_ms=0.1 total_ms=4.1 +2026-05-05T22:08:01.302333Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=24.3 +2026-05-05T22:08:07.868528Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.1 +2026-05-05T22:08:11.985786Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=5.5 json_ms=0.1 total_ms=5.6 +2026-05-05T22:08:14.126304Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=22.2 +2026-05-05T22:09:36.351097Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:09:37.648717Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:09:37.650429Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:09:37.718577Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T22:09:38.022594Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.2 json_ms=0.2 total_ms=3.4 +2026-05-05T22:09:38.479616Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=15.1 +2026-05-05T22:09:42.116891Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.3 +2026-05-05T22:09:42.129082Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.7 +2026-05-05T22:09:43.385938Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.5 json_ms=0.1 total_ms=4.6 +2026-05-05T22:09:43.405845Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=24.7 +2026-05-05T22:09:45.802330Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=6.0 json_ms=1.7 total_ms=7.7 +2026-05-05T22:09:46.150374Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.9 json_ms=0.1 total_ms=4.0 +2026-05-05T22:09:47.635412Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.4 json_ms=0.1 total_ms=4.5 +2026-05-05T22:09:51.024342Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=26.9 +2026-05-05T22:09:57.125364Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.0 +2026-05-05T22:10:01.670253Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.0 json_ms=0.1 total_ms=3.1 +2026-05-05T22:10:03.962206Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=21.3 +2026-05-05T22:11:29.323311Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:11:29.324866Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:11:29.326169Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:11:29.327416Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:11:29.341892Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:11:29.342825Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:11:29.358511Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:11:29.361667Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:11:31.233803Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:11:31.233808Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:11:31.244858Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:11:31.244881Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:11:31.244950Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:11:31.246951Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:11:31.285478Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:11:31.286881Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:22:58.183462Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=83099 parallel=true cells_before_filter=312 cells_after_filter=300 truncated=false bounds=51.4958,-0.1756,51.5342,-0.0844 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=1.0 json_ms=0.2 total_ms=1.1 +2026-05-05T22:22:59.659662Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=89195da49c3ffff resolution=9 total_count=238 filters=0 filters_raw="-" ms=0.3 +2026-05-05T22:23:00.015894Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=64311 parallel=true cells_before_filter=249 cells_after_filter=229 truncated=false bounds=51.4958,-0.1632,51.5342,-0.0968 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.8 json_ms=0.1 total_ms=0.9 +2026-05-05T22:23:11.413301Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=64311 parallel=true cells_before_filter=249 cells_after_filter=229 truncated=false bounds=51.4958,-0.1632,51.5342,-0.0968 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=0.9 json_ms=0.2 total_ms=1.0 +2026-05-05T22:23:18.040570Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=64311 parallel=true cells_before_filter=249 cells_after_filter=229 truncated=false bounds=51.4958,-0.1632,51.5342,-0.0968 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=0.9 json_ms=0.2 total_ms=1.2 +2026-05-05T22:43:15.610059Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=83099 parallel=true cells_before_filter=312 cells_after_filter=300 truncated=false bounds=51.4958,-0.1756,51.5342,-0.0844 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.8 json_ms=0.2 total_ms=1.0 +2026-05-05T22:43:16.903828Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=149 truncated=false bounds=51.4958,-0.1497,51.5342,-0.1103 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.6 json_ms=0.1 total_ms=0.7 +2026-05-05T22:43:20.549697Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=19171 parallel=false cells_before_filter=105 cells_after_filter=94 truncated=false bounds=51.4978,-0.1407,51.5322,-0.1193 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.4 json_ms=0.1 total_ms=0.4 +2026-05-05T22:43:21.976727Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=19171 parallel=false cells_before_filter=105 cells_after_filter=100 truncated=false bounds=51.4978,-0.1424,51.5322,-0.1176 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.5 json_ms=0.1 total_ms=0.6 +2026-05-05T22:43:22.293571Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=40248 parallel=false cells_before_filter=186 cells_after_filter=175 truncated=false bounds=51.4978,-0.1547,51.5322,-0.1053 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.7 json_ms=0.1 total_ms=0.8 +2026-05-05T22:43:22.845608Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.6 json_ms=0.1 total_ms=0.6 +2026-05-05T22:43:23.303420Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=89195da4d23ffff resolution=9 total_count=4 filters=0 filters_raw="-" ms=0.1 +2026-05-05T22:43:42.565671Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:43:44.001279Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:43:44.001506Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:43:44.076119Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T22:43:44.654476Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.5 json_ms=0.1 total_ms=2.6 +2026-05-05T22:43:44.894850Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=11.6 +2026-05-05T22:43:48.729626Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T22:43:48.741364Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.6 +2026-05-05T22:43:48.926131Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.1 json_ms=0.2 total_ms=4.3 +2026-05-05T22:43:49.231122Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=28.6 +2026-05-05T22:43:51.908240Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=8.9 json_ms=2.3 total_ms=11.2 +2026-05-05T22:43:53.360428Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.1 json_ms=0.2 total_ms=4.2 +2026-05-05T22:43:57.147224Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.1 json_ms=0.1 total_ms=4.2 +2026-05-05T22:43:57.169568Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=26.6 +2026-05-05T22:44:07.124405Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.0 +2026-05-05T22:44:11.794994Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.1 json_ms=0.1 total_ms=3.2 +2026-05-05T22:44:15.007697Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=26.1 +2026-05-05T22:44:33.883430Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:44:33.883631Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:44:33.956903Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:44:33.957097Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:44:34.066338Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:44:34.066345Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:44:34.151042Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:44:34.151631Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:44:34.917734Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.6 json_ms=0.1 total_ms=0.7 +2026-05-05T22:45:56.400232Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.6 json_ms=0.1 total_ms=0.7 +2026-05-05T22:46:00.243885Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.6 json_ms=0.1 total_ms=1.7 +2026-05-05T22:46:02.123616Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=151 truncated=false bounds=51.4957,-0.1512,51.5334,-0.1097 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.5 json_ms=0.1 total_ms=1.6 +2026-05-05T22:46:03.665847Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=90632 parallel=true cells_before_filter=347 cells_after_filter=312 truncated=false bounds=51.4868,-0.1624,51.5414,-0.1022 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.8 json_ms=0.3 total_ms=2.1 +2026-05-05T22:46:04.264588Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=414377 parallel=true cells_before_filter=1471 cells_after_filter=1371 truncated=false bounds=51.4530,-0.2043,51.5713,-0.0741 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=3.6 json_ms=1.1 total_ms=4.7 +2026-05-05T22:46:06.547788Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.5 json_ms=0.1 total_ms=1.7 +2026-05-05T22:46:16.636099Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.5 json_ms=0.1 total_ms=1.6 +2026-05-05T22:46:23.394449Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.6 json_ms=0.1 total_ms=1.7 +2026-05-05T22:46:24.308069Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=162 cells_after_filter=145 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=1 filters_raw="Price per sqm:12:30077.969" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.5 json_ms=0.1 total_ms=1.6 +2026-05-05T22:46:24.553931Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=32331 filters=1 travel=0 total=26612 filters_raw="Price per sqm:12:30077.969" ms=0.8 +2026-05-05T22:46:26.959319Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32787 parallel=false cells_before_filter=151 cells_after_filter=134 truncated=false bounds=51.4952,-0.1532,51.5297,-0.1152 filters=1 filters_raw="Price per sqm:12:30077.969" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.6 json_ms=0.1 total_ms=1.7 +2026-05-05T22:46:27.318926Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=58963 parallel=true cells_before_filter=238 cells_after_filter=206 truncated=false bounds=51.4900,-0.1588,51.5326,-0.1119 filters=1 filters_raw="Price per sqm:12:30077.969" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.2 json_ms=0.2 total_ms=1.4 +2026-05-05T22:46:27.749837Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=108235 parallel=true cells_before_filter=389 cells_after_filter=374 truncated=false bounds=51.4786,-0.1710,51.5391,-0.1044 filters=1 filters_raw="Price per sqm:12:30077.969" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.6 json_ms=0.4 total_ms=2.0 +2026-05-05T22:46:28.171700Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=339930 parallel=true cells_before_filter=1157 cells_after_filter=1088 truncated=false bounds=51.4504,-0.2014,51.5554,-0.0858 filters=1 filters_raw="Price per sqm:12:30077.969" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=3.0 json_ms=1.0 total_ms=4.0 +2026-05-05T22:46:28.601824Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=749457 parallel=true cells_before_filter=3198 cells_after_filter=3059 truncated=false bounds=51.3997,-0.2558,51.5845,-0.0524 filters=1 filters_raw="Price per sqm:12:30077.969" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=6.0 json_ms=2.1 total_ms=8.1 +2026-05-05T22:46:29.055179Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=8 rows=1560750 parallel=true cells_before_filter=1545 cells_after_filter=1535 truncated=false bounds=51.3051,-0.3572,51.6387,0.0098 filters=1 filters_raw="Price per sqm:12:30077.969" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=11.5 json_ms=1.0 total_ms=12.5 +2026-05-05T22:46:29.321372Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=1560750 filters=1 travel=0 total=1299177 filters_raw="Price per sqm:12:30077.969" ms=34.9 +2026-05-05T22:46:33.087766Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=7 rows=2261657 parallel=true cells_before_filter=616 cells_after_filter=616 truncated=false bounds=51.1810,-0.4615,51.7329,0.1455 filters=1 filters_raw="Price per sqm:12:30077.969" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=12.7 json_ms=0.4 total_ms=13.1 +2026-05-05T22:46:33.494231Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=7 rows=2918823 parallel=true cells_before_filter=1362 cells_after_filter=1362 truncated=false bounds=51.0169,-0.6036,51.8540,0.3166 filters=1 filters_raw="Price per sqm:12:30077.969" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=12.6 json_ms=1.0 total_ms=13.7 +2026-05-05T22:46:33.752516Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=2918823 filters=1 travel=0 total=2383011 filters_raw="Price per sqm:12:30077.969" ms=62.9 +2026-05-05T22:46:41.495897Z INFO property_map_server::routes::pois: GET /api/pois results=30 candidates=110817 categories=1 categories_raw="Ferry" ms=1.1 +2026-05-05T22:46:54.343178Z INFO property_map_server::routes::pois: GET /api/pois results=546 candidates=110817 categories=2 categories_raw="Ferry,Rail station" ms=1.4 +2026-05-05T22:46:55.441445Z INFO property_map_server::routes::pois: GET /api/pois results=548 candidates=110817 categories=3 categories_raw="Ferry,Rail station,Airport" ms=1.5 +2026-05-05T22:46:55.794750Z INFO property_map_server::routes::pois: GET /api/pois results=549 candidates=110817 categories=4 categories_raw="Ferry,Rail station,Airport,Bus station" ms=1.5 +2026-05-05T22:46:56.155646Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=110817 categories=5 categories_raw="Ferry,Rail station,Airport,Bus station,Bus stop" ms=6.7 +2026-05-05T22:48:05.525357Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=87195db43ffffff resolution=7 total_count=91 filters=1 filters_raw="Price per sqm:12:30077.969" ms=0.1 +2026-05-05T22:50:01.895537Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=87195db43ffffff resolution=7 total_count=127 filters=0 filters_raw="-" ms=0.1 +2026-05-05T22:50:02.051971Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=7 rows=2918823 parallel=true cells_before_filter=1363 cells_after_filter=1363 truncated=false bounds=51.0169,-0.6036,51.8540,0.3166 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=6.3 json_ms=0.6 total_ms=7.0 +2026-05-05T22:50:31.118058Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=7 rows=2918823 parallel=true cells_before_filter=1363 cells_after_filter=1363 truncated=false bounds=51.0169,-0.6036,51.8540,0.3166 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=7.1 json_ms=0.6 total_ms=7.8 +2026-05-05T22:50:31.118295Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=110817 categories=5 categories_raw="Ferry,Rail station,Airport,Bus station,Bus stop" ms=8.0 +2026-05-05T22:51:30.713271Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=7 rows=2918823 parallel=true cells_before_filter=1363 cells_after_filter=1363 truncated=false bounds=51.0169,-0.6036,51.8540,0.3166 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=7.2 json_ms=0.7 total_ms=7.9 +2026-05-05T22:51:30.714292Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=110817 categories=5 categories_raw="Ferry,Rail station,Airport,Bus station,Bus stop" ms=8.8 +2026-05-05T22:53:32.469648Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:53:32.472277Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:53:49.086905Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.6 json_ms=0.1 total_ms=0.7 +2026-05-05T22:54:09.482457Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.6 json_ms=0.1 total_ms=0.7 +2026-05-05T22:54:21.493756Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:54:21.496988Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:54:26.683522Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:54:26.689059Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:55:49.934502Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:55:51.273763Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:55:51.274240Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:55:51.342597Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T22:55:51.625779Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.6 json_ms=0.1 total_ms=2.7 +2026-05-05T22:55:51.883818Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=13.2 +2026-05-05T22:56:00.674036Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.0 +2026-05-05T22:56:00.688452Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.6 +2026-05-05T22:56:01.660467Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.3 json_ms=0.2 total_ms=3.5 +2026-05-05T22:56:01.686325Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=29.2 +2026-05-05T22:56:08.892303Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=10.0 json_ms=2.4 total_ms=12.4 +2026-05-05T22:56:09.044778Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.5 json_ms=0.2 total_ms=4.6 +2026-05-05T22:56:27.273066Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.5 json_ms=0.1 total_ms=3.5 +2026-05-05T22:56:27.290297Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=20.8 +2026-05-05T22:56:41.380242Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.1 +2026-05-05T22:56:48.559932Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=5.9 json_ms=0.1 total_ms=6.0 +2026-05-05T22:56:48.598808Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=25.7 +2026-05-05T22:59:17.850275Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:59:19.683668Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T22:59:19.685209Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T22:59:19.868856Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-05T22:59:20.700955Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.9 json_ms=0.2 total_ms=3.1 +2026-05-05T22:59:21.388973Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=18.5 +2026-05-05T22:59:30.197488Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.0 +2026-05-05T22:59:30.209877Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.8 +2026-05-05T22:59:31.524992Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.1 json_ms=0.1 total_ms=4.2 +2026-05-05T22:59:31.552172Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=31.5 +2026-05-05T22:59:39.058584Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=8.2 json_ms=2.4 total_ms=10.5 +2026-05-05T22:59:40.888781Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.3 json_ms=0.2 total_ms=4.4 +2026-05-05T22:59:49.369015Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.9 json_ms=0.1 total_ms=3.0 +2026-05-05T22:59:53.656223Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=24.4 +2026-05-05T23:00:06.632909Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.1 +2026-05-05T23:00:14.326078Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.6 json_ms=0.1 total_ms=4.7 +2026-05-05T23:00:14.345041Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=24.1 +2026-05-05T23:02:44.138033Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:02:45.527629Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:02:45.528980Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:02:45.591980Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.7 +2026-05-05T23:02:45.870217Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.3 json_ms=0.2 total_ms=2.5 +2026-05-05T23:02:46.138216Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=13.9 +2026-05-05T23:02:55.255284Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.3 +2026-05-05T23:02:55.284710Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.3 +2026-05-05T23:02:56.543228Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=5.1 json_ms=0.2 total_ms=5.2 +2026-05-05T23:02:56.565466Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=27.6 +2026-05-05T23:03:04.737677Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=8.4 json_ms=2.3 total_ms=10.7 +2026-05-05T23:03:06.524250Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.0 json_ms=0.2 total_ms=4.1 +2026-05-05T23:03:21.842452Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.6 json_ms=0.1 total_ms=4.7 +2026-05-05T23:03:21.864802Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=27.0 +2026-05-05T23:03:42.145302Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.1 +2026-05-05T23:03:46.908451Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=499440 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.4549,53.5912,-2.0354 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.5 json_ms=0.1 total_ms=2.6 +2026-05-05T23:03:47.229906Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=499440 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=24.5 +2026-05-05T23:05:31.402218Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:05:31.414308Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:05:31.415566Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:05:31.415719Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:05:31.436317Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:05:31.436387Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:05:31.451985Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:05:31.452263Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:05:31.961090Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.7 json_ms=0.1 total_ms=0.8 +2026-05-05T23:06:57.415147Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:06:58.764931Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:06:58.766642Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:06:58.836054Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.5 +2026-05-05T23:06:59.176972Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.3 json_ms=0.1 total_ms=2.5 +2026-05-05T23:06:59.430262Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=12.3 +2026-05-05T23:07:08.481220Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.9 +2026-05-05T23:07:08.494481Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.8 +2026-05-05T23:07:09.211888Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.7 json_ms=0.1 total_ms=3.9 +2026-05-05T23:07:09.235165Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=27.3 +2026-05-05T23:07:16.474238Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=7.3 json_ms=2.7 total_ms=9.9 +2026-05-05T23:07:21.423747Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.3 json_ms=0.2 total_ms=4.4 +2026-05-05T23:07:28.025215Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.0 json_ms=0.1 total_ms=3.1 +2026-05-05T23:07:30.260151Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=21.9 +2026-05-05T23:07:40.399802Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=470423 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3848,-2.4911,53.5741,-2.0174 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.0 json_ms=0.1 total_ms=3.1 +2026-05-05T23:07:42.310630Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=328746 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4065,-2.4487,53.5527,-2.0829 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.3 json_ms=0.1 total_ms=3.4 +2026-05-05T23:07:42.807273Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=328746 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4065,-2.4487,53.5527,-2.0829 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.1 json_ms=0.1 total_ms=2.2 +2026-05-05T23:07:42.872719Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=328746 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=17.6 +2026-05-05T23:07:44.921638Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.1 +2026-05-05T23:07:46.846641Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=283073 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4065,-2.4029,53.5527,-2.1286 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.1 json_ms=0.1 total_ms=3.2 +2026-05-05T23:07:47.055307Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=283073 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=11.3 +2026-05-05T23:09:24.286826Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:09:24.288081Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:09:24.310068Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:09:24.310452Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:09:24.328925Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:09:24.330142Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:09:24.376513Z INFO property_map_server::routes::features: GET /api/features +2026-05-05T23:09:24.386911Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-05T23:09:24.866051Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.8 json_ms=0.1 total_ms=0.9 diff --git a/server-rs/logs/server.log.2026-05-06 b/server-rs/logs/server.log.2026-05-06 new file mode 100644 index 0000000..4fc0e8a --- /dev/null +++ b/server-rs/logs/server.log.2026-05-06 @@ -0,0 +1,78 @@ +2026-05-06T06:24:15.704164Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T06:24:15.851886Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-06T07:12:47.756563Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=149 truncated=false bounds=51.4958,-0.1497,51.5342,-0.1103 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=0.6 json_ms=0.1 total_ms=0.7 +2026-05-06T07:12:51.057411Z INFO property_map_server::routes::pois: GET /api/pois results=8114 candidates=8143 categories=94 categories_raw="Airport,Bus station,Bus stop,Ferry,Rail station,Taxi rank,Tube station,Aldi,Asda,Bakery,Booths,Budgens,Butcher & Fishmonger,COOK,Co-op,Convenience Store,Costco,Deli & Specialty,Farmfoods,Greengrocer,Heron Foods,Iceland,Lidl,M&S,Makro,Morrisons,Off-Licence,Planet Organic,Sainsbury's,Spar,Supermarket,Tesco,Waitrose,Whole Foods Market,Bar,Café,Cinema,Entertainment,Fast Food,Live Music & Events,Nightclub,Park,Playground,Pub,Restaurant,Sports Centre,Theatre,School,Care Home,Counselling & Therapy,Dentist,GP Surgery,Hospital & Clinic,Medical & Mobility,Optician,Pharmacy,Physiotherapy,Ambulance Station,Fire Station,Police,Community Centre,EV Charging,Fuel Station,Hotel,Local Business,Offices,Arts Centre,Gallery,Library,Museum,Place of Worship,Tourist Attraction,Zoo,Bank,Car Services,Dry Cleaner & Laundry,Gym & Fitness,Hairdresser & Beauty,Other,Post Office,Travel Agent,Vet & Pet Care,Bookshop,Charity Shop,DIY & Hardware,Department Store,Electronics,Fashion & Clothing,Gift & Hobby,Home & Garden,Newsagent,Pet Shop,Specialist Shop,Sports & Outdoor" ms=2.9 +2026-05-06T07:12:53.465923Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=109329 parallel=true cells_before_filter=400 cells_after_filter=367 truncated=false bounds=51.4830,-0.1594,51.5444,-0.0964 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=1.1 json_ms=0.2 total_ms=1.3 +2026-05-06T07:12:53.470208Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=13896 categories=94 categories_raw="Airport,Bus station,Bus stop,Ferry,Rail station,Taxi rank,Tube station,Aldi,Asda,Bakery,Booths,Budgens,Butcher & Fishmonger,COOK,Co-op,Convenience Store,Costco,Deli & Specialty,Farmfoods,Greengrocer,Heron Foods,Iceland,Lidl,M&S,Makro,Morrisons,Off-Licence,Planet Organic,Sainsbury's,Spar,Supermarket,Tesco,Waitrose,Whole Foods Market,Bar,Café,Cinema,Entertainment,Fast Food,Live Music & Events,Nightclub,Park,Playground,Pub,Restaurant,Sports Centre,Theatre,School,Care Home,Counselling & Therapy,Dentist,GP Surgery,Hospital & Clinic,Medical & Mobility,Optician,Pharmacy,Physiotherapy,Ambulance Station,Fire Station,Police,Community Centre,EV Charging,Fuel Station,Hotel,Local Business,Offices,Arts Centre,Gallery,Library,Museum,Place of Worship,Tourist Attraction,Zoo,Bank,Car Services,Dry Cleaner & Laundry,Gym & Fitness,Hairdresser & Beauty,Other,Post Office,Travel Agent,Vet & Pet Care,Bookshop,Charity Shop,DIY & Hardware,Department Store,Electronics,Fashion & Clothing,Gift & Hobby,Home & Garden,Newsagent,Pet Shop,Specialist Shop,Sports & Outdoor" ms=4.4 +2026-05-06T07:12:54.729810Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=163973 parallel=true cells_before_filter=583 cells_after_filter=552 truncated=false bounds=51.4759,-0.1656,51.5526,-0.0869 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=1.3 json_ms=0.3 total_ms=1.5 +2026-05-06T07:12:54.734619Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=17509 categories=94 categories_raw="Airport,Bus station,Bus stop,Ferry,Rail station,Taxi rank,Tube station,Aldi,Asda,Bakery,Booths,Budgens,Butcher & Fishmonger,COOK,Co-op,Convenience Store,Costco,Deli & Specialty,Farmfoods,Greengrocer,Heron Foods,Iceland,Lidl,M&S,Makro,Morrisons,Off-Licence,Planet Organic,Sainsbury's,Spar,Supermarket,Tesco,Waitrose,Whole Foods Market,Bar,Café,Cinema,Entertainment,Fast Food,Live Music & Events,Nightclub,Park,Playground,Pub,Restaurant,Sports Centre,Theatre,School,Care Home,Counselling & Therapy,Dentist,GP Surgery,Hospital & Clinic,Medical & Mobility,Optician,Pharmacy,Physiotherapy,Ambulance Station,Fire Station,Police,Community Centre,EV Charging,Fuel Station,Hotel,Local Business,Offices,Arts Centre,Gallery,Library,Museum,Place of Worship,Tourist Attraction,Zoo,Bank,Car Services,Dry Cleaner & Laundry,Gym & Fitness,Hairdresser & Beauty,Other,Post Office,Travel Agent,Vet & Pet Care,Bookshop,Charity Shop,DIY & Hardware,Department Store,Electronics,Fashion & Clothing,Gift & Hobby,Home & Garden,Newsagent,Pet Shop,Specialist Shop,Sports & Outdoor" ms=4.8 +2026-05-06T07:13:00.198267Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=360388 parallel=true cells_before_filter=1242 cells_after_filter=1226 truncated=false bounds=51.4759,-0.2171,51.5526,-0.0354 filters=0 filters_raw="-" fields=0 travel_entries=0 grid_ms=0.0 agg_ms=2.3 json_ms=0.6 total_ms=2.8 +2026-05-06T07:13:00.201735Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=28781 categories=94 categories_raw="Airport,Bus station,Bus stop,Ferry,Rail station,Taxi rank,Tube station,Aldi,Asda,Bakery,Booths,Budgens,Butcher & Fishmonger,COOK,Co-op,Convenience Store,Costco,Deli & Specialty,Farmfoods,Greengrocer,Heron Foods,Iceland,Lidl,M&S,Makro,Morrisons,Off-Licence,Planet Organic,Sainsbury's,Spar,Supermarket,Tesco,Waitrose,Whole Foods Market,Bar,Café,Cinema,Entertainment,Fast Food,Live Music & Events,Nightclub,Park,Playground,Pub,Restaurant,Sports Centre,Theatre,School,Care Home,Counselling & Therapy,Dentist,GP Surgery,Hospital & Clinic,Medical & Mobility,Optician,Pharmacy,Physiotherapy,Ambulance Station,Fire Station,Police,Community Centre,EV Charging,Fuel Station,Hotel,Local Business,Offices,Arts Centre,Gallery,Library,Museum,Place of Worship,Tourist Attraction,Zoo,Bank,Car Services,Dry Cleaner & Laundry,Gym & Fitness,Hairdresser & Beauty,Other,Post Office,Travel Agent,Vet & Pet Care,Bookshop,Charity Shop,DIY & Hardware,Department Store,Electronics,Fashion & Clothing,Gift & Hobby,Home & Garden,Newsagent,Pet Shop,Specialist Shop,Sports & Outdoor" ms=6.3 +2026-05-06T07:13:05.333847Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=360388 parallel=true cells_before_filter=1242 cells_after_filter=1226 truncated=false bounds=51.4759,-0.2171,51.5526,-0.0354 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=3.3 json_ms=0.9 total_ms=4.2 +2026-05-06T07:13:08.713423Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=360388 parallel=true cells_before_filter=1242 cells_after_filter=1226 truncated=false bounds=51.4759,-0.2171,51.5526,-0.0354 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=3.2 json_ms=0.9 total_ms=4.1 +2026-05-06T07:13:13.136900Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=360388 parallel=true cells_before_filter=1242 cells_after_filter=1226 truncated=false bounds=51.4759,-0.2171,51.5526,-0.0354 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=3.1 json_ms=0.9 total_ms=4.0 +2026-05-06T07:14:05.699501Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T07:14:07.875074Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T07:14:07.877346Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-06T07:14:08.019024Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.4 +2026-05-06T07:14:08.941722Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.9 json_ms=0.1 total_ms=3.1 +2026-05-06T07:14:09.179080Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=12.0 +2026-05-06T07:14:18.221435Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.1 +2026-05-06T07:14:18.236889Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.3 +2026-05-06T07:14:19.840645Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.5 json_ms=0.1 total_ms=4.7 +2026-05-06T07:14:19.866316Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=24.0 +2026-05-06T07:14:26.999239Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=8.4 json_ms=2.5 total_ms=10.9 +2026-05-06T07:14:31.542557Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=5.3 json_ms=0.2 total_ms=5.5 +2026-05-06T07:14:37.389719Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=418717 parallel=true cells_before_filter=1460 cells_after_filter=1344 truncated=false bounds=51.4738,-0.2209,51.5536,-0.0316 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=5.7 json_ms=1.1 total_ms=6.8 +2026-05-06T07:14:37.391144Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=29908 categories=94 categories_raw="Airport,Bus station,Bus stop,Ferry,Rail station,Taxi rank,Tube station,Aldi,Asda,Bakery,Booths,Budgens,Butcher & Fishmonger,COOK,Co-op,Convenience Store,Costco,Deli & Specialty,Farmfoods,Greengrocer,Heron Foods,Iceland,Lidl,M&S,Makro,Morrisons,Off-Licence,Planet Organic,Sainsbury's,Spar,Supermarket,Tesco,Waitrose,Whole Foods Market,Bar,Café,Cinema,Entertainment,Fast Food,Live Music & Events,Nightclub,Park,Playground,Pub,Restaurant,Sports Centre,Theatre,School,Care Home,Counselling & Therapy,Dentist,GP Surgery,Hospital & Clinic,Medical & Mobility,Optician,Pharmacy,Physiotherapy,Ambulance Station,Fire Station,Police,Community Centre,EV Charging,Fuel Station,Hotel,Local Business,Offices,Arts Centre,Gallery,Library,Museum,Place of Worship,Tourist Attraction,Zoo,Bank,Car Services,Dry Cleaner & Laundry,Gym & Fitness,Hairdresser & Beauty,Other,Post Office,Travel Agent,Vet & Pet Care,Bookshop,Charity Shop,DIY & Hardware,Department Store,Electronics,Fashion & Clothing,Gift & Hobby,Home & Garden,Newsagent,Pet Shop,Specialist Shop,Sports & Outdoor" ms=7.8 +2026-05-06T07:14:38.216101Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=234725 parallel=true cells_before_filter=806 cells_after_filter=680 truncated=false bounds=51.4911,-0.1905,51.5453,-0.0620 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=3.7 json_ms=0.8 total_ms=4.5 +2026-05-06T07:14:38.222170Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=19659 categories=94 categories_raw="Airport,Bus station,Bus stop,Ferry,Rail station,Taxi rank,Tube station,Aldi,Asda,Bakery,Booths,Budgens,Butcher & Fishmonger,COOK,Co-op,Convenience Store,Costco,Deli & Specialty,Farmfoods,Greengrocer,Heron Foods,Iceland,Lidl,M&S,Makro,Morrisons,Off-Licence,Planet Organic,Sainsbury's,Spar,Supermarket,Tesco,Waitrose,Whole Foods Market,Bar,Café,Cinema,Entertainment,Fast Food,Live Music & Events,Nightclub,Park,Playground,Pub,Restaurant,Sports Centre,Theatre,School,Care Home,Counselling & Therapy,Dentist,GP Surgery,Hospital & Clinic,Medical & Mobility,Optician,Pharmacy,Physiotherapy,Ambulance Station,Fire Station,Police,Community Centre,EV Charging,Fuel Station,Hotel,Local Business,Offices,Arts Centre,Gallery,Library,Museum,Place of Worship,Tourist Attraction,Zoo,Bank,Car Services,Dry Cleaner & Laundry,Gym & Fitness,Hairdresser & Beauty,Other,Post Office,Travel Agent,Vet & Pet Care,Bookshop,Charity Shop,DIY & Hardware,Department Store,Electronics,Fashion & Clothing,Gift & Hobby,Home & Garden,Newsagent,Pet Shop,Specialist Shop,Sports & Outdoor" ms=8.5 +2026-05-06T07:14:44.419446Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=105806 parallel=true cells_before_filter=404 cells_after_filter=317 truncated=false bounds=51.4911,-0.1541,51.5453,-0.0984 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=2.2 json_ms=0.4 total_ms=2.5 +2026-05-06T07:14:44.423580Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=11596 categories=94 categories_raw="Airport,Bus station,Bus stop,Ferry,Rail station,Taxi rank,Tube station,Aldi,Asda,Bakery,Booths,Budgens,Butcher & Fishmonger,COOK,Co-op,Convenience Store,Costco,Deli & Specialty,Farmfoods,Greengrocer,Heron Foods,Iceland,Lidl,M&S,Makro,Morrisons,Off-Licence,Planet Organic,Sainsbury's,Spar,Supermarket,Tesco,Waitrose,Whole Foods Market,Bar,Café,Cinema,Entertainment,Fast Food,Live Music & Events,Nightclub,Park,Playground,Pub,Restaurant,Sports Centre,Theatre,School,Care Home,Counselling & Therapy,Dentist,GP Surgery,Hospital & Clinic,Medical & Mobility,Optician,Pharmacy,Physiotherapy,Ambulance Station,Fire Station,Police,Community Centre,EV Charging,Fuel Station,Hotel,Local Business,Offices,Arts Centre,Gallery,Library,Museum,Place of Worship,Tourist Attraction,Zoo,Bank,Car Services,Dry Cleaner & Laundry,Gym & Fitness,Hairdresser & Beauty,Other,Post Office,Travel Agent,Vet & Pet Care,Bookshop,Charity Shop,DIY & Hardware,Department Store,Electronics,Fashion & Clothing,Gift & Hobby,Home & Garden,Newsagent,Pet Shop,Specialist Shop,Sports & Outdoor" ms=6.6 +2026-05-06T07:14:44.661886Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.3 json_ms=0.1 total_ms=4.4 +2026-05-06T07:14:44.686961Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=29.1 +2026-05-06T07:14:46.392737Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=32331 parallel=false cells_before_filter=163 cells_after_filter=146 truncated=false bounds=51.4978,-0.1490,51.5322,-0.1110 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=1.9 json_ms=0.1 total_ms=2.1 +2026-05-06T07:14:46.394380Z INFO property_map_server::routes::pois: GET /api/pois results=6986 candidates=7010 categories=94 categories_raw="Airport,Bus station,Bus stop,Ferry,Rail station,Taxi rank,Tube station,Aldi,Asda,Bakery,Booths,Budgens,Butcher & Fishmonger,COOK,Co-op,Convenience Store,Costco,Deli & Specialty,Farmfoods,Greengrocer,Heron Foods,Iceland,Lidl,M&S,Makro,Morrisons,Off-Licence,Planet Organic,Sainsbury's,Spar,Supermarket,Tesco,Waitrose,Whole Foods Market,Bar,Café,Cinema,Entertainment,Fast Food,Live Music & Events,Nightclub,Park,Playground,Pub,Restaurant,Sports Centre,Theatre,School,Care Home,Counselling & Therapy,Dentist,GP Surgery,Hospital & Clinic,Medical & Mobility,Optician,Pharmacy,Physiotherapy,Ambulance Station,Fire Station,Police,Community Centre,EV Charging,Fuel Station,Hotel,Local Business,Offices,Arts Centre,Gallery,Library,Museum,Place of Worship,Tourist Attraction,Zoo,Bank,Car Services,Dry Cleaner & Laundry,Gym & Fitness,Hairdresser & Beauty,Other,Post Office,Travel Agent,Vet & Pet Care,Bookshop,Charity Shop,DIY & Hardware,Department Store,Electronics,Fashion & Clothing,Gift & Hobby,Home & Garden,Newsagent,Pet Shop,Specialist Shop,Sports & Outdoor" ms=3.7 +2026-05-06T07:14:55.383153Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=89195da4d2bffff resolution=9 total_count=166 filters=0 filters_raw="-" ms=0.3 +2026-05-06T07:14:55.521238Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=470423 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3851,-2.4904,53.5738,-2.0185 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.6 json_ms=0.1 total_ms=2.7 +2026-05-06T07:14:57.292200Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=387398 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3999,-2.4614,53.5591,-2.0632 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.2 json_ms=0.1 total_ms=3.3 +2026-05-06T07:14:57.327444Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=387398 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=16.0 +2026-05-06T07:14:58.285866Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=328746 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4065,-2.4487,53.5527,-2.0829 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.5 json_ms=0.1 total_ms=2.6 +2026-05-06T07:14:58.350203Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=328746 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=16.5 +2026-05-06T07:14:58.617181Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=89195da4d63ffff resolution=9 total_count=382 filters=0 filters_raw="-" ms=0.3 +2026-05-06T07:15:00.740312Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.2 +2026-05-06T07:15:02.197947Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=283073 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4065,-2.4029,53.5527,-2.1286 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.1 json_ms=0.1 total_ms=2.2 +2026-05-06T07:15:02.491433Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=283073 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=12.8 +2026-05-06T07:15:13.901971Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T07:15:15.283795Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-06T07:15:15.284213Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T07:15:15.347797Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=1.6 +2026-05-06T07:15:15.636170Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=163 cells_after_filter=163 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=0 filters_raw="-" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.9 json_ms=0.1 total_ms=5.1 +2026-05-06T07:15:15.900377Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=1 travel=1 total=41544 filters_raw="-" ms=13.9 +2026-05-06T07:15:24.985267Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.1 +2026-05-06T07:15:25.003392Z INFO property_map_server::routes::travel_destinations: GET /api/travel-destinations mode="transit" results=2752 ms=2.1 +2026-05-06T07:15:25.539775Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.0 json_ms=0.2 total_ms=3.2 +2026-05-06T07:15:25.556452Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=20439 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=19.8 +2026-05-06T07:15:27.290918Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=64311 parallel=true cells_before_filter=249 cells_after_filter=229 truncated=false bounds=51.4958,-0.1632,51.5342,-0.0968 filters=0 filters_raw="-" fields=1 travel_entries=0 grid_ms=0.0 agg_ms=2.3 json_ms=0.3 total_ms=2.6 +2026-05-06T07:15:27.294614Z INFO property_map_server::routes::pois: GET /api/pois results=10000 candidates=11740 categories=94 categories_raw="Airport,Bus station,Bus stop,Ferry,Rail station,Taxi rank,Tube station,Aldi,Asda,Bakery,Booths,Budgens,Butcher & Fishmonger,COOK,Co-op,Convenience Store,Costco,Deli & Specialty,Farmfoods,Greengrocer,Heron Foods,Iceland,Lidl,M&S,Makro,Morrisons,Off-Licence,Planet Organic,Sainsbury's,Spar,Supermarket,Tesco,Waitrose,Whole Foods Market,Bar,Café,Cinema,Entertainment,Fast Food,Live Music & Events,Nightclub,Park,Playground,Pub,Restaurant,Sports Centre,Theatre,School,Care Home,Counselling & Therapy,Dentist,GP Surgery,Hospital & Clinic,Medical & Mobility,Optician,Pharmacy,Physiotherapy,Ambulance Station,Fire Station,Police,Community Centre,EV Charging,Fuel Station,Hotel,Local Business,Offices,Arts Centre,Gallery,Library,Museum,Place of Worship,Tourist Attraction,Zoo,Bank,Car Services,Dry Cleaner & Laundry,Gym & Fitness,Hairdresser & Beauty,Other,Post Office,Travel Agent,Vet & Pet Care,Bookshop,Charity Shop,DIY & Hardware,Department Store,Electronics,Fashion & Clothing,Gift & Hobby,Home & Garden,Newsagent,Pet Shop,Specialist Shop,Sports & Outdoor" ms=6.3 +2026-05-06T07:15:33.072972Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=2446 cells_after_filter=2433 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=7.3 json_ms=2.6 total_ms=9.9 +2026-05-06T07:15:33.220203Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=134 cells_after_filter=134 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.7 json_ms=0.1 total_ms=3.9 +2026-05-06T07:15:47.139336Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=556230 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3675,-2.5248,53.5912,-1.9654 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=4.1 json_ms=0.1 total_ms=4.2 +2026-05-06T07:15:47.158892Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=556230 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=23.7 +2026-05-06T07:16:01.664304Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=387398 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.3999,-2.4614,53.5591,-2.0632 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=3.3 json_ms=0.1 total_ms=3.4 +2026-05-06T07:16:02.312074Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=338007 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4063,-2.4490,53.5529,-2.0824 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.8 json_ms=0.1 total_ms=2.9 +2026-05-06T07:16:03.862614Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=328746 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4065,-2.4487,53.5527,-2.0829 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.5 json_ms=0.1 total_ms=2.6 +2026-05-06T07:16:03.875136Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=328746 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=15.0 +2026-05-06T07:16:06.187821Z INFO property_map_server::routes::hexagon_stats: GET /api/hexagon-stats h3=891951b70abffff resolution=9 total_count=1487 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=1.1 +2026-05-06T07:16:07.771759Z INFO property_map_server::routes::hexagons: GET /api/hexagons resolution=9 rows=283073 parallel=true cells_before_filter=59 cells_after_filter=59 truncated=false bounds=53.4065,-2.4029,53.5527,-2.1286 filters=4 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" fields=0 travel_entries=1 grid_ms=0.0 agg_ms=2.4 json_ms=0.1 total_ms=2.4 +2026-05-06T07:16:07.828161Z INFO property_map_server::routes::filter_counts: GET /api/filter-counts rows=283073 filters=5 travel=1 total=12434 filters_raw="Property type:Flats/Maisonettes|Terraced;;Estimated current price:175000:450000;;Serious crime per 1k residents (avg/yr):0:55;;Noise (dB):50:68" ms=14.7 +2026-05-06T07:16:41.428217Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T07:16:41.429461Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-06T07:16:41.458276Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T07:16:41.464802Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-06T07:16:41.466920Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T07:16:41.468098Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-06T07:16:41.474421Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T07:16:41.475516Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 +2026-05-06T18:23:02.915468Z INFO property_map_server::routes::features: GET /api/features +2026-05-06T18:23:02.922130Z INFO property_map_server::routes::pois: GET /api/poi-categories count=94 groups=11 diff --git a/video/package.json b/video/package.json index f158f1b..c513fae 100644 --- a/video/package.json +++ b/video/package.json @@ -11,6 +11,7 @@ "record": "tsc && node dist/record.js", "record:vertical": "tsc && ASPECT=9x16 node dist/record.js", "encode": "ffmpeg -y -i output/recording.webm -c:v libx264 -pix_fmt yuv420p -crf 14 -preset fast -movflags +faststart output/recording.mp4", + "verify-output": "tsc && node dist/verify.js", "render": "./render.sh" }, "dependencies": { diff --git a/video/render.sh b/video/render.sh index 09e2d59..2689f16 100755 --- a/video/render.sh +++ b/video/render.sh @@ -23,20 +23,16 @@ PB_ADMIN_EMAIL="${PB_ADMIN_EMAIL:-admin@propertymap.local}" PB_ADMIN_PASSWORD="${PB_ADMIN_PASSWORD:-propertymap-dev-2024}" PB_EMAIL="${PB_EMAIL:-demo-video@local.test}" PB_PASSWORD="${PB_PASSWORD:-DemoVideoPass123!}" -MAX_DURATION_S="${MAX_DURATION_S:-15}" -RECORD_SCALE="${RECORD_SCALE:-2}" # 2x raw capture -> real 50fps after speed-up -OUTPUT_FPS="${OUTPUT_FPS:-50}" # matches RECORD_SCALE=2 output cadence -CAPTURE_SCALE="${CAPTURE_SCALE:-1.5}" # sharper than 1x without the 2x software-GL cost AUTH_TTL_HOURS="${AUTH_TTL_HOURS:-24}" # re-auth if auth.json older than this # Where the homepage