-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Fixed loop way handling - Added unit tests - Added GitHub actions
- Loading branch information
1 parent
f948988
commit f3c868a
Showing
21 changed files
with
3,013 additions
and
654 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
name: Pull Request Check | ||
on: | ||
pull_request: | ||
branches: | ||
- dev/* | ||
- master | ||
jobs: | ||
unit-tests: | ||
name: Unit Tests | ||
uses: ./.github/workflows/unit-tests.yml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: Publish | ||
on: | ||
push: | ||
branches: master | ||
jobs: | ||
unit-tests: | ||
name: Unit Tests | ||
uses: ./.github/workflows/unit-tests.yml | ||
publish: | ||
name: Publish | ||
needs: unit-tests | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
with: | ||
ref: ${{ github.ref }} | ||
- name: Setup Node | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 20 | ||
registry-url: https://registry.npmjs.org/ | ||
- name: Get package.json | ||
id: get-package | ||
run: echo PACKAGE=$(cat ./package.json) >> $GITHUB_OUTPUT | ||
- name: Get package version | ||
id: get-package-version | ||
run: echo VERSION="${{ fromJson(steps.get-package.outputs.PACKAGE).version }}" >> $GITHUB_OUTPUT | ||
- name: Install | ||
run: npm ci | ||
- name: Build | ||
run: npm run build | ||
- name: Publish | ||
run: npm publish | ||
env: | ||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
- name: Tag | ||
run: | | ||
git config --global user.name "ponlawat-w" | ||
git config --global user.email "[email protected]" | ||
git tag -fa ${{ steps.get-package-version.outputs.VERSION }} | ||
git push --force origin ${{ steps.get-package-version.outputs.VERSION }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
name: Unit Tests | ||
on: workflow_call | ||
jobs: | ||
unit-tests: | ||
name: Unit Tests | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
with: | ||
ref: ${{ github.ref }} | ||
- name: Setup Node | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 20 | ||
- name: Install | ||
run: npm ci | ||
- name: Test | ||
run: npm run test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,186 +4,112 @@ | |
|
||
## Instructions | ||
|
||
This extension is an interaction type in OpenLayers which requires a few setup steps: | ||
|
||
### 1. Vector layer for OSM ways | ||
```bash | ||
npm install ol-osmwaysnap | ||
``` | ||
|
||
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. | ||
Create an instance of class `OSMWaySnap` and add it to map. (Default snapping to OSM roads) | ||
|
||
```ts | ||
import VectorLayer from 'ol/layer/Vector'; | ||
import { OSMWaySource } from 'ol-osmwaysnap'; | ||
import VectorSource from 'ol/source/Vector'; | ||
import { OSMWaySnap } from 'ol-osmwaysnap'; | ||
|
||
const targetLayer = new VectorLayer<VectorSource<Feature<LineString>>>({ | ||
source: new VectorSource<Feature<LineString>>() | ||
}); | ||
map.addLayer(targetLayer); | ||
|
||
// 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() | ||
const interaction = new OSMWaySnap({ | ||
source: targetLayer.getSource(), | ||
maximumResolution: 5, | ||
fetchBufferSize: 250, | ||
overpassEndpointURL: 'https://...' // Choose one instance from https://wiki.openstreetmap.org/wiki/Overpass_API#Public_Overpass_API_instances | ||
}); | ||
map.addInteraction(interaction); | ||
``` | ||
|
||
Or specify a custom OverpassQL for different way elements, for example to railways. | ||
|
||
```ts | ||
// 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() | ||
const interaction = new OSMWaySnap({ | ||
source: targetLayer.getSource(), | ||
maximumResolution: 5, | ||
fetchBufferSize: 250, | ||
overpassQuery: '(way["railway"];>;);', | ||
overpassEndpointURL: 'https://...' // Choose one instance from https://wiki.openstreetmap.org/wiki/Overpass_API#Public_Overpass_API_instances | ||
}); | ||
map.addInteraction(interaction); | ||
``` | ||
|
||
### 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. | ||
Or use a custom vector source (not OSM) for snapping. | ||
|
||
```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() | ||
})); | ||
const interaction = new OSMWaySnap({ | ||
source: targetLayer.getSource(), | ||
waySource: someVectorSource, | ||
maximumResolution: 5, | ||
fetchBufferSize: 250 | ||
}); | ||
map.addInteraction(interaction); | ||
``` | ||
|
||
## Constructor Options | ||
|
||
- `autoFocus?: boolean` - True to automatically fit map view to next candidantes. (default: true) | ||
- `focusPadding?: number` - Used with autoFocus, specify number to add padding to view fitting. (default: 50 !PROJECTION SENSITIVE!) | ||
- `sketchStyle?: StyleLike` - Style of sketch features (default is predefined, overwrite if necessary) | ||
- `source: VectorSource<Feature<LineString>>` - Target source of edition | ||
- `waySource?: VectorSource<Feature<LineString>>` - Ways source for snapping (default to a new instance of OSMOverpassWaySource) | ||
- `createAndAddWayLayer?: boolean` - Create a new way layer from way source (if provided) and add to map (default: true) | ||
- `wrapX?: boolean` - WrapX | ||
|
||
If `waySource` is not provided, `OSMOverpass` will be used as source for snapping, so the constructor options for `OSMWaySnap` will be extended to include [thoses options from `OSMOverpassSourceBase`](https://github.com/ponlawat-w/ol-osmoverpass#constructor-options). | ||
|
||
## Examples | ||
|
||
[Full page example using the library from CDN](./examples/index.html) | ||
|
||
### Using as module | ||
|
||
```ts | ||
import Map from 'ol/Map'; | ||
import View from 'ol/View'; | ||
import { Map, View } from 'ol'; | ||
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 VectorSource from 'ol/source/Vector'; | ||
import Feature from 'ol/Feature'; | ||
import { OSMWaySource, OSMWaySnap } from 'ol-osmwaysnap'; | ||
import LineString from 'ol/geom/LineString'; | ||
import 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 targetLayer = new VectorLayer<VectorSource<Feature<LineString>>>({ | ||
source: new VectorSource() | ||
}); | ||
|
||
const targetFeaturesLayer = new VectorLayer<VectorSource<Feature<LineString>>>({ | ||
source: new VectorSource<Feature<LineString>>() | ||
const view = new View({ | ||
center: [11018989, 2130015], | ||
zoom: 16 | ||
}); | ||
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 | ||
}) | ||
layers: [basemap, targetLayer], | ||
view | ||
}); | ||
|
||
map.addInteraction(new OSMWaySnap({ | ||
source: targetFeaturesLayer.getSource()!, | ||
waySource: osmWayLayer.getSource()! | ||
})); | ||
map.addInteraction(new Snap({ | ||
source: osmWayLayer.getSource()! | ||
})); | ||
const interaction = new OSMWaySnap({ | ||
source: targetLayer.getSource(), | ||
maximumResolution: 5, | ||
fetchBufferSize: 250, | ||
overpassEndpointURL: 'https://...' // Choose one instance from https://wiki.openstreetmap.org/wiki/Overpass_API#Public_Overpass_API_instances | ||
}); | ||
mao.addInteraction(interaction); | ||
``` | ||
|
||
### 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` | ||
[HTML Example](./examples/index.html) | ||
|
||
--- |
Oops, something went wrong.