Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ponlawat-w committed Nov 22, 2023
0 parents commit 60c0db3
Show file tree
Hide file tree
Showing 13 changed files with 3,855 additions and 0 deletions.
165 changes: 165 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Created by https://www.toptal.com/developers/gitignore/api/node,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=node,visualstudiocode

### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

### Node Patch ###
# Serverless Webpack directories
.webpack/

# Optional stylelint cache

# SvelteKit build / generate output
.svelte-kit

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Local History for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide

# End of https://www.toptal.com/developers/gitignore/api/node,visualstudiocode

examples/*
189 changes: 189 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# OpenLayers OSMWaySnap

[OpenLayers](https://openlayers.org/) extension for drawing line string with snapping to way elements from [OpenStreetMap](https://wiki.openstreetmap.org/wiki/About_OpenStreetMap) using [OverpassAPI](https://wiki.openstreetmap.org/wiki/Overpass_API).

## Instructions

This extension is an interaction type in OpenLayers which requires a few setup steps:

### 1. Vector layer for OSM ways

To begin with, it is necessary to setup a vector layer that contains OSM ways. Using builtin `OSMWaySource` class that automatically fetches ways from OpenStreetMap using OverpassAPI, or alternatively, it can also be used with other linestring feature layer.

```ts
import VectorLayer from 'ol/layer/Vector';
import { OSMWaySource } from 'ol-osmwaysnap';

// Default: Snap to roads (OSM highway)
const osmWayLayer = new VectorLayer({
source: new OSMWaySource({
maximumResolution: 5,
fetchBufferSize: 250,
overpassEndpointURL: 'https://...' // Choose one instance from https://wiki.openstreetmap.org/wiki/Overpass_API#Public_Overpass_API_instances
}),
style: OSMWaySource.getDefaultStyle()
});

// Snap to railways
const osmWayLayer = new VectorLayer({
source: new OSMWaySource({
maximumResolution: 5,
fetchBufferSize: 250,
overpassQuery: '(way["railway"];>;);',
overpassEndpointURL: 'https://...' // Choose one instance from https://wiki.openstreetmap.org/wiki/Overpass_API#Public_Overpass_API_instances
}),
style: OSMWaySource.getDefaultStyle()
});
```

### 2. Add interactions

There are at least 2 interactions to be added in order for the extension to work 1) `OSMWaySnap` and 2) `Snap` interaction from default OpenLayers interactions.

```ts
import { OSMWaySnap } from 'ol-osmwaysnap';
import Snap from 'ol/interaction/Snap';

map.addInteraction(new OSMWaySnap({
source: targetFeatureLayer.getSource(),
waySource: osmWayLayer.getSource()
}));
map.addInteraction(new Snap({
source: osmWayLayer.getSource()
}));
```

## Examples

### Using as module

```ts
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import OSM from 'ol/source/OSM';
import Snap from 'ol/interaction/Snap';
import LineString from 'ol/geom/LineString';
import Feature from 'ol/Feature';
import { OSMWaySource, OSMWaySnap } from 'ol-osmwaysnap';

const basemap = new TileLayer({ source: new OSM() });

const osmWaySource = new OSMWaySource({
maximumResolution: 5,
fetchBufferSize: 250,
overpassEndpointURL: 'https://...' // Choose one instance from https://wiki.openstreetmap.org/wiki/Overpass_API#Public_Overpass_API_instances
});

const targetFeaturesLayer = new VectorLayer<VectorSource<Feature<LineString>>>({
source: new VectorSource<Feature<LineString>>()
});
const osmWayLayer = new VectorLayer({source: osmWaySource, style: OSMWaySource.getDefaultStyle()});

const map = new Map({
target: 'map',
layers: [basemap, osmWayLayer, targetFeaturesLayer],
view: new View({
center: [11018989, 2130015],
zoom: 16
})
});

map.addInteraction(new OSMWaySnap({
source: targetFeaturesLayer.getSource()!,
waySource: osmWayLayer.getSource()!
}));
map.addInteraction(new Snap({
source: osmWayLayer.getSource()!
}));
```

### Using as CDN

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/ol.css">
<style>
#map {
width: 100%;
height: 90vh;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="status"></div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ol.js"></script>
<script src="https://www.unpkg.com/ol-osmwaysnap/dist/webpack/index.js"></script>
<script lang="js">
const basemap = new ol.layer.Tile({ source: new ol.source.OSM() });
const targetFeaturesLayer = new ol.layer.Vector({
source: new ol.source.Vector()
});
const osmWayLayer = new ol.layer.Vector({
source: new OSMWaySnap.OSMWaySource({
maximumResolution: 5,
fetchBufferSize: 250,
overpassEndpointURL: 'https://...' // Choose one instance from https://wiki.openstreetmap.org/wiki/Overpass_API#Public_Overpass_API_instances
}),
style: OSMWaySnap.OSMWaySource.getDefaultStyle()
});
osmWayLayer.getSource().on('featuresloadstart', () => {
document.getElementById('status').innerHTML = 'Loading…';
});
osmWayLayer.getSource().on('featuresloadend', () => {
document.getElementById('status').innerHTML = '';
});
osmWayLayer.getSource().on('featuresloaderror', () => {
document.getElementById('status').innerHTML = 'ERROR';
});
const map = new ol.Map({
target: 'map',
layers: [basemap, osmWayLayer, targetFeaturesLayer],
view: new ol.View({
center: [11018989, 2130015],
zoom: 16
})
});
map.addInteraction(new OSMWaySnap.OSMWaySnap({
source: targetFeaturesLayer.getSource(),
waySource: osmWayLayer.getSource()
}));
map.addInteraction(new ol.interaction.Snap({
source: osmWayLayer.getSource()
}));
</script>
</body>
</html>
```

## Options

### `OSMWaySource` constructor options

- `cachedFeaturesCount: number` - The number of features to store before getting cleared. This is to prevent heavy memory consumption.
- `fetchBufferSize: number` - Buffer size to apply to the extent of fetching OverpassAPI. This is to prevent excessive call despite slight map view panning. **USE THE SAME PROJECTION WITH THE LAYER**.
- `maximumResolution: number` - Map view resolution to start fetching OverpassAPI. This is to prevent fetching elements in too big extent. **USE THE SAME PROJECTION WITH THE LAYER**
- `overpassEndpointURL?: string` - OverpassAPI endpoint URL (https://wiki.openstreetmap.org/wiki/Overpass_API#Public_Overpass_API_instances)
- `overpassQuery: string` - OverpassQL statement for ways to fetch, default to OSM highways.

### `OSMWaySnap` constructor options

- `autoFocus?: boolean` - True to automatically fit map view to next candidantes.
- `focusPadding?: number` - Used with autoFocus, specify number to add padding to view fitting.
- `sketchStyle?: StyleLike` - Style of sketch features.
- `source: VectorSource<Feature<LineString>>` - Target source of edition.
- `waySource: VectorSource<Feature<LineString>>` - Source to OSMWays for snapping.
- `wrapX?: boolean`

---
Loading

0 comments on commit 60c0db3

Please sign in to comment.