Skip to content
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
112 changes: 77 additions & 35 deletions src/components/my-map/drawing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,15 @@ import { MultiPoint, Polygon } from "ol/geom";
import { Draw, Modify, Snap } from "ol/interaction";
import { Vector as VectorLayer } from "ol/layer";
import { Vector as VectorSource } from "ol/source";
import { Fill, RegularShape, Stroke, Style } from "ol/style";
import { Circle, Fill, RegularShape, Stroke, Style } from "ol/style";
import CircleStyle from "ol/style/Circle";
import { StyleLike } from "ol/style/Style";
import { pointsSource } from "./snapping";

export type DrawTypeEnum = "Polygon" | "Point"; // ref https://openlayers.org/en/latest/apidoc/module-ol_geom_Geometry.html#~Type
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

export type DrawPointerEnum = "crosshair" | "dot";

const redLineBase = {
color: "#ff0000",
width: 3,
};

const redLineStroke = new Stroke(redLineBase);

const redDashedStroke = new Stroke({
...redLineBase,
lineDash: [2, 8],
});

const redLineFill = new Fill({
color: "rgba(255, 0, 0, 0.1)",
});

// drawPointer styles
const crosshair = new RegularShape({
stroke: new Stroke({
color: "red",
Expand All @@ -41,7 +28,24 @@ const dot = new CircleStyle({
}),
});

const drawingVertices = new Style({
// feature style: red-line site boundary
const redLineBase = {
color: "#ff0000",
width: 3,
};

const redLineStroke = new Stroke(redLineBase);

const redDashedStroke = new Stroke({
...redLineBase,
lineDash: [2, 8],
});

const redLineFill = new Fill({
color: "rgba(255, 0, 0, 0.1)",
});

const polygonVertices = new Style({
image: new RegularShape({
fill: new Fill({
color: "#fff",
Expand All @@ -66,28 +70,66 @@ const drawingVertices = new Style({
},
});

export const drawingSource = new VectorSource();
const boundaryLayerStyle: StyleLike = [
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there might be future scope for extracting these out into a style.ts or similar 👍

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep totally fair, definitely getting a bit cluttered as-is !

new Style({
fill: redLineFill,
stroke: redLineStroke,
}),
polygonVertices,
];

function configureBoundaryDrawStyle(pointerStyle: DrawPointerEnum) {
return new Style({
stroke: redDashedStroke,
fill: redLineFill,
image: pointerStyle === "crosshair" ? crosshair : dot,
});
}

export const drawingLayer = new VectorLayer({
source: drawingSource,
style: [
new Style({
fill: redLineFill,
stroke: redLineStroke,
// feature style: single point
function configurePointLayerStyle(pointColor: string) {
return new Style({
image: new Circle({
radius: 9,
fill: new Fill({ color: pointColor }),
}),
drawingVertices,
],
});
});
}

function configurePointDrawStyle(pointColor: string) {
return new Style({
fill: new Fill({ color: pointColor }),
});
}

export function configureDraw(pointerStyle: DrawPointerEnum) {
export const drawingSource = new VectorSource();

export function configureDrawingLayer(
drawType: DrawTypeEnum,
pointColor: string
) {
return new VectorLayer({
source: drawingSource,
style:
drawType === "Polygon"
? boundaryLayerStyle
: configurePointLayerStyle(pointColor),
});
}

// configure the key openlayers interactions
export function configureDraw(
drawType: DrawTypeEnum,
pointerStyle: DrawPointerEnum,
pointColor: string
) {
return new Draw({
source: drawingSource,
type: "Polygon",
style: new Style({
stroke: redDashedStroke,
fill: redLineFill,
image: pointerStyle === "crosshair" ? crosshair : dot,
}),
type: drawType,
style:
drawType === "Polygon"
? configureBoundaryDrawStyle(pointerStyle)
: configurePointDrawStyle(pointColor),
});
}

Expand Down
39 changes: 29 additions & 10 deletions src/components/my-map/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import { last } from "rambda";
import { northArrowControl, scaleControl, resetControl } from "./controls";
import {
configureDraw,
configureDrawingLayer,
configureModify,
drawingLayer,
drawingSource,
DrawPointerEnum,
DrawTypeEnum,
snap,
} from "./drawing";
import pinIcon from "./icons/poi-alt.svg";
Expand Down Expand Up @@ -71,6 +72,12 @@ export class MyMap extends LitElement {
@property({ type: Boolean })
drawMode = false;

@property({ type: String })
drawType: DrawTypeEnum = "Polygon";

@property({ type: String })
drawPointColor = "#2c2c2c";

@property({ type: Object })
drawGeojsonData = {
type: "Feature",
Expand Down Expand Up @@ -114,7 +121,7 @@ export class MyMap extends LitElement {
markerLongitude = this.longitude;

@property({ type: String })
markerColor = "#000000";
markerColor = "#2c2c2c";

@property({ type: Object })
geojsonData = {
Expand Down Expand Up @@ -234,7 +241,11 @@ export class MyMap extends LitElement {
window.olMap = import.meta.env.VITEST ? this.map : undefined;

// make configurable interactions available
const draw = configureDraw(this.drawPointer);
const draw = configureDraw(
this.drawType,
this.drawPointer,
this.drawPointColor
);
const modify = configureModify(this.drawPointer);

// add custom scale line and north arrow controls to the map
Expand All @@ -261,10 +272,13 @@ export class MyMap extends LitElement {
drawingSource.clear();

this.dispatch("geojsonChange", {});
this.dispatch(
"areaChange",
`0 ${this.areaUnit === "m2" ? "m²" : this.areaUnit}`
);

if (this.drawType === "Polygon") {
this.dispatch(
"areaChange",
`0 ${this.areaUnit === "m2" ? "m²" : this.areaUnit}`
);
}

map.addInteraction(draw);
map.addInteraction(snap);
Expand Down Expand Up @@ -335,6 +349,10 @@ export class MyMap extends LitElement {
}

// draw interactions
const drawingLayer = configureDrawingLayer(
this.drawType,
this.drawPointColor
);
if (this.drawMode) {
// make sure drawingSource is cleared upfront, even if drawGeojsonData is provided
drawingSource.clear();
Expand Down Expand Up @@ -375,22 +393,23 @@ export class MyMap extends LitElement {
})
);

if (lastSketchGeom) {
if (lastSketchGeom && this.drawType === "Polygon") {
this.dispatch(
"areaChange",
formatArea(lastSketchGeom, this.areaUnit)
);
}

// limit to drawing a single polygon, only allow modifications to existing shape
// limit to drawing a single feature, only allow modifications to existing shape
map.removeInteraction(draw);
}
});
}

// show snapping points when in drawMode, with vector tile basemap enabled, and at qualifying zoom
// show snapping points when in boundary drawMode, with vector tile basemap enabled, and at qualifying zoom
if (
this.drawMode &&
this.drawType === "Polygon" &&
Boolean(this.osVectorTilesApiKey) &&
!this.disableVectorTiles
) {
Expand Down