Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Zero-dependency TypeScript package for working with openstreetmap data via the Overpass API

License

NotificationsYou must be signed in to change notification settings

vineyardbovines/openstreetmap-api

Repository files navigation

Zero-dependency TypeScript package for working withopenstreetmap data via theOverpass API.

Features

  • 🏗️Query Builder - Build complex Overpass queries with a type-safe interface
  • 🌐API Service - Handle overpass API requests with automatic retries and fallbacks
  • 🗺️GeoJSON Support - Direct conversion to GeoJSON formats
Table of Contents

Installation

With your package manager of choice:

npm install @vineyardbovines/openstreetmapyarn add @vineyardbovines/openstreetmappnpm add @vineyardbovines/openstreetmapbun add @vineyardbovines/openstreetmap

Quick Start

import{OverpassQueryBuilder,overpass,OverpassOutput}from'@vineyardbovines/openstreetmap';constquery=newOverpassQueryBuilder().setTimeout(25).node().withTags([{key:'amenity',operator:'=',value:'restaurant'},{key:'cuisine',operator:'=',value:'italian'}]).bbox([-0.1,51.5,0.0,51.6]).out('qt',true).build();constresponse=awaitoverpass(query,{output:OverpassOutput.GeoJSON,verbose:true});

API Service

Basic usage:

import{overpass,OverpassOutput}from'@vineyardbovines/openstreetmap-api';// Simple queryconstresponse=awaitoverpass('[out:json];node["amenity"="cafe"](51.5,-0.1,51.6,0.0);out;');// With GeoJSON outputconstgeojson=awaitoverpass('[out:json];node["amenity"="cafe"](51.5,-0.1,51.6,0.0);out;',{output:OverpassOutput.GeoJSON});

Configuration Options

