Map GeoJSON geometry editor. See Demo
Supported features:
LineString
Polygon
MultiLineString
MultiPolygon
-
GeometryCollection
coming someday.
npm install geoditor
yarn add geoditor
Geoditor is initialising with 2 types of modules.
- Controller (required) to render features onto map. Provides API between Geoditor core and map implementation. Currently only MapBox is supported.
- Tools (optional) to edit data. If no tools is passed, default set will be used.
import { Geoditor, PenTool, MoveTool } from "geoditor";
const geoditor = new Geoditor({
controller: {...},
tools: {
pen: new PenTool(),
move: new MoveTool(),
hand: new HandTool(),
delete: new DeleteTool(),
}
});
Any tool can be reused under different names with different settings (if supported). For example, multiple instances of Pen tool to create only lineal or polygonal geometries tools:
tools: {
line: new PenTool({ types: ["LineString", "MultiLineString"]}),
polygon: new PenTool({ types: ["Polygon", "MultiPolygon"] }),
}
Using with MapBox
import { Geoditor, MapboxController, PenTool, MoveTool } from "geoditor";
import { MapBox } from "mapbox-gl";
const mapbox = new MapBox({
/* options */
...
});
const geoditor = new Geoditor({
controller: new MapboxController(mapbox),
...
});
All options and optional. Use it only if you want to change rendering style or interactivity.
Both config
and layerStyles
are used for visual representation of the layers, and
area
is used to define areas of interactivity.
More info
type Options = {
config?: LayerConfig;
layerStyles?: Omit<mapboxgl.Layer, "id">[];
area?: {
points?: number | false;
lines?: number | false;
planes?: false;
};
}
If layerStyles
is provided config
will be ignored. Any layer type can be used but:
-
FillLayer
types are used to renderplanes
-
LineLayer
types are used to renderlines
. - Every other layer will be used for rendering
points
.
Use the following feature-states to distinct features in different states:
disabled
, hover
or active
Config is used to generate mapbox.Layers for planes
, lines
and points
separately.
type LayerConfig = {
points: {
type: mapboxgl.Layer["type"];
paint: {
// Feature states representation
default: mapboxgl.AnyPaint,
/** Keep in mind that any paint properties key
* missing in "default" will be ignored */
hover: mapboxgl.AnyPaint,
active: mapboxgl.AnyPaint,
disabled: mapboxgl.AnyPaint
}
layout?: mapboxgl.AnyLayout;
},
// lines and planes configs are the same
lines: {...},
planes: {...}
}
You can access or set data at any given moment. LineString
, Polygon
, MultiLineString
, and MultiPolygon
are supported. Rest won't be deleted or changed in any way but will be ignored in render.
// Get features
const features = geoditor.data;
// Set features
geoditor.data = [
{
type: "Feature",
geometry: {
type: "LineString",
coordinates: [[35.00, 50.00], [35.00, 51.00]],
},
},
]
Access or set selected features indices.
// Get selection
const selected: number[] = geoditor.selected;
// Set single/multiple selection
geoditor.selected = [0];
geoditor.selected = [0, 1, 2];
// Select feature's shape
geoditor.selected = [[0]]
geoditor.selected = [[1, 0]]
// Remove selection
geoditor.selected = [];
Fires when Controller is initialized and ready. You can start working with Geoditor.
geoditor.on("load", () => {
/** EXAMPLE:
Starts pen tool. Feature properties can be passed as argument. */
geoditor.tools.pen({ color: "red" });
});
Fires on data change. Array of GeoJSON features is passed into listener. If you had provided some data to Geoditor before all feature properties will be kept.
geoditor.on("change", (data: GeoJSON.Feature[]) => {
// data === geoditor.data
console.log(data, geoditor.data);
/** EXAMPLE:
Switch to "move" tool after drawing */
if (geoditor.tool === "pen") geoditor.tools.move();
});
Fires on feature selection change. Array of selected indices is passed into listener.
geoditor.on("select", (selected: number[]) => {
/**
selected !== geoditor.selected
selected: number[] includes only indices of selected features
geoditor.selected: (number | number[])[] returns selected shapes of features (if any)
*/
console.log(selected, geoditor.selected);
});
Fires on tool switch. Current tool name is passed into listener.
geoditor.on("tool", (tool?: string) => {
/**
tool === geoditor.tool
*/
console.log(tool, geoditor.tool);
});
Fires every render. Can be used for simultaneous features update in a different source/map.
import * as mapboxgl from "mapbox-gl";
geoditor.on("render", (data: GeoJSON.Feature[]) => {
// data !== geoditor.data
console.log(data, geoditor.data);
// EXAMPLE:
mapboxgl.getSource("some-source")?.setData(data)
});
Draws geometry. Different tools can be initialised with PenTool using different options:
Property | Description | Type | Default |
---|---|---|---|
types | Types of created features |
LineString | Polygon | MultiLineString | MultiPolygon | Array<"LineString" | "Polygon" | "MultiLineString" | "MultiPolygon">
|
["LineString", "Polygon", "MultiLineString", "MultiPolygon"] |
append | Extends line geometry and converts single geometry to multi if corresponding types are provided. |
boolean | shift | alt | ctrl | meta
|
true |
subtract | Subtract shapes from polygonal features. |
boolean | shift | alt | ctrl | meta
|
true |
create | Add new features. |
boolean | shift | alt | ctrl | meta
|
true |
filter | Filter predicate to exclude specific geometries from interaction and render |
|
() => true |
const PolygonTool = new PenTool({
types: ["Polygon", "MultiPolygon"],
append: "shift",
subtract: "alt",
});
const AppendTool = new PenTool({
create: false,
subtract: false,
});
Moves and modifies geometry. You can provide key modifier to enable editing point mode. If no modifier is provided this mode enables by double click.
Property | Description | Type | Default |
---|---|---|---|
modify | Sets modifier key to activate point editing mode. If true second click enables this mode |
boolean | dblclick | alt | ctrl | meta
|
true |
filter | Filter predicate to exclude specific geometries from interaction and render |
|
() => true |
const ModifyTool = new MoveTool({
modify: "dblclick",
});
const MoveOnlyTool = new MoveTool({
modify: false,
});