npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ol-geom-editor

v1.2.0

Published

An elegant OpenLayers extension for editing geometric shapes.

Readme

ol-geom-editor

An elegant OpenLayers extension for editing geometric shapes. Really easy to use with elegant and intuitive api.

docs and demo

code in github. If helpful, give me a star!

Usage

installation

in node

npm i ol-geom-editor

then

import { GeomEditor } from 'ol-geom-editor'
// import style if need show tool bar
import 'ol-geom-editor/dist/index.css'

const geomEditor = new GeomEditor(olMap) // pass ol map instance

in browser

<!-- import style if need show tool bar -->
<link href="https://unpkg.com/ol-geom-editor/dist/index.css" rel="stylesheet" />
<script src="https://unpkg.com/ol-geom-editor"></script>

then

const { GeomEditor } = window.olGeomEditor

const geomEditor = new GeomEditor(olMap) // pass ol map instance

ol-geom-editor depends on ol, you should import ol firstly!

create a GeomEditor instance

GeomEditor constructor has two params,the second is optional object.

const geomEditor = new GeomEditor(olMapInstance, options)

options has some props:

| prop | type | default | desc | | --------------- | ------------------------------- | --------------------------------------------- | ---------------------------- | | showToolBar | boolean | true | render tool bar or not | | supportFreehand | boolean | true | support freehand draw or not | | drawTypes | Array | ['Point', 'LineString', 'Polygon', 'Circle'] | draw feature types | | actions | Array | ['remove', 'modify', 'translate', 'complete'] | operations on feature | | layerStyle | Style | StyleLike | FlatStyle | openLayers default feature style | default feature style | | selectedStyle | StyleLike | below | feature style is selected |

default selected style:

import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style'

const selectedStyle = new Style({
  fill: new Fill({ color: 'rgba(255,255,255,0.5)' }),
  stroke: new Stroke({
    width: 2.5,
    color: 'red',
  }),
  image: new CircleStyle({
    radius: 5,
    stroke: new Stroke({ width: 2.5, color: 'red' }),
  }),
})

GeomEditor has some methods

| method | desc | | ------------------ | ------------------------------------------------------------ | | addFeatureFromWKT | add feature by wkt | | addFeatureFromJSON | add feature by GeoJSON or GeoJSON Object | | enableDraw | enable draw interaction | | disableDraw | disable draw interaction | | enableFreehand | enable freehand draw | | disableFreehand | disable freehand draw | | select | select features | | deselect | deselect features | | enableSelect | enable select interaction | | disableSelect | disable select interaction | | enableModify | enable modify interaction,modify only one feature once time | | disableModify | disable modify interaction | | enableTranslate | enable translate interaction,can translate multi features | | disableTranslate | disable translate interaction | | removeFeatures | remove features | | removeAllFeatures | remove all features | | completeEdit | complete edit |

add features

You can add feature by WKT or GeoJSON.

addFeatureFromWKT(wkt:string, id?:string, dataProjection?:string | FeatureOptions): Feature | null

| param | type | default | optional | desc | | -------------- | ------------------------ | ------------- | -------- | --------------- | | wkt | string | | required | WKT | | id | string | number | random string | ✅ | id of feature | | dataProjection | string | FeatureOptions | 'EPSG:4326' | ✅ | EPSG projection |

FeatureOptions is a Object :

| prop | type | default | optional | desc | | ----------------- | --------- | ------------------------ | -------- | --------------- | | dataProjection | string | 'EPSG:4326' | ✅ | EPSG projection | | featureProjection | string | 'EPSG:3857' | ✅ | map projection | | style | StyleLike | default ol feature style | ✅ | feature style |

addFeatureFromJSON(JSON:string | geoJSONObj, dataProjection?:string | FeatureOptions): Feature | null

examples

const lineWKT = 'LINESTRING(106.55773424492708 26.68974989181626,106.79592190619702 26.712142565234185)'
geomEditor.addFeatureFromWKT(lineWKT, 'test', 'EPSG:3857')
const pointJSON = JSON.stringify({
  type: 'Feature',
  feature: {
    type: 'Point',
    coordinates: [106.51521987473564, 26.73992541007939],
  },
  properties: null,
  id: 'p2CQqn2lFk',
})
geomEditor.addFeatureFromJSON(pointJSON, 'EPSG:3857')

