此 MCP 可以做什么
Provides mapping tools for routing, truck and ADR routing, geocoding, distance matrices, and isochrones.
工具
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'TruckSpec': {'type': 'object', 'properties': {'hazmat': {'type': 'boolean', 'default': False, 'description': 'Whether the vehicle carries dangerous goods (ADR). Defaults to\nfalse.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres.'}, 'height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle height in metres.'}, 'length_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle length in metres.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels).'}, 'gross_weight_t': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross combination weight in metric tonnes.'}}, 'description': 'Truck profile for routing: physical dimensions plus the ADR\ndangerous-goods declaration. Omitted dimensions default to the EU\nmaximum authorised dimensions of Council Directive 96/53/EC (4.0 m\nheight, 2.55 m width, 16.5 m length, 40 t gross weight).'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'truck': {'anyOf': [{'$ref': '#/$defs/TruckSpec'}, {'type': 'null'}], 'description': 'Truck profile (dimensions + ADR declaration). Requires costing\n"truck"; the detours then respect dimensional/ADR restrictions.'}, 'min_kw': {'type': ['number', 'null'], 'format': 'double', 'description': 'Keep only charge points whose best connector is rated at least this\nmany kW (e.g. 50 for rapid charging only).'}, 'origin': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Route origin (with `destination`, when no geometry is given).'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing model for the route and detour matrix: "auto" (default),\n"truck", "bicycle", "pedestrian" or "motor_scooter".'}, 'connectors': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': 'Keep only charge points offering at least one of these connector\nstandards: "type2", "type1", "ccs", "chademo", "tesla", "domestic"\nor "other". Omitted â\x87\x92 every standard.'}, 'destination': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Route destination.'}, 'max_results': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Maximum results (default 5, at most 25).'}, 'available_only': {'type': ['boolean', 'null'], 'description': 'Keep only charge points with a bay reported free right now. Needs\nthe deployment to have a live availability feed; without one the\ncall is refused rather than silently returning nothing.'}, 'geometry_polyline6': {'type': ['string', 'null'], 'description': "An existing route geometry as an encoded polyline6 (the `route`\ntool's `geometry_polyline6`). Provide either this or `origin` +\n`destination`, not both."}, 'max_detour_minutes': {'type': ['number', 'null'], 'format': 'double', 'description': 'Largest acceptable detour in minutes (default 10, at most 120).'}}}
输出模式
{'type': 'object', '$defs': {'ChargerHit': {'type': 'object', 'required': ['charger_id', 'source', 'lat', 'lon', 'connector_standards', 'evse_count', 'status_live', 'detour_minutes', 'detour_s', 'along_route_position', 'off_route_m'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'WGS84 latitude in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'WGS84 longitude in decimal degrees.'}, 'name': {'type': ['string', 'null'], 'description': 'Site name, where the operator publishes one.'}, 'source': {'type': 'string', 'description': 'Which operator feed this came from.'}, 'detour_s': {'type': 'number', 'format': 'double', 'description': 'The same detour in seconds.'}, 'operator': {'type': ['string', 'null'], 'description': 'Operator display name.'}, 'detour_km': {'type': ['number', 'null'], 'format': 'double', 'description': 'Extra distance of the detour in kilometres, when the engine\nreported distances.'}, 'charger_id': {'type': 'string', 'description': 'Operator-scoped stable id.'}, 'evse_count': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'Number of charging positions (EVSEs) at the site.'}, 'updated_at': {'type': ['string', 'null'], 'description': 'When the operator last updated this record.'}, 'off_route_m': {'type': 'number', 'format': 'double', 'description': 'Straight-line offset from the route geometry, metres.'}, 'status_live': {'type': 'boolean', 'description': 'Whether the status came from a live feed rather than the last\ningest.'}, 'max_power_kw': {'type': ['number', 'null'], 'format': 'double', 'description': 'Highest rated power at the site, kW.'}, 'available_now': {'type': ['boolean', 'null'], 'description': 'Whether a bay is free right now. Present only where a live\navailability feed backs the claim â\x80\x94 absent means unknown, never\n"occupied".'}, 'best_connector': {'anyOf': [{'$ref': '#/$defs/ChargerConnector'}, {'type': 'null'}], 'description': 'The highest-rated connector at the site.'}, 'detour_minutes': {'type': 'number', 'format': 'double', 'description': 'Real extra travel time of stopping here, minutes.'}, 'connector_standards': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Every distinct connector standard at the site.'}, 'along_route_position': {'type': 'number', 'format': 'double', 'description': 'How far along the route the charge point sits, 0.0â\x80\x931.0.'}}, 'description': 'One charge point along the route, with its real engine-computed detour.'}, 'ChargingSource': {'type': 'object', 'required': ['source_id', 'operator', 'chargers'], 'properties': {'licence': {'type': ['string', 'null'], 'description': 'Licence or statutory basis of the feed.'}, 'chargers': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'How many charge points this operator contributes.'}, 'operator': {'type': 'string', 'description': 'Operator display name.'}, 'source_id': {'type': 'string', 'description': 'Operator id.'}, 'coverage_note': {'type': ['string', 'null'], 'description': "Plain-language statement of what this operator's feed does and\ndoes not cover."}}, 'description': "One operator's coverage and licence, as published by the deployment."}, 'ChargerConnector': {'type': 'object', 'required': ['standard', 'dc'], 'properties': {'dc': {'type': 'boolean', 'description': 'Whether this connector delivers DC (rapid) rather than AC.'}, 'power_kw': {'type': ['number', 'null'], 'format': 'double', 'description': 'Rated power in kW, where the operator publishes enough to know it.'}, 'standard': {'type': 'string', 'description': 'Normalised standard: "type2", "type1", "ccs", "chademo", "tesla",\n"domestic" or "other".'}, 'power_kw_source': {'type': ['string', 'null'], 'description': '"declared" when the operator published the rating, "derived" when\nit was computed from voltage Ã\x97 amperage Ã\x97 phases. Never present\nthe two as the same thing to a user.'}}, 'description': 'The highest-rated connector at a charge point.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['costing', 'route_length_m', 'candidates_considered', 'candidates_costed', 'candidate_cap', 'max_detour_minutes', 'results', 'coverage_note', 'sources', 'availability_live', 'availability_note', 'say'], 'properties': {'say': {'type': 'string', 'description': "**Always present.** The whole answer as one short spoken line,\ncomposed by the gateway. Coverage is inside the claim rather than\nappended to it: the line scopes its superlative to the operators\nthis deployment holds, and an empty result's line says the\nemptiness is about those operators, never about the road. Safe to\nread to a driver verbatim."}, 'note': {'type': ['string', 'null'], 'description': 'Why `results` is empty, when it is â\x80\x94 the cause, not a bare list.'}, 'costing': {'type': 'string', 'description': 'The costing the detours were computed with.'}, 'results': {'type': 'array', 'items': {'$ref': '#/$defs/ChargerHit'}, 'description': 'Charge points within the detour budget, most powerful first\n(power, then detour).'}, 'sources': {'type': 'array', 'items': {'$ref': '#/$defs/ChargingSource'}, 'description': 'Every operator in the dataset, with its own coverage note and\nlicence. Present even when `results` is empty.'}, 'candidate_cap': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'The matrix fan-out cap in force.'}, 'coverage_note': {'type': 'string', 'description': '**Always present.** What this deployment\'s charge-point dataset\ndoes and does not cover. An empty `results` means "none from these\noperators within the budget" â\x80\x94 never "there are no chargers here".\nShow this to the user alongside the results.'}, 'route_length_m': {'type': 'number', 'format': 'double', 'description': 'Length of the route geometry in metres.'}, 'route_distance_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Direct originâ\x86\x92destination distance in metres.'}, 'route_duration_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'Direct originâ\x86\x92destination travel time in seconds (same estimator\nas the detour legs), when routable.'}, 'availability_live': {'type': 'boolean', 'description': 'Whether statuses are live (a bring-your-own availability feed) or\nthe values captured at the last ingest.'}, 'availability_note': {'type': 'string', 'description': 'Plain-language explanation of what the statuses mean here.'}, 'candidates_costed': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'Candidates actually costed through the engine (fan-out capped at\n`candidate_cap`, most powerful kept).'}, 'max_detour_minutes': {'type': 'number', 'format': 'double', 'description': 'The detour budget applied, minutes.'}, 'charging_attribution': {'type': ['string', 'null'], 'description': 'Attribution string for the charge-point operators actually\nreturned â\x80\x94 display it with the results (a licence obligation).'}, 'candidates_considered': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'Charge points matching the filters that passed the corridor\npre-filter.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'TruckSpec': {'type': 'object', 'properties': {'hazmat': {'type': 'boolean', 'default': False, 'description': 'Whether the vehicle carries dangerous goods (ADR). Defaults to\nfalse.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres.'}, 'height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle height in metres.'}, 'length_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle length in metres.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels).'}, 'gross_weight_t': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross combination weight in metric tonnes.'}}, 'description': 'Truck profile for routing: physical dimensions plus the ADR\ndangerous-goods declaration. Omitted dimensions default to the EU\nmaximum authorised dimensions of Council Directive 96/53/EC (4.0 m\nheight, 2.55 m width, 16.5 m length, 40 t gross weight).'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'fuel': {'type': ['string', 'null'], 'description': 'Which fuel to price: "diesel" (default), "petrol_95", "petrol_98",\n"premium_diesel", "e85" or "lpg" (aliases "petrol", "unleaded",\n"e10", "super_unleaded", "e5", "b7" and "sdv" are accepted).'}, 'truck': {'anyOf': [{'$ref': '#/$defs/TruckSpec'}, {'type': 'null'}], 'description': 'Truck profile (dimensions + ADR declaration). Requires costing\n"truck"; the detours then respect dimensional/ADR restrictions.'}, 'origin': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Route origin (with `destination`, when no geometry is given).'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing model for the route and detour matrix: "auto" (default),\n"truck", "bicycle", "pedestrian" or "motor_scooter".'}, 'destination': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Route destination.'}, 'fill_litres': {'type': ['number', 'null'], 'format': 'double', 'description': 'Optional fill size in litres; each result then also carries\n`saving_total` = `saving_per_litre` Ã\x97 `fill_litres`.'}, 'max_results': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Maximum results (default 5, at most 25).'}, 'geometry_polyline6': {'type': ['string', 'null'], 'description': "An existing route geometry as an encoded polyline6 (the `route`\ntool's `geometry_polyline6`). Provide either this or `origin` +\n`destination`, not both."}, 'max_detour_minutes': {'type': ['number', 'null'], 'format': 'double', 'description': 'Largest acceptable detour in minutes (default 10, at most 120).'}}}
输出模式
{'type': 'object', '$defs': {'FuelBaseline': {'type': 'object', 'required': ['currency', 'value', 'station_id', 'updated_at', 'stale'], 'properties': {'name': {'type': ['string', 'null'], 'description': "The baseline station's human label, when known."}, 'brand': {'type': ['string', 'null'], 'description': "The baseline station's brand, when known."}, 'stale': {'type': 'boolean', 'description': 'True when the baseline price could not be verified fresher than\n24 hours.'}, 'value': {'type': 'number', 'format': 'double', 'description': 'Baseline price per litre.'}, 'currency': {'type': 'string', 'description': 'ISO 4217 currency this baseline covers.'}, 'station_id': {'type': 'string', 'description': "The baseline station's id."}, 'updated_at': {'type': 'string', 'description': "The baseline price's source timestamp, verbatim."}}, 'description': 'The cheapest effectively-on-route option in one currency â\x80\x94 what the\ndriver pays by just pulling in without a detour; the reference the\nper-result savings are computed against. Only a fresh price is\neligible, so this is `stale: false` by construction.'}, 'FuelPriceQuote': {'type': 'object', 'required': ['value', 'currency', 'updated_at', 'stale'], 'properties': {'stale': {'type': 'boolean', 'description': 'True when the price could not be verified fresher than 24 hours:\nunless BOTH the source\'s own `updated_at` and the snapshot\'s fetch\ntime fall inside that window, and always when either is missing.\nTreat it as indicative, not bindable â\x80\x94 say "last seen at X on\n<date>", never quote it as today\'s price or as a saving.'}, 'value': {'type': 'number', 'format': 'double', 'description': 'Price per litre in `currency`.'}, 'currency': {'type': 'string', 'description': 'ISO 4217 code (GBP for the UK sources, EUR for FR/DE).'}, 'updated_at': {'type': 'string', 'description': "The source's own price timestamp, verbatim."}}, 'description': "One live pump price: per-litre value in an ISO 4217 currency, with the\nsource's own update timestamp and a 24-hour staleness flag."}, 'FuelStationHit': {'type': 'object', 'required': ['station_id', 'source', 'lat', 'lon', 'price', 'detour_minutes', 'detour_s', 'along_route_position', 'off_route_m'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'WGS84 latitude in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'WGS84 longitude.'}, 'name': {'type': ['string', 'null'], 'description': 'Human label: trading name, town or address, where the feed\ncarries one.'}, 'brand': {'type': ['string', 'null'], 'description': 'Brand where the feed carries one.'}, 'price': {'$ref': '#/$defs/FuelPriceQuote', 'description': "The requested fuel's live pump price at this station."}, 'source': {'type': 'string', 'description': 'Which national feed the station came from ("uk-fuelfinder", "uk",\n"fr", "de").'}, 'detour_s': {'type': 'number', 'format': 'double', 'description': 'The same detour in raw seconds.'}, 'detour_km': {'type': ['number', 'null'], 'format': 'double', 'description': 'Extra travel distance in kilometres, when the engine reported\ndistances.'}, 'station_id': {'type': 'string', 'description': 'Source-scoped stable station id.'}, 'off_route_m': {'type': 'number', 'format': 'double', 'description': 'Straight-line distance from the station to the route, metres.'}, 'saving_total': {'type': ['number', 'null'], 'format': 'double', 'description': "`saving_per_litre` Ã\x97 the request's `fill_litres`, when both exist."}, 'detour_minutes': {'type': 'number', 'format': 'double', 'description': 'Extra travel time of refuelling here, in minutes (rounded to 0.1):\n(originâ\x86\x92station) + (stationâ\x86\x92destination) â\x88\x92 (originâ\x86\x92destination),\nall computed by the routing engine â\x80\x94 never a straight-line guess.'}, 'saving_per_litre': {'type': ['number', 'null'], 'format': 'double', 'description': 'Per-litre saving against the cheapest effectively-on-route station\nin the same currency (negative = dearer than staying on route).\nAbsent when no FRESH station sits on the route itself in this\ncurrency, and always absent on a stale result: an unverifiable\nprice may state a number but never claim a saving.'}, 'along_route_position': {'type': 'number', 'format': 'double', 'description': 'Where along the route the station sits, 0.0 (origin) to 1.0\n(destination).'}}, 'description': 'One fuel station along the route, priced with its honest detour.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['fuel', 'costing', 'route_length_m', 'candidates_considered', 'candidates_costed', 'candidate_cap', 'max_detour_minutes', 'baseline', 'results', 'say'], 'properties': {'say': {'type': 'string', 'description': "**Always present.** The whole answer as one short spoken line,\ncomposed by the gateway: the number, the detour, and the honest\nqualifier where one applies. Safe to read to a driver verbatim,\nand safe on an empty result, where it names the cause rather than\nimplying there is no fuel on the road. A stale price's line states\nthe figure and the day it was last seen and claims no saving."}, 'fuel': {'type': 'string', 'description': 'The normalised fuel code that was priced (e.g. "diesel").'}, 'costing': {'type': 'string', 'description': 'The costing the detours were priced with.'}, 'results': {'type': 'array', 'items': {'$ref': '#/$defs/FuelStationHit'}, 'description': 'Stations within the detour budget, cheapest first (price, then\ndetour).'}, 'baseline': {'type': 'array', 'items': {'$ref': '#/$defs/FuelBaseline'}, 'description': 'The cheapest effectively-on-route option per currency (empty when\nno station sits on the route itself).'}, 'candidate_cap': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'The matrix fan-out cap in force.'}, 'route_length_m': {'type': 'number', 'format': 'double', 'description': 'Length of the route geometry in metres.'}, 'fuel_attribution': {'type': ['string', 'null'], 'description': 'Attribution string for the fuel-price data sources actually\nreturned â\x80\x94 display it with the prices (a licence obligation).'}, 'route_distance_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Direct originâ\x86\x92destination distance in metres.'}, 'route_duration_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'Direct originâ\x86\x92destination travel time in seconds (same estimator\nas the detour legs), when routable.'}, 'candidates_costed': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'Candidates actually priced through the engine (fan-out capped at\n`candidate_cap`, cheapest kept).'}, 'max_detour_minutes': {'type': 'number', 'format': 'double', 'description': 'The detour budget applied, minutes.'}, 'candidates_considered': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'Stations selling the fuel that passed the corridor pre-filter.'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['hazmat', 'tunnel_category'], 'properties': {'hazmat': {'type': 'boolean', 'description': 'Whether the vehicle carries dangerous goods at all. When false the\nADR tunnel matrix does not apply and every tunnel is permitted.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none". Leave unset for a hazmat load of unknown\ncode (conservatively treated as code B).'}, 'tunnel_category': {'type': 'string', 'description': 'ADR category of the tunnel to check: "A", "B", "C", "D" or "E".'}}}
输出模式
{'type': 'object', '$defs': {'DecisionStatus': {'oneOf': [{'type': 'string', 'const': 'allowed', 'description': 'Passage is permitted.'}, {'type': 'string', 'const': 'blocked', 'description': 'Passage is forbidden.'}], 'description': 'The tunnel-entry decision, mirroring `sn_adr::Decision`.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['decision', 'explanation', 'forbidden_tunnel_categories'], 'properties': {'reason': {'type': ['string', 'null'], 'description': 'Why passage is forbidden (present only when blocked); cites the\nADR 8.6.4 rule that applied.'}, 'decision': {'$ref': '#/$defs/DecisionStatus', 'description': 'Whether passage is allowed or blocked.'}, 'explanation': {'type': 'string', 'description': 'Human-readable explanation of how the decision was reached,\nincluding the conservative worst-case reading.'}, 'forbidden_tunnel_categories': {'type': 'array', 'items': {'type': 'string'}, 'description': 'ADR tunnel categories this load is forbidden from under the\nworst-case reading (conditional clauses assumed to apply). Empty\nwhen unrestricted.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['origin', 'destination', 'height_m'], 'properties': {'origin': {'$ref': '#/$defs/LatLon', 'description': 'Route origin.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres. Supplying it asks the width axis as well as\nthe height axis; the width answer is reported separately and is\nnever a headroom.'}, 'height_m': {'type': 'number', 'format': 'double', 'description': 'Vehicle height in metres. Required: there is no default vehicle,\nbecause a default vehicle is how somebody gets an answer about a\nlorry that is not theirs.'}, 'margin_m': {'type': ['number', 'null'], 'format': 'double', 'description': "Operating margin in metres, added to the height before the verdict\nis decided (default 0). Your compliance policy, not ours: the\nmeasured figure and the safe bound are both reported whatever you\nset here, and the margin is echoed back. It is applied to the\nmeasurement, not to the routing step, where the map's own posted\nheights already carry a margin of their own."}, 'destination': {'$ref': '#/$defs/LatLon', 'description': 'Route destination.'}}}
输出模式
{'type': 'object', '$defs': {'ClearanceEnforcement': {'type': 'object', 'required': ['basis', 'route_certified', 'vertical_datum', 'caveat'], 'properties': {'basis': {'type': 'string', 'description': 'How the figures were arrived at. Always\n`"surveyed_pointcloud_within_survey_difference"`: the difference\nbetween two heights measured in the same survey, on the same date,\nby the same processing. No map tag, no terrain model and no absolute\nvertical datum enters it.'}, 'caveat': {'type': 'string', 'description': 'What this answer does and does not prove, in one paragraph.'}, 'vertical_datum': {'type': 'string', 'description': 'The vertical frame the surveyed figures live in, spelled for a\nreader.'}, 'route_certified': {'type': 'boolean', 'description': 'Whether the route has been certified against a structure inventory.\nAlways `false`, and there is no future in which it is true: this is\na measurement with a bound, never a certificate about a route.'}}, 'description': "How a clearance answer was arrived at, and what it therefore does and\ndoes not prove.\n\nThe [`TunnelEnforcement`] pattern, applied to the other safety-adjacent\nanswer this server gives, and for the same reason: a headroom figure\nwith a bound on it reads like permission. It is not one. The block is\ncarried on every response including the clear one, because the clear one\nis the dangerous one.\n\nEvery field is taken verbatim from the gateway's report rather than\nrebuilt here. `vertical_datum` is a property of the survey the figures\ncame from, so this server cannot know it; and copying the caveat text\ninto a second crate is exactly the drift the single-source-of-truth rule\nexists to prevent. When the gateway omits any part of it, the tool\nrefuses the answer rather than emitting a report with a hollow caveat."}, 'LimitingPointSummary': {'type': 'object', 'required': ['lat', 'lon', 'route_distance_m', 'headroom_m', 'sigma_m', 'sampling_gap_m', 'safe_headroom_m', 'overhead_class', 'surveyed_on', 'dataset'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude of the point, decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude of the point, decimal degrees.'}, 'dataset': {'type': 'string', 'description': 'The dataset the measurement came from.'}, 'sigma_m': {'type': 'number', 'format': 'double', 'description': 'One-sigma measurement uncertainty on that figure, metres.'}, 'headroom_m': {'type': 'number', 'format': 'double', 'description': 'Measured headroom: the surveyed gap between the road surface and\nthe lowest validated surface above it, metres.'}, 'surveyed_on': {'type': 'string', 'description': 'Last capture date of the survey behind this measurement, ISO.'}, 'overhead_class': {'type': 'string', 'description': 'What the overhead surface is made of: `structure`, `vegetation`,\n`wire` or `unknown`. Foliage is compressible and seasonal, so an old\nreading of it stops deciding.'}, 'sampling_gap_m': {'type': 'number', 'format': 'double', 'description': 'One-sided sampling bias bound, metres: how far below the lowest\nsample the true low point could hang, given the sample spacing.'}, 'safe_headroom_m': {'type': 'number', 'format': 'double', 'description': '`headroom_m` less the uncertainty terms, metres. This is the number\nthe verdict is decided on, and the number to plan against.'}, 'route_distance_m': {'type': 'number', 'format': 'double', 'description': 'How far along the route the point sits, metres.'}}, 'description': 'One measured clearance on the route, with the bounds that qualify it.\n\nThere is no field here for a posted, signed or otherwise legally\nbinding height, and that absence is deliberate. A survey measures the\nphysical gap; a sign records a restriction a road authority posted, set\nbelow the physical gap on purpose. They are different quantities and\nthis server never reports one as the other.'}, 'ClearanceWidthSummary': {'type': 'object', 'required': ['verdict'], 'properties': {'reason': {'type': ['string', 'null'], 'description': 'Why the width axis declined to answer, present for\n`not_assessed`.'}, 'verdict': {'type': 'string', 'description': '`pass`, `fail`, `indeterminate`, `no_verdict`, or `not_assessed`\nwhere the geometry or the request did not support an answer.'}, 'clear_width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Free width of the narrowest clear corridor found, metres. Present\nwhere a corridor edge was actually measured.'}, 'safe_clear_width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'That width less its uncertainty terms, metres: the number the width\nverdict is decided on.'}}, 'description': 'The width axis: how wide the clear corridor is, never how tall.\n\nA separate type from [`LimitingPointSummary`] on purpose, with no\nheadroom field on it. These are different physical quantities, and a\nshared type is how the reader of a width answer ends up quoting a\nheadroom.'}, 'ClearanceDatasetSummary': {'type': 'object', 'required': ['dataset', 'survey_dates', 'stale'], 'properties': {'stale': {'type': 'boolean', 'description': 'Whether the clearance field lags the survey it was baked from, or\nhas never been checked against it. Either way no route passes on it.'}, 'dataset': {'type': 'string', 'description': 'The dataset id.'}, 'survey_dates': {'type': 'string', 'description': 'Capture range, `from/to` in ISO dates.'}}, 'description': 'One survey the report drew on.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['verdict', 'basis', 'clearance_enforcement', 'route_distance_m', 'route_duration_s', 'geometry_polyline6', 'assessed_m', 'not_surveyed_m', 'insufficient_data_m', 'width', 'datasets', 'advisories', 'indeterminate_reasons', 'explanation'], 'properties': {'basis': {'type': 'string', 'description': 'Always `"surveyed_geometry_not_signage"`.'}, 'width': {'$ref': '#/$defs/ClearanceWidthSummary', 'description': 'The width axis, answered separately when `width_m` was given.'}, 'verdict': {'type': 'string', 'description': '`pass`, `fail`, `indeterminate` or `no_verdict` for the height axis.\nA `pass` is possible over completely surveyed ground and nowhere\nelse: unsurveyed ground yields `no_verdict`, never a pass.'}, 'datasets': {'type': 'array', 'items': {'$ref': '#/$defs/ClearanceDatasetSummary'}, 'description': 'The surveys drawn on, with their capture dates and staleness.'}, 'limiting': {'anyOf': [{'$ref': '#/$defs/LimitingPointSummary'}, {'type': 'null'}], 'description': 'The limiting point on a `fail`, the tightest point on a `pass`, the\nworst contested point on an `indeterminate`. Absent on a\n`no_verdict`, and absent on a `pass` where the survey found nothing\nat all above the corridor.'}, 'view_url': {'type': ['string', 'null'], 'description': 'Deep link to that exact view in the survey viewer, so the reading\ncan be looked at rather than taken on trust.'}, 'advisories': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Notes on stretches of the route: vegetation age, a reading limited\nby a wire, a seam between surveys.'}, 'assessed_m': {'type': 'number', 'format': 'double', 'description': 'Metres of route measured against survey data good enough to decide\non.'}, 'explanation': {'type': 'string', 'description': 'What was measured, when, with what bound, and what the tool declined\nto conclude. It may over-restrict; it never under-restricts.'}, 'not_surveyed_m': {'type': 'number', 'format': 'double', 'description': 'Metres of route no survey covers. This is the absence of a\nmeasurement, and it is never the same statement as a measured open\nsky. No verdict is drawn over it.'}, 'resolution_hint': {'type': ['string', 'null'], 'description': 'What would resolve an `indeterminate`, in one sentence, as the\nmeasuring service phrased it.'}, 'route_distance_m': {'type': 'number', 'format': 'double', 'description': 'Length of the route the vehicle was routed over, metres.'}, 'route_duration_s': {'type': 'number', 'format': 'double', 'description': 'Estimated driving time for that route, seconds.'}, 'geometry_polyline6': {'type': 'string', 'description': 'The route as a six-digit-precision encoded polyline, so the same\nshape can be drawn or re-measured without routing again.'}, 'insufficient_data_m': {'type': 'number', 'format': 'double', 'description': 'Metres of route a survey covers but too sparsely, or too stale, to\ndecide on. Also an absence, and reported apart from\n`not_surveyed_m` because the two have different remedies.'}, 'clearance_enforcement': {'$ref': '#/$defs/ClearanceEnforcement', 'description': 'What this answer does and does not prove. Read it.'}, 'indeterminate_reasons': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Why an `indeterminate` could not be called, as machine-readable\ncodes (`inside_uncertainty_band`, `vegetation_age_exceeded`,\n`artefact_stale`, `artefact_freshness_unchecked`). Empty on every\nother verdict. These are for branching on, not for reading out: the\nsame reasons appear as English in `explanation`, and a person shown\n`artefact_freshness_unchecked` has been failed by whatever displayed\nit.'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'theme': {'description': 'â\x80¦or an inline theme document (as accepted by `create_style`).\nExactly one of `style_id`/`theme` must be given.'}, 'style_id': {'type': ['string', 'null'], 'description': 'Hosted style id whose latest theme should be checkedâ\x80¦'}}}
输出模式
{'type': 'object', '$defs': {'ContrastFindingInfo': {'type': 'object', 'required': ['variant', 'kind', 'foreground', 'background', 'description', 'ratio', 'threshold', 'passes'], 'properties': {'kind': {'type': 'string', 'description': 'Pair kind: "text" (threshold 4.5) or "graphics" (threshold 3.0).'}, 'ratio': {'type': 'number', 'format': 'double', 'description': 'Measured WCAG 2.1 contrast ratio.'}, 'passes': {'type': 'boolean', 'description': 'Whether the pair meets its threshold.'}, 'variant': {'type': 'string', 'description': 'Palette variant audited: "light" or "dark".'}, 'threshold': {'type': 'number', 'format': 'double', 'description': 'The WCAG threshold applied.'}, 'background': {'type': 'string', 'description': 'Effective backing palette slot.'}, 'foreground': {'type': 'string', 'description': 'Foreground palette slot.'}, 'description': {'type': 'string', 'description': 'Why this pair matters cartographically.'}}, 'description': 'One audited colour pair of a contrast report.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['passes', 'findings'], 'properties': {'passes': {'type': 'boolean', 'description': 'True when every audited pair meets its WCAG threshold.'}, 'findings': {'type': 'array', 'items': {'$ref': '#/$defs/ContrastFindingInfo'}, 'description': 'Every audited pair, failing pairs first.'}}}
输入模式
{'type': 'object', '$defs': {'TerritorySpec': {'type': 'object', 'required': ['id', 'polygon'], 'properties': {'id': {'type': 'string', 'description': 'Caller-chosen id, echoed back and referenced by\n`vehicles[].territory_ids`. Must be unique within the request.'}, 'polygon': {'type': 'array', 'items': {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2}, 'description': 'The outer ring as GeoJSON `[lon, lat]` positions â\x80\x94 longitude\nFIRST. Closed or open; an unclosed ring is closed for you.'}}, 'description': 'One named territory: a polygon that bounds which vehicle may serve\nwhich stop.'}, 'ClusterLocationSpec': {'type': 'object', 'required': ['id', 'lat', 'lon'], 'properties': {'id': {'type': 'string', 'description': "Caller-chosen id, echoed back as the cluster's membership. Must be\nunique within the request."}, 'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees.'}, 'load': {'type': ['number', 'null'], 'format': 'double', 'description': 'Optional weight â\x80\x94 parcels, kilograms, litres, minutes of service.\nSummed per cluster and reported; constrains the clustering only\nunder `max_cluster_load`.'}}, 'description': 'One stop to be clustered.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['locations'], 'properties': {'seed': {'type': ['integer', 'null'], 'format': 'uint64', 'minimum': 0, 'description': 'Seed for the k-means++ seeding (default 42). The same request with\nthe same seed always returns the same clusters, on every\ndeployment.'}, 'clusters': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'How many clusters to produce, balanced by stop count. Give exactly\none of `clusters`, `max_cluster_locations` or `max_cluster_load`.'}, 'locations': {'type': 'array', 'items': {'$ref': '#/$defs/ClusterLocationSpec'}, 'description': 'The stops to group. Ids must be unique; at most 5,000.'}, 'territories': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/TerritorySpec'}, 'description': 'Optional territories. Given, no cluster straddles one: each\nterritory is clustered on its own, and so are the stops inside none\nof them.'}, 'max_cluster_load': {'type': ['number', 'null'], 'format': 'double', 'description': 'At most this much summed `load` per cluster; the cluster count is\nderived from it. A load ceiling with lumpy loads is a bin-packing\nproblem and may have no solution at the derived count â\x80\x94 the\nresponse says so rather than pretending.'}, 'max_cluster_locations': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'At most this many stops per cluster; the cluster count is derived\nfrom it.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['clusters', 'parameters', 'balance', 'basis'], 'properties': {'basis': {'type': 'string', 'description': 'The method statement: this is STRAIGHT-LINE clustering. Distances\nare between coordinates, not along roads â\x80\x94 two stops either side of\nan estuary look adjacent. Show it. It is the sentence that stops a\ncentroid being read as a plan.'}, 'balance': {'description': 'The constraint applied, the largest cluster produced, and whether\nthe ceiling had to be relaxed to place every stop.'}, 'clusters': {'description': 'The clusters: each with its `id`, member `locations` (your ids),\n`count`, summed `load`, `centroid` and the `territory` it belongs\nto.'}, 'parameters': {'description': 'The seed, the cluster count, the locations seen, how many\nterritories were used, the iterations run and whether it converged.'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['name'], 'properties': {'base': {'type': ['string', 'null'], 'description': 'Optional named base to start from, e.g. "streets", "midnight",\n"navigator-night", "fleet". Call `list_style_layers` for the\ncatalogue, including which bases expect an overlay of their own. The\nbase\'s whole document is laid down first and `theme` is merged over\nit, so a base plus two palette entries is a complete style. Omitted,\nthe style starts from the default light theme as it always did.'}, 'name': {'type': 'string', 'description': 'Human-readable style name; its kebab-case slug seeds the style id.'}, 'theme': {'description': 'Optional theme document (palette/layer overrides). Merged over\n`base` when one is given; on its own, it replaces the default theme\noutright.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['style_id', 'version', 'style_url', 'theme'], 'properties': {'theme': {'description': 'The theme document that was stored.'}, 'version': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'The published version (always 1 on create).'}, 'style_id': {'type': 'string', 'description': 'The generated style id â\x80\x94 pass it to `set_palette`,\n`set_layer_paint` and `get_style`.'}, 'style_url': {'type': 'string', 'description': 'Immutable URL of the compiled style at this version.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'points': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'Points to sample. Provide this or `encoded_polyline`, not both.'}, 'encoded_polyline': {'type': ['string', 'null'], 'description': 'A route as a Google encoded polyline with six digits of precision.\nProvide this or `points`, not both.'}, 'resample_distance_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Resamples `encoded_polyline` at this spacing in metres before\nsampling height (ignored for `points`).'}}}
输出模式
{'type': 'object', '$defs': {'ElevationSample': {'type': 'object', 'properties': {'lat': {'type': ['number', 'null'], 'format': 'double', 'description': 'Latitude of the (possibly resampled) point, when known.'}, 'lon': {'type': ['number', 'null'], 'format': 'double', 'description': 'Longitude of the (possibly resampled) point, when known.'}, 'range_km': {'type': ['number', 'null'], 'format': 'double', 'description': 'Cumulative distance from the first point in kilometres, present\nonly for the `encoded_polyline` form.'}, 'elevation_m': {'type': ['number', 'null'], 'format': 'double', 'description': "Elevation in metres, or `null` when the engine has no DEM tile\ncoverage at this point â\x80\x94 Valhalla's own honest value, never a\nguess."}}, 'description': 'One elevation sample: `elevation_m` and, when the request set\n`encoded_polyline`, the resampled point and its cumulative distance\nfrom the start.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['samples'], 'properties': {'samples': {'type': 'array', 'items': {'$ref': '#/$defs/ElevationSample'}, 'description': 'One sample per input point (or per resampled shape point, in the\n`encoded_polyline` form), in order.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['points'], 'properties': {'points': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'The coordinates to consider.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['area_sq_m'], 'properties': {'area_sq_m': {'type': 'number', 'format': 'double', 'description': 'Enclosed area in square metres, always positive regardless of\nwinding order.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['points'], 'properties': {'points': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'The coordinates to consider.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['min_lat', 'min_lon', 'max_lat', 'max_lon'], 'properties': {'max_lat': {'type': 'number', 'format': 'double', 'description': 'Maximum latitude (north edge).'}, 'max_lon': {'type': 'number', 'format': 'double', 'description': 'Maximum longitude (east edge).'}, 'min_lat': {'type': 'number', 'format': 'double', 'description': 'Minimum latitude (south edge).'}, 'min_lon': {'type': 'number', 'format': 'double', 'description': 'Minimum longitude (west edge).'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['from', 'to'], 'properties': {'to': {'$ref': '#/$defs/LatLon', 'description': 'End coordinate.'}, 'from': {'$ref': '#/$defs/LatLon', 'description': 'Start coordinate.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['bearing_deg'], 'properties': {'bearing_deg': {'type': 'number', 'format': 'double', 'description': 'Initial bearing from `from` to `to`, degrees clockwise from true\nnorth, normalised to 0â\x80\x93360. Note this is the bearing at the start\nof the geodesic: over long distances the bearing changes en route.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['points'], 'properties': {'points': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'The coordinates to consider.'}}}
输出模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['point'], 'properties': {'point': {'$ref': '#/$defs/LatLon', 'description': 'The computed coordinate.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'city': {'type': ['string', 'null'], 'description': 'Structured component: town or city, e.g. "London". Matches the\ncontaining city as well as the immediate locality, so a suburb name\nworks here too.'}, 'lang': {'type': ['string', 'null'], 'description': 'Language of the place names to match and return, as a two-letter\ncode. Defaults to "en", which is what makes English exonyms\n("Munich", "Cologne", "Geneva") resolve to the place meant rather\nthan a same-named town elsewhere. Set it to the language your\nquery is written in; "default" asks for each place\'s own local\nname. Deployments support a fixed set (this one: "en", "de",\n"fr"), and anything outside it is refused.'}, 'focus': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Optional location bias: results near this point rank higher.'}, 'limit': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Maximum number of results (1â\x80\x9350, default 10).'}, 'query': {'type': ['string', 'null'], 'description': 'Free-text place query, e.g. "Dover ferry terminal". Required unless\nat least one structured component is supplied.'}, 'street': {'type': ['string', 'null'], 'description': 'Structured component: street name, e.g. "Downing Street". Matches\nthe street of addresses and POIs (transliterated street names\nincluded) as well as the street itself.'}, 'country': {'type': ['string', 'null'], 'description': 'Structured component: ISO 3166-1 alpha-2 code or country name â\x80\x94\n"GB", "gb", "United Kingdom" and "UK" all mean the same country.\nA value naming no country is refused rather than quietly applied as\na filter that matches nothing.'}, 'postcode': {'type': ['string', 'null'], 'description': 'Structured component: postcode in any spacing or case â\x80\x94 "SW1A 2AA"\nand "sw1a2aa" are one query. A bare UK outward code ("SW1A")\nselects the whole district.'}, 'housenumber': {'type': ['string', 'null'], 'description': 'Structured component: house number, e.g. "10" or "221B". Only\nmeaningful alongside `street` â\x80\x94 a house number on its own excludes\nnearly everything and identifies nothing.'}}}
输出模式
{'type': 'object', '$defs': {'GeocodeHit': {'type': 'object', 'required': ['label', 'lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees.'}, 'city': {'type': ['string', 'null'], 'description': 'City or town, when known.'}, 'name': {'type': ['string', 'null'], 'description': 'Place name, when the source feature has one.'}, 'type': {'type': ['string', 'null'], 'description': 'Feature type, e.g. "house", "street", "city" (falls back to the\nOSM value when the endpoint does not classify).'}, 'label': {'type': 'string', 'description': 'Human-readable one-line label assembled from the address parts.'}, 'match': {'anyOf': [{'$ref': '#/$defs/GeocodeMatch'}, {'type': 'null'}], 'description': "How far this hit can be trusted to be the place that was asked\nfor â\x80\x94 see [`GeocodeMatch`]. Present whenever the MapMap gateway\nanswered; absent on a deployment falling back to the direct Photon\ngeocoder, and absent on the gateway's own fast paths (a pasted\ncoordinate pair, a bare UK outward code, a category browse), which\nanswer without a ranking to report on."}, 'country': {'type': ['string', 'null'], 'description': 'Country, when known.'}, 'postcode': {'type': ['string', 'null'], 'description': 'Postcode, when known.'}}, 'description': 'One geocoding result.'}, 'GeocodeMatch': {'type': 'object', 'required': ['components', 'score_gap', 'source'], 'properties': {'source': {'type': 'string', 'description': 'Which backend answered: "mapmap-index" (the first-party index) or\n"photon".'}, 'score_gap': {'type': 'number', 'format': 'double', 'description': 'The top result\'s score minus the runner-up\'s, rounded to 3 decimal\nplaces. `0` for a single result, and `0` from the `photon` source,\nwhich publishes no per-result score â\x80\x94 so a `0` is "no signal", not\n"a tie".'}, 'components': {'$ref': '#/$defs/GeocodeMatchComponents', 'description': 'Per-component verdict on this hit: one entry for each structured\ncomponent supplied, and empty when the query was free text only.'}}, 'description': 'How well one geocoding result answers what was actually asked.\n\nGeocoding\'s real failure mode is not "no answer" but a confident answer\nto a different question: a plausible row on the wrong street, with\nnothing in the response to say so. This object is that missing say-so,\nand an agent should read it before acting on an address.\n\nHow to read it:\n\n* Any component `unmatched` or `inferred` on the TOP hit means the\n answer does not carry the address that was asked for â\x80\x94 an `unmatched`\n postcode means the result has no postcode at all, `inferred` means it\n has a different one. Neither is a match. Say so rather than presenting\n the hit as the address, and reach for `verify_places` when the address\n came from a model or a user and needs checking rather than using.\n* A small `score_gap` means the ranking barely chose between this hit\n and the runner-up, which is exactly when to show the alternatives\n instead of picking one for the user.'}, 'GeocodeMatchComponents': {'type': 'object', 'properties': {'city': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `city`.'}, 'street': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `street`.'}, 'country': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `country`.'}, 'postcode': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `postcode`.'}, 'housenumber': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `housenumber`.'}}, 'description': 'Per-component verdicts inside a [`GeocodeMatch`]. Each is one of\n"matched", "inferred" or "unmatched"; a component that was not supplied\nis absent entirely.\n\n* "matched" â\x80\x94 the result\'s own field carries the value asked for (case-\n and accent-insensitive, and by containment, so `city: "London"`\n matches "City of London").\n* "inferred" â\x80\x94 the result carries a value for that component, but not\n the one asked for. It reached the page through ranking, as when a\n street is found by its transliterated name and displayed under its\n canonical one.\n* "unmatched" â\x80\x94 the result carries no value for that component at all.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['results'], 'properties': {'results': {'type': 'array', 'items': {'$ref': '#/$defs/GeocodeHit'}, 'description': 'Matching places, best first.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['from', 'bearing_deg', 'distance_m'], 'properties': {'from': {'$ref': '#/$defs/LatLon', 'description': 'Starting coordinate.'}, 'distance_m': {'type': 'number', 'format': 'double', 'description': 'Distance to travel in metres.'}, 'bearing_deg': {'type': 'number', 'format': 'double', 'description': 'Bearing in degrees clockwise from true north.'}}}
输出模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['point'], 'properties': {'point': {'$ref': '#/$defs/LatLon', 'description': 'The computed coordinate.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['from', 'to'], 'properties': {'to': {'$ref': '#/$defs/LatLon', 'description': 'End coordinate.'}, 'from': {'$ref': '#/$defs/LatLon', 'description': 'Start coordinate.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['distance_m'], 'properties': {'distance_m': {'type': 'number', 'format': 'double', 'description': 'Distance in metres along the WGS84 ellipsoid.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['points'], 'properties': {'points': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'The coordinates to consider.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['length_m'], 'properties': {'length_m': {'type': 'number', 'format': 'double', 'description': 'Total geodesic length in metres.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['point', 'line'], 'properties': {'line': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': "The polyline's coordinates, 2 or more."}, 'point': {'$ref': '#/$defs/LatLon', 'description': 'The coordinate to measure from.'}}}
输出模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['point', 'distance_m'], 'properties': {'point': {'$ref': '#/$defs/LatLon', 'description': 'The closest position on the line, which may lie between vertices.'}, 'distance_m': {'type': 'number', 'format': 'double', 'description': 'Geodesic distance from the input point to that position, metres.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['point', 'polygon'], 'properties': {'point': {'$ref': '#/$defs/LatLon', 'description': 'The coordinate to test.'}, 'polygon': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': "The polygon's outer ring, 3 or more coordinates. Closed\nautomatically if the last point does not repeat the first."}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['inside'], 'properties': {'inside': {'type': 'boolean', 'description': 'True when the point is strictly inside the ring. Points exactly on\nthe boundary are **not** counted as inside.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['points', 'tolerance_deg'], 'properties': {'points': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': "The polyline's coordinates, 2 or more."}, 'tolerance_deg': {'type': 'number', 'format': 'double', 'description': 'Douglas-Peucker tolerance in **degrees**, not metres. Around\n0.0001 drops detail finer than roughly 10 m at the equator.'}}}
输出模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['points', 'removed'], 'properties': {'points': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'The retained coordinates, endpoints always preserved.'}, 'removed': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'How many coordinates were removed.'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The job id returned by `submit_optimise_job`.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id', 'kind', 'status', 'terminal', 'created_at', 'units_charged', 'refunded'], 'properties': {'id': {'type': 'string', 'description': 'The job id.'}, 'kind': {'type': 'string', 'description': '`optimise`, `replan` or `matrix`.'}, 'error': {'type': ['string', 'null'], 'description': 'Why it failed, once `status` is `failed`.'}, 'result': {'description': 'The answer, inline, once `status` is `succeeded` â\x80\x94 exactly the body\nthe synchronous tool would have returned. A matrix job answers\n`durations_s` and `distances_m`, as the `matrix` tool does; it also\nstill carries the same numbers as `durations` and `distances`, which\nare DEPRECATED and will be removed in a future release.'}, 'status': {'type': 'string', 'description': '`queued`, `running`, `succeeded` or `failed`. Only `succeeded` and\n`failed` are terminal; keep polling on the other two.'}, 'refunded': {'type': 'boolean', 'description': "Whether a failure refunded the submission's units."}, 'terminal': {'type': 'boolean', 'description': 'Whether `status` is one this job will never leave.'}, 'created_at': {'type': 'string', 'description': 'RFC 3339 UTC submission time.'}, 'started_at': {'type': ['string', 'null'], 'description': 'RFC 3339 UTC time a worker picked it up.'}, 'finished_at': {'type': ['string', 'null'], 'description': 'RFC 3339 UTC time it finished, either way.'}, 'units_charged': {'type': 'integer', 'format': 'int64', 'description': 'Metered units the SUBMISSION drew. This is what was charged;\n`refunded` says whether it came back.'}, 'webhook_status': {'type': ['string', 'null'], 'description': '`delivered` or `delivery_failed`, once a webhook was attempted.'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['style_id'], 'properties': {'style_id': {'type': 'string', 'description': 'Hosted style id, e.g. "midnight-fleet-a1b2c3".'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['style_id', 'style_url', 'theme'], 'properties': {'theme': {'description': 'The latest theme document â\x80\x94 the editable source the next version\nis published from.'}, 'style_id': {'type': 'string', 'description': 'Hosted style id.'}, 'style_url': {'type': 'string', 'description': 'URL of the latest compiled MapLibre style (point MapLibre GL at\nit).'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'to': {'type': ['string', 'null'], 'description': 'Last day to report, `YYYY-MM-DD` (UTC) inclusive. Defaults to\ntoday.'}, 'from': {'type': ['string', 'null'], 'description': 'First day to report, `YYYY-MM-DD` (UTC) inclusive. Defaults to the\nfirst day of the current month. At most 92 days may separate\n`from` and `to`.'}}}
输出模式
{'type': 'object', '$defs': {'UsageDay': {'type': 'object', 'required': ['day', 'endpoints', 'total_units'], 'properties': {'day': {'type': 'string', 'description': 'The day, `YYYY-MM-DD`.'}, 'endpoints': {'type': 'array', 'items': {'$ref': '#/$defs/UsageEndpointTotal'}, 'description': 'Units per endpoint on this day, heaviest first.'}, 'total_units': {'type': 'integer', 'format': 'int64', 'description': 'Total units on this day.'}}, 'description': "One day's usage, in units per endpoint."}, 'UsageEndpointTotal': {'type': 'object', 'required': ['endpoint', 'units'], 'properties': {'units': {'type': 'integer', 'format': 'int64', 'description': 'Weighted quota units, never a count of calls.'}, 'endpoint': {'type': 'string', 'description': 'The endpoint label the meter records, e.g. `/route`, `/geocode`,\n`/tiles`. Labels are collapsed by the meter, so several request\nshapes can share one.'}}, 'description': 'Units attributed to one endpoint.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['key_id', 'identity_pooled', 'from', 'to', 'days', 'totals', 'total_units', 'month_used_units', 'monthly_quota_units', 'balance_millipence'], 'properties': {'to': {'type': 'string', 'description': 'Last day covered, `YYYY-MM-DD` inclusive.'}, 'days': {'type': 'array', 'items': {'$ref': '#/$defs/UsageDay'}, 'description': 'Per-day breakdown over the range, oldest first. A day with no\nusage is absent rather than reported as zero.'}, 'from': {'type': 'string', 'description': 'First day covered, `YYYY-MM-DD` inclusive.'}, 'key_id': {'type': 'string', 'description': 'Identifier of the key this usage belongs to.'}, 'totals': {'type': 'array', 'items': {'$ref': '#/$defs/UsageEndpointTotal'}, 'description': 'Units per endpoint over the whole range.'}, 'total_units': {'type': 'integer', 'format': 'int64', 'description': 'Total units over the whole range.'}, 'identity_pooled': {'type': 'boolean', 'description': "Whether quota is pooled across every key belonging to the same\nidentity. When true, these figures are the identity's shared\nconsumption, so another key of the same owner also spends them."}, 'month_used_units': {'type': 'integer', 'format': 'int64', 'description': 'Units counted against the monthly quota right now: the very number\nthe quota check enforces on, independent of `from`/`to`. Quota is\nmonthly, so this â\x80\x94 not `total_units` â\x80\x94 is what to compare with\n`monthly_quota_units`. It includes units recorded but not yet\nwritten to the daily counters, so over a whole-month range it can\nexceed `total_units`; that is not a discrepancy.'}, 'balance_millipence': {'type': 'integer', 'format': 'int64', 'description': 'Prepaid balance in millipence (thousandths of a penny), for usage\nbeyond the monthly allowance.'}, 'monthly_quota_units': {'type': 'integer', 'format': 'int64', 'description': "The key's monthly allowance in units."}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['geometry_polyline6'], 'properties': {'max_lines': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Ceiling on how many lines come back, 1 to 50 (default 12).'}, 'min_gap_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Least distance between two lines, metres (default 400). A floor\nunder the time budget in every case.'}, 'min_gap_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'Least time between two lines, seconds (default 900, which is four\nan hour). Applied only with `duration_s`.'}, 'duration_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'That route\'s own duration, seconds: `duration_s` from the same\nanswer. **Supply it.** Without it the silence budget falls back to\na distance, and "three to five lines an hour" is a claim about\ntime that a distance answers wrongly at both ends.'}, 'max_offset_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'How near a plaque must come to the route before its line may be\nspoken, metres (default 60, hard ceiling 80).'}, 'voice_format': {'type': ['string', 'null'], 'description': "Container to address each line's audio clip in: `opus` or `m4a`.\nGiven, every line gains a `clip` with its synthesis cache key and\nURL. It NEVER synthesises: the key is a pure function of the\nsentence, so asking here buys nothing."}, 'geometry_polyline6': {'type': 'string', 'description': "The route shape, precision-6 encoded: `geometry_polyline6`\nstraight out of the `route` tool's answer."}}}
输出模式
{'type': 'object', '$defs': {'HeritageLine': {'type': 'object', 'required': ['at_m', 'offset_m', 'say', 'subject', 'basis', 'id'], 'properties': {'id': {'type': 'string', 'description': "The corpus entry's own id, stable across responses, so a client\ncan remember which lines it has already played."}, 'say': {'type': 'string', 'description': 'The sentence to say, verbatim. Written by a person from a\npublic-domain plaque inscription and reviewed by a person.'}, 'at_m': {'type': 'number', 'format': 'double', 'description': 'Distance along the route where this belongs, metres.'}, 'clip': {'description': "The line's audio address (only when `voice_format` was given):\n`hash`, `url` and `format`. Nothing was synthesised to produce it."}, 'basis': {'type': 'string', 'description': 'What the line rests on, in words.'}, 'subject': {'type': 'string', 'description': "The subject's name as the source dataset records it."}, 'offset_m': {'type': 'number', 'format': 'double', 'description': 'Measured perpendicular distance from the plaque\'s own recorded\ncoordinate to the route, metres. Published on every line because\nit is the entire warrant for the word "here", and because the\ncoordinate behind it was recorded by a volunteer and has never\nbeen surveyed.'}, 'plaque_ids': {'type': 'array', 'items': {'type': 'integer', 'format': 'uint32', 'minimum': 0}, 'description': 'The source plaque records, by their OpenPlaques id, so any claim\ncan be taken back to its source.'}}, 'description': 'One reviewed line about the ground the route is on.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['route_length_m', 'corridor', 'lines', 'census', 'attribution', 'caveat'], 'properties': {'lines': {'type': 'array', 'items': {'$ref': '#/$defs/HeritageLine'}, 'description': 'The lines, in route order. Empty is the ordinary answer nearly\neverywhere: read `census` before saying anything about it.'}, 'caveat': {'type': 'string', 'description': 'The standing limits, for relaying to users.'}, 'census': {'description': 'The census of what was NOT said: `corpus_entries`, `within_reach`,\n`beyond_reach`, `spoken`, `silenced_by_budget`, the gap that was\napplied and what it was derived from. An empty `lines` with every\nentry in `beyond_reach` means this feature does not cover the\njourney; an empty `lines` with entries in `silenced_by_budget`\nmeans the budget is working. They are different answers and must\nnot be reported the same way.'}, 'corridor': {'description': 'The corridor that was consulted: its id, name, the road it runs\non and the date its lines were reviewed.'}, 'attribution': {'type': 'string', 'description': 'The licence notice for this answer.'}, 'route_length_m': {'type': 'number', 'format': 'double', 'description': "The route's own length, metres."}}}
输入模式
{'type': 'object', 'properties': {}}
输出模式
{'type': 'object', '$defs': {'PlaceCategory': {'type': 'object', 'required': ['category', 'aliases', 'description'], 'properties': {'aliases': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Colloquial phrases that resolve to this category, sorted. Passing\none of these as free text works too, but the canonical `category`\nis exact.'}, 'category': {'type': 'string', 'description': 'The canonical token to pass as a category filter, e.g. `fuel`.'}, 'description': {'type': 'string', 'description': 'What the category covers, in one line.'}}, 'description': 'One canonical place category, the phrases that name it, and what it\ncovers.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['categories'], 'properties': {'categories': {'type': 'array', 'items': {'$ref': '#/$defs/PlaceCategory'}, 'description': 'Every category `nearby_places`, `search_along_route` and `geocode`\nrecognise, sorted alphabetically by `category`.'}}}
输入模式
{'type': 'object', 'properties': {}}
输出模式
{'type': 'object', '$defs': {'StyleBaseInfo': {'type': 'object', 'required': ['id', 'label', 'description', 'group', 'restrictions'], 'properties': {'id': {'type': 'string', 'description': 'Base id: what `create_style`\'s `base` and the static-map API\'s\n`style=` accept, e.g. "navigator-night".'}, 'group': {'type': 'string', 'description': '"base" for the two stock slates (`light`, `dark`), "designed" for a\ndrawn style.'}, 'label': {'type': 'string', 'description': 'Short display label, e.g. "Navigator Night".'}, 'description': {'type': 'string', 'description': 'One line saying what the base is for. This is what to choose on.'}, 'restrictions': {'type': 'boolean', 'description': "True when the base is drawn to sit under MapMap's\nvehicle-restriction overlay (only `fleet`). That overlay is a\nmapmap.ai runtime layer, not tile data and not part of any compiled\nstyle, so it draws in Studio and on /map and nowhere else. Asking\nfor this base anywhere else gets the palette alone; for a real\nrestriction answer use `check_clearance_on_route` or\n`check_adr_tunnel`, which answer for an actual vehicle."}}, 'description': 'One entry in the named-base catalogue (`sn_style::list_bases`).'}, 'PaletteSlotInfo': {'type': 'object', 'required': ['slot', 'light', 'dark'], 'properties': {'dark': {'type': 'string', 'description': 'Default colour on the dark base theme.'}, 'slot': {'type': 'string', 'description': 'Slot name, e.g. "water" or "roadMajor".'}, 'light': {'type': 'string', 'description': 'Default colour on the light base theme.'}}, 'description': 'One themable palette slot with its built-in light/dark defaults.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['bases', 'palette_slots', 'layer_ids', 'source_layers', 'attribution'], 'properties': {'bases': {'type': 'array', 'items': {'$ref': '#/$defs/StyleBaseInfo'}, 'description': "The first-party named bases a style can start from, in display\norder: pass one to `create_style`'s `base`, or to the static-map\nAPI's `style=`."}, 'layer_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': "The skeleton layer ids a theme's `layers` may override, in paint\norder (first = bottom)."}, 'attribution': {'type': 'string', 'description': 'The attribution contract: enforced on every compiled style, not\nthemable.'}, 'palette_slots': {'type': 'array', 'items': {'$ref': '#/$defs/PaletteSlotInfo'}, 'description': "The named palette slots a theme's `palette` may override, with\ntheir light/dark defaults, in presentation order."}, 'source_layers': {'type': 'array', 'items': {'type': 'string'}, 'description': 'The OpenMapTiles source-layers the tiles emit; `extra_layers` must\nreference one of these.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'shape': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'The trace as an ordered list of recorded points, oldest first.\nBetween 2 and 2000 points. Provide this or `encoded_polyline`.'}, 'costing': {'anyOf': [{'$ref': '#/$defs/CostingKind'}, {'type': 'null'}], 'description': 'Costing model the trace was travelled under: `auto` (default),\n`truck`, `bicycle`, `pedestrian` or `motor_scooter`. It decides\nwhich roads the trace may be matched onto, so a walked trace\nmatched as `auto` snaps to the carriageway rather than the path.'}, 'encoded_polyline': {'type': ['string', 'null'], 'description': 'The trace as a Google encoded polyline with six digits of decimal\nprecision (polyline6) â\x80\x94 the geometry `route` and `match_trace`\nthemselves return. Provide this or `shape`.'}}}
输出模式
{'type': 'object', '$defs': {'SegmentSummary': {'type': 'object', 'required': ['distance_m', 'edge_count'], 'properties': {'distance_m': {'type': 'number', 'format': 'double', 'description': 'Distance carrying this flag in metres. Zero means none of the\nmatched path did.'}, 'edge_count': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'How many matched segments carried this flag.'}}, 'description': 'How much of the matched path carried one flag (toll, bridge, tunnel).\nThe engine reports no separate time for these, so distance and a count\nare all that can honestly be given.'}, 'SurfaceSummary': {'type': 'object', 'required': ['surface', 'distance_m', 'edge_count'], 'properties': {'surface': {'type': 'string', 'description': 'The surface, as the routing graph records it: `paved_smooth`,\n`paved`, `paved_rough`, `compacted`, `dirt`, `gravel`, `path`,\n`impassable`.'}, 'distance_m': {'type': 'number', 'format': 'double', 'description': 'Distance on this surface in metres.'}, 'edge_count': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'How many matched segments carried this surface.'}}, 'description': 'Distance the matched path spent on one road surface.'}, 'AdminAreaSummary': {'type': 'object', 'required': ['distance_m', 'duration_s', 'edge_count'], 'properties': {'state': {'type': ['string', 'null'], 'default': None, 'description': 'State/region name, or null when the graph records none.'}, 'country': {'type': ['string', 'null'], 'default': None, 'description': 'Country name, or null as for `country_code`.'}, 'distance_m': {'type': 'number', 'format': 'double', 'description': 'Distance in this area in metres.'}, 'duration_s': {'type': 'number', 'format': 'double', 'description': 'Time in this area in seconds.'}, 'edge_count': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'How many matched segments fell in this area.'}, 'state_code': {'type': ['string', 'null'], 'default': None, 'description': 'State/region code, or null when the graph records none.'}, 'country_code': {'type': ['string', 'null'], 'default': None, 'description': 'ISO 3166-1 alpha-2 country code, or null where the routing graph\nplaces the segment in no admin area at all.'}}, 'description': 'Distance and time the matched path spent in one administrative area.'}, 'RoadClassSummary': {'type': 'object', 'required': ['road_class', 'distance_m', 'duration_s', 'edge_count'], 'properties': {'distance_m': {'type': 'number', 'format': 'double', 'description': 'Distance on this road class in metres.'}, 'duration_s': {'type': 'number', 'format': 'double', 'description': 'Time on this road class in seconds.'}, 'edge_count': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'How many matched segments carried this road class.'}, 'road_class': {'type': 'string', 'description': 'The road class, as the routing graph records it: `motorway`,\n`trunk`, `primary`, `secondary`, `tertiary`, `unclassified`,\n`residential`, `service_other`.'}}, 'description': 'Distance and time the matched path spent on one road class.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['geometry_polyline6', 'distance_m', 'duration_s', 'summary', 'costing', 'edge_count', 'by_road_class', 'by_admin', 'by_surface', 'toll', 'bridge', 'tunnel'], 'properties': {'toll': {'$ref': '#/$defs/SegmentSummary', 'description': 'Tolled portion of the matched path.'}, 'bridge': {'$ref': '#/$defs/SegmentSummary', 'description': 'Bridge portion of the matched path.'}, 'tunnel': {'$ref': '#/$defs/SegmentSummary', 'description': 'Tunnel portion of the matched path.'}, 'costing': {'type': 'string', 'description': 'Costing the trace was matched under.'}, 'summary': {'type': 'string', 'description': 'One-line human summary of the match, for reading aloud.'}, 'by_admin': {'type': 'array', 'items': {'$ref': '#/$defs/AdminAreaSummary'}, 'description': 'Distance and time by administrative area, longest first. An entry\nwhose codes are all null covers segments the graph could not place\nin any admin area â\x80\x94 counted honestly rather than guessed at.'}, 'by_surface': {'type': 'array', 'items': {'$ref': '#/$defs/SurfaceSummary'}, 'description': 'Distance by road surface (`paved`, `paved_smooth`, `gravel`, â\x80¦),\nlongest first. Empty when the graph records no surface for any\nmatched segment.'}, 'distance_m': {'type': 'number', 'format': 'double', 'description': 'Length of the matched path in metres.'}, 'duration_s': {'type': 'number', 'format': 'double', 'description': "Travel time along the matched path in seconds, from the engine's\nown time model."}, 'edge_count': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'How many road segments the trace matched onto.'}, 'by_road_class': {'type': 'array', 'items': {'$ref': '#/$defs/RoadClassSummary'}, 'description': 'Distance and time by road class (`motorway`, `primary`,\n`residential`, â\x80¦), longest first.'}, 'geometry_polyline6': {'type': 'string', 'description': 'The matched path as a Google encoded polyline with six digits of\ndecimal precision (polyline6). This is the trace snapped to real\nroads, not the raw input.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'TruckSpec': {'type': 'object', 'properties': {'hazmat': {'type': 'boolean', 'default': False, 'description': 'Whether the vehicle carries dangerous goods (ADR). Defaults to\nfalse.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres.'}, 'height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle height in metres.'}, 'length_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle length in metres.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels).'}, 'gross_weight_t': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross combination weight in metric tonnes.'}}, 'description': 'Truck profile for routing: physical dimensions plus the ADR\ndangerous-goods declaration. Omitted dimensions default to the EU\nmaximum authorised dimensions of Council Directive 96/53/EC (4.0 m\nheight, 2.55 m width, 16.5 m length, 40 t gross weight).'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['origins', 'destinations'], 'properties': {'truck': {'anyOf': [{'$ref': '#/$defs/TruckSpec'}, {'type': 'null'}], 'description': 'Truck profile (dimensions + ADR declaration). Requires costing\n"truck".'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing model: "auto" (default), "truck", "bicycle", "pedestrian"\nor "motor_scooter".'}, 'origins': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'Origin locations (matrix rows).'}, 'destinations': {'type': 'array', 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'Destination locations (matrix columns).'}, 'exclude_polygons': {'type': ['array', 'null'], 'items': {'type': 'array', 'items': {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2}}, 'description': 'Areas to avoid â\x80\x94 scenario analysis ("close this bridge and\nrecompute the matrix"): an array of polygons, each an array of\n`[lon, lat]` pairs forming one exterior ring (GeoJSON-style,\nlongitude FIRST). Roads intersecting any ring are excluded from\nevery cell\'s path finding. Applies to the Valhalla engine;\nunsupported on the GraphHopper engine, where it is ignored.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['durations_s', 'distances_m'], 'properties': {'distances_m': {'type': 'array', 'items': {'type': 'array', 'items': {'type': ['number', 'null'], 'format': 'double'}}, 'description': 'Travel distances in metres, same shape as `durations_s`. Null\ncells are unreachable pairs.'}, 'durations_s': {'type': 'array', 'items': {'type': 'array', 'items': {'type': ['number', 'null'], 'format': 'double'}}, 'description': 'Travel times in seconds; `durations_s[i][j]` is origin `i` â\x86\x92\ndestination `j`. Null cells are unreachable pairs.'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude of the search point in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude of the search point in decimal degrees (â\x88\x92180 to 180).'}, 'name': {'type': ['string', 'null'], 'description': 'The name or brand of the place to find â\x80\x94 "Lloyds", "Lloyds Bank",\n"Sainsbury\'s" â\x80\x94 for "where is the nearest X" questions. Every word\nmust appear in the place\'s name or one of its alternative names,\ncase- and accent-insensitively, with the last word also matching as\na prefix ("Sains" finds Sainsbury\'s). Combine with `category` to\ndisambiguate a brand used by more than one kind of place ("Lloyds"\nplus "bank" excludes Lloyds Pharmacy). Optional when `category` is\ngiven; at least one of the two is required.'}, 'limit': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Maximum number of results (1â\x80\x9310, default 5).'}, 'fov_deg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Field of view: the full width in degrees of a cone centred on\n`heading_deg`, outside which results are dropped â\x80\x94 it is the\nFULL width, so 90 keeps only what lies within 45 degrees either\nside of dead ahead. Needs\n`heading_deg` â\x80\x94 a cone has to point somewhere. The count of\nresults removed is reported as `out_of_view`.'}, 'category': {'type': ['string', 'null'], 'description': 'The kind of place to find. The gateway matches it against the\nindex\'s lowercased OSM tag values (the value of the POI\'s\n`amenity`/`shop`/`tourism`/`railway`/â\x80¦ tag) â\x80\x94 e.g. "cafe", "fuel",\n"charging_station", "parking", "pharmacy", "supermarket", "hotel",\n"restaurant", "fast_food", "atm", "bakery", "hospital", "station" â\x80\x94\nand normalises common colloquial names first ("coffee" â\x86\x92 cafe;\n"ev_charging", "ev charging" â\x86\x92 charging_station; "petrol" â\x86\x92 fuel;\n"chemist" â\x86\x92 pharmacy). A category the index does not carry matches\nnothing: the result is an empty list, not an error. Optional when\n`name` is given; at least one of the two is required.'}, 'radius_m': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Maximum straight-line distance of any result from the point, in\nmetres (1â\x80\x93100000, default 2500).'}, 'heading_deg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Which way the user is facing, in degrees **clockwise from true\nnorth** (0 = north, 90 = east, 180 = south, 270 = west). Supply it\nand every result is also described from the user\'s point of view\n("just ahead on your right"); omit it and results fall back to\ncardinal directions ("to the north-east"), so the tool works with\nor without a compass.'}}}
输出模式
{'type': 'object', '$defs': {'NearbyPlace': {'type': 'object', 'required': ['label', 'lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude of the place in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude of the place in decimal degrees.'}, 'city': {'type': ['string', 'null'], 'description': 'City or town, when known.'}, 'name': {'type': ['string', 'null'], 'description': 'Place name, when the source feature has one.'}, 'type': {'type': ['string', 'null'], 'description': 'Feature type â\x80\x94 "poi" for category-browse hits.'}, 'label': {'type': 'string', 'description': 'Human-readable one-line label assembled from the address parts.'}, 'country': {'type': ['string', 'null'], 'description': 'Country, when known: a country name, or the ISO 3166-1 alpha-2\ncode (e.g. "GB") on first-party hits, which carry only the code.'}, 'details': {'description': 'Whitelisted OSM display tags on POI hits (opening_hours, website,\nphone, brand, cuisine, wheelchair, wikipedia, ...), passed through\nverbatim when present.'}, 'postcode': {'type': ['string', 'null'], 'description': 'Postcode, when known.'}, 'direction': {'type': ['string', 'null'], 'description': 'The direction phrased for speech â\x80\x94 "ahead and slightly to your\nright, about 80 metres" with a heading, "to the north-east, about\n80 metres" without one. Deliver this verbatim rather than reading\nout coordinates.'}, 'categories': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': 'POI categories (e.g. ["cafe"]), when the index carries them.'}, 'distance_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Straight-line distance from the queried point in metres.'}, 'bearing_deg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Bearing from the queried point to this place, degrees clockwise\nfrom true north. Always present.'}, 'relative_bearing_deg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Where this place is relative to the way the user is facing:\nnegative to the left, positive to the right, â\x88\x92180 to 180. Present\nonly when the request supplied `heading_deg`.'}}, 'description': 'One `nearby_places` result: a place matching the requested category\nand/or name near the queried point. The same shape family as [`GeocodeHit`], plus the\nbrowse-only extras (`distance_m`, `categories`, `details`) and the\negocentric extras (`bearing_deg`, `relative_bearing_deg`, `direction`).'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['results'], 'properties': {'results': {'type': 'array', 'items': {'$ref': '#/$defs/NearbyPlace'}, 'description': 'Matching places, nearest first. Empty when the index has no such\nplace within the radius.'}, 'out_of_view': {'type': 'integer', 'format': 'uint32', 'minimum': 0, 'description': 'How many otherwise-matching places were dropped for falling\noutside `fov_deg`. Non-zero means there are matching places near\nthe user that are simply not in front of them â\x80\x94 say so rather\nthan reporting nothing nearby. Always 0 when no field of view was\nset.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'RelaxSpec': {'type': 'object', 'properties': {'allow_overtime_s': {'type': ['integer', 'null'], 'format': 'int64', 'description': "Extend every vehicle's shift END by this many seconds. Shift starts\nare never moved earlier â\x80\x94 a driver cannot begin before they begin."}, 'time_windows_by_s': {'type': ['integer', 'null'], 'format': 'int64', 'description': 'Widen every task time window by this many seconds at EACH end. A\n09:00â\x80\x9312:00 window with 1800 becomes 08:30â\x80\x9312:30.'}}, 'description': 'What the caller is willing to give up if the first solve leaves work\nunassigned. At least one field is required.'}, 'TruckSpec': {'type': 'object', 'properties': {'hazmat': {'type': 'boolean', 'default': False, 'description': 'Whether the vehicle carries dangerous goods (ADR). Defaults to\nfalse.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres.'}, 'height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle height in metres.'}, 'length_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle length in metres.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels).'}, 'gross_weight_t': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross combination weight in metric tonnes.'}}, 'description': 'Truck profile for routing: physical dimensions plus the ADR\ndangerous-goods declaration. Omitted dimensions default to the EU\nmaximum authorised dimensions of Council Directive 96/53/EC (4.0 m\nheight, 2.55 m width, 16.5 m length, 40 t gross weight).'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}, 'ReloadsSpec': {'type': 'object', 'required': ['max_trips'], 'properties': {'depot': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Where the vehicle reloads. Omitted, its own `start` is used (or its\n`end` if it declared only that).'}, 'max_trips': {'type': 'integer', 'format': 'uint32', 'minimum': 0, 'description': 'How many trips this vehicle may run in its shift, 2â\x80\x935. A BUDGET,\nnot a prediction: the shift is cut into that many fixed windows\nbefore the solve, so asking for five trips on a shift that supports\nthree shrinks every window to a fifth and can make the whole day\nworse. Ask for the number of trips you actually expect to run.'}, 'reload_time_s': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Seconds at the depot between trips â\x80\x94 tipping, reloading, the\nweighbridge. Held out of the shift before it is partitioned, so it\nis never accidentally spent driving.'}}, 'description': "A vehicle's multi-trip reload plan."}, 'EmissionsFuel': {'oneOf': [{'type': 'string', 'const': 'petrol', 'description': "Petrol, including petrol hybrids (schemes rate a hybrid by its\ncombustion engine's approval)."}, {'type': 'string', 'const': 'diesel', 'description': 'Diesel, including diesel hybrids.'}, {'type': 'string', 'const': 'electric', 'description': 'Battery-electric.'}, {'type': 'string', 'const': 'hydrogen', 'description': 'Hydrogen fuel cell.'}, {'type': 'string', 'const': 'gas', 'description': 'LPG or CNG; rated as petrol by every scheme in the dataset.'}], 'description': 'What a vehicle burns, in clean-air-zone scheme terms.'}, 'EmissionsSpec': {'type': 'object', 'required': ['vehicle_category', 'fuel'], 'properties': {'fuel': {'$ref': '#/$defs/EmissionsFuel', 'description': 'What it burns.'}, 'euro_standard': {'type': ['integer', 'null'], 'format': 'uint8', 'maximum': 255, 'minimum': 0, 'description': 'Its Euro emission standard, 1â\x80\x936. Heavy-duty approvals are written\nin Roman numerals (Euro VI); declare Euro VI as `6`. Required for\nany combustion fuel â\x80\x94 without it no zone can be resolved, and a\nhalf-declared vehicle is indistinguishable from an undeclared one.\nOptional only for `electric` or `hydrogen`.'}, 'vehicle_category': {'$ref': '#/$defs/EmissionsVehicleCategory', 'description': 'What kind of vehicle this is, in scheme terms.'}}, 'description': "A vehicle's emission declaration, for clean-air / low-emission zone\nassessment."}, 'TerritorySpec': {'type': 'object', 'required': ['id', 'polygon'], 'properties': {'id': {'type': 'string', 'description': 'Caller-chosen id, echoed back and referenced by\n`vehicles[].territory_ids`. Must be unique within the request.'}, 'polygon': {'type': 'array', 'items': {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2}, 'description': 'The outer ring as GeoJSON `[lon, lat]` positions â\x80\x94 longitude\nFIRST. Closed or open; an unclosed ring is closed for you.'}}, 'description': 'One named territory: a polygon that bounds which vehicle may serve\nwhich stop.'}, 'OptimiseJobSpec': {'type': 'object', 'required': ['id', 'location'], 'properties': {'id': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'Caller-chosen job id, echoed back in steps and `unassigned`.'}, 'pickup': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Quantities picked up at the job (matches vehicle `capacity`).'}, 'skills': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'uint32', 'minimum': 0}, 'description': 'Skills the job requires.'}, 'delivery': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Quantities delivered to the job (matches vehicle `capacity`).'}, 'location': {'$ref': '#/$defs/LatLon', 'description': 'Job location.'}, 'service_s': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'On-site service time in seconds.'}, 'time_windows': {'type': ['array', 'null'], 'items': {'type': 'array', 'items': {'type': 'integer', 'format': 'int64'}}, 'description': 'Acceptable `[start, end]` windows in seconds.'}}, 'description': 'One single-stop job of an optimisation problem.'}, 'OptimiseVehicleSpec': {'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'Caller-chosen vehicle id, echoed back on its route.'}, 'end': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'End location; omitted, the route ends at its last stop.'}, 'start': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Start location; at least one of `start`/`end` is required.'}, 'skills': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'uint32', 'minimum': 0}, 'description': 'Skills this vehicle provides.'}, 'reloads': {'anyOf': [{'$ref': '#/$defs/ReloadsSpec'}, {'type': 'null'}], 'description': 'Let this vehicle return to a depot, reload and go out again â\x80\x94 the\nwaste-collection tipping round, the van that comes back for a\nsecond wave of parcels.'}, 'capacity': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Multidimensional capacity (same length as job `delivery`/`pickup`).'}, 'time_window': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Working window as `[start, end]` in seconds (any consistent epoch).'}, 'territory_ids': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': "Ids of the request's `territories` this vehicle may work in.\nOmitted or empty, the vehicle is UNRESTRICTED and may serve any\ntask, inside a territory or outside every one of them. Listed, the\nvehicle may serve a task only if that task sits inside at least one\nof the named territories."}}, 'description': 'One vehicle of an optimisation fleet.'}, 'OptimiseShipmentSpec': {'type': 'object', 'required': ['pickup', 'delivery'], 'properties': {'amount': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Quantities moved (matches vehicle `capacity`).'}, 'pickup': {'$ref': '#/$defs/OptimiseShipmentStopSpec', 'description': 'The pickup end.'}, 'skills': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'uint32', 'minimum': 0}, 'description': 'Skills the shipment requires.'}, 'delivery': {'$ref': '#/$defs/OptimiseShipmentStopSpec', 'description': 'The delivery end.'}}, 'description': 'A pickup+delivery pair that must ride the same vehicle, pickup first.'}, 'EmissionsVehicleCategory': {'oneOf': [{'type': 'string', 'const': 'car', 'description': 'A private car.'}, {'type': 'string', 'const': 'van', 'description': 'A van or light goods vehicle up to 3.5 tonnes.'}, {'type': 'string', 'const': 'minibus', 'description': 'A minibus (typically 8+ passenger seats, up to 5 tonnes).'}, {'type': 'string', 'const': 'hgv', 'description': 'A heavy goods vehicle over 3.5 tonnes.'}, {'type': 'string', 'const': 'bus', 'description': 'A bus over 5 tonnes.'}, {'type': 'string', 'const': 'coach', 'description': 'A coach over 5 tonnes.'}, {'type': 'string', 'const': 'taxi', 'description': 'A licensed hackney carriage.'}, {'type': 'string', 'const': 'phv', 'description': 'A private hire vehicle.'}, {'type': 'string', 'const': 'motorcycle', 'description': 'A motorcycle, moped or tricycle.'}, {'type': 'string', 'const': 'motorhome', 'description': 'A motor caravan or campervan.'}], 'description': 'What a vehicle is, in clean-air-zone scheme terms.\n\nDeclaring this turns "charge depends on vehicle emissions" into an\nanswer. Without it a zone can only be named, never priced.'}, 'OptimiseShipmentStopSpec': {'type': 'object', 'required': ['id', 'location'], 'properties': {'id': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'Caller-chosen stop id, echoed back in steps and `unassigned`.'}, 'location': {'$ref': '#/$defs/LatLon', 'description': 'Stop location.'}, 'service_s': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'On-site service time in seconds.'}}, 'description': 'One end (pickup or delivery) of a shipment.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['vehicles'], 'properties': {'jobs': {'type': 'array', 'items': {'$ref': '#/$defs/OptimiseJobSpec'}, 'description': 'Single-stop jobs (at least one job or shipment overall).'}, 'truck': {'anyOf': [{'$ref': '#/$defs/TruckSpec'}, {'type': 'null'}], 'description': 'Truck profile (dimensions + ADR declaration). Requires costing\n"truck"; the travel-time matrix then respects dimensional and\ndangerous-goods restrictions, so the whole plan is truck-legal.'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing model for the travel-time matrix: "auto" (default),\n"truck", "bicycle", "pedestrian" or "motor_scooter".'}, 'vehicles': {'type': 'array', 'items': {'$ref': '#/$defs/OptimiseVehicleSpec'}, 'description': 'The fleet (at least one vehicle, each with a start and/or end).'}, 'emissions': {'anyOf': [{'$ref': '#/$defs/EmissionsSpec'}, {'type': 'null'}], 'description': "The fleet's emission declaration, for UK clean-air / low-emission\nzone assessment. On its own it annotates: the response's `zones`\nblock names every zone containing one of the problem's own\nlocations and what this vehicle would pay there. With\n`avoid_zones` it also steers the internal travel-time matrix away\nfrom those zones, so the plan itself changes."}, 'shipments': {'type': 'array', 'items': {'$ref': '#/$defs/OptimiseShipmentSpec'}, 'description': 'Pickup+delivery pairs.'}, 'avoid_zones': {'type': ['boolean', 'null'], 'description': "Keep the optimisation's travel-time matrix out of every zone the\ndeclared vehicle would be charged or banned in. Requires\n`emissions`."}, 'territories': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/TerritorySpec'}, 'description': 'Fleet territories: named polygons that bound which vehicle may\nserve which stop, referenced by `vehicles[].territory_ids`. These\nare request data â\x80\x94 caller-drawn rounds, validated per call and\nnever stored. Nothing to do with clean-air zones or with the\noffline map packages of the same word.'}, 'relax_if_unassigned': {'anyOf': [{'$ref': '#/$defs/RelaxSpec'}, {'type': 'null'}], 'description': 'Re-solve ONCE with these relaxations if the first solve leaves work\nunassigned, and say honestly which plan came back. At most one\nsecond solve, never beyond the caps you state, and the relaxed plan\nis returned only if it assigns MORE work than the first â\x80\x94 giving\naway constraints for nothing is strictly worse than not giving them\naway. Breaks are never widened, nor are capacities, skills,\nterritories or task caps: only time windows move, and only by the\nstated amounts. Bills as two solves when the second one runs.'}}}
输出模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'OptimisedStep': {'type': 'object', 'required': ['type', 'arrival_s', 'duration_s', 'service_s', 'waiting_time_s'], 'properties': {'id': {'type': ['integer', 'null'], 'format': 'uint64', 'minimum': 0, 'description': 'The job/shipment-stop id, absent on start/end steps.'}, 'load': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Vehicle load after the step, when reported.'}, 'type': {'type': 'string', 'description': 'Step kind: "start", "job", "pickup", "delivery", "break" or "end".'}, 'location': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': "The step's location resolved back to coordinates."}, 'arrival_s': {'type': 'integer', 'format': 'int64', 'description': "Arrival time in seconds (same epoch as the request's windows)."}, 'service_s': {'type': 'integer', 'format': 'int64', 'description': 'On-site service time in seconds.'}, 'duration_s': {'type': 'integer', 'format': 'int64', 'description': 'Cumulative travel time when the step begins, in seconds.'}, 'waiting_time_s': {'type': 'integer', 'format': 'int64', 'description': 'Waiting time before the step in seconds.'}}, 'description': 'One step of an optimised vehicle route.'}, 'OptimisedRoute': {'type': 'object', 'required': ['vehicle', 'duration_s', 'service_s', 'waiting_time_s', 'steps'], 'properties': {'steps': {'type': 'array', 'items': {'$ref': '#/$defs/OptimisedStep'}, 'description': 'Ordered steps: start, tasks in visit order, end.'}, 'vehicle': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'The vehicle id from the request.'}, 'service_s': {'type': 'integer', 'format': 'int64', 'description': 'Total on-site service time in seconds.'}, 'distance_m': {'type': ['integer', 'null'], 'format': 'int64', 'description': 'Total travel distance in metres, when reported.'}, 'duration_s': {'type': 'integer', 'format': 'int64', 'description': 'Total travel time in seconds.'}, 'waiting_time_s': {'type': 'integer', 'format': 'int64', 'description': 'Total waiting time in seconds.'}}, 'description': "One vehicle's optimised route."}, 'UnassignedTask': {'type': 'object', 'required': ['id', 'type'], 'properties': {'id': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'The task id from the request.'}, 'type': {'type': 'string', 'description': 'Task kind: "job", "pickup" or "delivery".'}, 'location': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': "The task's location, when known."}}, 'description': 'One unassigned task of an optimisation solution.'}, 'OptimiseSummary': {'type': 'object', 'required': ['cost', 'routes', 'unassigned', 'duration_s', 'service_s', 'waiting_time_s'], 'properties': {'cost': {'type': 'integer', 'format': 'int64', 'description': 'Solver cost of the plan (travel seconds under the default model).'}, 'routes': {'type': 'integer', 'format': 'int64', 'description': 'Number of vehicle routes in the plan.'}, 'service_s': {'type': 'integer', 'format': 'int64', 'description': 'Total service time in seconds.'}, 'distance_m': {'type': ['integer', 'null'], 'format': 'int64', 'description': 'Total travel distance in metres, when reported.'}, 'duration_s': {'type': 'integer', 'format': 'int64', 'description': 'Total travel time in seconds.'}, 'unassigned': {'type': 'integer', 'format': 'int64', 'description': 'Number of unassigned tasks.'}, 'waiting_time_s': {'type': 'integer', 'format': 'int64', 'description': 'Total waiting time in seconds.'}}, 'description': 'Solution summary of the `optimise_routes` tool.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['profile', 'summary', 'unassigned', 'routes'], 'properties': {'zones': {'description': "Clean-air / low-emission zones touching the problem's own\nlocations, and what the declared vehicle pays in each. Present only\nwhen `emissions` was declared."}, 'routes': {'type': 'array', 'items': {'$ref': '#/$defs/OptimisedRoute'}, 'description': 'One optimised route per used vehicle.'}, 'profile': {'type': 'string', 'description': 'The matrix costing profile the plan was computed with ("auto",\n"truck", "bicycle", "pedestrian" or "motor_scooter").'}, 'reloads': {'description': "The multi-trip split: each vehicle's trips, their windows, the\ndepot each returns to, and the stated approximation. Present only\nwhen a vehicle declared `reloads`.\n\nRead the `basis` inside it before quoting arrival times. The trip\nwindows are fixed BEFORE the solve, so a lorry that tips early\ncannot lend the spare time to its next trip: stops can come back\nunassigned that a truly sequential model would have served. The\nplan is feasible, never optimistic â\x80\x94 it cannot put a vehicle in two\nplaces at once â\x80\x94 but it is not optimal. Re-plan after each tip\nthrough `replan_routes` for the tighter answer."}, 'summary': {'$ref': '#/$defs/OptimiseSummary', 'description': 'Solution summary.'}, 'relaxation': {'description': 'The relaxation report: the caps requested, whether a second solve\nran, whether ITS plan is the one returned, what was widened, and\nwhat is still unassigned. Present only when `relax_if_unassigned`\nwas declared.\n\nAlways read `second_solve` and `relaxed_plan_used` before telling\nanyone the day fits. A plan produced under relaxation has had\npromises moved, and the block is what says so.'}, 'unassigned': {'type': 'array', 'items': {'$ref': '#/$defs/UnassignedTask'}, 'description': 'Tasks the solver could not assign to any vehicle.'}, 'territories': {'description': 'How the territories bound the plan: which vehicle was eligible for\nwhat, and any task no eligible vehicle existed for. Present only\nwhen `territories` was declared.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'TruckSpec': {'type': 'object', 'properties': {'hazmat': {'type': 'boolean', 'default': False, 'description': 'Whether the vehicle carries dangerous goods (ADR). Defaults to\nfalse.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres.'}, 'height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle height in metres.'}, 'length_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle length in metres.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels).'}, 'gross_weight_t': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross combination weight in metric tonnes.'}}, 'description': 'Truck profile for routing: physical dimensions plus the ADR\ndangerous-goods declaration. Omitted dimensions default to the EU\nmaximum authorised dimensions of Council Directive 96/53/EC (4.0 m\nheight, 2.55 m width, 16.5 m length, 40 t gross weight).'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}, 'OrderStopSpec': {'type': 'object', 'required': ['location'], 'properties': {'label': {'type': ['string', 'null'], 'description': 'Human-readable label echoed back in the ordered plan\n(e.g. "chemist" or "site B").'}, 'location': {'$ref': '#/$defs/LatLon', 'description': "The stop's location."}, 'service_s': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'On-site time in seconds (waiting, loading, shopping).'}}, 'description': 'One errand stop of an `order_stops` request.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['start', 'stops'], 'properties': {'end': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Optional fixed final destination. Mutually exclusive with\n`round_trip`; omitted (and not a round trip), the run ends at\nwhichever stop the solver visits last.'}, 'start': {'$ref': '#/$defs/LatLon', 'description': 'Where the run starts.'}, 'stops': {'type': 'array', 'items': {'$ref': '#/$defs/OrderStopSpec'}, 'description': 'The stops to put in the best visiting order (1â\x80\x93100).'}, 'truck': {'anyOf': [{'$ref': '#/$defs/TruckSpec'}, {'type': 'null'}], 'description': 'Truck profile (dimensions + ADR declaration); requires costing\n"truck". The travel-time matrix then respects dimensional and\ndangerous-goods restrictions.'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing model: "auto" (default) or "truck".'}, 'round_trip': {'type': 'boolean', 'default': False, 'description': 'Return to `start` after the last stop (default false).'}}}
输出模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'OrderedStop': {'type': 'object', 'required': ['order', 'stop_index', 'location', 'arrival_s'], 'properties': {'label': {'type': ['string', 'null'], 'description': "The request's label for this stop, when one was given."}, 'order': {'type': 'integer', 'format': 'uint32', 'minimum': 0, 'description': '1-based visit order.'}, 'location': {'$ref': '#/$defs/LatLon', 'description': "The stop's location."}, 'arrival_s': {'type': 'integer', 'format': 'int64', 'description': 'Arrival time as an offset from departure, in seconds.'}, 'stop_index': {'type': 'integer', 'format': 'uint32', 'minimum': 0, 'description': "The stop's 0-based index in the request's `stops` array."}}, 'description': 'One stop of an ordered errand plan.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['profile', 'ordered', 'unassigned_stop_indexes', 'duration_s'], 'properties': {'ordered': {'type': 'array', 'items': {'$ref': '#/$defs/OrderedStop'}, 'description': 'The stops in optimal visiting order.'}, 'profile': {'type': 'string', 'description': 'The matrix costing profile ("auto" or "truck").'}, 'distance_m': {'type': ['integer', 'null'], 'format': 'int64', 'description': 'Total travel distance in metres, when reported.'}, 'duration_s': {'type': 'integer', 'format': 'int64', 'description': 'Total travel time in seconds.'}, 'unassigned_stop_indexes': {'type': 'array', 'items': {'type': 'integer', 'format': 'uint32', 'minimum': 0}, 'description': '0-based indexes of stops the solver could not fit (empty in the\nnormal, unconstrained case).'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['lat', 'lon', 'bearing_deg'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude of the observer in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude of the observer in decimal degrees (â\x88\x92180 to 180).'}, 'name': {'type': ['string', 'null'], 'description': 'A place name or brand to look for. At least one of `category` and\n`name` is required.'}, 'limit': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Maximum number of results (1â\x80\x9325, default 5).'}, 'fov_deg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Full width in degrees of the cone centred on `bearing_deg` (1â\x80\x93360,\ndefault 60, so 30 degrees either side). The FULL width, not the\nhalf angle.'}, 'category': {'type': ['string', 'null'], 'description': 'The kind of place to look for, from the same vocabulary\n`nearby_places` uses ("cafe", "pub", "fuel", "charging_station" â\x80¦).\nUse "building" to ask what a named building over there is. At\nleast one of `category` and `name` is required.'}, 'radius_m': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Maximum straight-line range in metres (1â\x80\x935000, default 1000).'}, 'bearing_deg': {'type': 'number', 'format': 'double', 'description': 'Which way the observer is facing, in degrees **clockwise from true\nnorth** (0 = north, 90 = east, 180 = south, 270 = west). Required:\nthis tool answers "what is over there", and "there" has to point\nsomewhere.'}, 'eye_height_m': {'type': ['number', 'null'], 'format': 'double', 'description': "Height of the observer's eye above the ground in metres (0â\x80\x93500,\ndefault 1.6, a standing adult). A driver's eye is nearer 1.2 m."}, 'visible_only': {'type': ['boolean', 'null'], 'description': 'When true, return only places whose visibility verdict is `clear`.\nDefault false, which returns everything in the cone WITH its\nverdict, usually the better answer, because "it is there but you\ncannot see it from here" is worth saying.'}}}
输出模式
{'type': 'object', '$defs': {'PlaceInView': {'type': 'object', 'required': ['name', 'label', 'lat', 'lon', 'distance_m', 'bearing_deg', 'angular_offset_deg', 'direction', 'visibility'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees.'}, 'name': {'type': 'string', 'description': 'Place name.'}, 'label': {'type': 'string', 'description': 'One-line label: name, street, postcode, town, country.'}, 'direction': {'type': 'string', 'description': 'The direction phrased for speech, from where the observer stands\n("ahead and slightly to your right, about 80 metres"). Prefer\nreading this aloud over coordinates.'}, 'categories': {'type': 'array', 'items': {'type': 'string'}, 'default': [], 'description': "The place's categories as the map tags them."}, 'distance_m': {'type': 'number', 'format': 'double', 'description': 'Straight-line distance from the observer, in metres.'}, 'visibility': {'$ref': '#/$defs/ViewVisibility', 'description': 'Whether it can be seen, and what that rests on.'}, 'bearing_deg': {'type': 'number', 'format': 'double', 'description': "The place's own bearing from the observer, degrees clockwise from\ntrue north."}, 'angular_offset_deg': {'type': 'number', 'format': 'double', 'description': "Signed angle from the observer's bearing to the place: negative to\nthe left, positive to the right."}}, 'description': "One place in the observer's field of view."}, 'ViewVisibility': {'type': 'object', 'required': ['verdict', 'basis', 'terrain', 'buildings'], 'properties': {'basis': {'type': 'string', 'description': 'What the verdict rests on: `terrain-and-buildings`,\n`terrain-only`, `buildings-only` or `nothing`. `terrain-only` in a\ntown is weak: it means hills were checked and buildings were not.'}, 'terrain': {'type': 'string', 'description': 'What the terrain check concluded: `clear`, `occluded` or\n`no-elevation-data`.'}, 'verdict': {'type': 'string', 'description': '`clear` (nothing in the data stands in the way), `occluded`\n(something does, and it is named), or `unknown` (no check could\nrun, so this result carries NO visibility claim: say so rather\nthan implying either).'}, 'buildings': {'type': 'string', 'description': 'What the building check concluded: `clear`, `occluded`,\n`no-building-data` or `beyond-building-range`.'}, 'obstruction': {'anyOf': [{'$ref': '#/$defs/ViewObstruction'}, {'type': 'null'}], 'description': 'The obstruction, present exactly when the verdict is `occluded`.'}}, 'description': 'Whether a place can be seen from the observer, and what that rests on.'}, 'ViewObstruction': {'type': 'object', 'required': ['kind', 'distance_m', 'height_above_sightline_m'], 'properties': {'kind': {'type': 'string', 'description': '`terrain` or `building`.'}, 'distance_m': {'type': 'number', 'format': 'double', 'description': 'How far along the sight line it stands, in metres.'}, 'building_name': {'type': ['string', 'null'], 'description': "The blocking building's name, when the map carries one."}, 'building_height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Height of the blocking building above its own ground, in metres.\nAbsent for terrain.'}, 'building_height_basis': {'type': ['string', 'null'], 'description': "`tagged` when somebody mapped the building's height, or\n`schema-default` when nobody did and the map's flat 5 m fallback\nwas used. A `schema-default` obstruction is a weaker finding and\nshould be described as one."}, 'height_above_sightline_m': {'type': 'number', 'format': 'double', 'description': 'How far its top rises above the sight line, in metres.'}}, 'description': 'What stands in the way of seeing a place.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['results', 'coverage', 'caveat'], 'properties': {'caveat': {'type': 'string', 'description': 'The standing caveat: visibility here is modelled, not observed.'}, 'results': {'type': 'array', 'items': {'$ref': '#/$defs/PlaceInView'}, 'description': 'Places inside the cone, best first: everything visible before\neverything unchecked before everything occluded, and within each\nof those, nearest and most nearly dead-ahead first.'}, 'coverage': {'type': 'string', 'description': 'One sentence naming which datasets the visibility verdicts were\nactually checked against. Worth repeating when a verdict is being\nrelied on.'}, 'out_of_sector': {'type': 'integer', 'format': 'uint32', 'minimum': 0, 'description': 'How many otherwise-matching places were dropped for lying outside\nthe cone. Non-zero means there ARE matching places near the\nobserver, just not in the direction they are facing, so say that\nrather than "nothing nearby".'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'TruckSpec': {'type': 'object', 'properties': {'hazmat': {'type': 'boolean', 'default': False, 'description': 'Whether the vehicle carries dangerous goods (ADR). Defaults to\nfalse.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres.'}, 'height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle height in metres.'}, 'length_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle length in metres.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels).'}, 'gross_weight_t': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross combination weight in metric tonnes.'}}, 'description': 'Truck profile for routing: physical dimensions plus the ADR\ndangerous-goods declaration. Omitted dimensions default to the EU\nmaximum authorised dimensions of Council Directive 96/53/EC (4.0 m\nheight, 2.55 m width, 16.5 m length, 40 t gross weight).'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}, 'PlanDayStopInput': {'type': 'object', 'properties': {'name': {'type': ['string', 'null'], 'description': 'Free-text name or address, geocoded when no `location` is given.'}, 'location': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Exact coordinates; skips geocoding.'}, 'dwell_minutes': {'type': ['number', 'null'], 'format': 'double', 'description': 'Time spent at the stop in minutes (default 0); shifts every later\nETA.'}}, 'description': 'One stop of a `plan_day` itinerary: an exact location, or a free-text\nname to geocode (ambiguous matches are flagged in the response, never\nguessed silently).'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['start', 'stops'], 'properties': {'start': {'$ref': '#/$defs/PlanDayStopInput', 'description': 'Where the day starts (name or location; `dwell_minutes` ignored).'}, 'stops': {'type': 'array', 'items': {'$ref': '#/$defs/PlanDayStopInput'}, 'description': 'The stops to visit (1â\x80\x9320). Visited in the given order unless\n`optimise` is true.'}, 'truck': {'anyOf': [{'$ref': '#/$defs/TruckSpec'}, {'type': 'null'}], 'description': 'Truck profile (dimensions + ADR declaration). Requires costing\n"truck".'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing model: "auto" (default), "truck", "bicycle", "pedestrian"\nor "motor_scooter".'}, 'optimise': {'type': 'boolean', 'default': False, 'description': 'Reorder the stops for the shortest day (VROOM solver; requires the\noptimisation sidecar). Default false: visit in the given order.'}, 'depart_at': {'type': ['string', 'null'], 'description': 'Departure time as RFC 3339 (e.g. "2026-07-18T09:00:00Z"); when\ngiven, every ETA is also returned as an absolute timestamp.'}, 'return_to_start': {'type': 'boolean', 'default': False, 'description': 'End the day back at the start (default false).'}}}
输出模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'PlanStart': {'type': 'object', 'required': ['location'], 'properties': {'name': {'type': ['string', 'null'], 'description': "The start's name, when one was given."}, 'location': {'$ref': '#/$defs/LatLon', 'description': "The start's resolved coordinates."}, 'resolution': {'anyOf': [{'$ref': '#/$defs/StopResolution'}, {'type': 'null'}], 'description': 'Geocoding details when the start was given as a name.'}}, 'description': "The day's starting point as resolved."}, 'ReturnLeg': {'type': 'object', 'required': ['travel_duration_s', 'travel_distance_m', 'arrival_offset_s'], 'properties': {'arrival_at': {'type': ['string', 'null'], 'description': 'Absolute arrival time (RFC 3339), when `depart_at` was given.'}, 'arrival_offset_s': {'type': 'number', 'format': 'double', 'description': 'Arrival back at the start, seconds after departure.'}, 'travel_distance_m': {'type': 'number', 'format': 'double', 'description': 'Distance back to the start, metres.'}, 'travel_duration_s': {'type': 'number', 'format': 'double', 'description': 'Travel time back to the start, seconds.'}}, 'description': 'The return leg of a `return_to_start` plan.'}, 'GeocodeHit': {'type': 'object', 'required': ['label', 'lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees.'}, 'city': {'type': ['string', 'null'], 'description': 'City or town, when known.'}, 'name': {'type': ['string', 'null'], 'description': 'Place name, when the source feature has one.'}, 'type': {'type': ['string', 'null'], 'description': 'Feature type, e.g. "house", "street", "city" (falls back to the\nOSM value when the endpoint does not classify).'}, 'label': {'type': 'string', 'description': 'Human-readable one-line label assembled from the address parts.'}, 'match': {'anyOf': [{'$ref': '#/$defs/GeocodeMatch'}, {'type': 'null'}], 'description': "How far this hit can be trusted to be the place that was asked\nfor â\x80\x94 see [`GeocodeMatch`]. Present whenever the MapMap gateway\nanswered; absent on a deployment falling back to the direct Photon\ngeocoder, and absent on the gateway's own fast paths (a pasted\ncoordinate pair, a bare UK outward code, a category browse), which\nanswer without a ranking to report on."}, 'country': {'type': ['string', 'null'], 'description': 'Country, when known.'}, 'postcode': {'type': ['string', 'null'], 'description': 'Postcode, when known.'}}, 'description': 'One geocoding result.'}, 'PlannedStop': {'type': 'object', 'required': ['input_index', 'location', 'dwell_minutes', 'travel_duration_s', 'travel_distance_m', 'arrival_offset_s', 'departure_offset_s'], 'properties': {'name': {'type': ['string', 'null'], 'description': "The stop's name (from the request or the geocoder)."}, 'location': {'$ref': '#/$defs/LatLon', 'description': "The stop's resolved coordinates."}, 'arrival_at': {'type': ['string', 'null'], 'description': 'Absolute arrival time (RFC 3339), when `depart_at` was given.'}, 'resolution': {'anyOf': [{'$ref': '#/$defs/StopResolution'}, {'type': 'null'}], 'description': 'Geocoding details when the stop was given as a name.'}, 'input_index': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': "Index of this stop in the request's `stops` array (visit order may\ndiffer when optimised)."}, 'departure_at': {'type': ['string', 'null'], 'description': 'Absolute departure time (RFC 3339), when `depart_at` was given.'}, 'dwell_minutes': {'type': 'number', 'format': 'double', 'description': 'Dwell time applied at this stop, minutes.'}, 'arrival_offset_s': {'type': 'number', 'format': 'double', 'description': 'Arrival, as seconds after departure from the start.'}, 'travel_distance_m': {'type': 'number', 'format': 'double', 'description': 'Distance of the leg arriving at this stop, metres.'}, 'travel_duration_s': {'type': 'number', 'format': 'double', 'description': 'Travel time of the leg arriving at this stop, seconds.'}, 'departure_offset_s': {'type': 'number', 'format': 'double', 'description': "Departure (arrival + dwell), as seconds after the day's start."}}, 'description': 'One planned stop with its leg and ETAs.'}, 'GeocodeMatch': {'type': 'object', 'required': ['components', 'score_gap', 'source'], 'properties': {'source': {'type': 'string', 'description': 'Which backend answered: "mapmap-index" (the first-party index) or\n"photon".'}, 'score_gap': {'type': 'number', 'format': 'double', 'description': 'The top result\'s score minus the runner-up\'s, rounded to 3 decimal\nplaces. `0` for a single result, and `0` from the `photon` source,\nwhich publishes no per-result score â\x80\x94 so a `0` is "no signal", not\n"a tie".'}, 'components': {'$ref': '#/$defs/GeocodeMatchComponents', 'description': 'Per-component verdict on this hit: one entry for each structured\ncomponent supplied, and empty when the query was free text only.'}}, 'description': 'How well one geocoding result answers what was actually asked.\n\nGeocoding\'s real failure mode is not "no answer" but a confident answer\nto a different question: a plausible row on the wrong street, with\nnothing in the response to say so. This object is that missing say-so,\nand an agent should read it before acting on an address.\n\nHow to read it:\n\n* Any component `unmatched` or `inferred` on the TOP hit means the\n answer does not carry the address that was asked for â\x80\x94 an `unmatched`\n postcode means the result has no postcode at all, `inferred` means it\n has a different one. Neither is a match. Say so rather than presenting\n the hit as the address, and reach for `verify_places` when the address\n came from a model or a user and needs checking rather than using.\n* A small `score_gap` means the ranking barely chose between this hit\n and the runner-up, which is exactly when to show the alternatives\n instead of picking one for the user.'}, 'StopResolution': {'type': 'object', 'required': ['query', 'chosen', 'ambiguous', 'alternatives'], 'properties': {'query': {'type': 'string', 'description': 'The name that was geocoded.'}, 'chosen': {'$ref': '#/$defs/GeocodeHit', 'description': 'The chosen match (best geocoder hit).'}, 'ambiguous': {'type': 'boolean', 'description': 'True when other plausible matches exist somewhere else â\x80\x94 check\n`alternatives` and re-run with an explicit `location` if the\nchosen one is wrong.'}, 'alternatives': {'type': 'array', 'items': {'$ref': '#/$defs/GeocodeHit'}, 'description': 'Up to three alternative matches, best first.'}}, 'description': 'How a free-text stop name was resolved to coordinates.'}, 'GeocodeMatchComponents': {'type': 'object', 'properties': {'city': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `city`.'}, 'street': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `street`.'}, 'country': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `country`.'}, 'postcode': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `postcode`.'}, 'housenumber': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `housenumber`.'}}, 'description': 'Per-component verdicts inside a [`GeocodeMatch`]. Each is one of\n"matched", "inferred" or "unmatched"; a component that was not supplied\nis absent entirely.\n\n* "matched" â\x80\x94 the result\'s own field carries the value asked for (case-\n and accent-insensitive, and by containment, so `city: "London"`\n matches "City of London").\n* "inferred" â\x80\x94 the result carries a value for that component, but not\n the one asked for. It reached the page through ranking, as when a\n street is found by its transliterated name and displayed under its\n canonical one.\n* "unmatched" â\x80\x94 the result carries no value for that component at all.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['costing', 'optimised', 'start', 'stops', 'total_travel_duration_s', 'total_dwell_s', 'total_distance_m', 'finish_offset_s', 'geometry_polyline6', 'summary'], 'properties': {'start': {'$ref': '#/$defs/PlanStart', 'description': "The day's starting point."}, 'stops': {'type': 'array', 'items': {'$ref': '#/$defs/PlannedStop'}, 'description': 'The stops in visit order, each with leg, ETAs and any geocoding\nresolution to double-check.'}, 'costing': {'type': 'string', 'description': 'The costing the plan was routed with.'}, 'summary': {'type': 'string', 'description': 'One-line human-readable summary of the day.'}, 'depart_at': {'type': ['string', 'null'], 'description': 'The departure time echoed back, when one was given.'}, 'finish_at': {'type': ['string', 'null'], 'description': 'Absolute end of the day (RFC 3339), when `depart_at` was given.'}, 'optimised': {'type': 'boolean', 'description': 'Whether the stop order was optimised (VROOM) or kept as given.'}, 'return_leg': {'anyOf': [{'$ref': '#/$defs/ReturnLeg'}, {'type': 'null'}], 'description': 'The leg back to the start, when `return_to_start` was set.'}, 'total_dwell_s': {'type': 'number', 'format': 'double', 'description': 'Total time at stops, seconds.'}, 'finish_offset_s': {'type': 'number', 'format': 'double', 'description': 'End of the day (last arrival + dwell), seconds after departure.'}, 'total_distance_m': {'type': 'number', 'format': 'double', 'description': 'Total travel distance, metres.'}, 'geometry_polyline6': {'type': 'string', 'description': 'Full multi-stop route geometry (polyline6) â\x80\x94 hand it to the map SDK\nor the `route` tool consumers directly.'}, 'total_travel_duration_s': {'type': 'number', 'format': 'double', 'description': 'Total driving/travel time, seconds.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'ErrandSpec': {'type': 'object', 'properties': {'id': {'type': ['string', 'null'], 'description': 'What to call this errand in the answer ("prescription", "petrol").\nDefaults to the category, or to "stop N".'}, 'place': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'A specific place the driver already knows, as a coordinate. Use\nthis for "the school", "the nursery", "Mum\'s": places the map\ncannot be expected to resolve from the words alone. Resolve a NAMED\nplace with `geocode` first and pass the coordinate here; never\nguess one.'}, 'category': {'type': ['string', 'null'], 'description': 'The KIND of place wanted: a category from `list_place_categories`\n("pharmacy", "fuel", "supermarket"), or a colloquial phrase the\nserver normalises ("petrol station", "chemist"). Use this for\nanything the driver described by what it is rather than by name.'}, 'dwell_minutes': {'type': ['number', 'null'], 'format': 'double', 'description': 'How long the driver is out of the car here, minutes (default 5).'}}, 'description': 'One errand in a `plan_errands` chain: a kind of place to find, or a\nplace the caller already knows.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['origin', 'destination', 'arrive_by', 'errands'], 'properties': {'origin': {'$ref': '#/$defs/LatLon', 'description': 'Where the driver sets off from.'}, 'errands': {'type': 'array', 'items': {'$ref': '#/$defs/ErrandSpec'}, 'description': 'The errands, in any order: the answer decides the order. One to\nfive.'}, 'arrive_by': {'type': 'string', 'description': 'The hard arrival time, RFC 3339 with an offset\n("2026-09-21T15:15:00+01:00"). Convert "quarter past three" to an\nabsolute instant in the driver\'s own offset before calling.'}, 'depart_at': {'type': ['string', 'null'], 'description': 'When they set off, RFC 3339. Defaults to now.'}, 'destination': {'$ref': '#/$defs/LatLon', 'description': 'Where they have to be by `arrive_by`.'}, 'destination_name': {'type': ['string', 'null'], 'description': 'What to call the destination in the answer ("the school").'}, 'max_detour_minutes': {'type': ['number', 'null'], 'format': 'double', 'description': 'How far off the direct route a candidate place may sit, as a detour\nin minutes (default 12, at most 45).'}}}
输出模式
{'type': 'object', '$defs': {'ErrandStop': {'type': 'object', 'required': ['errand', 'kind', 'lat', 'lon', 'arrive', 'depart', 'drive_s', 'hours'], 'properties': {'id': {'type': ['string', 'null'], 'description': 'The index id, for an indexed place. Its presence is what makes the\nstop checkable; a stop without one is a coordinate the caller gave.'}, 'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude.'}, 'kind': {'type': 'string', 'description': '"category" for a place the index found, "place" for one the caller\nsupplied.'}, 'name': {'type': ['string', 'null'], 'description': "The place's name."}, 'hours': {'type': 'string', 'description': 'What the map\'s opening-hours tag says about the arrival time:\n"open_on_the_tag" (the tag covers it, which is evidence and NOT a\npromise) or "unknown" (no usable tag). A stop the tag proves shut\nis never proposed, so "closed" never appears here.'}, 'label': {'type': ['string', 'null'], 'description': 'Its full label, for reading aloud.'}, 'arrive': {'type': 'string', 'description': 'When the driver arrives, RFC 3339.'}, 'depart': {'type': 'string', 'description': 'When they leave, RFC 3339.'}, 'errand': {'type': 'string', 'description': 'Which errand this stop discharges.'}, 'drive_s': {'type': 'number', 'format': 'double', 'description': 'Driving time of the leg into this stop, seconds.'}, 'hours_tag': {'type': ['string', 'null'], 'description': 'The tag itself, when the map carries one.'}}, 'description': 'One planned stop in an errand chain.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['feasible', 'departure', 'arrive_by', 'stops', 'dropped', 'corridor_note', 'opening_hours_note', 'usage_note', 'verification_note'], 'properties': {'stops': {'type': 'array', 'items': {'$ref': '#/$defs/ErrandStop'}, 'description': 'The stops, in visit order. On an infeasible answer these are the\nstops of the reduced plan, the one that DOES fit.'}, 'reason': {'type': ['string', 'null'], 'description': 'The same cause in plain language, for the driver.'}, 'arrival': {'type': ['string', 'null'], 'description': 'When the plan arrives, RFC 3339. Present whenever there is a plan,\nincluding the reduced plan on an infeasible answer.'}, 'dropped': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Errands that had to be dropped for the plan to fit. Empty when\nfeasible.'}, 'slack_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'Spare seconds before the deadline.'}, 'feasible': {'type': 'boolean', 'description': '**Whether every errand fits before the deadline.** False is an\nANSWER, not an error: report `reason`, the errand named in\n`blocking_errand`, and what `dropped` says has to go.'}, 'arrive_by': {'type': 'string', 'description': 'The deadline, echoed.'}, 'departure': {'type': 'string', 'description': 'When the driver sets off, RFC 3339.'}, 'over_by_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'How late the whole chain would be, seconds.'}, 'usage_note': {'type': 'string', 'description': '**Always present.** Why this is planned stationary rather than at\nthe wheel. Show it.'}, 'attribution': {'type': ['string', 'null'], 'description': 'Credit owed for the place data, when the answer used the index.'}, 'reason_code': {'type': ['string', 'null'], 'description': 'Machine token for why the chain does not fit: "deadline_missed",\n"destination_unreachable_in_time", "no_candidates_in_corridor",\n"all_candidates_closed" or "unroutable".'}, 'corridor_note': {'type': 'string', 'description': '**Always present.** What the corridor search did and did not look\nat. An empty answer is a statement about this index and this\ncorridor, never about what exists on the ground.'}, 'failed_errand': {'type': ['string', 'null'], 'description': 'The errand a "no_candidates_in_corridor" or "all_candidates_closed"\nanswer is about.'}, 'total_drive_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'Total driving time, seconds.'}, 'total_dwell_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'Total time out of the car, seconds.'}, 'blocking_errand': {'type': ['string', 'null'], 'description': 'The errand that costs the most time, when the deadline is missed.'}, 'verification_note': {'type': 'string', 'description': '**Always present.** That every stop is an indexed place or a\nsupplied coordinate, never a generated one.'}, 'geometry_polyline6': {'type': ['string', 'null'], 'description': 'The planned journey as an encoded polyline6.'}, 'opening_hours_note': {'type': 'string', 'description': '**Always present.** How opening hours were used, and how little of\nthe map carries them.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'EvVehicleSpec': {'type': 'object', 'properties': {'name': {'type': ['string', 'null'], 'description': 'Display name for the vehicle in the answer.'}, 'aux_kw': {'type': ['number', 'null'], 'format': 'double', 'description': 'Auxiliary load in kW â\x80\x94 lights, electronics, cabin conditioning.\nWinter heating is several times the mild-weather default.'}, 'mass_kg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Kerb mass, kg.'}, 'profile': {'type': ['string', 'null'], 'description': 'A published default profile: "small_hatch", "saloon", "suv" or\n"van". On its own it selects that vehicle; alongside any inline\nfigure below it is the base the figure overrides.'}, 'connectors': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': 'Connectors the vehicle accepts: "type1", "type2", "ccs1", "ccs2",\n"chademo", "tesla", "gbt".'}, 'battery_kwh': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross nominal battery capacity, kWh.'}, 'drag_area_m2': {'type': ['number', 'null'], 'format': 'double', 'description': 'Drag area (drag coefficient Ã\x97 frontal area), m².'}, 'usable_fraction': {'type': ['number', 'null'], 'format': 'double', 'description': 'Fraction of the gross pack the vehicle will actually use, 0â\x80\x931.'}}, 'description': 'The vehicle for `plan_ev_route`: one of the published defaults by name,\ninline figures, or a named default with inline figures over it.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['origin', 'destination'], 'properties': {'min_kw': {'type': ['number', 'null'], 'format': 'double', 'description': 'Keep only charge points with a usable connector rated at least this\nmany kW (e.g. 50 for rapid charging only).'}, 'origin': {'$ref': '#/$defs/LatLon', 'description': 'Where the journey starts.'}, 'vehicle': {'anyOf': [{'$ref': '#/$defs/EvVehicleSpec'}, {'type': 'null'}], 'description': 'The vehicle. Omitted â\x87\x92 the published "saloon" default, and the\nanswer says which vehicle it used.'}, 'start_soc': {'type': ['number', 'null'], 'format': 'double', 'description': 'State of charge at the start, 0â\x80\x931 (default 0.9).'}, 'waypoints': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/LatLon'}, 'description': 'Intermediate points the route must pass through, in order (at most\n8). Charge stops are inserted around them.'}, 'connectors': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': 'Keep only charge points offering at least one of these connector\nstandards: "type2", "type1", "ccs", "chademo", "tesla", "domestic",\n"other". This narrows the vehicle\'s own set, never widens it.'}, 'destination': {'$ref': '#/$defs/LatLon', 'description': 'Where it ends.'}, 'reserve_soc': {'type': ['number', 'null'], 'format': 'double', 'description': 'The floor the state of charge must never fall below mid-route\n(default 0.1). Distinct from the arrival figure.'}, 'min_arrival_soc': {'type': ['number', 'null'], 'format': 'double', 'description': 'Lowest acceptable state of charge on arrival (default 0.1).'}, 'max_detour_minutes': {'type': ['number', 'null'], 'format': 'double', 'description': 'How far off the route a charge point may sit, as a detour in\nminutes (default 15, at most 120).'}, 'ambient_temperature_c': {'type': ['number', 'null'], 'format': 'double', 'description': "Ambient temperature in °C. Derates traction energy from a published\nstudy; cabin heating belongs in the vehicle's `aux_kw`."}}}
输出模式
{'type': 'object', '$defs': {'EvPlanLeg': {'type': 'object', 'required': ['from', 'to', 'duration_s', 'distance_m', 'start_soc', 'end_soc', 'consumed_wh', 'regen_wh'], 'properties': {'to': {'type': 'string', 'description': 'Where it ends: a charge point\'s id or "destination".'}, 'from': {'type': 'string', 'description': 'Where the leg starts: "origin" or a charge point\'s id.'}, 'end_soc': {'type': 'number', 'format': 'double', 'description': 'State of charge at the end.'}, 'min_soc': {'type': ['number', 'null'], 'format': 'double', 'description': 'Lowest state of charge anywhere within the leg.'}, 'regen_wh': {'type': 'number', 'format': 'double', 'description': 'Battery energy regenerative braking gives back, Wh.'}, 'start_soc': {'type': 'number', 'format': 'double', 'description': 'State of charge at the start of the leg.'}, 'distance_m': {'type': 'number', 'format': 'double', 'description': 'Engine-computed distance, metres.'}, 'duration_s': {'type': 'number', 'format': 'double', 'description': 'Engine-computed driving time, seconds.'}, 'consumed_wh': {'type': 'number', 'format': 'double', 'description': 'Battery energy the leg spends, Wh.'}}, 'description': 'One driving leg of the plan, with its state-of-charge bookkeeping.'}, 'EvPlanStop': {'type': 'object', 'required': ['charger_id', 'source', 'lat', 'lon', 'dc', 'arrive_soc', 'depart_soc', 'charge_s', 'along_route_position', 'off_route_m', 'status_live'], 'properties': {'dc': {'type': 'boolean', 'description': 'Whether the connector delivers DC (rapid) rather than AC.'}, 'lat': {'type': 'number', 'format': 'double', 'description': 'WGS84 latitude in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'WGS84 longitude in decimal degrees.'}, 'name': {'type': ['string', 'null'], 'description': 'Site name, where the operator publishes one.'}, 'source': {'type': 'string', 'description': 'Which operator feed this came from.'}, 'charge_s': {'type': 'number', 'format': 'double', 'description': "Time plugged in, seconds â\x80\x94 integrated over the vehicle's charging\ncurve capped by the charge point, not energy ÷ peak power."}, 'detour_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'Extra driving time this stop costs against going straight past it,\nseconds.'}, 'operator': {'type': ['string', 'null'], 'description': 'Operator display name.'}, 'arrive_soc': {'type': 'number', 'format': 'double', 'description': 'State of charge on arrival. Never below the reserve floor.'}, 'charger_id': {'type': 'string', 'description': 'Operator-scoped stable id.'}, 'charger_kw': {'type': ['number', 'null'], 'format': 'double', 'description': "That connector's rated power, kW â\x80\x94 what the charge time was\ncomputed against."}, 'depart_soc': {'type': 'number', 'format': 'double', 'description': 'State of charge on departure.'}, 'off_route_m': {'type': 'number', 'format': 'double', 'description': 'Straight-line offset from the route geometry, metres.'}, 'status_live': {'type': 'boolean', 'description': 'Whether the status came from a live feed rather than the last\ningest.'}, 'available_now': {'type': ['boolean', 'null'], 'description': 'Whether a bay is free right now. Present only where a live\navailability feed backs the claim â\x80\x94 absent means unknown, never\n"occupied".'}, 'power_kw_source': {'type': ['string', 'null'], 'description': '"declared" when the operator published the rating, "derived" when it\nwas computed from voltage Ã\x97 amperage Ã\x97 phases. Never present the two\nas the same thing to a user.'}, 'connector_standard': {'type': ['string', 'null'], 'description': 'The connector the plan charges on.'}, 'along_route_position': {'type': 'number', 'format': 'double', 'description': 'How far along the route this stop sits, 0.0â\x80\x931.0.'}}, 'description': 'One charge stop in the plan.'}, 'EvPlanSummary': {'type': 'object', 'required': ['stops', 'total_drive_s', 'total_charge_s', 'total_duration_s', 'total_distance_m', 'start_soc', 'energy_kwh'], 'properties': {'stops': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'How many charge stops the plan contains. Zero on a journey the car\nmakes on its own â\x80\x94 and zero on an infeasible one.'}, 'start_soc': {'type': 'number', 'format': 'double', 'description': 'State of charge the journey starts at.'}, 'energy_kwh': {'type': 'number', 'format': 'double', 'description': 'Net battery energy the journey costs, kWh.'}, 'arrival_soc': {'type': ['number', 'null'], 'format': 'double', 'description': 'State of charge on arrival, when the journey is feasible.'}, 'total_drive_s': {'type': 'number', 'format': 'double', 'description': 'Time spent driving, seconds.'}, 'total_charge_s': {'type': 'number', 'format': 'double', 'description': 'Time spent plugged in, seconds.'}, 'total_distance_m': {'type': 'number', 'format': 'double', 'description': 'Distance of the planned journey, metres.'}, 'total_duration_s': {'type': 'number', 'format': 'double', 'description': 'Driving plus charging, seconds â\x80\x94 the number a user cares about.'}}, 'description': 'The plan at a glance.'}, 'EvPlanSocPoint': {'type': 'object', 'required': ['at', 'soc', 'along_route_position'], 'properties': {'at': {'type': 'string', 'description': '"origin", a charge point\'s id, or "destination".'}, 'soc': {'type': 'number', 'format': 'double', 'description': 'State of charge on arrival at this point.'}, 'departing_soc': {'type': ['number', 'null'], 'format': 'double', 'description': 'State of charge on leaving, at a charge stop.'}, 'along_route_position': {'type': 'number', 'format': 'double', 'description': 'How far along the route this point sits, 0.0â\x80\x931.0.'}}, 'description': 'One point on the state-of-charge trace.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['feasible', 'summary', 'stops', 'legs', 'soc_trace', 'gradient_data', 'coverage_note', 'availability_live'], 'properties': {'legs': {'type': 'array', 'items': {'$ref': '#/$defs/EvPlanLeg'}, 'description': 'The driving legs, in order.'}, 'stops': {'type': 'array', 'items': {'$ref': '#/$defs/EvPlanStop'}, 'description': 'The charge stops, in visit order. Always empty when `feasible` is\nfalse: a journey that cannot be completed has no stop list.'}, 'reason': {'type': ['string', 'null'], 'description': 'The same cause in plain language, for the user.'}, 'summary': {'$ref': '#/$defs/EvPlanSummary', 'description': 'The plan at a glance.'}, 'vehicle': {'type': ['string', 'null'], 'description': 'The vehicle the plan was computed for.'}, 'feasible': {'type': 'boolean', 'description': "**Whether the journey is possible at all.** False means no plan\nexists â\x80\x94 a charger desert, a connector mismatch, or a gap wider than\nthe car's range. Report the `reason` and the furthest reachable\npoint; never describe an infeasible answer as a plan."}, 'soc_trace': {'type': 'array', 'items': {'$ref': '#/$defs/EvPlanSocPoint'}, 'description': 'State of charge at every point of the journey.'}, 'reason_code': {'type': ['string', 'null'], 'description': 'Machine token for why no plan exists, when none does:\n"no_chargers_in_corridor", "connector_mismatch", "out_of_range",\n"dead_end", "below_min_kw", "chargers_unrated", "stop_limit",\n"dataset_empty", "no_charge_curve" or "unroutable".'}, 'coverage_note': {'type': 'string', 'description': '**Always present.** What this deployment\'s charge-point dataset does\nand does not cover. An infeasible plan means "none from these\noperators", never "there are no chargers here". Show this alongside\nthe answer.'}, 'gradient_data': {'type': 'string', 'description': '"complete", "partial" or "absent". **"absent" means the deployment\nhad no elevation data and consumption was modelled on the flat**,\nwhich under-reads a hilly route. Say so rather than presenting the\nfigure as measured.'}, 'profile_source': {'type': ['string', 'null'], 'description': '"default" when a published profile supplied the figures, "inline"\nwhen the caller did.'}, 'route_distance_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Distance of the planned route, metres.'}, 'route_duration_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'Driving time of the planned route, seconds.'}, 'availability_live': {'type': 'boolean', 'description': 'Whether charge-point statuses came from a live availability feed. A\nstatic planner is the default: without a feed, nothing in this\nanswer is a claim about which bays are free right now.'}, 'geometry_polyline6': {'type': ['string', 'null'], 'description': "The planned journey's geometry as an encoded polyline6, through the\ncharge stops."}, 'charging_attribution': {'type': ['string', 'null'], 'description': 'Attribution string for the charge-point operators actually used â\x80\x94\ndisplay it with the plan (a licence obligation).'}, 'furthest_reachable_lat': {'type': ['number', 'null'], 'format': 'double', 'description': 'Latitude of that furthest reachable point.'}, 'furthest_reachable_lon': {'type': ['number', 'null'], 'format': 'double', 'description': 'Longitude of that furthest reachable point.'}, 'furthest_reachable_position': {'type': ['number', 'null'], 'format': 'double', 'description': 'How far along the route the vehicle can get unaided, 0.0â\x80\x931.0, when\nno plan exists.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['origin', 'contours_minutes'], 'properties': {'origin': {'$ref': '#/$defs/LatLon', 'description': 'Origin the reachable area is computed from.'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Travel mode: "auto" (default), "truck", "bicycle", "pedestrian"\nor "motor_scooter".'}, 'polygons': {'type': ['boolean', 'null'], 'description': 'Return filled polygons instead of contour linestrings (default\nfalse). Polygons draw directly as a MapLibre fill layer.'}, 'contours_minutes': {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'description': 'Contour boundaries in minutes of travel time, e.g. [5, 10, 15]\nfor 5/10/15-minute rings. 1â\x80\x9310 values, each between 0 and 120\nminutes.'}, 'exclude_polygons': {'type': ['array', 'null'], 'items': {'type': 'array', 'items': {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2}}, 'description': 'Areas to avoid â\x80\x94 scenario analysis ("close this bridge and\nrecompute reachability"): an array of polygons, each an array of\n`[lon, lat]` pairs forming one exterior ring (GeoJSON-style,\nlongitude FIRST). Roads intersecting any ring are excluded from\nthe reachability search. Applies to the Valhalla engine;\nunsupported on the GraphHopper engine, where it is ignored.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['geojson'], 'properties': {'geojson': {'description': "GeoJSON FeatureCollection of the reachability contours, one\nfeature per requested minute value (each feature's `contour`\nproperty is its minutes), as returned by the routing engine."}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'RelaxSpec': {'type': 'object', 'properties': {'allow_overtime_s': {'type': ['integer', 'null'], 'format': 'int64', 'description': "Extend every vehicle's shift END by this many seconds. Shift starts\nare never moved earlier â\x80\x94 a driver cannot begin before they begin."}, 'time_windows_by_s': {'type': ['integer', 'null'], 'format': 'int64', 'description': 'Widen every task time window by this many seconds at EACH end. A\n09:00â\x80\x9312:00 window with 1800 becomes 08:30â\x80\x9312:30.'}}, 'description': 'What the caller is willing to give up if the first solve leaves work\nunassigned. At least one field is required.'}, 'TruckSpec': {'type': 'object', 'properties': {'hazmat': {'type': 'boolean', 'default': False, 'description': 'Whether the vehicle carries dangerous goods (ADR). Defaults to\nfalse.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres.'}, 'height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle height in metres.'}, 'length_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle length in metres.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels).'}, 'gross_weight_t': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross combination weight in metric tonnes.'}}, 'description': 'Truck profile for routing: physical dimensions plus the ADR\ndangerous-goods declaration. Omitted dimensions default to the EU\nmaximum authorised dimensions of Council Directive 96/53/EC (4.0 m\nheight, 2.55 m width, 16.5 m length, 40 t gross weight).'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}, 'ReloadsSpec': {'type': 'object', 'required': ['max_trips'], 'properties': {'depot': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Where the vehicle reloads. Omitted, its own `start` is used (or its\n`end` if it declared only that).'}, 'max_trips': {'type': 'integer', 'format': 'uint32', 'minimum': 0, 'description': 'How many trips this vehicle may run in its shift, 2â\x80\x935. A BUDGET,\nnot a prediction: the shift is cut into that many fixed windows\nbefore the solve, so asking for five trips on a shift that supports\nthree shrinks every window to a fifth and can make the whole day\nworse. Ask for the number of trips you actually expect to run.'}, 'reload_time_s': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Seconds at the depot between trips â\x80\x94 tipping, reloading, the\nweighbridge. Held out of the shift before it is partitioned, so it\nis never accidentally spent driving.'}}, 'description': "A vehicle's multi-trip reload plan."}, 'EmissionsFuel': {'oneOf': [{'type': 'string', 'const': 'petrol', 'description': "Petrol, including petrol hybrids (schemes rate a hybrid by its\ncombustion engine's approval)."}, {'type': 'string', 'const': 'diesel', 'description': 'Diesel, including diesel hybrids.'}, {'type': 'string', 'const': 'electric', 'description': 'Battery-electric.'}, {'type': 'string', 'const': 'hydrogen', 'description': 'Hydrogen fuel cell.'}, {'type': 'string', 'const': 'gas', 'description': 'LPG or CNG; rated as petrol by every scheme in the dataset.'}], 'description': 'What a vehicle burns, in clean-air-zone scheme terms.'}, 'EmissionsSpec': {'type': 'object', 'required': ['vehicle_category', 'fuel'], 'properties': {'fuel': {'$ref': '#/$defs/EmissionsFuel', 'description': 'What it burns.'}, 'euro_standard': {'type': ['integer', 'null'], 'format': 'uint8', 'maximum': 255, 'minimum': 0, 'description': 'Its Euro emission standard, 1â\x80\x936. Heavy-duty approvals are written\nin Roman numerals (Euro VI); declare Euro VI as `6`. Required for\nany combustion fuel â\x80\x94 without it no zone can be resolved, and a\nhalf-declared vehicle is indistinguishable from an undeclared one.\nOptional only for `electric` or `hydrogen`.'}, 'vehicle_category': {'$ref': '#/$defs/EmissionsVehicleCategory', 'description': 'What kind of vehicle this is, in scheme terms.'}}, 'description': "A vehicle's emission declaration, for clean-air / low-emission zone\nassessment."}, 'TerritorySpec': {'type': 'object', 'required': ['id', 'polygon'], 'properties': {'id': {'type': 'string', 'description': 'Caller-chosen id, echoed back and referenced by\n`vehicles[].territory_ids`. Must be unique within the request.'}, 'polygon': {'type': 'array', 'items': {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2}, 'description': 'The outer ring as GeoJSON `[lon, lat]` positions â\x80\x94 longitude\nFIRST. Closed or open; an unclosed ring is closed for you.'}}, 'description': 'One named territory: a polygon that bounds which vehicle may serve\nwhich stop.'}, 'OptimiseJobSpec': {'type': 'object', 'required': ['id', 'location'], 'properties': {'id': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'Caller-chosen job id, echoed back in steps and `unassigned`.'}, 'pickup': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Quantities picked up at the job (matches vehicle `capacity`).'}, 'skills': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'uint32', 'minimum': 0}, 'description': 'Skills the job requires.'}, 'delivery': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Quantities delivered to the job (matches vehicle `capacity`).'}, 'location': {'$ref': '#/$defs/LatLon', 'description': 'Job location.'}, 'service_s': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'On-site service time in seconds.'}, 'time_windows': {'type': ['array', 'null'], 'items': {'type': 'array', 'items': {'type': 'integer', 'format': 'int64'}}, 'description': 'Acceptable `[start, end]` windows in seconds.'}}, 'description': 'One single-stop job of an optimisation problem.'}, 'ReplanChangesSpec': {'type': 'object', 'properties': {'add_jobs': {'type': 'array', 'items': {'$ref': '#/$defs/OptimiseJobSpec'}, 'description': 'New single-stop jobs, in exactly the `optimise_routes` job shape.'}, 'add_shipments': {'type': 'array', 'items': {'$ref': '#/$defs/OptimiseShipmentSpec'}, 'description': 'New pickup+delivery pairs, in exactly the `optimise_routes`\nshipment shape.'}, 'cancel_job_ids': {'type': 'array', 'items': {'type': 'integer', 'format': 'uint64', 'minimum': 0}, 'description': 'Ids of jobs that no longer need doing. A job already reported\ncompleted cannot be cancelled; the response says so rather than\nsilently dropping it.'}}, 'description': 'What has changed about the work since the plan was made.'}, 'ReplanProgressSpec': {'type': 'object', 'required': ['vehicle'], 'properties': {'vehicle': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'The vehicle this progress belongs to â\x80\x94 an `id` from `vehicles`.'}, 'unavailable': {'type': ['boolean', 'null'], 'description': 'The vehicle has dropped out of the shift â\x80\x94 breakdown, illness, end\nof hours. It leaves the fleet for the re-plan; what it already\ncompleted stays completed.'}, 'current_position': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Where the vehicle is now; becomes its start for the re-plan.\nOmitted, its last completed stop is used; with neither, its\noriginal start.'}, 'completed_stop_ids': {'type': 'array', 'items': {'type': 'integer', 'format': 'uint64', 'minimum': 0}, 'description': 'Ids of the stops this vehicle has already served, IN THE ORDER IT\nSERVED THEM. Each is a job id or a shipment pickup/delivery id.\nThis is the locked prefix: it already happened, so no re-plan may\nmove it.'}}, 'description': "One vehicle's progress through its shift."}, 'OptimiseVehicleSpec': {'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'Caller-chosen vehicle id, echoed back on its route.'}, 'end': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'End location; omitted, the route ends at its last stop.'}, 'start': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Start location; at least one of `start`/`end` is required.'}, 'skills': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'uint32', 'minimum': 0}, 'description': 'Skills this vehicle provides.'}, 'reloads': {'anyOf': [{'$ref': '#/$defs/ReloadsSpec'}, {'type': 'null'}], 'description': 'Let this vehicle return to a depot, reload and go out again â\x80\x94 the\nwaste-collection tipping round, the van that comes back for a\nsecond wave of parcels.'}, 'capacity': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Multidimensional capacity (same length as job `delivery`/`pickup`).'}, 'time_window': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Working window as `[start, end]` in seconds (any consistent epoch).'}, 'territory_ids': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': "Ids of the request's `territories` this vehicle may work in.\nOmitted or empty, the vehicle is UNRESTRICTED and may serve any\ntask, inside a territory or outside every one of them. Listed, the\nvehicle may serve a task only if that task sits inside at least one\nof the named territories."}}, 'description': 'One vehicle of an optimisation fleet.'}, 'OptimiseShipmentSpec': {'type': 'object', 'required': ['pickup', 'delivery'], 'properties': {'amount': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Quantities moved (matches vehicle `capacity`).'}, 'pickup': {'$ref': '#/$defs/OptimiseShipmentStopSpec', 'description': 'The pickup end.'}, 'skills': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'uint32', 'minimum': 0}, 'description': 'Skills the shipment requires.'}, 'delivery': {'$ref': '#/$defs/OptimiseShipmentStopSpec', 'description': 'The delivery end.'}}, 'description': 'A pickup+delivery pair that must ride the same vehicle, pickup first.'}, 'EmissionsVehicleCategory': {'oneOf': [{'type': 'string', 'const': 'car', 'description': 'A private car.'}, {'type': 'string', 'const': 'van', 'description': 'A van or light goods vehicle up to 3.5 tonnes.'}, {'type': 'string', 'const': 'minibus', 'description': 'A minibus (typically 8+ passenger seats, up to 5 tonnes).'}, {'type': 'string', 'const': 'hgv', 'description': 'A heavy goods vehicle over 3.5 tonnes.'}, {'type': 'string', 'const': 'bus', 'description': 'A bus over 5 tonnes.'}, {'type': 'string', 'const': 'coach', 'description': 'A coach over 5 tonnes.'}, {'type': 'string', 'const': 'taxi', 'description': 'A licensed hackney carriage.'}, {'type': 'string', 'const': 'phv', 'description': 'A private hire vehicle.'}, {'type': 'string', 'const': 'motorcycle', 'description': 'A motorcycle, moped or tricycle.'}, {'type': 'string', 'const': 'motorhome', 'description': 'A motor caravan or campervan.'}], 'description': 'What a vehicle is, in clean-air-zone scheme terms.\n\nDeclaring this turns "charge depends on vehicle emissions" into an\nanswer. Without it a zone can only be named, never priced.'}, 'OptimiseShipmentStopSpec': {'type': 'object', 'required': ['id', 'location'], 'properties': {'id': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'Caller-chosen stop id, echoed back in steps and `unassigned`.'}, 'location': {'$ref': '#/$defs/LatLon', 'description': 'Stop location.'}, 'service_s': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'On-site service time in seconds.'}}, 'description': 'One end (pickup or delivery) of a shipment.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['vehicles'], 'properties': {'jobs': {'type': 'array', 'items': {'$ref': '#/$defs/OptimiseJobSpec'}, 'description': 'Single-stop jobs (at least one job or shipment overall).'}, 'truck': {'anyOf': [{'$ref': '#/$defs/TruckSpec'}, {'type': 'null'}], 'description': 'Truck profile (dimensions + ADR declaration). Requires costing\n"truck"; the travel-time matrix then respects dimensional and\ndangerous-goods restrictions, so the whole plan is truck-legal.'}, 'changes': {'anyOf': [{'$ref': '#/$defs/ReplanChangesSpec'}, {'type': 'null'}], 'description': 'Changes to the work itself. Optional, on the same condition.'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing model for the travel-time matrix: "auto" (default),\n"truck", "bicycle", "pedestrian" or "motor_scooter".'}, 'progress': {'type': 'array', 'items': {'$ref': '#/$defs/ReplanProgressSpec'}, 'description': 'Per-vehicle progress. Optional, but at least one progress entry or\none change is required â\x80\x94 a re-plan that reports nothing new is the\noriginal problem.'}, 'vehicles': {'type': 'array', 'items': {'$ref': '#/$defs/OptimiseVehicleSpec'}, 'description': 'The fleet (at least one vehicle, each with a start and/or end).'}, 'emissions': {'anyOf': [{'$ref': '#/$defs/EmissionsSpec'}, {'type': 'null'}], 'description': "The fleet's emission declaration, for UK clean-air / low-emission\nzone assessment. On its own it annotates: the response's `zones`\nblock names every zone containing one of the problem's own\nlocations and what this vehicle would pay there. With\n`avoid_zones` it also steers the internal travel-time matrix away\nfrom those zones, so the plan itself changes."}, 'shipments': {'type': 'array', 'items': {'$ref': '#/$defs/OptimiseShipmentSpec'}, 'description': 'Pickup+delivery pairs.'}, 'avoid_zones': {'type': ['boolean', 'null'], 'description': "Keep the optimisation's travel-time matrix out of every zone the\ndeclared vehicle would be charged or banned in. Requires\n`emissions`."}, 'territories': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/TerritorySpec'}, 'description': 'Fleet territories: named polygons that bound which vehicle may\nserve which stop, referenced by `vehicles[].territory_ids`. These\nare request data â\x80\x94 caller-drawn rounds, validated per call and\nnever stored. Nothing to do with clean-air zones or with the\noffline map packages of the same word.'}, 'relax_if_unassigned': {'anyOf': [{'$ref': '#/$defs/RelaxSpec'}, {'type': 'null'}], 'description': 'Re-solve ONCE with these relaxations if the first solve leaves work\nunassigned, and say honestly which plan came back. At most one\nsecond solve, never beyond the caps you state, and the relaxed plan\nis returned only if it assigns MORE work than the first â\x80\x94 giving\naway constraints for nothing is strictly worse than not giving them\naway. Breaks are never widened, nor are capacities, skills,\nterritories or task caps: only time windows move, and only by the\nstated amounts. Bills as two solves when the second one runs.'}}}
输出模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'OptimisedStep': {'type': 'object', 'required': ['type', 'arrival_s', 'duration_s', 'service_s', 'waiting_time_s'], 'properties': {'id': {'type': ['integer', 'null'], 'format': 'uint64', 'minimum': 0, 'description': 'The job/shipment-stop id, absent on start/end steps.'}, 'load': {'type': ['array', 'null'], 'items': {'type': 'integer', 'format': 'int64'}, 'description': 'Vehicle load after the step, when reported.'}, 'type': {'type': 'string', 'description': 'Step kind: "start", "job", "pickup", "delivery", "break" or "end".'}, 'location': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': "The step's location resolved back to coordinates."}, 'arrival_s': {'type': 'integer', 'format': 'int64', 'description': "Arrival time in seconds (same epoch as the request's windows)."}, 'service_s': {'type': 'integer', 'format': 'int64', 'description': 'On-site service time in seconds.'}, 'duration_s': {'type': 'integer', 'format': 'int64', 'description': 'Cumulative travel time when the step begins, in seconds.'}, 'waiting_time_s': {'type': 'integer', 'format': 'int64', 'description': 'Waiting time before the step in seconds.'}}, 'description': 'One step of an optimised vehicle route.'}, 'OptimisedRoute': {'type': 'object', 'required': ['vehicle', 'duration_s', 'service_s', 'waiting_time_s', 'steps'], 'properties': {'steps': {'type': 'array', 'items': {'$ref': '#/$defs/OptimisedStep'}, 'description': 'Ordered steps: start, tasks in visit order, end.'}, 'vehicle': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'The vehicle id from the request.'}, 'service_s': {'type': 'integer', 'format': 'int64', 'description': 'Total on-site service time in seconds.'}, 'distance_m': {'type': ['integer', 'null'], 'format': 'int64', 'description': 'Total travel distance in metres, when reported.'}, 'duration_s': {'type': 'integer', 'format': 'int64', 'description': 'Total travel time in seconds.'}, 'waiting_time_s': {'type': 'integer', 'format': 'int64', 'description': 'Total waiting time in seconds.'}}, 'description': "One vehicle's optimised route."}, 'UnassignedTask': {'type': 'object', 'required': ['id', 'type'], 'properties': {'id': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'The task id from the request.'}, 'type': {'type': 'string', 'description': 'Task kind: "job", "pickup" or "delivery".'}, 'location': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': "The task's location, when known."}}, 'description': 'One unassigned task of an optimisation solution.'}, 'OptimiseSummary': {'type': 'object', 'required': ['cost', 'routes', 'unassigned', 'duration_s', 'service_s', 'waiting_time_s'], 'properties': {'cost': {'type': 'integer', 'format': 'int64', 'description': 'Solver cost of the plan (travel seconds under the default model).'}, 'routes': {'type': 'integer', 'format': 'int64', 'description': 'Number of vehicle routes in the plan.'}, 'service_s': {'type': 'integer', 'format': 'int64', 'description': 'Total service time in seconds.'}, 'distance_m': {'type': ['integer', 'null'], 'format': 'int64', 'description': 'Total travel distance in metres, when reported.'}, 'duration_s': {'type': 'integer', 'format': 'int64', 'description': 'Total travel time in seconds.'}, 'unassigned': {'type': 'integer', 'format': 'int64', 'description': 'Number of unassigned tasks.'}, 'waiting_time_s': {'type': 'integer', 'format': 'int64', 'description': 'Total waiting time in seconds.'}}, 'description': 'Solution summary of the `optimise_routes` tool.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['profile', 'summary', 'unassigned', 'routes', 'replan'], 'properties': {'zones': {'description': "Clean-air / low-emission zones touching the problem's own\nlocations, and what the declared vehicle pays in each. Present only\nwhen `emissions` was declared."}, 'replan': {'description': 'What the re-plan locked and why: the prefix held per vehicle, where\neach vehicle re-plans from and how that was decided, stops released\nfrom a vehicle that could no longer serve them, tasks forced\nunassigned, and a note for every id that did not resolve.\n\nRead it. A stop that vanished from the plan is named here rather\nthan left for the dispatcher to notice at four in the afternoon.'}, 'routes': {'type': 'array', 'items': {'$ref': '#/$defs/OptimisedRoute'}, 'description': 'One optimised route per used vehicle.'}, 'profile': {'type': 'string', 'description': 'The matrix costing profile the plan was computed with ("auto",\n"truck", "bicycle", "pedestrian" or "motor_scooter").'}, 'reloads': {'description': "The multi-trip split: each vehicle's trips, their windows, the\ndepot each returns to, and the stated approximation. Present only\nwhen a vehicle declared `reloads`.\n\nRead the `basis` inside it before quoting arrival times. The trip\nwindows are fixed BEFORE the solve, so a lorry that tips early\ncannot lend the spare time to its next trip: stops can come back\nunassigned that a truly sequential model would have served. The\nplan is feasible, never optimistic â\x80\x94 it cannot put a vehicle in two\nplaces at once â\x80\x94 but it is not optimal. Re-plan after each tip\nthrough `replan_routes` for the tighter answer."}, 'summary': {'$ref': '#/$defs/OptimiseSummary', 'description': 'Solution summary.'}, 'relaxation': {'description': 'The relaxation report: the caps requested, whether a second solve\nran, whether ITS plan is the one returned, what was widened, and\nwhat is still unassigned. Present only when `relax_if_unassigned`\nwas declared.\n\nAlways read `second_solve` and `relaxed_plan_used` before telling\nanyone the day fits. A plan produced under relaxation has had\npromises moved, and the block is what says so.'}, 'unassigned': {'type': 'array', 'items': {'$ref': '#/$defs/UnassignedTask'}, 'description': 'Tasks the solver could not assign to any vehicle.'}, 'territories': {'description': 'How the territories bound the plan: which vehicle was eligible for\nwhat, and any task no eligible vehicle existed for. Present only\nwhen `territories` was declared.'}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'MapIssueCategory': {'oneOf': [{'type': 'string', 'const': 'road_closed', 'description': 'A road the map shows as open is closed (roadworks, collapse, event).'}, {'type': 'string', 'const': 'wrong_restriction', 'description': 'A turn/access/dimension/weight restriction is wrong or missing.'}, {'type': 'string', 'const': 'wrong_speed_limit', 'description': "The posted speed limit differs from the map's value."}, {'type': 'string', 'const': 'missing_road', 'description': 'A road exists on the ground but is absent from the map.'}, {'type': 'string', 'const': 'wrong_oneway', 'description': 'A one-way direction is wrong (or the road is not one-way at all).'}, {'type': 'string', 'const': 'access_changed', 'description': 'Access has changed (e.g. now gated, private, or newly public).'}, {'type': 'string', 'const': 'other', 'description': 'Anything else that does not fit the categories above.'}], 'description': 'The kind of map/live-world mismatch an agent is reporting.\n\nA first-party *observation* only: it records what the agent saw on the\nground, never an edit to any map or OSM-derived database.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['location', 'category'], 'properties': {'way_id': {'type': ['integer', 'null'], 'format': 'uint64', 'minimum': 0, 'description': 'The OSM way id the observation concerns, when the caller knows it.\nOptional â\x80\x94 the report stands on its own as a first-party\nobservation and is never tied to OSM data beyond this hint.'}, 'category': {'$ref': '#/$defs/MapIssueCategory', 'description': 'What kind of mismatch this is.'}, 'location': {'$ref': '#/$defs/LatLon', 'description': 'Where the mismatch was observed (WGS84 decimal degrees).'}, 'description': {'type': ['string', 'null'], 'description': 'Free-text detail of what was observed on the ground, e.g. "barrier\nacross the lane, diversion signed via the B4009". Bounded length.'}, 'evidence_url': {'type': ['string', 'null'], 'description': 'A URL backing the observation (photo, notice, news item), when one\nexists. Bounded length.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['report_id', 'status', 'category'], 'properties': {'status': {'type': 'string', 'description': 'Always "queued": the report awaits human/agent review and changes\nnothing about routing immediately.'}, 'category': {'type': 'string', 'description': 'The category, echoed back as its snake_case wire tag.'}, 'report_id': {'type': 'string', 'description': 'The generated id of the queued report (cite it in follow-ups).'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}, 'limit': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Maximum number of results (1â\x80\x9310, default 5). The hosted\nfirst-party index answers at most 5 nearest hits per lookup.'}, 'fov_deg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Field of view: the full width in degrees of a cone centred on\n`heading_deg`, outside which results are dropped â\x80\x94 it is the\nFULL width, so 90 keeps only what lies within 45 degrees either\nside of dead ahead. Needs\n`heading_deg` â\x80\x94 a cone has to point somewhere. The count of\nresults removed is reported as `out_of_view`.'}, 'heading_deg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Which way the user is facing, in degrees **clockwise from true\nnorth** (0 = north, 90 = east, 180 = south, 270 = west). Supply it\nand every result is also described from the user\'s point of view\n("just ahead on your right"); omit it and results fall back to\ncardinal directions ("to the north-east"), so the tool works with\nor without a compass.'}}}
输出模式
{'type': 'object', '$defs': {'ReverseGeocodeHit': {'type': 'object', 'required': ['label', 'lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude of the place in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude of the place in decimal degrees.'}, 'city': {'type': ['string', 'null'], 'description': 'City or town, when known.'}, 'name': {'type': ['string', 'null'], 'description': 'Place name, when the source feature has one.'}, 'type': {'type': ['string', 'null'], 'description': 'Feature type, e.g. "address", "street", "poi", "locality".'}, 'label': {'type': 'string', 'description': 'Human-readable one-line label assembled from the address parts.'}, 'country': {'type': ['string', 'null'], 'description': 'Country, when known: a country name, or the ISO 3166-1 alpha-2\ncode (e.g. "GB") on first-party hits, which carry only the code.'}, 'details': {'description': 'Whitelisted OSM display tags on POI hits (opening_hours, website,\nphone, brand, cuisine, wheelchair, wikipedia, ...), passed through\nverbatim when present.'}, 'postcode': {'type': ['string', 'null'], 'description': 'Postcode, when known.'}, 'direction': {'type': ['string', 'null'], 'description': 'The direction phrased for speech â\x80\x94 "ahead and slightly to your\nright, about 80 metres" with a heading, "to the north-east, about\n80 metres" without one. Deliver this verbatim rather than reading\nout coordinates.'}, 'categories': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': 'POI categories (e.g. ["cafe"]), when the index carries them.'}, 'distance_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Straight-line distance from the queried point in metres, when the\nbackend reports one (first-party gateway hits always do).'}, 'bearing_deg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Bearing from the queried point to this place, degrees clockwise\nfrom true north. Always present.'}, 'relative_bearing_deg': {'type': ['number', 'null'], 'format': 'double', 'description': 'Where this place is relative to the way the user is facing:\nnegative to the left, positive to the right, â\x88\x92180 to 180. Present\nonly when the request supplied `heading_deg`.'}}, 'description': 'One reverse-geocoding result: a place near the queried point. The same\nshape family as [`GeocodeHit`], plus the reverse-only extras\n(`distance_m`, `categories`, `details`) and the egocentric extras\n(`bearing_deg`, `relative_bearing_deg`, `direction`).'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['results'], 'properties': {'results': {'type': 'array', 'items': {'$ref': '#/$defs/ReverseGeocodeHit'}, 'description': 'Nearby places, nearest first.'}, 'out_of_view': {'type': 'integer', 'format': 'uint32', 'minimum': 0, 'description': 'How many otherwise-matching places were dropped for falling\noutside `fov_deg`. Non-zero means there are places near the user\nthat are simply not in front of them â\x80\x94 say so rather than\nreporting nothing nearby. Always 0 when no field of view was set.'}}}
输入模式
{'type': 'object', '$defs': {'TruckSpec': {'type': 'object', 'properties': {'hazmat': {'type': 'boolean', 'default': False, 'description': 'Whether the vehicle carries dangerous goods (ADR). Defaults to\nfalse.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres.'}, 'height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle height in metres.'}, 'length_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle length in metres.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels).'}, 'gross_weight_t': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross combination weight in metric tonnes.'}}, 'description': 'Truck profile for routing: physical dimensions plus the ADR\ndangerous-goods declaration. Omitted dimensions default to the EU\nmaximum authorised dimensions of Council Directive 96/53/EC (4.0 m\nheight, 2.55 m width, 16.5 m length, 40 t gross weight).'}, 'BicycleSpec': {'type': 'object', 'properties': {'use_hills': {'type': ['number', 'null'], 'format': 'double', 'description': 'Willingness to take hills, 0.0â\x80\x931.0 (0.0 = avoid climbs even at the\ncost of longer routes).'}, 'use_roads': {'type': ['number', 'null'], 'format': 'double', 'description': 'Willingness to ride roads alongside motor traffic, 0.0â\x80\x931.0\n(0.0 = prefer cycleways and quiet streets â\x80\x94 the quiet-ride slider).'}, 'bicycle_type': {'type': ['string', 'null'], 'description': 'Bicycle type: "road", "hybrid" (default), "city", "cross" or\n"mountain". Sets default speed and surface tolerance.'}, 'avoid_bad_surfaces': {'type': ['number', 'null'], 'format': 'double', 'description': 'Avoidance of surfaces unsuited to the bicycle type, 0.0â\x80\x931.0\n(1.0 = strictly avoid bad surfaces).'}, 'use_living_streets': {'type': ['number', 'null'], 'format': 'double', 'description': 'Preference for living/shared streets, 0.0â\x80\x931.0.'}}, 'description': 'Bicycle options for costing "bicycle": the bicycle type plus road,\nsurface and hill preference weights, mapped onto Valhalla\n`costing_options.bicycle`.'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}, 'AvoidFeature': {'enum': ['tolls', 'highways', 'ferries'], 'type': 'string', 'description': 'A road feature to avoid as a PREFERENCE, not a ban. "tolls" and "highways" apply to motorised costings only (auto, truck, bus, motor_scooter, motorcycle); "ferries" applies to every costing. Asking for one on a costing whose engine table has no field for it is refused rather than silently ignored.'}, 'EmissionsFuel': {'oneOf': [{'type': 'string', 'const': 'petrol', 'description': "Petrol, including petrol hybrids (schemes rate a hybrid by its\ncombustion engine's approval)."}, {'type': 'string', 'const': 'diesel', 'description': 'Diesel, including diesel hybrids.'}, {'type': 'string', 'const': 'electric', 'description': 'Battery-electric.'}, {'type': 'string', 'const': 'hydrogen', 'description': 'Hydrogen fuel cell.'}, {'type': 'string', 'const': 'gas', 'description': 'LPG or CNG; rated as petrol by every scheme in the dataset.'}], 'description': 'What a vehicle burns, in clean-air-zone scheme terms.'}, 'EmissionsSpec': {'type': 'object', 'required': ['vehicle_category', 'fuel'], 'properties': {'fuel': {'$ref': '#/$defs/EmissionsFuel', 'description': 'What it burns.'}, 'euro_standard': {'type': ['integer', 'null'], 'format': 'uint8', 'maximum': 255, 'minimum': 0, 'description': 'Its Euro emission standard, 1â\x80\x936. Heavy-duty approvals are written\nin Roman numerals (Euro VI); declare Euro VI as `6`. Required for\nany combustion fuel â\x80\x94 without it no zone can be resolved, and a\nhalf-declared vehicle is indistinguishable from an undeclared one.\nOptional only for `electric` or `hydrogen`.'}, 'vehicle_category': {'$ref': '#/$defs/EmissionsVehicleCategory', 'description': 'What kind of vehicle this is, in scheme terms.'}}, 'description': "A vehicle's emission declaration, for clean-air / low-emission zone\nassessment."}, 'RouteLocation': {'type': 'object', 'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'properties': {'preferred_side': {'anyOf': [{'$ref': '#/$defs/PreferredSideKind'}, {'type': 'null'}], 'description': "Which side of the street to arrive on (or depart from). `same` (or\n`curb`) puts the vehicle on the door's side of the road, resolved\nagainst the locale's driving side. Two honest limits: this is a\n**snapping preference**, not a manoeuvre guarantee â\x80\x94 the engine\nprefers an edge on that side, it does not promise the driver never\ncrosses â\x80\x94 and it needs a coordinate genuinely offset from the road\ncentreline, because a point on the centreline has no side."}, 'street_side_tolerance_m': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Metres: nearer than this to the road centreline, the side of street\nis treated as `none` and `preferred_side` does nothing. Engine\ndefault 5 m.'}, 'street_side_max_distance_m': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Metres: further than this from the road centreline, the side of\nstreet is treated as `none` and `preferred_side` does nothing.\nEngine default 1000 m. Together with `street_side_tolerance_m` this\nis a WINDOW: a pair that leaves no window (tolerance at or above\nmax distance) is refused here rather than answered with a route on\nwhich the kerbside preference was silently inert.'}}, 'description': 'One location of a `route` request: a coordinate, plus the optional\nkerbside approach for arriving at it.\n\nA bare `{lat, lon}` is still a complete location â\x80\x94 every kerbside field\nis optional and omitting all of them is exactly the request that was\nmade before they existed.'}, 'ExcludeFeature': {'enum': ['tolls', 'highways', 'ferries', 'bridges', 'tunnels'], 'type': 'string', 'description': "A road feature to exclude outright. A hard exclusion can leave a request with no path at all â\x80\x94 that is the honest answer, not a failure â\x80\x94 and it depends on the routing engine's own hard-exclusion setting, which nothing here can read."}, 'PedestrianSpec': {'type': 'object', 'properties': {'type': {'type': ['string', 'null'], 'description': 'Pedestrian type: "wheelchair" (avoids steps, kerbs and steep\ngrades where mapped) or "blind" (richer guidance detail). Omit for\nthe default on-foot profile.'}, 'use_lit': {'type': ['number', 'null'], 'format': 'double', 'description': 'Preference for lit streets, 0.0â\x80\x931.0 (1.0 = prefer lit paths as\nstrongly as possible â\x80\x94 the "walk me home on lit streets" option).\nUnlit ways are still used when no lit alternative exists.'}, 'max_hiking_difficulty': {'type': ['integer', 'null'], 'format': 'uint8', 'maximum': 255, 'minimum': 0, 'description': 'Maximum hiking-trail difficulty the route may use, as OSM\n`sac_scale` 1â\x80\x936 (1 = well-cleared, mostly flat trails; 6 =\ndemanding alpine terrain). Default 1.'}}, 'description': 'Pedestrian options for costing "pedestrian": lit-street preference,\naccessibility type and hiking difficulty, mapped onto Valhalla\n`costing_options.pedestrian`. All preferences, never guarantees â\x80\x94 the\nrouter prefers matching ways where the map data supports it.'}, 'PreferredSideKind': {'oneOf': [{'type': 'string', 'const': 'same', 'description': "The side the location itself projects to â\x80\x94 the kerb, resolved\nagainst the locale's driving side (the left kerb in the UK, the\nright in Germany)."}, {'type': 'string', 'const': 'opposite', 'description': 'The far side of the road from the location.'}, {'type': 'string', 'const': 'either', 'description': 'No side preference.'}, {'type': 'string', 'const': 'curb', 'description': 'Alias for `same`, from the OSRM/Mapbox `approaches` vocabulary.'}, {'type': 'string', 'const': 'unrestricted', 'description': 'Alias for `either`, from the OSRM/Mapbox `approaches` vocabulary.'}], 'description': "Side-of-street preference for arriving at or departing from a location.\n\nCarries both vocabularies: MapMap's own `same`/`opposite`/`either` and\nthe OSRM/Mapbox `approaches` words `curb`/`unrestricted`, which are\naliases for `same` and `either`. Both spell the same request, on this\nsurface and on the HTTP API."}, 'EmissionsVehicleCategory': {'oneOf': [{'type': 'string', 'const': 'car', 'description': 'A private car.'}, {'type': 'string', 'const': 'van', 'description': 'A van or light goods vehicle up to 3.5 tonnes.'}, {'type': 'string', 'const': 'minibus', 'description': 'A minibus (typically 8+ passenger seats, up to 5 tonnes).'}, {'type': 'string', 'const': 'hgv', 'description': 'A heavy goods vehicle over 3.5 tonnes.'}, {'type': 'string', 'const': 'bus', 'description': 'A bus over 5 tonnes.'}, {'type': 'string', 'const': 'coach', 'description': 'A coach over 5 tonnes.'}, {'type': 'string', 'const': 'taxi', 'description': 'A licensed hackney carriage.'}, {'type': 'string', 'const': 'phv', 'description': 'A private hire vehicle.'}, {'type': 'string', 'const': 'motorcycle', 'description': 'A motorcycle, moped or tricycle.'}, {'type': 'string', 'const': 'motorhome', 'description': 'A motor caravan or campervan.'}], 'description': 'What a vehicle is, in clean-air-zone scheme terms.\n\nDeclaring this turns "charge depends on vehicle emissions" into an\nanswer. Without it a zone can only be named, never priced.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['origin', 'destination'], 'properties': {'avoid': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/AvoidFeature'}, 'description': "Road features to avoid as a PREFERENCE. Rendered as the costing's\nwillingness factor set to zero â\x80\x94 a thumb on the scale, not a ban.\nThe engine's own reference is explicit that a value of zero is not\nguaranteed to avoid the feature entirely, and it does not: asking\nto avoid tolls across the Dartford Crossing returns the same tolled\nroute, because the untolled alternative is fifty kilometres\nfurther. Use `exclude` when you mean a ban."}, 'truck': {'anyOf': [{'$ref': '#/$defs/TruckSpec'}, {'type': 'null'}], 'description': 'Truck profile (dimensions + ADR declaration). Requires costing\n"truck"; when present, ADR dangerous-goods costing options are\nmerged into the request.'}, 'origin': {'$ref': '#/$defs/RouteLocation', 'description': 'Route origin.'}, 'scenic': {'type': ['boolean', 'null'], 'description': 'Ask whether there is a prettier way (default false, `auto`\ncosting only). The route in `geometry_polyline6` is NEVER swapped:\nwhat comes back is a peer offer beside it, in `scenic`, carrying\nthe plain sentence that justifies it. No sentence, no offer: a\nroute that scores well but cannot support one is dropped rather\nthan dressed up, and `scenic.reason` is then null, which is an\nanswer. Every candidate that lost says why in\n`scenic.rejections[]` (`same_route`, `no_scenic_gain`,\n`not_scenic_enough`, `over_time_budget`, `nothing_to_say`), so\n"no prettier way" is always attributable. Opt-in because it\ncosts: at most two extra metered route computations, the same\nbilling shape as `rationale`. Needs the MapMap gateway, whose\nbasemap archive the scoring is measured against.'}, 'bicycle': {'anyOf': [{'$ref': '#/$defs/BicycleSpec'}, {'type': 'null'}], 'description': 'Bicycle options (bicycle type, road/surface/hill preferences).\nRequires costing "bicycle".'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing model: "auto" (default), "truck", "bicycle", "pedestrian"\nor "motor_scooter".'}, 'exclude': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/ExcludeFeature'}, 'description': "Road features to exclude outright, rendered as the costing's hard\nexclusion flag. Two things follow from that and both matter: a hard\nexclusion can return NO ROUTE rather than a detour (excluding\ntunnels on a Rotherhithe crossing has no answer), and the flags\ndepend on the routing engine's `allow_hard_exclusions` setting,\nwhich the engine does not expose and nothing here can read â\x80\x94 so\nthis is never promised, only requested."}, 'emissions': {'anyOf': [{'$ref': '#/$defs/EmissionsSpec'}, {'type': 'null'}], 'description': "The vehicle's emission declaration, for UK clean-air / low-emission\nzone assessment. Given, the response's `zones` block names every\nzone the route enters and what THIS vehicle pays there, with the\npublishing authority cited. Without it a zone can only be named,\nnever priced. Needs the MapMap gateway, which holds the curated\nzone dataset; the full dataset is readable at `GET /v1/zones`."}, 'landmarks': {'type': ['boolean', 'null'], 'description': 'Name landmarks in the turn instructions (default false): each\nmanoeuvre that passes a recognisable place â\x80\x94 a petrol station, a\nsupermarket, a household-name chain â\x80\x94 gains a\n`landmark_instruction` like "Turn right just after the Shell\ngarage" beside the engine\'s own street-name instruction, which is\nnever replaced. Nothing is named unless it is recognisable from the\nroad, within 40 m of the junction and not tagged as closed, so many\nroutes come back with none: a wrong landmark is worse than no\nlandmark. Needs the MapMap gateway, whose place index does the\nlookup.'}, 'rationale': {'type': ['boolean', 'null'], 'description': 'Explain the route (default false): re-routes with each declared\ntruck constraint (truck costing) or avoidance-side routing\npreference (auto, bicycle, pedestrian, motor_scooter) relaxed and\nreports the ones that actually changed the route as\n`rationale.avoided[]`. Opt-in â\x80\x94 it costs up to 1 + N extra routing\ncalls, one per declared field plus one combined probe, and it is\nbilled for the ones it actually makes: at most 8 in total,\ntypically fewer, and 1 when there is nothing to probe. Against the\nhosted gateway each probe is its own metered route call, which is\nexactly what `POST /route` with `rationale: true` charges for its\nown fan-out, so the two surfaces price the same explanation the\nsame way.'}, 'waypoints': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/RouteLocation'}, 'description': 'Optional intermediate stops, visited in order between origin and\ndestination.'}, 'pedestrian': {'anyOf': [{'$ref': '#/$defs/PedestrianSpec'}, {'type': 'null'}], 'description': 'Pedestrian options (lit-street preference, wheelchair/blind type,\nhiking difficulty). Requires costing "pedestrian".'}, 'destination': {'$ref': '#/$defs/RouteLocation', 'description': 'Route destination.'}, 'exclude_polygons': {'type': ['array', 'null'], 'items': {'type': 'array', 'items': {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2}}, 'description': 'Areas to avoid â\x80\x94 scenario analysis ("close this bridge and\nre-route"): an array of polygons, each an array of `[lon, lat]`\npairs forming one exterior ring (GeoJSON-style, longitude FIRST).\nRoads intersecting any ring are excluded from the search. Applies\nto the Valhalla engine; unsupported on the GraphHopper engine,\nwhere it is ignored.'}}}
输出模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'AppliedAdr': {'type': 'object', 'required': ['hazmat', 'forbidden_tunnel_categories', 'tunnel_enforcement', 'costing_options'], 'properties': {'hazmat': {'type': 'boolean', 'description': 'Whether the profile declared dangerous goods.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'Canonical ADR tunnel restriction code applied ("B/D", "(â\x80\x94)", â\x80¦),\nor null when no code was declared.'}, 'costing_options': {'description': 'The exact Valhalla `costing_options` JSON merged into the request.'}, 'tunnel_enforcement': {'$ref': '#/$defs/TunnelEnforcement', 'description': 'What the router did with `forbidden_tunnel_categories`, and the\nboundary of the resulting guarantee.'}, 'forbidden_tunnel_categories': {'type': 'array', 'items': {'type': 'string'}, 'description': 'ADR tunnel categories **the vehicle** is forbidden from under the\nworst-case reading of ADR 8.6.4 (conditional clauses assumed to\napply). Empty when unrestricted. This is not a claim that the\nreturned route contains no tunnel of these categories â\x80\x94 read\n[`AppliedAdr::tunnel_enforcement`] for what was actually applied.'}}, 'description': 'The ADR costing that was merged into a truck route request.\n\nEvery field here describes the **request**: the declared load and the\ncosting options built from it. Nothing here is an assertion about the\nreturned geometry â\x80\x94 see [`TunnelEnforcement`].'}, 'ManeuverOut': {'type': 'object', 'required': ['instruction', 'distance_m', 'duration_s'], 'properties': {'distance_m': {'type': 'number', 'format': 'double', 'description': 'Length of the maneuver in metres.'}, 'duration_s': {'type': 'number', 'format': 'double', 'description': 'Estimated duration of the maneuver in seconds.'}, 'instruction': {'type': 'string', 'description': 'Written instruction, e.g. "Turn right onto Main Street".'}, 'landmark_instruction': {'type': ['string', 'null'], 'description': 'The same manoeuvre anchored to a recognisable place, e.g. "Turn\nright just after the Shell garage" â\x80\x94 present only when the request\nset `landmarks: true` and a place near the junction cleared the\nsalience bar. Prefer reading this aloud when it is there: it is how\na passenger would give the direction. `instruction` is always the\nengine\'s own and is never replaced.'}}, 'description': 'One turn-by-turn instruction of a computed route.'}, 'ScenicOffer': {'type': 'object', 'required': ['available', 'chosen', 'caveats', 'block'], 'properties': {'note': {'type': ['string', 'null'], 'description': 'Why no assessment ran (only when `available` is false).'}, 'block': {'description': "The gateway's whole `scenic` block, verbatim: candidates, feature\nshares, tile coverage, metering and budget."}, 'chosen': {'type': 'string', 'description': 'Which route the assessment would offer: `"fastest"` (the quick way\nis already the pretty one, or nothing beat it) or `"scenic"`.'}, 'reason': {'type': ['string', 'null'], 'description': 'The plain, speakable sentence behind the offer. **Null is an\nanswer**: nothing on this corridor measured above the floor, so\nno claim is made rather than one being invented.'}, 'spoken': {'type': ['string', 'null'], 'description': 'The trade phrased for speech, e.g. "About seven minutes longer\nthan the quick way." Prefer reading this aloud over the seconds.'}, 'caveats': {'type': 'string', 'description': 'The standing limits of the method, for relaying to users.'}, 'available': {'type': 'boolean', 'description': 'Whether scenery could be assessed at all on this deployment. When\nfalse, `note` says why and nothing below was measured: that is\n"we could not look", never "there is nothing there".'}, 'rejections': {'type': 'array', 'items': {'$ref': '#/$defs/ScenicRejection'}, 'description': 'Why each candidate that lost lost. Empty when none did. Relay it:\nit is what makes "no prettier way" an attributable answer instead\nof a shrug.'}, 'extra_time_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'How much longer the offered route takes than the fastest one,\nseconds, and the sentence for it. Absent when nothing was offered.'}, 'alternative_geometry_polyline6': {'type': ['string', 'null'], 'description': "The scenic route's own geometry, polyline6, when there is one to\noffer. `geometry_polyline6` on the route itself is byte-for-byte\nwhat the same request returns without the flag."}}, 'description': "The scenic assessment beside a route: a peer offer, never a\nsubstitution.\n\nThe fields here are the ones a client must actually read before\nsaying anything. `block` keeps the gateway's whole answer beside them\nso a figure can always be audited back to the source that produced\nit, rather than to this mapping."}, 'RouteRationale': {'type': 'object', 'required': ['method', 'avoided', 'caveats'], 'properties': {'note': {'type': ['string', 'null'], 'description': 'Why the list is empty or incomplete, when it is.'}, 'method': {'type': 'string', 'description': 'Always "route_divergence".'}, 'avoided': {'type': 'array', 'items': {'$ref': '#/$defs/AvoidedConstraint'}, 'description': 'The declared constraints or preferences that changed the route,\nwith locations and costs. Empty when nothing was binding.'}, 'caveats': {'type': 'string', 'description': "The method's limits, spelled out for relaying to users."}}, 'description': 'Why the route goes the way it does â\x80\x94 the `route` tool\'s opt-in\nrationale block, computed for truck, auto, bicycle, pedestrian and\nmotor_scooter costings. **Method honesty:** the routing engine exposes\nno exclusion set, so entries are derived by re-routing with each\ndeclared constraint or preference relaxed\n(`basis: "route_divergence"`); this proves a field was binding and\nwhere, but never names the physical restriction or feature (the\nspecific signed bridge, hill or unlit street). No live traffic or\nincident data enters the comparison and no delay is ever estimated\nfrom one â\x80\x94 the engine has no live speed field.'}, 'LandmarkSummary': {'type': 'object', 'required': ['annotated'], 'properties': {'note': {'type': ['string', 'null'], 'description': 'Why the count is what it is, when there is something to say: the\nper-route lookup cap was reached, or the deployment has no place\nindex at all. Absent means the number is simply the number, so a\nzero with no note means this route genuinely passes nothing\nrecognisable rather than that landmarks could not be looked up.'}, 'annotated': {'type': 'integer', 'format': 'uint32', 'minimum': 0, 'description': 'How many manoeuvres gained a `landmark_instruction`.'}}, 'description': "The gateway's `landmarks` summary block."}, 'ScenicRejection': {'type': 'object', 'required': ['source', 'code', 'detail'], 'properties': {'code': {'type': 'string', 'description': 'The rejection code: `same_route`, `no_scenic_gain`,\n`not_scenic_enough`, `over_time_budget` or `nothing_to_say`.'}, 'detail': {'type': 'string', 'description': 'The code in words, including the minutes an `over_time_budget`\ncandidate would have cost, so raising the budget is an informed\nchoice rather than a guess.'}, 'source': {'type': 'string', 'description': 'Where the candidate came from: `"fastest"`, `"engine_alternate"`\nor `"no_motorway"`.'}}, 'description': 'Why one candidate route was not offered.'}, 'AppliedAvoidance': {'type': 'object', 'required': ['costing_option_fields', 'caveats'], 'properties': {'avoid': {'type': 'array', 'items': {'type': 'string'}, 'description': 'The `avoid` values that were applied, echoed back.'}, 'caveats': {'type': 'array', 'items': {'type': 'string'}, 'description': 'The caveats that apply to this request, in words fit to repeat to a\nuser. Always present when anything was applied.'}, 'exclude': {'type': 'array', 'items': {'type': 'string'}, 'description': 'The `exclude` values that were applied, echoed back.'}, 'costing_option_fields': {'description': 'The engine costing-option fields these words became, e.g.\n`{"use_tolls": 0.0, "exclude_ferries": true}`. This is the whole of\nwhat was sent â\x80\x94 there is no hidden second mechanism.'}}, 'description': 'What the avoidance lists actually did, reported back so a 200 is never\nreadable as a certificate.'}, 'AvoidedConstraint': {'type': 'object', 'required': ['kind', 'constraint', 'value', 'basis', 'baseline', 'location', 'rejoins_at', 'diverged_length_m', 'time_saved_s', 'distance_saved_m', 'reason'], 'properties': {'kind': {'type': 'string', 'description': 'Reason kind. Truck: "max_height", "max_width", "max_length",\n"max_weight", "hazmat", "adr_tunnel". Preferences: "hill_avoided",\n"surface_avoided", "road_avoided", "highway_avoided",\n"toll_avoided", "ferry_avoided", "living_street_avoided",\n"primary_road_avoided", "unlit_street_avoided",\n"hiking_difficulty_limited", "access_profile". Any costing:\n"combined". There is deliberately no "incident_avoided" or\n"traffic_delay_avoided": the engine consumes no live incident or\ntraffic-speed input, so no divergence can be attributed to them.'}, 'unit': {'type': ['string', 'null'], 'description': 'Unit of `value` ("m", "t") when dimensional.'}, 'basis': {'type': 'string', 'description': 'Always "route_divergence": the entry was derived by re-routing\nwithout the field and diffing geometry, not from sign or\nmap-feature data.'}, 'value': {'description': 'The declared value for the field (null for "combined"). NOTE: for\ntruck this is the vehicle\'s dimension, not the infrastructure\nlimit â\x80\x94 the physical restriction is not identified.'}, 'fields': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': 'For kind "combined": the constraint fields that only bind together.'}, 'reason': {'type': 'string', 'description': 'Human-readable explanation, honest about the method.'}, 'baseline': {'type': 'string', 'description': 'What the probe compared against: "relaxed_to_non_binding" (truck\nconstraints set to explicitly non-binding values),\n"engine_default" (preference removed so the engine default\napplies) or "cap_lifted" (a hard cap raised to its maximum).'}, 'location': {'$ref': '#/$defs/LatLon', 'description': 'Where the constrained and unconstrained routes part ways.'}, 'constraint': {'type': 'string', 'description': 'The costing-options field that was relaxed ("height", "use_hills",\nâ\x80¦, or "combined").'}, 'rejoins_at': {'$ref': '#/$defs/LatLon', 'description': 'Where they rejoin.'}, 'time_saved_s': {'type': 'number', 'format': 'double', 'description': 'Travel time the constraint costs (unconstrained is this much\nfaster), seconds. Zero when the alternative is no faster.'}, 'distance_saved_m': {'type': 'number', 'format': 'double', 'description': 'Distance the constraint costs, metres.'}, 'diverged_length_m': {'type': 'number', 'format': 'double', 'description': 'Length of the diverging span along the constrained route, metres.'}}, 'description': 'One constraint or preference the route provably changed for, derived\nby route divergence (see [`RouteRationale`]).'}, 'TunnelEnforcement': {'type': 'object', 'required': ['basis', 'route_certified', 'caveat'], 'properties': {'basis': {'type': 'string', 'description': 'How the code is applied. `"graph_adr_tunnel_category"`: merged into\n`costing_options.truck.adr_tunnel_code` and matched, during the\nsearch, against each road\'s ADR tunnel category as recorded in the\nrouting graph.'}, 'caveat': {'type': 'string', 'description': 'What an unchanged route does and does not prove, in one sentence.'}, 'route_certified': {'type': 'boolean', 'description': 'Whether the returned route has been checked against a tunnel\ninventory *after* it was computed. Always `false`: exclusion happens\nduring the search, and only for roads the graph has a category for.\nA 200 is not a compliance certificate, and must not be relied on as\none.'}}, 'description': 'How the declared ADR tunnel code reaches the routing engine, and what a\nreturned route therefore does â\x80\x94 and does not â\x80\x94 prove.\n\nThis block exists because [`AppliedAdr::forbidden_tunnel_categories`] is\na statement about the **load** (ADR 8.6.4 applied to the declared code),\nand on its own it reads like a statement about the **route**. It is not\none. The engine excludes a road only where the routing graph records an\nADR tunnel category for it, and that category is derived from OSM\n`hazmat:*` tagging. Coverage is therefore uneven: a corridor with no\nsuch tagging is not excluded and looks, in the response, exactly like a\ncorridor that was checked and cleared.\n\nThe field is emitted on every `applied_adr`, so a caller can never\nreceive the categories without the boundary that qualifies them.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['distance_m', 'duration_s', 'summary', 'maneuvers', 'geometry_polyline6'], 'properties': {'zones': {'description': "Clean-air / low-emission zones this route enters and what the\ndeclared vehicle pays in each, with the publishing authority cited\n(only when `emissions` was declared). Passed through verbatim from\nthe gateway's curated dataset â\x80\x94 the same figures `GET /v1/zones`\npublishes, so a charge can always be audited back to its source."}, 'scenic': {'anyOf': [{'$ref': '#/$defs/ScenicOffer'}, {'type': 'null'}], 'description': 'The scenic peer offer (only when `scenic: true` was requested):\nwhether there is a prettier way, the sentence that justifies it,\nwhat the detour costs, and why every candidate that lost lost.\nThe route above is never swapped for it.'}, 'summary': {'type': 'string', 'description': 'One-line human-readable summary of the route.'}, 'avoidance': {'anyOf': [{'$ref': '#/$defs/AppliedAvoidance'}, {'type': 'null'}], 'description': 'What `avoid`/`exclude` became, and the caveats that go with it\n(only when either list carried something).'}, 'landmarks': {'anyOf': [{'$ref': '#/$defs/LandmarkSummary'}, {'type': 'null'}], 'description': 'The landmark-annotation summary (only when `landmarks: true` was\nrequested): how many manoeuvres gained a `landmark_instruction`,\nand a `note` when the per-route cap was hit or the deployment has\nno place index. A zero with no note means this route genuinely\npasses nothing recognisable.'}, 'maneuvers': {'type': 'array', 'items': {'$ref': '#/$defs/ManeuverOut'}, 'description': 'Ordered turn-by-turn maneuvers across all legs.'}, 'rationale': {'anyOf': [{'$ref': '#/$defs/RouteRationale'}, {'type': 'null'}], 'description': 'Why the route goes this way (only when `rationale: true` was\nrequested; computed for truck, auto, bicycle, pedestrian and\nmotor_scooter costings).'}, 'distance_m': {'type': 'number', 'format': 'double', 'description': 'Total route distance in metres.'}, 'duration_s': {'type': 'number', 'format': 'double', 'description': 'Total estimated travel time in seconds.'}, 'applied_adr': {'anyOf': [{'$ref': '#/$defs/AppliedAdr'}, {'type': 'null'}], 'description': 'The ADR costing merged into the request, or null when no truck\nprofile was given.'}, 'geometry_polyline6': {'type': 'string', 'description': 'Full route geometry as a Google encoded polyline with six digits of\ndecimal precision (polyline6).'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['geometry_polyline6'], 'properties': {'units': {'type': ['string', 'null'], 'description': 'Units for the spoken distances: `miles` (default) or\n`kilometers`. `kilometres` and `km` are accepted too.'}, 'min_gap_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Least distance along the route between two observations, metres\n(default 2000). A FLOOR, not a target: when the route holds more\nthan `max_observations`, the gap widens past this on its own so\nthe survivors stay spread over the whole journey.'}, 'max_observations': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Ceiling on how many observations come back, 1 to 200 (default\n40).'}, 'geometry_polyline6': {'type': 'string', 'description': "The route shape, precision-6 encoded: `geometry_polyline6`\nstraight out of the `route` tool's answer. Nothing else is\naccepted: there is no origin/destination form, because this tool\nannotates a route somebody already chose rather than computing\none."}}}
输出模式
{'type': 'object', '$defs': {'RouteObservation': {'type': 'object', 'required': ['at_m', 'kind', 'subject', 'say', 'basis'], 'properties': {'say': {'type': 'string', 'description': 'The sentence to say. Prefer reading this aloud verbatim: it is\nalready shaped for speech and already checked for length.'}, 'at_m': {'type': 'number', 'format': 'double', 'description': 'Distance along the route where this applies, metres. The whole\npoint of the answer: said anywhere else it is trivia, not an\nobservation.'}, 'kind': {'type': 'string', 'description': '`crossing`, `landscape`, `settlement`, `watercourse`, `road` or\n`climb`. Each claims a different thing and rests on different\nevidence.'}, 'basis': {'type': 'string', 'description': 'Which map layer and tag the claim rests on, so anybody who doubts\none can go and look at the same feature.'}, 'run_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'For a run-length observation (a road or a landscape), how far the\nrun lasted, metres.'}, 'subject': {'type': 'string', 'description': "The subject's name exactly as the map records it, before any\nwording."}, 'offset_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'For a settlement, how far off the route the mapped centre lies,\nmetres. A settlement is a labelled POINT, not a boundary, so this\nis the number behind the word "through" and nobody has to take it\non trust.'}, 'elevation_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'For a climb, the height at the top, metres above sea level.'}}, 'description': 'One thing worth saying about one point on a route.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['route_length_m', 'observations', 'coverage', 'attribution', 'caveat'], 'properties': {'caveat': {'type': 'string', 'description': 'The standing limits of the method, for relaying to users.'}, 'coverage': {'description': 'What the archive and the elevation model could and could not say:\n`tiles_read`, `tiles_missing`, `uncovered_m`, and the per-kind\ncensuses. **Read it before reporting an empty list.** `tiles_read`\nof 0 means nothing was looked at, which is not the same claim as\nquiet countryside.'}, 'attribution': {'type': 'string', 'description': 'The licence notice for this answer. The obligation attaches to the\nproduct, not to each spoken sentence, so a visible or linked\ncredit in the app satisfies it.'}, 'observations': {'type': 'array', 'items': {'$ref': '#/$defs/RouteObservation'}, 'description': 'The observations, in route order, already thinned to the silence\nbudget.'}, 'route_length_m': {'type': 'number', 'format': 'double', 'description': "The route's own length, metres, as walked."}}}
输入模式
{'type': 'object', '$defs': {'LatLon': {'anyOf': [{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees (â\x88\x9290 to 90).'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees (â\x88\x92180 to 180).'}}}, {'type': 'array', 'items': {'type': 'number', 'format': 'double'}, 'maxItems': 2, 'minItems': 2, 'description': 'GeoJSON position [lon, lat]: longitude FIRST.'}], 'description': 'A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server.'}, 'TruckSpec': {'type': 'object', 'properties': {'hazmat': {'type': 'boolean', 'default': False, 'description': 'Whether the vehicle carries dangerous goods (ADR). Defaults to\nfalse.'}, 'width_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle width in metres.'}, 'height_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle height in metres.'}, 'length_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Vehicle length in metres.'}, 'tunnel_code': {'type': ['string', 'null'], 'description': 'ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D",\n"B/D", or "(â\x80\x94)"/"none" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels).'}, 'gross_weight_t': {'type': ['number', 'null'], 'format': 'double', 'description': 'Gross combination weight in metric tonnes.'}}, 'description': 'Truck profile for routing: physical dimensions plus the ADR\ndangerous-goods declaration. Omitted dimensions default to the EU\nmaximum authorised dimensions of Council Directive 96/53/EC (4.0 m\nheight, 2.55 m width, 16.5 m length, 40 t gross weight).'}, 'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['query'], 'properties': {'query': {'type': 'string', 'description': 'Free-text POI query, e.g. "coffee", "EV charger", "truck stop".'}, 'truck': {'anyOf': [{'$ref': '#/$defs/TruckSpec'}, {'type': 'null'}], 'description': 'Truck profile (dimensions + ADR declaration). Requires costing\n"truck"; the detours then respect dimensional/ADR restrictions.'}, 'origin': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Route origin (with `destination`, when no geometry is given).'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing model for the route and detour matrix: "auto" (default),\n"truck", "bicycle", "pedestrian" or "motor_scooter".'}, 'category': {'type': ['string', 'null'], 'description': 'Explicit place category ("fuel", "cafe", "charging_station" â\x80\x94 same\nvocabulary as nearby_places). Colloquial phrases are normalised\nserver-side; prefer this over query for category intents.'}, 'destination': {'anyOf': [{'$ref': '#/$defs/LatLon'}, {'type': 'null'}], 'description': 'Route destination.'}, 'max_results': {'type': ['integer', 'null'], 'format': 'uint32', 'minimum': 0, 'description': 'Maximum results (default 5, at most 25).'}, 'geometry_polyline6': {'type': ['string', 'null'], 'description': "An existing route geometry as an encoded polyline6 (the `route`\ntool's `geometry_polyline6`). Provide either this or `origin` +\n`destination`, not both."}, 'max_detour_minutes': {'type': ['number', 'null'], 'format': 'double', 'description': 'Largest acceptable detour in minutes (default 10, at most 120).'}}, 'additionalProperties': False}
输出模式
{'type': 'object', '$defs': {'GeocodeHit': {'type': 'object', 'required': ['label', 'lat', 'lon'], 'properties': {'lat': {'type': 'number', 'format': 'double', 'description': 'Latitude in decimal degrees.'}, 'lon': {'type': 'number', 'format': 'double', 'description': 'Longitude in decimal degrees.'}, 'city': {'type': ['string', 'null'], 'description': 'City or town, when known.'}, 'name': {'type': ['string', 'null'], 'description': 'Place name, when the source feature has one.'}, 'type': {'type': ['string', 'null'], 'description': 'Feature type, e.g. "house", "street", "city" (falls back to the\nOSM value when the endpoint does not classify).'}, 'label': {'type': 'string', 'description': 'Human-readable one-line label assembled from the address parts.'}, 'match': {'anyOf': [{'$ref': '#/$defs/GeocodeMatch'}, {'type': 'null'}], 'description': "How far this hit can be trusted to be the place that was asked\nfor â\x80\x94 see [`GeocodeMatch`]. Present whenever the MapMap gateway\nanswered; absent on a deployment falling back to the direct Photon\ngeocoder, and absent on the gateway's own fast paths (a pasted\ncoordinate pair, a bare UK outward code, a category browse), which\nanswer without a ranking to report on."}, 'country': {'type': ['string', 'null'], 'description': 'Country, when known.'}, 'postcode': {'type': ['string', 'null'], 'description': 'Postcode, when known.'}}, 'description': 'One geocoding result.'}, 'GeocodeMatch': {'type': 'object', 'required': ['components', 'score_gap', 'source'], 'properties': {'source': {'type': 'string', 'description': 'Which backend answered: "mapmap-index" (the first-party index) or\n"photon".'}, 'score_gap': {'type': 'number', 'format': 'double', 'description': 'The top result\'s score minus the runner-up\'s, rounded to 3 decimal\nplaces. `0` for a single result, and `0` from the `photon` source,\nwhich publishes no per-result score â\x80\x94 so a `0` is "no signal", not\n"a tie".'}, 'components': {'$ref': '#/$defs/GeocodeMatchComponents', 'description': 'Per-component verdict on this hit: one entry for each structured\ncomponent supplied, and empty when the query was free text only.'}}, 'description': 'How well one geocoding result answers what was actually asked.\n\nGeocoding\'s real failure mode is not "no answer" but a confident answer\nto a different question: a plausible row on the wrong street, with\nnothing in the response to say so. This object is that missing say-so,\nand an agent should read it before acting on an address.\n\nHow to read it:\n\n* Any component `unmatched` or `inferred` on the TOP hit means the\n answer does not carry the address that was asked for â\x80\x94 an `unmatched`\n postcode means the result has no postcode at all, `inferred` means it\n has a different one. Neither is a match. Say so rather than presenting\n the hit as the address, and reach for `verify_places` when the address\n came from a model or a user and needs checking rather than using.\n* A small `score_gap` means the ranking barely chose between this hit\n and the runner-up, which is exactly when to show the alternatives\n instead of picking one for the user.'}, 'AlongRouteHit': {'type': 'object', 'required': ['place', 'detour_minutes', 'detour_s', 'along_route_position', 'off_route_m'], 'properties': {'place': {'$ref': '#/$defs/GeocodeHit', 'description': 'The place (geocoder hit: name, label, coordinates, type).'}, 'detour_s': {'type': 'number', 'format': 'double', 'description': 'The same detour in raw seconds.'}, 'detour_km': {'type': ['number', 'null'], 'format': 'double', 'description': 'Extra travel distance in kilometres, when the engine reported\ndistances.'}, 'fuel_brand': {'type': ['string', 'null'], 'description': "The matched fuel station's brand, when known (same conditions as\n`fuel_prices`)."}, 'fuel_prices': {'description': 'Live pump prices for this fuel/petrol station, keyed by fuel code\n(e.g. "diesel", "petrol_95"), each `{value, currency, updated_at}`.\nOnly ever present when the server is gateway-preferred AND the\ndeployment configured `SN_FUEL_PRICES` AND this result matched a\nstation within range â\x80\x94 never fabricated. Direct-backend fallback\nnever sets this (see the gap this closes in the PR description).'}, 'off_route_m': {'type': 'number', 'format': 'double', 'description': 'Straight-line distance from the place to the route, metres.'}, 'detour_minutes': {'type': 'number', 'format': 'double', 'description': "Extra travel time of visiting this place, in minutes (rounded to\n0.1): (originâ\x86\x92place) + (placeâ\x86\x92destination) â\x88\x92 (originâ\x86\x92destination),\nall computed by the routing engine with the request's costing."}, 'fuel_updated_at': {'type': ['string', 'null'], 'description': "When the matched fuel station's prices were last refreshed (RFC\n3339), when known (same conditions as `fuel_prices`)."}, 'along_route_position': {'type': 'number', 'format': 'double', 'description': 'Where along the route the place sits, 0.0 (origin) to 1.0\n(destination), by distance along the geometry.'}}, 'description': 'One place found along the route, with its honest detour cost.'}, 'GeocodeMatchComponents': {'type': 'object', 'properties': {'city': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `city`.'}, 'street': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `street`.'}, 'country': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `country`.'}, 'postcode': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `postcode`.'}, 'housenumber': {'type': ['string', 'null'], 'description': 'Verdict on the supplied `housenumber`.'}}, 'description': 'Per-component verdicts inside a [`GeocodeMatch`]. Each is one of\n"matched", "inferred" or "unmatched"; a component that was not supplied\nis absent entirely.\n\n* "matched" â\x80\x94 the result\'s own field carries the value asked for (case-\n and accent-insensitive, and by containment, so `city: "London"`\n matches "City of London").\n* "inferred" â\x80\x94 the result carries a value for that component, but not\n the one asked for. It reached the page through ranking, as when a\n street is found by its transliterated name and displayed under its\n canonical one.\n* "unmatched" â\x80\x94 the result carries no value for that component at all.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['query', 'costing', 'route_length_m', 'candidates_considered', 'candidates_costed', 'candidate_cap', 'max_detour_minutes', 'results'], 'properties': {'query': {'type': 'string', 'description': 'The query as interpreted.'}, 'costing': {'type': 'string', 'description': 'The costing the detours were priced with.'}, 'results': {'type': 'array', 'items': {'$ref': '#/$defs/AlongRouteHit'}, 'description': 'Places within the detour budget, cheapest detour first.'}, 'candidate_cap': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'The matrix fan-out cap in force.'}, 'route_length_m': {'type': 'number', 'format': 'double', 'description': 'Length of the route geometry in metres.'}, 'fuel_attribution': {'type': ['string', 'null'], 'description': 'Attribution string for fuel-price data sources, present only when\nat least one returned result carries `fuel_prices` (gateway-preferred\nmode with `SN_FUEL_PRICES` configured; see [`AlongRouteHit`]).'}, 'route_distance_m': {'type': ['number', 'null'], 'format': 'double', 'description': 'Direct originâ\x86\x92destination distance in metres.'}, 'route_duration_s': {'type': ['number', 'null'], 'format': 'double', 'description': 'Direct originâ\x86\x92destination travel time in seconds (same estimator\nas the detour legs), when routable.'}, 'candidates_costed': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'Candidates actually priced through the engine (fan-out is capped\nat `candidate_cap` nearest-to-route).'}, 'matched_categories': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': 'The normalised category tokens the candidates were browsed by,\npresent only when a category browse actually ran (an explicit\n`category`, or a query the server promoted to one). Absent means\nfree-text name matching answered the call, so a caller can tell how\nits words were understood rather than inferring it from the results.'}, 'max_detour_minutes': {'type': 'number', 'format': 'double', 'description': 'The detour budget applied, minutes.'}, 'candidates_considered': {'type': 'integer', 'format': 'uint', 'minimum': 0, 'description': 'Candidates found near the corridor before pricing.'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['style_id', 'layer_id', 'property', 'value'], 'properties': {'value': {'description': 'The paint value (any MapLibre-valid JSON: number, colour string or\nexpression array).'}, 'layer_id': {'type': 'string', 'description': 'Skeleton layer id, e.g. "road-major". Call `list_style_layers`\nfor the accepted ids.'}, 'property': {'type': 'string', 'description': 'MapLibre paint property name, e.g. "line-width" or "fill-color".'}, 'style_id': {'type': 'string', 'description': 'Hosted style id.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['style_id', 'version', 'style_url'], 'properties': {'version': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'The newly published version.'}, 'style_id': {'type': 'string', 'description': 'Hosted style id.'}, 'style_url': {'type': 'string', 'description': 'Immutable URL of the compiled style at this version.'}}}
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['style_id', 'colours'], 'properties': {'colours': {'type': 'object', 'description': 'Palette overrides: slot name â\x86\x92 CSS colour (e.g.\n{"water": "#0b2038"}). Call `list_style_layers` for the slot names.', 'additionalProperties': {'type': 'string'}}, 'style_id': {'type': 'string', 'description': 'Hosted style id.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['style_id', 'version', 'style_url'], 'properties': {'version': {'type': 'integer', 'format': 'uint64', 'minimum': 0, 'description': 'The newly published version.'}, 'style_id': {'type': 'string', 'description': 'Hosted style id.'}, 'style_url': {'type': 'string', 'description': 'Immutable URL of the compiled style at this version.'}}}
输入模式
{'type': 'object', '$defs': {'RetroProblemArea': {'oneOf': [{'type': 'string', 'const': 'sdk', 'description': 'The mobile/web SDKs.'}, {'type': 'string', 'const': 'api', 'description': 'The hosted HTTP API.'}, {'type': 'string', 'const': 'mcp', 'description': 'The MCP tool surface.'}, {'type': 'string', 'const': 'docs', 'description': 'Documentation.'}, {'type': 'string', 'const': 'billing', 'description': 'Billing, keys or quotas.'}, {'type': 'string', 'const': 'self-host', 'description': 'Self-hosted deployment.'}, {'type': 'string', 'const': 'other', 'description': 'Anything else.'}], 'description': "The platform area an integration problem belongs to (mirrors the\ngateway's `POST /v1/feedback` schema)."}, 'RetroProblemInput': {'type': 'object', 'required': ['area', 'description', 'workaround_found'], 'properties': {'area': {'$ref': '#/$defs/RetroProblemArea', 'description': 'Which part of the platform the problem was in.'}, 'description': {'type': 'string', 'description': 'What went wrong (at most 1000 bytes).'}, 'workaround_found': {'type': 'boolean', 'description': 'Whether a workaround was found.'}}, 'description': 'One problem hit during the integration.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['what_built'], 'properties': {'wins': {'type': 'array', 'items': {'type': 'string'}, 'default': [], 'description': 'What went well (at most 20 entries Ã\x97 500 bytes).'}, 'gotchas': {'type': 'array', 'items': {'type': 'string'}, 'default': [], 'description': 'Surprises/traps worth documenting (at most 20 entries Ã\x97 500 bytes).'}, 'problems': {'type': 'array', 'items': {'$ref': '#/$defs/RetroProblemInput'}, 'default': [], 'description': 'Problems hit during the integration (at most 20).'}, 'docs_gaps': {'type': 'array', 'items': {'type': 'string'}, 'default': [], 'description': 'Documentation gaps hit (at most 20 entries Ã\x97 500 bytes).'}, 'agent_name': {'type': ['string', 'null'], 'description': 'The submitting agent\'s name, e.g. "Claude Code" (at most 100\nbytes).'}, 'what_built': {'type': 'string', 'description': 'What was built with MapMap, in one or two sentences (required, at\nmost 500 bytes).'}, 'sdk_version': {'type': ['string', 'null'], 'description': 'MapMap SDK version integrated against, when known (at most 50\nbytes).'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['retro_id', 'status', 'delivery', 'message'], 'properties': {'status': {'type': 'string', 'description': '`received` when the gateway stored it; `queued` when it was\nappended to the local review queue.'}, 'message': {'type': 'string', 'description': "A short, honest sentence for the agent saying where the retro\nlanded â\x80\x94 sent to MapMap, or held in this server's local queue."}, 'delivery': {'type': 'string', 'description': 'How it was delivered: `gateway` or `local-queue`.'}, 'retro_id': {'type': 'string', 'description': 'Id of the stored retro (gateway id, or the local queue id).'}}}
输入模式
{'type': 'object', '$defs': {'JobKind': {'oneOf': [{'type': 'string', 'const': 'optimise', 'description': 'A fleet optimisation â\x80\x94 the `optimise_routes` problem, at ten times\nthe synchronous location cap.'}, {'type': 'string', 'const': 'replan', 'description': 'A mid-shift re-plan â\x80\x94 the `replan_routes` problem, counted on the\nremaining work.'}, {'type': 'string', 'const': 'matrix', 'description': 'A many-to-many time/distance matrix â\x80\x94 the `matrix` problem, at four\ntimes the synchronous element cap.'}], 'description': 'Which asynchronous problem is being submitted.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['kind', 'problem'], 'properties': {'kind': {'$ref': '#/$defs/JobKind', 'description': 'Which problem this is. It selects both the body shape below and the\nceiling the submission is judged against.'}, 'problem': {'description': 'The problem itself, in exactly the shape the synchronous tool takes\nâ\x80\x94 `optimise_routes` input for `optimise`, `replan_routes` input for\n`replan`, `matrix` input for `matrix`. Moving a working synchronous\ncall onto this lane changes nothing but the tool you call it with.'}, 'webhook_url': {'type': ['string', 'null'], 'description': 'Optional HTTPS URL to POST a signed `{job_id, kind, status,\nresult_url}` notification to when the job finishes. The RESULT is\nnever pushed â\x80\x94 the notification says where to fetch it. Requires a\nwebhook signing secret on the key; without one the submission is\nrefused rather than delivered unsigned. An agent that can poll does\nnot need this: polling with `get_job` is free.'}}}
输出模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id', 'kind', 'status', 'result_url', 'units_charged', 'next'], 'properties': {'id': {'type': 'string', 'description': 'The job id. Pass it to `get_job` to poll.'}, 'kind': {'type': 'string', 'description': '`optimise`, `replan` or `matrix`.'}, 'next': {'type': 'string', 'description': 'What to do next, in one sentence: poll `get_job`, and how often is\nreasonable.'}, 'status': {'type': 'string', 'description': 'Always `queued` â\x80\x94 no worker has looked at it yet.'}, 'result_url': {'type': 'string', 'description': 'The HTTP URL this job (and its result) can be fetched from. The\nsame URL a webhook carries. `get_job` is the tool that reads it.'}, 'units_charged': {'type': 'integer', 'format': 'int64', 'description': 'Quota units this submission drew. Charged now, handed back in full\nif the job fails.'}}}
输入模式
{'type': 'object', '$defs': {'XY': {'type': 'object', 'required': ['x', 'y'], 'properties': {'x': {'type': 'number', 'format': 'double'}, 'y': {'type': 'number', 'format': 'double'}}, 'description': "One coordinate from the dataset, in the dataset's own units â\x80\x94 NOT\nnecessarily degrees. Named `x`/`y` rather than `lon`/`lat` precisely\nbecause whether they are degrees is the thing in question."}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['declared_crs', 'coordinates'], 'properties': {'coordinates': {'type': 'array', 'items': {'$ref': '#/$defs/XY'}, 'description': "A sample of the dataset's coordinates. A few dozen is plenty; the\ncheck is about ranges and spans, not volume."}, 'declared_crs': {'type': 'string', 'description': 'The CRS the dataset claims, e.g. `"EPSG:4326"`, `"EPSG:32610"`,\n`"EPSG:3857"`, `"EPSG:27700"`.'}}}
输出模式
{'type': 'object', '$defs': {'Extent': {'type': 'object', 'required': ['min_x', 'max_x', 'min_y', 'max_y'], 'properties': {'max_x': {'type': 'number', 'format': 'double'}, 'max_y': {'type': 'number', 'format': 'double'}, 'min_x': {'type': 'number', 'format': 'double'}, 'min_y': {'type': 'number', 'format': 'double'}}}, 'Verdict': {'oneOf': [{'type': 'string', 'const': 'consistent', 'description': 'Coordinates are consistent with the declared CRS.'}, {'type': 'string', 'const': 'suspect', 'description': 'Consistent only under an assumption worth stating (e.g. the values\nfit, but the axis order looks swapped).'}, {'type': 'string', 'const': 'impossible', 'description': 'The declared CRS cannot describe these coordinates at all.'}], 'description': 'How much the declared CRS and the coordinates disagree.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['verdict', 'interpreted_as', 'problems', 'suggestions', 'extent'], 'properties': {'extent': {'$ref': '#/$defs/Extent', 'description': "Observed extent of the sample, in the dataset's own units."}, 'verdict': {'$ref': '#/$defs/Verdict'}, 'problems': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Plain-language findings, most important first. Empty when consistent.'}, 'suggestions': {'type': 'array', 'items': {'type': 'string'}, 'description': 'What the numbers look like, when they do not match the declaration.'}, 'interpreted_as': {'type': 'string', 'description': 'The CRS family the declaration was understood as.'}}}
输入模式
{'type': 'object', '$defs': {'CostingKind': {'oneOf': [{'type': 'string', 'const': 'auto', 'description': 'Standard car costing.'}, {'type': 'string', 'const': 'truck', 'description': 'Truck costing; honours dimensional limits and, when a `truck`\nprofile is supplied, ADR dangerous-goods restrictions.'}, {'type': 'string', 'const': 'bicycle', 'description': 'Bicycle costing; tune it with a `bicycle` options object.'}, {'type': 'string', 'const': 'pedestrian', 'description': 'Pedestrian (walking) costing; tune it with a `pedestrian` options\nobject (lit streets, wheelchair/blind, hiking difficulty).'}, {'type': 'string', 'const': 'motor_scooter', 'description': 'Motor scooter (moped) costing: like auto but prefers lower-speed\nroads and may use ways closed to larger motor vehicles.'}], 'description': 'Costing models exposed by the MCP tools (a deliberate subset of the\nValhalla costing list), serialised in snake_case exactly as Valhalla\nnames them.'}, 'VerifyClaimInput': {'type': 'object', 'required': ['name'], 'properties': {'id': {'type': ['string', 'null'], 'description': 'Caller-chosen id, echoed back on the matching result. Auto-assigned\n("claim-1", â\x80¦) when omitted.'}, 'name': {'type': 'string', 'description': 'The place name as claimed, e.g. "The Eagle and Child".'}, 'locality': {'type': ['string', 'null'], 'description': 'Optional disambiguating context, e.g. "Oxford". Country-level words\n("UK", "England", â\x80¦) are stripped before querying â\x80\x94 they add noise,\nnot signal, to name search.'}, 'sequence': {'type': ['integer', 'null'], 'format': 'int64', 'description': 'Itinerary position. Claims that share increasing `sequence` values\nand both carry `claimed_time` form legs the feasibility pass checks.'}, 'claimed_time': {'type': ['string', 'null'], 'description': 'ISO 8601 timestamp: when the itinerary claims you are at this place.'}}, 'description': 'One place claim for the `verify_places` tool: a place an AI mentioned,\nto be checked for existence and (as part of an itinerary) feasibility.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'text': {'type': ['string', 'null'], 'description': 'Free text to extract place claims from (best-effort heuristic:\nquoted phrases and Title Case runs after "at/in/near/to/from/\nvisiting" â\x80\x94 not NLP or an LLM call, and it does not attempt\nitinerary feasibility since there are no explicit times to anchor\nlegs to). Mutually exclusive with `claims`. Max 8,000 characters.'}, 'claims': {'type': ['array', 'null'], 'items': {'$ref': '#/$defs/VerifyClaimInput'}, 'description': 'Structured claims â\x80\x94 the reliable path, and the only path that\nsupports itinerary feasibility. Mutually exclusive with `text`.\nMax 20 per request.'}, 'costing': {'$ref': '#/$defs/CostingKind', 'default': 'auto', 'description': 'Costing for feasibility legs: "auto" (default), "truck", "bicycle",\n"pedestrian" or "motor_scooter".'}}}
输出模式
{'type': 'object', '$defs': {'VerifyVerdict': {'oneOf': [{'type': 'string', 'const': 'verified', 'description': 'Matched a real, findable place in the index.'}, {'type': 'string', 'const': 'contradicted', 'description': 'A specific, dated, sourced fact contradicts the claim (currently:\nan itinerary leg the routing engine proves cannot be driven in the\nstated time). Never used to assert a business does not exist or\nhas closed.'}, {'type': 'string', 'const': 'unverified', 'description': 'No evidence either way: no confident name match, or the check\ncould not run.'}], 'description': 'The three-state verdict â\x80\x94 see `crate::verify` module docs for why\nthere is no fourth "does not exist" state and never a boolean.'}, 'VerifyEvidence': {'type': 'object', 'required': ['source', 'checked_at', 'detail'], 'properties': {'detail': {'type': 'string', 'description': 'Short factual note, always from a fixed template (see\n`crate::verify`) â\x80\x94 never free-form text that could assert\nnon-existence or closure.'}, 'source': {'type': 'string', 'description': 'Where the evidence came from, e.g. "mapmap-geocode", "mapmap-matrix".'}, 'checked_at': {'type': 'string', 'description': "ISO 8601 timestamp of when this evidence was gathered (a check\ntime, not necessarily the underlying map data's edit date)."}}, 'description': 'One piece of evidence backing a verdict. Always dated.'}, 'VerifyClaimEcho': {'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string'}, 'locality': {'type': ['string', 'null']}, 'sequence': {'type': ['integer', 'null'], 'format': 'int64'}}, 'description': 'The claim as echoed back (a subset of the input, for context).'}, 'VerifyPlaceMatch': {'type': 'object', 'required': ['id', 'name', 'lat', 'lon'], 'properties': {'id': {'type': 'string', 'description': 'Stable identifier when the geocoding backend supplies one,\notherwise a coordinate-based fallback.'}, 'lat': {'type': 'number', 'format': 'double'}, 'lon': {'type': 'number', 'format': 'double'}, 'name': {'type': 'string'}, 'category': {'type': ['string', 'null']}}, 'description': 'The place a claim matched, when one was found.'}, 'VerifyClaimResult': {'type': 'object', 'required': ['id', 'claim', 'verdict', 'evidence'], 'properties': {'id': {'type': 'string'}, 'claim': {'$ref': '#/$defs/VerifyClaimEcho'}, 'match': {'anyOf': [{'$ref': '#/$defs/VerifyPlaceMatch'}, {'type': 'null'}]}, 'verdict': {'$ref': '#/$defs/VerifyVerdict'}, 'evidence': {'type': 'array', 'items': {'$ref': '#/$defs/VerifyEvidence'}}, 'feasibility': {'anyOf': [{'$ref': '#/$defs/VerifyFeasibility'}, {'type': 'null'}]}}, 'description': 'The result for one claim.'}, 'VerifyFeasibility': {'type': 'object', 'required': ['from_id', 'from_name', 'to_id', 'to_name', 'available_minutes', 'status'], 'properties': {'to_id': {'type': 'string'}, 'status': {'$ref': '#/$defs/VerifyFeasibilityStatus'}, 'from_id': {'type': 'string'}, 'to_name': {'type': 'string'}, 'from_name': {'type': 'string'}, 'available_minutes': {'type': 'number', 'format': 'double', 'description': 'Minutes the itinerary claims are available for this leg.'}, 'travel_time_minutes': {'type': ['number', 'null'], 'format': 'double', 'description': 'Minutes the routing engine computed, or null when it could not\ncompute one at all (e.g. beyond its routable distance).'}}, 'description': 'Feasibility of the leg arriving at this stop, when computable.'}, 'VerifyFeasibilityStatus': {'oneOf': [{'enum': ['feasible', 'impossible'], 'type': 'string'}, {'type': 'string', 'const': 'implausible', 'description': 'Tight â\x80\x94 flagged, but not asserted as impossible (not certain enough\nto contradict).'}], 'description': 'Feasibility status of one itinerary leg.'}}, '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['results', 'summary'], 'properties': {'results': {'type': 'array', 'items': {'$ref': '#/$defs/VerifyClaimResult'}}, 'summary': {'type': 'string', 'description': "Always present: a concise plain-text summary alongside the\nstructured `results` â\x80\x94 several MCP clients (notably ChatGPT\nconnectors) drop non-text content blocks, so this must stand on\nits own. This same string is also returned as the tool call's text\ncontent block, not only inside the structured JSON."}}}
近期工具变更
类似的 MCP 服务器
SupplyGraph.AI Data
Provides China-focused location, surrounding-area, company, industry-chain, property, population, retail, and regional business i…
Microburbs Australian Property Data
Provides Australian property, suburb, valuation, sales, rental, zoning, school, risk, geospatial, and census statistics.
gisgp
Provides GIS geocoding, routing, spatial transformations, ArcGIS layer inspection and export, and location due diligence for haza…
ikeytz Einsatzgebiet-Karten
Provides public map and service-area data, geographic search, proximity calculations, area boundaries, business contact details, …
Namaste America
Helps users find Indian-American restaurants, temples, events, businesses, professionals, services, movies, offers, and community…
MolTravel
Searches and provides details for flights, hotels, rental cars, ferries, airports, travel experiences, destinations, country info…
EasyTerritory MCP
Builds, balances, analyzes, and edits sales or service territories, with geocoding, routing, scheduling, map visualization, and G…
Wmata
Provides Washington Metro rail and bus routes, stops, stations, service incidents, route details, and real-time arrival predictio…