Skip to content

Commit e32a23d

Browse files
committed
feat: added bounding box option in layer (for future usage)
1 parent f95e43a commit e32a23d

File tree

13 files changed

+345
-80
lines changed

13 files changed

+345
-80
lines changed

src/App.js

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import ToolsScreen from "./components/ToolsScreen";
55
import Layers from "./containers/LayersContainer";
66

77
import "./App.css";
8-
import { setQueryHistory, getQueryHistory } from "./common/utils/queryHistoryStorage";
8+
import {
9+
setQueryHistory,
10+
getQueryHistory
11+
} from "./common/utils/queryHistoryStorage";
912

1013
class App extends Component {
1114
constructor() {
@@ -15,6 +18,9 @@ class App extends Component {
1518
this.zoomToLayer = this.zoomToLayer.bind(this);
1619
this.getLayers = this.getLayers.bind(this);
1720
}
21+
state = {
22+
isDrawing: false
23+
};
1824

1925
getLayers(layer) {
2026
return this.layers.getLayers(layer);
@@ -26,12 +32,31 @@ class App extends Component {
2632
this.layers.zoomToLayer(layer);
2733
}
2834

35+
setDrawRectange = isDrawingRectange => {
36+
this.setState({ isDrawingRectange });
37+
if (!isDrawingRectange) {
38+
this.setState({ drawedRectange: null });
39+
}
40+
};
41+
onDrawingDone = box => {
42+
this.setState({ drawedRectange: box });
43+
// this.layers.doneDrawingRectange(box);
44+
};
45+
2946
render() {
47+
const { drawedRectange } = this.state;
3048
return (
3149
<div className="root">
3250
<div className="screen-left">
33-
<Layers onRef={ref => (this.layers = ref)} />
34-
<Map />
51+
<Layers
52+
onRef={ref => (this.layers = ref)}
53+
setDrawRectange={this.setDrawRectange}
54+
drawedRectange={drawedRectange}
55+
/>
56+
<Map
57+
isDrawingRectange={this.state.isDrawingRectange}
58+
onDrawingDone={this.onDrawingDone}
59+
/>
3560
</div>
3661
<div className="screen-right">
3762
<ToolsScreen

src/action-creators/map.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
import { ADD_LAYER, REMOVE_LAYER } from '../action-types/map';
1+
import { ADD_LAYER, REMOVE_LAYER } from "../action-types/map";
22

3-
export const createAddLayerAction = (id, data) => {
3+
export const createAddLayerAction = (id, layerType, data) => {
44
return {
55
type: ADD_LAYER,
66
payload: {
7+
layerType,
78
id,
8-
data,
9-
},
9+
data
10+
}
1011
};
1112
};
1213

13-
export const createRemoveLayerAction = (id) => {
14+
export const createRemoveLayerAction = id => {
1415
return {
1516
type: REMOVE_LAYER,
17+
1618
payload: {
17-
id,
18-
},
19+
id
20+
}
1921
};
20-
};
22+
};

src/common/FileFormats.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ export default {
44
displayName: "Excel File",
55
isLayer: false
66
},
7+
"application/vnd.ms-excel": {
8+
ext: ".xls",
9+
displayName: "Excel File",
10+
isLayer: false
11+
},
712
"application/json": {
813
ext: ".json",
914
displayName: "Map Layer",

src/common/LayerTypes.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const LayerTypes = {
2+
GEO_JSON: 0,
3+
BOUNDING_BOX:1
4+
}
5+
export default LayerTypes;

src/components/Icons/Icons.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,16 @@ export function PlusIcon({ className }) {
153153
</svg>
154154
);
155155
}
156+
157+
export function BoundingBoxIcon({ className }) {
158+
return (
159+
<svg
160+
className={className}
161+
xmlns="http://www.w3.org/2000/svg"
162+
version="1.1"
163+
viewBox="0 0 89.534 89.535" // viewBox="0 0 304.588 304.588"
164+
>
165+
<path d="M12.241,88.083v-7.84h65.053v7.84c0,0.762,0.616,1.377,1.377,1.377s1.377-0.615,1.377-1.377v-8.107h8.109 c0.761,0,1.377-0.617,1.377-1.377c0-0.761-0.616-1.377-1.377-1.377h-8.109V12.313h8.109c0.761,0,1.377-0.617,1.377-1.377 c0-0.762-0.616-1.377-1.377-1.377h-8.109V1.451c0-0.761-0.616-1.377-1.377-1.377s-1.377,0.616-1.377,1.377V9.56H12.241V1.451 c0-0.761-0.616-1.377-1.377-1.377c-0.761,0-1.377,0.616-1.377,1.377V9.56h-8.11C0.616,9.56,0,10.175,0,10.937 c0,0.76,0.616,1.377,1.377,1.377h7.985v64.909H1.377C0.616,77.222,0,77.837,0,78.599c0,0.76,0.616,1.377,1.377,1.377h8.109v8.106 c0,0.761,0.616,1.377,1.377,1.377C11.624,89.459,12.241,88.845,12.241,88.083z M12.179,33.272V12.313h21.113v20.959H12.179z M34.21,33.272V12.313h21.052v20.959H34.21z M56.242,33.272V12.313h21.052v20.959H56.242z M12.179,55.306V34.19h21.113v21.114 H12.179V55.306z M34.211,55.306V34.191h21.053v21.115H34.211L34.211,55.306z M56.242,55.306V34.191h21.052v21.115H56.242 L56.242,55.306z M12.179,77.336V56.224h21.114v21.112H12.179z M34.211,77.336V56.224h21.053v21.112H34.211z M56.242,77.336V56.224 h21.052v21.112H56.242z M13.767,75.625V58.292h17.332v17.332H13.767z" />
166+
</svg>
167+
);
168+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from "react";
2+
import PropTypes from "prop-types";
3+
import Checkbox from "./checkbox";
4+
5+
export default class CheckableItem extends React.Component {
6+
onClick = identifier => this.props.onClick(identifier);
7+
8+
render() {
9+
const { value, highlight, data, content } = this.props;
10+
return (
11+
<div className={`layer ${highlight ? "highlighted" : ""}`}>
12+
<Checkbox
13+
isDisplayed={value}
14+
onClick={this.onClick}
15+
identifier={data}
16+
/>
17+
<span>{content}</span>
18+
</div>
19+
);
20+
}
21+
}
22+
23+
CheckableItem.propTypes = {
24+
onClick: PropTypes.func,
25+
constent: PropTypes.any,
26+
highlight: PropTypes.bool,
27+
value: PropTypes.bool,
28+
content: PropTypes.string
29+
};

src/components/Layers/Layers.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
}
3333

3434
.layers input[type="file"] {
35-
margin: 6px 18px;
35+
margin: 6px 8px;
3636
}
3737

3838
.layers .layer svg {

src/components/Layers/Layers.js

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ import React, { Component } from "react";
22

33
import "./Layers.css";
44
import { UploadFromUrl, GetLayerUrlFromId } from "./RemoteStorage";
5-
import { LayersIcon } from "../Icons/Icons";
6-
import Checkbox from "./checkbox";
5+
import { LayersIcon, BoundingBoxIcon } from "../Icons/Icons";
76
import axios from "axios";
87
import UploadFile from "./UploadFile";
8+
import LayerTypes from '../../common/LayerTypes'
9+
10+
import "leaflet-draw/dist/leaflet.draw.css";
11+
import CheckableItem from "./CheckableItem";
912

1013
export default class Layers extends Component {
1114
constructor(props) {
@@ -16,7 +19,8 @@ export default class Layers extends Component {
1619
}
1720
state = {
1821
highlighted: {},
19-
layersList: []
22+
layersList: [],
23+
bboxList: []
2024
};
2125

2226
componentDidMount() {
@@ -29,16 +33,20 @@ export default class Layers extends Component {
2933
}
3034

3135
fetchLayersList() {
32-
let layersList;
36+
let layersList, bboxList;
3337
try {
34-
layersList = JSON.parse(localStorage.getItem("LayersList"));
35-
if (!Array.isArray(layersList)) layersList = [];
38+
const data = JSON.parse(localStorage.getItem("LayersList"));
39+
bboxList = data.bboxList;
40+
layersList = data.layersList;
41+
42+
layersList.forEach(layer => (layer.displayed = false));
43+
bboxList.forEach(bbox => (bbox.displayed = false));
3644
} catch (err) {
37-
this.props.alert.error("Failed to load layers");
3845
layersList = [];
46+
bboxList = [];
3947
}
40-
layersList.forEach(layer => (layer.displayed = false));
41-
this.setState({ layersList: layersList });
48+
49+
this.setState({ layersList, bboxList });
4250
}
4351

4452
setHighlightedLayer(layerId, isHighlighted) {
@@ -77,12 +85,16 @@ export default class Layers extends Component {
7785
const layersList = this.state.layersList.concat(nonExistingLayers);
7886

7987
this.setState({ layersList });
80-
8188
layersToAdd.map(({ id }) => this.highlight(id));
89+
this.saveToLocalStorage(layersList, this.state.bboxList);
90+
}
8291

92+
saveToLocalStorage(layersList, bboxList) {
93+
layersList.map(({ name, id }) => ({ name, id }));
94+
bboxList.map(({ id, name, box }) => ({ id, name, box }));
8395
localStorage.setItem(
8496
"LayersList",
85-
JSON.stringify(layersList.map(({ name, id }) => ({ name, id })))
97+
JSON.stringify({ layersList, bboxList })
8698
);
8799
}
88100

@@ -103,13 +115,13 @@ export default class Layers extends Component {
103115
axios
104116
.get(GetLayerUrlFromId(layer.id))
105117
.then(({ data }) => data)
106-
.then(geojson => this.props.addLayerToMap(layer.id, geojson));
118+
.then(geojson => this.props.addLayerToMap(layer.id,LayerTypes.GEO_JSON, geojson));
107119
} else {
108120
this.props.removeLayerFromMap(layer.id);
109121
}
110122

111-
const layersList = this.state.layersList.map(
112-
layer => (layer.id === layerId ? newLayer : layer)
123+
const layersList = this.state.layersList.map(layer =>
124+
layer.id === layerId ? newLayer : layer
113125
);
114126
this.setState({ layersList });
115127
}
@@ -126,28 +138,71 @@ export default class Layers extends Component {
126138
});
127139
}
128140

141+
addBoundingBox = bbox => {
142+
const bboxList = this.state.bboxList.concat([
143+
{
144+
box: bbox,
145+
name: "Bounding Box",
146+
id: Math.random()
147+
.toString(36)
148+
.substring(7)
149+
}
150+
]);
151+
this.setState({ bboxList });
152+
this.saveToLocalStorage(this.state.layersList, bboxList);
153+
};
154+
155+
toggleBbox = bboxId => {
156+
let bbox = this.state.bboxList.filter(bbox => bbox.id === bboxId)[0];
157+
bbox = { ...bbox, displayed: !bbox.displayed };
158+
159+
if (bbox.displayed) {
160+
this.props.addLayerToMap(bbox.id, LayerTypes.BOUNDING_BOX, bbox.box);
161+
} else {
162+
this.props.removeLayerFromMap(bbox.id);
163+
}
164+
165+
const bboxList = this.state.bboxList.map(b =>
166+
b.id === bboxId ? bbox : b
167+
);
168+
this.setState({ bboxList });
169+
};
129170
render() {
171+
const { setDrawRectange, drawedRectange } = this.props;
130172
return (
131173
<div className="layers">
132174
<h3 className="title">
133175
<LayersIcon className="layers-icon" />
134176
<span>Layers</span>
135177
</h3>
136-
<UploadFile concatLayers={this.concatLayers} />
178+
<UploadFile
179+
concatLayers={this.concatLayers}
180+
addBoundingBox={this.addBoundingBox}
181+
setDrawRectange={setDrawRectange}
182+
drawedRectange={drawedRectange}
183+
/>
137184
{this.state.layersList.map(layer => (
138-
<div
139-
className={`layer ${
140-
this.state.highlighted[layer.id] ? "highlighted" : ""
141-
}`}
185+
<CheckableItem
186+
highlight={!!this.state.highlighted[layer.id]}
187+
data={layer.id}
188+
onClick={this.toggleLayer}
189+
content={layer.name}
190+
value={layer.displayed}
142191
key={layer.id}
143-
>
144-
<Checkbox
145-
isDisplayed={layer.displayed}
146-
onClick={this.toggleLayer}
147-
identifier={layer.id}
148-
/>
149-
<span>{layer.name}</span>
150-
</div>
192+
/>
193+
))}
194+
<h3 className="title">
195+
<BoundingBoxIcon className="layers-icon" />
196+
<span>Bounding Boxes</span>
197+
</h3>
198+
{this.state.bboxList.map(bbox => (
199+
<CheckableItem
200+
data={bbox.id}
201+
onClick={this.toggleBbox}
202+
content={bbox.name}
203+
value={bbox.displayed}
204+
key={bbox.id}
205+
/>
151206
))}
152207
</div>
153208
);

src/components/Layers/UploadFile.css

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
.upload-files {
1717
position: absolute;
18-
height: 50px;
18+
padding-top: 20px;
1919
left: 3px;
2020
right: 3px;
2121
top: 3px;
@@ -24,7 +24,7 @@
2424
}
2525

2626
.upload-files input {
27-
position: absolute;
27+
display: inline-block;
2828
bottom: 0;
2929
right: 0;
3030
left: 20px;
@@ -41,7 +41,7 @@
4141
}
4242

4343
.upload-files .upload-button {
44-
position: absolute;
44+
display: inline-block;
4545
height: 25px;
4646
width: 25px;
4747
bottom: 7px;
@@ -54,3 +54,17 @@
5454
width: 20px !important;
5555
height: 20px !important;
5656
}
57+
58+
.upload-files .bbox-draw-start{
59+
background-color: #EEE;
60+
border: none;
61+
display: block;
62+
margin: 5px;
63+
width: calc(100% - 11px);
64+
border-radius: 5px;
65+
}
66+
67+
.upload-files .or-label{
68+
padding: 4px;
69+
text-align: center;
70+
}

0 commit comments

Comments
 (0)