const circle = {
  type: 'Feature',
  feature: {
    type: 'Polygon',
    coordinates: [
      [
        [106.66476503874576, 26.738016763637745],
        [106.68640913786953, 26.736111276601743],
        [106.70721936319747, 26.730468229538047],
        [106.72639420813869, 26.721305014609847],
        [106.74319560707363, 26.708974566151827],
        [106.75697747969463, 26.69395167555302],
        [106.76721062138205, 26.676814601696407],
        [106.77350297396065, 26.658222705723794],
        [106.77561450846642, 26.63889099150018],
        [106.77346617656862, 26.619562548517454],
        [106.76714262863425, 26.6009799682551],
        [106.75688864282368, 26.58385683635614],
        [106.7430994506547, 26.568850391436218],
        [106.7263053711149, 26.556536388677117],
        [106.70715137023352, 26.54738711575494],
        [106.68637234032467, 26.541753384449873],
        [106.66476503874576, 26.539851168674797],
        [106.64315773716687, 26.541753384449873],
        [106.62237870725802, 26.54738711575494],
        [106.60322470637662, 26.556536388677117],
        [106.58643062683683, 26.568850391436218],
        [106.57264143466786, 26.58385683635614],
        [106.5623874488573, 26.6009799682551],
        [106.55606390092291, 26.619562548517454],
        [106.55391556902511, 26.63889099150018],
        [106.55602710353088, 26.658222705723794],
        [106.56231945610948, 26.676814601696407],
        [106.5725525977969, 26.69395167555302],
        [106.5863344704179, 26.708974566151827],
        [106.60313586935284, 26.721305014609847],
        [106.62231071429407, 26.730468229538047],
        [106.64312093962201, 26.736111276601743],
        [106.66476503874576, 26.738016763637745],
      ],
    ],
  },
  properties: {
    geometryType: 'circle',
    center3857: [11873867.329697348, 3078433.290578392],
    center: [106.66476503874576, 26.638933966156273],
    radius: 11017.51961571537,
  },
}
geomEditor.addFeatureFromJSON(circle, { featureProjection: 'EPSG:3857' })

draw feature

enableDraw(type: GeomType, style?: Style | StyleLike | FlatStyle)

| param | type | default | optional | desc | | ----- | ------------------------------- | ----------------------- | -------- | ----------------- | | type | string | | required | draw feature type | | style | Style | StyleLike | FlatStyle | ol default sketch style | ✅ | sketch style |

type pass None to draw nothing.

disableDraw() -- disable draw interaction.

enableFreehand() -- enable freehand draw interaction.

disableFreehand() -- disable freehand draw interaction.

select feature

select(id: Id | Id[], options?: SelectOptions): Feature[]

select some features.

| param | type | default | optional | desc | | ------- | -------------------- | ------- | -------- | ---------- | | id | string | string[] | | required | feature id | | options | SelectOptions Object | below | ✅ | |

options is a object , props :

| prop | type | default | optional | desc | | ------------- | -------------------------------- | ------- | -------- | ---------------------------- | | selectedStyle | Style | StyleLike | FlatStyle | below | ✅ | selected style | | eachFeature | function | | ✅ | traverse features | | fit | boolean | viewFitOptions Object | true | ✅ | fit selected feature to view |

default selected style:

import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style'

const highlightStyle = new Style({
  fill: new Fill({ color: 'rgba(255,255,255,0.5)' }),
  stroke: new Stroke({
    width: 2.5,
    color: 'red',
  }),
  image: new CircleStyle({
    radius: 5,
    stroke: new Stroke({ width: 2.5, color: 'red' }),
  }),
})

eachFeature return truthy value, will stop traverse.

examples

const fillColor = 'rgba(218,228,194,0.5)'
const strokeColor = 'rgba(255, 204, 51, 0.9)'

const features = geomEditor.select(['line1', 'p2CQqn2lFk'], {
  selectedStyle: new Style({
    fill: new Fill({
      color: fillColor,
    }),
    stroke: new Stroke({
      color: strokeColor,
      width: 4,
    }),
    image: new CircleStyle({
      radius: 7,
      fill: new Fill({ color: fillColor }),
      stroke: new Stroke({ color: strokeColor, width: 2 }),
    }),
  }),
  eachFeature: (feat: Feature, index: number) => {
    console.log({ feat })
    if (index === 0) return true
  },
})

