Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.1.0 #1

Merged
merged 3 commits into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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