Skip to content

Commit

Permalink
0.1.0 (#1)
Browse files Browse the repository at this point in the history
- Fixed loop way handling
- Added unit tests
- Added GitHub actions
  • Loading branch information
ponlawat-w authored Nov 25, 2023
1 parent f948988 commit f3c868a
Show file tree
Hide file tree
Showing 21 changed files with 3,013 additions and 654 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/pr.yml
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
42 changes: 42 additions & 0 deletions .github/workflows/publish.yml
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 }}
19 changes: 19 additions & 0 deletions .github/workflows/unit-tests.yml
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
212 changes: 69 additions & 143 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

---
Loading

0 comments on commit f3c868a

Please sign in to comment.