interfaceOverpassFetchOptions<TextendsOverpassOutput>{endpoint?:string;// Primary endpoint to usefallbackEndpoints?:string[];// Custom fallback endpointsverbose?:boolean;// Enable detailed logginguserAgent?:string;// Custom User-Agent headeroutput?:T;// Output formatretry?:{maxRetries:number;// Maximum retry attemptsinitialDelay:number;// Initial delay in msmaxDelay:number;// Maximum delay in msbackoff:number;// Backoff multiplier};}

Default retry options:

{maxRetries:3,initialDelay:1000,// 1 secondmaxDelay:10000,// 10 secondsbackoff:2// Exponential backoff multiplier}

Output Formats

The service supports multiple output formats through theOverpassOutput enum:

enumOverpassOutput{Raw='raw',// Raw Overpass JSON responseGeoJSON='geojson',// Converted to GeoJSON formatParsed='parsed',// Parsed element tagsParsedGeoJSON='parsedgeojson'// Parsed tags in GeoJSON format}

'Parsed' converts string values to primitive values (string, number, boolean) when appropriate, i.e.

{building:"yes",level:"1"}// becomes{building:true,level:1}

Error Handling

The API service usesfetch, so error handling is the same. There is a custom overpass error class to handle specific statuses.

try{constresponse=awaitoverpass(query,{verbose:true,retry:{maxRetries:5,initialDelay:2000}});}catch(error){if(errorinstanceofOverpassError){// Handle Overpass-specific errorsconsole.error('Overpass error:',error.message);}else{// Handle other errorsconsole.error('Request failed:',error);}}

Settingverbose: true enables console logging for development, and will log:

  • Retry attempts
  • Endpoint switches
  • Error messages
  • Delay durations

Fallback Endpoints

The service automatically handles fallback endpoints based on the primary endpoint:

  • Main endpoints: Falls back to MainAlt1 → MainAlt2
  • Kumi endpoints: Falls back to KumiAlt1 → KumiAlt2 → KumiAlt3
  • Others: Falls back to Main → Kumi → France

Custom fallback sequences can be specified:

constresponse=awaitoverpass(query,{endpoint:OverpassEndpoint.Main,fallbackEndpoints:['CustomAlt1','CustomAlt2']});

Query Builder

Basic usage:

import{OverpassQueryBuilder}from'overpass-query-builder';// Create a new builder instanceconstbuilder=newOverpassQueryBuilder();// Build a simple query for restaurantsconstquery=builder.node().hasTag('amenity','restaurant').out('qt').build();

Element types:

  • node(): Query nodes
  • way(): Query ways
  • relation(): Query relations
// Query specific node by IDbuilder.node('(123)');// Query multiple nodesbuilder.node('(123,456,789)');

Tag Matching

// Check tag existencebuilder.hasTag('amenity');// Match exact valuebuilder.hasTag('amenity','restaurant');builder.withTag({key:'name',operator:'~',value:'cafe.*',regexModifier:'case_insensitive'});// Numeric comparisonsbuilder.withTag({key:'lanes',operator:'>=',value:2});

Partial Key Matching

Useful for finding elements where the key contains, starts with, or ends with a specific string:

// Match any key containing 'toilet'builder.withPartialKey('toilet','contains');// Combined exact and partial matchingbuilder.withTags([{key:'amenity',operator:'=',value:'toilets'},{key:'toilets',keyMatchStrategy:'contains'}],false);// false for OR logic

Geographic Filters

Bounding Box

Supports both GeoJSON format and object format:

// GeoJSON format [west, south, east, north]builder.bbox([-0.1,51.5,0.0,51.6]);// Object formatbuilder.bbox({south:51.5,west:-0.1,north:51.6,east:0.0});

Around

// Search within radius (meters) of a pointbuilder.around(100,51.5,-0.1);

Output Formats

// Default outputbuilder.out();// Skeleton output (minimal data)builder.out('skel');// Quick output with tagsbuilder.out('qt');// Include bodybuilder.out('qt',true);

Complex Queries

// Find Italian restaurants in London with outdoor seatingconstrestaurantQuery=newOverpassQueryBuilder().setTimeout(30).node().withTags([{key:'amenity',operator:'=',value:'restaurant'},{key:'cuisine',operator:'=',value:'italian'},{key:'outdoor_seating',operator:'=',value:'yes'}]).bbox([-0.1,51.5,0.0,51.6]).out('qt',true).build();// Find all toilet facilities including partial matchesconsttoiletQuery=newOverpassQueryBuilder().node().withTags([{key:'amenity',operator:'=',value:'toilets'},{key:'toilets',keyMatchStrategy:'contains'}],false).around(100,51.5,-0.1).out('qt',true).build();

Configuration

You can set global options when creating the builder:

constbuilder=newOverpassQueryBuilder({timeout:30,// secondsmaxsize:536870912// bytes (512MB)});// Or update them laterbuilder.setTimeout(25);builder.setMaxSize(1000000);

Error Handling

The builder methods use method chaining and returnthis, allowing you to catch any errors at the build stage:

try{constquery=builder.node().hasTag('amenity','restaurant').build();}catch(error){console.error('Failed to build query:',error);}

Recipes

Examples using the query builder with the API service.

Find Cafes Within Walking Distance

import{OverpassQueryBuilder,overpass,OverpassOutput}from'@vineyardbovines/openstreetmap-api';asyncfunctionfindNearbyCafes(lat:number,lon:number,radius:number=500){constquery=newOverpassQueryBuilder().setTimeout(30).node().withTags([{key:'amenity',operator:'=',value:'cafe'},{key:'opening_hours',existence:'exists'}// Only get cafes with opening hours]).around(radius,lat,lon).out('qt',true).build();returnawaitoverpass(query,{output:OverpassOutput.ParsedGeoJSON,retry:{maxRetries:3,initialDelay:1000}});}// Usageconstcafes=awaitfindNearbyCafes(51.5074,-0.1278);

Find Parks with Playgrounds and Water Features

asyncfunctionfindEquippedParks(bbox:[number,number,number,number]){constquery=newOverpassQueryBuilder().way().withTags([{key:'leisure',operator:'=',value:'park'},{key:'playground',existence:'exists'}]).bbox(bbox).out('qt').recurse('down')// Get all nodes making up the ways.out('qt').build();returnawaitoverpass(query,{output:OverpassOutput.ParsedGeoJSON});}

Find Cycle-Friendly Routes

asyncfunctionfindCycleRoutes(start:[number,number],radius:number){constquery=newOverpassQueryBuilder().way().withTags([{key:'highway',existence:'exists'},{key:'bicycle',operator:'~',value:'yes|designated',regexModifier:'case_insensitive'}]).around(radius,start[0],start[1]).out('body').recurse('down').out('skel').build();returnawaitoverpass(query,{output:OverpassOutput.ParsedGeoJSON});}

Find Historical Buildings by Age

asyncfunctionfindHistoricalBuildings(area:[number,number,number,number],minYear:number){constquery=newOverpassQueryBuilder().way().withTags([{key:'building',existence:'exists'},{key:'historic',existence:'exists'},{key:'start_date',operator:'<',value:minYear.toString()}]).bbox(area).out('body').build();returnawaitoverpass(query,{output:OverpassOutput.ParsedGeoJSON});}

Count Amenities by Type

asyncfunctioncountAmenitiesByType(bbox:[number,number,number,number]){constquery=newOverpassQueryBuilder().node().withTag({key:'amenity',existence:'exists'}).bbox(bbox).out('qt',true).build();constresponse=awaitoverpass(query,{output:OverpassOutput.Parsed});// Group by amenity typereturnresponse.elements.reduce((acc,element)=>{consttype=element.tags?.amenity;if(type){acc[type]=(acc[type]||0)+1;}returnacc;},{}asRecord<string,number>);}

About

Zero-dependency TypeScript package for working with openstreetmap data via the Overpass API

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors2

  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp