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

Feature: Display of drawn feature #371

Merged
merged 18 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
15 changes: 6 additions & 9 deletions elements/drawtools/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,22 @@

## [0.4.2](https://github.com/EOX-A/EOxElements/compare/drawtools-v0.4.1...drawtools-v0.4.2) (2023-10-19)


### Bug Fixes

* Emit drawupdate event also on discard ([#348](https://github.com/EOX-A/EOxElements/issues/348)) ([04d9ebf](https://github.com/EOX-A/EOxElements/commit/04d9ebf1f086f38a2d1b6d08387142ce5651a0f0))
* Prevent zoom on double-click while drawing ([#328](https://github.com/EOX-A/EOxElements/issues/328)) ([a79cb2a](https://github.com/EOX-A/EOxElements/commit/a79cb2a16959f5d43469ae0134402f79ee9c3a3c))
* **style:** Replace buttons with icons ([#347](https://github.com/EOX-A/EOxElements/issues/347)) ([5d0f80b](https://github.com/EOX-A/EOxElements/commit/5d0f80b5806e55e302bcc44c37f10e0088b5842d))

- Emit drawupdate event also on discard ([#348](https://github.com/EOX-A/EOxElements/issues/348)) ([04d9ebf](https://github.com/EOX-A/EOxElements/commit/04d9ebf1f086f38a2d1b6d08387142ce5651a0f0))
- Prevent zoom on double-click while drawing ([#328](https://github.com/EOX-A/EOxElements/issues/328)) ([a79cb2a](https://github.com/EOX-A/EOxElements/commit/a79cb2a16959f5d43469ae0134402f79ee9c3a3c))
- **style:** Replace buttons with icons ([#347](https://github.com/EOX-A/EOxElements/issues/347)) ([5d0f80b](https://github.com/EOX-A/EOxElements/commit/5d0f80b5806e55e302bcc44c37f10e0088b5842d))

### Miscellaneous Chores

* **docs:** Add story description ([bf52202](https://github.com/EOX-A/EOxElements/commit/bf522028075a7861c82cba02ce9838edec735ae4))
* Update readme ([1da4fcf](https://github.com/EOX-A/EOxElements/commit/1da4fcf655ddfc769035d680f93940629f7eabc3))
- **docs:** Add story description ([bf52202](https://github.com/EOX-A/EOxElements/commit/bf522028075a7861c82cba02ce9838edec735ae4))
- Update readme ([1da4fcf](https://github.com/EOX-A/EOxElements/commit/1da4fcf655ddfc769035d680f93940629f7eabc3))

## [0.4.1](https://github.com/EOX-A/EOxElements/compare/drawtools-v0.4.0...drawtools-v0.4.1) (2023-10-19)


### Bug Fixes

* Prevent zoom on double-click while drawing ([#328](https://github.com/EOX-A/EOxElements/issues/328)) ([a79cb2a](https://github.com/EOX-A/EOxElements/commit/a79cb2a16959f5d43469ae0134402f79ee9c3a3c))
- Prevent zoom on double-click while drawing ([#328](https://github.com/EOX-A/EOxElements/issues/328)) ([a79cb2a](https://github.com/EOX-A/EOxElements/commit/a79cb2a16959f5d43469ae0134402f79ee9c3a3c))

## 0.4.0 (2023-10-11)

Expand Down
25 changes: 25 additions & 0 deletions elements/drawtools/drawtools.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,28 @@ export const MultiPolygon = {
multiple-features
></eox-drawtools>`,
};

/**
* By setting the `show-list` attribute or `showList` property to `true`,
* List of features will be visible
*/
export const MultiPolygonWithList = {
render: () => html`
<div style="display: flex">
<eox-map
id="multi"
style="width: 500px; height: 300px;"
layers='[
{"type": "Vector","id": "draw","source": {"type": "Vector"}},
{"type":"Tile","source":{"type":"OSM"}}
]'
></eox-map>
<eox-drawtools
for="eox-map#multi"
layer="draw"
multiple-features
show-list
></eox-drawtools>
</div>
`,
};
164 changes: 164 additions & 0 deletions elements/drawtools/src/components/list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { LitElement, html, nothing } from "lit";
import { keyed } from "lit/directives/keyed.js";
import { styleEOX, styleListEOX } from "../style.eox";
import { getDefaultPolygonStyle, getSelectedPolygonStyle } from "../helpers";

/**
* Display list of features
*
* @element eox-drawtools-list
*/
export class EOxDrawToolsList extends LitElement {
static properties = {
eoxMap: { attribute: false, state: true },
olMap: { attribute: false, state: true },
draw: { attribute: false, state: true },
drawLayer: { attribute: false, state: true },
drawnFeatures: { attribute: false, state: true, type: Array },
modify: { attribute: false, state: true },
unstyled: { type: Boolean },
};

constructor() {
super();

/**
* @type import("../../../map/main").EOxMap
*/
this.eoxMap = null;

/**
* @type import("ol").Map
*/
this.olMap = null;

/**
* The current native OpenLayers `draw` interaction
* @type import("ol/interaction").Draw
*/

this.draw = null;

/**
* The current native OpenLayers draw `layer`
* @type import("ol/layer").Vector<import("ol/source").Vector>
*/

this.drawLayer = null;

/**
* The array of drawn native OpenLayers features. Normally includes only one feature, until multiple feature drawing is enabled.
* @type Array<import("ol").Feature>
*/
this.drawnFeatures = [];

/**
* The current native OpenLayers `modify` interaction
* @type import("ol/interaction").Modify
*/

this.modify = null;

/**
* Render the element without additional styles
*/
this.unstyled = false;

/**
* Index of selected feature
* @type Number || null
*/
this.selectedFeatureIndex = null;
}

/**
* Delete individual feature @param {any} evt
*/
_handleDelete(evt) {
evt.stopPropagation();
const index = evt.target.getAttribute("index");
const feature = this.drawnFeatures[index];
this.drawLayer.getSource().removeFeature(feature);
this.drawnFeatures.splice(index, 1);

// If selected feature gets deletes fit to available bound
if (this.selectedFeatureIndex === Number(index)) {
const newExtent = this.drawLayer.getSource().getExtent();
if (this.drawnFeatures.length) this.olMap.getView().fit(newExtent);
this.selectedFeatureIndex = null;
}

// If selected index is greater than deleted feature index then changing index cursor by 1
else if (this.selectedFeatureIndex > Number(index)) {
this.selectedFeatureIndex = this.selectedFeatureIndex - 1;
this._handleSelectFeature(
this.selectedFeatureIndex,
this.drawnFeatures[this.selectedFeatureIndex]
);
}
this.requestUpdate();
}

/**
* Select a feature @param {Number} i
* Select a feature @param {import("ol").Feature} feature
*/
_handleSelectFeature(i, feature) {
if (this.selectedFeatureIndex === i) return;
silvester-pari marked this conversation as resolved.
Show resolved Hide resolved
if (this.selectedFeatureIndex !== null)
this.drawnFeatures[this.selectedFeatureIndex].setStyle(
getDefaultPolygonStyle()
);
feature.setStyle(getSelectedPolygonStyle());
this.olMap.getView().fit(feature.getGeometry().getExtent());
silvester-pari marked this conversation as resolved.
Show resolved Hide resolved
this.selectedFeatureIndex = i;
this.requestUpdate();
}

render() {
return html`
<style>
${!this.unstyled && styleEOX}
${!this.unstyled && styleListEOX}
</style>
<ul>
${this.drawnFeatures.map((feature, i) =>
keyed(
i + 1,
html`
<li
class="${this.selectedFeatureIndex === i
? "selected"
: nothing}"
@mouseover=${() => {
if (this.selectedFeatureIndex === i) return;
feature.setStyle(getSelectedPolygonStyle());
}}
@mouseout=${() => {
if (this.selectedFeatureIndex === i) return;
feature.setStyle(getDefaultPolygonStyle());
}}
>
<div
class="list"
@click="${() => this._handleSelectFeature(i, feature)}"
>
<span class="title">Feature #${i + 1}</span>
<button
index=${i}
class="remove-icon icon"
@click="${this._handleDelete}"
>
${this.unstyled ? "x" : nothing}
</button>
</div>
</li>
`
)
)}
</ul>
`;
}
}

customElements.define("eox-drawtools-list", EOxDrawToolsList);
41 changes: 41 additions & 0 deletions elements/drawtools/src/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as ol from "ol/style.js";
srijitcoder marked this conversation as resolved.
Show resolved Hide resolved

/**
* Default polygon style
*
* @returns {ol.Style}
*/
export const getDefaultPolygonStyle = () => {
const fill = new ol.Fill({
color: "rgba(255,255,255,0.4)",
});
const stroke = new ol.Stroke({
color: "#3399CC",
width: 1.25,
});

return new ol.Style({
fill: fill,
stroke: stroke,
});
};

/**
* Default selected polygon style
*
* @returns {ol.Style}
*/
export const getSelectedPolygonStyle = () => {
const fill = new ol.Fill({
color: "rgba(51, 153, 204,0.5)",
});
const stroke = new ol.Stroke({
color: "#3399CC",
width: 2.5,
});

return new ol.Style({
fill: fill,
stroke: stroke,
});
};
20 changes: 20 additions & 0 deletions elements/drawtools/src/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { LitElement, html, nothing } from "lit";
import "./components/list";
import { style } from "./style";
import { styleEOX } from "./style.eox";

Expand All @@ -17,6 +18,7 @@ export class EOxDrawTools extends LitElement {
layer: { type: String },
modify: { attribute: false, state: true },
multipleFeatures: { attribute: "multiple-features", type: Boolean },
showList: { attribute: "show-list", type: Boolean },
unstyled: { type: Boolean },
};
}
Expand Down Expand Up @@ -83,6 +85,11 @@ export class EOxDrawTools extends LitElement {
*/
this.multipleFeatures = false;

/**
* Show list of features
*/
this.showList = false;

/**
* Render the element without additional styles
*/
Expand Down Expand Up @@ -198,6 +205,19 @@ export class EOxDrawTools extends LitElement {
discard
</button>
</div>
${this.showList && this.drawnFeatures?.length
? html`<eox-drawtools-list
.eoxMap=${this.#eoxMap}
.olMap=${this.#olMap}
.draw=${this.draw}
.drawLayer=${this.drawLayer}
.drawnFeatures=${this.drawnFeatures}
.modify=${this.modify}
.unstyled=${this.unstyled}
@changed=${() => this.requestUpdate()}
>
</eox-drawtools-list>`
: nothing}
`;
}
}
Expand Down
77 changes: 77 additions & 0 deletions elements/drawtools/src/style.eox.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,80 @@ button.polygon:before {
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23004170' viewBox='0 0 24 24'%3E%3Ctitle%3Eshape-polygon-plus%3C/title%3E%3Cpath d='M17,15.7V13H19V17L10,21L3,14L7,5H11V7H8.3L5.4,13.6L10.4,18.6L17,15.7M22,5V7H19V10H17V7H14V5H17V2H19V5H22Z' /%3E%3C/svg%3E");
}
`;

export const styleListEOX = `
silvester-pari marked this conversation as resolved.
Show resolved Hide resolved
* {
font-family: Roboto, sans-serif;
}
ul {
padding: 0;
}
ul ul {
padding-left: 48px;
}
li:hover {
background: #f0f5f9;
}
li.selected {
background: #f0f5f9;
}
li {
list-style: none;
padding: 4px;
}
li {
border-bottom: 1px solid #0041703a;
}
li:first-child {
border-top: 1px solid #0041703a;
}
li.sortable-chosen {
background: #eeea;
}
li.sortable-drag {
opacity: 0;
}
li.sortable-ghost {
}
eox-drawtools-list {
width: 100%;
}
.list {
width: 100%;
align-items: center;
justify-content: space-between;
display: flex;
align-items: center;
cursor: pointer;
font-size: small;
gap: 10px;

}
label {
gap: 10px;
}
label, span {
display: flex;
align-items: center;
cursor: pointer;
font-size: small;
flex-grow: 1;
}
.list .remove-icon::before {
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23ff0000' viewBox='0 0 24 24'%3E%3Ctitle%3Edelete-outline%3C/title%3E%3Cpath d='M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19M8,9H16V19H8V9M15.5,4L14.5,3H9.5L8.5,4H5V6H19V4H15.5Z' /%3E%3C/svg%3E");
silvester-pari marked this conversation as resolved.
Show resolved Hide resolved
}
button.icon {
transition: opacity .2s;
opacity: .7;
display: flex;
justify-content: center;
background: transparent;
}
button.icon:hover {
opacity: 1;
}
button.icon, button.icon::before {
height: 16px;
width: 16px;
}
`;
Loading