deselect feature

deselect(id: Id | Id[], options?: DeselectOptions)

options is a object, props:

| prop | type | default | optional | desc | | --------------- | ------------------------------- | ------- | -------- | ----------------- | | deselectedStyle | Style | StyleLike | FlatStyle | | ✅ | deselected style | | eachFeature | function | | ✅ | traverse features |

examples

geomEditor.deselect(['line1', 'p2CQqn2lFk'])

select interaction

enableSelect(options?: SelectModeOptions) -- enable select interaction

options is a object, set select mode

| prop | type | default | optional | desc | | ------ | ------- | ------- | -------- | --------------------------- | | multi | boolean | true | ✅ | select multiple features | | single | boolean | false | ✅ | only can select one feature |

translate interaction support multi mode default, modify interaction support single mode only.

disableSelect() -- disable select interaction

modify feature

enableModify(style?: StyleLike | FlatStyle) -- enable modify interaction

disableModify() -- disable modify interaction

translate features

enableTranslate() -- enable translate interaction

disableTranslate() -- disable translate interaction

translate interaction support multi mode default, modify interaction support single mode only.

remove feature

removeFeatures(id?: Id | Id[]) - remove features

| param | type | default | optional | desc | | ----- | ------------------ | ------- | -------- | ---------- | | id | string | string[] | | ✅ | feature id |

if don't pass id, will remove all selected features.

removeAllFeatures():Promise<boolean> -- remove all features

examples

geomEditor.removeFeatures() // remove all selected features
geomEditor.removeFeatures('test') // remove one feature by id
geomEditor.removeFeatures(['test1', 'test2']) // remove features by id array
geomEditor.removeAllFeatures().then(success => {
  console.log({ success })
})

complete edit

completeEdit() -- complete edit

All style of features will reset original status.

events

GeomEditor trigger some events when interact with features.

GeomEditor trigger custom events and trigger ol interaction event.

Custom events have a better name over ol, like drawBegin is better than drawbegin in ol event style name in my opinion.

All events includes soma data you can use directly and align with the original event.

event list:

| event | when emit | | ----------------- | ------------------------- | | select | select feature | | deselect | deselect feature | | drawBegin | begin draw feature | | drawComplete | finish draw feature | | modifyBegin | begin modify feature | | modifyComplete | finish modify feature | | translateBegin | begin translate features | | translateComplete | finish translate features | | remove | remove feature | | complete | complete edit feature |

The original event will also be triggered during interacting.

Recommend use GeomEditor events, because it has converted feature to WKT and GeoJSON and include data in original event. More convenient!

The order in which the events are triggered is as follows:

# draw geometry
drawstart # original event
↓
drawBegin # recommend, it is more convenient
↓
drawend # original event
↓ # NOTE
drawComplete # recommend! You can set style when it emit

# modify geometry
select
↓
modifystart
↓
modifyBegin
↓
modifyend
↓
modifyComplete
↓ # NOTE
deselect # click on the non feature area
# set style when deselect

# translate geometry
select
↓
translatestart
↓
translateBegin
↓
translateend
↓
translateComplete # recommend!
↓ # NOTE
deselect # click on the non feature area
# set style when deselect

examples

// original event
geomEditor.on('modifystart', event => {
  console.log({ event })
})
// original event
geomEditor.on('modifyend', event => {
  console.log({ event })
})
// NOTE GeomEditor event, you can get data including original event
geomEditor.on('modifyBegin', event => {
  console.log({ event })
})
geomEditor.on('modifyComplete', event => {
  console.log({ event })
})
geomEditor.on('remove', event => {
  console.log({ event })
})
geomEditor.on('complete', event => {
  console.log({ event })
})

Open the console panel on this page, operate the demo, and check the events.

🤝 Contributing

Contributions are always welcome! Feel free to open an issue, suggest a feature, or submit a pull request.

⭐ Support

If you find this project helpful, please consider giving it a star ⭐ — it helps others discover the project and keeps us motivated! give me a star